From d6f8a0cf71782ebabb5d481afaeb41fb8fa0db83 Mon Sep 17 00:00:00 2001 From: Nick Mayhall Date: Wed, 3 May 2023 10:34:15 -0400 Subject: [PATCH] added README.md --- README.md | 45 +++++++++++++++++- orbitalpartitioning/orbitalpartitioning.py | 5 +- .../tests/{test_data => data}/CrOCr.ipynb | 0 .../tests/{test_data => data}/README.md | 0 .../{test_data => data}/data_CrOCr.pickle | Bin .../tests/test_orbitalpartitioning.py | 2 +- 6 files changed, 48 insertions(+), 4 deletions(-) rename orbitalpartitioning/tests/{test_data => data}/CrOCr.ipynb (100%) rename orbitalpartitioning/tests/{test_data => data}/README.md (100%) rename orbitalpartitioning/tests/{test_data => data}/data_CrOCr.pickle (100%) diff --git a/README.md b/README.md index c7a5daf..58a6f79 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,49 @@ OrbitalPartitioning [![codecov](https://codecov.io/gh/nmayhall-vt/OrbitalPartitioning/branch/main/graph/badge.svg)](https://codecov.io/gh/nmayhall-vt/OrbitalPartitioning/branch/main) -A short description of the project (less than one line). - + +A very simple package that contains a few functions that perform SVD-based orbital rotations. This doesn't depend on any particular electronic structure theory packages, only numpy/scipy. + +## Function: `spade_partitioning` (NYI) +In SPADE [(ref)](https://pubs.acs.org/doi/10.1021/acs.jctc.8b01112), the occupied space is partitioned into two smaller spaces: +1. the `fragment` space: +the orbitals that most strongly overlaps with a user specified set of atoms (or rather their basis functions). This is computed by performing an SVD of the projection of the occupied orbitals onto the specified AOs. The `fragment` orbitals are thus the span of the projected AO's. In the original paper, we also truncated the number of orbitals we keep, by dividing at the largest gap in the singular values. +2. the `environment` space: +the remaining orbitals. This includes not only the null space of the projected occupied orbitals, but also any singular vectors discarded from the `fragment` space. + +example usage: + + C_frag, C_env = spade_partitioning(C_occ, P, S) + +where: +- `C_occ` is a numpy matrix of the occupied MO coefficients, $C_{\mu,i}$ +- `P` is a AO x nfrag projection matrix (really it's the span of the projection matrix) that defines the AO's to project onto, defining the fragment. For typical cases, this will just be selected columns of the $S^{1/2}_{\mu\nu}$ matrix, indicating that the occupied space is being projected onto the symetrically orthogonalized AOs. Keeping only columns of the identity matrix corresponds to projection onto the non-orthogonal AOs. +- `S` is the AO x AO overlap matrix. + +## Function: `svd_subspace_partioning` +Find orbitals that most strongly overlap with the projector, `P`, by doing rotations within each orbital block. This function will split a list of Orbital Spaces up into separate `fragment` and `environment` blocks, _while maintiaing the same number of fragment orbitals as specified by the projector_. + +For example, if we have 3 orbital blocks, say the occupied, singly, and virtual orbitals, + + CF, CE = spade_partitioning([Cocc, Csing, Cvirt], P, S) + (Cocc_f, Csing_f, Cvirt_f) = CF + (Cocc_e, Csing_e, Cvirt_e) = CE + +However, instead of simply running `spade_partitioning` 3 separate times, this function above, keeps only the largest singular values across all subspaces, so that the number of columns in each of the `CF` blocks is equal to the number for fragment orbitals (i.e., the rank of the projector). + +## Function: `sym_ortho` + +Symmetrically orthogonalize list of MO coefficients. E.g., + + + [C1, C2, C3, ... ] = sym_ortho([C1, C2, C3, ...], S, thresh=1e-8): + +where each `Cn` matrix is a set of MO vectors in the AO basis, $C_{\mu,p}$. + + +## Function: `DMET_partitioning` (NYI) + +--- ### Copyright Copyright (c) 2023, Nick Mayhall diff --git a/orbitalpartitioning/orbitalpartitioning.py b/orbitalpartitioning/orbitalpartitioning.py index 26f6be7..cebd8e7 100644 --- a/orbitalpartitioning/orbitalpartitioning.py +++ b/orbitalpartitioning/orbitalpartitioning.py @@ -1,8 +1,11 @@ import numpy as np import scipy +def spade_partitioning(Cocc, Pv, S): + pass + -def spade_partitioning(orbitals_blocks, Pv, S): +def svd_subspace_partitioning(orbitals_blocks, Pv, S): """ Find orbitals that most strongly overlap with the projector, P, by doing rotations within each orbital block. [C1, C2, C3] -> [(C1f, C2f, C3f), (C1e, C2e, C3e)] diff --git a/orbitalpartitioning/tests/test_data/CrOCr.ipynb b/orbitalpartitioning/tests/data/CrOCr.ipynb similarity index 100% rename from orbitalpartitioning/tests/test_data/CrOCr.ipynb rename to orbitalpartitioning/tests/data/CrOCr.ipynb diff --git a/orbitalpartitioning/tests/test_data/README.md b/orbitalpartitioning/tests/data/README.md similarity index 100% rename from orbitalpartitioning/tests/test_data/README.md rename to orbitalpartitioning/tests/data/README.md diff --git a/orbitalpartitioning/tests/test_data/data_CrOCr.pickle b/orbitalpartitioning/tests/data/data_CrOCr.pickle similarity index 100% rename from orbitalpartitioning/tests/test_data/data_CrOCr.pickle rename to orbitalpartitioning/tests/data/data_CrOCr.pickle diff --git a/orbitalpartitioning/tests/test_orbitalpartitioning.py b/orbitalpartitioning/tests/test_orbitalpartitioning.py index 014f123..5d56ebe 100644 --- a/orbitalpartitioning/tests/test_orbitalpartitioning.py +++ b/orbitalpartitioning/tests/test_orbitalpartitioning.py @@ -38,7 +38,7 @@ def test1(): for fi,f in enumerate(frags): print() print(" Fragment: ", f) - (Of, Sf, Vf), (_, _, _) = orbitalpartitioning.spade_partitioning((Cdocc, Csing, Cvirt), Pf[fi], S) + (Of, Sf, Vf), (_, _, _) = orbitalpartitioning.svd_subspace_partitioning((Cdocc, Csing, Cvirt), Pf[fi], S) Cfrags.append(np.hstack((Of, Sf, Vf))) ndocc_f = Of.shape[1] init_fspace.append((ndocc_f+Sf.shape[1], ndocc_f))