Beispiel #1
0
 def get_region_data(self):
     # mesh regions
     self.ele_length_map = {}  # { 'ElementString' : element length }
     self.ele_node_map = {}  # { 'ElementString' : [element nodes] }
     if not self.mesh_obj.MeshRegionList:
         # print ('  No mesh regions.')
         pass
     else:
         print ('  Mesh regions, we need to get the elements.')
         # by the use of MeshRegion object and a BooleanSplitCompound there could be problems with node numbers see
         # http://forum.freecadweb.org/viewtopic.php?f=18&t=18780&start=40#p149467
         # http://forum.freecadweb.org/viewtopic.php?f=18&t=18780&p=149520#p149520
         part = self.part_obj
         if self.mesh_obj.MeshRegionList:
             if part.Shape.ShapeType == "Compound" and hasattr(part, "Proxy"):  # other part obj might not have a Proxy, thus an exception would be raised
                 if (part.Proxy.Type == "FeatureBooleanFragments" or part.Proxy.Type == "FeatureSlice" or part.Proxy.Type == "FeatureXOR"):
                     error_message = "  The mesh to shape is a boolean split tools Compound and the mesh has mesh region list. GMSH could return unexpected meshes in such circumstances. It is strongly recommended to extract the shape to mesh from the Compound and use this one."
                     FreeCAD.Console.PrintError(error_message + "\n")
                     # TODO: no gui popup because FreeCAD will be in a endless print loop
                     #       as long as the pop up is on --> maybe find a better solution for
                     #       either of both --> thus the pop up is in task panel
         for mr_obj in self.mesh_obj.MeshRegionList:
             # print(mr_obj.Name)
             # print(mr_obj.CharacteristicLength)
             # print(Units.Quantity(mr_obj.CharacteristicLength).Value)
             if mr_obj.CharacteristicLength:
                 if mr_obj.References:
                     for sub in mr_obj.References:
                         # print(sub[0])  # Part the elements belongs to
                         # check if the shape of the mesh region is an element of the Part to mesh, if not try to find the element in the shape to mesh
                         search_ele_in_shape_to_mesh = False
                         if not self.part_obj.Shape.isSame(sub[0].Shape):
                             # print("  One element of the meshregion " + mr_obj.Name + " is not an element of the Part to mesh.")
                             # print("  But we are going to try to find it in the Shape to mesh :-)")
                             search_ele_in_shape_to_mesh = True
                         for elems in sub[1]:
                             # print(elems)  # elems --> element
                             if search_ele_in_shape_to_mesh:
                                 # we're going to try to find the element in the Shape to mesh and use the found element as elems
                                 ele_shape = FemMeshTools.get_element(sub[0], elems)  # the method getElement(element) does not return Solid elements
                                 found_element = FemMeshTools.find_element_in_shape(self.part_obj.Shape, ele_shape)
                                 if found_element:
                                     elems = found_element
                                 else:
                                     FreeCAD.Console.PrintError("One element of the meshregion " + mr_obj.Name + " could not be found in the Part to mesh. It will be ignored.\n")
                             # print(elems)  # element
                             if elems not in self.ele_length_map:
                                 self.ele_length_map[elems] = Units.Quantity(mr_obj.CharacteristicLength).Value
                             else:
                                 FreeCAD.Console.PrintError("The element " + elems + " of the meshregion " + mr_obj.Name + " has been added to another mesh region.\n")
                 else:
                     FreeCAD.Console.PrintError("The meshregion: " + mr_obj.Name + " is not used to create the mesh because the reference list is empty.\n")
             else:
                 FreeCAD.Console.PrintError("The meshregion: " + mr_obj.Name + " is not used to create the mesh because the CharacteristicLength is 0.0 mm.\n")
         for eleml in self.ele_length_map:
             ele_shape = FemMeshTools.get_element(self.part_obj, eleml)  # the method getElement(element) does not return Solid elements
             ele_vertexes = FemMeshTools.get_vertexes_by_element(self.part_obj.Shape, ele_shape)
             self.ele_node_map[eleml] = ele_vertexes
         print('  {}'.format(self.ele_length_map))
         print('  {}'.format(self.ele_node_map))
Beispiel #2
0
 def get_region_data(self):
     # mesh regions
     self.ele_length_map = {}  # { 'ElementString' : element length }
     self.ele_node_map = {}  # { 'ElementString' : [element nodes] }
     if not self.mesh_obj.MeshRegionList:
         # print ('  No mesh regions.')
         pass
     else:
         print ('  Mesh regions, we need to get the elements.')
         # by the use of MeshRegion object and a BooleanSplitCompound there could be problems with node numbers see
         # http://forum.freecadweb.org/viewtopic.php?f=18&t=18780&start=40#p149467
         # http://forum.freecadweb.org/viewtopic.php?f=18&t=18780&p=149520#p149520
         part = self.part_obj
         if self.mesh_obj.MeshRegionList:
             if part.Shape.ShapeType == "Compound" and hasattr(part, "Proxy"):  # other part obj might not have a Proxy, thus an exception would be raised
                 if (part.Proxy.Type == "FeatureBooleanFragments" or part.Proxy.Type == "FeatureSlice" or part.Proxy.Type == "FeatureXOR"):
                     error_message = "  The mesh to shape is a boolean split tools Compound and the mesh has mesh region list. Gmsh could return unexpected meshes in such circumstances. It is strongly recommended to extract the shape to mesh from the Compound and use this one."
                     FreeCAD.Console.PrintError(error_message + "\n")
                     # TODO: no gui popup because FreeCAD will be in a endless print loop
                     #       as long as the pop up is on --> maybe find a better solution for
                     #       either of both --> thus the pop up is in task panel
         for mr_obj in self.mesh_obj.MeshRegionList:
             # print(mr_obj.Name)
             # print(mr_obj.CharacteristicLength)
             # print(Units.Quantity(mr_obj.CharacteristicLength).Value)
             if mr_obj.CharacteristicLength:
                 if mr_obj.References:
                     for sub in mr_obj.References:
                         # print(sub[0])  # Part the elements belongs to
                         # check if the shape of the mesh region is an element of the Part to mesh, if not try to find the element in the shape to mesh
                         search_ele_in_shape_to_mesh = False
                         if not self.part_obj.Shape.isSame(sub[0].Shape):
                             # print("  One element of the meshregion " + mr_obj.Name + " is not an element of the Part to mesh.")
                             # print("  But we are going to try to find it in the Shape to mesh :-)")
                             search_ele_in_shape_to_mesh = True
                         for elems in sub[1]:
                             # print(elems)  # elems --> element
                             if search_ele_in_shape_to_mesh:
                                 # we're going to try to find the element in the Shape to mesh and use the found element as elems
                                 ele_shape = FemMeshTools.get_element(sub[0], elems)  # the method getElement(element) does not return Solid elements
                                 found_element = FemMeshTools.find_element_in_shape(self.part_obj.Shape, ele_shape)
                                 if found_element:
                                     elems = found_element
                                 else:
                                     FreeCAD.Console.PrintError("One element of the meshregion " + mr_obj.Name + " could not be found in the Part to mesh. It will be ignored.\n")
                             # print(elems)  # element
                             if elems not in self.ele_length_map:
                                 self.ele_length_map[elems] = Units.Quantity(mr_obj.CharacteristicLength).Value
                             else:
                                 FreeCAD.Console.PrintError("The element " + elems + " of the meshregion " + mr_obj.Name + " has been added to another mesh region.\n")
                 else:
                     FreeCAD.Console.PrintError("The meshregion: " + mr_obj.Name + " is not used to create the mesh because the reference list is empty.\n")
             else:
                 FreeCAD.Console.PrintError("The meshregion: " + mr_obj.Name + " is not used to create the mesh because the CharacteristicLength is 0.0 mm.\n")
         for eleml in self.ele_length_map:
             ele_shape = FemMeshTools.get_element(self.part_obj, eleml)  # the method getElement(element) does not return Solid elements
             ele_vertexes = FemMeshTools.get_vertexes_by_element(self.part_obj.Shape, ele_shape)
             self.ele_node_map[eleml] = ele_vertexes
         print('  {}'.format(self.ele_length_map))
         print('  {}'.format(self.ele_node_map))
Beispiel #3
0
    def get_constraints_pressure_faces(self):
        # TODO see comments in get_constraints_force_nodeloads(), it applies here too. Mhh it applies to all constraints ...
        '''
        # depreciated version
        # get the faces and face numbers
        for femobj in self.pressure_objects:  # femobj --> dict, FreeCAD document object is femobj['Object']
            femobj['PressureFaces'] = FemMeshTools.get_pressure_obj_faces_depreciated(self.femmesh, femobj)
            # print(femobj['PressureFaces'])
        '''

        if not self.femnodes_mesh:
            self.femnodes_mesh = self.femmesh.Nodes
        if not self.femelement_table:
            self.femelement_table = FemMeshTools.get_femelement_table(
                self.femmesh)
        if not self.femnodes_ele_table:
            self.femnodes_ele_table = FemMeshTools.get_femnodes_ele_table(
                self.femnodes_mesh, self.femelement_table)

        for femobj in self.pressure_objects:  # femobj --> dict, FreeCAD document object is femobj['Object']
            pressure_faces = FemMeshTools.get_pressure_obj_faces(
                self.femmesh, self.femelement_table, self.femnodes_ele_table,
                femobj)
            # print(len(pressure_faces))
            femobj['PressureFaces'] = [(femobj['Object'].Name + ': face load',
                                        pressure_faces)]
            print(femobj['PressureFaces'])
Beispiel #4
0
    def get_group_data(self):
        self.group_elements = {}
        # TODO solids, faces, edges and vertexes seam not work together in one group, some print or make them work together

        # mesh groups and groups of analysis member
        if not self.mesh_obj.MeshGroupList:
            print ('  No mesh group objects.')
        else:
            print ('  Mesh group objects, we need to get the elements.')
            for mg in self.mesh_obj.MeshGroupList:
                new_group_elements = FemMeshTools.get_mesh_group_elements(mg, self.part_obj)
                for ge in new_group_elements:
                    if ge not in self.group_elements:
                        self.group_elements[ge] = new_group_elements[ge]
                    else:
                        FreeCAD.Console.PrintError("  A group with this name exists already.\n")
        if self.analysis:
            print('  Group meshing.')
            new_group_elements = FemMeshTools.get_analysis_group_elements(self.analysis, self.part_obj)
            for ge in new_group_elements:
                if ge not in self.group_elements:
                    self.group_elements[ge] = new_group_elements[ge]
                else:
                    FreeCAD.Console.PrintError("  A group with this name exists already.\n")
        else:
            print('  No anlysis members for group meshing.')
        print('  {}'.format(self.group_elements))
Beispiel #5
0
 def get_constraints_force_nodeloads(self):
     # check shape type of reference shape
     for femobj in self.force_objects:  # femobj --> dict, FreeCAD document object is femobj['Object']
         frc_obj = femobj['Object']
         if femobj['RefShapeType'] == 'Vertex':
             # print("load on vertices --> we do not need the femelement_table and femnodes_mesh for node load calculation")
             pass
         elif femobj['RefShapeType'] == 'Face' and FemMeshTools.is_solid_femmesh(self.femmesh) and not FemMeshTools.has_no_face_data(self.femmesh):
             # print("solid_mesh with face data --> we do not need the femelement_table but we need the femnodes_mesh for node load calculation")
             if not self.femnodes_mesh:
                 self.femnodes_mesh = self.femmesh.Nodes
         else:
             # print("mesh without needed data --> we need the femelement_table and femnodes_mesh for node load calculation")
             if not self.femnodes_mesh:
                 self.femnodes_mesh = self.femmesh.Nodes
             if not self.femelement_table:
                 self.femelement_table = FemMeshTools.get_femelement_table(self.femmesh)
     # get node loads
     for femobj in self.force_objects:  # femobj --> dict, FreeCAD document object is femobj['Object']
         frc_obj = femobj['Object']
         if frc_obj.Force == 0:
             print('  Warning --> Force = 0')
         if femobj['RefShapeType'] == 'Vertex':  # point load on vertieces
             femobj['NodeLoadTable'] = FemMeshTools.get_force_obj_vertex_nodeload_table(self.femmesh, frc_obj)
         elif femobj['RefShapeType'] == 'Edge':  # line load on edges
             femobj['NodeLoadTable'] = FemMeshTools.get_force_obj_edge_nodeload_table(self.femmesh, self.femelement_table, self.femnodes_mesh, frc_obj)
         elif femobj['RefShapeType'] == 'Face':  # area load on faces
             femobj['NodeLoadTable'] = FemMeshTools.get_force_obj_face_nodeload_table(self.femmesh, self.femelement_table, self.femnodes_mesh, frc_obj)
Beispiel #6
0
 def write_z88_elements_properties(self):
     element_properties_file_path = self.file_name + 'elp.txt'
     elements_data = []
     if FemMeshTools.is_edge_femmesh(self.femmesh):
         if len(self.beamsection_objects) == 1:
             beam_obj = self.beamsection_objects[0]['Object']
             width = beam_obj.Width.getValueAs('mm')
             height = beam_obj.Height.getValueAs('mm')
             area = str(width * height)
             elements_data.append('1 ' + str(self.element_count) + ' ' + area + ' 0 0 0 0 0 0 ')
             print("Be aware, only trusses are supported for edge meshes!")
         else:
             print("Multiple beamsections for Z88 not yet supported!")
     elif FemMeshTools.is_face_femmesh(self.femmesh):
         if len(self.shellthickness_objects) == 1:
             thick_obj = self.shellthickness_objects[0]['Object']
             thickness = str(thick_obj.Thickness.getValueAs('mm'))
             elements_data.append('1 ' + str(self.element_count) + ' ' + thickness + ' 0 0 0 0 0 0 ')
         else:
             print("Multiple thicknesses for Z88 not yet supported!")
     elif FemMeshTools.is_solid_femmesh(self.femmesh):
         elements_data.append('1 ' + str(self.element_count) + ' 0 0 0 0 0 0 0')
     else:
         print("Error!")
     f = open(element_properties_file_path, 'w')
     f.write(str(len(elements_data)) + '\n')
     for e in elements_data:
         f.write(e)
     f.write('\n')
     f.close()
Beispiel #7
0
 def write_z88_elements_properties(self):
     element_properties_file_path = self.file_name + 'elp.txt'
     elements_data = []
     if FemMeshTools.is_edge_femmesh(self.femmesh):
         if len(self.beamsection_objects) == 1:
             beam_obj = self.beamsection_objects[0]['Object']
             width = beam_obj.Width.getValueAs('mm')
             height = beam_obj.Height.getValueAs('mm')
             area = str(width * height)
             elements_data.append('1 ' + str(self.element_count) + ' ' +
                                  area + ' 0 0 0 0 0 0 ')
             print("Be aware, only trusses are supported for edge meshes!")
         else:
             print("Multiple beamsections for Z88 not yet supported!")
     elif FemMeshTools.is_face_femmesh(self.femmesh):
         if len(self.shellthickness_objects) == 1:
             thick_obj = self.shellthickness_objects[0]['Object']
             thickness = str(thick_obj.Thickness.getValueAs('mm'))
             elements_data.append('1 ' + str(self.element_count) + ' ' +
                                  thickness + ' 0 0 0 0 0 0 ')
         else:
             print("Multiple thicknesses for Z88 not yet supported!")
     elif FemMeshTools.is_solid_femmesh(self.femmesh):
         elements_data.append('1 ' + str(self.element_count) +
                              ' 0 0 0 0 0 0 0')
     else:
         print("Error!")
     f = open(element_properties_file_path, 'w')
     f.write(str(len(elements_data)) + '\n')
     for e in elements_data:
         f.write(e)
     f.write('\n')
     f.close()
Beispiel #8
0
    def get_group_data(self):
        self.group_elements = {}
        # TODO: solids, faces, edges and vertexes don't seem to work together in one group,
        #       some print or make them work together

        # mesh groups and groups of analysis member
        if not self.mesh_obj.MeshGroupList:
            print('  No mesh group objects.')
        else:
            print('  Mesh group objects, we need to get the elements.')
            for mg in self.mesh_obj.MeshGroupList:
                new_group_elements = FemMeshTools.get_mesh_group_elements(
                    mg, self.part_obj)
                for ge in new_group_elements:
                    if ge not in self.group_elements:
                        self.group_elements[ge] = new_group_elements[ge]
                    else:
                        FreeCAD.Console.PrintError(
                            "  A group with this name exists already.\n")
        if self.analysis:
            print('  Group meshing.')
            new_group_elements = FemMeshTools.get_analysis_group_elements(
                self.analysis, self.part_obj)
            for ge in new_group_elements:
                if ge not in self.group_elements:
                    self.group_elements[ge] = new_group_elements[ge]
                else:
                    FreeCAD.Console.PrintError(
                        "  A group with this name exists already.\n")
        else:
            print('  No anlysis members for group meshing.')
        print('  {}'.format(self.group_elements))
Beispiel #9
0
 def get_group_data(self):
     if self.analysis:
         print('  Group meshing.')
         import FemMeshTools
         self.group_elements = FemMeshTools.get_analysis_group_elements(self.analysis, self.part_obj)
         print(self.group_elements)
     else:
         print('  NO group meshing.')
     self.ele_length_map = self.mesh_obj.CharacteristicLengthMap
     self.ele_node_map = {}
     if self.ele_length_map:
         import FemMeshTools
         print(self.ele_length_map)
         self.ele_node_map = {}
         for e in self.ele_length_map:
             if not e.startswith('Solid'):
                 # Face, Edge, Vertex
                 ele_shape = self.part_obj.Shape.getElement(e)
             else:
                 # Solid
                 ele_shape_index = int(e.lstrip('Solid')) - 1
                 ele_shape = self.part_obj.Shape.Solids[ele_shape_index]
             ele_vertexes = FemMeshTools.get_vertexes_by_element(self.part_obj.Shape, ele_shape)
             self.ele_node_map[e] = ele_vertexes
         print(self.ele_node_map)
Beispiel #10
0
 def get_ccx_elsets_multiple_mat_multiple_beam(self):
     if not self.femelement_table:
         self.femelement_table = FemMeshTools.get_femelement_table(
             self.femmesh)
     FemMeshTools.get_femelement_sets(self.femmesh, self.femelement_table,
                                      self.beamsection_objects)
     FemMeshTools.get_femelement_sets(self.femmesh, self.femelement_table,
                                      self.material_objects)
     for beamsec_data in self.beamsection_objects:
         beamsec_obj = beamsec_data['Object']
         for mat_data in self.material_objects:
             mat_obj = mat_data['Object']
             ccx_elset = {}
             ccx_elset['beamsection_obj'] = beamsec_obj
             elemids = []
             for elemid in beamsec_data['FEMElements']:
                 if elemid in mat_data['FEMElements']:
                     elemids.append(elemid)
             ccx_elset['ccx_elset'] = elemids
             ccx_elset['ccx_elset_name'] = get_ccx_elset_beam_name(
                 mat_obj.Name, beamsec_obj.Name, mat_data['ShortName'],
                 beamsec_data['ShortName'])
             ccx_elset['mat_obj_name'] = mat_obj.Name
             ccx_elset['ccx_mat_name'] = mat_obj.Material['Name']
             self.ccx_elsets.append(ccx_elset)
Beispiel #11
0
 def get_ccx_elsets_multiple_mat_multiple_shell(self):
     if not self.femelement_table:
         self.femelement_table = FemMeshTools.get_femelement_table(
             self.femmesh)
     FemMeshTools.get_femelement_sets(self.femmesh, self.femelement_table,
                                      self.shellthickness_objects)
     FemMeshTools.get_femelement_sets(self.femmesh, self.femelement_table,
                                      self.material_objects)
     for shellth_data in self.shellthickness_objects:
         shellth_obj = shellth_data['Object']
         for mat_data in self.material_objects:
             mat_obj = mat_data['Object']
             ccx_elset = {}
             ccx_elset['shellthickness_obj'] = shellth_obj
             elemids = []
             for elemid in shellth_data['FEMElements']:
                 if elemid in mat_data['FEMElements']:
                     elemids.append(elemid)
             ccx_elset['ccx_elset'] = elemids
             ccx_elset['ccx_elset_name'] = get_ccx_elset_shell_name(
                 mat_obj.Name, shellth_obj.Name, mat_data['ShortName'],
                 shellth_data['ShortName'])
             ccx_elset['mat_obj_name'] = mat_obj.Name
             ccx_elset['ccx_mat_name'] = mat_obj.Material['Name']
             self.ccx_elsets.append(ccx_elset)
Beispiel #12
0
 def write_z88_elements_properties(self):
     element_properties_file_path = self.file_name + "elp.txt"
     elements_data = []
     if FemMeshTools.is_edge_femmesh(self.femmesh):
         if len(self.beamsection_objects) == 1:
             beam_obj = self.beamsection_objects[0]["Object"]
             width = beam_obj.RectWidth.getValueAs("mm")
             height = beam_obj.RectHeight.getValueAs("mm")
             area = str(width * height)
             elements_data.append("1 " + str(self.element_count) + " " + area + " 0 0 0 0 0 0 ")
             print("Be aware, only trusses are supported for edge meshes!")
         else:
             print("Multiple beamsections for Z88 not yet supported!")
     elif FemMeshTools.is_face_femmesh(self.femmesh):
         if len(self.shellthickness_objects) == 1:
             thick_obj = self.shellthickness_objects[0]["Object"]
             thickness = str(thick_obj.Thickness.getValueAs("mm"))
             elements_data.append("1 " + str(self.element_count) + " " + thickness + " 0 0 0 0 0 0 ")
         else:
             print("Multiple thicknesses for Z88 not yet supported!")
     elif FemMeshTools.is_solid_femmesh(self.femmesh):
         elements_data.append("1 " + str(self.element_count) + " 0 0 0 0 0 0 0")
     else:
         print("Error!")
     f = open(element_properties_file_path, "w")
     f.write(str(len(elements_data)) + "\n")
     for e in elements_data:
         f.write(e)
     f.write("\n")
     f.close()
Beispiel #13
0
 def get_element_geometry2D_elements(self):
     # get element ids and write them into the objects
     if not self.femelement_table:
         self.femelement_table = FemMeshTools.get_femelement_table(
             self.femmesh)
     FemMeshTools.get_femelement_sets(self.femmesh, self.femelement_table,
                                      self.shellthickness_objects)
Beispiel #14
0
 def get_element_fluid1D_elements(self):
     # get element ids and write them into the objects
     if not self.femelement_table:
         self.femelement_table = FemMeshTools.get_femelement_table(
             self.femmesh)
     FemMeshTools.get_femelement_sets(self.femmesh, self.femelement_table,
                                      self.fluidsection_objects)
Beispiel #15
0
def get_z88_element_type(femmesh, femelement_table=None):
    import FemMeshTools
    if not femmesh:
        print("Error: No femmesh!")
    if not femelement_table:
        print("We need to get the femelement_table first!")
        femelement_table = FemMeshTools.get_femelement_table(femmesh)
    # in some cases lowest key in femelement_table is not [1]
    for elem in sorted(femelement_table):
        elem_length = len(femelement_table[elem])
        print(elem_length)
        break  # break after the first elem
    if FemMeshTools.is_solid_femmesh(femmesh):
        if femmesh.TetraCount == femmesh.VolumeCount:
            if elem_length == 4:
                return 17
            elif elem_length == 10:
                return 16
            else:
                print('Tetra with neiter 4 nor 10 nodes')
        elif femmesh.HexaCount == femmesh.VolumeCount:
            if elem_length == 8:
                return 1
            elif elem_length == 20:
                return 10
            else:
                print('Hexa with neither 8 nor 20 nodes')
                return 0
        else:
            print('no tetra, no hexa or Mixed Volume Elements')
    elif FemMeshTools.is_face_femmesh(femmesh):
        if femmesh.TriangleCount == femmesh.FaceCount:
            if elem_length == 3:
                print('tria3mesh, not supported by z88')
                return 0
            elif elem_length == 6:
                return 24
            else:
                print('Tria with neither 3 nor 6 nodes')
                return 0
        elif femmesh.QuadrangleCount == femmesh.FaceCount:
            if elem_length == 4:
                print('quad4mesh, not supported by z88')
                return 0
            elif elem_length == 8:
                return 23
            else:
                print('Quad with neiter 4 nor 8 nodes')
                return 0
        else:
            print('no tria, no quad')
            return 0
    elif FemMeshTools.is_edge_femmesh(femmesh):
        print('Edge femmesh will be exported as 3D truss element nr 4')
        return 4
    else:
        print('Neither, edge, face or solid femmesh')
        return 0
    return 0
Beispiel #16
0
def get_z88_element_type(femmesh, femelement_table=None):
    import FemMeshTools
    if not femmesh:
        print("Error: No femmesh!")
    if not femelement_table:
        print("We need to get the femelement_table first!")
        femelement_table = FemMeshTools.get_femelement_table(femmesh)
    # in some cases lowest key in femelement_table is not [1]
    for elem in sorted(femelement_table):
        elem_length = len(femelement_table[elem])
        print(elem_length)
        break  # break after the first elem
    if FemMeshTools.is_solid_femmesh(femmesh):
        if femmesh.TetraCount == femmesh.VolumeCount:
            if elem_length == 4:
                return 17
            elif elem_length == 10:
                return 16
            else:
                print('Tetra with neiter 4 nor 10 nodes')
        elif femmesh.HexaCount == femmesh.VolumeCount:
            if elem_length == 8:
                return 1
            elif elem_length == 20:
                return 10
            else:
                print('Hexa with neither 8 nor 20 nodes')
                return 0
        else:
            print('no tetra, no hexa or Mixed Volume Elements')
    elif FemMeshTools.is_face_femmesh(femmesh):
        if femmesh.TriangleCount == femmesh.FaceCount:
            if elem_length == 3:
                print('tria3mesh, not supported by z88')
                return 0
            elif elem_length == 6:
                return 24
            else:
                print('Tria with neither 3 nor 6 nodes')
                return 0
        elif femmesh.QuadrangleCount == femmesh.FaceCount:
            if elem_length == 4:
                print('quad4mesh, not supported by z88')
                return 0
            elif elem_length == 8:
                return 23
            else:
                print('Quad with neiter 4 nor 8 nodes')
                return 0
        else:
            print('no tria, no quad')
            return 0
    elif FemMeshTools.is_edge_femmesh(femmesh):
        print('Edge femmesh will be exported as 3D truss element nr 4')
        return 4
    else:
        print('Neither, edge, face or solid femmesh')
        return 0
    return 0
Beispiel #17
0
 def get_element_geometry1D_elements(self):
     # get element ids and write them into the objects
     print("Beam sections")
     if not self.femelement_table:
         self.femelement_table = FemMeshTools.get_femelement_table(
             self.femmesh)
     FemMeshTools.get_femelement_sets(self.femmesh, self.femelement_table,
                                      self.beamsection_objects)
    def get_group_data(self):
        if self.analysis:
            print('  Group meshing.')
            self.group_elements = FemMeshTools.get_analysis_group_elements(self.analysis, self.part_obj)
            print('  {}'.format(self.group_elements))
        else:
            print('  NO group meshing.')

        self.ele_length_map = {}  # { 'ElementString' : element length }
        self.ele_node_map = {}  # { 'ElementString' : [element nodes] }
        if not self.mesh_obj.MeshRegionList:
            print ('  No Mesh regions.')
        else:
            print ('  Mesh regions, we need to get the elements.')
            if self.part_obj.Shape.ShapeType == 'Compound':
                # see http://forum.freecadweb.org/viewtopic.php?f=18&t=18780&start=40#p149467 and http://forum.freecadweb.org/viewtopic.php?f=18&t=18780&p=149520#p149520
                err = "GMSH could return unexpected meshes for a boolean split tools Compound. It is strongly recommended to extract the shape to mesh from the Compound and use this one."
                FreeCAD.Console.PrintError(err + "\n")
            for mr_obj in self.mesh_obj.MeshRegionList:
                # print(mr_obj.Name)
                # print(mr_obj.CharacteristicLength)
                # print(Units.Quantity(mr_obj.CharacteristicLength).Value)
                if mr_obj.CharacteristicLength:
                    if mr_obj.References:
                        for sub in mr_obj.References:
                            # print(sub[0])  # Part the elements belongs to
                            # check if the shape of the mesh region is an element of the Part to mesh, if not try to find the element in the shape to mesh
                            search_ele_in_shape_to_mesh = False
                            if not self.part_obj.Shape.isSame(sub[0].Shape):
                                # print("  One element of the meshregion " + mr_obj.Name + " is not an element of the Part to mesh.")
                                # print("  But we gone try to find it in the Shape to mesh :-)")
                                search_ele_in_shape_to_mesh = True
                            for eles in sub[1]:
                                # print(eles)  # element
                                if search_ele_in_shape_to_mesh:
                                    # we gone try to find the element it in the Shape to mesh and use the found element as eles
                                    ele_shape = FemMeshTools.get_element(sub[0], eles)  # the method getElement(element) does not return Solid elements
                                    found_element = FemMeshTools.find_element_in_shape(self.part_obj.Shape, ele_shape)
                                    if found_element:
                                        eles = found_element
                                    else:
                                        FreeCAD.Console.PrintError("One element of the meshregion " + mr_obj.Name + " could not be found in the Part to mesh. It will be ignored.\n")
                                # print(eles)  # element
                                if eles not in self.ele_length_map:
                                    self.ele_length_map[eles] = Units.Quantity(mr_obj.CharacteristicLength).Value
                                else:
                                    FreeCAD.Console.PrintError("The element " + eles + " of the meshregion " + mr_obj.Name + " has been added to another mesh region.\n")
                    else:
                        FreeCAD.Console.PrintError("The meshregion: " + mr_obj.Name + " is not used to create the mesh because the reference list is empty.\n")
                else:
                    FreeCAD.Console.PrintError("The meshregion: " + mr_obj.Name + " is not used to create the mesh because the CharacteristicLength is 0.0 mm.\n")
            for elel in self.ele_length_map:
                ele_shape = FemMeshTools.get_element(self.part_obj, elel)  # the method getElement(element) does not return Solid elements
                ele_vertexes = FemMeshTools.get_vertexes_by_element(self.part_obj.Shape, ele_shape)
                self.ele_node_map[elel] = ele_vertexes
        print('  {}'.format(self.ele_length_map))
        print('  {}'.format(self.ele_node_map))
Beispiel #19
0
 def get_ccx_elsets_multiple_mat_solid(self):
     if not self.femelement_table:
         self.femelement_table = FemMeshTools.get_femelement_table(self.femmesh)
     FemMeshTools.get_femelement_sets(self.femmesh, self.femelement_table, self.material_objects)
     for mat_data in self.material_objects:
         mat_obj = mat_data['Object']
         ccx_elset = {}
         ccx_elset['ccx_elset'] = mat_data['FEMElements']
         ccx_elset['ccx_elset_name'] = get_ccx_elset_solid_name(mat_obj.Name, None, mat_data['ShortName'])
         ccx_elset['mat_obj_name'] = mat_obj.Name
         ccx_elset['ccx_mat_name'] = mat_obj.Material['Name']
         self.ccx_elsets.append(ccx_elset)
 def write_constraints_transform(self, f):
     f.write('\n***********************************************************\n')
     f.write('** Transform Constaints\n')
     f.write('** written by {} function\n'.format(sys._getframe().f_code.co_name))
     for trans_object in self.transform_objects:
         trans_obj = trans_object['Object']
         if trans_obj.TransformType == "Rectangular":
             f.write('*TRANSFORM, NSET=Rect' + trans_obj.Name + ', TYPE=R\n')
             coords = FemMeshTools.get_rectangular_coords(trans_obj)
             f.write(coords + '\n')
         elif trans_obj.TransformType == "Cylindrical":
             f.write('*TRANSFORM, NSET=Cylin' + trans_obj.Name + ', TYPE=C\n')
             coords = FemMeshTools.get_cylindrical_coords(trans_obj)
             f.write(coords + '\n')
 def get_ccx_elsets_single_mat_multiple_shell(self):
     if not self.femelement_table:
         self.femelement_table = FemMeshTools.get_femelement_table(self.femmesh)
     mat_obj = self.material_objects[0]['Object']
     FemMeshTools.get_femelement_sets(self.femmesh, self.femelement_table, self.shellthickness_objects)
     for shellth_data in self.shellthickness_objects:
         shellth_obj = shellth_data['Object']
         ccx_elset = {}
         ccx_elset['shellthickness_obj'] = shellth_obj
         ccx_elset['ccx_elset'] = shellth_data['FEMElements']
         ccx_elset['ccx_elset_name'] = get_ccx_elset_shell_name(mat_obj.Name, shellth_obj.Name, None, shellth_data['ShortName'])
         ccx_elset['mat_obj_name'] = mat_obj.Name
         ccx_elset['ccx_mat_name'] = mat_obj.Material['Name']
         self.ccx_elsets.append(ccx_elset)
Beispiel #22
0
 def get_ccx_elsets_multiple_mat_single_shell(self):
     if not self.femelement_table:
         self.femelement_table = FemMeshTools.get_femelement_table(self.femmesh)
     shellth_obj = self.shellthickness_objects[0]['Object']
     FemMeshTools.get_femelement_sets(self.femmesh, self.femelement_table, self.material_objects)
     for mat_data in self.material_objects:
         mat_obj = mat_data['Object']
         ccx_elset = {}
         ccx_elset['shellthickness_obj'] = shellth_obj
         ccx_elset['ccx_elset'] = mat_data['FEMElements']
         ccx_elset['ccx_elset_name'] = get_ccx_elset_shell_name(mat_obj.Name, shellth_obj.Name, mat_data['ShortName'])
         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_single_beam(self):
     if not self.femelement_table:
         self.femelement_table = FemMeshTools.get_femelement_table(self.femmesh)
     beamsec_obj = self.beamsection_objects[0]['Object']
     FemMeshTools.get_femelement_sets(self.femmesh, self.femelement_table, self.material_objects)
     for mat_data in self.material_objects:
         mat_obj = mat_data['Object']
         ccx_elset = {}
         ccx_elset['beamsection_obj'] = beamsec_obj
         ccx_elset['ccx_elset'] = mat_data['FEMElements']
         ccx_elset['ccx_elset_name'] = get_ccx_elset_beam_name(mat_obj.Name, beamsec_obj.Name, mat_data['ShortName'])
         ccx_elset['mat_obj_name'] = mat_obj.Name
         ccx_elset['ccx_mat_name'] = mat_obj.Material['Name']
         self.ccx_elsets.append(ccx_elset)
Beispiel #24
0
 def get_constraints_fluidsection_nodes(self):
     # get nodes
     for femobj in self.fluidsection_objects:  # femobj --> dict, FreeCAD document object is femobj['Object']
         print("Constraint fluid section: " + femobj['Object'].Name)
         femobj[
             'Nodes'] = FemMeshTools.get_femnodes_by_femobj_with_references(
                 self.femmesh, femobj)
Beispiel #25
0
 def get_constraints_displacement_nodes(self):
     # get nodes
     for femobj in self.displacement_objects:  # femobj --> dict, FreeCAD document object is femobj['Object']
         femobj['Nodes'] = FemMeshTools.get_femnodes_by_references(self.femmesh, femobj['Object'].References)
         # add nodes to constraint_conflict_nodes, needed by constraint plane rotation
         for node in femobj['Nodes']:
             self.constraint_conflict_nodes.append(node)
Beispiel #26
0
    def get_constraints_pressure_faces(self):
        # TODO see comments in get_constraints_force_nodeloads(), it applies here too. Mhh it applies to all constraints ...

        # get the faces and face numbers
        for femobj in self.pressure_objects:  # femobj --> dict, FreeCAD document object is femobj['Object']
            femobj['PressureFaces'] = FemMeshTools.get_pressure_obj_faces(
                self.femmesh, femobj)
 def get_ccx_elsets_multiple_mat_solid(self):
     all_found = False
     if self.femmesh.GroupCount:
         all_found = FemMeshTools.get_femelement_sets_from_group_data(self.femmesh, self.material_objects)
         print(all_found)
     if all_found is False:
         if not self.femelement_table:
             self.femelement_table = FemMeshTools.get_femelement_table(self.femmesh)
         FemMeshTools.get_femelement_sets(self.femmesh, self.femelement_table, self.material_objects)
     for mat_data in self.material_objects:
         mat_obj = mat_data['Object']
         ccx_elset = {}
         ccx_elset['ccx_elset'] = mat_data['FEMElements']
         ccx_elset['ccx_elset_name'] = get_ccx_elset_solid_name(mat_obj.Name, None, mat_data['ShortName'])
         ccx_elset['mat_obj_name'] = mat_obj.Name
         ccx_elset['ccx_mat_name'] = mat_obj.Material['Name']
         self.ccx_elsets.append(ccx_elset)
Beispiel #28
0
def import_inp(filename):
    "create imported objects in FreeCAD, currently only FemMesh"

    m = read_inp(filename)
    mesh = FemMeshTools.make_femmesh(m)
    mesh_name = os.path.splitext(os.path.basename(filename))[0]
    mesh_object = FreeCAD.ActiveDocument.addObject('Fem::FemMeshObject', mesh_name)
    mesh_object.FemMesh = mesh
def import_z88_mesh(filename, analysis=None):
    '''insert a FreeCAD FEM Mesh object in the ActiveDocument
    '''
    mesh_data = read_z88_mesh(filename)
    mesh_name = os.path.basename(os.path.splitext(filename)[0])
    femmesh = FemMeshTools.make_femmesh(mesh_data)
    if femmesh:
        mesh_object = FreeCAD.ActiveDocument.addObject('Fem::FemMeshObject', mesh_name)
        mesh_object.FemMesh = femmesh
Beispiel #30
0
def import_inp(filename):
    "create imported objects in FreeCAD, currently only FemMesh"

    m = read_inp(filename)
    mesh = FemMeshTools.make_femmesh(m)
    mesh_name = os.path.splitext(os.path.basename(filename))[0]
    mesh_object = FreeCAD.ActiveDocument.addObject('Fem::FemMeshObject',
                                                   mesh_name)
    mesh_object.FemMesh = mesh
Beispiel #31
0
 def get_constraints_fixed_nodes(self):
     # get nodes
     for femobj in self.fixed_objects:  # femobj --> dict, FreeCAD document object is femobj['Object']
         print("Constraint fixed: " + femobj['Object'].Name)
         femobj[
             'Nodes'] = FemMeshTools.get_femnodes_by_femobj_with_references(
                 self.femmesh, femobj)
         # add nodes to constraint_conflict_nodes, needed by constraint plane rotation
         for node in femobj['Nodes']:
             self.constraint_conflict_nodes.append(node)
Beispiel #32
0
def import_z88_mesh(filename, analysis=None):
    '''insert a FreeCAD FEM Mesh object in the ActiveDocument
    '''
    mesh_data = read_z88_mesh(filename)
    mesh_name = os.path.basename(os.path.splitext(filename)[0])
    femmesh = FemMeshTools.make_femmesh(mesh_data)
    if femmesh:
        mesh_object = FreeCAD.ActiveDocument.addObject('Fem::FemMeshObject',
                                                       mesh_name)
        mesh_object.FemMesh = femmesh
Beispiel #33
0
 def get_ccx_elsets_multiple_mat_multiple_beam(self):
     if not self.femelement_table:
         self.femelement_table = FemMeshTools.get_femelement_table(self.femmesh)
     FemMeshTools.get_femelement_sets(self.femmesh, self.femelement_table, self.beamsection_objects)
     FemMeshTools.get_femelement_sets(self.femmesh, self.femelement_table, self.material_objects)
     for beamsec_data in self.beamsection_objects:
         beamsec_obj = beamsec_data['Object']
         for mat_data in self.material_objects:
             mat_obj = mat_data['Object']
             ccx_elset = {}
             ccx_elset['beamsection_obj'] = beamsec_obj
             elemids = []
             for elemid in beamsec_data['FEMElements']:
                 if elemid in mat_data['FEMElements']:
                     elemids.append(elemid)
             ccx_elset['ccx_elset'] = elemids
             ccx_elset['ccx_elset_name'] = get_ccx_elset_beam_name(mat_obj.Name, beamsec_obj.Name, mat_data['ShortName'], beamsec_data['ShortName'])
             ccx_elset['mat_obj_name'] = mat_obj.Name
             ccx_elset['ccx_mat_name'] = mat_obj.Material['Name']
             self.ccx_elsets.append(ccx_elset)
Beispiel #34
0
    def get_group_data(self):
        # TODO: solids, faces, edges and vertexes don't seem to work together in one group,
        #       some print or make them work together

        # mesh group objects
        if not self.mesh_obj.MeshGroupList:
            # print ('  No mesh group objects.')
            pass
        else:
            print('  Mesh group objects, we need to get the elements.')
            for mg in self.mesh_obj.MeshGroupList:
                new_group_elements = FemMeshTools.get_mesh_group_elements(
                    mg, self.part_obj)
                for ge in new_group_elements:
                    if ge not in self.group_elements:
                        self.group_elements[ge] = new_group_elements[ge]
                    else:
                        FreeCAD.Console.PrintError(
                            "  A group with this name exists already.\n")

        # group meshing for analysis
        analysis_group_meshing = FreeCAD.ParamGet(
            "User parameter:BaseApp/Preferences/Mod/Fem/General").GetBool(
                "AnalysisGroupMeshing", True)
        if self.analysis and analysis_group_meshing:
            print('  Group meshing for analysis.')
            self.group_nodes_export = True
            new_group_elements = FemMeshTools.get_analysis_group_elements(
                self.analysis, self.part_obj)
            for ge in new_group_elements:
                if ge not in self.group_elements:
                    self.group_elements[ge] = new_group_elements[ge]
                else:
                    FreeCAD.Console.PrintError(
                        "  A group with this name exists already.\n")
        else:
            print('  No Group meshing for analysis.')

        if self.group_elements:
            print('  {}'.format(self.group_elements))
Beispiel #35
0
 def has_equal_references_shape_types(self):
     import FemMeshTools
     if not self.references:
         self.references_shape_type = None
     for ref in self.references:
         r = FemMeshTools.get_element(ref[0], ref[1])  # the method getElement(element) does not return Solid elements
         # print('  ReferenceShape : ', r.ShapeType, ', ', ref[0].Name, ', ', ref[0].Label, ' --> ', ref[1])
         if self.references_shape_type is None:
             self.references_shape_type = r.ShapeType
         if r.ShapeType != self.references_shape_type:
             FreeCAD.Console.PrintError('Different ShapeTypes in Reference List not allowed\n')
             return False
     return True
    def get_constraints_pressure_faces(self):
        # TODO see comments in get_constraints_force_nodeloads(), it applies here too. Mhh it applies to all constraints ...

        '''
        # depreciated version
        # get the faces and face numbers
        for femobj in self.pressure_objects:  # femobj --> dict, FreeCAD document object is femobj['Object']
            femobj['PressureFaces'] = FemMeshTools.get_pressure_obj_faces_depreciated(self.femmesh, femobj)
            # print(femobj['PressureFaces'])
        '''

        if not self.femnodes_mesh:
            self.femnodes_mesh = self.femmesh.Nodes
        if not self.femelement_table:
            self.femelement_table = FemMeshTools.get_femelement_table(self.femmesh)
        if not self.femnodes_ele_table:
            self.femnodes_ele_table = FemMeshTools.get_femnodes_ele_table(self.femnodes_mesh, self.femelement_table)

        for femobj in self.pressure_objects:  # femobj --> dict, FreeCAD document object is femobj['Object']
            pressure_faces = FemMeshTools.get_pressure_obj_faces(self.femmesh, self.femelement_table, self.femnodes_ele_table, femobj)
            # print(len(pressure_faces))
            femobj['PressureFaces'] = [(femobj['Object'].Name + ': face load', pressure_faces)]
Beispiel #37
0
 def get_constraints_force_nodeloads(self):
     # check shape type of reference shape
     for femobj in self.force_objects:  # femobj --> dict, FreeCAD document object is femobj['Object']
         frc_obj = femobj['Object']
         # in GUI defined frc_obj all ref_shape have the same shape type
         # TODO in FemTools: check if all RefShapes really have the same type an write type to dictionary
         femobj['RefShapeType'] = ''
         if frc_obj.References:
             first_ref_obj = frc_obj.References[0]
             first_ref_shape = first_ref_obj[0].Shape.getElement(first_ref_obj[1][0])
             femobj['RefShapeType'] = first_ref_shape.ShapeType
         else:
             # frc_obj.References could be empty ! # TODO in FemTools: check
             FreeCAD.Console.PrintError('At least one Force Object has empty References!\n')
         if femobj['RefShapeType'] == 'Vertex':
             # print("load on vertices --> we do not need the femelement_table and femnodes_mesh for node load calculation")
             pass
         elif femobj['RefShapeType'] == 'Face' and FemMeshTools.is_solid_femmesh(self.femmesh) and not FemMeshTools.has_no_face_data(self.femmesh):
             # print("solid_mesh with face data --> we do not need the femelement_table but we need the femnodes_mesh for node load calculation")
             if not self.femnodes_mesh:
                 self.femnodes_mesh = self.femmesh.Nodes
         else:
             # print("mesh without needed data --> we need the femelement_table and femnodes_mesh for node load calculation")
             if not self.femnodes_mesh:
                 self.femnodes_mesh = self.femmesh.Nodes
             if not self.femelement_table:
                 self.femelement_table = FemMeshTools.get_femelement_table(self.femmesh)
     # get node loads
     for femobj in self.force_objects:  # femobj --> dict, FreeCAD document object is femobj['Object']
         frc_obj = femobj['Object']
         if frc_obj.Force == 0:
             print('  Warning --> Force = 0')
         if femobj['RefShapeType'] == 'Vertex':  # point load on vertieces
             femobj['NodeLoadTable'] = FemMeshTools.get_force_obj_vertex_nodeload_table(self.femmesh, frc_obj)
         elif femobj['RefShapeType'] == 'Edge':  # line load on edges
             femobj['NodeLoadTable'] = FemMeshTools.get_force_obj_edge_nodeload_table(self.femmesh, self.femelement_table, self.femnodes_mesh, frc_obj)
         elif femobj['RefShapeType'] == 'Face':  # area load on faces
             femobj['NodeLoadTable'] = FemMeshTools.get_force_obj_face_nodeload_table(self.femmesh, self.femelement_table, self.femnodes_mesh, frc_obj)
 def get_constraints_force_nodeloads(self):
     # check shape type of reference shape
     for femobj in self.force_objects:  # femobj --> dict, FreeCAD document object is femobj['Object']
         frc_obj = femobj['Object']
         # in GUI defined frc_obj all ref_shape have the same shape type
         # TODO in FemTools: check if all RefShapes really have the same type an write type to dictionary
         femobj['RefShapeType'] = ''
         if frc_obj.References:
             first_ref_obj = frc_obj.References[0]
             first_ref_shape = first_ref_obj[0].Shape.getElement(first_ref_obj[1][0])
             femobj['RefShapeType'] = first_ref_shape.ShapeType
         else:
             # frc_obj.References could be empty ! # TODO in FemTools: check
             FreeCAD.Console.PrintError('At least one Force Object has empty References!\n')
         if femobj['RefShapeType'] == 'Vertex':
             # print("load on vertices --> we do not need the femelement_table and femnodes_mesh for node load calculation")
             pass
         elif femobj['RefShapeType'] == 'Face' and FemMeshTools.is_solid_femmesh(self.femmesh) and not FemMeshTools.has_no_face_data(self.femmesh):
             # print("solid_mesh with face data --> we do not need the femelement_table but we need the femnodes_mesh for node load calculation")
             if not self.femnodes_mesh:
                 self.femnodes_mesh = self.femmesh.Nodes
         else:
             # print("mesh without needed data --> we need the femelement_table and femnodes_mesh for node load calculation")
             if not self.femnodes_mesh:
                 self.femnodes_mesh = self.femmesh.Nodes
             if not self.femelement_table:
                 self.femelement_table = FemMeshTools.get_femelement_table(self.femmesh)
     # get node loads
     for femobj in self.force_objects:  # femobj --> dict, FreeCAD document object is femobj['Object']
         frc_obj = femobj['Object']
         if frc_obj.Force == 0:
             print('  Warning --> Force = 0')
         if femobj['RefShapeType'] == 'Vertex':  # point load on vertieces
             femobj['NodeLoadTable'] = FemMeshTools.get_force_obj_vertex_nodeload_table(self.femmesh, frc_obj)
         elif femobj['RefShapeType'] == 'Edge':  # line load on edges
             femobj['NodeLoadTable'] = FemMeshTools.get_force_obj_edge_nodeload_table(self.femmesh, self.femelement_table, self.femnodes_mesh, frc_obj)
         elif femobj['RefShapeType'] == 'Face':  # area load on faces
             femobj['NodeLoadTable'] = FemMeshTools.get_force_obj_face_nodeload_table(self.femmesh, self.femelement_table, self.femnodes_mesh, frc_obj)
 def has_equal_references_shape_types(self):
     import FemMeshTools
     ref_shty = ''
     for ref in self.references:
         r = FemMeshTools.get_element(ref[0], ref[1])  # the method getElement(element) does not return Solid elements
         # print('  ReferenceShape : ', r.ShapeType, ', ', ref[0].Name, ', ', ref[0].Label, ' --> ', ref[1])
         if not ref_shty:
             ref_shty = r.ShapeType
         if r.ShapeType != ref_shty:
             message = 'Multiple shape types are not allowed in the reference list.\n'
             FreeCAD.Console.PrintError(message)
             QMessageBox.critical(None, "Multiple ShapeTypes not allowed", message)
             return False
     return True
 def has_equal_references_shape_types(self):
     import FemMeshTools
     ref_shty = ''
     for ref in self.references:
         r = FemMeshTools.get_element(ref[0], ref[1])  # the method getElement(element) does not return Solid elements
         # print('  ReferenceShape : ', r.ShapeType, ', ', ref[0].Name, ', ', ref[0].Label, ' --> ', ref[1])
         if not ref_shty:
             ref_shty = r.ShapeType
         if r.ShapeType != ref_shty:
             message = 'Multiple shape types are not allowed in the reference list.\n'
             FreeCAD.Console.PrintError(message)
             QMessageBox.critical(None, "Multiple ShapeTypes not allowed", message)
             return False
     return True
def export(objectslist, filename):
    "called when freecad exports a file"
    if len(objectslist) != 1:
        FreeCAD.Console.PrintError("This exporter can only export one object.\n")
        return
    obj = objectslist[0]
    if not obj.isDerivedFrom("Fem::FemMeshObject"):
        FreeCAD.Console.PrintError("No FEM mesh object selected.\n")
        return
    femnodes_mesh = obj.FemMesh.Nodes
    femelement_table = FemMeshTools.get_femelement_table(obj.FemMesh)
    z88_element_type = get_z88_element_type(obj.FemMesh, femelement_table)
    f = pyopen(filename, "wb")
    write_z88_mesh_to_file(femnodes_mesh, femelement_table, z88_element_type, f)
    f.close()
 def has_equal_references_shape_types(self):
     import FemMeshTools
     if not self.references:
         self.references_shape_type = None
     for ref in self.references:
         r = FemMeshTools.get_element(
             ref[0], ref[1]
         )  # the method getElement(element) does not return Solid elements
         # print('  ReferenceShape : ', r.ShapeType, ', ', ref[0].Name, ', ', ref[0].Label, ' --> ', ref[1])
         if self.references_shape_type is None:
             self.references_shape_type = r.ShapeType
         if r.ShapeType != self.references_shape_type:
             FreeCAD.Console.PrintError(
                 'Different ShapeTypes in Reference List not allowed\n')
             return False
     return True
Beispiel #43
0
 def write_z88_input(self):
     if not self.femnodes_mesh:
         self.femnodes_mesh = self.femmesh.Nodes
     if not self.femelement_table:
         self.femelement_table = FemMeshTools.get_femelement_table(self.femmesh)
         self.element_count = len(self.femelement_table)
     self.set_z88_elparam()
     self.write_z88_mesh()
     self.write_z88_contraints()
     self.write_z88_face_loads()
     self.write_z88_materials()
     self.write_z88_elements_properties()
     self.write_z88_integration_properties()
     self.write_z88_memory_parameter()
     self.write_z88_solver_parameter()
     return self.dir_name
Beispiel #44
0
 def write_z88_input(self):
     if not self.femnodes_mesh:
         self.femnodes_mesh = self.femmesh.Nodes
     if not self.femelement_table:
         self.femelement_table = FemMeshTools.get_femelement_table(self.femmesh)
         self.element_count = len(self.femelement_table)
     self.set_z88_elparam()
     self.write_z88_mesh()
     self.write_z88_contraints()
     self.write_z88_face_loads()
     self.write_z88_materials()
     self.write_z88_elements_properties()
     self.write_z88_integration_properties()
     self.write_z88_memory_parameter()
     self.write_z88_solver_parameter()
     return self.dir_name
Beispiel #45
0
def export(objectslist, filename):
    "called when freecad exports a file"
    if len(objectslist) != 1:
        FreeCAD.Console.PrintError(
            "This exporter can only export one object.\n")
        return
    obj = objectslist[0]
    if not obj.isDerivedFrom("Fem::FemMeshObject"):
        FreeCAD.Console.PrintError("No FEM mesh object selected.\n")
        return
    femnodes_mesh = obj.FemMesh.Nodes
    femelement_table = FemMeshTools.get_femelement_table(obj.FemMesh)
    z88_element_type = get_z88_element_type(obj.FemMesh, femelement_table)
    f = pyopen(filename, "wb")
    write_z88_mesh_to_file(femnodes_mesh, femelement_table, z88_element_type,
                           f)
    f.close()
Beispiel #46
0
def get_refshape_type(fem_doc_object):
    # returns the reference shape type
    # for force object:
    # in GUI defined frc_obj all frc_obj have at leas one ref_shape and ref_shape have all the same shape type
    # for material object:
    # in GUI defined material_obj could have no RefShape and RefShapes could be different type
    # we gone need the RefShapes to be the same type inside one fem_doc_object
    # TODO here: check if all RefShapes inside the object really have the same type
    import FemMeshTools
    if hasattr(fem_doc_object, 'References') and fem_doc_object.References:
        first_ref_obj = fem_doc_object.References[0]
        first_ref_shape = FemMeshTools.get_element(first_ref_obj[0], first_ref_obj[1][0])
        st = first_ref_shape.ShapeType
        print(fem_doc_object.Name + ' has ' + st + ' reference shapes.')
        return st
    else:
        print(fem_doc_object.Name + ' has empty References.')
        return ''
Beispiel #47
0
def get_refshape_type(fem_doc_object):
    # returns the reference shape type
    # for force object:
    # in GUI defined frc_obj all frc_obj have at leas one ref_shape and ref_shape have all the same shape type
    # for material object:
    # in GUI defined material_obj could have no RefShape and RefShapes could be different type
    # we're going to need the RefShapes to be the same type inside one fem_doc_object
    # TODO: check if all RefShapes inside the object really have the same type
    import FemMeshTools
    if hasattr(fem_doc_object, 'References') and fem_doc_object.References:
        first_ref_obj = fem_doc_object.References[0]
        first_ref_shape = FemMeshTools.get_element(first_ref_obj[0], first_ref_obj[1][0])
        st = first_ref_shape.ShapeType
        print(fem_doc_object.Name + ' has ' + st + ' reference shapes.')
        return st
    else:
        print(fem_doc_object.Name + ' has empty References.')
        return ''
Beispiel #48
0
 def write_node_sets_constraints_planerotation(self, f):
     # get nodes
     self.get_constraints_planerotation_nodes()
     # write nodes to file
     if not self.femnodes_mesh:
         self.femnodes_mesh = self.femmesh.Nodes
     f.write(
         '\n***********************************************************\n')
     f.write('** Node set for plane rotation constraint\n')
     f.write('** written by {} function\n'.format(
         sys._getframe().f_code.co_name))
     # info about self.constraint_conflict_nodes:
     # is used to check if MPC and constraint fixed and constraint displacement share same nodes,
     # because MPC's and constriants fixed an constraints displacement can't share same nodes.
     # thus call write_node_sets_constraints_planerotation has to be after constraint fixed and constraint displacement
     for femobj in self.planerotation_objects:  # femobj --> dict, FreeCAD document object is femobj['Object']
         l_nodes = femobj['Nodes']
         fric_obj = femobj['Object']
         f.write('*NSET,NSET=' + fric_obj.Name + '\n')
         # Code to extract nodes and coordinates on the PlaneRotation support face
         nodes_coords = []
         for node in l_nodes:
             nodes_coords.append(
                 (node, self.femnodes_mesh[node].x,
                  self.femnodes_mesh[node].y, self.femnodes_mesh[node].z))
         node_planerotation = FemMeshTools.get_three_non_colinear_nodes(
             nodes_coords)
         for i in range(len(l_nodes)):
             if l_nodes[i] not in node_planerotation:
                 node_planerotation.append(l_nodes[i])
         MPC_nodes = []
         for i in range(len(node_planerotation)):
             cnt = 0
             for j in range(len(self.constraint_conflict_nodes)):
                 if node_planerotation[i] == self.constraint_conflict_nodes[
                         j]:
                     cnt = cnt + 1
             if cnt == 0:
                 MPC = node_planerotation[i]
                 MPC_nodes.append(MPC)
         for i in range(len(MPC_nodes)):
             f.write(str(MPC_nodes[i]) + ',\n')
Beispiel #49
0
 def write_node_sets_constraints_planerotation(self, f):
     # get nodes
     self.get_constraints_planerotation_nodes()
     # write nodes to file
     if not self.femnodes_mesh:
         self.femnodes_mesh = self.femmesh.Nodes
     f.write('\n***********************************************************\n')
     f.write('** Node set for plane rotation constraint\n')
     f.write('** written by {} function\n'.format(sys._getframe().f_code.co_name))
     # info about self.constraint_conflict_nodes:
     # is used to check if MPC and constraint fixed and constraint displacement share same nodes,
     # because MPC's and constriants fixed an constraints displacement can't share same nodes.
     # thus call write_node_sets_constraints_planerotation has to be after constraint fixed and constraint displacement
     for femobj in self.planerotation_objects:  # femobj --> dict, FreeCAD document object is femobj['Object']
         l_nodes = femobj['Nodes']
         fric_obj = femobj['Object']
         f.write('*NSET,NSET=' + fric_obj.Name + '\n')
         # Code to extract nodes and coordinates on the PlaneRotation support face
         nodes_coords = []
         for node in l_nodes:
             nodes_coords.append((node, self.femnodes_mesh[node].x, self.femnodes_mesh[node].y, self.femnodes_mesh[node].z))
         node_planerotation = FemMeshTools.get_three_non_colinear_nodes(nodes_coords)
         for i in range(len(l_nodes)):
             if l_nodes[i] not in node_planerotation:
                 node_planerotation.append(l_nodes[i])
         MPC_nodes = []
         for i in range(len(node_planerotation)):
             cnt = 0
             for j in range(len(self.constraint_conflict_nodes)):
                 if node_planerotation[i] == self.constraint_conflict_nodes[j]:
                     cnt = cnt + 1
             if cnt == 0:
                 MPC = node_planerotation[i]
                 MPC_nodes.append(MPC)
         for i in range(len(MPC_nodes)):
             f.write(str(MPC_nodes[i]) + ',\n')
Beispiel #50
0
 def get_constraints_force_nodeloads(self):
     # check shape type of reference shape
     for femobj in self.force_objects:  # femobj --> dict, FreeCAD document object is femobj['Object']
         print("Constraint force: " + femobj['Object'].Name)
         frc_obj = femobj['Object']
         if femobj['RefShapeType'] == 'Vertex':
             # print("load on vertices --> we do not need the femelement_table and femnodes_mesh for node load calculation")
             pass
         elif femobj[
                 'RefShapeType'] == 'Face' and FemMeshTools.is_solid_femmesh(
                     self.femmesh) and not FemMeshTools.has_no_face_data(
                         self.femmesh):
             # print("solid_mesh with face data --> we do not need the femelement_table but we need the femnodes_mesh for node load calculation")
             if not self.femnodes_mesh:
                 self.femnodes_mesh = self.femmesh.Nodes
         else:
             # print("mesh without needed data --> we need the femelement_table and femnodes_mesh for node load calculation")
             if not self.femnodes_mesh:
                 self.femnodes_mesh = self.femmesh.Nodes
             if not self.femelement_table:
                 self.femelement_table = FemMeshTools.get_femelement_table(
                     self.femmesh)
     # get node loads
     for femobj in self.force_objects:  # femobj --> dict, FreeCAD document object is femobj['Object']
         frc_obj = femobj['Object']
         if frc_obj.Force == 0:
             print('  Warning --> Force = 0')
         if femobj['RefShapeType'] == 'Vertex':  # point load on vertieces
             femobj[
                 'NodeLoadTable'] = FemMeshTools.get_force_obj_vertex_nodeload_table(
                     self.femmesh, frc_obj)
         elif femobj['RefShapeType'] == 'Edge':  # line load on edges
             femobj[
                 'NodeLoadTable'] = FemMeshTools.get_force_obj_edge_nodeload_table(
                     self.femmesh, self.femelement_table,
                     self.femnodes_mesh, frc_obj)
         elif femobj['RefShapeType'] == 'Face':  # area load on faces
             femobj[
                 'NodeLoadTable'] = FemMeshTools.get_force_obj_face_nodeload_table(
                     self.femmesh, self.femelement_table,
                     self.femnodes_mesh, frc_obj)
Beispiel #51
0
def importFrd(filename, analysis=None):
    m = readResult(filename)
    mesh_object = None
    if(len(m['Nodes']) > 0):
        if analysis is None:
            analysis_name = os.path.splitext(os.path.basename(filename))[0]
            import FemAnalysis
            analysis_object = FemAnalysis.makeFemAnalysis('Analysis')
            analysis_object.Label = analysis_name
        else:
            analysis_object = analysis  # see if statement few lines later, if not analysis -> no FemMesh object is created !

        if 'Nodes' in m:
            positions = []
            for k, v in m['Nodes'].iteritems():
                positions.append(v)
            p_x_max, p_y_max, p_z_max = map(max, zip(*positions))
            p_x_min, p_y_min, p_z_min = map(min, zip(*positions))

            x_span = abs(p_x_max - p_x_min)
            y_span = abs(p_y_max - p_y_min)
            z_span = abs(p_z_max - p_z_min)
            span = max(x_span, y_span, z_span)

        if (not analysis):
            import FemMeshTools
            mesh = FemMeshTools.make_femmesh(m)

            if len(m['Nodes']) > 0:
                mesh_object = FreeCAD.ActiveDocument.addObject('Fem::FemMeshObject', 'ResultMesh')
                mesh_object.FemMesh = mesh
                analysis_object.Member = analysis_object.Member + [mesh_object]

        for result_set in m['Results']:
            eigenmode_number = result_set['number']
            if eigenmode_number > 0:
                results_name = 'Mode_' + str(eigenmode_number) + '_results'
            else:
                results_name = 'Results'
            results = FreeCAD.ActiveDocument.addObject('Fem::FemResultObject', results_name)
            for m in analysis_object.Member:
                if m.isDerivedFrom("Fem::FemMeshObject"):
                    results.Mesh = m
                    break

            disp = result_set['disp']
            l = len(disp)
            displacement = []
            for k, v in disp.iteritems():
                displacement.append(v)

            x_max, y_max, z_max = map(max, zip(*displacement))
            if eigenmode_number > 0:
                max_disp = max(x_max, y_max, z_max)
                # Allow for max displacement to be 0.1% of the span
                # FIXME - add to Preferences
                max_allowed_disp = 0.001 * span
                scale = max_allowed_disp / max_disp
            else:
                scale = 1.0

            if len(disp) > 0:
                results.DisplacementVectors = map((lambda x: x * scale), disp.values())
                results.NodeNumbers = disp.keys()
                if(mesh_object):
                    results.Mesh = mesh_object

            stress = result_set['stress']
            if len(stress) > 0:
                mstress = []
                for i in stress.values():
                    mstress.append(calculate_von_mises(i))
                if eigenmode_number > 0:
                    results.StressValues = map((lambda x: x * scale), mstress)
                    results.Eigenmode = eigenmode_number
                else:
                    results.StressValues = mstress

            if (results.NodeNumbers != 0 and results.NodeNumbers != stress.keys()):
                print("Inconsistent FEM results: element number for Stress doesn't equal element number for Displacement {} != {}"
                      .format(results.NodeNumbers, len(results.StressValues)))
                results.NodeNumbers = stress.keys()

            x_min, y_min, z_min = map(min, zip(*displacement))
            sum_list = map(sum, zip(*displacement))
            x_avg, y_avg, z_avg = [i / l for i in sum_list]

            s_max = max(results.StressValues)
            s_min = min(results.StressValues)
            s_avg = sum(results.StressValues) / l

            disp_abs = []
            for d in displacement:
                disp_abs.append(sqrt(pow(d[0], 2) + pow(d[1], 2) + pow(d[2], 2)))
            results.DisplacementLengths = disp_abs

            a_max = max(disp_abs)
            a_min = min(disp_abs)
            a_avg = sum(disp_abs) / l

            results.Stats = [x_min, x_avg, x_max,
                             y_min, y_avg, y_max,
                             z_min, z_avg, z_max,
                             a_min, a_avg, a_max,
                             s_min, s_avg, s_max]
            analysis_object.Member = analysis_object.Member + [results]

        if(FreeCAD.GuiUp):
            import FemGui
            FemGui.setActiveAnalysis(analysis_object)
 def get_constraints_displacement_nodes(self):
     # get nodes
     for femobj in self.displacement_objects:  # femobj --> dict, FreeCAD document object is femobj['Object']
         femobj['Nodes'] = FemMeshTools.get_femnodes_by_references(self.femmesh, femobj['Object'].References)
Beispiel #53
0
 def get_constraints_temperature_nodes(self):
     # get nodes
     for femobj in self.temperature_objects:  # femobj --> dict, FreeCAD document object is femobj['Object']
         femobj['Nodes'] = FemMeshTools.get_femnodes_by_femobj_with_references(self.femmesh, femobj)
Beispiel #54
0
    def get_boundary_layer_data(self):
        # mesh boundary layer,
        # currently only one boundary layer setting object is allowed, but multiple boundary can be selected
        # Mesh.CharacteristicLengthMin, must be zero, or a value less than first inflation layer height
        self.bl_setting_list = []  # list of dict, each item map to MeshBoundaryLayer object
        self.bl_boundary_list = []  # to remove duplicated boundary edge or faces

        if not self.mesh_obj.MeshBoundaryLayerList:
            print ('  No mesh boundary layer setting document object.')
        else:
            print ('  Mesh boundary layers, we need to get the elements.')
            if self.part_obj.Shape.ShapeType == 'Compound':
                # see http://forum.freecadweb.org/viewtopic.php?f=18&t=18780&start=40#p149467 and http://forum.freecadweb.org/viewtopic.php?f=18&t=18780&p=149520#p149520
                err = "GMSH could return unexpected meshes for a boolean split tools Compound. It is strongly recommended to extract the shape to mesh from the Compound and use this one."
                FreeCAD.Console.PrintError(err + "\n")
            for mr_obj in self.mesh_obj.MeshBoundaryLayerList:
                if mr_obj.MinimumThickness and Units.Quantity(mr_obj.MinimumThickness).Value > 0:
                    if mr_obj.References:
                        belem_list = []
                        for sub in mr_obj.References:
                            # print(sub[0])  # Part the elements belongs to
                            # check if the shape of the mesh boundary_layer is an element of the Part to mesh, if not try to find the element in the shape to mesh
                            search_ele_in_shape_to_mesh = False
                            if not self.part_obj.Shape.isSame(sub[0].Shape):
                                # print("  One element of the mesh boundary layer " + mr_obj.Name + " is not an element of the Part to mesh.")
                                # print("  But we going to find it in the Shape to mesh :-)")
                                search_ele_in_shape_to_mesh = True
                            for elems in sub[1]:
                                # print(elems)  # elems --> element
                                if search_ele_in_shape_to_mesh:
                                    # we try to find the element it in the Shape to mesh and use the found element as elems
                                    ele_shape = FemMeshTools.get_element(sub[0], elems)  # the method getElement(element) does not return Solid elements
                                    found_element = FemMeshTools.find_element_in_shape(self.part_obj.Shape, ele_shape)
                                    if found_element:  # also
                                        elems = found_element
                                    else:
                                        FreeCAD.Console.PrintError("One element of the mesh boudary layer " + mr_obj.Name + " could not be found in the Part to mesh. It will be ignored.\n")
                                # print(elems)  # element
                                if elems not in self.bl_boundary_list:
                                    # fetch settings in DocumentObject, fan setting is not implemented
                                    belem_list.append(elems)
                                    self.bl_boundary_list.append(elems)
                                else:
                                    FreeCAD.Console.PrintError("The element " + elems + " of the mesh boundary layer " + mr_obj.Name + " has been added to another mesh  boudary layer.\n")
                        setting = {}
                        setting['hwall_n'] = Units.Quantity(mr_obj.MinimumThickness).Value
                        setting['ratio'] = mr_obj.GrowthRate
                        setting['thickness'] = sum([setting['hwall_n'] * setting['ratio'] ** i for i in range(mr_obj.NumberOfLayers)])
                        setting['hwall_t'] = setting['thickness']  # setting['hwall_n'] * 5 # tangetial cell dimension

                        # hfar: cell dimension outside boundary should be set later if some character length is set
                        if self.clmax > setting['thickness'] * 0.8 and self.clmax < setting['thickness'] * 1.6:
                            setting['hfar'] = self.clmax
                        else:
                            setting['hfar'] = setting['thickness']  # set a value for safety, it may works as background mesh cell size
                        # from face name -> face id is done in geo file write up
                        #fan angle setup is not implemented yet
                        if self.dimension == '2':
                            setting['EdgesList'] = belem_list
                        elif self.dimension == '3':
                            setting['FacesList'] = belem_list
                        else:
                            FreeCAD.Console.PrintError("boundary layer is only  supported for 2D and 3D mesh")
                        self.bl_setting_list.append(setting)
                    else:
                        FreeCAD.Console.PrintError("The mesh boundary layer: " + mr_obj.Name + " is not used to create the mesh because the reference list is empty.\n")
                else:
                    FreeCAD.Console.PrintError("The mesh boundary layer: " + mr_obj.Name + " is not used to create the mesh because the min thickness is 0.0 mm.\n")
        print('  {}'.format(self.bl_setting_list))
Beispiel #55
0
    def get_constraints_pressure_faces(self):
        # TODO see comments in get_constraints_force_nodeloads(), it applies here too. Mhh it applies to all constraints ...

        # get the faces and face numbers
        for femobj in self.pressure_objects:  # femobj --> dict, FreeCAD document object is femobj['Object']
            femobj['PressureFaces'] = FemMeshTools.get_pressure_obj_faces(self.femmesh, femobj)