def processDynamicMeshRefinement(self): settings = self.settings settings['dynamicMeshEnabled'] = True # Check whether transient if not self.physics_model.Time == 'Transient': raise RuntimeError( "Dynamic mesh refinement is not supported by steady-state solvers" ) # Check whether cellLevel supported if self.mesh_obj.MeshUtility not in ['cfMesh', 'snappyHexMesh']: raise RuntimeError( "Dynamic mesh refinement is only supported by cfMesh and snappyHexMesh" ) # Check whether 2D extrusion present mesh_refinements = CfdTools.getMeshRefinementObjs(self.mesh_obj) for mr in mesh_refinements: if mr.Extrusion: if mr.ExtrusionType == '2DPlanar' or mr.ExtrusionType == '2DWedge': raise RuntimeError( "Dynamic mesh refinement will not work with 2D or wedge mesh" ) settings['dynamicMesh'] = CfdTools.propsToDict( self.dynamic_mesh_refinement_obj)
def setupPatchNames(self): print('Populating createPatchDict to update BC names') settings = self.settings settings['createPatches'] = {} settings['createPatchesSnappyBaffles'] = {} bc_group = self.bc_group defaultPatchType = "patch" 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': '"patch_' + str(bc_id + 1) + '_.*"', 'PatchType': patchType } if bc_obj.DefaultBoundary: defaultPatchType = patchType if bcType == 'baffle' and self.mesh_obj.MeshUtility == 'snappyHexMesh': settings['createPatchesFromSnappyBaffles'] = True settings['createPatchesSnappyBaffles'][bc_obj.Label] = { 'PatchNamesList': '"' + bc_obj.Name + '_[^_]*"', 'PatchNamesListSlave': '"' + bc_obj.Name + '_.*_slave"' } # Set up default BC for unassigned faces settings['createPatches']['defaultFaces'] = { 'PatchNamesList': '"patch_0_0"', 'PatchType': defaultPatchType } # Assign any extruded patches as the appropriate type mr_objs = CfdTools.getMeshRefinementObjs(self.mesh_obj) for mr_id, mr_obj in enumerate(mr_objs): if mr_obj.Extrusion and mr_obj.ExtrusionType == "2DPlanar": settings['createPatches'][mr_obj.Label] = { 'PatchNamesList': '"patch_.*_' + str(mr_id + 1) + '"', 'PatchType': "empty" } settings['createPatches'][mr_obj.Label + 'BackFace'] = { 'PatchNamesList': '"patch_.*_' + str(mr_id + 1) + '_back"', 'PatchType': "empty" } elif mr_obj.Extrusion and mr_obj.ExtrusionType == "2DWedge": settings['createPatches'][mr_obj.Label] = { 'PatchNamesList': '"patch_.*_' + str(mr_id + 1) + '"', 'PatchType': "symmetry" } settings['createPatches'][mr_obj.Label + 'BackFace'] = { 'PatchNamesList': '"patch_.*_' + str(mr_id + 1) + '_back"', 'PatchType': "symmetry" } else: # Add others to default faces list settings['createPatches']['defaultFaces'][ 'PatchNamesList'] += ' "patch_0_' + str(mr_id + 1) + '"'
def processExtrusions(self): """ Find and process any extrusion objects """ twoD_extrusion_objs = [] other_extrusion_objs = [] mesh_refinements = CfdTools.getMeshRefinementObjs(self.mesh_obj) self.extrusion_settings['ExtrusionsPresent'] = False self.extrusion_settings['ExtrudeTo2D'] = False self.extrusion_settings['Extrude2DPlanar'] = False for mr in mesh_refinements: if mr.Extrusion: self.extrusion_settings['ExtrusionsPresent'] = True if mr.ExtrusionType == '2DPlanar' or mr.ExtrusionType == '2DWedge': twoD_extrusion_objs.append(mr) else: other_extrusion_objs.append(mr) if mr.ExtrusionType == '2DPlanar': self.extrusion_settings['Extrude2DPlanar'] = True if len(twoD_extrusion_objs) > 1: raise RuntimeError( "For 2D meshing, there must be exactly one 2D mesh extrusion object." ) elif len(twoD_extrusion_objs) == 1: self.extrusion_settings['ExtrudeTo2D'] = True all_extrusion_objs = other_extrusion_objs + twoD_extrusion_objs # Ensure 2D extrusion happens last self.extrusion_settings['Extrusions'] = [] for extrusion_obj in all_extrusion_objs: extrusion_shape = extrusion_obj.Shape this_extrusion_settings = {} if len(extrusion_shape.Faces) == 0: raise RuntimeError("Extrusion object '{}' is empty.".format( extrusion_obj.Label)) this_extrusion_settings[ 'KeepExistingMesh'] = extrusion_obj.KeepExistingMesh if extrusion_obj.ExtrusionType == '2DPlanar' or extrusion_obj.ExtrusionType == '2DWedge': this_extrusion_settings['KeepExistingMesh'] = False all_faces_planar = True for faces in extrusion_shape.Faces: if not isinstance(faces.Surface, Part.Plane): all_faces_planar = False break if not all_faces_planar: raise RuntimeError( "2D mesh extrusion surface must be a flat plane.") normal = extrusion_shape.Faces[0].Surface.Axis normal.multiply(1.0 / normal.Length) this_extrusion_settings['Normal'] = (normal.x, normal.y, normal.z) this_extrusion_settings[ 'ExtrusionType'] = extrusion_obj.ExtrusionType # Get the names of the faces being extruded mri = mesh_refinements.index(extrusion_obj) efl = [] for l, ff in enumerate(self.patch_faces): f = ff[mri + 1] if len(f): efl.append(self.patch_names[l][mri + 1]) if not efl: raise RuntimeError( "Extrusion patch for '{}' could not be found in the shape being meshed." .format(extrusion_obj.Label)) this_extrusion_settings['FrontFaceList'] = tuple(efl) this_extrusion_settings['BackFace'] = efl[0] + '_back' this_extrusion_settings[ 'Distance'] = extrusion_obj.ExtrusionThickness.getValueAs('m') this_extrusion_settings[ 'Angle'] = extrusion_obj.ExtrusionAngle.getValueAs('deg') this_extrusion_settings[ 'NumLayers'] = extrusion_obj.ExtrusionLayers this_extrusion_settings[ 'ExpansionRatio'] = extrusion_obj.ExtrusionRatio this_extrusion_settings['AxisPoint'] = \ tuple(Units.Quantity(p, Units.Length).getValueAs('m') for p in extrusion_obj.ExtrusionAxisPoint) axis_direction = extrusion_obj.ExtrusionAxisDirection # Flip axis if necessary to go in same direction as patch normal (otherwise negative volume cells result) if len(extrusion_shape.Faces) > 0: in_plane_vector = extrusion_shape.Faces[ 0].CenterOfMass - extrusion_obj.ExtrusionAxisPoint extrusion_normal = extrusion_obj.ExtrusionAxisDirection.cross( in_plane_vector) face_normal = extrusion_shape.Faces[0].normalAt(0.5, 0.5) if extrusion_normal.dot(face_normal) < 0: axis_direction = -axis_direction this_extrusion_settings['AxisDirection'] = tuple( d for d in axis_direction) self.extrusion_settings['Extrusions'].append( this_extrusion_settings)
def processRefinements(self): """ Process mesh refinements """ mr_objs = CfdTools.getMeshRefinementObjs(self.mesh_obj) cf_settings = self.cf_settings cf_settings['MeshRegions'] = {} cf_settings['BoundaryLayers'] = {} cf_settings['InternalRegions'] = {} snappy_settings = self.snappy_settings snappy_settings['MeshRegions'] = {} snappy_settings['BoundaryLayers'] = {} snappy_settings['InternalRegions'] = {} # Make list of all faces in meshed shape with original index mesh_face_list = list( zip(self.mesh_obj.Part.Shape.Faces, range(len(self.mesh_obj.Part.Shape.Faces)))) # Make list of all boundary references CfdTools.cfdMessage("Matching boundary patches\n") boundary_face_list = [] bc_group = None analysis_obj = CfdTools.getParentAnalysisObject(self.mesh_obj) if not analysis_obj: analysis_obj = CfdTools.getActiveAnalysis() if analysis_obj: bc_group = CfdTools.getCfdBoundaryGroup(analysis_obj) for bc_id, bc_obj in enumerate(bc_group): for ri, ref in enumerate(bc_obj.ShapeRefs): try: bf = CfdTools.resolveReference(ref) except RuntimeError as re: raise RuntimeError( "Error processing boundary condition {}: {}".format( bc_obj.Label, str(re))) for si, s in enumerate(bf): boundary_face_list += [(sf, (bc_id, ri, si)) for sf in s[0].Faces] # Match them up to faces in the main geometry bc_matched_faces = CfdTools.matchFaces(boundary_face_list, mesh_face_list) # Check for and filter duplicates bc_match_per_shape_face = [-1] * len(mesh_face_list) for k in range(len(bc_matched_faces)): match = bc_matched_faces[k][1] prev_k = bc_match_per_shape_face[match] if prev_k >= 0: nb, ri, si = bc_matched_faces[k][0] nb2, ri2, si2 = bc_matched_faces[prev_k][0] bc = bc_group[nb] bc2 = bc_group[nb2] CfdTools.cfdWarning( "Boundary '{}' reference {}:{} also assigned as " "boundary '{}' reference {}:{} - ignoring duplicate\n". format(bc.Label, bc.ShapeRefs[ri][0].Name, bc.ShapeRefs[ri][1][si], bc2.Label, bc.ShapeRefs[ri][0].Name, bc.ShapeRefs[ri][1][si])) else: bc_match_per_shape_face[match] = k # Match relevant mesh regions to the shape being meshed: boundary layer mesh regions for cfMesh, # all surface mesh refinements for snappyHexMesh, and extrusion patches for all meshers. # For cfMesh, surface mesh refinements are written as separate surfaces so need not be matched CfdTools.cfdMessage("Matching mesh refinement regions\n") mr_face_list = [] for mr_id, mr_obj in enumerate(mr_objs): if mr_obj.Extrusion or ( self.mesh_obj.MeshUtility == 'cfMesh' and not mr_obj.Internal and mr_obj.NumberLayers > 0) or ( self.mesh_obj.MeshUtility == 'snappyHexMesh' and not mr_obj.Internal): for ri, r in enumerate(mr_obj.ShapeRefs): try: bf = CfdTools.resolveReference(r) except RuntimeError as re: raise RuntimeError( "Error processing mesh refinement {}: {}".format( mr_obj.Label, str(re))) for si, s in enumerate(bf): mr_face_list += [(f, (mr_id, ri, si)) for f in s[0].Faces] # Match them up to the primary geometry mr_matched_faces = CfdTools.matchFaces(mr_face_list, mesh_face_list) # Check for and filter duplicates mr_match_per_shape_face = [-1] * len(mesh_face_list) for k in range(len(mr_matched_faces)): match = mr_matched_faces[k][1] prev_k = mr_match_per_shape_face[match] if prev_k >= 0: nr, ri, si = mr_matched_faces[k][0] nr2, ri2, si2 = mr_matched_faces[prev_k][0] CfdTools.cfdWarning( "Mesh refinement '{}' reference {}:{} also assigned as " "mesh refinement '{}' reference {}:{} - ignoring duplicate\n" .format(mr_objs[nr].Label, mr_objs[nr].ShapeRefs[ri][0].Name, mr_objs[nr].ShapeRefs[ri][1][si], mr_objs[nr2].Label, mr_objs[nr2].ShapeRefs[ri2][0].Name, mr_objs[nr2].ShapeRefs[ri2][1][si2])) else: mr_match_per_shape_face[match] = k self.patch_faces = [] self.patch_names = [] for k in range(len(bc_group) + 1): self.patch_faces.append([]) self.patch_names.append([]) for l in range(len(mr_objs) + 1): self.patch_faces[k].append([]) self.patch_names[k].append("patch_" + str(k) + "_" + str(l)) for i in range(len(mesh_face_list)): k = bc_match_per_shape_face[i] l = mr_match_per_shape_face[i] nb = -1 nr = -1 if k >= 0: nb, bri, bsi = bc_matched_faces[k][0] if l >= 0: nr, rri, ssi = mr_matched_faces[l][0] self.patch_faces[nb + 1][nr + 1].append(i) # For gmsh, match mesh refinement with vertices in original mesh mr_matched_vertices = [] if self.mesh_obj.MeshUtility == 'gmsh': # Make list of all vertices in meshed shape with original index mesh_vertices_list = list( zip(self.mesh_obj.Part.Shape.Vertexes, range(len(self.mesh_obj.Part.Shape.Vertexes)))) CfdTools.cfdMessage("Matching mesh refinements\n") mr_vertices_list = [] for mr_id, mr_obj in enumerate(mr_objs): if not mr_obj.Internal: for ri, r in enumerate(mr_obj.ShapeRefs): try: bf = CfdTools.resolveReference(r) except RuntimeError as re: raise RuntimeError( "Error processing mesh refinement {}: {}". format(mr_obj.Label, str(re))) for si, s in enumerate(bf): mr_vertices_list += [(v, (mr_id, ri, si)) for v in s[0].Vertexes] mr_matched_vertices = CfdTools.matchFaces(mr_vertices_list, mesh_vertices_list) self.ele_length_map = {} self.ele_node_map = {} # For snappyHexMesh, also match surface mesh refinements to the boundary conditions, to identify boundary # conditions on supplementary geometry defined by the surface mesh refinements # Also matches baffles to surface mesh refinements bc_mr_matched_faces = [] if self.mesh_obj.MeshUtility == 'snappyHexMesh': bc_mr_matched_faces = CfdTools.matchFaces(boundary_face_list, mr_face_list) # Handle baffles for bc_id, bc_obj in enumerate(bc_group): if bc_obj.BoundaryType == 'baffle': baffle_matches = [ m for m in bc_mr_matched_faces if m[0][0] == bc_id ] mr_match_per_baffle_ref = [] for r in bc_obj.ShapeRefs: mr_match_per_baffle_ref += [[-1] * len(r[1])] for m in baffle_matches: mr_match_per_baffle_ref[m[0][1]][m[0][2]] = m[1][0] # For each mesh region, the refs that are part of this baffle baffle_patch_refs = [[] for ri in range(len(mr_objs) + 1)] for ri, mr in enumerate(mr_match_per_baffle_ref): for si, mri in enumerate(mr_match_per_baffle_ref[ri]): baffle_patch_refs[mri + 1].append( (bc_obj.ShapeRefs[ri][0], (bc_obj.ShapeRefs[ri][1][si], ))) # Write these geometries for ri, refs in enumerate(baffle_patch_refs): try: shape = CfdTools.makeShapeFromReferences(refs) except RuntimeError as re: raise RuntimeError( "Error processing baffle {}: {}".format( bc_obj.Label, str(re))) solid_name = bc_obj.Name + "_" + str(ri) if shape: CfdTools.cfdMessage( "Triangulating baffle {}, section {}\n".format( bc_obj.Label, ri)) writeSurfaceMeshFromShape(shape, self.triSurfaceDir, solid_name, self.mesh_obj) if ri > 0: # The parts of the baffle corresponding to a surface mesh region obj mr_obj = mr_objs[ri - 1] refinement_level = CfdTools.relLenToRefinementLevel( mr_obj.RelativeLength) edge_level = CfdTools.relLenToRefinementLevel( mr_obj.RegionEdgeRefinement) else: # The parts of the baffle with no refinement obj refinement_level = 0 edge_level = 0 snappy_settings['MeshRegions'][solid_name] = { 'RefinementLevel': refinement_level, 'EdgeRefinementLevel': edge_level, 'MaxRefinementLevel': max(refinement_level, edge_level), 'Baffle': True } for mr_id, mr_obj in enumerate(mr_objs): Internal = mr_obj.Internal mr_rellen = mr_obj.RelativeLength if mr_rellen > 1.0: mr_rellen = 1.0 FreeCAD.Console.PrintError( "The mesh refinement region '{}' should not use a relative length greater " "than unity.\n".format(mr_obj.Name)) elif mr_rellen < 0.001: mr_rellen = 0.001 # Relative length should not be less than 0.1% of base length FreeCAD.Console.PrintError( "The mesh refinement region '{}' should not use a relative length smaller " "than 0.001.\n".format(mr_obj.Name)) if self.mesh_obj.MeshUtility == 'gmsh': # Generate element maps for gmsh if not Internal: mesh_vertex_idx = [ mf[1] for mf in mr_matched_vertices if mf[0][0] == mr_id ] self.ele_length_map[mr_obj.Name] = mr_rellen * self.clmax self.ele_node_map[mr_obj.Name] = mesh_vertex_idx else: # Find any matches with boundary conditions; mark those matching baffles for removal bc_matches = [ m for m in bc_mr_matched_faces if m[1][0] == mr_id ] bc_match_per_mr_ref = [] for ri, r in enumerate(mr_obj.ShapeRefs): bc_match_per_mr_ref.append([-1] * len(r[1])) for m in bc_matches: bc_match_per_mr_ref[m[1][1]][m[1][2]] = -2 if bc_group[ m[0][0]].BoundaryType == 'baffle' else m[0][0] # Unmatch those in primary geometry main_geom_matches = [ m for m in mr_matched_faces if m[0][0] == mr_id ] for m in main_geom_matches: bc_match_per_mr_ref[m[0][1]][m[0][2]] = -1 # For each boundary, the refs that are part of this mesh region mr_patch_refs = [[] for ri in range(len(bc_group) + 1)] for ri, m in enumerate(bc_match_per_mr_ref): for si, bci in enumerate(m): if bci > -2: mr_patch_refs[bci + 1].append( (mr_obj.ShapeRefs[ri][0], (mr_obj.ShapeRefs[ri][1][si], ))) # Loop over and write the sub-sections of this mesh object for bi in range(len(mr_patch_refs)): if len(mr_patch_refs[bi]) and not mr_obj.Extrusion: if bi == 0: mr_patch_name = mr_obj.Name else: mr_patch_name = self.patch_names[bi][mr_id + 1] CfdTools.cfdMessage( "Triangulating mesh refinement region {}, section {}\n" .format(mr_obj.Label, bi)) try: shape = CfdTools.makeShapeFromReferences( mr_patch_refs[bi]) except RuntimeError as re: raise RuntimeError( "Error processing mesh refinement region {}: {}" .format(mr_obj.Label, str(re))) if shape: writeSurfaceMeshFromShape(shape, self.triSurfaceDir, mr_patch_name, self.mesh_obj) refinement_level = CfdTools.relLenToRefinementLevel( mr_obj.RelativeLength) if self.mesh_obj.MeshUtility == 'cfMesh': if not Internal: cf_settings['MeshRegions'][mr_patch_name] = { 'RefinementLevel': refinement_level, 'RefinementThickness': self.scale * Units.Quantity( mr_obj.RefinementThickness).Value, } else: cf_settings['InternalRegions'][mr_obj.Name] = { 'RefinementLevel': refinement_level, 'RelativeLength': mr_rellen * self.clmax * self.scale } elif self.mesh_obj.MeshUtility == 'snappyHexMesh': if not Internal: edge_level = CfdTools.relLenToRefinementLevel( mr_obj.RegionEdgeRefinement) snappy_settings['MeshRegions'][ mr_patch_name] = { 'RefinementLevel': refinement_level, 'EdgeRefinementLevel': edge_level, 'MaxRefinementLevel': max(refinement_level, edge_level), 'Baffle': False } else: snappy_settings['InternalRegions'][ mr_patch_name] = { 'RefinementLevel': refinement_level } # In addition, for cfMesh and SnappyHesMesh, record matched boundary layer patches if (self.mesh_obj.MeshUtility == 'cfMesh' or self.mesh_obj.MeshUtility == 'snappyHexMesh') \ and mr_obj.NumberLayers > 0 and not Internal and not mr_obj.Extrusion: for k in range(len(self.patch_faces)): if len(self.patch_faces[k][mr_id + 1]): # Limit expansion ratio to greater than 1.0 and less than 1.2 expratio = mr_obj.ExpansionRatio expratio = min(1.2, max(1.0, expratio)) if self.mesh_obj.MeshUtility == 'cfMesh': cf_settings['BoundaryLayers'][self.patch_names[k][mr_id + 1]] = \ { 'NumberLayers': mr_obj.NumberLayers, 'ExpansionRatio': expratio, 'FirstLayerHeight': self.scale * Units.Quantity(mr_obj.FirstLayerHeight).Value } elif self.mesh_obj.MeshUtility == 'snappyHexMesh': snappy_settings['BoundaryLayers'][self.patch_names[k][mr_id + 1]] = \ { 'NumberLayers': mr_obj.NumberLayers, 'ExpansionRatio': expratio, # 'FinalLayerHeight': self.scale * Units.Quantity(mr_obj.FinalLayerHeight).Value }
def processBoundaryConditions(self): """ Compute any quantities required before case build """ settings = self.settings # Copy keys so that we can delete while iterating bc_names = list(settings['boundaries'].keys()) for bc_name in bc_names: bc = settings['boundaries'][bc_name] if not bc['VelocityIsCartesian']: veloMag = bc['VelocityMag'] face = bc['DirectionFace'].split(':') if not face[0]: face = bc['ShapeRefs'][0].Name # See if entered face actually exists and is planar try: selected_object = self.analysis_obj.Document.getObject( face[0]) if hasattr(selected_object, "Shape"): elt = selected_object.Shape.getElement(face[1]) if elt.ShapeType == 'Face' and CfdTools.isPlanar(elt): n = elt.normalAt(0.5, 0.5) if bc['ReverseNormal']: n = [-ni for ni in n] velocity = [ni * veloMag for ni in n] bc['Ux'] = velocity[0] bc['Uy'] = velocity[1] bc['Uz'] = velocity[2] else: raise RuntimeError else: raise RuntimeError except (SystemError, RuntimeError): raise RuntimeError( str(bc['DirectionFace']) + " is not a valid, planar face.") if settings['solver']['SolverName'] in [ 'simpleFoam', 'porousSimpleFoam', 'pimpleFoam' ]: bc['KinematicPressure'] = bc['Pressure'] / settings[ 'fluidProperties'][0]['Density'] if bc['PorousBaffleMethod'] == 'porousScreen': wireDiam = bc['ScreenWireDiameter'] spacing = bc['ScreenSpacing'] CD = 1.0 # Drag coeff of wire (Simmons - valid for Re > ~300) beta = (1 - wireDiam / spacing)**2 bc['PressureDropCoeff'] = CD * (1 - beta) if settings['solver']['SolverName'] in [ 'interFoam', 'multiphaseInterFoam' ]: # Make sure the first n-1 alpha values exist, and write the n-th one # consistently for multiphaseInterFoam sum_alpha = 0.0 alphas_new = {} for i, m in enumerate(settings['fluidProperties']): alpha_name = m['Name'] if i == len(settings['fluidProperties']) - 1: if settings['solver'][ 'SolverName'] == 'multiphaseInterFoam': alphas_new[alpha_name] = 1.0 - sum_alpha else: alpha = Units.Quantity( bc.get('VolumeFractions', {}).get(alpha_name, '0')).Value alphas_new[alpha_name] = alpha sum_alpha += alpha bc['VolumeFractions'] = alphas_new # Copy turbulence settings bc['TurbulenceIntensity'] = bc[ 'TurbulenceIntensityPercentage'] / 100.0 physics = settings['physics'] if physics['Turbulence'] == 'RANS' and physics[ 'TurbulenceModel'] == 'SpalartAllmaras': if (bc['BoundaryType'] == 'inlet' or bc['BoundaryType'] == 'open') and \ bc['TurbulenceInletSpecification'] == 'intensityAndLengthScale': if bc['BoundarySubType'] == 'uniformVelocityInlet' or bc[ 'BoundarySubType'] == 'farField': Uin = (bc['Ux']**2 + bc['Uy']**2 + bc['Uz']**2)**0.5 # Turb Intensity and length scale I = bc['TurbulenceIntensity'] l = bc['TurbulenceLengthScale'] # Spalart Allmaras bc['NuTilda'] = (3.0 / 2.0)**0.5 * Uin * I * l else: raise RuntimeError( "Inlet type currently unsupported for calculating turbulence inlet conditions from " "intensity and length scale.") if bc['DefaultBoundary']: if settings['boundaries'].get('defaultFaces'): raise ValueError("More than one default boundary defined") settings['boundaries']['defaultFaces'] = bc if not settings['boundaries'].get('defaultFaces'): settings['boundaries']['defaultFaces'] = { 'BoundaryType': 'wall', 'BoundarySubType': 'slipWall', 'ThermalBoundaryType': 'zeroGradient' } # Assign any extruded patches as the appropriate type mr_objs = CfdTools.getMeshRefinementObjs(self.mesh_obj) for mr_id, mr_obj in enumerate(mr_objs): if mr_obj.Extrusion and mr_obj.ExtrusionType == "2DPlanar": settings['boundaries'][mr_obj.Label] = { 'BoundaryType': 'constraint', 'BoundarySubType': 'empty' } settings['boundaries'][mr_obj.Label + "BackFace"] = { 'BoundaryType': 'constraint', 'BoundarySubType': 'empty' } if mr_obj.Extrusion and mr_obj.ExtrusionType == "2DWedge": settings['boundaries'][mr_obj.Label] = { 'BoundaryType': 'constraint', 'BoundarySubType': 'symmetry' } settings['boundaries'][mr_obj.Label + "BackFace"] = { 'BoundaryType': 'constraint', 'BoundarySubType': 'symmetry' }