Skip to content

SOC (1e and 2e cases)#128

Open
VladimirMakhnev wants to merge 15 commits into
Open-Quantum-Platform:mainfrom
VladimirMakhnev:soc-mrsf
Open

SOC (1e and 2e cases)#128
VladimirMakhnev wants to merge 15 commits into
Open-Quantum-Platform:mainfrom
VladimirMakhnev:soc-mrsf

Conversation

@VladimirMakhnev
Copy link
Copy Markdown
Contributor

Added: SOC calculations.

The calculation procedure:
SCF -- MRSF (singlet) -- MRSF (triplet) -- SOC
(see runfunc.py)

Keywords:

  • new runtype: "runtype = soc"
  • new input keyword: "soc_2e". Two modes supported:
    "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".

pass
else:
pass
# soc_type = mol.config['properties']['soc']
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This part may be needed when we perform NAMD calculations considering SOC, so it may be better to make it compatible with this one.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

What arrays are required for the NAMD calculations? What is prefereable output from SOC module for the NAMD?

@Alireza-Lashkaripour
Copy link
Copy Markdown
Contributor

Thank you for your PR, here are the result of my review:
After run_test, I got two errors:
Execution Date: 2026-05-19 06:44:46
Git Branch Info: soc-mrsf
Git Commit Info: 3318034
Output dir: /bighome/alireza/clone/pr128/oqp/openqp_test_tmp_2026-05-19_06-43-24
Total tests: 201
Passed: 199
Failed: 0
Errors: 2
image

For the example/SOC files, please change the names of the inputs into more detailed format, like for example: C2H4_BHHLYP-MRSFTDDFT_MECI.inp
Also, we need to save the result for the SOC test in .json format for future tests.

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

Copy link
Copy Markdown
Collaborator

@ConstLike ConstLike left a comment

Choose a reason for hiding this comment

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

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) to constants.F90?
  • keyword soc_2e -> [tdhf]?
  • add new SOC tests with PR.

Comment on lines +102 to +103
# mol.data['OQP::soc_']

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.

rm 4 lines.

Comment on lines +1302 to +1307


!TEST
! write(*,'(a,i0)') 'DEBUG compute_soc2e_ints called, ng=', ng


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.

rm

if (allocated(gdat%fj )) deallocate(gdat%fj )

end subroutine soc2e_gdat_clean

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.

rm

Comment on lines +1277 to +1278


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.

rm

ng, gdat%nroots, nmax, mmax, nimax, njmax, nkmax, nlmax, &
gdat%dij, gdat%dkl)

!if (gdat%am(1)==0 .and. gdat%am(2)==0 .and. &
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.

rm

nstate = ns + 3*nt
nstate4 = int(nstate, 4)

! Fixed lwork: safe minimum for small matrices, avoids workspace query overhead
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.

  1. 'lwork' is GMS style.
  2. Chech comment

character(len=*), parameter :: module_name = "soc_mrsf_mod"


real(kind=dp), parameter :: ZEFF_321G(54) = [ &
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.

Where do you use it?

mol.data.set_tdhf_multiplicity(1)
mol.singlet_energies = sp.excitation(ref_energy)

mol.data['OQP::td_singlet_energies'] = mol.data['OQP::td_energies']
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.

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)
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.

den_rohf -> den_core?

! ---- Exchange 12 ----
! W(K,J) += -3*D(I,L)*VAL
! W(K,I) -= -3*D(J,L)*VAL
val3 = -3.0_dp
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.

why -3? add comment.

@ConstLike
Copy link
Copy Markdown
Collaborator

Consider adding OpenMP multithreading support to the soc2e_driver.

Copy link
Copy Markdown
Contributor

@karmachoi karmachoi left a comment

Choose a reason for hiding this comment

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

Codex review focused on OpenMP/MPI readiness of the SOC integral paths:

  1. 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.

  1. 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.

  1. 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.

Copy link
Copy Markdown
Contributor

@karmachoi karmachoi left a comment

Choose a reason for hiding this comment

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

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 zheev call uses integer(4) LAPACK arguments. source/modules/soc_mrsf.F90:1006 and the call at source/modules/soc_mrsf.F90:1039 bypass OQP's blas_int abstraction used in source/mathlib/eigen.F90. On ILP64 builds this is an ABI mismatch and can corrupt the call or crash. Please use integer(blas_int)/oqp_linalg, or add a complex Hermitian wrapper consistent with eigen.

  • Blocking: SOC results are not returned in Python/JSON. compute_soc stores tagarray outputs, but pyoqp/oqp/molecule/molecule.py:228-233 still returns [] from get_soc(), and pyoqp/oqp/pyoqp.py:141 reports self.mol.soc, which is never populated from OQP::soc_*. Reference JSON/tests for runtype=soc will therefore show empty SOC even when Fortran produced SOC data.

  • High: 2e SOC debug logging is always enabled. source/modules/soc_mrsf.F90:91 sets debug_soc_prints = .true., causing shell tables and full AO SOC matrices to be printed for every 2e SOC run at source/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-2195 writes 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:39 still tells users that "soc and neb are recognized but not implemented yet" even though soc was 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.

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