SOC (1e and 2e cases)#128
Conversation
This reverts commit ea10080. revert commit with lx,ly functions
…case, 0 for 1e only.
| pass | ||
| else: | ||
| pass | ||
| # soc_type = mol.config['properties']['soc'] |
There was a problem hiding this comment.
This part may be needed when we perform NAMD calculations considering SOC, so it may be better to make it compatible with this one.
There was a problem hiding this comment.
What arrays are required for the NAMD calculations? What is prefereable output from SOC module for the NAMD?
|
Thank you for your PR, here are the result of my review: For the example/SOC files, please change the names of the inputs into more detailed format, like for example: C2H4_BHHLYP-MRSFTDDFT_MECI.inp Regarding Wiki, please give a more detail explanation for the keywords in SOC inputs, so we can put then in wiki as will as a detail explantion of inputs and log files for https://github.com/Open-Quantum-Platform/openqp/wiki/Example%20Input%20Files |
ConstLike
left a comment
There was a problem hiding this comment.
LGTM! Thanks for your work!
Please address some minor corrections:
- move new constants to
source/physical_constants.F90 - clean from GMS traces
- Move all the
cutoffs (CHANGE THE NAME TO CLEAR MEANING) toconstants.F90? - keyword soc_2e -> [tdhf]?
- add new SOC tests with PR.
| # mol.data['OQP::soc_'] | ||
|
|
|
|
||
|
|
||
| !TEST | ||
| ! write(*,'(a,i0)') 'DEBUG compute_soc2e_ints called, ng=', ng | ||
|
|
||
|
|
| if (allocated(gdat%fj )) deallocate(gdat%fj ) | ||
|
|
||
| end subroutine soc2e_gdat_clean | ||
|
|
|
|
||
|
|
| ng, gdat%nroots, nmax, mmax, nimax, njmax, nkmax, nlmax, & | ||
| gdat%dij, gdat%dkl) | ||
|
|
||
| !if (gdat%am(1)==0 .and. gdat%am(2)==0 .and. & |
| nstate = ns + 3*nt | ||
| nstate4 = int(nstate, 4) | ||
|
|
||
| ! Fixed lwork: safe minimum for small matrices, avoids workspace query overhead |
There was a problem hiding this comment.
- 'lwork' is GMS style.
- Chech comment
| character(len=*), parameter :: module_name = "soc_mrsf_mod" | ||
|
|
||
|
|
||
| real(kind=dp), parameter :: ZEFF_321G(54) = [ & |
| mol.data.set_tdhf_multiplicity(1) | ||
| mol.singlet_energies = sp.excitation(ref_energy) | ||
|
|
||
| mol.data['OQP::td_singlet_energies'] = mol.data['OQP::td_energies'] |
There was a problem hiding this comment.
maybe mol.data['OQP::td_singlet_energies'] = mol.data['OQP::td_energies'].copy()? check it.
|
|
||
| ! --- Step 2b: 2e mean-field SOC correction --- | ||
| if (do_2e_soc) then | ||
| allocate(den_rohf(nbf, nbf), stat=ok) |
| ! ---- Exchange 12 ---- | ||
| ! W(K,J) += -3*D(I,L)*VAL | ||
| ! W(K,I) -= -3*D(J,L)*VAL | ||
| val3 = -3.0_dp |
|
Consider adding OpenMP multithreading support to the |
karmachoi
left a comment
There was a problem hiding this comment.
Codex review focused on OpenMP/MPI readiness of the SOC integral paths:
- P1 — 1e SOC integral path is not MPI/OpenMP-ready
compute_soc_ao in source/modules/soc_mrsf.F90 zeroes the full AO SOC buffers and then serially loops over all shell pairs while updating shared packed matrices. There is no MPI rank partitioning / allreduce, and adding OpenMP around this loop would race on lx_ao, ly_ao, and lz_ao through update_triang_matrix unless each thread uses private scratch/accumulators.
Please make the 1e SOC path follow the existing parallel integral pattern: split shell pairs across MPI ranks, use thread-private shpair_t/SOC block scratch and private AO accumulators for OpenMP, reduce the thread-local AO buffers, then MPI-allreduce the final Lx/Ly/Lz AO matrices.
- P1 — 2e SOC / ERI path has MPI splitting but is not OpenMP-ready
soc2e_driver in source/integrals/grd2_rys.F90 partitions shell-pair work across MPI ranks, but the quartet loop remains serial and calls soc2e_rys_compute, which accumulates directly into the shared wao tensor inside compute_soc2e_ao. Sharing gdat or wao under an OpenMP loop would race.
Please make the 2e ERI/SOC path OpenMP-ready by using thread-private soc2e_int_data_t scratch plus per-thread wao accumulators, reducing those AO tensors before the existing MPI allreduce. This should cover the 2e ERI path rather than leaving it serial on each MPI-assigned chunk.
- P2 — SOC output/debug path is not MPI-safe
soc_mrsf opens/appends the same log file from every rank, leaves debug_soc_prints = .true., and writes AO/debug/SOC tables without rank gating. Once 1e/2e integral work is distributed, this will produce duplicate or interleaved output and potentially duplicated tag publication.
Please gate printing and tag publication to rank 0, or use the repository’s existing parallel-aware printing/data-publication pattern.
Overall: the SOC implementation should not be merged as-is until both 1e and 2e integral paths are explicitly OpenMP- and MPI-ready.
Generated with Codex CLI and checked against PR #128 diff.
karmachoi
left a comment
There was a problem hiding this comment.
Codex CLI review for PR #128
Codex reviewed the PR diff in read-only mode and did not modify files or run project code.
Findings
-
Blocking: direct
zheevcall usesinteger(4)LAPACK arguments.source/modules/soc_mrsf.F90:1006and the call atsource/modules/soc_mrsf.F90:1039bypass OQP'sblas_intabstraction used insource/mathlib/eigen.F90. On ILP64 builds this is an ABI mismatch and can corrupt the call or crash. Please useinteger(blas_int)/oqp_linalg, or add a complex Hermitian wrapper consistent witheigen. -
Blocking: SOC results are not returned in Python/JSON.
compute_socstores tagarray outputs, butpyoqp/oqp/molecule/molecule.py:228-233still returns[]fromget_soc(), andpyoqp/oqp/pyoqp.py:141reportsself.mol.soc, which is never populated fromOQP::soc_*. Reference JSON/tests forruntype=socwill therefore show empty SOC even when Fortran produced SOC data. -
High: 2e SOC debug logging is always enabled.
source/modules/soc_mrsf.F90:91setsdebug_soc_prints = .true., causing shell tables and full AO SOC matrices to be printed for every 2e SOC run atsource/modules/soc_mrsf.F90:166-193. This will make normal outputs very large and unstable for reference comparisons. -
High: unconditional stdout debug prints remain in integral kernels.
source/integrals/mod_1e_primitives.F90:2188-2195writes derivative debug tables directly to stdout for d/d shell pairs. These bypass the log/verbosity system and will pollute CLI/test output. -
Medium: SOC input help still says SOC is unimplemented.
pyoqp/oqp/utils/input_checker.py:39still tells users that "soc and neb are recognized but not implemented yet" even thoughsocwas moved into supported runtypes. Please update the help text and docs/examples together.
Given the two blocking issues above, Codex would not merge this PR as-is.
# Conflicts: # pyoqp/oqp/utils/input_checker.py

Added: SOC calculations.
The calculation procedure:
SCF -- MRSF (singlet) -- MRSF (triplet) -- SOC
(see runfunc.py)
Keywords:
"soc_2e = 0" -- only 1e SOC calculation
"soc_2e = 1" -- 1e and 2e SOC calculation
New input folder -- "SOC" with examples of thymine and CH3Br.
New module: "soc_mrsf.F90".