https://mooseframework.inl.gov
MOOSEQuantityToNEML2.C
Go to the documentation of this file.
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 
22 
23 template <typename T, unsigned int state>
26 {
27  auto params = MOOSEToNEML2::validParams();
29 
30  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  params.template addRequiredParam<std::string>("from_moose",
34  "Name of the MOOSE quantity to read from");
35  MooseEnum moose_type("TIME SCALAR FUNCTION VARIABLE MATERIAL", "MATERIAL");
36  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.
43  execute_options = {EXEC_INITIAL, EXEC_LINEAR, EXEC_NONLINEAR};
44  params.set<ExecFlagEnum>("execute_on") = execute_options;
45 
46  return params;
47 }
48 
49 template <typename T, unsigned int state>
51  : MOOSEToNEML2(params),
52  ElementUserObject(params)
53 #ifdef NEML2_ENABLED
54  ,
55  _type(getParam<MooseEnum>("quantity_type").template getEnum<NEML2Utils::MOOSEIOType>()),
56  _var_scalar(
57  _type == NEML2Utils::MOOSEIOType::SCALAR && state == 0
58  ? &this->_fe_problem.getScalarVariable(_tid, getParam<std::string>("from_moose")).sln()
59  : nullptr),
60  _var_scalar_old(
61  _type == NEML2Utils::MOOSEIOType::SCALAR && state == 1
62  ? &this->_fe_problem.getScalarVariable(_tid, getParam<std::string>("from_moose"))
63  .slnOld()
64  : nullptr),
65  _func(_type == NEML2Utils::MOOSEIOType::FUNCTION
66  ? &this->_fe_problem.getFunction(getParam<std::string>("from_moose"), _tid)
67  : nullptr),
68  _mat_prop(
69  _type == NEML2Utils::MOOSEIOType::MATERIAL && state == 0
70  ? &this->template getMaterialPropertyByName<T>(getParam<std::string>("from_moose"))
71  : nullptr),
72  _mat_prop_old(
73  _type == NEML2Utils::MOOSEIOType::MATERIAL && state == 1
74  ? &this->template getMaterialPropertyOldByName<T>(getParam<std::string>("from_moose"))
75  : nullptr),
76  _var(_type == NEML2Utils::MOOSEIOType::VARIABLE && state == 0
77  ? &this->_fe_problem.getStandardVariable(_tid, getParam<std::string>("from_moose"))
78  .sln()
79  : nullptr),
80  _var_old(_type == NEML2Utils::MOOSEIOType::VARIABLE && state == 1
81  ? &this->_fe_problem.getStandardVariable(_tid, getParam<std::string>("from_moose"))
82  .slnOld()
83  : nullptr),
84  _batched(_type != NEML2Utils::MOOSEIOType::TIME && _type != NEML2Utils::MOOSEIOType::SCALAR)
85 #endif
86 {
87 }
88 
89 #ifdef NEML2_ENABLED
90 template <typename T, unsigned int state>
91 void
93 {
94  _buffer.clear();
95 }
96 
97 template <typename T, unsigned int state>
98 void
100 {
101  if (!_batched)
102  return;
103 
104  for (unsigned int qp = 0; qp < _qrule->n_points(); qp++)
105  _buffer.emplace_back(qpData(qp));
106 }
107 
108 template <typename T, unsigned int state>
109 void
111 {
112  if (!_batched)
113  return;
114  // append vectors
115  const auto & m2n = static_cast<const MOOSEQuantityToNEML2<T, state> &>(uo);
116  _buffer.insert(_buffer.end(), m2n._buffer.begin(), m2n._buffer.end());
117 }
118 
119 template <typename T, unsigned int state>
120 neml2::Tensor
122 {
123  if (!_batched)
124  {
125  switch (_type)
126  {
128  return state == 0 ? neml2::Scalar::full(_t, neml2::kFloat64)
129  : neml2::Scalar::full(_t_old, neml2::kFloat64);
131  return state == 0 ? neml2::Scalar::full((*_var_scalar)[0], neml2::kFloat64)
132  : neml2::Scalar::full((*_var_scalar_old)[0], neml2::kFloat64);
136  mooseError(
137  "Unbatched quantity cannot be of type MATERIAL or VARIABLE. This should never happen.");
138  default:
139  mooseError("Invalid MOOSE quantity type. This should never happen.");
140  }
141  }
142 
143  return NEML2Utils::fromBlob(_buffer);
144 }
145 
146 template <typename T, unsigned int state>
147 T
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  return state == 0 ? (*_mat_prop)[qp] : (*_mat_prop_old)[qp];
157  else
158  switch (_type)
159  {
161  mooseError("Batched quantity cannot be of type TIME. This should never happen.");
163  mooseError("Batched quantity cannot be of type SCALAR. This should never happen.");
165  return _func->value(state == 0 ? _t : _t_old, _q_point[qp]);
167  return state == 0 ? (*_var)[qp] : (*_var_old)[qp];
169  return state == 0 ? (*_mat_prop)[qp] : (*_mat_prop_old)[qp];
170  default:
171  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 
std::string name(const ElemQuality q)
A MultiMooseEnum object to hold "execute_on" flags.
Definition: ExecFlagEnum.h:21
MOOSEQuantityToNEML2(const InputParameters &params)
SCALAR
registerMOOSEQuantityToNEML2(Real)
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:311
static InputParameters validParams()
Gather a MOOSE quantity for insertion into the NEML2 model.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
ExecFlagEnum getDefaultExecFlagEnum()
Definition: MooseUtils.C:961
void execute() override
Execute method.
void threadJoin(const UserObject &) override
Must override.
neml2::Tensor gatheredData() const override
Convert data gathered from MOOSE into neml2::Tensor.
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition: MooseEnum.h:54
const ExecFlagType EXEC_LINEAR
Definition: Moose.C:31
instantiateMOOSEQuantityToNEML2(Real)
std::string demangle(const char *name)
T qpData(unsigned int) const
const ExecFlagType EXEC_NONLINEAR
Definition: Moose.C:33
static InputParameters validParams()
Common interface for inserting gathered MOOSE data into the NEML2 material model. ...
Definition: MOOSEToNEML2.h:28
static InputParameters validParams()
Definition: MOOSEToNEML2.C:13
void initialize() override
Called before execute() is ever called so that data can be cleared.
Base class for user-specific data.
Definition: UserObject.h:19
neml2::Tensor fromBlob(const std::vector< T > &data)
Map from std::vector<T> to neml2::Tensor without copying the data.
Definition: NEML2Utils.h:112
const ExecFlagType EXEC_INITIAL
Definition: Moose.C:30