<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE article PUBLIC "-//NLM//DTD Journal Publishing with OASIS Tables v3.0 20080202//EN" "journalpub-oasis3.dtd">
<article xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:oasis="http://docs.oasis-open.org/ns/oasis-exchange/table" xml:lang="en" dtd-version="3.0" article-type="research-article"><?xmltex \makeatother\@nolinetrue\makeatletter?><?xmltex \hack{\allowdisplaybreaks}?><?xmltex \bartext{Development and technical paper}?>
  <front>
    <journal-meta><journal-id journal-id-type="publisher">GMD</journal-id><journal-title-group>
    <journal-title>Geoscientific Model Development</journal-title>
    <abbrev-journal-title abbrev-type="publisher">GMD</abbrev-journal-title><abbrev-journal-title abbrev-type="nlm-ta">Geosci. Model Dev.</abbrev-journal-title>
  </journal-title-group><issn pub-type="epub">1991-9603</issn><publisher>
    <publisher-name>Copernicus Publications</publisher-name>
    <publisher-loc>Göttingen, Germany</publisher-loc>
  </publisher></journal-meta>
    <article-meta>
      <article-id pub-id-type="doi">10.5194/gmd-16-659-2023</article-id><title-group><article-title>A simple, efficient, mass-conservative approach to solving <?xmltex \hack{\break}?>Richards' equation (openRE, v1.0)</article-title><alt-title>A simple, efficient, mass-conservative approach to solving Richards' equation</alt-title>
      </title-group><?xmltex \runningtitle{A simple, efficient, mass-conservative approach to solving Richards' equation}?><?xmltex \runningauthor{A.~M.~Ireson~et~al.}?>
      <contrib-group>
        <contrib contrib-type="author" corresp="yes" rid="aff1 aff2">
          <name><surname>Ireson</surname><given-names>Andrew M.</given-names></name>
          <email>andrew.ireson@usask.ca</email>
        <ext-link>https://orcid.org/0000-0003-1957-7355</ext-link></contrib>
        <contrib contrib-type="author" corresp="no" rid="aff3">
          <name><surname>Spiteri</surname><given-names>Raymond J.</given-names></name>
          
        </contrib>
        <contrib contrib-type="author" corresp="no" rid="aff4">
          <name><surname>Clark</surname><given-names>Martyn P.</given-names></name>
          
        </contrib>
        <contrib contrib-type="author" corresp="no" rid="aff5">
          <name><surname>Mathias</surname><given-names>Simon A.</given-names></name>
          
        </contrib>
        <aff id="aff1"><label>1</label><institution>Global Institute for Water Security, University of Saskatchewan, Saskatoon, Saskatchewan, Canada</institution>
        </aff>
        <aff id="aff2"><label>2</label><institution>School of Environment and Sustainability, University of Saskatchewan, Saskatoon, Saskatchewan, Canada</institution>
        </aff>
        <aff id="aff3"><label>3</label><institution>Department of Computer Science, University of Saskatchewan, Saskatoon, Saskatchewan, Canada</institution>
        </aff>
        <aff id="aff4"><label>4</label><institution>Department of Geography and Planning, University of Saskatchewan, Saskatoon, Saskatchewan, Canada</institution>
        </aff>
        <aff id="aff5"><label>5</label><institution>Department of Engineering, Durham University, Durham, UK</institution>
        </aff>
      </contrib-group>
      <author-notes><corresp id="corr1">Andrew M. Ireson (andrew.ireson@usask.ca)</corresp></author-notes><pub-date><day>27</day><month>January</month><year>2023</year></pub-date>
      
      <volume>16</volume>
      <issue>2</issue>
      <fpage>659</fpage><lpage>677</lpage>
      <history>
        <date date-type="received"><day>17</day><month>July</month><year>2022</year></date>
           <date date-type="accepted"><day>4</day><month>January</month><year>2023</year></date>
           <date date-type="rev-recd"><day>31</day><month>December</month><year>2022</year></date>
           <date date-type="rev-request"><day>2</day><month>August</month><year>2022</year></date>
      </history>
      <permissions>
        <copyright-statement>Copyright: © 2023 Andrew M. Ireson et al.</copyright-statement>
        <copyright-year>2023</copyright-year>
      <license license-type="open-access"><license-p>This work is licensed under the Creative Commons Attribution 4.0 International License. To view a copy of this licence, visit <ext-link ext-link-type="uri" xlink:href="https://creativecommons.org/licenses/by/4.0/">https://creativecommons.org/licenses/by/4.0/</ext-link></license-p></license></permissions><self-uri xlink:href="https://gmd.copernicus.org/articles/16/659/2023/gmd-16-659-2023.html">This article is available from https://gmd.copernicus.org/articles/16/659/2023/gmd-16-659-2023.html</self-uri><self-uri xlink:href="https://gmd.copernicus.org/articles/16/659/2023/gmd-16-659-2023.pdf">The full text article is available as a PDF file from https://gmd.copernicus.org/articles/16/659/2023/gmd-16-659-2023.pdf</self-uri>
      <abstract><title>Abstract</title>

      <p id="d1e140">A simple numerical solution procedure – namely the method of lines combined with an off-the-shelf ordinary differential equation (ODE) solver – was shown in previous work to
provide efficient, mass-conservative solutions to the pressure-head form of Richards' equation. We implement such a solution in our model openRE. We
developed a novel method to quantify the boundary fluxes that reduce water balance errors without negative impacts on model runtimes – the
solver flux output method (SFOM). We compare this solution with alternatives, including the classic modified Picard iteration method and
the Hydrus 1D model. We reproduce a set of benchmark solutions with all models. We find that Celia's solution has the best water balance, but it can
incur significant truncation errors in the simulated boundary fluxes, depending on the time steps used. Our solution has comparable runtimes to
Hydrus and better water balance performance (though both models have excellent water balance closure for all the problems we considered). Our
solution can be implemented in an interpreted language, such as MATLAB or Python, making use of off-the-shelf ODE solvers. We evaluated alternative
SciPy ODE solvers that are available in Python and make practical recommendations about the best way to implement them for Richards' equation. There
are two advantages of our approach: (i) the code is concise, making it ideal for teaching purposes; and (ii) the method can be easily extended to
represent alternative properties (e.g., novel ways to parameterize the <inline-formula><mml:math id="M1" display="inline"><mml:mrow><mml:mi>K</mml:mi><mml:mo>(</mml:mo><mml:mi mathvariant="italic">ψ</mml:mi><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula> relationship) and processes (e.g., it is straightforward to
couple heat or solute transport), making it ideal for testing alternative hypotheses.</p>
  </abstract>
    </article-meta>
  </front>
<body>
      

<sec id="Ch1.S1" sec-type="intro">
  <label>1</label><title>Introduction</title>
      <p id="d1e166">Richards' equation (RE) describes the movement of water in variably saturated porous media. Almost any practical application of RE requires a
numerical solution; yet RE remains challenging to solve reliably and accurately for a given set of boundary conditions and soil hydraulic properties
(Farthing and Ogden, 2017). RE has been extensively reviewed (e.g., Vereecken et al., 2016; Farthing and Ogden, 2017, and references therein). RE has
practical limitations in representing the flow processes in real soils containing macropores, especially with modeling infiltration and rapid
percolation processes (Beven and Germann, 2013). The strength of RE is its ability to represent matrix drainage and capillary flows, which control
evapotranspiration processes, and its ability to be coupled to heat and solute transport models. For this reason, RE remains a common approach to
simulate soil moisture in many terrestrial system models (e.g., vadose zone models, ecohydrology models, and land-surface models; Vereecken et al.,
2016; Clark et al., 2015, 2021).</p>
      <p id="d1e169">Our objective in this paper is to (i) implement a simple and practical approach to solve RE that is efficient, is mass conservative, and uses
open-source software (written in Python) that is readily available, including as a teaching tool; and (ii) present an improved mass balance
calculation procedure for use with ordinary differential equation (ODE) solvers that apply adaptive time-stepping (ATS) schemes. We investigate how to
maximize the efficiency and accuracy of ODE solvers and provide guidance on the subtle challenges that arise in evaluating the boundary fluxes and the
water balance. For our purposes, we define the following five criteria for success for an RE solver: (i) the solver should successfully reproduce
benchmark solutions for <inline-formula><mml:math id="M2" display="inline"><mml:mrow><mml:mi mathvariant="italic">ψ</mml:mi><mml:mo>(</mml:mo><mml:mi>t</mml:mi><mml:mo>,</mml:mo><mml:mi>z</mml:mi><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula> or <inline-formula><mml:math id="M3" display="inline"><mml:mrow><mml:mi mathvariant="italic">θ</mml:mi><mml:mo>(</mml:mo><mml:mi>t</mml:mi><mml:mo>,</mml:mo><mml:mi>z</mml:mi><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula>; (ii) the solver should be mass conservative, with errors that are negligible based on the
specific application; (iii) truncation errors in the simulated boundary fluxes should be negligible for the given time step; (iv) the solver should be
computationally efficient; and (v) all else being equal on criteria (i)–(iv), the simplest code should be preferred. Simple code should be the most
human readable/editable code, which means it should be clean, concise, modular, and free from redundancies.</p>
      <p id="d1e208">The remainder of this paper is organized as follows. In Sect. 2, we describe a simple yet powerful approach to solve RE numerically using ODE solvers
that we implement and test in the Python and MATLAB programming languages. In Sect. 2, we also discuss the complexities of closing the water balance
in RE and present a novel solution that can be applied with any ODE solver: openRE. In Sect. 3, we benchmark the performance of our proposed solution
against existing numerical models and solutions, including Hydrus 1D, and the solution method proposed by Celia at al. (1990). In Sect. 4, we
summarize our recommendations.</p>
</sec>
<sec id="Ch1.S2">
  <label>2</label><title>Solving Richards' equation</title>
      <p id="d1e219">RE is derived from the mass continuity equation applied to a control volume of soil, <inline-formula><mml:math id="M4" display="inline"><mml:mrow><mml:mi mathvariant="normal">Δ</mml:mi><mml:mi>x</mml:mi><mml:mi mathvariant="normal">Δ</mml:mi><mml:mi>y</mml:mi><mml:mi mathvariant="normal">Δ</mml:mi><mml:mi>z</mml:mi></mml:mrow></mml:math></inline-formula> (<inline-formula><mml:math id="M5" display="inline"><mml:mrow class="unit"><mml:msup><mml:mi mathvariant="normal">L</mml:mi><mml:mn mathvariant="normal">3</mml:mn></mml:msup></mml:mrow></mml:math></inline-formula>), and for
one-dimensional vertical flow passing through the area <inline-formula><mml:math id="M6" display="inline"><mml:mrow><mml:mi mathvariant="normal">Δ</mml:mi><mml:mi>x</mml:mi><mml:mi mathvariant="normal">Δ</mml:mi><mml:mi>y</mml:mi></mml:mrow></mml:math></inline-formula> (<inline-formula><mml:math id="M7" display="inline"><mml:mrow class="unit"><mml:msup><mml:mi mathvariant="normal">L</mml:mi><mml:mn mathvariant="normal">2</mml:mn></mml:msup></mml:mrow></mml:math></inline-formula>), we have
          <disp-formula id="Ch1.E1" content-type="numbered"><label>1</label><mml:math id="M8" display="block"><mml:mrow><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mrow><mml:mo>∂</mml:mo><mml:mi>m</mml:mi></mml:mrow><mml:mrow><mml:mo>∂</mml:mo><mml:mi>t</mml:mi></mml:mrow></mml:mfrac></mml:mstyle><mml:mo>=</mml:mo><mml:mo>-</mml:mo><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mrow><mml:mo>∂</mml:mo><mml:mo>(</mml:mo><mml:mi>q</mml:mi><mml:mi mathvariant="italic">ρ</mml:mi><mml:mo>)</mml:mo></mml:mrow><mml:mrow><mml:mo>∂</mml:mo><mml:mi>z</mml:mi></mml:mrow></mml:mfrac></mml:mstyle><mml:mo>,</mml:mo></mml:mrow></mml:math></disp-formula>
        where <inline-formula><mml:math id="M9" display="inline"><mml:mi>m</mml:mi></mml:math></inline-formula> (<inline-formula><mml:math id="M10" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">M</mml:mi><mml:mspace width="0.125em" linebreak="nobreak"/><mml:msup><mml:mi mathvariant="normal">L</mml:mi><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">3</mml:mn></mml:mrow></mml:msup></mml:mrow></mml:math></inline-formula>) is the mass of water per control volume of soil, <inline-formula><mml:math id="M11" display="inline"><mml:mi mathvariant="italic">ρ</mml:mi></mml:math></inline-formula> (<inline-formula><mml:math id="M12" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">M</mml:mi><mml:mspace linebreak="nobreak" width="0.125em"/><mml:msup><mml:mi mathvariant="normal">L</mml:mi><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">3</mml:mn></mml:mrow></mml:msup></mml:mrow></mml:math></inline-formula>) is the density of water,
<inline-formula><mml:math id="M13" display="inline"><mml:mi>q</mml:mi></mml:math></inline-formula> (<inline-formula><mml:math id="M14" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">L</mml:mi><mml:mspace width="0.125em" linebreak="nobreak"/><mml:msup><mml:mi mathvariant="normal">T</mml:mi><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msup></mml:mrow></mml:math></inline-formula>) is the flux of water, and <inline-formula><mml:math id="M15" display="inline"><mml:mi>t</mml:mi></mml:math></inline-formula> (<inline-formula><mml:math id="M16" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">T</mml:mi></mml:mrow></mml:math></inline-formula>) is time and <inline-formula><mml:math id="M17" display="inline"><mml:mi>z</mml:mi></mml:math></inline-formula> (<inline-formula><mml:math id="M18" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">L</mml:mi></mml:mrow></mml:math></inline-formula>) is depth below some fixed datum. Assuming that density is
constant, we may write
          <disp-formula id="Ch1.E2" content-type="numbered"><label>2</label><mml:math id="M19" display="block"><mml:mrow><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mrow><mml:mo>∂</mml:mo><mml:mi mathvariant="italic">θ</mml:mi></mml:mrow><mml:mrow><mml:mo>∂</mml:mo><mml:mi>t</mml:mi></mml:mrow></mml:mfrac></mml:mstyle><mml:mo>=</mml:mo><mml:mo>-</mml:mo><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mrow><mml:mo>∂</mml:mo><mml:mi>q</mml:mi></mml:mrow><mml:mrow><mml:mo>∂</mml:mo><mml:mi>z</mml:mi></mml:mrow></mml:mfrac></mml:mstyle><mml:mo>,</mml:mo></mml:mrow></mml:math></disp-formula>
        where <inline-formula><mml:math id="M20" display="inline"><mml:mi mathvariant="italic">θ</mml:mi></mml:math></inline-formula> (<inline-formula><mml:math id="M21" display="inline"><mml:mrow class="unit"><mml:msup><mml:mi mathvariant="normal">L</mml:mi><mml:mn mathvariant="normal">3</mml:mn></mml:msup><mml:mspace width="0.125em" linebreak="nobreak"/><mml:msup><mml:mi mathvariant="normal">L</mml:mi><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">3</mml:mn></mml:mrow></mml:msup></mml:mrow></mml:math></inline-formula>) is the volumetric water content, defined as the volume of water per control volume of soil. The vertical flux is
given by Darcy's law,
          <disp-formula id="Ch1.E3" content-type="numbered"><label>3</label><mml:math id="M22" display="block"><mml:mrow><mml:msub><mml:mi>q</mml:mi><mml:mi>z</mml:mi></mml:msub><mml:mo>=</mml:mo><mml:mo>-</mml:mo><mml:mi>K</mml:mi><mml:mo>(</mml:mo><mml:mi mathvariant="italic">ψ</mml:mi><mml:mo>)</mml:mo><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mrow><mml:mi mathvariant="normal">d</mml:mi><mml:mi>h</mml:mi></mml:mrow><mml:mrow><mml:mi mathvariant="normal">d</mml:mi><mml:mi>z</mml:mi></mml:mrow></mml:mfrac></mml:mstyle><mml:mo>=</mml:mo><mml:mo>-</mml:mo><mml:mi>K</mml:mi><mml:mo>(</mml:mo><mml:mi mathvariant="italic">ψ</mml:mi><mml:mo>)</mml:mo><mml:mfenced open="(" close=")"><mml:mrow><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mrow><mml:mi mathvariant="normal">d</mml:mi><mml:mi mathvariant="italic">ψ</mml:mi></mml:mrow><mml:mrow><mml:mi mathvariant="normal">d</mml:mi><mml:mi>z</mml:mi></mml:mrow></mml:mfrac></mml:mstyle><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:mfenced><mml:mo>,</mml:mo></mml:mrow></mml:math></disp-formula>
        where <inline-formula><mml:math id="M23" display="inline"><mml:mi>h</mml:mi></mml:math></inline-formula> (<inline-formula><mml:math id="M24" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">L</mml:mi></mml:mrow></mml:math></inline-formula>) and <inline-formula><mml:math id="M25" display="inline"><mml:mi mathvariant="italic">ψ</mml:mi></mml:math></inline-formula> (<inline-formula><mml:math id="M26" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">L</mml:mi></mml:mrow></mml:math></inline-formula>) are the hydraulic head and matric potential head, respectively, and <inline-formula><mml:math id="M27" display="inline"><mml:mrow><mml:mi>K</mml:mi><mml:mo>(</mml:mo><mml:mi mathvariant="italic">ψ</mml:mi><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula> (<inline-formula><mml:math id="M28" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">L</mml:mi><mml:mspace width="0.125em" linebreak="nobreak"/><mml:msup><mml:mi mathvariant="normal">T</mml:mi><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msup></mml:mrow></mml:math></inline-formula>) is the
hydraulic conductivity. Combining Eqs. (<xref ref-type="disp-formula" rid="Ch1.E2"/>) and (<xref ref-type="disp-formula" rid="Ch1.E3"/>) we have
          <disp-formula id="Ch1.E4" content-type="numbered"><label>4</label><mml:math id="M29" display="block"><mml:mrow><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mrow><mml:mo>∂</mml:mo><mml:mi mathvariant="italic">θ</mml:mi></mml:mrow><mml:mrow><mml:mo>∂</mml:mo><mml:mi>t</mml:mi></mml:mrow></mml:mfrac></mml:mstyle><mml:mo>=</mml:mo><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mo>∂</mml:mo><mml:mrow><mml:mo>∂</mml:mo><mml:mi>z</mml:mi></mml:mrow></mml:mfrac></mml:mstyle><mml:mfenced open="(" close=")"><mml:mrow><mml:mi>K</mml:mi><mml:mo>(</mml:mo><mml:mi mathvariant="italic">ψ</mml:mi><mml:mo>)</mml:mo><mml:mfenced close=")" open="("><mml:mrow><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mrow><mml:mo>∂</mml:mo><mml:mi mathvariant="italic">ψ</mml:mi></mml:mrow><mml:mrow><mml:mo>∂</mml:mo><mml:mi>z</mml:mi></mml:mrow></mml:mfrac></mml:mstyle><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:mfenced></mml:mrow></mml:mfenced><mml:mo>,</mml:mo></mml:mrow></mml:math></disp-formula>
        which is the mixed form of RE (Celia et al., 1990). If we let <inline-formula><mml:math id="M30" display="inline"><mml:mrow><mml:mi>C</mml:mi><mml:mo>(</mml:mo><mml:mi mathvariant="italic">ψ</mml:mi><mml:mo>)</mml:mo><mml:mo>=</mml:mo><mml:mi mathvariant="normal">d</mml:mi><mml:mi mathvariant="italic">θ</mml:mi><mml:mo>/</mml:mo><mml:mi mathvariant="normal">d</mml:mi><mml:mi mathvariant="italic">ψ</mml:mi></mml:mrow></mml:math></inline-formula> (<inline-formula><mml:math id="M31" display="inline"><mml:mrow class="unit"><mml:msup><mml:mi mathvariant="normal">L</mml:mi><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msup></mml:mrow></mml:math></inline-formula>), we can write
          <disp-formula id="Ch1.E5" content-type="numbered"><label>5</label><mml:math id="M32" display="block"><mml:mrow><mml:mi>C</mml:mi><mml:mo>(</mml:mo><mml:mi mathvariant="italic">ψ</mml:mi><mml:mo>)</mml:mo><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mrow><mml:mo>∂</mml:mo><mml:mi mathvariant="italic">ψ</mml:mi></mml:mrow><mml:mrow><mml:mo>∂</mml:mo><mml:mi>t</mml:mi></mml:mrow></mml:mfrac></mml:mstyle><mml:mo>=</mml:mo><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mo>∂</mml:mo><mml:mrow><mml:mo>∂</mml:mo><mml:mi>z</mml:mi></mml:mrow></mml:mfrac></mml:mstyle><mml:mfenced open="(" close=")"><mml:mrow><mml:mi>K</mml:mi><mml:mo>(</mml:mo><mml:mi mathvariant="italic">ψ</mml:mi><mml:mo>)</mml:mo><mml:mfenced open="(" close=")"><mml:mrow><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mrow><mml:mo>∂</mml:mo><mml:mi mathvariant="italic">ψ</mml:mi></mml:mrow><mml:mrow><mml:mo>∂</mml:mo><mml:mi>z</mml:mi></mml:mrow></mml:mfrac></mml:mstyle><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:mfenced></mml:mrow></mml:mfenced><mml:mo>,</mml:mo></mml:mrow></mml:math></disp-formula>
        which is the <inline-formula><mml:math id="M33" display="inline"><mml:mi mathvariant="italic">ψ</mml:mi></mml:math></inline-formula>-based form of RE (Celia et al., 1990). We can also express this as the <inline-formula><mml:math id="M34" display="inline"><mml:mi mathvariant="italic">θ</mml:mi></mml:math></inline-formula> form of RE, given by
          <disp-formula id="Ch1.E6" content-type="numbered"><label>6</label><mml:math id="M35" display="block"><mml:mrow><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mrow><mml:mo>∂</mml:mo><mml:mi mathvariant="italic">θ</mml:mi></mml:mrow><mml:mrow><mml:mo>∂</mml:mo><mml:mi>t</mml:mi></mml:mrow></mml:mfrac></mml:mstyle><mml:mo>=</mml:mo><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mo>∂</mml:mo><mml:mrow><mml:mo>∂</mml:mo><mml:mi>z</mml:mi></mml:mrow></mml:mfrac></mml:mstyle><mml:mfenced open="(" close=")"><mml:mrow><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mrow><mml:mi>K</mml:mi><mml:mo>(</mml:mo><mml:mi mathvariant="italic">θ</mml:mi><mml:mo>)</mml:mo></mml:mrow><mml:mrow><mml:mi>C</mml:mi><mml:mo>(</mml:mo><mml:mi mathvariant="italic">θ</mml:mi><mml:mo>)</mml:mo></mml:mrow></mml:mfrac></mml:mstyle><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mrow><mml:mo>∂</mml:mo><mml:mi mathvariant="italic">θ</mml:mi></mml:mrow><mml:mrow><mml:mo>∂</mml:mo><mml:mi>z</mml:mi></mml:mrow></mml:mfrac></mml:mstyle><mml:mo>-</mml:mo><mml:mi>K</mml:mi><mml:mo>(</mml:mo><mml:mi mathvariant="italic">θ</mml:mi><mml:mo>)</mml:mo></mml:mrow></mml:mfenced><mml:mo>,</mml:mo></mml:mrow></mml:math></disp-formula>
        where the constitutive relationships <inline-formula><mml:math id="M36" display="inline"><mml:mrow><mml:mi>C</mml:mi><mml:mo>(</mml:mo><mml:mi mathvariant="italic">θ</mml:mi><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula> and <inline-formula><mml:math id="M37" display="inline"><mml:mrow><mml:mi>K</mml:mi><mml:mo>(</mml:mo><mml:mi mathvariant="italic">θ</mml:mi><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula> are expressed as functions of <inline-formula><mml:math id="M38" display="inline"><mml:mi mathvariant="italic">θ</mml:mi></mml:math></inline-formula> (Celia et al., 1990). Changes in storage
in Eqs. (<xref ref-type="disp-formula" rid="Ch1.E4"/>)–(<xref ref-type="disp-formula" rid="Ch1.E6"/>) are associated with the filling and draining of soil pores. Because <inline-formula><mml:math id="M39" display="inline"><mml:mrow><mml:mi mathvariant="normal">d</mml:mi><mml:mi mathvariant="italic">θ</mml:mi><mml:mo>/</mml:mo><mml:mi mathvariant="normal">d</mml:mi><mml:mi mathvariant="italic">ψ</mml:mi><mml:mo>=</mml:mo><mml:mn mathvariant="normal">0</mml:mn></mml:mrow></mml:math></inline-formula> in saturated, or close to saturated, soils, an elastic storage term is needed to solve RE in these conditions. This term represents the compression of the pore water and
the expansion of the pore space as a function of increasing pore water pressure (though the latter is orders of magnitude larger than the former). The
<inline-formula><mml:math id="M40" display="inline"><mml:mi mathvariant="italic">ψ</mml:mi></mml:math></inline-formula> form of RE with elastic storage is written
          <disp-formula id="Ch1.E7" content-type="numbered"><label>7</label><mml:math id="M41" display="block"><mml:mrow><mml:mfenced open="(" close=")"><mml:mrow><mml:msub><mml:mi>S</mml:mi><mml:mi mathvariant="normal">S</mml:mi></mml:msub><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mrow><mml:mi mathvariant="italic">θ</mml:mi><mml:mo>(</mml:mo><mml:mi mathvariant="italic">ψ</mml:mi><mml:mo>)</mml:mo></mml:mrow><mml:mrow><mml:msub><mml:mi mathvariant="italic">θ</mml:mi><mml:mi mathvariant="normal">s</mml:mi></mml:msub></mml:mrow></mml:mfrac></mml:mstyle><mml:mo>+</mml:mo><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mrow><mml:mo>∂</mml:mo><mml:mi mathvariant="italic">θ</mml:mi></mml:mrow><mml:mrow><mml:mo>∂</mml:mo><mml:mi mathvariant="italic">ψ</mml:mi></mml:mrow></mml:mfrac></mml:mstyle></mml:mrow></mml:mfenced><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mrow><mml:mo>∂</mml:mo><mml:mi mathvariant="italic">ψ</mml:mi></mml:mrow><mml:mrow><mml:mo>∂</mml:mo><mml:mi>t</mml:mi></mml:mrow></mml:mfrac></mml:mstyle><mml:mo>=</mml:mo><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mo>∂</mml:mo><mml:mrow><mml:mo>∂</mml:mo><mml:mi>z</mml:mi></mml:mrow></mml:mfrac></mml:mstyle><mml:mfenced open="(" close=")"><mml:mrow><mml:mi>K</mml:mi><mml:mo>(</mml:mo><mml:mi mathvariant="italic">ψ</mml:mi><mml:mo>)</mml:mo><mml:mfenced close=")" open="("><mml:mrow><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mrow><mml:mo>∂</mml:mo><mml:mi mathvariant="italic">ψ</mml:mi></mml:mrow><mml:mrow><mml:mo>∂</mml:mo><mml:mi>z</mml:mi></mml:mrow></mml:mfrac></mml:mstyle><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:mfenced></mml:mrow></mml:mfenced><mml:mo>,</mml:mo></mml:mrow></mml:math></disp-formula>
        where <inline-formula><mml:math id="M42" display="inline"><mml:mrow><mml:msub><mml:mi>S</mml:mi><mml:mi mathvariant="normal">S</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula> (<inline-formula><mml:math id="M43" display="inline"><mml:mrow class="unit"><mml:msup><mml:mi mathvariant="normal">L</mml:mi><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msup></mml:mrow></mml:math></inline-formula>) is the specific storage coefficient and <inline-formula><mml:math id="M44" display="inline"><mml:mrow><mml:msub><mml:mi mathvariant="italic">θ</mml:mi><mml:mi mathvariant="normal">s</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula> is the saturated water content, equal to the porosity (Kavetski et al., 2001). If
<inline-formula><mml:math id="M45" display="inline"><mml:mrow><mml:msub><mml:mi>S</mml:mi><mml:mi mathvariant="normal">S</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula> is large, it may have a non-negligible impact on the water balance, which needs to be accounted for (e.g., as in Clark et al., 2021,
Eq. 80). <inline-formula><mml:math id="M46" display="inline"><mml:mrow><mml:msub><mml:mi>S</mml:mi><mml:mi mathvariant="normal">S</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula> is often treated as a numerical smoothing factor for RE when conditions are saturated or close to saturation, and its impact
on the water balance is neglected (e.g., as in Tocci et al., 1997; Ireson et al., 2009). For convenience, hereafter we define
<inline-formula><mml:math id="M47" display="inline"><mml:mrow><mml:mi>C</mml:mi><mml:mo>(</mml:mo><mml:mi mathvariant="italic">ψ</mml:mi><mml:mo>)</mml:mo><mml:mo>=</mml:mo><mml:msub><mml:mi>S</mml:mi><mml:mi mathvariant="normal">S</mml:mi></mml:msub><mml:mstyle displaystyle="false"><mml:mfrac style="text"><mml:mrow><mml:mi mathvariant="italic">θ</mml:mi><mml:mo>(</mml:mo><mml:mi mathvariant="italic">ψ</mml:mi><mml:mo>)</mml:mo></mml:mrow><mml:mrow><mml:msub><mml:mi mathvariant="italic">θ</mml:mi><mml:mi mathvariant="normal">s</mml:mi></mml:msub></mml:mrow></mml:mfrac></mml:mstyle><mml:mo>+</mml:mo><mml:mstyle displaystyle="false"><mml:mfrac style="text"><mml:mrow><mml:mo>∂</mml:mo><mml:mi mathvariant="italic">θ</mml:mi></mml:mrow><mml:mrow><mml:mo>∂</mml:mo><mml:mi mathvariant="italic">ψ</mml:mi></mml:mrow></mml:mfrac></mml:mstyle></mml:mrow></mml:math></inline-formula>, such that elastic storage can be
ignored by setting <inline-formula><mml:math id="M48" display="inline"><mml:mrow><mml:msub><mml:mi>S</mml:mi><mml:mi mathvariant="normal">S</mml:mi></mml:msub><mml:mo>=</mml:mo><mml:mn mathvariant="normal">0</mml:mn></mml:mrow></mml:math></inline-formula>.</p>
      <p id="d1e1167">The <inline-formula><mml:math id="M49" display="inline"><mml:mi mathvariant="italic">ψ</mml:mi></mml:math></inline-formula> form or mixed form of RE with elastic storage included can be shown to work for saturated conditions (Miller et al., 1998) and so can be
considered a general governing equation for flow in soils, aquitards, and confined and unconfined aquifers. Some numerical solutions to the
<inline-formula><mml:math id="M50" display="inline"><mml:mi mathvariant="italic">ψ</mml:mi></mml:math></inline-formula> form of RE are reportedly subject to poor mass conservation (Milly, 1984, 1985; Celia et al., 1990; Farthing and Ogden, 2017; Clark et al.,
2021; Tubini and Rigon, 2022), though it has been shown that mass balance errors can be effectively
controlled using ATS (Rathfelder and Abriola, 1994; Tocci et al., 1997). We carefully assess the mass balance performance of our model in this paper.</p>
      <p id="d1e1184">We consider a finite-difference numerical solution for the <inline-formula><mml:math id="M51" display="inline"><mml:mi mathvariant="italic">ψ</mml:mi></mml:math></inline-formula> form of RE that applies the method of lines to reduce the partial differential equation (PDE) in Eq. (<xref ref-type="disp-formula" rid="Ch1.E7"/>)
to a system of ODEs of the form
          <disp-formula id="Ch1.E8" content-type="numbered"><label>8</label><mml:math id="M52" display="block"><mml:mrow><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mrow><mml:mi mathvariant="normal">d</mml:mi><mml:mi mathvariant="bold-italic">ψ</mml:mi></mml:mrow><mml:mrow><mml:mi mathvariant="normal">d</mml:mi><mml:mi>t</mml:mi></mml:mrow></mml:mfrac></mml:mstyle><mml:mo>=</mml:mo><mml:mi>f</mml:mi><mml:mo>(</mml:mo><mml:mi mathvariant="bold-italic">ψ</mml:mi><mml:mo>,</mml:mo><mml:mi>t</mml:mi><mml:mo>,</mml:mo><mml:mi mathvariant="bold-italic">z</mml:mi><mml:mo>)</mml:mo><mml:mo>,</mml:mo></mml:mrow></mml:math></disp-formula>
        where <inline-formula><mml:math id="M53" display="inline"><mml:mi mathvariant="bold-italic">ψ</mml:mi></mml:math></inline-formula> and <inline-formula><mml:math id="M54" display="inline"><mml:mi mathvariant="bold-italic">z</mml:mi></mml:math></inline-formula> represent vectors containing discrete values of <inline-formula><mml:math id="M55" display="inline"><mml:mi mathvariant="italic">ψ</mml:mi></mml:math></inline-formula> and <inline-formula><mml:math id="M56" display="inline"><mml:mi>z</mml:mi></mml:math></inline-formula>. A similar approach was taken by Tocci et al. (1997) and Farthing and Ogden
(2017). There are various methods that can be applied to integrate Eq. (8) with respect to time –
for our purposes, it is useful to consider three specific classes of methods.
<list list-type="bullet"><list-item>
      <p id="d1e1265"><italic>Fixed-step non-iterative methods (NIMs).</italic> These methods provide a solution for a fixed time interval and can be either explicit or
implicit. Explicit methods are simple but impractical because they require very small time steps. Semi-implicit non-iterative methods take a single
iteration based on the linearization of the spatially discretized governing equations. These methods are more stable than explicit methods but have
limitations for solving RE over a fixed time interval because they do not iterate to improve the convergence of the problem, which is problematic
due to the non-linear dependence of <inline-formula><mml:math id="M57" display="inline"><mml:mi>K</mml:mi></mml:math></inline-formula> and <inline-formula><mml:math id="M58" display="inline"><mml:mi>C</mml:mi></mml:math></inline-formula> on <inline-formula><mml:math id="M59" display="inline"><mml:mi mathvariant="italic">ψ</mml:mi></mml:math></inline-formula> (Celia et al., 1990). Celia et al. (1990) did not present results using a NIM, but their
Eq. (<xref ref-type="disp-formula" rid="Ch1.E4"/>) can be solved directly (a semi-implicit non-iterative method, which we implemented and discuss in Sect. 3.1). We include NIM here
because they may be instructive to new researchers learning about these problems.</p></list-item><list-item>
      <p id="d1e1294"><italic>Fixed-step iterative methods (FIMs).</italic> Iterative implicit methods are very widely used (Celia et al., 1990; Rathfelder and Abriola,
1994). The iterations allow the solution to find more representative values of <inline-formula><mml:math id="M60" display="inline"><mml:mi>K</mml:mi></mml:math></inline-formula> and <inline-formula><mml:math id="M61" display="inline"><mml:mi>C</mml:mi></mml:math></inline-formula> over the
time step. These methods can be applied to either the <inline-formula><mml:math id="M62" display="inline"><mml:mi mathvariant="italic">ψ</mml:mi></mml:math></inline-formula> form or mixed form of RE. For the mixed form of RE, the convergence criterion can be
based directly on water balance closure, as in Celia's modified Picard iteration method. For the <inline-formula><mml:math id="M63" display="inline"><mml:mi mathvariant="italic">ψ</mml:mi></mml:math></inline-formula> form of RE, the convergence criterion is
based on <inline-formula><mml:math id="M64" display="inline"><mml:mi mathvariant="italic">ψ</mml:mi></mml:math></inline-formula> values, and the solution is subject to larger water balance errors (Celia et al., 1990; Rathfelder and Abriola, 1994; Farthing and Ogden, 2017).</p></list-item><list-item>
      <p id="d1e1335"><italic>Adaptive time-stepping (ATS) methods.</italic> An implicit or explicit method is used to find <inline-formula><mml:math id="M65" display="inline"><mml:mrow><mml:msub><mml:mi mathvariant="bold-italic">ψ</mml:mi><mml:mrow><mml:mi>t</mml:mi><mml:mo>+</mml:mo><mml:mi mathvariant="normal">Δ</mml:mi><mml:mi>t</mml:mi></mml:mrow></mml:msub></mml:mrow></mml:math></inline-formula> over some
<italic>calculation</italic> time step; the truncation error in the solution is assessed, for example, by comparing two different-order solutions, as in
Kavetski et al. (2001); and depending on the size of the error, the time step is either reduced to improve the accuracy or increased to improve the
efficiency. The solution marches forward until reaching what we term the <italic>reporting</italic> time step, where the state variables are output. The
advantage of this approach is that the states and fluxes calculated at the intermediate calculation steps contain useful information that
can be exploited in the output, as we demonstrate in this paper. Kavetski et al. (2001, 2002a, b) developed ATS solvers designed specifically to
solve the different forms of RE, while other workers have applied readily available “black-box” (Kavetski, et al., 2001) ODE or DAE (differential
algebraic equation) solvers to RE (Tocci et al., 1997; Ireson et al., 2009; Ireson and Butler, 2013; Mathias et al., 2015; Clark et al., 2021). A
wide range of ODE solvers are available in many different programming languages. Solutions are simple to implement and, as we show in this study,
can outperform other methods in terms of accuracy and efficiency.</p></list-item></list></p>
      <p id="d1e1364">In this study, we implement each of the three possible methods for solving RE in scripts that are available from Ireson (2022,
<uri>https://github.com/amireson/openRE</uri>, last access: 24 January 2023). All of the models in this study were coded in Python (version
3.8.11). We make use of the following libraries: NumPy  (version 1.20.3); Matplotlib (version 3.4.2); SciPy (version 1.7.1),
which contains various ODE solvers, described below; and Numba  (version 0.53.1, Lam et al., 2015), which is a just-in-time (JIT) compiler that is
optional but speeds up the model runs considerably. We organize and run the models using makefiles (Jackson, 2016).</p>
      <p id="d1e1371">We also provide a MATLAB version of our recommended solution (implemented in MATLAB R2017b installed on a Mac). The MATLAB
implementation will not be described further, but compared with the optimal Python solution, the MATLAB model is somewhat simpler and achieves an
equivalent performance in terms of simulated states and fluxes. We do not recommend Python over MATLAB (or vice versa) – both platforms work well,
and the choice will come down to numerous factors, including, e.g., the availability of, and user familiarity with, either package or the need to use
non-proprietary software to satisfy open-science requirements.</p>
<sec id="Ch1.S2.SS1">
  <label>2.1</label><title>Fixed-step non-iterative and iterative solutions</title>
      <p id="d1e1381">For the NIM and FIM methods, we have coded up the numerical solutions from Celia et al. (1990). This provides a typical NIM method (first-order
backward Euler implicit solution, Eq. 4 in Celia et al., 1990) and two alternative FIMs: Picard iteration that solves the <inline-formula><mml:math id="M66" display="inline"><mml:mi mathvariant="italic">ψ</mml:mi></mml:math></inline-formula> form of RE and
their improved modified Picard iteration method (MPM) solution that solves the mixed form of RE. Fully reproducible details of these models were
provided by Celia et al. (1990) and so will not be repeated here. These models were implemented in Python, and the code is provided at Ireson (2022,
<uri>https://github.com/amireson/openRE</uri>, last access: 24 January 2023). The NIM model was coded up in 67 lines of code (note that blank
lines and comment lines are not counted in the number of lines of code), with an additional 52 lines of code to configure the problem (define the
grid, hydraulic properties, etc.). The FIM Picard iteration method was coded up in 79 lines of code and required the same 52 lines of code to
configure the problem. The FIM modified Picard iteration was implemented using the Numba  just-in-time compiler (Sect. A5) and was coded up in
90 lines of code, with an additional 59 lines of code to configure the problem. All solutions make use of the Thomas algorithm to solve the
tridiagonal linear system arising from the implicit method.</p>
</sec>
<sec id="Ch1.S2.SS2">
  <label>2.2</label><title>Adaptive time-stepping solution</title>
      <p id="d1e1402">One major benefit of using a standard ODE solver to integrate RE is that the code is concise and easy to read and understand. Our objective is to
write a function that will evaluate the right-hand side of Eq. (8) and feed this to the ODE solver. Within this function, the problem can be treated
as instantaneous in time so that we only need to consider the spatial differences in our finite-difference solution scheme. We will use a
cell-centered grid (Bear and Cheng, 2010, p. 533) in space; i.e., state variables are stored at nodes located at the center of grid cells, while
fluxes are defined at the cell boundaries, as shown schematically in Fig. 1 (note that this is equivalent to what is called a “staggered grid” in fluid
dynamics). For simplicity here, we consider a uniform grid (constant <inline-formula><mml:math id="M67" display="inline"><mml:mrow><mml:mi mathvariant="normal">Δ</mml:mi><mml:mi>z</mml:mi><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula>, but it is straightforward to adapt these solutions to non-uniform
grids. We introduce two spatial indices (Fig. 1): <inline-formula><mml:math id="M68" display="inline"><mml:mi>i</mml:mi></mml:math></inline-formula> represents the nodal values, and <inline-formula><mml:math id="M69" display="inline"><mml:mi>j</mml:mi></mml:math></inline-formula> represents the cell boundaries, both of which have an
initial value of zero (because Python uses zero-based indexing). Hence, <inline-formula><mml:math id="M70" display="inline"><mml:mrow><mml:mi>j</mml:mi><mml:mo>=</mml:mo><mml:mi>i</mml:mi><mml:mo>+</mml:mo><mml:mn mathvariant="normal">1</mml:mn><mml:mo>/</mml:mo><mml:mn mathvariant="normal">2</mml:mn></mml:mrow></mml:math></inline-formula>. We will start with the <inline-formula><mml:math id="M71" display="inline"><mml:mi mathvariant="italic">ψ</mml:mi></mml:math></inline-formula> form of RE, for which the governing
equation is given in the form
            <disp-formula id="Ch1.E9" content-type="numbered"><label>9</label><mml:math id="M72" display="block"><mml:mrow><mml:msub><mml:mfenced open="" close="|"><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mrow><mml:mo>∂</mml:mo><mml:mi mathvariant="italic">ψ</mml:mi></mml:mrow><mml:mrow><mml:mo>∂</mml:mo><mml:mi>t</mml:mi></mml:mrow></mml:mfrac></mml:mstyle></mml:mfenced><mml:mi>i</mml:mi></mml:msub><mml:mo>=</mml:mo><mml:mo>-</mml:mo><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mn mathvariant="normal">1</mml:mn><mml:mrow><mml:mi>C</mml:mi><mml:mo>(</mml:mo><mml:msub><mml:mi mathvariant="italic">ψ</mml:mi><mml:mi>i</mml:mi></mml:msub><mml:mo>)</mml:mo></mml:mrow></mml:mfrac></mml:mstyle><mml:msub><mml:mfenced open="" close="|"><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mrow><mml:mo>∂</mml:mo><mml:mi>q</mml:mi></mml:mrow><mml:mrow><mml:mo>∂</mml:mo><mml:mi>z</mml:mi></mml:mrow></mml:mfrac></mml:mstyle></mml:mfenced><mml:mi>i</mml:mi></mml:msub></mml:mrow></mml:math></disp-formula>
          and
            <disp-formula id="Ch1.E10" content-type="numbered"><label>10</label><mml:math id="M73" display="block"><mml:mrow><mml:msub><mml:mfenced close="|" open=""><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mrow><mml:mo>∂</mml:mo><mml:mi>q</mml:mi></mml:mrow><mml:mrow><mml:mo>∂</mml:mo><mml:mi>z</mml:mi></mml:mrow></mml:mfrac></mml:mstyle></mml:mfenced><mml:mi>i</mml:mi></mml:msub><mml:mo>=</mml:mo><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mrow><mml:msub><mml:mi>q</mml:mi><mml:mrow><mml:mi>i</mml:mi><mml:mo>+</mml:mo><mml:mfrac><mml:mn mathvariant="normal">1</mml:mn><mml:mn mathvariant="normal">2</mml:mn></mml:mfrac></mml:mrow></mml:msub><mml:mo>-</mml:mo><mml:msub><mml:mi>q</mml:mi><mml:mrow><mml:mi>i</mml:mi><mml:mo>-</mml:mo><mml:mfrac><mml:mn mathvariant="normal">1</mml:mn><mml:mn mathvariant="normal">2</mml:mn></mml:mfrac></mml:mrow></mml:msub></mml:mrow><mml:mrow><mml:mi mathvariant="normal">Δ</mml:mi><mml:mi>z</mml:mi></mml:mrow></mml:mfrac></mml:mstyle><mml:mo>=</mml:mo><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mrow><mml:msub><mml:mi>q</mml:mi><mml:mrow><mml:mi>j</mml:mi><mml:mo>+</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msub><mml:mo>-</mml:mo><mml:msub><mml:mi>q</mml:mi><mml:mi>j</mml:mi></mml:msub></mml:mrow><mml:mrow><mml:mi mathvariant="normal">Δ</mml:mi><mml:mi>z</mml:mi></mml:mrow></mml:mfrac></mml:mstyle><mml:mo>.</mml:mo></mml:mrow></mml:math></disp-formula></p>

      <?xmltex \floatpos{t}?><fig id="Ch1.F1"><?xmltex \currentcnt{1}?><?xmltex \def\figurename{Figure}?><label>Figure 1</label><caption><p id="d1e1607">Schematic representation of the cell-centered finite-difference grid, for a soil column of depth <inline-formula><mml:math id="M74" display="inline"><mml:mi>L</mml:mi></mml:math></inline-formula>, showing the zero-based Python indices of the states (<inline-formula><mml:math id="M75" display="inline"><mml:mrow><mml:msub><mml:mi mathvariant="italic">ψ</mml:mi><mml:mi>i</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula>) and fluxes (<inline-formula><mml:math id="M76" display="inline"><mml:mrow><mml:msub><mml:mi>q</mml:mi><mml:mi>j</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula>) on the left and depths of the nodes on the right, assuming a regular grid. There are <inline-formula><mml:math id="M77" display="inline"><mml:mi>N</mml:mi></mml:math></inline-formula> states and <inline-formula><mml:math id="M78" display="inline"><mml:mrow><mml:mi>N</mml:mi><mml:mo>+</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:math></inline-formula> fluxes. The upper- and lower-boundary conditions are <inline-formula><mml:math id="M79" display="inline"><mml:mrow><mml:msub><mml:mi>q</mml:mi><mml:mrow><mml:mi>j</mml:mi><mml:mo>=</mml:mo><mml:mn mathvariant="normal">0</mml:mn></mml:mrow></mml:msub></mml:mrow></mml:math></inline-formula> and <inline-formula><mml:math id="M80" display="inline"><mml:mrow><mml:msub><mml:mi>q</mml:mi><mml:mrow><mml:msub><mml:mi>j</mml:mi><mml:mi>N</mml:mi></mml:msub></mml:mrow></mml:msub></mml:mrow></mml:math></inline-formula>, respectively.</p></caption>
          <?xmltex \igopts{width=170.716535pt}?><graphic xlink:href="https://gmd.copernicus.org/articles/16/659/2023/gmd-16-659-2023-f01.png"/>

        </fig>

      <p id="d1e1696">Here, the fluxes are given by
            <disp-formula id="Ch1.E11" content-type="numbered"><label>11</label><mml:math id="M81" display="block"><mml:mtable class="split" rowspacing="0.2ex" displaystyle="true" columnalign="right left"><mml:mtr><mml:mtd><mml:mrow><mml:msub><mml:mi>q</mml:mi><mml:mrow><mml:mi>i</mml:mi><mml:mo>+</mml:mo><mml:mstyle scriptlevel="+1"><mml:mfrac><mml:mn mathvariant="normal">1</mml:mn><mml:mn mathvariant="normal">2</mml:mn></mml:mfrac></mml:mstyle></mml:mrow></mml:msub><mml:mo>=</mml:mo></mml:mrow></mml:mtd><mml:mtd><mml:mrow><mml:mspace width="0.25em" linebreak="nobreak"/><mml:msub><mml:mi>q</mml:mi><mml:mrow><mml:mi>j</mml:mi><mml:mo>+</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msub><mml:mo>=</mml:mo><mml:mo>-</mml:mo><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mrow><mml:mi>K</mml:mi><mml:mo>(</mml:mo><mml:msub><mml:mi mathvariant="italic">ψ</mml:mi><mml:mrow><mml:mi>i</mml:mi><mml:mo>+</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msub><mml:mo>)</mml:mo><mml:mo>+</mml:mo><mml:mi>K</mml:mi><mml:mo>(</mml:mo><mml:msub><mml:mi mathvariant="italic">ψ</mml:mi><mml:mi>i</mml:mi></mml:msub><mml:mo>)</mml:mo></mml:mrow><mml:mn mathvariant="normal">2</mml:mn></mml:mfrac></mml:mstyle></mml:mrow></mml:mtd></mml:mtr><mml:mtr><mml:mtd/><mml:mtd><mml:mrow><mml:mo>×</mml:mo><mml:mfenced open="(" close=")"><mml:mrow><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mrow><mml:msub><mml:mi mathvariant="italic">ψ</mml:mi><mml:mrow><mml:mi>i</mml:mi><mml:mo>+</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msub><mml:mo>-</mml:mo><mml:msub><mml:mi mathvariant="italic">ψ</mml:mi><mml:mi>i</mml:mi></mml:msub></mml:mrow><mml:mrow><mml:mi mathvariant="normal">Δ</mml:mi><mml:mi>z</mml:mi></mml:mrow></mml:mfrac></mml:mstyle><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:mfenced></mml:mrow></mml:mtd></mml:mtr><mml:mtr><mml:mtd><mml:mrow><mml:msub><mml:mi>q</mml:mi><mml:mrow><mml:mi>i</mml:mi><mml:mo>-</mml:mo><mml:mstyle scriptlevel="+1"><mml:mfrac><mml:mn mathvariant="normal">1</mml:mn><mml:mn mathvariant="normal">2</mml:mn></mml:mfrac></mml:mstyle></mml:mrow></mml:msub><mml:mo>=</mml:mo></mml:mrow></mml:mtd><mml:mtd><mml:mrow><mml:mspace width="0.25em" linebreak="nobreak"/><mml:msub><mml:mi>q</mml:mi><mml:mi>j</mml:mi></mml:msub><mml:mo>=</mml:mo><mml:mo>-</mml:mo><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mrow><mml:mi>K</mml:mi><mml:mo>(</mml:mo><mml:msub><mml:mi mathvariant="italic">ψ</mml:mi><mml:mi>i</mml:mi></mml:msub><mml:mo>)</mml:mo><mml:mo>+</mml:mo><mml:mi>K</mml:mi><mml:mo>(</mml:mo><mml:msub><mml:mi mathvariant="italic">ψ</mml:mi><mml:mrow><mml:mi>i</mml:mi><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msub><mml:mo>)</mml:mo></mml:mrow><mml:mn mathvariant="normal">2</mml:mn></mml:mfrac></mml:mstyle></mml:mrow></mml:mtd></mml:mtr><mml:mtr><mml:mtd/><mml:mtd><mml:mrow><mml:mo>×</mml:mo><mml:mfenced open="(" close=")"><mml:mrow><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mrow><mml:msub><mml:mi mathvariant="italic">ψ</mml:mi><mml:mi>i</mml:mi></mml:msub><mml:mo>-</mml:mo><mml:msub><mml:mi mathvariant="italic">ψ</mml:mi><mml:mrow><mml:mi>i</mml:mi><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msub><mml:mspace width="0.125em" linebreak="nobreak"/></mml:mrow><mml:mrow><mml:mi mathvariant="normal">Δ</mml:mi><mml:mi>z</mml:mi></mml:mrow></mml:mfrac></mml:mstyle><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:mfenced><mml:mo>.</mml:mo></mml:mrow></mml:mtd></mml:mtr></mml:mtable></mml:math></disp-formula></p>
      <p id="d1e1917">In Eq. (11), we are using the arithmetic mean of <inline-formula><mml:math id="M82" display="inline"><mml:mi>K</mml:mi></mml:math></inline-formula> at the nodal points to estimate <inline-formula><mml:math id="M83" display="inline"><mml:mi>K</mml:mi></mml:math></inline-formula> at the cell boundaries, but other options are possible (see,
e.g., Bear and Cheng, 2010, p. 535). It is possible to combine Eqs. (9)–(11), but keeping them separate keeps the code modular and simple.</p>
      <p id="d1e1934">There are three commonly used boundary conditions for this problem, namely
<list list-type="custom"><list-item><label>i.</label>
      <p id="d1e1939">a specified flux, <inline-formula><mml:math id="M84" display="inline"><mml:mrow><mml:msub><mml:mi>q</mml:mi><mml:mi mathvariant="normal">T</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula> (<inline-formula><mml:math id="M85" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">L</mml:mi><mml:mspace width="0.125em" linebreak="nobreak"/><mml:msup><mml:mi mathvariant="normal">T</mml:mi><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msup></mml:mrow></mml:math></inline-formula>) (type-II boundary) is often used at the upper boundary to represent infiltration, where<disp-formula id="Ch1.E12" content-type="numbered"><label>12</label><mml:math id="M86" display="block"><mml:mrow><mml:msub><mml:mi>q</mml:mi><mml:mrow><mml:mi>j</mml:mi><mml:mo>=</mml:mo><mml:mn mathvariant="normal">0</mml:mn></mml:mrow></mml:msub><mml:mo>=</mml:mo><mml:msub><mml:mi>q</mml:mi><mml:mi mathvariant="normal">T</mml:mi></mml:msub><mml:mo>;</mml:mo></mml:mrow></mml:math></disp-formula></p></list-item><list-item><label>ii.</label>
      <p id="d1e1995">a free-drainage boundary is often used at the lower boundary, where<disp-formula id="Ch1.E13" content-type="numbered"><label>13</label><mml:math id="M87" display="block"><mml:mrow><mml:msub><mml:mi>q</mml:mi><mml:mrow><mml:mi>j</mml:mi><mml:mo>=</mml:mo><mml:mi>N</mml:mi></mml:mrow></mml:msub><mml:mo>=</mml:mo><mml:mi>K</mml:mi><mml:mo>(</mml:mo><mml:msub><mml:mi mathvariant="italic">ψ</mml:mi><mml:mrow><mml:mi>i</mml:mi><mml:mo>=</mml:mo><mml:mi>N</mml:mi><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msub><mml:mo>)</mml:mo><mml:mo>;</mml:mo></mml:mrow></mml:math></disp-formula></p></list-item><list-item><label>iii.</label>
      <p id="d1e2038">a fixed <inline-formula><mml:math id="M88" display="inline"><mml:mi mathvariant="italic">ψ</mml:mi></mml:math></inline-formula> (type-I) boundary maybe used at the upper boundary, <inline-formula><mml:math id="M89" display="inline"><mml:mrow><mml:msub><mml:mi mathvariant="italic">ψ</mml:mi><mml:mi mathvariant="normal">T</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula> (<inline-formula><mml:math id="M90" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">L</mml:mi></mml:mrow></mml:math></inline-formula>), typically to indicate a ponding
depth, or at the lower boundary, <inline-formula><mml:math id="M91" display="inline"><mml:mrow><mml:msub><mml:mi mathvariant="italic">ψ</mml:mi><mml:mi mathvariant="normal">B</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula> (<inline-formula><mml:math id="M92" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">L</mml:mi></mml:mrow></mml:math></inline-formula>), typically to represent a fixed water table, where<disp-formula id="Ch1.E14" content-type="numbered"><label>14</label><mml:math id="M93" display="block"><mml:mtable class="split" rowspacing="0.2ex" displaystyle="true" columnalign="right left"><mml:mtr><mml:mtd><mml:mrow><mml:msub><mml:mi>q</mml:mi><mml:mrow><mml:mi>j</mml:mi><mml:mo>=</mml:mo><mml:mn mathvariant="normal">0</mml:mn></mml:mrow></mml:msub><mml:mo>=</mml:mo></mml:mrow></mml:mtd><mml:mtd><mml:mrow><mml:mspace linebreak="nobreak" width="0.25em"/><mml:mo>-</mml:mo><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mrow><mml:mi>K</mml:mi><mml:mo>(</mml:mo><mml:msub><mml:mi mathvariant="italic">ψ</mml:mi><mml:mi mathvariant="normal">T</mml:mi></mml:msub><mml:mo>)</mml:mo><mml:mo>+</mml:mo><mml:mi>K</mml:mi><mml:mo>(</mml:mo><mml:msub><mml:mi mathvariant="italic">ψ</mml:mi><mml:mrow><mml:mi>i</mml:mi><mml:mo>=</mml:mo><mml:mn mathvariant="normal">0</mml:mn></mml:mrow></mml:msub><mml:mo>)</mml:mo></mml:mrow><mml:mn mathvariant="normal">2</mml:mn></mml:mfrac></mml:mstyle></mml:mrow></mml:mtd></mml:mtr><mml:mtr><mml:mtd/><mml:mtd><mml:mrow><mml:mo>×</mml:mo><mml:mfenced open="(" close=")"><mml:mrow><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mrow><mml:msub><mml:mi mathvariant="italic">ψ</mml:mi><mml:mi mathvariant="normal">T</mml:mi></mml:msub><mml:mo>-</mml:mo><mml:msub><mml:mi mathvariant="italic">ψ</mml:mi><mml:mrow><mml:mi>i</mml:mi><mml:mo>=</mml:mo><mml:mn mathvariant="normal">0</mml:mn></mml:mrow></mml:msub></mml:mrow><mml:mrow><mml:mi mathvariant="normal">Δ</mml:mi><mml:mi>z</mml:mi><mml:mo>/</mml:mo><mml:mn mathvariant="normal">2</mml:mn></mml:mrow></mml:mfrac></mml:mstyle><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:mfenced></mml:mrow></mml:mtd></mml:mtr><mml:mtr><mml:mtd><mml:mrow><mml:msub><mml:mi>q</mml:mi><mml:mrow><mml:mi>j</mml:mi><mml:mo>=</mml:mo><mml:mi>N</mml:mi></mml:mrow></mml:msub><mml:mo>=</mml:mo></mml:mrow></mml:mtd><mml:mtd><mml:mrow><mml:mspace linebreak="nobreak" width="0.25em"/><mml:mo>-</mml:mo><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mrow><mml:mi>K</mml:mi><mml:mo>(</mml:mo><mml:msub><mml:mi mathvariant="italic">ψ</mml:mi><mml:mrow><mml:mi>i</mml:mi><mml:mo>=</mml:mo><mml:mi>N</mml:mi><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msub><mml:mo>)</mml:mo><mml:mo>+</mml:mo><mml:mi>K</mml:mi><mml:mo>(</mml:mo><mml:msub><mml:mi mathvariant="italic">ψ</mml:mi><mml:mi mathvariant="normal">B</mml:mi></mml:msub><mml:mo>)</mml:mo></mml:mrow><mml:mn mathvariant="normal">2</mml:mn></mml:mfrac></mml:mstyle></mml:mrow></mml:mtd></mml:mtr><mml:mtr><mml:mtd/><mml:mtd><mml:mrow><mml:mo>×</mml:mo><mml:mfenced close=")" open="("><mml:mrow><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mrow><mml:msub><mml:mi mathvariant="italic">ψ</mml:mi><mml:mrow><mml:mi>i</mml:mi><mml:mo>=</mml:mo><mml:mi>N</mml:mi><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msub><mml:mo>-</mml:mo><mml:msub><mml:mi mathvariant="italic">ψ</mml:mi><mml:mi mathvariant="normal">B</mml:mi></mml:msub></mml:mrow><mml:mrow><mml:mi mathvariant="normal">Δ</mml:mi><mml:mi>z</mml:mi><mml:mo>/</mml:mo><mml:mn mathvariant="normal">2</mml:mn></mml:mrow></mml:mfrac></mml:mstyle><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:mfenced><mml:mo>.</mml:mo></mml:mrow></mml:mtd></mml:mtr></mml:mtable></mml:math></disp-formula></p></list-item></list></p>
      <p id="d1e2292">Box 1 provides Python-based pseudo-code that implements this solution (Eqs. 9–14) in a function for <inline-formula><mml:math id="M94" display="inline"><mml:mrow><mml:mi mathvariant="normal">d</mml:mi><mml:mi mathvariant="italic">ψ</mml:mi><mml:mo>/</mml:mo><mml:mi mathvariant="normal">d</mml:mi><mml:mi>t</mml:mi></mml:mrow></mml:math></inline-formula> with a type-II
boundary at the upper boundary and a free-drainage boundary at the lower boundary and contains just seven lines of code. This function can be called by
the ODE solver.</p><?xmltex \setfigures?><?xmltex \setboxes?><?xmltex \floatpos{t}?><fig id="Ch1.F2" specific-use="star"><?xmltex \currentcnt{1}?><?xmltex \def\figurename{Box}?><label>Box 1</label><caption><p id="d1e2314">Python-based pseudo-code implementation of RE with a cell-centered finite-difference approach in a function to be called by an ODE solver. Arrays are zero-indexed; <inline-formula><mml:math id="M95" display="inline"><mml:mrow><mml:mi>q</mml:mi><mml:mo>[</mml:mo><mml:mn mathvariant="normal">0</mml:mn><mml:mo>]</mml:mo></mml:mrow></mml:math></inline-formula> and <inline-formula><mml:math id="M96" display="inline"><mml:mrow><mml:mi>q</mml:mi><mml:mo>[</mml:mo><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn><mml:mo>]</mml:mo></mml:mrow></mml:math></inline-formula> refer to the first and last item in the <inline-formula><mml:math id="M97" display="inline"><mml:mi>q</mml:mi></mml:math></inline-formula> array, respectively, and <inline-formula><mml:math id="M98" display="inline"><mml:mrow><mml:mi>K</mml:mi><mml:mo>[</mml:mo><mml:mn mathvariant="normal">1</mml:mn><mml:mo>:</mml:mo><mml:mo>]</mml:mo></mml:mrow></mml:math></inline-formula> and <inline-formula><mml:math id="M99" display="inline"><mml:mrow><mml:mi>K</mml:mi><mml:mo>[</mml:mo><mml:mo>:</mml:mo><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn><mml:mo>]</mml:mo></mml:mrow></mml:math></inline-formula> refer to a slice of the array <inline-formula><mml:math id="M100" display="inline"><mml:mi>K</mml:mi></mml:math></inline-formula> from the second to the last node and from the first to the second-to-last node, respectively.</p></caption>
          <?xmltex \igopts{width=341.433071pt}?><graphic xlink:href="https://gmd.copernicus.org/articles/16/659/2023/gmd-16-659-2023-b01.png"/>

        </fig>

</sec>
<sec id="Ch1.S2.SS3">
  <label>2.3</label><title>Mass balance closure</title>
      <p id="d1e2410">When RE is solved over some time interval, <inline-formula><mml:math id="M101" display="inline"><mml:mrow><mml:mi>t</mml:mi><mml:mo>=</mml:mo><mml:msub><mml:mi>t</mml:mi><mml:mn mathvariant="normal">0</mml:mn></mml:msub><mml:mo>→</mml:mo><mml:msub><mml:mi>t</mml:mi><mml:mi>M</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula> (where <inline-formula><mml:math id="M102" display="inline"><mml:mrow><mml:msub><mml:mi>t</mml:mi><mml:mi>M</mml:mi></mml:msub><mml:mo>-</mml:mo><mml:msub><mml:mi>t</mml:mi><mml:mn mathvariant="normal">0</mml:mn></mml:msub></mml:mrow></mml:math></inline-formula> typically corresponds to multiple years in practical application)
for a soil profile <inline-formula><mml:math id="M103" display="inline"><mml:mrow><mml:mn mathvariant="normal">0</mml:mn><mml:mo>≤</mml:mo><mml:mi>z</mml:mi><mml:mo>≤</mml:mo><mml:mi>L</mml:mi></mml:mrow></mml:math></inline-formula>, the cumulative inflow minus outflow should equal the change in storage in the profile over the same interval; i.e.,
<inline-formula><mml:math id="M104" display="inline"><mml:mrow><mml:msub><mml:mi mathvariant="italic">ϵ</mml:mi><mml:mi mathvariant="normal">B</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula> (<inline-formula><mml:math id="M105" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">mm</mml:mi></mml:mrow></mml:math></inline-formula>), the bias error, defined in Eq. (15), should be zero.
            <disp-formula id="Ch1.E15" content-type="numbered"><label>15</label><mml:math id="M106" display="block"><mml:mtable rowspacing="0.2ex" class="split" displaystyle="true" columnalign="right left"><mml:mtr><mml:mtd><mml:mrow><mml:msub><mml:mi mathvariant="italic">ϵ</mml:mi><mml:mi mathvariant="normal">B</mml:mi></mml:msub><mml:mo>=</mml:mo></mml:mrow></mml:mtd><mml:mtd><mml:mrow><mml:munderover><mml:mo movablelimits="false">∫</mml:mo><mml:mrow><mml:mi>t</mml:mi><mml:mo>=</mml:mo><mml:msub><mml:mi>t</mml:mi><mml:mn mathvariant="normal">0</mml:mn></mml:msub></mml:mrow><mml:mrow><mml:msub><mml:mi>t</mml:mi><mml:mi>M</mml:mi></mml:msub></mml:mrow></mml:munderover><mml:mo>(</mml:mo><mml:mi>q</mml:mi><mml:mo>(</mml:mo><mml:mi>t</mml:mi><mml:mo>,</mml:mo><mml:mn mathvariant="normal">0</mml:mn><mml:mo>)</mml:mo><mml:mo>-</mml:mo><mml:mi>q</mml:mi><mml:mo>(</mml:mo><mml:mi>t</mml:mi><mml:mo>,</mml:mo><mml:msub><mml:mi>z</mml:mi><mml:mi>N</mml:mi></mml:msub><mml:mo>)</mml:mo><mml:mo>)</mml:mo><mml:mi mathvariant="normal">d</mml:mi><mml:mi>t</mml:mi></mml:mrow></mml:mtd></mml:mtr><mml:mtr><mml:mtd/><mml:mtd><mml:mrow><mml:mo>-</mml:mo><mml:munderover><mml:mo movablelimits="false">∫</mml:mo><mml:mrow><mml:mi>z</mml:mi><mml:mo>=</mml:mo><mml:mn mathvariant="normal">0</mml:mn></mml:mrow><mml:mi>L</mml:mi></mml:munderover><mml:mo>(</mml:mo><mml:mi mathvariant="italic">θ</mml:mi><mml:mo>(</mml:mo><mml:msub><mml:mi>t</mml:mi><mml:mi>M</mml:mi></mml:msub><mml:mo>,</mml:mo><mml:mi>z</mml:mi><mml:mo>)</mml:mo><mml:mo>-</mml:mo><mml:mi mathvariant="italic">θ</mml:mi><mml:mo>(</mml:mo><mml:msub><mml:mi>t</mml:mi><mml:mn mathvariant="normal">0</mml:mn></mml:msub><mml:mo>,</mml:mo><mml:mi>z</mml:mi><mml:mo>)</mml:mo><mml:mo>)</mml:mo><mml:mi mathvariant="normal">d</mml:mi><mml:mi>z</mml:mi></mml:mrow></mml:mtd></mml:mtr></mml:mtable></mml:math></disp-formula></p>
      <p id="d1e2622">The bias error can be treated as a mass balance performance metric for the model, but this metric may underestimate the true errors in the water
balance that occur within the time period simulated, which may cancel out over the entire run. The metric used by Celia et al. (1990), Rathfelder and
Abriola (1994), and Tocci et al. (1997) has the same problem. A more rigorous mass balance performance metric is the root mean squared error of the
daily (or some other time increment) cumulative net flux minus the change in storage, <inline-formula><mml:math id="M107" display="inline"><mml:mrow><mml:msub><mml:mi mathvariant="italic">ϵ</mml:mi><mml:mi mathvariant="normal">R</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula> (mm), where
            <disp-formula id="Ch1.E16" content-type="numbered"><label>16</label><mml:math id="M108" display="block"><mml:mrow><mml:msub><mml:mi mathvariant="italic">ϵ</mml:mi><mml:mi mathvariant="normal">R</mml:mi></mml:msub><mml:mo>=</mml:mo><mml:msqrt><mml:mrow><mml:munderover><mml:mo movablelimits="false">∑</mml:mo><mml:mrow><mml:mi>j</mml:mi><mml:mo>=</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow><mml:mi>M</mml:mi></mml:munderover><mml:msup><mml:mfenced close=")" open="("><mml:mtable class="array" columnalign="left"><mml:mtr><mml:mtd><mml:mrow><mml:munderover><mml:mo movablelimits="false">∫</mml:mo><mml:mrow><mml:mi>t</mml:mi><mml:mo>=</mml:mo><mml:msub><mml:mi>t</mml:mi><mml:mi>j</mml:mi></mml:msub></mml:mrow><mml:mrow><mml:msub><mml:mi>t</mml:mi><mml:mrow><mml:mi>j</mml:mi><mml:mo>+</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msub></mml:mrow></mml:munderover><mml:mo>(</mml:mo><mml:mi>q</mml:mi><mml:mo>(</mml:mo><mml:mi>t</mml:mi><mml:mo>,</mml:mo><mml:mn mathvariant="normal">0</mml:mn><mml:mo>)</mml:mo><mml:mo>-</mml:mo><mml:mi>q</mml:mi><mml:mo>(</mml:mo><mml:mi>t</mml:mi><mml:mo>,</mml:mo><mml:msub><mml:mi>z</mml:mi><mml:mi>N</mml:mi></mml:msub><mml:mo>)</mml:mo><mml:mo>)</mml:mo><mml:mi mathvariant="normal">d</mml:mi><mml:mi>t</mml:mi></mml:mrow></mml:mtd></mml:mtr><mml:mtr><mml:mtd><mml:mrow><mml:mo>-</mml:mo><mml:munderover><mml:mo movablelimits="false">∫</mml:mo><mml:mrow><mml:mi>z</mml:mi><mml:mo>=</mml:mo><mml:mn mathvariant="normal">0</mml:mn></mml:mrow><mml:mi>L</mml:mi></mml:munderover><mml:mo>(</mml:mo><mml:mi mathvariant="italic">θ</mml:mi><mml:mo>(</mml:mo><mml:msub><mml:mi>t</mml:mi><mml:mrow><mml:mi>j</mml:mi><mml:mo>+</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msub><mml:mo>,</mml:mo><mml:mi>z</mml:mi><mml:mo>)</mml:mo><mml:mo>-</mml:mo><mml:mi mathvariant="italic">θ</mml:mi><mml:mo>(</mml:mo><mml:msub><mml:mi>t</mml:mi><mml:mi>j</mml:mi></mml:msub><mml:mo>,</mml:mo><mml:mi>z</mml:mi><mml:mo>)</mml:mo><mml:mo>)</mml:mo><mml:mi mathvariant="normal">d</mml:mi><mml:mi>z</mml:mi></mml:mrow></mml:mtd></mml:mtr></mml:mtable></mml:mfenced><mml:mn mathvariant="normal">2</mml:mn></mml:msup><mml:mo>/</mml:mo><mml:mi>M</mml:mi></mml:mrow></mml:msqrt><mml:mo>,</mml:mo></mml:mrow></mml:math></disp-formula>
          where <inline-formula><mml:math id="M109" display="inline"><mml:mi>j</mml:mi></mml:math></inline-formula> is an index in time, and <inline-formula><mml:math id="M110" display="inline"><mml:mi>M</mml:mi></mml:math></inline-formula> is the number of time steps considered. Reporting both metrics is informative – a high <inline-formula><mml:math id="M111" display="inline"><mml:mrow><mml:msub><mml:mi mathvariant="italic">ϵ</mml:mi><mml:mi mathvariant="normal">R</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula>
with a low <inline-formula><mml:math id="M112" display="inline"><mml:mrow><mml:msub><mml:mi mathvariant="italic">ϵ</mml:mi><mml:mi mathvariant="normal">B</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula> indicates that daily errors are occurring but canceling one another out; a high <inline-formula><mml:math id="M113" display="inline"><mml:mrow><mml:msub><mml:mi mathvariant="italic">ϵ</mml:mi><mml:mi mathvariant="normal">B</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula> with a low
<inline-formula><mml:math id="M114" display="inline"><mml:mrow><mml:msub><mml:mi mathvariant="italic">ϵ</mml:mi><mml:mi mathvariant="normal">R</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula> indicates that small daily errors are systematic in one direction and hence accumulate to give a high bias.</p>
      <p id="d1e2861">The fluxes in the mass balance calculation depend on the boundary conditions. For type-I (specified <inline-formula><mml:math id="M115" display="inline"><mml:mi mathvariant="italic">ψ</mml:mi></mml:math></inline-formula>) and free-drainage-type boundary
conditions, the boundary flux depends on the simulated <inline-formula><mml:math id="M116" display="inline"><mml:mi mathvariant="italic">ψ</mml:mi></mml:math></inline-formula> value at the node closest to the boundary. Over a time increment <inline-formula><mml:math id="M117" display="inline"><mml:mrow><mml:msub><mml:mi>t</mml:mi><mml:mi>j</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula> to <inline-formula><mml:math id="M118" display="inline"><mml:mrow><mml:msub><mml:mi>t</mml:mi><mml:mrow><mml:mi>j</mml:mi><mml:mo>+</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msub></mml:mrow></mml:math></inline-formula>,
<inline-formula><mml:math id="M119" display="inline"><mml:mi mathvariant="italic">ψ</mml:mi></mml:math></inline-formula> values will change continuously and hence so will the boundary flux. Due to the non-linearity of the <inline-formula><mml:math id="M120" display="inline"><mml:mrow><mml:mi>K</mml:mi><mml:mo>(</mml:mo><mml:mi mathvariant="italic">ψ</mml:mi><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula> relationship, the flux will
change in a non-linear manner. The cumulative flux over the time increment, <inline-formula><mml:math id="M121" display="inline"><mml:mrow><mml:msub><mml:mi>Q</mml:mi><mml:mrow><mml:mi>j</mml:mi><mml:mo>→</mml:mo><mml:mi>j</mml:mi><mml:mo>+</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msub></mml:mrow></mml:math></inline-formula> (mm), is given by
            <disp-formula id="Ch1.E17" content-type="numbered"><label>17</label><mml:math id="M122" display="block"><mml:mrow><mml:msub><mml:mi>Q</mml:mi><mml:mrow><mml:mi>j</mml:mi><mml:mo>→</mml:mo><mml:mi>j</mml:mi><mml:mo>+</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msub><mml:mo>=</mml:mo><mml:munderover><mml:mo movablelimits="false">∫</mml:mo><mml:mrow><mml:mi>t</mml:mi><mml:mo>=</mml:mo><mml:msub><mml:mi>t</mml:mi><mml:mi>j</mml:mi></mml:msub></mml:mrow><mml:mrow><mml:msub><mml:mi>t</mml:mi><mml:mrow><mml:mi>j</mml:mi><mml:mo>+</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msub></mml:mrow></mml:munderover><mml:mi>q</mml:mi><mml:mo>(</mml:mo><mml:mi>t</mml:mi><mml:mo>)</mml:mo><mml:mi mathvariant="normal">d</mml:mi><mml:mi>t</mml:mi><mml:mo>.</mml:mo></mml:mrow></mml:math></disp-formula></p>
      <p id="d1e3006"><inline-formula><mml:math id="M123" display="inline"><mml:mrow><mml:msub><mml:mi>Q</mml:mi><mml:mrow><mml:mi>j</mml:mi><mml:mo>→</mml:mo><mml:mi>j</mml:mi><mml:mo>+</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msub></mml:mrow></mml:math></inline-formula> is estimated from discrete values of <inline-formula><mml:math id="M124" display="inline"><mml:mi>q</mml:mi></mml:math></inline-formula> (which in turn are approximated from discrete values of <inline-formula><mml:math id="M125" display="inline"><mml:mi mathvariant="italic">ψ</mml:mi></mml:math></inline-formula>, using either a forward
difference approximation, where <inline-formula><mml:math id="M126" display="inline"><mml:mrow><mml:msub><mml:mi>Q</mml:mi><mml:mrow><mml:mi>j</mml:mi><mml:mo>→</mml:mo><mml:mi>j</mml:mi><mml:mo>+</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msub><mml:mo>≈</mml:mo><mml:msub><mml:mi>q</mml:mi><mml:mi>j</mml:mi></mml:msub><mml:mi mathvariant="normal">Δ</mml:mi><mml:mi>t</mml:mi></mml:mrow></mml:math></inline-formula>; a backward difference approximation (as in Celia et al., 1990), where <inline-formula><mml:math id="M127" display="inline"><mml:mrow><mml:msub><mml:mi>Q</mml:mi><mml:mrow><mml:mi>j</mml:mi><mml:mo>→</mml:mo><mml:mi>j</mml:mi><mml:mo>+</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msub><mml:mo>≈</mml:mo><mml:msub><mml:mi>q</mml:mi><mml:mrow><mml:mi>j</mml:mi><mml:mo>+</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msub><mml:mi mathvariant="normal">Δ</mml:mi><mml:mi>t</mml:mi></mml:mrow></mml:math></inline-formula>; or a central difference approximation (as in trapezoidal integration), where <inline-formula><mml:math id="M128" display="inline"><mml:mrow><mml:msub><mml:mi>Q</mml:mi><mml:mrow><mml:mi>j</mml:mi><mml:mo>→</mml:mo><mml:mi>j</mml:mi><mml:mo>+</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msub><mml:mo>≈</mml:mo><mml:mo>(</mml:mo><mml:msub><mml:mi>q</mml:mi><mml:mi>j</mml:mi></mml:msub><mml:mo>+</mml:mo><mml:msub><mml:mi>q</mml:mi><mml:mrow><mml:mi>j</mml:mi><mml:mo>+</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msub><mml:mo>)</mml:mo><mml:mi mathvariant="normal">Δ</mml:mi><mml:mi>t</mml:mi><mml:mo>/</mml:mo><mml:mn mathvariant="normal">2</mml:mn></mml:mrow></mml:math></inline-formula>. These discrete approximations for <inline-formula><mml:math id="M129" display="inline"><mml:mrow><mml:msub><mml:mi>Q</mml:mi><mml:mrow><mml:mi>j</mml:mi><mml:mo>→</mml:mo><mml:mi>j</mml:mi><mml:mo>+</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msub></mml:mrow></mml:math></inline-formula> can be poor if the time step is large – or, more precisely, if the
changes in <inline-formula><mml:math id="M130" display="inline"><mml:mi>q</mml:mi></mml:math></inline-formula> over a time step are large and non-linear.</p>
      <p id="d1e3189">This leads to an important limitation with Celia's mixed form solution to RE (and other equivalent iterative solutions). This solution has excellent
mass balance closure, but because it uses a fixed-step iterative solution procedure with a backward difference approximation for <inline-formula><mml:math id="M131" display="inline"><mml:mrow><mml:msub><mml:mi>Q</mml:mi><mml:mrow><mml:mi>j</mml:mi><mml:mo>→</mml:mo><mml:mi>j</mml:mi><mml:mo>+</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msub></mml:mrow></mml:math></inline-formula>, the
simulated boundary fluxes can be shown to be sensitive to the time step (see Sect. 3.2). Hence, even though for larger <inline-formula><mml:math id="M132" display="inline"><mml:mrow><mml:mi mathvariant="normal">Δ</mml:mi><mml:mi>t</mml:mi></mml:mrow></mml:math></inline-formula> the water balance
is still perfectly closed, the actual terms within the water balance have changed, so there is less inflow and less change in storage.</p>
      <p id="d1e3222">ATS solvers can provide a practical solution to solving RE with good mass balance performance and boundary fluxes that do not depend on the user-specified time step. The basic idea behind ATS solvers is that when there are large changes in <inline-formula><mml:math id="M133" display="inline"><mml:mi mathvariant="italic">ψ</mml:mi></mml:math></inline-formula> in the model, small steps can be taken to
capture the shape of <inline-formula><mml:math id="M134" display="inline"><mml:mrow><mml:mi>C</mml:mi><mml:mo>(</mml:mo><mml:mi mathvariant="italic">ψ</mml:mi><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula> and <inline-formula><mml:math id="M135" display="inline"><mml:mrow><mml:msub><mml:mi>Q</mml:mi><mml:mrow><mml:mi>j</mml:mi><mml:mo>→</mml:mo><mml:mi>j</mml:mi><mml:mo>+</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msub></mml:mrow></mml:math></inline-formula> and minimize the integration errors over a time step. When the changes in <inline-formula><mml:math id="M136" display="inline"><mml:mi mathvariant="italic">ψ</mml:mi></mml:math></inline-formula> are small,
larger steps can be taken to maximize efficiency. We will refer to these adaptive time steps as <italic>calculation</italic> steps. The user specifies the
time steps at which they wish the results to be saved, which we will refer to as the <italic>reporting</italic> time steps. In typical practical applications,
the reporting step would be the resolution of the driving data (e.g., hourly or daily). The solver may take many calculation steps of varying lengths
between the reporting steps, saving the outcomes internally each time that the error tolerance is satisfied and a successful step is taken.</p>
      <p id="d1e3280">To accurately calculate the boundary fluxes, it is necessary to use the <inline-formula><mml:math id="M137" display="inline"><mml:mi mathvariant="italic">ψ</mml:mi></mml:math></inline-formula> information from the calculation time steps because <inline-formula><mml:math id="M138" display="inline"><mml:mi mathvariant="italic">ψ</mml:mi></mml:math></inline-formula> may have
evolved non-linearly over the reporting time step. However, this is not trivial. Two possible ways to do this (which are equivalent to one another)
are to (i) enable dense output from the ODE solver (if this feature is supported by the ODE solver) or (ii) force the ODE solver to make the
reporting steps equal to the calculation steps. However, both of these approaches are more computationally demanding in terms of memory and runtime –
a significant disadvantage. We propose here a third method for calculating the boundary fluxes that can be used with any ODE solver. At an instance in
time, the cumulative boundary flux, <inline-formula><mml:math id="M139" display="inline"><mml:mi>Q</mml:mi></mml:math></inline-formula>, is related to the instantaneous flux, <inline-formula><mml:math id="M140" display="inline"><mml:mi>q</mml:mi></mml:math></inline-formula>, by
            <disp-formula id="Ch1.E18" content-type="numbered"><label>18</label><mml:math id="M141" display="block"><mml:mrow><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mrow><mml:mi mathvariant="normal">d</mml:mi><mml:mi>Q</mml:mi></mml:mrow><mml:mrow><mml:mi mathvariant="normal">d</mml:mi><mml:mi>t</mml:mi></mml:mrow></mml:mfrac></mml:mstyle><mml:mo>=</mml:mo><mml:mi>q</mml:mi><mml:mo>.</mml:mo></mml:mrow></mml:math></disp-formula></p>
      <p id="d1e3334">We can therefore use the ODE solver to integrate this expression and solve for <inline-formula><mml:math id="M142" display="inline"><mml:mi>Q</mml:mi></mml:math></inline-formula>. To do this, we add to the system of ODEs defined by Eq. (8) two
new ODE expressions that represent the cumulative boundary fluxes. The dependent variable vector that is sent to the ODE solver now is <inline-formula><mml:math id="M143" display="inline"><mml:mi mathvariant="bold-italic">F</mml:mi></mml:math></inline-formula>,
defined
            <disp-formula id="Ch1.E19" content-type="numbered"><label>19</label><mml:math id="M144" display="block"><mml:mrow><mml:mi mathvariant="bold-italic">F</mml:mi><mml:mo>=</mml:mo><mml:mfenced open="[" close="]"><mml:mtable class="matrix" columnalign="center" framespacing="0em"><mml:mtr><mml:mtd><mml:mrow><mml:msub><mml:mi>Q</mml:mi><mml:mrow><mml:mi>T</mml:mi><mml:mo>:</mml:mo><mml:msub><mml:mi>t</mml:mi><mml:mn mathvariant="normal">0</mml:mn></mml:msub><mml:mo>→</mml:mo><mml:mi>t</mml:mi></mml:mrow></mml:msub></mml:mrow></mml:mtd></mml:mtr><mml:mtr><mml:mtd><mml:mrow><mml:msub><mml:mi mathvariant="italic">ψ</mml:mi><mml:mn mathvariant="normal">0</mml:mn></mml:msub></mml:mrow></mml:mtd></mml:mtr><mml:mtr><mml:mtd><mml:mrow><mml:msub><mml:mi mathvariant="italic">ψ</mml:mi><mml:mn mathvariant="normal">1</mml:mn></mml:msub></mml:mrow></mml:mtd></mml:mtr><mml:mtr><mml:mtd><mml:mi mathvariant="normal">⋮</mml:mi></mml:mtd></mml:mtr><mml:mtr><mml:mtd><mml:mrow><mml:msub><mml:mi mathvariant="italic">ψ</mml:mi><mml:mrow><mml:mi>N</mml:mi><mml:mo>-</mml:mo><mml:mn mathvariant="normal">2</mml:mn></mml:mrow></mml:msub></mml:mrow></mml:mtd></mml:mtr><mml:mtr><mml:mtd><mml:mrow><mml:msub><mml:mi mathvariant="italic">ψ</mml:mi><mml:mrow><mml:mi>N</mml:mi><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msub></mml:mrow></mml:mtd></mml:mtr><mml:mtr><mml:mtd><mml:mrow><mml:msub><mml:mi>Q</mml:mi><mml:mrow><mml:mi>B</mml:mi><mml:mo>:</mml:mo><mml:msub><mml:mi>t</mml:mi><mml:mn mathvariant="normal">0</mml:mn></mml:msub><mml:mo>→</mml:mo><mml:mi>t</mml:mi></mml:mrow></mml:msub></mml:mrow></mml:mtd></mml:mtr></mml:mtable></mml:mfenced><mml:mo>,</mml:mo></mml:mrow></mml:math></disp-formula>
          where <inline-formula><mml:math id="M145" display="inline"><mml:mrow><mml:msub><mml:mi>Q</mml:mi><mml:mrow><mml:mi>T</mml:mi><mml:mo>:</mml:mo><mml:msub><mml:mi>t</mml:mi><mml:mn mathvariant="normal">0</mml:mn></mml:msub><mml:mo>→</mml:mo><mml:mi>t</mml:mi></mml:mrow></mml:msub></mml:mrow></mml:math></inline-formula> and <inline-formula><mml:math id="M146" display="inline"><mml:mrow><mml:msub><mml:mi>Q</mml:mi><mml:mrow><mml:mi>B</mml:mi><mml:mo>:</mml:mo><mml:msub><mml:mi>t</mml:mi><mml:mn mathvariant="normal">0</mml:mn></mml:msub><mml:mo>→</mml:mo><mml:mi>t</mml:mi></mml:mrow></mml:msub></mml:mrow></mml:math></inline-formula> are the cumulative boundary fluxes at the current time, <inline-formula><mml:math id="M147" display="inline"><mml:mi>t</mml:mi></mml:math></inline-formula>, since the start of the
simulation, <inline-formula><mml:math id="M148" display="inline"><mml:mrow><mml:msub><mml:mi>t</mml:mi><mml:mn mathvariant="normal">0</mml:mn></mml:msub></mml:mrow></mml:math></inline-formula>. The ODE solver will integrate the equation
            <disp-formula id="Ch1.E20" content-type="numbered"><label>20</label><mml:math id="M149" display="block"><mml:mrow><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mrow><mml:mi mathvariant="normal">d</mml:mi><mml:mi mathvariant="bold-italic">F</mml:mi></mml:mrow><mml:mrow><mml:mi mathvariant="normal">d</mml:mi><mml:mi>t</mml:mi></mml:mrow></mml:mfrac></mml:mstyle><mml:mo>=</mml:mo><mml:mi>f</mml:mi><mml:mo>(</mml:mo><mml:mi mathvariant="bold-italic">F</mml:mi><mml:mo>,</mml:mo><mml:mi>t</mml:mi><mml:mo>,</mml:mo><mml:mi mathvariant="bold-italic">z</mml:mi><mml:mo>)</mml:mo></mml:mrow></mml:math></disp-formula>
          to solve for <inline-formula><mml:math id="M150" display="inline"><mml:mi mathvariant="bold-italic">F</mml:mi></mml:math></inline-formula>. The function that is called by the ODE solver will evaluate the vector
            <disp-formula id="Ch1.E21" content-type="numbered"><label>21</label><mml:math id="M151" display="block"><mml:mrow><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mrow><mml:mi mathvariant="normal">d</mml:mi><mml:mi mathvariant="bold-italic">F</mml:mi></mml:mrow><mml:mrow><mml:mi mathvariant="normal">d</mml:mi><mml:mi>t</mml:mi></mml:mrow></mml:mfrac></mml:mstyle><mml:mo>=</mml:mo><mml:mfenced close="]" open="["><mml:mtable class="matrix" columnalign="center" framespacing="0em"><mml:mtr><mml:mtd><mml:mfrac><mml:mrow><mml:mi mathvariant="normal">d</mml:mi><mml:msub><mml:mi>Q</mml:mi><mml:mrow><mml:mi>T</mml:mi><mml:mo>:</mml:mo><mml:msub><mml:mi>t</mml:mi><mml:mn mathvariant="normal">0</mml:mn></mml:msub><mml:mo>→</mml:mo><mml:msub><mml:mi>t</mml:mi><mml:mi>j</mml:mi></mml:msub></mml:mrow></mml:msub></mml:mrow><mml:mrow><mml:mi mathvariant="normal">d</mml:mi><mml:mi>t</mml:mi></mml:mrow></mml:mfrac></mml:mtd></mml:mtr><mml:mtr><mml:mtd><mml:mstyle displaystyle="false"><mml:mstyle displaystyle="false"><mml:mfrac style="text"><mml:mrow><mml:mi mathvariant="normal">d</mml:mi><mml:msub><mml:mi mathvariant="italic">ψ</mml:mi><mml:mn mathvariant="normal">0</mml:mn></mml:msub></mml:mrow><mml:mrow><mml:mi mathvariant="normal">d</mml:mi><mml:mi>t</mml:mi></mml:mrow></mml:mfrac></mml:mstyle></mml:mstyle></mml:mtd></mml:mtr><mml:mtr><mml:mtd><mml:mstyle displaystyle="false"><mml:mstyle displaystyle="false"><mml:mfrac style="text"><mml:mrow><mml:mi mathvariant="normal">d</mml:mi><mml:msub><mml:mi mathvariant="italic">ψ</mml:mi><mml:mn mathvariant="normal">1</mml:mn></mml:msub></mml:mrow><mml:mrow><mml:mi mathvariant="normal">d</mml:mi><mml:mi>t</mml:mi></mml:mrow></mml:mfrac></mml:mstyle></mml:mstyle></mml:mtd></mml:mtr><mml:mtr><mml:mtd><mml:mi mathvariant="normal">⋮</mml:mi></mml:mtd></mml:mtr><mml:mtr><mml:mtd><mml:mstyle displaystyle="false"><mml:mstyle displaystyle="false"><mml:mfrac style="text"><mml:mrow><mml:mi mathvariant="normal">d</mml:mi><mml:msub><mml:mi mathvariant="italic">ψ</mml:mi><mml:mrow><mml:mi>N</mml:mi><mml:mo>-</mml:mo><mml:mn mathvariant="normal">2</mml:mn></mml:mrow></mml:msub></mml:mrow><mml:mrow><mml:mi mathvariant="normal">d</mml:mi><mml:mi>t</mml:mi></mml:mrow></mml:mfrac></mml:mstyle></mml:mstyle></mml:mtd></mml:mtr><mml:mtr><mml:mtd><mml:mstyle displaystyle="false"><mml:mstyle displaystyle="false"><mml:mfrac style="text"><mml:mrow><mml:mi mathvariant="normal">d</mml:mi><mml:msub><mml:mi mathvariant="italic">ψ</mml:mi><mml:mrow><mml:mi>N</mml:mi><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msub></mml:mrow><mml:mrow><mml:mi mathvariant="normal">d</mml:mi><mml:mi>t</mml:mi></mml:mrow></mml:mfrac></mml:mstyle></mml:mstyle></mml:mtd></mml:mtr><mml:mtr><mml:mtd><mml:mstyle displaystyle="false"><mml:mstyle displaystyle="false"><mml:mfrac style="text"><mml:mrow><mml:mi mathvariant="normal">d</mml:mi><mml:msub><mml:mi>Q</mml:mi><mml:mrow><mml:mi>B</mml:mi><mml:mo>:</mml:mo><mml:msub><mml:mi>t</mml:mi><mml:mn mathvariant="normal">0</mml:mn></mml:msub><mml:mo>→</mml:mo><mml:msub><mml:mi>t</mml:mi><mml:mi>j</mml:mi></mml:msub></mml:mrow></mml:msub></mml:mrow><mml:mrow><mml:mi mathvariant="normal">d</mml:mi><mml:mi>t</mml:mi></mml:mrow></mml:mfrac></mml:mstyle></mml:mstyle></mml:mtd></mml:mtr></mml:mtable></mml:mfenced><mml:mo>=</mml:mo><mml:mfenced open="[" close="]"><mml:mtable class="matrix" columnalign="center" framespacing="0em"><mml:mtr><mml:mtd><mml:mrow><mml:msub><mml:mi>q</mml:mi><mml:mi mathvariant="normal">T</mml:mi></mml:msub></mml:mrow></mml:mtd></mml:mtr><mml:mtr><mml:mtd><mml:mrow><mml:mo>-</mml:mo><mml:mstyle displaystyle="false"><mml:mstyle displaystyle="false"><mml:mfrac style="text"><mml:mn mathvariant="normal">1</mml:mn><mml:mrow><mml:mi>C</mml:mi><mml:mo>(</mml:mo><mml:msub><mml:mi mathvariant="italic">ψ</mml:mi><mml:mn mathvariant="normal">0</mml:mn></mml:msub><mml:mo>)</mml:mo></mml:mrow></mml:mfrac></mml:mstyle></mml:mstyle><mml:msub><mml:mfenced close="|" open=""><mml:mstyle displaystyle="false"><mml:mstyle displaystyle="false"><mml:mfrac style="text"><mml:mrow><mml:mo>∂</mml:mo><mml:mi>q</mml:mi></mml:mrow><mml:mrow><mml:mo>∂</mml:mo><mml:mi>z</mml:mi></mml:mrow></mml:mfrac></mml:mstyle></mml:mstyle></mml:mfenced><mml:mn mathvariant="normal">0</mml:mn></mml:msub></mml:mrow></mml:mtd></mml:mtr><mml:mtr><mml:mtd><mml:mrow><mml:mo>-</mml:mo><mml:mstyle displaystyle="false"><mml:mstyle displaystyle="false"><mml:mfrac style="text"><mml:mn mathvariant="normal">1</mml:mn><mml:mrow><mml:mi>C</mml:mi><mml:mo>(</mml:mo><mml:msub><mml:mi mathvariant="italic">ψ</mml:mi><mml:mn mathvariant="normal">1</mml:mn></mml:msub><mml:mo>)</mml:mo></mml:mrow></mml:mfrac></mml:mstyle></mml:mstyle><mml:msub><mml:mfenced open="" close="|"><mml:mstyle displaystyle="false"><mml:mstyle displaystyle="false"><mml:mfrac style="text"><mml:mrow><mml:mo>∂</mml:mo><mml:mi>q</mml:mi></mml:mrow><mml:mrow><mml:mo>∂</mml:mo><mml:mi>z</mml:mi></mml:mrow></mml:mfrac></mml:mstyle></mml:mstyle></mml:mfenced><mml:mn mathvariant="normal">1</mml:mn></mml:msub></mml:mrow></mml:mtd></mml:mtr><mml:mtr><mml:mtd><mml:mi mathvariant="normal">⋮</mml:mi></mml:mtd></mml:mtr><mml:mtr><mml:mtd><mml:mrow><mml:mo>-</mml:mo><mml:mstyle displaystyle="false"><mml:mstyle displaystyle="false"><mml:mfrac style="text"><mml:mn mathvariant="normal">1</mml:mn><mml:mrow><mml:mi>C</mml:mi><mml:mo>(</mml:mo><mml:msub><mml:mi mathvariant="italic">ψ</mml:mi><mml:mrow><mml:mi>N</mml:mi><mml:mo>-</mml:mo><mml:mn mathvariant="normal">2</mml:mn></mml:mrow></mml:msub><mml:mo>)</mml:mo></mml:mrow></mml:mfrac></mml:mstyle></mml:mstyle><mml:msub><mml:mfenced close="|" open=""><mml:mstyle displaystyle="false"><mml:mstyle displaystyle="false"><mml:mfrac style="text"><mml:mrow><mml:mo>∂</mml:mo><mml:mi>q</mml:mi></mml:mrow><mml:mrow><mml:mo>∂</mml:mo><mml:mi>z</mml:mi></mml:mrow></mml:mfrac></mml:mstyle></mml:mstyle></mml:mfenced><mml:mrow><mml:mi>N</mml:mi><mml:mo>-</mml:mo><mml:mn mathvariant="normal">2</mml:mn></mml:mrow></mml:msub></mml:mrow></mml:mtd></mml:mtr><mml:mtr><mml:mtd><mml:mrow><mml:mo>-</mml:mo><mml:mstyle displaystyle="false"><mml:mstyle displaystyle="false"><mml:mfrac style="text"><mml:mn mathvariant="normal">1</mml:mn><mml:mrow><mml:mi>C</mml:mi><mml:mo>(</mml:mo><mml:msub><mml:mi mathvariant="italic">ψ</mml:mi><mml:mrow><mml:mi>N</mml:mi><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msub><mml:mo>)</mml:mo></mml:mrow></mml:mfrac></mml:mstyle></mml:mstyle><mml:msub><mml:mfenced open="" close="|"><mml:mstyle displaystyle="false"><mml:mstyle displaystyle="false"><mml:mfrac style="text"><mml:mrow><mml:mo>∂</mml:mo><mml:mi>q</mml:mi></mml:mrow><mml:mrow><mml:mo>∂</mml:mo><mml:mi>z</mml:mi></mml:mrow></mml:mfrac></mml:mstyle></mml:mstyle></mml:mfenced><mml:mrow><mml:mi>N</mml:mi><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msub></mml:mrow></mml:mtd></mml:mtr><mml:mtr><mml:mtd><mml:mrow><mml:msub><mml:mi>q</mml:mi><mml:mi mathvariant="normal">B</mml:mi></mml:msub></mml:mrow></mml:mtd></mml:mtr></mml:mtable></mml:mfenced><mml:mo>.</mml:mo></mml:mrow></mml:math></disp-formula></p>
      <p id="d1e3932">We note that each term in Eq. (21) is expressed at a single instant in time, <inline-formula><mml:math id="M152" display="inline"><mml:mi>t</mml:mi></mml:math></inline-formula>, and subscripts <inline-formula><mml:math id="M153" display="inline"><mml:mrow><mml:mn mathvariant="normal">0</mml:mn><mml:mo>,</mml:mo><mml:mn mathvariant="normal">1</mml:mn><mml:mo>,</mml:mo><mml:mi mathvariant="normal">…</mml:mi><mml:mo>,</mml:mo><mml:mi>N</mml:mi><mml:mo>-</mml:mo><mml:mn mathvariant="normal">2</mml:mn><mml:mo>,</mml:mo><mml:mi>N</mml:mi><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:math></inline-formula> refer to the indices of
the finite-difference discretization points, and we use zero-based indexing to be consistent with the Python language and Fig. 1. After solving
for <inline-formula><mml:math id="M154" display="inline"><mml:mi mathvariant="bold-italic">F</mml:mi></mml:math></inline-formula>, the first and last rows of <inline-formula><mml:math id="M155" display="inline"><mml:mi mathvariant="bold-italic">F</mml:mi></mml:math></inline-formula> correspond to the cumulative boundary fluxes, which at time <inline-formula><mml:math id="M156" display="inline"><mml:mi>t</mml:mi></mml:math></inline-formula> are <inline-formula><mml:math id="M157" display="inline"><mml:mrow><mml:msub><mml:mi>Q</mml:mi><mml:mrow><mml:mi>T</mml:mi><mml:mo>:</mml:mo><mml:msub><mml:mi>t</mml:mi><mml:mn mathvariant="normal">0</mml:mn></mml:msub><mml:mo>→</mml:mo><mml:mi>t</mml:mi></mml:mrow></mml:msub></mml:mrow></mml:math></inline-formula> and
<inline-formula><mml:math id="M158" display="inline"><mml:mrow><mml:msub><mml:mi>Q</mml:mi><mml:mrow><mml:mi>B</mml:mi><mml:mo>:</mml:mo><mml:msub><mml:mi>t</mml:mi><mml:mn mathvariant="normal">0</mml:mn></mml:msub><mml:mo>→</mml:mo><mml:mi>t</mml:mi></mml:mrow></mml:msub></mml:mrow></mml:math></inline-formula>. The cumulative fluxes over each time step are obtained from
            <disp-formula id="Ch1.E22" content-type="numbered"><label>22</label><mml:math id="M159" display="block"><mml:mtable class="split" rowspacing="0.2ex" displaystyle="true" columnalign="right left"><mml:mtr><mml:mtd/><mml:mtd><mml:mrow><mml:msub><mml:mi>Q</mml:mi><mml:mrow><mml:mi>T</mml:mi><mml:mo>:</mml:mo><mml:msub><mml:mi>t</mml:mi><mml:mi>j</mml:mi></mml:msub><mml:mo>→</mml:mo><mml:msub><mml:mi>t</mml:mi><mml:mrow><mml:mi>j</mml:mi><mml:mo>+</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msub></mml:mrow></mml:msub><mml:mo>=</mml:mo><mml:msub><mml:mi>Q</mml:mi><mml:mrow><mml:mi>T</mml:mi><mml:mo>:</mml:mo><mml:msub><mml:mi>t</mml:mi><mml:mn mathvariant="normal">0</mml:mn></mml:msub><mml:mo>→</mml:mo><mml:msub><mml:mi>t</mml:mi><mml:mrow><mml:mi>j</mml:mi><mml:mo>+</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msub></mml:mrow></mml:msub><mml:mo>-</mml:mo><mml:msub><mml:mi>Q</mml:mi><mml:mrow><mml:mi>T</mml:mi><mml:mo>:</mml:mo><mml:msub><mml:mi>t</mml:mi><mml:mn mathvariant="normal">0</mml:mn></mml:msub><mml:mo>→</mml:mo><mml:msub><mml:mi>t</mml:mi><mml:mi>j</mml:mi></mml:msub></mml:mrow></mml:msub></mml:mrow></mml:mtd></mml:mtr><mml:mtr><mml:mtd/><mml:mtd><mml:mrow><mml:msub><mml:mi>Q</mml:mi><mml:mrow><mml:mi>B</mml:mi><mml:mo>:</mml:mo><mml:msub><mml:mi>t</mml:mi><mml:mi>j</mml:mi></mml:msub><mml:mo>→</mml:mo><mml:msub><mml:mi>t</mml:mi><mml:mrow><mml:mi>j</mml:mi><mml:mo>+</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msub></mml:mrow></mml:msub><mml:mo>=</mml:mo><mml:msub><mml:mi>Q</mml:mi><mml:mrow><mml:mi>B</mml:mi><mml:mo>:</mml:mo><mml:msub><mml:mi>t</mml:mi><mml:mn mathvariant="normal">0</mml:mn></mml:msub><mml:mo>→</mml:mo><mml:msub><mml:mi>t</mml:mi><mml:mrow><mml:mi>j</mml:mi><mml:mo>+</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msub></mml:mrow></mml:msub><mml:mo>-</mml:mo><mml:msub><mml:mi>Q</mml:mi><mml:mrow><mml:mi>B</mml:mi><mml:mo>:</mml:mo><mml:msub><mml:mi>t</mml:mi><mml:mn mathvariant="normal">0</mml:mn></mml:msub><mml:mo>→</mml:mo><mml:msub><mml:mi>t</mml:mi><mml:mi>j</mml:mi></mml:msub></mml:mrow></mml:msub><mml:mo>.</mml:mo></mml:mrow></mml:mtd></mml:mtr></mml:mtable></mml:math></disp-formula></p>
      <p id="d1e4206">Solving systems of ODEs in this way is straightforward – requiring the user to pack and unpack the dependent variable vector. Python-based pseudo-code showing how this can be implemented is given in Box 2. Note that here we multiply the fluxes by 1000 within the solver (equivalent to converting the fluxes from <inline-formula><mml:math id="M160" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">m</mml:mi><mml:mspace linebreak="nobreak" width="0.125em"/><mml:msup><mml:mi mathvariant="normal">d</mml:mi><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msup></mml:mrow></mml:math></inline-formula> to <inline-formula><mml:math id="M161" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">mm</mml:mi><mml:mspace width="0.125em" linebreak="nobreak"/><mml:msup><mml:mi mathvariant="normal">d</mml:mi><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msup></mml:mrow></mml:math></inline-formula>), so that the magnitude of the fluxes is comparable with the magnitude of the changes in <inline-formula><mml:math id="M162" display="inline"><mml:mi mathvariant="italic">ψ</mml:mi></mml:math></inline-formula> (typically in <inline-formula><mml:math id="M163" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">m</mml:mi></mml:mrow></mml:math></inline-formula>),
which can improve the water balance estimate. Any arbitrary scaling factor can be applied here, as long as the output fluxes are re-scaled to the
correct units. We shall refer to this method for calculating the boundary fluxes as the <italic>solver flux output method</italic> (SFOM).</p>

      <?xmltex \floatpos{t}?><fig id="Ch1.F3" specific-use="star"><?xmltex \currentcnt{2}?><?xmltex \def\figurename{Box}?><label>Box 2</label><caption><p id="d1e4264">Python-based pseudo-code implementation of an ODE solver solution. The ODE function returns the time derivative of the dependent variable array, given in Eq. (21). Note that <inline-formula><mml:math id="M164" display="inline"><mml:mrow><mml:mi>F</mml:mi><mml:mo>[</mml:mo><mml:mo>:</mml:mo><mml:mo>,</mml:mo><mml:mn mathvariant="normal">1</mml:mn><mml:mo>:</mml:mo><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn><mml:mo>]</mml:mo></mml:mrow></mml:math></inline-formula> is a slice through the array <inline-formula><mml:math id="M165" display="inline"><mml:mi>F</mml:mi></mml:math></inline-formula> that takes all the items in the first (time) dimension and the second to second-to-last items in the second dimension.</p></caption>
          <?xmltex \igopts{width=341.433071pt}?><graphic xlink:href="https://gmd.copernicus.org/articles/16/659/2023/gmd-16-659-2023-b02.png"/>

        </fig>

</sec>
<sec id="Ch1.S2.SS4">
  <label>2.4</label><title>Improving efficiency</title>
      <p id="d1e4312">Here, we provide details of two techniques that can be used to improve the computational runtime of the model. These methods have no impact on the
accuracy of the solution, so they are optional, but combined they can result in better than a factor of 10 reduction in the runtime at the cost of only a
few additional lines of code. In Appendix A, we investigate the impact of a range of different possible model decisions/assumptions on the accuracy,
mass balance, efficiency, and simplicity of the model.</p>
<sec id="Ch1.S2.SS4.SSS1">
  <label>2.4.1</label><title>Defining the Jacobian pattern</title>
      <p id="d1e4322">For the form of RE given by Eq. (9), the Jacobian matrix, <inline-formula><mml:math id="M166" display="inline"><mml:mi mathvariant="bold">J</mml:mi></mml:math></inline-formula>, is an <inline-formula><mml:math id="M167" display="inline"><mml:mrow><mml:mi>n</mml:mi><mml:mo>×</mml:mo><mml:mi>n</mml:mi></mml:mrow></mml:math></inline-formula> matrix, where the cell in each row, <inline-formula><mml:math id="M168" display="inline"><mml:mi>i</mml:mi></mml:math></inline-formula>, and column, <inline-formula><mml:math id="M169" display="inline"><mml:mi>j</mml:mi></mml:math></inline-formula>,
is defined by the derivative
              <disp-formula id="Ch1.E23" content-type="numbered"><label>23</label><mml:math id="M170" display="block"><mml:mrow><mml:msub><mml:mi>J</mml:mi><mml:mrow><mml:mi>i</mml:mi><mml:mo>,</mml:mo><mml:mi>j</mml:mi></mml:mrow></mml:msub><mml:mo>=</mml:mo><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mi mathvariant="normal">d</mml:mi><mml:mrow><mml:mi mathvariant="normal">d</mml:mi><mml:msub><mml:mi mathvariant="italic">ψ</mml:mi><mml:mi>j</mml:mi></mml:msub></mml:mrow></mml:mfrac></mml:mstyle><mml:mfenced close=")" open="("><mml:mrow><mml:msub><mml:mfenced close="|" open=""><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mrow><mml:mi mathvariant="normal">d</mml:mi><mml:mi mathvariant="italic">ψ</mml:mi></mml:mrow><mml:mrow><mml:mi mathvariant="normal">d</mml:mi><mml:mi>t</mml:mi></mml:mrow></mml:mfrac></mml:mstyle></mml:mfenced><mml:mi>i</mml:mi></mml:msub></mml:mrow></mml:mfenced><mml:mo>=</mml:mo><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mi mathvariant="normal">d</mml:mi><mml:mrow><mml:mi mathvariant="normal">d</mml:mi><mml:msub><mml:mi mathvariant="italic">ψ</mml:mi><mml:mi>j</mml:mi></mml:msub></mml:mrow></mml:mfrac></mml:mstyle><mml:mfenced open="(" close=")"><mml:mrow><mml:mo>-</mml:mo><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mn mathvariant="normal">1</mml:mn><mml:mrow><mml:mi>C</mml:mi><mml:mo>(</mml:mo><mml:msub><mml:mi mathvariant="italic">ψ</mml:mi><mml:mi>i</mml:mi></mml:msub><mml:mo>)</mml:mo></mml:mrow></mml:mfrac></mml:mstyle><mml:msub><mml:mfenced close="|" open=""><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mrow><mml:mo>∂</mml:mo><mml:mi>q</mml:mi></mml:mrow><mml:mrow><mml:mo>∂</mml:mo><mml:mi>z</mml:mi></mml:mrow></mml:mfrac></mml:mstyle></mml:mfenced><mml:mi>i</mml:mi></mml:msub></mml:mrow></mml:mfenced><mml:mo>.</mml:mo></mml:mrow></mml:math></disp-formula></p>
      <p id="d1e4457">Each entry in <inline-formula><mml:math id="M171" display="inline"><mml:mrow><mml:msub><mml:mi>J</mml:mi><mml:mrow><mml:mi>i</mml:mi><mml:mo>,</mml:mo><mml:mi>j</mml:mi></mml:mrow></mml:msub></mml:mrow></mml:math></inline-formula> can be evaluated in a function that is passed to the ODE solver (assuming that the particular ODE solver being used
has this functionality), in order to speed up the solution process. For the spatial discretization scheme described above, all the terms of the
Jacobian are zero, except for where <inline-formula><mml:math id="M172" display="inline"><mml:mrow><mml:mi>j</mml:mi><mml:mo>=</mml:mo><mml:mi>i</mml:mi><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:math></inline-formula>, <inline-formula><mml:math id="M173" display="inline"><mml:mrow><mml:mi>j</mml:mi><mml:mo>=</mml:mo><mml:mi>i</mml:mi></mml:mrow></mml:math></inline-formula>, and <inline-formula><mml:math id="M174" display="inline"><mml:mrow><mml:mi>j</mml:mi><mml:mo>=</mml:mo><mml:mi>i</mml:mi><mml:mo>+</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:math></inline-formula> (ignoring when <inline-formula><mml:math id="M175" display="inline"><mml:mrow><mml:mi>i</mml:mi><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn><mml:mo>&lt;</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:math></inline-formula> and <inline-formula><mml:math id="M176" display="inline"><mml:mrow><mml:mi>i</mml:mi><mml:mo>+</mml:mo><mml:mn mathvariant="normal">1</mml:mn><mml:mo>&gt;</mml:mo><mml:mi>n</mml:mi></mml:mrow></mml:math></inline-formula>, which would be zero terms anyway, for any boundary
condition). A simpler alternative to defining the full Jacobian matrix is to define the Jacobian pattern. The Jacobian pattern is a matrix of
ones and zeros that defines the location of the structurally non-zero elements of the Jacobian – that is, where the terms are not identically
zero. For the spatially discretized RE as given in Eq. (9), the Jacobian pattern is a simple tridiagonal matrix, with ones on the three main
diagonals and zeros everywhere else. To implement this requires an ODE solver capable of using the Jacobian pattern (also referred to as the Jacobian
sparsity matrix). The SciPy ODE solvers <italic>ode</italic> and <italic>solve_ivp</italic> have the ability to define a banded Jacobian
pattern: setting <italic>uband</italic> and <italic>lband</italic> arguments to 1 tells the ODE solver that the Jacobian is a tridiagonal matrix. The SciPy
ODE solver <italic>solve_ivp</italic> can also handle a general <inline-formula><mml:math id="M177" display="inline"><mml:mrow><mml:mi>n</mml:mi><mml:mo>×</mml:mo><mml:mi>n</mml:mi></mml:mrow></mml:math></inline-formula> Jacobian pattern, which is more adaptable for multi-dependent
variable coupled problems (e.g., Goudarzi et al., 2016). The MATLAB ODE solvers can read the Jacobian sparsity pattern matrix from the JPattern
argument. We report on the relative performance/complexity of each of these methods in Sect. A4.</p>
</sec>
<sec id="Ch1.S2.SS4.SSS2">
  <label>2.4.2</label><title>Just-in-time compilation</title>
      <p id="d1e4589">In this paper, we are providing guidance for the use of interpreted programming languages (e.g., Python or MATLAB) to solve RE. Interpreted languages
have a number of advantages over compiled languages (such as FORTRAN, C, and C<inline-formula><mml:math id="M178" display="inline"><mml:mrow><mml:mo>+</mml:mo><mml:mo>+</mml:mo><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula>, including that they are, at least in our opinion, easier to
learn, with excellent teaching resources widely and freely available; they tend to have higher level abstractions, so that the same task can be
completed in fewer lines of code; and they are cross platform and typically easier to install. Interpreted languages are not pre-compiled and are
hence slower to execute than compiled languages. A nice compromise between the simplicity of interpreted languages and efficiency of compiled
languages is to use a just-in-time compiler. In Python, the Numba library is such a just-in-time compiler (Lam et al., 2015). Numba compiles
selected Python functions once at the start of the runtime, and then all subsequent calls to the code run much faster. We find that using
Numba  in conjunction with our preferred ODE solver solution described above, results in up to 10<inline-formula><mml:math id="M179" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> faster code execution (see
Sect. A5). The drawback to using Numba  is that some re-factoring of the code may be necessary to make a script that previously ran
without Numba  work using Numba – in particular, there are complications around how variables are allocated into NumPy
arrays. We include code in Ireson (2022, <uri>https://github.com/amireson/openRE</uri>, last access: 24 January 2023) that demonstrates how
to successfully implement Numba.</p>
</sec>
</sec>
</sec>
<sec id="Ch1.S3">
  <label>3</label><title>Benchmarking the model performance</title>
      <p id="d1e4624">In this section, we run our RE solver, openRE, on a number of benchmark problems, comparing the different solution procedures and assessing the
performance of all solutions against the five success criteria identified in the introduction, namely (i) accuracy of <inline-formula><mml:math id="M180" display="inline"><mml:mrow><mml:mi mathvariant="italic">θ</mml:mi><mml:mo>(</mml:mo><mml:mi>t</mml:mi><mml:mo>,</mml:mo><mml:mi>z</mml:mi><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula> and
<inline-formula><mml:math id="M181" display="inline"><mml:mrow><mml:mi mathvariant="italic">ψ</mml:mi><mml:mo>(</mml:mo><mml:mi>t</mml:mi><mml:mo>,</mml:mo><mml:mi>z</mml:mi><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula>, (ii) mass balance performance, (iii) consistent boundary fluxes with <inline-formula><mml:math id="M182" display="inline"><mml:mrow><mml:mi mathvariant="normal">Δ</mml:mi><mml:mi>t</mml:mi></mml:mrow></mml:math></inline-formula>, (iv) computational efficiency (i.e., runtime), and
(v) simplicity of the code. For the purposes of comparing efficiency (iv), all simulations were run on the same laptop computer, and we report the
runtimes as a measure of relative performance. For the purposes of comparing simplicity of the code (v) we use a very simple metric of lines of code,
which is reported above in Sect. 2.</p><?xmltex \hack{\newpage}?>
<sec id="Ch1.S3.SS1">
  <label>3.1</label><title>Published model benchmarks</title>
<sec id="Ch1.S3.SS1.SSS1">
  <label>3.1.1</label><title>Celia's problem</title>
      <p id="d1e4688">Celia's test case (Celia et al., 1990) is used to compare our ATS solution with the different solutions schemes previously proposed by Celia
et al. (1990). The test problem uses a 40 <inline-formula><mml:math id="M183" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">cm</mml:mi></mml:mrow></mml:math></inline-formula> deep vertical soil profile (<inline-formula><mml:math id="M184" display="inline"><mml:mrow><mml:msub><mml:mi>z</mml:mi><mml:mi>N</mml:mi></mml:msub><mml:mo>=</mml:mo><mml:mn mathvariant="normal">40</mml:mn></mml:mrow></mml:math></inline-formula>) with a uniform 1 <inline-formula><mml:math id="M185" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">cm</mml:mi></mml:mrow></mml:math></inline-formula> space step (<inline-formula><mml:math id="M186" display="inline"><mml:mrow><mml:mi mathvariant="normal">d</mml:mi><mml:mi>z</mml:mi><mml:mo>=</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:math></inline-formula>), a
360 <inline-formula><mml:math id="M187" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">s</mml:mi></mml:mrow></mml:math></inline-formula> duration (<inline-formula><mml:math id="M188" display="inline"><mml:mrow><mml:msub><mml:mi>t</mml:mi><mml:mn mathvariant="normal">0</mml:mn></mml:msub><mml:mo>=</mml:mo><mml:mn mathvariant="normal">0</mml:mn><mml:mo>;</mml:mo><mml:msub><mml:mi>t</mml:mi><mml:mi>M</mml:mi></mml:msub><mml:mo>=</mml:mo><mml:mn mathvariant="normal">360</mml:mn></mml:mrow></mml:math></inline-formula>) with a 1 <inline-formula><mml:math id="M189" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">s</mml:mi></mml:mrow></mml:math></inline-formula> time step (<inline-formula><mml:math id="M190" display="inline"><mml:mrow><mml:mi mathvariant="normal">Δ</mml:mi><mml:mi>t</mml:mi><mml:mo>=</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:math></inline-formula>), and the following initial and type-I boundary conditions:
              <disp-formula id="Ch1.E24" content-type="numbered"><label>24</label><mml:math id="M191" display="block"><mml:mtable class="split" rowspacing="0.2ex" displaystyle="true" columnalign="right left"><mml:mtr><mml:mtd/><mml:mtd><mml:mrow><mml:mi mathvariant="italic">ψ</mml:mi><mml:mo>(</mml:mo><mml:mi>t</mml:mi><mml:mo>=</mml:mo><mml:msub><mml:mi>t</mml:mi><mml:mn mathvariant="normal">0</mml:mn></mml:msub><mml:mo>,</mml:mo><mml:mn mathvariant="normal">0</mml:mn><mml:mo>≤</mml:mo><mml:mi>z</mml:mi><mml:mo>≤</mml:mo><mml:msub><mml:mi>z</mml:mi><mml:mi>N</mml:mi></mml:msub><mml:mo>)</mml:mo><mml:mo>=</mml:mo><mml:mo>-</mml:mo><mml:mn mathvariant="normal">61.5</mml:mn><mml:mspace width="0.125em" linebreak="nobreak"/><mml:mrow class="unit"><mml:mi mathvariant="normal">cm</mml:mi></mml:mrow></mml:mrow></mml:mtd></mml:mtr><mml:mtr><mml:mtd/><mml:mtd><mml:mrow><mml:mi mathvariant="italic">ψ</mml:mi><mml:mo>(</mml:mo><mml:msub><mml:mi>t</mml:mi><mml:mn mathvariant="normal">0</mml:mn></mml:msub><mml:mo>≤</mml:mo><mml:mi>t</mml:mi><mml:mo>≤</mml:mo><mml:msub><mml:mi>t</mml:mi><mml:mi>M</mml:mi></mml:msub><mml:mo>,</mml:mo><mml:mi>z</mml:mi><mml:mo>=</mml:mo><mml:mn mathvariant="normal">0</mml:mn><mml:mo>)</mml:mo><mml:mo>=</mml:mo><mml:mo>-</mml:mo><mml:mn mathvariant="normal">20.7</mml:mn><mml:mspace width="0.125em" linebreak="nobreak"/><mml:mrow class="unit"><mml:mi mathvariant="normal">cm</mml:mi></mml:mrow></mml:mrow></mml:mtd></mml:mtr><mml:mtr><mml:mtd/><mml:mtd><mml:mrow><mml:mi mathvariant="italic">ψ</mml:mi><mml:mo>(</mml:mo><mml:msub><mml:mi>t</mml:mi><mml:mn mathvariant="normal">0</mml:mn></mml:msub><mml:mo>≤</mml:mo><mml:mi>t</mml:mi><mml:mo>≤</mml:mo><mml:msub><mml:mi>t</mml:mi><mml:mi>M</mml:mi></mml:msub><mml:mo>,</mml:mo><mml:mi>z</mml:mi><mml:mo>=</mml:mo><mml:msub><mml:mi>z</mml:mi><mml:mi>N</mml:mi></mml:msub><mml:mo>)</mml:mo><mml:mo>=</mml:mo><mml:mo>-</mml:mo><mml:mn mathvariant="normal">61.5</mml:mn><mml:mspace linebreak="nobreak" width="0.125em"/><mml:mrow class="unit"><mml:mi mathvariant="normal">cm</mml:mi></mml:mrow><mml:mo>.</mml:mo></mml:mrow></mml:mtd></mml:mtr></mml:mtable></mml:math></disp-formula></p><?xmltex \setfigures?><?xmltex \floatpos{t}?><fig id="Ch1.F4" specific-use="star"><?xmltex \currentcnt{2}?><?xmltex \def\figurename{Figure}?><label>Figure 2</label><caption><p id="d1e4940">Reproduction of Celia's model benchmark: the <inline-formula><mml:math id="M192" display="inline"><mml:mi mathvariant="italic">ψ</mml:mi></mml:math></inline-formula> breakthrough curve using a backward difference implicit Euler solution with the no-iteration scheme, backward difference implicit Euler with Picard iteration, Celia's modified Picard iteration method (MPM), and the ODE solver with adaptive time stepping. The ODE solver produces consistent <inline-formula><mml:math id="M193" display="inline"><mml:mrow><mml:mi mathvariant="italic">ψ</mml:mi><mml:mo>(</mml:mo><mml:mi>t</mml:mi><mml:mi>z</mml:mi><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula> results independently of the mass balance calculation procedure. The time steps reported are calculation time steps for Celia's solutions but are reporting time steps for the ODE solver, which uses an adaptive time step for calculation steps.</p></caption>
            <?xmltex \igopts{width=455.244094pt}?><graphic xlink:href="https://gmd.copernicus.org/articles/16/659/2023/gmd-16-659-2023-f02.png"/>

          </fig>

      <p id="d1e4972">The soil hydraulic properties are given by
              <disp-formula id="Ch1.E25" content-type="numbered"><label>25</label><mml:math id="M194" display="block"><mml:mtable class="split" rowspacing="0.2ex" displaystyle="true" columnalign="right left"><mml:mtr><mml:mtd/><mml:mtd><mml:mrow><mml:mi mathvariant="italic">θ</mml:mi><mml:mo>=</mml:mo><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mrow><mml:mi mathvariant="italic">α</mml:mi><mml:mo>(</mml:mo><mml:msub><mml:mi mathvariant="italic">θ</mml:mi><mml:mi mathvariant="normal">s</mml:mi></mml:msub><mml:mo>-</mml:mo><mml:msub><mml:mi mathvariant="italic">θ</mml:mi><mml:mi mathvariant="normal">r</mml:mi></mml:msub><mml:mo>)</mml:mo></mml:mrow><mml:mrow><mml:mi mathvariant="italic">α</mml:mi><mml:mo>+</mml:mo><mml:msup><mml:mfenced open="|" close="|"><mml:mi mathvariant="italic">ψ</mml:mi></mml:mfenced><mml:mi mathvariant="italic">β</mml:mi></mml:msup></mml:mrow></mml:mfrac></mml:mstyle><mml:mo>+</mml:mo><mml:msub><mml:mi mathvariant="italic">θ</mml:mi><mml:mi mathvariant="normal">r</mml:mi></mml:msub></mml:mrow></mml:mtd></mml:mtr><mml:mtr><mml:mtd/><mml:mtd><mml:mrow><mml:mi>K</mml:mi><mml:mo>=</mml:mo><mml:msub><mml:mi>K</mml:mi><mml:mi mathvariant="normal">s</mml:mi></mml:msub><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mi>A</mml:mi><mml:mrow><mml:mi>A</mml:mi><mml:mo>+</mml:mo><mml:msup><mml:mfenced close="|" open="|"><mml:mi mathvariant="italic">ψ</mml:mi></mml:mfenced><mml:mi mathvariant="italic">γ</mml:mi></mml:msup></mml:mrow></mml:mfrac></mml:mstyle><mml:mo>,</mml:mo></mml:mrow></mml:mtd></mml:mtr></mml:mtable></mml:math></disp-formula>
            where the parameter values are <inline-formula><mml:math id="M195" display="inline"><mml:mi mathvariant="italic">α</mml:mi></mml:math></inline-formula> <inline-formula><mml:math id="M196" display="inline"><mml:mo>=</mml:mo></mml:math></inline-formula> 1.611 <inline-formula><mml:math id="M197" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M198" display="inline"><mml:msup><mml:mi/><mml:mn mathvariant="normal">6</mml:mn></mml:msup></mml:math></inline-formula>, <inline-formula><mml:math id="M199" display="inline"><mml:mrow><mml:msub><mml:mi mathvariant="italic">θ</mml:mi><mml:mi mathvariant="normal">s</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula> <inline-formula><mml:math id="M200" display="inline"><mml:mo>=</mml:mo></mml:math></inline-formula> 0.287, <inline-formula><mml:math id="M201" display="inline"><mml:mrow><mml:msub><mml:mi mathvariant="italic">θ</mml:mi><mml:mi mathvariant="normal">r</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula> <inline-formula><mml:math id="M202" display="inline"><mml:mo>=</mml:mo></mml:math></inline-formula> 0.075,
<inline-formula><mml:math id="M203" display="inline"><mml:mi mathvariant="italic">β</mml:mi></mml:math></inline-formula> <inline-formula><mml:math id="M204" display="inline"><mml:mo>=</mml:mo></mml:math></inline-formula> =3.96, <inline-formula><mml:math id="M205" display="inline"><mml:mrow><mml:msub><mml:mi>K</mml:mi><mml:mi mathvariant="normal">s</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula> <inline-formula><mml:math id="M206" display="inline"><mml:mo>=</mml:mo></mml:math></inline-formula> 00944 <inline-formula><mml:math id="M207" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">cm</mml:mi><mml:mspace linebreak="nobreak" width="0.125em"/><mml:msup><mml:mi mathvariant="normal">s</mml:mi><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msup></mml:mrow></mml:math></inline-formula>, <inline-formula><mml:math id="M208" display="inline"><mml:mi>A</mml:mi></mml:math></inline-formula> <inline-formula><mml:math id="M209" display="inline"><mml:mo>=</mml:mo></mml:math></inline-formula> 1.175 <inline-formula><mml:math id="M210" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M211" display="inline"><mml:msup><mml:mi/><mml:mn mathvariant="normal">6</mml:mn></mml:msup></mml:math></inline-formula>, and <inline-formula><mml:math id="M212" display="inline"><mml:mrow><mml:mi mathvariant="italic">γ</mml:mi><mml:mo>=</mml:mo><mml:mn mathvariant="normal">4.74</mml:mn></mml:mrow></mml:math></inline-formula>. Celia et al. (1990) presented three solution
schemes: the “no-iteration scheme” uses the <inline-formula><mml:math id="M213" display="inline"><mml:mi mathvariant="italic">ψ</mml:mi></mml:math></inline-formula> form of RE and solves the problem with a single backward implicit step and no iteration (which
we achieved using the Thomas algorithm), the “Picard iteration scheme” also solves the <inline-formula><mml:math id="M214" display="inline"><mml:mi mathvariant="italic">ψ</mml:mi></mml:math></inline-formula> form of RE but uses the Picard iteration method to
improve the solution, with errors in <inline-formula><mml:math id="M215" display="inline"><mml:mi mathvariant="italic">ψ</mml:mi></mml:math></inline-formula> used as a convergence criterion, and finally the “modified Picard iteration method” (MPM) uses the
mixed-form of RE and uses errors in <inline-formula><mml:math id="M216" display="inline"><mml:mi mathvariant="italic">θ</mml:mi></mml:math></inline-formula> as a convergence criterion. The MPM is mass conservative because the iteration ensures that the
cumulative change in fluxes (the right-hand side of RE) balances the changes in storage (the left-hand side of the mixed form of RE). Celia's three
solutions were reproduced in Python scripts (<uri>https://github.com/amireson/openRE</uri>, last access: 24 January 2023) and compared with our ATS/SFOM solution. Results from all three solutions are shown in Fig. 2. All methods are consistent for very small time steps. The fixed-step
method with no iteration performs poorly, with delayed breakthrough of the wetting front when the time step is large. The solution is improved by
using the Picard iteration, but there are still some delays. The MPM has a much better performance but, as with all implicit Euler time-stepping schemes,
is still subject to some numerical dispersion for larger time steps (van Genuchten and Gray, 1978). The
ATS solution reproduces the <inline-formula><mml:math id="M217" display="inline"><mml:mi mathvariant="italic">ψ</mml:mi></mml:math></inline-formula> breakthrough curve but with no dispersion and no differences associated with the time step. We note that the time
steps for plotting the ATS solution only represent the reporting time step – the underlying calculation time steps are likely much
smaller (Sect. 2.2).</p>

      <?xmltex \floatpos{t}?><fig id="Ch1.F5" specific-use="star"><?xmltex \currentcnt{3}?><?xmltex \def\figurename{Figure}?><label>Figure 3</label><caption><p id="d1e5260">Mass balance of Celia's three models and our adaptive time-stepping model. Panel <bold>(a)</bold> shows a reproduction of Celia's mass balance calculation. Panel <bold>(b)</bold> shows the cumulative inflow that is simulated.</p></caption>
            <?xmltex \igopts{width=284.527559pt}?><graphic xlink:href="https://gmd.copernicus.org/articles/16/659/2023/gmd-16-659-2023-f03.png"/>

          </fig>

      <p id="d1e5275">In Fig. 3, we show the cumulative inflow simulated by each of these models for Celia's benchmark problem, along with the mass balance bias error, for
different reporting time steps. The fixed-step solution with no iteration and the Picard iteration solution both have poor mass balance performance
unless the time step is very small – on this basis, we do not consider these solutions further. We see that the MPM method is perfectly mass
conservative for any <inline-formula><mml:math id="M218" display="inline"><mml:mrow><mml:mi mathvariant="normal">Δ</mml:mi><mml:mi>t</mml:mi></mml:mrow></mml:math></inline-formula> used in the model, as we should expect. However, we can see that the cumulative inflow is sensitive
to <inline-formula><mml:math id="M219" display="inline"><mml:mrow><mml:mi mathvariant="normal">Δ</mml:mi><mml:mi>t</mml:mi></mml:mrow></mml:math></inline-formula>. Hence, even though for larger <inline-formula><mml:math id="M220" display="inline"><mml:mrow><mml:mi mathvariant="normal">Δ</mml:mi><mml:mi>t</mml:mi></mml:mrow></mml:math></inline-formula> the water balance is still perfectly closed, the actual terms within the water balance have
changed, so there is less inflow and less change in storage. This is perhaps an underappreciated limitation of Celia's MPM solution and solutions to
the mixed form of RE generally – which is that mass balance is a necessary but insufficient criterion for model performance assessment, and
truncation errors can still be present in the fluxes even with perfect water balance closure.</p>
      <p id="d1e5308">In Fig. 3, we also show the water balance performance of our ATS solution, using either reporting-time-step information for the water balance
calculation or using calculation-time-step information (i.e., using the SFOM described in Sect. 2.3). Using reporting-time-step information is the
easiest and most intuitive approach to take – you numerically integrate (1) discrete <inline-formula><mml:math id="M221" display="inline"><mml:mi mathvariant="italic">θ</mml:mi></mml:math></inline-formula> values over depth to get storage and (2) discrete
<inline-formula><mml:math id="M222" display="inline"><mml:mi>q</mml:mi></mml:math></inline-formula> values during reporting time steps to get <inline-formula><mml:math id="M223" display="inline"><mml:mi>Q</mml:mi></mml:math></inline-formula> (e.g., using trapezoidal integration). However, this approach fails to capture non-linear changes
in <inline-formula><mml:math id="M224" display="inline"><mml:mi>q</mml:mi></mml:math></inline-formula> over a reporting time step and results in large water balance errors and errors in the cumulative fluxes, as is clear in Fig. 3. Using the SFOM,
we see that the water balance is almost exactly closed, and the boundary fluxes are independent of the reporting time step. It is also important to
note that the discrete <inline-formula><mml:math id="M225" display="inline"><mml:mrow><mml:mi mathvariant="italic">ψ</mml:mi><mml:mo>(</mml:mo><mml:mi>t</mml:mi><mml:mi>z</mml:mi><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula> values simulated by both ATS solution procedures here are identical (see Fig. 2) – the only difference is how the
boundary fluxes are calculated.</p>
</sec>
<sec id="Ch1.S3.SS1.SSS2">
  <label>3.1.2</label><title>Miller's saturated infiltration pulse problem</title>
      <p id="d1e5363">Miller et al. (1998) investigated solutions to RE that aimed to address numerical convergence problems associated with challenging boundary
conditions, and they specifically looked at the problem of infiltration from a ponded upper boundary into a hydrostatic soil profile with a fixed
water table at the lower boundary. This is a good benchmark because it requires the model to deal with perched saturated conditions over unsaturated
conditions and involves highly non-linear changes in properties over short distances and time steps. The problem uses van Genuchten (1980) hydraulic
properties, given by

                  <disp-formula specific-use="gather" content-type="numbered"><mml:math id="M226" display="block"><mml:mtable displaystyle="true"><mml:mlabeledtr id="Ch1.E26"><mml:mtd><mml:mtext>26</mml:mtext></mml:mtd><mml:mtd><mml:mrow><mml:mstyle class="stylechange" displaystyle="true"/><mml:msub><mml:mi>S</mml:mi><mml:mi mathvariant="normal">e</mml:mi></mml:msub><mml:mo>=</mml:mo><mml:mo>(</mml:mo><mml:mn mathvariant="normal">1</mml:mn><mml:mo>+</mml:mo><mml:mo>(</mml:mo><mml:mi mathvariant="italic">α</mml:mi><mml:mi mathvariant="italic">ψ</mml:mi><mml:msup><mml:mo>)</mml:mo><mml:mi>n</mml:mi></mml:msup><mml:msup><mml:mo>)</mml:mo><mml:mrow><mml:mo>-</mml:mo><mml:mi>m</mml:mi></mml:mrow></mml:msup><mml:mo>,</mml:mo></mml:mrow></mml:mtd></mml:mlabeledtr><mml:mlabeledtr id="Ch1.E27"><mml:mtd><mml:mtext>27</mml:mtext></mml:mtd><mml:mtd><mml:mrow><mml:mstyle class="stylechange" displaystyle="true"/><mml:mi mathvariant="italic">θ</mml:mi><mml:mo>=</mml:mo><mml:msub><mml:mi mathvariant="italic">θ</mml:mi><mml:mi mathvariant="normal">r</mml:mi></mml:msub><mml:mo>+</mml:mo><mml:mo>(</mml:mo><mml:msub><mml:mi mathvariant="italic">θ</mml:mi><mml:mi mathvariant="normal">s</mml:mi></mml:msub><mml:mo>-</mml:mo><mml:msub><mml:mi mathvariant="italic">θ</mml:mi><mml:mi mathvariant="normal">r</mml:mi></mml:msub><mml:mo>)</mml:mo><mml:msub><mml:mi>S</mml:mi><mml:mi mathvariant="normal">e</mml:mi></mml:msub><mml:mo>,</mml:mo></mml:mrow></mml:mtd></mml:mlabeledtr><mml:mlabeledtr id="Ch1.E28"><mml:mtd><mml:mtext>28</mml:mtext></mml:mtd><mml:mtd><mml:mrow><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mrow><mml:mi mathvariant="normal">d</mml:mi><mml:mi mathvariant="italic">θ</mml:mi></mml:mrow><mml:mrow><mml:mi mathvariant="normal">d</mml:mi><mml:mi mathvariant="italic">ψ</mml:mi></mml:mrow></mml:mfrac></mml:mstyle><mml:mo>=</mml:mo><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mrow><mml:mo>-</mml:mo><mml:mi mathvariant="italic">α</mml:mi><mml:mi>m</mml:mi><mml:mo>(</mml:mo><mml:msub><mml:mi mathvariant="italic">θ</mml:mi><mml:mi mathvariant="normal">s</mml:mi></mml:msub><mml:mo>-</mml:mo><mml:msub><mml:mi mathvariant="italic">θ</mml:mi><mml:mi mathvariant="normal">r</mml:mi></mml:msub><mml:mo>)</mml:mo></mml:mrow><mml:mrow><mml:mn mathvariant="normal">1</mml:mn><mml:mo>-</mml:mo><mml:mi>m</mml:mi></mml:mrow></mml:mfrac></mml:mstyle><mml:msubsup><mml:mi>S</mml:mi><mml:mi mathvariant="normal">e</mml:mi><mml:mrow><mml:mn mathvariant="normal">1</mml:mn><mml:mo>/</mml:mo><mml:mi>m</mml:mi></mml:mrow></mml:msubsup><mml:mo>(</mml:mo><mml:mn mathvariant="normal">1</mml:mn><mml:mo>-</mml:mo><mml:msubsup><mml:mi>S</mml:mi><mml:mi mathvariant="normal">e</mml:mi><mml:mrow><mml:mn mathvariant="normal">1</mml:mn><mml:mo>/</mml:mo><mml:mi>m</mml:mi></mml:mrow></mml:msubsup><mml:msup><mml:mo>)</mml:mo><mml:mi>m</mml:mi></mml:msup><mml:mo>,</mml:mo></mml:mrow></mml:mtd></mml:mlabeledtr><mml:mlabeledtr id="Ch1.E29"><mml:mtd><mml:mtext>29</mml:mtext></mml:mtd><mml:mtd><mml:mrow><mml:mstyle class="stylechange" displaystyle="true"/><mml:mi>K</mml:mi><mml:mo>=</mml:mo><mml:msub><mml:mi>K</mml:mi><mml:mi mathvariant="normal">s</mml:mi></mml:msub><mml:msubsup><mml:mi>S</mml:mi><mml:mi mathvariant="normal">e</mml:mi><mml:mrow><mml:mn mathvariant="normal">1</mml:mn><mml:mo>/</mml:mo><mml:mn mathvariant="normal">2</mml:mn></mml:mrow></mml:msubsup><mml:mo>(</mml:mo><mml:mn mathvariant="normal">1</mml:mn><mml:mo>-</mml:mo><mml:mo>(</mml:mo><mml:mn mathvariant="normal">1</mml:mn><mml:mo>-</mml:mo><mml:msubsup><mml:mi>S</mml:mi><mml:mi mathvariant="normal">e</mml:mi><mml:mrow><mml:mn mathvariant="normal">1</mml:mn><mml:mo>/</mml:mo><mml:mi>m</mml:mi></mml:mrow></mml:msubsup><mml:msup><mml:mo>)</mml:mo><mml:mi>m</mml:mi></mml:msup><mml:mo>)</mml:mo><mml:mo>,</mml:mo></mml:mrow></mml:mtd></mml:mlabeledtr></mml:mtable></mml:math></disp-formula>

              where <inline-formula><mml:math id="M227" display="inline"><mml:mrow><mml:msub><mml:mi>S</mml:mi><mml:mi mathvariant="normal">e</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula> (–) is the effective saturation; <inline-formula><mml:math id="M228" display="inline"><mml:mi mathvariant="italic">α</mml:mi></mml:math></inline-formula> (<inline-formula><mml:math id="M229" display="inline"><mml:mrow class="unit"><mml:msup><mml:mi mathvariant="normal">L</mml:mi><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msup></mml:mrow></mml:math></inline-formula>), <inline-formula><mml:math id="M230" display="inline"><mml:mi>n</mml:mi></mml:math></inline-formula> (–), and <inline-formula><mml:math id="M231" display="inline"><mml:mi>m</mml:mi></mml:math></inline-formula> (–) are parameters that determine the shape of the
<inline-formula><mml:math id="M232" display="inline"><mml:mrow><mml:mi mathvariant="italic">θ</mml:mi><mml:mo>(</mml:mo><mml:mi mathvariant="italic">ψ</mml:mi><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula> curve; <inline-formula><mml:math id="M233" display="inline"><mml:mrow><mml:msub><mml:mi mathvariant="italic">θ</mml:mi><mml:mi mathvariant="normal">r</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula> (–) and <inline-formula><mml:math id="M234" display="inline"><mml:mrow><mml:msub><mml:mi mathvariant="italic">θ</mml:mi><mml:mi mathvariant="normal">s</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula> (–) are the residual and saturated volumetric water contents; and
<inline-formula><mml:math id="M235" display="inline"><mml:mrow><mml:msub><mml:mi>K</mml:mi><mml:mi mathvariant="normal">s</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula> (<inline-formula><mml:math id="M236" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">L</mml:mi><mml:mspace linebreak="nobreak" width="0.125em"/><mml:msup><mml:mi mathvariant="normal">T</mml:mi><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msup></mml:mrow></mml:math></inline-formula>) is the saturated hydraulic conductivity. Miller's problem uses the parameters in Table 1 for three different soil
types.</p>

<?xmltex \floatpos{t}?><table-wrap id="Ch1.T1"><?xmltex \currentcnt{1}?><label>Table 1</label><caption><p id="d1e5721">Soil hydraulic properties used the Miller et al. (1998) problem.</p></caption><oasis:table frame="topbot"><oasis:tgroup cols="4">
     <oasis:colspec colnum="1" colname="col1" align="left"/>
     <oasis:colspec colnum="2" colname="col2" align="right"/>
     <oasis:colspec colnum="3" colname="col3" align="right"/>
     <oasis:colspec colnum="4" colname="col4" align="right"/>
     <oasis:thead>
       <oasis:row rowsep="1">
         <oasis:entry colname="col1">Parameter</oasis:entry>
         <oasis:entry colname="col2">Sand</oasis:entry>
         <oasis:entry colname="col3">Loam</oasis:entry>
         <oasis:entry colname="col4">Clay loam</oasis:entry>
       </oasis:row>
     </oasis:thead>
     <oasis:tbody>
       <oasis:row>
         <oasis:entry colname="col1"><inline-formula><mml:math id="M237" display="inline"><mml:mrow><mml:msub><mml:mi mathvariant="italic">θ</mml:mi><mml:mi mathvariant="normal">r</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula></oasis:entry>
         <oasis:entry colname="col2">0.093</oasis:entry>
         <oasis:entry colname="col3">0.078</oasis:entry>
         <oasis:entry colname="col4">0.095</oasis:entry>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1"><inline-formula><mml:math id="M238" display="inline"><mml:mrow><mml:msub><mml:mi mathvariant="italic">θ</mml:mi><mml:mi mathvariant="normal">s</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula></oasis:entry>
         <oasis:entry colname="col2">0.301</oasis:entry>
         <oasis:entry colname="col3">0.430</oasis:entry>
         <oasis:entry colname="col4">0.410</oasis:entry>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1"><inline-formula><mml:math id="M239" display="inline"><mml:mi mathvariant="italic">α</mml:mi></mml:math></inline-formula></oasis:entry>
         <oasis:entry colname="col2">5.470</oasis:entry>
         <oasis:entry colname="col3">3.600</oasis:entry>
         <oasis:entry colname="col4">1.900</oasis:entry>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1"><inline-formula><mml:math id="M240" display="inline"><mml:mi>n</mml:mi></mml:math></inline-formula></oasis:entry>
         <oasis:entry colname="col2">4.264</oasis:entry>
         <oasis:entry colname="col3">1.560</oasis:entry>
         <oasis:entry colname="col4">1.310</oasis:entry>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1"><inline-formula><mml:math id="M241" display="inline"><mml:mrow><mml:msub><mml:mi>K</mml:mi><mml:mi mathvariant="normal">s</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula> (<inline-formula><mml:math id="M242" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">m</mml:mi><mml:mspace linebreak="nobreak" width="0.125em"/><mml:msup><mml:mi mathvariant="normal">d</mml:mi><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msup></mml:mrow></mml:math></inline-formula>)</oasis:entry>
         <oasis:entry colname="col2">5.040</oasis:entry>
         <oasis:entry colname="col3">0.250</oasis:entry>
         <oasis:entry colname="col4">0.062</oasis:entry>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1"><inline-formula><mml:math id="M243" display="inline"><mml:mrow><mml:msub><mml:mi>S</mml:mi><mml:mi mathvariant="normal">S</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula></oasis:entry>
         <oasis:entry colname="col2">10<inline-formula><mml:math id="M244" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">6</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
         <oasis:entry colname="col3">10<inline-formula><mml:math id="M245" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">6</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
         <oasis:entry colname="col4">10<inline-formula><mml:math id="M246" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">6</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
       </oasis:row>
     </oasis:tbody>
   </oasis:tgroup></oasis:table></table-wrap>

<?xmltex \floatpos{t}?><table-wrap id="Ch1.T2" specific-use="star"><?xmltex \currentcnt{2}?><label>Table 2</label><caption><p id="d1e5950">Runtime and water balance performance for the Celia MPM and ATS SFOM solutions, applied to the problem in Miller et al. (1998). We also show here the solver settings. For the ATS solutions, we had to reduce the relative and absolute tolerances (<inline-formula><mml:math id="M247" display="inline"><mml:mrow class="chem"><mml:mi mathvariant="normal">atol</mml:mi></mml:mrow></mml:math></inline-formula>/<inline-formula><mml:math id="M248" display="inline"><mml:mrow class="chem"><mml:mi mathvariant="normal">rtol</mml:mi></mml:mrow></mml:math></inline-formula>) of the integrator from the default settings and increase the maximum number of calculations steps allowed within a reporting step (nsteps). Note that time steps (<inline-formula><mml:math id="M249" display="inline"><mml:mrow><mml:mtext>d</mml:mtext><mml:mi>t</mml:mi></mml:mrow></mml:math></inline-formula>) in ATS solutions are reporting time steps.</p></caption><oasis:table frame="topbot"><oasis:tgroup cols="6">
     <oasis:colspec colnum="1" colname="col1" align="left"/>
     <oasis:colspec colnum="2" colname="col2" align="left"/>
     <oasis:colspec colnum="3" colname="col3" align="left"/>
     <oasis:colspec colnum="4" colname="col4" align="right"/>
     <oasis:colspec colnum="5" colname="col5" align="right"/>
     <oasis:colspec colnum="6" colname="col6" align="right"/>
     <oasis:thead>
       <oasis:row rowsep="1">
         <oasis:entry colname="col1">Solution</oasis:entry>
         <oasis:entry colname="col2">Soil</oasis:entry>
         <oasis:entry colname="col3">Solver settings</oasis:entry>
         <oasis:entry colname="col4">Runtime (<inline-formula><mml:math id="M250" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">s</mml:mi></mml:mrow></mml:math></inline-formula>)</oasis:entry>
         <oasis:entry colname="col5">MB bias (<inline-formula><mml:math id="M251" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">mm</mml:mi></mml:mrow></mml:math></inline-formula>)</oasis:entry>
         <oasis:entry colname="col6">MB RMSE (<inline-formula><mml:math id="M252" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">mm</mml:mi></mml:mrow></mml:math></inline-formula>)</oasis:entry>
       </oasis:row>
     </oasis:thead>
     <oasis:tbody>
       <oasis:row>
         <oasis:entry colname="col1">Celia MPM</oasis:entry>
         <oasis:entry colname="col2">Sand</oasis:entry>
         <oasis:entry colname="col3"><inline-formula><mml:math id="M253" display="inline"><mml:mrow><mml:mtext>d</mml:mtext><mml:mi>t</mml:mi></mml:mrow></mml:math></inline-formula> <inline-formula><mml:math id="M254" display="inline"><mml:mo>=</mml:mo></mml:math></inline-formula> 0.001 <inline-formula><mml:math id="M255" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">d</mml:mi></mml:mrow></mml:math></inline-formula></oasis:entry>
         <oasis:entry colname="col4">4.4</oasis:entry>
         <oasis:entry colname="col5"><inline-formula><mml:math id="M256" display="inline"><mml:mo>-</mml:mo></mml:math></inline-formula>4.2 <inline-formula><mml:math id="M257" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M258" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">6</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
         <oasis:entry colname="col6">4.5 <inline-formula><mml:math id="M259" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M260" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">6</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1"/>
         <oasis:entry colname="col2">Loam</oasis:entry>
         <oasis:entry colname="col3"><inline-formula><mml:math id="M261" display="inline"><mml:mrow><mml:mtext>d</mml:mtext><mml:mi>t</mml:mi></mml:mrow></mml:math></inline-formula> <inline-formula><mml:math id="M262" display="inline"><mml:mo>=</mml:mo></mml:math></inline-formula> 0.001 <inline-formula><mml:math id="M263" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">d</mml:mi></mml:mrow></mml:math></inline-formula></oasis:entry>
         <oasis:entry colname="col4">31.7</oasis:entry>
         <oasis:entry colname="col5"><inline-formula><mml:math id="M264" display="inline"><mml:mo>-</mml:mo></mml:math></inline-formula>1.6 <inline-formula><mml:math id="M265" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M266" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">3</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
         <oasis:entry colname="col6">5.3 <inline-formula><mml:math id="M267" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M268" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">6</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
       </oasis:row>
       <oasis:row rowsep="1">
         <oasis:entry colname="col1"/>
         <oasis:entry colname="col2">Clay loam</oasis:entry>
         <oasis:entry colname="col3"><inline-formula><mml:math id="M269" display="inline"><mml:mrow><mml:mtext>d</mml:mtext><mml:mi>t</mml:mi></mml:mrow></mml:math></inline-formula> <inline-formula><mml:math id="M270" display="inline"><mml:mo>=</mml:mo></mml:math></inline-formula> 0.001 <inline-formula><mml:math id="M271" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">d</mml:mi></mml:mrow></mml:math></inline-formula></oasis:entry>
         <oasis:entry colname="col4">32.6</oasis:entry>
         <oasis:entry colname="col5"><inline-formula><mml:math id="M272" display="inline"><mml:mo>-</mml:mo></mml:math></inline-formula>8.0 <inline-formula><mml:math id="M273" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M274" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">2</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
         <oasis:entry colname="col6">2.5 <inline-formula><mml:math id="M275" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M276" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">4</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1">ATS SFOM</oasis:entry>
         <oasis:entry colname="col2">Sand</oasis:entry>
         <oasis:entry colname="col3"><inline-formula><mml:math id="M277" display="inline"><mml:mrow class="chem"><mml:mi mathvariant="normal">atol</mml:mi></mml:mrow></mml:math></inline-formula>/<inline-formula><mml:math id="M278" display="inline"><mml:mrow class="chem"><mml:mi mathvariant="normal">rtol</mml:mi></mml:mrow></mml:math></inline-formula> <inline-formula><mml:math id="M279" display="inline"><mml:mo>=</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M280" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">6</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
         <oasis:entry colname="col4">11.7</oasis:entry>
         <oasis:entry colname="col5"><inline-formula><mml:math id="M281" display="inline"><mml:mo>-</mml:mo></mml:math></inline-formula>1.5 <inline-formula><mml:math id="M282" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M283" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">2</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
         <oasis:entry colname="col6">8.8 <inline-formula><mml:math id="M284" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M285" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">4</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1"/>
         <oasis:entry colname="col2"/>
         <oasis:entry colname="col3">nsteps <inline-formula><mml:math id="M286" display="inline"><mml:mo>=</mml:mo></mml:math></inline-formula> 10 000</oasis:entry>
         <oasis:entry colname="col4"/>
         <oasis:entry colname="col5"/>
         <oasis:entry colname="col6"/>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1"/>
         <oasis:entry rowsep="1" colname="col2"/>
         <oasis:entry rowsep="1" colname="col3"><inline-formula><mml:math id="M287" display="inline"><mml:mrow><mml:mtext>d</mml:mtext><mml:mi>t</mml:mi></mml:mrow></mml:math></inline-formula> <inline-formula><mml:math id="M288" display="inline"><mml:mo>=</mml:mo></mml:math></inline-formula> 0.01</oasis:entry>
         <oasis:entry rowsep="1" colname="col4"/>
         <oasis:entry rowsep="1" colname="col5"/>
         <oasis:entry rowsep="1" colname="col6"/>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1"/>
         <oasis:entry colname="col2">Loam</oasis:entry>
         <oasis:entry colname="col3"><inline-formula><mml:math id="M289" display="inline"><mml:mrow class="chem"><mml:mi mathvariant="normal">atol</mml:mi></mml:mrow></mml:math></inline-formula>/<inline-formula><mml:math id="M290" display="inline"><mml:mrow class="chem"><mml:mi mathvariant="normal">rtol</mml:mi></mml:mrow></mml:math></inline-formula> <inline-formula><mml:math id="M291" display="inline"><mml:mo>=</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M292" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">6</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
         <oasis:entry colname="col4">16.7</oasis:entry>
         <oasis:entry colname="col5"><inline-formula><mml:math id="M293" display="inline"><mml:mo>-</mml:mo></mml:math></inline-formula>8.8 <inline-formula><mml:math id="M294" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M295" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">2</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
         <oasis:entry colname="col6">2.0 <inline-formula><mml:math id="M296" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M297" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">3</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1"/>
         <oasis:entry colname="col2"/>
         <oasis:entry colname="col3">nsteps <inline-formula><mml:math id="M298" display="inline"><mml:mo>=</mml:mo></mml:math></inline-formula> 10 000</oasis:entry>
         <oasis:entry colname="col4"/>
         <oasis:entry colname="col5"/>
         <oasis:entry colname="col6"/>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1"/>
         <oasis:entry rowsep="1" colname="col2"/>
         <oasis:entry rowsep="1" colname="col3"><inline-formula><mml:math id="M299" display="inline"><mml:mrow><mml:mtext>d</mml:mtext><mml:mi>t</mml:mi></mml:mrow></mml:math></inline-formula> <inline-formula><mml:math id="M300" display="inline"><mml:mo>=</mml:mo></mml:math></inline-formula> 0.01</oasis:entry>
         <oasis:entry rowsep="1" colname="col4"/>
         <oasis:entry rowsep="1" colname="col5"/>
         <oasis:entry rowsep="1" colname="col6"/>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1"/>
         <oasis:entry colname="col2">Clay loam</oasis:entry>
         <oasis:entry colname="col3"><inline-formula><mml:math id="M301" display="inline"><mml:mrow class="chem"><mml:mi mathvariant="normal">atol</mml:mi></mml:mrow></mml:math></inline-formula>/<inline-formula><mml:math id="M302" display="inline"><mml:mrow class="chem"><mml:mi mathvariant="normal">rtol</mml:mi></mml:mrow></mml:math></inline-formula> <inline-formula><mml:math id="M303" display="inline"><mml:mo>=</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M304" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">5</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
         <oasis:entry colname="col4">30.8</oasis:entry>
         <oasis:entry colname="col5"><inline-formula><mml:math id="M305" display="inline"><mml:mo>-</mml:mo></mml:math></inline-formula>3.2 <inline-formula><mml:math id="M306" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M307" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
         <oasis:entry colname="col6">1.3 <inline-formula><mml:math id="M308" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M309" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">3</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1"/>
         <oasis:entry colname="col2"/>
         <oasis:entry colname="col3">nsteps <inline-formula><mml:math id="M310" display="inline"><mml:mo>=</mml:mo></mml:math></inline-formula> 10 000</oasis:entry>
         <oasis:entry colname="col4"/>
         <oasis:entry colname="col5"/>
         <oasis:entry colname="col6"/>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1"/>
         <oasis:entry colname="col2"/>
         <oasis:entry colname="col3"><inline-formula><mml:math id="M311" display="inline"><mml:mrow><mml:mtext>d</mml:mtext><mml:mi>t</mml:mi></mml:mrow></mml:math></inline-formula> <inline-formula><mml:math id="M312" display="inline"><mml:mo>=</mml:mo></mml:math></inline-formula> 0.001</oasis:entry>
         <oasis:entry colname="col4"/>
         <oasis:entry colname="col5"/>
         <oasis:entry colname="col6"/>
       </oasis:row>
     </oasis:tbody>
   </oasis:tgroup></oasis:table></table-wrap>

      <p id="d1e6771">A hydrostatic initial condition is used, with a fixed water table at depth of 10, 5, and 2 <inline-formula><mml:math id="M313" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">m</mml:mi></mml:mrow></mml:math></inline-formula> below ground surface for sand, loam, and clay
loam, respectively. At the upper boundary, 0.1 <inline-formula><mml:math id="M314" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">m</mml:mi></mml:mrow></mml:math></inline-formula> of ponding is applied throughout the simulation runtime of 0.18, 2.25, and 1.0 <inline-formula><mml:math id="M315" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">d</mml:mi></mml:mrow></mml:math></inline-formula> for
sand, loam, and clay loam, respectively. We simulated this problem with our ATS solution and with Celia's MPM model for comparison purposes. Both
models faced challenges with this problem. For Celia's MPM, we had to use a small time step to get the solver to produce accurate <inline-formula><mml:math id="M316" display="inline"><mml:mrow><mml:mi mathvariant="italic">ψ</mml:mi><mml:mo>(</mml:mo><mml:mi>z</mml:mi><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula> profiles
(Fig. 4). For the ATS solutions using the default ODE solver settings, the models failed to propagate the wetting front into the soil correctly. It
was necessary to increase the maximum number of calculation steps allowed per reporting time step (we increased this from the default 500 to 10 000)
so that very small time steps could be taken (Table 2). It was also necessary (for loam and clay loam) or beneficial (for sand) to reduce the solver
error tolerances – see values in Fig. 4 and Table 2. The results from these simulations are shown in Fig. 4 and are consistent with those reported in
Fig. 1 of Miller et al. (1998), showing that both models are able to successfully reproduce this benchmark. The runtimes and water balance for each
solution are tabulated in Table 2. Celia's MPM has consistently better water balance performance, though we think the water balance errors in both
models are acceptably low. The ATS solution is slower for sand, faster for loam, and about the same for clay loam. We note that the runtimes and water
balances of the ATS solution are sensitive to the reporting time step <inline-formula><mml:math id="M317" display="inline"><mml:mrow><mml:mi mathvariant="normal">Δ</mml:mi><mml:mi>t</mml:mi></mml:mrow></mml:math></inline-formula> and the solver settings nsteps, <inline-formula><mml:math id="M318" display="inline"><mml:mrow class="chem"><mml:mi mathvariant="normal">atol</mml:mi></mml:mrow></mml:math></inline-formula>, and <inline-formula><mml:math id="M319" display="inline"><mml:mrow class="chem"><mml:mi mathvariant="normal">rtol</mml:mi></mml:mrow></mml:math></inline-formula> – an improved
solution might be attainable by optimizing these settings. On the other hand, for Celia's MPM solution, we only needed to optimize <inline-formula><mml:math id="M320" display="inline"><mml:mrow><mml:mi mathvariant="normal">Δ</mml:mi><mml:mi>t</mml:mi></mml:mrow></mml:math></inline-formula>.</p>

      <?xmltex \floatpos{t}?><fig id="Ch1.F6"><?xmltex \currentcnt{4}?><?xmltex \def\figurename{Figure}?><label>Figure 4</label><caption><p id="d1e6851">Reproduction of the Miller infiltration pulse result, using Celia's MPM model and our ATS SFOM solution. Both models are satisfactorily consistent with the output reported by Miller et al. (1998), in their Fig. 1.</p></caption>
            <?xmltex \igopts{width=221.931496pt}?><graphic xlink:href="https://gmd.copernicus.org/articles/16/659/2023/gmd-16-659-2023-f04.png"/>

          </fig>

</sec>
<sec id="Ch1.S3.SS1.SSS3">
  <label>3.1.3</label><title>Mathias' solution for horizontal infiltration</title>
      <p id="d1e6868">Mathias and Sander (2021) developed a pseudospectral similarity solution for horizontal infiltration (i.e., solving RE without gravity) that is fast
and accurate. This solution assumes a semi-infinite horizontal soil column (<inline-formula><mml:math id="M321" display="inline"><mml:mrow><mml:mn mathvariant="normal">0</mml:mn><mml:mo>≤</mml:mo><mml:mi>x</mml:mi><mml:mo>&lt;</mml:mo><mml:mi mathvariant="normal">∞</mml:mi></mml:mrow></mml:math></inline-formula>) with a uniform initial condition
(<inline-formula><mml:math id="M322" display="inline"><mml:mrow><mml:mi mathvariant="italic">ψ</mml:mi><mml:mo>(</mml:mo><mml:mi>t</mml:mi><mml:mo>=</mml:mo><mml:mn mathvariant="normal">0</mml:mn><mml:mo>)</mml:mo><mml:mo>=</mml:mo><mml:msub><mml:mi mathvariant="italic">ψ</mml:mi><mml:mn mathvariant="normal">0</mml:mn></mml:msub></mml:mrow></mml:math></inline-formula>) and a type-I boundary condition on the left boundary (<inline-formula><mml:math id="M323" display="inline"><mml:mrow><mml:mi mathvariant="italic">ψ</mml:mi><mml:mo>(</mml:mo><mml:mi>x</mml:mi><mml:mo>=</mml:mo><mml:mn mathvariant="normal">0</mml:mn><mml:mo>)</mml:mo><mml:mo>=</mml:mo><mml:msub><mml:mi mathvariant="italic">ψ</mml:mi><mml:mi mathvariant="normal">L</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula>). The model was run for
100 <inline-formula><mml:math id="M324" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">min</mml:mi></mml:mrow></mml:math></inline-formula> (<inline-formula><mml:math id="M325" display="inline"><mml:mrow><mml:mn mathvariant="normal">0</mml:mn><mml:mo>≤</mml:mo><mml:mi>t</mml:mi><mml:mo>≤</mml:mo></mml:mrow></mml:math></inline-formula> 100 <inline-formula><mml:math id="M326" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">min</mml:mi></mml:mrow></mml:math></inline-formula>). The solution can resolve very large gradients in saturation and <inline-formula><mml:math id="M327" display="inline"><mml:mi mathvariant="italic">ψ</mml:mi></mml:math></inline-formula> at the boundary that
propagate into the soil rapidly – and as such this is another challenging problem for a numerical RE model to reproduce. We solved this problem for
three soil types, namely, Hygiene sandstone, silt loam GE 3, and Beit Netofa clay, with properties from van Genuchten (1980) as listed in
Table 3. <inline-formula><mml:math id="M328" display="inline"><mml:mrow><mml:msub><mml:mi>S</mml:mi><mml:mi mathvariant="normal">S</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula> was set to 0, consistent with Mathias' solution. To configure our model for horizontal flow, it is necessary to remove the
gravity term from the flux calculations (i.e., Eq. 11). We solved this problem for a left-hand boundary effective saturation of 0.99 and an initial
saturation of 0.01. The grid is configured such that the wetting pulse does not reach the right-hand boundary over the simulation runtime.</p>

<?xmltex \floatpos{t}?><table-wrap id="Ch1.T3"><?xmltex \currentcnt{3}?><label>Table 3</label><caption><p id="d1e6989">Soil hydraulic properties used the Miller et al. (1998) problem.</p></caption><oasis:table frame="topbot"><oasis:tgroup cols="4">
     <oasis:colspec colnum="1" colname="col1" align="left"/>
     <oasis:colspec colnum="2" colname="col2" align="right"/>
     <oasis:colspec colnum="3" colname="col3" align="right"/>
     <oasis:colspec colnum="4" colname="col4" align="right"/>
     <oasis:thead>
       <oasis:row rowsep="1">
         <oasis:entry colname="col1">Parameter</oasis:entry>
         <oasis:entry colname="col2">Sand</oasis:entry>
         <oasis:entry colname="col3">Loam</oasis:entry>
         <oasis:entry colname="col4">Clay loam</oasis:entry>
       </oasis:row>
     </oasis:thead>
     <oasis:tbody>
       <oasis:row>
         <oasis:entry colname="col1"><inline-formula><mml:math id="M329" display="inline"><mml:mrow><mml:msub><mml:mi mathvariant="italic">θ</mml:mi><mml:mi mathvariant="normal">r</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula></oasis:entry>
         <oasis:entry colname="col2">0.153</oasis:entry>
         <oasis:entry colname="col3">0.131</oasis:entry>
         <oasis:entry colname="col4">0.</oasis:entry>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1"><inline-formula><mml:math id="M330" display="inline"><mml:mrow><mml:msub><mml:mi mathvariant="italic">θ</mml:mi><mml:mi mathvariant="normal">s</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula></oasis:entry>
         <oasis:entry colname="col2">0.250</oasis:entry>
         <oasis:entry colname="col3">0.396</oasis:entry>
         <oasis:entry colname="col4">0.446</oasis:entry>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1"><inline-formula><mml:math id="M331" display="inline"><mml:mi mathvariant="italic">α</mml:mi></mml:math></inline-formula></oasis:entry>
         <oasis:entry colname="col2">0.0079</oasis:entry>
         <oasis:entry colname="col3">0.00423</oasis:entry>
         <oasis:entry colname="col4">0.00152</oasis:entry>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1"><inline-formula><mml:math id="M332" display="inline"><mml:mi>n</mml:mi></mml:math></inline-formula></oasis:entry>
         <oasis:entry colname="col2">10.4</oasis:entry>
         <oasis:entry colname="col3">2.06</oasis:entry>
         <oasis:entry colname="col4">1.17</oasis:entry>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1"><inline-formula><mml:math id="M333" display="inline"><mml:mrow><mml:msub><mml:mi>K</mml:mi><mml:mi mathvariant="normal">s</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula> (<inline-formula><mml:math id="M334" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">cm</mml:mi><mml:mspace linebreak="nobreak" width="0.125em"/><mml:msup><mml:mi mathvariant="normal">d</mml:mi><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msup></mml:mrow></mml:math></inline-formula>)</oasis:entry>
         <oasis:entry colname="col2">108.</oasis:entry>
         <oasis:entry colname="col3">4.96</oasis:entry>
         <oasis:entry colname="col4">0.082</oasis:entry>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1"><inline-formula><mml:math id="M335" display="inline"><mml:mrow><mml:msub><mml:mi>S</mml:mi><mml:mi mathvariant="normal">S</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula></oasis:entry>
         <oasis:entry colname="col2">0.</oasis:entry>
         <oasis:entry colname="col3">0.</oasis:entry>
         <oasis:entry colname="col4">0.</oasis:entry>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1"><inline-formula><mml:math id="M336" display="inline"><mml:mrow><mml:mtext>d</mml:mtext><mml:mi>t</mml:mi></mml:mrow></mml:math></inline-formula> (<inline-formula><mml:math id="M337" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">min</mml:mi></mml:mrow></mml:math></inline-formula>)</oasis:entry>
         <oasis:entry colname="col2">0.1</oasis:entry>
         <oasis:entry colname="col3">0.01</oasis:entry>
         <oasis:entry colname="col4">0.01</oasis:entry>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1"><inline-formula><mml:math id="M338" display="inline"><mml:mrow><mml:mtext>d</mml:mtext><mml:mi>x</mml:mi></mml:mrow></mml:math></inline-formula> (<inline-formula><mml:math id="M339" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">cm</mml:mi></mml:mrow></mml:math></inline-formula>)</oasis:entry>
         <oasis:entry colname="col2">0.25</oasis:entry>
         <oasis:entry colname="col3">0.05</oasis:entry>
         <oasis:entry colname="col4">0.0025</oasis:entry>
       </oasis:row>
     </oasis:tbody>
   </oasis:tgroup></oasis:table></table-wrap>

      <?xmltex \floatpos{t}?><fig id="Ch1.F7" specific-use="star"><?xmltex \currentcnt{5}?><?xmltex \def\figurename{Figure}?><label>Figure 5</label><caption><p id="d1e7248">Comparison of our ATS solver flux output model for horizontal infiltration with the Mathias and Sander (2021) pseudospectral similarity solution (denoted analytical in the legend).</p></caption>
            <?xmltex \igopts{width=369.885827pt}?><graphic xlink:href="https://gmd.copernicus.org/articles/16/659/2023/gmd-16-659-2023-f05.png"/>

          </fig>

<?xmltex \floatpos{t}?><table-wrap id="Ch1.T4" specific-use="star"><?xmltex \currentcnt{4}?><label>Table 4</label><caption><p id="d1e7261">Runtime and water balance performance for the Celia MPM and ATS SFOM solutions, applied to the problem described by Mathias and Sander (2021).</p></caption><oasis:table frame="topbot"><oasis:tgroup cols="6">
     <oasis:colspec colnum="1" colname="col1" align="left"/>
     <oasis:colspec colnum="2" colname="col2" align="left"/>
     <oasis:colspec colnum="3" colname="col3" align="right"/>
     <oasis:colspec colnum="4" colname="col4" align="right"/>
     <oasis:colspec colnum="5" colname="col5" align="right"/>
     <oasis:colspec colnum="6" colname="col6" align="right"/>
     <oasis:thead>
       <oasis:row rowsep="1">
         <oasis:entry colname="col1">Solution</oasis:entry>
         <oasis:entry colname="col2">Soil</oasis:entry>
         <oasis:entry colname="col3">Runtime (<inline-formula><mml:math id="M340" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">s</mml:mi></mml:mrow></mml:math></inline-formula>)</oasis:entry>
         <oasis:entry colname="col4">MB bias (<inline-formula><mml:math id="M341" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">mm</mml:mi></mml:mrow></mml:math></inline-formula>)</oasis:entry>
         <oasis:entry colname="col5">MB RMSE (<inline-formula><mml:math id="M342" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">mm</mml:mi></mml:mrow></mml:math></inline-formula>)</oasis:entry>
         <oasis:entry colname="col6">Cumulative infiltration (<inline-formula><mml:math id="M343" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">mm</mml:mi></mml:mrow></mml:math></inline-formula>)</oasis:entry>
       </oasis:row>
     </oasis:thead>
     <oasis:tbody>
       <oasis:row>
         <oasis:entry colname="col1">Celia MPM</oasis:entry>
         <oasis:entry colname="col2">Sandstone</oasis:entry>
         <oasis:entry colname="col3">2.4</oasis:entry>
         <oasis:entry colname="col4">4.0 <inline-formula><mml:math id="M344" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M345" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">3</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
         <oasis:entry colname="col5">6.5 <inline-formula><mml:math id="M346" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M347" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">6</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
         <oasis:entry colname="col6">63.2</oasis:entry>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1"/>
         <oasis:entry colname="col2">Silt loam</oasis:entry>
         <oasis:entry colname="col3">12.8</oasis:entry>
         <oasis:entry colname="col4">2.2 <inline-formula><mml:math id="M348" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M349" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">2</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
         <oasis:entry colname="col5">3.8 <inline-formula><mml:math id="M350" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M351" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">6</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
         <oasis:entry colname="col6">34.2</oasis:entry>
       </oasis:row>
       <oasis:row rowsep="1">
         <oasis:entry colname="col1"/>
         <oasis:entry colname="col2">Clay</oasis:entry>
         <oasis:entry colname="col3">69.4</oasis:entry>
         <oasis:entry colname="col4">2.2 <inline-formula><mml:math id="M352" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M353" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">3</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
         <oasis:entry colname="col5">4.1 <inline-formula><mml:math id="M354" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M355" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">7</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
         <oasis:entry colname="col6">3.4</oasis:entry>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1">ATS SFOM</oasis:entry>
         <oasis:entry colname="col2">Sandstone</oasis:entry>
         <oasis:entry colname="col3">2.3</oasis:entry>
         <oasis:entry colname="col4"><inline-formula><mml:math id="M356" display="inline"><mml:mo>-</mml:mo></mml:math></inline-formula>1.1 <inline-formula><mml:math id="M357" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M358" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">3</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
         <oasis:entry colname="col5">4.8 <inline-formula><mml:math id="M359" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M360" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">6</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
         <oasis:entry colname="col6">63.3</oasis:entry>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1"/>
         <oasis:entry colname="col2">Silt loam</oasis:entry>
         <oasis:entry colname="col3">18.8</oasis:entry>
         <oasis:entry colname="col4">1.9 <inline-formula><mml:math id="M361" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M362" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">2</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
         <oasis:entry colname="col5">3.9 <inline-formula><mml:math id="M363" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M364" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">6</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
         <oasis:entry colname="col6">34.2</oasis:entry>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1"/>
         <oasis:entry colname="col2">Clay</oasis:entry>
         <oasis:entry colname="col3">32.1</oasis:entry>
         <oasis:entry colname="col4">2.2 <inline-formula><mml:math id="M365" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M366" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">3</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
         <oasis:entry colname="col5">3.9 <inline-formula><mml:math id="M367" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M368" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">7</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
         <oasis:entry colname="col6">3.4</oasis:entry>
       </oasis:row>
     </oasis:tbody>
   </oasis:tgroup></oasis:table></table-wrap>

      <p id="d1e7693">We solved this problem with our ATS solution, with Celia's MPM solution, and with the pseudospectral similarity solution (Mathias and Sander, 2021,
implemented in MATLAB). The results in Fig. 5 show that both the ATS solution and the Celia solution do an excellent job of reproducing this solution
for <inline-formula><mml:math id="M369" display="inline"><mml:mrow><mml:mi mathvariant="italic">θ</mml:mi><mml:mo>(</mml:mo><mml:mi>t</mml:mi><mml:mi>x</mml:mi><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula> (where <inline-formula><mml:math id="M370" display="inline"><mml:mi>x</mml:mi></mml:math></inline-formula>, <inline-formula><mml:math id="M371" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">m</mml:mi></mml:mrow></mml:math></inline-formula>, is horizontal distance). The runtimes and water balance for each solution are tabulated in Table 4. Here, we
see that the ATS and Celia solutions have the same performance in terms of the water balance and the cumulative fluxes simulated. Runtimes vary
between models: both are the same for sandstone, Celia's solution is faster for silt loam, and the ATS solution is faster for clay.</p>
</sec>
</sec>
<sec id="Ch1.S3.SS2">
  <label>3.2</label><title>Comparison with Hydrus 1D</title>
      <p id="d1e7736">Hydrus 1D (Šimůnek et al., 2005, 2016) is a widely used one-dimensional RE solver. The calculations within Hydrus are undertaken using openly
available FORTRAN source code, and the software runs through a (closed-source) graphical user interface on Microsoft Windows. The FORTRAN code can be
compiled using gfortran on the macOS operating system and run from the command line, which we did here, so that the runtime comparisons with our model
are fair. Within Hydrus, the user interface provides somewhat limited control over the error tolerances. We were unable to modify any settings to
improve the water balance, and so we present here model runs that use the default iteration criteria (maximum number of iterations <inline-formula><mml:math id="M372" display="inline"><mml:mo>=</mml:mo></mml:math></inline-formula> 100; water
content tolerance <inline-formula><mml:math id="M373" display="inline"><mml:mo>=</mml:mo></mml:math></inline-formula> 0.001; pressure head tolerance <inline-formula><mml:math id="M374" display="inline"><mml:mo>=</mml:mo></mml:math></inline-formula> 10 <inline-formula><mml:math id="M375" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">mm</mml:mi></mml:mrow></mml:math></inline-formula>; lower/upper optimal iteration range <inline-formula><mml:math id="M376" display="inline"><mml:mo>=</mml:mo></mml:math></inline-formula> 0.7/1.3; lower/upper time step
multiplication factor <inline-formula><mml:math id="M377" display="inline"><mml:mo>=</mml:mo></mml:math></inline-formula> 1.3/0.7; lower/upper limit of tension interval <inline-formula><mml:math id="M378" display="inline"><mml:mo>=</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M379" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">6</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula>/10<inline-formula><mml:math id="M380" display="inline"><mml:msup><mml:mi/><mml:mn mathvariant="normal">3</mml:mn></mml:msup></mml:math></inline-formula> <inline-formula><mml:math id="M381" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">cm</mml:mi></mml:mrow></mml:math></inline-formula>).</p>

<?xmltex \floatpos{t}?><table-wrap id="Ch1.T5" specific-use="star"><?xmltex \currentcnt{5}?><label>Table 5</label><caption><p id="d1e7822">Comparison of model runtimes and mass balance performance.</p></caption><oasis:table frame="topbot"><oasis:tgroup cols="4">
     <oasis:colspec colnum="1" colname="col1" align="left"/>
     <oasis:colspec colnum="2" colname="col2" align="right"/>
     <oasis:colspec colnum="3" colname="col3" align="right"/>
     <oasis:colspec colnum="4" colname="col4" align="right"/>
     <oasis:thead>
       <oasis:row rowsep="1">
         <oasis:entry colname="col1">Model</oasis:entry>
         <oasis:entry colname="col2">Runtime (<inline-formula><mml:math id="M382" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">s</mml:mi></mml:mrow></mml:math></inline-formula>)</oasis:entry>
         <oasis:entry colname="col3">MB bias (<inline-formula><mml:math id="M383" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">mm</mml:mi></mml:mrow></mml:math></inline-formula>)</oasis:entry>
         <oasis:entry colname="col4">MB RMSE (<inline-formula><mml:math id="M384" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">mm</mml:mi></mml:mrow></mml:math></inline-formula>)</oasis:entry>
       </oasis:row>
     </oasis:thead>
     <oasis:tbody>
       <oasis:row>
         <oasis:entry colname="col1">ATS solution, <inline-formula><mml:math id="M385" display="inline"><mml:mrow class="chem"><mml:mi mathvariant="normal">rtol</mml:mi></mml:mrow></mml:math></inline-formula> <inline-formula><mml:math id="M386" display="inline"><mml:mo>=</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M387" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">6</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
         <oasis:entry colname="col2">1.71</oasis:entry>
         <oasis:entry colname="col3"><inline-formula><mml:math id="M388" display="inline"><mml:mo>-</mml:mo></mml:math></inline-formula>0.018</oasis:entry>
         <oasis:entry colname="col4">8.06 <inline-formula><mml:math id="M389" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M390" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">5</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1">ATS solution, <inline-formula><mml:math id="M391" display="inline"><mml:mrow class="chem"><mml:mi mathvariant="normal">rtol</mml:mi></mml:mrow></mml:math></inline-formula> <inline-formula><mml:math id="M392" display="inline"><mml:mo>=</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M393" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">7</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
         <oasis:entry colname="col2">2.30</oasis:entry>
         <oasis:entry colname="col3">0.0003</oasis:entry>
         <oasis:entry colname="col4">6.92 <inline-formula><mml:math id="M394" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M395" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">5</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1">Celia MPM solution</oasis:entry>
         <oasis:entry colname="col2">3.2</oasis:entry>
         <oasis:entry colname="col3">0.0</oasis:entry>
         <oasis:entry colname="col4">2.3 <inline-formula><mml:math id="M396" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M397" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">10</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1">Hydrus</oasis:entry>
         <oasis:entry colname="col2">2.21</oasis:entry>
         <oasis:entry colname="col3"><inline-formula><mml:math id="M398" display="inline"><mml:mo>-</mml:mo></mml:math></inline-formula>0.0021</oasis:entry>
         <oasis:entry colname="col4">4.05 <inline-formula><mml:math id="M399" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M400" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">3</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
       </oasis:row>
     </oasis:tbody>
   </oasis:tgroup></oasis:table></table-wrap>

      <?xmltex \floatpos{t}?><fig id="Ch1.F8" specific-use="star"><?xmltex \currentcnt{6}?><?xmltex \def\figurename{Figure}?><label>Figure 6</label><caption><p id="d1e8082">Comparison of water balance performance from Hydrus 1D, the ATS solution, and our implementation of Celia's MPM solution. The water balance error is <inline-formula><mml:math id="M401" display="inline"><mml:mrow><mml:msub><mml:mi>q</mml:mi><mml:mi mathvariant="normal">T</mml:mi></mml:msub><mml:mo>-</mml:mo><mml:msub><mml:mi>q</mml:mi><mml:mi mathvariant="normal">B</mml:mi></mml:msub><mml:mo>-</mml:mo><mml:mi mathvariant="normal">Δ</mml:mi><mml:mi>S</mml:mi></mml:mrow></mml:math></inline-formula>, and we show the balance for each time step <bold>(a)</bold> and cumulative balances since the start of the simulation <bold>(b)</bold>. In panels <bold>(c)</bold> and <bold>(d)</bold> the time step error is plotted against the infiltration rate.</p></caption>
          <?xmltex \igopts{width=341.433071pt}?><graphic xlink:href="https://gmd.copernicus.org/articles/16/659/2023/gmd-16-659-2023-f06.png"/>

        </fig>

      <?xmltex \floatpos{t}?><fig id="Ch1.F9"><?xmltex \currentcnt{7}?><?xmltex \def\figurename{Figure}?><label>Figure 7</label><caption><p id="d1e8130">Simulated storage <bold>(a)</bold> and drainage <bold>(b)</bold> using Hydrus 1D, the ATS solution, and our implementation of Celia's MPM solution.</p></caption>
          <?xmltex \igopts{width=236.157874pt}?><graphic xlink:href="https://gmd.copernicus.org/articles/16/659/2023/gmd-16-659-2023-f07.png"/>

        </fig>

      <p id="d1e8145">We configured Hydrus 1D, our ATS solution, and our implementation of Celia's MPM solution for a simple numerical experiment, where we simulate the
infiltration of a 10-year time series of daily precipitation into a 1.5 <inline-formula><mml:math id="M402" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">m</mml:mi></mml:mrow></mml:math></inline-formula> deep soil column, with a free-drainage lower-boundary condition. The
minimum, mean, and maximum annual precipitation was 265, 484, and 680 <inline-formula><mml:math id="M403" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">mm</mml:mi><mml:mspace linebreak="nobreak" width="0.125em"/><mml:msup><mml:mi mathvariant="normal">yr</mml:mi><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msup></mml:mrow></mml:math></inline-formula>, and the maximum daily precipitation
was 55 <inline-formula><mml:math id="M404" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">mm</mml:mi><mml:mspace linebreak="nobreak" width="0.125em"/><mml:msup><mml:mi mathvariant="normal">d</mml:mi><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msup></mml:mrow></mml:math></inline-formula>. We used silt loam GE 3 soil hydraulic properties from van Genuchten (1980), where
<inline-formula><mml:math id="M405" display="inline"><mml:mrow><mml:msub><mml:mi mathvariant="italic">θ</mml:mi><mml:mi mathvariant="normal">r</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula> <inline-formula><mml:math id="M406" display="inline"><mml:mo>=</mml:mo></mml:math></inline-formula> 0.131, <inline-formula><mml:math id="M407" display="inline"><mml:mrow><mml:msub><mml:mi mathvariant="italic">θ</mml:mi><mml:mi mathvariant="normal">s</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula> <inline-formula><mml:math id="M408" display="inline"><mml:mo>=</mml:mo></mml:math></inline-formula> 0.396, <inline-formula><mml:math id="M409" display="inline"><mml:mi mathvariant="italic">α</mml:mi></mml:math></inline-formula> <inline-formula><mml:math id="M410" display="inline"><mml:mo>=</mml:mo></mml:math></inline-formula> 0.423 <inline-formula><mml:math id="M411" display="inline"><mml:mrow class="unit"><mml:msup><mml:mi mathvariant="normal">m</mml:mi><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msup></mml:mrow></mml:math></inline-formula>,
<inline-formula><mml:math id="M412" display="inline"><mml:mrow><mml:msub><mml:mi>K</mml:mi><mml:mi mathvariant="normal">s</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula> <inline-formula><mml:math id="M413" display="inline"><mml:mo>=</mml:mo></mml:math></inline-formula> 0.0496 <inline-formula><mml:math id="M414" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">m</mml:mi><mml:mspace linebreak="nobreak" width="0.125em"/><mml:msup><mml:mi mathvariant="normal">d</mml:mi><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msup></mml:mrow></mml:math></inline-formula>, and <inline-formula><mml:math id="M415" display="inline"><mml:mrow><mml:mi>n</mml:mi><mml:mo>=</mml:mo><mml:mn mathvariant="normal">2.06</mml:mn></mml:mrow></mml:math></inline-formula>. We set <inline-formula><mml:math id="M416" display="inline"><mml:mrow><mml:msub><mml:mi>S</mml:mi><mml:mi mathvariant="normal">S</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula> <inline-formula><mml:math id="M417" display="inline"><mml:mo>=</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M418" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">6</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula> <inline-formula><mml:math id="M419" display="inline"><mml:mrow class="unit"><mml:msup><mml:mi mathvariant="normal">m</mml:mi><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msup></mml:mrow></mml:math></inline-formula> and used a uniform <inline-formula><mml:math id="M420" display="inline"><mml:mi mathvariant="italic">ψ</mml:mi></mml:math></inline-formula> initial
condition of <inline-formula><mml:math id="M421" display="inline"><mml:mo>-</mml:mo></mml:math></inline-formula>3.59 <inline-formula><mml:math id="M422" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">m</mml:mi></mml:mrow></mml:math></inline-formula>. The results of the simulations with each model are given in Table 5, showing the runtime and water balance
performance; Fig. 6, showing the detailed water balance performance; and Fig. 7, showing the simulated storage and drainage.</p>
      <p id="d1e8370">In our ATS solution, we can trade off between water balance error and the runtime by modifying the <inline-formula><mml:math id="M423" display="inline"><mml:mrow class="chem"><mml:mi mathvariant="normal">rtol</mml:mi></mml:mrow></mml:math></inline-formula> argument for the ODE solver. We found
that the default <inline-formula><mml:math id="M424" display="inline"><mml:mrow class="chem"><mml:mrow class="chem"><mml:mi mathvariant="normal">rtol</mml:mi></mml:mrow></mml:mrow></mml:math></inline-formula> of 10<inline-formula><mml:math id="M425" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">6</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula> had the fastest runtime, but the water balance performance, whilst good enough for all practical
purposes, was the worst overall (Table 5, Fig. 6). Therefore, we reduced <inline-formula><mml:math id="M426" display="inline"><mml:mrow class="chem"><mml:mi mathvariant="normal">rtol</mml:mi></mml:mrow></mml:math></inline-formula> to 10<inline-formula><mml:math id="M427" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">7</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula>, which improved the water balance performance but
increased the runtime. Even though the water balance errors reported here are all very small, it is still interesting to look closely at how these
compare for the different models, as shown in Fig. 6. The first thing to note is that the Celia MPM solution has water balance errors of essentially
zero, which we expect, because this solution enforces water balance closure. Celia's solution did have the longest runtime – approximately
40 % slower than the other solutions. In the ATS solutions, on a daily basis, the water balance errors are much smaller than in Hydrus. However,
in Hydrus, the water balance errors appear random, with a mean of zero, and hence when looking at the cumulative errors in Hydrus, there is no
systematic accumulation in the errors. In the ATS solutions, in the lower-right panel of Fig. 6, we can see that the water balance errors are strongly
correlated to the infiltration flux at the upper boundary – larger fluxes result in larger errors. Hence, for the ATS solution with
<inline-formula><mml:math id="M428" display="inline"><mml:mrow class="chem"><mml:mi mathvariant="normal">rtol</mml:mi></mml:mrow></mml:math></inline-formula> <inline-formula><mml:math id="M429" display="inline"><mml:mo>=</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M430" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">6</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula>, we see that the errors accumulate, and after 4 years, the cumulative errors in the ATS solution exceed those in
Hydrus. For the ATS solution with <inline-formula><mml:math id="M431" display="inline"><mml:mrow class="chem"><mml:mi mathvariant="normal">rtol</mml:mi></mml:mrow></mml:math></inline-formula> <inline-formula><mml:math id="M432" display="inline"><mml:mo>=</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M433" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">7</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula>, the errors do not accumulate monotonically, and the long-term cumulative errors tend to
oscillate about zero. The water balance performance of the ATS solution with <inline-formula><mml:math id="M434" display="inline"><mml:mrow class="chem"><mml:mi mathvariant="normal">rtol</mml:mi></mml:mrow></mml:math></inline-formula> <inline-formula><mml:math id="M435" display="inline"><mml:mo>=</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M436" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">7</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula> is therefore better than the performance in
Hydrus (Table 5, Fig. 6), while the runtimes of these models are essentially the same (Hydrus is slightly faster, with a runtime of 2.21 vs. 2.30 <inline-formula><mml:math id="M437" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">s</mml:mi></mml:mrow></mml:math></inline-formula>, Table 5).</p>
      <p id="d1e8513">Looking at the simulated storage and discharge in Fig. 7, the two ATS solutions are visually indistinguishable and are both broadly consistent with
the Hydrus 1D model outputs. The Celia MPM solution has non-negligible differences with all other solutions. This is because the MPM solution applies
an iterative solution procedure to solve the model at a daily time step, and the boundary fluxes are therefore subject to errors, as discussed
above. The solution scheme imposes mass balance on the problem but does not track the truncation errors in the fluxes. The avoidance of this issue
represents a significant advantage of adaptive time-stepping solutions.</p>
</sec>
</sec>
<sec id="Ch1.S4" sec-type="conclusions">
  <label>4</label><title>Summary and recommendations</title>
      <p id="d1e8526">We developed a simple adaptive time-stepping scheme (ATS) for RE using the interpreted language Python and making use of the SciPy ODE solver
<italic>ode</italic>. We also developed a new solver flux output method (SFOM) whereby cumulative boundary fluxes can be included within the dependent
variable vector, allowing the determination of highly accurate integrated fluxes over designated time periods. The SFOM is particularly useful for
providing reliable assessment of mass balance closure. In principle, SFOM can be implemented in any ODE solver because it does not require any special
output (such as dense output) to be available. Our model was coded up in Python and released with the name openRE (Ireson, 2022). Our model performed
well against our five success criteria: (i) we successfully reproduced benchmark solutions for <inline-formula><mml:math id="M438" display="inline"><mml:mrow><mml:mi mathvariant="italic">ψ</mml:mi><mml:mo>(</mml:mo><mml:mi>t</mml:mi><mml:mo>,</mml:mo><mml:mi>z</mml:mi><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula> and <inline-formula><mml:math id="M439" display="inline"><mml:mrow><mml:mi mathvariant="italic">θ</mml:mi><mml:mo>(</mml:mo><mml:mi>t</mml:mi><mml:mi>z</mml:mi><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula> from Celia
et al. (1990), Miller et al. (1998), and Mathias and Sander (2021); (ii) we report negligibly low mass balance errors; (iii) we simulate boundary
fluxes that are independent of the reporting time step (unlike Celia's solution, as demonstrated in Fig. 7); (iv) we have low runtimes (as good as
Hydrus 1D); and (v) our code is very simple, concise (92 lines of code for the solver plus 68 lines of code for model configuration for the numerical
experiment in Sect. 3.2), and easily adaptable to new problems. Our solution had the best balance of efficiency, accuracy, and simplicity as compared
to alternative established solution procedures.</p>
</sec>

      
      </body>
    <back><app-group>

<app id="App1.Ch1.S1">
  <?xmltex \currentcnt{A}?><label>Appendix A</label><title>Navigating pitfalls in ODE solver solutions</title>
      <p id="d1e8577">There are several subtle decisions that must be made when solving RE using a generic ODE solver. Here, we test a number of alternative model
configurations and report the impact of these decisions using the following metrics: for model accuracy (criteria i), we report the RMSE of <inline-formula><mml:math id="M440" display="inline"><mml:mi mathvariant="italic">ψ</mml:mi></mml:math></inline-formula>
at all grid points in <inline-formula><mml:math id="M441" display="inline"><mml:mi>t</mml:mi></mml:math></inline-formula> and <inline-formula><mml:math id="M442" display="inline"><mml:mi>z</mml:mi></mml:math></inline-formula> between the current model run and a reference model run; for the mass balance (criteria ii), we report both the bias
error (Eq. 15) and the more rigorous daily water balance RMSE (Eq. 16); for the model efficiency (criteria iv), we simply report the runtime, where
all runs were undertaken on the same laptop computer. For these numerical experiments, we used the 10-year infiltration numerical experiment
described in Sect. 3.2.</p>

      <?xmltex \floatpos{t}?><fig id="App1.Ch1.S1.F10" specific-use="star"><?xmltex \currentcnt{A1}?><?xmltex \def\figurename{Figure}?><label>Figure A1</label><caption><p id="d1e8603">Water balance performance plot for 10-year infiltration experiment, with the best model configuration, showing the cumulative change in storage in the profile and the cumulative inflow minus outflow. The water balance bias was <inline-formula><mml:math id="M443" display="inline"><mml:mo>-</mml:mo></mml:math></inline-formula>0.018 <inline-formula><mml:math id="M444" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">mm</mml:mi></mml:mrow></mml:math></inline-formula>, and the RMSE of the daily water balance errors was 8.06 <inline-formula><mml:math id="M445" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M446" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">5</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula> <inline-formula><mml:math id="M447" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">mm</mml:mi></mml:mrow></mml:math></inline-formula>.</p></caption>
        <?xmltex \igopts{width=426.791339pt}?><graphic xlink:href="https://gmd.copernicus.org/articles/16/659/2023/gmd-16-659-2023-f08.png"/>

      </fig>

      <p id="d1e8654">The best model configuration, against which all other model configurations are compared, was as follows: use the SciPy ODE solver <italic>ode</italic> with the
method BDF (backward differentiation formula, Brown et al., 1989), use our SFOM solution (Sect. 2.3/A2), use the analytical expression
for <inline-formula><mml:math id="M448" display="inline"><mml:mrow><mml:mi>C</mml:mi><mml:mo>(</mml:mo><mml:mi mathvariant="italic">ψ</mml:mi><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula>, use a banded Jacobian sparsity pattern matrix (Sect. 2.4.1/A4), and use the Numba JIT compiler
(Sect. 2.4.2/A5). The water balance performance of this model, showing the cumulative change in storage against cumulative inflow (as
infiltration at the surface) minus outflow (as drainage at the base), is plotted in Fig. A1.</p>
<sec id="App1.Ch1.S1.SS1">
  <label>A1</label><title>Alternative SciPy ODE solvers</title>
      <p id="d1e8682">Here, we compare the alternative ODE solvers that were available in SciPy at the time of writing, which includes <italic>ode</italic>, <italic>odeint</italic>, and
<italic>solve_ivp</italic>. These functions are alternative wrappers to classic ODE solvers written in Fortran, of which we consider here VODE
with the method BDF (Brown et al., 1989, available within <italic>ode</italic> and <italic>solve_ivp</italic>) and LSODA (available with all
three functions, Petzold, 1983). Note that for all solutions reported here we used the banded Jacobian sparsity pattern, with the exception of
<italic>solve_ivp</italic> BDF, which only allows for the full Jacobian sparsity pattern to be defined and which we found slowed the solution
down – hence the results for the <italic>solve_ivp</italic> BDF model do not use any information about the Jacobian matrix.</p>

<?xmltex \floatpos{t}?><table-wrap id="App1.Ch1.S1.T6" specific-use="star"><?xmltex \currentcnt{A1}?><label>Table A1</label><caption><p id="d1e8710">Model performance for the different ODE solvers/methods available in SciPy.</p></caption><oasis:table frame="topbot"><oasis:tgroup cols="6">
     <oasis:colspec colnum="1" colname="col1" align="left"/>
     <oasis:colspec colnum="2" colname="col2" align="left"/>
     <oasis:colspec colnum="3" colname="col3" align="right"/>
     <oasis:colspec colnum="4" colname="col4" align="left"/>
     <oasis:colspec colnum="5" colname="col5" align="right"/>
     <oasis:colspec colnum="6" colname="col6" align="right"/>
     <oasis:thead>
       <oasis:row rowsep="1">
         <oasis:entry colname="col1">ODE solver</oasis:entry>
         <oasis:entry colname="col2">Method</oasis:entry>
         <oasis:entry colname="col3">Runtime (<inline-formula><mml:math id="M449" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">s</mml:mi></mml:mrow></mml:math></inline-formula>)</oasis:entry>
         <oasis:entry colname="col4"><inline-formula><mml:math id="M450" display="inline"><mml:mi mathvariant="bold-italic">ψ</mml:mi></mml:math></inline-formula> RMSE (<inline-formula><mml:math id="M451" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">m</mml:mi></mml:mrow></mml:math></inline-formula>)</oasis:entry>
         <oasis:entry colname="col5">MB bias (<inline-formula><mml:math id="M452" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">mm</mml:mi></mml:mrow></mml:math></inline-formula>)</oasis:entry>
         <oasis:entry colname="col6">MB RMSE (<inline-formula><mml:math id="M453" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">mm</mml:mi></mml:mrow></mml:math></inline-formula>)</oasis:entry>
       </oasis:row>
     </oasis:thead>
     <oasis:tbody>
       <oasis:row>
         <oasis:entry colname="col1">ode</oasis:entry>
         <oasis:entry colname="col2">BDF</oasis:entry>
         <oasis:entry colname="col3">1.71</oasis:entry>
         <oasis:entry colname="col4">0.000</oasis:entry>
         <oasis:entry colname="col5"><inline-formula><mml:math id="M454" display="inline"><mml:mo>-</mml:mo></mml:math></inline-formula>0.018</oasis:entry>
         <oasis:entry colname="col6">8.06 <inline-formula><mml:math id="M455" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M456" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">5</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1">ode</oasis:entry>
         <oasis:entry colname="col2">LSODA</oasis:entry>
         <oasis:entry colname="col3">1.96</oasis:entry>
         <oasis:entry colname="col4">0.000</oasis:entry>
         <oasis:entry colname="col5">0.001</oasis:entry>
         <oasis:entry colname="col6">7.11 <inline-formula><mml:math id="M457" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M458" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">5</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1">odeint</oasis:entry>
         <oasis:entry colname="col2">LSODA</oasis:entry>
         <oasis:entry colname="col3">2.69</oasis:entry>
         <oasis:entry colname="col4">0.000</oasis:entry>
         <oasis:entry colname="col5">0.000</oasis:entry>
         <oasis:entry colname="col6">7.04 <inline-formula><mml:math id="M459" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M460" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">5</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1">solve_ivp</oasis:entry>
         <oasis:entry colname="col2">BDF</oasis:entry>
         <oasis:entry colname="col3">7.45</oasis:entry>
         <oasis:entry colname="col4">0.001</oasis:entry>
         <oasis:entry colname="col5"><inline-formula><mml:math id="M461" display="inline"><mml:mo>-</mml:mo></mml:math></inline-formula>0.594</oasis:entry>
         <oasis:entry colname="col6">3.33 <inline-formula><mml:math id="M462" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M463" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">3</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1">solve_ivp</oasis:entry>
         <oasis:entry colname="col2">LSODA</oasis:entry>
         <oasis:entry colname="col3">2.44</oasis:entry>
         <oasis:entry colname="col4">0.000</oasis:entry>
         <oasis:entry colname="col5">0.059</oasis:entry>
         <oasis:entry colname="col6">6.12 <inline-formula><mml:math id="M464" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M465" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">4</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
       </oasis:row>
     </oasis:tbody>
   </oasis:tgroup></oasis:table></table-wrap>

      <p id="d1e9009">We see that <italic>solve_ivp</italic> underperforms in accuracy, water balance, and efficiency. The <italic>odeint</italic> solver has the best performance in terms
of accuracy and water balance but is slower by a non-negligible amount. The <italic>ode</italic> BDF method is the most efficient but has slightly worse water
balance performance – however, the water balance performance of all methods is extremely good, and errors are negligible for practical purposes. We
therefore chose <italic>ode</italic> BDF as our preferred solution – but <italic>ode</italic> LSODA is also a good option. It is also possible to increase the error
tolerances in the ODE solver, reduce the maximum number of time steps, and increase the minimum time step – all of which could result in a faster
runtime at the cost of lower accuracy/water balance closure.</p>
</sec>
<sec id="App1.Ch1.S1.SS2">
  <label>A2</label><title>Alternative boundary flux calculation methods</title>
      <p id="d1e9035">As detailed in Sect. 2.3, there are alternative ways to calculate the boundary fluxes for use in the water balance calculation. In Sect. 3.3, we
developed a novel approach to calculating the boundary fluxes – the SFOM. In addition to this method, we consider methods that calculate the boundary
fluxes based on the output model states at either reporting-step or calculation-step information. We also consider using forward,
backward, or central difference approximations to integrate the flux over a time step (Eq. 18). The results of this analysis are provided in Table A2.</p>

<?xmltex \floatpos{t}?><table-wrap id="App1.Ch1.S1.T7" specific-use="star"><?xmltex \currentcnt{A2}?><label>Table A2</label><caption><p id="d1e9041">Model performance using different calculation methods for the boundary fluxes.</p></caption><oasis:table frame="topbot"><oasis:tgroup cols="6">
     <oasis:colspec colnum="1" colname="col1" align="left"/>
     <oasis:colspec colnum="2" colname="col2" align="left" colsep="1"/>
     <oasis:colspec colnum="3" colname="col3" align="right"/>
     <oasis:colspec colnum="4" colname="col4" align="right"/>
     <oasis:colspec colnum="5" colname="col5" align="right"/>
     <oasis:colspec colnum="6" colname="col6" align="right"/>
     <oasis:thead>
       <oasis:row rowsep="1">
         <oasis:entry namest="col1" nameend="col2" align="center" colsep="1">Method </oasis:entry>
         <oasis:entry colname="col3">Runtime (<inline-formula><mml:math id="M466" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">s</mml:mi></mml:mrow></mml:math></inline-formula>)</oasis:entry>
         <oasis:entry colname="col4"><inline-formula><mml:math id="M467" display="inline"><mml:mi mathvariant="bold-italic">ψ</mml:mi></mml:math></inline-formula> RMSE (<inline-formula><mml:math id="M468" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">m</mml:mi></mml:mrow></mml:math></inline-formula>)</oasis:entry>
         <oasis:entry colname="col5">MB bias (<inline-formula><mml:math id="M469" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">mm</mml:mi></mml:mrow></mml:math></inline-formula>)</oasis:entry>
         <oasis:entry colname="col6">MB RMSE (<inline-formula><mml:math id="M470" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">mm</mml:mi></mml:mrow></mml:math></inline-formula>)</oasis:entry>
       </oasis:row>
     </oasis:thead>
     <oasis:tbody>
       <oasis:row>
         <oasis:entry namest="col1" nameend="col2" align="center" colsep="1">SFOM </oasis:entry>
         <oasis:entry colname="col3">1.71</oasis:entry>
         <oasis:entry colname="col4">0.000</oasis:entry>
         <oasis:entry colname="col5"><inline-formula><mml:math id="M471" display="inline"><mml:mo>-</mml:mo></mml:math></inline-formula>0.018</oasis:entry>
         <oasis:entry colname="col6">8.06 <inline-formula><mml:math id="M472" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M473" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">5</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1">Reporting step</oasis:entry>
         <oasis:entry colname="col2">central</oasis:entry>
         <oasis:entry colname="col3">1.66</oasis:entry>
         <oasis:entry colname="col4">0.000</oasis:entry>
         <oasis:entry colname="col5">0.119</oasis:entry>
         <oasis:entry colname="col6">2.64 <inline-formula><mml:math id="M474" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M475" display="inline"><mml:msup><mml:mi/><mml:mn mathvariant="normal">0</mml:mn></mml:msup></mml:math></inline-formula></oasis:entry>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1">Reporting step</oasis:entry>
         <oasis:entry colname="col2">forward</oasis:entry>
         <oasis:entry colname="col3">1.66</oasis:entry>
         <oasis:entry colname="col4">0.000</oasis:entry>
         <oasis:entry colname="col5">0.119</oasis:entry>
         <oasis:entry colname="col6">5.29 <inline-formula><mml:math id="M476" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M477" display="inline"><mml:msup><mml:mi/><mml:mn mathvariant="normal">0</mml:mn></mml:msup></mml:math></inline-formula></oasis:entry>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1">Reporting step</oasis:entry>
         <oasis:entry colname="col2">backward</oasis:entry>
         <oasis:entry colname="col3">1.66</oasis:entry>
         <oasis:entry colname="col4">0.000</oasis:entry>
         <oasis:entry colname="col5">0.119</oasis:entry>
         <oasis:entry colname="col6">5.92 <inline-formula><mml:math id="M478" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M479" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">2</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1">Calculation step</oasis:entry>
         <oasis:entry colname="col2">central</oasis:entry>
         <oasis:entry colname="col3">5.24</oasis:entry>
         <oasis:entry colname="col4">0.000</oasis:entry>
         <oasis:entry colname="col5">0.046</oasis:entry>
         <oasis:entry colname="col6">1.13 <inline-formula><mml:math id="M480" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M481" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">4</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1">Calculation step</oasis:entry>
         <oasis:entry colname="col2">forward</oasis:entry>
         <oasis:entry colname="col3">5.24</oasis:entry>
         <oasis:entry colname="col4">0.000</oasis:entry>
         <oasis:entry colname="col5">0.046</oasis:entry>
         <oasis:entry colname="col6">3.24 <inline-formula><mml:math id="M482" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M483" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">3</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1">Calculation step</oasis:entry>
         <oasis:entry colname="col2">backward</oasis:entry>
         <oasis:entry colname="col3">5.24</oasis:entry>
         <oasis:entry colname="col4">0.000</oasis:entry>
         <oasis:entry colname="col5">0.046</oasis:entry>
         <oasis:entry colname="col6">3.14 <inline-formula><mml:math id="M484" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M485" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">3</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
       </oasis:row>
     </oasis:tbody>
   </oasis:tgroup></oasis:table></table-wrap>

      <p id="d1e9401">Model state variables are unaffected by the different boundary flux calculation methods. The SFOM has the best water balance performance, both in
terms of bias and RMSE. Using calculation-step-level information results in good water balance closure, with the central difference approximation
giving the lowest errors. However, the efficiency of this is poor, with runtimes increased by more than a factor of 3. This is because many
additional calculations need to be performed outside the ODE solver for each calculation time step. By default, the ODE solver allows up to 500
calculation time steps for every reporting time step – so this is very inefficient. Calculating the boundary fluxes using reporting-time-step
information is very efficient and slightly faster than our method, but the water balance errors are significantly larger. These reporting-step errors
will increase with an increased reporting time step, as is shown in Fig. 3. Overall then, the SFOM provides the performance of using calculation-step
information without the loss of computational efficiency.</p>
      <p id="d1e9405">The key take-home point here is that the easiest and most obvious approach to calculating the boundary fluxes is to use reporting-step
information. This is a bad idea – the mass balance errors are large, and if this is combined with other bad decisions (such as using discrete
approximations for <inline-formula><mml:math id="M486" display="inline"><mml:mrow><mml:mi>C</mml:mi><mml:mo>(</mml:mo><mml:mi mathvariant="italic">ψ</mml:mi><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula> as discussed in the next section), the results can be catastrophic (water balance errors <inline-formula><mml:math id="M487" display="inline"><mml:mo>&gt;</mml:mo></mml:math></inline-formula> 100 <inline-formula><mml:math id="M488" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">mm</mml:mi></mml:mrow></mml:math></inline-formula>).</p>
</sec>
<sec id="App1.Ch1.S1.SS3">
  <label>A3</label><?xmltex \opttitle{Alternative estimation methods for ${\mathrm{d}{\theta}}/{\mathrm{d}{\psi}}$}?><title>Alternative estimation methods for <inline-formula><mml:math id="M489" display="inline"><mml:mrow><mml:mi mathvariant="normal">d</mml:mi><mml:mi mathvariant="italic">θ</mml:mi><mml:mo>/</mml:mo><mml:mi mathvariant="normal">d</mml:mi><mml:mi mathvariant="italic">ψ</mml:mi></mml:mrow></mml:math></inline-formula></title>
      <p id="d1e9461">When we use a parametric expression for <inline-formula><mml:math id="M490" display="inline"><mml:mrow><mml:mi mathvariant="italic">θ</mml:mi><mml:mo>(</mml:mo><mml:mi mathvariant="italic">ψ</mml:mi><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula>, such as the van Genuchten equations (Eqs. 26–29), we can obtain an analytical expression
for <inline-formula><mml:math id="M491" display="inline"><mml:mrow><mml:mi mathvariant="normal">d</mml:mi><mml:mi mathvariant="italic">θ</mml:mi><mml:mo>/</mml:mo><mml:mi mathvariant="normal">d</mml:mi><mml:mi mathvariant="italic">ψ</mml:mi></mml:mrow></mml:math></inline-formula>, as in Eq. (28), and this can be used to calculate <inline-formula><mml:math id="M492" display="inline"><mml:mrow><mml:mi>C</mml:mi><mml:mo>(</mml:mo><mml:mi mathvariant="italic">ψ</mml:mi><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula> as implemented in RE in
Eq. (<xref ref-type="disp-formula" rid="Ch1.E5"/>). However, depending on the numerical solution procedure that is adopted, this can lead to errors with mass conservation, and it is
recommended by some researchers (Rathfelder and Abriola, 1994; Clark et al., 2021) that a discrete approximation is used
for <inline-formula><mml:math id="M493" display="inline"><mml:mrow><mml:mi mathvariant="normal">d</mml:mi><mml:mi mathvariant="italic">θ</mml:mi><mml:mo>/</mml:mo><mml:mi mathvariant="normal">d</mml:mi><mml:mi mathvariant="italic">ψ</mml:mi></mml:mrow></mml:math></inline-formula>, whereby
            <disp-formula id="App1.Ch1.S1.E30" content-type="numbered"><label>A1</label><mml:math id="M494" display="block"><mml:mrow><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mrow><mml:mi mathvariant="normal">d</mml:mi><mml:mi mathvariant="italic">θ</mml:mi></mml:mrow><mml:mrow><mml:mi mathvariant="normal">d</mml:mi><mml:mi mathvariant="italic">ψ</mml:mi></mml:mrow></mml:mfrac></mml:mstyle><mml:mo>=</mml:mo><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mrow><mml:msub><mml:mi mathvariant="italic">θ</mml:mi><mml:mi>n</mml:mi></mml:msub><mml:mo>-</mml:mo><mml:msub><mml:mi mathvariant="italic">θ</mml:mi><mml:mrow><mml:mi>n</mml:mi><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msub></mml:mrow><mml:mrow><mml:msub><mml:mi mathvariant="italic">ψ</mml:mi><mml:mi>n</mml:mi></mml:msub><mml:mo>-</mml:mo><mml:msub><mml:mi mathvariant="italic">ψ</mml:mi><mml:mrow><mml:mi>n</mml:mi><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msub></mml:mrow></mml:mfrac></mml:mstyle><mml:mo>,</mml:mo></mml:mrow></mml:math></disp-formula>
          where here <inline-formula><mml:math id="M495" display="inline"><mml:mi>n</mml:mi></mml:math></inline-formula> is a time index. This approach could be seen as equivalent to solving the mixed form of RE and can minimize water balance errors in the
model that arise because the changes in <inline-formula><mml:math id="M496" display="inline"><mml:mrow><mml:mi mathvariant="normal">d</mml:mi><mml:mi mathvariant="italic">θ</mml:mi><mml:mo>/</mml:mo><mml:mi mathvariant="normal">d</mml:mi><mml:mi mathvariant="italic">ψ</mml:mi></mml:mrow></mml:math></inline-formula> over a time step are non-linear, as shown by Celia et al.,
(1990). However, it is necessary to apply this very carefully in the context of ATS methods. The values of <inline-formula><mml:math id="M497" display="inline"><mml:mrow><mml:msub><mml:mi mathvariant="italic">θ</mml:mi><mml:mrow><mml:mi>n</mml:mi><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msub></mml:mrow></mml:math></inline-formula> and <inline-formula><mml:math id="M498" display="inline"><mml:mrow><mml:msub><mml:mi mathvariant="italic">ψ</mml:mi><mml:mrow><mml:mi>n</mml:mi><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msub></mml:mrow></mml:math></inline-formula> must be
available from the previous calculation time step and not the previous reporting time step. If reporting-time-step information is used, the model will
fail badly because as the calculation steps move forward in time over a reporting step, <inline-formula><mml:math id="M499" display="inline"><mml:mrow><mml:mi>C</mml:mi><mml:mo>(</mml:mo><mml:mi mathvariant="italic">ψ</mml:mi><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula> is constantly referenced back to the beginning of
the reporting step. This is clearly an erroneous approach, resulting in mass balance errors of more than 100 <inline-formula><mml:math id="M500" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">mm</mml:mi></mml:mrow></mml:math></inline-formula> for our problem. For the
solver flux output method of calculating the boundary fluxes, it is necessary to output states at reporting steps, and therefore it is not possible to
use the discrete approximation for <inline-formula><mml:math id="M501" display="inline"><mml:mrow><mml:mi>C</mml:mi><mml:mo>(</mml:mo><mml:mi mathvariant="italic">ψ</mml:mi><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula>. The results in Table A3 all use calculation-step information. A more subtle issue is the order of the
temporal integrator used by the ODE solver, which can be specified by the user. Here, we use either first-order or (variable) higher-order (as
determined by the ODE solver) temporal integration methods. For the solver flux output method, we use higher-order temporal integration. The results
are given in Table A3.</p>

<?xmltex \floatpos{t}?><table-wrap id="App1.Ch1.S1.T8" specific-use="star"><?xmltex \currentcnt{A3}?><label>Table A3</label><caption><p id="d1e9682">Model performance using different approaches to calculate <inline-formula><mml:math id="M502" display="inline"><mml:mrow><mml:mi>C</mml:mi><mml:mo>(</mml:mo><mml:mi mathvariant="italic">ψ</mml:mi><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula>.</p></caption><oasis:table frame="topbot"><oasis:tgroup cols="6">
     <oasis:colspec colnum="1" colname="col1" align="left"/>
     <oasis:colspec colnum="2" colname="col2" align="left" colsep="1"/>
     <oasis:colspec colnum="3" colname="col3" align="right"/>
     <oasis:colspec colnum="4" colname="col4" align="right"/>
     <oasis:colspec colnum="5" colname="col5" align="right"/>
     <oasis:colspec colnum="6" colname="col6" align="right"/>
     <oasis:thead>
       <oasis:row rowsep="1">
         <oasis:entry namest="col1" nameend="col2" align="center" colsep="1">Method </oasis:entry>
         <oasis:entry colname="col3">Runtime (<inline-formula><mml:math id="M503" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">s</mml:mi></mml:mrow></mml:math></inline-formula>)</oasis:entry>
         <oasis:entry colname="col4"><inline-formula><mml:math id="M504" display="inline"><mml:mi mathvariant="bold-italic">ψ</mml:mi></mml:math></inline-formula> RMSE (<inline-formula><mml:math id="M505" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">m</mml:mi></mml:mrow></mml:math></inline-formula>)</oasis:entry>
         <oasis:entry colname="col5">MB bias (<inline-formula><mml:math id="M506" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">mm</mml:mi></mml:mrow></mml:math></inline-formula>)</oasis:entry>
         <oasis:entry colname="col6">MB RMSE (<inline-formula><mml:math id="M507" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">mm</mml:mi></mml:mrow></mml:math></inline-formula>)</oasis:entry>
       </oasis:row>
     </oasis:thead>
     <oasis:tbody>
       <oasis:row>
         <oasis:entry colname="col1">Analytical <inline-formula><mml:math id="M508" display="inline"><mml:mrow><mml:mi>C</mml:mi><mml:mo>(</mml:mo><mml:mi mathvariant="italic">ψ</mml:mi><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula></oasis:entry>
         <oasis:entry colname="col2">solver flux output method</oasis:entry>
         <oasis:entry colname="col3">1.71</oasis:entry>
         <oasis:entry colname="col4">0.000</oasis:entry>
         <oasis:entry colname="col5"><inline-formula><mml:math id="M509" display="inline"><mml:mo>-</mml:mo></mml:math></inline-formula>0.018</oasis:entry>
         <oasis:entry colname="col6">8.06 <inline-formula><mml:math id="M510" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M511" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">5</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1">Analytical <inline-formula><mml:math id="M512" display="inline"><mml:mrow><mml:mi>C</mml:mi><mml:mo>(</mml:mo><mml:mi mathvariant="italic">ψ</mml:mi><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula></oasis:entry>
         <oasis:entry colname="col2">first order</oasis:entry>
         <oasis:entry colname="col3">36.25</oasis:entry>
         <oasis:entry colname="col4">0.000</oasis:entry>
         <oasis:entry colname="col5"><inline-formula><mml:math id="M513" display="inline"><mml:mo>-</mml:mo></mml:math></inline-formula>0.49</oasis:entry>
         <oasis:entry colname="col6">4.97 <inline-formula><mml:math id="M514" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M515" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">4</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1">Analytical <inline-formula><mml:math id="M516" display="inline"><mml:mrow><mml:mi>C</mml:mi><mml:mo>(</mml:mo><mml:mi mathvariant="italic">ψ</mml:mi><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula></oasis:entry>
         <oasis:entry colname="col2">high order</oasis:entry>
         <oasis:entry colname="col3">5.17</oasis:entry>
         <oasis:entry colname="col4">0.000</oasis:entry>
         <oasis:entry colname="col5">0.046</oasis:entry>
         <oasis:entry colname="col6">3.14 <inline-formula><mml:math id="M517" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M518" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">3</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1">Discrete <inline-formula><mml:math id="M519" display="inline"><mml:mrow><mml:mi>C</mml:mi><mml:mo>(</mml:mo><mml:mi mathvariant="italic">ψ</mml:mi><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula></oasis:entry>
         <oasis:entry colname="col2">first order</oasis:entry>
         <oasis:entry colname="col3">44.62</oasis:entry>
         <oasis:entry colname="col4">0.000</oasis:entry>
         <oasis:entry colname="col5">0.317</oasis:entry>
         <oasis:entry colname="col6">1.92 <inline-formula><mml:math id="M520" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M521" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">7</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1">Discrete <inline-formula><mml:math id="M522" display="inline"><mml:mrow><mml:mi>C</mml:mi><mml:mo>(</mml:mo><mml:mi mathvariant="italic">ψ</mml:mi><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula></oasis:entry>
         <oasis:entry colname="col2">high order</oasis:entry>
         <oasis:entry colname="col3">7.2</oasis:entry>
         <oasis:entry colname="col4">0.003</oasis:entry>
         <oasis:entry colname="col5">11.939</oasis:entry>
         <oasis:entry colname="col6">9.72 <inline-formula><mml:math id="M523" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M524" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">3</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
       </oasis:row>
     </oasis:tbody>
   </oasis:tgroup></oasis:table></table-wrap>

<?xmltex \floatpos{h!}?><table-wrap id="App1.Ch1.S1.T9" specific-use="star"><?xmltex \currentcnt{A4}?><label>Table A4</label><caption><p id="d1e10060">Model performance using different approaches to define the Jacobian matrix.</p></caption><oasis:table frame="topbot"><oasis:tgroup cols="6">
     <oasis:colspec colnum="1" colname="col1" align="left"/>
     <oasis:colspec colnum="2" colname="col2" align="left" colsep="1"/>
     <oasis:colspec colnum="3" colname="col3" align="right"/>
     <oasis:colspec colnum="4" colname="col4" align="right"/>
     <oasis:colspec colnum="5" colname="col5" align="right"/>
     <oasis:colspec colnum="6" colname="col6" align="right"/>
     <oasis:thead>
       <oasis:row rowsep="1">
         <oasis:entry namest="col1" nameend="col2" align="center" colsep="1">Method </oasis:entry>
         <oasis:entry colname="col3">Runtime (<inline-formula><mml:math id="M525" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">s</mml:mi></mml:mrow></mml:math></inline-formula>)</oasis:entry>
         <oasis:entry colname="col4"><inline-formula><mml:math id="M526" display="inline"><mml:mi mathvariant="bold-italic">ψ</mml:mi></mml:math></inline-formula> RMSE (<inline-formula><mml:math id="M527" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">m</mml:mi></mml:mrow></mml:math></inline-formula>)</oasis:entry>
         <oasis:entry colname="col5">MB bias (<inline-formula><mml:math id="M528" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">mm</mml:mi></mml:mrow></mml:math></inline-formula>)</oasis:entry>
         <oasis:entry colname="col6">MB RMSE (<inline-formula><mml:math id="M529" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">mm</mml:mi></mml:mrow></mml:math></inline-formula>)</oasis:entry>
       </oasis:row>
     </oasis:thead>
     <oasis:tbody>
       <oasis:row>
         <oasis:entry colname="col1">Solver flux output method</oasis:entry>
         <oasis:entry colname="col2">Jacobian pattern</oasis:entry>
         <oasis:entry colname="col3">1.71</oasis:entry>
         <oasis:entry colname="col4">0</oasis:entry>
         <oasis:entry colname="col5"><inline-formula><mml:math id="M530" display="inline"><mml:mo>-</mml:mo></mml:math></inline-formula>0.018</oasis:entry>
         <oasis:entry colname="col6">8.06 <inline-formula><mml:math id="M531" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M532" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">5</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
       </oasis:row>
       <oasis:row rowsep="1">
         <oasis:entry colname="col1"/>
         <oasis:entry colname="col2">no Jacobian</oasis:entry>
         <oasis:entry colname="col3">2.17</oasis:entry>
         <oasis:entry colname="col4">0</oasis:entry>
         <oasis:entry colname="col5"><inline-formula><mml:math id="M533" display="inline"><mml:mo>-</mml:mo></mml:math></inline-formula>0.015</oasis:entry>
         <oasis:entry colname="col6">7.53 <inline-formula><mml:math id="M534" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M535" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">5</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1">Reporting-step flux calculation method</oasis:entry>
         <oasis:entry colname="col2">no Jacobian</oasis:entry>
         <oasis:entry colname="col3">2.16</oasis:entry>
         <oasis:entry colname="col4">0</oasis:entry>
         <oasis:entry colname="col5">0.119</oasis:entry>
         <oasis:entry colname="col6">5.92 <inline-formula><mml:math id="M536" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M537" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">2</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1"/>
         <oasis:entry colname="col2">Jacobian pattern</oasis:entry>
         <oasis:entry colname="col3">1.63</oasis:entry>
         <oasis:entry colname="col4">0</oasis:entry>
         <oasis:entry colname="col5">0.119</oasis:entry>
         <oasis:entry colname="col6">5.92 <inline-formula><mml:math id="M538" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M539" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">2</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1"/>
         <oasis:entry colname="col2">full Jacobian</oasis:entry>
         <oasis:entry colname="col3">1.58</oasis:entry>
         <oasis:entry colname="col4">0</oasis:entry>
         <oasis:entry colname="col5">0.123</oasis:entry>
         <oasis:entry colname="col6">5.92 <inline-formula><mml:math id="M540" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M541" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">2</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
       </oasis:row>
     </oasis:tbody>
   </oasis:tgroup></oasis:table></table-wrap>

<?xmltex \floatpos{h!}?><table-wrap id="App1.Ch1.S1.T10" specific-use="star"><?xmltex \currentcnt{A5}?><label>Table A5</label><caption><p id="d1e10355">Model performance with and without Numba JIT compilation.</p></caption><oasis:table frame="topbot"><oasis:tgroup cols="5">
     <oasis:colspec colnum="1" colname="col1" align="left"/>
     <oasis:colspec colnum="2" colname="col2" align="right"/>
     <oasis:colspec colnum="3" colname="col3" align="right"/>
     <oasis:colspec colnum="4" colname="col4" align="right"/>
     <oasis:colspec colnum="5" colname="col5" align="right"/>
     <oasis:thead>
       <oasis:row rowsep="1">
         <oasis:entry colname="col1">Configuration</oasis:entry>
         <oasis:entry colname="col2">Runtime (<inline-formula><mml:math id="M542" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">s</mml:mi></mml:mrow></mml:math></inline-formula>)</oasis:entry>
         <oasis:entry colname="col3"><inline-formula><mml:math id="M543" display="inline"><mml:mi mathvariant="bold-italic">ψ</mml:mi></mml:math></inline-formula> RMSE (<inline-formula><mml:math id="M544" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">m</mml:mi></mml:mrow></mml:math></inline-formula>)</oasis:entry>
         <oasis:entry colname="col4">MB bias (<inline-formula><mml:math id="M545" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">mm</mml:mi></mml:mrow></mml:math></inline-formula>)</oasis:entry>
         <oasis:entry colname="col5">MB RMSE (<inline-formula><mml:math id="M546" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">mm</mml:mi></mml:mrow></mml:math></inline-formula>)</oasis:entry>
       </oasis:row>
     </oasis:thead>
     <oasis:tbody>
       <oasis:row>
         <oasis:entry colname="col1">With Numba</oasis:entry>
         <oasis:entry colname="col2">1.71</oasis:entry>
         <oasis:entry colname="col3">0.00</oasis:entry>
         <oasis:entry colname="col4"><inline-formula><mml:math id="M547" display="inline"><mml:mo>-</mml:mo></mml:math></inline-formula>0.018</oasis:entry>
         <oasis:entry colname="col5">8.06 <inline-formula><mml:math id="M548" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M549" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">5</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
       </oasis:row>
       <oasis:row>
         <oasis:entry colname="col1">Without Numba</oasis:entry>
         <oasis:entry colname="col2">26.07</oasis:entry>
         <oasis:entry colname="col3">0.00</oasis:entry>
         <oasis:entry colname="col4"><inline-formula><mml:math id="M550" display="inline"><mml:mo>-</mml:mo></mml:math></inline-formula>0.018</oasis:entry>
         <oasis:entry colname="col5">8.06 <inline-formula><mml:math id="M551" display="inline"><mml:mo>×</mml:mo></mml:math></inline-formula> 10<inline-formula><mml:math id="M552" display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">5</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
       </oasis:row>
     </oasis:tbody>
   </oasis:tgroup></oasis:table></table-wrap>

      <p id="d1e10520">We see in Table 3 that the discrete <inline-formula><mml:math id="M553" display="inline"><mml:mrow><mml:mi>C</mml:mi><mml:mo>(</mml:mo><mml:mi mathvariant="italic">ψ</mml:mi><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula> approach works quite well for first-order integration methods but is very slow. When higher-order
integration methods are used, the model is faster, but the mass balance is chronically degraded. We think that this happens because with higher-order
methods the model states evolve in a more complex manner (i.e., non-linear manner) over a calculation time step, so the linear approximation in
Eq. (A1) is not good. It is noteworthy that the modeled <inline-formula><mml:math id="M554" display="inline"><mml:mi mathvariant="italic">ψ</mml:mi></mml:math></inline-formula> values were slightly modified using the discrete high-order approach. For comparison
purposes, we looked at using analytical representations of <inline-formula><mml:math id="M555" display="inline"><mml:mrow><mml:mi>C</mml:mi><mml:mo>(</mml:mo><mml:mi mathvariant="italic">ψ</mml:mi><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula> with first-order and higher-order methods, and this time the higher-order
methods performed better. Overall, we recommend against using discrete <inline-formula><mml:math id="M556" display="inline"><mml:mrow><mml:mi>C</mml:mi><mml:mo>(</mml:mo><mml:mi mathvariant="italic">ψ</mml:mi><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula> approximations, unless using a tailor-made ODE solver (such as
Kavetski et al., 2001, 2002a, b).</p>
</sec>
<sec id="App1.Ch1.S1.SS4">
  <label>A4</label><title>Alternative approaches to defining the Jacobian</title>
      <p id="d1e10580">As described in Sect. 4.1, providing the ODE solver with information about the Jacobian matrix is reported to improve the solution efficiency. Here we
compare three approaches: no information provided about the Jacobian, defining the Jacobian pattern, and defining the full Jacobian matrix. For the
last case, this was complex to define for our method, and therefore it was implemented for the high-order reporting-step solution procedure described
in Sect. 4.3.2. The results are reported in Table A4.</p>
      <p id="d1e10583">We see that for both model configurations, defining the banded Jacobian sparsity pattern matrix led to improvements in performance of
around 20 %. This is modest, but because it is trivial to define the banded matrix, this is worthwhile. For the reporting-step model, when we
defined the full Jacobian matrix, this led to a very slight improvement in performance over the banded solution (1.58 <inline-formula><mml:math id="M557" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">s</mml:mi></mml:mrow></mml:math></inline-formula>
vs. 1.63 <inline-formula><mml:math id="M558" display="inline"><mml:mrow class="unit"><mml:mi mathvariant="normal">s</mml:mi></mml:mrow></mml:math></inline-formula>). Defining the full Jacobian is challenging and requires an additional function/function call in the code – we therefore recommend
against using the full Jacobian matrix and recommend instead defining the banded matrix.</p><?xmltex \hack{\newpage}?>
</sec>
<sec id="App1.Ch1.S1.SS5">
  <label>A5</label><title>Running the model with and without Numba JIT compilation</title>
      <p id="d1e10611">The best model configuration was also run with and without the Numba JIT compiler, and the result is shown in Table A5. It can be seen
that Numba has no impact on the model output (accuracy and mass balance are identical for each run) as expected, but using Numba
improves the runtime by a factor of <inline-formula><mml:math id="M559" display="inline"><mml:mo>∼</mml:mo></mml:math></inline-formula> 15. All other model runs reported in this paper use Numba.</p>
</sec>
</app>
  </app-group><notes notes-type="codedataavailability"><title>Code and data availability</title>

      <p id="d1e10626">All of the scripts developed in this study are available from <uri>https://github.com/amireson/openRE</uri> (last access: 24 January 2023), release v1.0.1, <ext-link xlink:href="https://doi.org/10.5281/zenodo.7497133" ext-link-type="DOI">10.5281/zenodo.7497133</ext-link> (Ireson, 2022). The code is written in Python and MATLAB and run using makefiles, which reproduce Figs. 2–7.</p>
  </notes><notes notes-type="authorcontribution"><title>Author contributions</title>

      <p id="d1e10638">AMI conceived of this study, wrote all the scripts (except the pseudospectral similarity solution, written in MATLAB by SAM), performed the analysis, and drafted the manuscript. SAM came up with the idea for the proposed solver flux output method (SFOM). MPC, RJS, and SAM assisted with the study design and implementation and edited the manuscript.</p>
  </notes><notes notes-type="competinginterests"><title>Competing interests</title>

      <p id="d1e10644">The contact author has declared that none of the authors has any competing interests.</p>
  </notes><notes notes-type="disclaimer"><title>Disclaimer</title>

      <p id="d1e10650">Publisher's note: Copernicus Publications remains neutral with regard to jurisdictional claims in published maps and institutional affiliations.</p>
  </notes><ack><title>Acknowledgements</title><p id="d1e10656">Support for this study was provided by the Global Institute for Water Security and the Canada First Research Excellence Fund's Global Water Futures program.</p></ack><notes notes-type="reviewstatement"><title>Review statement</title>

      <p id="d1e10661">This paper was edited by Ludovic Räss and reviewed by James Craig and one anonymous referee.</p>
  </notes><ref-list>
    <title>References</title>

      <ref id="bib1.bib1"><label>1</label><?label 2?><mixed-citation>Bear, J. and Cheng, A. H. D.:
Modeling groundwater flow and contaminant transport, Vol. 23, in: Theory and Applications of Transport in Porous Media, Springer, Dordrecht, 834, <ext-link xlink:href="https://doi.org/10.1007/978-1-4020-6682-5" ext-link-type="DOI">10.1007/978-1-4020-6682-5</ext-link>, 2010.</mixed-citation></ref>
      <ref id="bib1.bib2"><label>2</label><?label 3?><mixed-citation>Beven, K., and Germann, P.:
Macropores and water flow in soils revisited, Water Resour. Res., 49, 3071–3092, <ext-link xlink:href="https://doi.org/10.1002/wrcr.20156" ext-link-type="DOI">10.1002/wrcr.20156</ext-link>, 2013.</mixed-citation></ref>
      <ref id="bib1.bib3"><label>3</label><?label 4?><mixed-citation>Brown, P. N., Hindmarsh, A. C., and Byrne, G. D.:
VODE. Variable Coefficient ODE Solver, SIAM J. Sci. Stat. Comp., 10, 1038–1051, <ext-link xlink:href="https://doi.org/10.1137/0910062" ext-link-type="DOI">10.1137/0910062</ext-link>, 1989.</mixed-citation></ref>
      <ref id="bib1.bib4"><label>4</label><?label 5?><mixed-citation>Celia, M. A., Bouloutas, E. T., and Zarba, R. L.:
A general mass-conservative numerical solution for the unsaturated flow equation, Water Resour. Res., 26, 1483–1496, <ext-link xlink:href="https://doi.org/10.1029/WR026i007p01483" ext-link-type="DOI">10.1029/WR026i007p01483</ext-link>, 1990.</mixed-citation></ref>
      <ref id="bib1.bib5"><label>5</label><?label 6?><mixed-citation>
Clark, M. P., Fan, Y., Lawrence, D. M., Adam, J. C., Bolster, D., Gochis, D. J., Hooper, R. P., Kumar, M., Leung, L. R., Mackay, D. S., and Maxwell, R. M.:
Improving the representation of hydrologic processes in Earth System Models, Water Resour. Res., 51, 5929–5956, 2015.</mixed-citation></ref>
      <ref id="bib1.bib6"><label>6</label><?label 7?><mixed-citation>Clark, M. P., Zolfaghari, R., Green, K. R., Trim, S., Knoben, W. J. M., Bennett, A., Nijssen, B., Ireson, A., and Spiteri, R. J.:
The Numerical Implementation of Land Models: Problem Formulation and Laugh Tests, J. Hydrometeorol., 22, 1627–1648, <ext-link xlink:href="https://doi.org/10.1175/JHM-D-20-0175.1" ext-link-type="DOI">10.1175/JHM-D-20-0175.1</ext-link>, 2021.</mixed-citation></ref>
      <ref id="bib1.bib7"><label>7</label><?label 8?><mixed-citation>Farthing, M. W. and Ogden, F. L.:
Numerical Solution of Richards' Equation: A Review of Advances and Challenges, Soil Sci. Soc. Am. J., 81, 1257–1269, <ext-link xlink:href="https://doi.org/10.2136/sssaj2017.02.0058" ext-link-type="DOI">10.2136/sssaj2017.02.0058</ext-link>, 2017.</mixed-citation></ref>
      <ref id="bib1.bib8"><label>8</label><?label 9?><mixed-citation>Goudarzi, S., Mathias, S. A., and Gluyas, J. G.:
Simulation of three-component two-phase flow in porous media using method of lines, Transport Porous Med., 112, 1–19, <ext-link xlink:href="https://doi.org/10.1007/s11242-016-0639-5" ext-link-type="DOI">10.1007/s11242-016-0639-5</ext-link>, 2016.</mixed-citation></ref>
      <ref id="bib1.bib9"><label>9</label><?label 10?><mixed-citation>Ireson, A. M.: openRE, v1.0.1, Zenodo [code], <ext-link xlink:href="https://doi.org/10.5281/zenodo.7497133" ext-link-type="DOI">10.5281/zenodo.7497133</ext-link>, 2022.</mixed-citation></ref>
      <ref id="bib1.bib10"><label>10</label><?label 11?><mixed-citation>Ireson, A. M. and Butler, A. P.:
A critical assessment of simple recharge models: application to the UK Chalk, Hydrol. Earth Syst. Sci., 17, 2083–2096, <ext-link xlink:href="https://doi.org/10.5194/hess-17-2083-2013" ext-link-type="DOI">10.5194/hess-17-2083-2013</ext-link>, 2013.</mixed-citation></ref>
      <ref id="bib1.bib11"><label>11</label><?label 12?><mixed-citation>Ireson, A. M., Mathias, S. A., Wheater, H. S., Butler, A. P., and Finch, J.:
A model for flow in the Chalk unsaturated zone incorporating progressive weathering. A model for flow in the Chalk unsaturated zone incorporating progressive weathering, J. Hydrol., 365, 244–260, <ext-link xlink:href="https://doi.org/10.1016/j.jhydrol.2008.11.043" ext-link-type="DOI">10.1016/j.jhydrol.2008.11.043</ext-link>, 2009.</mixed-citation></ref>
      <ref id="bib1.bib12"><label>12</label><?label 13?><mixed-citation>Jackson, M. (Ed.): Software Carpentry: Automation and Make,
Version 2016.06,
<uri>https://github.com/swcarpentry/make-novice</uri> (last access: 24 January 2023), June 2016.</mixed-citation></ref>
      <ref id="bib1.bib13"><label>13</label><?label 14?><mixed-citation>Kavetski, D., Binning, P., and Sloan, S. W.:
Adaptive time stepping and error control in a mass conservative numerical solution of the mixed form of Richards equation, Adv. Water Resour., 24, 595–605, <ext-link xlink:href="https://doi.org/10.1016/S0309-1708(00)00076-2" ext-link-type="DOI">10.1016/S0309-1708(00)00076-2</ext-link>, 2001.</mixed-citation></ref>
      <ref id="bib1.bib14"><label>14</label><?label 15?><mixed-citation>Kavetski, D., Binning, P., and Sloan, S. W.:
Adaptive backward Euler time stepping with truncation error control for numerical modelling of unsaturated fluid flow, Int. J. Numer. Meth. Eng., 53, 1301–1322, <ext-link xlink:href="https://doi.org/10.1002/nme.329" ext-link-type="DOI">10.1002/nme.329</ext-link>, 2002a.</mixed-citation></ref>
      <ref id="bib1.bib15"><label>15</label><?label 16?><mixed-citation>Kavetski, D., Binning, P., and Sloan, S. W.:
Noniterative time stepping schemes with adaptive truncation error control for the solution of Richards equation: NONITERATIVE TIME STEPPING SCHEMES, Water Resour. Res., 38, 29–1-29–10, <ext-link xlink:href="https://doi.org/10.1029/2001WR000720" ext-link-type="DOI">10.1029/2001WR000720</ext-link>, 2002b.</mixed-citation></ref>
      <ref id="bib1.bib16"><label>16</label><?label 17?><mixed-citation>Lam, S. K., Pitrou, A., and Seibert, S.:
Numba: A LLVM-based Python JIT compiler, Proceedings of the Second Workshop on the LLVM Compiler Infrastructure in HPC, SC15: The International Conference for High Performance Computing, Networking, Storage and Analysis, Austin, Texas, 15 November 2015, 1–6, <ext-link xlink:href="https://doi.org/10.1145/2833157.2833162" ext-link-type="DOI">10.1145/2833157.2833162</ext-link>, 2015.</mixed-citation></ref>
      <ref id="bib1.bib17"><label>17</label><?label 19?><mixed-citation>Mathias, S. A. and Sander, G. C.:
Pseudospectral methods provide fast and accurate solutions for the horizontal infiltration equation, J. Hydrol., 598, 126407, <ext-link xlink:href="https://doi.org/10.1016/j.jhydrol.2021.126407" ext-link-type="DOI">10.1016/j.jhydrol.2021.126407</ext-link>, 2021.</mixed-citation></ref>
      <ref id="bib1.bib18"><label>18</label><?label 18?><mixed-citation>Mathias, S. A., Skaggs, T. H., Quinn, S. A., Egan, S. N., Finch, L. E., and Oldham, C. D.:
A soil moisture accounting-procedure with a Richards' equation-based soil texture-dependent parameterization, Water Resour. Res., 51, 506–523, <ext-link xlink:href="https://doi.org/10.1002/2014WR016144" ext-link-type="DOI">10.1002/2014WR016144</ext-link>, 2015.</mixed-citation></ref>
      <ref id="bib1.bib19"><label>19</label><?label 20?><mixed-citation>Miller, C. T., Williams, G. A., Kelley, C. T., and Tocci, M. D.:
Robust solution of Richards' equation for nonuniform porous media, Water Resour. Res., 34(, 2599–2610, <ext-link xlink:href="https://doi.org/10.1029/98WR01673" ext-link-type="DOI">10.1029/98WR01673</ext-link>, 1998.</mixed-citation></ref>
      <ref id="bib1.bib20"><label>20</label><?label 21?><mixed-citation>Milly, P. C. D.:
A mass-conservative procedure for time-stepping in models of unsaturated flow, Adv. Water Resour., 8, 32–36, <ext-link xlink:href="https://doi.org/10.1016/0309-1708(85)90078-8" ext-link-type="DOI">10.1016/0309-1708(85)90078-8</ext-link>, 1985.</mixed-citation></ref>
      <ref id="bib1.bib21"><label>21</label><?label 22?><mixed-citation>Milly, P. C. D.:
A Mass-Conservative Procedure for Time-Stepping in Models of Unsaturated Flow, in: Finite Elements in Water Resources, edited by: Laible, J. P., Brebbia, C. A., Gray, W., and Pinder, G., Springer, Berlin, Heidelberg, <ext-link xlink:href="https://doi.org/10.1007/978-3-662-11744-6_9" ext-link-type="DOI">10.1007/978-3-662-11744-6_9</ext-link>, pp. 103–112, 1984.</mixed-citation></ref>
      <ref id="bib1.bib22"><label>22</label><?label 24?><mixed-citation>Petzold, L.:
Automatic Selection of Methods for Solving Stiff and Nonstiff Systems of Ordinary Differential Equations, SIAM J. Sci. Stat. Comp., 4, 136–148, <ext-link xlink:href="https://doi.org/10.1137/0904010" ext-link-type="DOI">10.1137/0904010</ext-link>, 1983.</mixed-citation></ref>
      <ref id="bib1.bib23"><label>23</label><?label 25?><mixed-citation>Rathfelder, K. and Abriola, L. M.:
Mass conservative numerical solutions of the head-based Richards equation, Water Resour. Res., 30, 2579–2586, <ext-link xlink:href="https://doi.org/10.1029/94WR01302" ext-link-type="DOI">10.1029/94WR01302</ext-link>, 1994.</mixed-citation></ref>
      <ref id="bib1.bib24"><label>24</label><?label 27?><mixed-citation>
Šimůnek, J., van Genuchten, M. Th., and Šejna, M.:
The Hydrus-1D software package for simulating the one-dimensional movement of water, heat, and multiple solutes in variably-saturated media. Version 3.0, HYDRUS Software Series 1, Department of Environmental Sciences, University of California Riverside, Riverside, CA, 2005.</mixed-citation></ref>
      <ref id="bib1.bib25"><label>25</label><?label 28?><mixed-citation>Šimůnek, J., van Genuchten, M. Th., and Šejna, M.:
Recent developments and applications of the HYDRUS computer software packages, Vadose Zone J., 15, 25, <ext-link xlink:href="https://doi.org/10.2136/vzj2016.04.0033" ext-link-type="DOI">10.2136/vzj2016.04.0033</ext-link>, 2016.</mixed-citation></ref>
      <ref id="bib1.bib26"><label>26</label><?label 29?><mixed-citation>Tocci, M. D., Kelley, C. T., and Miller, C. T.:
Accurate and economical solution of the pressure-head form of Richards' equation by the method of lines, Adv. Water Resour., 20, 1–14, <ext-link xlink:href="https://doi.org/10.1016/S0309-1708(96)00008-5" ext-link-type="DOI">10.1016/S0309-1708(96)00008-5</ext-link>, 1997.</mixed-citation></ref>
      <ref id="bib1.bib27"><label>27</label><?label 30?><mixed-citation>Tubini, N. and Rigon, R.:
Implementing the Water, HEat and Transport model in GEOframe (WHETGEO-1D v.1.0): algorithms, informatics, design patterns, open science features, and 1D deployment, Geosci. Model Dev., 15, 75–104, <ext-link xlink:href="https://doi.org/10.5194/gmd-15-75-2022" ext-link-type="DOI">10.5194/gmd-15-75-2022</ext-link>, 2022.</mixed-citation></ref>
      <ref id="bib1.bib28"><label>28</label><?label 32?><mixed-citation>van Genuchten, M.:
A Closed-form Equation for Predicting the Hydraulic Conductivity of Unsaturated Soils 1, Soil Sci. Soc. Am. J., 44, 892–898, <ext-link xlink:href="https://doi.org/10.2136/sssaj1980.03615995004400050002x" ext-link-type="DOI">10.2136/sssaj1980.03615995004400050002x</ext-link>, 1980.
</mixed-citation></ref><?xmltex \hack{\newpage}?>
      <ref id="bib1.bib29"><label>29</label><?label 31?><mixed-citation>Van Genuchten, M. T. H. and Gray, W. G.:
Analysis of some dispersion corrected numerical schemes for solution of the transport equation, Int. J. Numer. Meth. Eng., 12, 387–404, <ext-link xlink:href="https://doi.org/10.1002/nme.1620120302" ext-link-type="DOI">10.1002/nme.1620120302</ext-link>, 1978.</mixed-citation></ref>
      <ref id="bib1.bib30"><label>30</label><?label 33?><mixed-citation>Vereecken, H., Schnepf, A., Hopmans, J. W., Javaux, M., Or, D., Roose, T., Vanderborght, J., Young, M. H., Amelung, W., Aitkenhead, M., Allison, S. D., Assouline, S., Baveye, P., Berli, M., Brüggemann, N., Finke, P., Flury, M., Gaiser, T., Govers, G., Ghezzehei, T., Hallett, P., Hendricks Franssen, H. J., Heppell, J., Horn, R., Huisman, J. A., Jacques, D., Jonard, F., Kollet, S., Lafolie, F., Lamorski, K., Leitner, D., McBratney, A., Minasny, B., Montzka, C., Nowak, W., Pachepsky, Y., Padarian, J., Romano, N., Roth, K., Rothfuss, Y., Rowe, E. C., Schwen, A., Šimůnek, J., Tiktak, A., Van Dam, J., van der Zee, S. E. A. T. M., Vogel, H. J., Vrugt, J. A., Wöhling, T., Young, I. M.:
Modeling Soil Processes: Review, Key Challenges, and New Perspectives, Vadose Zone J., 15, vzj2015.09.0131, <ext-link xlink:href="https://doi.org/10.2136/vzj2015.09.0131" ext-link-type="DOI">10.2136/vzj2015.09.0131</ext-link>, 2016.</mixed-citation></ref>

  </ref-list></back>
    <!--<article-title-html>A simple, efficient, mass-conservative approach to solving Richards' equation (openRE, v1.0)</article-title-html>
<abstract-html/>
<ref-html id="bib1.bib1"><label>1</label><mixed-citation>
Bear, J. and Cheng, A. H. D.:
Modeling groundwater flow and contaminant transport, Vol. 23, in: Theory and Applications of Transport in Porous Media, Springer, Dordrecht, 834, <a href="https://doi.org/10.1007/978-1-4020-6682-5" target="_blank">https://doi.org/10.1007/978-1-4020-6682-5</a>, 2010.
</mixed-citation></ref-html>
<ref-html id="bib1.bib2"><label>2</label><mixed-citation>
Beven, K., and Germann, P.:
Macropores and water flow in soils revisited, Water Resour. Res., 49, 3071–3092, <a href="https://doi.org/10.1002/wrcr.20156" target="_blank">https://doi.org/10.1002/wrcr.20156</a>, 2013.
</mixed-citation></ref-html>
<ref-html id="bib1.bib3"><label>3</label><mixed-citation>
Brown, P. N., Hindmarsh, A. C., and Byrne, G. D.:
VODE. Variable Coefficient ODE Solver, SIAM J. Sci. Stat. Comp., 10, 1038–1051, <a href="https://doi.org/10.1137/0910062" target="_blank">https://doi.org/10.1137/0910062</a>, 1989.
</mixed-citation></ref-html>
<ref-html id="bib1.bib4"><label>4</label><mixed-citation>
Celia, M. A., Bouloutas, E. T., and Zarba, R. L.:
A general mass-conservative numerical solution for the unsaturated flow equation, Water Resour. Res., 26, 1483–1496, <a href="https://doi.org/10.1029/WR026i007p01483" target="_blank">https://doi.org/10.1029/WR026i007p01483</a>, 1990.
</mixed-citation></ref-html>
<ref-html id="bib1.bib5"><label>5</label><mixed-citation>
Clark, M. P., Fan, Y., Lawrence, D. M., Adam, J. C., Bolster, D., Gochis, D. J., Hooper, R. P., Kumar, M., Leung, L. R., Mackay, D. S., and Maxwell, R. M.:
Improving the representation of hydrologic processes in Earth System Models, Water Resour. Res., 51, 5929–5956, 2015.
</mixed-citation></ref-html>
<ref-html id="bib1.bib6"><label>6</label><mixed-citation>
Clark, M. P., Zolfaghari, R., Green, K. R., Trim, S., Knoben, W. J. M., Bennett, A., Nijssen, B., Ireson, A., and Spiteri, R. J.:
The Numerical Implementation of Land Models: Problem Formulation and Laugh Tests, J. Hydrometeorol., 22, 1627–1648, <a href="https://doi.org/10.1175/JHM-D-20-0175.1" target="_blank">https://doi.org/10.1175/JHM-D-20-0175.1</a>, 2021.
</mixed-citation></ref-html>
<ref-html id="bib1.bib7"><label>7</label><mixed-citation>
Farthing, M. W. and Ogden, F. L.:
Numerical Solution of Richards' Equation: A Review of Advances and Challenges, Soil Sci. Soc. Am. J., 81, 1257–1269, <a href="https://doi.org/10.2136/sssaj2017.02.0058" target="_blank">https://doi.org/10.2136/sssaj2017.02.0058</a>, 2017.
</mixed-citation></ref-html>
<ref-html id="bib1.bib8"><label>8</label><mixed-citation>
Goudarzi, S., Mathias, S. A., and Gluyas, J. G.:
Simulation of three-component two-phase flow in porous media using method of lines, Transport Porous Med., 112, 1–19, <a href="https://doi.org/10.1007/s11242-016-0639-5" target="_blank">https://doi.org/10.1007/s11242-016-0639-5</a>, 2016.
</mixed-citation></ref-html>
<ref-html id="bib1.bib9"><label>9</label><mixed-citation>
Ireson, A. M.: openRE, v1.0.1, Zenodo [code], <a href="https://doi.org/10.5281/zenodo.7497133" target="_blank">https://doi.org/10.5281/zenodo.7497133</a>, 2022.
</mixed-citation></ref-html>
<ref-html id="bib1.bib10"><label>10</label><mixed-citation>
Ireson, A. M. and Butler, A. P.:
A critical assessment of simple recharge models: application to the UK Chalk, Hydrol. Earth Syst. Sci., 17, 2083–2096, <a href="https://doi.org/10.5194/hess-17-2083-2013" target="_blank">https://doi.org/10.5194/hess-17-2083-2013</a>, 2013.
</mixed-citation></ref-html>
<ref-html id="bib1.bib11"><label>11</label><mixed-citation>
Ireson, A. M., Mathias, S. A., Wheater, H. S., Butler, A. P., and Finch, J.:
A model for flow in the Chalk unsaturated zone incorporating progressive weathering. A model for flow in the Chalk unsaturated zone incorporating progressive weathering, J. Hydrol., 365, 244–260, <a href="https://doi.org/10.1016/j.jhydrol.2008.11.043" target="_blank">https://doi.org/10.1016/j.jhydrol.2008.11.043</a>, 2009.
</mixed-citation></ref-html>
<ref-html id="bib1.bib12"><label>12</label><mixed-citation>
Jackson, M. (Ed.): Software Carpentry: Automation and Make,
Version 2016.06,
<a href="https://github.com/swcarpentry/make-novice" target="_blank"/> (last access: 24 January 2023), June 2016.
</mixed-citation></ref-html>
<ref-html id="bib1.bib13"><label>13</label><mixed-citation>
Kavetski, D., Binning, P., and Sloan, S. W.:
Adaptive time stepping and error control in a mass conservative numerical solution of the mixed form of Richards equation, Adv. Water Resour., 24, 595–605, <a href="https://doi.org/10.1016/S0309-1708(00)00076-2" target="_blank">https://doi.org/10.1016/S0309-1708(00)00076-2</a>, 2001.
</mixed-citation></ref-html>
<ref-html id="bib1.bib14"><label>14</label><mixed-citation>
Kavetski, D., Binning, P., and Sloan, S. W.:
Adaptive backward Euler time stepping with truncation error control for numerical modelling of unsaturated fluid flow, Int. J. Numer. Meth. Eng., 53, 1301–1322, <a href="https://doi.org/10.1002/nme.329" target="_blank">https://doi.org/10.1002/nme.329</a>, 2002a.
</mixed-citation></ref-html>
<ref-html id="bib1.bib15"><label>15</label><mixed-citation>
Kavetski, D., Binning, P., and Sloan, S. W.:
Noniterative time stepping schemes with adaptive truncation error control for the solution of Richards equation: NONITERATIVE TIME STEPPING SCHEMES, Water Resour. Res., 38, 29–1-29–10, <a href="https://doi.org/10.1029/2001WR000720" target="_blank">https://doi.org/10.1029/2001WR000720</a>, 2002b.
</mixed-citation></ref-html>
<ref-html id="bib1.bib16"><label>16</label><mixed-citation>
Lam, S. K., Pitrou, A., and Seibert, S.:
Numba: A LLVM-based Python JIT compiler, Proceedings of the Second Workshop on the LLVM Compiler Infrastructure in HPC, SC15: The International Conference for High Performance Computing, Networking, Storage and Analysis, Austin, Texas, 15 November 2015, 1–6, <a href="https://doi.org/10.1145/2833157.2833162" target="_blank">https://doi.org/10.1145/2833157.2833162</a>, 2015.
</mixed-citation></ref-html>
<ref-html id="bib1.bib17"><label>17</label><mixed-citation>
Mathias, S. A. and Sander, G. C.:
Pseudospectral methods provide fast and accurate solutions for the horizontal infiltration equation, J. Hydrol., 598, 126407, <a href="https://doi.org/10.1016/j.jhydrol.2021.126407" target="_blank">https://doi.org/10.1016/j.jhydrol.2021.126407</a>, 2021.
</mixed-citation></ref-html>
<ref-html id="bib1.bib18"><label>18</label><mixed-citation>
Mathias, S. A., Skaggs, T. H., Quinn, S. A., Egan, S. N., Finch, L. E., and Oldham, C. D.:
A soil moisture accounting-procedure with a Richards' equation-based soil texture-dependent parameterization, Water Resour. Res., 51, 506–523, <a href="https://doi.org/10.1002/2014WR016144" target="_blank">https://doi.org/10.1002/2014WR016144</a>, 2015.
</mixed-citation></ref-html>
<ref-html id="bib1.bib19"><label>19</label><mixed-citation>
Miller, C. T., Williams, G. A., Kelley, C. T., and Tocci, M. D.:
Robust solution of Richards' equation for nonuniform porous media, Water Resour. Res., 34(, 2599–2610, <a href="https://doi.org/10.1029/98WR01673" target="_blank">https://doi.org/10.1029/98WR01673</a>, 1998.
</mixed-citation></ref-html>
<ref-html id="bib1.bib20"><label>20</label><mixed-citation>
Milly, P. C. D.:
A mass-conservative procedure for time-stepping in models of unsaturated flow, Adv. Water Resour., 8, 32–36, <a href="https://doi.org/10.1016/0309-1708(85)90078-8" target="_blank">https://doi.org/10.1016/0309-1708(85)90078-8</a>, 1985.
</mixed-citation></ref-html>
<ref-html id="bib1.bib21"><label>21</label><mixed-citation>
Milly, P. C. D.:
A Mass-Conservative Procedure for Time-Stepping in Models of Unsaturated Flow, in: Finite Elements in Water Resources, edited by: Laible, J. P., Brebbia, C. A., Gray, W., and Pinder, G., Springer, Berlin, Heidelberg, <a href="https://doi.org/10.1007/978-3-662-11744-6_9" target="_blank">https://doi.org/10.1007/978-3-662-11744-6_9</a>, pp. 103–112, 1984.
</mixed-citation></ref-html>
<ref-html id="bib1.bib22"><label>22</label><mixed-citation>
Petzold, L.:
Automatic Selection of Methods for Solving Stiff and Nonstiff Systems of Ordinary Differential Equations, SIAM J. Sci. Stat. Comp., 4, 136–148, <a href="https://doi.org/10.1137/0904010" target="_blank">https://doi.org/10.1137/0904010</a>, 1983.
</mixed-citation></ref-html>
<ref-html id="bib1.bib23"><label>23</label><mixed-citation>
Rathfelder, K. and Abriola, L. M.:
Mass conservative numerical solutions of the head-based Richards equation, Water Resour. Res., 30, 2579–2586, <a href="https://doi.org/10.1029/94WR01302" target="_blank">https://doi.org/10.1029/94WR01302</a>, 1994.
</mixed-citation></ref-html>
<ref-html id="bib1.bib24"><label>24</label><mixed-citation>
Šimůnek, J., van Genuchten, M. Th., and Šejna, M.:
The Hydrus-1D software package for simulating the one-dimensional movement of water, heat, and multiple solutes in variably-saturated media. Version 3.0, HYDRUS Software Series 1, Department of Environmental Sciences, University of California Riverside, Riverside, CA, 2005.
</mixed-citation></ref-html>
<ref-html id="bib1.bib25"><label>25</label><mixed-citation>
Šimůnek, J., van Genuchten, M. Th., and Šejna, M.:
Recent developments and applications of the HYDRUS computer software packages, Vadose Zone J., 15, 25, <a href="https://doi.org/10.2136/vzj2016.04.0033" target="_blank">https://doi.org/10.2136/vzj2016.04.0033</a>, 2016.
</mixed-citation></ref-html>
<ref-html id="bib1.bib26"><label>26</label><mixed-citation>
Tocci, M. D., Kelley, C. T., and Miller, C. T.:
Accurate and economical solution of the pressure-head form of Richards' equation by the method of lines, Adv. Water Resour., 20, 1–14, <a href="https://doi.org/10.1016/S0309-1708(96)00008-5" target="_blank">https://doi.org/10.1016/S0309-1708(96)00008-5</a>, 1997.
</mixed-citation></ref-html>
<ref-html id="bib1.bib27"><label>27</label><mixed-citation>
Tubini, N. and Rigon, R.:
Implementing the Water, HEat and Transport model in GEOframe (WHETGEO-1D v.1.0): algorithms, informatics, design patterns, open science features, and 1D deployment, Geosci. Model Dev., 15, 75–104, <a href="https://doi.org/10.5194/gmd-15-75-2022" target="_blank">https://doi.org/10.5194/gmd-15-75-2022</a>, 2022.
</mixed-citation></ref-html>
<ref-html id="bib1.bib28"><label>28</label><mixed-citation>
van Genuchten, M.:
A Closed-form Equation for Predicting the Hydraulic Conductivity of Unsaturated Soils 1, Soil Sci. Soc. Am. J., 44, 892–898, <a href="https://doi.org/10.2136/sssaj1980.03615995004400050002x" target="_blank">https://doi.org/10.2136/sssaj1980.03615995004400050002x</a>, 1980.

</mixed-citation></ref-html>
<ref-html id="bib1.bib29"><label>29</label><mixed-citation>
Van Genuchten, M. T. H. and Gray, W. G.:
Analysis of some dispersion corrected numerical schemes for solution of the transport equation, Int. J. Numer. Meth. Eng., 12, 387–404, <a href="https://doi.org/10.1002/nme.1620120302" target="_blank">https://doi.org/10.1002/nme.1620120302</a>, 1978.
</mixed-citation></ref-html>
<ref-html id="bib1.bib30"><label>30</label><mixed-citation>
Vereecken, H., Schnepf, A., Hopmans, J. W., Javaux, M., Or, D., Roose, T., Vanderborght, J., Young, M. H., Amelung, W., Aitkenhead, M., Allison, S. D., Assouline, S., Baveye, P., Berli, M., Brüggemann, N., Finke, P., Flury, M., Gaiser, T., Govers, G., Ghezzehei, T., Hallett, P., Hendricks Franssen, H. J., Heppell, J., Horn, R., Huisman, J. A., Jacques, D., Jonard, F., Kollet, S., Lafolie, F., Lamorski, K., Leitner, D., McBratney, A., Minasny, B., Montzka, C., Nowak, W., Pachepsky, Y., Padarian, J., Romano, N., Roth, K., Rothfuss, Y., Rowe, E. C., Schwen, A., Šimůnek, J., Tiktak, A., Van Dam, J., van der Zee, S. E. A. T. M., Vogel, H. J., Vrugt, J. A., Wöhling, T., Young, I. M.:
Modeling Soil Processes: Review, Key Challenges, and New Perspectives, Vadose Zone J., 15, vzj2015.09.0131, <a href="https://doi.org/10.2136/vzj2015.09.0131" target="_blank">https://doi.org/10.2136/vzj2015.09.0131</a>, 2016.
</mixed-citation></ref-html>--></article>
