NEML2 2.1.0
Loading...
Searching...
No Matches
Use LLM to explain NEML2 input file in natural language

Overall workflow

  1. Generate the NEML2 syntax database
  2. Parse an input file to extract objects and parameters
  3. Lookup each object's and parameter's description from the syntax database
  4. Convert the input file into a structured prompt
  5. Instantiate a chat-completion client
  6. Post the prompt to the client
  7. Receive the response from the chat client
import json
import os
import requests
from pathlib import Path
import subprocess
import neml2
from neml2.reader import describe
from neml2.reader._syntax import SyntaxDB
from neml2.reader._llm import LLMClient

Client

neml2.reader._llm.LLMClient defines the protocol for chat-completion client. It can be extended to define custom clients, e.g., OpenAI clients, Anthropic clients, etc.

In this example, we will use Argonne's Argo as the chat client. If you are not on Argonne's internal network, this example will not work. However, you can still use this example as a reference when wrapping your own chat clients.

For ANL employees, the request body requires a field "user" which should be your ANL domain username

ARGO_URL = "https://apps-dev.inside.anl.gov/argoapi/api/v1/resource/chat/"
class ArgoClient(LLMClient):
"""LLM client backed by the ANL Argo API."""
def __init__(self, model: str, api_key: str | None):
self._model = model
self._api_key = api_key or os.environ["ARGO_API_KEY"]
def complete(self, system: str, user: str) -> str:
payload = json.dumps(
{
"user": self._api_key,
"model": self._model,
"messages": [
{"role": "system", "content": system},
{"role": "user", "content": user},
],
"stop": [],
"temperature": 0.1,
"top_p": 0.9,
"max_completion_tokens": 64000,
}
)
headers = {"Content-Type": "application/json"}
response = requests.post(ARGO_URL, data=payload, headers=headers)
status = response.status_code
if status != 200:
raise RuntimeError(f"Argo API request failed with status {status}: {response.text}")
return response.json()["response"]

Extract the syntax database

# use the neml2-syntax tool to extract the syntax database from the C++ backend
bin = Path(neml2.__path__[0]) / "bin"
result = subprocess.run([str(bin / "neml2-syntax")], capture_output=True, text=True)
syntax = result.stdout
syntax_db = SyntaxDB(syntax=syntax)

Build the prompt

The describe method parses the input file and looks up object and parameter descriptions from the syntax database.

prompt = describe("demo_model.i", syntax_db, include_params=True)

Call the LLM chat client

client = ArgoClient(model="gpt54", api_key="thu") # replace with your actual API key
response = client.complete(*prompt)
# render the response as markdown in the notebook
from IPython.display import display, Markdown
display(Markdown(response))

This input defines a small-strain, isotropic elastoplastic material model with:

  • linear isotropic elasticity,
  • von Mises yielding,
  • Voce isotropic hardening,
  • and a temperature/rate-sensitive plastic flow law based on Kocks–Mecking ideas.

Its intended use is for metals where plastic flow changes character with temperature and strain rate: essentially rate-independent plasticity in one regime, but smooth transition to viscoplastic (Perzyna-type) flow when thermal activation becomes important.

High-level picture

You can think of the model as a standard J2 metal plasticity framework, but with a “smart gearbox” for the plastic multiplier:

  • when the normalized activation energy indicates conventional low-temperature / low-thermal-activation behavior, it behaves like rate-independent plasticity;
  • when activation becomes large enough, it switches to a rate-dependent overstress law;
  • the switch is smooth, not abrupt.

So the backbone is familiar: elastic predictor + von Mises yield check + isotropic hardening + associative flow, but the flow rate is governed by a Kocks–Mecking-based transition between two regimes.

Key components and how they interact

1. Stress measure and equivalent stress

  • mandel_stress maps Cauchy stress to Mandel stress. Under small strain isotropic conditions, these are effectively the same.
  • vonmises computes the von Mises equivalent stress s from the internal stress tensor M.

This provides the scalar driving stress for yielding.

2. Yield stress from Kocks–Mecking scaling

Three constants are defined:

  • A = -8.679
  • B = -0.744
  • C = -5.41

These are Kocks–Mecking parameters controlling thermal activation/rate sensitivity behavior.

ys computes the base yield stress as

\[\sigma_y = e^C \mu \]

where mu is the shear modulus, interpolated from temperature.

So the initial yield stress scales with the temperature-dependent shear modulus, which is physically reasonable for metals.

3. Isotropic hardening

isoharden is a Voce hardening law:

\[h = R \left(1 - e^{-d \bar{\varepsilon}_p}\right) \]

Here:

  • R = saturation hardening magnitude,
  • d = saturation rate,
  • both are interpolated from temperature.

This means the hardening response evolves with temperature: both the amount of hardening and how fast it saturates can change across the training temperatures.

The internal hardening variable k enters the yield condition as an additive resistance.

4. Yield function

yield defines the usual overstress function:

\[f = \bar{\sigma} - \sigma_y - k \]

where:

  • \bar{\sigma} is the von Mises stress,
  • \sigma_y is the Kocks–Mecking-based yield stress,
  • k is isotropic hardening.

There is also yield_zero, which sets the yield stress term to zero and writes an alternative yield function fp_alt. From the structure, this appears to be used specifically for the rate-dependent flow law, likely so the overstress expression is built in a convenient form using only hardening resistance. It is a modeling/implementation detail rather than a different physical mechanism.

5. Flow direction: associative plasticity

normality computes derivatives of the yield function with respect to:

  • stress M, giving the plastic flow direction NM,
  • hardening variable k, giving Nk.

Then:

  • Eprate uses associative flow to generate plastic strain rate:

    \[ \dot{\varepsilon}_p = -\dot{\gamma}\,\frac{\partial f}{\partial M} \]

  • eprate maps the same plastic multiplier to equivalent plastic strain rate:

    \[ \dot{\bar{\varepsilon}}_p = -\dot{\gamma}\,\frac{\partial f}{\partial k} \]

So this is classical associative J2 plasticity: plastic flow is normal to the yield surface.

6. Rate-independent and rate-dependent flow rules

Two possible plastic flow rates are computed.

Rate-independent branch

ri_flowrate enforces the standard consistency/complementarity condition through a smooth residual form. This is the usual return-mapping style plasticity behavior.

Rate-dependent branch

rd_flowrate uses a Perzyna overstress law:

\[\dot{\gamma} = \left(\frac{\langle f \rangle}{\eta}\right)^n \]

where:

  • n is from km_sensitivity,
  • \eta is from km_viscosity.

Both n and \eta depend on temperature and shear modulus through Kocks–Mecking relations, so the viscous response is physically informed rather than purely phenomenological.

7. Kocks–Mecking transition criterion

The model computes a normalized activation energy g:

\[g = \frac{kT}{\mu b^3}\ln\left(\frac{\dot{\varepsilon}_0}{\dot{\varepsilon}}\right) \]

This compares thermal energy and strain-rate effects against the material resistance scale.

A threshold g0 is computed from A, B, and C.
Then flowrate uses KocksMeckingFlowSwitch to smoothly blend between:

  • gamma_rate_ri (rate-independent),
  • gamma_rate_rd (rate-dependent),

with a sharpness of 100, meaning the transition is quite steep but still continuous.

Physically, this says: when thermal activation is below a critical level, use classical plasticity; above it, use thermally activated viscoplastic flow.

Elasticity and strain decomposition

elasticity is standard small-strain isotropic linear elasticity with:

  • Young’s modulus = 1e5
  • Poisson’s ratio = 0.3

and it is written in rate form.

Eerate computes elastic strain rate as:

\[\dot{\varepsilon}_e = \dot{\varepsilon} - \dot{\varepsilon}_p \]

So total strain rate is split into elastic and plastic parts in the usual additive small-strain sense.

Erate, integrate_stress, and integrate_ep indicate backward-Euler time integration of total strain, stress, and equivalent plastic strain/internal variables.

Temperature dependence

Several quantities are interpolated from temperature:

  • mu(T) shear modulus,
  • R(T) Voce saturation hardening,
  • d(T) Voce saturation rate.

This means the model is explicitly thermomechanically coupled through prescribed temperature-dependent properties, though not through heat generation or full thermodynamic temperature evolution. Temperature acts as an input field affecting stiffness, strength, hardening, and rate sensitivity.

Physical meaning of notable parameters

  • A, B, C: Kocks–Mecking constants controlling rate sensitivity, flow viscosity, threshold activation energy, and base yield level.
  • mu(T): temperature-dependent shear modulus; softens strength/rate parameters with temperature.
  • R(T): saturation amount of isotropic hardening.
  • d(T): rate at which hardening approaches saturation.
  • E = 1e5, ν = 0.3: linear elastic constants.
  • b = 2.474e-7: Burgers vector magnitude used in thermal activation formulas.
  • k = 1.38064e-20: Boltzmann constant in the chosen unit system.
  • eps0 = 1e10: reference strain rate for the Kocks–Mecking activation and viscosity expressions.
  • sharpness = 100: makes the RI/RD switch fairly abrupt.

The magnitude of the constants suggests a specific unit system is being used consistently; that matters a lot for interpreting the Boltzmann constant, Burgers vector, stress, and strain-rate scales.

Assumptions, limitations, and special features

Assumptions

  • Small strain formulation.
  • Isotropic elasticity and isotropic hardening.
  • J2/von Mises plasticity, so no tension-compression asymmetry or anisotropy.
  • Associative flow.
  • Temperature is an input, not a solved thermodynamic variable.

Limitations

  • No kinematic hardening, so cyclic phenomena like Bauschinger effect are not captured.
  • No crystal anisotropy or texture effects.
  • No finite-strain plasticity.
  • No damage, softening, or creep mechanism separate from the overstress law.

Special features

  • The most distinctive feature is the Kocks–Mecking-based smooth switch between rate-independent and rate-dependent plasticity.
  • Hardening and modulus are temperature-interpolated, allowing calibration to tabulated data.
  • The formulation is designed for mixed control, so it can handle combinations of prescribed stress and strain components in simulations.

In one sentence

This is a temperature-dependent small-strain J2 metal plasticity model with linear elasticity, Voce isotropic hardening, and a Kocks–Mecking-informed transition from classical rate-independent plasticity to Perzyna viscoplasticity as thermal activation and strain-rate effects become important.