def resultsToDict(self): """Extracts all important results into dictionary, making it easier for printout or csv extraction. """ parms=["DOptMu","DOptPx","prodOpt","degrOpt","success","Rsq","MeanRsq","fitDegr","fitProd","fitPinned","equOn","x0"] dic=pyfrp_misc_module.objAttr2Dict(self,attr=parms) roiNames=pyfrp_misc_module.objAttrToList(self.ROIsFitted,"name") #equFacts=np.asarray(self.equFacts).astype(str) dic["ROIsFitted"]=" , ".join(roiNames) for i in range(len(roiNames)): if self.equOn: dic["equFactor "+roiNames[i]]=self.equFacts[i] else: dic["equFactor "+roiNames[i]]="" dic["Rsq("+roiNames[i]+")"]=self.RsqByROI[roiNames[i]] return dic
def getAttrFromROI(self, attr): """First finds all ROIs in ``geometry.embryo.ROIs`` that have an attribute called ``attr``, then lets the user select one of them and then returns the value of ``attr`` of the selected ROI. """ possROIs = list(self.geometry.embryo.ROIs) possROIsNew = [] for r in possROIs: if hasattr(r, attr): possROIsNew.append(r) possROIs = list(possROIsNew) if len(possROIs) < 1: printWarning( "Cannot create selection of ROIs, there is none with attribute " + attr + " .") return None nameList = pyfrp_misc_module.objAttrToList(possROIs, 'name') selectorDialog = pyfrp_gui_basics.basicSelectorDialog(nameList, self) if selectorDialog.exec_(): selectedROIName = selectorDialog.getItem() if selectedROIName == None: return None r = self.geometry.embryo.getROIByName(selectedROIName) attrVal = getattr(r, attr) return attrVal
def resultsToDict(self): """Extracts all important results into dictionary, making it easier for printout or csv extraction. """ parms = [ "DOptMu", "DOptPx", "prodOpt", "degrOpt", "success", "Rsq", "MeanRsq", "fitDegr", "fitProd", "fitPinned", "equOn", "x0" ] dic = pyfrp_misc_module.objAttr2Dict(self, attr=parms) roiNames = pyfrp_misc_module.objAttrToList(self.ROIsFitted, "name") #equFacts=np.asarray(self.equFacts).astype(str) dic["ROIsFitted"] = " , ".join(roiNames) for i in range(len(roiNames)): if self.equOn: dic["equFactor " + roiNames[i]] = self.equFacts[i] else: dic["equFactor " + roiNames[i]] = "" dic["Rsq(" + roiNames[i] + ")"] = self.RsqByROI[roiNames[i]] return dic
def getAttrFromROI(self,attr): """First finds all ROIs in ``geometry.embryo.ROIs`` that have an attribute called ``attr``, then lets the user select one of them and then returns the value of ``attr`` of the selected ROI. """ possROIs=list(self.geometry.embryo.ROIs) possROIsNew=[] for r in possROIs: if hasattr(r,attr): possROIsNew.append(r) possROIs=list(possROIsNew) if len(possROIs)<1: printWarning("Cannot create selection of ROIs, there is none with attribute " + attr + " .") return None nameList=pyfrp_misc_module.objAttrToList(possROIs,'name') selectorDialog = pyfrp_gui_basics.basicSelectorDialog(nameList,self) if selectorDialog.exec_(): selectedROIName = selectorDialog.getItem() if selectedROIName==None: return None r=self.geometry.embryo.getROIByName(selectedROIName) attrVal=getattr(r,attr) return attrVal
def updateNormROILbl(self): nameList=pyfrp_misc_module.objAttrToList(self.embryo.ROIs,'name') if self.normName in nameList: pass else: self.normName="" self.lblNormVal.setText(self.normName)
def updateBkgdROILbl(self): nameList = pyfrp_misc_module.objAttrToList(self.embryo.ROIs, 'name') if self.bkgdName in nameList: pass else: self.bkgdName = "" self.lblBkgdVal.setText(self.bkgdName)
def updateNormROILbl(self): nameList = pyfrp_misc_module.objAttrToList(self.embryo.ROIs, 'name') if self.normName in nameList: pass else: self.normName = "" self.lblNormVal.setText(self.normName)
def updateBkgdROILbl(self): nameList=pyfrp_misc_module.objAttrToList(self.embryo.ROIs,'name') if self.bkgdName in nameList: pass else: self.bkgdName="" self.lblBkgdVal.setText(self.bkgdName)
def __init__(self,embryo,parent): super(boundaryLayerAroundROISettingsDialog,self).__init__(parent) # Set default variables self.embryo=embryo self.initDefaults() # Generate all widgets self.lblSegments,self.qleSegments = pyfrp_gui_builder.genSettingQLE(self,"Segments",self.segments,callback=self.setSegments,validator=self.intValid) self.lblIter,self.qleIter = pyfrp_gui_builder.genSettingQLE(self,"Iterations",self.iterations,callback=self.setIter,validator=self.intValid) self.lblTriangIter,self.qleTriangIter = pyfrp_gui_builder.genSettingQLE(self,"triangIterations",self.triangIterations,callback=self.setTriangIter,validator=self.intValid) self.lblVolSizePx,self.qleVolSizePx = pyfrp_gui_builder.genSettingQLE(self,"volSizePx",self.volSizePx,callback=self.setVolSizePx,validator=self.doubleValid) self.lblVolSizeLayer,self.qleVolSizeLayer = pyfrp_gui_builder.genSettingQLE(self,"volSizeLayer",self.volSizeLayer,callback=self.setVolSizeLayer,validator=self.doubleValid) self.lblThickness,self.qleThickness = pyfrp_gui_builder.genSettingQLE(self,"thickness",self.thickness,callback=self.setThickness,validator=self.doubleValid) self.lblAngleThresh,self.qleAngleThresh = pyfrp_gui_builder.genSettingQLE(self,"angleThresh",self.angleThresh,callback=self.setAngleThresh,validator=self.doubleValid) self.lblFaces,self.qleFaces = pyfrp_gui_builder.genSettingQLE(self,"Faces",self.faces,callback=self.setFaces,validator=None) self.lblFnOut,self.btnFnOut = pyfrp_gui_builder.genSettingBtn(self,"fnOut","Change",callback=self.setFnOut) self.lblOnlyAbs,self.cbOnlyAbs = pyfrp_gui_builder.genSettingCB(self,"onlyAbs",self.onlyAbs,callback=self.checkOnlyAbs) self.lblSimplify,self.cbSimplify = pyfrp_gui_builder.genSettingCB(self,"simplify",self.simplify,callback=self.checkSimplify) self.lblFixSurf,self.cbFixSurf = pyfrp_gui_builder.genSettingCB(self,"fixSurfaces",self.fixSurfaces,callback=self.checkFixSurf) self.lblApproxBySpline,self.cbApproxBySpline = pyfrp_gui_builder.genSettingCB(self,"approxBySpline",self.approxBySpline,callback=self.checkApproxBySpline) self.lblDebug,self.cbDebug = pyfrp_gui_builder.genSettingCB(self,"debug",self.debug,callback=self.checkDebug) self.lblCleanUp,self.cbCleanUp = pyfrp_gui_builder.genSettingCB(self,"cleanUp",self.cleanUp,callback=self.checkCleanUp) self.lblROI,self.comboROI = pyfrp_gui_builder.genSettingCombo(self,"ROI",pyfrp_misc_module.objAttrToList(self.embryo.ROIs,"name"),callback=self.setROI,idx=self.embryo.getROIIdx(self.roiUsed)) # Put them in list lbls1 = [self.lblROI,self.lblFaces,self.lblOnlyAbs,self.lblFnOut] qles1 = [self.comboROI,self.qleFaces,self.cbOnlyAbs,self.btnFnOut] lbls2 = [self.lblVolSizePx,self.lblVolSizeLayer,self.lblThickness] qles2 = [self.qleVolSizePx,self.qleVolSizeLayer,self.qleThickness] lbls3 = [self.lblSegments,self.lblIter,self.lblTriangIter] qles3 = [self.qleSegments,self.qleIter,self.qleTriangIter] lbls4 = [self.lblSimplify,self.lblFixSurf,self.lblApproxBySpline,self.lblAngleThresh] qles4 = [self.cbSimplify,self.cbFixSurf,self.cbApproxBySpline,self.qleAngleThresh] lbls5 = [self.lblDebug,self.lblCleanUp] qles5 = [self.cbDebug,self.cbCleanUp] lbls=[lbls1,lbls2,lbls3,lbls4,lbls5] qles=[qles1,qles2,qles3,qles4,qles5] # Add to Layout nRows=self.grid.rowCount() for i in range(len(lbls)): for j in range(len(lbls[i])): self.grid.addWidget(lbls[i][j],nRows+j+1,(2*i)) self.grid.addWidget(qles[i][j],nRows+j+1,(2*i+1)) self.setWindowTitle("Boundary Layer Mesh around ROI settings") self.show()
def setNormROI(self): nameList=pyfrp_misc_module.objAttrToList(self.embryo.ROIs,'name') selectorDialog = pyfrp_gui_basics.basicSelectorDialog(nameList,self) if selectorDialog.exec_(): selectedROIName = selectorDialog.getItem() if selectedROIName==None: return self.normName=selectedROIName self.updateNormROILbl()
def setNormROI(self): nameList = pyfrp_misc_module.objAttrToList(self.embryo.ROIs, 'name') selectorDialog = pyfrp_gui_basics.basicSelectorDialog(nameList, self) if selectorDialog.exec_(): selectedROIName = selectorDialog.getItem() if selectedROIName == None: return self.normName = selectedROIName self.updateNormROILbl()
def sumUpResults(self, sameSettings=False): """Sums up results from all fits in ``selFits`` list. Keyword Args: sameSettings (bool): Fits must overlap in parameters defined in ``crucialParameters``. Returns: bool: True if success, False else. """ if sameSettings: lastFit = self.selFits[0] #Check that all fits have roughly the same parameters for fit in self.selFits: #Check if fit is fitted if not fit.isFitted(): printError("Cannot average fits, since fits " + fit.name + "has not been fitted yet.") return False same, different, notInBoth = pyfrp_misc_module.compareObjAttr( lastFit, fit) for item in self.crucialParameters: if item in different.keys(): printError( "Cannot average fits, since fits " + lastFit.name + " and " + fit.name + "do not have the same value for " + item + ". However, this parameter is marked as crucial.") return False elif item in notInBoth: printError( "Cannot average fits, since one of the fits " + lastFit.name + " and " + fit.name + " lacks the parameter " + item + ".") return False #Compute Statistics self.DOptMu, self.DOptMuStd, self.DOptMuSterr = pyfrp_stats_module.parameterStats( pyfrp_misc_module.objAttrToList(self.selFits, "DOptMu")) self.DOptPx, self.DOptPxStd, self.DOptPxSterr = pyfrp_stats_module.parameterStats( pyfrp_misc_module.objAttrToList(self.selFits, "DOptPx")) self.prodOpt, self.prodOptStd, self.prodOptSterr = pyfrp_stats_module.parameterStats( pyfrp_misc_module.objAttrToList(self.selFits, "prodOpt")) self.degrOpt, self.degrOptStd, self.degrOptSterr = pyfrp_stats_module.parameterStats( pyfrp_misc_module.objAttrToList(self.selFits, "degrOpt")) self.Rsq = np.mean(pyfrp_misc_module.objAttrToList( self.selFits, "Rsq")) self.MeanRsq = np.mean( pyfrp_misc_module.objAttrToList(self.selFits, "MeanRsq")) return True
def checkEmbryoNames(self): """Check if all embryos in ``embryos`` list have different names. Returns: bool: True if all different, False else. """ names = pyfrp_misc_module.objAttrToList(self.embryos, 'name') b = True for name in names: if names.count(name) > 1: printWarning('There is more than one embryo called ' + name + ' in molecule ' + self.name) b = False return b
def checkEmbryoNames(self): """Check if all embryos in ``embryos`` list have different names. Returns: bool: True if all different, False else. """ names=pyfrp_misc_module.objAttrToList(self.embryos,'name') b=True for name in names: if names.count(name)>1: printWarning('There is more than one embryo called '+ name + ' in molecule ' + self.name) b=False return b
def addROI(self): nameList=pyfrp_misc_module.objAttrToList(self.fit.embryo.ROIs,'name') selectorDialog = pyfrp_gui_basics.basicSelectorDialog(nameList,self) if selectorDialog.exec_(): selectedROIName = selectorDialog.getItem() if selectedROIName==None: return selectedROI=self.fit.embryo.ROIs[nameList.index(selectedROIName)] if selectedROI not in self.fit.ROIsFitted: self.fit.addROI(selectedROI) self.updateROIList()
def test_surfaceFuse(): """Test surface fuse function. Reads in .stl, tries to fuse a few surfaces and checks if new surface lineLoop has proper number of vertices.""" d=pyfrp_gmsh_IO_module.readStlFile(pyfrp_misc_module.fixPath(pyfrp_misc_module.getMeshfilesDir()+"tests/surfaceFuse.stl")) sfID=1 toFuseIDs=[2,3,4,5,6,7] # Grab first surface sf1=d.getRuledSurfaceById(sfID)[0] # Try to successively fuse for ID in toFuseIDs: sf1.fuse(d.getRuledSurfaceById(ID)[0],debug=True) assert pyfrp_misc_module.objAttrToList(sf1.lineLoop.getVertices(),'Id') == [1, 2, 4, 5, 6, 7, 8, 9, 3]
def test_surfaceFuse(): """Test surface fuse function. Reads in .stl, tries to fuse a few surfaces and checks if new surface lineLoop has proper number of vertices.""" d = pyfrp_gmsh_IO_module.readStlFile( pyfrp_misc_module.fixPath(pyfrp_misc_module.getMeshfilesDir() + "tests/surfaceFuse.stl")) sfID = 1 toFuseIDs = [2, 3, 4, 5, 6, 7] # Grab first surface sf1 = d.getRuledSurfaceById(sfID)[0] # Try to successively fuse for ID in toFuseIDs: sf1.fuse(d.getRuledSurfaceById(ID)[0], debug=True) assert pyfrp_misc_module.objAttrToList( sf1.lineLoop.getVertices(), 'Id') == [1, 2, 4, 5, 6, 7, 8, 9, 3]
def sumUpResults(self,sameSettings=False): """Sums up results from all fits in ``selFits`` list. Keyword Args: sameSettings (bool): Fits must overlap in parameters defined in ``crucialParameters``. Returns: bool: True if success, False else. """ if sameSettings: lastFit=self.selFits[0] #Check that all fits have roughly the same parameters for fit in self.selFits: #Check if fit is fitted if not fit.isFitted(): printError("Cannot average fits, since fits " + fit.name + "has not been fitted yet.") return False same,different,notInBoth=pyfrp_misc_module.compareObjAttr(lastFit,fit) for item in self.crucialParameters: if item in different.keys(): printError("Cannot average fits, since fits " + lastFit.name + " and " + fit.name + "do not have the same value for " + item +". However, this parameter is marked as crucial.") return False elif item in notInBoth: printError("Cannot average fits, since one of the fits " + lastFit.name + " and " + fit.name + " lacks the parameter " + item +".") return False #Compute Statistics self.DOptMu,self.DOptMuStd,self.DOptMuSterr=pyfrp_stats_module.parameterStats(pyfrp_misc_module.objAttrToList(self.selFits,"DOptMu")) self.DOptPx,self.DOptPxStd,self.DOptPxSterr=pyfrp_stats_module.parameterStats(pyfrp_misc_module.objAttrToList(self.selFits,"DOptPx")) self.prodOpt,self.prodOptStd,self.prodOptSterr=pyfrp_stats_module.parameterStats(pyfrp_misc_module.objAttrToList(self.selFits,"prodOpt")) self.degrOpt,self.degrOptStd,self.degrOptSterr=pyfrp_stats_module.parameterStats(pyfrp_misc_module.objAttrToList(self.selFits,"degrOpt")) self.Rsq=np.mean(pyfrp_misc_module.objAttrToList(self.selFits,"Rsq")) self.MeanRsq=np.mean(pyfrp_misc_module.objAttrToList(self.selFits,"MeanRsq")) return True
def __init__(self, embryo, parent): super(boundaryLayerAroundROISettingsDialog, self).__init__(parent) # Set default variables self.embryo = embryo self.initDefaults() # Generate all widgets self.lblSegments, self.qleSegments = pyfrp_gui_builder.genSettingQLE( self, "Segments", self.segments, callback=self.setSegments, validator=self.intValid) self.lblIter, self.qleIter = pyfrp_gui_builder.genSettingQLE( self, "Iterations", self.iterations, callback=self.setIter, validator=self.intValid) self.lblTriangIter, self.qleTriangIter = pyfrp_gui_builder.genSettingQLE( self, "triangIterations", self.triangIterations, callback=self.setTriangIter, validator=self.intValid) self.lblVolSizePx, self.qleVolSizePx = pyfrp_gui_builder.genSettingQLE( self, "volSizePx", self.volSizePx, callback=self.setVolSizePx, validator=self.doubleValid) self.lblVolSizeLayer, self.qleVolSizeLayer = pyfrp_gui_builder.genSettingQLE( self, "volSizeLayer", self.volSizeLayer, callback=self.setVolSizeLayer, validator=self.doubleValid) self.lblThickness, self.qleThickness = pyfrp_gui_builder.genSettingQLE( self, "thickness", self.thickness, callback=self.setThickness, validator=self.doubleValid) self.lblAngleThresh, self.qleAngleThresh = pyfrp_gui_builder.genSettingQLE( self, "angleThresh", self.angleThresh, callback=self.setAngleThresh, validator=self.doubleValid) self.lblFaces, self.qleFaces = pyfrp_gui_builder.genSettingQLE( self, "Faces", self.faces, callback=self.setFaces, validator=None) self.lblFnOut, self.btnFnOut = pyfrp_gui_builder.genSettingBtn( self, "fnOut", "Change", callback=self.setFnOut) self.lblOnlyAbs, self.cbOnlyAbs = pyfrp_gui_builder.genSettingCB( self, "onlyAbs", self.onlyAbs, callback=self.checkOnlyAbs) self.lblSimplify, self.cbSimplify = pyfrp_gui_builder.genSettingCB( self, "simplify", self.simplify, callback=self.checkSimplify) self.lblFixSurf, self.cbFixSurf = pyfrp_gui_builder.genSettingCB( self, "fixSurfaces", self.fixSurfaces, callback=self.checkFixSurf) self.lblApproxBySpline, self.cbApproxBySpline = pyfrp_gui_builder.genSettingCB( self, "approxBySpline", self.approxBySpline, callback=self.checkApproxBySpline) self.lblDebug, self.cbDebug = pyfrp_gui_builder.genSettingCB( self, "debug", self.debug, callback=self.checkDebug) self.lblCleanUp, self.cbCleanUp = pyfrp_gui_builder.genSettingCB( self, "cleanUp", self.cleanUp, callback=self.checkCleanUp) self.lblROI, self.comboROI = pyfrp_gui_builder.genSettingCombo( self, "ROI", pyfrp_misc_module.objAttrToList(self.embryo.ROIs, "name"), callback=self.setROI, idx=self.embryo.getROIIdx(self.roiUsed)) # Put them in list lbls1 = [self.lblROI, self.lblFaces, self.lblOnlyAbs, self.lblFnOut] qles1 = [self.comboROI, self.qleFaces, self.cbOnlyAbs, self.btnFnOut] lbls2 = [self.lblVolSizePx, self.lblVolSizeLayer, self.lblThickness] qles2 = [self.qleVolSizePx, self.qleVolSizeLayer, self.qleThickness] lbls3 = [self.lblSegments, self.lblIter, self.lblTriangIter] qles3 = [self.qleSegments, self.qleIter, self.qleTriangIter] lbls4 = [ self.lblSimplify, self.lblFixSurf, self.lblApproxBySpline, self.lblAngleThresh ] qles4 = [ self.cbSimplify, self.cbFixSurf, self.cbApproxBySpline, self.qleAngleThresh ] lbls5 = [self.lblDebug, self.lblCleanUp] qles5 = [self.cbDebug, self.cbCleanUp] lbls = [lbls1, lbls2, lbls3, lbls4, lbls5] qles = [qles1, qles2, qles3, qles4, qles5] # Add to Layout nRows = self.grid.rowCount() for i in range(len(lbls)): for j in range(len(lbls[i])): self.grid.addWidget(lbls[i][j], nRows + j + 1, (2 * i)) self.grid.addWidget(qles[i][j], nRows + j + 1, (2 * i + 1)) self.setWindowTitle("Boundary Layer Mesh around ROI settings") self.show()
def addBoundaryLayerAroundROI(self, roi, fnOut=None, segments=48, simplify=True, iterations=3, triangIterations=2, fixSurfaces=True, debug=False, volSizePx=None, volSizeLayer=10, thickness=15., cleanUp=True, approxBySpline=True, angleThresh=0.95, faces='all', onlyAbs=True): """Adds boundary layer around ROI to the mesh. Does this by: * Generating a stl file describing ROI, see also :py:func:`pyfrp.subclasses.pyfrp_ROI.ROI.render2StlInGeometry`. * Read in stl file as new :py:class:`pyfrp.modules.pyfrp_gmsh_geometry.domain` via :py:func:`pyfrp.modules.pyfrp_gmsh_IO_module.readStlFile`. * Simplify new geometry via :py:func:`pyfrp.modules.pyfrp_gmsh_geometry.domain.simplifySurfaces`. * Extracting selected surfaces via :py:func:`pyfrp.modules.pyfrp_gmsh_geometry.gmshElement.extract`. * If selected, surface boundaries are approximated into splines via :py:func:`pyfrp.modules.pyfrp_gmsh_geometry.gmshElement.extract`. * Reading in geometry's .geo file via :py:func:`pyfrp.sublcasses.pyfrp_geometry.geometry.readGeoFile`. * Merging ROI geometry into main geometry via :py:func:`pyfrp.modules.pyfrp_gmsh_geometry.domain.merge`. * Adding a boundary layer mesh via :py:func:`pyfrp.modules.pyfrp_gmsh_geometry.domain.addBoundaryLayerField`. * Adding all surfaces of ROI's domain to boundary layer, see :py:func:`pyfrp.modules.pyfrp_gmsh_geometry.boundaryLayerField.addFaceListByID`. * Writing new .geo file. * Setting new .geo file as ``fnGeo``. * Running :py:func:`genMesh`. * Clean up .stl and .scad files that are not needed anymore. .. note:: ``volSizeLayer`` only allows a single definition of mesh size in layer. Note that the :py:class:`pyfrp.modules.pyfrp_gmsh_geometry.boundaryLayerField` class allows different mesh sizes normal and along surfaces. For more information, see its documentation. .. note:: If no ``fnOut`` is given, will save a new .geo file in same folder as original ``fnGeo`` with subfix: ``fnGeo_roiName_BL.geo``. .. note:: :py:func:`pyfrp.modules.pyfrp_gmsh_geometry.domain.simplifySurfaces` is not a simple procedure, we recommend reading its documentation. If ``volSizePx`` is given, will overwrite mesh's ``volSizePx`` and set it globally at all nodes. Args: roi (pyfrp.subclasses.pyfrp_ROI.ROI): An ROI. Keyword Args: fnOut (str): Path to new .geo file. segments (int): Number of segments used for convex hull of surface. simplify (bool): Simplify surfaces of stl file. iterations (int): Number of iterations used for simplification. triangIterations (int): Number of iterations used for subdivision of surfaces. addPoints (bool): Allow adding points inside surface triangles. fixSurfaces (bool): Allow fixing of surfaces, making sure they are coherent with Gmsh requirements. debug (bool): Print debugging messages. volSizePx (float): Global mesh density. volSizeLayer (float): Boundary layer mesh size. thickness (float): Thickness of boundary layer. cleanUp (bool): Clean up temporary files when finished. approxBySpline (bool): Approximate curvatures by spline. angleThresh (float): Threshold angle under which loops are summarized. faces (list): List of faces. onlyAbs (bool): Take absolute value of faces into account. dim (int): Dimension of mesh. Returns: str: Path to new .geo file. """ if fnOut == None: fnOut = self.simulation.embryo.geometry.fnGeo.replace( ".geo", "_" + roi.name + "_BL.geo") #Build stl file for ROI fnStl = roi.render2StlInGeometry(segments=segments, fn=fnOut.replace(".geo", ".stl")) #Read in stl file and simplify dROI = pyfrp_gmsh_IO_module.readStlFile(fnStl) if simplify: dROI.simplifySurfaces(iterations=iterations, triangIterations=triangIterations, fixSurfaces=fixSurfaces, debug=debug, addPoints=bool(triangIterations > 0)) # If we extract faces, we have to put them in new ROI if faces != 'all' and len(faces) > 0: # Grab surfaces sfs = dROI.getRuledSurfacesByNormal(faces, onlyAbs=onlyAbs) # Insert in new domain d2 = pyfrp_gmsh_geometry.domain() for sf in sfs: sf.extract(d=d2, debug=debug) # Overwrite sfs and dROI sfs = d2.ruledSurfaces dROI = d2 #Approximate complicated curves by splines if approxBySpline: for sf in sfs: sf.lineLoop.approxBySpline(angleThresh=angleThresh) dROI.fixAllLoops() #Read in geometry and merge dGeo = self.simulation.embryo.geometry.readGeoFile() dGeo.merge(dROI) #Create boundary layer blf = dGeo.addBoundaryLayerField(hfar=volSizeLayer, hwall_n=volSizeLayer, hwall_t=volSizeLayer, thickness=thickness, Quads=0.) #Add surfaces to boundary layer mesh blf.addFaceListByID(pyfrp_misc_module.objAttrToList(sfs, 'Id')) blf.setAsBkgdField() #Set global volSize if volSizePx != None: dGeo.setGlobalVolSize(volSizePx) self.volSizePx = volSizePx else: dGeo.setGlobalVolSize(self.getVolSizePx()) #Write and set as new geometry dGeo.writeToFile(fnOut) self.simulation.embryo.geometry.setFnGeo(fnOut) #Generate mesh self.genMesh() #Clean up temporary files if cleanUp: os.remove(fnStl) os.remove(fnStl.replace(".stl", ".scad")) return fnOut
def addBoundaryLayerAroundROI(self,roi,fnOut=None,segments=48,simplify=True,iterations=3,triangIterations=2, fixSurfaces=True,debug=False,volSizePx=None,volSizeLayer=10,thickness=15.,cleanUp=True, approxBySpline=True,angleThresh=0.95,faces='all',onlyAbs=True): """Adds boundary layer around ROI to the mesh. Does this by: * Generating a stl file describing ROI, see also :py:func:`pyfrp.subclasses.pyfrp_ROI.ROI.render2StlInGeometry`. * Read in stl file as new :py:class:`pyfrp.modules.pyfrp_gmsh_geometry.domain` via :py:func:`pyfrp.modules.pyfrp_gmsh_IO_module.readStlFile`. * Simplify new geometry via :py:func:`pyfrp.modules.pyfrp_gmsh_geometry.domain.simplifySurfaces`. * Extracting selected surfaces via :py:func:`pyfrp.modules.pyfrp_gmsh_geometry.gmshElement.extract`. * If selected, surface boundaries are approximated into splines via :py:func:`pyfrp.modules.pyfrp_gmsh_geometry.gmshElement.extract`. * Reading in geometry's .geo file via :py:func:`pyfrp.sublcasses.pyfrp_geometry.geometry.readGeoFile`. * Merging ROI geometry into main geometry via :py:func:`pyfrp.modules.pyfrp_gmsh_geometry.domain.merge`. * Adding a boundary layer mesh via :py:func:`pyfrp.modules.pyfrp_gmsh_geometry.domain.addBoundaryLayerField`. * Adding all surfaces of ROI's domain to boundary layer, see :py:func:`pyfrp.modules.pyfrp_gmsh_geometry.boundaryLayerField.addFaceListByID`. * Writing new .geo file. * Setting new .geo file as ``fnGeo``. * Running :py:func:`genMesh`. * Clean up .stl and .scad files that are not needed anymore. .. note:: ``volSizeLayer`` only allows a single definition of mesh size in layer. Note that the :py:class:`pyfrp.modules.pyfrp_gmsh_geometry.boundaryLayerField` class allows different mesh sizes normal and along surfaces. For more information, see its documentation. .. note:: If no ``fnOut`` is given, will save a new .geo file in same folder as original ``fnGeo`` with subfix: ``fnGeo_roiName_BL.geo``. .. note:: :py:func:`pyfrp.modules.pyfrp_gmsh_geometry.domain.simplifySurfaces` is not a simple procedure, we recommend reading its documentation. If ``volSizePx`` is given, will overwrite mesh's ``volSizePx`` and set it globally at all nodes. Args: roi (pyfrp.subclasses.pyfrp_ROI.ROI): An ROI. Keyword Args: fnOut (str): Path to new .geo file. segments (int): Number of segments used for convex hull of surface. simplify (bool): Simplify surfaces of stl file. iterations (int): Number of iterations used for simplification. triangIterations (int): Number of iterations used for subdivision of surfaces. addPoints (bool): Allow adding points inside surface triangles. fixSurfaces (bool): Allow fixing of surfaces, making sure they are coherent with Gmsh requirements. debug (bool): Print debugging messages. volSizePx (float): Global mesh density. volSizeLayer (float): Boundary layer mesh size. thickness (float): Thickness of boundary layer. cleanUp (bool): Clean up temporary files when finished. approxBySpline (bool): Approximate curvatures by spline. angleThresh (float): Threshold angle under which loops are summarized. faces (list): List of faces. onlyAbs (bool): Take absolute value of faces into account. dim (int): Dimension of mesh. Returns: str: Path to new .geo file. """ if fnOut==None: fnOut=self.simulation.embryo.geometry.fnGeo.replace(".geo","_"+roi.name+"_BL.geo") #Build stl file for ROI fnStl=roi.render2StlInGeometry(segments=segments,fn=fnOut.replace(".geo",".stl")) #Read in stl file and simplify dROI=pyfrp_gmsh_IO_module.readStlFile(fnStl) if simplify: dROI.simplifySurfaces(iterations=iterations,triangIterations=triangIterations,fixSurfaces=fixSurfaces,debug=debug,addPoints=bool(triangIterations>0)) # If we extract faces, we have to put them in new ROI if faces!='all' and len(faces)>0: # Grab surfaces sfs=dROI.getRuledSurfacesByNormal(faces,onlyAbs=onlyAbs) # Insert in new domain d2=pyfrp_gmsh_geometry.domain() for sf in sfs: sf.extract(d=d2,debug=debug) # Overwrite sfs and dROI sfs=d2.ruledSurfaces dROI=d2 #Approximate complicated curves by splines if approxBySpline: for sf in sfs: sf.lineLoop.approxBySpline(angleThresh=angleThresh) dROI.fixAllLoops() #Read in geometry and merge dGeo=self.simulation.embryo.geometry.readGeoFile() dGeo.merge(dROI) #Create boundary layer blf=dGeo.addBoundaryLayerField(hfar=volSizeLayer,hwall_n=volSizeLayer,hwall_t=volSizeLayer,thickness=thickness,Quads=0.) #Add surfaces to boundary layer mesh blf.addFaceListByID(pyfrp_misc_module.objAttrToList(sfs,'Id')) blf.setAsBkgdField() #Set global volSize if volSizePx!=None: dGeo.setGlobalVolSize(volSizePx) self.volSizePx=volSizePx else: dGeo.setGlobalVolSize(self.getVolSizePx()) #Write and set as new geometry dGeo.writeToFile(fnOut) self.simulation.embryo.geometry.setFnGeo(fnOut) #Generate mesh self.genMesh() #Clean up temporary files if cleanUp: os.remove(fnStl) os.remove(fnStl.replace(".stl",".scad")) return fnOut