Source code for pycif.plugins.modes.adjtl_test.execute

import copy
from logging import info

import numpy as np

from .testing_adj import testing_AD_whole
from .testing_TL import testing_TL_linearity, testing_TL_Taylor
from .testing_adj_sym import testing_AD_symmetry


[docs] def execute(self, **kwargs): """Dispatch and run the requested adjoint / tangent-linear test. Builds the perturbation increment ``dx`` (or ``chi`` in the reduced space) according to ``incrmode`` and ``testspace``, then delegates to the appropriate test function based on ``testtype``: * ``'adj'`` — full adjoint test via :func:`testing_AD_whole`. * ``'tllinearity'`` — linearity test via :func:`testing_TL_linearity`. * ``'tltaylor'`` — Taylor expansion test via :func:`testing_TL_Taylor`. * ``'adj_sym'`` — symmetry test via :func:`testing_AD_symmetry`. Args: self (Plugin): mode plugin carrying all configuration attributes. **kwargs: forwarded verbatim to the individual test functions. Returns: float or None: for ``testtype='adj'``, the adjoint-test ratio expressed in multiples of machine epsilon; ``None`` for other test types. """ # Working directory workdir = self.workdir # Control vector controlvect = self.controlvect # Observation operator obsoper = self.obsoperator # Obsvervation vector obsvect = self.obsvect # Simulation window datei = self.datei datef = self.datef # Check that the observation vector is not empty if len(obsvect.yobs) == 0: raise Exception( "WARNING: trying to run a test of the adjoint with no " "observation points! Please check your monitor file" ) # Check that the control vector is not empty if controlvect.dim == 0: raise Exception( "WARNING! There is no element in your control vector. " "Please check your data vector." ) # Increments in x increments = self.increments incrmode = self.incrmode testspace = self.testspace testtype = self.testtype if incrmode == "rand": np.random.seed(self.random_seed) if testspace == "control": if incrmode == "cst": controlvect.dx = \ increments * controlvect.std elif incrmode == "rand": controlvect.dx = ( np.random.normal(0, increments, controlvect.dim) * controlvect.std ) elif testspace == "chi": if incrmode == "cst": controlvect.chi[:] = increments elif incrmode == "rand": controlvect.chi = np.random.normal(0, increments, controlvect.chi_dim) controlvect.dx = ( controlvect.sqrtbprod(controlvect.chi, **kwargs) - controlvect.xb ) if testspace not in ["control", "chi"] or incrmode not in ["cst", "rand"]: raise ValueError( f"Unsupported increment mode '{incrmode}' or test space '{testspace}'. " + "Please check the definition of the running mode in your Yaml file" ) controlvect.x = copy.deepcopy(controlvect.xb) controlvect.dx_save = copy.deepcopy(controlvect.dx) # Some verbose info("Computing the test of the adjoint") # Get the machine accuracy accuracy = np.finfo(np.float64).eps if testtype == 'tllinearity': testing_TL_linearity(self, accuracy) elif testtype == 'tltaylor': testing_TL_Taylor(self, accuracy) elif testtype == 'adj_sym': testing_AD_symmetry(self, accuracy, increments, testspace) if testtype == 'adj': return testing_AD_whole(self, accuracy, testspace)