示例#1
0
    def get_region_data(self):
        """ Mesh regions """
        self.ele_length_map = {}  # { 'mrNameString' : element length }
        self.ele_refinethick_map = {
        }  # { 'mrNameString' : refinement thickness }
        self.ele_firstlayerheight_map = {
        }  # { 'mrNameString' : first layer height }
        self.ele_numlayer_map = {}  # { 'mrNameString' : number of layers }
        self.ele_expratio_map = {}  # { 'mrNameString' : expansion ratio }
        self.snappyMeshRegions = {}
        from collections import defaultdict
        self.ele_meshpatch_map = defaultdict(list)
        if not self.mesh_obj.MeshRegionList:
            print('  No mesh regions.')
        else:
            print('  Mesh regions, we need to get the elements.')
            if "Boolean" in self.part_obj.Name:
                err = "Cartesian meshes should not be generated for boolean split compounds."
                FreeCAD.Console.PrintError(err + "\n")
            for mr_obj in self.mesh_obj.MeshRegionList:
                if mr_obj.RelativeLength:
                    if mr_obj.References:
                        # Store parameters per region
                        mr_rellen = mr_obj.RelativeLength
                        if mr_rellen > 1.0:
                            mr_rellen = 1.0
                            FreeCAD.Console.PrintError(
                                "The meshregion: " + mr_obj.Name +
                                " should not use a relative length greater than unity.\n"
                            )
                        elif mr_rellen < 0.01:
                            mr_rellen = 0.01  # Relative length should not be less than 1/100 of base length
                            FreeCAD.Console.PrintError(
                                "The meshregion: " + mr_obj.Name +
                                " should not use a relative length smaller than 0.01.\n"
                            )

                        self.ele_length_map[
                            mr_obj.Name] = mr_rellen * self.clmax * self.scale
                        self.ele_refinethick_map[mr_obj.Name] = self.scale*Units.Quantity\
                            (mr_obj.RefinementThickness).Value
                        self.ele_numlayer_map[
                            mr_obj.Name] = mr_obj.NumberLayers
                        self.ele_expratio_map[
                            mr_obj.Name] = mr_obj.ExpansionRatio
                        self.ele_firstlayerheight_map[mr_obj.Name] = self.scale*Units.Quantity\
                            (mr_obj.FirstLayerHeight).Value

                        # STL containing the faces in the reference list
                        # For long and many reasons related to snappy and baffles we cannot
                        # use multi-region .stl for creating baffles. Therefore exporting each
                        # mesh region face as an independent .stl surface. To not confuse cfMesh behaviour
                        # leaving cfMesh as is.
                        if self.mesh_obj.MeshUtility == "cfMesh":
                            f = open(
                                os.path.join(self.triSurfaceDir,
                                             mr_obj.Name + '.stl'), 'w')
                            #f.write("solid {}\n".format(mr_obj.Name))

                        mr_obj.Name
                        snappyTemp = []
                        subC = -1
                        for sub in mr_obj.References:
                            subC += 1
                            # print(sub[0])  # Part the elements belongs to
                            elems_list = []
                            elemC = -1
                            for elems in sub[1]:
                                elemC += 1
                                # print(elems)  # elems --> element
                                if not elems in elems_list:
                                    elt = sub[0].Shape.getElement(elems)
                                    if elt.ShapeType == 'Face':
                                        facemesh = MeshPart.meshFromShape(
                                            elt,
                                            LinearDeflection=self.mesh_obj.
                                            STLLinearDeflection)
                                        # Write separate stls allowing for individual baffle definition
                                        if self.mesh_obj.MeshUtility == "snappyHexMesh":
                                            f = open(
                                                os.path.join(
                                                    self.triSurfaceDir,
                                                    mr_obj.Name + sub[0].Name +
                                                    elems + '.stl'), 'w')
                                            snappyTemp.append(mr_obj.Name +
                                                              sub[0].Name +
                                                              elems)
                                        f.write(
                                            "solid {}\n".format(mr_obj.Name +
                                                                "Sub" +
                                                                str(subC) +
                                                                "Elem" +
                                                                str(elemC)))
                                        for face in facemesh.Facets:
                                            f.write(" facet normal 0 0 0\n")
                                            f.write("  outer loop\n")
                                            for i in range(3):
                                                p = face.Points[i]
                                                f.write("    vertex {} {} {}".
                                                        format(
                                                            self.scale * p[0],
                                                            self.scale * p[1],
                                                            self.scale * p[2]))
                                                f.write("\n")
                                            f.write("  endloop\n")
                                            f.write(" endfacet\n")
                                        f.write("endsolid {}\n".format(
                                            mr_obj.Name + "Sub" + str(subC) +
                                            "Elem" + str(elemC)))

                                        # Similarity search for patch used in boundary layer meshing
                                        meshFaceList = self.mesh_obj.Part.Shape.Faces
                                        for (i, mf) in enumerate(meshFaceList):
                                            import FemMeshTools
                                            isSameGeo = FemMeshTools.is_same_geometry(
                                                elt, mf)
                                            if isSameGeo:  # Only one matching face
                                                sfN = self.mesh_obj.ShapeFaceNames[
                                                    i]
                                                self.ele_meshpatch_map[
                                                    mr_obj.Name].append(sfN)
                                        if self.mesh_obj.MeshUtility == "snappyHexMesh":
                                            f.close()
                                    else:
                                        FreeCAD.Console.PrintError(
                                            "Cartesian meshes only support surface refinement.\n"
                                        )
                                else:
                                    FreeCAD.Console.PrintError(
                                        "The element {} has already been added.\n"
                                    )
                        #f.write("endsolid {}\n".format(mr_obj.Name))
                        if self.mesh_obj.MeshUtility == "cfMesh":
                            f.close()
                        if self.mesh_obj.MeshUtility == "snappyHexMesh":
                            self.snappyMeshRegions[mr_obj.Name] = snappyTemp
                    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")
        print('  {}'.format(self.ele_length_map))
示例#2
0
    def setupPatchNames(self):
        print('Populating createPatchDict to update BC names')
        settings = self.settings
        settings['createPatches'] = {}
        bc_group = self.bc_group
        mobj = self.mesh_obj
        bc_allocated = []
        for bc_id, bc_obj in enumerate(bc_group):
            bc_list = []
            meshFaceList = mobj.Part.Shape.Faces
            for (i, mf) in enumerate(meshFaceList):
                bcFacesList = bc_obj.Shape.Faces
                for bf in bcFacesList:
                    isSameGeo = CfdTools.isSameGeometry(bf, mf)
                    if isSameGeo:
                        bc_list.append(mobj.ShapeFaceNames[i])
                        if mobj.ShapeFaceNames[i] in bc_allocated:
                            print('Error: {} has been assigned twice'.format(
                                mobj.ShapeFaceNames[i]))
                        else:
                            bc_allocated.append(mobj.ShapeFaceNames[i])

            bcDict = bc_obj.BoundarySettings
            bcType = bcDict["BoundaryType"]
            bcSubType = bcDict["BoundarySubtype"]
            patchType = CfdTools.getPatchType(bcType, bcSubType)
            settings['createPatches'][bc_obj.Label] = {
                'PatchNamesList': bc_list,
                'PatchType': patchType
            }

            # In almost all cases the number of faces associated with a bc is going to be less than the number of
            # external or mesh faces.
            # if not (len(bc_list) == len(meshFaceList)):
            #     raise Exception('Mismatch between boundary faces and mesh faces')

        if self.mesh_obj.MeshRegionList:
            for regionObj in self.mesh_obj.MeshRegionList:
                #if regionObj.snappedRefine:
                if regionObj.internalBaffle:
                    settings['createPatchesFromSnappyBaffles'] = True

        if settings['createPatchesFromSnappyBaffles']:
            settings['createPatchesSnappyBaffles'] = {}
            # TODO Still need to include an error checker in the event that
            # an internal baffle is created using snappy but is not linked up
            # with a baffle boundary condition (as in there is no baffle boundary condition which
            # corresponds. Currently openfoam will throw a contextually
            # confusing error (only that the boundary does not exist). The primary difficulty with such a checker is
            # that it is possible to define a boundary face as a baffle, which will be overriden
            # by the actual boundary name and therefore won't exist anymore.
            for bc_id, bc_obj in enumerate(bc_group):
                bcDict = bc_obj.BoundarySettings
                bcType = bcDict["BoundaryType"]
                if bcType == "baffle":
                    tempBaffleList = []
                    tempBaffleListSlave = []
                    if self.mesh_obj.MeshRegionList:
                        for regionObj in self.mesh_obj.MeshRegionList:
                            print regionObj.Name
                            if regionObj.internalBaffle:
                                for sub in regionObj.References:
                                    print sub[0].Name
                                    for elems in sub[1]:
                                        elt = sub[0].Shape.getElement(elems)
                                        if elt.ShapeType == 'Face':
                                            #isSameGeo = FemMeshTools.is_same_geometry(bf, mf)
                                            bcFacesList = bc_obj.Shape.Faces
                                            for bf in bcFacesList:
                                                import FemMeshTools
                                                isSameGeo = FemMeshTools.is_same_geometry(
                                                    bf, elt)
                                                if isSameGeo:
                                                    tempBaffleList.append(
                                                        regionObj.Name +
                                                        sub[0].Name + elems)
                                                    tempBaffleListSlave.append(
                                                        regionObj.Name +
                                                        sub[0].Name + elems +
                                                        "_slave")
                    settings['createPatchesSnappyBaffles'][bc_obj.Label] = {
                        "PatchNamesList": tempBaffleList,
                        "PatchNamesListSlave": tempBaffleListSlave
                    }

        # Add default faces
        flagName = False
        def_bc_list = []
        for name in mobj.ShapeFaceNames:
            if not name in bc_allocated:
                def_bc_list.append(name)
                flagName = True
        if flagName:
            settings['createPatches']['defaultFaces'] = {
                'PatchNamesList': def_bc_list,
                'PatchType': "patch"
            }