def downloadHisa(self): filename = self.download(self.hisa_url, HISA_FILE_EXT, "HiSA") if CfdTools.getFoamRuntime() == "MinGW": self.user_dir = None self.signals.status.emit("Installing HiSA...") CfdTools.runFoamCommand( '{{ mkdir -p "$FOAM_APPBIN" && cd "$FOAM_APPBIN" && unzip -o "{}"; }}' .format(CfdTools.translatePath(filename))) else: self.user_dir = CfdTools.runFoamCommand( "echo $WM_PROJECT_USER_DIR")[0].rstrip().split('\n')[-1] # We can't reverse-translate the path for docker since it sits inside the container. Just report it as such. if CfdTools.getFoamRuntime() != 'WindowsDocker': self.user_dir = CfdTools.reverseTranslatePath(self.user_dir) self.signals.status.emit("Extracting HiSA...") if CfdTools.getFoamRuntime() == 'WindowsDocker': from zipfile import ZipFile with ZipFile(filename, 'r') as zip: with tempfile.TemporaryDirectory() as tempdir: zip.extractall(path=tempdir) CfdTools.runFoamCommand( '{{ mkdir -p "$WM_PROJECT_USER_DIR" && cp -r "{}" "$WM_PROJECT_USER_DIR/"; }}' .format( CfdTools.translatePath( os.path.join(tempdir, HISA_FILE_BASE)))) else: CfdTools.runFoamCommand( '{{ mkdir -p "$WM_PROJECT_USER_DIR" && cd "$WM_PROJECT_USER_DIR" && ( rm -r {}; unzip -o "{}"; ); }}' .format(HISA_FILE_BASE, CfdTools.translatePath(filename)))
def processSystemSettings(self): system_settings = self.settings['system'] system_settings['FoamRuntime'] = CfdTools.getFoamRuntime() system_settings['CasePath'] = self.case_folder system_settings['FoamPath'] = CfdTools.getFoamDir() if CfdTools.getFoamRuntime() != 'WindowsDocker': system_settings['TranslatedFoamPath'] = CfdTools.translatePath( CfdTools.getFoamDir())
def threadFinished(self, status): if self.thread.task == DOWNLOAD_CFMESH: if status: if CfdTools.getFoamRuntime() != "MinGW": self.consoleMessage("Download completed") user_dir = self.thread.user_dir self.consoleMessage( "Building cfMesh. Lengthy process - please wait...") self.consoleMessage("Log file: {}/{}/log.Allwmake".format( user_dir, CFMESH_FILE_BASE)) if CfdTools.getFoamRuntime() == 'WindowsDocker': # There seem to be issues when using multi processors to build in docker self.install_process = CfdTools.startFoamApplication( "export WM_NCOMPPROCS=1; ./Allwmake", "$WM_PROJECT_USER_DIR/" + CFMESH_FILE_BASE, 'log.Allwmake', self.installFinished, stderr_hook=self.stderrFilter) else: self.install_process = CfdTools.startFoamApplication( "export WM_NCOMPPROCS=`nproc`; ./Allwmake", "$WM_PROJECT_USER_DIR/" + CFMESH_FILE_BASE, 'log.Allwmake', self.installFinished, stderr_hook=self.stderrFilter) else: self.consoleMessage("Install completed") # Reset foam dir for now in case the user presses 'Cancel' CfdTools.setFoamDir(self.initial_foam_dir) elif self.thread.task == DOWNLOAD_HISA: if status: if CfdTools.getFoamRuntime() != "MinGW": self.consoleMessage("Download completed") user_dir = self.thread.user_dir self.consoleMessage("Building HiSA. Please wait...") self.consoleMessage("Log file: {}/{}/log.Allwmake".format( user_dir, HISA_FILE_BASE)) if CfdTools.getFoamRuntime() == 'WindowsDocker': # There seem to be issues when using multi processors to build in docker self.install_process = CfdTools.startFoamApplication( "export WM_NCOMPPROCS=1; ./Allwmake", "$WM_PROJECT_USER_DIR/" + HISA_FILE_BASE, 'log.Allwmake', self.installFinished, stderr_hook=self.stderrFilter) else: self.install_process = CfdTools.startFoamApplication( "export WM_NCOMPPROCS=`nproc`; ./Allwmake", "$WM_PROJECT_USER_DIR/" + HISA_FILE_BASE, 'log.Allwmake', self.installFinished, stderr_hook=self.stderrFilter) else: self.consoleMessage("Install completed") # Reset foam dir for now in case the user presses 'Cancel' CfdTools.setFoamDir(self.initial_foam_dir) self.thread = None
def testGetRuntime(self, disable_exception=True): """ Set the foam dir temporarily and see if we can detect the runtime """ CfdTools.setFoamDir(self.foam_dir) try: runtime = CfdTools.getFoamRuntime() except IOError as e: runtime = None if not disable_exception: raise CfdTools.setFoamDir(self.initial_foam_dir) return runtime
def writeMeshCase(self): """ Collect case settings, and finally build a runnable case. """ CfdTools.cfdMessage( "Populating mesh dictionaries in folder {}\n".format( self.meshCaseDir)) # cfMesh settings if self.mesh_obj.MeshUtility == "cfMesh": self.cf_settings['ClMax'] = self.clmax * self.scale if len(self.cf_settings['BoundaryLayers']) > 0: self.cf_settings['BoundaryLayerPresent'] = True else: self.cf_settings['BoundaryLayerPresent'] = False if len(self.cf_settings["InternalRegions"]) > 0: self.cf_settings['InternalRefinementRegionsPresent'] = True else: self.cf_settings['InternalRefinementRegionsPresent'] = False # SnappyHexMesh settings elif self.mesh_obj.MeshUtility == "snappyHexMesh": bound_box = self.part_obj.Shape.BoundBox bC = 5 # Number of background mesh buffer cells x_min = (bound_box.XMin - bC * self.clmax) * self.scale x_max = (bound_box.XMax + bC * self.clmax) * self.scale y_min = (bound_box.YMin - bC * self.clmax) * self.scale y_max = (bound_box.YMax + bC * self.clmax) * self.scale z_min = (bound_box.ZMin - bC * self.clmax) * self.scale z_max = (bound_box.ZMax + bC * self.clmax) * self.scale cells_x = int(math.ceil(bound_box.XLength / self.clmax) + 2 * bC) cells_y = int(math.ceil(bound_box.YLength / self.clmax) + 2 * bC) cells_z = int(math.ceil(bound_box.ZLength / self.clmax) + 2 * bC) snappy_settings = self.snappy_settings snappy_settings['BlockMesh'] = { "xMin": x_min, "xMax": x_max, "yMin": y_min, "yMax": y_max, "zMin": z_min, "zMax": z_max, "cellsX": cells_x, "cellsY": cells_y, "cellsZ": cells_z } if len(self.snappy_settings['BoundaryLayers']) > 0: self.snappy_settings['BoundaryLayerPresent'] = True else: self.snappy_settings['BoundaryLayerPresent'] = False if self.mesh_obj.ImplicitEdgeDetection: snappy_settings['ImplicitEdgeDetection'] = True else: snappy_settings['ImplicitEdgeDetection'] = False inside_x = Units.Quantity( self.mesh_obj.PointInMesh.get('x')).Value * self.scale inside_y = Units.Quantity( self.mesh_obj.PointInMesh.get('y')).Value * self.scale inside_z = Units.Quantity( self.mesh_obj.PointInMesh.get('z')).Value * self.scale shape_patch_names_list = [] for k in range(len(self.patch_faces)): for j in range(len(self.patch_faces[k])): if len(self.patch_faces[k][j]): shape_patch_names_list.append(self.patch_names[k][j]) snappy_settings['ShapePatchNames'] = tuple(shape_patch_names_list) snappy_settings[ 'EdgeRefinementLevel'] = CfdTools.relLenToRefinementLevel( self.mesh_obj.EdgeRefinement) snappy_settings['PointInMesh'] = \ { "x": inside_x, "y": inside_y, "z": inside_z } snappy_settings[ 'CellsBetweenLevels'] = self.mesh_obj.CellsBetweenLevels if len(self.snappy_settings["InternalRegions"]) > 0: self.snappy_settings['InternalRefinementRegionsPresent'] = True else: self.snappy_settings[ 'InternalRefinementRegionsPresent'] = False # GMSH settings elif self.mesh_obj.MeshUtility == "gmsh": exe = CfdTools.getGmshExecutable() self.gmsh_settings['Executable'] = CfdTools.translatePath(exe) self.gmsh_settings['HasLengthMap'] = False if self.ele_length_map: self.gmsh_settings['HasLengthMap'] = True self.gmsh_settings['LengthMap'] = self.ele_length_map self.gmsh_settings['NodeMap'] = {} for e in self.ele_length_map: ele_nodes = (''.join( (str(n + 1) + ', ') for n in self.ele_node_map[e])).rstrip(', ') self.gmsh_settings['NodeMap'][e] = ele_nodes self.gmsh_settings['ClMax'] = self.clmax self.gmsh_settings['ClMin'] = self.clmin sols = (''.join( (str(n + 1) + ', ') for n in range(len(self.mesh_obj.Part.Shape.Solids))) ).rstrip(', ') self.gmsh_settings['Solids'] = sols self.gmsh_settings['BoundaryFaceMap'] = {} for k in range(len(self.patch_faces)): for l in range(len(self.patch_faces[k])): patch_faces = self.patch_faces[k][l] patch_name = self.patch_names[k][l] if len(patch_faces): self.gmsh_settings['BoundaryFaceMap'][ patch_name] = ', '.join( str(fi + 1) for fi in patch_faces) # Perform initialisation here rather than __init__ in case of path changes self.template_path = os.path.join(CfdTools.getModulePath(), "Data", "Templates", "mesh") mesh_region_present = False if self.mesh_obj.MeshUtility == "cfMesh" and len(self.cf_settings['MeshRegions']) > 0 or \ self.mesh_obj.MeshUtility == "snappyHexMesh" and len(self.snappy_settings['MeshRegions']) > 0: mesh_region_present = True self.settings = { 'Name': self.part_obj.Name, 'MeshPath': self.meshCaseDir, 'FoamRuntime': CfdTools.getFoamRuntime(), 'MeshUtility': self.mesh_obj.MeshUtility, 'MeshRegionPresent': mesh_region_present, 'CfSettings': self.cf_settings, 'SnappySettings': self.snappy_settings, 'GmshSettings': self.gmsh_settings, 'ExtrusionSettings': self.extrusion_settings, 'ConvertToDualMesh': self.mesh_obj.ConvertToDualMesh } if CfdTools.getFoamRuntime() != 'WindowsDocker': self.settings['TranslatedFoamPath'] = CfdTools.translatePath( CfdTools.getFoamDir()) if self.mesh_obj.NumberOfProcesses <= 1: self.settings['ParallelMesh'] = False self.settings['NumberOfProcesses'] = 1 else: self.settings['ParallelMesh'] = True self.settings[ 'NumberOfProcesses'] = self.mesh_obj.NumberOfProcesses self.settings['NumberOfThreads'] = self.mesh_obj.NumberOfThreads TemplateBuilder(self.meshCaseDir, self.template_path, self.settings) # Update Allmesh permission - will fail silently on Windows fname = os.path.join(self.meshCaseDir, "Allmesh") import stat s = os.stat(fname) os.chmod(fname, s.st_mode | stat.S_IEXEC) self.analysis.NeedsMeshRewrite = False CfdTools.cfdMessage( "Successfully wrote meshCase to folder {}\n".format( self.meshCaseDir))