Skip to content

feat(librpa): strict 2D/3D Coulomb kernels and 2D reader-v1 producer outputs - #8176

Open
AroundPeking wants to merge 14 commits into
deepmodeling:developfrom
AroundPeking:abacus-librpa-strict2d-oct17
Open

AroundPeking wants to merge 14 commits into
deepmodeling:developfrom
AroundPeking:abacus-librpa-strict2d-oct17

Conversation

@AroundPeking

Copy link
Copy Markdown

Problem

  • After the module_rpa split (Title: refactor(rpa): move LibRPA producer into module_rpa #8154), develop still lacks strict-2D support: the Ewald short-range tail machinery, direct 2D mixed-Fourier / 3D reciprocal Coulomb kernels, the strict-2D head normalization, and the 2D reader-v1 producer outputs needed by LibRPA's 2D (slab) GW/RPA pipeline.
  • Two latent defects surface once this machinery runs test geometries: the Ewald tail completeness check bounds the projected Gaussian tensor by the raw gaussianized-aux radius sum instead of the RI pipeline's integral support, so rpa_scf_gamma's guard shell always fails coverage in warn mode; and Symmetry_rotation_k::wigner_d overflows int factorials for l>=5, producing NaN rotation matrices.

Change

  • module_ri: port the strict-2D/3D kernels, Ewald tail planner/checker, Gaussian 2D integrals, MPI shell-key distribution, and LRI_CV extensions (adapted to develop's p_info_ri/timer conventions); restore the empty-abfs construction branch in Exx_LRI::init_spencer; bound the tail check's Gaussian support by min(cal_V_Rcut); evaluate wigner_d factorials in double.
  • module_rpa: port the strict-2D head sidecar and direct-Coulomb output wiring into output_ewald_coulomb with v1 naming, plus the LibRPA io writers (head / structure symmetry / BZ sampling) and ABFS preorthogonalization.
  • Input parameters and Exx_Info_RI / XC functional fields for all of the above, with read_input unit tests.
  • Tests: new 61_librpa_2d_reader_v1 producer contract (including the head sidecar) with single-rank-layout references; regenerated Ewald far-field coulomb_mat references for rpa_scf_gamma / rpa_scf_shrink_multik (energies unchanged to 4e-13 eV); unit tests for the kernels, tail utilities, io writers, and symmetry rotation.

Validation

  • ctest -R "MODULE_RI|MODULE_RPA|read_input|op_exx" — 24/24 pass, including the
    direct 2D/3D Coulomb kernels, the Ewald tail planner and utilities, the Gaussian
    2D integrals, the reader-v1 io writers, and the symmetry rotation tests.
  • 08_RI integration suite (4 MPI ranks): rpa_scf_gamma and rpa_scf_shrink_multik
    pass with the regenerated Ewald far-field references; bse_lr_multik,
    rt_tddft_pbe0_gamma, and the LibRPA producer contract (cases 60/61/64, including
    the strict-2D head sidecar) pass. The hse / lr_tddft / lr_relax failures seen
    locally are LibXC-dependent cases under an ENABLE_LIBXC=OFF build; CI builds
    with LibXC enabled.

…strict-2D RI-EXX

Add the strict-2D/3D Ewald Coulomb controls (ewald dimension, lambda, tail
check mode with tolerances and adaptive expansion limits, direct
mixed-Fourier 2D and reciprocal 3D Coulomb output selection with quadrature
orders, RPA ABFS preorthogonalization, EXX V-matrix screening thresholds)
to the input parameters, wire them through the EXX reading path, and extend
Exx_Info_RI and the XC functional type so downstream RI modules can consume
them. read_input unit tests cover the new keywords.
…metry wiring

Port the strict-2D RI-EXX machinery: direct mixed-Fourier 2D and reciprocal
3D bare-Coulomb kernels, the Ewald short-range tail planner with its
completeness check, Gaussian auxiliary-basis 2D integrals, MPI shell-key
distribution, and the extended LRI_CV pipeline, adapted to develop's
p_info_ri and timer conventions. Restore the empty-abfs construction
branch in Exx_LRI::init_spencer that the signature unification dropped.
The tail completeness check now bounds the projected Gaussian tensor by
the RI integral pipeline's own support min(cal_V_Rcut) instead of the raw
gaussianized-aux radius sum, which demanded identically-zero blocks and
failed coverage in warn mode. Evaluate wigner_d factorials in double so
high-L (l>=5) rotation matrices no longer overflow int and produce NaN.
Wire the EXX LCAO operator, LR-TDDFT esolver, RDMFT, and center2orbital
paths to the extended interfaces, and add unit tests for the kernels,
tail utilities, and symmetry rotation.
…s in module_rpa

Port the master_ghj output wiring that the module_rpa split dropped: the
strict-2D Coulomb head normalization sidecar written next to the reader-v1
Ewald outputs, the direct mixed-Fourier 2D / reciprocal 3D Coulomb output
block with its reader-v1 basis export, and the LibRPA io writers (2D head,
structure symmetry, BZ sampling) plus RPA ABFS preorthogonalization, all
using develop's v1 output naming. Unit tests cover the new io writers.
…cker kinds

Add tests/08_RI/61_librpa_2d_reader_v1 exercising the strict-2D Ewald
reader-v1 producer contract including the Coulomb head sidecar, with
references generated at the producer's single-rank layout, and register it
in the LibRPA producer case list. Extend check_librpa_producer.py with the
strict_2d_head kind and its self-test. Regenerate the Ewald far-field
coulomb_mat references of rpa_scf_gamma and rpa_scf_shrink_multik for the
ported tail machinery (energies unchanged to 4e-13 eV).
…il sources

Comment the construction the ported kernels implement: the positive Gram
quadrature of the direct mixed-Fourier route (the tan-mapped kz rule and
the Massidda-constrained Gamma plane), the analytic 2D Gaussian
compensation integrals, the Ewald tail planner decision table, the
Gaussian decay exponent search, and the strict-2D head normalization.
The new sources carried essentially no comments, repeating the review
finding from the reader-v1 producer PR.

Also drop the INTERFACE OpenMP link added to the device object library
during the port: this PR's OpenMP usage lives in the module_ri targets,
and develop links the same device objects without publishing OpenMP, so
the hunk was unrelated to this PR's scope.
The new operator_exx_nscf_cell_nearest test target referenced
lcao_set_mat2d.cpp with one ../ level too many, which only surfaces
when ENABLE_LIBRI=ON (the CI test configuration), breaking CMake
generate. Two new headers used #pragma once, which the repository
governance checker rejects; use traditional include guards, matching
the guard style of the neighboring headers.
…rmat

The operator cell-nearest test target never compiled under GNU CI
toolchain before: its AddTest source list missed the translation
units providing ModuleIO::save_sparse and hamilt::transferSerial2Parallels,
and ri OBJECT-library members were duplicated on the link line.

- complete the source list (hs_sparse_io, lat_r_csr, hcontainer
  transfer sources, center2orb, orb_read, elem_basis_idx_orb,
  restart) and link the ri object library instead of re-listing
  its members
- drop tmp_mocks entries now provided by the real translation units
- write the CSR fixtures in the sparse-file format the develop
  csrFileReader parses (SR.csr-style header with lattice block)
- relax the high-L Gamma closed-form check from 2e-11 to 1e-9
  relative: the degree-14 Hermite reference agrees with the kernel
  to a constant 2.09e-11 relative on glibc, so the old bound was
  knife-edge across libms
…x restart CSR

The symmetry entry derived case metadata positionally, which broke when
the strict-2D case joined the producer list: the generic 3D meshes
tripped the nkz = 1 guard of the 2D Ewald path, and the nspin pairing
appended nupdown to an unpolarized case. Derive the mesh variants and
nspin from each case's INPUT instead, and iterate every listed case so
the nspin = 2 coverage is kept.

write_Hexxs_csr emitted the bare save_sparse layout, which
read_Hexxs_csr cannot parse back. Emit the sparse-file layout shared
with the DM(R) restart files (header, lattice block, CSR blocks per R)
and pin the contract with a read-back unit test. List ucell_io.cpp in
the two test targets that now reference UcellIO::write_ucell.
double C_grad_R_threshold = 0;
double V_grad_R_threshold = 0;
double ccp_rmesh_times = 10;
double ewald_lambda = 1.0;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Please align the code and pay attention to the usage of spaces and tabs.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed in acbe254: the member declarations are aligned with the surrounding 4-space struct indentation, tabs removed.

#include "source_base/global_function.h"
#include "source_base/tool_title.h"
#include "source_base/constants.h"
#include "source_io/module_parameter/parameter.h"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

we don't want to include "parameter.h", we spend a lot of time to delete it!

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed in acbe254: module_xc no longer includes parameter.h. resolve_runtime_xc_type now takes the input functional explicitly, and the Exx_LRI_Interface call sites pass PARAM.inp.dft_functional from their own scope.

mohanchen and others added 2 commits October 20, 2026 11:08
- resolve_runtime_xc_type now takes the input functional explicitly;
  the Exx_LRI_Interface call sites pass PARAM.inp.dft_functional from
  their own scope, so module_xc no longer includes parameter.h
- align the Exx_Info_RI member declarations with the surrounding
  4-space struct indentation

@ABACUS-PR-BOT ABACUS-PR-BOT left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Static review of acbe254 against ffc4d0d. No build or runtime tests were run; CI diagnostics were unavailable. The inline findings are source/analytic conclusions. Finite-mesh Gamma equivalence, compensation-tail error bounds, and sparse-restart/symmetry edge cases remain unresolved; this is not full numerical acceptance.

};

template <typename T>
struct has_weighted_short_config<T, std::void_t<typename T::Weighted_Short_Config>> : std::true_type

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[P1] Keep the detection traits compatible with the LibRI C++14 build

The regular CPU configuration with ENABLE_LIBRI sets CMAKE_CXX_STANDARD to 14, but these unguarded std::void_t specializations require C++17. EXX clients therefore fail to compile even when weighted screening is disabled. Please use a C++14-compatible detection alias and verify the ordinary CPU configuration.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Addressed in de29636: the detection traits now use a C++14-compatible void_t alias (ExxLriDetail::make_void) instead of std::void_t. The regular CPU configuration with ENABLE_LIBRI (which pins the standard to C++14) is verified: all LibRI-enabled jobs build green on d691c13.

std::ostringstream stem;
stem << "direct_2d_coulomb_iq" << iq;
Direct2dCoulomb::write_reader_v1(
result.matrix, atom_naux, iq + 1, mpi_rank, "v1_coulomb_full_iq_");

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[P2] Preserve the reader-v1 output path in both direct methods

Both direct drivers write v1_coulomb_full_iq_rank.dat in the working directory, then return before the normal writer creates rpa_outdir/V_full_r.dat. The existing reader and producer manifest expect the latter, so selecting either direct method leaves the full Coulomb files undiscoverable. Please pass rpa_outdir and the established naming convention through both drivers and cover them with a producer test using a non-default directory.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Addressed in de29636: both direct drivers take rpa_outdir and write V_full_<q>_r<rank>.dat through the established writer and naming convention, so the reader and producer manifest keep finding the files. The drivers are covered by the direct 2D/3D Coulomb unit tests.

this->add_item(item);
}
{
Input_Item item("rpa_abfs_preorth");

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[P2] Connect the preorthogonalization option to production

The new finalizer is called only by its helper tests; neither RPA_LRI::cal_postSCF_exx/cal_large_Cs nor ExxLriDetail::prepare_abfs invokes it. Consequently rpa_abfs_preorth=onsite_coulomb is accepted but has the same production effect as none. Please finalize the actual active/full auxiliary bases before their C/V/overlap consumers and test the INPUT-to-output path.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Addressed in de29636: RPA_LRI::cal_postSCF_exx now calls finalize_rpa_abfs_from_input on the active auxiliary basis before the C/V/overlap consumers, so rpa_abfs_preorth=onsite_coulomb takes effect in production. The INPUT-to-finalizer path is exercised by the dedicated preorthogonalization unit test.

Comment thread source/source_lcao/module_ri/exx_lri.h Outdated

std::vector< std::map<TA, std::map<TAC, RI::Tensor<Tdata>>>> Hexxs;
std::array<std::vector<std::vector<std::map<TA, std::map<TAC, RI::Tensor<Tdata>>>>>, 3> dHexxs;
double Eexx;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[P2] Retain deterministic initialization of Eexx

This removes the existing zero initialization, while both constructors initialize only info/runtime. The NSCF HexxR-loading branch does not calculate Eexx, but ESolver_KS_LCAO::hamilt2rho_single still reads get_Eexx() into the energy report, so that supported restart path now reads an indeterminate double. Please restore Eexx = 0.0 and retain coverage of the HexxR-only NSCF branch.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Restored in d691c13: double Eexx = 0.0; is back as an in-class initializer, with a comment documenting why the deterministic default matters (the NSCF HexxR-loading branch never computes Eexx, while the energy report still reads get_Eexx() on that path).

{
// Only L=0 is singular and L=1 has a direction-dependent q->0
// limit. The L>=2 Coulomb channels have finite Gamma limits.
if (excluded_gamma_term && (std::abs(power + 2.0) >= 1e-12 || L < 2))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[P2] Keep the finite normal-dipole contribution at Gamma

For separated centers, the L=1,M=0 term has a unique nonzero limit: dI2/dtau_z tends to -pierf(tau_z/(2sqrt(beta))). Skipping every L<2 discards this s-pz coupling, and DPcal_Vq_2d restores only L=0; di2_dtau also returns zero at q=0. Please retain the analytic normal-dipole limit and test a Gamma s/pz pair with nonzero z separation.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Addressed in de29636 and completed in d691c13: the finite L=1, M=0 normal-dipole term is kept in the Gamma dipole path, and test_gaussian_abfs_gamma_dipole.cpp is linked with the full cell/neighbor closure and passes in CI.

#define MODULE_RI_RPA_ABFS_PREORTHOGONALIZATION_H

#include "source_basis/module_ao/orb_atomic_lm.h"
#include "source_io/module_parameter/input_parameter.h"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Non-blocking: This header only needs Input_para for a const-reference declaration. Please forward-declare it here and include input_parameter.h in the implementation to avoid propagating the full parameter definition. This cleanup can be a follow-up.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Addressed in de29636: the header now forward-declares struct Input_para; and only the implementation file includes the full input_parameter.h definition.

AddTest(
TARGET MODULE_RI_EXX_SYMMETRY_abf_rotation
LIBS base ${math_libs} device symmetry neighbor parameter
SOURCES abf_rotation_test.cpp ../symm_rotation.cpp

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Non-blocking: The newly added abf_rotation_test.cpp and nspin4_restore_test.cpp use the historical suffix convention. Please apply the required test_<module_name>.cpp naming, consolidating cases where appropriate, and update these CMake entries; existing historical tests need not be renamed.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Renamed in de29636: the tests now follow the test_-prefixed convention as test_abf_rotation.cpp and test_nspin4_restore.cpp under module_exx_symmetry/test/, alongside the existing test_symm_rotation.cpp.

Comment thread source/source_lcao/module_ri/exx_lri.h Outdated
// Split RPA_LRI sources construct cut/full-coulomb helpers from a local
// Exx_Info_RI copy; default the runtime the same way the esolver path does.
Exx_LRI(const Exx_Info_RI& info_in)
: Exx_LRI(info_in, make_exx_lri_runtime()) {}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Non-blocking: The new initializer calls a runtime factory, while the current constructor rule limits initializers to direct parameter passthrough. Please prepare ExxLriRuntime at the remaining callers and use the explicit-runtime constructor, as the interface/RDMFT paths already do. This can be a focused follow-up; the PR-wide global-reference budget itself is non-increasing.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Addressed in de29636 and completed in d691c13: the factory-delegating constructor is gone; every construction site builds the runtime explicitly (make_exx_lri_runtime()) and passes it to the two-argument Exx_LRI(info, runtime) constructor.

}
}

double min_weight = 0.0, max_weight = 0.0;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Non-blocking: Please split min_weight and max_weight into separate declarations to follow the project one-variable-per-line rule. This is a small follow-up cleanup.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Split in de29636: min_weight and max_weight are now declared in separate statements (rpa_lri_overlap_io.cpp).

Comment thread source/source_lcao/module_rpa/rpa_lri.h Outdated

// Tdata post_process_Erpa( const Tdata &Erpa_in ) const;

ModuleSymmetry::Symmetry_rotation symmetry_rotation_;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Non-blocking: The new symmetry_rotation_ and use_spacegroup_symmetry_ members are never referenced; production uses the local symrot in cal_postSCF_exx. Please remove the unused state and its added symmetry-header dependency. This cleanup can be a follow-up.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Addressed in de29636: the unused symmetry_rotation_ and use_spacegroup_symmetry_ members were removed; the rotation data is derived locally where it is actually consumed.

…, and review fixes

- Extend Parallel_Reduce/Parallel_Common with sub-communicator overloads
  (reduce_all/max/min, reduce_max_loc, gather_int_all, bcast from an
  arbitrary root, my_rank/nproc/barrier) plus MPI_Type<unsigned long long>,
  and route the new tail reductions, direct-output drivers, eigenvector
  guards and raw-overlap writer through them instead of raw MPI calls.
- Remove the unused symmetry_rotation_/use_spacegroup_symmetry_ members of
  RPA_LRI together with the now-unneeded symmetry-header dependency.
- Construct the cut/full-coulomb Exx_LRI helpers with an explicit
  ExxLriRuntime at the remaining callers and drop the factory-delegating
  single-argument constructor.
- Rename abf_rotation_test.cpp and nspin4_restore_test.cpp to the
  test_<module_name>.cpp convention and update the CMake entries.
- Complete the INPUT metadata of the new registrations: strict-2D slab,
  k-mesh and force restrictions; tail-mode warn abort conditions on
  incomplete coverage or a failed Hermitian check; direct quadrature
  convergence notes; missing guard-shell tolerance descriptions.
- Fix the dangling default argument on cal_ewald_coulomb, un-nest the
  ExxLriDetail void_t block that shadowed the enclosing namespace, and
  qualify RpaAbfsPreorthReport at the production call site in rpa_lri.cpp.
…d close gamma-dipole test link

Removing the factory-delegating single-argument Exx_LRI constructor
missed three call sites, so every ENABLE_LIBRI configuration failed to
compile: the LR workspace in exx_workspace.cpp and both esolver_lr_init
constructions. The workspace now copies the owning solver's runtime, and
the esolver sites call make_exx_lri_runtime() like the interface, RDMFT
and RPA paths.

The new gamma-dipole unit test linked cell without the libraries its
members depend on; add neighbor_search, domain_decomposition and
neighbor so the mdcell_reader, record_adj and domain_decomposition
symbols resolve.
@mohanchen

mohanchen commented Oct 21, 2026 •

Copy link
Copy Markdown
Collaborator

If you have fixed specific issues, please reply to each comment. @AroundPeking

@AroundPeking

Copy link
Copy Markdown
Author

Thanks for the detailed review. All inline comments have been addressed and replied to individually:

  • The LibRI C++14 compatibility (void_t), the reader-v1 output path, the preorthogonalization wiring, the z-image removal in the strict-2D real-space sum, the dual-lattice Massidda bound, the scaled-erfc evaluation, the direct-3D Carrier q-mesh population, the removed interface defaults, the test renames, and the MPI wrapper routing all landed in de29636.
  • The deterministic Eexx initializer, the explicit ExxLriRuntime construction sites, and the gamma-dipole test link closure landed in d691c13.
  • The INPUT registration metadata (strict-2D slab/k-mesh/force restrictions, tail-mode warn abort conditions, direct-quadrature convergence notes) is complete; docs/parameters.yaml and input-main.md regenerate through the CI documentation pipeline after merge.

CI is green on d691c13 (16/16 checks).

AroundPeking and others added 2 commits October 21, 2026 10:00
…rict2d-oct17

# Conflicts:
#	source/source_lcao/module_operator_lcao/test/CMakeLists.txt
#	source/source_lcao/module_ri/CMakeLists.txt
#	source/source_lcao/module_ri/module_exx_symmetry/test/CMakeLists.txt
#	source/source_lcao/module_rpa/CMakeLists.txt
#	source/source_lcao/module_rpa/module_librpa_io/unittests/CMakeLists.txt
#	source/source_lcao/module_rpa/unittests/CMakeLists.txt

This branch has not been deployed

No deployments
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.

3 participants