5. Boundary and Initial Conditions
Boundary conditions (BCs) tell the solver how heat and gas enter and leave the 1-D column; initial conditions set the temperature and composition at t = 0. This chapter shows how to build a BoundaryConditionSet, the complete catalogue of thermal, mass, pressure, and mesh-motion BCs with every field and default, how the surface energy balance is solved, and how to specify initial temperature and concentration profiles. The physics and derivations behind each BC live in the Technical Reference §12 (and the radiation models in §8); this chapter is about how to specify them correctly.
Coordinate and sign reminders (see Technical Reference §2). The axial coordinate is
z.z = 0is the bottom / substrate (tag:bottom, boundary id 2);z = Lis the top / exposed surface (tag:top, boundary id 1). Heat normally enters from the top. For all BCs in this package the sign convention is: positive flux = into the domain (heating, or mass entering). A gas escaping out of the top therefore has a negative boundary mass flux in the BC's own convention.
5.1 The BoundaryConditionSet
All boundary conditions are bundled in a single tag-keyed container, BoundaryConditionSet. It holds exactly two kinds of BC — thermal and mass — each as a NamedTuple keyed by boundary tag (:top, :bottom in 1-D):
using Pyrolysis
bc_set = BoundaryConditionSet(
thermal = (top = HeatFluxBC(50e3) + RadiativeBC(ε = 0.9, T_inf = 300.0),
bottom = AdiabaticBC()),
mass = (top = DiffusiveMassBC(0.01),
bottom = ImpermeableBC()),
)Both keyword arguments default to fully-insulated, impermeable boundaries:
# Equivalent to the explicit defaults below
bc_set = BoundaryConditionSet()
# thermal = (top = AdiabaticBC(), bottom = AdiabaticBC())
# mass = (top = ImpermeableBC(), bottom = ImpermeableBC())Key facts about the constructor:
- Partial specification is allowed. Whatever you supply is merged over the defaults, so
BoundaryConditionSet(thermal = (top = HeatFluxBC(50e3),))leaves the bottom adiabatic and both mass faces impermeable. (Note the trailing comma — a one-elementNamedTupleneeds it.) - Type checking is enforced at construction. Passing a mass BC into a thermal slot (or vice-versa) throws an
ArgumentErrorimmediately. - It is type-stable. Each tag compiles to a direct field read via
Val{tag}dispatch, so the residual specializes statically with zero runtime overhead.
The set is then handed to PyrolysisProblem via the bc_set keyword:
problem = PyrolysisProblem(
mesh = mesh,
material = material,
bc_set = bc_set,
T_initial = z -> 300.0,
ξ_initial = [z -> 1190.0, z -> 0.0],
tspan = (0.0, 100.0),
)Note on mesh motion and radiation BCs. The
BoundaryConditionSethas onlythermalandmassfields. ALE mesh motion needs no BC at all — it is computed automatically from the physics (§5.7) — and the P1 radiation BCs (§5.6) are not stored in this container: they live in a separateRadiationBCSetinside theExperimentalmodule. External incident radiation (cone heater, panel) is specified as a thermal BC (RadiativeFluxBC, §5.2.6), not as a radiation BC.
5.2 Thermal boundary conditions
Thermal BCs are subtypes of AbstractThermalBC. They are the heat-side input to the surface energy balance that the solver closes by a Newton iteration for the surface temperature T_s (§5.4). Every flux is reported with the positive = into domain convention.
| BC type | Physical flux q_BC | Key parameters (defaults) |
|---|---|---|
AdiabaticBC | 0 | — |
HeatFluxBC | q(t) (prescribed) | flux |
ConvectiveBC | h·(T_∞ − T_s) | h, T_inf |
RadiativeBC | F·ε_eff·σ·(T_∞⁴ − T_s⁴) | ε (nothing), T_inf, F (1.0) |
RadiativeFluxBC | α·Φ_incident (model-dependent) | flux, absorptivity (nothing ⇒ a_eff) |
DirichletThermalBC | enforces T_s = T | T |
CombinedThermalBC | Σ_i q_BC,i | built via + |
All exported by using Pyrolysis.
5.2.1 AdiabaticBC — perfect insulation
bc = AdiabaticBC()Zero heat flux. This is the default for both faces and the usual choice for the substrate (back face) in a cone-calorimeter idealization where the sample is mounted on insulation.
5.2.2 HeatFluxBC — prescribed flux
bc = HeatFluxBC(50e3) # constant 50 kW/m² into the surface
bc = HeatFluxBC(t -> 50e3 * (1 - exp(-t / 10))) # ramp-up over ~10 sThe single field, flux, is the heat flux q_BC in W/m², positive into the domain. It may be a constant (Real) or a function of time t. Use this for direct-contact heating or for an opaque surface where you want to inject a flux directly (rather than via the radiation models, see RadiativeFluxBC). dq_BC/dT_s = 0, so it does not couple to the surface temperature.
5.2.3 ConvectiveBC — Newton cooling
bc = ConvectiveBC(h = 10.0, T_inf = 300.0)
bc = ConvectiveBC(h = 10.0, T_inf = t -> 300 + 0.1 * t) # warming ambientNewton's cooling law q_BC = h·(T_∞ − T_s). Fields:
h— convective heat-transfer coefficienth_convin W·m⁻²·K⁻¹. Constant orh(t). Validated to be non-negative.T_inf— ambient temperatureT_∞in K. Constant orT_∞(t). Validated to be positive.
The flux is positive (heating) when T_∞ > T_s and negative (cooling) when the surface is hotter than the surroundings — the usual re-radiation/convection loss direction during pyrolysis. Its temperature derivative dq_BC/dT_s = −h makes the Newton solve converge quickly.
Blowing. Strong outgassing thickens the boundary layer and suppresses convective exchange, and a gas denser than the free stream can pool on the face. How a ConvectiveBC responds is its blowing model, NoBlowing() by default (the coefficient stays h whatever leaves the face). The surface balance hands the model the outward mass flux of every gas component at the face at each iterate, so the back face is unaffected automatically (no outflow). Four models ship:
ConvectiveBC(h = 15.0, T_inf = 300.0, blowing = CouetteFilm()) # h·B/(e^B − 1), B = ṁ″·c_p,g/h
ConvectiveBC(h = 11.2, T_inf = 360.0, blowing = CouetteFilm(0.31)) # film law with a fitted constant
ConvectiveBC(h = 11.2, T_inf = 360.0, blowing = PropertyRatioFilm(NITROGEN))
ConvectiveBC(h = 11.2, T_inf = 360.0, blowing = PoolingFilm(NITROGEN; volatiles = pyrolysate))
ConvectiveBC(h = 11.2, T_inf = 360.0, blowing = FunctionBlowing((face, h, T_inf) -> 0.8))CouetteFilm(λ = 0.5): the classical film lawh → h·φ/(e^φ − 1),φ = 2λ·ṁ″·c_p,g/hwith the heat capacity of the gas leaving the face.λ = 0.5is the Couette film (φ = B). At a wood-like peakṁ″ ≈ 10 g·m⁻²·s⁻¹againsth ≈ 10this is a 35–50 % reduction ofh; at PMMA-like peaks (B ≈ 4) convective cooling is essentially extinguished. A smallerλfitted to a resolved flow holds for that gas only.PropertyRatioFilm(free_stream; n_Γ = 0.6): the film law for any light gas,φ = (ṁ″·c_p,∞/h)·(Γ_∞/Γ_g)^n_ΓwithΓ = k/c_pof the free stream and of the leaving mixture (heat capacity by mass fraction, conductivity by Wilke's rule). No constant is refitted for a new gas.PoolingFilm(free_stream; n_Γ, n_D, ψ0, Λc, Λw): the same with a pooling factorψ,h → h·φ/(e^{φ/ψ} − 1), that falls from 1 to the floorψ0when the gas at the face is denser than the free stream. The face composition comes from a species-by-species film balance with the binary diffusivities into the free stream. The three switch constants belong to the apparatus flow (the defaults are the CAPA chamber's); the gas enters through its properties. Describe the volatiles either through the material's gas components, with Fuller diffusion volumesdiffusion_volume = (name = V, ...), or as one lumpedGasSpecies(volatiles = ...).FunctionBlowing(f): your own ruleχ = f(face, h, T_inf)from theBlowingFace(outward species fluxesface.ṁ, surface temperatureface.T_s,face.material).
The free stream is a GasSpecies (molar mass, c_p(T), k(T), Fuller diffusion volume, optional viscosity); NITROGEN ships, and nasa7_heat_capacity builds a heat capacity from NASA-7 coefficients. Each convective member of a combined BC applies its own model. The solution records the applied ratio and, for the pooling model, ψ, the face fraction and the face buoyancy in extras.surface_blowing_ratio, surface_pooling_factor, surface_face_fraction and surface_face_buoyancy. The shipped examples were calibrated with the bare coefficient (and without flame feedback — the two partially cancel; see Technical Reference §1.8.1 before recalibrating).
5.2.4 RadiativeBC — surface re-radiation
bc = RadiativeBC(T_inf = 300.0) # uses material's effective emissivity
bc = RadiativeBC(ε = 0.9, T_inf = 300.0) # fixed emissivity
bc = RadiativeBC(T_inf = 300.0, F = 0.7) # partially enclosed surface
bc = RadiativeBC(ε = T -> 0.85 + 0.1*(T-300)/700, T_inf = 300.0) # T-dependent εGray-body radiative exchange with the surroundings, q_BC = F·ε_eff·σ·(T_∞⁴ − T_s⁴), where σ = 5.670374419×10⁻⁸ W·m⁻²·K⁻⁴. Fields:
ε— surface emissivity. Defaultnothing, which means use the effective emissivityε_eff = Σ_j v_j ε_j(T)(volume-weighted, each component emissivity evaluated at the boundary-cell temperature) computed from the live composition. This is the recommended setting: it automatically tracks the change from virgin polymer to char as the material decomposes, and any temperature dependence you gave the componentε. You can also pass a constant in[0, 1]or a functionε(T).T_inf— surroundings temperatureT_∞in K (constant orT_∞(t)).F— view factor in[0, 1], default1.0(surface fully sees the surroundings). UseF < 1for partially enclosed geometries.
Its temperature derivative is dq_BC/dT_s = −4·F·ε_eff·σ·T_s³. When ε is a function of temperature, the solver neglects the dε/dT term in this derivative; this slightly slows Newton convergence but does not change the converged root (see Technical Reference §12.2).
5.2.5 DirichletThermalBC — prescribed temperature
bc = DirichletThermalBC(500.0) # hold this face at 500 K
bc = DirichletThermalBC(t -> 300 + 5*t) # ramped wall temperatureForces the surface to a prescribed temperature T = T_s. This BC bypasses the ordinary surface-balance Newton iteration and is instead enforced with a large penalty conductance (h_large = 1e8 W·m⁻²·K⁻¹) plus a special case in the RHS assembly. Use it for verification problems or when an experiment fixes the surface temperature directly. The single field T may be constant or T(t).
5.2.6 RadiativeFluxBC — external incident radiation
This is the BC for a cone heater, furnace, or radiant panel — an external radiation source heating the surface. It is distinct from RadiativeBC (which is the surface's own re-radiation loss) and from HeatFluxBC (which injects a bare flux with no absorptivity or in-depth treatment).
bc = RadiativeFluxBC(flux = 25e3) # incident 25 kW/m², α = a_eff
bc = RadiativeFluxBC(flux = 50e3, absorptivity = 0.9) # fixed absorptivity
bc = RadiativeFluxBC(flux = t -> 25e3*(1 - exp(-t/10))) # time-varying fluxFields:
flux— incident radiative fluxΦ_incidentin W/m² (constant orΦ(t)).absorptivity— surface absorptivityαin[0, 1]. Defaultnothing, which uses the material's effective surface absorptivitya_eff = Σ_j v_j a_j: each component's ownabsorptivitywhen set, else its emissivityε_j(T)(Kirchhoff's law). With no component absorptivity set this is exactlyε_eff; setting one lets the absorbed heater flux differ from the re-radiation without splitting the BC. Either way it tracks composition and temperature automatically. You can override with a constant orα(t).
Its behavior depends on the radiation_model keyword passed to solve() (see §7.4 and Technical Reference §8):
radiation_model (in solve) | What RadiativeFluxBC does |
|---|---|
NO_RADIATION | Absorbed flux α·Φ deposited as a surface boundary heat flux |
SURFACE_ABSORPTION | Same — absorbed at the surface (opaque material) |
BEER_LAMBERT | Boundary flux is zero; the absorbed α·Φ is distributed in-depth volumetrically (extras.volumetric_absorption) |
P1_QUASI_STEADY | Boundary flux is zero; radiation handled by the P1 solver (Experimental) |
The boundary flux from this BC has dq_BC/dT_s = 0 (it is the incoming source and does not depend on the surface temperature).
Do not double-count radiation. Do not combine
RadiativeFluxBCandHeatFluxBCfor the same radiation source — that adds the energy twice.RadiativeFluxBCis the correct, absorptivity-aware choice for a radiant source.
5.2.7 CombinedThermalBC — adding BCs with +
A real exposed surface usually has several simultaneous heat exchanges: incoming radiation, re-radiation loss, and convective loss. Add them with +:
top_thermal =
RadiativeFluxBC(flux = 50e3, absorptivity = 0.96) + # cone heater (incoming)
RadiativeBC(ε = 0.96, T_inf = 330.0) + # re-radiation loss
ConvectiveBC(h = 10.0, T_inf = 330.0) # convective lossThe combined flux is the sum of the component fluxes, q_BC = Σ_i q_BC,i(T_s, t), and the derivative is summed likewise — assembled by a generated function for type stability. You can chain any number of thermal BCs. Each term keeps its own T_inf (§5.8).
A canonical cone-calorimeter top face:
bc_set = BoundaryConditionSet(
thermal = (
top = RadiativeFluxBC(flux = 50e3, absorptivity = 0.96) +
RadiativeBC(ε = 0.96, T_inf = 330.0) +
ConvectiveBC(h = 10.0, T_inf = 330.0),
bottom = AdiabaticBC(),
),
mass = (
top = ConvectiveMassBC(h_m = 0.05, ξ_inf = 0.0),
bottom = ImpermeableBC(),
),
)
# Pair with: solve(problem; radiation_model = SURFACE_ABSORPTION)5.3 Mass boundary conditions
Mass BCs (subtypes of AbstractMassBC) control how gas escapes (or enters) through a boundary. Solid and liquid components never transport across the boundary; only gaseous components do. The sign convention is positive = mass into the domain, so gas escaping at the top has a negative flux in the BC's own convention (the solver applies the correct face orientation internally).
| BC type | Physical flux J_j | Key parameters (defaults) |
|---|---|---|
ImpermeableBC | 0 | — |
MassFluxBC | J(t) (prescribed) | flux |
ConvectiveMassBC | h_m·(ξ_∞ − ξ_s) | h_m, ξ_inf (0.0) |
DiffusiveMassBC | combined internal + external resistance | h_m (Inf) |
CombinedMassBC | Σ_i J_j,i | built via + |
Pressure BCs (§5.5) are also AbstractMassBC subtypes but only act in Darcy mode. The first four BC types above (and the pressure BCs) are exported by using Pyrolysis; CombinedMassBC is produced by the + operator rather than called directly.
5.3.1 ImpermeableBC — no gas escape
bc = ImpermeableBC()Zero mass flux for every component. This is the default for both faces and the usual choice for the substrate.
5.3.2 MassFluxBC — prescribed mass flux
bc = MassFluxBC(0.0) # constant prescribed flux [kg/(m²·s)]
bc = MassFluxBC(t -> 1e-3) # time-varyingPrescribes the boundary mass flux J directly (positive = into domain), as a constant or J(t). The same value applies to all gas components.
5.3.3 ConvectiveMassBC — external convective transfer
bc = ConvectiveMassBC(h_m = 0.05, ξ_inf = 0.0) # gas swept away to clean atmosphereExternal convective mass transfer, J_j = h_m·(ξ_{j,∞} − ξ_{j,s}). Fields:
h_m— external (film) mass-transfer coefficienth_min m/s (velocity-based). Constant orh_m(t); validated non-negative. Typical values: natural convection 0.01–0.05 m/s, forced convection 0.05–0.5 m/s. As a rule of thumb from the heat–mass analogy,h_m ≈ h_conv / (ρ_air · c_{p,air}); forh_conv ≈ 10W·m⁻²·K⁻¹ this givesh_m ≈ 0.008m/s.ξ_inf— ambient mass concentrationξ_∞in kg/m³, default0.0(gas escapes into clean surroundings). Accepts a scalar (broadcast to every gas species), a function of timet -> ξ_∞(t), or anNTuplewith one entry per component (ξ_inf = (0.0, 0.0, 0.27)— e.g. ambient air ingress for a background-air species without injecting pyrolyzate). Entries are validated non-negative; a tuple's length must equal the material's component count.
5.3.4 DiffusiveMassBC — internal diffusion with optional external resistance
bc = DiffusiveMassBC() # pure internal diffusion (h_m = Inf, default)
bc = DiffusiveMassBC(0.01) # add a finite external film resistance, h_m = 0.01 m/sCouples the internal Fickian diffusion gradient in the surface cell to an optional external film resistance. The single field is:
h_m— external mass-transfer coefficient in m/s. DefaultInf(the no-argument constructorDiffusiveMassBC()setsh_m = Inf), meaning no external resistance — the flux is the pure diffusive limitJ_j = −λ_j ξ_{j,s}/d, wheredis the distance from the surface cell center to the boundary face. A finiteh_madds a series resistance:J_j = −λ_j h_m ξ_{j,s}/(λ_j + h_m d).
This is the most physically consistent escape BC because it ties the surface loss to the same internal transport law used everywhere else (it also keeps the species balance consistent with ALE surface recession). Use it (with Inf or a finite h_m) when you want gas escape governed by the material's own gas transfer coefficient rather than an imposed convective coefficient.
5.3.5 CombinedMassBC — adding mass BCs with +
bc = DiffusiveMassBC(Inf) + ConvectiveMassBC(h_m = 0.01, ξ_inf = 0.0)Sums component mass fluxes, J_j = Σ_i J_{j,i}, via the + operator (generated function, type-stable). For most pyrolysis runs a single mass BC suffices; combined mass BCs are for modeling competing transport mechanisms or research/validation studies.
5.4 The surface energy balance (how thermal BCs are applied)
Thermal BCs are not applied as a raw flux in the cell; instead the solver finds the surface (face) temperature T_s that makes the boundary energy balance close, then conducts the resulting flux into the adjacent cell. The balance is
q_BC(T_s) = k_eff · (T_s − T_cell) / Δz_{1/2}— the applied BC flux equals the heat conducted from the surface face into the first cell center, with k_eff the effective conductivity, T_cell the adjacent cell temperature, and Δz_{1/2} the face-to-center distance. This is solved by a damped Newton iteration on T_s (see Technical Reference §12.2). You do not call this yourself — it runs inside the RHS assembly — but it is worth knowing because it explains a few user-visible behaviors:
- Convergence is robust for physical BCs: convective flux is linear in
T_s, radiative isT_s⁴; typical solves converge in 2–5 iterations (default tolerance1e-10, up to 50 iterations). - Surface temperature is clamped to
[200, 3000] Kduring the iteration to prevent unphysical excursions. - The solver is AD-aware: it carries
ForwardDiff.Dualtypes through the Newton iteration so the Jacobian's derivatives with respect to the state flow correctly throughT_s. - The converged surface temperature is available afterwards as
solution.surface_T, and the flux decomposition (absorbed, re-radiation, convection, conducted) is reported insolution.extras(§9.3).
The balance has no surface gas-enthalpy term. The enthalpy carried by the escaping gas is already in the energy equation as the volumetric advection source S_conv = −Σ_g c_{p,g} J_g ∂T/∂z; a surface term Σ_g ṁ_g Δh_g(T_s, T_∞) would overlap it by exactly ∫S_conv and count that enthalpy a second time. The outward gas flux enters the boundary only through the blowing model of a ConvectiveBC (§5.2.3).
5.5 Pressure boundary conditions (Darcy mode only)
When the material has a permeability (so the solver runs in Darcy–Fick transport mode, see Technical Reference §9), gas transport is pressure-driven and you can prescribe pressure at a boundary. Pressure BCs are AbstractMassBC subtypes, so they go in the mass slot of the BoundaryConditionSet. They do not contribute a diffusive mass flux; instead they set the Darcy gas velocity at the boundary face (via apply_pressure_bc_to_darcy_velocity!). In Fickian (non-Darcy) mode they have no effect.
| BC type | Effect | Parameters (defaults) |
|---|---|---|
DirichletPressureBC | fixed boundary pressure P | P (101325.0) |
NeumannPressureBC | prescribed pressure gradient ∂P/∂n | ∂P∂n (0.0 = impermeable) |
ConvectivePressureBC | Robin outflow v_g·n = h_P·(P_int − P_ext) | h_P, P_ext |
All three are exported by using Pyrolysis.
5.5.1 DirichletPressureBC — fixed pressure
bc = DirichletPressureBC() # default: atmospheric, 101325 Pa
bc = DirichletPressureBC(101325.0) # explicit atmosphericHolds the boundary at pressure P (Pa, validated positive). The Darcy velocity is computed from the gradient between the boundary and the interior cell, v_g = −(κ/μ)·(P_bc − P_interior)/d. This is the natural exposed-surface condition: the outer face sits at atmospheric pressure and gas flows out down the pressure gradient built up by pyrolysis.
5.5.2 NeumannPressureBC — prescribed gradient
bc = NeumannPressureBC() # default: zero gradient (impermeable to gas flow)
bc = NeumannPressureBC(0.0) # same as above
bc = NeumannPressureBC(1000.0) # prescribed gradient [Pa/m] forcing an outflowSets the normal pressure gradient ∂P/∂n (Pa/m), default 0.0. A zero gradient is a no-flow (impermeable) back face for the pressure field — the usual choice for a sealed substrate in Darcy mode.
5.5.3 ConvectivePressureBC — Robin (resistive) outflow
bc = ConvectivePressureBC(1e-6, 101325.0) # finite surface resistance, atmospheric exteriorA Robin-type condition, v_g·n = h_P·(P_internal − P_external), for a surface with finite resistance to gas flow (a char skin, a coating). Fields:
h_P— pressure-transfer coefficienth_Pin m·Pa⁻¹·s⁻¹.P_ext— external pressureP_externalin Pa.
Limits: h_P → ∞ approaches DirichletPressureBC; h_P → 0 approaches an impermeable (zero-flow) boundary.
5.6 Radiation boundary conditions (P1 model, Experimental)
The four radiation models are selected by the radiation_model keyword of solve() (default NO_RADIATION), not by a BC in the set. For NO_RADIATION, SURFACE_ABSORPTION, and BEER_LAMBERT, the incoming radiation is specified by a RadiativeFluxBC in the thermal slot (§5.2.6) — there is nothing else to set.
The P1 quasi-steady model (P1_QUASI_STEADY) is different: it solves a volumetric radiation field and needs its own boundary treatment (Marshak, reflective, or Dirichlet on the intensity G). These P1 BCs are experimental and live in Pyrolysis.Experimental, not in the BoundaryConditionSet:
import Pyrolysis.Experimental: MarshakRadiationBC, ReflectiveRadiationBC,
DirichletRadiationBC, RadiationBCSet, P1_QUASI_STEADYThe standard P1 configuration is a Marshak condition on the exposed top (carrying the external flux and ambient field) and a reflective condition on the insulated bottom. The Marshak flux is q_BC = c·(G_ext + 4·I_ext − G_surf) with c = ε/(2(2−ε)) and G_ext = 4σT_∞⁴ — the external flux carries the half-range weight 4c = 2ε/(2−ε), the same weight as the ambient term (see Technical Reference §8.6 for the derivation).
Status caveat. P1 radiation is in
Pyrolysis.Experimentaland runs through a separate residual path. For most cone-calorimeter and TGA work,SURFACE_ABSORPTION(opaque) orBEER_LAMBERT(semi-transparent) with a plainRadiativeFluxBCis the supported, production route. Reach for P1 only when you specifically need in-depth re-radiation in an optically thick sample.
5.7 Mesh motion in ALE simulations (no boundary conditions needed)
ALE mesh motion is not configured through boundary conditions — there are no mesh-motion BC types, and BoundaryConditionSet carries only thermal and mass slots. The mesh-velocity boundary treatment is fixed by the formulation: the bottom node is pinned (w_1 = 0, hard-coded in the residual's mesh-velocity integration) and every other node's velocity follows cumulatively from the volumetric strain as the material shrinks or swells (see Technical Reference §11.3), so the top surface automatically follows the material (recedes or expands). You enable the moving mesh simply with solve(problem; use_ale = true).
5.8 Choosing ambient temperatures
Two thermal BCs carry an ambient temperature T_∞: ConvectiveBC and RadiativeBC each have their own T_inf, which enters only that BC's own flux. BCs without an ambient (HeatFluxBC, AdiabaticBC, RadiativeFluxBC, DirichletThermalBC) carry none. In a CombinedThermalBC each term keeps its own T_inf: a top BC of RadiativeBC(T_inf = 330) plus ConvectiveBC(T_inf = 300) re-radiates to 330 K and convects to 300 K. The surface energy balance (§5.4) has no ambient reference temperature of its own.
Practical guidance: set T_inf consistently on the loss terms (RadiativeBC, ConvectiveBC) to the experimental surroundings temperature. In a cone calorimeter the cone shroud and chamber are warmer than room temperature; values in the 300–360 K range are common and used in the shipped examples.
5.9 Time-dependent parameters
Any BC parameter shown above as "constant or function of t" accepts a single-argument function. The solver evaluates it at the current time. Examples:
# Heat-flux ramp
HeatFluxBC(t -> 50e3 * min(t / 5.0, 1.0)) # linear ramp to 50 kW/m² over 5 s
# Time-varying incident radiation
RadiativeFluxBC(flux = t -> 25e3 * (1 - exp(-t / 10)))
# Warming ambient in a convective loss term
ConvectiveBC(h = 10.0, T_inf = t -> 300 + 0.5 * t)
# Pulsed mass extraction
MassFluxBC(t -> t < 50 ? 0.0 : -1e-3)Note on time-varying radiation flux. When
radiation_modelisSURFACE_ABSORPTIONorBEER_LAMBERT,solve()re-samples the incident flux of the topRadiativeFluxBCat every RHS evaluation — constant and time-varying fluxes alike, with no up-front constancy detection. A ramped or modulated flux is therefore always tracked exactly. You do not need to do anything special — just supplyflux = t -> ….
5.10 Initial conditions
Initial conditions are supplied to PyrolysisProblem as functions of the spatial coordinate z (in meters, with z = 0 at the bottom, z = L at the top). Two inputs:
T_initial— a functionz -> Treturning the initial temperature in K. Default:z -> 300.0.ξ_initial— the initial mass concentrationsξ_j(z)in kg/m³, one entry per component. Accepts aVectorof functions (one per component), a single function (broadcast to all components), or you may omit it for the auto-default.
problem = PyrolysisProblem(
mesh = mesh,
material = material, # NC = 2 here: virgin solid + gas
bc_set = bc_set,
T_initial = z -> 300.0, # uniform 300 K
ξ_initial = [z -> 1190.0, z -> 0.0], # full virgin density, no gas
tspan = (0.0, 100.0),
)5.10.1 Auto-defaults
If you omit ξ_initial, the constructor builds a sensible default: the first component, if it is a solid, is placed at its reference density (its density function evaluated at 300 K) and all other components are set to zero. This is correct for the common "single virgin solid that decomposes into gas(es) and char" setup, where component 1 is the virgin solid. Always double-check it matches your component ordering; if not, pass ξ_initial explicitly.
T_initial defaults to a uniform 300 K.
5.10.2 Uniform vs. depth-varying profiles
A uniform value is just a constant-returning closure:
T_initial = z -> 300.0
ξ_initial = [z -> 1190.0, z -> 0.0] # uniform compositionFor a non-uniform start (e.g. a pre-charred surface layer, or a moisture gradient) make the closures depend on z:
L = 0.02 # domain thickness [m]
# Warmer at the exposed top, cooler at the substrate
T_initial = z -> 300.0 + 50.0 * (z / L)
# A thin char layer near the surface (component 2 = char), virgin below
ξ_initial = [
z -> z > 0.9 * L ? 200.0 : 1190.0, # virgin: depleted near top
z -> z > 0.9 * L ? 150.0 : 0.0, # char: present near top
z -> 0.0, # gas: none initially
]The initial conditions are evaluated at each cell center and stored in the mesh. They also populate the per-cell dry-solid mass denominator used by the lateral-shrinkage (χ) dynamics, computed as m_{dry,i} = V_i · Σ_{solid} ξ_{j,i}(0) (see Technical Reference §12.8 and §10.3).
5.10.3 Profile helper functions
Convenience profile builders are available in the Problem submodule (not top-level exported). Import them explicitly when you want them:
import Pyrolysis.Problem: step_profile, linear_profile, gaussian_profile, tanh_profile
z_int = 0.9 * L
# Sharp step: char above the interface, virgin below
ξ_char_initial = z -> step_profile(z; z_interface = z_int,
value_left = 0.0, value_right = 150.0)
# Linear temperature ramp through the thickness
T_initial = z -> linear_profile(z; z_min = 0.0, z_max = L,
value_min = 300.0, value_max = 350.0)
# Smooth (tanh) interface instead of a hard step
ξ_char_initial = z -> tanh_profile(z; z_center = z_int, width = 0.001,
value_left = 0.0, value_right = 150.0)
# Gaussian bump (e.g. a localized moisture pocket)
ξ_moist_initial = z -> gaussian_profile(z; z_center = 0.5 * L, width = 0.002,
amplitude = 100.0, baseline = 0.0)Their signatures:
| Helper | Keyword arguments |
|---|---|
step_profile(z; z_interface, value_left, value_right) | step at z_interface |
linear_profile(z; z_min, z_max, value_min, value_max) | clamped linear ramp |
gaussian_profile(z; z_center, width, amplitude, baseline = 0.0) | Gaussian bump |
tanh_profile(z; z_center, width, value_left, value_right) | smooth step |
A smooth (tanh) interface is generally preferable to a hard step_profile for the solver: sharp discontinuities at t = 0 can provoke small startup transients.
5.11 Common configurations (worked recipes)
5.11.1 Cone calorimeter (opaque charring solid)
External cone flux absorbed at the surface, with re-radiation and convective losses; gas escapes by convective mass transfer; insulated, impermeable back face:
bc_set = BoundaryConditionSet(
thermal = (
top = RadiativeFluxBC(flux = 50e3, absorptivity = 0.96) +
RadiativeBC(ε = 0.96, T_inf = 330.0) +
ConvectiveBC(h = 10.0, T_inf = 330.0),
bottom = AdiabaticBC(),
),
mass = (
top = ConvectiveMassBC(h_m = 0.05, ξ_inf = 0.0),
bottom = ImpermeableBC(),
),
)
solution = solve(problem; radiation_model = SURFACE_ABSORPTION)5.11.2 Semi-transparent polymer (in-depth absorption)
Same incoming radiation, but absorbed in depth via Beer–Lambert (requires absorption coefficients on the components):
bc_set = BoundaryConditionSet(
thermal = (
top = RadiativeFluxBC(flux = 50e3) + # α defaults to a_eff (= ε_eff by Kirchhoff)
RadiativeBC(T_inf = 300.0) +
ConvectiveBC(h = 10.0, T_inf = 300.0),
bottom = AdiabaticBC(),
),
mass = (top = DiffusiveMassBC(), bottom = ImpermeableBC()),
)
solution = solve(problem; radiation_model = BEER_LAMBERT)5.11.3 Furnace temperature program on the exposed face
A prescribed heating program is most directly modeled by holding the surface temperature with a time-dependent DirichletThermalBC:
β = 10.0 / 60.0 # 10 K/min in K/s
bc_set = BoundaryConditionSet(
thermal = (top = DirichletThermalBC(t -> 300.0 + β * t),
bottom = AdiabaticBC()),
mass = (top = DiffusiveMassBC(), bottom = ImpermeableBC()),
)5.11.4 Pressure-driven char (Darcy mode)
With a permeable material, set atmospheric pressure on the exposed face and a sealed (zero-gradient) back face. The transport mode switches to Darcy–Fick automatically when the material has permeability:
bc_set = BoundaryConditionSet(
thermal = (top = HeatFluxBC(50e3) + RadiativeBC(ε = 0.9, T_inf = 300.0),
bottom = AdiabaticBC()),
mass = (top = DirichletPressureBC(101325.0), # atmospheric exposed face
bottom = NeumannPressureBC(0.0)), # sealed substrate
)5.12 Caveats and pitfalls
The escaping gas carries no surface enthalpy term. The volumetric gas-advection source
S_conv = −Σ_g c_{p,g} J_g ∂T/∂zis always active and already carries the gas enthalpy (Technical Reference §7.4.3, §12.2); a surface termΣ_g ṁ_g Δh_g(T_s, T_∞)on top of it would double-count that enthalpy, a spurious ~5–10 kW/m² sink that under-predicts surface temperature and mass-loss rate. TheS_conv-only convention matches ThermaKin, Gpyro, and FDS. Parameter sets calibrated with a code that adds a surface gas-enthalpy term may need re-calibration.radiation_modeldefaults toNO_RADIATION. ARadiativeFluxBConly does something if you pass an appropriateradiation_modeltosolve(). With the defaultNO_RADIATION, an incidentRadiativeFluxBCis still absorbed at the surface (the absorbed flux is applied as a boundary heat flux), but chooseSURFACE_ABSORPTION(opaque) orBEER_LAMBERT(semi-transparent) explicitly to make the intent clear and to enable the in-depth distribution.Only thermal and mass BCs go in the set.
BoundaryConditionSetaccepts onlyAbstractThermalBCandAbstractMassBCpayloads — a wrong-kind BC throws at construction. ALE mesh motion needs no BC at all (it is automatic withuse_ale = true), and P1 radiation BCs (MarshakRadiationBCetc.) go through the Experimental P1 residual path, not the set.Pressure BCs need Darcy mode.
DirichletPressureBC/NeumannPressureBC/ConvectivePressureBConly have an effect when the material has permeability (Darcy–Fick transport). In Fickian mode they contribute zero flux and are silently inert — useImpermeableBC/DiffusiveMassBC/ConvectiveMassBCfor diffusion-only gas escape.Don't double-specify a radiation source. Use
RadiativeFluxBC(not alsoHeatFluxBC) for the cone/panel; useRadiativeBCfor the surface's own re-radiation loss. They are different physical terms.Match
ξ_initialto your component order. The auto-default only fills component 1 (if solid). For multi-solid or moisture-bearing materials, supplyξ_initialexplicitly so virgin solid, char, moisture, and gases start with the right concentrations.
For deeper background on the boundary physics, the surface Newton solve, and the radiation models, see Technical Reference §12 (boundary and initial conditions), §8 (thermal radiation), §7 (energy assembly and the S_conv convention), and §9 (gas transport and pressure).