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.HeatFluxBCType
HeatFluxBC{F} <: AbstractThermalBC

Prescribed 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-varying
source
Pyrolysis.BoundaryConditions.ConvectiveBCType
ConvectiveBC{Fh,FT} <: AbstractThermalBC

Convective 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 ambient
source
Pyrolysis.BoundaryConditions.RadiativeBCType
RadiativeBC{Fε,FT,FF} <: AbstractThermalBC

Radiative 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).

source
Pyrolysis.BoundaryConditions.RadiativeFluxBCType
RadiativeFluxBC{F,A} <: AbstractThermalBC

External 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:

  1. Surface absorptivity: fraction (absorptivity) enters material, rest is reflected
  2. Radiation distribution: controlled by radiation_model parameter in solve()

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-transparent

Note

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.

source
Pyrolysis.BoundaryConditions.CombinedThermalBCType
CombinedThermalBC{BCs<:Tuple} <: AbstractThermalBC

Combined 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)
source

Mass (species)

Pyrolysis.BoundaryConditions.ConvectiveMassBCType
ConvectiveMassBC{Fh,Fξ} <: AbstractMassBC

Convective 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 Function of t — 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 > 0 would feed that concentration of every gas species into the domain.

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))
source
Pyrolysis.BoundaryConditions.DiffusiveMassBCType
DiffusiveMassBC{Fh} <: AbstractMassBC

Diffusive 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)
source
Pyrolysis.BoundaryConditions.CombinedMassBCType
CombinedMassBC{BCs<:Tuple} <: AbstractMassBC

Combined 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
source

Pressure (Darcy mode)

Pyrolysis.BoundaryConditions.DirichletPressureBCType
DirichletPressureBC <: AbstractMassBC

Fixed 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 Pa
source
Pyrolysis.BoundaryConditions.NeumannPressureBCType
NeumannPressureBC <: AbstractMassBC

Zero 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 gradient
source
Pyrolysis.BoundaryConditions.ConvectivePressureBCType
ConvectivePressureBC <: AbstractMassBC

Pressure-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 exterior

Note

hP → ∞ approaches DirichletPressureBC behavior hP → 0 approaches ImpermeableBC behavior

source

Container and helpers

Pyrolysis.BoundaryConditions.BoundaryConditionSetType
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)
source
Pyrolysis.Physics.background_gas_concentrationFunction
background_gas_concentration(material, species, ξ, T; P = 101325.0) -> Float64

Bulk 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)
source