https://mooseframework.inl.gov
Loading...
Searching...
No Matches
Classes | Enumerations | Functions | Variables
NEML2Utils Namespace Reference

Classes

struct  Layout
 
struct  Layout< RankFourTensor >
 
struct  Layout< RankTwoTensor >
 
struct  Layout< Real >
 
struct  Layout< RealVectorValue >
 
struct  Layout< SymmetricRankFourTensor >
 
struct  Layout< SymmetricRankTwoTensor >
 
class  ScopedDefaultDtype
 RAII guard forcing libtorch's default scalar type to Float64 for its lifetime, restoring the previous default on destruction. More...
 
class  ScopedNumThreads
 RAII guard that pins libtorch's intra-op thread count for the current scope and restores the previous value on destruction. More...
 

Enumerations

enum class  MOOSEIOType {
  TIME , SCALAR , FUNCTION , VARIABLE ,
  MATERIAL
}
 

Functions

std::string stringify (MOOSEIOType type)
 
std::pair< std::string, int > parseLag (const std::string &name)
 Parse NEML2 v3 lag notation: "var~N" is the N-th old value of a variable (var~1 == old var, var~2 == older, ...).
 
std::string lagName (const std::string &base, int lag)
 Inverse of parseLag: build the variable name for a base name + lag.
 
bool contains (const std::vector< std::string > &v, const std::string &s)
 Whether a vector of strings contains a given string.
 
template<typename T >
at::Tensor fromBlob (const std::vector< T > &data)
 Map from std::vector<T> to an at::Tensor without copying the data.
 
template<typename T >
void copyTensorToMOOSEData (const at::Tensor &src, T &dest)
 Directly copy a contiguous chunk of memory of a at::Tensor to a MOOSE data of type T.
 
template<typename T >
void copyBlobToMOOSEData (const Real *src, T &dest)
 Copy one element's worth of doubles from a contiguous host buffer into a MOOSE datum of type T.
 
void redirectLogsToConsole (const ConsoleStream &console)
 Route NEML2's log output into MOOSE's console.
 
void dumpInputsToTorchScript (const std::map< std::string, at::Tensor > &inputs, const std::string &filename)
 Serialize a set of named NEML2 input tensors to a TorchScript archive at filename (a torch::jit::Module whose buffers are the input tensors), loadable offline in Python via torch.jit.load.
 
std::string docstring (const std::string &desc)
 Augment docstring if NEML2 is not enabled.
 
void assertNEML2Enabled ()
 Assert that NEML2 is enabled.
 

Variables

static std::string NEML2_help_message
 
static const std::string missing_neml2
 

Enumeration Type Documentation

◆ MOOSEIOType

enum class NEML2Utils::MOOSEIOType
strong
Enumerator
TIME 
SCALAR 
FUNCTION 
VARIABLE 
MATERIAL 

Definition at line 41 of file NEML2Utils.h.

42{
43 // unbatched
44 TIME,
45 SCALAR,
46 // batched
50};

Function Documentation

◆ assertNEML2Enabled()

void NEML2Utils::assertNEML2Enabled ( )

Assert that NEML2 is enabled.

A MooseError is raised if NEML2 is not enabled.

Definition at line 90 of file NEML2Utils.C.

91{
92#ifndef NEML2_ENABLED
93 mooseError(missing_neml2);
94#endif
95}
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311

Referenced by NEML2Action::NEML2Action(), NEML2ActionCommon::NEML2ActionCommon(), and NEML2ToMOOSEMaterialProperty< T >::NEML2ToMOOSEMaterialProperty().

◆ contains()

bool NEML2Utils::contains ( const std::vector< std::string > &  v,
const std::string &  s 
)
inline

Whether a vector of strings contains a given string.

Definition at line 78 of file NEML2Utils.h.

79{
80 return std::find(v.begin(), v.end(), s) != v.end();
81}

◆ copyBlobToMOOSEData()

template<typename T >
void NEML2Utils::copyBlobToMOOSEData ( const Real *  src,
T &  dest 
)

Copy one element's worth of doubles from a contiguous host buffer into a MOOSE datum of type T.

This is the raw-pointer analogue of copyTensorToMOOSEData: src must point at a run of Layout<T>::strides[0] doubles (one element) inside a contiguous, host-resident, double-typed buffer – e.g. the data of a NEML2 output tensor already moved to the host. It performs a plain memcpy with no per-call at::Tensor allocation/dispatch, which matters when retrieving outputs element-by-element over a large batch. The layout assumption is identical to copyTensorToMOOSEData (row-major, matching Layout<T>).

Definition at line 195 of file NEML2Utils.h.

196{
197 std::memcpy(reinterpret_cast<Real *>(&dest), src, Layout<T>::strides[0] * sizeof(Real));
198}

◆ copyTensorToMOOSEData()

template<typename T >
void NEML2Utils::copyTensorToMOOSEData ( const at::Tensor &  src,
T &  dest 
)

Directly copy a contiguous chunk of memory of a at::Tensor to a MOOSE data of type T.

This assumes the at::Tensor and T have the same layout, for example both row-major with T = RankTwoTensor. If the layouts are different, we may need to reshape/reorder/transpose the at::Tensor before copying.

For this method to work,

  1. the address of dest must align with the first element of the data,
  2. the number of elements in dest must match the number of elements in src,
  3. the src tensor must be of type at::kDouble, and
  4. data in dest must be reinterpretable as Real.

Definition at line 166 of file NEML2Utils.h.

167{
168 if (src.dtype() != at::kDouble)
170 "Cannot copy at::Tensor with dtype ", src.dtype(), " into ", demangle(typeid(T).name()));
171 if (src.numel() != Layout<T>::strides[0])
172 mooseError("Cannot copy at::Tensor with shape ",
173 src.sizes(),
174 " into ",
175 demangle(typeid(T).name()),
176 " with different number of elements.");
177 auto dest_tensor = at::from_blob(
178 reinterpret_cast<Real *>(&dest), Layout<T>::shape, at::TensorOptions().dtype(at::kDouble));
179 dest_tensor.copy_(src.reshape(Layout<T>::shape));
180}

◆ docstring()

std::string NEML2Utils::docstring ( const std::string &  desc)

Augment docstring if NEML2 is not enabled.

Definition at line 80 of file NEML2Utils.C.

81{
82#ifndef NEML2_ENABLED
83 return missing_neml2 + " (Original description: " + desc + ")";
84#else
85 return desc;
86#endif
87}
static const std::string missing_neml2
Definition NEML2Utils.C:76

◆ dumpInputsToTorchScript()

void NEML2Utils::dumpInputsToTorchScript ( const std::map< std::string, at::Tensor > &  inputs,
const std::string &  filename 
)

Serialize a set of named NEML2 input tensors to a TorchScript archive at filename (a torch::jit::Module whose buffers are the input tensors), loadable offline in Python via torch.jit.load.

Used to capture the exact inputs of a failed constitutive solve so the model can be re-evaluated independently of MOOSE. Buffer names are the input variable names with characters that are not valid identifiers ('~', '/') replaced by '_'; the original names are recoverable from the NEML2 model's input list.

Definition at line 25 of file NEML2Utils.C.

27{
28 // Stash each defined input tensor (moved to host) as a buffer on a TorchScript module, then save.
29 // Buffer names must be valid identifiers, so sanitize '~'/'/' etc. to '_'.
30 torch::jit::Module mod("neml2_failed_inputs");
31 for (const auto & [name, tensor] : inputs)
32 {
33 if (!tensor.defined())
34 continue;
35 std::string key = name;
36 for (auto & c : key)
37 if (!std::isalnum(static_cast<unsigned char>(c)) && c != '_')
38 c = '_';
39 mod.register_buffer(key, tensor.detach().to(at::kCPU).contiguous());
40 }
41 mod.save(filename);
42}
if(!dmm->_nl) SETERRQ(PETSC_COMM_WORLD

◆ fromBlob()

template<typename T >
at::Tensor NEML2Utils::fromBlob ( const std::vector< T > &  data)

Map from std::vector<T> to an at::Tensor without copying the data.

This method is used in gatherers which gather data from MOOSE as input variables to the NEML2 material model. So in theory, we only need to provide Layout specializations for MOOSE types that can potentially be used as NEML2 input variables. The returned tensor has shape (data.size(), *Layout<T>::shape), i.e. a leading batch axis followed by the variable's base shape, which is the (*B, *base_shape) convention NEML2 v3's C++ API expects.

For this method to work, the underlying data in data must be reinterpretable as Real (at::kDouble). The data class T must also be aligned and follow the striding implied by Layout<T>::shape. The data class T must also have no padding or overhead.

Definition at line 139 of file NEML2Utils.h.

140{
141 // Full shape: leading batch dim followed by the base shape.
142 std::vector<int64_t> shape;
143 shape.reserve(1 + Layout<T>::shape.size());
144 shape.push_back(static_cast<int64_t>(data.size()));
145 shape.insert(shape.end(), Layout<T>::shape.begin(), Layout<T>::shape.end());
146 // The const_cast is fine because torch works with non-const ptr so that it can optionally handle
147 // deallocation. But we are not going to let torch do that.
148 return at::from_blob(const_cast<T *>(data.data()), shape, at::TensorOptions().dtype(at::kDouble));
149}

Referenced by MOOSEQuantityToNEML2< T, state >::gatheredData().

◆ lagName()

std::string NEML2Utils::lagName ( const std::string &  base,
int  lag 
)
inline

Inverse of parseLag: build the variable name for a base name + lag.

Definition at line 71 of file NEML2Utils.h.

72{
73 return lag == 0 ? base : base + "~" + std::to_string(lag);
74}

Referenced by lagName().

◆ parseLag()

std::pair< std::string, int > NEML2Utils::parseLag ( const std::string &  name)
inline

Parse NEML2 v3 lag notation: "var~N" is the N-th old value of a variable (var~1 == old var, var~2 == older, ...).

Returns {base_name, lag}; lag == 0 when there is no "~N" suffix. Defined here (shared, namespaced, inline) so the NEML2 unity build does not see duplicate definitions.

Definition at line 58 of file NEML2Utils.h.

59{
60 const auto pos = name.rfind('~');
61 if (pos == std::string::npos)
62 return {name, 0};
63 const auto suffix = name.substr(pos + 1);
64 if (suffix.empty() || suffix.find_first_not_of("0123456789") != std::string::npos)
65 return {name, 0};
66 return {name.substr(0, pos), std::stoi(suffix)};
67}
std::string name(const ElemQuality q)

Referenced by parseLag().

◆ redirectLogsToConsole()

void NEML2Utils::redirectLogsToConsole ( const ConsoleStream &  console)

Route NEML2's log output into MOOSE's console.

NEML2 v3 emits its diagnostics (warnings, per-solve info, debug detail across all evaluation routes) through a single process-global sink. This installs a sink that writes each already-formatted line (carrying the [neml2:<channel>] prefix) to console, so NEML2's output lands in MOOSE's console instead of raw stdout/stderr. Verbosity levels are left at NEML2's defaults. The sink captures a copy of console (bound to the app-owned OutputWarehouse, valid for the app's lifetime); calling this again – e.g. once per [NEML2] block – is idempotent.

Definition at line 45 of file NEML2Utils.C.

46{
47 // Capture a copy of the ConsoleStream (it binds the app-owned OutputWarehouse by reference, so
48 // the copy stays valid for the app's lifetime) and hand every NEML2 log line to it. The line
49 // already carries the [neml2:<channel>] prefix; NEML2's verbosity levels are left at their
50 // defaults.
51 neml2::aoti::log::set_sink([console](neml2::aoti::log::Level, const std::string & line)
52 { console << line << std::endl; });
53}

Referenced by NEML2ModelInterface< T >::makeModelHandle(), and NEML2Action::NEML2Action().

◆ stringify()

std::string NEML2Utils::stringify ( MOOSEIOType  type)

Definition at line 56 of file NEML2Utils.C.

57{
58 switch (type)
59 {
61 return "TIME";
63 return "SCALAR";
65 return "FUNCTION";
67 return "VARIABLE";
69 return "MATERIAL";
70 default:
71 mooseError("Unknown MOOSE IO type.");
72 }
73}

Referenced by NEML2Action::printSummary().

Variable Documentation

◆ missing_neml2

const std::string NEML2Utils::missing_neml2
static
Initial value:
= "The `NEML2` library is required but not enabled. Refer "
"to the documentation for guidance on how to enable it."

Definition at line 76 of file NEML2Utils.C.

Referenced by assertNEML2Enabled(), and docstring().

◆ NEML2_help_message

std::string NEML2Utils::NEML2_help_message
static
Initial value:
= R""""(
==============================================================================
To debug NEML2 related issues:
1. Build and run MOOSE in dbg mode.
2. Re-run the simulation using the dbg executable, and often times
NEML2 will provide a more helpful error message.
3. If the error message is not helpful, or if there is still no error message,
run the simulation through a debugger: See
https://mooseframework.inl.gov/application_development/debugging.html
4. If the issue is due to a NEML2 bug, feel free to report it at
https://github.com/applied-material-modeling/neml2/issues
==============================================================================
)""""

Definition at line 263 of file NEML2Utils.h.

Referenced by NEML2ModelExecutor::extractOutputs(), NEML2ModelExecutor::fillInputs(), and NEML2ModelExecutor::solve().