LCOV - code coverage report
Current view: top level - include/utils - GeochemistrySpeciesSwapper.h (source / functions) Hit Total Coverage
Test: idaholab/moose geochemistry: 602416 Lines: 1 1 100.0 %
Date: 2025-07-18 11:37:48 Functions: 0 0 -
Legend: Lines: hit not hit

          Line data    Source code
       1             : //* This file is part of the MOOSE framework
       2             : //* https://mooseframework.inl.gov
       3             : //*
       4             : //* All rights reserved, see COPYRIGHT for full restrictions
       5             : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
       6             : //*
       7             : //* Licensed under LGPL 2.1, please see LICENSE for details
       8             : //* https://www.gnu.org/licenses/lgpl-2.1.html
       9             : 
      10             : #pragma once
      11             : 
      12             : #include "DenseMatrix.h"
      13             : #include "PertinentGeochemicalSystem.h"
      14             : #include <libmesh/dense_vector.h>
      15             : 
      16             : /**
      17             :  * Class to swap basis species with equilibrium species
      18             :  */
      19             : class GeochemistrySpeciesSwapper
      20             : {
      21             : public:
      22             :   /**
      23             :    * @param basis_size Number of basis species in the geochemical model
      24             :    * @param stoi_tol Swapping involves inverting matrices via a singular value decomposition. During
      25             :    * this process: (1) if abs(singular value) < stoi_tol * L1norm(singular values), then the matrix
      26             :    * is deemed singular (so the basis swap is deemed invalid); (2) if abs(any stoichiometric
      27             :    * coefficient) < stoi_tol then it is set to zero.  A suggested reasonable value is stoi_tol=1E-6
      28             :    */
      29             :   GeochemistrySpeciesSwapper(unsigned basis_size, Real stoi_tol);
      30             : 
      31             :   bool operator==(const GeochemistrySpeciesSwapper & rhs) const
      32             :   {
      33           2 :     return (_stoi_tol == rhs._stoi_tol) && (_swap_matrix.m() == rhs._swap_matrix.m());
      34             :   };
      35             : 
      36             :   /**
      37             :    * Check that replacing the named basis species with the named equilibrium species is valid.  In
      38             :    * performing this check, the "swap" matrix is inverted, so the check is somewhat expensive.
      39             :    * Therefore, if the swap will be performed, assuming it's valid, the performSwap method should be
      40             :    * used instead.
      41             :    * A mooseError or mooseException will result if the swap is invalid
      42             :    * @param mgd The ModelGeochemicalDatabase that holds all information regarding basis
      43             :    * components, equilibrium species, stoichiometries, etc
      44             :    * @param replace_this The basis component that will be removed from the basis and added to the
      45             :    * equilibrium species list
      46             :    * @param with_this The equilibrium species that will be removed from the equilibrium species list
      47             :    * and added to the basis component list
      48             :    */
      49             :   void checkSwap(const ModelGeochemicalDatabase & mgd,
      50             :                  const std::string & replace_this,
      51             :                  const std::string & with_this);
      52             : 
      53             :   /**
      54             :    * Check that replacing the indexed basis species with the indexed equilibrium species is valid.
      55             :    * In performing this check, the "swap" matrix is inverted, so the check is somewhat expensive.
      56             :    * Therefore, if the swap will be performed, assuming it's valid, the performSwap method should be
      57             :    * used instead.
      58             :    * A mooseError or mooseException will result if the swap is invalid
      59             :    * @param mgd The ModelGeochemicalDatabase that holds all information regarding basis
      60             :    * components, equilibrium species, stoichiometries, etc
      61             :    * @param basis_index_to_replace The index of the basis component that will be removed from the
      62             :    * basis and added to the equilibrium species list
      63             :    * @param eqm_index_to_insert The index of the equilibrium species that will be removed from the
      64             :    * equilibrium species list and added to the basis component list
      65             :    */
      66             :   void checkSwap(const ModelGeochemicalDatabase & mgd,
      67             :                  unsigned basis_index_to_replace,
      68             :                  unsigned eqm_index_to_insert);
      69             : 
      70             :   /**
      71             :    * Check that replacing the named basis species with the named equilibrium species is valid, and
      72             :    * then perform this swap by altering the mgd data structure.
      73             :    * A mooseError or mooseException will result if the swap is invalid
      74             :    * @param mgd The ModelGeochemicalDatabase that holds all information regarding basis
      75             :    * components, equilibrium species, stoichiometries, etc
      76             :    * @param replace_this The basis component that will be removed from the basis and added to the
      77             :    * equilibrium species list
      78             :    * @param with_this The equilibrium species that will be removed from the equilibrium species list
      79             :    * and added to the basis component list
      80             :    */
      81             :   void performSwap(ModelGeochemicalDatabase & mgd,
      82             :                    const std::string & replace_this,
      83             :                    const std::string & with_this);
      84             : 
      85             :   /**
      86             :    * Check that replacing the indexed basis species with the indexed equilibrium species is valid,
      87             :    * and then perform this swap by altering the mgd data structure.
      88             :    * A mooseError or mooseException will result if the swap is invalid
      89             :    * @param mgd The ModelGeochemicalDatabase that holds all information regarding basis
      90             :    * components, equilibrium species, stoichiometries, etc
      91             :    * @param basis_index_to_replace The index of the basis component that will be removed from the
      92             :    * basis and added to the equilibrium species list
      93             :    * @param eqm_index_to_insert The index of the equilibrium species that will be removed from the
      94             :    * equilibrium species list and added to the basis component list
      95             :    */
      96             :   void performSwap(ModelGeochemicalDatabase & mgd,
      97             :                    unsigned basis_index_to_replace,
      98             :                    unsigned eqm_index_to_insert);
      99             : 
     100             :   /**
     101             :    * Check that replacing the named basis species with the named equilibrium species is valid, and
     102             :    * then perform this swap by altering the mgd data structure, and calculate the bulk composition
     103             :    * of the new system.
     104             :    * A mooseError or mooseException will result if the swap is invalid
     105             :    * @param mgd The ModelGeochemicalDatabase that holds all information regarding basis
     106             :    * components, equilibrium species, stoichiometries, etc
     107             :    * @param[in/out] bulk_composition Upon entry, the bulk composition in the original basis.  Upon
     108             :    * exit, the bulk composition in the basis after the swap
     109             :    * @param replace_this The basis component that will be removed from the basis and added to the
     110             :    * equilibrium species list
     111             :    * @param with_this The equilibrium species that will be removed from the equilibrium species list
     112             :    * and added to the basis component list
     113             :    */
     114             :   void performSwap(ModelGeochemicalDatabase & mgd,
     115             :                    DenseVector<Real> & bulk_composition,
     116             :                    const std::string & replace_this,
     117             :                    const std::string & with_this);
     118             : 
     119             :   /**
     120             :    * Check that replacing the indexed basis species with the indexed equilibrium species is valid,
     121             :    * and then perform this swap by altering the mgd data structure, and calculate the bulk
     122             :    * composition of the new system.
     123             :    * A mooseError or mooseException will result if the swap is invalid
     124             :    * @param mgd The ModelGeochemicalDatabase that holds all information regarding basis
     125             :    * components, equilibrium species, stoichiometries, etc
     126             :    * @param[in/out] bulk_composition Upon entry, the bulk composition in the original basis.  Upon
     127             :    * exit, the bulk composition in the basis after the swap
     128             :    * @param basis_index_to_replace The index of the basis component that will be removed from the
     129             :    * basis and added to the equilibrium species list
     130             :    * @param eqm_index_to_insert The index of the equilibrium species that will be removed from the
     131             :    * equilibrium species list and added to the basis component list
     132             :    */
     133             :   void performSwap(ModelGeochemicalDatabase & mgd,
     134             :                    DenseVector<Real> & bulk_composition,
     135             :                    unsigned basis_index_to_replace,
     136             :                    unsigned eqm_index_to_insert);
     137             : 
     138             :   /**
     139             :    * For the the given basis index, find the equilibrium index that it should be swapped with
     140             :    * @param basis_ind index of basis species in mgd that we'd like to swap out of the basis
     141             :    * @param mgd the model's geochemical databgase
     142             :    * @param eqm_molality the molality of all the equilibrium species
     143             :    * @param minerals_allowed if false, best_eqm_species will not correspond to a mineral.  Since
     144             :    * equilibrium minerals have molality=0 it is very unlikely that best_eqm_species will correspond
     145             :    * to a mineral, even if this flag is true.
     146             :    * @param gases_allowed if false, best_eqm_species will not correspond to a gas.  Since
     147             :    * equilibrium gases have molality=0 it is very unlikely that best_eqm_species will correspond to
     148             :    * a gas, even if this flag is true.
     149             :    * @param sorption_allowed if false, best_eqm_species will not be involved in sorption
     150             :    * @param[out] best_eqm_species the index of the equilibrium species that should be swapped with
     151             :    * basis_ind
     152             :    * @return true if a valid swap was found.  if false, then best_eqm_species will be garbage
     153             :    */
     154             :   bool findBestEqmSwap(unsigned basis_ind,
     155             :                        const ModelGeochemicalDatabase & mgd,
     156             :                        const std::vector<Real> & eqm_molality,
     157             :                        bool minerals_allowed,
     158             :                        bool gas_allowed,
     159             :                        bool sorption_allowed,
     160             :                        unsigned & best_eqm_species) const;
     161             : 
     162             : private:
     163             :   /**
     164             :    * Construct the swap matrix, and its inverse, that describes the swap between the indexed basis
     165             :    * species and the indexed equilibrium index.  The inverse of the swap matrix is used in alterMGD
     166             :    * to modify its datastructures to implement the swap.
     167             :    * A mooseError or mooseException will result if the swap is invalid
     168             :    * @param mgd The ModelGeochemicalDatabase that holds all information regarding basis
     169             :    * components, equilibrium species, stoichiometries, etc
     170             :    * @param basis_index_to_replace The index of the basis component that will be removed from the
     171             :    * basis and added to the equilibrium species list
     172             :    * @param eqm_index_to_insert The index of the equilibrium species that will be removed from the
     173             :    * equilibrium species list and added to the basis component list
     174             :    */
     175             :   void constructInverseMatrix(const ModelGeochemicalDatabase & mgd,
     176             :                               unsigned basis_index_to_replace,
     177             :                               unsigned eqm_index_to_insert);
     178             : 
     179             :   /**
     180             :    * Modify the ModelGeochemicalDatabase mgd to swap the indexed basis
     181             :    * species and the indexed equilibrium index.
     182             :    * @param mgd The ModelGeochemicalDatabase that holds all information regarding basis
     183             :    * components, equilibrium species, stoichiometries, etc
     184             :    * @param basis_index_to_replace The index of the basis component that will be removed from the
     185             :    * basis and added to the equilibrium species list
     186             :    * @param eqm_index_to_insert The index of the equilibrium species that will be removed from the
     187             :    * equilibrium species list and added to the basis component list
     188             :    */
     189             :   void alterMGD(ModelGeochemicalDatabase & mgd,
     190             :                 unsigned basis_index_to_replace,
     191             :                 unsigned eqm_index_to_insert);
     192             : 
     193             :   /**
     194             :    * Calculate the bulk composition in the new basis based on the bulk composition in the original
     195             :    * basis
     196             :    * @param basis_size Size of basis, which is only used for error checking
     197             :    * @param[in/out] bulk_composition Upon entry, the bulk composition in the original basis.  Upon
     198             :    * exit, the bulk composition in the basis after the swap
     199             :    */
     200             :   void alterBulkComposition(unsigned basis_size, DenseVector<Real> & bulk_composition) const;
     201             : 
     202             :   /// tolerance for matrix inversion and stoichiometric coefficients
     203             :   Real _stoi_tol;
     204             : 
     205             :   /// swap matrix
     206             :   DenseMatrix<Real> _swap_matrix;
     207             : 
     208             :   /**
     209             :    * Before _swap_matrix.svd (a non-const method) is called, we copy _true_swap_matrix =
     210             :    * _swap_matrix. It is necessary to record _swap_matrix in this fashion so that
     211             :    * mgd.swap_to_original_basis can be modified using it
     212             :    */
     213             :   DenseMatrix<Real> _true_swap_matrix;
     214             : 
     215             :   /// inverse of swap matrix
     216             :   DenseMatrix<Real> _inv_swap_matrix;
     217             : 
     218             :   /// used in SVD decomposition of swap matrix
     219             :   DenseVector<Real> _swap_sigma;
     220             : 
     221             :   /// used in SVD decomposition of swap matrix
     222             :   DenseMatrix<Real> _swap_U;
     223             : 
     224             :   /// used in SVD decomposition of swap matrix
     225             :   DenseMatrix<Real> _swap_VT;
     226             : };

Generated by: LCOV version 1.14