From 9107e92b525f3a5a2859e91d5160552b51a554a6 Mon Sep 17 00:00:00 2001 From: Bernd Hahnebach Date: Mon, 1 Aug 2016 21:56:47 +0100 Subject: [PATCH] FEM: constraint contact: add implementation for solver CalculiX --- src/Mod/Fem/FemInputWriter.py | 2 ++ src/Mod/Fem/FemInputWriterCcx.py | 52 ++++++++++++++++++++++++++++++++ src/Mod/Fem/FemInputWriterZ88.py | 2 ++ src/Mod/Fem/FemTools.py | 9 ++++++ src/Mod/Fem/FemToolsCcx.py | 1 + src/Mod/Fem/FemToolsZ88.py | 1 + 6 files changed, 67 insertions(+) diff --git a/src/Mod/Fem/FemInputWriter.py b/src/Mod/Fem/FemInputWriter.py index dc60e1f1e8a9..39e6eb373ee2 100644 --- a/src/Mod/Fem/FemInputWriter.py +++ b/src/Mod/Fem/FemInputWriter.py @@ -45,6 +45,7 @@ def __init__(self, analysis_obj, solver_obj, mesh_obj, mat_obj, fixed_obj, displacement_obj, + contact_obj, selfweight_obj, force_obj, pressure_obj, beamsection_obj, shellthickness_obj, analysis_type, eigenmode_parameters, @@ -56,6 +57,7 @@ def __init__(self, self.material_objects = mat_obj self.fixed_objects = fixed_obj self.displacement_objects = displacement_obj + self.contact_objects = contact_obj self.selfweight_objects = selfweight_obj self.force_objects = force_obj self.pressure_objects = pressure_obj diff --git a/src/Mod/Fem/FemInputWriterCcx.py b/src/Mod/Fem/FemInputWriterCcx.py index 4b3a5fafb9b7..360c11a7834e 100644 --- a/src/Mod/Fem/FemInputWriterCcx.py +++ b/src/Mod/Fem/FemInputWriterCcx.py @@ -40,6 +40,7 @@ def __init__(self, analysis_obj, solver_obj, mesh_obj, mat_obj, fixed_obj, displacement_obj, + contact_obj, selfweight_obj, force_obj, pressure_obj, beamsection_obj, shellthickness_obj, analysis_type=None, eigenmode_parameters=None, @@ -49,6 +50,7 @@ def __init__(self, analysis_obj, solver_obj, mesh_obj, mat_obj, fixed_obj, displacement_obj, + contact_obj, selfweight_obj, force_obj, pressure_obj, beamsection_obj, shellthickness_obj, analysis_type, eigenmode_parameters, @@ -69,8 +71,12 @@ def write_calculix_input_file(self): self.write_node_sets_constraints_fixed(inpfile) if self.displacement_objects: self.write_node_sets_constraints_displacement(inpfile) + if self.contact_objects: + self.write_surfaces_contraints_contact(inpfile) self.write_materials(inpfile) self.write_femelementsets(inpfile) + if self.contact_objects: + self.write_constraints_contact(inpfile) self.write_step_begin(inpfile) if self.fixed_objects: self.write_constraints_fixed(inpfile) @@ -152,6 +158,30 @@ def write_node_sets_constraints_displacement(self, f): for n in femobj['Nodes']: f.write(str(n) + ',\n') + def write_surfaces_contraints_contact(self, f): + # get surface nodes and write them to file + f.write('\n***********************************************************\n') + f.write('** Surfaces for contact constraint\n') + f.write('** written by {} function\n'.format(sys._getframe().f_code.co_name)) + obj = 0 + for femobj in self.contact_objects: # femobj --> dict, FreeCAD document object is femobj['Object'] + contact_obj = femobj['Object'] + cnt = 0 + obj = obj + 1 + for o, elem_tup in contact_obj.References: + for elem in elem_tup: + ref_shape = o.Shape.getElement(elem) + cnt = cnt + 1 + if ref_shape.ShapeType == 'Face': + if cnt == 1: + name = "DEP" + str(obj) + else: + name = "IND" + str(obj) + f.write('*SURFACE, NAME =' + name + '\n') + v = self.mesh_object.FemMesh.getccxVolumesByFace(ref_shape) + for i in v: + f.write("{},S{}\n".format(i[0], i[1])) + def write_materials(self, f): f.write('\n***********************************************************\n') f.write('** Materials\n') @@ -286,6 +316,28 @@ def write_constraints_displacement(self, f): f.write(disp_obj_name + ',6,6,' + str(disp_obj.zRotation) + '\n') f.write('\n') + def write_constraints_contact(self, f): + f.write('\n***********************************************************\n') + f.write('** Contact Constraints\n') + f.write('** written by {} function\n'.format(sys._getframe().f_code.co_name)) + obj = 0 + for femobj in self.contact_objects: # femobj --> dict, FreeCAD document object is femobj['Object'] + obj = obj + 1 + contact_obj = femobj['Object'] + f.write('*CONTACT PAIR, INTERACTION=INT' + str(obj) + ',TYPE=SURFACE TO SURFACE\n') + ind_surf = "IND" + str(obj) + dep_surf = "DEP" + str(obj) + f.write(dep_surf + ',' + ind_surf + '\n') + f.write('*SURFACE INTERACTION, NAME=INT' + str(obj) + '\n') + f.write('*SURFACE BEHAVIOR,PRESSURE-OVERCLOSURE=LINEAR\n') + slope = contact_obj.Slope + f.write(str(slope) + ' \n') + friction = contact_obj.Friction + if friction > 0: + f.write('*FRICTION \n') + stick = (slope / 10.0) + f.write(str(friction) + ', ' + str(stick) + ' \n') + def write_constraints_selfweight(self, f): f.write('\n***********************************************************\n') f.write('** Self weight\n') diff --git a/src/Mod/Fem/FemInputWriterZ88.py b/src/Mod/Fem/FemInputWriterZ88.py index 8508d92e6f12..9b30e7c73960 100644 --- a/src/Mod/Fem/FemInputWriterZ88.py +++ b/src/Mod/Fem/FemInputWriterZ88.py @@ -37,6 +37,7 @@ def __init__(self, analysis_obj, solver_obj, mesh_obj, mat_obj, fixed_obj, displacement_obj, + contact_obj, selfweight_obj, force_obj, pressure_obj, beamsection_obj, shellthickness_obj, analysis_type=None, eigenmode_parameters=None, @@ -46,6 +47,7 @@ def __init__(self, analysis_obj, solver_obj, mesh_obj, mat_obj, fixed_obj, displacement_obj, + contact_obj, selfweight_obj, force_obj, pressure_obj, beamsection_obj, shellthickness_obj, analysis_type, eigenmode_parameters, diff --git a/src/Mod/Fem/FemTools.py b/src/Mod/Fem/FemTools.py index 3280620f6eaf..8c01bbbdea57 100644 --- a/src/Mod/Fem/FemTools.py +++ b/src/Mod/Fem/FemTools.py @@ -153,6 +153,7 @@ def update_objects(self): # [{'Object':pressure_constraints, 'xxxxxxxx':value}, {}, ...] # [{'Object':beam_sections, 'xxxxxxxx':value}, {}, ...] # [{'Object':shell_thicknesses, 'xxxxxxxx':value}, {}, ...] + # [{'Object':contact_constraints, 'xxxxxxxx':value}, {}, ...] ## @var mesh # mesh of the analysis. Used to generate .inp file and to show results @@ -189,6 +190,10 @@ def update_objects(self): # set of displacements for the analysis. Updated with update_objects # Individual displacement_constraints are Proxy.Type "FemConstraintDisplacement" self.displacement_constraints = [] + ## @var contact_constraints + # set of contact constraints from the analysis. Updated with update_objects + # Individual constraints are "Fem::ConstraintContact" type + self.contact_constraints = [] found_solver_for_use = False for m in self.analysis.Member: @@ -235,6 +240,10 @@ def update_objects(self): displacement_constraint_dict = {} displacement_constraint_dict['Object'] = m self.displacement_constraints.append(displacement_constraint_dict) + elif m.isDerivedFrom("Fem::ConstraintContact"): + contact_constraint_dict = {} + contact_constraint_dict['Object'] = m + self.contact_constraints.append(contact_constraint_dict) elif hasattr(m, "Proxy") and m.Proxy.Type == "FemBeamSection": beam_section_dict = {} beam_section_dict['Object'] = m diff --git a/src/Mod/Fem/FemToolsCcx.py b/src/Mod/Fem/FemToolsCcx.py index 895c0397a258..f61b49379be9 100644 --- a/src/Mod/Fem/FemToolsCcx.py +++ b/src/Mod/Fem/FemToolsCcx.py @@ -92,6 +92,7 @@ def write_inp_file(self): self.analysis, self.solver, self.mesh, self.materials, self.fixed_constraints, self.displacement_constraints, + self.contact_constraints, self.selfweight_constraints, self.force_constraints, self.pressure_constraints, self.beam_sections, self.shell_thicknesses, self.analysis_type, self.eigenmode_parameters, diff --git a/src/Mod/Fem/FemToolsZ88.py b/src/Mod/Fem/FemToolsZ88.py index 8dd664b79cde..460a18428109 100644 --- a/src/Mod/Fem/FemToolsZ88.py +++ b/src/Mod/Fem/FemToolsZ88.py @@ -84,6 +84,7 @@ def write_inp_file(self): self.analysis, self.solver, self.mesh, self.materials, self.fixed_constraints, self.displacement_constraints, + self.contact_constraints, self.selfweight_constraints, self.force_constraints, self.pressure_constraints, self.beam_sections, self.shell_thicknesses, self.analysis_type, None,