LCOV - code coverage report
Current view: top level - src/neml2/userobjects - MOOSEQuantityToNEML2.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 9a5f1f Lines: 50 80 62.5 %
Date: 2026-06-21 21:23:42 Functions: 14 56 25.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 "MOOSEQuantityToNEML2.h"
      11             : #include "Function.h"
      12             : #include "MooseVariableScalar.h"
      13             : 
      14             : #define registerMOOSEQuantityToNEML2(T)                                                            \
      15             :   registerMooseObject("MooseApp", MOOSE##T##ToNEML2);                                              \
      16             :   registerMooseObject("MooseApp", MOOSEOld##T##ToNEML2)
      17             : 
      18             : registerMOOSEQuantityToNEML2(Real);
      19             : registerMOOSEQuantityToNEML2(RankTwoTensor);
      20             : registerMOOSEQuantityToNEML2(SymmetricRankTwoTensor);
      21             : registerMOOSEQuantityToNEML2(RealVectorValue);
      22             : 
      23             : template <typename T, unsigned int state>
      24             : InputParameters
      25       24571 : MOOSEQuantityToNEML2<T, state>::validParams()
      26             : {
      27       24571 :   auto params = MOOSEToNEML2::validParams();
      28       24571 :   params += ElementUserObject::validParams();
      29             : 
      30       24571 :   params.addClassDescription(
      31             :       "Gather a MOOSE quantity of type " + demangle(typeid(T).name()) +
      32             :       " for insertion into the specified input or model parameter of a NEML2 model.");
      33       98284 :   params.template addRequiredParam<std::string>("from_moose",
      34             :                                                 "Name of the MOOSE quantity to read from");
      35       98284 :   MooseEnum moose_type("TIME SCALAR FUNCTION VARIABLE MATERIAL", "MATERIAL");
      36       73713 :   params.template addParam<MooseEnum>(
      37             :       "quantity_type", moose_type, "Type of the MOOSE quantity to read from.");
      38             : 
      39             :   // Since we use the NEML2 model to evaluate the residual AND the Jacobian at the same time, we
      40             :   // want to execute this user object only at execute_on = LINEAR (i.e. during residual evaluation).
      41             :   // The NONLINEAR exec flag below is for computing Jacobian during automatic scaling.
      42       24571 :   ExecFlagEnum execute_options = MooseUtils::getDefaultExecFlagEnum();
      43       98284 :   execute_options = {EXEC_INITIAL, EXEC_LINEAR, EXEC_NONLINEAR};
      44       24571 :   params.set<ExecFlagEnum>("execute_on") = execute_options;
      45             : 
      46       49142 :   return params;
      47       49142 : }
      48             : 
      49             : template <typename T, unsigned int state>
      50          42 : MOOSEQuantityToNEML2<T, state>::MOOSEQuantityToNEML2(const InputParameters & params)
      51             :   : MOOSEToNEML2(params),
      52           0 :     ElementUserObject(params)
      53             : #ifdef NEML2_ENABLED
      54             :     ,
      55          42 :     _type(getParam<MooseEnum>("quantity_type").template getEnum<NEML2Utils::MOOSEIOType>()),
      56          42 :     _var_scalar(
      57          42 :         _type == NEML2Utils::MOOSEIOType::SCALAR && state == 0
      58          42 :             ? &this->_fe_problem.getScalarVariable(_tid, getParam<std::string>("from_moose")).sln()
      59             :             : nullptr),
      60          42 :     _var_scalar_old(
      61           0 :         _type == NEML2Utils::MOOSEIOType::SCALAR && state == 1
      62           0 :             ? &this->_fe_problem.getScalarVariable(_tid, getParam<std::string>("from_moose"))
      63           0 :                    .slnOld()
      64             :             : nullptr),
      65          84 :     _func(_type == NEML2Utils::MOOSEIOType::FUNCTION
      66          42 :               ? &this->_fe_problem.getFunction(getParam<std::string>("from_moose"), _tid)
      67             :               : nullptr),
      68          42 :     _mat_prop(
      69          42 :         _type == NEML2Utils::MOOSEIOType::MATERIAL && state == 0
      70          58 :             ? &this->template getMaterialPropertyByName<T>(getParam<std::string>("from_moose"))
      71             :             : nullptr),
      72          42 :     _mat_prop_old(
      73           0 :         _type == NEML2Utils::MOOSEIOType::MATERIAL && state == 1
      74           0 :             ? &this->template getMaterialPropertyOldByName<T>(getParam<std::string>("from_moose"))
      75             :             : nullptr),
      76          84 :     _var(_type == NEML2Utils::MOOSEIOType::VARIABLE && state == 0
      77          94 :              ? &this->_fe_problem.getStandardVariable(_tid, getParam<std::string>("from_moose"))
      78          26 :                     .sln()
      79             :              : nullptr),
      80          42 :     _var_old(_type == NEML2Utils::MOOSEIOType::VARIABLE && state == 1
      81           0 :                  ? &this->_fe_problem.getStandardVariable(_tid, getParam<std::string>("from_moose"))
      82           0 :                         .slnOld()
      83             :                  : nullptr),
      84          84 :     _batched(_type != NEML2Utils::MOOSEIOType::TIME && _type != NEML2Utils::MOOSEIOType::SCALAR)
      85             : #endif
      86             : {
      87          42 : }
      88             : 
      89             : #ifdef NEML2_ENABLED
      90             : template <typename T, unsigned int state>
      91             : void
      92        3411 : MOOSEQuantityToNEML2<T, state>::initialize()
      93             : {
      94        3411 :   _buffer.clear();
      95        3411 : }
      96             : 
      97             : template <typename T, unsigned int state>
      98             : void
      99       38230 : MOOSEQuantityToNEML2<T, state>::execute()
     100             : {
     101       38230 :   if (!_batched)
     102           0 :     return;
     103             : 
     104      148890 :   for (unsigned int qp = 0; qp < _qrule->n_points(); qp++)
     105      110660 :     _buffer.emplace_back(qpData(qp));
     106             : }
     107             : 
     108             : template <typename T, unsigned int state>
     109             : void
     110         352 : MOOSEQuantityToNEML2<T, state>::threadJoin(const UserObject & uo)
     111             : {
     112         352 :   if (!_batched)
     113           0 :     return;
     114             :   // append vectors
     115         352 :   const auto & m2n = static_cast<const MOOSEQuantityToNEML2<T, state> &>(uo);
     116         352 :   _buffer.insert(_buffer.end(), m2n._buffer.begin(), m2n._buffer.end());
     117             : }
     118             : 
     119             : template <typename T, unsigned int state>
     120             : neml2::Tensor
     121        1821 : MOOSEQuantityToNEML2<T, state>::gatheredData() const
     122             : {
     123        1821 :   if (!_batched)
     124             :   {
     125           0 :     switch (_type)
     126             :     {
     127           0 :       case NEML2Utils::MOOSEIOType::TIME:
     128           0 :         return state == 0 ? neml2::Scalar::full(_t, neml2::kFloat64)
     129           0 :                           : neml2::Scalar::full(_t_old, neml2::kFloat64);
     130           0 :       case NEML2Utils::MOOSEIOType::SCALAR:
     131           0 :         return state == 0 ? neml2::Scalar::full((*_var_scalar)[0], neml2::kFloat64)
     132           0 :                           : neml2::Scalar::full((*_var_scalar_old)[0], neml2::kFloat64);
     133           0 :       case NEML2Utils::MOOSEIOType::FUNCTION:
     134             :       case NEML2Utils::MOOSEIOType::VARIABLE:
     135             :       case NEML2Utils::MOOSEIOType::MATERIAL:
     136           0 :         mooseError(
     137             :             "Unbatched quantity cannot be of type MATERIAL or VARIABLE. This should never happen.");
     138           0 :       default:
     139           0 :         mooseError("Invalid MOOSE quantity type. This should never happen.");
     140             :     }
     141             :   }
     142             : 
     143        1821 :   return NEML2Utils::fromBlob(_buffer);
     144             : }
     145             : 
     146             : template <typename T, unsigned int state>
     147             : T
     148      110660 : MOOSEQuantityToNEML2<T, state>::qpData(unsigned int qp) const
     149             : {
     150             :   mooseAssert(
     151             :       _batched,
     152             :       "elemMOOSEData should only be called for batched quantities. This should never happen.");
     153             : 
     154             :   // non-scalar type can only be MATERIAL
     155             :   if constexpr (!std::is_same_v<T, Real>)
     156           0 :     return state == 0 ? (*_mat_prop)[qp] : (*_mat_prop_old)[qp];
     157             :   else
     158      110660 :     switch (_type)
     159             :     {
     160           0 :       case NEML2Utils::MOOSEIOType::TIME:
     161           0 :         mooseError("Batched quantity cannot be of type TIME. This should never happen.");
     162           0 :       case NEML2Utils::MOOSEIOType::SCALAR:
     163           0 :         mooseError("Batched quantity cannot be of type SCALAR. This should never happen.");
     164           0 :       case NEML2Utils::MOOSEIOType::FUNCTION:
     165           0 :         return _func->value(state == 0 ? _t : _t_old, _q_point[qp]);
     166       76460 :       case NEML2Utils::MOOSEIOType::VARIABLE:
     167       76460 :         return state == 0 ? (*_var)[qp] : (*_var_old)[qp];
     168       34200 :       case NEML2Utils::MOOSEIOType::MATERIAL:
     169       34200 :         return state == 0 ? (*_mat_prop)[qp] : (*_mat_prop_old)[qp];
     170           0 :       default:
     171           0 :         mooseError("Invalid MOOSE quantity type. This should never happen.");
     172             :     }
     173             : }
     174             : #endif
     175             : 
     176             : #define instantiateMOOSEQuantityToNEML2(T)                                                         \
     177             :   template class MOOSEQuantityToNEML2<T, 0>;                                                       \
     178             :   template class MOOSEQuantityToNEML2<T, 1>
     179             : 
     180             : instantiateMOOSEQuantityToNEML2(Real);
     181             : instantiateMOOSEQuantityToNEML2(RankTwoTensor);
     182             : instantiateMOOSEQuantityToNEML2(SymmetricRankTwoTensor);
     183             : instantiateMOOSEQuantityToNEML2(RealVectorValue);

Generated by: LCOV version 1.14