Examples
A collection of 2D meshing examples. Note that all the codes are available in the examples directory.
Polygon Mesh
using DistMesh
using CairoMakieFirst, define the vertices of the polygon as a list of points (tuples)
pv = [(-0.4, -0.5), (0.4, -0.2), (0.4, -0.7), (1.5, -0.4),
(0.9, 0.1), (1.6, 0.8), (0.5, 0.5), (0.2, 1.0),
(0.1, 0.4), (-0.7, 0.7), (-0.4, -0.5)];Next, use the dpoly function and these vertices to define the distance function
fd(p) = dpoly(p, pv)fd (generic function with 1 method)We use a uniform mesh size function, with a given desired edge length
hmin = 0.15
fh = huniformhuniform (generic function with 1 method)DistMesh also needs a bounding box, which must enclose the polygon
bbox = ((-1,-1), (2,1))((-1, -1), (2, 1))Sharp corners have to be provided in the pfix argument
pfix = pv11-element Vector{Tuple{Float64, Float64}}:
(-0.4, -0.5)
(0.4, -0.2)
(0.4, -0.7)
(1.5, -0.4)
(0.9, 0.1)
(1.6, 0.8)
(0.5, 0.5)
(0.2, 1.0)
(0.1, 0.4)
(-0.7, 0.7)
(-0.4, -0.5)Generate the mesh
msh = distmesh2d(fd, fh, hmin, bbox, pfix)DMesh: 2D, 107 nodes, 160 triangle elementsFinally, plot the resulting mesh
plot(msh)
NACA Airfoil Mesh
This example shows how to generate a mesh around a NACA0012 airfoil.
First, load the required packages and define a convenient short-hand for static 2D points.
using DistMesh
using CairoMakie
using StaticArrays
const Point2d = SVector{2, Float64}SVector{2, Float64} (alias for StaticArraysCore.SArray{Tuple{2}, Float64, 1, 2})First, we define the size function for the NACA airfoil. It consists of the minimum of several point sources and constants:
- A point source at the tip of the airfoil, with size
hlead - A point source at the trailing edge of the airfoil, with size
htrail - A maximum element size in the entire domain
hmax
function hnaca(p; hlead=0.01, htrail=0.04, hmax=2.0)
minimum((hlead + 0.3 * dcircle(p, c=(0, 0), r=0),
htrail + 0.3 * dcircle(p, c=(1, 0), r=0),
hmax))
endhnaca (generic function with 1 method)Next, we define the fix points. This could be as simple as just the trailing edge at (1,0). However, the mesh quality is improved by providing several points along the surface, spread out consistently with the size function above. Therefore, this function also needs the edge length htrail from before. We also add the symmetry point (0,0).
function fixnaca(; htrail=0.04)
a0, a14... = naca_coeffs
fixx = 1 .- htrail * cumsum(1.3 .^ (0:4))
fixy = a0 * sqrt.(fixx) .+ fixx .^ (1:4)' * a14
fix = vcat(Point2d[(0,0),(1,0)], [ Point2d[(x,y),(x,-y)] for (x,y) in zip(fixx,fixy) ]...)
endfixnaca (generic function with 1 method)Finally, we can define a function for generating the arguments to distmesh2d for generating the NACA mesh. The parameters are the sizes from before, as well as a center point (circx,0) and a radius for the far-field circle boundary.
function dm_naca(; hlead=0.01, htrail=0.04, hmax=2.0, circx=2.0, circr=4.0)
# Distance function: Difference between the outer circle and the NACA airfoil
dfcn(p) = ddiff(dcircle(p, c=(circx, 0), r=circr), dnaca(p))
# Size function: Given by `hnaca` above
hfcn(p) = hnaca(p; hlead=hlead, htrail=htrail, hmax=hmax)
# Fix points: Add symmetry points for the circle plus the ones from `fixnaca`
fix = Point2d[(1,0),(0,1),(-1,0),(0,-1)] .* circr .+ Point2d[(circx,0)]
fix = vcat(fix, fixnaca(htrail=htrail))
# Bounding box: Determined by the far-field circle
bbox = [(circx - circr, -circr), (circx + circr, circr)]
# The `hmin` parameter needs to be the smallest element size in the domain
hmin = minimum((hlead, htrail, hmax))
dfcn, hfcn, hmin, bbox, fix
enddm_naca (generic function with 1 method)Now we can generate and plot the default mesh
msh = distmesh2d(dm_naca()...)
plot(msh)
We can modify the mesh, e.g. by shrinking the farfield circle
msh = distmesh2d(dm_naca(circx=1, circr=1.5)...)
plot(msh)
Finally, we can increase the element sizes at the sources
msh = distmesh2d(dm_naca(circx=1, circr=1.5, hlead=0.05, htrail=0.1)...)
plot(msh)