Norma is a Julia prototype for testing algorithms and ideas for coupling and multiphysics, primarily in solid mechanics and heat conduction.
Impact simulation of two bars using different time integrators and
mesh types: the left bar uses hexahedral elements with an implicit
time integrator; the right bar uses tetrahedral elements with an
explicit time integrator. Each subdomain advances independently with
its own time step. (~100,000 elements)
Dynamic torsion of a solid cylinder undergoing large deformations. (~160,000 elements)
Large-deformation vibration of a soft rubber ball. The animation
plays in real time (100 frames per second) to match simulation
time. (~300,000 elements)
# Self-activating CLI wrapper (recommended)
bin/norma input.yaml
# Multi-threaded
bin/norma input.yaml --threads 8
# Or directly with julia
julia --project=. src/Norma.jl input.yamlInteractive:
using Pkg; Pkg.activate(".")
using Norma
Norma.run("input.yaml")- A prototyping framework for multiphysics and coupling algorithms
- Focused on solid mechanics and heat conduction
- Designed for high extensibility and experimentation
- Supports implicit and explicit time integrators
- Features
- Installation
- Running the Code
- Testing
- Examples
- Profiling
- Debugging
- Troubleshooting
- License
- Documentation
A prototyping framework for solid mechanics, multiphysics, and coupling algorithms, with an emphasis on extensibility and experimentation. The capabilities currently implemented are:
Material models (infinitesimal- and finite-strain kinematics)
- Linear elastic
- Saint-Venant–Kirchhoff
- Neohookean
- Seth-Hill (generalized hyperelastic with tunable exponents)
- J2 plasticity (finite deformation, multiplicative split, radial return, linear isotropic hardening)
Time integration
- Quasi-static (with adaptive stepping)
- Newmark (implicit dynamic)
- Central difference (explicit dynamic, CFL-controlled)
Solvers
- Newton's method (Hessian minimizer) with optional backtracking line search
- Matrix-free steepest descent
- Explicit (lumped-mass) solver
Element library
- 1D: BAR2
- 2D: TRI3, TRI6, QUAD4
- 3D: TETRA4, TETRA10, HEX8
- Gauss, Dunavant, and Keast quadrature rules
Multidomain coupling — Schwarz alternating method
- Single-domain and multi-domain simulations
- Overlapping and non-overlapping (Dirichlet–Neumann) Schwarz
- Robin–Robin and impedance-matching (absorbing) Schwarz
- Frictionless/tied contact via Schwarz
- Fixed and Aitken (Irons–Tuck) adaptive relaxation, with interface predictor acceleration
Boundary conditions
- Dirichlet (time-dependent displacement/velocity/acceleration)
- Neumann traction and pressure
- Robin (mixed displacement–traction)
- Inclined-surface support via rotation matrices
Reduced-order models
- Operator Inference (OpInf): linear, quadratic, cubic, and neural-network ROMs (the neural-network variant needs the optional PyCall + PyTorch backend; the rest are pure Julia)
- RBF kernel ROMs (Gaussian, inverse quadratic, inverse multiquadric, thin-plate-spline, Matérn variants)
Adaptive mesh swapping
- Triggered by time, stress-recovery error, overlap L2 displacement error, or elastic-to-plastic transition
Nodal recovery and field transfer
- L2-projection recovery (lumped and consistent mass) of stress, von Mises stress, deformation gradient, and internal variables
- Mesh-to-mesh field transfer for multidomain and remeshing workflows
Input/output
- YAML input configuration
- Exodus II output (nodal, element, and global variables)
- CSV output of nodal and side-set quantities
cd /path/to
git clone git@github.com:sandialabs/Norma.jl.git
cd Norma.jl
juliaWithin the Julia package manager (enter by pressing ] in the Julia REPL):
pkg> activate .
pkg> registry update
pkg> update
pkg> instantiatePress Backspace or Delete to exit the package manager.
This installs no Python dependencies. Norma's full-order solver, Schwarz
coupling, the linear/quadratic/cubic OpInf ROMs, and the RBF kernel ROMs are all
pure Julia. Only the neural-network OpInf ROM needs Python (PyTorch via
PyCall); it is an optional package extension.
To enable it, add PyCall to the environment and make sure its Python has
torch installed:
pkg> add PyCallJulia then loads the backend automatically. Without it, requesting a
neural network opinf rom aborts with a message telling you to install PyCall.
If Interested in Reduced Order Model (ROM) Capabilities in Norma: Clone and Build Norma-OpInf Repository
cd /path/to
git clone git@gitlab-ex.sandia.gov:ejparis/norma-opinf.git
cd /path/to/norma-opinf
pip install -e .For this, Python3 is required. For more details and troubleshooting, please see the norma-opinf repository.
To run the main program, assuming Julia is in your executable path:
julia --project=@/path/to/Norma.jl /path/to/Norma.jl/src/Norma.jl input.yamlTo run Norma interactively from a Julia session:
cd /path/to/Norma.jl
julia
using Pkg
Pkg.activate(".")
using NormaThen, navigate to your desired example folder and run the simulation. For example:
cd("examples/contact/implicit-dynamic/2-bars")
Norma.run("bars.yaml")Note: If you make changes to the Norma code, you need to reload the Norma module (using Norma) for those changes to take effect.
Running Norma with OpInf ROMs is a process consisting of three steps. More details can be found in the README file found here.
Run the main program in FOM mode, assuming Julia is in your executable path:
julia --project=@/path/to/Norma.jl /path/to/Norma.jl/src/Norma.jl input.yamlafter modifying input.yaml to enable CSV output and CSV write sidesets, e.g.,
CSV output interval: {time_step}
CSV write sidesets: true
An example input file can be found here.
Please see the Norma-OpInf repo Wiki Page for details.
Run the main program in ROM mode, assuming Julia is in your executable path:
julia --project=@/path/to/Norma.jl /path/to/Norma.jl/src/Norma.jl input_rom.yamlafter modifying input_rom.yaml to utilize a ROM model type and read in the .npz file produced in Step 2, e.g.,
model:
type: linear opinf rom
model-file: opinf-operator.npz
An example ROM input file can be found here.
bin/norma input.yaml --threads 8Or via the environment variable:
JULIA_NUM_THREADS=8 julia --project=. src/Norma.jl input.yamlInside Julia:
using Pkg
Pkg.activate("/path/to/Norma.jl")
using Norma
Norma.run("input.yaml")To run the test suite using the Julia REPL:
using Pkg
Pkg.test()Or from the command line:
cd /path/to/Norma.jl/test
julia --project=@/path/to/Norma.jl ./runtests.jlBy default, all tests are run.
You can control which tests are run using command-line arguments.
julia --project=@/path/to/Norma.jl ./runtests.jl --quickUse this when you want to verify functionality quickly without running the full suite.
julia --project=@/path/to/Norma.jl ./runtests.jl 1 3 5julia --project=@/path/to/Norma.jl ./runtests.jl --listTo run tests whose filenames contain a given string (case-insensitive):
julia --project=@/path/to/Norma.jl ./runtests.jl --filter cubeYou can combine filters with specific indices or --quick:
julia --project=@/path/to/Norma.jl ./runtests.jl --quick --filter dynamic
julia --project=@/path/to/Norma.jl ./runtests.jl 2 4 --filter staticTo run the examples/contact/implicit-dynamic/2-bars example:
cd /path/to/Norma.jl/examples/contact/implicit-dynamic/2-bars
julia
]
activate .
using Norma
Norma.run("bars.yaml")To identify performance bottlenecks in Norma.jl, you can use Julia's built-in Profile module and visualize results with ProfileCanvas.jl:
using Profile
include("/path/to/Norma.jl/src/Norma.jl")
cd("/path/to/Norma.jl/examples/contact/implicit-dynamic/2-bars")
@profile Norma.run("bars.yaml")using Pkg; Pkg.add("ProfileCanvas")
using ProfileCanvas
ProfileCanvas.canvas()julia --project=@/path/to/Norma.jl -e 'using Profile; using Norma; cd("examples/contact/implicit-dynamic/2-bars"); @profile Norma.run("bars.yaml")' -E 'using ProfileCanvas; ProfileCanvas.canvas()'To enable debug-level logging in Norma.jl, use the JULIA_DEBUG environment variable:
JULIA_DEBUG=Norma julia --project=@/path/to/Norma.jl /path/to/Norma.jl/src/Norma.jl input.yamlTo add debug messages in code:
@debug "Starting simulation with input file: input.yaml"To disable debug printing:
unset JULIA_DEBUGOr suppress it at launch:
JULIA_DEBUG= julia --project=@/path/to/Norma.jl /path/to/Norma.jl/src/Norma.jl input.yamlIf you are on Sandia's network and run into SSL/TLS certificate errors when installing or fetching packages, see README-sandia.md for a complete setup guide.
Norma.jl is licensed under the BSD 3-Clause License. See LICENSE.md for details.
While we do not have documentation of the Norma.jl code, we have documented a number of application-motivated test cases available in the Norma.jl repository in the following slides. The input and mesh files for these test cases can be found in the Norma.jl/examples/ahead directory.