コード例 #1
0
ファイル: CfdSolverFoam.py プロジェクト: kliberty/CfdOF
 def doubleClicked(self, vobj):
     if FreeCADGui.activeWorkbench().name() != 'CfdOFWorkbench':
         FreeCADGui.activateWorkbench("CfdOFWorkbench")
     doc = FreeCADGui.getDocument(vobj.Object.Document)
     # it should be possible to find the AnalysisObject although it is not a documentObjectGroup
     if not CfdTools.getActiveAnalysis():
         analysis_obj = CfdTools.getParentAnalysisObject(self.Object)
         if analysis_obj:
             CfdTools.setActiveAnalysis(analysis_obj)
         else:
             FreeCAD.Console.PrintError(
                 'No Active Analysis is detected from solver object in the active Document!\n'
             )
     if not doc.getInEdit():
         if CfdTools.getActiveAnalysis().Document is FreeCAD.ActiveDocument:
             if self.Object in CfdTools.getActiveAnalysis().Group:
                 doc.setEdit(vobj.Object.Name)
             else:
                 FreeCAD.Console.PrintError(
                     'Activate the analysis this solver belongs to!\n')
         else:
             FreeCAD.Console.PrintError(
                 'Active Analysis is not in active Document!\n')
     else:
         FreeCAD.Console.PrintError('Task dialog already open\n')
     return True
コード例 #2
0
ファイル: CfdMesh.py プロジェクト: wkangholy/CfdOF
 def Activated(self):
     FreeCAD.ActiveDocument.openTransaction("Create CFD mesh")
     analysis_obj = CfdTools.getActiveAnalysis()
     if analysis_obj:
         meshObj = CfdTools.getMesh(analysis_obj)
         if not meshObj:
             sel = FreeCADGui.Selection.getSelection()
             if len(sel) == 1:
                 if sel[0].isDerivedFrom("Part::Feature"):
                     mesh_obj_name = sel[0].Name + "_Mesh"
                     FreeCADGui.doCommand("")
                     FreeCADGui.addModule("CfdMesh")
                     FreeCADGui.doCommand("CfdMesh.makeCfdMesh('" +
                                          mesh_obj_name + "')")
                     FreeCADGui.doCommand(
                         "App.ActiveDocument.ActiveObject.Part = App.ActiveDocument."
                         + sel[0].Name)
                     if CfdTools.getActiveAnalysis():
                         FreeCADGui.addModule("CfdTools")
                         FreeCADGui.doCommand(
                             "CfdTools.getActiveAnalysis().addObject(App.ActiveDocument.ActiveObject)"
                         )
                     FreeCADGui.ActiveDocument.setEdit(
                         FreeCAD.ActiveDocument.ActiveObject.Name)
     else:
         print("ERROR: You cannot have more than one mesh object")
     FreeCADGui.Selection.clearSelection()
コード例 #3
0
ファイル: CfdSolverFoam.py プロジェクト: kliberty/CfdOF
    def setEdit(self, vobj, mode):
        if CfdTools.getActiveAnalysis():
            from CfdRunnableFoam import CfdRunnableFoam
            foamRunnable = CfdRunnableFoam(CfdTools.getActiveAnalysis(),
                                           self.Object)
            from _TaskPanelCfdSolverControl import _TaskPanelCfdSolverControl
            taskd = _TaskPanelCfdSolverControl(foamRunnable)
            taskd.obj = vobj.Object

            FreeCADGui.Control.showDialog(taskd)
        return True
コード例 #4
0
    def Activated(self):
        filters = u"IDES mesh (*.unv);;Med mesh(*.med);;VTK mesh (*.vtk *.vtu)"
        mesh_file = QFileDialog.getOpenFileName(None, u"Open mesh files",
                                                u"./", filters)
        mesh_file = mesh_file[0]
        # why return a tuple of filename and selectedfilter

        import CfdTools
        if not CfdTools.getActiveAnalysis():
            CfdTools.createAnalysis()

        FreeCADGui.addModule("CfdTools")
        sel = FreeCADGui.Selection.getSelection()
        if (len(sel) == 1) and (sel[0].isDerivedFrom("Part::Feature")):
            # using existing part_feature, no need to import geometry, but get obj as link
            geo_obj = sel[0]
            CfdTools.importGeometryAndMesh(
                geo_obj, mesh_file)  #Todo: macro recording is yet support
        else:
            filters = u"BREP (*.brep *.brp);;STEP (*.step *.stp);;IGES (*.iges *.igs);; FcStd (*.fcstd)"
            geo_file = QFileDialog.getOpenFileName(None,
                                                   u"Open geometry files",
                                                   u"./", filters)
            geo_file = geo_file[0]
            FreeCADGui.doCommand(
                "CfdTools.importGeometryAndMesh(u'{}', u'{}')".format(
                    geo_file, mesh_file))
        FreeCADGui.Selection.clearSelection()

        FreeCADGui.addModule("FemGui")
        #if FemGui.getActiveAnalysis():  # besides addModule, FemGui need to be imported
        FreeCADGui.doCommand(
            "FemGui.getActiveAnalysis().addObject(App.ActiveDocument.ActiveObject)"
        )
コード例 #5
0
 def doubleClicked(self, vobj):
     if not CfdTools.getActiveAnalysis() == self.Object:
         if FreeCADGui.activeWorkbench().name() != 'CfdOFWorkbench':
             FreeCADGui.activateWorkbench("CfdOFWorkbench")
         CfdTools.setActiveAnalysis(self.Object)
         return True
     return True
コード例 #6
0
 def doubleClicked(self, vobj):
     if FreeCADGui.activeWorkbench().name() != 'CfdWorkbench':
         FreeCADGui.activateWorkbench("CfdWorkbench")
     doc = FreeCADGui.getDocument(vobj.Object.Document)
     # it should be possible to find the AnalysisObject although it is not a documentObjectGroup
     if not FemGui.getActiveAnalysis():
         analysis_obj = CfdTools.getActiveAnalysis(self.Object)
         if analysis_obj:
             FemGui.setActiveAnalysis(analysis_obj)
         else:
             FreeCAD.Console.PrintError(
                 'No Active Analysis is detected from solver object in the active Document!\n'
             )
     if not doc.getInEdit():
         if FemGui.getActiveAnalysis().Document is FreeCAD.ActiveDocument:
             if self.Object in FemGui.getActiveAnalysis().Member:
                 doc.setEdit(vobj.Object.Name)
             else:
                 FreeCAD.Console.PrintError(
                     'Activate the analysis this solver belongs to!\n')
         else:
             FreeCAD.Console.PrintError(
                 'Active Analysis is not in active Document!\n')
     else:
         FreeCAD.Console.PrintError(
             'Active Task Dialog found! Please close this one first!\n')
     return True
コード例 #7
0
 def getMeshObject(self):
     analysis_obj = CfdTools.getActiveAnalysis()
     mesh_obj = CfdTools.getMeshObject(analysis_obj)
     if mesh_obj is None:
         message = "Mesh object not found - please re-create."
         QtGui.QMessageBox.critical(None, 'Missing mesh object', message)
         doc = FreeCADGui.getDocument(self.obj.Document)
         doc.resetEdit()
     return mesh_obj
コード例 #8
0
 def doubleClicked(self, vobj):
     doc = FreeCADGui.getDocument(vobj.Object.Document)
     if not CfdTools.getActiveAnalysis():
         analysis_obj = CfdTools.getParentAnalysisObject(self.Object)
         if analysis_obj:
             CfdTools.setActiveAnalysis(analysis_obj)
         else:
             CfdTools.cfdError('No parent analysis object detected')
     if not doc.getInEdit():
         doc.setEdit(vobj.Object.Name)
     else:
         FreeCAD.Console.PrintError('Active Task Dialog found! Please close this one first!\n')
     return True
コード例 #9
0
    def Activated(self):
        # Todo: a dialog could be used to replace the content of this, adding length unit scaling
        if not CfdTools.getActiveAnalysis():
            CfdTools.createAnalysis()
        FreeCADGui.addModule("CfdTools")

        #self.select_without_widget()
        self.select_with_widget()

        FreeCADGui.addModule("FemGui")
        #if FemGui.getActiveAnalysis():  # besides addModule, FemGui need to be imported
        FreeCADGui.doCommand(
            "FemGui.getActiveAnalysis().addObject(App.ActiveDocument.ActiveObject)"
        )
コード例 #10
0
    def Activated(self):
        FreeCAD.ActiveDocument.openTransaction("Initialise the internal flow variables")
        isPresent = False
        members = CfdTools.getActiveAnalysis().Group
        for i in members:
            if "InitialiseFields" in i.Name:
                FreeCADGui.activeDocument().setEdit(i.Name)
                isPresent = True

        # Allow to re-create if deleted
        if not isPresent:
            FreeCADGui.doCommand("")
            FreeCADGui.addModule("CfdInitialiseFlowField")
            FreeCADGui.doCommand(
                "CfdTools.getActiveAnalysis().addObject(CfdInitialiseFlowField.makeCfdInitialFlowField())")
            FreeCADGui.ActiveDocument.setEdit(FreeCAD.ActiveDocument.ActiveObject.Name)
コード例 #11
0
ファイル: CfdSolverFoam.py プロジェクト: kliberty/CfdOF
    def Activated(self):
        CfdTools.hide_parts_show_meshes()
        isPresent = False
        members = CfdTools.getActiveAnalysis().Group
        for i in members:
            if isinstance(i.Proxy, _CfdSolverFoam):
                FreeCADGui.activeDocument().setEdit(i.Name)
                isPresent = True

        # Allowing user to re-create if CFDSolver was deleted.
        if not isPresent:
            FreeCADGui.addModule("CfdTools")
            FreeCADGui.addModule("CfdSolverFoam")
            FreeCADGui.doCommand(
                "CfdTools.getActiveAnalysis().addObject(CfdSolverFoam.makeCfdSolverFoam())"
            )
            FreeCADGui.doCommand(
                "Gui.activeDocument().setEdit(App.ActiveDocument.ActiveObject.Name)"
            )
コード例 #12
0
    def Activated(self):
        FreeCAD.ActiveDocument.openTransaction(
            "Choose appropriate physics model")
        isPresent = False
        members = CfdTools.getActiveAnalysis().Group
        for i in members:
            if isinstance(i.Proxy, _CfdPhysicsModel):
                FreeCADGui.activeDocument().setEdit(i.Name)
                isPresent = True

        # Allow to re-create if deleted
        if not isPresent:
            FreeCADGui.doCommand("")
            FreeCADGui.addModule("CfdPhysicsSelection")
            FreeCADGui.addModule("CfdTools")
            FreeCADGui.doCommand(
                "CfdTools.getActiveAnalysis().addObject(CfdPhysicsSelection.makeCfdPhysicsSelection())"
            )
            FreeCADGui.ActiveDocument.setEdit(
                FreeCAD.ActiveDocument.ActiveObject.Name)
コード例 #13
0
    def __init__(self, analysis=None, solver=None):
        super(CfdRunnable, self).__init__()
        if analysis and isinstance(analysis.Proxy, CfdAnalysis._CfdAnalysis):
            self.analysis = analysis
        else:
            if FreeCAD.GuiUp:
                self.analysis = CfdTools.getActiveAnalysis()

        self.solver = None
        if solver:
            self.solver = solver
        else:
            if analysis:
                self.solver = CfdTools.getSolver(self.analysis)
            if not self.solver:
                FreeCAD.Console.printMessage("Solver object is missing from Analysis Object")

        if self.analysis:
            self.results_present = False
            self.result_object = None
        else:
            raise Exception('No active analysis found')
コード例 #14
0
 def Activated(self):
     FreeCAD.Console.PrintMessage("Set fluid properties \n")
     FreeCAD.ActiveDocument.openTransaction("Set CfdFluidMaterialProperty")
     FreeCADGui.doCommand("")
     FreeCADGui.addModule("CfdTools")
     FreeCADGui.addModule("CfdFluidMaterial")
     editing_existing = False
     analysis_object = CfdTools.getActiveAnalysis()
     if analysis_object is None:
         CfdTools.cfdError("No active analysis object found")
         return False
     physics_model = CfdTools.getPhysicsModel(analysis_object)
     if not physics_model or physics_model.Phase == 'Single':
         members = analysis_object.Group
         for i in members:
             if isinstance(i.Proxy, _CfdMaterial):
                 FreeCADGui.activeDocument().setEdit(i.Name)
                 editing_existing = True
     if not editing_existing:
         FreeCADGui.doCommand(
             "CfdTools.getActiveAnalysis().addObject(CfdFluidMaterial.makeCfdFluidMaterial('FluidProperties'))")
         FreeCADGui.ActiveDocument.setEdit(FreeCAD.ActiveDocument.ActiveObject.Name)
コード例 #15
0
    def __init__(self, solver_runner_obj):
        ui_path = os.path.join(os.path.dirname(__file__),
                               "TaskPanelCfdSolverControl.ui")
        self.form = FreeCADGui.PySideUic.loadUi(ui_path)

        self.analysis_object = CfdTools.getActiveAnalysis()

        self.solver_runner = solver_runner_obj
        self.solver_object = solver_runner_obj.solver

        # update UI
        self.console_message = ''

        self.solver_run_process = CfdConsoleProcess(
            finishedHook=self.solverFinished,
            stdoutHook=self.gotOutputLines,
            stderrHook=self.gotErrorLines)
        self.Timer = QtCore.QTimer()
        self.Timer.setInterval(1000)
        self.Timer.timeout.connect(self.updateText)

        self.form.terminateSolver.clicked.connect(self.killSolverProcess)
        self.form.terminateSolver.setEnabled(False)

        self.open_paraview = QtCore.QProcess()

        self.working_dir = CfdTools.getOutputPath(self.analysis_object)

        self.updateUI()

        # Connect Signals and Slots
        self.form.pb_write_inp.clicked.connect(self.write_input_file_handler)
        self.form.pb_edit_inp.clicked.connect(self.editSolverInputFile)
        self.form.pb_run_solver.clicked.connect(self.runSolverProcess)
        self.form.pb_paraview.clicked.connect(self.openParaview)

        self.Start = time.time()
        self.Timer.start()
コード例 #16
0
ファイル: CfdMeshTools.py プロジェクト: zhjzhang/CfdOF
    def processDimension(self):
        """ Additional checking/processing for 2D vs 3D """
        # 3D cfMesh and snappyHexMesh, and 2D by conversion, while in future cfMesh may support 2D directly
        if self.dimension != '3D' and self.dimension != '2D':
            FreeCAD.Console.PrintError(
                'Invalid element dimension. Setting to 3D.')
            self.dimension = '3D'
        print('  ElementDimension: ' + self.dimension)

        # Check for 2D boundaries
        twoDPlanes = []
        analysis_obj = CfdTools.getParentAnalysisObject(self.mesh_obj)
        if not analysis_obj:
            analysis_obj = CfdTools.getActiveAnalysis()
        if analysis_obj:
            boundaries = CfdTools.getCfdBoundaryGroup(analysis_obj)
            for b in boundaries:
                if b.BoundaryType == 'constraint' and \
                   b.BoundarySubType == 'twoDBoundingPlane':
                    twoDPlanes.append(b.Name)

        if self.dimension == '2D':
            self.two_d_settings['ConvertTo2D'] = True
            if len(twoDPlanes) != 2:
                raise RuntimeError(
                    "For 2D meshing, two separate, parallel, 2D bounding planes must be present as "
                    "boundary conditions in the CFD analysis object.")
            doc_name = str(analysis_obj.Document.Name)
            fFObjName = twoDPlanes[0]
            bFObjName = twoDPlanes[1]
            frontObj = FreeCAD.getDocument(doc_name).getObject(fFObjName)
            backObj = FreeCAD.getDocument(doc_name).getObject(bFObjName)
            fShape = frontObj.Shape
            bShape = backObj.Shape
            if len(fShape.Faces) == 0 or len(bShape.Faces) == 0:
                raise RuntimeError("A 2D bounding plane is empty.")
            else:
                allFFacesPlanar = True
                allBFacesPlanar = True
                for faces in fShape.Faces:
                    if not isinstance(faces.Surface, Part.Plane):
                        allFFacesPlanar = False
                        break
                for faces in bShape.Faces:
                    if not isinstance(faces.Surface, Part.Plane):
                        allBFacesPlanar = False
                        break
                if allFFacesPlanar and allBFacesPlanar:
                    A1 = fShape.Faces[0].Surface.Axis
                    A1.multiply(1.0 / A1.Length)
                    A2 = bShape.Faces[0].Surface.Axis
                    A2.multiply(1.0 / A2.Length)
                    if (A1 - A2).Length <= 1e-6 or (A1 + A2).Length <= 1e-6:
                        if len(frontObj.Shape.Vertexes) == len(backObj.Shape.Vertexes) and \
                           len(frontObj.Shape.Vertexes) > 0 and \
                           abs(frontObj.Shape.Area) > 0 and \
                           abs(frontObj.Shape.Area - backObj.Shape.Area)/abs(frontObj.Shape.Area) < 1e-6:
                            self.two_d_settings[
                                'Distance'] = fShape.distToShape(
                                    bShape)[0] / 1000
                        else:
                            raise RuntimeError(
                                "2D bounding planes do not match up.")
                    else:
                        raise RuntimeError(
                            "2D bounding planes are not aligned.")
                else:
                    raise RuntimeError(
                        "2D bounding planes need to be flat surfaces.")

            case = CfdCaseWriterFoam.CfdCaseWriterFoam(analysis_obj)
            case.settings = {}
            case.settings['createPatchesFromSnappyBaffles'] = False
            case.setupPatchNames()
            keys = list(case.settings['createPatches'].keys())

            frontPatchIndex = keys.index(frontObj.Label)
            self.two_d_settings['FrontFaceList'] = case.settings[
                'createPatches'][keys[frontPatchIndex]]['PatchNamesList']

            backPatchIndex = keys.index(backObj.Label)
            self.two_d_settings['BackFaceList'] = case.settings[
                'createPatches'][keys[backPatchIndex]]['PatchNamesList']

            if not self.two_d_settings[
                    'BackFaceList'] or not self.two_d_settings['FrontFaceList']:
                raise RuntimeError(
                    "2D front and/or back plane(s) could not be found in the shape being meshed."
                )

            self.two_d_settings['BackFace'] = self.two_d_settings[
                'BackFaceList'][0]
        else:
            self.two_d_settings['ConvertTo2D'] = False
            if len(twoDPlanes):
                raise RuntimeError(
                    "2D bounding planes can not be used in 3D mesh")
コード例 #17
0
    def processRefinements(self):
        """ Process mesh refinements """

        mr_objs = CfdTools.getMeshRefinementObjs(self.mesh_obj)

        if self.mesh_obj.MeshUtility == "gmsh":
            # mesh regions
            self.ele_length_map = {}  # { 'ElementString' : element length }
            self.ele_node_map = {}  # { 'ElementString' : [element nodes] }
            if not mr_objs:
                print('  No mesh refinements')
            else:
                print('  Mesh refinements found - getting 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 mr_objs:
                    if mr_obj.RelativeLength:
                        if mr_obj.References:
                            for sub in mr_obj.References:
                                # 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
                                ref = FreeCAD.ActiveDocument.getObject(sub[0])
                                if not self.part_obj.Shape.isSame(ref.Shape):
                                    search_ele_in_shape_to_mesh = True
                                elems = sub[1]
                                if search_ele_in_shape_to_mesh:
                                    # Try to find the element in the Shape to mesh
                                    ele_shape = FemGeomTools.get_element(
                                        ref, elems
                                    )  # the method getElement(element) does not return Solid elements
                                    found_element = CfdTools.findElementInShape(
                                        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"
                                        )
                                        elems = None
                                if elems:
                                    if elems not in self.ele_length_map:
                                        # self.ele_length_map[elems] = Units.Quantity(mr_obj.CharacteristicLength).Value
                                        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[
                                            elems] = mr_rellen * self.clmax
                                    else:
                                        FreeCAD.Console.PrintError(
                                            "The element " + elems +
                                            " of the mesh refinement " +
                                            mr_obj.Name +
                                            " has been added to another mesh refinement.\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 = FemGeomTools.get_element(
                        self.part_obj, eleml
                    )  # the method getElement(element) does not return Solid elements
                    ele_vertexes = FemGeomTools.get_vertexes_by_element(
                        self.part_obj.Shape, ele_shape)
                    self.ele_node_map[eleml] = ele_vertexes

        else:
            cf_settings = self.cf_settings
            cf_settings['MeshRegions'] = {}
            cf_settings['BoundaryLayers'] = {}
            cf_settings['InternalRegions'] = {}
            snappy_settings = self.snappy_settings
            snappy_settings['MeshRegions'] = {}
            snappy_settings['InternalRegions'] = {}

            # Make list of all faces in meshed shape with original index
            mesh_face_list = list(
                zip(self.mesh_obj.Part.Shape.Faces,
                    range(len(self.mesh_obj.Part.Shape.Faces))))

            # Make list of all boundary references
            CfdTools.cfdMessage("Matching boundary patches\n")
            bc_group = None
            analysis_obj = CfdTools.getParentAnalysisObject(self.mesh_obj)
            if not analysis_obj:
                analysis_obj = CfdTools.getActiveAnalysis()
            if analysis_obj:
                bc_group = CfdTools.getCfdBoundaryGroup(analysis_obj)
            boundary_face_list = []
            for bc_id, bc_obj in enumerate(bc_group):
                for ri, ref in enumerate(bc_obj.References):
                    try:
                        bf = CfdTools.resolveReference(ref)
                    except RuntimeError as re:
                        raise RuntimeError(
                            "Error processing boundary condition {}: {}".
                            format(bc_obj.Label, str(re)))
                    boundary_face_list.append((bf, (bc_id, ref, ri)))

            # Match them up to faces in the main geometry
            bc_matched_faces = CfdTools.matchFaces(boundary_face_list,
                                                   mesh_face_list)

            # Make list of all boundary layer mesh regions for cfMesh
            bl_matched_faces = []
            if self.mesh_obj.MeshUtility == 'cfMesh':
                CfdTools.cfdMessage("Matching boundary layer regions\n")

                bl_face_list = []
                for mr_id, mr_obj in enumerate(mr_objs):
                    if mr_obj.NumberLayers > 1 and not mr_obj.Internal:
                        for ri, r in enumerate(mr_obj.References):
                            try:
                                f = CfdTools.resolveReference(r)
                            except RuntimeError as re:
                                raise RuntimeError(
                                    "Error processing mesh refinement {}: {}".
                                    format(mr_obj.Label, str(re)))
                            bl_face_list.append((f, (mr_id, r, ri)))

                # Match them up
                bl_matched_faces = CfdTools.matchFaces(bl_face_list,
                                                       mesh_face_list)

            # Check for and filter duplicates
            bc_match_per_shape_face = [-1] * len(mesh_face_list)
            for k in range(len(bc_matched_faces)):
                match = bc_matched_faces[k][1]
                prev_k = bc_match_per_shape_face[match]
                if prev_k >= 0:
                    nb, bref, ri = bc_matched_faces[k][0]
                    nb2, bref2, ri2 = bc_matched_faces[prev_k][0]
                    CfdTools.cfdMessage(
                        "Boundary '{}' reference {}:{} also assigned as "
                        "boundary '{}' reference {}:{} - ignoring duplicate\n".
                        format(bc_group[nb].Label, bref[0], bref[1],
                               bc_group[nb2].Label, bref2[0], bref2[1]))
                else:
                    bc_match_per_shape_face[match] = k

            bl_match_per_shape_face = [-1] * len(mesh_face_list)
            for k in range(len(bl_matched_faces)):
                match = bl_matched_faces[k][1]
                prev_k = bl_match_per_shape_face[match]
                if prev_k >= 0:
                    nr, ref, ri = bl_matched_faces[k][0]
                    nr2, ref2, ri2 = bl_matched_faces[prev_k][0]
                    CfdTools.cfdMessage(
                        "Mesh refinement '{}' reference {}:{} also assigned as "
                        "mesh refinement '{}' reference {}:{} - ignoring duplicate\n"
                        .format(mr_objs[nr].Label, ref[0], ref[1],
                                mr_objs[nr2].Label, ref2[0], ref2[1]))
                else:
                    bl_match_per_shape_face[match] = k

            self.patch_faces = []
            self.patch_names = []
            for k in range(len(bc_group) + 1):
                self.patch_faces.append([])
                self.patch_names.append([])
                for l in range(len(mr_objs) + 1):
                    self.patch_faces[k].append([])
                    self.patch_names[k].append("patch_" + str(k) + "_" +
                                               str(l))
            for i in range(len(mesh_face_list)):
                k = bc_match_per_shape_face[i]
                l = bl_match_per_shape_face[i]
                nb = -1
                nr = -1
                if k >= 0:
                    nb, bref, bri = bc_matched_faces[k][0]
                if l >= 0:
                    nr, ref, rri = bl_matched_faces[l][0]
                self.patch_faces[nb + 1][nr + 1].append(i)

            # Additionally for snappy, match baffles to any surface mesh refinements
            # as well as matching each surface mesh refinement region to boundary conditions
            mr_face_list = []
            bc_mr_matched_faces = []
            if self.mesh_obj.MeshUtility == 'snappyHexMesh':
                CfdTools.cfdMessage("Matching surface geometries\n")

                for mr_id, mr_obj in enumerate(mr_objs):
                    if not mr_obj.Internal:
                        for ri, r in enumerate(mr_obj.References):
                            try:
                                f = CfdTools.resolveReference(r)
                            except RuntimeError as re:
                                raise RuntimeError(
                                    "Error processing mesh refinement {}: {}".
                                    format(mr_obj.Label, str(re)))
                            mr_face_list.append((f, (mr_id, r, ri)))

                # Match mesh regions to the boundary conditions, to identify boundary conditions on supplementary
                # geometry (including on baffles)
                bc_mr_matched_faces = CfdTools.matchFaces(
                    boundary_face_list, mr_face_list)

            for bc_id, bc_obj in enumerate(bc_group):
                if bc_obj.BoundaryType == 'baffle':
                    baffle_matches = [
                        m for m in bc_mr_matched_faces if m[0][0] == bc_id
                    ]
                    mr_match_per_baffle_ref = [-1] * len(bc_obj.References)
                    for m in baffle_matches:
                        mr_match_per_baffle_ref[m[0][2]] = m[1][0]
                    # For each mesh region, the refs that are part of this baffle
                    baffle_patch_refs = [[] for ri in range(len(mr_objs) + 1)]
                    for ri, mri in enumerate(mr_match_per_baffle_ref):
                        baffle_patch_refs[mri + 1].append(
                            bc_obj.References[ri])

                    # Write these geometries
                    for ri, refs in enumerate(baffle_patch_refs):
                        try:
                            shape = CfdTools.makeShapeFromReferences(refs)
                        except RuntimeError as re:
                            raise RuntimeError(
                                "Error processing baffle {}: {}".format(
                                    bc_obj.Label, str(re)))
                        solid_name = bc_obj.Name + "_" + str(ri)
                        if shape:
                            CfdTools.cfdMessage(
                                "Triangulating baffle {}, section {} ...".
                                format(bc_obj.Label, ri))
                            facemesh = MeshPart.meshFromShape(
                                shape,
                                LinearDeflection=self.mesh_obj.
                                STLLinearDeflection)

                            CfdTools.cfdMessage(" writing to file\n")
                            with open(
                                    os.path.join(self.triSurfaceDir,
                                                 solid_name + '.stl'),
                                    'w') as fid:
                                CfdTools.writePatchToStl(
                                    solid_name, facemesh, fid, self.scale)

                            if ri > 0:  # The parts of the baffle corresponding to a surface mesh region obj
                                mr_obj = mr_objs[ri - 1]
                                refinement_level = CfdTools.relLenToRefinementLevel(
                                    mr_obj.RelativeLength)
                                edge_level = CfdTools.relLenToRefinementLevel(
                                    mr_obj.RegionEdgeRefinement)
                            else:  # The parts of the baffle with no refinement obj
                                refinement_level = 0
                                edge_level = 0
                            snappy_settings['MeshRegions'][solid_name] = {
                                'RefinementLevel':
                                refinement_level,
                                'EdgeRefinementLevel':
                                edge_level,
                                'MaxRefinementLevel':
                                max(refinement_level, edge_level),
                                'Baffle':
                                True
                            }

            mr_matched_faces = []
            if self.mesh_obj.MeshUtility == 'snappyHexMesh':
                # Match mesh regions to the primary geometry
                mr_matched_faces = CfdTools.matchFaces(mr_face_list,
                                                       mesh_face_list)

            for mr_id, mr_obj in enumerate(mr_objs):
                Internal = mr_obj.Internal
                mr_rellen = mr_obj.RelativeLength
                if mr_rellen > 1.0:
                    mr_rellen = 1.0
                    FreeCAD.Console.PrintError(
                        "The mesh refinement region '{}' should not use a relative length greater "
                        "than unity.\n".format(mr_obj.Name))
                elif mr_rellen < 0.001:
                    mr_rellen = 0.001  # Relative length should not be less than 0.1% of base length
                    FreeCAD.Console.PrintError(
                        "The mesh refinement region '{}' should not use a relative length smaller "
                        "than 0.001.\n".format(mr_obj.Name))

                # Find any matches with boundary conditions; mark those matching baffles for removal
                bc_matches = [
                    m for m in bc_mr_matched_faces if m[1][0] == mr_id
                ]
                bc_match_per_mr_ref = [-1] * len(mr_obj.References)
                for m in bc_matches:
                    bc_match_per_mr_ref[m[1][2]] = -2 if bc_group[
                        m[0][0]].BoundaryType == 'baffle' else m[0][0]

                # Unmatch those in primary geometry
                main_geom_matches = [
                    m for m in mr_matched_faces if m[0][0] == mr_id
                ]
                for m in main_geom_matches:
                    bc_match_per_mr_ref[m[0][2]] = -1

                # For each boundary, the refs that are part of this mesh region
                mr_patch_refs = [[] for ri in range(len(bc_group) + 1)]
                for ri, bci in enumerate(bc_match_per_mr_ref):
                    if bci > -2:
                        mr_patch_refs[bci + 1].append(mr_obj.References[ri])

                # Loop over and write the sub-sections of this mesh object
                for bi in range(len(mr_patch_refs)):
                    if len(mr_patch_refs[bi]):
                        if bi == 0:
                            mr_patch_name = mr_obj.Name
                        else:
                            mr_patch_name = self.patch_names[bi][mr_id + 1]

                        CfdTools.cfdMessage(
                            "Triangulating mesh refinement region {}, section {} ..."
                            .format(mr_obj.Label, bi))

                        try:
                            shape = CfdTools.makeShapeFromReferences(
                                mr_patch_refs[bi])
                        except RuntimeError as re:
                            raise RuntimeError(
                                "Error processing mesh refinement region {}: {}"
                                .format(mr_obj.Label, str(re)))
                        if shape:
                            facemesh = MeshPart.meshFromShape(
                                shape,
                                LinearDeflection=self.mesh_obj.
                                STLLinearDeflection)

                            CfdTools.cfdMessage(" writing to file\n")
                            with open(
                                    os.path.join(self.triSurfaceDir,
                                                 mr_patch_name + '.stl'),
                                    'w') as fid:
                                CfdTools.writePatchToStl(
                                    mr_patch_name, facemesh, fid, self.scale)

                        if self.mesh_obj.MeshUtility == 'cfMesh':
                            if not Internal:
                                cf_settings['MeshRegions'][mr_patch_name] = {
                                    'RelativeLength':
                                    mr_rellen * self.clmax * self.scale,
                                    'RefinementThickness':
                                    self.scale * Units.Quantity(
                                        mr_obj.RefinementThickness).Value,
                                }
                            else:
                                cf_settings['InternalRegions'][mr_obj.Name] = {
                                    'RelativeLength':
                                    mr_rellen * self.clmax * self.scale
                                }

                        elif self.mesh_obj.MeshUtility == 'snappyHexMesh':
                            refinement_level = CfdTools.relLenToRefinementLevel(
                                mr_obj.RelativeLength)
                            if not Internal:
                                edge_level = CfdTools.relLenToRefinementLevel(
                                    mr_obj.RegionEdgeRefinement)
                                snappy_settings['MeshRegions'][
                                    mr_patch_name] = {
                                        'RefinementLevel':
                                        refinement_level,
                                        'EdgeRefinementLevel':
                                        edge_level,
                                        'MaxRefinementLevel':
                                        max(refinement_level, edge_level),
                                        'Baffle':
                                        False
                                    }
                            else:
                                snappy_settings['InternalRegions'][
                                    mr_patch_name] = {
                                        'RefinementLevel': refinement_level
                                    }

                # In addition, for cfMesh, record matched boundary layer patches
                if self.mesh_obj.MeshUtility == 'cfMesh' and mr_obj.NumberLayers > 1 and not Internal:
                    for k in range(len(self.patch_faces)):
                        # Limit expansion ratio to greater than 1.0 and less than 1.2
                        expratio = mr_obj.ExpansionRatio
                        expratio = min(1.2, max(1.0, expratio))

                        cf_settings['BoundaryLayers'][
                            self.patch_names[k][mr_id]] = {
                                'NumberLayers':
                                mr_obj.NumberLayers,
                                'ExpansionRatio':
                                expratio,
                                'FirstLayerHeight':
                                self.scale *
                                Units.Quantity(mr_obj.FirstLayerHeight).Value
                            }
コード例 #18
0
 def IsActive(self):
     return CfdTools.getActiveAnalysis() is not None
コード例 #19
0
ファイル: CfdMesh.py プロジェクト: wkangholy/CfdOF
 def IsActive(self):
     sel = FreeCADGui.Selection.getSelection()
     analysis = CfdTools.getActiveAnalysis()
     return analysis is not None and sel and len(
         sel) == 1 and sel[0].isDerivedFrom("Part::Feature")