22#ifndef _libint2_include_derivmap_h_
23#define _libint2_include_derivmap_h_
25#include <libint2/util/cxxstd.h>
26#if LIBINT2_CPLUSPLUS_STD < 2011
27# error "The simple Libint API requires C++11 support"
34#include <libint2/braket.h>
35#include <libint2/tensor.h>
52 static void initialize() {
53 int max_deriv_order = 0;
54#if defined(LIBINT2_MAX_DERIV_ORDER)
55 max_deriv_order = LIBINT2_MAX_DERIV_ORDER;
58 if (INCLUDE_ERI > max_deriv_order) max_deriv_order = INCLUDE_ERI;
61 if (INCLUDE_ERI3 > max_deriv_order) max_deriv_order = INCLUDE_ERI3;
64 for (
int d = 1; d <= max_deriv_order; ++d) {
65 braket_xx_xx().push_back(DerivMapGenerator::generate_deriv_index_map(d, BraKet::xx_xx));
66 braket_xs_xx().push_back(DerivMapGenerator::generate_deriv_index_map(d, BraKet::xs_xx));
71 static std::vector<Tensor<size_t>>& braket_xx_xx() {
72 static std::vector<Tensor<size_t>> braket_xx_xx_maps;
73 return braket_xx_xx_maps;
76 static std::vector<Tensor<size_t>>& braket_xs_xx() {
77 static std::vector<Tensor<size_t>> braket_xs_xx_maps;
78 return braket_xs_xx_maps;
85 return braket_xx_xx()[deriv_order_ - 1];
88 return braket_xs_xx()[deriv_order_ - 1];
91 assert(
false &&
"Derivative index permutation maps for this braket type not yet supported.");
101 static void cwr_recursion(std::vector<size_t> inp,
102 std::vector<size_t> &out,
103 std::vector<std::vector<size_t>> &result,
104 size_t k,
size_t i,
size_t n)
107 if (out.size() == k){
108 result.push_back(out);
111 for (
size_t j = i; j < n; j++){
112 out.push_back(inp[j]);
113 cwr_recursion(inp, out, result, k, j, n);
122 static size_t how_many_derivs(
size_t k,
size_t n) {
124 size_t factorial = 1;
125 for (
size_t i=0; i < n; i++) {
147 static std::vector<std::vector<size_t>> generate_multi_index_lookup(
size_t nparams,
size_t deriv_order) {
151 for (
size_t i = 0; i < nparams; i++) {
157 vector<vector<size_t>> combos;
158 cwr_recursion(inp, out, combos, deriv_order, 0, nparams);
167 vector<size_t> swap_braket_perm;
168 vector<size_t> swap_bra_perm;
169 vector<size_t> swap_ket_perm;
170 vector<vector<size_t>> swap_combos;
173 case BraKet::xx_xx: {
174 swap_braket_perm = {6,7,8,9,10,11,0,1,2,3,4,5};
175 swap_bra_perm = {3,4,5,0,1,2,6,7,8,9,10,11};
176 swap_ket_perm = {0,1,2,3,4,5,9,10,11,6,7,8};
178 swap_combos = {{0, 0, 0},
189 case BraKet::xs_xx: {
190 swap_braket_perm = {0,1,2,3,4,5,6,7,8};
191 swap_bra_perm = {0,1,2,3,4,5,6,7,8};
192 swap_ket_perm = {0,1,2,6,7,8,3,4,5};
193 swap_combos = {{0,0,0}, {0,0,1}};
199 assert(
false &&
"Derivative index maps for this BraKet type not implemented.");
203 auto nderivs = how_many_derivs(ncenters, deriv_order);
205 auto nparams = ncenters * 3;
218 vector<vector<size_t>> lookup = generate_multi_index_lookup(nparams, deriv_order);
221 for (
size_t swap = 0; swap < swap_combos.size(); swap++){
222 auto swap_braket = swap_combos[swap][0];
223 auto swap_bra = swap_combos[swap][1];
224 auto swap_ket = swap_combos[swap][2];
227 for (
size_t i = 0; i < nderivs; i++){
228 vector<size_t> multi_idx = lookup[i];
229 vector<size_t> permuted_indices;
230 for (
size_t j=0; j < multi_idx.size(); j++){
231 size_t idx = multi_idx[j];
232 if (swap_braket == 1) idx = swap_braket_perm[idx];
233 if (swap_bra == 1) idx = swap_bra_perm[idx];
234 if (swap_ket == 1) idx = swap_ket_perm[idx];
235 permuted_indices.push_back(idx);
238 sort(permuted_indices.begin(), permuted_indices.end());
244 auto it = lower_bound(lookup.begin(), lookup.end(), permuted_indices);
245 if (it != lookup.end()) new_idx = it - lookup.begin();
246 (*mapDerivIndex.data(swap_braket,swap_bra,swap_ket,i)) = new_idx;
249 return mapDerivIndex;
This class statically initializes all index permutation maps for each BraKet type which requires them...
Definition: deriv_map.h:48
Defaults definitions for various parameters assumed by Libint.
Definition: algebra.cc:24
BraKet
types of shell sets supported by Engine, in chemist notation (i.e.
Definition: include/libint2/braket.h:36