86 struct timeval start, end;
87 gettimeofday(&start, NULL);
88 const int L = prob->
gL();
91 for (
int cnt = 0; cnt < L*L*L*L*L*L; cnt++ ){ result[ cnt ] = 0.0; }
94 int * irreps =
new int[ L ];
95 for (
int orb = 0; orb < L; orb++ ){ irreps[ orb ] = prob->
gIrrep(( prob->
gReorder() ) ? prob->
gf1( orb ) : orb ); }
98 double * G3dotF =
new double[ L*L*L*L ];
99 double * lambda2 =
new double[ L*L*L*L ];
100 double * G2multF =
new double[ L*L*L*L ];
101 double * L2multF =
new double[ L*L*L*L ];
102 double * gamma1 =
new double[ L*L ];
103 double * G1multF =
new double[ L*L ];
104 double * G2dotF =
new double[ L*L ];
105 double * L2dotF =
new double[ L*L ];
106 for (
int cnt = 0; cnt < L*L*L*L; cnt++ ){ G3dotF[ cnt ] = 0.0; }
107 for (
int cnt = 0; cnt < L*L*L*L; cnt++ ){ lambda2[ cnt ] = 0.0; }
108 for (
int cnt = 0; cnt < L*L*L*L; cnt++ ){ G2multF[ cnt ] = 0.0; }
109 for (
int cnt = 0; cnt < L*L*L*L; cnt++ ){ L2multF[ cnt ] = 0.0; }
110 for (
int cnt = 0; cnt < L*L; cnt++ ){ gamma1[ cnt ] = 0.0; }
111 for (
int cnt = 0; cnt < L*L; cnt++ ){ G1multF[ cnt ] = 0.0; }
112 for (
int cnt = 0; cnt < L*L; cnt++ ){ G2dotF[ cnt ] = 0.0; }
113 for (
int cnt = 0; cnt < L*L; cnt++ ){ L2dotF[ cnt ] = 0.0; }
117 for (
int i = 0; i < L; i++ ){
118 for (
int j = i; j < L; j++ ){
120 gamma1[ i + L * j ] = value;
121 gamma1[ j + L * i ] = value;
127 for (
int i = 0; i < L; i++ ){
128 for (
int j = i; j < L; j++ ){
130 for (
int p = i; p < L; p++ ){
131 for (
int q = i; q < L; q++ ){
133 if ( irrep_ij == irrep_pq ){
136 for (
int l = 0; l < L; l++ ){
137 for (
int s = 0; s < L; s++ ){
138 if ( irreps[ l ] == irreps[ s ] ){
139 value += the3DM->
get_ham_index(i,j,l,p,q,s) * fock[ l + L * s ];
143 G3dotF[ i + L * ( j + L * ( p + L * q )) ] = value;
144 G3dotF[ j + L * ( i + L * ( q + L * p )) ] = value;
145 G3dotF[ p + L * ( q + L * ( i + L * j )) ] = value;
146 G3dotF[ q + L * ( p + L * ( j + L * i )) ] = value;
149 const double val_lambda = the2DM->
getTwoDMA_HAM( i, j, p, q )
150 - gamma1[ i + L * p ] * gamma1[ j + L * q ]
151 + gamma1[ i + L * q ] * gamma1[ j + L * p ] * 0.5;
152 lambda2[ i + L * ( j + L * ( p + L * q )) ] = val_lambda;
153 lambda2[ j + L * ( i + L * ( q + L * p )) ] = val_lambda;
154 lambda2[ p + L * ( q + L * ( i + L * j )) ] = val_lambda;
155 lambda2[ q + L * ( p + L * ( j + L * i )) ] = val_lambda;
165 for (
int i = 0; i < L; i++ ){
166 for (
int j = 0; j < L; j++ ){
167 if ( irreps[ i ] == irreps[ j ] ){
169 for (
int p = 0; p < L; p++ ){
170 if ( irreps[ j ] == irreps[ p ] ){
171 value += gamma1[ i + L * p ] * fock[ p + L * j ];
174 G1multF[ i + L * j ] = value;
177 G1dotF += G1multF[ i * ( L + 1 ) ];
182 for (
int i = 0; i < L; i++ ){
183 for (
int j = i; j < L; j++ ){
184 if ( irreps[ i ] == irreps[ j ] ){
185 double val_gamma = 0.0;
186 double val_lambda = 0.0;
187 for (
int p = 0; p < L; p++ ){
188 for (
int q = 0; q < L; q++ ){
189 if ( irreps[ p ] == irreps[ q ] ){
190 val_gamma += fock[ p + L * q ] * the2DM->
getTwoDMA_HAM( i, p, j, q );
191 val_lambda += fock[ p + L * q ] * lambda2[ i + L * ( p + L * ( j + L * q )) ];
195 G2dotF[ i + L * j ] = val_gamma;
196 G2dotF[ j + L * i ] = val_gamma;
197 L2dotF[ i + L * j ] = val_lambda;
198 L2dotF[ j + L * i ] = val_lambda;
205 for (
int i = 0; i < L; i++ ){
206 for (
int j = 0; j < L; j++ ){
208 for (
int k = 0; k < L; k++ ){
209 for (
int s = 0; s < L; s++ ){
211 if ( irrep_ij == irrep_ks ){
212 double val_gamma = 0.0;
213 double val_lambda = 0.0;
214 for (
int l = 0; l < L; l++ ){
215 if ( irreps[ l ] == irreps[ s ] ){
216 val_gamma += fock[ l + L * s ] * the2DM->
getTwoDMA_HAM( i, l, j, k );
217 val_lambda += fock[ l + L * s ] * lambda2[ i + L * ( l + L * ( j + L * k ) ) ];
220 G2multF[ i + L * ( s + L * ( j + L * k ) ) ] = val_gamma;
221 L2multF[ i + L * ( s + L * ( j + L * k ) ) ] = val_lambda;
229 #pragma omp parallel for schedule(dynamic) 230 for (
int i = 0; i < L; i++ ){
231 for (
int j = i; j < L; j++ ){
232 for (
int k = i; k < L; k++ ){
234 for (
int p = i; p < L; p++ ){
235 for (
int q = i; q < L; q++ ){
236 for (
int r = q; r < L; r++ ){
238 if ( irrep_ijk == irrep_pqr ){
240 double dm3_contribution = 0.0;
241 double gamma2_part1 = 0.0;
242 double gamma2_part2 = 0.0;
243 double lambda2_part1 = 0.0;
244 double lambda2_part2 = 0.0;
246 for (
int ls = 0; ls < L; ls++ ){
248 dm3_contribution += ( the3DM->
get_ham_index( ls, j, k, p, q, r ) * G1multF[ i + L * ls ]
249 + the3DM->
get_ham_index( i, ls, k, p, q, r ) * G1multF[ j + L * ls ]
250 + the3DM->
get_ham_index( i, j, ls, p, q, r ) * G1multF[ k + L * ls ]
251 + the3DM->
get_ham_index( i, j, k, ls, q, r ) * G1multF[ p + L * ls ]
252 + the3DM->
get_ham_index( i, j, k, p, ls, r ) * G1multF[ q + L * ls ]
253 + the3DM->
get_ham_index( i, j, k, p, q, ls ) * G1multF[ r + L * ls ] );
255 gamma2_part1 += ( the2DM->
getTwoDMA_HAM( i, j, p, ls ) * G2multF[ k + L * ( ls + L * ( r + L * q )) ]
256 + the2DM->
getTwoDMA_HAM( i, j, ls, q ) * G2multF[ k + L * ( ls + L * ( r + L * p )) ]
257 + the2DM->
getTwoDMA_HAM( i, k, p, ls ) * G2multF[ j + L * ( ls + L * ( q + L * r )) ]
258 + the2DM->
getTwoDMA_HAM( i, k, ls, r ) * G2multF[ j + L * ( ls + L * ( q + L * p )) ]
259 + the2DM->
getTwoDMA_HAM( k, j, ls, q ) * G2multF[ i + L * ( ls + L * ( p + L * r )) ]
260 + the2DM->
getTwoDMA_HAM( k, j, r, ls ) * G2multF[ i + L * ( ls + L * ( p + L * q )) ] );
262 gamma2_part2 += ( the2DM->
getTwoDMA_HAM( i, j, r, ls ) * ( G2multF[ k + L * ( ls + L * ( p + L * q )) ]
263 + 0.5 * G2multF[ k + L * ( ls + L * ( q + L * p )) ] )
264 + the2DM->
getTwoDMA_HAM( i, j, ls, r ) * ( G2multF[ k + L * ( ls + L * ( q + L * p )) ]
265 + 0.5 * G2multF[ k + L * ( ls + L * ( p + L * q )) ] )
266 + the2DM->
getTwoDMA_HAM( i, k, q, ls ) * ( G2multF[ j + L * ( ls + L * ( p + L * r )) ]
267 + 0.5 * G2multF[ j + L * ( ls + L * ( r + L * p )) ] )
268 + the2DM->
getTwoDMA_HAM( i, k, ls, q ) * ( G2multF[ j + L * ( ls + L * ( r + L * p )) ]
269 + 0.5 * G2multF[ j + L * ( ls + L * ( p + L * r )) ] )
270 + the2DM->
getTwoDMA_HAM( k, j, p, ls ) * ( G2multF[ i + L * ( ls + L * ( r + L * q )) ]
271 + 0.5 * G2multF[ i + L * ( ls + L * ( q + L * r )) ] )
272 + the2DM->
getTwoDMA_HAM( k, j, ls, p ) * ( G2multF[ i + L * ( ls + L * ( q + L * r )) ]
273 + 0.5 * G2multF[ i + L * ( ls + L * ( r + L * q )) ] ) );
275 lambda2_part1 += ( lambda2[ i + L * ( j + L * ( p + L * ls )) ] * L2multF[ k + L * ( ls + L * ( r + L * q )) ]
276 + lambda2[ i + L * ( j + L * ( ls + L * q )) ] * L2multF[ k + L * ( ls + L * ( r + L * p )) ]
277 + lambda2[ i + L * ( k + L * ( p + L * ls )) ] * L2multF[ j + L * ( ls + L * ( q + L * r )) ]
278 + lambda2[ i + L * ( k + L * ( ls + L * r )) ] * L2multF[ j + L * ( ls + L * ( q + L * p )) ]
279 + lambda2[ k + L * ( j + L * ( ls + L * q )) ] * L2multF[ i + L * ( ls + L * ( p + L * r )) ]
280 + lambda2[ k + L * ( j + L * ( r + L * ls )) ] * L2multF[ i + L * ( ls + L * ( p + L * q )) ] );
282 lambda2_part2 += ( lambda2[ i + L * ( j + L * ( r + L * ls )) ] * ( L2multF[ k + L * ( ls + L * ( p + L * q )) ]
283 + 0.5 * L2multF[ k + L * ( ls + L * ( q + L * p )) ] )
284 + lambda2[ i + L * ( j + L * ( ls + L * r )) ] * ( L2multF[ k + L * ( ls + L * ( q + L * p )) ]
285 + 0.5 * L2multF[ k + L * ( ls + L * ( p + L * q )) ] )
286 + lambda2[ i + L * ( k + L * ( q + L * ls )) ] * ( L2multF[ j + L * ( ls + L * ( p + L * r )) ]
287 + 0.5 * L2multF[ j + L * ( ls + L * ( r + L * p )) ] )
288 + lambda2[ i + L * ( k + L * ( ls + L * q )) ] * ( L2multF[ j + L * ( ls + L * ( r + L * p )) ]
289 + 0.5 * L2multF[ j + L * ( ls + L * ( p + L * r )) ] )
290 + lambda2[ k + L * ( j + L * ( p + L * ls )) ] * ( L2multF[ i + L * ( ls + L * ( r + L * q )) ]
291 + 0.5 * L2multF[ i + L * ( ls + L * ( q + L * r )) ] )
292 + lambda2[ k + L * ( j + L * ( ls + L * p )) ] * ( L2multF[ i + L * ( ls + L * ( q + L * r )) ]
293 + 0.5 * L2multF[ i + L * ( ls + L * ( r + L * q )) ] ) );
296 const double contracted_value = ( the3DM->
get_ham_index( i, j, k, p, q, r ) * G1dotF
298 + G3dotF[ i + L * ( j + L * ( p + L * q )) ] * gamma1[ k + L * r ]
299 - 0.5 * G3dotF[ i + L * ( j + L * ( r + L * q )) ] * gamma1[ k + L * p ]
300 - 0.5 * G3dotF[ i + L * ( j + L * ( p + L * r )) ] * gamma1[ k + L * q ]
301 + G3dotF[ i + L * ( k + L * ( p + L * r )) ] * gamma1[ j + L * q ]
302 - 0.5 * G3dotF[ i + L * ( k + L * ( q + L * r )) ] * gamma1[ j + L * p ]
303 - 0.5 * G3dotF[ i + L * ( k + L * ( p + L * q )) ] * gamma1[ j + L * r ]
304 + G3dotF[ j + L * ( k + L * ( q + L * r )) ] * gamma1[ i + L * p ]
305 - 0.5 * G3dotF[ j + L * ( k + L * ( p + L * r )) ] * gamma1[ i + L * q ]
306 - 0.5 * G3dotF[ j + L * ( k + L * ( q + L * p )) ] * gamma1[ i + L * r ]
308 - 0.5 * dm3_contribution
311 + 0.5 * the2DM->
getTwoDMA_HAM( i, j, p, r ) * G2dotF[ k + L * q ]
312 + 0.5 * the2DM->
getTwoDMA_HAM( i, j, r, q ) * G2dotF[ k + L * p ]
314 + 0.5 * the2DM->
getTwoDMA_HAM( i, k, p, q ) * G2dotF[ j + L * r ]
315 + 0.5 * the2DM->
getTwoDMA_HAM( i, k, q, r ) * G2dotF[ j + L * p ]
317 + 0.5 * the2DM->
getTwoDMA_HAM( k, j, p, q ) * G2dotF[ i + L * r ]
318 + 0.5 * the2DM->
getTwoDMA_HAM( k, j, r, p ) * G2dotF[ i + L * q ]
323 + 2 * lambda2[ i + L * ( j + L * ( p + L * q )) ] * L2dotF[ k + L * r ]
324 - lambda2[ i + L * ( j + L * ( p + L * r )) ] * L2dotF[ k + L * q ]
325 - lambda2[ i + L * ( j + L * ( r + L * q )) ] * L2dotF[ k + L * p ]
326 + 2 * lambda2[ i + L * ( k + L * ( p + L * r )) ] * L2dotF[ j + L * q ]
327 - lambda2[ i + L * ( k + L * ( p + L * q )) ] * L2dotF[ j + L * r ]
328 - lambda2[ i + L * ( k + L * ( q + L * r )) ] * L2dotF[ j + L * p ]
329 + 2 * lambda2[ k + L * ( j + L * ( r + L * q )) ] * L2dotF[ i + L * p ]
330 - lambda2[ k + L * ( j + L * ( p + L * q )) ] * L2dotF[ i + L * r ]
331 - lambda2[ k + L * ( j + L * ( r + L * p )) ] * L2dotF[ i + L * q ]
334 + lambda2_part2 / 1.5 );
336 result[ i + L * ( j + L * ( k + L * ( p + L * ( q + L * r )))) ] = contracted_value;
337 result[ i + L * ( k + L * ( j + L * ( p + L * ( r + L * q )))) ] = contracted_value;
338 result[ j + L * ( i + L * ( k + L * ( q + L * ( p + L * r )))) ] = contracted_value;
339 result[ k + L * ( i + L * ( j + L * ( r + L * ( p + L * q )))) ] = contracted_value;
340 result[ j + L * ( k + L * ( i + L * ( q + L * ( r + L * p )))) ] = contracted_value;
341 result[ k + L * ( j + L * ( i + L * ( r + L * ( q + L * p )))) ] = contracted_value;
342 result[ p + L * ( q + L * ( r + L * ( i + L * ( j + L * k )))) ] = contracted_value;
343 result[ p + L * ( r + L * ( q + L * ( i + L * ( k + L * j )))) ] = contracted_value;
344 result[ q + L * ( p + L * ( r + L * ( j + L * ( i + L * k )))) ] = contracted_value;
345 result[ r + L * ( p + L * ( q + L * ( k + L * ( i + L * j )))) ] = contracted_value;
346 result[ q + L * ( r + L * ( p + L * ( j + L * ( k + L * i )))) ] = contracted_value;
347 result[ r + L * ( q + L * ( p + L * ( k + L * ( j + L * i )))) ] = contracted_value;
366 gettimeofday(&end, NULL);
367 const double elapsed = (end.tv_sec - start.tv_sec) + 1e-6 * (end.tv_usec - start.tv_usec);
368 std::cout <<
"Cumulant :: Contraction of cu(4)-4RDM with CASPT2 Fock operator took " << elapsed <<
" seconds." << std::endl;
372 double CheMPS2::Cumulant::lambda2_ham(
const TwoDM * the2DM,
const int i,
const int j,
const int p,
const int q){
382 const int p,
const int q,
const int r,
const int s){
446 const double part3 = ( lambda2_ham(the2DM,i,j,p,q) * lambda2_ham(the2DM,k,l,r,s)
447 - lambda2_ham(the2DM,i,j,p,r) * lambda2_ham(the2DM,k,l,q,s) * 0.5
448 - lambda2_ham(the2DM,i,j,p,s) * lambda2_ham(the2DM,k,l,r,q) * 0.5
449 - lambda2_ham(the2DM,i,j,r,q) * lambda2_ham(the2DM,k,l,p,s) * 0.5
450 - lambda2_ham(the2DM,i,j,s,q) * lambda2_ham(the2DM,k,l,r,p) * 0.5
451 + lambda2_ham(the2DM,i,j,r,s) * lambda2_ham(the2DM,k,l,p,q) / 3.0
452 + lambda2_ham(the2DM,i,j,r,s) * lambda2_ham(the2DM,k,l,q,p) / 6.0
453 + lambda2_ham(the2DM,i,j,s,r) * lambda2_ham(the2DM,k,l,p,q) / 6.0
454 + lambda2_ham(the2DM,i,j,s,r) * lambda2_ham(the2DM,k,l,q,p) / 3.0
455 + lambda2_ham(the2DM,i,k,p,r) * lambda2_ham(the2DM,j,l,q,s)
456 - lambda2_ham(the2DM,i,k,p,q) * lambda2_ham(the2DM,j,l,r,s) * 0.5
457 - lambda2_ham(the2DM,i,k,p,s) * lambda2_ham(the2DM,j,l,q,r) * 0.5
458 - lambda2_ham(the2DM,i,k,q,r) * lambda2_ham(the2DM,j,l,p,s) * 0.5
459 - lambda2_ham(the2DM,i,k,s,r) * lambda2_ham(the2DM,j,l,q,p) * 0.5
460 + lambda2_ham(the2DM,i,k,q,s) * lambda2_ham(the2DM,j,l,p,r) / 3.0
461 + lambda2_ham(the2DM,i,k,s,q) * lambda2_ham(the2DM,j,l,p,r) / 6.0
462 + lambda2_ham(the2DM,i,k,q,s) * lambda2_ham(the2DM,j,l,r,p) / 6.0
463 + lambda2_ham(the2DM,i,k,s,q) * lambda2_ham(the2DM,j,l,r,p) / 3.0
464 + lambda2_ham(the2DM,i,l,p,s) * lambda2_ham(the2DM,k,j,r,q)
465 - lambda2_ham(the2DM,i,l,p,r) * lambda2_ham(the2DM,k,j,s,q) * 0.5
466 - lambda2_ham(the2DM,i,l,p,q) * lambda2_ham(the2DM,k,j,r,s) * 0.5
467 - lambda2_ham(the2DM,i,l,r,s) * lambda2_ham(the2DM,k,j,p,q) * 0.5
468 - lambda2_ham(the2DM,i,l,q,s) * lambda2_ham(the2DM,k,j,r,p) * 0.5
469 + lambda2_ham(the2DM,i,l,r,q) * lambda2_ham(the2DM,k,j,p,s) / 3.0
470 + lambda2_ham(the2DM,i,l,q,r) * lambda2_ham(the2DM,k,j,p,s) / 6.0
471 + lambda2_ham(the2DM,i,l,r,q) * lambda2_ham(the2DM,k,j,s,p) / 6.0
472 + lambda2_ham(the2DM,i,l,q,r) * lambda2_ham(the2DM,k,j,s,p) / 3.0 );
474 return ( part1 - part2 + 2 * part3 );
double get1RDM_HAM(const int cnt1, const int cnt2) const
Get a 1-RDM term, using the HAM indices.
bool gReorder() const
Get whether the Hamiltonian orbitals are reordered for the DMRG calculation.
double getTwoDMA_HAM(const int cnt1, const int cnt2, const int cnt3, const int cnt4) const
Get a 2DM_A term, using the HAM indices.
int gIrrep(const int nOrb) const
Get an orbital irrep.
int gf1(const int HamOrb) const
Get the DMRG index corresponding to a Ham index.
static int directProd(const int Irrep1, const int Irrep2)
Get the direct product of the irreps with numbers Irrep1 and Irrep2: a bitwise XOR for psi4's convent...
int gL() const
Get the number of orbitals.
static void gamma4_fock_contract_ham(const Problem *prob, const ThreeDM *the3DM, const TwoDM *the2DM, double *fock, double *result)
Contract the CASPT2 Fock operator with the cumulant approximation of in time, using HAM indices...
double get_ham_index(const int cnt1, const int cnt2, const int cnt3, const int cnt4, const int cnt5, const int cnt6) const
Get a 3-RDM, using the HAM indices.
static double gamma4_ham(const Problem *prob, const ThreeDM *the3DM, const TwoDM *the2DM, const int i, const int j, const int k, const int l, const int p, const int q, const int r, const int s)
Get the cumulant approximation of , using HAM indices.