From 890b42a5d4d9327045b9d2f141401eb64e07097c Mon Sep 17 00:00:00 2001 From: vdwalts Date: Wed, 2 Nov 2016 18:08:58 +0100 Subject: [PATCH 1/6] FEM: Add split input writer option to preferences dialog GUI --- src/Mod/Fem/Gui/DlgSettingsFemCcx.ui | 128 ++++++++++++----------- src/Mod/Fem/Gui/DlgSettingsFemCcxImp.cpp | 2 + src/Mod/Fem/_FemSolverCalculix.py | 4 + 3 files changed, 75 insertions(+), 59 deletions(-) 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..872a2d64d 100644 --- a/src/Mod/Fem/Gui/DlgSettingsFemCcxImp.cpp +++ b/src/Mod/Fem/Gui/DlgSettingsFemCcxImp.cpp @@ -69,6 +69,8 @@ void DlgSettingsFemCcxImp::saveSettings() fc_ext_editor->onSave(); cb_ccx_binary_std->onSave(); fc_ccx_binary_path->onSave(); + cb_split_inp_writer->onSave(); + cb_split_inp_writer->onRestore(); } void DlgSettingsFemCcxImp::loadSettings() diff --git a/src/Mod/Fem/_FemSolverCalculix.py b/src/Mod/Fem/_FemSolverCalculix.py index 954cd690a..f725a3c06 100644 --- a/src/Mod/Fem/_FemSolverCalculix.py +++ b/src/Mod/Fem/_FemSolverCalculix.py @@ -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, From 0d8f42637c59e947bdb55e14c6e26bf1f983a113 Mon Sep 17 00:00:00 2001 From: vdwalts Date: Wed, 2 Nov 2016 18:09:06 +0100 Subject: [PATCH 2/6] FEM: Add separate definitions for split AND non-split input writer files to FemInputWriterCcx.py --- src/Mod/Fem/FemInputWriterCcx.py | 175 +++++++++++++++++++++++++++++++ src/Mod/Fem/FemToolsCcx.py | 2 +- 2 files changed, 176 insertions(+), 1 deletion(-) diff --git a/src/Mod/Fem/FemInputWriterCcx.py b/src/Mod/Fem/FemInputWriterCcx.py index 75e87aea1..815766868 100644 --- a/src/Mod/Fem/FemInputWriterCcx.py +++ b/src/Mod/Fem/FemInputWriterCcx.py @@ -61,6 +61,14 @@ class FemInputWriterCcx(FemInputWriter.FemInputWriter): print('FemInputWriterCcx --> self.dir_name --> ' + self.dir_name) print('FemInputWriterCcx --> self.file_name --> ' + self.file_name) + def select_input_writer_mode(self): + if self.solver_obj.SplitInputWriter == True: + self.write_calculix_splitted_input_file() + else: + self.write_calculix_input_file() + + return self.file_name + def write_calculix_input_file(self): timestart = time.clock() self.femmesh.writeABAQUS(self.file_name) @@ -146,6 +154,173 @@ class FemInputWriterCcx(FemInputWriter.FemInputWriter): 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 = "" + for i in range(len(self.file_name)-4): + name = name + self.file_name[i] + + 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=' + 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=' + 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=' + 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=' + 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=' + 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=' + 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=' + 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=' + 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') +# return self.file_name + def write_element_sets_material_and_femelement_type(self, f): f.write('\n***********************************************************\n') f.write('** Element sets for materials and FEM element type (solid, shell, beam)\n') diff --git a/src/Mod/Fem/FemToolsCcx.py b/src/Mod/Fem/FemToolsCcx.py index d110197d8..936f7feed 100644 --- a/src/Mod/Fem/FemToolsCcx.py +++ b/src/Mod/Fem/FemToolsCcx.py @@ -97,7 +97,7 @@ class FemToolsCcx(FemTools.FemTools): self.temperature_constraints, self.heatflux_constraints, self.initialtemperature_constraints, self.beam_sections, self.shell_thicknesses, self.analysis_type, self.working_dir) - self.inp_file_name = inp_writer.write_calculix_input_file() + self.inp_file_name = inp_writer.select_input_writer_mode() except: print("Unexpected error when writing CalculiX input file:", sys.exc_info()[0]) raise From fc91712b85ddd3695aef34bbdf558566606ab9ab Mon Sep 17 00:00:00 2001 From: Bernd Hahnebach Date: Wed, 2 Nov 2016 18:09:10 +0100 Subject: [PATCH 3/6] FEM: ccx input file splitting, small improvements --- src/Mod/Fem/FemInputWriterCcx.py | 34 +++++++++++++++----------------- src/Mod/Fem/FemToolsCcx.py | 2 +- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/src/Mod/Fem/FemInputWriterCcx.py b/src/Mod/Fem/FemInputWriterCcx.py index 815766868..6516e3756 100644 --- a/src/Mod/Fem/FemInputWriterCcx.py +++ b/src/Mod/Fem/FemInputWriterCcx.py @@ -57,19 +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 select_input_writer_mode(self): + def write_calculix_input_file(self): if self.solver_obj.SplitInputWriter == True: self.write_calculix_splitted_input_file() else: - self.write_calculix_input_file() - + self.write_calculix_one_input_file() return self.file_name - def write_calculix_input_file(self): + def write_calculix_one_input_file(self): timestart = time.clock() self.femmesh.writeABAQUS(self.file_name) @@ -152,7 +153,6 @@ 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() @@ -166,9 +166,8 @@ class FemInputWriterCcx(FemInputWriter.FemInputWriter): inpfileMain.write('\n\n') # write nodes and elements - name = "" - for i in range(len(self.file_name)-4): - name = name + self.file_name[i] + 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") @@ -176,7 +175,7 @@ class FemInputWriterCcx(FemInputWriter.FemInputWriter): inpfileMain.write('\n***********************************************************\n') inpfileMain.write('**Nodes and Elements\n') inpfileMain.write('** written by femmesh.writeABAQUS\n') - inpfileMain.write('*INCLUDE,INPUT=' + name + "_Node_Elem_sets.inp \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: @@ -214,19 +213,19 @@ class FemInputWriterCcx(FemInputWriter.FemInputWriter): 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=' + name + "_Node_sets.inp \n") + 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=' + name + "_Surface_Contact.inp \n") + 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=' + name + "_Node_Transform.inp \n") + 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) @@ -237,7 +236,7 @@ class FemInputWriterCcx(FemInputWriter.FemInputWriter): 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=' + name + "_Node_Temp.inp \n") + inpfileMain.write('*INCLUDE,INPUT=' + include_name + "_Node_Temp.inp \n") # materials and fem element types self.write_materials(inpfileMain) @@ -296,20 +295,20 @@ class FemInputWriterCcx(FemInputWriter.FemInputWriter): inpfileMain.write('** Node loads\n') inpfileMain.write('** written by write_constraints_force\n') if self.force_objects: - inpfileMain.write('*INCLUDE,INPUT=' + name + "_Node_Force.inp \n") + 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=' + name + "_Pressure.inp \n") + 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=' + name + "_Node_Heatlfux.inp \n") + inpfileMain.write('*INCLUDE,INPUT=' + include_name + "_Node_Heatlfux.inp \n") # output and step end self.write_outputs_types(inpfileMain) @@ -319,7 +318,6 @@ class FemInputWriterCcx(FemInputWriter.FemInputWriter): self.write_footer(inpfileMain) inpfileMain.close() print("Writing time input file: " + str(time.clock() - timestart) + ' \n') -# return self.file_name def write_element_sets_material_and_femelement_type(self, f): f.write('\n***********************************************************\n') diff --git a/src/Mod/Fem/FemToolsCcx.py b/src/Mod/Fem/FemToolsCcx.py index 936f7feed..d110197d8 100644 --- a/src/Mod/Fem/FemToolsCcx.py +++ b/src/Mod/Fem/FemToolsCcx.py @@ -97,7 +97,7 @@ class FemToolsCcx(FemTools.FemTools): self.temperature_constraints, self.heatflux_constraints, self.initialtemperature_constraints, self.beam_sections, self.shell_thicknesses, self.analysis_type, self.working_dir) - self.inp_file_name = inp_writer.select_input_writer_mode() + self.inp_file_name = inp_writer.write_calculix_input_file() except: print("Unexpected error when writing CalculiX input file:", sys.exc_info()[0]) raise From c333e069ad5ff925f63e23e937c55f04ffb45c26 Mon Sep 17 00:00:00 2001 From: Bernd Hahnebach Date: Wed, 2 Nov 2016 18:09:15 +0100 Subject: [PATCH 4/6] FEM: ccx input file splitting, fix restore of pref --- src/Mod/Fem/Gui/DlgSettingsFemCcxImp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Mod/Fem/Gui/DlgSettingsFemCcxImp.cpp b/src/Mod/Fem/Gui/DlgSettingsFemCcxImp.cpp index 872a2d64d..04f245df8 100644 --- a/src/Mod/Fem/Gui/DlgSettingsFemCcxImp.cpp +++ b/src/Mod/Fem/Gui/DlgSettingsFemCcxImp.cpp @@ -70,7 +70,6 @@ void DlgSettingsFemCcxImp::saveSettings() cb_ccx_binary_std->onSave(); fc_ccx_binary_path->onSave(); cb_split_inp_writer->onSave(); - cb_split_inp_writer->onRestore(); } void DlgSettingsFemCcxImp::loadSettings() @@ -94,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"); From 20dfdbe6a967da448f3cce1f15b1c2c6cfdc7460 Mon Sep 17 00:00:00 2001 From: Bernd Hahnebach Date: Wed, 2 Nov 2016 18:09:18 +0100 Subject: [PATCH 5/6] FEM: solver, do not initialize the solver working directory, since it is eventually only used if it is left blank in preferences --- src/Mod/Fem/_FemSolverCalculix.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Mod/Fem/_FemSolverCalculix.py b/src/Mod/Fem/_FemSolverCalculix.py index f725a3c06..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 From 45bd4e1ca1ce38a90d1e6e45dbe6232184ddbfef Mon Sep 17 00:00:00 2001 From: Bernd Hahnebach Date: Wed, 2 Nov 2016 18:09:22 +0100 Subject: [PATCH 6/6] FEM: example files, udate to new solver attributes --- data/examples/FemCalculixCantilever2D.FCStd | Bin 23504 -> 23622 bytes data/examples/FemCalculixCantilever3D.FCStd | Bin 30365 -> 30436 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/data/examples/FemCalculixCantilever2D.FCStd b/data/examples/FemCalculixCantilever2D.FCStd index 00c69faea0c6641d5683c078586f922512b8c11f..7029b54be6c733b839994c65427fa31c752d128e 100644 GIT binary patch delta 6810 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 LysQG#-}wInM0;tx delta 6609 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 diff --git a/data/examples/FemCalculixCantilever3D.FCStd b/data/examples/FemCalculixCantilever3D.FCStd index 5b50ab2d960d574b08f9bff709b5b381f2f70a0a..f001970390c16ba8470004cbadfa18bba931d433 100644 GIT binary patch delta 7163 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 delta 7136 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