From 302e9e83746b818bdae892a3277fe611c4159bb1 Mon Sep 17 00:00:00 2001 From: ebrahimraeyat Date: Sun, 19 Apr 2020 10:07:04 +0430 Subject: [PATCH] FEM: writer base and ccx writer, move some calculix writer methods to writerbase --- src/Mod/Fem/femsolver/calculix/writer.py | 402 +--------------------- src/Mod/Fem/femsolver/writerbase.py | 405 +++++++++++++++++++++++ 2 files changed, 408 insertions(+), 399 deletions(-) diff --git a/src/Mod/Fem/femsolver/calculix/writer.py b/src/Mod/Fem/femsolver/calculix/writer.py index cc4193ec6732..2d6ac560e6b3 100644 --- a/src/Mod/Fem/femsolver/calculix/writer.py +++ b/src/Mod/Fem/femsolver/calculix/writer.py @@ -1212,73 +1212,13 @@ def write_footer(self, f): # ******************************************************************************************** # material and fem element type def write_element_sets_material_and_femelement_type(self, f): + + self.get_element_sets_material_and_femelement_type() + f.write("\n***********************************************************\n") 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're going to 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() - if len(self.beamsection_objects) > 1: - self.get_element_geometry1D_elements() - if len(self.fluidsection_objects) > 1: - self.get_element_fluid1D_elements() - - # get the element ids for material objects and write them into the material object - if len(self.material_objects) > 1: - self.get_material_elements() - - # create the ccx_elsets - if len(self.material_objects) == 1: - if self.femmesh.Volumes: - # we only could do this for volumes, if a mesh contains volumes - # we're going to use them in the analysis - # but a mesh could contain the element faces of the volumes as faces - # and the edges of the faces as edges - # there we have to check for some geometric objects - self.get_ccx_elsets_single_mat_solid() - if len(self.shellthickness_objects) == 1: - self.get_ccx_elsets_single_mat_single_shell() - elif len(self.shellthickness_objects) > 1: - self.get_ccx_elsets_single_mat_multiple_shell() - if len(self.beamsection_objects) == 1: - self.get_ccx_elsets_single_mat_single_beam() - elif len(self.beamsection_objects) > 1: - self.get_ccx_elsets_single_mat_multiple_beam() - if len(self.fluidsection_objects) == 1: - self.get_ccx_elsets_single_mat_single_fluid() - elif len(self.fluidsection_objects) > 1: - self.get_ccx_elsets_single_mat_multiple_fluid() - elif len(self.material_objects) > 1: - if self.femmesh.Volumes: - # we only could do this for volumes, if a mseh contains volumes - # we're going to use them in the analysis - # but a mesh could contain the element faces of the volumes as faces - # and the edges of the faces as edges - # there we have to check for some geometric objects - # volume is a bit special - # because retrieving ids from group mesh data is implemented - self.get_ccx_elsets_multiple_mat_solid() - if len(self.shellthickness_objects) == 1: - self.get_ccx_elsets_multiple_mat_single_shell() - elif len(self.shellthickness_objects) > 1: - self.get_ccx_elsets_multiple_mat_multiple_shell() - if len(self.beamsection_objects) == 1: - self.get_ccx_elsets_multiple_mat_single_beam() - elif len(self.beamsection_objects) > 1: - self.get_ccx_elsets_multiple_mat_multiple_beam() - if len(self.fluidsection_objects) == 1: - self.get_ccx_elsets_multiple_mat_single_fluid() - elif len(self.fluidsection_objects) > 1: - self.get_ccx_elsets_multiple_mat_multiple_fluid() - # TODO: some elementIDs are collected for 1D-Flow calculation, # this should be a def somewhere else, preferable inside the get_ccx_elsets_... methods for ccx_elset in self.ccx_elsets: @@ -1318,296 +1258,6 @@ def write_element_sets_material_and_femelement_type(self, f): for elid in ccx_elset["ccx_elset"]: f.write(str(elid) + ",\n") - # self.ccx_elsets = [ { - # "ccx_elset" : [e1, e2, e3, ... , en] or elements set name strings - # "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 - # "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"] - beamrot_data = self.beamrotation_objects[0] - for i, beamdirection in enumerate(beamrot_data["FEMRotations1D"]): - # ID's for this direction - elset_data = beamdirection["ids"] - 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 - # normal for this direction - ccx_elset["beam_normal"] = beamdirection["normal"] - 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"] - beamsec_ids = set(beamsec_data["FEMElements"]) - for i, beamdirection in enumerate(beamrot_data["FEMRotations1D"]): - beamdir_ids = set(beamdirection["ids"]) - # empty intersection sets possible - elset_data = list(sorted(beamsec_ids.intersection(beamdir_ids))) - if elset_data: - 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 - # normal for this direction - ccx_elset["beam_normal"] = beamdirection["normal"] - 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 - # normal for this direction - ccx_elset["beam_normal"] = beamdirection["normal"] - 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"]) - # empty intersection sets possible - elset_data = list(sorted( - beamsec_ids.intersection(mat_ids).intersection(beamdir_ids) - )) - 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 - # normal for this direction - ccx_elset["beam_normal"] = beamdirection["normal"] - self.ccx_elsets.append(ccx_elset) - - # fluid - def get_ccx_elsets_single_mat_single_fluid(self): - mat_obj = self.material_objects[0]["Object"] - fluidsec_obj = self.fluidsection_objects[0]["Object"] - elset_data = self.ccx_eedges - names = [{"short": "M0"}, {"short": "F0"}] - 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["fluidsection_obj"] = fluidsec_obj - self.ccx_elsets.append(ccx_elset) - - def get_ccx_elsets_single_mat_multiple_fluid(self): - mat_obj = self.material_objects[0]["Object"] - for fluidsec_data in self.fluidsection_objects: - fluidsec_obj = fluidsec_data["Object"] - elset_data = fluidsec_data["FEMElements"] - names = [{"short": "M0"}, {"short": fluidsec_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["fluidsection_obj"] = fluidsec_obj - self.ccx_elsets.append(ccx_elset) - - def get_ccx_elsets_multiple_mat_single_fluid(self): - fluidsec_obj = self.fluidsection_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": "F0"}] - 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["fluidsection_obj"] = fluidsec_obj - self.ccx_elsets.append(ccx_elset) - - def get_ccx_elsets_multiple_mat_multiple_fluid(self): - for fluidsec_data in self.fluidsection_objects: - fluidsec_obj = fluidsec_data["Object"] - for mat_data in self.material_objects: - mat_obj = mat_data["Object"] - fluidsec_ids = set(fluidsec_data["FEMElements"]) - mat_ids = set(mat_data["FEMElements"]) - # empty intersection sets possible - elset_data = list(sorted(fluidsec_ids.intersection(mat_ids))) - if elset_data: - names = [ - {"short": mat_data["ShortName"]}, - {"short": fluidsec_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["fluidsection_obj"] = fluidsec_obj - self.ccx_elsets.append(ccx_elset) - - # shell - def get_ccx_elsets_single_mat_single_shell(self): - mat_obj = self.material_objects[0]["Object"] - shellth_obj = self.shellthickness_objects[0]["Object"] - elset_data = self.ccx_efaces - names = [ - {"long": mat_obj.Name, "short": "M0"}, - {"long": shellth_obj.Name, "short": "S0"} - ] - ccx_elset = {} - ccx_elset["ccx_elset"] = elset_data - ccx_elset["ccx_elset_name"] = get_ccx_elset_name_standard(names) - ccx_elset["mat_obj_name"] = mat_obj.Name - ccx_elset["ccx_mat_name"] = mat_obj.Material["Name"] - ccx_elset["shellthickness_obj"] = shellth_obj - self.ccx_elsets.append(ccx_elset) - - def get_ccx_elsets_single_mat_multiple_shell(self): - mat_obj = self.material_objects[0]["Object"] - for shellth_data in self.shellthickness_objects: - shellth_obj = shellth_data["Object"] - elset_data = shellth_data["FEMElements"] - names = [ - {"long": mat_obj.Name, "short": "M0"}, - {"long": shellth_obj.Name, "short": shellth_data["ShortName"]} - ] - ccx_elset = {} - ccx_elset["ccx_elset"] = elset_data - ccx_elset["ccx_elset_name"] = get_ccx_elset_name_standard(names) - ccx_elset["mat_obj_name"] = mat_obj.Name - ccx_elset["ccx_mat_name"] = mat_obj.Material["Name"] - ccx_elset["shellthickness_obj"] = shellth_obj - self.ccx_elsets.append(ccx_elset) - - def get_ccx_elsets_multiple_mat_single_shell(self): - shellth_obj = self.shellthickness_objects[0]["Object"] - for mat_data in self.material_objects: - mat_obj = mat_data["Object"] - elset_data = mat_data["FEMElements"] - names = [ - {"long": mat_obj.Name, "short": mat_data["ShortName"]}, - {"long": shellth_obj.Name, "short": "S0"} - ] - ccx_elset = {} - ccx_elset["ccx_elset"] = elset_data - ccx_elset["ccx_elset_name"] = get_ccx_elset_name_standard(names) - ccx_elset["mat_obj_name"] = mat_obj.Name - ccx_elset["ccx_mat_name"] = mat_obj.Material["Name"] - ccx_elset["shellthickness_obj"] = shellth_obj - self.ccx_elsets.append(ccx_elset) - - def get_ccx_elsets_multiple_mat_multiple_shell(self): - for shellth_data in self.shellthickness_objects: - shellth_obj = shellth_data["Object"] - for mat_data in self.material_objects: - mat_obj = mat_data["Object"] - shellth_ids = set(shellth_data["FEMElements"]) - mat_ids = set(mat_data["FEMElements"]) - # empty intersection sets possible - elset_data = list(sorted(shellth_ids.intersection(mat_ids))) - if elset_data: - names = [ - {"long": mat_obj.Name, "short": mat_data["ShortName"]}, - {"long": shellth_obj.Name, "short": shellth_data["ShortName"]} - ] - ccx_elset = {} - ccx_elset["ccx_elset"] = elset_data - ccx_elset["ccx_elset_name"] = get_ccx_elset_name_standard(names) - ccx_elset["mat_obj_name"] = mat_obj.Name - ccx_elset["ccx_mat_name"] = mat_obj.Material["Name"] - ccx_elset["shellthickness_obj"] = shellth_obj - self.ccx_elsets.append(ccx_elset) - - # solid - def get_ccx_elsets_single_mat_solid(self): - mat_obj = self.material_objects[0]["Object"] - elset_data = self.ccx_evolumes - names = [ - {"long": mat_obj.Name, "short": "M0"}, - {"long": "Solid", "short": "Solid"} - ] - ccx_elset = {} - ccx_elset["ccx_elset"] = elset_data - ccx_elset["ccx_elset_name"] = get_ccx_elset_name_standard(names) - ccx_elset["mat_obj_name"] = mat_obj.Name - ccx_elset["ccx_mat_name"] = mat_obj.Material["Name"] - self.ccx_elsets.append(ccx_elset) - - def get_ccx_elsets_multiple_mat_solid(self): - for mat_data in self.material_objects: - mat_obj = mat_data["Object"] - elset_data = mat_data["FEMElements"] - names = [ - {"long": mat_obj.Name, "short": mat_data["ShortName"]}, - {"long": "Solid", "short": "Solid"} - ] - ccx_elset = {} - ccx_elset["ccx_elset"] = elset_data - ccx_elset["ccx_elset_name"] = get_ccx_elset_name_standard(names) - ccx_elset["mat_obj_name"] = mat_obj.Name - ccx_elset["ccx_mat_name"] = mat_obj.Material["Name"] - self.ccx_elsets.append(ccx_elset) - def is_density_needed(self): if self.analysis_type == "frequency": return True @@ -1786,52 +1436,6 @@ def write_femelementsets(self, f): # ************************************************************************************************ # Helpers -# 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 = "" - for name in names: - ccx_elset_name += name["long"] - if len(ccx_elset_name) < 81: - return ccx_elset_name - else: - ccx_elset_name = "" - for name in names: - ccx_elset_name += name["short"] - if len(ccx_elset_name) < 81: - return ccx_elset_name - else: - error = ( - "FEM: Trouble in ccx input file, because an " - "elset name is longer than 80 character! {}\n" - .format(ccx_elset_name) - ) - raise Exception(error) - - -def get_ccx_elset_name_short(names): - # restricted max length = 20 (beam elsets) - ccx_elset_name = "" - for name in names: - ccx_elset_name += name["short"] - if len(ccx_elset_name) < 21: - return ccx_elset_name - else: - error = ( - "FEM: Trouble in ccx input file, because an" - "beam elset name is longer than 20 character! {}\n" - .format(ccx_elset_name) - ) - raise Exception(error) - - def is_fluid_section_inlet_outlet(ccx_elsets): """ Fluid section: Inlet and Outlet requires special element definition """ diff --git a/src/Mod/Fem/femsolver/writerbase.py b/src/Mod/Fem/femsolver/writerbase.py index 1c7bb88fe61a..4439b78965d5 100644 --- a/src/Mod/Fem/femsolver/writerbase.py +++ b/src/Mod/Fem/femsolver/writerbase.py @@ -581,8 +581,413 @@ def get_material_elements(self): self.material_objects ) + def get_element_sets_material_and_femelement_type(self): + # in any case if we have beams, we're going to 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() + if len(self.beamsection_objects) > 1: + self.get_element_geometry1D_elements() + if len(self.fluidsection_objects) > 1: + self.get_element_fluid1D_elements() + + # get the element ids for material objects and write them into the material object + if len(self.material_objects) > 1: + self.get_material_elements() + + # create the ccx_elsets + if len(self.material_objects) == 1: + if self.femmesh.Volumes: + # we only could do this for volumes, if a mesh contains volumes + # we're going to use them in the analysis + # but a mesh could contain the element faces of the volumes as faces + # and the edges of the faces as edges + # there we have to check for some geometric objects + self.get_ccx_elsets_single_mat_solid() + if len(self.shellthickness_objects) == 1: + self.get_ccx_elsets_single_mat_single_shell() + elif len(self.shellthickness_objects) > 1: + self.get_ccx_elsets_single_mat_multiple_shell() + if len(self.beamsection_objects) == 1: + self.get_ccx_elsets_single_mat_single_beam() + elif len(self.beamsection_objects) > 1: + self.get_ccx_elsets_single_mat_multiple_beam() + if len(self.fluidsection_objects) == 1: + self.get_ccx_elsets_single_mat_single_fluid() + elif len(self.fluidsection_objects) > 1: + self.get_ccx_elsets_single_mat_multiple_fluid() + elif len(self.material_objects) > 1: + if self.femmesh.Volumes: + # we only could do this for volumes, if a mseh contains volumes + # we're going to use them in the analysis + # but a mesh could contain the element faces of the volumes as faces + # and the edges of the faces as edges + # there we have to check for some geometric objects + # volume is a bit special + # because retrieving ids from group mesh data is implemented + self.get_ccx_elsets_multiple_mat_solid() + if len(self.shellthickness_objects) == 1: + self.get_ccx_elsets_multiple_mat_single_shell() + elif len(self.shellthickness_objects) > 1: + self.get_ccx_elsets_multiple_mat_multiple_shell() + if len(self.beamsection_objects) == 1: + self.get_ccx_elsets_multiple_mat_single_beam() + elif len(self.beamsection_objects) > 1: + self.get_ccx_elsets_multiple_mat_multiple_beam() + if len(self.fluidsection_objects) == 1: + self.get_ccx_elsets_multiple_mat_single_fluid() + elif len(self.fluidsection_objects) > 1: + self.get_ccx_elsets_multiple_mat_multiple_fluid() + + # self.ccx_elsets = [ { + # "ccx_elset" : [e1, e2, e3, ... , en] or elements set name strings + # "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 + # "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"] + beamrot_data = self.beamrotation_objects[0] + for i, beamdirection in enumerate(beamrot_data["FEMRotations1D"]): + # ID's for this direction + elset_data = beamdirection["ids"] + 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 + # normal for this direction + ccx_elset["beam_normal"] = beamdirection["normal"] + 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"] + beamsec_ids = set(beamsec_data["FEMElements"]) + for i, beamdirection in enumerate(beamrot_data["FEMRotations1D"]): + beamdir_ids = set(beamdirection["ids"]) + # empty intersection sets possible + elset_data = list(sorted(beamsec_ids.intersection(beamdir_ids))) + if elset_data: + 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 + # normal for this direction + ccx_elset["beam_normal"] = beamdirection["normal"] + 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 + # normal for this direction + ccx_elset["beam_normal"] = beamdirection["normal"] + 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"]) + # empty intersection sets possible + elset_data = list(sorted( + beamsec_ids.intersection(mat_ids).intersection(beamdir_ids) + )) + 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 + # normal for this direction + ccx_elset["beam_normal"] = beamdirection["normal"] + self.ccx_elsets.append(ccx_elset) + + # fluid + def get_ccx_elsets_single_mat_single_fluid(self): + mat_obj = self.material_objects[0]["Object"] + fluidsec_obj = self.fluidsection_objects[0]["Object"] + elset_data = self.ccx_eedges + names = [{"short": "M0"}, {"short": "F0"}] + 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["fluidsection_obj"] = fluidsec_obj + self.ccx_elsets.append(ccx_elset) + + def get_ccx_elsets_single_mat_multiple_fluid(self): + mat_obj = self.material_objects[0]["Object"] + for fluidsec_data in self.fluidsection_objects: + fluidsec_obj = fluidsec_data["Object"] + elset_data = fluidsec_data["FEMElements"] + names = [{"short": "M0"}, {"short": fluidsec_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["fluidsection_obj"] = fluidsec_obj + self.ccx_elsets.append(ccx_elset) + + def get_ccx_elsets_multiple_mat_single_fluid(self): + fluidsec_obj = self.fluidsection_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": "F0"}] + 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["fluidsection_obj"] = fluidsec_obj + self.ccx_elsets.append(ccx_elset) + + def get_ccx_elsets_multiple_mat_multiple_fluid(self): + for fluidsec_data in self.fluidsection_objects: + fluidsec_obj = fluidsec_data["Object"] + for mat_data in self.material_objects: + mat_obj = mat_data["Object"] + fluidsec_ids = set(fluidsec_data["FEMElements"]) + mat_ids = set(mat_data["FEMElements"]) + # empty intersection sets possible + elset_data = list(sorted(fluidsec_ids.intersection(mat_ids))) + if elset_data: + names = [ + {"short": mat_data["ShortName"]}, + {"short": fluidsec_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["fluidsection_obj"] = fluidsec_obj + self.ccx_elsets.append(ccx_elset) + + # shell + def get_ccx_elsets_single_mat_single_shell(self): + mat_obj = self.material_objects[0]["Object"] + shellth_obj = self.shellthickness_objects[0]["Object"] + elset_data = self.ccx_efaces + names = [ + {"long": mat_obj.Name, "short": "M0"}, + {"long": shellth_obj.Name, "short": "S0"} + ] + ccx_elset = {} + ccx_elset["ccx_elset"] = elset_data + ccx_elset["ccx_elset_name"] = get_ccx_elset_name_standard(names) + ccx_elset["mat_obj_name"] = mat_obj.Name + ccx_elset["ccx_mat_name"] = mat_obj.Material["Name"] + ccx_elset["shellthickness_obj"] = shellth_obj + self.ccx_elsets.append(ccx_elset) + + def get_ccx_elsets_single_mat_multiple_shell(self): + mat_obj = self.material_objects[0]["Object"] + for shellth_data in self.shellthickness_objects: + shellth_obj = shellth_data["Object"] + elset_data = shellth_data["FEMElements"] + names = [ + {"long": mat_obj.Name, "short": "M0"}, + {"long": shellth_obj.Name, "short": shellth_data["ShortName"]} + ] + ccx_elset = {} + ccx_elset["ccx_elset"] = elset_data + ccx_elset["ccx_elset_name"] = get_ccx_elset_name_standard(names) + ccx_elset["mat_obj_name"] = mat_obj.Name + ccx_elset["ccx_mat_name"] = mat_obj.Material["Name"] + ccx_elset["shellthickness_obj"] = shellth_obj + self.ccx_elsets.append(ccx_elset) + + def get_ccx_elsets_multiple_mat_single_shell(self): + shellth_obj = self.shellthickness_objects[0]["Object"] + for mat_data in self.material_objects: + mat_obj = mat_data["Object"] + elset_data = mat_data["FEMElements"] + names = [ + {"long": mat_obj.Name, "short": mat_data["ShortName"]}, + {"long": shellth_obj.Name, "short": "S0"} + ] + ccx_elset = {} + ccx_elset["ccx_elset"] = elset_data + ccx_elset["ccx_elset_name"] = get_ccx_elset_name_standard(names) + ccx_elset["mat_obj_name"] = mat_obj.Name + ccx_elset["ccx_mat_name"] = mat_obj.Material["Name"] + ccx_elset["shellthickness_obj"] = shellth_obj + self.ccx_elsets.append(ccx_elset) + + def get_ccx_elsets_multiple_mat_multiple_shell(self): + for shellth_data in self.shellthickness_objects: + shellth_obj = shellth_data["Object"] + for mat_data in self.material_objects: + mat_obj = mat_data["Object"] + shellth_ids = set(shellth_data["FEMElements"]) + mat_ids = set(mat_data["FEMElements"]) + # empty intersection sets possible + elset_data = list(sorted(shellth_ids.intersection(mat_ids))) + if elset_data: + names = [ + {"long": mat_obj.Name, "short": mat_data["ShortName"]}, + {"long": shellth_obj.Name, "short": shellth_data["ShortName"]} + ] + ccx_elset = {} + ccx_elset["ccx_elset"] = elset_data + ccx_elset["ccx_elset_name"] = get_ccx_elset_name_standard(names) + ccx_elset["mat_obj_name"] = mat_obj.Name + ccx_elset["ccx_mat_name"] = mat_obj.Material["Name"] + ccx_elset["shellthickness_obj"] = shellth_obj + self.ccx_elsets.append(ccx_elset) + + # solid + def get_ccx_elsets_single_mat_solid(self): + mat_obj = self.material_objects[0]["Object"] + elset_data = self.ccx_evolumes + names = [ + {"long": mat_obj.Name, "short": "M0"}, + {"long": "Solid", "short": "Solid"} + ] + ccx_elset = {} + ccx_elset["ccx_elset"] = elset_data + ccx_elset["ccx_elset_name"] = get_ccx_elset_name_standard(names) + ccx_elset["mat_obj_name"] = mat_obj.Name + ccx_elset["ccx_mat_name"] = mat_obj.Material["Name"] + self.ccx_elsets.append(ccx_elset) + + def get_ccx_elsets_multiple_mat_solid(self): + for mat_data in self.material_objects: + mat_obj = mat_data["Object"] + elset_data = mat_data["FEMElements"] + names = [ + {"long": mat_obj.Name, "short": mat_data["ShortName"]}, + {"long": "Solid", "short": "Solid"} + ] + ccx_elset = {} + ccx_elset["ccx_elset"] = elset_data + ccx_elset["ccx_elset_name"] = get_ccx_elset_name_standard(names) + ccx_elset["mat_obj_name"] = mat_obj.Name + ccx_elset["ccx_mat_name"] = mat_obj.Material["Name"] + self.ccx_elsets.append(ccx_elset) + + +# ************************************************************************************************ +# Helpers +# 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 = "" + for name in names: + ccx_elset_name += name["long"] + if len(ccx_elset_name) < 81: + return ccx_elset_name + else: + ccx_elset_name = "" + for name in names: + ccx_elset_name += name["short"] + if len(ccx_elset_name) < 81: + return ccx_elset_name + else: + error = ( + "FEM: Trouble in ccx input file, because an " + "elset name is longer than 80 character! {}\n" + .format(ccx_elset_name) + ) + raise Exception(error) + + +def get_ccx_elset_name_short(names): + # restricted max length = 20 (beam elsets) + ccx_elset_name = "" + for name in names: + ccx_elset_name += name["short"] + if len(ccx_elset_name) < 21: + return ccx_elset_name + else: + error = ( + "FEM: Trouble in ccx input file, because an" + "beam elset name is longer than 20 character! {}\n" + .format(ccx_elset_name) + ) + raise Exception(error) # helper + + def print_obj_info(obj, log=False): if log is False: FreeCAD.Console.PrintMessage("{}:\n".format(obj.Label))