I am currently a post-doctoral researcher at the Université de Pau et des Pays de l’Adour in the LMAP. My research focuses on numerical methods for shape and topology optimization on curved meshes and is supervised by Fabien Caubet and Charles Pierre.
Before that, I was a research engineer at INRIA Paris working on cardiac hemodynamics, where I worked on numerical methods for cardiac hemodynamics in collaboration with Oscar Ruz, and the COMMEDIA team.
I did my Ph.D. at the Laboratoire Jean Kuntzmann in Grenoble under the supervision of Charles Dapogny, Eric Bonnetier and Rafael Estevez, where I developed numerical methods for surface shape and topology optimization and created a C++ finite element code called Rodin.
Broadly, my work sits at the interface between shape and topology optimization, differential geometry and scientific computing. I am interested in problems where the geometry itself is the unknown: how to represent an evolving shape (level sets, body-fitted meshes), how to differentiate a physical quantity with respect to it (shape and topological derivatives), and how to turn both into robust numerical algorithms. On the computational side, I care about writing finite element software that stays readable and fast, and that people other than its author can actually use.
Jiajun Wang (M2, 2026) — co-encadrement with Clément Moreau.
Level-Set Shape Optimization for Hydrodynamic Resistance in Stokes Flow.
Rodin is a modern C++20 finite element library for shape and topology optimization, providing the functionalities needed by such algorithms — from refining and remeshing the underlying shape to specifying and solving variational problems. It is named after Auguste Rodin, considered the founder of modern sculpture, and is distributed under the Boost Software License.
Variational formulations are written directly in C++20, close to their mathematical statement. Given a domain \( \Omega \) with boundary \( \Gamma := \partial \Omega \), the Poisson problem
\[\left\{ \begin{aligned} -\Delta u &= f && \text{in } \Omega \\ u &= 0 && \text{on } \Gamma \ , \end{aligned} \right.\]has the associated weak formulation
\[\text{find } u \in H^1_0(\Omega) \quad \text{s.t.} \quad \forall v \in H^1_0(\Omega), \quad \int_\Omega \nabla u \cdot \nabla v \ dx = \int_\Omega f v \ dx ,\]with \( H^1_0(\Omega) := { v \in H^1(\Omega) \mid v = 0 \text{ on } \Gamma } \), which is implemented in a few lines of code:
#include <Rodin/Types.h>
#include <Rodin/Solver.h>
#include <Rodin/Geometry.h>
#include <Rodin/Assembly.h>
#include <Rodin/Variational.h>
#include <Rodin/IO/XDMF.h>
using namespace Rodin;
using namespace Rodin::Solver;
using namespace Rodin::Geometry;
using namespace Rodin::Variational;
int main(int, char**)
{
Mesh mesh;
mesh = mesh.UniformGrid(Polytope::Type::Triangle, { 16, 16 });
mesh.getConnectivity().compute(1, 2); // Compute the boundary
P1 vh(mesh);
TrialFunction u(vh);
TestFunction v(vh);
RealFunction f = 1;
Problem poisson(u, v);
poisson = Integral(Grad(u), Grad(v))
- Integral(f, v)
+ DirichletBC(u, Zero());
CG(poisson).solve();
// Export for ParaView
IO::XDMF xdmf("Poisson");
xdmf.grid().setMesh(mesh).add("u", u.getSolution());
xdmf.write().flush();
xdmf.close();
return 0;
}
Beyond the form language, Rodin offers:
Full high-level mesh access. Iterators over cells, faces and vertices, on-demand connectivity between polytopes of any two dimensions, submesh extraction, boundary and interface meshes, level-set discretization and advection, and mesh partitioning (including a Scotch backend).
mesh.getConnectivity().compute(1, 2); // Given a face, its incident cells
for (auto it = mesh.getCell(); it; ++it)
std::cout << it->getIndex() << " : " << it->getMeasure() << '\n';
Finite element spaces and quadrature. P0, P1 and high-order H1 spaces (GLL, Fekete, warp and blend, and Dubiner bases), together with Gauss-Legendre, Gauss-Lobatto, Grundmann-Möller, and the Xiao-Gimbutas and Witherden-Vincent simplex rules.
P1 vh(mesh); // Piecewise linear
H1 wh(std::integral_constant<size_t, 2>{}, mesh); // Second order
QF::XiaoGimbutas qf(4, Polytope::Type::Triangle); // Degree 4 rule
Solvers. Eigen-backed iterative and direct solvers (CG, BiCGSTAB, GMRES, MINRES, IDR(s), SparseLU, SparseQR, Simplicial LDLT/LLT), optional SuiteSparse (UMFPACK, CHOLMOD, SPQR) and Apple Accelerate backends, and a Newton solver for nonlinear problems.
CG(poisson).solve(); // Iterative
SparseLU(poisson).solve(); // Direct
MMG integration. Bidimensional and tridimensional surface and volume remeshing is available directly from Rodin, controlling minimal and maximal edge sizes, gradation and Hausdorff distance — which is what makes level-set based shape optimization on evolving geometries practical.
MMG::Mesh Omega;
Omega.load("Omega.mesh", IO::FileFormat::MEDIT);
MMG::Optimizer().setHMin(0.01).setHMax(0.05).setGradation(1.2).optimize(Omega);
PETSc integration. A dedicated layer exposes the PETSc linear and nonlinear solvers, together with MPI-distributed P0 and H1 finite element spaces, for large-scale and distributed computations. It backs the Stokes, Navier-Stokes and fluid-structure interaction examples.
PETSc::Variational::TrialFunction u(vh);
PETSc::Variational::TestFunction v(vh);
Problem poisson(u, v);
// ... assemble, then solve with a PETSc Krylov method
Solver::KSP(poisson).solve();
Input/output and visualization. MEDIT and MFEM mesh and grid function formats, plus XDMF/HDF5 output — including time series — for direct visualization in ParaView.
mesh.save("Omega.mesh", IO::FileFormat::MEDIT);
IO::XDMF xdmf("Solution");
xdmf.grid().setMesh(mesh).add("u", u.getSolution());
xdmf.write().flush();
The repository ships examples ranging from level-set shape optimization (cantilevers, arches, eigenvalue problems) and optimization of regions supporting boundary conditions (acoustic cloaking, clamp locators, surface cooling) to Stokes and Navier-Stokes flows, fluid-structure interaction, nonlinear solid mechanics, Eikonal solvers and cardiac hemodynamics. The project is under active development, and every commit is built, tested, benchmarked and documented in CI. See the repository, the documentation or the getting started guide.
My thesis is available here.
It focused on the optimization of regions embedded within surfaces in \( \mathbb{R}^d \). It revisited classical shape optimization tools—such as Hadamard’s boundary variation technique and the topological derivative—and adapted them to a novel differential geometry framework tailored for surface-based problems.
A significant contribution was the development of a numerical strategy based on the level set method combined with precise geometric meshing, allowing for the tracking of evolving regions on curved surfaces under complex velocity fields, including large deformations and topological changes.
The work addressed the optimization of regions supporting specific boundary conditions (Dirichlet, Neumann, Robin) in PDE-constrained physical models. Applications included:
To support these developments, an open-source C++20 library was implemented for surface-based shape optimization. The thesis discussed the library’s design principles, syntax, and implementation examples, along with directions for future improvements.
Powered by Jekyll and Minimal Light theme.