\chapter{Animals}\label{ch:animals}
\section{Rations, retention and product transfer}
\subsection*{Physics}
Animal activity intake is the sum of feed concentrations multiplied by
their daily ration amounts. Seasonal rations determine the relative
contributions of different feed materials.

Retention components represent distinct biological response times. Each
accumulates intake and loses activity through biological turnover and
radioactive decay. Component fractions, biological release rates and the
product transfer factor convert retained activity to concentrations in milk,
meat or eggs \cite{mueller1993}. Inhalation during cloud passage enters the
same retention calculation over the deposition day \cite{excelmanual}.

The result represents production from a continually renewed herd,
not an individually tracked animal. For a product with a mast duration,
contributions older than that rolling window leave the product stream even
if intake from today's ration continues. Later, from the specified calendar
boundary, the model switches to an equilibrium approximation.
The transition is prescribed rather than determined by a convergence
criterion for the animal state.
\subsection*{Equations}
Let $q_{am}$ be the ration in \si{\kilogram\per\day} and $C_m$ the feed
concentration in \si{\becquerel\per\kilogram}. On interval
$(t_{i-1},t_i]$, $J_{a,i}=\sum_m q_{am}(t_{i-1})C_m(t_{i-1})$ in
\si{\becquerel\per\day}. Here $p$ indexes an animal product, rather than
a plant. For its retention component $j$, let
$b_{apj}=\ln2/T_{b,apj}$ after converting the biological half-life to days.
The combined rate is $k_{apj}=b_{apj}+\lambda_{\phys}$, both rates in
\si{\per\day}. The feed-driven state $X^{\rm feed}_{apj}$ has units Bq and obeys
\begin{equation}\label{eq:animalstate}
X^{\rm feed}_{apj,i}=X^{\rm feed}_{apj,i-1}e^{-k_{apj}\Delta t_i}+
J_{a,i}\frac{1-e^{-k_{apj}\Delta t_i}}{k_{apj}}.
\end{equation}
Including the inhaled state $X^{\rm air}_{apj}$ below, put
$X_{apj}=X^{\rm feed}_{apj}+X^{\rm air}_{apj}$. With component fraction
$\alpha_{apj}$, the regular (pre-equilibrium) product concentration is
\begin{equation}\label{eq:animalproduct}
C_{ap}(t_i)=F_{ap}\sum_j \alpha_{apj} b_{apj}
\bigl[X_{apj}(t_i)-X_{apj}(t_i-M_a)e^{-k_{apj}M_a}\bigr],
\end{equation}
when a positive mast duration $M_a$ has elapsed; before then the bracket is
the current full state. $F_{ap}$ has contextual units \si{\day\per\kilogram},
$\alpha$ is dimensionless, and $bX$ has \si{\becquerel\per\day}; hence
$C_{ap}$ is \si{\becquerel\per\kilogram}. The bracket includes the inhaled
state in both endpoints and is clamped non-negative in the implementation.
For integrated deposition-day air $C_a$ and animal inhalation rate $B_a$ in
\si{\cubic\metre\per\second}, total inhaled activity is $H_a=C_aB_a$ Bq.
It enters at uniform rate $H_a/D$ for $0\leq t\leq D=1$ day, yielding
\begin{equation}\label{eq:animalair}
X_{apj}^{\rm air}(t)=H_a
\frac{1-e^{-k_{apj}\min(t,D)}}{k_{apj}D}
e^{-k_{apj}\max(t-D,0)}.
\end{equation}
For the optional $D=0$ kernel limit, this is an impulse
$H_ae^{-k_{apj}t}$; the engine passes $D=1$ day (\sd{17}).
\subsection*{Parameters}
\begin{center}\footnotesize\begin{tabular}{@{}p{.10\linewidth}@{\hspace{3pt}}p{.14\linewidth}@{\hspace{3pt}}p{.35\linewidth}@{\hspace{3pt}}p{.35\linewidth}@{}}\toprule Symbol & Unit & SQLite table.column & Compiled field\\\midrule
$q_{am}$ & \si{\kilogram\per\day} & animal\_feed\_ration.amount\_kg\_day,start\_day,feed\_material\_id & ration\_amounts\_kg\_day, ration\_feed\_positions\\
$\alpha_{apj},T_{b,apj}$ & 1, yr & retention\_component.fraction,half\_life\_years & retention\_fractions, retention\_half\_lives\_years\\
$F_{ap}$ & contextual \si{\day\per\kilogram} & animal\_product\_transfer.factor & transfer\_factors\\
$M_a,B_a$ & d, \si{\cubic\metre\per\hour} & animal.mast\_duration\_days,inhalation\_rate\_m3\_h & mast\_durations\_days,inhalation\_rates\_m3\_h\\\bottomrule\end{tabular}\end{center}
Loader \coderef{ecosys/data/loader.py}{306}{321},
\coderef{ecosys/data/loader.py}{478}{520}; compiler
\coderef{ecosys/data/compile.py}{562}{690}. Database transfer numbers are
dimensionless records but acquire the contextual unit at the engine boundary
(\sd{05}); no numeric conversion is applied.
\subsection*{Implementation}
\coderef{ecosys/kernels/animals.py}{49}{113} interpolates rations;
\coderef{ecosys/kernels/animals.py}{116}{156} averages them by calendar
day; \coderef{ecosys/kernels/animals.py}{209}{436} solves the product.
Engine orchestration, staged animal feeds and the inhalation duration are
\coderef{ecosys/engine.py}{1131}{1391}.
\subsection*{Numerical treatment}
Seasonal rations are interpolated separately for each feed material.
During transient integration, ration amounts and feed concentrations are
held at their left-node values on each interval. The exponential recurrence
is exact for this constant intake, using \codefn{expm1}; time support
determines how closely it represents the varying intake history.
The mast boundary state is analytically reconstructed inside
a support interval; no hidden state node is inserted. After January 1 of the
third year after the event year (i.e. the fourth calendar year),
\coderef{ecosys/engine.py}{1402}{1408} enables the code's equilibrium formula:
for positive mast duration its factor for component $j$ is
$\alpha_j b_j(1-e^{-b_j M_a})/k_j$ times intake calculated from
interval-averaged rations and current-node feed concentrations, followed by
$F_{ap}$; without mast duration the
factor is one. This formula differs from the transient rolling state and
uses the biological rate $b_j$, rather than the combined rate $k_j$, in
the mast exponential.
\relation{Equations~(14)--(16) of \cite{mueller1993} describe feed-to-product
transfer and exclude animal inhalation. The inhalation extension follows
\cite{excelmanual}; its timing and the equilibrium-ration convention are
specified by \sd{17} and \sd{10}. Historical comparisons are in
Appendix~\ref{sec:history-animals}.}
\evidence{\codefn{tests/kernels/test_rations.py::test_average_rations_match_daily_means_and_reduce_to_the_seasonal_mean},
\codefn{tests/kernels/test_animal_products.py::test_inhalation_spread_over_its_duration_matches_uniform_intake},
\codefn{tests/kernels/test_animal_retention.py},
\codefn{tests/integration/test_event_animals.py}.}
