13 #include "libmesh/petsc_vector.h" 16 #include <ATen/ops/from_blob.h> 19 #include "neml2/tensors/functions/discretization/scatter.h" 20 #include "neml2/tensors/functions/discretization/interpolate.h" 35 "This user object provides an interface to NEML2 for finite element " 36 "interpolation of variables and their gradients. It gathers the shape " 37 "functions and DOF maps for each variable in the assembly and provides " 38 "them as NEML2 tensors for use in NEML2 models.");
41 "assembly",
"The NEML2Assembly object to use to provide assembly information");
59 auto [it, success] =
_vars.emplace(var_name, neml2::Tensor());
64 _phis.emplace(var->feType(), &var->phi());
74 auto [it, success] =
_grad_vars.emplace(var_name, neml2::Tensor());
79 _grad_phis.emplace(var->feType(), &var->gradPhi());
91 const auto it =
_neml2_phi.find(var->feType());
95 _phis.emplace(var->feType(), &var->phi());
96 auto [it2, success] =
_neml2_phi.emplace(var->feType(), neml2::Tensor());
100 const neml2::Tensor &
109 _grad_phis.emplace(var->feType(), &var->gradPhi());
110 auto [it2, success] =
_neml2_grad_phi.emplace(var->feType(), neml2::Tensor());
114 const neml2::Tensor &
120 const std::vector<dof_id_type> &
140 mooseError(
"NEML2FEInterpolation only supports variables of type MooseVariableFE<Real>");
142 if (var_fe->scalingFactor() != 1)
143 mooseError(
"Scaling factors other than unity are not yet supported");
149 "' must be defined on all blocks '",
163 mooseError(
"Only solution vectors of type PetscVector are currently supported");
206 for (
const auto & [var_name, var] : main_uo._moose_vars)
209 if (main_uo._phis.count(var->feType()))
211 if (main_uo._grad_phis.count(var->feType()))
221 "NEML2FEInterpolation becomes out of sync with other thread");
226 auto merge_map_vecs = [](
auto & map1,
const auto & map2)
228 for (
const auto & [key, map2_val] : map2)
230 auto & map1_val = map1[key];
231 map1_val.insert(map1_val.end(), map2_val.begin(), map2_val.end());
252 if (!success && std::size_t(it->second) !=
_dof_indices.size())
253 mooseError(
"DOF map size mismatch for variable ",
263 moose_dof_map.push_back(
_petsc_solution->map_global_to_local_index(dof));
264 moose_dof_map_global.push_back(dof);
269 for (
const auto & [fetype, phi] :
_phis)
274 moose_phi.push_back((*phi)[i][qp]);
278 for (
const auto & [fetype, grad_phi] :
_grad_phis)
284 moose_grad_phi.push_back((*grad_phi)[i][qp](j));
291 TIME_SECTION(
"finalize", 1,
"Updating FEM context and interpolations for NEML2");
303 TIME_SECTION(
"updateFEMContext", 2,
"Updating FEM context for NEML2");
322 auto ndofe =
_ndofe.at(var->feType());
325 if (moose_dof_map.size() != std::size_t(nelem * ndofe))
327 "dof map size mismatch, expected ", nelem * ndofe,
" but got ", moose_dof_map.size());
331 neml2::Tensor(at::from_blob(moose_dof_map.data(), {nelem, ndofe}, torch::kInt64), 2)
347 auto ndofe =
_ndofe.at(fetype);
350 if (moose_phi.size() != std::size_t(nelem * ndofe * nqp))
351 mooseError(
"shape function size mismatch, expected ",
356 neml2::Tensor(at::from_blob(moose_phi.data(), {nelem, ndofe, nqp}, torch::kFloat64), 3)
370 auto ndofe =
_ndofe.at(fetype);
373 if (moose_grad_phi.size() != std::size_t(nelem * ndofe * nqp * 3))
374 mooseError(
"shape function gradient size mismatch, expected ",
375 nelem * ndofe * nqp * 3,
377 moose_grad_phi.size());
379 neml2::Tensor(at::from_blob(moose_grad_phi.data(), {nelem, ndofe, nqp, 3}, torch::kFloat64),
388 TIME_SECTION(
"updateInterpolations", 2,
"Updating FEM interpolations for NEML2");
391 auto sol = at::from_blob(const_cast<Real *>(
_petsc_solution->get_array_read()),
397 for (
auto & [var_name, val] :
_vars)
400 const auto fetype =
_moose_vars[var_name]->feType();
402 auto sol_scattered = neml2::discretization::scatter(sol, dof_map);
410 const auto fetype =
_moose_vars[var_name]->feType();
412 auto sol_scattered = neml2::discretization::scatter(sol, dof_map);
This user object serves as the "interface" for interpolating MOOSE variable values and gradients from...
const THREAD_ID _tid
Thread ID of this postprocessor.
const neml2::Tensor & getPhiGradient(const std::string &var_name)
Get the shape function gradient associated with a MOOSE variable.
const std::vector< dof_id_type > & getGlobalDofMap(const std::string &var_name)
Similar to getDofMap, but returns the global dof map (as a flattened vector of dof_id_type) ...
virtual void updateInterpolations()
virtual const NumericVector< Number > *const & currentSolution() const =0
The solution vector that is currently being operated on.
const neml2::Tensor & getGradient(const std::string &var_name)
Get the variable gradient of a MOOSE nonlinear variable converted to a NEML2 tensor.
A MultiMooseEnum object to hold "execute_on" flags.
std::unordered_map< FEType, const VariablePhiGradient * > _grad_phis
void initialize() override
Called before execute() is ever called so that data can be cleared.
const MooseArray< Point > & _q_point
T & getUserObject(const std::string &name, unsigned int tid=0) const
Get the user object by its name.
bool _fem_context_up_to_date
Whether the current FEM context is up to date.
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
bool _interp_up_to_date
Whether the current interpolations are up to date.
int64_t numQP() const
Number of quadrature points per element.
static InputParameters validParams()
const NEML2Assembly & _neml2_assembly
Assembly.
const neml2::Tensor & getValue(const std::string &var_name)
Get the variable value of a MOOSE nonlinear variable converted to a NEML2 tensor. ...
std::unordered_map< std::string, neml2::Tensor > _vars
coupled variables (by value) requested by other objects
virtual void updateDofMap()
NEML2FEInterpolation(const InputParameters ¶meters)
virtual const std::set< SubdomainID > & blockIDs() const
Return the block subdomain ids for this object Note, if this is not block restricted, this function returns all mesh subdomain ids.
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
const PetscVector< Real > * _petsc_solution
PETSc solution vector.
virtual const MooseVariableFieldBase & getVariable(const THREAD_ID tid, const std::string &var_name, Moose::VarKindType expected_var_type=Moose::VarKindType::VAR_ANY, Moose::VarFieldType expected_var_field_type=Moose::VarFieldType::VAR_FIELD_ANY) const override
Returns the variable reference for requested variable which must be of the expected_var_type (Nonline...
void initialSetup() override
Gets called at the beginning of the simulation before this object is asked to do its job...
registerMooseObject("MooseApp", NEML2FEInterpolation)
auto max(const L &left, const R &right)
ExecFlagEnum getDefaultExecFlagEnum()
FEProblemBase & _fe_problem
Reference to the FEProblemBase for this user object.
void threadJoin(const UserObject &) override
Must override.
virtual libMesh::DofMap & dofMap()
Gets writeable reference to the dof map.
const std::string & name() const
Get the name of the class.
virtual void syncWithMainThread()
int64_t _local_ndof
Number of local dofs (including ghost dofs)
virtual void updateFEMContext()
std::unordered_map< std::string, neml2::Tensor > _neml2_dof_map
std::unordered_map< std::string, neml2::Tensor > _grad_vars
coupled variables (by gradient) requested by other objects
void invalidateInterpolations()
Invalidate the cached interpolations.
void execute() override
Execute method.
std::unordered_map< FEType, neml2::Tensor > _neml2_phi
torch::DeviceType getLibtorchDevice() const
Get the device torch is supposed to be running on.
MooseApp & _app
The MOOSE application this is associated with.
const ExecFlagType EXEC_LINEAR
static InputParameters validParams()
const neml2::Tensor & getPhi(const std::string &var_name)
Get the shape function associated with a MOOSE variable.
std::unordered_map< FEType, int64_t > _ndofe
cached information on the requested function spaces
int64_t numElem() const
Number of active elements on this rank.
void finalize() override
Finalize.
This user object caches assembly information from MOOSE.
std::unordered_map< FEType, std::vector< Real > > _moose_phi
std::unordered_map< FEType, neml2::Tensor > _neml2_grad_phi
SystemBase & _sys
Reference to the system object for this user object.
const neml2::Tensor & getDofMap(const std::string &var_name)
Get the local dof map associated with a MOOSE variable.
std::unordered_map< FEType, std::vector< Real > > _moose_grad_phi
const MooseVariableFE< Real > * getMOOSEVariable(const std::string &var_name) const
Helper to get the MOOSE variable and check for common restrictions.
const Elem *const & _current_elem
The current element pointer (available during execute())
std::unordered_map< FEType, const VariablePhiValue * > _phis
void meshChanged() override
Called on this object when the mesh changes.
std::unordered_map< std::string, std::vector< dof_id_type > > _moose_dof_map_global
IntRange< T > make_range(T beg, T end)
int64_t local_ndof() const
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type and optionally a file path to the top-level block p...
std::unordered_map< std::string, const MooseVariableFE< Real > * > _moose_vars
moose variables that have been coupled
virtual void updateGradPhi()
void invalidateFEMContext()
Invalidate the cached FEM context such as dof map, shape functions, etc.
void interpolate(InterpMethod m, T &result, const T2 &value1, const T3 &value2, const FaceInfo &fi, const bool one_is_elem)
Provides interpolation of face values for non-advection-specific purposes (although it can/will still...
auto index_range(const T &sizable)
Base class for user-specific data.
std::vector< dof_id_type > _dof_indices
Helper vector to store local dof indices.
std::unordered_map< std::string, std::vector< int64_t > > _moose_dof_map
const ExecFlagType EXEC_INITIAL