Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,7 @@
path = framework/contrib/neml2
url = ../../applied-material-modeling/neml2.git
update = none
[submodule "framework/contrib/pytorch"]
path = framework/contrib/pytorch
url = ../../pytorch/pytorch.git
update = none
2 changes: 1 addition & 1 deletion conda/moose-dev/meta.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# REMEMBER TO UPDATE the .yaml files for the following packages:
# moose/conda_build_config.yaml
# As well as any directions pertaining to modifying those files.
{% set version = "2026.04.21" %}
{% set version = "2026.05.06" %}

package:
name: moose-dev
Expand Down
2 changes: 1 addition & 1 deletion framework/contrib/neml2
Submodule neml2 updated 966 files
17 changes: 14 additions & 3 deletions framework/contrib/neml2.mk
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,20 @@ endif
# NEML2 flags
comma := ,
neml2_CPPFLAGS += -DNEML2_ENABLED
neml2_INCLUDES += $(shell pkg-config --cflags $(NEML2_PC))
neml2_LDFLAGS += $(foreach libdir,$(shell pkg-config --libs-only-L $(NEML2_PC)),$(patsubst -L%,-Wl$(comma)-rpath$(comma)%,$(libdir)))
neml2_LIBS += $(shell pkg-config --libs $(NEML2_PC))

# When MOOSE manages torch separately (ENABLE_LIBTORCH=true), filter torch flags out of
# NEML2's bundled pkg-config. Otherwise libtool deduplicates the -l flags keeping the last
# occurrence (embedded deep in the .la chain), pushing torch after petsc.
NEML2_TORCH_PC := $(NEML2_DIR)/share/pkgconfig/neml2-torch.pc
ifneq ($(wildcard $(NEML2_TORCH_PC)),)
neml2_torch_INCLUDES := $(shell pkg-config --cflags $(NEML2_TORCH_PC))
neml2_torch_LDIRS := $(shell pkg-config --libs-only-L $(NEML2_TORCH_PC))
neml2_torch_LIBS := $(shell pkg-config --libs $(NEML2_TORCH_PC))
endif

neml2_INCLUDES += $(filter-out $(neml2_torch_INCLUDES),$(shell pkg-config --cflags $(NEML2_PC)))
neml2_LDFLAGS += $(foreach libdir,$(filter-out $(neml2_torch_LDIRS),$(shell pkg-config --libs-only-L $(NEML2_PC))),$(patsubst -L%,-Wl$(comma)-rpath$(comma)%,$(libdir)))
neml2_LIBS += $(filter-out $(neml2_torch_LIBS),$(shell pkg-config --libs $(NEML2_PC)))

# Append to libmesh flags
libmesh_CXXFLAGS += $(neml2_CPPFLAGS) # I think MOOSE Makefiles tend to abuse libmesh_CXXFLAGS for preprocessor flags
Expand Down
1 change: 1 addition & 0 deletions framework/contrib/pytorch
Submodule pytorch added at 783837

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# MOOSEMaterialPropertyToNEML2

!if! function=hasCapability('neml2')

!alert note
Users are +NOT+ expected to directly use this object in an input file. Instead, it is always recommended to use the [NEML2 action](syntax/NEML2/index.md).

## Description

This object collects a MOOSE quantity given by [!param](/UserObjects/MOOSEQuantityToNEML2/from_moose) for use as a NEML2 input variable or model parameter [!param](/UserObjects/MOOSEQuantityToNEML2/to_neml2). The source of data is specified by [!param](/UserObjects/MOOSEQuantityToNEML2/quantity_type). This object has an "old" counterpart to retrieve the corresponding MOOSE data from the previous time step. The naming convention is

!syntax parameters /UserObjects/MOOSEQuantityToNEML2

!if-end!

!else

!include neml2/neml2_warning.md

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,6 @@ This object uses the specified NEML2 material model to perform mesh-wise (or sub

Each NEML2 model +input variable+ is gathered from MOOSE by a `MOOSEToNEML2` user object (gatherer) given in [!param](/UserObjects/NEML2ModelExecutor/gatherers). Optionally, NEML2 model +parameters+ can also be gathered from MOOSE by gatherers given in [!param](/UserObjects/NEML2ModelExecutor/param_gatherers).

Currently, three types of gatherers are available:

- [MOOSEMaterialPropertyToNEML2](MOOSEMaterialPropertyToNEML2.md) gathers material property stored at each quadrature point.
- [MOOSEVariableToNEML2](MOOSEVariableToNEML2.md) gathers (auxiliary) variables interpolated at quadrature points.
- [MOOSEPostprocessorToNEML2](MOOSEPostprocessorToNEML2.md) gathers postprocessor value broadcast to all quadrature points.

Each model +output+ and its +derivatives+ with respect to input variables and model parameters can be retireved by a [NEML2ToMOOSEMaterialProperty](NEML2ToMOOSEMaterialProperty.md) material object.

## NEML2 model execution
Expand Down
28 changes: 10 additions & 18 deletions framework/doc/content/syntax/NEML2/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,29 +35,21 @@ In each sub-block, there are a total of 6 groups of parameters that can be speci

The configuration of model is controlled by parameters such as [!param](/NEML2/model), [!param](/NEML2/verbose), [!param](/NEML2/device), etc., each of which is explained in the syntax documentation at the bottom of the page.

The other 5 groups of parameters are all related to data transfer between MOOSE and NEML2. The 2nd and the 3rd groups of parameters correspond to the transfer of data +from MOOSE to NEML2+. The 4th, 5th and the 6th groups of parameters correspond to the transfer of data +from NEML2 to MOOSE+.
[!param](/NEML2/input_types) is a list of enums denoting the type of the MOOSE data structure used to hold the input variables. The following enums are supported

Each group has three parameters in the following form:

- `moose_<*>_types`: List of types denoting the type of the MOOSE data structure.
- `moose_<*>s`: Names of quantities to be transferred from/to MOOSE.
- `neml2_<*>s`: Names of quantities to be transferred from/to NEML2.

where `<*>` are placeholders representing the data being transferred, e.g., `input`, `parameter`, `output`, `derivative`, `parameter_derivative`. Using `input` as an example, the three parameters are

- `moose_input_types`
- `moose_inputs`
- `neml2_inputs`
- `TIME`: Simulation time.
- `SCALAR`: The input variables are retrieved from a scalar variable and broadcast to all quadrature points.
- `FUNCTION`: The input variables are retrieved from a function evaluated at each quadrature points.
- `VARIABLE`: The input variables are retrieved from (auxiliary) variables interpolated at each quadrature point.
- `MATERIAL`: The input variables are retrieved from material properties stored at each quadrature point.

The length of the three lists must be the same. [!param](/NEML2/moose_input_types) is a list of enums denoting the type of the MOOSE data structure used to hold the input variables. The following enums are supported
All NEML2 input variables are automatically retrieved from the host MOOSE simulation. Quantities with the same name as each input variable are retrieved. An error is raised if ambiguity exists, in which case [!param](/NEML2/input_types) and [!param](/NEML2/inputs) can be used to explicitly specify the type of quantities to be retrieved.

- `MATERIAL`: The input variables are retrieved from material properties stored at each quadrature point.
- `VARIABLE`: The input variables are retrieved from (auxiliary) variables interpolated at each quadrature point.
- `POSTPROCESSOR`: The input variables are retrieved from a postprocessor and broadcast to all quadrature points.
All NEML2 output variables are retrieved and stored as MOOSE material properties after each evaluation, unless [!param](/NEML2/auto_output) is set to `false`.

Currently, for the groups of parameters that control the data transfer from NEML2 to MOOSE, only the `MATERIAL` is supported, i.e., NEML2 output variables and derivatives can only be transferred to MOOSE material properties.
For stateful variables, i.e., input variables needing values from previous time steps (usually with suffix `~N` with `N` being the number of steps backward in time), the corresponding MOOSE quantities from previous time steps are automatically retrieved. The advance of stateful variables is managed by the MOOSE native material system, unless [!param](/NEML2/manage_state_advance) is set to true, in which case NEML2 handles the storage and advance of stateful variables. Note that currently `manage_state_advance = true` is not compatible with mesh change events.

It is worth noting that for [!param](/NEML2/neml2_derivatives) and [!param](/NEML2/neml2_parameter_derivatives), a pair of names must be specified for each entry. The first name in the pair denotes the quantity (NEML2 output variable) to take derivative of, and the second name in the pair denotes the quantity (NEML2 input variable or model parameter) to take derivative with respect to.
It is worth noting that for [!param](/NEML2/neml2_derivatives) and [!param](/NEML2/neml2_parameter_derivatives), a pair of names must be specified for each entry. The first name in the pair denotes the quantity (NEML2 output variable) to take derivative of, and the second name in the pair denotes the quantity (NEML2 input variable or model parameter) to take derivative with respect to. Pairs are delimited by `;`.

## Inspect NEML2 information

Expand Down
95 changes: 32 additions & 63 deletions framework/include/neml2/actions/NEML2Action.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@
#endif

#include "Action.h"
#include "NEML2Utils.h"
#include "DerivativeMaterialPropertyNameInterface.h"

class NEML2ActionCommon;

/**
* Action to set up NEML2 objects.
*/
class NEML2Action : public Action
class NEML2Action : public Action, public DerivativeMaterialPropertyNameInterface
{
public:
static InputParameters validParams();
Expand All @@ -38,78 +40,47 @@ class NEML2Action : public Action

const FileName & fname() const { return _fname; }

enum class MOOSEIOType
{
MATERIAL,
VARIABLE,
POSTPROCESSOR
};

struct MOOSEIO
{
const std::string name;
const MOOSEIOType type;
};

struct NEML2IO
{
const neml2::VariableName name;
const neml2::TensorType type;
};

struct NEML2Param
{
const std::string name;
const neml2::TensorType type;
};

struct VariableMapping
{
const MOOSEIO moose;
const NEML2IO neml2;
std::string name;
NEML2Utils::MOOSEIOType moose_type;
neml2::TensorType neml2_type;
std::size_t history_order;
};

struct ParameterMapping
{
const MOOSEIO moose;
const NEML2Param neml2;
std::string name;
NEML2Utils::MOOSEIOType moose_type;
neml2::TensorType neml2_type;
};

struct DerivativeMapping
{
const MOOSEIO moose;
const struct NEML2Derivative
{
const NEML2IO y;
const NEML2IO x;
} neml2;
};

struct ParameterDerivativeMapping
{
const MOOSEIO moose;
const struct NEML2Derivative
{
const NEML2IO y;
const NEML2Param x;
} neml2;
std::string name;
std::string y;
std::string x;
};

/// Set up MOOSE-NEML2 input variable mappings
void setupInputMappings(const neml2::Model &);

/// Set up MOOSE-NEML2 model parameter mappings
void setupParameterMappings(const neml2::Model &);

/// Set up MOOSE-NEML2 output variable mappings
void setupOutputMappings(const neml2::Model &);

/// Set up MOOSE-NEML2 model parameter mappings
void setupParameterMappings(const neml2::Model &);

/// Set up MOOSE-NEML2 derivative mappings
void setupDerivativeMappings(const neml2::Model &);

/// Set up MOOSE-NEML2 parameter derivative mappings
void setupParameterDerivativeMappings(const neml2::Model &);

/// Infer the MOOSE IO type from the variable name and type
NEML2Utils::MOOSEIOType inferMOOSEIOType(const neml2::VariableName & name,
const neml2::TensorType & type) const;

/// Name of the NEML2 input file
FileName _fname;

Expand All @@ -132,7 +103,7 @@ class NEML2Action : public Action
std::vector<DerivativeMapping> _derivs;

/// MOOSE-NEML2 parameter derivative mappings
std::vector<ParameterDerivativeMapping> _param_derivs;
std::vector<DerivativeMapping> _param_derivs;

#endif
/// Name of the NEML2Executor user object
Expand All @@ -144,6 +115,9 @@ class NEML2Action : public Action
/// Blocks this sub-block action applies to
const std::vector<SubdomainName> _block;

/// Input variables to skip (i.e., not to set up mappings for)
std::vector<std::string> _skip_input_variables;

/// Material property initial conditions
std::map<MaterialPropertyName, MaterialPropertyName> _initialize_output_values;

Expand All @@ -153,22 +127,17 @@ class NEML2Action : public Action
private:
#ifdef NEML2_ENABLED
/// Get parameter lists for mapping between MOOSE and NEML2 quantities
template <typename EnumType, typename T1, typename T2>
std::tuple<std::vector<EnumType>, std::vector<T1>, std::vector<T2>>
getInputParameterMapping(const std::string & moose_type_opt,
const std::string & moose_name_opt,
const std::string & neml2_name_opt) const
template <typename EnumType, typename T>
std::tuple<std::vector<EnumType>, std::vector<T>>
getInputParameterMapping(const std::string & source_opt, const std::string & name_opt) const
{
const auto moose_types = getParam<MultiMooseEnum>(moose_type_opt).getSetValueIDs<EnumType>();
const auto moose_names = getParam<std::vector<T1>>(moose_name_opt);
const auto neml2_names = getParam<std::vector<T2>>(neml2_name_opt);
const auto moose_types = getParam<MultiMooseEnum>(source_opt).getSetValueIDs<EnumType>();
const auto neml2_names = getParam<std::vector<T>>(name_opt);

if (moose_types.size() != moose_names.size())
paramError(moose_name_opt, moose_name_opt, " must have the same length as ", moose_type_opt);
if (moose_names.size() != neml2_names.size())
paramError(moose_name_opt, moose_name_opt, " must have the same length as ", neml2_name_opt);
if (moose_types.size() != neml2_names.size())
paramError(source_opt, source_opt, " must have the same length as ", name_opt);

return {moose_types, moose_names, neml2_names};
return {moose_types, neml2_names};
}

/// Print a summary of the NEML2 model
Expand Down
Loading