MUESLI
MUESLI (Material UnivErSal LIbrary) is an open-source, object-oriented C++ library of constitutive models at the continuum scale. It offers a common, solver-agnostic interface to a broad catalogue of materials — mechanical, thermal, diffusive and coupled — that can be embedded in finite element, finite volume or finite difference codes.
The library is developed jointly by the Computational Solid Mechanics group
at IMDEA Materials Institute and the Modelling and Simulation in Mechanical Engineering group
at the UPM. The main author and project coordinator is Prof. I. Romero.
Questions, comments and suggestions can be addressed to muesli.materials@imdea.org.
🔑 Key characteristics of the library
- Object-oriented hierarchy of material families, easily extended with new models.
- High level of abstraction based on dedicated tensor classes, with an optional Eigen backend.
- Uniform property-map interface for material parameters, and a global material database for registration and lookup.
- Built-in numerical verification of stored-energy derivatives (stresses and tangents).
- Modern C++, distributed as a static library with C-linkage interfaces to commercial FE codes.
📦 Material models
- Small-strain mechanics: elasticity (isotropic, orthotropic, transversely isotropic, general anisotropic), viscoelasticity, plasticity, viscoplasticity, damage.
- Finite-strain mechanics: hyperelasticity (neo-Hookean, Mooney–Rivlin, Yeoh, Arruda–Boyce, Saint-Venant–Kirchhoff), plasticity, viscoplasticity, Johnson–Cook and Zerilli–Armstrong models, damage.
- Coupled problems: thermo-mechanics, chemo-mechanics and mass diffusion, hydrogen-assisted models, and phase-field fracture, in both the small- and finite-strain regimes.
- Fluids: Newtonian.
- Heat-conducting and diffusive materials, including additive-manufacturing models.
- Reduced strain states: plane strain, plane stress, uniaxial (bar), beam and shell kinematics.
- Failure criteria: Johnson–Cook, Brown–Miller.
- Frequency-domain materials.
- Data-driven / neural-network material models.
🪪 Obtaining the library
MUESLI is free software released under the GNU GPL v3 licence. The latest version is available from its public git repository.
📥 Installing the library
MUESLI compiles into a single static library, libmuesli_<arch>.a, that other codes link
against; the architecture is detected automatically from the host. From the cloned
repository:
cd muesli/muesli
make # build the static library into ../lib
make install # copy the library and public headers into ../lib and ../include
make all # build, install, and run the verification suite
The only hard requirements are a C++11 compiler and BLAS/LAPACK. An optional
Eigen backend for the tensor algebra can be enabled by
uncommenting WITHEIGEN in muesli/makefile and setting EIGEN_PATH; otherwise the
bundled tensor classes are used. When building your own code against MUESLI, put the
repository root on the include path so that #include "muesli/muesli.h" resolves.
🧮 The role of Eigen
Eigen is a header-only C++ template library for linear algebra. In MUESLI it is an optional backend for the whole tensor-algebra layer, and using it or not is decided entirely at build time.
By default MUESLI ships its own, self-contained tensor algebra. The objects of
continuum mechanics — vectors and second-order tensors in R³ (ivector, itensor),
symmetric tensors (istensor), skew tensors (skewtensor), third- and fourth-order
tensors (itensor3, itensor4), quaternions and rotations (iquaternion, irotation) —
and every operation on them (products and contractions, trace, determinant, inverse,
transpose, deviatoric/volumetric split, symmetric and skew parts, spectral decomposition,
tensor square root, push-forward/pull-back, and the fourth-order identities and projectors)
are implemented by hand in Math/mtensor.*, with the general dense matrix, realvector
and complexvector in Math/mmatrix.* and Math/mrealvector.*. This path has no external
dependency beyond a C++11 compiler and a BLAS/LAPACK (on macOS, the Accelerate framework).
When MUESLI is built against Eigen, that entire native layer is swapped out. Enabling
it — uncommenting WITHEIGEN in muesli/makefile (which defines -DWITHEIGEN) and
pointing EIGEN_PATH at the Eigen headers — makes muesli/tensor.h (together with
matrix.h and realvector.h) select the Eigen implementation instead: ivector,
itensor, iquaternion and irotation become aliases for Eigen::Vector3d,
Eigen::Matrix3d and Eigen::Quaterniond; istensor, skewtensor, itensor3 and
itensor4 become thin subclasses of Eigen types whose operations are expressed through
Eigen expressions and solvers (for instance SelfAdjointEigenSolver for the spectral
decomposition); and matrix, realvector and complexvector become Eigen::MatrixXd,
Eigen::VectorXd and Eigen::VectorXcd. The native translation units mtensor.o,
mmatrix.o and mrealvector.o are then dropped from the build and BLAS/LAPACK is no
longer linked.
The two backends expose the same class names and the same method signatures, so constitutive models — stored energies, stresses and consistent tangents — are written once and compile unchanged either way. Choosing Eigen only changes which linear-algebra engine executes the tensor operations underneath; it adds no material models and does not alter the tensor interface.
🧪 Testing the library
Every material model carries a test() routine that numerically checks its implementation:
first- and second-order derivatives of the stored energy — that is, stresses and tangent
moduli — are compared against finite-difference approximations. A unit-test driver calls the
test() method of every model, and a separate benchmark suite verifies the reduced strain
models (bar, plane, beam, shell) against reference solutions:
cd muesli/muesli && make # the library must be built first
cd ../test && make # build and run the whole benchmark suite
Each program checks its own result and reports PASS or FAIL; the driver also writes a
detailed testmuesli.log. Running the suite is the recommended way to validate a material
class after adding or modifying it.
🧱 Using MUESLI materials
A material is constructed once with its parameters and then evaluated at each integration point through a lightweight material-point object that carries the local state:
#include "muesli/muesli.h"
// isotropic J2 elastoplastic material with mixed hardening
muesli::splasticMaterial mat("steel", 210.0e9, 0.3, 7850.0,
1.0e9, 2.0e9, 250.0e6, 0.0, "mises");
muesli::smallStrainMP* p = mat.createMaterialPoint();
istensor strain; // strain tensor for the current step
p->updateCurrentState(step, strain);
istensor sigma; p->stress(sigma); // Cauchy stress
itensor4 c; p->tangentTensor(c); // consistent tangent moduli
p->commitCurrentState(); // accept the step (resetCurrentState discards it)
delete p;
Every physics domain follows the same pattern: a *Material class paired with a *MP state
object. Parameters may be passed directly to the constructor, through the
materialProperties map, or resolved from the global materialDB registry.
➕ Adding a new model to a material family
Each family lives in its own directory (Smallstrain/, Finitestrain/, Fluid/, …) and
provides an abstract base pair — a *Material class and its *MP material point — from which
every concrete model derives. To add a model to an existing family:
- Create
Family/newmodel.handFamily/newmodel.cpp. Derive the material from the family base (e.g.smallStrainMaterial) and its point from the corresponding base (smallStrainMP). - Implement the pure virtual interface: on the material,
check(),getProperty(),print(),waveVelocity(),createMaterialPoint()andtest(); on the point,storedEnergy(),stress(),tangentTensor()and the state accessors. Read parameters from thematerialPropertiesmap using the names inUtils/utils.h. - Register the object files: add
newmodel.otoOBJECTSinFamily/makefile, and the matching$(OBJPATH)/Family/newmodel.oentry toMUESLI_FILESinmuesli/makefile. - Expose the header through
muesli.hif the model is part of the public API. - Add a call to the model’s
test()intest/core/test.cppand rebuild the verification suite.
Because test() reuses the built-in testImplementation() helper, a new model is checked
against finite-difference derivatives of its stored energy as soon as it is wired in, with no
extra test code to write.
🔗 Linking MUESLI to commercial codes
MUESLI is not meant to run standalone; it is embedded in a host solver through a thin,
largely method-agnostic adapter, so the same models can be driven from finite element,
finite volume or finite difference discretisations. Ready-made, C-linkage user-material
routines are provided for Abaqus (UMAT), ANSYS (USERMAT) and LS-DYNA
(*MAT_USER_DEFINED). The workflow is:
- Build MUESLI as a static library (see above).
- Compile the supplied user-subroutine stub and link it against
libmuesli_<arch>.a. - In the solver input deck, declare a user material with the constants the chosen MUESLI model expects and set the integer material label that selects it inside the interface routine.
Worked input decks and subroutine stubs for each code are collected under examples/ in the
repository.
🎯 Philosophy
- Clarity and extensibility are favoured over raw speed: models are written to be read, reused and derived from.
📘 User manual
A user manual can be freely accessed.
📗 Citing MUESLI
If you use the library, please cite the journal article in which it was described:
Portillo, D., del Pozo, D., Rodríguez-Galán, D., Segurado, J., Romero, I. (2017). MUESLI — a Material UnivErSal LIbrary. Advances in Engineering Software, 106, 1–8. doi:10.1016/j.advengsoft.2017.01.007