Skip to content

Conversation

@jhale
Copy link
Member

@jhale jhale commented Jan 28, 2026

Joint work with @chrisrichardson

This adds an optional SuperLU_dist interface to DOLFINx for solving systems constructed using MatrixCSR. The purpose of this is to provide a reasonable MPI-capable LU solver for DOLFINx builds without PETSc on all platforms.

The implementation is pretty light, and does not include SuperLU headers into our headers.

TODO:

  • Remove C++ demo, as it is trivial.
  • Currently hard-coded to use PETSc's SuperLU_dist, which is obviously missing the point.
  • Further documentation.

In future PRs:

  • dolfinx.fem.LinearProblem class for beginners.
  • To discuss: dolfinx.fem.NonlinearProblem class for beginners.

…enics/dolfinx into jhale/superlu-interface-deleters
L = form(L, dtype=dtype)

u_bc = Function(V, dtype=dtype)
u_bc.interpolate(lambda x: x[1]**3)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it be better to define

def u_ex(x):
    return x[1]**3

f = -div(grad(x))
u_bc.interpolate(u_ex)

so that if we ever change u_ex it is reflected everywhere at once.

declare_superlu_solver<double>(m, "float64");
declare_superlu_solver<float>(m, "float32");
declare_superlu_solver<std::complex<double>>(m, "complex128");
#endif // HAS_SUPERLU_DIST
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should just put the #ifdef inside declare_superlu_solver() - it gets called, but does nothing - just looks neater with fewer #ifdefs.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't mind the slight overuse of template ifs as long as they aren't nested.


uh = Function(V, dtype=dtype)
solver = superlu_solver(A)
solver.solve(b._cpp_object, uh.x._cpp_object)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this supposed to work without ._cpp_object?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, still TODO.

Co-authored-by: Jørgen Schartum Dokken <dokken92@gmail.com>
stype = _cpp.la.SuperLUSolver_complex128
else:
raise NotImplementedError(f"Type {dtype} not supported.")
return stype(A._cpp_object)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be wrapped in SuperLUSolver above?

Comment on lines +44 to +52
x = SpatialCoordinate(mesh)
u_exact = x[1] ** 3
f = -div(grad(u_exact))

L = inner(f, v) * dx
L = form(L, dtype=dtype)

u_bc = Function(V, dtype=dtype)
u_bc.interpolate(lambda x: x[1] ** 3)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
x = SpatialCoordinate(mesh)
u_exact = x[1] ** 3
f = -div(grad(u_exact))
L = inner(f, v) * dx
L = form(L, dtype=dtype)
u_bc = Function(V, dtype=dtype)
u_bc.interpolate(lambda x: x[1] ** 3)
def u_ex(x):
return x[1] ** 3
x = SpatialCoordinate(mesh)
f = -div(grad(u_ex(x)))
L = inner(f, v) * dx
L = form(L, dtype=dtype)
u_bc = Function(V, dtype=dtype)
u_bc.interpolate(u_ex)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants