Skip to content

Conversation

@loriab
Copy link
Member

@loriab loriab commented Feb 23, 2024

Description

Implements OpenOrbitalOptimizer support in Psi4.

User API & Changelog headlines

  • OOO for SCF works for RHF and UHF (Reverts to internal for others)
  • test suite passes with OOO on by default
  • (for review) you can skip all the tests changes and stick with the SCF and driver
  • OOO for SAD is still WIP, not for this PR
  • (Optional) If OpenOrbitalOptimizer support is enabled at compile-time, an improved atomic Hartree-Fock solver is used in the SAD, SADMO, and HUCKEL guesses. In contrast to the legacy solver in Psi4, the OpenOrbitalOptimizer atomic self-consistent field is fully symmetry aware, which is especially important for e.g. transition metal atoms.

Dev notes & details

  • Feature1
  • Feature2

TODO (some need pyooo)

  • set psivar SCF TOTAL ENERGIES (scf2)
  • SCF did not converge and FAIL_ON_MAXITER is set to true (scf2)
  • sto-3g Col::subvec(): indices out of bounds or incorrectly used (mints10, pywrap-all, weird_bases)
    • why invoked at all if converged
  • bottoms out at den -6 (sapt-dft-api, sapt-dft2, dft-grac) or worse (dftd3/psithon2)
  • diff behavior -n1 vs -n8 like conv vs bad mat (dft-grad-meta)
  • soscf (soscf-dft)
  • mom (mom)
  • frac (frac, frac-traverse)
  • efp
  • pcm
  • cppe
  • ddx
  • SCF ITERATION ENERGY
  • stdsuite
  • auto grac
  • level shift
  • v2rdm_casscf (not worth adapting as convergence is tough anyways)
  • guess_mix (special code in uhf.cc) (guess_mix_for_broken_symmetry)
  • test_erisieve.py::test_rhf_vs_uhf_screening
  • test_erisieve.py various excused quartets
  • diff errors in -n1 -n4 -n6 (cc48) sometimes PSIO_ERROR, sometimes Root diff
  • generalize for fractional occupations around line 1229, 1297 rhf.cc
  • check that the huckel guess works with OOO

Checklist

Status

  • Ready for review
  • Ready for merge

@susilehtola
Copy link
Member

Can you rebase the branch @loriab

@susilehtola
Copy link
Member

Copy link
Member

@jturney jturney left a comment

Choose a reason for hiding this comment

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

Looks good so far!

@loriab loriab moved this to In Progress in LAB's v1.10 Release Aug 12, 2025
@loriab loriab marked this pull request as ready for review August 14, 2025 16:14

* The conda package is (for the C++ interface) a header-only library.

* If using the |PSIfour| binary, OpenOrbitalOptimizer has already been compiled in.
Copy link
Member

Choose a reason for hiding this comment

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

great!

Copy link
Member Author

Choose a reason for hiding this comment

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

On Unix at least. There are some Windows build complications that I haven't faced yet.

BUILD_COMMAND ""
BUILD_IN_SOURCE 1
# master: INSTALL_COMMAND ${Python_EXECUTABLE} -m pip install git+https://github.com/MolSSI/QCManyBody.git#egg=proj
# master: INSTALL_COMMAND ${Python_EXECUTABLE} -m pip install git+https://github.com/MolSSI/ QCManyBody.git#egg=proj
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
# master: INSTALL_COMMAND ${Python_EXECUTABLE} -m pip install git+https://github.com/MolSSI/ QCManyBody.git#egg=proj
# master: INSTALL_COMMAND ${Python_EXECUTABLE} -m pip install git+https://github.com/MolSSI/QCManyBody.git#egg=proj

Comment on lines 62 to 68
#ifdef USING_LAPACK_MKL
#include <mkl.h>
#define ARMA_USE_MKL
#define ARMA_USE_MKL_TYPES
#endif
#define ARMA_DONT_USE_FORTRAN_HIDDEN_ARGS
#define ARMA_DONT_USE_WRAPPER
Copy link
Member

Choose a reason for hiding this comment

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

this is already done by the psi4/libmints/matrix.h include, no? no need to duplicate the logic here

Comment on lines +1242 to +1243
if (iteration_ == options_.get_int("MAXITER"))
printf("%d = |%e| < %e && %e < %e\n", converged, e_delta, e_conv, d_rms, d_conv);
Copy link
Member

Choose a reason for hiding this comment

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

should this be here?

Copy link
Member Author

Choose a reason for hiding this comment

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

Strictly, no, it's a violation of expected printing location. But practically there's a lot of can't reach convcrit, variation upon repeat, and not all CI modes show the output file, so it's very helpful to have the final line, and it only triggers when the SCF fails.

Comment on lines +1227 to +1229
if(nalphapi_[h]>0)
occupations[h].subvec(0,nalphapi_[h]-1).ones();
occupations[h] *= 2;
Copy link
Member

Choose a reason for hiding this comment

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

this could be generalized to the case of input fractional occupations

Copy link
Member Author

Choose a reason for hiding this comment

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

added to list

Comment on lines +1290 to +1297
// We hope that the occupations are integer...
arma::uvec nonzero(arma::find(occupations[h]>0.0));
double diff(arma::norm(occupations[h](nonzero)-2*arma::ones<arma::vec>(nonzero.n_elem),2));
if(diff!=0.0) {
fprintf(stderr,"Non-integer occupations in symmetry block %i\n",h);
occupations[h].print("occs"); // stdout
}
nalphapi_[h] = (int) nonzero.n_elem;
Copy link
Member

Choose a reason for hiding this comment

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

the fractional occupation logic should be also fixed here

Comment on lines 44 to 51
#ifdef USING_OpenOrbitalOptimizer
#ifdef USING_LAPACK_MKL
#include <mkl.h>
#define ARMA_USE_MKL
#define ARMA_USE_MKL_TYPES
#endif
#define ARMA_DONT_USE_FORTRAN_HIDDEN_ARGS
#define ARMA_DONT_USE_WRAPPER
Copy link
Member

Choose a reason for hiding this comment

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

include the matrix header instead instead of duplicating the definitions here

auto ints_tolerance_changed = Process::environment.options.use_local(ints_tolerance_key).has_changed();
Process::environment.options.set_double("SCF", ints_tolerance_key, 0.0);

// set_jk(jk);
Copy link
Member

Choose a reason for hiding this comment

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

should this be dropped altogether?


// Setup JK
std::unique_ptr<JK> jk;
// std::unique_ptr<JK> jk;
Copy link
Member

Choose a reason for hiding this comment

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

should this be dropped altogether?

psi_C->set(ii, jj, Cp2(ii, jj));
}
}
// TODO: Build Fock matrix
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// TODO: Build Fock matrix
// Build Fock matrix

Comment on lines +1110 to +1128
// TODO save the energies (elements of E_occ) and orbitals (C_occ) and density (P_AO) onto the Chuckel object. but need to resize Chuckel & Ehuckel & density one (sq; atomic_D elsewhere; D (3rd to last) in this fn)

for(int i=0; i<nbf; i++)
for(int j=0; j<nbf; j++)
D->set(i, j, P_AO(i,j)); // /2

#if 0
// Copy Huckel coefficients and energies
double** Coccp = Chuckel->pointer();
double** Cp = Ca->pointer();
for (int i = 0; i < nbf; i++) {
C_DCOPY(occ_a->dim(), Cp[i], 1, Coccp[i], 1);
}
double* Eoccp = Ehuckel->pointer();
double* Ep = Ea->pointer();
for (int i = 0; i < occ_a->dim(); i++) {
Eoccp[i] = Ep[i];
}
#endif
Copy link
Member

Choose a reason for hiding this comment

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

one should check that the huckel guess works with OOO

Comment on lines 32 to 40
#ifdef USING_OpenOrbitalOptimizer
#ifdef USING_LAPACK_MKL
#include <mkl.h>
#define ARMA_USE_MKL
#define ARMA_USE_MKL_TYPES
#endif
#define ARMA_DONT_USE_FORTRAN_HIDDEN_ARGS
#define ARMA_DONT_USE_WRAPPER
#include <armadillo>
Copy link
Member

Choose a reason for hiding this comment

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

include the matrix header

void form_D();
void form_C();

//void set_jk(std::unique_ptr<JK> & jkin) { jk = jkin; }
Copy link
Member

Choose a reason for hiding this comment

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

drop this?

Comment on lines 29 to 36
#ifdef USING_OpenOrbitalOptimizer
#ifdef USING_LAPACK_MKL
#include <mkl.h>
#define ARMA_USE_MKL
#define ARMA_USE_MKL_TYPES
#endif
#define ARMA_DONT_USE_FORTRAN_HIDDEN_ARGS
#define ARMA_DONT_USE_WRAPPER
Copy link
Member

Choose a reason for hiding this comment

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

include the matrix header

@loriab loriab enabled auto-merge August 18, 2025 05:11
@loriab loriab added this pull request to the merge queue Aug 18, 2025
Merged via the queue into psi4:master with commit d50ba83 Aug 18, 2025
6 checks passed
@github-project-automation github-project-automation bot moved this from In Progress to Done in LAB's v1.10 Release Aug 18, 2025
@loriab loriab deleted the openorbopt branch August 20, 2025 16:59
@loriab loriab mentioned this pull request Sep 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants