Getting Started
Installation
GridGeneration.jl is registered in the General registry:
using Pkg
Pkg.add("GridGeneration")To work on the package itself, clone the repository and run Pkg.develop(path="path/to/GridGeneration.jl").
Grid and metric conventions
- A block is a
[2, Ni, Nj]array:block[1, i, j]andblock[2, i, j]are the x and y coordinates of node(i, j). - An initial block can be built from its four edges with
TFI. The edges are given as[top, right, bottom, left], each anN×2array, all running left→right or bottom→top. - A metric is any function
M(x, y) -> (M11, M22)returning the diagonal of the metric tensor. Larger values ask for finer spacing: with a constant metricm, the target spacing is1/sqrt(m).make_getMetricbuilds distance-based metrics around a polyline and/or a hotspot. - Boundary conditions (
bndInfo) and block-to-block interfaces (interInfo) are vectors of dictionaries; see Grid Format. For a single block with no special boundaries, empty vectors are fine.
A first grid
Build a 4×2 rectangle, ask for fine spacing near the point (1, 0), split it into four blocks, redistribute the points, and smooth:
using GridGeneration
N = 41
top = [range(0, 4, length=N) fill(2.0, N)]
right = [fill(4.0, N) range(0, 2, length=N)]
bottom = [range(0, 4, length=N) zeros(N)]
left = [zeros(N) range(0, 2, length=N)]
initialGrid = TFI([top, right, bottom, left])
# background spacing ≈ 0.1 everywhere, refined around (1, 0)
hotspot = make_getMetric(nothing; A_origin = 2000.0, ℓ_origin = 0.3, p_origin = 2,
origin_center = (1.0, 0.0), floor = 100.0)
params = SimParams(
splitLocations = [[11], [11]], # split at i = 11 and j = 11
boundarySolver = :analytic,
smoothMethod = :ellipticSS,
elliptic = EllipticParams(max_iter = 2000, useBottomWall = true),
)
result = GenerateGrid(initialGrid, Any[], Any[], hotspot; params = params)
size.(result.smoothBlocks)4-element Vector{Tuple{Int64, Int64, Int64}}:
(2, 27, 17)
(2, 52, 17)
(2, 27, 23)
(2, 52, 23)GenerateGrid returns a NamedTuple:
keys(result)(:smoothBlocks, :blocks, :bndInfo, :interInfo, :finalErrors, :finalIterations)blocksis the grid after edge redistribution,smoothBlocksafter elliptic smoothing.bndInfoandinterInfoare updated to the new block sizes.finalErrorsandfinalIterationsreport the smoother's convergence for each block.
result.finalIterations4-element Vector{Int64}:
1676
1842
2000
2000Each stage can be switched off through SimParams (useSplitting, useEdgeSolver, useSmoothing), or run directly with SplitMultiBlock, SolveAllBlocks and SmoothBlocks.
Saving to a Tortuga grid file
Tortuga grids are 3D, so the 2D blocks are extruded first:
mesh3D, bnd3D, itf3D = convert_2D_to_3D(result.smoothBlocks, result.bndInfo, result.interInfo,
0.1, 20) # extrusion length, number of k-layers
write_turtle_grid(mesh3D, itf3D, bnd3D, "mygrid.grid")An existing grid is read back with ImportTurtleGrid, and a metric field file with readTurtleFields.
More examples
The repository's examples/ folder has a complete airfoil case and a template for regenerating an existing Tortuga grid; see examples/README.md.