Example #1
0
def export_fenics_mesh(obj, meshfileString):
    if not (meshfileString[-4:] == ".xml" or meshfileString[-5:] == ".hdf5"):
        error = "Error: only xml or hdf5 mesh is supported by gmsh conversion"
        FreeCAD.Console.PrintError(error)
        return error
    meshfileStem = (meshfileString[:-4])
    if isinstance(meshfileStem, (type(b"bytes type"),)):
        meshfileStem = meshfileStem.decode('utf8')

    gmsh = CaeMesherGmsh.CaeMesherGmsh(obj, CfdTools.getParentAnalysisObject(obj))
    meshfile = gmsh.export_mesh(u"Gmsh MSH", meshfileStem + u".msh")
    if meshfile:
        msg = "Info: Mesh has been written to `{}` by Gmsh\n".format(meshfile)
        FreeCAD.Console.PrintMessage(msg)
        # once Fenics is installed, dolfin-convert should be in path
        #comandlist = [u'dolfin-convert', u'-i gmsh', unicode(meshfileStem) + u".msh", unicode(meshfileStem) + u".xml"]
        comandlist = ['dolfin-convert {}.msh {}.xml'.format(meshfileStem,meshfileStem)]  # work only with shell = True
        # mixed str and unicode in comandlist cause error to run in subprocess
        error = _run_command(comandlist)
        if not os.path.exists(meshfileStem+"_facet_region.xml"):
            FreeCAD.Console.PrintWarning("Mesh  boundary file `{}` not generated\n".format(meshfileStem+"_physical_region.xml"))
        if error:
            return error
        if meshfileString[-5:] == ".hdf5":
            raise NotImplementedError('')
    else:
        error = "Failed to write mesh file `{}` by Gmsh\n".format(meshfileString)
        FreeCAD.Console.PrintError(error)
        return error
 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.getParentAnalysisObject(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().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(
             'Active Task Dialog found! Please close this one first!\n')
     return True
Example #3
0
    def __init__(self, cart_mesh_obj):
        self.mesh_obj = cart_mesh_obj
        self.analysis = CfdTools.getParentAnalysisObject(self.mesh_obj)

        self.part_obj = self.mesh_obj.Part  # Part to mesh
        self.scale = 0.001  # Scale mm to m

        # Default to 2 % of bounding box characteristic length
        self.clmax = Units.Quantity(self.mesh_obj.CharacteristicLengthMax).Value
        if self.clmax <= 0.0:
            shape = self.part_obj.Shape
            cl_bound_box = math.sqrt(shape.BoundBox.XLength**2 + shape.BoundBox.YLength**2 + shape.BoundBox.ZLength**2)
            self.clmax = 0.02*cl_bound_box  # Always in internal format, i.e. mm

        # Only used by gmsh - what purpose?
        self.clmin = 0.0

        self.dimension = self.mesh_obj.ElementDimension

        shape_face_names = []
        for (i, f) in enumerate(self.part_obj.Shape.Faces):
            face_name = ("face{}".format(i))
            shape_face_names.append(face_name)
        self.mesh_obj.ShapeFaceNames = shape_face_names

        self.cf_settings = {}
        self.snappy_settings = {}
        self.gmsh_settings = {}
        self.two_d_settings = {}

        self.error = False

        output_path = CfdTools.getOutputPath(self.analysis)
        self.getFilePaths(output_path)
Example #4
0
def export(objectslist, fileString):
    "called when freecad exports a mesh file supprted by gmsh generation"
    if len(objectslist) != 1:
        FreeCAD.Console.PrintError(
            "This exporter can only export one object.\n")
        return
    obj = objectslist[0]
    if not obj.isDerivedFrom("Fem::FemMeshObject"):
        FreeCAD.Console.PrintError("No FEM mesh object selected.\n")
        return
    if not obj.Proxy.Type == 'FemMeshGmsh':
        FreeCAD.Console.PrintError(
            "Object selected is not a FemMeshGmsh type\n")
        return

    gmsh = CaeMesherGmsh.CaeMesherGmsh(obj,
                                       CfdTools.getParentAnalysisObject(obj))

    if fileString != "":
        fileName, fileExtension = os.path.splitext(fileString)
        for k in CaeMesherGmsh.CaeMesherGmsh.output_format_suffix:
            if CaeMesherGmsh.CaeMesherGmsh.output_format_suffix[
                    k] == fileExtension.lower():
                ret = gmsh.export_mesh(k, fileString)
                if not ret:
                    FreeCAD.Console.PrintError(
                        "Mesh is written to `{}` by Gmsh\n".format(ret))
                return
        FreeCAD.Console.PrintError(
            "Export mesh format with suffix `{}` is not supported by Gmsh\n".
            format(fileExtension.lower()))
Example #5
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
 def setEdit(self, vobj, mode):
     analysis_object = CfdTools.getParentAnalysisObject(self.Object)
     if analysis_object is None:
         FreeCAD.Console.PrintError("Boundary must have a parent analysis object")
         return False
     # hide all meshes
     for o in FreeCAD.ActiveDocument.Objects:
         if o.isDerivedFrom("Fem::FemMeshObject"):
             o.ViewObject.hide()
     # show task panel
     taskd = _TaskPanelCfdFluidBoundary(self.Object)
     taskd.obj = vobj.Object
     FreeCADGui.Control.showDialog(taskd)
     return True
 def setEdit(self, vobj, mode):
     analysis_object = CfdTools.getParentAnalysisObject(self.Object)
     if analysis_object is None:
         CfdTools.cfdError("No parent analysis object found")
         return False
     physics_model = CfdTools.getPhysicsModel(analysis_object)
     if not physics_model:
         CfdTools.cfdError("Analysis object must have a physics object")
         return False
     import _TaskPanelCfdFluidProperties
     taskd = _TaskPanelCfdFluidProperties.TaskPanelCfdFluidProperties(self.Object, physics_model)
     taskd.obj = vobj.Object
     FreeCADGui.Control.showDialog(taskd)
     return True
Example #8
0
 def writeMesh(self):
     import importlib
     importlib.reload(CfdMeshTools)
     self.console_message_cart = ''
     self.Start = time.time()
     self.Timer.start()
     # Re-initialise CfdMeshTools with new parameters
     self.store()
     FreeCADGui.addModule("CfdMeshTools")
     FreeCADGui.addModule("CfdTools")
     FreeCADGui.doCommand(
         "FreeCAD.ActiveDocument." + self.mesh_obj.Name +
         ".Proxy.cart_mesh = "
         "CfdMeshTools.CfdMeshTools(FreeCAD.ActiveDocument." +
         self.mesh_obj.Name + ")")
     FreeCADGui.doCommand("cart_mesh = FreeCAD.ActiveDocument." +
                          self.mesh_obj.Name + ".Proxy.cart_mesh")
     cart_mesh = self.mesh_obj.Proxy.cart_mesh
     self.consoleMessage("Preparing meshing ...")
     try:
         QApplication.setOverrideCursor(Qt.WaitCursor)
         setQuantity(self.form.if_max, str(cart_mesh.getClmax()))
         print('Part to mesh:\n  Name: ' + cart_mesh.part_obj.Name +
               ', Label: ' + cart_mesh.part_obj.Label + ', ShapeType: ' +
               cart_mesh.part_obj.Shape.ShapeType)
         print('  CharacteristicLengthMax: ' + str(cart_mesh.clmax))
         analysis = CfdTools.getParentAnalysisObject(self.mesh_obj)
         FreeCADGui.doCommand(
             "cart_mesh.getFilePaths(CfdTools.getOutputPath(FreeCAD.ActiveDocument."
             + analysis.Name + "))")
         FreeCADGui.doCommand("cart_mesh.setupMeshCaseDir()")
         self.consoleMessage("Exporting mesh refinement data ...")
         FreeCADGui.doCommand("cart_mesh.processRefinements()"
                              )  # Writes stls so need file structure
         FreeCADGui.doCommand("cart_mesh.processDimension()")
         FreeCADGui.doCommand("cart_mesh.writeMeshCase()")
         self.consoleMessage("Exporting the part surfaces ...")
         FreeCADGui.doCommand("cart_mesh.writePartFile()")
         self.consoleMessage("Mesh case written to {}".format(
             self.cart_mesh.meshCaseDir))
     except Exception as ex:
         self.consoleMessage("Error " + type(ex).__name__ + ": " + str(ex),
                             '#FF0000')
         raise
     finally:
         self.Timer.stop()
         QApplication.restoreOverrideCursor()
     self.updateUI()
Example #9
0
def export_foam_mesh(obj, meshfileString, foamCaseFolder=None):
    # support only 3D
    gmsh = CaeMesherGmsh.CaeMesherGmsh(obj, CfdTools.getParentAnalysisObject(obj))
    meshfile = gmsh.export_mesh(u"Gmsh MSH", meshfileString)
    if meshfile:
        msg = "Info: Mesh is not written to `{}` by Gmsh\n".format(meshfile)
        FreeCAD.Console.PrintMessage(msg)
        if not foamCaseFolder:
            comandlist = [u'gmshToFoam', u'-case', foamCaseFolder, meshfile]
        else:
            comandlist = [u'gmshToFoam', meshfile]
        return _run_command(comandlist)
    else:
        error = "Mesh is NOT written to `{}` by Gmsh\n".format(meshfileString)
        FreeCAD.Console.PrintError(error)
        return error
Example #10
0
    def __init__(self, solver):
        if solver and solver.isDerivedFrom("Fem::FemSolverObjectPython"):
            ## @var solver
            #  solver of the analysis. Used to store the active solver and analysis parameters
            self.solver = solver
        else:
            raise TypeError(
                "FemSolver object is missing in constructing CfdRunnable object"
            )
        self.analysis = CfdTools.getParentAnalysisObject(self.solver)

        if self.analysis:
            self.results_present = False
            self.result_object = None
        else:
            raise Exception('FEM: No active analysis found!')
Example #11
0
    def setEdit(self, vobj, mode):
        analysis_object = CfdTools.getParentAnalysisObject(self.Object)
        if analysis_object is None:
            CfdTools.cfdError("No parent analysis object found")
            return False
        physics_model, is_present = CfdTools.getPhysicsModel(analysis_object)
        if not is_present:
            CfdTools.cfdError("Analysis object must have a physics object")
            return False
        boundaries = CfdTools.getCfdBoundaryGroup(analysis_object)

        import _TaskPanelCfdInitialiseInternalFlowField
        taskd = _TaskPanelCfdInitialiseInternalFlowField._TaskPanelCfdInitialiseInternalFlowField(
            self.Object, physics_model, boundaries)
        taskd.obj = vobj.Object
        FreeCADGui.Control.showDialog(taskd)
        return True
Example #12
0
    def accept(self):
        changed_transient = False
        if self.obj.PhysicsModel['Time'] != self.physicsModel['Time']:
            changed_transient = True

        self.obj.PhysicsModel = self.physicsModel
        doc = FreeCADGui.getDocument(self.obj.Document)
        doc.resetEdit()

        FreeCADGui.doCommand(
            "\nphys = FreeCAD.ActiveDocument.{}.PhysicsModel".format(
                self.obj.Name))
        FreeCADGui.doCommand("phys['Time'] = '{}'".format(
            self.physicsModel['Time']))
        FreeCADGui.doCommand("phys['Flow'] = '{}'".format(
            self.physicsModel['Flow']))
        FreeCADGui.doCommand("phys['Turbulence'] = '{}'".format(
            self.physicsModel['Turbulence']))
        FreeCADGui.doCommand("phys['TurbulenceModel'] = '{}'".format(
            self.physicsModel['TurbulenceModel']))
        FreeCADGui.doCommand("phys['Thermal'] = {}".format(
            self.physicsModel['Thermal']))
        FreeCADGui.doCommand("phys['Gravity'] = {}".format(
            self.physicsModel['Gravity']))
        FreeCADGui.doCommand(
            "FreeCAD.ActiveDocument.{}.PhysicsModel = phys".format(
                self.obj.Name))

        if changed_transient:
            # TODO
            # For now, init the solver object's time values to sensible defaults for steady or transient
            # The user can then edit further
            a = CfdTools.getParentAnalysisObject(self.obj)
            if a:
                sol = CfdTools.getSolver(a)
                if sol:
                    FreeCADGui.doCommand(
                        "\nsol = FreeCAD.ActiveDocument.{}".format(sol.Name))
                    if self.obj.PhysicsModel['Time'] == 'Steady':
                        FreeCADGui.doCommand("sol.EndTime = 1000\n"
                                             "sol.TimeStep = 1\n"
                                             "sol.WriteInterval = 100\n")
                    else:
                        FreeCADGui.doCommand("sol.EndTime = 1\n"
                                             "sol.TimeStep = 0.001\n"
                                             "sol.WriteInterval = 0.1\n")
Example #13
0
    def initialiseUponReload(self):
        if self.physicsModel['Time'] == 'Steady':
            self.form.radioButtonSteady.toggle()
        elif self.physicsModel['Time'] == 'Transient':
            self.form.radioButtonTransient.toggle()

        if self.physicsModel['Flow'] == 'Incompressible':
            self.form.radioButtonIncompressible.toggle()
        elif self.physicsModel['Flow'] == 'Compressible':
            self.form.radioButtonCompressible.toggle()

        if self.physicsModel['Turbulence'] == 'Laminar':
            self.form.turbulenceCheckBox.toggle()
            self.form.radioButtonLaminar.toggle()
        elif self.physicsModel['Turbulence'] == 'RANS':
            self.form.turbulenceCheckBox.toggle()
            self.form.radioButtonRANS.toggle()
        ti = CfdTools.indexOrDefault(RANS_MODELS,
                                     self.physicsModel.get('TurbulenceType'),
                                     0)
        self.form.turbulenceComboBox.setCurrentIndex(ti)

        if self.physicsModel['Thermal'] == "Energy":
            self.form.thermalCheckBox.toggle()
            self.form.radioButtonEnergy.toggle()
        elif self.physicsModel['Thermal'] == "Buoyancy":
            self.form.thermalCheckBox.toggle()
            self.form.radioButtonBuoyancy.toggle()

        material_objs = CfdTools.getMaterials(
            CfdTools.getParentAnalysisObject(self.obj))
        if len(material_objs) > 1:
            self.form.gravityFrame.setVisible(True)
            # Add if absent for backward file compatibility
            if not self.physicsModel.get('Gravity'):
                self.physicsModel['Gravity'] = {
                    'gx': 0.0,
                    'gy': -9.81,
                    'gz': 0.0
                }
            gx = self.physicsModel['Gravity']['gx']
            gy = self.physicsModel['Gravity']['gy']
            gz = self.physicsModel['Gravity']['gz']
            setInputFieldQuantity(self.form.gx, "{} m/s^2".format(gx))
            setInputFieldQuantity(self.form.gy, "{} m/s^2".format(gy))
            setInputFieldQuantity(self.form.gz, "{} m/s^2".format(gz))
Example #14
0
    def __init__(self, obj):

        self.obj = obj
        analysis_obj = CfdTools.getParentAnalysisObject(obj)
        solver_obj = CfdTools.getSolver(analysis_obj)
        material_objs = CfdTools.getMaterials(analysis_obj)

        self.boundaryWidget = CfdBoundaryWidget(obj, None, solver_obj,
                                                material_objs)
        # fill the table in each variable tab, saved from the previous setup, existing case if BC name, done in each widget

        # geometry selection widget, only face is needed as boundary for CFD
        # GeometryElementsSelection(ref, eltypes=[], multigeom=True)  # allow_multiple_geom_types = multigeom
        self.selectionWidget = FemSelectionWidgets.GeometryElementsSelection(
            obj.References, ['Face'], False)
        # check references, has to be after initialization of selectionWidget
        try:
            self.selectionWidget.has_equal_references_shape_types(
            )  # boundarySelector has no such method
        except:
            print(
                '`selectionWidget.has_equal_references_shape_types()` is only available in FreeCAD 0.18+'
            )

        #the magic to have two widgets in one taskpanel
        self.form = [self.selectionWidget, self.boundaryWidget]
        if True:  # todo: check if solver is 'OpenFOAM'
            from CfdFoamTools import getVariableList
            solverSettings = CfdTools.getSolverSettings(
                solver_obj)  # physical_model
            variable_list = getVariableList(solverSettings)

            # TODO: if boundary_settings is empty dict, default setting for each variable could be provided
            if "FoamBoundarySettings" in self.obj.PropertiesList and self.obj.FoamBoundarySettings:
                self.foam_boundary_conditions = self.obj.FoamBoundarySettings
            else:
                print("debug print: variable_list", variable_list)
                self.foam_boundary_conditions = {
                    var: {}
                    for var in variable_list
                }  # {varible: bc_dict, ...}

            from FoamCaseBuilder.FoamBoundaryWidget import FoamBoundaryWidget
            s = {"variables": self.foam_boundary_conditions}
            self.foamWidget = FoamBoundaryWidget(s)
            self.form.append(self.foamWidget)
    def setEdit(self, vobj, mode):
        analysis_object = CfdTools.getParentAnalysisObject(self.Object)
        if analysis_object is None:
            CfdTools.cfdError("Boundary must have a parent analysis object")
            return False
        physics_model, is_present = CfdTools.getPhysicsModel(analysis_object)
        if not is_present:
            CfdTools.cfdError("Analysis object must have a physics object")
            return False

        import _TaskPanelCfdFluidBoundary
        taskd = _TaskPanelCfdFluidBoundary.TaskPanelCfdFluidBoundary(self.Object, physics_model)
        for obj in FreeCAD.ActiveDocument.Objects:
            if obj.isDerivedFrom("Fem::FemMeshObject"):
                obj.ViewObject.hide()
                obj.Part.ViewObject.show()
        self.Object.ViewObject.show()
        taskd.obj = vobj.Object
        FreeCADGui.Control.showDialog(taskd)
        return True
    def __init__(self, cart_mesh_obj):
        self.mesh_obj = cart_mesh_obj
        self.analysis = CfdTools.getParentAnalysisObject(self.mesh_obj)

        self.part_obj = self.mesh_obj.Part  # Part to mesh
        self.scale = 0.001  # Scale mm to m

        # Default to 2 % of bounding box characteristic length
        self.clmax = Units.Quantity(
            self.mesh_obj.CharacteristicLengthMax).Value
        if self.clmax <= 0.0:
            shape = self.part_obj.Shape
            cl_bound_mag = math.sqrt(shape.BoundBox.XLength**2 +
                                     shape.BoundBox.YLength**2 +
                                     shape.BoundBox.ZLength**2)
            cl_bound_min = min(
                min(shape.BoundBox.XLength, shape.BoundBox.YLength),
                shape.BoundBox.ZLength)
            self.clmax = min(
                0.02 * cl_bound_mag,
                0.4 * cl_bound_min)  # Always in internal format, i.e. mm

        # Only used by gmsh - what purpose?
        self.clmin = 0.0

        self.dimension = self.mesh_obj.ElementDimension

        self.cf_settings = {}
        self.snappy_settings = {}
        self.gmsh_settings = {}
        self.two_d_settings = {}

        self.error = False

        output_path = CfdTools.getOutputPath(self.analysis)
        self.getFilePaths(output_path)

        # 2D array of list of faces (index into shape) in each patch, indexed by [bc_id+1][meshregion_id+1]
        self.patch_faces = []
        # 2D array of names of each patch, indexed by [bc_id+1][meshregion_id+1]
        self.patch_names = []
    def __init__(self, obj):

        self.obj = obj
        analysis_obj = CfdTools.getParentAnalysisObject(obj)
        solver_obj = CfdTools.getSolver(analysis_obj)
        material_objs = CfdTools.getMaterials(analysis_obj)

        from CfdBoundaryWidget import CfdBoundaryWidget
        self.boundaryWidget = CfdBoundaryWidget(obj, None, solver_obj, material_objs)
        # fill the table in each variable tab, saved from the previous setup, existing case if BC name, done in each widget

        # geometry selection widget, only face is needed as boundary
        self.selectionWidget = FemSelectionWidgets.BoundarySelector()
        self.selectionWidget.setReferences(obj.References)
        # check references, has to be after initialisation of selectionWidget
        try:
            self.selectionWidget.has_equal_references_shape_types()
        except:
            RuntimeError('this function only works for FreeCAD 0.18')

        #the magic to have two widgets in one taskpanel
        self.form = [self.selectionWidget, self.boundaryWidget]
        if True:  # todo: check if solver is 'OpenFOAM'
            from CfdFoamTools import getVariableList
            solverSettings = CfdTools.getSolverSettings(solver_obj)  # physical_model
            variable_list = getVariableList(solverSettings)

            # build a parameterTabWidget, with each tab has a tableView
            # TODO: if boundary_settings is empty dict, default setting for each variable could be provided
            if not self.obj.FoamBoundarySettings:
                self.foam_boundary_conditions = {'U': {"key": "value"}, 'p':{"key": "value"}}  # {varible: bc_dict, ...}
            else:
                self.foam_boundary_conditions = self.obj.FoamBoundarySettings
            from FoamCaseBuilder.FoamBoundaryWidget import FoamBoundaryWidget
            self.foamWidget = FoamBoundaryWidget(self.foam_boundary_conditions)
            self.form.append(self.foamWidget)
Example #18
0
    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")
Example #19
0
    def __init__(self, obj):
        FreeCADGui.Selection.clearSelection()
        self.sel_server = None
        self.obj = obj
        self.shapeListOrig = list(self.obj.shapeList)
        self.partNameList = list(self.obj.partNameList)
        self.partNameListOrig = list(self.obj.partNameList)

        self.form = FreeCADGui.PySideUic.loadUi(os.path.join(os.path.dirname(__file__), "TaskPanelCfdZone.ui"))

        self.form.selectReference.clicked.connect(self.selectReference)
        self.form.listWidget.itemPressed.connect(self.setSelection)
        self.form.pushButtonDelete.clicked.connect(self.deleteFeature)

        if self.obj.Name.startswith('PorousZone'):
            self.p = dict(self.obj.porousZoneProperties)
            self.form.stackedWidgetZoneType.setCurrentIndex(0)

            self.form.comboBoxCorrelation.currentIndexChanged.connect(self.comboBoxCorrelationChanged)

            self.form.e1x.textEdited.connect(self.e1Changed)
            self.form.e1y.textEdited.connect(self.e1Changed)
            self.form.e1z.textEdited.connect(self.e1Changed)
            self.form.e2x.textEdited.connect(self.e2Changed)
            self.form.e2y.textEdited.connect(self.e2Changed)
            self.form.e2z.textEdited.connect(self.e2Changed)
            self.form.e3x.textEdited.connect(self.e3Changed)
            self.form.e3y.textEdited.connect(self.e3Changed)
            self.form.e3z.textEdited.connect(self.e3Changed)
            self.form.e1x.editingFinished.connect(self.e1Done)
            self.form.e1y.editingFinished.connect(self.e1Done)
            self.form.e1z.editingFinished.connect(self.e1Done)
            self.form.e2x.editingFinished.connect(self.e2Done)
            self.form.e2y.editingFinished.connect(self.e2Done)
            self.form.e2z.editingFinished.connect(self.e2Done)
            self.form.e3x.editingFinished.connect(self.e3Done)
            self.form.e3y.editingFinished.connect(self.e3Done)
            self.form.e3z.editingFinished.connect(self.e3Done)
            self.lastEVectorChanged = 1
            self.lastLastEVectorChanged = 2

            self.form.comboAspectRatio.currentIndexChanged.connect(self.comboAspectRatioChanged)

            self.form.pushButtonDelete.setEnabled(False)

            self.form.comboBoxCorrelation.addItems(POROUS_CORRELATION_NAMES)
            self.form.comboAspectRatio.addItems(ASPECT_RATIO_NAMES)

        elif self.obj.Name.startswith('InitialisationZone'):
            self.p = dict(self.obj.initialisationZoneProperties)
            self.form.stackedWidgetZoneType.setCurrentIndex(1)

            self.form.comboFluid.currentIndexChanged.connect(self.comboFluidChanged)
            self.form.checkAlpha.stateChanged.connect(self.checkAlphaChanged)
            self.form.checkVelocity.stateChanged.connect(self.checkVelocityChanged)
            self.form.checkPressure.stateChanged.connect(self.checkPressureChanged)
            self.form.inputVolumeFraction.valueChanged.connect(self.inputVolumeFractionChanged)
            self.form.inputUx.valueChanged.connect(self.inputUxChanged)
            self.form.inputUy.valueChanged.connect(self.inputUyChanged)
            self.form.inputUz.valueChanged.connect(self.inputUzChanged)
            self.form.inputPressure.valueChanged.connect(self.inputPressureChanged)

            material_objs = CfdTools.getMaterials(CfdTools.getParentAnalysisObject(obj))
            self.form.frameVolumeFraction.setVisible(len(material_objs) > 1)
            if len(material_objs) > 1:
                fluid_names = [m.Label for m in material_objs]
                self.form.comboFluid.addItems(fluid_names[:-1])

        self.setInitialValues()
Example #20
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
                            }
    def __init__(self, obj):
        FreeCADGui.Selection.clearSelection()
        self.sel_server = None
        self.obj = obj

        self.ReferencesOrig = list(self.obj.References)

        self.form = FreeCADGui.PySideUic.loadUi(
            os.path.join(os.path.dirname(__file__), "TaskPanelCfdZone.ui"))

        self.form.framePorousZone.setVisible(False)
        self.form.frameInitialisationZone.setVisible(False)

        self.alphas = {}

        if self.obj.Name.startswith('PorousZone'):
            self.form.framePorousZone.setVisible(True)

            self.form.comboBoxCorrelation.currentIndexChanged.connect(
                self.updateUI)

            self.form.e1x.textEdited.connect(self.e1Changed)
            self.form.e1y.textEdited.connect(self.e1Changed)
            self.form.e1z.textEdited.connect(self.e1Changed)
            self.form.e2x.textEdited.connect(self.e2Changed)
            self.form.e2y.textEdited.connect(self.e2Changed)
            self.form.e2z.textEdited.connect(self.e2Changed)
            self.form.e3x.textEdited.connect(self.e3Changed)
            self.form.e3y.textEdited.connect(self.e3Changed)
            self.form.e3z.textEdited.connect(self.e3Changed)
            self.form.e1x.editingFinished.connect(self.e1Done)
            self.form.e1y.editingFinished.connect(self.e1Done)
            self.form.e1z.editingFinished.connect(self.e1Done)
            self.form.e2x.editingFinished.connect(self.e2Done)
            self.form.e2y.editingFinished.connect(self.e2Done)
            self.form.e2z.editingFinished.connect(self.e2Done)
            self.form.e3x.editingFinished.connect(self.e3Done)
            self.form.e3y.editingFinished.connect(self.e3Done)
            self.form.e3z.editingFinished.connect(self.e3Done)
            self.lastEVectorChanged = 1
            self.lastLastEVectorChanged = 2

            self.form.comboAspectRatio.currentIndexChanged.connect(
                self.comboAspectRatioChanged)

            self.form.comboBoxCorrelation.addItems(
                CfdZone.POROUS_CORRELATION_NAMES)
            self.form.comboAspectRatio.addItems(CfdZone.ASPECT_RATIO_NAMES)

        elif self.obj.Name.startswith('InitialisationZone'):
            self.form.frameInitialisationZone.setVisible(True)

            self.form.comboFluid.currentIndexChanged.connect(
                self.comboFluidChanged)
            self.form.checkAlpha.stateChanged.connect(self.updateUI)
            self.form.checkVelocity.stateChanged.connect(self.updateUI)
            self.form.checkPressure.stateChanged.connect(self.updateUI)
            self.form.inputVolumeFraction.valueChanged.connect(
                self.inputVolumeFractionChanged)

            material_objs = CfdTools.getMaterials(
                CfdTools.getParentAnalysisObject(obj))
            self.form.frameVolumeFraction.setVisible(len(material_objs) > 1)
            if len(material_objs) > 1:
                fluid_names = [m.Label for m in material_objs]
                self.form.comboFluid.addItems(fluid_names[:-1])

        self.load()
        self.comboFluidChanged()
        self.updateUI()

        # Face list selection panel - modifies obj.References passed to it
        self.faceSelector = CfdFaceSelectWidget.CfdFaceSelectWidget(
            self.form.faceSelectWidget, self.obj, False, True)
Example #22
0
    def accept(self):
        doc = FreeCADGui.getDocument(self.obj.Document)
        doc.resetEdit()

        FreeCADGui.doCommand("\nobj = FreeCAD.ActiveDocument.{}".format(
            self.obj.Name))
        changed_transient = False
        if self.form.radioButtonSteady.isChecked():
            if self.obj.Time != 'Steady':
                changed_transient = True
            FreeCADGui.doCommand("obj.Time = 'Steady'")
        elif self.form.radioButtonTransient.isChecked():
            if self.obj.Time != 'Transient':
                changed_transient = True
            FreeCADGui.doCommand("obj.Time = 'Transient'")

        if self.form.radioButtonSinglePhase.isChecked():
            FreeCADGui.doCommand("obj.Phase = 'Single'")
        elif self.form.radioButtonFreeSurface.isChecked():
            FreeCADGui.doCommand("obj.Phase = 'FreeSurface'")

        if self.form.radioButtonIncompressible.isChecked():
            FreeCADGui.doCommand("obj.Flow = 'Incompressible'")
            FreeCADGui.doCommand("obj.Thermal = 'None'")
        elif self.form.radioButtonCompressible.isChecked():
            if self.form.checkBoxHighMach.isChecked():
                FreeCADGui.doCommand("obj.Flow = 'HighMachCompressible'")
                FreeCADGui.doCommand("obj.Thermal = 'Energy'")
            else:
                FreeCADGui.doCommand("obj.Flow = 'Compressible'")
                FreeCADGui.doCommand("obj.Thermal = 'None'")

        if self.form.viscousCheckBox.isChecked():
            if self.form.radioButtonLaminar.isChecked():
                FreeCADGui.doCommand("obj.Turbulence = 'Laminar'")
            elif self.form.radioButtonRANS.isChecked():
                FreeCADGui.doCommand("obj.Turbulence = 'RANS'")
                FreeCADGui.doCommand("obj.TurbulenceModel = '{}'".format(
                    self.form.turbulenceComboBox.currentText()))
        else:
            FreeCADGui.doCommand("obj.Turbulence = 'Inviscid'")

        #if self.form.radioButtonEnergy.isChecked():
        #    FreeCADGui.doCommand("obj.Thermal = 'Energy'")
        #elif self.form.radioButtonBuoyancy.isChecked():
        #    FreeCADGui.doCommand("obj.Thermal = 'Buoyancy'")

        FreeCADGui.doCommand("obj.gx = '{}'".format(self.form.gx.text()))
        FreeCADGui.doCommand("obj.gy = '{}'".format(self.form.gy.text()))
        FreeCADGui.doCommand("obj.gz = '{}'".format(self.form.gz.text()))

        if changed_transient:
            # TODO
            # For now, init the solver object's time values to sensible defaults for steady or transient
            # The user can then edit further
            a = CfdTools.getParentAnalysisObject(self.obj)
            if a:
                sol = CfdTools.getSolver(a)
                if sol:
                    FreeCADGui.doCommand(
                        "\nsol = FreeCAD.ActiveDocument.{}".format(sol.Name))
                    if self.obj.Time == 'Steady':
                        FreeCADGui.doCommand("sol.EndTime = 1000\n"
                                             "sol.TimeStep = 1\n"
                                             "sol.WriteInterval = 100\n")
                    else:
                        FreeCADGui.doCommand("sol.EndTime = 1\n"
                                             "sol.TimeStep = 0.001\n"
                                             "sol.WriteInterval = 0.1\n")