def store(self): FreeCADGui.doCommand( "\nFreeCAD.ActiveDocument.{}.CharacteristicLengthMax " "= '{}'".format(self.mesh_obj.Name, getQuantity(self.form.if_max))) FreeCADGui.doCommand("FreeCAD.ActiveDocument.{}.MeshUtility " "= '{}'".format( self.mesh_obj.Name, self.form.cb_utility.currentText())) FreeCADGui.doCommand("FreeCAD.ActiveDocument.{}.ElementDimension " "= '{}'".format( self.mesh_obj.Name, self.form.cb_dimension.currentText())) FreeCADGui.doCommand("FreeCAD.ActiveDocument.{}.CellsBetweenLevels " "= {}".format( self.mesh_obj.Name, self.form.if_cellsbetweenlevels.value())) FreeCADGui.doCommand("FreeCAD.ActiveDocument.{}.EdgeRefinement " "= {}".format(self.mesh_obj.Name, self.form.if_edgerefine.value())) point_in_mesh = { 'x': getQuantity(self.form.if_pointInMeshX), 'y': getQuantity(self.form.if_pointInMeshY), 'z': getQuantity(self.form.if_pointInMeshZ) } FreeCADGui.doCommand("FreeCAD.ActiveDocument.{}.PointInMesh " "= {}".format(self.mesh_obj.Name, point_in_mesh)) self.cart_mesh = CfdMeshTools.CfdMeshTools(self.mesh_obj)
def __init__(self, obj): self.mesh_obj = obj self.form = FreeCADGui.PySideUic.loadUi(os.path.join(os.path.dirname(__file__), "TaskPanelCfdMesh.ui")) self.Timer = QtCore.QTimer() self.Start = time.time() self.console_message_cart = '' self.error_message = '' self.cart_mesh = CfdMeshTools.CfdMeshTools(self.mesh_obj) self.paraviewScriptName = "" self.mesh_process = CfdConsoleProcess(finishedHook=self.meshFinished, stdoutHook=self.gotOutputLines, stderrHook=self.gotErrorLines) self.edit_prcess = None QtCore.QObject.connect(self.form.if_max, QtCore.SIGNAL("valueChanged(Base::Quantity)"), self.max_changed) QtCore.QObject.connect(self.form.if_pointInMeshX, QtCore.SIGNAL("valueChanged(Base::Quantity)"), self.pointInMeshX_changed) QtCore.QObject.connect(self.form.if_pointInMeshY, QtCore.SIGNAL("valueChanged(Base::Quantity)"), self.pointInMeshY_changed) QtCore.QObject.connect(self.form.if_pointInMeshZ, QtCore.SIGNAL("valueChanged(Base::Quantity)"), self.pointInMeshZ_changed) QtCore.QObject.connect(self.form.if_cellsbetweenlevels, QtCore.SIGNAL("valueChanged(int)"), self.cellsbetweenlevels_changed) QtCore.QObject.connect(self.form.if_edgerefine, QtCore.SIGNAL("valueChanged(int)"), self.edgerefine_changed) QtCore.QObject.connect(self.form.cb_dimension, QtCore.SIGNAL("activated(int)"), self.choose_dimension) QtCore.QObject.connect(self.form.cb_utility, QtCore.SIGNAL("activated(int)"), self.choose_utility) QtCore.QObject.connect(self.Timer, QtCore.SIGNAL("timeout()"), self.update_timer_text) self.open_paraview = QtCore.QProcess() self.form.pb_write_mesh.clicked.connect(self.writeMesh) self.form.pb_edit_mesh.clicked.connect(self.editMesh) self.form.pb_run_mesh.clicked.connect(self.runMesh) self.form.pb_stop_mesh.clicked.connect(self.killMeshProcess) self.form.pb_paraview.clicked.connect(self.openParaview) self.form.pb_load_mesh.clicked.connect(self.pbLoadMeshClicked) self.form.pb_clear_mesh.clicked.connect(self.pbClearMeshClicked) self.form.pb_searchPointInMesh.clicked.connect(self.searchPointInMesh) self.form.pb_stop_mesh.setEnabled(False) self.form.pb_paraview.setEnabled(False) self.form.snappySpecificProperties.setVisible(False) self.form.cb_dimension.addItems(_CfdMesh._CfdMesh.known_element_dimensions) self.form.cb_utility.addItems(_CfdMesh._CfdMesh.known_mesh_utility) self.form.if_max.setToolTip("Select 0 to use default value") self.form.pb_searchPointInMesh.setToolTip("Specify below a point vector inside of the mesh or press 'Search' " "to try and automatically find a point") self.form.if_cellsbetweenlevels.setToolTip("Number of cells between each of level of refinement.") self.form.if_edgerefine.setToolTip("Number of refinement levels for all edges.") self.get_mesh_params() self.order = '1st' # Default to first order for CFD mesh self.get_active_analysis() self.update() self.updateUI()
def __init__(self, obj): self.mesh_obj = obj self.form = FreeCADGui.PySideUic.loadUi( os.path.join(os.path.dirname(__file__), "TaskPanelCfdMesh.ui")) self.console_message_cart = '' self.error_message = '' self.cart_mesh = CfdMeshTools.CfdMeshTools(self.mesh_obj) self.paraviewScriptName = "" self.mesh_process = CfdConsoleProcess(finishedHook=self.meshFinished, stdoutHook=self.gotOutputLines, stderrHook=self.gotErrorLines) self.form.cb_utility.activated.connect(self.choose_utility) self.Timer = QtCore.QTimer() self.Timer.setInterval(1000) self.Timer.timeout.connect(self.update_timer_text) self.open_paraview = QtCore.QProcess() self.form.pb_write_mesh.clicked.connect(self.writeMesh) self.form.pb_edit_mesh.clicked.connect(self.editMesh) self.form.pb_run_mesh.clicked.connect(self.runMesh) self.form.pb_stop_mesh.clicked.connect(self.killMeshProcess) self.form.pb_paraview.clicked.connect(self.openParaview) self.form.pb_load_mesh.clicked.connect(self.pbLoadMeshClicked) self.form.pb_clear_mesh.clicked.connect(self.pbClearMeshClicked) self.form.pb_searchPointInMesh.clicked.connect(self.searchPointInMesh) self.form.pb_stop_mesh.setEnabled(False) self.form.pb_paraview.setEnabled(False) self.form.snappySpecificProperties.setVisible(False) self.form.cb_dimension.addItems(_CfdMesh.known_element_dimensions) self.form.cb_utility.addItems(_CfdMesh.known_mesh_utility) self.form.if_max.setToolTip("Enter 0 to use default value") self.form.pb_searchPointInMesh.setToolTip( "Specify below a point vector inside of the mesh or press 'Search' " "to try to automatically find a point") self.form.if_cellsbetweenlevels.setToolTip( "Number of cells between each of level of refinement") self.form.if_edgerefine.setToolTip( "Number of refinement levels for all edges") self.load() self.updateUI() self.Start = time.time() self.Timer.start()
def runMeshProcess(self): self.console_message_cart = '' self.Start = time.time() self.Timer.start() # Re-initialise CfdMeshTools with new parameters self.set_mesh_params() self.cart_mesh = CfdMeshTools.CfdMeshTools(self.mesh_obj) self.consoleMessage("Starting meshing ...") try: QApplication.setOverrideCursor(Qt.WaitCursor) self.get_active_analysis() self.set_mesh_params() cart_mesh = self.cart_mesh setInputFieldQuantity(self.form.if_max, str(cart_mesh.get_clmax())) print("\nStarting meshing ...\n") print(' Part to mesh: 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)) cart_mesh.get_dimension() cart_mesh.get_file_paths(CfdTools.getOutputPath(self.analysis)) cart_mesh.setup_mesh_case_dir() self.consoleMessage("Exporting mesh region data ...") cart_mesh.get_region_data( ) # Writes region stls so need file structure cart_mesh.write_mesh_case() self.consoleMessage("Exporting the part surfaces ...") cart_mesh.write_part_file() self.consoleMessage("Running {} ...".format(self.utility)) self.runCart(cart_mesh) except Exception as ex: self.consoleMessage("Error: " + str(ex), '#FF0000') self.Timer.stop() raise finally: QApplication.restoreOverrideCursor()
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" }
def writeMesh(self): """ Convert or copy mesh files """ if self.mesh_obj.Proxy.Type == "CfdMesh": import CfdMeshTools # Move Cartesian mesh files from temporary mesh directory to case directory self.cart_mesh = CfdMeshTools.CfdMeshTools(self.mesh_obj) cart_mesh = self.cart_mesh # Update output file locations cart_mesh.get_file_paths(CfdTools.getOutputPath(self.analysis_obj)) if self.mesh_obj.MeshUtility == "cfMesh": print("Writing Cartesian mesh\n") CfdTools.copyFilesRec( cart_mesh.polyMeshDir, os.path.join(self.case_folder, 'constant', 'polyMesh')) CfdTools.copyFilesRec( cart_mesh.triSurfaceDir, os.path.join(self.case_folder, 'constant', 'triSurface')) # shutil.copy2(cart_mesh.temp_file_meshDict, os.path.join(self.case_folder,'system')) shutil.copy2( os.path.join(cart_mesh.meshCaseDir, 'system', 'meshDict'), os.path.join(self.case_folder, 'system')) shutil.copy2(os.path.join(cart_mesh.meshCaseDir, 'Allmesh'), self.case_folder) shutil.copy2( os.path.join(cart_mesh.meshCaseDir, 'log.cartesianMesh'), self.case_folder) shutil.copy2( os.path.join(cart_mesh.meshCaseDir, 'log.surfaceFeatureEdges'), self.case_folder) elif self.mesh_obj.MeshUtility == "snappyHexMesh": print("Writing snappyHexMesh generated Cartesian mesh\n") CfdTools.copyFilesRec( cart_mesh.polyMeshDir, os.path.join(self.case_folder, 'constant', 'polyMesh')) CfdTools.copyFilesRec( cart_mesh.triSurfaceDir, os.path.join(self.case_folder, 'constant', 'triSurface')) # shutil.copy2(cart_mesh.temp_file_blockMeshDict, os.path.join(self.case_folder,'system')) # shutil.copy2(cart_mesh.temp_file_snappyMeshDict, os.path.join(self.case_folder,'system')) # shutil.copy2(cart_mesh.temp_file_surfaceFeatureExtractDict, os.path.join(self.case_folder,'system')) shutil.copy2( os.path.join(cart_mesh.meshCaseDir, 'system', 'blockMeshDict'), os.path.join(self.case_folder, 'system')) shutil.copy2( os.path.join(cart_mesh.meshCaseDir, 'system', 'snappyHexMeshDict'), os.path.join(self.case_folder, 'system')) shutil.copy2( os.path.join(cart_mesh.meshCaseDir, 'system', 'surfaceFeatureExtractDict'), os.path.join(self.case_folder, 'system')) shutil.copy2(os.path.join(cart_mesh.meshCaseDir, 'Allmesh'), self.case_folder) shutil.copy2( os.path.join(cart_mesh.meshCaseDir, 'log.blockMesh'), self.case_folder) shutil.copy2( os.path.join(cart_mesh.meshCaseDir, 'log.surfaceFeatureExtract'), self.case_folder) shutil.copy2( os.path.join(cart_mesh.meshCaseDir, 'log.snappyHexMesh'), self.case_folder) elif self.mesh_obj.MeshUtility == "gmsh": print("Writing gmsh generated mesh\n") CfdTools.copyFilesRec( cart_mesh.polyMeshDir, os.path.join(self.case_folder, 'constant', 'polyMesh')) CfdTools.copyFilesRec( cart_mesh.triSurfaceDir, os.path.join(self.case_folder, 'constant', 'gmsh')) shutil.copy2(os.path.join(cart_mesh.meshCaseDir, 'Allmesh'), self.case_folder) shutil.copy2( os.path.join(cart_mesh.meshCaseDir, 'log.gmshToFoam'), self.case_folder) if self.mesh_obj.ElementDimension == '2D': shutil.copy2( os.path.join(os.path.join(cart_mesh.meshCaseDir, 'system'), 'extrudeMeshDict'), os.path.join(self.case_folder, 'system')) shutil.copy2( os.path.join(cart_mesh.meshCaseDir, 'log.extrudeMesh'), self.case_folder) else: raise RuntimeError("Unrecognised mesh type")
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" }