Geometry and meshes
One-dimensional cell-centered finite-volume meshes. See the User Guide's meshes chapter.
Pyrolysis.Geometry.create_uniform_mesh — Function
create_uniform_mesh(L::Real, n_cells::Int, ::Val{NC};
T_initial::Real=300.0,
ξ_initial=nothing,
cross_section_area::Real=1.0) -> Mesh1D{NC}Create a uniform 1D mesh.
Arguments
L: Domain length (thickness) [m]n_cells: Number of cellsVal{NC}: Number of components as a type parameter (useVal(NC))T_initial=300.0: Initial temperature [K]ξ_initial=nothing: Initial concentrations (NTuple or scalar)cross_section_area=1.0: Cross-sectional area [m²]
Returns
A Mesh1D{NC} with uniform cell spacing.
Convention
- z = 0 is the BOTTOM surface (substrate, boundary_id = 2)
- z = L is the TOP surface (exposed surface, boundary_id = 1)
- Cell 1 is at z ≈ 0 (bottom), Cell N is at z ≈ L (top)
- Heat enters from the top (z = L), material shrinks toward bottom
Example
mesh = create_uniform_mesh(0.01, 100, Val(2)) # 1 cm, 100 cells, 2 componentsPyrolysis.Geometry.create_stretched_mesh — Function
create_stretched_mesh(L::Real, n_cells::Int, ::Val{NC}, stretch::Real;
T_initial::Real=300.0,
ξ_initial=nothing,
cross_section_area::Real=1.0,
stretch_from::Symbol=:top) -> Mesh1D{NC}Create a geometrically stretched 1D mesh with the finest cells at the boundary named by stretch_from and cell sizes growing geometrically (ratio stretch) away from it.
Arguments
L: Domain length [m]n_cells: Number of cellsVal{NC}: Number of components as a type parameter (useVal(NC))stretch: Geometric size ratio between adjacent cells (must be ≥ 1; 1 = uniform). Each cell isstretchtimes thicker than its neighbor on the refined side.T_initial=300.0: Initial temperature [K]ξ_initial=nothing: Initial concentrationscross_section_area=1.0: Cross-sectional area [m²]stretch_from=:top: Which boundary gets the finest cells —:top(exposed surface at z = L, the default) or:bottom(substrate at z = 0)
Returns
A Mesh1D{NC} with geometric stretching.
Example
# Fine mesh near top surface (z=L), coarser toward bottom (z=0)
mesh = create_stretched_mesh(0.01, 50, Val(2), 1.1; stretch_from=:top)Pyrolysis.Geometry.MeshTopology — Type
MeshTopology — immutable connectivity.
A MeshTopology{D, NC} carries everything that does not change once the mesh is built: nodes, cells, faces, boundary tags, and dimensional metadata. Its mutable counterpart is MeshGeometry.
The pair is the dimension-parameterised mesh description for a multi-dimensional extension. ProblemDef carries a MeshTopology, but the 1D residual and Jacobian read connectivity from Mesh1D and geometry from the StateCache; neither reads this type.
Type Parameters
D: Spatial dimension (1 today; 2/3 are the design target)NC: Number of components (carried for compile-time dispatch by consumers)
Fields
nodes::Vector{NodeT}: Node objects (Node1D for D=1)cells::Vector{CellT}: Cell objectsfaces::Vector{FaceT}: Face objectsboundary_tags::Dict{Symbol,Vector{Int}}: tag => face IDs (e.g.:top,:bottom)n_active_cells::Int: Active (leaf) cell count for AMR
Pyrolysis.Geometry.MeshGeometry — Type
MeshGeometry — mutable per-step geometry.
A MeshGeometry{D} carries the geometric quantities that change as the mesh moves (ALE) or is regenerated (AMR): node positions, cell volumes, face areas and (for D ≥ 2) face normals. The cross-sectional area A(t) for the 1D specialization lives here as a scalar.
The Workspace carries one, built from the mesh at construction, as the mutable counterpart of the immutable MeshTopology for a multi-dimensional extension. The 1D residual reads its geometry from the StateCache, not from this type.
Type Parameters
D: Spatial dimension (1 today; 2/3 are the design target)
Fields (1D specialization layout)
node_positions::Vector{Float64}: currentzper nodenode_positions_ref::Vector{Float64}: reference (initial)zper nodecell_centers::Vector{Float64}: cell center positionscell_volumes::Vector{Float64}: cell volumesface_positions::Vector{Float64}: face positionsface_areas::Vector{Float64}: face cross-sectional areasnode_velocities::Vector{Float64}: ALE mesh velocitiesmesh_time::Base.RefValue{Float64}: timestamp of the geometry snapshotcross_section_area::Base.RefValue{Float64}: currentA(t)(scalar in 1D)cross_section_area_initial::Float64: calibration referenceA_0
For D ≥ 2, node_positions and face_normals become Vector{SVector{D,Float64}} and cross_section_area* becomes a per-face scalar.