LCOV - code coverage report
Current view: top level - src/actions - AddGeochemistrySolverAction.C (source / functions) Hit Total Coverage
Test: idaholab/moose geochemistry: 2bf808 Lines: 146 153 95.4 %
Date: 2025-07-17 01:29:12 Functions: 4 4 100.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             : #include "AddGeochemistrySolverAction.h"
      11             : #include "GeochemicalModelDefinition.h"
      12             : #include "GeochemistryReactorBase.h"
      13             : #include "NearestNodeNumber.h"
      14             : #include "GeochemistryConsoleOutput.h"
      15             : #include "BlockRestrictable.h"
      16             : #include "BoundaryRestrictable.h"
      17             : 
      18             : registerMooseAction("GeochemistryApp", AddGeochemistrySolverAction, "add_output");
      19             : registerMooseAction("GeochemistryApp", AddGeochemistrySolverAction, "add_user_object");
      20             : registerMooseAction("GeochemistryApp",
      21             :                     AddGeochemistrySolverAction,
      22             :                     "add_geochemistry_molality_aux");
      23             : 
      24             : InputParameters
      25         623 : AddGeochemistrySolverAction::validParams()
      26             : {
      27         623 :   InputParameters params = Action::validParams();
      28        1246 :   params.addParam<UserObjectName>(
      29             :       "geochemistry_reactor_name",
      30             :       "geochemistry_reactor",
      31             :       "The name that will be given to the GeochemistryReactor UserObject built by this action");
      32        1246 :   params.addParam<bool>("include_moose_solve",
      33        1246 :                         false,
      34             :                         "Include a usual MOOSE solve involving Variables and Kernels.  In pure "
      35             :                         "reaction systems (without transport) include_moose_solve = false is "
      36             :                         "appropriate, but with transport 'true' must be used");
      37             : 
      38        1246 :   params.addRequiredParam<UserObjectName>("model_definition",
      39             :                                           "The name of the GeochemicalModelDefinition user object "
      40             :                                           "(you must create this UserObject yourself)");
      41         623 :   params += GeochemistryReactorBase::sharedParams();
      42             : 
      43         623 :   params += BlockRestrictable::validParams();
      44         623 :   params += BoundaryRestrictable::validParams();
      45             : 
      46        1869 :   params.addRangeCheckedParam<Real>(
      47             :       "stoichiometry_tolerance",
      48        1246 :       1E-6,
      49             :       "stoichiometry_tolerance >= 0.0",
      50             :       "Swapping involves inverting matrices via a singular value decomposition. During this "
      51             :       "process: (1) if abs(singular value) < stoi_tol * L1norm(singular values), then the "
      52             :       "matrix is deemed singular (so the basis swap is deemed invalid); (2) if abs(any "
      53             :       "stoichiometric coefficient) < stoi_tol then it is set to zero.");
      54             : 
      55             :   // following are exclusively for the GeochemistryConsoleOutput
      56         623 :   params += GeochemistryConsoleOutput::sharedParams();
      57         623 :   ExecFlagEnum exec_enum = MooseUtils::getDefaultExecFlagEnum();
      58        2492 :   exec_enum = {EXEC_INITIAL, EXEC_FINAL};
      59        1246 :   params.addParam<ExecFlagEnum>(
      60             :       "execute_console_output_on", exec_enum, "When to execute the geochemistry console output");
      61         623 :   params.addParam<Point>("point",
      62         623 :                          Point(0.0, 0.0, 0.0),
      63             :                          "The geochemistry console output will be regarding the aqueous "
      64             :                          "solution at node that is closest to this point");
      65             : 
      66             :   // following are the Aux possibilities
      67        1246 :   params.addParam<bool>(
      68             :       "add_aux_solvent_kg",
      69        1246 :       true,
      70             :       "Add AuxVariable, called kg_solvent_H2O, that records the kg of solvent water");
      71        1246 :   params.addParam<bool>(
      72        1246 :       "add_aux_pH", true, "Add AuxVariable, called pH, that records the pH of solvent water");
      73        1246 :   params.addParam<bool>(
      74             :       "add_aux_molal",
      75        1246 :       true,
      76             :       "Add AuxVariables measured in molal units (ie mol(species)/kg(solvent_water)).  These are "
      77             :       "named molal_name, where 'name' is the species name.  AuxVariables are added for all species "
      78             :       "except minerals");
      79        1246 :   params.addParam<bool>("add_aux_mg_per_kg",
      80        1246 :                         true,
      81             :                         "Add AuxVariables measured in mg(species)/kg(solvent_water).  These are "
      82             :                         "named mg_per_kg_name, where 'name' is the species name.  AuxVariables are "
      83             :                         "added for all species except minerals");
      84        1246 :   params.addParam<bool>("add_aux_free_mg",
      85        1246 :                         true,
      86             :                         "Add AuxVariables for all minerals measured in free mg.  These are named "
      87             :                         "free_mg_name, where 'name' is the species name");
      88        1246 :   params.addParam<bool>("add_aux_free_cm3",
      89        1246 :                         true,
      90             :                         "Add AuxVariables for all minerals measured in free cm^3.  These are named "
      91             :                         "free_cm3_name, where 'name' is the species name");
      92        1246 :   params.addParam<bool>(
      93             :       "add_aux_activity",
      94        1246 :       true,
      95             :       "Add AuxVariables that record the activity for all species (for gas species this equals the "
      96             :       "gas fugacity).  These are called activity_name where 'name' is the species name.");
      97        1246 :   params.addParam<bool>(
      98             :       "add_aux_bulk_moles",
      99        1246 :       true,
     100             :       "Add AuxVariables that record the number of bulk-composition moles for all species.  Note "
     101             :       "that these will be zero for any species not currently in the basis.  These are called "
     102             :       "bulk_moles_name where 'name' is the species name.");
     103        1246 :   params.addParam<bool>("add_aux_surface_charge",
     104        1246 :                         true,
     105             :                         "Add AuxVariables, measured in C/m^2, corresponding to specific surface "
     106             :                         "charge for each mineral involved in surface sorption.  These are "
     107             :                         "surface_charge_name, where 'name' is the mineral name");
     108        1246 :   params.addParam<bool>("add_aux_surface_potential",
     109        1246 :                         true,
     110             :                         "Add AuxVariables, measured in V, corresponding to surface potential "
     111             :                         "for each mineral involved in surface sorption.  These are "
     112             :                         "surface_potential_name, where 'name' is the mineral name");
     113        1246 :   params.addParam<bool>("add_aux_temperature",
     114        1246 :                         true,
     115             :                         "Add AuxVariable, called solution_temperature, that records the "
     116             :                         "temperature of the aqueous solution in degC");
     117        1246 :   params.addParam<bool>(
     118             :       "add_aux_kinetic_moles",
     119        1246 :       true,
     120             :       "Add AuxVariables that record the number of moles for all kinetic species.  These are called "
     121             :       "moles_name where 'name' is the species name.");
     122        1246 :   params.addParam<bool>("add_aux_kinetic_additions",
     123        1246 :                         true,
     124             :                         "Add AuxVariables that record the rate-of-change (-reaction_rate * dt) for "
     125             :                         "all kinetic species.  These are called "
     126             :                         "mol_change_name where 'name' is the species name.");
     127        1246 :   params.addClassDescription("Base class for an Action that sets up a reaction solver.  This class "
     128             :                              "adds a GeochemistryConsoleOutput and AuxVariables corresponding to "
     129             :                              "molalities, etc.  Derived classes will create the solver.");
     130             : 
     131         623 :   return params;
     132         623 : }
     133             : 
     134         623 : AddGeochemistrySolverAction::AddGeochemistrySolverAction(const InputParameters & params)
     135         623 :   : Action(params)
     136             : {
     137         623 : }
     138             : 
     139             : void
     140        4345 : AddGeochemistrySolverAction::act()
     141             : {
     142        5591 :   if (_current_task == "add_user_object" && isParamValid("execute_console_output_on"))
     143             :   {
     144         431 :     const std::string class_name = "NearestNodeNumberUO";
     145         431 :     auto params = _factory.getValidParams(class_name);
     146         862 :     params.set<Point>("point") = getParam<Point>("point");
     147         862 :     if (isParamValid("block"))
     148           0 :       params.set<std::vector<SubdomainName>>("block") =
     149           0 :           getParam<std::vector<SubdomainName>>("block");
     150         862 :     if (isParamValid("boundary"))
     151           0 :       params.set<std::vector<BoundaryName>>("boundary") =
     152           0 :           getParam<std::vector<BoundaryName>>("boundary");
     153         431 :     params.set<ExecFlagEnum>("execute_on") = EXEC_INITIAL; // NOTE: adaptivity not active yet
     154         431 :     _problem->addUserObject(class_name, "geochemistry_nearest_node_number", params);
     155         431 :   }
     156        5112 :   else if (_current_task == "add_output" && isParamValid("execute_console_output_on"))
     157             :   {
     158         407 :     const std::string class_name = "GeochemistryConsoleOutput";
     159         407 :     auto params = _factory.getValidParams(class_name);
     160         814 :     params.set<UserObjectName>("geochemistry_reactor") =
     161         407 :         getParam<UserObjectName>("geochemistry_reactor_name");
     162         814 :     params.set<unsigned>("precision") = getParam<unsigned>("precision");
     163         814 :     params.set<Real>("mol_cutoff") = getParam<Real>("mol_cutoff");
     164         814 :     params.set<Real>("stoichiometry_tolerance") = getParam<Real>("stoichiometry_tolerance");
     165         814 :     params.set<bool>("solver_info") = getParam<bool>("solver_info");
     166         814 :     params.set<UserObjectName>("nearest_node_number_UO") = "geochemistry_nearest_node_number";
     167        1221 :     params.set<ExecFlagEnum>("execute_on") = getParam<ExecFlagEnum>("execute_console_output_on");
     168         407 :     _problem->addOutput(class_name, "geochemistry_console_output", params);
     169         407 :   }
     170        3507 :   else if (_current_task == "add_geochemistry_molality_aux")
     171             :   {
     172         599 :     const ModelGeochemicalDatabase & mgd = _problem
     173         599 :                                                ->getUserObject<GeochemicalModelDefinition>(
     174         599 :                                                    getParam<UserObjectName>("model_definition"))
     175         599 :                                                .getDatabase();
     176             :     // add temperature aux, if requested
     177        1198 :     if (getParam<bool>("add_aux_temperature"))
     178        1194 :       addAuxSpecies("solution_temperature", "H2O", "temperature");
     179             :     // add water, if requested
     180        1198 :     if (getParam<bool>("add_aux_solvent_kg"))
     181        1194 :       addAuxSpecies("kg_solvent_H2O", "H2O", "molal");
     182        1198 :     if (getParam<bool>("add_aux_activity"))
     183        1194 :       addAuxSpecies("activity_H2O", "H2O", "activity");
     184        1198 :     if (getParam<bool>("add_aux_bulk_moles"))
     185        1194 :       addAuxSpecies("bulk_moles_H2O", "H2O", "bulk_moles");
     186             :     // add pH, if requested
     187        1198 :     if (getParam<bool>("add_aux_pH"))
     188        1130 :       addAuxSpecies("pH", "H+", "neglog10a");
     189             : 
     190             :     // add the remaining ones
     191         599 :     const unsigned num_basis = mgd.basis_species_name.size();
     192        3931 :     for (unsigned i = 1; i < num_basis; ++i)
     193             :     {
     194        9996 :       if (getParam<bool>("add_aux_molal") && !mgd.basis_species_mineral[i])
     195        6656 :         addAuxSpecies("molal_" + mgd.basis_species_name[i], mgd.basis_species_name[i], "molal");
     196        9996 :       if (getParam<bool>("add_aux_mg_per_kg") && !mgd.basis_species_mineral[i])
     197        9984 :         addAuxSpecies(
     198        6656 :             "mg_per_kg_" + mgd.basis_species_name[i], mgd.basis_species_name[i], "mg_per_kg");
     199        9996 :       if (getParam<bool>("add_aux_free_cm3") && mgd.basis_species_mineral[i])
     200           0 :         addAuxSpecies(
     201           0 :             "free_cm3_" + mgd.basis_species_name[i], mgd.basis_species_name[i], "free_cm3");
     202        9996 :       if (getParam<bool>("add_aux_free_mg") && mgd.basis_species_mineral[i])
     203           0 :         addAuxSpecies("free_mg_" + mgd.basis_species_name[i], mgd.basis_species_name[i], "free_mg");
     204        6664 :       if (getParam<bool>("add_aux_activity"))
     205        9984 :         addAuxSpecies(
     206        6656 :             "activity_" + mgd.basis_species_name[i], mgd.basis_species_name[i], "activity");
     207        6664 :       if (getParam<bool>("add_aux_bulk_moles"))
     208        9984 :         addAuxSpecies(
     209        6656 :             "bulk_moles_" + mgd.basis_species_name[i], mgd.basis_species_name[i], "bulk_moles");
     210             :     }
     211         599 :     const unsigned num_eqm = mgd.eqm_species_name.size();
     212       16237 :     for (unsigned j = 0; j < num_eqm; ++j)
     213             :     {
     214       46914 :       if (getParam<bool>("add_aux_molal") && !mgd.eqm_species_mineral[j])
     215       28996 :         addAuxSpecies("molal_" + mgd.eqm_species_name[j], mgd.eqm_species_name[j], "molal");
     216       46914 :       if (getParam<bool>("add_aux_mg_per_kg") && !mgd.eqm_species_mineral[j])
     217       28996 :         addAuxSpecies("mg_per_kg_" + mgd.eqm_species_name[j], mgd.eqm_species_name[j], "mg_per_kg");
     218       46914 :       if (getParam<bool>("add_aux_free_cm3") && mgd.eqm_species_mineral[j])
     219        2272 :         addAuxSpecies("free_cm3_" + mgd.eqm_species_name[j], mgd.eqm_species_name[j], "free_cm3");
     220       46914 :       if (getParam<bool>("add_aux_free_mg") && mgd.eqm_species_mineral[j])
     221        2272 :         addAuxSpecies("free_mg_" + mgd.eqm_species_name[j], mgd.eqm_species_name[j], "free_mg");
     222       31276 :       if (getParam<bool>("add_aux_activity"))
     223       31268 :         addAuxSpecies("activity_" + mgd.eqm_species_name[j], mgd.eqm_species_name[j], "activity");
     224       31276 :       if (getParam<bool>("add_aux_bulk_moles"))
     225       46902 :         addAuxSpecies(
     226       31268 :             "bulk_moles_" + mgd.eqm_species_name[j], mgd.eqm_species_name[j], "bulk_moles");
     227             :     }
     228             :     // add the kinetic aux variables
     229         599 :     const unsigned num_kin = mgd.kin_species_name.size();
     230         713 :     for (unsigned k = 0; k < num_kin; ++k)
     231             :     {
     232         342 :       if (getParam<bool>("add_aux_free_cm3") && mgd.kin_species_mineral[k])
     233         196 :         addAuxSpecies("free_cm3_" + mgd.kin_species_name[k], mgd.kin_species_name[k], "free_cm3");
     234         342 :       if (getParam<bool>("add_aux_free_mg") && mgd.kin_species_mineral[k])
     235         196 :         addAuxSpecies("free_mg_" + mgd.kin_species_name[k], mgd.kin_species_name[k], "free_mg");
     236         228 :       if (getParam<bool>("add_aux_kinetic_moles"))
     237         228 :         addAuxSpecies("moles_" + mgd.kin_species_name[k], mgd.kin_species_name[k], "kinetic_moles");
     238         228 :       if (getParam<bool>("add_aux_kinetic_additions"))
     239         342 :         addAuxSpecies(
     240         228 :             "mol_change_" + mgd.kin_species_name[k], mgd.kin_species_name[k], "kinetic_additions");
     241             :     }
     242             : 
     243             :     // add surface stuff
     244         677 :     for (const auto & mineral : mgd.surface_sorption_name)
     245             :     {
     246         156 :       if (getParam<bool>("add_aux_surface_charge"))
     247         156 :         addAuxSpecies("surface_charge_" + mineral, mineral, "surface_charge");
     248         156 :       if (getParam<bool>("add_aux_surface_potential"))
     249         156 :         addAuxSpecies("surface_potential_" + mineral, mineral, "surface_potential");
     250             :     }
     251             :   }
     252        4345 : }
     253             : 
     254             : void
     255       79381 : AddGeochemistrySolverAction::addAuxSpecies(const std::string & var_name,
     256             :                                            const std::string & species_name,
     257             :                                            const std::string & quantity)
     258             : {
     259             :   // add AuxVariable
     260       79381 :   auto var_params = _factory.getValidParams("MooseVariable");
     261       79381 :   _problem->addAuxVariable("MooseVariable", var_name, var_params);
     262             :   // add AuxKernel
     263       79381 :   const std::string class_name = "GeochemistryQuantityAux";
     264       79381 :   auto params = _factory.getValidParams(class_name);
     265       79381 :   params.set<std::string>("species") = species_name;
     266       79381 :   params.set<MooseEnum>("quantity") = quantity;
     267      238143 :   params.set<UserObjectName>("reactor") = getParam<UserObjectName>("geochemistry_reactor_name");
     268      158762 :   params.set<AuxVariableName>("variable") = var_name;
     269       79381 :   params.set<ExecFlagEnum>("execute_on") = EXEC_TIMESTEP_END;
     270       79381 :   _problem->addAuxKernel(class_name, var_name, params);
     271      158762 : }

Generated by: LCOV version 1.14