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 : #pragma once 11 : 12 : #include "MOOSEToNEML2.h" 13 : #include "ElementUserObject.h" 14 : 15 : /** 16 : * @brief Generic gatherer for collecting "batched" MOOSE data for NEML2 17 : * 18 : * It is generic in the sense that it can be used for most MOOSE data types that take the form of 19 : * MooseArray<T>. 20 : * 21 : * It is not so generic in the sense that the collected data is always a std::vector of 22 : * MooseArray<T>, where the vector size is generally the number of elements this ElementUserObject 23 : * operates on, and the MooseArray<T> size is generally the number of quadrature points in each 24 : * element. 25 : * 26 : * @tparam T Type of the underlying MOOSE data, e.g., Real, SymmetricRankTwoTensor, etc. 27 : */ 28 : template <typename T> 29 : class MOOSEToNEML2Batched : public MOOSEToNEML2, public ElementUserObject 30 : { 31 : public: 32 : static InputParameters validParams(); 33 : 34 : MOOSEToNEML2Batched(const InputParameters & params); 35 : 36 : #ifndef NEML2_ENABLED 37 0 : void initialize() override {} 38 0 : void execute() override {} 39 0 : void finalize() override {} 40 0 : void threadJoin(const UserObject &) override {} 41 : #else 42 : void initialize() override; 43 : void execute() override; 44 2951 : void finalize() override {} 45 : void threadJoin(const UserObject &) override; 46 : 47 : neml2::Tensor gatheredData() const override; 48 : 49 : // The number of batches 50 : std::size_t size() const { return _buffer.size(); } 51 : 52 : protected: 53 : /// MOOSE data for the current element 54 : virtual const MooseArray<T> & elemMOOSEData() const = 0; 55 : 56 : /// Intermediate data buffer, filled during the element loop 57 : std::vector<T> _buffer; 58 : #endif 59 : }; 60 : 61 : template <typename T> 62 : InputParameters 63 142725 : MOOSEToNEML2Batched<T>::validParams() 64 : { 65 142725 : auto params = MOOSEToNEML2::validParams(); 66 142725 : params += ElementUserObject::validParams(); 67 : 68 : // Since we use the NEML2 model to evaluate the residual AND the Jacobian at the same time, we 69 : // want to execute this user object only at execute_on = LINEAR (i.e. during residual evaluation). 70 : // The NONLINEAR exec flag below is for computing Jacobian during automatic scaling. 71 142725 : ExecFlagEnum execute_options = MooseUtils::getDefaultExecFlagEnum(); 72 570900 : execute_options = {EXEC_INITIAL, EXEC_LINEAR, EXEC_NONLINEAR}; 73 142725 : params.set<ExecFlagEnum>("execute_on") = execute_options; 74 : 75 285450 : return params; 76 285450 : } 77 : 78 : template <typename T> 79 38 : MOOSEToNEML2Batched<T>::MOOSEToNEML2Batched(const InputParameters & params) 80 38 : : MOOSEToNEML2(params), ElementUserObject(params) 81 : { 82 38 : } 83 : 84 : #ifdef NEML2_ENABLED 85 : template <typename T> 86 : void 87 3303 : MOOSEToNEML2Batched<T>::initialize() 88 : { 89 3303 : _buffer.clear(); 90 3303 : } 91 : 92 : template <typename T> 93 : void 94 29530 : MOOSEToNEML2Batched<T>::execute() 95 : { 96 29530 : const auto & elem_data = this->elemMOOSEData(); 97 105390 : for (auto i : index_range(elem_data)) 98 75860 : _buffer.push_back(elem_data[i]); 99 29530 : } 100 : 101 : template <typename T> 102 : void 103 352 : MOOSEToNEML2Batched<T>::threadJoin(const UserObject & uo) 104 : { 105 : // append vectors 106 352 : const auto & m2n = static_cast<const MOOSEToNEML2Batched<T> &>(uo); 107 352 : _buffer.insert(_buffer.end(), m2n._buffer.begin(), m2n._buffer.end()); 108 352 : } 109 : 110 : template <typename T> 111 : neml2::Tensor 112 1731 : MOOSEToNEML2Batched<T>::gatheredData() const 113 : { 114 1731 : return NEML2Utils::fromBlob(_buffer); 115 : } 116 : #endif