| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
Symbolic differentiation. C++ code generation. Nonlinear optimization. Differentiable simulation.
Docs · PDF · ACM Page
SymX is a C++ library for symbolic differentiation with automatic code generation, compilation and evaluation. Write complex mathematical expressions concisely, differentiate them arbitrarily, and let SymX evaluate them on your data structures — including global gradient and Hessian assembly.
SymX targets non-linear optimization pipelines typical of FEM solvers, but it can be used for any application that needs JIT compiled math. It uses a stencil-based perspective: expressions are defined per element and evaluated over a discretization. SymX is the core engine of STARK, a simulation framework for FEM elasticity, shells, rigid bodies, and frictional contact. SymX implements the adjoint method for differentiating through converged nonlinear simulations, enabling efficient inverse problems such as material, control, and shape identification.
Here is an overview of the SymX pipeline for FEM elasticity simulation:
The goal is to reduce time-to-solution. In research, the bottleneck is often the time between an idea and a trustworthy result. SymX lets you quickly iterate while avoiding sinking time in manual differentiation, testing derivatives, manual optimization, stack-indexed evaluation loops, parallelism/SIMD and more. You can develop complex solvers with great performance in a fraction of the time and code footprint, which quickly compounds productivity.
Here a list of simulations solved using SymX, corresponding to public research listed in Research Using SymX:
The following gallery shows some of such results:
Here are "hello world" examples for the lowest and highest entry points of SymX.
Workspace sws;
Scalar x = sws.make_scalar();
Scalar dsinx_dx = diff(sin(x), x);
Compiled<double> compiled({ dsinx_dx }, "hello_world", "../codegen");
compiled.set(x, 0.0);
View<double> result = compiled.run();
std::cout << "dsinx_dx(0.0) = " << result[0] << std::endl;It defines an expression containing derivatives. SymX writes the generated source, compiles it with your system compiler and loads the shared object. Then a numerical value is set for the symbol x, the function is executed and the result printed.
spGlobalPotential G = GlobalPotential::create();
G->add_potential("neohookean_tet4", tets,
[&](MappedWorkspace<double>& mws, Element& elem)
{
std::vector<Vector> x = mws.make_vectors(data.x, elem);
std::vector<Vector> X = mws.make_vectors(data.X, elem);
Scalar mu = mws.make_scalar(data.mu);
Scalar lambda = mws.make_scalar(data.lambda);
return neohookean_strain_energy_tet4(X, x, mu, lambda);
}
);
G->add_potential("inertia", vertices,
[&](MappedWorkspace<double>& mws, Element& elem)
{
Vector x = mws.make_vector(data.x, elem[0]);
Vector x0 = mws.make_vector(data.x0, elem[0]);
Vector v0 = mws.make_vector(data.v0, elem[0]);
Vector a = mws.make_vector(data.a, elem[0]);
Scalar m = mws.make_scalar(data.m, elem[0]);
Scalar dt = mws.make_scalar(data.dt);
return inertia_energy(x, x0, v0, a, dt, m);
}
);
G->add_dof(data.x);
spContext context = Context::create();
NewtonsMethod newton(G, context);
SolverReturn ret = newton.solve();Here we define two energy potentials using the functions shown in the diagram above. SymX solves the problem using Newton's Method with all default parameters. Data initialization is omitted for simplicity. SymX takes over the heavy lifting: differentiation of element gradient and Hessian, code generation, compilation, evaluation, projection to PD, assembly, linear solves, line search, etc.
This repository comes with a few examples to get you started. Select the desired experiment (or all) in examples/examples_main.cpp. You can find descriptions and links to the code in Examples in Docs.
Here is a summary:
Full documentation: https://symx.physics-simulation.org/
SymX bundles its core dependencies, requiring only CMake 3.15+ and a C++17 compiler.
cmake -B build
cmake --build build --parallel
build/tests/tests # Run tests
build/examples/examples # Run examplesSee Setup in Docs for a detailed explanation of how to set SymX up and integrate it in a parent CMake project.
Note for Windows users: JIT compilation may be significantly slower on Windows than on Linux or macOS due to the way compiler toolchains are loaded dynamically.
If SymX contributes to your research, please cite the paper.
@article{10.1145/3764928,
author = {Fern\'{a}ndez-Fern\'{a}ndez, Jos\'{e} Antonio and L\"{o}schner, Fabian and Westhofen, Lukas and Longva, Andreas and Bender, Jan},
title = {SymX: Energy-based Simulation from Symbolic Expressions},
year = {2025},
issue_date = {February 2026},
publisher = {Association for Computing Machinery},
address = {New York, NY, USA},
volume = {45},
number = {1},
issn = {0730-0301},
url = {https://doi.org/10.1145/3764928},
doi = {10.1145/3764928},
journal = {ACM Trans. Graph.},
month = oct,
articleno = {5},
numpages = {19},
keywords = {Physically-based simulation, symbolic differentiation, optimization time integration}
}SymX is exactly the kind of project that benefits from real use in real environments.
If you are:
then feel free to reach out!
| Back | FazBrowse Home | New Git URL |