[SOLVED] Run calculix from python API using a previously written .inp file

About the development of the FEM module/workbench.

Moderator: bernd

EkaitzEsteban
Posts: 108
Joined: Wed Sep 12, 2018 1:31 pm

[SOLVED] Run calculix from python API using a previously written .inp file

Post by EkaitzEsteban »

Hello,

I create a simple box in freecad. The .inp of this file is the following one:

DEFAULT .INP file

Code: Select all

** written by FreeCAD inp file writer for CalculiX,Abaqus meshes
** highest dimension mesh elements only.

** Nodes
*Node, NSET=Nall
1, 0, 0, 10
2, 0, 0, 0
3, 0, 30, 10
4, 0, 30, 0
5, 20, 0, 10
6, 20, 0, 0
7, 20, 30, 10
8, 20, 30, 0
9, 0, 0, 5
10, 0, 15, 10
11, 0, 30, 5
12, 0, 15, 0
13, 20, 0, 5
14, 20, 15, 10
15, 20, 30, 5
16, 20, 15, 0
17, 10, 0, 0
18, 10, 0, 10
19, 10, 30, 0
20, 10, 30, 10
21, 0, 15, 5
22, 0, 7.5, 2.5
23, 0, 7.5, 7.5
24, 0, 22.5, 7.5
25, 0, 22.5, 2.5
26, 20, 15, 5
27, 20, 7.5, 2.5
28, 20, 7.5, 7.5
29, 20, 22.5, 7.5
30, 20, 22.5, 2.5
31, 10, 0, 5
32, 5, 0, 2.5
33, 5, 0, 7.5
34, 15, 0, 7.5
35, 15, 0, 2.5
36, 10, 30, 5
37, 5, 30, 7.5
38, 5, 30, 2.5
39, 15, 30, 7.5
40, 15, 30, 2.5
41, 10, 15, 0
42, 5, 22.5, 0
43, 5, 7.5, 0
44, 15, 7.5, 0
45, 15, 22.5, 0
46, 10, 15, 10
47, 5, 22.5, 10
48, 5, 7.5, 10
49, 15, 7.5, 10
50, 15, 22.5, 10
51, 10, 7.5, 7.5
52, 10, 7.5, 2.5
53, 10, 22.5, 7.5
54, 10, 22.5, 2.5
55, 5, 15, 7.5
56, 5, 15, 2.5
57, 10, 15, 5
58, 5, 7.5, 5
59, 15, 15, 2.5
60, 15, 15, 7.5
61, 15, 7.5, 5
62, 5, 22.5, 5
63, 15, 22.5, 5


** Volume elements
*Element, TYPE=C3D10, ELSET=Evolumes
37, 46, 5, 1, 31, 49, 18, 48, 51, 34, 33
38, 6, 41, 2, 31, 44, 43, 17, 35, 52, 32
39, 46, 3, 7, 36, 47, 20, 50, 53, 37, 39
40, 41, 8, 4, 36, 45, 19, 42, 54, 40, 38
41, 41, 46, 21, 31, 57, 55, 56, 52, 51, 58
42, 26, 46, 41, 31, 60, 57, 59, 61, 51, 52
43, 41, 21, 46, 36, 56, 55, 57, 54, 62, 53
44, 26, 41, 46, 36, 59, 57, 60, 63, 54, 53
45, 46, 1, 21, 31, 48, 23, 55, 51, 33, 58
46, 6, 26, 41, 31, 27, 59, 44, 35, 61, 52
47, 41, 4, 21, 36, 42, 25, 56, 54, 38, 62
48, 26, 8, 41, 36, 30, 45, 59, 63, 40, 54
49, 26, 5, 46, 31, 28, 49, 60, 61, 34, 51
50, 41, 21, 2, 31, 56, 22, 43, 52, 58, 32
51, 26, 46, 7, 36, 60, 50, 29, 63, 53, 39
52, 46, 21, 3, 36, 55, 24, 47, 53, 62, 37
53, 3, 21, 4, 36, 24, 25, 11, 37, 62, 38
54, 6, 5, 26, 31, 13, 28, 27, 35, 34, 61
55, 1, 2, 21, 31, 9, 22, 23, 33, 32, 58
56, 26, 7, 8, 36, 29, 15, 30, 63, 39, 40
57, 3, 1, 21, 46, 10, 23, 24, 47, 48, 55
58, 46, 7, 5, 26, 50, 14, 49, 60, 29, 28
59, 26, 41, 8, 6, 59, 45, 30, 27, 44, 16
60, 21, 2, 4, 41, 22, 12, 25, 56, 43, 42

** Define element set Eall
*ELSET, ELSET=Eall
Evolumes



***********************************************************
** Element sets for materials and FEM element type (solid, shell, beam, fluid)
** written by write_element_sets_material_and_femelement_type function
*ELSET,ELSET=SolidMaterialSolid
Evolumes

***********************************************************
** Node sets for fixed constraint
** written by write_node_sets_constraints_fixed function
** FemConstraintFixed
*NSET,NSET=FemConstraintFixed
1,
2,
5,
6,
9,
13,
17,
18,
31,
32,
33,
34,
35,

***********************************************************
** Materials
** written by write_materials function
** Young's modulus unit is MPa = N/mm2
** Density's unit is t/mm^3
** FreeCAD material name: CalculiX-Steel
** Steel
*MATERIAL, NAME=SolidMaterial
*ELASTIC
210000, 0.300
*DENSITY
7.900e-09

***********************************************************
** Sections
** written by write_femelementsets function
*SOLID SECTION, ELSET=SolidMaterialSolid, MATERIAL=SolidMaterial

***********************************************************
** At least one step is needed to run an CalculiX analysis of FreeCAD
** written by write_step_begin function
*STEP
*FREQUENCY
3,0.0,100000.0


***********************************************************
** Fixed Constraints
** written by write_constraints_fixed function
** FemConstraintFixed
*BOUNDARY
FemConstraintFixed,1
FemConstraintFixed,2
FemConstraintFixed,3


***********************************************************
** Outputs --> frd file
** written by write_outputs_types function
*NODE FILE
U
*EL FILE
S, E
** outputs --> dat file
*NODE PRINT , NSET=Nall
U 
*EL PRINT , ELSET=Eall
S 

***********************************************************
** written by write_step_end function
*END STEP 

***********************************************************
** CalculiX Input file
** written by write_footer function
**   written by    --> FreeCAD 0.17.13528 (Git)
**   written on    --> Sun Sep 23 12:50:46 2018
**   file name     --> SimpleBox.FCStd
**   analysis name --> Analysis
**
**
**
**   Units
**
**   Geometry (mesh data)        --> mm
**   Materials (Young's modulus) --> N/mm2 = MPa
**   Loads (nodal loads)         --> N
**
I modify the .inp file in order to obtain exactly the same results:

MY .INP file

Code: Select all

** written by FreeCAD inp file writer for CalculiX,Abaqus meshes
** highest dimension mesh elements only.

** Nodes
*Node, NSET=Nall
1, 0, 0, 10
2, 0, 0, 0
3, 0, 30, 10
4, 0, 30, 0
5, 20, 0, 10
6, 20, 0, 0
7, 20, 30, 10
8, 20, 30, 0
9, 0, 0, 5
10, 0, 15, 10
11, 0, 30, 5
12, 0, 15, 0
13, 20, 0, 5
14, 20, 15, 10
15, 20, 30, 5
16, 20, 15, 0
17, 10, 0, 0
18, 10, 0, 10
19, 10, 30, 0
20, 10, 30, 10
21, 0, 15, 5
22, 0, 7.5, 2.5
23, 0, 7.5, 7.5
24, 0, 22.5, 7.5
25, 0, 22.5, 2.5
26, 20, 15, 5
27, 20, 7.5, 2.5
28, 20, 7.5, 7.5
29, 20, 22.5, 7.5
30, 20, 22.5, 2.5
31, 10, 0, 5
32, 5, 0, 2.5
33, 5, 0, 7.5
34, 15, 0, 7.5
35, 15, 0, 2.5
36, 10, 30, 5
37, 5, 30, 7.5
38, 5, 30, 2.5
39, 15, 30, 7.5
40, 15, 30, 2.5
41, 10, 15, 0
42, 5, 22.5, 0
43, 5, 7.5, 0
44, 15, 7.5, 0
45, 15, 22.5, 0
46, 10, 15, 10
47, 5, 22.5, 10
48, 5, 7.5, 10
49, 15, 7.5, 10
50, 15, 22.5, 10
51, 10, 7.5, 7.5
52, 10, 7.5, 2.5
53, 10, 22.5, 7.5
54, 10, 22.5, 2.5
55, 5, 15, 7.5
56, 5, 15, 2.5
57, 10, 15, 5
58, 5, 7.5, 5
59, 15, 15, 2.5
60, 15, 15, 7.5
61, 15, 7.5, 5
62, 5, 22.5, 5
63, 15, 22.5, 5


** Volume elements
*Element, TYPE=C3D10, ELSET=Evolumes
37, 46, 5, 1, 31, 49, 18, 48, 51, 34, 33
38, 6, 41, 2, 31, 44, 43, 17, 35, 52, 32
39, 46, 3, 7, 36, 47, 20, 50, 53, 37, 39
40, 41, 8, 4, 36, 45, 19, 42, 54, 40, 38
41, 41, 46, 21, 31, 57, 55, 56, 52, 51, 58
42, 26, 46, 41, 31, 60, 57, 59, 61, 51, 52
43, 41, 21, 46, 36, 56, 55, 57, 54, 62, 53
44, 26, 41, 46, 36, 59, 57, 60, 63, 54, 53
45, 46, 1, 21, 31, 48, 23, 55, 51, 33, 58
46, 6, 26, 41, 31, 27, 59, 44, 35, 61, 52
47, 41, 4, 21, 36, 42, 25, 56, 54, 38, 62
48, 26, 8, 41, 36, 30, 45, 59, 63, 40, 54
49, 26, 5, 46, 31, 28, 49, 60, 61, 34, 51
50, 41, 21, 2, 31, 56, 22, 43, 52, 58, 32
51, 26, 46, 7, 36, 60, 50, 29, 63, 53, 39
52, 46, 21, 3, 36, 55, 24, 47, 53, 62, 37
53, 3, 21, 4, 36, 24, 25, 11, 37, 62, 38
54, 6, 5, 26, 31, 13, 28, 27, 35, 34, 61
55, 1, 2, 21, 31, 9, 22, 23, 33, 32, 58
56, 26, 7, 8, 36, 29, 15, 30, 63, 39, 40
57, 3, 1, 21, 46, 10, 23, 24, 47, 48, 55
58, 46, 7, 5, 26, 50, 14, 49, 60, 29, 28
59, 26, 41, 8, 6, 59, 45, 30, 27, 44, 16
60, 21, 2, 4, 41, 22, 12, 25, 56, 43, 42

** Define element set Eall
*ELSET, ELSET=Eall
Evolumes



***********************************************************
** Element sets for materials and FEM element type (solid, shell, beam, fluid)
** written by write_element_sets_material_and_femelement_type function
*ELSET,ELSET=SolidMaterialSolid
37,
39,
40,
41,
42,
43,
44,
45,
47,
48,
49,
50,
51,
52,
53,
55,
56,
57,
58,
60,
*ELSET,ELSET=MaterialSelectedNodes
38,
46,
54,
59,

***********************************************************
** Node sets for fixed constraint
** written by write_node_sets_constraints_fixed function
** FemConstraintFixed
*NSET,NSET=FemConstraintFixed
1,
2,
5,
6,
9,
13,
17,
18,
31,
32,
33,
34,
35,

***********************************************************
** Materials
** written by write_materials function
** Young's modulus unit is MPa = N/mm2
** Density's unit is t/mm^3
** FreeCAD material name: CalculiX-Steel
** Steel
*MATERIAL, NAME=SolidMaterial
*ELASTIC
210000, 0.300
*DENSITY
7.900e-09
*MATERIAL, NAME=SolidMaterialSelectedNodes
*ELASTIC
210000, 0.300
*DENSITY
7.900e-09

***********************************************************
** Sections
** written by write_femelementsets function
*SOLID SECTION, ELSET=SolidMaterialSolid, MATERIAL=SolidMaterial
*SOLID SECTION, ELSET=MaterialSelectedNodes, MATERIAL=SolidMaterialSelectedNodes

***********************************************************
** At least one step is needed to run an CalculiX analysis of FreeCAD
** written by write_step_begin function
*STEP
*FREQUENCY
3,0.0,100000.0


***********************************************************
** Fixed Constraints
** written by write_constraints_fixed function
** FemConstraintFixed
*BOUNDARY
FemConstraintFixed,1
FemConstraintFixed,2
FemConstraintFixed,3


***********************************************************
** Outputs --> frd file
** written by write_outputs_types function
*NODE FILE
U
*EL FILE
S, E
** outputs --> dat file
*NODE PRINT , NSET=Nall
U 
*EL PRINT , ELSET=Eall
S 

***********************************************************
** written by write_step_end function
*END STEP 

***********************************************************
** CalculiX Input file
** written by write_footer function
**   written by    --> FreeCAD 0.17.13528 (Git)
**   written on    --> Sun Sep 23 12:50:46 2018
**   file name     --> SimpleBox.FCStd
**   analysis name --> Analysis
**
**
**
**   Units
**
**   Geometry (mesh data)        --> mm
**   Materials (Young's modulus) --> N/mm2 = MPa
**   Loads (nodal loads)         --> N
**
A manual procedure exists; which consists on copy and paste my,inp content in edit.inp file option, save it and then press run calculix button. However, this is not a solution because I want to run in a loop a large amount of simulations automatically.

The main problem is how to execute calculix from FreeCAD python API in order to read my.inp file and simulate.

I attached my file: SimpleBox.FCStd

BTW: This post is related with the following three questions:

https://forum.freecadweb.org/viewtopic.php?f=18&t=31100
https://forum.freecadweb.org/viewtopic.php?f=18&t=31123
https://forum.freecadweb.org/viewtopic.php?f=22&t=23467 - here I post here too but I dont if it is the correct place, because it is related with FEM and run calculix solver....

Thank you in advance,

Ekaitz.

EDIT: Solved here:
https://forum.freecadweb.org/viewtopic. ... 10#p258417
Thank you bernd.
Attachments
SimpleBox.FCStd
(9.31 KiB) Downloaded 72 times
User avatar
bernd
Veteran
Posts: 12849
Joined: Sun Sep 08, 2013 8:07 pm
Location: Zürich, Switzerland
Contact:

Re: [Help] Run calculix from python API using a previously written .inp file

Post by bernd »

- open FEM example from StartWB
- run analysis in Python

Code: Select all

# run the analysis
import FemGui
FemGui.setActiveAnalysis(App.ActiveDocument.Analysis)
from femtools import ccxtools
fea = ccxtools.FemToolsCcx()
fea.update_objects()
message = fea.check_prerequisites()
if not message:
    fea.reset_all()
    fea.run()
    fea.load_results()
else:
    FreeCAD.Console.PrintError("Houston, we have a problem! {}\n".format(message))  # in report view
    print("Houston, we have a problem! {}\n".format(message))  # in python console
#


to get the input file name we do a:

Code: Select all

fea.inp_file_name

Code: Select all

>>> fea.inp_file_name
'c:\\users\\bha\\appdata\\local\\temp\\Box_Mesh.inp'
>>> 
give it a try in a file explorer ... for me the file is there.


- ok have got an input file now, let's try to run CalculiX with this input file from FreeCAD.
- I got it working but is is a hack !!!
- close FreeCAD
- change the module ccxtools.py (see after the code block)
- start FreeCAD
- make a new document and add a Analysis (a CcxToolsSolver will be added too)
- run the code (you need to adapt your inputfile)

Code: Select all

import FemGui
FemGui.setActiveAnalysis(App.ActiveDocument.Analysis)
from femtools import ccxtools
fea = ccxtools.FemToolsCcx()
fea.update_objects()
fea.inp_file_name = 'c:\\users\\bha\\appdata\\local\\temp\\Box_Mesh.inp'
fea.reset_all()  # restes only FreeCAD objects, not result file from CalculiX, better to make sure there is no result file enymore !!!
fea.run()

code change in ccx tools.
https://github.com/FreeCAD/FreeCAD/blob ... #L172-L174
to

Code: Select all

        message = ''  # self.check_prerequisites()
        if not message:
            # self.write_inp_file()
EkaitzEsteban
Posts: 108
Joined: Wed Sep 12, 2018 1:31 pm

Re: [Help] Run calculix from python API using a previously written .inp file

Post by EkaitzEsteban »

bernd wrote: Tue Sep 25, 2018 8:06 am - open FEM example from StartWB
- run analysis in Python

Code: Select all

# run the analysis
import FemGui
FemGui.setActiveAnalysis(App.ActiveDocument.Analysis)
from femtools import ccxtools
fea = ccxtools.FemToolsCcx()
fea.update_objects()
message = fea.check_prerequisites()
if not message:
    fea.reset_all()
    fea.run()
    fea.load_results()
else:
    FreeCAD.Console.PrintError("Houston, we have a problem! {}\n".format(message))  # in report view
    print("Houston, we have a problem! {}\n".format(message))  # in python console
#


to get the input file name we do a:

Code: Select all

fea.inp_file_name

Code: Select all

>>> fea.inp_file_name
'c:\\users\\bha\\appdata\\local\\temp\\Box_Mesh.inp'
>>> 
give it a try in a file explorer ... for me the file is there.


- ok have got an input file now, let's try to run CalculiX with this input file from FreeCAD.
- I got it working but is is a hack !!!
- close FreeCAD
- change the module ccxtools.py (see after the code block)
- start FreeCAD
- make a new document and add a Analysis (a CcxToolsSolver will be added too)
- run the code (you need to adapt your inputfile)

Code: Select all

import FemGui
FemGui.setActiveAnalysis(App.ActiveDocument.Analysis)
from femtools import ccxtools
fea = ccxtools.FemToolsCcx()
fea.update_objects()
fea.inp_file_name = 'c:\\users\\bha\\appdata\\local\\temp\\Box_Mesh.inp'
fea.reset_all()  # restes only FreeCAD objects, not result file from CalculiX, better to make sure there is no result file enymore !!!
fea.run()

code change in ccx tools.
https://github.com/FreeCAD/FreeCAD/blob ... #L172-L174
to

Code: Select all

        message = ''  # self.check_prerequisites()
        if not message:
            # self.write_inp_file()
Awesome! Another way to do that. It is fantastic

Best regards,
Ekaitz.
EkaitzEsteban
Posts: 108
Joined: Wed Sep 12, 2018 1:31 pm

Re: [SOLVED] Run calculix from python API using a previously written .inp file

Post by EkaitzEsteban »

Hello,

I mix both solutions for adding a new functionality to ccxtools.py without hack in.

I add the following function to ccxtools.py for custom runs using your own .inp files.

Code: Select all

def myrun(self):
        ret_code = 0
        message = self.check_prerequisites()
        if not message:
            from FreeCAD import Base
            progress_bar = Base.ProgressIndicator()
            progress_bar.start("Running CalculiX ccx...", 0)
            ret_code = self.start_ccx()
            self.finished.emit(ret_code)
            progress_bar.stop()
            if ret_code or self.ccx_stderr:
                FreeCAD.Console.PrintError("CalculiX failed with exit code {}\n".format(ret_code))
                FreeCAD.Console.PrintMessage("--------start of stderr-------\n")
                FreeCAD.Console.PrintMessage(self.ccx_stderr)
                FreeCAD.Console.PrintMessage("--------end of stderr---------\n")
                FreeCAD.Console.PrintMessage("--------start of stdout-------\n")
                FreeCAD.Console.PrintMessage(self.ccx_stdout)
                self.has_for_nonpositive_jacobians()
                FreeCAD.Console.PrintMessage("--------end of stdout---------\n")
            else:
                FreeCAD.Console.PrintMessage("CalculiX finished without error\n")
        else:
            FreeCAD.Console.PrintError("CalculiX was not started due to missing prerequisites:\n{}\n".format(message))


Now ccxtools.py has two ways for performing a FEM calculus.

1) Usual way. FreeCAD writes the .inp file and it will run the analysis. Type the following commands in python API:

Code: Select all

# --------------------------------------------------------------
### Run analysis - FreeCAD writes the .inp file and then call calculix 
# --------------------------------------------------------------
FemGui.setActiveAnalysis(FreeCAD.getDocument("SimpleBox").Analysis)
fea = ccxtools.FemToolsCcx()
fea.update_objects()
message = fea.check_prerequisites()
if not message:
    fea.reset_all()
    fea.run()
    fea.load_results()
else:
    FreeCAD.Console.PrintError("Houston, we have a problem! {}\n".format(message))  # in report view
2) Custom way. Include in fea.inp_file_name the path of your inp file and then call fea.myrun() new function. Type the following commands in python API:

Code: Select all

# --------------------------------------------------------------
### Run custom analysis - FreeCAD call calculix using your custom .inp file
# --------------------------------------------------------------
FemGui.setActiveAnalysis(FreeCAD.getDocument("SimpleBox").Analysis)
fea = ccxtools.FemToolsCcx()
fea.update_objects()
message = fea.check_prerequisites()
fea.inp_file_name ='C:\\filepath\\custom.inp'  # this .inp file must be correctly written (I think that ccxtools.py is unable to check that.)
if not message:
    fea.reset_all()
    fea.myrun() # calls def myrun(self): function defined in ccxtools.py 
    fea.load_results()
else:
    FreeCAD.Console.PrintError("Houston, we have a problem! {}\n".format(message))  # in report view
Both options are available without hacking the program :P ;)

Thank you bernd for your help. This works perfectly without changing the current functionality of FreeCAD :mrgreen: .

Tested in:

OS: Windows 10
Word size of OS: 64-bit
Word size of FreeCAD: 64-bit
Version: 0.17.13528 (Git)
Build type: Release
Branch: releases/FreeCAD-0-17
Hash: 5c3f7bf8ec51e2c7187789f7edba71a7aa82a88b
Python version: 2.7.14
Qt version: 4.8.7
Coin version: 4.0.0a
OCC version: 7.2.0
Locale: Spanish/Spain (es_ES)
User avatar
bernd
Veteran
Posts: 12849
Joined: Sun Sep 08, 2013 8:07 pm
Location: Zürich, Switzerland
Contact:

Re: [SOLVED] Run calculix from python API using a previously written .inp file

Post by bernd »

Ahh, yes your one is better than my hack. Still it is no smart enough to integrate in FreeCAD master!

We should change the run def to be able to run without a precheck and without the inputfile write. In such a case we should even be able to run without a solver object. May be the new solver frame work does the trick much more simpler. I may have a look at all this.

bernd
User avatar
bernd
Veteran
Posts: 12849
Joined: Sun Sep 08, 2013 8:07 pm
Location: Zürich, Switzerland
Contact:

Re: [SOLVED] Run calculix from python API using a previously written .inp file

Post by bernd »

User avatar
bernd
Veteran
Posts: 12849
Joined: Sun Sep 08, 2013 8:07 pm
Location: Zürich, Switzerland
Contact:

Re: [SOLVED] Run calculix from python API using a previously written .inp file

Post by bernd »

should be possible without test mode just by setting the input file name since git commit 3f8c524
hex41434
Posts: 12
Joined: Mon Mar 01, 2021 11:03 am

Re: [SOLVED] Run calculix from python API using a previously written .inp file

Post by hex41434 »

Hi, I would like to run a written .inp file in python (not inside FreeCAD)

I have a cuboid (fixed constraint : the bottom surface) and I punch it on top, from different points, multiple times=> so it deforms!
after each punch, I create mesh from resultmesh--> shape from mesh-->convert to solid. then press the shape again and do this inside a loop for multiple times. after each step, the mesh grows and become very slow after 6-7 times.

to make the process fast, I need to keep the mesh fixed. I used this link to update femmesh using 'Displacment' :
https://forum.freecadweb.org/viewtopic. ... 18&t=27481

Code: Select all

# REPLACE OLD FEMMESH (USE DISPLACEMENT VECTORS)
def uptade_femmesh(doc):
    
    old_femmesh_obj = doc.CubeFemMesh.FemMesh
    doc.removeObject('CubeFemMesh')
    
    #add updated femmesh - with the same name (->>> update old femmesh)
    mesh_obj = doc.addObject('Fem::FemMeshObject', 'CubeFemMesh')

    new_femmesh = Fem.FemMesh()
    res_coord = doc.CCX_Results.DisplacementVectors
    res_nd_no = doc.CCX_Results.NodeNumbers
    res_mesh = doc.ResultMesh.FemMesh
    for n in res_nd_no: #add Nodes
        new_femmesh.addNode((res_mesh.Nodes[n].x + res_coord[n-1].x), (res_mesh.Nodes[n].y + res_coord[n-1].y), (res_mesh.Nodes[n].z + res_coord[n-1].z), n)

    for f in old_femmesh_obj.Faces:#add faces
        new_femmesh.addFace(list(old_femmesh_obj.getElementNodes(f)))

    for e in old_femmesh_obj.Edges:#add edges
        new_femmesh.addEdge(list(old_femmesh_obj.getElementNodes(e)))
    
    for v in res_mesh.Volumes:#add Volumes
        new_femmesh.addVolume(list(res_mesh.getElementNodes(v)))

    mesh_obj.FemMesh = new_femmesh
    doc.Analysis.addObject(mesh_obj) 
    #-----------------------------------------------------------------remove old result
    doc.removeObject("ResultMesh")
    doc.removeObject("CCX_Results")
    doc.recompute()
    
    return doc,new_femmesh
so I replace the old femmesh with the new one in the Analysis, then use: fea1.write_inp_file() to update nodes and volumes in inp file

then manually update the inp file for force constraint (CLOAD). and run this code to take one step:

Code: Select all

#Step 0 (initialize)

doc = App.newDocument("doc")

box_obj = doc.addObject('Part::Box', 'Box')
box_obj.Height = 2
box_obj.Width = 5
box_obj.Length = 50

analysis_object = ObjectsFem.makeAnalysis(FreeCAD.ActiveDocument, 'Analysis')

femmesh_obj = doc.addObject('Fem::FemMeshShapeNetgenObject', 'CubeFemMesh')
femmesh_obj.Shape = box_obj 
femmesh_obj.Fineness = "VeryCoarse"
femmesh_obj.MaxSize = 100

doc.Analysis.addObject(femmesh_obj)
doc.recompute()

doc.addObject("Fem::ConstraintFixed","FemConstraintFixed")
doc.FemConstraintFixed.Scale = 1
doc.Analysis.addObject(doc.FemConstraintFixed)

doc.FemConstraintFixed.Scale = 1
doc.FemConstraintFixed.References = [(doc.Box,"Face5")]#bottom surface
doc.recompute()

doc.addObject("Fem::ConstraintForce","FemConstraintForce")
doc.FemConstraintForce.Force = 1 #min force for min displacement
doc.FemConstraintForce.Reversed = False
doc.FemConstraintForce.Scale = 1
doc.FemConstraintForce.References = [(doc.Box,"Face6")]
doc.Analysis.addObject(doc.FemConstraintForce)
doc.recompute()

analysis_object.addObject(ObjectsFem.makeSolverCalculixCcxTools(doc))

## material
material_object = ObjectsFem.makeMaterialSolid(doc, "SolidMaterial")
mat = material_object.Material
mat['Name'] = "Steel-Generic"
mat['YoungsModulus'] = "210000 MPa"
mat['PoissonRatio'] = "0.30"
mat['Density'] = "7900 kg/m^3"
material_object.Material = mat
analysis_object.addObject(material_object)

# run the analysis step by step
fea1 = ccxtools.FemToolsCcx()
fea1.update_objects()
fea1.setup_working_dir('../scripts/inp_test')

fea1.setup_ccx()
message = fea1.check_prerequisites()
if not message:
    fea1.purge_results()
    fea1.write_inp_file()
    cc= fea1.ccx_run()
    print(f'cc:{cc}')
    fea1.load_results()
else:
    FreeCAD.Console.PrintError("Oh, we have a problem! {}\n".format(message))  # in report view
    print("Oh, we have a problem! {}\n".format(message))  # in python console


femmesh_obj = doc.getObject("ResultMesh").FemMesh
result = doc.getObject("CCX_Results")

out = femmesh.femmesh2mesh.femmesh_2_mesh(femmesh_obj, result)
out_mesh = Mesh.Mesh(out) #state0

use the deformed mesh and continue...

Code: Select all

# Step 1
fea1.update_objects()
fea1.purge_results()

message = fea1.check_prerequisites()#
print(f'message: {message}')

if not message:
     #update nodes and volumes in inp file
    fea1.write_inp_file() 
    
    #--- prepare_inp_cload_block()
    #--- update_inp_file()
    
    cc = fea1.ccx_run()
    print(f'cc:{cc}')
    fea1.load_results()
else:
    print("Oh, we have a problem! {}\n".format(message)) 

femmesh_obj = doc.getObject("ResultMesh").FemMesh
result = doc.getObject("CCX_Results")

out = femmesh.femmesh2mesh.femmesh_2_mesh(femmesh_obj, result)
out_mesh = Mesh.Mesh(out) #state1


It runs successfully, but I can do this process only once, and for the 2nd time I got the error:
--------------------------------------------------------------
190 'Problem on frd file import. No nodes found in frd file.\n'
...
--> 192 return res_obj
193
194
UnboundLocalError: local variable 'res_obj' referenced before assignment
--------------------------------------------------------------

(I supposed that I can edit inp file between the fea1.write_inp_file() and fea1.ccx_run() lines, so that fea1.ccx_run() only runs the ccx)

I attach the ipynb file too. (I installed freecad conda on linux)

many thanks in advance,
Aida
Attachments
inp_hack_final.ipynb.zip
(4.82 KiB) Downloaded 43 times
hex41434
Posts: 12
Joined: Mon Mar 01, 2021 11:03 am

Re: [SOLVED] Run calculix from python API using a previously written .inp file

Post by hex41434 »

bernd wrote: Fri Mar 01, 2019 3:29 pm should be possible without test mode just by setting the input file name since git commit 3f8c524
sorry if it was confusing... actually my main question:
is there anyway to ONLY read inp file, solve with calculix and return the result_mesh all in python script? ( I tried it in freecad app, I can click on ccx_solver, press write_inp, press edit button and change the inp file, and press run calculix. ) but I need to do the same outside freecad.

Best
Aida
fandaL
Posts: 440
Joined: Thu Jul 24, 2014 8:29 am

Re: [SOLVED] Run calculix from python API using a previously written .inp file

Post by fandaL »

hex41434 wrote: Thu Jan 26, 2023 4:51 pm is there anyway to ONLY read inp file, solve with calculix and return the result_mesh all in python script?

Code: Select all

from femtools import ccxtools
import sys
import subprocess
import feminout.importCcxFrdResults

inp_file = "/home/fanda/Downloads/tmp/fc_fem/SolverCcxTools/SolverCcxTools/FEMMeshGmsh"

# run CalculiX
fea = ccxtools.FemToolsCcx()
fea.setup_ccx()
path_calculix = fea.ccx_binary
subprocess.run([path_calculix, os.path.normpath(inp_file)])

# import output file
frd_file = inp_file + ".frd"
doc_name = FreeCAD.ActiveDocument.Name
feminout.importCcxFrdResults.insert(frd_file, doc_name)
The script requires that you have a FC file with the Analysis container.
Post Reply