Migrate depletion module to C++ part 1 of N#3986
Conversation
|
May be interesting to compare this with: |
paulromano
left a comment
There was a problem hiding this comment.
@eepeterson Thanks a ton for the PR! I haven't had a chance to look through in full yet, but right off the bat it would be very useful if you could share if you've done any comparisons on the accuracy of CRAM solutions for realistic systems as well as performance testing versus the current develop branch.
This repo has a nice set of benchmarks, perhaps the SS316 steel is a reasonably complex one |
Description
This PR is the first of a handful of steps towards moving the majority of the depletion module to C++. There are a number of reasons why we might want to do that some of which are listed below (there are tradeoffs as well obviously).
multiprocessingmodule which can cause installation and runtime headaches particularly on HPC systems.The general outline of the migration plan is as follows:
Specifically this PR replaces
CRAM16andCRAM48callables with analogous functions throughopenmc.liband the C API. To make this work we need to replacescipy.sparse.linalg.spsolvecalls with our own minimal sparse solver specific to CRAM. I debated trying to pull in SuperLU or Eigen for the sparse solve, but after digging into the details of both libraries and what is needed for CRAM specifically, I opted to roll our own solver which has many benefits. In particular, because the IPF form of CRAM has complex values on the diagonal whose imaginary parts are larger than 1, the pivots are unconditionally well-behaved and we don't need any of the partial (or complete) pivoting algorithms employed by SuperLU or Eigen.The main additions of this PR are the$A dt - \theta_\ell I$ explicitly and isn't intended to be a generic LU factorization routine but rather does the numeric factorization on the fly specific to the CRAM matrix structure. The symbolic factorization of $A dt - \theta_\ell I$ is done once and reused by each numeric factorization for all the poles of the cram solve. Then
CSCPatternandCSCMatrixclasses for theSymbolicLUFactorizationof matrices and data storage of burnup matrix elements. Then theBatemanSolverabstract base class and concrete implementation via theIPFCramSolverare added in C++ as mirrors of the current functionality on the Python side. The C++ CRAM solver is made accessible throughopenmc.liband it is wired in to take the place of the scipy based solver for theCRAM16andCRAM48functions. The numeric linear algebra work specific to CRAM is kept inbateman_solvers.cppsince thenumeric_factorize_cramfunction doesn't build the matrixtriangular_solve_luingests theSymbolicLUFactorizationandNumericLUFactorizationand performs the linear solve for each pole which then get accumulated to compute the final nuclide density from the initial one.Fixes # (issue)
Checklist