示例#1
0
    def setupPatchNames(self):
        print('Populating createPatchDict to update BC names')
        import CfdMeshTools
        # Init in case not meshed yet
        CfdMeshTools.CfdMeshTools(self.mesh_obj)
        settings = self.settings
        settings['createPatches'] = {}
        bc_group = self.bc_group
        mobj = self.mesh_obj

        # Make list of list of all boundary references for their corresponding boundary
        boundary_ref_lists = []
        for bc_id, bc_obj in enumerate(bc_group):
            boundary_ref_lists.append(bc_obj.References)

        # Match them up with faces in the meshed part
        matched_faces = CfdTools.matchFacesToTargetShape(
            boundary_ref_lists, mobj.Part.Shape)

        bc_lists = []
        for bc in bc_group:
            bc_lists.append([])
        for i in range(len(matched_faces)):
            if matched_faces[i]:
                nb, bref = matched_faces[i][0]
                bc_lists[nb].append(mobj.ShapeFaceNames[i])
                for k in range(len(matched_faces[i]) - 1):
                    nb2, bref2 = matched_faces[i][k + 1]
                    if nb2 != nb:
                        cfdMessage(
                            "Boundary '{}' reference {}:{} also assigned as "
                            "boundary '{}' reference {}:{}\n".format(
                                bc_group[nb].Label, bref[0], bref[1],
                                bc_group[nb2].Label, bref2[0], bref2[1]))

        for bc_id, bc_obj in enumerate(bc_group):
            bcType = bc_obj.BoundaryType
            bcSubType = bc_obj.BoundarySubType
            patchType = CfdTools.getPatchType(bcType, bcSubType)
            settings['createPatches'][bc_obj.Label] = {
                'PatchNamesList':
                tuple(bc_lists[bc_id]
                      ),  # Tuple used so that case writer outputs as an array
                'PatchType': patchType
            }

        if self.mesh_obj.MeshUtility == 'snappyHexMesh':
            for regionObj in CfdTools.getMeshRefinementObjs(self.mesh_obj):
                if regionObj.Baffle:
                    settings['createPatchesFromSnappyBaffles'] = True

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

        # Add default faces
        flagName = False
        def_bc_list = []
        for i in range(len(matched_faces)):
            if not matched_faces[i]:
                def_bc_list.append(mobj.ShapeFaceNames[i])
                flagName = True
        if flagName:
            settings['createPatches']['defaultFaces'] = {
                'PatchNamesList': tuple(def_bc_list),
                'PatchType': "patch"
            }
示例#2
0
    def writeCase(self, progressCallback=None):
        """ writeCase() will collect case settings, and finally build a runnable case. """
        cfdMessage("Start to write case to folder {}\n".format(
            self.working_dir))
        if not os.path.exists(self.working_dir):
            raise IOError("Path " + self.solver_obj.working_dir +
                          " does not exist.")

        # Perform initialisation here rather than __init__ in case of path changes
        self.case_folder = os.path.join(self.working_dir,
                                        self.solver_obj.InputCaseName)
        self.case_folder = os.path.expanduser(os.path.abspath(
            self.case_folder))
        self.mesh_file_name = os.path.join(self.case_folder,
                                           self.solver_obj.InputCaseName,
                                           u".unv")

        self.template_path = os.path.join(CfdTools.get_module_path(), "data",
                                          "defaults")

        # Collect settings into single dictionary
        if not self.mesh_obj:
            raise RuntimeError("No mesh object found in analysis")
        phys_settings = CfdTools.propsToDict(self.physics_model)

        # TODO: Make sure boundary labels are unique and valid

        self.settings = {
            'physics':
            phys_settings,
            'fluidProperties': [],  # Order is important, so use a list
            'initialValues':
            CfdTools.propsToDict(self.initial_conditions),
            'boundaries':
            dict((b.Label, CfdTools.propsToDict(b)) for b in self.bc_group),
            'bafflesPresent':
            self.bafflesPresent(),
            'porousZones': {},
            'porousZonesPresent':
            False,
            'initialisationZones': {
                o.Label: CfdTools.propsToDict(o)
                for o in self.initialisationZone_objs
            },
            'initialisationZonesPresent':
            len(self.initialisationZone_objs) > 0,
            'zones': {
                o.Label: {
                    'PartNameList': tuple(r[0] for r in o.References)
                }
                for o in self.zone_objs
            },
            'zonesPresent':
            len(self.zone_objs) > 0,
            'meshType':
            self.mesh_obj.Proxy.Type,
            'meshDimension':
            self.mesh_obj.ElementDimension,
            'meshDir':
            "../" + self.mesh_obj.CaseName,
            'solver':
            CfdTools.propsToDict(self.solver_obj),
            'system': {},
            'runChangeDictionary':
            False
        }

        self.processSystemSettings()
        self.processSolverSettings()
        self.processFluidProperties()
        self.processBoundaryConditions()
        self.processInitialConditions()
        self.clearCase()

        self.exportZoneStlSurfaces()
        if self.porousZone_objs:
            self.processPorousZoneProperties()
        self.processInitialisationZoneProperties()

        self.settings['createPatchesFromSnappyBaffles'] = False
        cfdMessage("Matching boundary conditions ...\n")
        if progressCallback:
            progressCallback("Matching boundary conditions ...")
        self.setupPatchNames()

        TemplateBuilder.TemplateBuilder(self.case_folder, self.template_path,
                                        self.settings)

        # Update Allrun permission - will fail silently on Windows
        fname = os.path.join(self.case_folder, "Allrun")
        import stat
        s = os.stat(fname)
        os.chmod(fname, s.st_mode | stat.S_IEXEC)

        cfdMessage("Successfully wrote case to folder {}\n".format(
            self.working_dir))
        return True
示例#3
0
    def setupPatchNames(self):
        print('Populating createPatchDict to update BC names')
        import CfdMeshTools
        # Init in case not meshed yet
        CfdMeshTools.CfdMeshTools(self.mesh_obj)
        settings = self.settings
        settings['createPatches'] = {}
        bc_group = self.bc_group
        mobj = self.mesh_obj

        # Make list of all boundary references
        boundary_face_list = []
        for bc_id, bc_obj in enumerate(bc_group):
            for ref in bc_obj.References:
                obj = FreeCAD.ActiveDocument.getObject(ref[0])
                if not obj:
                    raise RuntimeError(
                        "Referenced object '{}' not found - object may "
                        "have been deleted".format(ref[0]))
                try:
                    bf = obj.Shape.getElement(ref[1])
                except Part.OCCError:
                    raise RuntimeError(
                        "Referenced face '{}:{}' not found - face may "
                        "have been deleted".format(ref[0], ref[1]))
                boundary_face_list.append((bf, (bc_id, ref)))

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

        # Match them up
        matched_faces = CfdTools.matchFaces(boundary_face_list, mesh_face_list)

        # Check for and filter duplicates
        match_per_shape_face = [-1] * len(mesh_face_list)
        for k in range(len(matched_faces)):
            match = matched_faces[k][1]
            prev_k = match_per_shape_face[match]
            if prev_k >= 0:
                nb, bref = matched_faces[k][0]
                nb2, bref2 = matched_faces[prev_k][0]
                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:
                match_per_shape_face[match] = k

        bc_lists = [[] for g in bc_group]
        for i in range(len(match_per_shape_face)):
            k = match_per_shape_face[i]
            if k >= 0:
                nb, bref = matched_faces[k][0]
                bc_lists[nb].append(mobj.ShapeFaceNames[i])

        for bc_id, bc_obj in enumerate(bc_group):
            bcType = bc_obj.BoundaryType
            bcSubType = bc_obj.BoundarySubType
            patchType = CfdTools.getPatchType(bcType, bcSubType)
            settings['createPatches'][bc_obj.Label] = {
                'PatchNamesList':
                tuple(bc_lists[bc_id]
                      ),  # Tuple used so that case writer outputs as an array
                'PatchType': patchType
            }

        if self.mesh_obj.MeshUtility == 'snappyHexMesh':
            for regionObj in CfdTools.getMeshRefinementObjs(self.mesh_obj):
                if regionObj.Baffle:
                    settings['createPatchesFromSnappyBaffles'] = True

        if settings['createPatchesFromSnappyBaffles']:
            settings['createPatchesSnappyBaffles'] = {}
            baffle_geoms = []
            for regionObj in self.mesh_obj.Group:
                if hasattr(regionObj, "Proxy") and isinstance(
                        regionObj.Proxy, CfdMeshRefinement._CfdMeshRefinement):
                    if regionObj.Baffle:
                        for sub in regionObj.References:
                            elems = sub[1]
                            elt = FreeCAD.ActiveDocument.getObject(
                                sub[0]).Shape.getElement(elems)
                            if elt.ShapeType == 'Face':
                                baffle_geoms.append(
                                    (elt, (regionObj.Name + sub[0] + elems,
                                           len(baffle_geoms))))

            print(boundary_face_list)
            matched_baffle_faces = CfdTools.matchFaces(boundary_face_list,
                                                       baffle_geoms)

            # Check for duplicates
            match_per_baffle_face = [-1] * len(baffle_geoms)
            for matchi, mf in enumerate(matched_baffle_faces):
                if match_per_baffle_face[mf[1][1]] > -1:
                    cfdMessage("Baffle face matches to boundary " + mf[0][1] +
                               " and " + matched_baffle_faces[
                                   match_per_baffle_face[mf[1][1]]][0][1] +
                               " - discarding duplicate")
                else:
                    match_per_baffle_face[mf[1][1]] = matchi

            for bfi, mi in enumerate(match_per_baffle_face):
                if mi > -1:
                    mf = matched_baffle_faces[mi]
                    bc_label = bc_group[mf[0][0]].Label
                    settings['createPatchesSnappyBaffles'][bc_label] = \
                        settings['createPatchesSnappyBaffles'].get(bc_label, {})
                    settings['createPatchesSnappyBaffles'][bc_label]['PatchNamesList'] = \
                        settings['createPatchesSnappyBaffles'][bc_label].get('PatchNamesList', ()) + \
                        (mf[1][0],)
                    settings['createPatchesSnappyBaffles'][bc_label]['PatchNamesListSlave'] = \
                        settings['createPatchesSnappyBaffles'][bc_label].get('PatchNamesListSlave', ()) + \
                        ((mf[1][0]+"_slave"),)
                else:
                    cfdMessage(
                        "No boundary condition specified for baffle face " +
                        baffle_geoms[bfi][1][0])

        # Add default faces
        flagName = False
        def_bc_list = []
        for i in range(len(match_per_shape_face)):
            if match_per_shape_face[i] < 0:
                def_bc_list.append(mobj.ShapeFaceNames[i])
                flagName = True
        if flagName:
            settings['createPatches']['defaultFaces'] = {
                'PatchNamesList': tuple(def_bc_list),
                'PatchType': "patch"
            }
示例#4
0
    def writeCase(self):
        """ writeCase() will collect case settings, and finally build a runnable case. """
        cfdMessage("Start to write case to folder {}\n".format(
            self.working_dir))
        if not os.path.exists(self.working_dir):
            raise IOError("Path " + self.solver_obj.working_dir +
                          " does not exist.")

        # Perform initialisation here rather than __init__ in case of path changes
        self.case_folder = os.path.join(self.working_dir,
                                        self.solver_obj.InputCaseName)
        self.case_folder = os.path.expanduser(os.path.abspath(
            self.case_folder))
        self.mesh_file_name = os.path.join(self.case_folder,
                                           self.solver_obj.InputCaseName,
                                           u".unv")

        self.template_path = os.path.join(CfdTools.get_module_path(), "data",
                                          "defaults")

        solverSettingsDict = CfdTools.getSolverSettings(self.solver_obj)

        # Collect settings into single dictionary
        if not self.mesh_obj:
            raise RuntimeError("No mesh object found in analysis")
        phys_settings = dict(
            zip(self.physics_model.PropertiesList,
                (getattr(self.physics_model, prop)
                 for prop in self.physics_model.PropertiesList)))
        if 'gx' in phys_settings:
            phys_settings['gx'] = Units.Quantity(
                phys_settings['gx']).getValueAs('m/s^2')
            phys_settings['gy'] = Units.Quantity(
                phys_settings['gy']).getValueAs('m/s^2')
            phys_settings['gz'] = Units.Quantity(
                phys_settings['gz']).getValueAs('m/s^2')

        self.settings = {
            'physics':
            phys_settings,
            'fluidProperties': [],  # Order is important, so use a list
            'initialValues':
            self.initial_conditions,
            'boundaries':
            dict((b.Label, b.BoundarySettings) for b in self.bc_group),
            'bafflesPresent':
            self.bafflesPresent(),
            'porousZones': {},
            'porousZonesPresent':
            False,
            'initialisationZones': {
                o.Label: o.initialisationZoneProperties
                for o in self.initialisationZone_objs
            },
            'initialisationZonesPresent':
            len(self.initialisationZone_objs) > 0,
            'zones': {
                o.Label: {
                    'PartNameList': tuple(o.partNameList)
                }
                for o in self.zone_objs
            },
            'zonesPresent':
            len(self.zone_objs) > 0,
            'meshType':
            self.mesh_obj.Proxy.Type,
            'meshDimension':
            self.mesh_obj.ElementDimension,
            'solver':
            solverSettingsDict,
            'system': {},
            'runChangeDictionary':
            False
        }

        self.processSystemSettings()
        self.processSolverSettings()
        self.processFluidProperties()
        self.processBoundaryConditions()
        self.processInitialConditions()
        self.clearCase()

        self.exportZoneStlSurfaces()
        if self.porousZone_objs:
            self.processPorousZoneProperties()
        self.processInitialisationZoneProperties()

        self.settings['createPatchesFromSnappyBaffles'] = False
        cfdMessage("Matching boundary conditions ...\n")
        self.setupPatchNames()

        TemplateBuilder.TemplateBuilder(self.case_folder, self.template_path,
                                        self.settings)
        self.writeMesh()

        # Update Allrun permission - will fail silently on Windows
        fname = os.path.join(self.case_folder, "Allrun")
        import stat
        s = os.stat(fname)
        os.chmod(fname, s.st_mode | stat.S_IEXEC)

        # Move mesh files, after being edited, to polyMesh.org
        CfdTools.movePolyMesh(self.case_folder)

        cfdMessage("Successfully wrote {} case to folder {}\n".format(
            self.solver_obj.SolverName, self.working_dir))
        return True
示例#5
0
    def writeCase(self):
        """ writeCase() will collect case settings, and finally build a runnable case. """
        cfdMessage("Start to write case to folder {}\n".format(self.solver_obj.WorkingDir))
        cwd = os.curdir
        if not os.path.exists(self.solver_obj.WorkingDir):
            raise IOError("Path " + self.solver_obj.WorkingDir + " does not exist.")
        os.chdir(self.solver_obj.WorkingDir)

        try:  # Make sure we restore cwd after exception here
            # Perform initialisation here rather than __init__ in case of path changes
            self.case_folder = os.path.join(self.solver_obj.WorkingDir, self.solver_obj.InputCaseName)
            self.case_folder = os.path.expanduser(os.path.abspath(self.case_folder))
            self.mesh_file_name = os.path.join(self.case_folder, self.solver_obj.InputCaseName, u".unv")

            self.template_path = os.path.join(CfdTools.get_module_path(), "data", "defaults")

            solverSettingsDict = CfdTools.getSolverSettings(self.solver_obj)

            self.check2DConversion()

            # Collect settings into single dictionary
            if not self.mesh_obj:
                raise RuntimeError("No mesh object found in analysis")
            self.settings = {
                'physics': self.physics_model,
                'fluidProperties': [],  # Order is important, so use a list
                'initialValues': self.initial_conditions,
                'boundaries': dict((b.Label, b.BoundarySettings) for b in self.bc_group),
                'bafflesPresent': self.bafflesPresent(),
                'porousZones': {},
                'porousZonesPresent': False,
                'initialisationZones': {o.Label: o.initialisationZoneProperties for o in self.initialisationZone_objs},
                'initialisationZonesPresent': len(self.initialisationZone_objs) > 0,
                'zones': {o.Label: {'PartNameList': tuple(o.partNameList)} for o in self.zone_objs},
                'zonesPresent': len(self.zone_objs) > 0,
                'meshType': self.mesh_obj.Proxy.Type,
                'solver': solverSettingsDict,
                'system': {},
                'runChangeDictionary':False
                }

            self.processSystemSettings()
            self.processSolverSettings()
            self.processFluidProperties()
            self.processBoundaryConditions()
            self.processInitialConditions()
            self.clearCase()

            self.exportZoneStlSurfaces()
            if self.porousZone_objs:
                self.processPorousZoneProperties()
            self.processInitialisationZoneProperties()

            self.settings['createPatchesFromSnappyBaffles'] = False
            if self.mesh_obj.Proxy.Type == "CfdMeshCart":  # Cut-cell Cartesian
                self.setupPatchNames()

            if self.meshConvertedTo2D and self.mesh_obj.Proxy.Type == "Fem::FemMeshGmsh":
                self.settings['runChangeDictionary'] = True

            TemplateBuilder.TemplateBuilder(self.case_folder, self.template_path, self.settings)
            self.writeMesh()

            # Update Allrun permission - will fail silently on Windows
            fname = os.path.join(self.case_folder, "Allrun")
            import stat
            s = os.stat(fname)
            os.chmod(fname, s.st_mode | stat.S_IEXEC)

            # Move mesh files, after being edited, to polyMesh.org
            CfdTools.movePolyMesh(self.case_folder)

        except:
            raise
        finally:
            os.chdir(cwd)  # Restore working dir
        cfdMessage("Successfully wrote {} case to folder {}\n".format(
                   self.solver_obj.SolverName, self.solver_obj.WorkingDir))
        return True