Hi there,
I am starting using pyFR for 2d incompressible flow around obstacles. The code used for generating meshes looks good, as I can visualize a body-fitted triangular mesh by opening the .msh file with gmsh. But the .msh file fails to be imported to .pyfrm due to unpaired faces. I do not understand where the problem comes from. Please check the meshing function I used. I cannot upload the .msh file by the way.
Thanks in advance for any suggestions.
def OMesh(self, extruded=False, xmin = -10.0, xmax = 10.0, ymin = -10.0, ymax = 10.0, obstacle_element_scale = 0.2, edge_method='polygon', laplace_smoothing_iter = 200, output_dir='./'):
def add_polygon(geom, vertices_tags):
lines = []
for (line_start, line_end) in zip(vertices_tags[:-1], vertices_tags[1:]):
lines.append(geom.add_line(line_start, line_end))
lines.append(geom.add_line(vertices_tags[-1],vertices_tags[0]))
return lines
obstacle_vertices_coords = self.curve_pts
obstacle_top_coord = np.max(obstacle_vertices_coords,axis=0)[1]
obstacle_bottom_coord = np.min(obstacle_vertices_coords,axis=0)[1]
centroid = np.mean(obstacle_vertices_coords,axis=0)
gmsh.initialize()
mod = gmsh.model
geom = mod.geo()
# curvatures, is_convex = curvature(self.curve_pts[:,:2])
obstacle_vertices = []
for pt in obstacle_vertices_coords:
pt_tag = geom.addPoint(*pt,obstacle_element_scale)
obstacle_vertices.append(pt_tag)
if edge_method == 'polygon':
obstacle_edge = add_polygon(geom, obstacle_vertices)
elif edge_method == 'polyline':
obstacle_edge = [geom.addPolyline(obstacle_vertices + [obstacle_vertices[0]])]
elif edge_method == 'spline':
obstacle_edge = [geom.add_spline(obstacle_vertices + [obstacle_vertices[0]])]
else:
raise(ValueError('Invalid edge_method {edge_method}; choose one of polygon polyline or spline'))
obstacle_loop = geom.add_curve_loop(obstacle_edge)
outer_vertices = []
outer_vertices.append(geom.add_point(xmax,ymax,0.0))
outer_vertices.append(geom.add_point(xmax,ymin,0.0))
outer_vertices.append(geom.add_point(xmin,ymin,0.0))
outer_vertices.append(geom.add_point(xmin,ymax,0.0))
outer_lines = add_polygon(geom, outer_vertices)
outer_loop = geom.add_curve_loop(outer_lines)
surf = geom.addPlaneSurface([outer_loop, obstacle_loop])
minaniso_fields = []
# if boundary_layer_parameters is not None:
boundary_layer_default_parameters = {
"Thickness": np.mean(np.linalg.norm(self.curve_pts-centroid,axis=1)),
"Quads": 1,
"Size": 0.01,
"SizeFar": 0.1,
"IntersectMetrics": 1
}
# boundary_layer_parameters = boundary_layer_parameters or {}
boundary_layer_parameters = {**boundary_layer_default_parameters}
blayer = mod.mesh.field.add("BoundaryLayer")
mod.mesh.field.setAsBoundaryLayer(blayer)
for param in boundary_layer_parameters:
mod.mesh.field.setNumber(blayer, param, boundary_layer_parameters[param])
mod.mesh.field.setNumbers(blayer, "CurvesList", [obstacle_loop])
minaniso_fields.append(blayer)
try:
bl_offset = 1.25*boundary_layer_parameters["Thickness"]
except:
bl_offset = 0
wake_refinement_default_parameters = {
"VIn": 0.2,
"VOut": 2.0,
"XMax": xmax,
"XMin": 0.0,
"YMax": obstacle_top_coord + bl_offset,
"YMin": obstacle_bottom_coord - bl_offset
}
wake_refinement_parameters = {**wake_refinement_default_parameters}
wrbox = mod.mesh.field.add("Box")
for param in wake_refinement_parameters:
mod.mesh.field.setNumber(wrbox, param, wake_refinement_parameters[param])
minaniso_fields.append(wrbox)
if len(minaniso_fields)>0:
minaniso = mod.mesh.field.add("MinAniso")
mod.mesh.field.setNumbers(minaniso, "FieldsList", minaniso_fields)
mod.mesh.field.setAsBackgroundMesh(minaniso)
geom.synchronize()
pg_out = mod.addPhysicalGroup(1,[outer_lines[0]])
mod.setPhysicalName(1,pg_out,"out")
pg_sym1 = mod.addPhysicalGroup(1,[outer_lines[1]])
mod.setPhysicalName(1,pg_sym1,"sym1")
pg_in = mod.addPhysicalGroup(1,[outer_lines[2]])
mod.setPhysicalName(1,pg_in,"in")
pg_sym2 = mod.addPhysicalGroup(1,[outer_lines[3]])
mod.setPhysicalName(1,pg_sym2,"sym2")
pg_obstacle = mod.addPhysicalGroup(1,[obstacle_loop])
mod.setPhysicalName(1,pg_obstacle,"obstacle")
pg_fluid = mod.addPhysicalGroup(2,[surf])
mod.setPhysicalName(2,pg_fluid,"fluid")
mod.mesh.generate(2)
mod.mesh.optimize("Laplace2D", niter=laplace_smoothing_iter)
filename = f'{output_dir}/{self.name}_{self.index}.msh'
gmsh.option.setNumber("Mesh.MshFileVersion",2.2)
gmsh.write(filename)
gmsh.write(filename[:-4]+ '.vtk')
gmsh.finalize()
return filename,0