diff --git a/data/examples/FemCalculixCantilever2D.FCStd b/data/examples/FemCalculixCantilever2D.FCStd
index 00c69faea..7029b54be 100644
Binary files a/data/examples/FemCalculixCantilever2D.FCStd and b/data/examples/FemCalculixCantilever2D.FCStd differ
diff --git a/data/examples/FemCalculixCantilever3D.FCStd b/data/examples/FemCalculixCantilever3D.FCStd
index 5b50ab2d9..f00197039 100644
Binary files a/data/examples/FemCalculixCantilever3D.FCStd and b/data/examples/FemCalculixCantilever3D.FCStd differ
diff --git a/src/Mod/Fem/FemInputWriterCcx.py b/src/Mod/Fem/FemInputWriterCcx.py
index 75e87aea1..6516e3756 100644
--- a/src/Mod/Fem/FemInputWriterCcx.py
+++ b/src/Mod/Fem/FemInputWriterCcx.py
@@ -57,11 +57,20 @@ class FemInputWriterCcx(FemInputWriter.FemInputWriter):
temperature_obj, heatflux_obj, initialtemperature_obj,
beamsection_obj, shellthickness_obj,
analysis_type, dir_name)
- self.file_name = self.dir_name + '/' + self.mesh_object.Name + '.inp'
+ self.main_file_name = self.mesh_object.Name + '.inp'
+ self.file_name = self.dir_name + '/' + self.main_file_name
print('FemInputWriterCcx --> self.dir_name --> ' + self.dir_name)
+ print('FemInputWriterCcx --> self.main_file_name --> ' + self.main_file_name)
print('FemInputWriterCcx --> self.file_name --> ' + self.file_name)
def write_calculix_input_file(self):
+ if self.solver_obj.SplitInputWriter == True:
+ self.write_calculix_splitted_input_file()
+ else:
+ self.write_calculix_one_input_file()
+ return self.file_name
+
+ def write_calculix_one_input_file(self):
timestart = time.clock()
self.femmesh.writeABAQUS(self.file_name)
@@ -144,7 +153,171 @@ class FemInputWriterCcx(FemInputWriter.FemInputWriter):
self.write_footer(inpfile)
inpfile.close()
print("Writing time input file: " + str(time.clock() - timestart) + ' \n')
- return self.file_name
+
+ def write_calculix_splitted_input_file(self):
+ timestart = time.clock()
+
+ # reopen file with "append" and add the analysis definition
+ # first open file with "write" to ensure that each new iteration of writing of inputfile starts in new file
+ # first open file with "write" to ensure that the .writeABAQUS also writes in inputfile
+ inpfileMain = open(self.file_name, 'w')
+ inpfileMain.close
+ inpfileMain = open(self.file_name, 'a')
+ inpfileMain.write('\n\n')
+
+ # write nodes and elements
+ name = self.file_name[:-4]
+ include_name = self.main_file_name[:-4]
+
+ inpfileNodesElem = open(name + "_Node_Elem_sets.inp", 'w')
+ self.femmesh.writeABAQUS(name + "_Node_Elem_sets.inp")
+ inpfileNodesElem.close
+ inpfileMain.write('\n***********************************************************\n')
+ inpfileMain.write('**Nodes and Elements\n')
+ inpfileMain.write('** written by femmesh.writeABAQUS\n')
+ inpfileMain.write('*INCLUDE,INPUT=' + include_name + "_Node_Elem_sets.inp \n")
+
+ # create seperate inputfiles for each node set or constraint
+ if self.fixed_objects or self.displacement_objects or self.planerotation_objects:
+ inpfileNodes = open(name + "_Node_sets.inp", 'w')
+ if self.analysis_type == "thermomech" and self.temperature_objects:
+ inpfileNodeTemp = open(name + "_Node_Temp.inp", 'w')
+ if self.force_objects:
+ inpfileForce = open(name + "_Node_Force.inp", 'w')
+ if self.pressure_objects:
+ inpfilePressure = open(name + "_Pressure.inp", 'w')
+ if self.analysis_type == "thermomech" and self.heatflux_objects:
+ inpfileHeatflux = open(name + "_Node_Heatlfux.inp", 'w')
+ if self.contact_objects:
+ inpfileContact = open(name + "_Surface_Contact.inp", 'w')
+ if self.transform_objects:
+ inpfileTransform = open(name + "_Node_Transform.inp", 'w')
+
+ # node and element sets
+ self.write_element_sets_material_and_femelement_type(inpfileMain)
+ if self.fixed_objects:
+ self.write_node_sets_constraints_fixed(inpfileNodes)
+ if self.displacement_objects:
+ self.write_node_sets_constraints_displacement(inpfileNodes)
+ if self.planerotation_objects:
+ self.write_node_sets_constraints_planerotation(inpfileNodes)
+ if self.contact_objects:
+ self.write_surfaces_contraints_contact(inpfileContact)
+ if self.transform_objects:
+ self.write_node_sets_constraints_transform(inpfileTransform)
+
+ # write commentary and include statement for static case node sets
+ inpfileMain.write('\n***********************************************************\n')
+ inpfileMain.write('**Node sets for constraints\n')
+ inpfileMain.write('** written by write_node_sets_constraints_fixed\n')
+ inpfileMain.write('** written by write_node_sets_constraints_displacement\n')
+ inpfileMain.write('** written by write_node_sets_constraints_planerotation\n')
+ if self.fixed_objects:
+ inpfileMain.write('*INCLUDE,INPUT=' + include_name + "_Node_sets.inp \n")
+
+ inpfileMain.write('\n***********************************************************\n')
+ inpfileMain.write('** Surfaces for contact constraint\n')
+ inpfileMain.write('** written by write_surfaces_contraints_contact\n')
+ if self.contact_objects:
+ inpfileMain.write('*INCLUDE,INPUT=' + include_name + "_Surface_Contact.inp \n")
+
+ inpfileMain.write('\n***********************************************************\n')
+ inpfileMain.write('** Node sets for transform constraint\n')
+ inpfileMain.write('** written by write_node_sets_constraints_transform\n')
+ if self.transform_objects:
+ inpfileMain.write('*INCLUDE,INPUT=' + include_name + "_Node_Transform.inp \n")
+
+ if self.analysis_type == "thermomech" and self.temperature_objects:
+ self.write_node_sets_constraints_temperature(inpfileNodeTemp)
+
+ # include seperately written temperature constraint in input file
+ if self.analysis_type == "thermomech":
+ inpfileMain.write('\n***********************************************************\n')
+ inpfileMain.write('**Node sets for temperature constraint\n')
+ inpfileMain.write('** written by write_node_sets_constraints_temperature\n')
+ if self.temperature_objects:
+ inpfileMain.write('*INCLUDE,INPUT=' + include_name + "_Node_Temp.inp \n")
+
+ # materials and fem element types
+ self.write_materials(inpfileMain)
+ if self.analysis_type == "thermomech" and self.initialtemperature_objects:
+ self.write_constraints_initialtemperature(inpfileMain)
+ self.write_femelementsets(inpfileMain)
+
+ # constraints independent from steps
+ if self.planerotation_objects:
+ self.write_constraints_planerotation(inpfileMain)
+ if self.contact_objects:
+ self.write_constraints_contact(inpfileMain)
+ if self.transform_objects:
+ self.write_constraints_transform(inpfileMain)
+
+ # step begin
+ if self.analysis_type == "frequency":
+ self.write_step_begin_static_frequency(inpfileMain)
+ self.write_analysis_frequency(inpfileMain)
+ elif self.analysis_type == "static":
+ self.write_step_begin_static_frequency(inpfileMain)
+ elif self.analysis_type == "thermomech":
+ self.write_step_begin_thermomech(inpfileMain)
+ self.write_analysis_thermomech(inpfileMain)
+
+ # constraints depend on step used in all analysis types
+ if self.fixed_objects:
+ self.write_constraints_fixed(inpfileMain)
+ if self.displacement_objects:
+ self.write_constraints_displacement(inpfileMain)
+
+ # constraints depend on step and depending on analysis type
+ if self.analysis_type == "frequency":
+ pass
+ elif self.analysis_type == "static":
+ if self.selfweight_objects:
+ self.write_constraints_selfweight(inpfileMain)
+ if self.force_objects:
+ self.write_constraints_force(inpfileForce)
+ if self.pressure_objects:
+ self.write_constraints_pressure(inpfilePressure)
+ elif self.analysis_type == "thermomech":
+ if self.selfweight_objects:
+ self.write_constraints_selfweight(inpfileMain)
+ if self.force_objects:
+ self.write_constraints_force(inpfileForce)
+ if self.pressure_objects:
+ self.write_constraints_pressure(inpfilePressure)
+ if self.temperature_objects:
+ self.write_constraints_temperature(inpfileMain)
+ if self.heatflux_objects:
+ self.write_constraints_heatflux(inpfileHeatflux)
+
+ # include seperately written constraints in input file
+ inpfileMain.write('\n***********************************************************\n')
+ inpfileMain.write('** Node loads\n')
+ inpfileMain.write('** written by write_constraints_force\n')
+ if self.force_objects:
+ inpfileMain.write('*INCLUDE,INPUT=' + include_name + "_Node_Force.inp \n")
+
+ inpfileMain.write('\n***********************************************************\n')
+ inpfileMain.write('** Element + CalculiX face + load in [MPa]\n')
+ inpfileMain.write('** written by write_constraints_pressure\n')
+ if self.pressure_objects:
+ inpfileMain.write('*INCLUDE,INPUT=' + include_name + "_Pressure.inp \n")
+
+ if self.analysis_type == "thermomech":
+ inpfileMain.write('\n***********************************************************\n')
+ inpfileMain.write('** Convective heat transfer (heat flux)\n')
+ inpfileMain.write('** written by write_constraints_heatflux\n')
+ if self.heatflux_objects:
+ inpfileMain.write('*INCLUDE,INPUT=' + include_name + "_Node_Heatlfux.inp \n")
+
+ # output and step end
+ self.write_outputs_types(inpfileMain)
+ self.write_step_end(inpfileMain)
+
+ # footer
+ self.write_footer(inpfileMain)
+ inpfileMain.close()
+ print("Writing time input file: " + str(time.clock() - timestart) + ' \n')
def write_element_sets_material_and_femelement_type(self, f):
f.write('\n***********************************************************\n')
diff --git a/src/Mod/Fem/Gui/DlgSettingsFemCcx.ui b/src/Mod/Fem/Gui/DlgSettingsFemCcx.ui
index 708550139..25bc8b147 100644
--- a/src/Mod/Fem/Gui/DlgSettingsFemCcx.ui
+++ b/src/Mod/Fem/Gui/DlgSettingsFemCcx.ui
@@ -6,16 +6,16 @@
0
0
- 555
- 652
+ 536
+ 752
CalculiX
-
- -
-
+
+
-
+
-
@@ -33,26 +33,33 @@
Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop
-
-
- QLayout::SetNoConstraint
-
-
-
-
-
-
-
-
- false
+
+
-
+
+
-
+
+
+ CalculiX binary
+
+
+
+ -
+
+
+ Use standard ccx binary path
+
+
+ true
- ExternalEditorPath
+ UseStandardCcxLocation
Mod/Fem/Ccx
- -
+
-
false
@@ -68,7 +75,7 @@
- -
+
-
false
@@ -108,7 +115,14 @@
- -
+
-
+
+
+ Editor
+
+
+
+ -
Use internal editor for .inp files
@@ -125,13 +139,6 @@
-
-
-
- Editor
-
-
-
- -
false
@@ -147,26 +154,42 @@
- -
-
-
- Use standard ccx binary path
-
-
- true
+
-
+
+
+ false
- UseStandardCcxLocation
+ ExternalEditorPath
Mod/Fem/Ccx
- -
-
+
-
+
- CalculiX binary
+ Split .inp
+
+
+
+ -
+
+
+ true
+
+
+ Split writing of .inp
+
+
+ false
+
+
+ SplitInputWriter
+
+
+ Mod/Fem/Ccx
@@ -340,13 +363,6 @@
- -
-
-
- Non-linear geometry
-
-
-
-
@@ -354,6 +370,13 @@
+ -
+
+
+ Non-linear geometry
+
+
+
-
@@ -509,8 +532,8 @@
Frequency defaults
-
-
-
+
+
-
-
@@ -617,19 +640,6 @@
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 40
-
-
-
-
diff --git a/src/Mod/Fem/Gui/DlgSettingsFemCcxImp.cpp b/src/Mod/Fem/Gui/DlgSettingsFemCcxImp.cpp
index 0bf52e32e..04f245df8 100644
--- a/src/Mod/Fem/Gui/DlgSettingsFemCcxImp.cpp
+++ b/src/Mod/Fem/Gui/DlgSettingsFemCcxImp.cpp
@@ -69,6 +69,7 @@ void DlgSettingsFemCcxImp::saveSettings()
fc_ext_editor->onSave();
cb_ccx_binary_std->onSave();
fc_ccx_binary_path->onSave();
+ cb_split_inp_writer->onSave();
}
void DlgSettingsFemCcxImp::loadSettings()
@@ -92,6 +93,7 @@ void DlgSettingsFemCcxImp::loadSettings()
fc_ext_editor->onRestore();
cb_ccx_binary_std->onRestore();
fc_ccx_binary_path->onRestore();
+ cb_split_inp_writer->onRestore();
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath
("User parameter:BaseApp/Preferences/Mod/Fem/Ccx");
diff --git a/src/Mod/Fem/_FemSolverCalculix.py b/src/Mod/Fem/_FemSolverCalculix.py
index 954cd690a..327da9cd1 100644
--- a/src/Mod/Fem/_FemSolverCalculix.py
+++ b/src/Mod/Fem/_FemSolverCalculix.py
@@ -43,8 +43,8 @@ class _FemSolverCalculix():
fem_prefs = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Fem/General")
ccx_prefs = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Fem/Ccx")
- obj.addProperty("App::PropertyPath", "WorkingDir", "Fem", "Working directory for calculations")
- obj.WorkingDir = fem_prefs.GetString("WorkingDir", "")
+ obj.addProperty("App::PropertyPath", "WorkingDir", "Fem", "Working directory for calculations, will only be used it is left blank in preferences")
+ # the working directory is not set, the solver working directory is only used if the preferences working directory is left blank
obj.addProperty("App::PropertyEnumeration", "AnalysisType", "Fem", "Type of the analysis")
obj.AnalysisType = FemToolsCcx.FemToolsCcx.known_analysis_types
@@ -97,6 +97,10 @@ class _FemSolverCalculix():
use_non_ccx_iterations_param = ccx_prefs.GetInt("UseNonCcxIterationParam", False)
obj.IterationsControlParameterTimeUse = use_non_ccx_iterations_param
+ obj.addProperty("App::PropertyBool", "SplitInputWriter", "Fem", "Split writing of ccx input file")
+ split = ccx_prefs.GetBool("SplitInputWriter", False)
+ obj.SplitInputWriter = split
+
ccx_default_time_incrementation_control_parameter = {
# iteration parameter
'I_0': 4,