Material Point Solver for Finite Strain Materials
Overview
The Material Point Solver (Finite Strain) provides a standalone driver for simulating the response of a single material point using finite strain constitutive models from the MAteRialMOdellingToolbox (marmot) framework.
Unlike the hypo-elastic solver, this class handles large deformations using full \(3\times3\) tensor kinematics. It solves for the Displacement Gradient (\(\nabla \mathbf{u}\)) and the Kirchhoff Stress (\(\boldsymbol{\tau}\)).
It is designed for:
Testing and verifying finite strain material models (e.g., hyperelasticity, finite plasticity),
Performing mixed displacement-gradient/stress-controlled loading paths,
Recording full tensor histories including material tangents and internal state variables.
The solver automatically handles time stepping, adaptive cutbacks upon non-convergence, and output formatting.
Main Features
Finite Strain Kinematics: Solves for \(\mathbf{F} = \mathbf{I} + \nabla \mathbf{u}\).
Mixed Control: Supports independent control of displacement gradient or stress for each of the 9 tensor components.
Adaptive Time Stepping: Automatically reduces time step size (\(\Delta t\)) if convergence fails.
Newton–Raphson Solver: robust iterative solver with configurable residual and correction tolerances.
History Recording: Stores time, stress, deformation gradient, tangent moduli, and state variables.
CSV Export: Exports simulation history for post-processing.
Solver Structure
The solver is organized around a few key data structures:
SolverOptions — Defines numerical tolerances (residual/correction) and iteration limits.
Step — Represents a loading phase. It defines target increments for \(\nabla \mathbf{u}\) and \(\boldsymbol{\tau}\), along with boolean flags determining which variable controls which tensor component.
Increment — A sub-step automatically generated within each Step based on time discretization.
HistoryEntry — Records the converged state (Time, \(\boldsymbol{\tau}\), \(\mathbf{F}\), \(\mathbb{C}\), state variables) at specific points.
Usage Workflow
A typical workflow consists of:
Initialize the solver with a material model name and properties.
Set the initial state (initial stress and internal variables).
Define one or more loading
Stepobjects with control flags and targets.Add the steps to the solver.
Solve the problem.
Inspect or export the resulting history.
Example Usage
Here is a simple example demonstrating how to set up and run the finite strain material point solver using a compressible Neo-Hookean material model.
It can be found in the examples/finite-strain-mp-solver/CompressibleNeoHooke directory of the Marmot repository together with the appropriate CMakeLists.txt.
1#include "Marmot/MarmotFastorTensorBasics.h"
2#include "Marmot/MarmotMaterialPointSolverFiniteStrain.h"
3
4int main()
5{
6 using namespace Marmot::Solvers;
7 using namespace Marmot::FastorStandardTensors;
8
9 // 1) Define the material model
10 std::string materialName = "COMPRESSIBLENEOHOOKE";
11 double properties[] = { 3500, 1500 }; // Example: Bulk and Shear moduli
12 int nProps = 2;
13
14 // 2) Configure solver options
15 MarmotMaterialPointSolverFiniteStrain::SolverOptions options;
16 options.maxIterations = 25;
17 options.residualTolerance = 1e-10;
18 options.correctionTolerance = 1e-10;
19
20 // 3) Create solver instance
21 MarmotMaterialPointSolverFiniteStrain solver( materialName, properties, nProps, options );
22
23 // 4) Set the initial state
24 int nSV = solver.getNumberOfStateVariables();
25 Eigen::VectorXd initialSV = Eigen::VectorXd::Zero( nSV );
26
27 // Initial stress is zero
28 solver.setInitialState( Tensor33d( 0.0 ), initialSV );
29
30 // 5) Define a loading step (Uniaxial extension in 11-direction)
31 MarmotMaterialPointSolverFiniteStrain::Step step;
32 step.timeStart = 0.0;
33 step.timeEnd = 1.0;
34 step.dTStart = 0.1;
35 step.dTMin = 1e-6;
36 step.dTMax = 0.5;
37
38 // Initialize targets and flags
39 step.gradUIncrementTarget = Tensor33d( 0.0 );
40 step.stressIncrementTarget = Tensor33d( 0.0 );
41 step.isGradUComponentControlled = Tensor33t< bool >( false );
42 step.isStressComponentControlled = Tensor33t< bool >( true );
43
44 // Setup Control:
45 // - Control gradU_11 (stretch to 50%)
46 step.gradUIncrementTarget( 0, 0 ) = 0.5;
47 step.isGradUComponentControlled( 0, 0 ) = true;
48
49 // - Unset control on tau_11
50 step.isStressComponentControlled( 0, 0 ) = false;
51
52 // 6) Run the solver
53 solver.addStep( step );
54 solver.solve();
55
56 // 7) Output the results
57 solver.exportHistoryToCSV( "finite_strain_history.csv" );
58
59 return 0;
60}
To compile and run the example, you can use cmake with the configuration CMakeLists.txt. Ensure that the paths to Marmot, Eigen, and Fastor match your system configuration.
1cmake_minimum_required(VERSION 3.16)
2project(MarmotSolverExample LANGUAGES CXX)
3
4set(CMAKE_CXX_STANDARD 20)
5set(CMAKE_CXX_STANDARD_REQUIRED ON)
6set(CMAKE_CXX_EXTENSIONS OFF)
7
8find_package(Python3 COMPONENTS Interpreter REQUIRED)
9
10execute_process(
11 COMMAND "${Python3_EXECUTABLE}" -c "import sys; print(sys.prefix, end='')"
12 OUTPUT_VARIABLE PYTHON_PREFIX
13 OUTPUT_STRIP_TRAILING_WHITESPACE
14)
15
16set(MARMOT_ROOT "${PYTHON_PREFIX}")
17set(EIGEN_DIR "${PYTHON_PREFIX}/include/eigen3")
18set(FASTOR_DIR "${PYTHON_PREFIX}/include/Fastor")
19
20add_executable(solver_example example.cpp)
21
22target_include_directories(solver_example PRIVATE
23 "${MARMOT_ROOT}/include"
24 "${EIGEN_DIR}"
25 "${FASTOR_DIR}"
26)
27
28target_link_directories(solver_example PRIVATE "${MARMOT_ROOT}/lib")
29
30target_link_libraries(solver_example PRIVATE Marmot)
31
32target_compile_options(solver_example PRIVATE -Wall -Wextra -fPIC)
33
34set_target_properties(solver_example PROPERTIES
35 BUILD_RPATH "${MARMOT_ROOT}/lib"
36 INSTALL_RPATH "${MARMOT_ROOT}/lib"
37)
Typical Output
Running the solver prints detailed convergence information to the console:
Solving step from 0 to 1
+------------------------------------------------------------------------------+
Solving increment 1, time: 0 to 0.1, dT: 0.1
Iteration 0, ||ddGradU||: 0.00e+00, ||R||: 5.00e-02
Iteration 1, ||ddGradU||: 1.25e-03, ||R||: 4.12e-05
Iteration 2, ||ddGradU||: 2.10e-07, ||R||: 1.10e-11
Converged after 3 iterations.
Material state for time: 1.000000e-01
tau:
[2.500000e+01, 0.000000e+00, 0.000000e+00
0.000000e+00, 0.000000e+00, 0.000000e+00
0.000000e+00, 0.000000e+00, 0.000000e+00]
...
Guidelines and Notes
Tensors: The solver uses the Fastor library. Inputs usually expect
Tensor33d(3x3 double) orTensor9d(flattened 9x1 double).Control Flags: For every component \((i,j)\) of the \(3\times3\) tensor, exactly one of
isGradUComponentControlled(i,j)orisStressComponentControlled(i,j)must be set to true. TheStep::checkControl()method enforces this.Singularity Handling: When using mixed control, the tangent matrix is modified to ensure invertibility. Rows corresponding to displacement-controlled components are zeroed and the diagonal set to 1.
Stress Measure: The solver works with Kirchhoff stress (\(\boldsymbol{\tau}\)). If the material model computes Cauchy stress, it must be converted internally or by the model.
CSV Export
The history can be exported to CSV. The columns are formatted as follows:
Time: Simulation time.
tau[9]: Kirchhoff stress components (11, 12, 13, 21, 22, 23, 31, 32, 33).
F[9]: Deformation gradient components (11, 12, 13, 21, 22, 23, 31, 32, 33).
SV[N]: Internal state variables (SV1, SV2, …).
-
class MarmotMaterialPointSolverFiniteStrain
Collaboration diagram for Marmot::Solvers::MarmotMaterialPointSolverFiniteStrain:
![digraph {
graph [bgcolor="#00000000"]
node [shape=rectangle style=filled fillcolor="#FFFFFF" font=Helvetica padding=2]
edge [color="#1414CE"]
"1" [label="Marmot::Solvers::MarmotMaterialPointSolverFiniteStrain" tooltip="Marmot::Solvers::MarmotMaterialPointSolverFiniteStrain" fillcolor="#BFBFBF"]
"2" [label="Marmot::Solvers::MarmotMaterialPointSolverFiniteStrain::SolverOptions" tooltip="Marmot::Solvers::MarmotMaterialPointSolverFiniteStrain::SolverOptions"]
"1" -> "2" [dir=forward tooltip="usage"]
}](../../_images/graphviz-210e4306797f93867821a57b9939c7e9823af127.png)
Solver for material point problems with finite strain materials.
This class implements a solver for material point problems using finite strain material models. It supports loading steps with controlled displacement gradient and stress components, adaptive time stepping, and history recording.
Public Functions
-
MarmotMaterialPointSolverFiniteStrain(const std::string &materialName, const double *materialProperties, const int nMaterialProperties, const SolverOptions &options)
Constructor for the MarmotMaterialPointSolverFiniteStrain class.
- Parameters:
materialName – Name of the finite strain material model
materialProperties – Array of material properties
nMaterialProperties – Number of material properties
options – Solver options controlling nonlinear iteration settings
-
void addStep(const Step &step)
Add a loading step to the solver.
- Parameters:
step – The Step to be added
-
inline std::vector<Step> getSteps() const
Get the list of added loading steps.
- Returns:
A vector of Step containing the added steps
-
inline void clearSteps()
Clear all added loading steps.
-
void setInitialState(const FastorStandardTensors::Tensor33d &initialStress, const Eigen::VectorXd &initialStateVars)
Set the initial state of the material model.
- Parameters:
initialStress – The initial stress in Voigt notation
initialStateVars – The initial state variables
-
inline int getNumberOfStateVariables() const
Get the number of state variables in the material model.
- Returns:
The number of state variables
-
void resetToInitialState()
Reset the solver to the initial state.
This function resets the initial stress and state variables of the material model.
-
void solve()
Solve the material point problem for all added steps.
-
inline const std::vector<HistoryEntry> &getHistory() const
Get the recorded history of the simulation.
- Returns:
A vector of HistoryEntry containing the recorded history
-
inline void clearHistory()
Clear the recorded history.
-
void printHistory()
Print the recorded history to the console.
-
void exportHistoryToCSV(const std::string &filename)
Export the recorded history to a CSV file.
- Parameters:
filename – The name of the CSV file to export to
Private Functions
-
void solveStep(const Step &step)
Solve a single loading step.
This function iterates over the increments defined in the step, calling solveIncrement for each increment. It manages time stepping and ensures that the entire step is covered.
- Parameters:
step – The Step to be solved
-
void solveIncrement(const Increment &increment)
Solve a single increment within a loading step.
This function implements a Newton-Raphson iterative solver to compute the stress and deformation state for the given increment. It updates the material state variables and records the history after convergence.
-
FastorStandardTensors::Tensor9d computeResidual(const FastorStandardTensors::Tensor9d &stressIncrement, const FastorStandardTensors::Tensor9d &target, const Increment &increment)
Compute the residual for the current increment.
This function calculates the residual vector based on the difference between the computed stress increment and the target increment, taking into account which components are controlled by strain or stress.
- Parameters:
stressIncrement – The computed stress increment
target – The target (mixed) stress/strain increment
increment – The Increment containing control information
- Returns:
The computed residual vector
-
void modifyTangent(FastorStandardTensors::Tensor99d &tangent, const Increment &increment)
Modify the material tangent matrix based on control type.
This function adjusts the tangent matrix to account for the components that are controlled by displacement gradient or stress, ensuring that the solver correctly handles mixed control scenarios. This is done by zeroing out rows corresponding to displacement gradient controlled components and setting their diagonal entries to one.
- Parameters:
tangent – The material tangent matrix to be modified
increment – The Increment containing control information
Private Members
-
std::unique_ptr<MarmotMaterialFiniteStrain> material
The finite strain material model.
-
int nStateVars
Number of state variables in the material model.
-
Eigen::VectorXd stateVars
Current state variables.
-
Eigen::VectorXd _initialStateVars
Initial state variables.
-
Eigen::VectorXd stateVarsTemp
Temporary state variables for computations.
-
FastorStandardTensors::Tensor33d stress = FastorStandardTensors::Tensor33d(0.0)
The Kirchhoff stress.
-
FastorStandardTensors::Tensor33d _initialStress = FastorStandardTensors::Tensor33d(0.0)
The initial Kirchhoff stress.
-
FastorStandardTensors::Tensor33d gradU = FastorStandardTensors::Tensor33d(0.0)
The displacement gradient.
-
FastorStandardTensors::Tensor3333d dTau_dF = FastorStandardTensors::Tensor3333d(0.0)
The material tangent dTau/dF.
-
std::vector<HistoryEntry> history = std::vector<HistoryEntry>()
History of the simulation.
-
const SolverOptions options
Solver options.
-
struct HistoryEntry
Struct to record the history of the simulation.
Each entry contains time, stress, deformation, and state variables.
Public Functions
-
inline void print() const
Print the history entry to the console.
-
inline HistoryEntry(double time, const FastorStandardTensors::Tensor33d &stress, const FastorStandardTensors::Tensor33d &F, const FastorStandardTensors::Tensor3333d &dTau_dF, const Eigen::VectorXd &stateVars)
Constructor for HistoryEntry.
- Parameters:
time – Time at the history entry
stress – Stress tensor at the history entry
F – Deformation gradient at the history entry
dTau_dF – Material tangent at the history entry
stateVars – State variables at the history entry
-
inline HistoryEntry()
Public Members
-
double time
Time at the history entry.
-
FastorStandardTensors::Tensor33d stress
Stress at the history entry.
-
FastorStandardTensors::Tensor33d F
deformation gradient at the history entry
-
FastorStandardTensors::Tensor3333d dTau_dF
Material tangent at the history entry.
-
Eigen::VectorXd stateVars
State variables at the history entry.
-
inline void print() const
-
struct Increment
Struct to define a loading increment.
Each increment contains displacement gradient and stress increments, control flags, time information, and iteration limits.
Public Members
-
FastorStandardTensors::Tensor9d gradUIncrement
Target displacement gradient increment for the step.
-
FastorStandardTensors::Tensor9d stressIncrement
Target Kirchhoff stress increment for the step.
-
FastorStandardTensors::Tensor9t<bool> isGradUComponentControlled
Flags to indicate which displecement gradient components are controlled
-
FastorStandardTensors::Tensor9t<bool> isStressComponentControlled
Flags to indicate which stress components are controlled.
-
double timeOld
Old time at the beginning of the increment.
-
double dT
Time step size for the increment.
-
FastorStandardTensors::Tensor9d gradUIncrement
-
struct SolverOptions
Struct to define solver options.
Contains parameters for controlling the solver’s behavior.
Public Members
-
int maxIterations = 25
Maximum number of iterations per increment (default: 25)
-
double residualTolerance = 1e-10
Convergence tolerance (default: 1e-10)
-
double correctionTolerance = 1e-10
Correction tolerance (default: 1e-10)
-
int maxIterations = 25
-
struct Step
Struct to define a loading step.
Each step contains targets for displacement gradient and stress states, time information and time step control parameters.
Public Functions
-
inline void checkControl() const
Check that for each component, either deformation or stress is controlled.
- Throws:
std::runtime_error – if the condition is not met
Public Members
-
FastorStandardTensors::Tensor33d gradUIncrementTarget
Target displacement gradient increment for the step.
-
FastorStandardTensors::Tensor33d stressIncrementTarget
Target Kirchhoff stress increment for the step.
-
FastorStandardTensors::Tensor33t<bool> isGradUComponentControlled
Flags to indicate which displacement gradient components are controlled
-
FastorStandardTensors::Tensor33t<bool> isStressComponentControlled
Flags to indicate which stress components are controlled.
-
double timeStart = 0.0
Start time of the step.
-
double timeEnd = 1.0
End time of the step.
-
double dTStart = 0.1
Initial time step size.
-
double dTMin = 1e-6
Minimum time step size.
-
double dTMax = 0.5
Maximum time step size.
-
int maxIncrements = 100
Maximum number of increments in the step.
-
inline void checkControl() const
-
MarmotMaterialPointSolverFiniteStrain(const std::string &materialName, const double *materialProperties, const int nMaterialProperties, const SolverOptions &options)