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);
|