def processPorousZoneProperties(self): settings = self.settings settings['porousZonesPresent'] = True porousZoneSettings = settings['porousZones'] for po in self.porousZone_objs: pd = {'PartNameList': tuple(r[0] for r in po.References)} po = CfdTools.propsToDict(po) if po['PorousCorrelation'] == 'DarcyForchheimer': pd['D'] = (po['D1'], po['D2'], po['D3']) pd['F'] = (po['F1'], po['F2'], po['F3']) pd['e1'] = tuple(po['e1']) pd['e3'] = tuple(po['e3']) elif po['PorousCorrelation'] == 'Jakob': # Calculate effective Darcy-Forchheimer coefficients # This is for equilateral triangles arranged with the triangles pointing in BundleLayerNormal # direction (direction of greater spacing - sqrt(3)*triangleEdgeLength) pd['e1'] = tuple(po['SpacingDirection'] ) # OpenFOAM modifies to be orthog to e3 pd['e3'] = tuple(po['TubeAxis']) spacing = po['TubeSpacing'] d0 = po['OuterDiameter'] u0 = po['VelocityEstimate'] aspectRatio = po['AspectRatio'] kinVisc = self.settings['fluidProperties'][ 'KinematicViscosity'] if kinVisc == 0.0: raise ValueError( "Viscosity must be set for Jakob correlation") if spacing < d0: raise ValueError( "Tube spacing may not be less than diameter") D = [0, 0, 0] F = [0, 0, 0] for (i, Sl, St) in [(0, aspectRatio * spacing, spacing), (1, spacing, aspectRatio * spacing)]: C = 1.0 / St * 0.5 * (1.0 + 0.47 / (Sl / d0 - 1)**1.06) * ( 1.0 / (1 - d0 / Sl))**(2.0 - 0.16) Di = C / d0 * 0.5 * (u0 * d0 / kinVisc)**(1.0 - 0.16) Fi = C * (u0 * d0 / kinVisc)**(-0.16) D[i] = Di F[i] = Fi pd['D'] = tuple(D) pd['F'] = tuple(F) # Currently assuming zero drag parallel to tube bundle (3rd principal dirn) else: raise RuntimeError( "Unrecognised method for porous baffle resistance") porousZoneSettings[po['Label']] = pd
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