From 9154825889c5a99aeb1b7167bd11d03d277ffd4a Mon Sep 17 00:00:00 2001 From: Bernd Hahnebach Date: Mon, 28 Nov 2016 01:18:08 +0100 Subject: [PATCH] FEM: gmsh mesh tool, add different mesh element size for Shape elements --- src/Mod/Fem/FemGmshTools.py | 27 ++++++++++++++++++++++- src/Mod/Fem/FemMeshTools.py | 43 +++++++++++++++++++++++++++++++++++++ src/Mod/Fem/_FemMeshGmsh.py | 2 ++ 3 files changed, 71 insertions(+), 1 deletion(-) diff --git a/src/Mod/Fem/FemGmshTools.py b/src/Mod/Fem/FemGmshTools.py index 8257a08f8..22b3aef95 100644 --- a/src/Mod/Fem/FemGmshTools.py +++ b/src/Mod/Fem/FemGmshTools.py @@ -223,6 +223,23 @@ class FemGmshTools(): 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) def write_part_file(self): self.part_obj.Shape.exportBrep(self.temp_file_geometry) @@ -232,7 +249,7 @@ class FemGmshTools(): geo.write('Merge "' + self.temp_file_geometry + '";\n') geo.write("\n") if self.analysis and self.group_elements: - print(' We gone have found elements to make mesh groups for!') + print(' We gone have found elements to make mesh groups for.') geo.write("// group data\n") # we use the element name of FreeCAD which starts with 1 (example: 'Face1'), same as GMSH for group in self.group_elements: @@ -256,6 +273,14 @@ class FemGmshTools(): # print(ele_nr) geo.write('Physical ' + physical_type + '("' + group + '") = {' + ele_nr + '};\n') geo.write("\n") + if self.ele_length_map: + # we use the index FreeCAD which starts with 0, we need to add 1 for the index in GMSH + geo.write("// Characteristic Length according CharacteristicLengthMap\n") + for e in self.ele_length_map: + ele_nodes = (''.join((str(n + 1) + ', ') for n in self.ele_node_map[e])).rstrip(', ') + geo.write("// " + e + "\n") + geo.write("Characteristic Length { " + ele_nodes + " } = " + self.ele_length_map[e] + ";\n") + geo.write("\n") geo.write("Mesh.CharacteristicLengthMax = " + str(self.clmax) + ";\n") geo.write("Mesh.CharacteristicLengthMin = " + str(self.clmin) + ";\n") geo.write("Mesh.ElementOrder = " + self.order + ";\n") diff --git a/src/Mod/Fem/FemMeshTools.py b/src/Mod/Fem/FemMeshTools.py index 42ace7d64..25141ccab 100644 --- a/src/Mod/Fem/FemMeshTools.py +++ b/src/Mod/Fem/FemMeshTools.py @@ -1162,6 +1162,49 @@ def find_element_in_shape(aShape, anElement): FreeCAD.Console.PrintError('Compound is not supported.\n') +def get_vertexes_by_element(aShape, anElement): + # we gone extent the method find_element_in_shape and return the vertexes + # import Part + ele_vertexes = [] + ele_st = anElement.ShapeType + if ele_st == 'Solid' or ele_st == 'CompSolid': + for index, solid in enumerate(aShape.Solids): + if is_same_geometry(solid, anElement): + for vele in aShape.Solids[index].Vertexes: + for i, v in enumerate(aShape.Vertexes): + if vele.isSame(v): # use isSame, because orientation could be different + ele_vertexes.append(i) + # print(' ' + str(sorted(ele_vertexes))) + return ele_vertexes + FreeCAD.Console.PrintError('Error, Solid ' + str(anElement) + ' not found in: ' + str(aShape) + '\n') + elif ele_st == 'Face' or ele_st == 'Shell': + for index, face in enumerate(aShape.Faces): + if is_same_geometry(face, anElement): + for vele in aShape.Faces[index].Vertexes: + for i, v in enumerate(aShape.Vertexes): + if vele.isSame(v): # use isSame, because orientation could be different + ele_vertexes.append(i) + # print(' ' + str(sorted(ele_vertexes))) + return ele_vertexes + elif ele_st == 'Edge' or ele_st == 'Wire': + for index, edge in enumerate(aShape.Edges): + if is_same_geometry(edge, anElement): + for vele in aShape.Edges[index].Vertexes: + for i, v in enumerate(aShape.Vertexes): + if vele.isSame(v): # use isSame, because orientation could be different + ele_vertexes.append(i) + # print(' ' + str(sorted(ele_vertexes))) + return ele_vertexes + elif ele_st == 'Vertex': + for index, vertex in enumerate(aShape.Vertexes): + if is_same_geometry(vertex, anElement): + ele_vertexes.append(index) + # print(' ' + str(sorted(ele_vertexes))) + return ele_vertexes + elif ele_st == 'Compound': + FreeCAD.Console.PrintError('Compound is not supported.\n') + + def is_same_geometry(shape1, shape2): # the vertexes and the CenterOfMass are compared # it is a hack, but I do not know any better ! diff --git a/src/Mod/Fem/_FemMeshGmsh.py b/src/Mod/Fem/_FemMeshGmsh.py index 978749c9e..5cfe46711 100644 --- a/src/Mod/Fem/_FemMeshGmsh.py +++ b/src/Mod/Fem/_FemMeshGmsh.py @@ -80,6 +80,8 @@ class _FemMeshGmsh(): obj.Algorithm3D = _FemMeshGmsh.known_mesh_algorithm_3D obj.Algorithm3D = 'Automatic' # ? + obj.addProperty("App::PropertyMap", "CharacteristicLengthMap", "FEM GMSH Mesh Params", "Map of CharacteristicLength of Shape elements") + def execute(self, obj): return