Пример #1
0
 def doubleClicked(self, vobj):
     if FreeCADGui.activeWorkbench().name() != 'CfdOFWorkbench':
         FreeCADGui.activateWorkbench("CfdOFWorkbench")
     doc = FreeCADGui.getDocument(vobj.Object.Document)
     if not CfdTools.getActiveAnalysis():
         analysis_obj = CfdTools.getParentAnalysisObject(self.Object)
         if analysis_obj:
             CfdTools.setActiveAnalysis(analysis_obj)
         else:
             FreeCAD.Console.PrintError(
                 'No Active Analysis 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(
                     'Please 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 active\n')
         FreeCADGui.Control.showTaskView()
     return True
Пример #2
0
 def Activated(self):
     FreeCAD.ActiveDocument.openTransaction("Create CFD mesh")
     analysis_obj = CfdTools.getActiveAnalysis()
     if analysis_obj:
         mesh_obj = CfdTools.getMesh(analysis_obj)
         if not mesh_obj:
             sel = FreeCADGui.Selection.getSelection()
             if len(sel) == 1:
                 if sel[0].isDerivedFrom("Part::Feature"):
                     mesh_obj_name = sel[0].Name + "_Mesh"
                     FreeCADGui.doCommand("from CfdOF.Mesh import CfdMesh")
                     FreeCADGui.doCommand("CfdMesh.makeCfdMesh('" +
                                          mesh_obj_name + "')")
                     FreeCADGui.doCommand(
                         "App.ActiveDocument.ActiveObject.Part = App.ActiveDocument."
                         + sel[0].Name)
                     if CfdTools.getActiveAnalysis():
                         FreeCADGui.doCommand("from CfdOF import 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
 def setEdit(self, vobj, mode):
     if CfdTools.getActiveAnalysis():
         from CfdOF.Solve.CfdRunnableFoam import CfdRunnableFoam
         foam_runnable = CfdRunnableFoam(CfdTools.getActiveAnalysis(),
                                         self.Object)
         from CfdOF.Solve import TaskPanelCfdSolverControl
         import importlib
         importlib.reload(TaskPanelCfdSolverControl)
         self.taskd = TaskPanelCfdSolverControl.TaskPanelCfdSolverControl(
             foam_runnable)
         self.taskd.obj = vobj.Object
         FreeCADGui.Control.showDialog(self.taskd)
     return True
Пример #4
0
    def Activated(self):
        is_present = False
        members = CfdTools.getMesh(CfdTools.getActiveAnalysis()).Group
        for i in members:
            if hasattr(i, 'Proxy') and isinstance(i.Proxy,
                                                  CfdDynamicMeshRefinement):
                FreeCADGui.activeDocument().setEdit(i.Name)
                is_present = True

        # Allow to re-create if deleted
        if not is_present:
            sel = FreeCADGui.Selection.getSelection()
            if len(sel) == 1:
                sobj = sel[0]
                if len(sel) == 1 and hasattr(sobj, "Proxy") and isinstance(
                        sobj.Proxy, CfdMesh):
                    FreeCAD.ActiveDocument.openTransaction(
                        "Create DynamicMesh")
                    FreeCADGui.doCommand("")
                    FreeCADGui.doCommand(
                        "from CfdOF.Mesh import CfdDynamicMeshRefinement")
                    FreeCADGui.doCommand("from CfdOF import CfdTools")
                    FreeCADGui.doCommand(
                        "CfdDynamicMeshRefinement.makeCfdDynamicMeshRefinement(App.ActiveDocument.{})"
                        .format(sobj.Name))
                    FreeCADGui.ActiveDocument.setEdit(
                        FreeCAD.ActiveDocument.ActiveObject.Name)

        FreeCADGui.Selection.clearSelection()
Пример #5
0
    def __init__(self, obj):
        self.obj = obj
        self.analysis_obj = CfdTools.getActiveAnalysis()
        self.physics_obj = CfdTools.getPhysicsModel(self.analysis_obj)

        ui_path = os.path.join(CfdTools.getModulePath(), 'Gui', "TaskPanelCfdReportingFunctions.ui")
        self.form = FreeCADGui.PySideUic.loadUi(ui_path)

        # Function Object types
        self.form.comboFunctionObjectType.addItems(CfdReportingFunction.OBJECT_NAMES)
        self.form.comboFunctionObjectType.currentIndexChanged.connect(self.comboFunctionObjectTypeChanged)

        self.form.inputReferencePressure.setToolTip("Reference pressure")
        self.form.inputWriteFields.setToolTip("Write output fields")
        self.form.inputCentreOfRotationx.setToolTip("Centre of rotation vector for moments")

        self.form.inputLiftDirectionx.setToolTip("Lift direction vector")
        self.form.inputDragDirectionx.setToolTip("Drag direction vector")
        self.form.inputMagnitudeUInf.setToolTip("Velocity magnitude reference")
        self.form.inputReferenceDensity.setToolTip("Density reference")
        self.form.inputLengthRef.setToolTip("Length reference")
        self.form.inputAreaRef.setToolTip("Area reference")

        self.form.inputNBins.setToolTip("Number of bins")
        self.form.inputDirectionx.setToolTip("Binning direction")
        self.form.inputCumulative.setToolTip("Cumulative")
        self.form.cb_patch_list.setToolTip("Patch (BC) group to monitor")

        self.list_of_bcs = [bc.Label for bc in CfdTools.getCfdBoundaryGroup(self.analysis_obj)]
        self.form.cb_patch_list.addItems(self.list_of_bcs)

        self.load()
        self.updateUI()
Пример #6
0
    def runTest(self, dir_name, macro_names):
        fccPrint('--------------- Start of CFD tests ---------------')
        for m in macro_names:
            macro_name = os.path.join(home_path, "Demos", dir_name, m)
            fccPrint('Running {} macro {} ...'.format(dir_name, macro_name))
            CfdTools.executeMacro(macro_name)

        fccPrint('Writing {} case files ...'.format(dir_name))
        analysis = CfdTools.getActiveAnalysis()
        analysis.OutputPath = temp_dir
        CfdTools.getSolver(analysis).InputCaseName = "case" + dir_name
        CfdTools.getMeshObject(analysis).CaseName = "meshCase" + dir_name
        self.writeCaseFiles()
        self.child_instance.assertTrue(self.writer, "CfdTest of writer failed")

        mesh_ref_dir = os.path.join(test_file_dir, "cases", dir_name, "meshCase")
        mesh_case_dir = self.meshwriter.meshCaseDir
        comparePaths(mesh_ref_dir, mesh_case_dir, self.child_instance)

        ref_dir = os.path.join(test_file_dir, "cases", dir_name, "case")
        case_dir = self.writer.case_folder
        comparePaths(ref_dir, case_dir, self.child_instance)

        #shutil.rmtree(mesh_case_dir)
        #shutil.rmtree(case_dir)

        fccPrint('--------------- End of CFD tests ---------------')
Пример #7
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
Пример #8
0
    def writeCaseFiles(self):
        analysis = CfdTools.getActiveAnalysis()
        self.meshwriter = CfdMeshTools.CfdMeshTools(CfdTools.getMeshObject(analysis))
        self.meshwriter.writeMesh()

        self.writer = CfdCaseWriterFoam.CfdCaseWriterFoam(FreeCAD.ActiveDocument.CfdAnalysis)
        self.writer.writeCase()
Пример #9
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
Пример #10
0
    def Activated(self):
        is_present = False
        members = CfdTools.getActiveAnalysis().Group
        for i in members:
            if isinstance(i.Proxy, CfdSolverFoam):
                FreeCADGui.activeDocument().setEdit(i.Name)
                is_present = True

        # Allowing user to re-create if CFDSolver was deleted.
        if not is_present:
            FreeCADGui.doCommand("from CfdOF import CfdTools")
            FreeCADGui.doCommand("from CfdOF.Solve import CfdSolverFoam")
            FreeCADGui.doCommand(
                "CfdTools.getActiveAnalysis().addObject(CfdSolverFoam.makeCfdSolverFoam())"
            )
            FreeCADGui.doCommand(
                "Gui.activeDocument().setEdit(App.ActiveDocument.ActiveObject.Name)"
            )
Пример #11
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("from CfdOF import CfdTools")
            FreeCADGui.doCommand(
                "from CfdOF.Solve import CfdInitialiseFlowField")
            FreeCADGui.doCommand(
                "CfdTools.getActiveAnalysis().addObject(CfdInitialiseFlowField.makeCfdInitialFlowField())"
            )
            FreeCADGui.ActiveDocument.setEdit(
                FreeCAD.ActiveDocument.ActiveObject.Name)
Пример #12
0
    def Activated(self):
        FreeCAD.ActiveDocument.openTransaction(
            "Choose appropriate physics model")
        is_present = False
        members = CfdTools.getActiveAnalysis().Group
        for i in members:
            if isinstance(i.Proxy, CfdPhysicsModel):
                FreeCADGui.activeDocument().setEdit(i.Name)
                is_present = True

        # Allow to re-create if deleted
        if not is_present:
            FreeCADGui.doCommand("")
            FreeCADGui.doCommand("from CfdOF.Solve import CfdPhysicsSelection")
            FreeCADGui.doCommand("from CfdOF import CfdTools")
            FreeCADGui.doCommand(
                "CfdTools.getActiveAnalysis().addObject(CfdPhysicsSelection.makeCfdPhysicsSelection())"
            )
            FreeCADGui.ActiveDocument.setEdit(
                FreeCAD.ActiveDocument.ActiveObject.Name)
Пример #13
0
 def Activated(self):
     FreeCAD.Console.PrintMessage("Set fluid properties \n")
     FreeCAD.ActiveDocument.openTransaction("Set CfdFluidMaterialProperty")
     FreeCADGui.doCommand("from CfdOF import CfdTools")
     FreeCADGui.doCommand("from CfdOF.Solve import CfdFluidMaterial")
     editing_existing = False
     analysis_object = CfdTools.getActiveAnalysis()
     if analysis_object is None:
         CfdTools.cfdErrorBox("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)
Пример #14
0
    def __init__(self, solver_runner_obj):
        ui_path = os.path.join(CfdTools.getModulePath(), 'Gui',
                               "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_object.Proxy.solver_process = CfdConsoleProcess(
            finished_hook=self.solverFinished,
            stdout_hook=self.gotOutputLines,
            stderr_hook=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()
Пример #15
0
 def constructAncillaryPlotters(self):
     reporting_functions = CfdTools.getReportingFunctionsGroup(
         CfdTools.getActiveAnalysis())
     if reporting_functions is not None:
         for rf in reporting_functions:
             if rf.ReportingFunctionType == "Force":
                 self.forces[rf.Label] = {}
                 if rf.Label not in self.solver.Proxy.forces_plotters:
                     self.solver.Proxy.forces_plotters[rf.Label] = \
                         TimePlot(title=rf.Label, y_label="Force [N]", is_log=False)
             elif rf.ReportingFunctionType == "ForceCoefficients":
                 self.force_coeffs[rf.Label] = {}
                 if rf.Label not in self.solver.Proxy.force_coeffs_plotters:
                     self.solver.Proxy.force_coeffs_plotters[rf.Label] = \
                         TimePlot(title=rf.Label, y_label="Coefficient", is_log=False)
             elif rf.ReportingFunctionType == 'Probes':
                 self.probes[rf.Label] = {
                     'field': rf.SampleFieldName,
                     'points': [rf.ProbePosition]
                 }
                 if rf.Label not in self.solver.Proxy.probes_plotters:
                     self.solver.Proxy.probes_plotters[rf.Label] = \
                         TimePlot(title=rf.Label, y_label=rf.SampleFieldName, is_log=False)
Пример #16
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')
Пример #17
0
    def processRefinements(self):
        """ Process mesh refinements """
        mr_objs = CfdTools.getMeshRefinementObjs(self.mesh_obj)

        cf_settings = self.cf_settings
        cf_settings['MeshRegions'] = {}
        cf_settings['BoundaryLayers'] = {}
        cf_settings['InternalRegions'] = {}
        snappy_settings = self.snappy_settings
        snappy_settings['MeshRegions'] = {}
        snappy_settings['BoundaryLayers'] = {}
        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")
        boundary_face_list = []
        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)
        for bc_id, bc_obj in enumerate(bc_group):
            for ri, ref in enumerate(bc_obj.ShapeRefs):
                try:
                    bf = CfdTools.resolveReference(ref)
                except RuntimeError as re:
                    raise RuntimeError(
                        "Error processing boundary condition {}: {}".format(
                            bc_obj.Label, str(re)))
                for si, s in enumerate(bf):
                    boundary_face_list += [(sf, (bc_id, ri, si))
                                           for sf in s[0].Faces]

        # Match them up to faces in the main geometry
        bc_matched_faces = CfdTools.matchFaces(boundary_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, ri, si = bc_matched_faces[k][0]
                nb2, ri2, si2 = bc_matched_faces[prev_k][0]
                bc = bc_group[nb]
                bc2 = bc_group[nb2]
                CfdTools.cfdWarning(
                    "Boundary '{}' reference {}:{} also assigned as "
                    "boundary '{}' reference {}:{} - ignoring duplicate\n".
                    format(bc.Label, bc.ShapeRefs[ri][0].Name,
                           bc.ShapeRefs[ri][1][si], bc2.Label,
                           bc.ShapeRefs[ri][0].Name, bc.ShapeRefs[ri][1][si]))
            else:
                bc_match_per_shape_face[match] = k

        # Match relevant mesh regions to the shape being meshed: boundary layer mesh regions for cfMesh,
        # all surface mesh refinements for snappyHexMesh, and extrusion patches for all meshers.
        # For cfMesh, surface mesh refinements are written as separate surfaces so need not be matched
        CfdTools.cfdMessage("Matching mesh refinement regions\n")
        mr_face_list = []
        for mr_id, mr_obj in enumerate(mr_objs):
            if mr_obj.Extrusion or (
                    self.mesh_obj.MeshUtility == 'cfMesh'
                    and not mr_obj.Internal and mr_obj.NumberLayers > 0) or (
                        self.mesh_obj.MeshUtility == 'snappyHexMesh'
                        and not mr_obj.Internal):
                for ri, r in enumerate(mr_obj.ShapeRefs):
                    try:
                        bf = CfdTools.resolveReference(r)
                    except RuntimeError as re:
                        raise RuntimeError(
                            "Error processing mesh refinement {}: {}".format(
                                mr_obj.Label, str(re)))
                    for si, s in enumerate(bf):
                        mr_face_list += [(f, (mr_id, ri, si))
                                         for f in s[0].Faces]

        # Match them up to the primary geometry
        mr_matched_faces = CfdTools.matchFaces(mr_face_list, mesh_face_list)

        # Check for and filter duplicates
        mr_match_per_shape_face = [-1] * len(mesh_face_list)
        for k in range(len(mr_matched_faces)):
            match = mr_matched_faces[k][1]
            prev_k = mr_match_per_shape_face[match]
            if prev_k >= 0:
                nr, ri, si = mr_matched_faces[k][0]
                nr2, ri2, si2 = mr_matched_faces[prev_k][0]
                CfdTools.cfdWarning(
                    "Mesh refinement '{}' reference {}:{} also assigned as "
                    "mesh refinement '{}' reference {}:{} - ignoring duplicate\n"
                    .format(mr_objs[nr].Label,
                            mr_objs[nr].ShapeRefs[ri][0].Name,
                            mr_objs[nr].ShapeRefs[ri][1][si],
                            mr_objs[nr2].Label,
                            mr_objs[nr2].ShapeRefs[ri2][0].Name,
                            mr_objs[nr2].ShapeRefs[ri2][1][si2]))
            else:
                mr_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 = mr_match_per_shape_face[i]
            nb = -1
            nr = -1
            if k >= 0:
                nb, bri, bsi = bc_matched_faces[k][0]
            if l >= 0:
                nr, rri, ssi = mr_matched_faces[l][0]
            self.patch_faces[nb + 1][nr + 1].append(i)

        # For gmsh, match mesh refinement with vertices in original mesh
        mr_matched_vertices = []
        if self.mesh_obj.MeshUtility == 'gmsh':
            # Make list of all vertices in meshed shape with original index
            mesh_vertices_list = list(
                zip(self.mesh_obj.Part.Shape.Vertexes,
                    range(len(self.mesh_obj.Part.Shape.Vertexes))))

            CfdTools.cfdMessage("Matching mesh refinements\n")
            mr_vertices_list = []
            for mr_id, mr_obj in enumerate(mr_objs):
                if not mr_obj.Internal:
                    for ri, r in enumerate(mr_obj.ShapeRefs):
                        try:
                            bf = CfdTools.resolveReference(r)
                        except RuntimeError as re:
                            raise RuntimeError(
                                "Error processing mesh refinement {}: {}".
                                format(mr_obj.Label, str(re)))
                        for si, s in enumerate(bf):
                            mr_vertices_list += [(v, (mr_id, ri, si))
                                                 for v in s[0].Vertexes]

            mr_matched_vertices = CfdTools.matchFaces(mr_vertices_list,
                                                      mesh_vertices_list)
            self.ele_length_map = {}
            self.ele_node_map = {}

        # For snappyHexMesh, also match surface mesh refinements to the boundary conditions, to identify boundary
        # conditions on supplementary geometry defined by the surface mesh refinements
        # Also matches baffles to surface mesh refinements
        bc_mr_matched_faces = []
        if self.mesh_obj.MeshUtility == 'snappyHexMesh':
            bc_mr_matched_faces = CfdTools.matchFaces(boundary_face_list,
                                                      mr_face_list)

        # Handle baffles
        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 = []
                for r in bc_obj.ShapeRefs:
                    mr_match_per_baffle_ref += [[-1] * len(r[1])]
                for m in baffle_matches:
                    mr_match_per_baffle_ref[m[0][1]][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, mr in enumerate(mr_match_per_baffle_ref):
                    for si, mri in enumerate(mr_match_per_baffle_ref[ri]):
                        baffle_patch_refs[mri + 1].append(
                            (bc_obj.ShapeRefs[ri][0],
                             (bc_obj.ShapeRefs[ri][1][si], )))

                # 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 {}\n".format(
                                bc_obj.Label, ri))
                        writeSurfaceMeshFromShape(shape, self.triSurfaceDir,
                                                  solid_name, self.mesh_obj)

                        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
                        }

        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))

            if self.mesh_obj.MeshUtility == 'gmsh':
                # Generate element maps for gmsh
                if not Internal:
                    mesh_vertex_idx = [
                        mf[1] for mf in mr_matched_vertices
                        if mf[0][0] == mr_id
                    ]
                    self.ele_length_map[mr_obj.Name] = mr_rellen * self.clmax
                    self.ele_node_map[mr_obj.Name] = mesh_vertex_idx
            else:
                # 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 = []
                for ri, r in enumerate(mr_obj.ShapeRefs):
                    bc_match_per_mr_ref.append([-1] * len(r[1]))
                for m in bc_matches:
                    bc_match_per_mr_ref[m[1][1]][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][1]][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, m in enumerate(bc_match_per_mr_ref):
                    for si, bci in enumerate(m):
                        if bci > -2:
                            mr_patch_refs[bci + 1].append(
                                (mr_obj.ShapeRefs[ri][0],
                                 (mr_obj.ShapeRefs[ri][1][si], )))

                # 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]) and not mr_obj.Extrusion:
                        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 {}\n"
                            .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:
                            writeSurfaceMeshFromShape(shape,
                                                      self.triSurfaceDir,
                                                      mr_patch_name,
                                                      self.mesh_obj)

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

                        elif self.mesh_obj.MeshUtility == 'snappyHexMesh':
                            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 and SnappyHesMesh, record matched boundary layer patches

            if (self.mesh_obj.MeshUtility == 'cfMesh' or self.mesh_obj.MeshUtility == 'snappyHexMesh') \
                    and mr_obj.NumberLayers > 0 and not Internal and not mr_obj.Extrusion:

                for k in range(len(self.patch_faces)):
                    if len(self.patch_faces[k][mr_id + 1]):
                        # 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))

                        if self.mesh_obj.MeshUtility == 'cfMesh':
                            cf_settings['BoundaryLayers'][self.patch_names[k][mr_id + 1]] = \
                            {
                                'NumberLayers': mr_obj.NumberLayers,
                                'ExpansionRatio': expratio,
                                'FirstLayerHeight': self.scale * Units.Quantity(mr_obj.FirstLayerHeight).Value
                            }
                        elif self.mesh_obj.MeshUtility == 'snappyHexMesh':
                            snappy_settings['BoundaryLayers'][self.patch_names[k][mr_id + 1]] = \
                            {
                                'NumberLayers': mr_obj.NumberLayers,
                                'ExpansionRatio': expratio,
                                # 'FinalLayerHeight': self.scale * Units.Quantity(mr_obj.FinalLayerHeight).Value
                            }
Пример #18
0
 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")
Пример #19
0
 def IsActive(self):
     return CfdTools.getActiveAnalysis() is not None
Пример #20
0
 def IsActive(self):
     return CfdTools.getActiveAnalysis(
     ) is not None  # Same as for boundary condition commands