98 for i, lay
in enumerate(self.
layers):
99 t = lay.thickness - (self.
receded if i == 0
else 0.0)
100 if i == 0
and t <= 0:
105 segs.append(xs
if i == 0
else xs[1:])
106 props.append((len(xs) - 1, lay))
108 self.
y = np.concatenate(segs)
109 k_cell, rc_cell, owner = [], [], []
111 k_cell += [lay.k] * n
112 rc_cell += [lay.rho * lay.cp] * n
114 self.
_k = np.array(k_cell)
115 self.
_rc = np.array(rc_cell)
116 self.
_varying = [(np.array([o
is lay
for o
in owner]), lay)
117 for lay
in self.
layers if lay.cp_of
is not None]
168 def step(self, dt: float, q_in: Callable[[float], float],
169 T_ablation: Optional[float] =
None, H_surface: Optional[float] =
None,
170 rho_surface: Optional[float] =
None,
171 chemical_mass_flux: Optional[Callable[[float], float]] =
None,
172 T_bracket: Tuple[float, float] = (150.0, 4500.0)) -> dict:
173 """Advance by dt. Returns the surface temperature, the recession this step [m] and
174 the surface mass flux [kg/(m^2 s)]."""
177 G0, C0, T0 = self.
_G[0], self.
_C[0], self.
T[0]
180 slope1 = lin1[0] - lin0[0]
183 T1 = lin0[0] + slope1 * s
184 return q_in(s) - C0 * (s - T0) / dt - G0 * (s - T1)
187 rlo, rhi = resid(lo), resid(hi)
193 s = brentq(resid, lo, hi, xtol=1e-6)
195 if T_ablation
is not None and s > T_ablation:
196 s = float(T_ablation)
198 mass_flux =
max(excess, 0.0) / H_surface
199 elif chemical_mass_flux
is not None:
200 mass_flux =
max(chemical_mass_flux(s), 0.0)
202 self.
T = np.concatenate([[s], interior])
204 if mass_flux > 0
and rho_surface:
211 return {
"T_surface": float(s),
"recession": float(recede),
"mass_flux": float(mass_flux)}