Problem Definition
Immersa.GridKind — Type
abstract type GridKind endAbstract type used to distinguish between different kinds of staggered grids. See Primal and Dual.
Immersa.Primal — Type
struct Primal <: GridKind endA GridKind tag for the main grid, typically used for primary variables (e.g., velocity).
Immersa.Dual — Type
struct Dual <: GridKind endA GridKind tag for the offset (dual) grid, often used for derived quantities (e.g., vorticity, pressure).
Immersa.GridLocation — Type
abstract type GridLocation{K<:GridKind} endAn abstract type representing where a variable is stored on a grid (e.g., node, cell, edge). It is parameterized by the GridKind K (either Primal or Dual).
Immersa.Node — Type
struct Node{K} <: GridLocation{K} endA GridLocation type indicating that a variable lives at a node of a grid of kind K.
Immersa.Edge — Type
struct Edge{K} <: GridLocation{K}
i::Int
endA GridLocation type indicating that a variable lives on an edge of a grid of kind K.
Fields
i::Int: Specifies the direction of the edge (e.g., 1 for x, 2 for y).
Immersa.Loc_u — Type
const Loc_u = Edge{Primal}Type alias for velocity, stored on the edges of the Primal grid.
Immersa.Loc_ω — Type
const Loc_ω = Edge{Dual}Type alias for vorticity, stored on the edges of the Dual grid.
Immersa.Grid — Type
struct Grid{N,T<:AbstractFloat}
h::T
n::SVector{N,Int}
x0::SVector{N,T}
levels::Int
endDefines a multi-resolution, uniform Cartesian grid.
Fields
h::T: Grid spacing (a scalar float, e.g., 0.01).n::SVector{N,Int}: Number of grid cells in each spatial dimensionN.x0::SVector{N,T}: Position of the bottom-left (origin) corner of the grid.levels::Int: Number of grid levels for multigrid.
Constructor
Grid(h::T, n, x0, levels)Creates a Grid. The number of cells n in each dimension is automatically rounded up to the nearest multiple of 4 to ensure compatibility with certain solvers (e.g., FFTs or multigrid coarsening).
Immersa.gridcorner — Function
gridcorner(grid::Grid)Returns the corner position (origin) of the base grid (grid.x0).
Arguments
grid::Grid: The grid object.
Returns
SVector: The physical coordinates of the grid's corner.
gridcorner(grid::Grid, level::Integer)Computes the corner position (origin) of a coarser multigrid level, which is centered relative to the fine grid.
Arguments
grid::Grid: The grid object.level::Integer: The multigrid level.
Returns
SVector: The physical coordinates of the coarse grid's corner.
Immersa.gridstep — Function
gridstep(grid::Grid)Returns the grid spacing (e.g., Δx) for the base grid (grid.h).
Arguments
grid::Grid: The grid object.
Returns
T: The base grid spacing.
gridstep(grid::Grid, level::Integer)Computes the grid spacing for a coarser multigrid level. Each level doubles the spacing (grid.h * 2^(level - 1)).
Arguments
grid::Grid: The grid object.level::Integer: The multigrid level.
Returns
T: The coarse grid spacing.
Immersa.coord — Function
coord(grid::Grid, loc, I::SVector{N,<:Integer}, args...)Computes the physical coordinates for a given grid index I and GridLocation loc. This is the core logic that accounts for staggered grid offsets.
Arguments
grid::Grid: The grid object.loc::GridLocation: The location type (e.g.,Node(),Edge{Primal}(1)).I::SVector: The integer grid index.args...: Optional multigrid level.
Returns
SVector: The physical coordinatesx(I) = x0 + h * (I + offset).
coord(grid, loc, I::Tuple, args...)Convenience method for coord that accepts indices as a Tuple.
coord(grid, loc, I::CartesianIndex, args...)Convenience method for coord that accepts indices as a CartesianIndex.
coord(grid, loc, r::Tuple{Vararg{AbstractRange}}, args...)Computes the physical coordinate ranges corresponding to a block of grid indices.
Arguments
grid: The grid object.loc: The grid location.r::Tuple{Vararg{AbstractRange}}: A tuple of index ranges.args...: Optional multigrid level.
Returns
Tuple: A tuple of physical coordinate ranges (e.g.,(xrange, yrange)).
Immersa._cellcoord — Function
_cellcoord(loc::Edge{Primal}, ::Val{N})Computes the fractional cell offset for a Primal edge (e.g., velocity). This is a half-cell offset in directions other than the edge's direction i.
Arguments
loc::Edge{Primal}: The primal edge location.::Val{N}: The grid dimension.
Returns
SVector: A vector of fractional offsets (e.g.,[0.0, 0.5]).
_cellcoord(loc::Edge{Dual}, ::Val{N})Computes the fractional cell offset for a Dual edge (e.g., vorticity). This is a half-cell offset along the edge's direction i.
Arguments
loc::Edge{Dual}: The dual edge location.::Val{N}: The grid dimension.
Returns
SVector: A vector of fractional offsets (e.g.,[0.5, 0.0]).
Immersa.IncludeBoundary — Type
struct IncludeBoundary endTag type used as a flag to request index ranges that include boundary points.
Immersa.ExcludeBoundary — Type
struct ExcludeBoundary endTag type used as a flag to request index ranges that exclude boundary points, returning only the grid interior.
Immersa.cell_axes — Function
cell_axes(n::SVector{N}, loc::Edge, ::IncludeBoundary)Determines the iterable index ranges for a grid location, including boundaries.
Arguments
n::SVector{N}: Number of grid cells per dimension.loc::Edge: The grid location.::IncludeBoundary: Tag specifying boundary inclusion.
Returns
TupleofUnitRange: Index ranges (e.g.,(0:n[1], 0:n[2]-1)).
cell_axes(n::SVector{N}, loc::Edge, ::ExcludeBoundary)Determines the iterable index ranges for a grid location, excluding boundaries.
Arguments
n::SVector{N}: Number of grid cells per dimension.loc::Edge: The grid location.::ExcludeBoundary: Tag specifying boundary exclusion.
Returns
TupleofUnitRange: Index ranges for the interior (e.g.,(1:n[1]-1, 0:n[2]-1)).
cell_axes(n::SVector{N}, loc::Type{<:Edge}, args...)Vectorized method for cell_axes. Returns a map of axes for all possible edge directions of a given Edge type.
Arguments
n::SVector{N}: Number of grid cells per dimension.loc::Type{<:Edge}: The edge type (e.g.,Loc_u).args...: Boundary flags (IncludeBoundaryorExcludeBoundary).
Returns
- A
maporOffsetTuplecontaining the axes for each component.
cell_axes(grid::Grid, args...)Convenience method for cell_axes that extracts the cell count n from the Grid object.
Immersa.grid_length — Function
grid_length(grid::Grid, loc::Edge, args...)Computes the total number of grid points for a single edge-centered component.
Arguments
grid::Grid: The grid object.loc::Edge: The specific edge component (e.g.,Loc_u(1)).args...: Boundary flags (IncludeBoundaryorExcludeBoundary).
Returns
Int: The total number of points (prod(length, cell_axes(...)).
grid_length(grid::Grid{N}, loc::Type{<:Edge}, args...)Computes the total number of grid points summed over all components of a given Edge type.
Arguments
grid::Grid: The grid object.loc::Type{<:Edge}: The edge type (e.g.,Loc_u).args...: Boundary flags.
Returns
Int: The sum of points over all components.
Immersa._on_bndry — Function
_on_bndry(loc::Edge{Primal}, j)Utility function. Returns true if a Primal edge (like velocity) is defined on the boundary in direction j.
Arguments
loc::Edge{Primal}: The primal edge location.j::Int: The coordinate direction to check.
Returns
Bool:trueifloc.i == j,falseotherwise.
_on_bndry(loc::Edge{Dual}, j)Utility function. Returns true if a Dual edge (like vorticity) is defined on the boundary in direction j.
Arguments
loc::Edge{Dual}: The dual edge location.j::Int: The coordinate direction to check.
Returns
Bool:trueifloc.i != j,falseotherwise.
Immersa.boundary_axes — Function
boundary_axes(n::SVector{N}, loc::Edge)Returns ranges of grid indices that lie exactly on the boundaries of a single edge-defined field component.
Arguments
n::SVector{N}: Number of grid cells per dimension.loc::Edge: A specific edge component (e.g.,Loc_u(1)).
Returns
SArray: An array of index ranges for each boundary face (e.g., left, right, top, bottom).
boundary_axes(n::SVector{N}, loc::Type{<:Edge}; dims=...)Applies boundary_axes to all edge directions for a vector-valued field, returning a list of boundary index ranges for each component.
Arguments
n::SVector{N}: Number of grid cells per dimension.loc::Type{<:Edge}: An edge type (e.g.,Loc_u).dims: The dimensions to iterate over.
Returns
- A
mapof results from the single-componentboundary_axesmethod.
boundary_axes(grid::Grid, args...; kw...)Convenience method for boundary_axes that extracts the cell count n from the Grid object.
Immersa.boundary_length — Function
boundary_length(grid::Grid, loc::Edge)Computes the total number of degrees of freedom (grid points) located exactly on the boundaries for a single staggered field component.
Arguments
grid::Grid: The grid object.loc::Edge: A specific edge component.
Returns
Int: Total number of boundary points for this component.
boundary_length(grid::Grid{N}, loc::Type{<:Edge})Computes the total number of boundary degrees of freedom summed over all components of a given Edge type.
Arguments
grid::Grid: The grid object.loc::Type{<:Edge}: An edge type (e.g.,Loc_u).
Returns
Int: Sum of boundary points over all components.
Immersa._exclude_boundary — Function
_exclude_boundary(a, grid, loc)Returns a collection of "interior" views of an array a, excluding boundary points.
Arguments
a: An array or tuple of arrays (one for each field component).grid::Grid: The grid object.loc: The grid location type (e.g.,Loc_u).
Returns
- A
TupleorArrayof non-allocating views (@view) into the interior region of each component array ina.
Immersa.edge_axes — Function
edge_axes(::Val{N}, loc::Type{<:Edge})Provides the list of possible directions (axes) associated with edges on a grid of dimension N.
Arguments
::Val{N}: The grid dimension.loc::Type{<:Edge}: The edge type.
Returns
- A tuple of directions, e.g.,
(1, 2)forN=2.
edge_axes(::Val{2}, loc::Type{Edge{Dual}})Provides the list of axes for a 2D Dual edge. This is a special case, likely for 2D vorticity, which returns OffsetTuple{3}((3,)) to represent the single z-component.
Arguments
::Val{2}: The grid dimension (specifically 2).loc::Type{Edge{Dual}}: The Dual edge type.
Returns
OffsetTuple{3}((3,))
Immersa.grid_zeros — Function
grid_zeros(backend, grid, loc::GridLocation, bndry=IncludeBoundary())Creates a single array of zeros, correctly sized and indexed for a given grid location, allocated on the specified backend.
Arguments
backend: TheKernelAbstractionsbackend (e.g.,CPU()).grid::Grid: The grid object.loc::GridLocation: The specific grid location (e.g.,Loc_u(1)).bndry: Boundary flag (default:IncludeBoundary()).
Returns
- A single
OffsetArrayof zeros, with indices matchingcell_axes.
grid_zeros(backend, grid, loc::Type{<:Edge}, args...; levels=1)Creates a structure of zero-filled arrays for all components of an Edge type, potentially replicated for multiple multigrid levels.
Arguments
backend: TheKernelAbstractionsbackend.grid::Grid: The grid object.loc::Type{<:Edge}: The edge type (e.g.,Loc_u).args...: Boundary flags.levels::Int: Number of multigrid levels (default: 1).
Returns
- A
map(orOffsetTuple) of arrays for all components, potentially nested inside anothermapiflevels > 1.
Immersa.boundary_zeros — Function
boundary_zeros(backend, grid::Grid{N,T}, loc)Returns a nested structure of zero-filled arrays to store values on the grid boundaries. These arrays are correctly indexed OffsetArrays allocated on the specified backend.
Arguments
backend: TheKernelAbstractionsbackend.grid::Grid: The grid object.loc: The grid location type (e.g.,Loc_u).
Returns
- A nested structure:
mapover components ->SArrayover faces ->OffsetArrayof zeros for that specific boundary face.
Immersa.grid_view — Function
grid_view(a, grid, loc, bndry)Creates views of grid data arrays, sliced according to the active region defined by cell_axes.
Arguments
a: An array or tuple of arrays (one for each field component).grid::Grid: The grid object.loc: The grid location type (e.g.,Loc_u).bndry: Boundary flag (IncludeBoundary()orExcludeBoundary()).
Returns
- A
mapof non-allocating views (@view) into the active region of each component array ina.
Immersa.IrrotationalFlow — Type
IrrotationalFlowAbstract type specifying a flow where the curl of the velocity is zero (∇ × u = 0). This is a "tag" type used for dispatch.
Immersa.UniformFlow — Type
UniformFlow(u)A type of IrrotationalFlow representing a flow that is uniform in space but may vary in time.
Fields
u: The freestream velocity. Can be a constantSVectoror a functionu(t)that returns anSVector.
Immersa.add_flow! — Function
add_flow!(u, flow::UniformFlow, _, _, _, t)Adds the background UniformFlow velocity to the velocity field u in-place. Computes u_new = u_old + u_flow(t).
Arguments
u: The velocity field (e.g., a tuple of arrays). Modified in-place.flow::UniformFlow: The background flow object._: Placeholders for unused arguments.t: The current simulation time.
Returns
- The modified velocity field
u.
Immersa.BodyPoints — Type
struct BodyPoints{N,T,V<:AbstractVector{SVector{N,T}},S<:AbstractVector{T}}
x::V
u::V
ds::S
endAn "immersed object container" that holds the Lagrangian body points and their attributes.
Fields
x: Vector of body point positions (each anSVector{N,T}).u: Vector of body point velocities (each anSVector{N,T}).ds: Vector of quadrature weights (e.g., line segment lengths) for each point.
Base.view — Method
Base.view(points::BodyPoints, r)Overloads Base.view to create a lightweight, non-allocating "slice" or "window" of a BodyPoints object.
Arguments
points::BodyPoints: The originalBodyPointsobject.r: An index range (e.g.,201:400).
Returns
BodyPoints: A newBodyPointsobject whose fields (x,u,ds) areviews into the fields of the original object.
Immersa.AbstractBody — Type
AbstractBodyAn abstract type defining the interface for a body that interacts with the fluid. A body specifies a set of points and prescribes the flow velocity in a small region near each point.
Immersa.IBProblem — Type
struct IBProblem{N,T,B<:AbstractBody,U<:IrrotationalFlow}
grid::Grid{N,T}
body::B
Re::T
u0::U
endDefines the entire immersed boundary problem to be solved. An IBProblem instance contains all necessary components: grid, body, Reynolds number, and background flow.
Parameters
N: Dimension of the problem (2D or 3D).T: Scalar type (e.g.,Float64).B<:AbstractBody: The concrete body type.U<:IrrotationalFlow: The concrete background flow type.
Fields
grid::Grid{N,T}: The fluid grid.body::B: The immersed body (must be a subtype ofAbstractBody).Re::T: The Reynolds number.u0::U: The background flow (must be a subtype ofIrrotationalFlow).