Boundary conditions
Thermal, mass, and pressure boundary conditions, collected per-face into a BoundaryConditionSet. Thermal and mass BCs compose additively with +. See the User Guide's boundary-conditions chapter.
Thermal
Pyrolysis.BoundaryConditions.AdiabaticBC — Type
AdiabaticBC <: AbstractThermalBCZero heat flux (perfectly insulated) boundary condition.
Pyrolysis.BoundaryConditions.HeatFluxBC — Type
HeatFluxBC{F} <: AbstractThermalBCPrescribed heat flux boundary condition: q" = flux(t) or constant.
Fields
flux::F: Heat flux [W/m²], positive into domain
Example
bc = HeatFluxBC(50e3) # Constant 50 kW/m²
bc = HeatFluxBC(t -> 50e3 * (1 - exp(-t/10))) # Time-varyingPyrolysis.BoundaryConditions.ConvectiveBC — Type
ConvectiveBC{Fh,FT} <: AbstractThermalBCConvective heat transfer boundary condition: q" = h(T∞ - T_surface)
Fields
h::Fh: Heat transfer coefficient [W/(m²·K)]T_inf::FT: Ambient temperature [K]
Example
bc = ConvectiveBC(h=10.0, T_inf=300.0)
bc = ConvectiveBC(h=10.0, T_inf=t -> 300 + 0.1*t) # Warming ambientPyrolysis.BoundaryConditions.RadiativeBC — Type
RadiativeBC{Fε,FT,FF} <: AbstractThermalBCRadiative heat transfer boundary condition: q" = F × ε × σ × (T∞⁴ - T_surface⁴)
Models thermal radiation exchange between a surface and its surroundings. The heat flux is positive when T∞ > Tsurface (heating) and negative when Tsurface > T∞ (cooling/re-radiation loss).
Fields
ε::Fε: Surface emissivity [-], range 0-1. Can be:nothing(default): Use effective emissivity from material properties (ε_eff = Σⱼ vⱼ εⱼ).
This is the recommended setting as it automatically tracks composition changes.- A constant value (e.g., 0.9)
- A temperature-dependent function (e.g., T -> 0.85 + 0.1*(T-300)/700)
Typical values:
- Polymers: 0.85 - 0.95
- Char/carbon: 0.90 - 0.98
- Polished metals: 0.02 - 0.10
- Oxidized metals: 0.40 - 0.80
T_inf::FT: Ambient/surroundings temperature [K]. Can be constant or time-dependent.F::FF: View factor [-], range 0-1. Fraction of radiation leaving the surface
that reaches the surroundings at T_inf. Default is 1.0 (surface fully sees surroundings). Use values < 1 for:
- Partially enclosed surfaces
- Surfaces facing walls at different temperatures
- Complex geometries with self-viewing
Example
# Use effective emissivity from material (recommended, default)
bc = RadiativeBC(T_inf=300.0)
# Override with fixed emissivity
bc = RadiativeBC(ε=0.9, T_inf=300.0)
# With view factor for partially enclosed surface
bc = RadiativeBC(T_inf=300.0, F=0.7)
# Temperature-dependent emissivity (e.g., char formation)
bc = RadiativeBC(ε=T -> 0.85 + 0.1*(T-300)/700, T_inf=300.0)Note
When ε=nothing (default), the effective emissivity is computed as the volume-weighted average of component emissivities: ε_eff = Σⱼ vⱼ εⱼ. This automatically tracks the change in surface properties as material decomposes (e.g., polymer → char).
Pyrolysis.BoundaryConditions.RadiativeFluxBC — Type
RadiativeFluxBC{F,A} <: AbstractThermalBCExternal radiative heat source (e.g., cone heater, furnace, radiant panel).
This BC represents incident radiation from an external source. Unlike HeatFluxBC which applies flux directly at the surface, RadiativeFluxBC accounts for:
- Surface absorptivity: fraction (absorptivity) enters material, rest is reflected
- Radiation distribution: controlled by
radiation_modelparameter insolve()
The absorbed flux is: qabsorbed = absorptivity × incidentflux
The distribution of absorbed radiation depends on the radiation_model passed to solve():
SURFACE_ABSORPTION: All absorbed radiation deposited in surface cell (opaque materials)BEER_LAMBERT: In-depth volumetric absorption via Beer-Lambert law (semi-transparent)P1_QUASI_STEADY: P1 radiative transfer with volumetric emission
Fields
flux::F: Incident radiative flux [W/m²] (constant or time-dependent)absorptivity::A: Surface absorptivity (0-1). Can be:nothing(default): Use effective emissivity from material properties (ε_eff = Σⱼ vⱼ εⱼ).
By Kirchhoff's law, absorptivity = emissivity at thermal equilibrium.- A constant value (e.g., 0.9)
- A time-dependent function (e.g., t -> 0.9 + 0.05*t/100)
Example
# Use effective emissivity as absorptivity (recommended)
bc = RadiativeFluxBC(flux=25e3)
# Override with fixed absorptivity
bc = RadiativeFluxBC(flux=50e3, absorptivity=0.9)
# Time-varying flux with dynamic absorptivity
bc = RadiativeFluxBC(flux=t -> 25e3 * (1 - exp(-t/10)))
# Control radiation distribution via solve()
solve(problem; radiation_model=SURFACE_ABSORPTION) # Opaque material
solve(problem; radiation_model=BEER_LAMBERT) # Semi-transparentNote
When absorptivity=nothing (default), the effective emissivity is used as absorptivity (Kirchhoff's law). This automatically tracks composition changes as material decomposes.
Do NOT combine RadiativeFluxBC with HeatFluxBC for the same radiation source - this would double-count the energy input.
Pyrolysis.BoundaryConditions.DirichletThermalBC — Type
DirichletThermalBC{FT} <: AbstractThermalBCPrescribed temperature boundary condition: T = T_bc
Fields
T::FT: Boundary temperature [K]
Pyrolysis.BoundaryConditions.CombinedThermalBC — Type
CombinedThermalBC{BCs<:Tuple} <: AbstractThermalBCCombined thermal boundary condition (sum of multiple BCs).
Fields
bcs::BCs: Tuple of boundary conditions
Example
bc = HeatFluxBC(50e3) + RadiativeBC(ε=0.9, T_inf=300.0) + ConvectiveBC(h=10.0, T_inf=300.0)Mass (species)
Pyrolysis.BoundaryConditions.ImpermeableBC — Type
ImpermeableBC <: AbstractMassBCZero mass flux (impermeable) boundary condition.
Pyrolysis.BoundaryConditions.MassFluxBC — Type
MassFluxBC{F} <: AbstractMassBCPrescribed mass flux boundary condition.
Fields
flux::F: Mass flux [kg/(m²·s)] for each gas component
Pyrolysis.BoundaryConditions.ConvectiveMassBC — Type
ConvectiveMassBC{Fh,Fξ} <: AbstractMassBCConvective mass transfer boundary condition for gas escape at boundaries.
The mass flux is computed as: J = hm × (ξinf - ξ_surface) [kg/(m²·s)]
where ξ is mass concentration [kg/m³]. This represents external convective mass transfer where gas is carried away by the external flow.
Fields
h_m::Fh: External mass transfer coefficient [m/s]. This is a velocity-based coefficient representing the convective mass transfer rate. Typical values:- Natural convection: 0.01 - 0.05 m/s
- Forced convection (low velocity): 0.05 - 0.1 m/s
- Forced convection (high velocity): 0.1 - 0.5 m/s
ξ_inf::Fξ: Ambient mass concentration [kg/m³]. One of:- a
Real— the same ambient concentration for every gas species (typically 0: the atmosphere carries no pyrolyzate); - a
Functionoft— time-varying scalar, broadcast to every gas species; - an
NTuple{NC,Real}— per-species ambient concentrations, indexed by the material's component index (condensed-phase entries are ignored — mass BCs only act on gas species). Required to represent ambient air ingress without injecting pyrolyzate: a scalarξ_inf > 0would feed that concentration of every gas species into the domain.
- a
Physical Interpretation
The coefficient hm can be estimated from heat-mass transfer analogy: hm ≈ h / (ρair × cpair) where h is the convective heat transfer coefficient [W/(m²·K)].
For a typical cone calorimeter with h ≈ 10 W/(m²·K): h_m ≈ 10 / (1.2 × 1000) ≈ 0.008 m/s
Example
bc = ConvectiveMassBC(h_m=0.05, ξ_inf=0.0) # Gas escapes to atmosphere
bc = ConvectiveMassBC(h_m=t -> 0.05*(1 + 0.1*t), ξ_inf=0.0) # Time-varying
# Per-species: components = (virgin_solid, pyrolyzate, O₂); ambient carries
# O₂ at 0.27 kg/m³ but no pyrolyzate:
bc = ConvectiveMassBC(h_m=0.05, ξ_inf=(0.0, 0.0, 0.27))Pyrolysis.BoundaryConditions.DiffusiveMassBC — Type
DiffusiveMassBC{Fh} <: AbstractMassBCDiffusive mass transfer boundary condition using the internal diffusion model.
The flux is computed as: J = λ × ξ / d × hmfactor
where:
- λ = gas transfer coefficient from material [m²/s]
- ξ = gas concentration at surface cell [kg/m³]
- d = distance from cell center to boundary [m]
- hmfactor = external resistance factor (default Inf = no external resistance)
For combined internal + external resistance: J = ξ / (d/λ + 1/hm) = λ × hm × ξ / (λ + h_m × d)
When hm → ∞: J = λ × ξ / d (pure diffusion, default) When hm → 0: J = 0 (impermeable)
This BC ensures consistency between species transport and ALE regression.
Fields
h_m::Fh: External mass transfer coefficient [m/s] (Inf = no external resistance)
Pyrolysis.BoundaryConditions.CombinedMassBC — Type
CombinedMassBC{BCs<:Tuple} <: AbstractMassBCCombined mass boundary condition (sum of multiple BCs).
This mirrors CombinedThermalBC and allows combining multiple mass BCs at a single boundary. The total mass flux is the sum of individual BC fluxes.
Fields
bcs::BCs: Tuple of boundary conditions
Example
# Combine diffusive and convective mass transfer
bc = DiffusiveMassBC(Inf) + ConvectiveMassBC(h_m=0.01, ξ_inf=0.0)Note
For most pyrolysis applications, a single mass BC (usually DiffusiveMassBC or ConvectiveMassBC) is sufficient. Combined mass BCs are useful for:
- Modeling competing transport mechanisms
- Complex surface resistance models
- Research/experimental validation
Pressure (Darcy mode)
Pyrolysis.BoundaryConditions.DirichletPressureBC — Type
DirichletPressureBC <: AbstractMassBCFixed pressure at boundary (typically atmospheric at exposed surface).
When Darcy flow is enabled, this BC computes the gas velocity from the pressure gradient between the boundary and the interior cell: vg = -(κ/μ) × (Pbc - P_interior) / d
where d is the distance from the cell center to the boundary.
Fields
P::Float64: Boundary pressure [Pa]
Example
bc = DirichletPressureBC(101325.0) # Atmospheric pressure
bc = DirichletPressureBC() # Default: 101325 PaPyrolysis.BoundaryConditions.NeumannPressureBC — Type
NeumannPressureBC <: AbstractMassBCZero or prescribed pressure gradient at boundary (impermeable or specified flux).
For Darcy flow:
- ∂P/∂n = 0 (default): Zero gas velocity (impermeable)
- ∂P/∂n ≠ 0: Gas velocity v_g = -(κ/μ) × ∂P/∂n
Fields
∂P∂n::Float64: Pressure gradient normal to boundary [Pa/m] (default: 0 = impermeable)
Example
bc = NeumannPressureBC() # Impermeable (zero gradient)
bc = NeumannPressureBC(0.0) # Same as above
bc = NeumannPressureBC(1000.0) # Prescribed pressure gradientPyrolysis.BoundaryConditions.ConvectivePressureBC — Type
ConvectivePressureBC <: AbstractMassBCPressure-driven outflow with resistance (Robin-type BC for pressure).
The gas velocity at the boundary is computed as: vg·n = hP × (Pinternal - Pexternal)
This models a surface with finite resistance to gas flow, such as:
- Surface char layer with limited permeability
- Protective coating or membrane
- Blowing resistance at high mass flux
Fields
h_P::Float64: Pressure transfer coefficient [m/(Pa·s)]P_ext::Float64: External pressure [Pa]
Example
bc = ConvectivePressureBC(1e-6, 101325.0) # Typical resistance, atmospheric exteriorNote
hP → ∞ approaches DirichletPressureBC behavior hP → 0 approaches ImpermeableBC behavior
Container and helpers
Pyrolysis.BoundaryConditions.BoundaryConditionSet — Type
BoundaryConditionSet{TT <: NamedTuple, MT <: NamedTuple}Type-stable, tag-keyed container for boundary conditions. Each tag (e.g. :top, :bottom for 1D, additional tags for 2D/3D) maps to one AbstractThermalBC and one AbstractMassBC. Internal storage is a typed NamedTuple per BC kind, so symbol lookup compiles to a direct field read and the residual specializes statically.
Fields
thermal::TT:NamedTuple{tags, Tuple{<: AbstractThermalBC, ...}}mass::MT:NamedTuple{tags, Tuple{<: AbstractMassBC, ...}}
1D convention
:top↔ exposed surface (z = L):bottom↔ substrate (z = 0)
Construction
The keyword constructor is the user-facing API. Each BC kind takes a NamedTuple of tag => BC mappings. A future 2D constructor takes a richer tag set without changing the field shape.
Example
bc_set = BoundaryConditionSet(
thermal = (top = HeatFluxBC(50e3) + RadiativeBC(ε = 0.9, T_inf = 300),
bottom = AdiabaticBC()),
mass = (top = DiffusiveMassBC(Inf),
bottom = ImpermeableBC()),
)Accessors
get_thermal_bc(bc_set, Val(:top))/Val(:bottom)get_mass_bc(bc_set, Val(:top))/Val(:bottom)
Pyrolysis.Physics.background_gas_concentration — Function
background_gas_concentration(material, species, ξ, T; P = 101325.0) -> Float64Bulk concentration [kg/m³] of gas component species whose partial pressure equals P in the pore space of composition ξ at temperature T — the single-species inverse of ideal_gas_pressure:
ξⱼ = P · Mⱼ · φ(ξ, T) / (R · T)Use this to initialize a background air component at ambient pressure in DarcyFick-mode problems: a pore space initialized to vacuum (all gas ξⱼ = 0) against a 101325 Pa pressure boundary spuriously advects early product gas inward down the absolute-pressure slope, instead of the gas being resisted by ~1 atm of pore air.
species is a component index or name. Porosity is evaluated from the condensed entries of ξ (gas entries carry no matrix volume), so passing a solids-only initial composition is exact. Partial pressures of coexisting gas species add — this function pressurizes species alone to P.
Example
air = GaseousComponent(:AIR, M = 0.02897, c = 1006.0, k = 0.026, λ = 2e-5)
# ... material includes `air`; ξ₀ is the condensed initial composition ...
ξ_air = background_gas_concentration(material, :AIR, ξ₀, 300.0)