<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="1.8.17">
  <compounddef id="Testing" kind="page">
    <compoundname>Testing</compoundname>
    <title>Testing</title>
    <briefdescription>
<para>MOM6 Validation and Verification. </para>
    </briefdescription>
    <detaileddescription>
<para>MOM6 Validation and Verification</para>
<para>In the software engineering world, people talk about validation and verification of their codes. Verification is the confirmation of design specifications, such as:</para>
<para><itemizedlist>
<listitem><para>Does it compile on the target platform? </para>
</listitem>
<listitem><para>Is it dimensionally consistent? </para>
</listitem>
<listitem><para>Do answers change with the number of processes? </para>
</listitem>
<listitem><para>Do answers change after a restart?</para>
</listitem>
</itemizedlist>
Validation is a little trickier:</para>
<para><itemizedlist>
<listitem><para>Does the model meet operational needs? </para>
</listitem>
<listitem><para>Does it produce realistic simulations? </para>
</listitem>
<listitem><para>Are relevant physical features present? </para>
</listitem>
<listitem><para>Can I reproduce my old simulations?</para>
</listitem>
</itemizedlist>
There are a number of ways in which MOM6 is tested before each commit, especially commits to the shared dev/main branch.</para>
<sect1 id="Testing_1Travis">
<title>Travis Testing</title>
<para>When pushing code to github, it is possible to set it up so that testing is performed automatically by travis. For MOM6, the .travis.yml file is executed, causing the code to be compiled and then run on all the tests in the .testing directory. It is also possible to run these tests on your local machine, but you might have to do some setup first. See <simplesect kind="see"><para>../../../.testing/README.md for more information.</para>
</simplesect>
</para>
</sect1>
<sect1 id="Testing_1Consortium_testing">
<title>Consortium Testing</title>
<para>For commits to the dev/main branch, there is an opportunity for all consortium members to weigh in on proposed updates. A view of the consortium is shown here:</para>
<para><image type="html" name="consortium.png">The MOM6 consortium.</image>
 <image type="latex" name="consortium.png">The MOM6 consortium.</image>
</para>
<para>Each group is expected to have their own tests and to keep track of expected answers when these tests are run to be compared to prior answers after the code is updated. Answer-changing updates have to be evaluated carefully, though there are circumstances in which the new answers may well be &quot;better&quot;.</para>
</sect1>
<sect1 id="Testing_1Novel_tests">
<title>Novel Tests</title>
<para>There are two classes of tests which MOM6 performs within the .testing suite which could be considered unusual, but which can be quite useful for finding bugs.</para>
<sect2 id="Testing_1Scalings">
<title>Scaling tests</title>
<para>The equations of motion can be multiplied by factors of two without changing answers. One can use that to scale each of six units by a different factor of two to check for consistent use of units. For instance, the equation:</para>
<para><formula id="233">\[ u^{n+1} = u^n + \Delta t \times \cal{F} \]</formula></para>
<para>can be scaled as:</para>
<para><formula id="234">\[ {2^{L-T}} u^{n+1} = {2^{L-T}} u^n + {2^T} \Delta t \times {2^{L-2T}} \cal{F} \]</formula></para>
<para>MOM6 has been recoded to include six different scale factors: <table rows="7" cols="3"><caption>Dimensional scale factors</caption>
<row>
<entry thead="yes"><para>Unit </para>
</entry><entry thead="yes"><para>Scaling </para>
</entry><entry thead="yes"><para>Name </para>
</entry></row>
<row>
<entry thead="no"><para>s </para>
</entry><entry thead="no"><para>T </para>
</entry><entry thead="no"><para>Time </para>
</entry></row>
<row>
<entry thead="no"><para>m </para>
</entry><entry thead="no"><para>L </para>
</entry><entry thead="no"><para>Horizontal length </para>
</entry></row>
<row>
<entry thead="no"><para>m </para>
</entry><entry thead="no"><para>H </para>
</entry><entry thead="no"><para>Layer thickness </para>
</entry></row>
<row>
<entry thead="no"><para>m </para>
</entry><entry thead="no"><para>Z </para>
</entry><entry thead="no"><para>Vertical length </para>
</entry></row>
<row>
<entry thead="no"><para>kg/m3 </para>
</entry><entry thead="no"><para>R </para>
</entry><entry thead="no"><para>Density </para>
</entry></row>
<row>
<entry thead="no"><para>J/kg </para>
</entry><entry thead="no"><para>Q </para>
</entry><entry thead="no"><para>Enthalpy </para>
</entry></row>
</table>
</para>
<para>You can add these integer scaling factors through the runtime parameters X_RESCALE_POWER, where X is one of T, L, H, Z, R, or Q. The valid range for these is -300 to 300.</para>
<para>When adding contributions to MOM6, this coding style with the scale factors must be maintained. For example, if you add new parameters to read from the input file: <programlisting><codeline><highlight class="normal">call<sp/>get_param(...,<sp/>&quot;DT&quot;,<sp/>...<sp/>,<sp/>scale=US%s_to_T)</highlight></codeline>
</programlisting></para>
<para>This is also required for explicit contants, though we are trying to move those out of the code: <programlisting><codeline><highlight class="normal">ustar<sp/>=<sp/>0.01<sp/>*<sp/>US%m_to_Z<sp/>*<sp/>US%T_to_s</highlight></codeline>
</programlisting></para>
<para>or for adding diagnostics: <programlisting><codeline><highlight class="normal">call<sp/>register_diag_field(...,<sp/>&quot;u&quot;,<sp/>...<sp/>,<sp/>&amp;</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/><sp/><sp/>conversion=US%L_T_to_m_s)</highlight></codeline>
</programlisting> <simplesect kind="see"><para><ref refid="namespacemom__unit__scaling" kindref="compound">mom_unit_scaling</ref></para>
</simplesect>
</para>
</sect2>
<sect2 id="Testing_1Rotations">
<title>Rotational tests</title>
<para>By setting the runtime option ROTATE_INDEX to True, the model rotates the domain by some number of 90 degree turns. This option can be used to look for bugs in which east-west operations do not match north-south operations. It changes the order of array elements as shown here:</para>
<para><image type="html" name="Rotated_indices.png">The original non-rotated domain is shown on the left while the right shows the domain rotated counterclockwise by 90 degrees. The array values are shown by the (invariant) colors, while the array indices (and dimensions) change.</image>
 <image type="latex" name="Rotated_indices.png">The original non-rotated domain is shown on the left while the right shows the domain rotated counterclockwise by 90 degrees. The array values are shown by the (invariant) colors, while the array indices (and dimensions) change.</image>
</para>
<para>It only currently runs in serial mode. One can ask for rotations of 90, 180, or 270 degrees, but only 90 degree turns are supported if there are open boundaries.</para>
<para>Because order matters in numerical computations, care must be taken for four-way averages to match between rotated and non-rotated runs. Say you want to compute the following quantity:</para>
<para><formula id="235">\[ \phi_{i,j}^{(c)} = \frac{1}{4} (\phi_A + \phi_B + \phi_C + \phi_D) \]</formula></para>
<para>as shown in this diagram:</para>
<para><image type="html" name="Diagonals1.png">Four h points around a q point.</image>
</para>
<para>You might write this first as: <formula id="236">\[ \frac{1}{4} ((\phi_A + \phi_B) + (\phi_C + \phi_D)) \]</formula> as shown on the left in this figure:</para>
<para><image type="html" name="Diagonals2.png">Naive grouping of terms on the left, diagonal grouping of terms on the right.</image>
</para>
<para>However, the round-off errors could give differing answers when rotated. Instead, you want to group the terms on the diagonal as shown in the right of the above figure and here: <formula id="237">\[ \frac{1}{4} ((\phi_A + \phi_D) + (\phi_B + \phi_C)) \]</formula> </para>
</sect2>
</sect1>
    </detaileddescription>
  </compounddef>
</doxygen>
