|
| 1 | +# ********************************************************************************* |
| 2 | +# * Copyright (C) 2025 Alexey V. Akimov |
| 3 | +# * |
| 4 | +# * This file is distributed under the terms of the GNU General Public License |
| 5 | +# * as published by the Free Software Foundation, either version 3 of |
| 6 | +# * the License, or (at your option) any later version. |
| 7 | +# * See the file LICENSE in the root directory of this distribution |
| 8 | +# * or <http://www.gnu.org/licenses/>. |
| 9 | +# * |
| 10 | +# *********************************************************************************/ |
| 11 | +""" |
| 12 | +
|
| 13 | +.. module:: mapping3 |
| 14 | + :platform: Unix, Windows |
| 15 | + :synopsis: This module implements the methods to map single-electron properties (e.g. KS basis) |
| 16 | + to many-electron ones (e.g. Slater Determinat basis and SAC basis) |
| 17 | +
|
| 18 | +.. moduleauthor:: Alexey V. Akimov |
| 19 | +
|
| 20 | +""" |
| 21 | + |
| 22 | +import os |
| 23 | +import sys |
| 24 | +import math |
| 25 | + |
| 26 | +# Fisrt, we add the location of the library to test to the PYTHON path |
| 27 | +if sys.platform == "cygwin": |
| 28 | + from cyglibra_core import * |
| 29 | +elif sys.platform == "linux" or sys.platform == "linux2": |
| 30 | + from liblibra_core import * |
| 31 | + |
| 32 | + |
| 33 | + |
| 34 | +def ovlp_arb(_SD1, _SD2, S, active_space=None, verbose=False): |
| 35 | + """Compute the overlap of two generic SDs: <SD1|SD2> |
| 36 | +
|
| 37 | + Args: |
| 38 | +
|
| 39 | + _SD1 ( lists of ints ): first SD, such that: |
| 40 | + SeeAlso: ```inp``` in the ```sd2indx(inp)``` function |
| 41 | +
|
| 42 | + _SD2 ( lists of ints ): second SD, such that: |
| 43 | + SeeAlso: ```inp``` in the ```sd2indx(inp)``` function |
| 44 | +
|
| 45 | + S ( CMATRIX(N,N) ): is the matrix in the space of 1-el orbital |
| 46 | +
|
| 47 | + active_space ( list of ints ): indices of the orbitals (starting from 1) to |
| 48 | + include into consideration. If None - all the orbitals will be used [ default: None ] |
| 49 | +
|
| 50 | + verbose ( Bool ): whether to print some extra info [ default: False] |
| 51 | +
|
| 52 | + Returns: |
| 53 | + complex: the overlap of the two determinants <SD1|SD2> |
| 54 | +
|
| 55 | + """ |
| 56 | + |
| 57 | + nbasis = S.num_of_rows |
| 58 | + |
| 59 | + SD1, SD2 = [], [] |
| 60 | + |
| 61 | + if active_space == None: |
| 62 | + SD1, SD2 = _SD1, _SD2 |
| 63 | + else: |
| 64 | + for a in _SD1: |
| 65 | + if abs(a) in active_space: |
| 66 | + SD1.append(a) |
| 67 | + for a in _SD2: |
| 68 | + if abs(a) in active_space: |
| 69 | + SD2.append(a) |
| 70 | + |
| 71 | + res = 0.0 + 0j |
| 72 | + if len(SD1) != len(SD2): |
| 73 | + print("Trying to compute an overlap of the SDs with different number of electrons") |
| 74 | + print("Exiting...") |
| 75 | + sys.exit(0) |
| 76 | + |
| 77 | + |
| 78 | + # Apply the determinant formula |
| 79 | + det_size = len(SD1) |
| 80 | + s = np.zeros( (det_size, det_size), dtype=np.float64); |
| 81 | + |
| 82 | + # Forming the overlap of the SDs |
| 83 | + for indx_I, I in enumerate(SD1): |
| 84 | + for indx_J, J in enumerate(SD2): |
| 85 | + # The overlap is non-zero only if the orbitals |
| 86 | + # are occupied with the same-spin electrons. |
| 87 | + if (I * J) > 0: |
| 88 | + i = abs(I) - 1 |
| 89 | + j = abs(J) - 1 |
| 90 | + s[indx_I, indx_J] = S.get(i, j).real |
| 91 | + else: |
| 92 | + s[indx_I, indx_J] = 0.0 |
| 93 | + |
| 94 | + if verbose==True: |
| 95 | + print(s) |
| 96 | + res = np.linalg.det(s) #* phase |
| 97 | + |
| 98 | + return res |
| 99 | + |
| 100 | + |
| 101 | + |
| 102 | + |
| 103 | +def ovlp_mat_arb(SD1, SD2, S, active_space): |
| 104 | + """Compute a matrix of overlaps in the SD basis |
| 105 | +
|
| 106 | + Args: |
| 107 | + SD1 ( list of lists of N ints ): a list of N SD determinants, such that: |
| 108 | + SD1[iSD] is a list of integers defining which orbitals are |
| 109 | + occupied in SD with index ```iSD``` and how |
| 110 | + SeeAlso: ```inp``` in the ```sd2indx(inp)``` function |
| 111 | +
|
| 112 | + SD2 ( list of lists of M ints ): a list of M SD determinants, such that: |
| 113 | + SD2[iSD] is a list of integers defining which orbitals are |
| 114 | + occupied in SD with index ```iSD``` and how |
| 115 | + SeeAlso: ```inp``` in the ```sd2indx(inp)``` function |
| 116 | +
|
| 117 | + S ( CMATRIX(K,K) ): is the matrix in the full space of 1-el orbitals. Note - the mapped indices should not |
| 118 | + be larger than K-1 |
| 119 | +
|
| 120 | + active_space ( list of ints ): indices of the orbitals (starting from 1) to |
| 121 | + include into consideration. If None - all the orbitals will be used [ default: None ] |
| 122 | +
|
| 123 | + Returns: |
| 124 | + CMATRIX(N, M): overlap matrix composed of elements <SD1(i)|SD2(j)> |
| 125 | +
|
| 126 | + """ |
| 127 | + |
| 128 | + N, M = len(SD1), len(SD2) |
| 129 | + res = CMATRIX(N, M) |
| 130 | + |
| 131 | + for n in range(0, N): |
| 132 | + for m in range(0, M): |
| 133 | + val = ovlp_arb(SD1[n], SD2[m], S, active_space, 0) |
| 134 | + res.set(n, m, val) |
| 135 | + |
| 136 | + return res |
| 137 | + |
0 commit comments