MUESLI Manual
Theory, implementation, and use of the Material UnivErSal LIbrary

Table of Contents

This document has been automatically generated by a LLM. It is being reviewed and can contain mistakes.

Introduction

Purpose

MUESLI is a continuum-level material library written in C++. Its purpose is to provide a reusable set of constitutive laws for solids, fluids, thermal problems, and coupled multiphysics problems, together with a software structure that makes new models easier to implement, verify, and transfer between simulation codes.

The library sits at the material point level. It does not replace a finite element, finite volume, meshfree, or multiscale solver. Instead, it supplies the local constitutive response required by those solvers: stresses, heat fluxes, thermodynamic conjugates, internal-variable updates, and consistent tangent operators.

Design goals

MUESLI has five practical design goals.

  • Clarity. The implementation should resemble the mathematics. Tensor operations, invariants, and constitutive maps should be readable enough that a model can be checked against a paper or textbook without mentally translating everything into Voigt-matrix algebra.
  • Extensibility. New materials should be implemented by adding a small number of classes inside an existing family, not by rewriting the whole library.
  • Reliability. Constitutive updates should be accompanied by self-checks and regression tests so that stress, tangent, and history evolution remain mutually consistent.
  • Plug-ability. The same constitutive code should be usable in research codes and, through thin adapters, in commercial solvers.
  • Reusability. Material behavior should be decoupled from the host code so that calibration, benchmarking, and algorithmic development can happen once and be reused in multiple environments.

Scope of the library

At the level publicly described for MUESLI, the library covers the following problem families.

Family Representative models and capabilities
Small-strain solids Linear isotropic elasticity, classical plasticity, classical viscoelasticity
Finite-strain solids Saint Venant-Kirchhoff, isotropic hyperelasticity, finite-strain plasticity
Hyperelasticity Neo-Hookean, Arruda-Boyce, Mooney-Rivlin, Yeoh
Impact/high-rate response Johnson-Cook, Zerilli-Armstrong, Arrhenius-type
Thermal analysis Isotropic and anisotropic Fourier heat conduction
Small-strain thermomechanics Thermoelasticity, thermoplasticity, thermoviscoelasticity
Fluids Newtonian fluid
Coupled problems Thermo-mechanics, chemo-mechanics, thermo-chemo-mechanics
Reduced-dimensionality models Plane stress, shells, plates, beams
Interfaces Adapters for Abaqus and LS-DYNA
Verification support Family-specific automatic consistency checks

This list should be read as the publicly documented envelope of the library. Any local branch may contain more models than those listed here.

What MUESLI is not

MUESLI is not a full simulation framework. In particular, the library should not be expected to provide:

  • mesh management,
  • global assembly,
  • linear algebra solvers,
  • nonlinear solution control,
  • contact, remeshing, or adaptivity,
  • time-step selection for a host solver,
  • postprocessing infrastructure.

Those remain responsibilities of the host application.

Intended audiences

This manual addresses three audiences.

  1. Users who want to link MUESLI into an existing solver and call material routines correctly.
  2. Developers who want to add a new constitutive law or modify an existing one.
  3. Researchers who want to understand the thermodynamic and algorithmic choices behind the implementation.

The constitutive point of view

Material points and local state

MUESLI follows the standard computational-mechanics view in which constitutive behavior is evaluated at material points. A material point receives local input from the host code - for example strain, deformation gradient, temperature, temperature gradient, strain rate, or chemical field variables - and returns the quantities needed by the discretization.

Typical outputs include:

  • stress in the measure expected by the host code,
  • heat flux,
  • entropy or internal energy contributions,
  • internal-variable updates,
  • algorithmic tangent operators,
  • diagnostic information about convergence or active mechanisms.

A central conceptual choice in MUESLI is that a material object represents one constitutive law and parameter set, while the point states store the history of the different integration points using that law.

Inputs and outputs by problem class

Problem class Typical inputs Typical outputs
Small strain solid strain, strain increment, temperature Cauchy stress, consistent tangent, state
Finite strain solid deformation gradient, temperature PK stress or Kirchhoff/Cauchy stress, tangent
Heat conduction temperature gradient heat flux, conductivity tangent
Thermomechanics strain or F, temperature, grad T stress, heat flux, coupling blocks, state
Fluid rate of deformation, pressure data deviatoric stress, viscosity contribution
Reduced model constrained generalized strains section resultants, reduced tangent
High-rate model plastic strain, strain rate, temperature flow stress, hardening data, state

The exact set of arguments depends on the model family and the adapter used by the host code.

History dependence

Many constitutive laws are path-dependent. MUESLI therefore distinguishes between two kinds of data.

  • Parameters are fixed for all points using the same material: elastic constants, hardening parameters, conductivity coefficients, reference temperatures, rate constants, and so on.
  • State variables evolve point by point: plastic strains, hardening variables, inelastic deformation tensors, viscous strains, accumulated dissipation, temperature-like internal variables, damage measures, and similar quantities.

A safe constitutive implementation separates trial evaluation from state commit. In a nonlinear global solve, the host code may need to evaluate a point many times before accepting the time increment. State variables must therefore be updated in a reversible or staged manner until the host announces convergence.

Tangent operators

For implicit solvers, the local constitutive law is not complete without the algorithmic tangent. In exact Newton methods, the rate of global convergence is governed as much by the consistency of the tangent as by the correctness of the stress update itself.

MUESLI treats the tangent as a first-class result of the constitutive update. For elastic models it is usually the derivative of stress with respect to the chosen strain measure. For inelastic models it is the consistent derivative of the discrete update map, not merely the continuum elastic tensor.

Theory of material modeling in MUESLI

Thermodynamic framework

The natural language of continuum constitutive modeling is thermodynamics. Although each family has its own variables and kinematics, the common organizing principle is a state potential and a dissipation statement.

For many models, the starting point is a Helmholtz free energy \[ \psi = \psi(\text{state variables}), \] with constitutive quantities derived as thermodynamic conjugates. In a small strain thermoelastic example one may write \[ \psi = \psi(\varepsilon^e, T, \alpha), \] where \(\varepsilon^e\) is elastic strain, \(T\) temperature, and \(\alpha\) collects internal variables.

The stress follows from \[ \sigma = \frac{\partial \psi}{\partial \varepsilon^e}, \] while other conjugates are obtained by differentiation with respect to the remaining state variables. The dissipation inequality then constrains the admissible evolution laws.

This thermodynamic organization is especially important for three reasons.

  1. It keeps the model internally coherent.
  2. It provides a route to derive the tangent operator.
  3. It supports the automated consistency checks that compare energies, thermodynamic conjugates, and linearizations.

Small-strain solids

At small strain, the kinematics are based on the symmetric gradient \[ \varepsilon = \frac{1}{2}(\nabla u + \nabla u^{T}). \]

For purely elastic response, stress is an instantaneous function of the current strain (and possibly temperature). In isotropic linear elasticity: \[ \sigma = \lambda \, \text{tr}(\varepsilon) I + 2 \mu \varepsilon, \] or, equivalently, \[ \sigma = C : \varepsilon. \]

For path-dependent small-strain solids, the total strain is split into contributions, for example \[ \varepsilon = \varepsilon^e + \varepsilon^p + \varepsilon^\theta + \varepsilon^v, \] depending on whether the model includes plastic, thermal, or viscous strains.

Classical plasticity

A classical rate-independent plasticity model usually contains:

  • a yield function \(f(\sigma, q) \le 0\),
  • a flow rule for plastic strain,
  • a hardening law for internal variables \(q\),
  • Kuhn-Tucker conditions,
  • a return-mapping algorithm for the discrete update.

A J2-type model is the canonical example. The constitutive algorithm uses an elastic predictor followed by a plastic corrector. The resulting consistent tangent differs from the elastic tangent whenever the point is plastic.

Classical viscoelasticity

Viscoelastic models represent delayed response through internal strains or internal stresses. They can be organized through rheological analogs such as Maxwell or Kelvin-Voigt branches, but in a constitutive library the important point is the update structure:

  • identify the internal variables carrying memory,
  • integrate their evolution over the time step,
  • compute the observable stress,
  • return the derivative of the discrete map.

The small-strain viscoelastic part of MUESLI follows this general architecture.

Finite-strain solids

At finite strain, the basic kinematic object is the deformation gradient \[ F = \frac{\partial \varphi}{\partial X}, \qquad J = \det F. \]

Different stress and strain measures become relevant. In hyperelasticity, the right Cauchy-Green tensor \[ C = F^{T}F \] and an energy density \(W(C)\) are often used. The second Piola stress is then \[ S = 2\frac{\partial W}{\partial C}, \] and the Cauchy stress follows by push-forward: \[ \sigma = \frac{1}{J} F S F^{T}. \]

The design consequence for a library such as MUESLI is that each model must be explicit about:

  • the strain measure it accepts,
  • the stress measure it returns internally,
  • how the adapter converts that result to the measure required by the host code,
  • the frame in which the tangent operator is expressed.

Saint Venant-Kirchhoff

Saint Venant-Kirchhoff is the finite-strain extension of linear elasticity written in terms of Green-Lagrange strain. It is useful as a pedagogical large-strain model and as a baseline for testing the finite-strain infrastructure.

Isotropic hyperelasticity

The publicly described hyperelastic models in MUESLI include compressible and incompressible variants of Neo-Hookean, Arruda-Boyce, and Mooney-Rivlin models, plus the Yeoh model.

The common pattern is:

  1. define a strain-energy density \(W\),
  2. evaluate its derivatives with respect to the chosen invariants or tensors,
  3. obtain stress and tangent through differentiation,
  4. handle volumetric and deviatoric parts carefully, especially near incompressibility.

For developers, the crucial lesson is that hyperelastic models are ideal candidates for the energy -> stress -> tangent verification pipeline.

Finite-strain plasticity

The finite-strain plasticity branch is described publicly as an \(F^e F^p\)-type formulation, meaning a multiplicative decomposition \[ F = F^e F^p. \]

This structure is standard in modern finite plasticity. The elastic response is computed from the elastic part of the deformation, while \(F^p\) evolves according to a flow rule defined in the intermediate configuration. Numerically, the local update usually involves:

  • a trial elastic predictor,
  • solution of a nonlinear scalar or tensorial consistency problem,
  • update of \(F^p\) and hardening variables,
  • computation of a consistent tangent in the chosen frame.

Because frame-indifference and measure conversion are easy to get wrong, this family benefits strongly from family-specific tests.

Thermal analysis

For thermal models the constitutive law relates temperature gradients to heat fluxes. The basic Fourier law is \[ q = -k \nabla T \] for isotropic conductivity and \[ q = -K \nabla T \] for anisotropic conductivity, where \(K\) is a symmetric positive-definite conductivity tensor.

In the library, thermal materials should expose:

  • conductivity parameters,
  • heat-flux evaluation,
  • directional or tensorial conductivity when required,
  • tangent information when used in nonlinear coupled solves.

Small-strain thermomechanics

Thermomechanical materials couple mechanical and thermal variables. A typical free energy may be decomposed as \[ \psi = \psi_{\text{mech}} + \psi_{\text{therm}} + \psi_{\text{coupling}}. \]

This decomposition gives access to:

  • thermal expansion,
  • temperature dependence of elastic moduli or hardening,
  • entropy and heat capacity effects,
  • dissipation-generated heating in inelastic models.

The thermodynamic structure matters because the solver may need not only the mechanical tangent and the thermal tangent, but also the off-diagonal coupling blocks. In a monolithic coupled solve, those blocks are essential to robustness.

Fluids

The fluid branch documented publicly is the Newtonian fluid model. In continuum form, a Newtonian constitutive law takes the form \[ \sigma = -p I + 2 \mu d + \lambda \, \text{tr}(d) I, \] where \(d\) is the symmetric part of the velocity gradient, \(\mu\) is the dynamic viscosity, and \(\lambda\) is the bulk-viscosity-like coefficient.

For library design, the important point is that fluids are expressed in terms of rates rather than total strains, so the interface of this family differs naturally from the solid families.

Impact and high-rate constitutive laws

The impact branch adds phenomenological high-rate, temperature-dependent plasticity models commonly used for metals subjected to severe loading.

Johnson-Cook

A standard Johnson-Cook flow stress has the form \[ \sigma_y = \left(A + B \bar{\varepsilon}_p^n \right) \left(1 + C \ln \frac{\dot{\bar{\varepsilon}}_p}{\dot{\bar{\varepsilon}}_0}\right) \left(1 - \theta^m \right), \] with \[ \theta = \frac{T - T_r}{T_m - T_r}. \]

The model separates hardening, strain-rate sensitivity, and thermal softening. Its appeal lies in ease of calibration and wide industrial use, although it is fundamentally phenomenological.

Zerilli-Armstrong

Zerilli-Armstrong models are also phenomenological, but their functional form is motivated differently and depends on the material class. In practice, the model combines temperature, strain-rate, and work-hardening terms in an exponential structure. The exact variant should be documented in the source code and kept together with the parameter definition.

Arrhenius-type laws

Arrhenius-type viscoplastic laws express the connection between stress, strain rate, and temperature through an activation mechanism, often in the form \[ \dot{\bar{\varepsilon}} = A \, [\sinh(\alpha \sigma)]^n \exp\left(-\frac{Q}{RT}\right). \]

These models are useful when thermally activated flow is central to the response. Compared with Johnson-Cook, they often require more care in inversion and parameter identification.

Coupled chemo-mechanics and thermo-chemo-mechanics

Coupled models introduce additional fields, most commonly concentration-like variables, swelling terms, chemically induced eigenstrains, transport laws, and coupling energies. The decisive implementation principle is the same as in thermomechanics: make the state variables and the thermodynamic coupling explicit, and return a block-structured linearization consistent with the update.

Reduced-dimensional constitutive models

Reduced models such as plane stress, shells, plates, and beams are not merely lower-dimensional copies of 3D materials. They are usually constrained 3D constitutive problems. For example, a plane-stress update may require solving for the out-of-plane strain component that enforces \(\sigma_{33}=0\).

This leads to two important implementation ideas.

  1. A reduced model may be built by wrapping a 3D constitutive law inside a local constrained solve.
  2. The tangent of the reduced model must include the effect of that constraint elimination, not just the unrestricted 3D tangent.

For shells, plates, and beams the same logic extends to generalized strains and section resultants, sometimes with through-thickness integration or section-level local solves.

Software architecture and implementation

Why tensor algebra matters

A defining MUESLI choice is to prefer tensor algebra over blanket reliance on Voigt notation. This is not just a matter of elegance.

  • Tensor notation preserves the natural structure of constitutive equations.
  • The difference between scalar, vector, second-order, and fourth-order objects remains visible in the code.
  • Frame transformations, invariants, contractions, and projections become easier to express and audit.
  • Model implementations resemble the literature more closely.

Voigt notation still has a role at interfaces, especially where a commercial code expects packed stress or tangent arrays. The key principle is: keep Voigt at the boundary, not at the heart of the model.

Core software concepts

A robust constitutive library usually separates five concerns.

Parameter objects

A parameter object stores material constants and algorithmic tolerances. It should be immutable during a constitutive update and sharable by all points using the same material.

Typical contents:

  • elastic constants,
  • hardening parameters,
  • reference temperatures,
  • viscosities or relaxation times,
  • conductivity data,
  • solver tolerances for local iterations.

Material objects

A material object represents a constitutive law together with one fixed parameter set. Public descriptions of MUESLI state that a material object encapsulates the data of all material points that share the same response. Conceptually, this means the object knows what law is being solved, while point states know where each point currently is on that law.

Responsibilities of the material object include:

  • exposing the family interface,
  • evaluating point updates,
  • providing helper functions common to all points,
  • owning or managing the collection of point states when that design is used,
  • running family-specific checks.

Point states

A point state stores all history-dependent data for one integration point. The state must be serializable, copyable, and easy to checkpoint.

Examples:

  • accumulated plastic strain,
  • hardening variables,
  • backstress tensors,
  • viscous strains,
  • inelastic deformation gradient,
  • temperature-like internal variables,
  • damage or porosity variables.

Input bundles

The host code should pass a compact input bundle to the constitutive law rather than a large number of unrelated scalar arguments. A clean input object typically contains:

  • the current kinematic quantity (strain, rate, or deformation gradient),
  • the increment and time-step size,
  • temperature and field values,
  • optional previous-step quantities already available in the host code,
  • flags indicating whether the solve is explicit, implicit, trial-only, etc.

Response bundles

Similarly, the constitutive law should return a response bundle that groups:

  • stress,
  • tangent,
  • heat flux,
  • updated state,
  • local iteration statistics,
  • flags or status codes.

This is better than returning stress alone and hiding everything else in side effects.

Family hierarchy

The public documentation emphasizes material families. The purpose of a family is to define a shared contract for all models of the same kinematic and physical type.

A conceptual hierarchy looks like this:

MaterialFamily
|- SmallStrainSolid
|  |- LinearElastic
|  |- J2Plasticity
|  `- Viscoelastic
|- FiniteStrainSolid
|  |- SaintVenantKirchhoff
|  |- NeoHookean
|  |- ArrudaBoyce
|  |- MooneyRivlin
|  |- Yeoh
|  `- FeFpPlasticity
|- ThermalMaterial
|  |- FourierIsotropic
|  `- FourierAnisotropic
|- ThermoMechanicalMaterial
|- FluidMaterial
|- ImpactMaterial
|- CoupledMaterial
`- ReducedMaterial

This tree is conceptual, not a claim about exact class names. The important design rule is that each family should define:

  • the admissible input variables,
  • the output variables,
  • the required constitutive methods,
  • the consistency checks applicable to that family.

Constitutive update pattern

Across families, the local algorithm should follow a predictable pattern.

  1. Read input and current state.
  2. Build trial quantities.
  3. Detect the active branch or mechanism.
  4. Solve the local nonlinear problem if necessary.
  5. Compute stress, fluxes, and updated internal variables.
  6. Compute the consistent tangent of the discrete update.
  7. Store the tentative state without permanently committing it.
  8. Return status information to the host.

In pseudocode:

Response Material::evaluate(const Input& in, const State& old_state) const
{
    State trial = old_state;
    Response out{};

    // 1. Elastic or reversible predictor
    TrialData td = compute_trial(in, old_state);

    // 2. Branch selection
    if (is_elastic(td)) {
        out.stress  = elastic_stress(td);
        out.tangent = elastic_tangent(td);
        out.state   = old_state;
        return out;
    }

    // 3. Local solve
    LocalSolution sol = solve_local_problem(td, old_state);

    // 4. Build final response
    out.stress  = stress_from_solution(sol);
    out.tangent = consistent_tangent(sol);
    out.state   = state_from_solution(sol);
    out.status  = sol.status;
    return out;
}

What matters is not the exact spelling, but the separation between trial, solution, and committed state.

Consistent linearization

Whenever the host uses Newton-type global iterations, the constitutive update should be linearized after discretization. This is especially important for:

  • return-mapping plasticity,
  • viscous updates integrated implicitly,
  • reduced models with local constraints,
  • coupled models with block tangents,
  • finite-strain algorithms with push-forward and pull-back operations.

A recurring source of bugs is to return a continuum tangent while the stress has been computed by a discrete algorithm. The solver may still converge, but only linearly or erratically.

Memory ownership and thread safety

Public release notes mention thread-safe compilation. In practice, thread safety at the constitutive level requires:

  • no writable global scratch variables,
  • no static mutable temporaries shared between points,
  • all point-level work arrays to be stack-based or point-owned,
  • deterministic treatment of caches and lazy initialization,
  • reentrant adapters when called by multithreaded host codes.

A good default is to assume that every constitutive call may occur concurrently on many integration points.

Error handling and diagnostics

Constitutive routines should fail loudly and informatively. Recommended failure modes include:

  • invalid parameter ranges,
  • loss of positive definiteness in quantities that must stay positive,
  • singular local Jacobians,
  • non-convergence of return mapping,
  • inadmissible deformation gradients such as \(J \le 0\),
  • temperatures outside model validity ranges.

A response bundle should therefore be able to carry:

  • a convergence flag,
  • the number of local iterations,
  • an error code,
  • optional residual norms.

Interfacing to host codes

One of MUESLI's main goals is transferability. The interface layer should be as thin as possible.

Responsibilities of an adapter include:

  • map host-code data structures to MUESLI input bundles,
  • convert stress and tangent measures,
  • reorder components when the host expects Voigt arrays,
  • manage state-variable storage in the host format,
  • handle commit and rollback at the correct stage of the global algorithm,
  • translate units and reference values consistently.

The constitutive core should not know whether the caller is a research code, Abaqus, LS-DYNA, or a standalone calibration tool.

Verification tools

MUESLI is publicly described as including automatic checks tailored to each family. The conceptual checks are:

  • energy-stress consistency: derivative of stored energy reproduces stress,
  • stress-tangent consistency: derivative of stress reproduces tangent,
  • symmetry and objectivity tests, where applicable,
  • reference-case recovery: known limiting cases are reproduced exactly,
  • interface regression: adapter output matches the direct core output.

Such checks are not full validation, but they are excellent at finding coding mistakes early.

Obtaining, building, and integrating the library

Getting the sources

Public project information describes two ways of obtaining MUESLI.

  1. Download a release archive from the project website.
  2. Clone the Bitbucket repository.

The public release history mentions versions 1.1, 1.3, 1.4, and 1.8. The release notes highlight, among other things, thermoelastic additions, thread-safe compilation, reduced models, the Yeoh material, and later impact and coupled models.

Platform expectations

The public description states that MUESLI has been used and tested on Linux and macOS. When preparing a new installation, verify:

  • compiler standard and version,
  • optimization flags,
  • BLAS/LAPACK or other numerical dependencies if your branch uses them,
  • thread-related flags if your host is multithreaded,
  • consistent floating-point behavior across debug and release builds.

Build system philosophy

This manual does not assume an exact build system, because that must be taken from the repository itself. In general, the build should produce:

  • a static or shared library containing the constitutive core,
  • headers exposing the public API,
  • test executables or drivers,
  • optional interface libraries or user subroutines for commercial codes,
  • optional examples and documentation targets.

A healthy build should support both a developer mode and a production mode.

Mode Typical flags and behavior
Developer debug symbols, assertions, warnings enabled, sanitizers when possible
Production optimization enabled, assertions reduced, reproducible floating-point

Recommended source-tree organization

A practical constitutive library benefits from keeping its code separated by role. A good repository layout is:

muesli/
|- doc/           manual, notes, examples
|- include/       public headers
|- src/           core implementation
|- materials/     material families and models
|- interfaces/    host-code adapters
|- tests/         unit and regression tests
|- examples/      standalone drivers
`- tools/         calibration or inspection utilities

Again, this is a recommended organization, not a claim about the exact current tree.

Integration checklist for a host code

Before linking MUESLI into a solver, answer the following.

  1. What stress measure does the solver expect?
  2. What strain or kinematic measure does it pass to the constitutive routine?
  3. When, exactly, is local state committed?
  4. How are state variables stored and restarted?
  5. What units are used for temperature, time, and mechanical quantities?
  6. Is the solve explicit, implicit, or staggered coupled?
  7. Does the solver require a symmetric tangent, and is that mathematically valid?
  8. Is the constitutive call made concurrently from multiple threads?

If any of these are unclear, the interface will be fragile.

Reproducibility

For scientific use, each material definition should be tied to:

  • a named model version,
  • a parameter set with units,
  • a calibration source,
  • a reference problem or regression test,
  • a known valid range of temperatures, rates, and deformations.

Without these, code reuse turns into guesswork.

How to use MUESLI

Standard workflow

A typical MUESLI-driven simulation follows this sequence.

  1. Choose the material family and model.
  2. Define the parameter set.
  3. Allocate or initialize one material object.
  4. Create one state per integration point.
  5. At each global step, assemble an input bundle for each point.
  6. Call the constitutive update.
  7. Use the returned stress, tangent, and fluxes in the host solver.
  8. Commit the tentative state only after the global step is accepted.
  9. Output state variables needed for restart and postprocessing.

Schematic example: small-strain elastoplastic point

The following example is schematic. It shows the usage pattern, not exact API names.

#include <vector>
// #include <muesli/...>   // Replace with your exact headers.

int main()
{
    // 1. Define parameters
    J2Parameters par;
    par.E        = 210e9;
    par.nu       = 0.30;
    par.sigma_y0 = 350e6;
    par.H        = 2.5e9;

    // 2. Create one material object shared by many points
    SmallStrainJ2 material(par);

    // 3. Create one state per integration point
    std::vector<J2State> state(ngp);
    for (auto& s : state) {
        s = material.initial_state();
    }

    // 4. Constitutive call inside the host loop
    for (int gp = 0; gp < ngp; ++gp) {
        SmallStrainInput in;
        in.strain_n      = eps_n[gp];
        in.strain_np1    = eps_np1[gp];
        in.temperature   = T_np1[gp];
        in.dt            = dt;

        auto out = material.evaluate(in, state[gp]);

        sigma[gp] = out.stress;
        C_alg[gp] = out.tangent;

        // Commit only after the global step is accepted
        trial_state[gp] = out.state;
    }

    if (global_step_converged) {
        state = trial_state;
    }
}

The essential ideas are:

  • one parameterized material object,
  • one history object per point,
  • evaluate many times,
  • commit only after acceptance.

Schematic example: finite-strain hyperelastic point

HyperelasticParameters par;
par.mu   = 0.8e6;
par.kappa = 8.0e6;

NeoHookean material(par);
HyperState state = material.initial_state();

FiniteStrainInput in;
in.F_np1 = F;
in.T     = temperature;

auto out = material.evaluate(in, state);

// The host may request PK2, Kirchhoff, or Cauchy stress;
// the adapter is responsible for final conversion if needed.
Tensor2 S = out.stress;
Tensor4 A = out.tangent;

For finite strain, always verify:

  • the stress measure returned by the core,
  • the tangent frame,
  • how incompressibility is treated,
  • whether the host expects material or spatial quantities.

Using coupled thermo-mechanical models

In a coupled solve, the input must carry both mechanical and thermal data, for example:

  • strain or deformation gradient,
  • temperature,
  • temperature gradient,
  • time increment,
  • possibly previous-step dissipation measures.

The returned response may contain a block structure like:

[ d sigma / d eps    d sigma / d T   ]
[ d q     / d eps    d q     / d gradT ]

In a staggered scheme, some of these blocks may be used only partially, but the constitutive update should still be internally consistent.

Explicit versus implicit use

MUESLI can be used in both explicit and implicit host codes, but the constitutive demands differ.

Explicit use

For explicit solvers, the constitutive call often needs only:

  • current or incremented kinematics,
  • updated stress,
  • updated state.

The tangent may be optional or used only for diagnostics. The emphasis is on efficiency and robustness under many short calls.

Implicit use

For implicit solvers, the constitutive law must be fully algorithmic:

  • local nonlinear problem solved to tolerance,
  • consistent tangent returned,
  • state update staged until global acceptance.

If the tangent is approximate, expect slower or less reliable global convergence.

Using MUESLI through commercial-code interfaces

Public project information describes interfaces to Abaqus and LS-DYNA. The recommended philosophy is:

  • keep the host-specific code as thin as possible,
  • perform all material logic inside the MUESLI core,
  • convert data only at the boundary,
  • maintain identical regression problems in direct and wrapped modes.

This allows the same constitutive model to be calibrated and debugged outside the commercial solver and then deployed there with minimal changes.

Postprocessing

For reproducibility and debugging, it is good practice to output not only the observable fields but also selected state variables, for example:

  • accumulated plastic strain,
  • hardening variables,
  • temperature or dissipation contributions,
  • active-branch flags,
  • local iteration counts,
  • failure or saturation indicators.

These outputs are often the fastest way to diagnose a wrong update.

Material family reference

Small-strain elasticity

Use this family when deformations are small and reversible response is sufficient.

  • State variables: usually none.
  • Inputs: strain, optionally temperature.
  • Outputs: stress and elastic tangent.
  • Typical numerical issues: almost none, which makes this family ideal for verifying the tensor layer, adapters, and stress-measure conventions.

Small-strain plasticity

Use when irreversible deformation occurs at small strain.

  • State variables: plastic strain-like variables, hardening variables, backstress if kinematic hardening is present.
  • Inputs: total strain or strain increment, temperature if thermally coupled.
  • Outputs: stress, consistent elastoplastic tangent, updated state.
  • Numerical core: return mapping with a local consistency solve.
  • Key verification: elastic limit, yield-surface consistency, tangent tests.

Small-strain viscoelasticity

Use for rate-dependent, reversible delayed response.

  • State variables: viscous branch variables.
  • Inputs: strain history through increments and time step.
  • Outputs: stress and discrete-time tangent.
  • Key verification: relaxation, creep, and recovery limits.

Finite-strain hyperelasticity

Use when large reversible deformations dominate.

  • State variables: typically none for purely elastic variants.
  • Inputs: deformation gradient.
  • Outputs: stress measure and tangent.
  • Key issues: incompressibility treatment, stress/tangent frame, derivative consistency from the energy density.

Finite-strain plasticity

Use when large deformations and permanent flow are both present.

  • State variables: inelastic deformation measure, hardening variables.
  • Inputs: deformation gradient, time step, temperature when required.
  • Outputs: stress, consistent tangent, updated inelastic state.
  • Key issues: objective update, admissibility of \(J\), local nonlinear solve.

Thermal conduction

Use for heat-transfer problems or as the thermal branch of coupled models.

  • State variables: usually none for linear Fourier conduction.
  • Inputs: temperature gradient.
  • Outputs: heat flux and conductivity tensor.
  • Key issues: anisotropy and unit consistency.

Small-strain thermomechanics

Use when temperature and deformation are mutually coupled.

  • State variables: mechanical and thermal history variables.
  • Inputs: strain, temperature, time step, possibly temperature gradient.
  • Outputs: stress, thermal quantities, coupling tangent blocks.
  • Key issues: reference temperature, thermal strain convention, dissipative heating.

Impact models

Use for high strain-rate metallic response.

  • State variables: accumulated plastic strain and rate/temperature-dependent auxiliary quantities.
  • Inputs: strain, strain rate, temperature.
  • Outputs: flow stress and consistent update data.
  • Key issues: parameter calibration, valid temperature/rate range, numerical protection against invalid logarithms or softening extremes.

Fluid materials

Use for viscous fluid response at the constitutive level.

  • State variables: often none for Newtonian response.
  • Inputs: rate of deformation and pressure-related data from the host.
  • Outputs: stress contribution and viscosity tangent.
  • Key issues: clear split between constitutive and incompressibility treatment.

Coupled chemo-mechanics and thermo-chemo-mechanics

Use when concentration, diffusion, swelling, or additional internal fields couple with mechanics and temperature.

  • State variables: transport and coupling variables.
  • Inputs: mechanical, thermal, and chemical fields.
  • Outputs: block-structured response and tangent.
  • Key issues: consistent coupling linearization and clear thermodynamic bookkeeping.

Reduced-dimensional models

Use when the host code solves plane stress, shells, plates, or beams through reduced kinematics.

  • State variables: inherited from the underlying 3D law plus constraint data.
  • Inputs: generalized strains or constrained strain components.
  • Outputs: reduced stresses/resultants and condensed tangent.
  • Key issues: exact satisfaction of the constraint and proper condensation of the tangent.

Extending MUESLI with a new material

Choose the right family first

New models should almost never be added as free-floating classes. First decide which family the model belongs to:

  • small strain or finite strain,
  • reversible or dissipative,
  • purely mechanical or coupled,
  • 3D or reduced,
  • rate-independent or rate-dependent.

The family determines the interface and the available tests.

Start from thermodynamics, not from code

Before writing C++, write down:

  • the state variables,
  • the free energy or stored-energy structure,
  • the dissipation potential or flow law,
  • the admissibility conditions,
  • the algorithmic unknowns of the local solve,
  • the quantities the host needs back.

If this cannot be written clearly on paper, the code will likely be unstable or hard to verify.

Define parameter and state objects

A good new model begins with two plain data structures.

struct MyModelParameters {
    double E;
    double nu;
    double sigma0;
    double H;
    double Tref;
};

struct MyModelState {
    Tensor2 eps_p;
    double  p = 0.0;
};

Keep parameters separate from evolving state.

Implement the local update

The local update should be small, explicit, and testable. Prefer a structure in which helper functions are easy to unit test independently:

  • trial predictor,
  • yield or activation evaluation,
  • local residual and Jacobian,
  • state reconstruction,
  • tangent construction.

Avoid monolithic hundred-line functions whose only output is stress.

Implement the tangent immediately

Do not postpone the tangent. A constitutive model without the correct tangent is half implemented. The best development order is:

  1. energy or reversible map,
  2. stress,
  3. local residual,
  4. update algorithm,
  5. consistent tangent,
  6. checks.

Register tests with the family checks

Every new material should come with:

  • a parameterized smoke test,
  • at least one path-dependent regression test if applicable,
  • numerical differentiation checks,
  • limiting-case checks against a simpler model,
  • adapter tests if the model will be deployed through external interfaces.

Schematic developer skeleton

class MyThermoPlasticity : public SmallStrainThermoMaterial
{
public:
    explicit MyThermoPlasticity(const MyModelParameters& par) : par_(par) {}

    MyModelState initial_state() const override
    {
        return {};
    }

    Response evaluate(const Input& in, const MyModelState& old_state) const override
    {
        // 1. Build trial data
        // 2. Solve local constitutive equations
        // 3. Return stress, tangent, new state, and diagnostics
    }

    void self_check() const override
    {
        // Run family-specific consistency checks
    }

private:
    MyModelParameters par_;
};

The exact inheritance chain is illustrative. The main point is that family contracts should remain visible in the code.

Documentation for each new material

Every new model should be documented with the same template.

  • model name,
  • governing equations,
  • parameters and units,
  • admissible input range,
  • stress and tangent measures,
  • state variables,
  • integration algorithm,
  • verification tests,
  • references.

If this template is enforced, the library becomes much easier to maintain.

Verification, validation, and debugging

Consistency versus validation

It is useful to distinguish two tasks.

  • Consistency checking asks whether the code correctly implements the equations.
  • Validation asks whether the equations describe reality for the target material.

MUESLI's automated checks are primarily consistency checks. Validation still requires experimental comparison, literature benchmarks, or trusted-code comparison.

Recommended consistency checks

Energy -> stress

For energy-based models, compare analytical stress with numerical derivatives of the energy.

Stress -> tangent

Perturb the kinematic input and compare finite differences of the stress with the returned tangent action.

Elastic limit recovery

For inelastic models, verify that the update reproduces the elastic law in the appropriate limit.

Objectivity and symmetry

For finite-strain models, test frame indifference. For symmetric tangents or conductivity tensors, test the expected symmetry numerically.

Path tests

For history-dependent materials, run loading-unloading cycles, strain-rate jumps, and temperature ramps that exercise different branches.

Benchmark problems

The following benchmarks are especially useful.

Family Suggested benchmark
Small-strain elasticity uniaxial tension, simple shear
Plasticity return mapping under monotonic and cyclic loading
Viscoelasticity stress relaxation and creep
Hyperelasticity large simple extension and nearly incompressible loading
Finite plasticity large-strain shear or compression with plastic flow
Thermal one-dimensional heat flux with isotropic and anisotropic cases
Thermomechanics constrained thermal expansion and dissipative heating
Reduced models plane-stress patch test or section-consistency test
Impact models Taylor-type impact or calibrated single-point high-rate loading

Common debugging patterns

When a constitutive model misbehaves, the following order is efficient.

  1. Reproduce the problem in a single-point driver.
  2. Freeze the global solver and inspect only the local update.
  3. Check the returned tangent by finite differences.
  4. Check state commit and rollback separately.
  5. Confirm units and reference values.
  6. Only then return to the full solver.

Constitutive bugs become much easier to see when the host code is stripped away.

Diagnostics worth logging

For difficult models, log:

  • local residual norm,
  • local iteration count,
  • active branch or mechanism,
  • determinant \(J\) for finite strain,
  • yield-function value before and after correction,
  • line-search or damping information,
  • extreme parameter combinations.

These logs are often worth far more than printing raw tensors.

Practical advice and common failure modes

Unit inconsistency

The most common non-coding failure is mixed units. Typical mistakes include:

  • MPa parameters with Pa stresses,
  • Celsius offsets treated as absolute temperatures,
  • milliseconds used with SI rate constants,
  • conductivity parameters defined in a different unit system than the solver.

Adopt one library-wide convention and document it.

Wrong stress or strain measure

Finite-strain integrations fail quietly if the host and constitutive law disagree about measures. Always document:

  • input measure,
  • output stress measure,
  • tangent frame,
  • conversion performed by the adapter.

Tangent mismatch

If the global Newton method stalls while the stress looks plausible, suspect the tangent first. Numerical differentiation of the discrete update is the fastest check.

State committed too early

If a global iteration evaluates the material several times per step, but the point state is overwritten permanently on the first call, path-dependent models will drift or harden incorrectly. This error is subtle and extremely common.

Reference temperature mistakes

High-rate and thermomechanical models often use reference, room, and melting temperatures. Mixing these or using a host temperature in different units can destroy the response without generating a clear code error.

Reduced-model inconsistency

For plane stress or shell wrappers, a frequent mistake is to satisfy the constraint in stress but return an uncondensed tangent. The response then looks right in postprocessing but destabilizes the solver.

Logarithms and exponentials in high-rate models

Johnson-Cook and Arrhenius-type models can become numerically invalid if:

  • strain rate is non-positive inside a logarithm,
  • normalized temperature leaves its intended range,
  • exponential arguments overflow,
  • thermal softening drives stress negative without safeguards.

Guard these operations explicitly.

Versioning, contribution, and citation

Public release milestones

Version Publicly noted additions or remarks
1.1 Early public release
1.3 Thermoelastic materials, thread-safe compilation, minor bug fixes
1.4 Reduced models, Yeoh material, minor bug fixes
1.8 Impact materials, coupled problems, additional bug fixes

This table reflects the public release notes and should be updated locally if your repository has more recent tags or branches.

Contribution workflow

A robust workflow for new contributions is:

  1. define the theory and parameters,
  2. implement the model inside the correct family,
  3. add tests,
  4. add a standalone example,
  5. document the model,
  6. run the family self-checks,
  7. run interface regression problems where relevant.

License

MUESLI is publicly described as being distributed under GPL 3.0. If the local repository adds exceptions, dual licensing, or commercial wrappers, document those terms clearly next to the core license.

How to cite the library

The canonical citation should point users to the main MUESLI paper and, if useful, to the project website or release tag used in the computations. A complete scientific citation should also state the specific constitutive model and the parameter set employed.

Appendix: Recommended notation

Symbol Meaning
\(u\) displacement
\(\varepsilon\) small-strain tensor
\(F\) deformation gradient
\(J\) determinant of \(F\)
\(C\) right Cauchy-Green tensor
\(\sigma\) Cauchy stress
\(S\) second Piola-Kirchhoff stress
\(\psi\) Helmholtz free energy
\(q\) heat flux
\(T\) absolute temperature
\(\alpha\) generic internal-variable collection
\(d\) symmetric part of velocity gradient
\(C_{\text{alg}}\) algorithmic tangent
\(F^e, F^p\) elastic and plastic parts of multiplicative split

Appendix: Template for documenting one material model

Copy the following block for every new material added to the library.

#+begin_example

Model name

Purpose

What physical behavior the model is intended to represent.

Governing equations

Free energy, yield function, flow rule, transport law, or other defining equations.

Parameters

List every parameter, its symbol, units, and admissible range.

Inputs

What the host code must pass in.

Outputs

Stress measure, tangent, fluxes, state variables, diagnostics.

State variables

Definition and physical meaning.

Integration algorithm

Predictor/corrector, local Newton solve, closed-form update, etc.

Verification

Energy/stress check, tangent check, benchmark cases.

Notes

Known limitations, reference ranges, calibration remarks. #+end_example

Appendix: Suggested single-point driver

A standalone driver is one of the most valuable files in a constitutive library. It should:

  • read a material parameter set,
  • generate one or more loading paths,
  • call the constitutive law without any host solver,
  • write stress, state, and tangent information,
  • compare against analytical or regression expectations.

Such a driver is the fastest route to debugging and to onboarding new users.

Appendix: Further reading

  • Portillo, del Pozo, Rodríguez-Galán, Segurado, Romero. MUESLI: A Material UnivErSal LIbrary. Advances in Engineering Software, 105, 1-8.
  • Project website and release notes for MUESLI.
  • Structural and reduced-model papers that build constrained section models on top of 3D constitutive updates.
  • Calibration studies using Johnson-Cook, Zerilli-Armstrong, and Arrhenius-type laws implemented in MUESLI.

Closing remarks

The value of a constitutive library is not only the number of models it contains, but the discipline with which those models are organized, verified, and reused. MUESLI is most effective when each constitutive family has a clear contract, each model has a clean thermodynamic statement, and each adapter keeps the constitutive core independent from the solver that calls it.

Author: Ignacio Romero

Created: 2026-03-13 Fri 13:34

Validate