Add Templating to ParticleSet, TrialWaveFunction, and OperatorBase?
- Dominant language
- C++
- Stars
- 403
- Forks
- 154
- Avg merge
- 1d 12h
- Merged PRs (30d)
- 82
Description
After discussion in PR#1934, and subsequent discussions related to fast force evaluation & spin-orbit implementations, I think it's time to discuss some potential design improvements. I'm open to anything that accomplishes my objectives, though I'm proposing the current solution for discussion.
**Summary:** Template ParticleSet and Wavefunctions on type of the degrees of freedom X. X=R, X=[R,S] for spin orbit code. Also template operators on X AND wave function type.
**Problems:**
1. Adding/manipulating degrees of freedom beyond 3D spin-conserved QMC in ParticleSet is an all-or-nothing approach. Moreover, addition of degrees of freedom often means we have to evaluate gradients and laplacians w.r.t. these additional degrees of freedom, which means adding new functions to TrialWaveFunction to allow access and evaluation to these quantities.
2. For fast force and spin-orbit evaluations, significant computational savings can be realized by exploiting the fact that we have determinantal+Jastrow style wavefunctions with small rank updates. For fast forces, its a factor of N speedup over the naiive implementation, and for spin-orbit, one can circumvent having to do an explicit integral over spin degrees of freedom, which saves a factor of N_grid (N_grid is the number of grid points used for numerical integration over the spin coordinate s. Remember that this is a nonlocal pseudopotential evaluation, so each spin value s has it's own pseudopotential quadrature calculation). Doing this currently is super awkward because TrialWaveFunction tries to be totally general and wavefunction component agnostic.
3. Spin dependent observables (spin-orbit \, spin density, etc) have fundamentally different evaluations based on whether we are doing spin-conserved or non-collinear/dynamical spin QMC. There's a risk of implicit coupling of ParticleSet and wave function type to the Operator if we spin off specific classes to handle these different evaluations.
**Design Objectives:**
1. Current behavior of code should be the default and ideally fallback behavior.
2. I would like the option to have faster operator evaluation based on wavefunction specific tricks. Faster evaluation means potentially storing wavefunction specific auxiliary quantities like temporary matrices by calling wavefunction specific functions.
3. I would like certain observables like spin-density to be handled by the same class. Details of how to evaluate if you have dynamical spins or how to speed up evaluation should be implementation details.
**Proposed Solution:**
1. ParticleSet and Walker will be templated on the type of X, which is the vector of dynamical degrees of freedom for each particle.
2. TrialWaveFunction will be templated on X; TrialWaveFunction\.
3. TrialWaveFunction\ types representing any special info that can be used to speed up evaluation. There are easily 3 cases I can think of:
- _General_: No special information other than it's a product wavefunction. Individual pieces can evaluate themselves efficiently, but that's it. Current behavior.
- _SPO based Determinantal+Jastrow (single and multideterminant)_: Single particle moves and one-body operators (like kinetic energy) have contributions from all SPO's in general. Backflow is the main example I can think of. Major formalism simplifications and potential speed ups for value and derivative evaluations by constructing and storing auxiliary matrices.
- _SPO based Determinantal+Jastrow with Rank 1 Updates (single and multideterminant)_: Single particle moves and one-body operators only work on single rows of slater matrix. Same advantages as above, but the low rank of the updates/one-body operators means you can shave factors off the operator evaluations.
- _Geminal based_? Dunno, but could be added once this framework is in place.
3. Operators and observables will be templated on X and wavefunction type; OperatorBase\. This allows a wavefunction agnostic default implementation for operators, with the opportunity to do wavefunction specific template instantiations to take advantage of performance tricks. To be specific, imagine a spin orbit operator: SOECPotential. Templated, I could have the following:
- SOECPotential\::evaluate(): Evaluates the s_z contribution to LxSx+LySy+LzSz, since s_x and s_y evaluate to zero in our normal spin conserved trial wavefunctions.
- SOECPotential\::evaluate(): Performs numerical integration over dynamical spin variable for arbitrary wavefunctions.
- SOECPotential\::evaluate(): Fast evaluation since spin integral can be done analytically given that I can build auxiliary quantities based on the spinors.
Contributor guide
Assessment
This issue has not been assessed yet.