FEM: beam rotaion, implement writer, this fixes a very old restiction, the beam analysis in z-axis
This commit is contained in:
129
src/Mod/Fem/femsolver/calculix/writer.py
Normal file → Executable file
129
src/Mod/Fem/femsolver/calculix/writer.py
Normal file → Executable file
@@ -337,14 +337,18 @@ class FemInputWriterCcx(FemInputWriter.FemInputWriter):
|
||||
f.write('** Element sets for materials and FEM element type (solid, shell, beam, fluid)\n')
|
||||
f.write('** written by {} function\n'.format(sys._getframe().f_code.co_name))
|
||||
|
||||
# in any case if we have beams, we gone need the element ids for the rotation elsets
|
||||
if self.beamsection_objects:
|
||||
# we will need to split the beam even for one beamobj
|
||||
# because no beam in z-direction can be used in ccx without a special adjustment
|
||||
# thus they need an own ccx_elset
|
||||
self.get_element_rotation1D_elements()
|
||||
|
||||
# get the element ids for face and edge elements and write them into the objects
|
||||
if len(self.shellthickness_objects) > 1:
|
||||
self.get_element_geometry2D_elements()
|
||||
elif len(self.beamsection_objects) > 1:
|
||||
self.get_element_geometry1D_elements()
|
||||
# we will need to split the beams even for one beamobj
|
||||
# because no beam in z-direction can be used in ccx without a special adjustment
|
||||
# thus they need an own ccx_elset --> but this is ccx specific and thus should not be in input writer!
|
||||
elif len(self.fluidsection_objects) > 1:
|
||||
self.get_element_fluid1D_elements()
|
||||
|
||||
@@ -631,25 +635,30 @@ class FemInputWriterCcx(FemInputWriter.FemInputWriter):
|
||||
beamsec_obj = ccx_elset['beamsection_obj']
|
||||
elsetdef = 'ELSET=' + ccx_elset['ccx_elset_name'] + ', '
|
||||
material = 'MATERIAL=' + ccx_elset['mat_obj_name']
|
||||
normal = ccx_elset['beam_normal']
|
||||
if beamsec_obj.SectionType == 'Rectangular':
|
||||
height = beamsec_obj.RectHeight.getValueAs('mm')
|
||||
width = beamsec_obj.RectWidth.getValueAs('mm')
|
||||
section_type = ', SECTION=RECT'
|
||||
setion_geo = str(height) + ', ' + str(width) + '\n'
|
||||
setion_def = '*BEAM SECTION, ' + elsetdef + material + section_type + '\n'
|
||||
setion_nor = str(normal[0]) + ', ' + str(normal[1]) + ', ' + str(normal[2]) + '\n'
|
||||
elif beamsec_obj.SectionType == 'Circular':
|
||||
radius = 0.5 * beamsec_obj.CircDiameter.getValueAs('mm')
|
||||
section_type = ', SECTION=CIRC'
|
||||
setion_geo = str(radius) + '\n'
|
||||
setion_def = '*BEAM SECTION, ' + elsetdef + material + section_type + '\n'
|
||||
setion_nor = str(normal[0]) + ', ' + str(normal[1]) + ', ' + str(normal[2]) + '\n'
|
||||
elif beamsec_obj.SectionType == 'Pipe':
|
||||
radius = 0.5 * beamsec_obj.PipeDiameter.getValueAs('mm')
|
||||
thickness = beamsec_obj.PipeThickness.getValueAs('mm')
|
||||
section_type = ', SECTION=PIPE'
|
||||
setion_geo = str(radius) + ', ' + str(thickness) + '\n'
|
||||
setion_def = '*BEAM GENERAL SECTION, ' + elsetdef + material + section_type + '\n'
|
||||
setion_nor = str(normal[0]) + ', ' + str(normal[1]) + ', ' + str(normal[2]) + '\n'
|
||||
f.write(setion_def)
|
||||
f.write(setion_geo)
|
||||
f.write(setion_nor)
|
||||
elif 'fluidsection_obj'in ccx_elset: # fluid mesh
|
||||
fluidsec_obj = ccx_elset['fluidsection_obj']
|
||||
elsetdef = 'ELSET=' + ccx_elset['ccx_elset_name'] + ', '
|
||||
@@ -1071,72 +1080,94 @@ class FemInputWriterCcx(FemInputWriter.FemInputWriter):
|
||||
# 'ccx_elset_name' : 'ccx_identifier_elset'
|
||||
# 'mat_obj_name' : 'mat_obj.Name'
|
||||
# 'ccx_mat_name' : 'mat_obj.Material['Name']' !!! not unique !!!
|
||||
# 'beamsection_obj' : 'beamsection_obj' if exists
|
||||
# 'fluidsection_obj' : 'fluidsection_obj' if exists
|
||||
# 'shellthickness_obj' : shellthickness_obj' if exists
|
||||
# 'beamsection_obj' : 'beamsection_obj' if exists
|
||||
# 'fluidsection_obj' : 'fluidsection_obj' if exists
|
||||
# 'shellthickness_obj' : shellthickness_obj' if exists
|
||||
# 'beam_normal' : normal vector for beams only
|
||||
# },
|
||||
# {}, ... , {} ]
|
||||
|
||||
# beam
|
||||
# TODO support multiple beamrotations
|
||||
# we do not need any more any data from the rotation document object, thus we do not need to save the rotation document object name in the else
|
||||
def get_ccx_elsets_single_mat_single_beam(self):
|
||||
mat_obj = self.material_objects[0]['Object']
|
||||
beamsec_obj = self.beamsection_objects[0]['Object']
|
||||
elset_data = self.ccx_eedges
|
||||
names = [{'short': 'M0'}, {'short': 'B0'}]
|
||||
ccx_elset = {}
|
||||
ccx_elset['ccx_elset'] = elset_data
|
||||
ccx_elset['ccx_elset_name'] = get_ccx_elset_name_short(names)
|
||||
ccx_elset['mat_obj_name'] = mat_obj.Name
|
||||
ccx_elset['ccx_mat_name'] = mat_obj.Material['Name']
|
||||
ccx_elset['beamsection_obj'] = beamsec_obj
|
||||
self.ccx_elsets.append(ccx_elset)
|
||||
beamrot_data = self.beamrotation_objects[0]
|
||||
for i, beamdirection in enumerate(beamrot_data['FEMRotations1D']):
|
||||
elset_data = beamdirection['ids'] # ID's for this direction
|
||||
names = [{'short': 'M0'}, {'short': 'B0'}, {'short': beamrot_data['ShortName']}, {'short': 'D' + str(i)}]
|
||||
ccx_elset = {}
|
||||
ccx_elset['ccx_elset'] = elset_data
|
||||
ccx_elset['ccx_elset_name'] = get_ccx_elset_name_short(names)
|
||||
ccx_elset['mat_obj_name'] = mat_obj.Name
|
||||
ccx_elset['ccx_mat_name'] = mat_obj.Material['Name']
|
||||
ccx_elset['beamsection_obj'] = beamsec_obj
|
||||
ccx_elset['beam_normal'] = beamdirection['normal'] # normal for this direction
|
||||
self.ccx_elsets.append(ccx_elset)
|
||||
|
||||
def get_ccx_elsets_single_mat_multiple_beam(self):
|
||||
mat_obj = self.material_objects[0]['Object']
|
||||
beamrot_data = self.beamrotation_objects[0]
|
||||
for beamsec_data in self.beamsection_objects:
|
||||
beamsec_obj = beamsec_data['Object']
|
||||
elset_data = beamsec_data['FEMElements']
|
||||
names = [{'short': 'M0'}, {'short': beamsec_data['ShortName']}]
|
||||
ccx_elset = {}
|
||||
ccx_elset['ccx_elset'] = elset_data
|
||||
ccx_elset['ccx_elset_name'] = get_ccx_elset_name_short(names)
|
||||
ccx_elset['mat_obj_name'] = mat_obj.Name
|
||||
ccx_elset['ccx_mat_name'] = mat_obj.Material['Name']
|
||||
ccx_elset['beamsection_obj'] = beamsec_obj
|
||||
self.ccx_elsets.append(ccx_elset)
|
||||
|
||||
def get_ccx_elsets_multiple_mat_single_beam(self):
|
||||
beamsec_obj = self.beamsection_objects[0]['Object']
|
||||
for mat_data in self.material_objects:
|
||||
mat_obj = mat_data['Object']
|
||||
elset_data = mat_data['FEMElements']
|
||||
names = [{'short': mat_data['ShortName']}, {'short': 'B0'}]
|
||||
ccx_elset = {}
|
||||
ccx_elset['ccx_elset'] = elset_data
|
||||
ccx_elset['ccx_elset_name'] = get_ccx_elset_name_short(names)
|
||||
ccx_elset['mat_obj_name'] = mat_obj.Name
|
||||
ccx_elset['ccx_mat_name'] = mat_obj.Material['Name']
|
||||
ccx_elset['beamsection_obj'] = beamsec_obj
|
||||
self.ccx_elsets.append(ccx_elset)
|
||||
|
||||
def get_ccx_elsets_multiple_mat_multiple_beam(self):
|
||||
for beamsec_data in self.beamsection_objects:
|
||||
beamsec_obj = beamsec_data['Object']
|
||||
for mat_data in self.material_objects:
|
||||
mat_obj = mat_data['Object']
|
||||
beamsec_ids = set(beamsec_data['FEMElements'])
|
||||
mat_ids = set(mat_data['FEMElements'])
|
||||
elset_data = list(sorted(beamsec_ids.intersection(mat_ids))) # empty intersection sets possible
|
||||
beamsec_ids = set(beamsec_data['FEMElements'])
|
||||
for i, beamdirection in enumerate(beamrot_data['FEMRotations1D']):
|
||||
beamdir_ids = set(beamdirection['ids'])
|
||||
elset_data = list(sorted(beamsec_ids.intersection(beamdir_ids))) # empty intersection sets possible
|
||||
if elset_data:
|
||||
names = [{'short': mat_data['ShortName']}, {'short': beamsec_data['ShortName']}]
|
||||
names = [{'short': 'M0'}, {'short': beamsec_data['ShortName']}, {'short': beamrot_data['ShortName']}, {'short': 'D' + str(i)}]
|
||||
ccx_elset = {}
|
||||
ccx_elset['ccx_elset'] = elset_data
|
||||
ccx_elset['ccx_elset_name'] = get_ccx_elset_name_short(names)
|
||||
ccx_elset['mat_obj_name'] = mat_obj.Name
|
||||
ccx_elset['ccx_mat_name'] = mat_obj.Material['Name']
|
||||
ccx_elset['beamsection_obj'] = beamsec_obj
|
||||
ccx_elset['beam_normal'] = beamdirection['normal'] # normal for this direction
|
||||
self.ccx_elsets.append(ccx_elset)
|
||||
|
||||
def get_ccx_elsets_multiple_mat_single_beam(self):
|
||||
beamsec_obj = self.beamsection_objects[0]['Object']
|
||||
beamrot_data = self.beamrotation_objects[0]
|
||||
for mat_data in self.material_objects:
|
||||
mat_obj = mat_data['Object']
|
||||
mat_ids = set(mat_data['FEMElements'])
|
||||
for i, beamdirection in enumerate(beamrot_data['FEMRotations1D']):
|
||||
beamdir_ids = set(beamdirection['ids'])
|
||||
elset_data = list(sorted(mat_ids.intersection(beamdir_ids)))
|
||||
if elset_data:
|
||||
names = [{'short': mat_data['ShortName']}, {'short': 'B0'}, {'short': beamrot_data['ShortName']}, {'short': 'D' + str(i)}]
|
||||
ccx_elset = {}
|
||||
ccx_elset['ccx_elset'] = elset_data
|
||||
ccx_elset['ccx_elset_name'] = get_ccx_elset_name_short(names)
|
||||
ccx_elset['mat_obj_name'] = mat_obj.Name
|
||||
ccx_elset['ccx_mat_name'] = mat_obj.Material['Name']
|
||||
ccx_elset['beamsection_obj'] = beamsec_obj
|
||||
ccx_elset['beam_normal'] = beamdirection['normal'] # normal for this direction
|
||||
self.ccx_elsets.append(ccx_elset)
|
||||
|
||||
def get_ccx_elsets_multiple_mat_multiple_beam(self):
|
||||
beamrot_data = self.beamrotation_objects[0]
|
||||
for beamsec_data in self.beamsection_objects:
|
||||
beamsec_obj = beamsec_data['Object']
|
||||
beamsec_ids = set(beamsec_data['FEMElements'])
|
||||
for mat_data in self.material_objects:
|
||||
mat_obj = mat_data['Object']
|
||||
mat_ids = set(mat_data['FEMElements'])
|
||||
for i, beamdirection in enumerate(beamrot_data['FEMRotations1D']):
|
||||
beamdir_ids = set(beamdirection['ids'])
|
||||
elset_data = list(sorted(beamsec_ids.intersection(mat_ids).intersection(beamdir_ids))) # empty intersection sets possible
|
||||
if elset_data:
|
||||
names = [{'short': mat_data['ShortName']}, {'short': beamsec_data['ShortName']}, {'short': beamrot_data['ShortName']}, {'short': 'D' + str(i)}]
|
||||
ccx_elset = {}
|
||||
ccx_elset['ccx_elset'] = elset_data
|
||||
ccx_elset['ccx_elset_name'] = get_ccx_elset_name_short(names)
|
||||
ccx_elset['mat_obj_name'] = mat_obj.Name
|
||||
ccx_elset['ccx_mat_name'] = mat_obj.Material['Name']
|
||||
ccx_elset['beamsection_obj'] = beamsec_obj
|
||||
ccx_elset['beam_normal'] = beamdirection['normal'] # normal for this direction
|
||||
self.ccx_elsets.append(ccx_elset)
|
||||
|
||||
# fluid
|
||||
def get_ccx_elsets_single_mat_single_fluid(self):
|
||||
mat_obj = self.material_objects[0]['Object']
|
||||
@@ -1283,7 +1314,7 @@ class FemInputWriterCcx(FemInputWriter.FemInputWriter):
|
||||
|
||||
|
||||
# Helpers
|
||||
# ccx elset names: M .. Material, B .. Beam, F .. Fluid, S .. Shell, TODO write comment into input file to elset ids and elset attributes
|
||||
# ccx elset names: M .. Material, B .. Beam, R .. BeamRotation, D ..Direction, F .. Fluid, S .. Shell, TODO write comment into input file to elset ids and elset attributes
|
||||
def get_ccx_elset_name_standard(names):
|
||||
# standard max length = 80
|
||||
ccx_elset_name = ''
|
||||
|
||||
@@ -78,6 +78,10 @@ class FemInputWriter():
|
||||
self.ccx_efaces = 'Efaces'
|
||||
self.ccx_eedges = 'Eedges'
|
||||
self.ccx_elsets = []
|
||||
if hasattr(self.mesh_object, "Shape"):
|
||||
self.theshape = self.mesh_object.Shape
|
||||
elif hasattr(self.mesh_object, "Part"):
|
||||
self.theshape = self.mesh_object.Part
|
||||
self.femmesh = self.mesh_object.FemMesh
|
||||
self.femnodes_mesh = {}
|
||||
self.femelement_table = {}
|
||||
@@ -195,6 +199,12 @@ class FemInputWriter():
|
||||
self.femelement_table = FemMeshTools.get_femelement_table(self.femmesh)
|
||||
FemMeshTools.get_femelement_sets(self.femmesh, self.femelement_table, self.beamsection_objects)
|
||||
|
||||
def get_element_rotation1D_elements(self):
|
||||
# get for each geometry edge direction the element ids and rotation norma
|
||||
if not self.femelement_table:
|
||||
self.femelement_table = FemMeshTools.get_femelement_table(self.femmesh)
|
||||
FemMeshTools.get_femelement_direction1D_set(self.femmesh, self.femelement_table, self.beamrotation_objects, self.theshape)
|
||||
|
||||
def get_element_fluid1D_elements(self):
|
||||
# get element ids and write them into the objects
|
||||
print("Fluid sections")
|
||||
|
||||
Reference in New Issue
Block a user