In-memory Python solver
The simcoon.solver package drives the C++ material-point solver directly
from Python: the loading path is defined with Block
and StepMeca / StepThermomeca
objects, and the results come back as numpy arrays — no path.txt,
output.dat or result files involved. Since simcoon 2.0 this package is
sim.solver; legacy loading files are parsed into loading objects with
from_file() (the raw pre-2.0 file-to-file runner remains
available as the low-level binding simcoon._core.solver).
Quick start
A uniaxial tension test on an elastic isotropic material:
import numpy as np
from simcoon import solver
step = solver.StepMeca(
control=['strain'] + ['stress'] * 5, # E11 driven, lateral stress-free
value=[0.01, 0, 0, 0, 0, 0], # targets, Voigt order [11,22,33,12,13,23]
time=1.0, ninc=100,
)
res = solver.solve(step, "ELISO", [70000., 0.3, 1.E-5], nstatev=1)
stress = res["Stress"] # Cauchy stress history, shape (6, N)
strain = res["Strain"] # Green-Lagrange strain history, shape (6, N)
Results follow the fedoo DataSet conventions — components first, one
column per increment — so they interoperate directly with fedoo utilities
(e.g. fedoo.util.voigt_tensors.StressTensorList(res["Stress"])).
Available fields include Stress (Cauchy), Kirchhoff, PKII,
Strain, LogStrain, F, R, DR ((3, 3, N)),
TangentMatrix ((6, 6, N)), Statev, Wm, Time, Temp and,
for thermomechanical runs, Q, r, Wt and the coupled tangents
dSdE, dSdT, drdE, drdT.
Loading control
controlsets each component to'strain'(kinematically driven) or'stress'(statically driven); mixed control is solved by Newton-Raphson.Block(control_type=...)selects the strain/stress measures:'small_strain'(default),'green_lagrange'(PKII control),'logarithmic'(Kirchhoff control),'biot', or the fully kinematic'F'/'gradU'(9 components of the deformation gradient).solve(corate=...)selects the objective rate for the finite-strain control types:'jaumann','green_naghdi','logarithmic'(default),'logarithmic_R','truesdell','logarithmic_F'.mode='sinusoidal'interpolates the step sinusoidally instead of linearly;mode='tabular'follows a user table passed in memory:
t = np.linspace(0.01, 1.0, 100)
e11 = 0.015 * np.sin(np.pi * t)
step = solver.StepMeca(control=['strain'] + ['zero'] * 5,
mode='tabular',
tabular=np.column_stack([t, e11]))
Cyclic loading repeats the steps of a block:
Block(steps=[...], ncycle=10). Tabular steps cannot be cycled (their time column is absolute); unroll the cycles into explicit steps instead.A rotation rate can be superimposed on the mixed finite-strain control types through
StepMeca(BC_w=...)(3x3 spin matrix).
Thermomechanical loading
StepThermomeca activates the coupled heat equation
(block type 2, small strain), with thermal_control set to
'temperature' (ramp to T_final), 'heat_flux' (prescribed Q) or
'convection' (0D convection with coefficient q_conv):
step = solver.StepThermomeca(control=['stress'] * 6, value=[0.] * 6,
T_final=340., ninc=50)
# ELISO thermomechanical props: rho, c_p, E, nu, alpha
res = solver.solve(step, "ELISO", [1.E-9, 1., 70000., 0.3, 1.E-5], nstatev=1)
Mechanical steps (StepMeca) also accept T_final:
the temperature then ramps as an imposed condition of the mechanical problem
(thermal expansion without the heat equation).
Tabular thermomechanical steps support the three thermal controls: with
thermal_control='temperature' the table carries a T column when
tabular_T=True (constant temperature otherwise); with 'heat_flux' the
thermal column is the prescribed flux Q; with 'convection' there is no
thermal column and q_conv applies.
For finite-element couplers, the point-wise thermomechanical UMAT batch entry
sim.umat_T(...) complements sim.umat(...); it returns
(sigma, statev, Wm, Wt, r, dSdE, dSdT, drdE, drdT).
Legacy file formats
Existing path.txt / material.dat inputs are parsed into loading
objects — same solve, one entry point:
blocks, T_init = solver.from_file("data", "path.txt")
material = solver.material_from_file("data", "material.dat")
res = solver.solve(blocks, T_init=T_init, **material)
JSON configuration
Materials and loading paths round-trip through JSON
(save_material_json(),
save_path_json(),
load_simulation_json()):
solver.save_material_json("material.json", "ELISO", [70000., 0.3, 1.E-5], 1)
solver.save_path_json("path.json", [solver.Block(steps=[step])], T_init=293.15)
res = solver.solve(**solver.load_simulation_json("material.json", "path.json"))
Results can be persisted with res.save("run.npz") /
SolverResults.load("run.npz"), or flattened with res.to_dataframe().
Solver parameters
solve() exposes the numeric controls of the adaptive Newton loop as
keyword arguments: precision (default 1e-6), maxiter/miniter,
div_tnew_dt/mul_tnew_dt (time-step cut/growth factors), inforce,
lambda_solver (penalty stiffness of strain-driven components), plus
tangent_mode ('none', 'continuum', 'algorithmic' — default)
and solver_type.
API reference
- class simcoon.solver.StepMeca(control: str | Sequence[str | int] = 'strain', value: Sequence[float] | None = None, time: float = 1.0, ninc: int = 100, mode: str | int = 'linear', Dn_init: float = 1.0, Dn_mini: float = 0.001, BC_w: Sequence[Sequence[float]] | None = None, T_final: float | None = None, tabular: ndarray | None = None, tabular_T: bool = False)
A mechanical loading step.
- Parameters:
control (str or sequence of str) – Per-component control: ‘strain’ (kinematic) or ‘stress’ (static); ‘zero’ holds a component at zero for tabular steps. A single string applies to all components.
value (array-like, optional) – Absolute target values at the end of the step, per component, in Voigt order (6 components; 9 row-major for control types ‘F’/’gradU’). Not used for tabular steps.
time (float) – Duration of the step.
ninc (int) – Number of increments (linear and sinusoidal modes).
mode (str or int) – ‘linear’, ‘sinusoidal’ or ‘tabular’.
Dn_init (float, optional) – Initial and minimal sub-increment fraction of one increment (adaptive stepping). Defaults: 1.0 and 1e-3.
Dn_mini (float, optional) – Initial and minimal sub-increment fraction of one increment (adaptive stepping). Defaults: 1.0 and 1e-3.
BC_w (array-like, optional) – 3x3 spin matrix (rotation rate) applied during the step, for the mixed finite-strain control types (‘green_lagrange’, ‘logarithmic’, ‘biot’).
T_final (float, optional) – Target temperature at the end of the step (temperature ramp applied to the mechanical UMAT). None (default) holds the temperature.
tabular (ndarray, optional) – Mode-3 table, one row per increment. Columns: [time, (thermal column, see tabular_T and StepThermomeca.thermal_control), controlled components in Voigt order]. Required when mode=’tabular’. The time column is ABSOLUTE simulation time and must continue from the previous step’s end time (a table restarting at 0 after an earlier step is rejected: it would produce negative time increments). Tabular steps cannot be cycled (Block.ncycle must be 1).
tabular_T (bool) – Whether the tabular table contains a temperature column (after the time column). Default False (constant temperature). For thermomechanical heat-flux steps the thermal column is the flux Q and is always required, regardless of this flag.
- T_end(T_hold: float) float
Temperature at the end of the step (for chaining T_final=None steps).
- to_dict(control_type: int, T_hold: float) dict
Marshal to the dict consumed by simcoon._core.solver_run.
- Parameters:
control_type (int) – The control type of the enclosing block (drives the 6/9 sizing).
T_hold (float) – Temperature to hold when T_final is None (running block value).
- class simcoon.solver.StepThermomeca(control: str | Sequence[str | int] = 'strain', value: Sequence[float] | None = None, time: float = 1.0, ninc: int = 100, mode: str | int = 'linear', Dn_init: float = 1.0, Dn_mini: float = 0.001, BC_w: Sequence[Sequence[float]] | None = None, T_final: float | None = None, tabular: ndarray | None = None, tabular_T: bool = False, thermal_control: str = 'temperature', Q: float = 0.0, q_conv: float = 0.0)
A thermomechanical loading step (coupled heat equation).
In addition to the mechanical control of StepMeca:
- Parameters:
thermal_control (str) – ‘temperature’ (ramp to T_final), ‘heat_flux’ (prescribed flux Q) or ‘convection’ (0D convection Q = -q_conv (T - T_init)).
Q (float) – Prescribed heat flux (thermal_control=’heat_flux’).
q_conv (float) – Convection coefficient rho*c_p/tau (thermal_control=’convection’).
- T_end(T_hold: float) float
Temperature at the end of the step; flux/convection steps leave the chained hold temperature unchanged (the reached T is solution-dependent).
- class simcoon.solver.Block(steps: ~typing.List[~simcoon.solver.blocks.StepMeca] = <factory>, control_type: str | int = 'small_strain', ncycle: int = 1)
A loading block: a sequence of steps repeated ncycle times.
- Parameters:
steps (list of StepMeca / StepThermomeca) – The loading steps. If any step is a StepThermomeca, the block is thermomechanical (coupled heat equation) and all steps must be.
control_type (str or int) – Loading control (see CONTROL_TYPES). Thermomechanical blocks only support ‘small_strain’.
ncycle (int) – Number of repetitions of the step sequence.
- to_dict(T_hold: float) dict
Marshal to the dict consumed by simcoon._core.solver_run.
- simcoon.solver.solve(blocks: Block | StepMeca | Sequence[Block | StepMeca], umat_name: str, props: Sequence[float], nstatev: int, T_init: float = 293.15, corate: str | int = 'logarithmic', tangent_mode: str | int = 2, solver_type: int = 0, orientation: Sequence[float] = (0.0, 0.0, 0.0), record_tangent: bool = True, raise_on_abort: bool = True, **params) SolverResults
Solve a homogeneous loading path with the C++ simcoon solver, in memory.
- Parameters:
blocks (Block, StepMeca or sequence of them) – The loading path. Bare steps are wrapped in a small-strain Block.
umat_name (str) – Constitutive model name (5 characters, e.g. ‘ELISO’, ‘EPICP’, ‘MODUL’).
props (array-like) – Material properties.
nstatev (int) – Number of internal state variables.
T_init (float) – Initial temperature.
corate (str or int) – Objective rate for the finite-strain control types (see CORATE_TYPES).
tangent_mode (str or int) – Tangent operator mode: ‘none’, ‘continuum’, ‘algorithmic’ (default) or ‘closest_point’ (reserved).
solver_type (int) – 0 = classic Newton-Raphson (default), 1 = RNL (control_type 1 only).
orientation (sequence of 3 floats) – Euler angles (psi, theta, phi) of the material orientation (rad).
record_tangent (bool) – Capture the tangent operator history (‘TangentMatrix’ or the coupled thermomechanical tangents).
raise_on_abort (bool) – Raise a RuntimeError when the solver aborts early (status != 0) instead of returning the partial history.
**params – Numeric solver controls forwarded to the C++ loop: div_tnew_dt, mul_tnew_dt, miniter, maxiter, inforce, precision, lambda_solver (penalty stiffness of the strain-driven components).
- Returns:
History of the converged increments (fedoo-style data layout).
- Return type:
- simcoon.solver.from_file(path_data: str = 'data', pathfile: str = 'path.txt') Tuple[List[Block], float]
Parse a legacy loading path file into Block objects.
- Parameters:
path_data (str) – Folder containing the path file (and any mode-3 increment files it references).
pathfile (str) – Name of the loading path file.
- Returns:
blocks (list of Block) – The loading path, ready for
solve().T_init (float) – The initial temperature declared in the file.
- simcoon.solver.material_from_file(path_data: str = 'data', materialfile: str = 'material.dat') dict
Parse a legacy material definition file into solve() keyword arguments.
- Returns:
{‘umat_name’, ‘props’, ‘nstatev’, ‘orientation’} — mergeable into
solve()like the JSON loader.- Return type:
dict
- class simcoon.solver.SolverResults(raw: Dict[str, ndarray])
Dict-like access to the solver history.
- scalar_data
Scalar histories, shape (N,): ‘Time’, ‘Temp’, ‘Block’, ‘Cycle’, ‘Step’, ‘Inc’; thermomechanical runs add ‘Q’ (heat flux) and ‘r’ (heat source).
- Type:
dict
- field_data
Tensor histories, components-first: ‘Stress’ (Cauchy, (6, N)), ‘Kirchhoff’, ‘PKII’, ‘Strain’ (Green-Lagrange), ‘LogStrain’, ‘Statev’ ((nstatev, N)), ‘Wm’ ((4, N)), ‘F’, ‘R’, ‘DR’ ((3, 3, N)); ‘TangentMatrix’ ((6, 6, N)) for mechanical runs; thermomechanical runs add ‘Wt’ ((3, N)) and the coupled tangents ‘dSdE’ ((6, 6, N)), ‘dSdT’ ((6, N)), ‘drdE’ ((6, N)), ‘drdT’ ((N,)).
- Type:
dict
- status
0 if the simulation ran to completion, 1 on early abort (the recorded history is then partial).
- Type:
int
- get_data(key: str) ndarray
fedoo-style accessor (alias of __getitem__).
- classmethod load(filename: str) SolverResults
Load a SolverResults previously written by save().
- save(filename: str) None
Save all histories to a compressed npz archive.
- to_dataframe()
Flatten scalar and 6-component histories to a pandas DataFrame.