10#ifdef MOOSE_LIBTORCH_ENABLED
13#include "libmesh/petsc_vector.h"
29 "This user object provides an interface to libtorch for finite element "
30 "interpolation of variables and their gradients. It gathers the shape "
31 "functions and DOF maps for each variable in the assembly and provides "
32 "them as libtorch tensors for use in batched finite-element kernels.");
35 "assembly",
"The TorchAssembly object to use to provide assembly information");
53 auto [it, success] =
_vars.emplace(var_name, at::Tensor());
58 _phis.emplace(var->feType(), &var->phi());
68 auto [it, success] =
_grad_vars.emplace(var_name, at::Tensor());
73 _grad_phis.emplace(var->feType(), &var->gradPhi());
85 const auto it =
_torch_phi.find(var->feType());
89 _phis.emplace(var->feType(), &var->phi());
90 auto [it2, success] =
_torch_phi.emplace(var->feType(), at::Tensor());
103 _grad_phis.emplace(var->feType(), &var->gradPhi());
104 auto [it2, success] =
_torch_grad_phi.emplace(var->feType(), at::Tensor());
114const std::vector<dof_id_type> &
134 mooseError(
"TorchFEInterpolation only supports variables of type MooseVariableFE<Real>");
136 if (var_fe->scalingFactor() != 1)
137 mooseError(
"Scaling factors other than unity are not yet supported");
143 "' must be defined on all blocks '",
157 mooseError(
"Only solution vectors of type PetscVector are currently supported");
200 for (
const auto & [var_name, var] : main_uo._moose_vars)
203 if (main_uo._phis.count(var->feType()))
205 if (main_uo._grad_phis.count(var->feType()))
213 const auto & other = cast_ref<const TorchFEInterpolation &>(y);
215 "TorchFEInterpolation becomes out of sync with other thread");
220 auto merge_map_vecs = [](
auto & map1,
const auto & map2)
222 for (
const auto & [key, map2_val] : map2)
224 auto & map1_val = map1[key];
225 map1_val.insert(map1_val.end(), map2_val.begin(), map2_val.end());
246 if (!success && std::size_t(it->second) !=
_dof_indices.size())
247 mooseError(
"DOF map size mismatch for variable ",
258 moose_dof_map_global.push_back(dof);
263 for (
const auto & [fetype, phi] :
_phis)
268 moose_phi.push_back((*phi)[i][qp]);
272 for (
const auto & [fetype, grad_phi] :
_grad_phis)
278 moose_grad_phi.push_back((*grad_phi)[i][qp](j));
285 TIME_SECTION(
"finalize", 1,
"Updating FEM context and interpolations for the Torch FEM kernels");
297 TIME_SECTION(
"updateFEMContext", 2,
"Updating FEM context for the Torch FEM kernels");
316 auto ndofe =
_ndofe.at(var->feType());
319 if (moose_dof_map.size() != std::size_t(nelem * ndofe))
321 "dof map size mismatch, expected ", nelem * ndofe,
" but got ", moose_dof_map.size());
325 at::from_blob(moose_dof_map.data(), {nelem, ndofe}, torch::kInt64).to(device);
340 auto ndofe =
_ndofe.at(fetype);
343 if (moose_phi.size() != std::size_t(nelem * ndofe * nqp))
344 mooseError(
"shape function size mismatch, expected ",
349 at::from_blob(moose_phi.data(), {nelem, ndofe, nqp}, torch::kFloat64).to(device);
362 auto ndofe =
_ndofe.at(fetype);
365 if (moose_grad_phi.size() != std::size_t(nelem * ndofe * nqp * 3))
366 mooseError(
"shape function gradient size mismatch, expected ",
367 nelem * ndofe * nqp * 3,
369 moose_grad_phi.size());
371 at::from_blob(moose_grad_phi.data(), {nelem, ndofe, nqp, 3}, torch::kFloat64).to(device);
378 TIME_SECTION(
"updateInterpolations", 2,
"Updating FEM interpolations for the Torch FEM kernels");
387 for (
auto & [var_name, val] :
_vars)
390 const auto fetype =
_moose_vars[var_name]->feType();
400 const auto fetype =
_moose_vars[var_name]->feType();
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
const ExecFlagType EXEC_INITIAL
const ExecFlagType EXEC_LINEAR
registerMooseObject("MooseApp", TorchFEInterpolation)
virtual const std::set< SubdomainID > & blockIDs() const
Return the block subdomain ids for this object Note, if this is not block restricted,...
static InputParameters validParams()
const Elem *const & _current_elem
The current element pointer (available during execute())
const MooseArray< Point > & _q_point
A MultiMooseEnum object to hold "execute_on" flags.
T & getUserObject(const std::string &name, unsigned int tid=0) const
Get the user object by its name.
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...
torch::DeviceType getLibtorchDevice() const
Get the device torch is supposed to be running on.
const std::string & name() const
Get the name of the class.
MooseApp & _app
The MOOSE application this is associated with.
Class for stuff related to variables.
virtual const NumericVector< Number > *const & currentSolution() const =0
The solution vector that is currently being operated on.
virtual libMesh::DofMap & dofMap()
Gets writeable reference to the dof map.
This user object caches assembly information (JxWxT) from MOOSE as a batched at::Tensor for the Torch...
int64_t numQP() const
Number of quadrature points per element.
int64_t numElem() const
Number of active elements on this rank.
This user object serves as the "interface" for interpolating MOOSE variable values and gradients from...
void invalidateInterpolations()
Invalidate the cached interpolations.
void invalidateFEMContext()
Invalidate the cached FEM context such as dof map, shape functions, etc.
std::unordered_map< FEType, std::vector< Real > > _moose_phi
void initialize() override
Called before execute() is ever called so that data can be cleared.
std::unordered_map< FEType, at::Tensor > _torch_grad_phi
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)
std::unordered_map< std::string, at::Tensor > _vars
coupled variables (by value) requested by other objects
bool _fem_context_up_to_date
Whether the current FEM context is up to date.
virtual void updateFEMContext()
int64_t _local_ndof
Number of local dofs (including ghost dofs)
const at::Tensor & getDofMap(const std::string &var_name)
Get the local dof map associated with a MOOSE variable.
static InputParameters validParams()
std::unordered_map< std::string, at::Tensor > _grad_vars
coupled variables (by gradient) requested by other objects
const at::Tensor & getPhiGradient(const std::string &var_name)
Get the shape function gradient associated with a MOOSE variable.
virtual void updateInterpolations()
std::unordered_map< std::string, const MooseVariableFE< Real > * > _moose_vars
moose variables that have been coupled
std::unordered_map< FEType, const VariablePhiGradient * > _grad_phis
std::vector< dof_id_type > _dof_indices
Helper vector to store local dof indices.
void meshChanged() override
Called on this object when the mesh changes.
const at::Tensor & getGradient(const std::string &var_name)
Get the variable gradient of a MOOSE nonlinear variable converted to a libtorch tensor.
const TorchAssembly & _assembly
Assembly.
void threadJoin(const UserObject &) override
Must override.
std::unordered_map< FEType, int64_t > _ndofe
cached information on the requested function spaces
void execute() override
Execute method.
void initialSetup() override
Gets called at the beginning of the simulation before this object is asked to do its job.
virtual void updateGradPhi()
std::unordered_map< std::string, std::vector< int64_t > > _moose_dof_map
void finalize() override
Finalize.
std::unordered_map< FEType, std::vector< Real > > _moose_grad_phi
std::unordered_map< std::string, std::vector< dof_id_type > > _moose_dof_map_global
bool _interp_up_to_date
Whether the current interpolations are up to date.
int64_t local_ndof() const
std::unordered_map< std::string, at::Tensor > _torch_dof_map
const libMesh::PetscVector< Real > * _petsc_solution
PETSc solution vector.
std::unordered_map< FEType, at::Tensor > _torch_phi
virtual void updateDofMap()
const at::Tensor & getValue(const std::string &var_name)
Get the variable value of a MOOSE nonlinear variable converted to a libtorch tensor.
const at::Tensor & getPhi(const std::string &var_name)
Get the shape function associated with a MOOSE variable.
const MooseVariableFE< Real > * getMOOSEVariable(const std::string &var_name) const
Helper to get the MOOSE variable and check for common restrictions.
virtual void syncWithMainThread()
TorchFEInterpolation(const InputParameters ¶meters)
std::unordered_map< FEType, const VariablePhiValue * > _phis
FEProblemBase & _fe_problem
Reference to the FEProblemBase for this user object.
const THREAD_ID _tid
Thread ID of this postprocessor.
SystemBase & _sys
Reference to the system object for this user object.
Base class for user-specific data.
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
numeric_index_type map_global_to_local_index(const numeric_index_type i) const
const PetscScalar * get_array_read() const
ExecFlagEnum getDefaultExecFlagEnum()
at::Tensor scatter(const at::Tensor &v, const at::Tensor &dof_map)
Gather global solution values into element-local DOF values: out[e,a,...] = v[dof_map[e,...
at::Tensor interpolate(const at::Tensor &elem_dofs, const at::Tensor &basis)
Interpolate element-local DOF values onto quadrature points by contracting over the per-element DOF a...
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
auto index_range(const T &sizable)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
IntRange< T > make_range(T beg, T end)