LCOV - code coverage report
Current view: top level - src/variables - MooseVariableBase.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #32971 (54bef8) with base c6cf66 Lines: 92 102 90.2 %
Date: 2026-05-29 20:35:17 Functions: 10 10 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 "MooseVariableBase.h"
      11             : 
      12             : #include "AddVariableAction.h"
      13             : #include "SubProblem.h"
      14             : #include "SystemBase.h"
      15             : #include "MooseMesh.h"
      16             : #include "MooseApp.h"
      17             : #include "InputParameterWarehouse.h"
      18             : #include "BlockRestrictable.h"
      19             : 
      20             : #include "libmesh/variable.h"
      21             : #include "libmesh/dof_map.h"
      22             : #include "libmesh/system.h"
      23             : #include "libmesh/fe_type.h"
      24             : #include "libmesh/string_to_enum.h"
      25             : 
      26             : using namespace libMesh;
      27             : 
      28             : // Users should never actually create this object
      29             : registerMooseObject("MooseApp", MooseVariableBase);
      30             : 
      31             : InputParameters
      32      404945 : MooseVariableBase::validParams()
      33             : {
      34      404945 :   InputParameters params = MooseObject::validParams();
      35      404945 :   params += BlockRestrictable::validParams();
      36      404945 :   params += OutputInterface::validParams();
      37             : 
      38     2429670 :   params.transferParam<MooseEnum>(AddVariableAction::validParams(), "order");
      39     2429670 :   params.transferParam<MooseEnum>(AddVariableAction::validParams(), "family");
      40             : 
      41             :   // ArrayVariable capability
      42     2024725 :   params.addRangeCheckedParam<unsigned int>(
      43      809890 :       "components", 1, "components>0", "Number of components for an array variable");
      44             : 
      45             :   // Advanced input options
      46     2429670 :   params.transferParam<std::vector<Real>>(AddVariableAction::validParams(), "scaling");
      47     1619780 :   params.addParam<bool>("eigen", false, "True to make this variable an eigen variable");
      48     1619780 :   params.addParam<bool>("fv", false, "True to make this variable a finite volume variable");
      49     1214835 :   params.addParam<bool>("array",
      50      809890 :                         false,
      51             :                         "True to make this variable a array variable regardless of number of "
      52             :                         "components. If 'components' > 1, this will automatically be set to true.");
      53             : 
      54     1619780 :   params.addParam<std::vector<std::string>>(
      55             :       "array_var_component_names",
      56             :       "Only for use with array variables, allows setting custom names for each array variable "
      57             :       "component. If this not set, the default name for each array variable componenet is "
      58             :       "`base_name`+'_'+component number. If used, a name must be provided for each component and "
      59             :       "the values are used to name the components as `base_name`+'_'+ "
      60             :       "`array_var_component_names[component]`.");
      61             : 
      62     1619780 :   params.addParam<SolverSystemName>("solver_sys",
      63             :                                     "nl0",
      64             :                                     "If this variable is a solver variable, this is the "
      65             :                                     "solver system to which it should be added.");
      66     1619780 :   params.addParam<bool>(
      67             :       "disable_p_refinement",
      68             :       "True to disable p-refinement for this variable. Note that because this happens on the "
      69             :       "family basis, users need to have this flag consistently set for all variables in the same "
      70             :       "family. Currently MOOSE disables p-refinement for variables in the following families by "
      71             :       "default: LAGRANGE NEDELEC_ONE RAVIART_THOMAS LAGRANGE_VEC CLOUGH BERNSTEIN and "
      72             :       "RATIONAL_BERNSTEIN.");
      73             : 
      74     1619780 :   params.addParamNamesToGroup("scaling eigen", "Advanced");
      75             : 
      76     1619780 :   params.addParam<bool>("use_dual", false, "True to use dual basis for Lagrange multipliers");
      77     2429670 :   params.transferParam<std::vector<Real>>(AddVariableAction::validParams(), "initial_condition");
      78     2429670 :   params.transferParam<std::string>(AddVariableAction::validParams(), "initial_from_file_var");
      79     1619780 :   params.addParamNamesToGroup("scaling eigen use_dual", "Advanced");
      80             : 
      81      809890 :   params.registerBase("MooseVariableBase");
      82      809890 :   params.addPrivateParam<SystemBase *>("_system_base");
      83      809890 :   params.addPrivateParam<FEProblemBase *>("_fe_problem_base");
      84      809890 :   params.addPrivateParam<Moose::VarKindType>("_var_kind");
      85      809890 :   params.addPrivateParam<unsigned int>("_var_num");
      86      809890 :   params.addPrivateParam<THREAD_ID>("tid");
      87             : 
      88      404945 :   params.addClassDescription(
      89             :       "Base class for Moose variables. This should never be the terminal object type");
      90      404945 :   return params;
      91           0 : }
      92             : 
      93      183856 : MooseVariableBase::MooseVariableBase(const InputParameters & parameters)
      94             :   : MooseObject(parameters),
      95             :     BlockRestrictable(this),
      96             :     OutputInterface(parameters),
      97             :     SetupInterface(this),
      98      183856 :     _sys(*getParam<SystemBase *>("_system_base")), // TODO: get from _fe_problem_base
      99      551568 :     _fe_type(Utility::string_to_enum<Order>(getParam<MooseEnum>("order")),
     100      551568 :              Utility::string_to_enum<FEFamily>(getParam<MooseEnum>("family"))),
     101      367712 :     _var_num(getParam<unsigned int>("_var_num")),
     102      367712 :     _is_eigen(getParam<bool>("eigen")),
     103      367712 :     _var_kind(getParam<Moose::VarKindType>("_var_kind")),
     104      183856 :     _subproblem(_sys.subproblem()),
     105      183856 :     _variable(_sys.system().variable(_var_num)),
     106      367712 :     _assembly(_subproblem.assembly(getParam<THREAD_ID>("_tid"),
     107      183856 :                                    (_var_kind == Moose::VAR_SOLVER) ? _sys.number() : 0)),
     108      183856 :     _dof_map(_sys.dofMap()),
     109      183856 :     _mesh(_subproblem.mesh()),
     110      367712 :     _tid(getParam<THREAD_ID>("tid")),
     111      367712 :     _count(getParam<unsigned int>("components")),
     112      367712 :     _scaling_factor(_count, 1.0),
     113      919280 :     _use_dual(getParam<bool>("use_dual"))
     114             : {
     115      735866 :   scalingFactor(isParamValid("scaling") ? getParam<std::vector<Real>>("scaling")
     116      367270 :                                         : std::vector<Real>(_count, 1.));
     117      564866 :   if (getParam<bool>("fv") && getParam<bool>("eigen"))
     118           0 :     paramError("eigen", "finite volume (fv=true) variables do not have eigen support");
     119      551568 :   if (getParam<bool>("fv") && _fe_type.family != MONOMIAL)
     120           0 :     paramError("family", "finite volume (fv=true) variables must be have MONOMIAL family");
     121      551568 :   if (getParam<bool>("fv") && _fe_type.order != 0)
     122           0 :     paramError("order", "finite volume (fv=true) variables currently support CONST order only");
     123             : 
     124      551568 :   if (isParamValid("array_var_component_names"))
     125             :   {
     126        2485 :     auto name0 = _sys.system().variable(_var_num).name();
     127        2485 :     std::size_t found = name0.find_last_of("_");
     128        2485 :     if (found == std::string::npos)
     129           0 :       mooseError("Error creating ArrayMooseVariable name with base name ", name0);
     130        2485 :     const auto name_base = name0.substr(0, found);
     131        4970 :     const auto & name_endings = getParam<std::vector<std::string>>("array_var_component_names");
     132        8121 :     for (const auto & name : name_endings)
     133        5636 :       _array_var_component_names.push_back(name_base + '_' + name);
     134        2485 :   }
     135      181371 :   else if (_count != 1)
     136           0 :     mooseError("Component size of normal variable (_count) must be one; equals " +
     137           0 :                std::to_string(_count) + "");
     138             : 
     139             :   // check parameters set automatically by SystemBase related to array variables
     140             :   mooseAssert(
     141             :       isArray() ? _count == _array_var_component_names.size() : true,
     142             :       "An inconsistent numer of names or no names were provided for array variable components");
     143      183856 :   if (_count > 1)
     144             :     mooseAssert(isArray(), "Must be true with component > 1");
     145      183856 : }
     146             : 
     147             : const std::string &
     148       24650 : MooseVariableBase::arrayVariableComponent(const unsigned int i) const
     149             : {
     150             :   mooseAssert(
     151             :       i < _array_var_component_names.size(),
     152             :       "Requested array variable component number is greater than the number of component names.");
     153       24650 :   return _array_var_component_names[i];
     154             : }
     155             : 
     156             : const std::vector<dof_id_type> &
     157       10306 : MooseVariableBase::allDofIndices() const
     158             : {
     159       10306 :   const auto it = _sys.subproblem()._var_dof_map.find(name());
     160       10306 :   if (it != _sys.subproblem()._var_dof_map.end())
     161       20612 :     return it->second;
     162             :   else
     163           0 :     mooseError("VariableAllDoFMap not prepared for ",
     164           0 :                name(),
     165             :                " . Check nonlocal coupling requirement for the variable.");
     166             : }
     167             : 
     168             : Order
     169   294930847 : MooseVariableBase::order() const
     170             : {
     171   294930847 :   return _fe_type.order;
     172             : }
     173             : 
     174             : std::vector<dof_id_type>
     175   123537616 : MooseVariableBase::componentDofIndices(const std::vector<dof_id_type> & dof_indices,
     176             :                                        unsigned int component) const
     177             : {
     178             :   mooseAssert(dof_indices.size() % this->count() == 0,
     179             :               "The dof indices container must be a multiple of count");
     180   123537616 :   std::vector<dof_id_type> new_dof_indices(dof_indices.size() / this->count());
     181   668876534 :   for (const auto i : index_range(new_dof_indices))
     182   545338918 :     new_dof_indices[i] = dof_indices[component * new_dof_indices.size() + i];
     183   123537616 :   return new_dof_indices;
     184           0 : }
     185             : 
     186             : void
     187      184997 : MooseVariableBase::scalingFactor(const std::vector<Real> & factor)
     188             : {
     189             :   mooseAssert(factor.size() == _count, "Inconsistent scaling factor size");
     190      373155 :   for (const auto i : make_range(_count))
     191      188158 :     _scaling_factor[i] = factor[i];
     192      184997 : }
     193             : 
     194             : void
     195      178263 : MooseVariableBase::initialSetup()
     196             : {
     197             :   // Currently the scaling vector is only used through AD residual computing objects
     198      189176 :   if ((_var_kind == Moose::VAR_SOLVER) && _subproblem.haveADObjects() &&
     199       32133 :       (_subproblem.automaticScaling() || (std::find_if(_scaling_factor.begin(),
     200             :                                                        _scaling_factor.end(),
     201       10633 :                                                        [](const Real element) {
     202       21266 :                                                          return !MooseUtils::absoluteFuzzyEqual(
     203       10633 :                                                              element, 1.);
     204      199483 :                                                        }) != _scaling_factor.end())))
     205             : 
     206         382 :     _sys.addScalingVector();
     207      178263 : }
     208             : 
     209             : const NumericVector<Number> &
     210      945124 : MooseVariableBase::getSolution(const Moose::StateArg & state) const
     211             : {
     212             :   // It's not safe to use solutionState(0) because it returns the libMesh System solution member
     213             :   // which is wrong during things like finite difference Jacobian evaluation, e.g. when PETSc
     214             :   // perturbs the solution vector we feed these perturbations into the current_local_solution
     215             :   // while the libMesh solution is frozen in the non-perturbed state
     216      945124 :   return (state.state == 0) ? *this->_sys.currentSolution()
     217      945124 :                             : this->_sys.solutionState(state.state, state.iteration_type);
     218             : }

Generated by: LCOV version 1.14