32 #include "MPIchemps2.h" 46 const long long linsize = (
long long ) L;
47 const long long size = (( disk ) ? linsize * linsize * linsize * linsize * linsize
48 : linsize * linsize * linsize * linsize * linsize * linsize );
49 assert( INT_MAX >= size );
53 elements =
new double[ array_size ];
55 for (
int cnt = 0; cnt < array_size; cnt++ ){ elements[ cnt ] = 0.0; }
58 temp_disk_orbs =
new int[ 6 * array_size ];
59 temp_disk_vals =
new double [ array_size ];
62 temp_disk_orbs = NULL;
63 temp_disk_vals = NULL;
71 if ( disk ){
delete [] temp_disk_orbs;
72 delete [] temp_disk_vals; }
76 #ifdef CHEMPS2_MPI_COMPILATION 81 for (
int orb = 0; orb < L; orb++ ){
83 MPIchemps2::allreduce_array_double( elements, temp_disk_vals, array_size );
85 for (
int cnt = 0; cnt < array_size; cnt++ ){ elements[ cnt ] = temp_disk_vals[ cnt ]; }
91 double * temp =
new double[ array_size ];
92 MPIchemps2::allreduce_array_double( elements, temp, array_size );
94 for (
int cnt = 0; cnt < array_size; cnt++ ){ elements[ cnt ] = temp[ cnt ]; }
102 void CheMPS2::ThreeDM::set_dmrg_index(
const int cnt1,
const int cnt2,
const int cnt3,
const int cnt4,
const int cnt5,
const int cnt6,
const double value ){
107 const int orb1 = (( prob->
gReorder() ) ? prob->
gf2( cnt1 ) : cnt1 );
108 const int orb2 = (( prob->
gReorder() ) ? prob->
gf2( cnt2 ) : cnt2 );
109 const int orb3 = (( prob->
gReorder() ) ? prob->
gf2( cnt3 ) : cnt3 );
110 const int orb4 = (( prob->
gReorder() ) ? prob->
gf2( cnt4 ) : cnt4 );
111 const int orb5 = (( prob->
gReorder() ) ? prob->
gf2( cnt5 ) : cnt5 );
112 const int orb6 = (( prob->
gReorder() ) ? prob->
gf2( cnt6 ) : cnt6 );
115 int private_counter = -1;
118 private_counter = temp_disk_counter;
121 assert( private_counter < array_size );
122 temp_disk_orbs[ 6 * private_counter + 0 ] = orb1;
123 temp_disk_orbs[ 6 * private_counter + 1 ] = orb2;
124 temp_disk_orbs[ 6 * private_counter + 2 ] = orb3;
125 temp_disk_orbs[ 6 * private_counter + 3 ] = orb4;
126 temp_disk_orbs[ 6 * private_counter + 4 ] = orb5;
127 temp_disk_orbs[ 6 * private_counter + 5 ] = orb6;
128 temp_disk_vals[ private_counter ] = value;
132 elements[ orb1 + L * ( orb2 + L * ( orb3 + L * ( orb4 + L * ( orb5 + L * orb6 )))) ] = value;
133 elements[ orb2 + L * ( orb3 + L * ( orb1 + L * ( orb5 + L * ( orb6 + L * orb4 )))) ] = value;
134 elements[ orb3 + L * ( orb1 + L * ( orb2 + L * ( orb6 + L * ( orb4 + L * orb5 )))) ] = value;
135 elements[ orb2 + L * ( orb1 + L * ( orb3 + L * ( orb5 + L * ( orb4 + L * orb6 )))) ] = value;
136 elements[ orb3 + L * ( orb2 + L * ( orb1 + L * ( orb6 + L * ( orb5 + L * orb4 )))) ] = value;
137 elements[ orb1 + L * ( orb3 + L * ( orb2 + L * ( orb4 + L * ( orb6 + L * orb5 )))) ] = value;
139 elements[ orb4 + L * ( orb5 + L * ( orb6 + L * ( orb1 + L * ( orb2 + L * orb3 )))) ] = value;
140 elements[ orb5 + L * ( orb6 + L * ( orb4 + L * ( orb2 + L * ( orb3 + L * orb1 )))) ] = value;
141 elements[ orb6 + L * ( orb4 + L * ( orb5 + L * ( orb3 + L * ( orb1 + L * orb2 )))) ] = value;
142 elements[ orb5 + L * ( orb4 + L * ( orb6 + L * ( orb2 + L * ( orb1 + L * orb3 )))) ] = value;
143 elements[ orb6 + L * ( orb5 + L * ( orb4 + L * ( orb3 + L * ( orb2 + L * orb1 )))) ] = value;
144 elements[ orb4 + L * ( orb6 + L * ( orb5 + L * ( orb1 + L * ( orb3 + L * orb2 )))) ] = value;
150 assert( disk ==
false );
151 return elements[ cnt1 + L * ( cnt2 + L * ( cnt3 + L * ( cnt4 + L * ( cnt5 + L * cnt6 )))) ];
157 assert( last_orb_start >= 0 );
158 assert( last_orb_num >= 1 );
159 assert( last_orb_start + last_orb_num <= L );
163 for (
int ham_orb = last_orb_start; ham_orb < ( last_orb_start + last_orb_num ); ham_orb++ ){
164 read_file( ham_orb );
165 const int shift = ( ham_orb - last_orb_start ) * array_size;
168 for (
int cnt = 0; cnt < array_size; cnt++ ){ storage[ shift + cnt ] = alpha * elements[ cnt ]; }
171 for (
int cnt = 0; cnt < array_size; cnt++ ){ storage[ shift + cnt ] += alpha * elements[ cnt ]; }
177 const int shift = last_orb_start * L * L * L * L * L;
178 const int size = last_orb_num * L * L * L * L * L;
181 for (
int cnt = 0; cnt < size; cnt++ ){ storage[ cnt ] = alpha * elements[ shift + cnt ]; }
184 for (
int cnt = 0; cnt < size; cnt++ ){ storage[ cnt ] += alpha * elements[ shift + cnt ]; }
197 for (
int cnt3 = 0; cnt3 < L; cnt3++ ){
199 for (
int cnt2 = 0; cnt2 < L; cnt2++ ){
200 for (
int cnt1 = 0; cnt1 < L; cnt1++ ){
201 value += elements[ cnt1 + L * ( cnt2 + L * ( cnt3 + L * ( cnt1 + L * cnt2 ))) ];
208 for (
int cnt3 = 0; cnt3 < L; cnt3++ ){
209 for (
int cnt2 = 0; cnt2 < L; cnt2++ ){
210 for (
int cnt1 = 0; cnt1 < L; cnt1++ ){
211 value +=
get_ham_index( cnt1, cnt2, cnt3, cnt1, cnt2, cnt3 );
222 void CheMPS2::ThreeDM::create_file()
const{
224 #ifdef CHEMPS2_MPI_COMPILATION 227 const int mpi_rank = 0;
230 assert( disk ==
true );
232 std::stringstream filename;
233 filename << CheMPS2::THREE_RDM_storage_prefix << mpi_rank <<
".h5";
235 hid_t file_id = H5Fcreate( filename.str().c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT );
236 hid_t group_id = H5Gcreate( file_id,
"three_rdm", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT );
238 for (
int orb = 0; orb < L; orb++ ){
240 std::stringstream storagename;
241 storagename <<
"elements_" << orb;
243 hsize_t dimarray = array_size;
244 hid_t dataspace_id = H5Screate_simple( 1, &dimarray, NULL );
245 hid_t dataset_id = H5Dcreate( group_id, storagename.str().c_str(), H5T_IEEE_F64LE, dataspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT );
246 H5Dwrite( dataset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, elements );
248 H5Dclose( dataset_id );
249 H5Sclose( dataspace_id );
253 H5Gclose( group_id );
258 void CheMPS2::ThreeDM::write_file(
const int last_ham_orb )
const{
260 #ifdef CHEMPS2_MPI_COMPILATION 263 const int mpi_rank = 0;
266 assert( disk ==
true );
268 std::stringstream filename;
269 filename << CheMPS2::THREE_RDM_storage_prefix << mpi_rank <<
".h5";
271 hid_t file_id = H5Fopen( filename.str().c_str(), H5F_ACC_RDWR, H5P_DEFAULT );
272 hid_t group_id = H5Gopen( file_id,
"three_rdm", H5P_DEFAULT );
274 std::stringstream storagename;
275 storagename <<
"elements_" << last_ham_orb;
277 hid_t dataset_id = H5Dopen( group_id, storagename.str().c_str(), H5P_DEFAULT );
278 H5Dwrite( dataset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, elements );
280 H5Dclose( dataset_id );
282 H5Gclose( group_id );
287 void CheMPS2::ThreeDM::read_file(
const int last_ham_orb ){
289 #ifdef CHEMPS2_MPI_COMPILATION 292 const int mpi_rank = 0;
295 assert( disk ==
true );
297 std::stringstream filename;
298 filename << CheMPS2::THREE_RDM_storage_prefix << mpi_rank <<
".h5";
300 hid_t file_id = H5Fopen( filename.str().c_str(), H5F_ACC_RDONLY, H5P_DEFAULT );
301 hid_t group_id = H5Gopen( file_id,
"three_rdm", H5P_DEFAULT );
303 std::stringstream storagename;
304 storagename <<
"elements_" << last_ham_orb;
306 hid_t dataset_id = H5Dopen( group_id, storagename.str().c_str(), H5P_DEFAULT );
307 H5Dread( dataset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, elements );
309 H5Dclose( dataset_id );
311 H5Gclose( group_id );
318 if ( prob->
gTwoS() != 0 ){
319 double alpha = 1.0 / ( prob->
gTwoS() + 1.0 );
322 for (
int ham_orb = 0; ham_orb < L; ham_orb++ ){
323 read_file( ham_orb );
324 dscal_( &array_size, &alpha, elements, &inc1 );
325 write_file( ham_orb );
328 dscal_( &array_size, &alpha, elements, &inc1 );
334 void CheMPS2::ThreeDM::flush_disk(){
336 assert( disk ==
true );
337 for (
int ham_orb = 0; ham_orb < L; ham_orb++ ){
339 read_file( ham_orb );
341 for (
int counter = 0; counter < temp_disk_counter; counter++ ){
343 const int orb1 = temp_disk_orbs[ 6 * counter + 0 ];
344 const int orb2 = temp_disk_orbs[ 6 * counter + 1 ];
345 const int orb3 = temp_disk_orbs[ 6 * counter + 2 ];
346 const int orb4 = temp_disk_orbs[ 6 * counter + 3 ];
347 const int orb5 = temp_disk_orbs[ 6 * counter + 4 ];
348 const int orb6 = temp_disk_orbs[ 6 * counter + 5 ];
349 const double value = temp_disk_vals[ counter ];
351 if ( orb1 == ham_orb ){ elements[ orb5 + L * ( orb6 + L * ( orb4 + L * ( orb2 + L * orb3 ))) ] = value;
352 elements[ orb6 + L * ( orb5 + L * ( orb4 + L * ( orb3 + L * orb2 ))) ] = value; }
353 if ( orb2 == ham_orb ){ elements[ orb6 + L * ( orb4 + L * ( orb5 + L * ( orb3 + L * orb1 ))) ] = value;
354 elements[ orb4 + L * ( orb6 + L * ( orb5 + L * ( orb1 + L * orb3 ))) ] = value; }
355 if ( orb3 == ham_orb ){ elements[ orb4 + L * ( orb5 + L * ( orb6 + L * ( orb1 + L * orb2 ))) ] = value;
356 elements[ orb5 + L * ( orb4 + L * ( orb6 + L * ( orb2 + L * orb1 ))) ] = value; }
357 if ( orb4 == ham_orb ){ elements[ orb2 + L * ( orb3 + L * ( orb1 + L * ( orb5 + L * orb6 ))) ] = value;
358 elements[ orb3 + L * ( orb2 + L * ( orb1 + L * ( orb6 + L * orb5 ))) ] = value; }
359 if ( orb5 == ham_orb ){ elements[ orb3 + L * ( orb1 + L * ( orb2 + L * ( orb6 + L * orb4 ))) ] = value;
360 elements[ orb1 + L * ( orb3 + L * ( orb2 + L * ( orb4 + L * orb6 ))) ] = value; }
361 if ( orb6 == ham_orb ){ elements[ orb1 + L * ( orb2 + L * ( orb3 + L * ( orb4 + L * orb5 ))) ] = value;
362 elements[ orb2 + L * ( orb1 + L * ( orb3 + L * ( orb5 + L * orb4 ))) ] = value; }
365 write_file( ham_orb );
373 assert( disk ==
false );
380 hid_t file_id = H5Fcreate( filename.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT );
381 long long linsize = (
long long ) LAS;
382 hsize_t dimarray = ( linsize * linsize * linsize * linsize * linsize * linsize );
383 hid_t group_id = H5Gcreate( file_id, tag.c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT );
384 hid_t dataspace_id = H5Screate_simple( 1, &dimarray, NULL );
385 hid_t dataset_id = H5Dcreate( group_id,
"elements", H5T_IEEE_F64LE, dataspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT );
387 H5Dwrite( dataset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, array );
389 H5Dclose( dataset_id );
390 H5Sclose( dataspace_id );
391 H5Gclose( group_id );
394 std::cout <<
"Saved the " << tag <<
" to the file " << filename << std::endl;
404 #ifdef CHEMPS2_MPI_COMPILATION 408 temp_disk_counter = 0;
409 const int orb_i = denT->
gIndex();
411 const double sq3 = sqrt( 3.0 );
416 double * workmem =
new double[ DIM * DIM ];
417 double * workmem2 =
new double[ DIM * DIM ];
419 const int upperbound1 = ( orb_i * ( orb_i + 1 )) / 2;
420 int jkl[] = { 0, 0, 0 };
421 #ifdef CHEMPS2_MPI_COMPILATION 422 #pragma omp for schedule(dynamic) nowait 424 #pragma omp for schedule(static) nowait 426 for (
int global = 0; global < upperbound1; global++ ){
428 const int orb_j = jkl[ 0 ];
429 const int orb_k = jkl[ 1 ];
431 #ifdef CHEMPS2_MPI_COMPILATION 432 if ( MPIRANK == MPIchemps2::owner_cdf( L, orb_j, orb_k ) )
435 const double d1 = diagram1( denT, F0tensors[orb_i-1][orb_k-orb_j][orb_i-1-orb_k], workmem );
436 set_dmrg_index( orb_j, orb_i, orb_i, orb_k, orb_i, orb_i, 4 * d1 );
437 set_dmrg_index( orb_j, orb_i, orb_i, orb_i, orb_k, orb_i, -2 * d1 );
442 const int triangle3 = L - orb_i - 1;
443 const int upperbound3 = ( triangle3 * ( triangle3 + 1 ) ) / 2;
444 #ifdef CHEMPS2_MPI_COMPILATION 445 #pragma omp for schedule(dynamic) nowait 447 #pragma omp for schedule(static) nowait 449 for (
int global = 0; global < upperbound3; global++ ){
451 const int orb_j = L - 1 - jkl[ 1 ];
452 const int orb_k = orb_j + jkl[ 0 ];
454 #ifdef CHEMPS2_MPI_COMPILATION 455 if ( MPIRANK == MPIchemps2::owner_cdf( L, orb_j, orb_k ) )
458 const double d3 = diagram3( denT, F0tensors[orb_i][orb_k-orb_j][orb_j-1-orb_i], workmem );
459 set_dmrg_index( orb_j, orb_i, orb_i, orb_k, orb_i, orb_i, 4 * d3 );
460 set_dmrg_index( orb_j, orb_i, orb_i, orb_i, orb_k, orb_i, -2 * d3 );
465 const int upperbound4 = ( orb_i * ( orb_i + 1 ) * ( orb_i + 2 ) ) / 6;
466 #ifdef CHEMPS2_MPI_COMPILATION 467 #pragma omp for schedule(dynamic) nowait 469 #pragma omp for schedule(static) nowait 471 for (
int global = 0; global < upperbound4; global++ ){
473 const int orb_j = jkl[ 0 ];
474 const int orb_k = jkl[ 1 ];
475 const int orb_l = jkl[ 2 ];
476 const int recalculate_global = orb_j + ( orb_k * ( orb_k + 1 ) ) / 2 + ( orb_l * ( orb_l + 1 ) * ( orb_l + 2 ) ) / 6;
477 assert( global == recalculate_global );
479 #ifdef CHEMPS2_MPI_COMPILATION 480 if ( MPIchemps2::owner_3rdm_diagram( L, orb_j, orb_k, orb_l ) == MPIRANK )
483 const int cnt1 = orb_k - orb_j;
484 const int cnt2 = orb_l - orb_k;
485 const int cnt3 = orb_i - 1 - orb_l;
487 const double d4 = diagram4_5_6_7_8_9( denT, dm3_b_J0_doublet[cnt1][cnt2][cnt3], workmem,
'B' );
488 const double d5 = (( cnt1 == 0 ) ? 0.0 : diagram4_5_6_7_8_9( denT, dm3_b_J1_doublet[cnt1][cnt2][cnt3], workmem,
'B' ));
489 set_dmrg_index( orb_j, orb_k, orb_i, orb_l, orb_i, orb_i, d4 + d5 );
490 set_dmrg_index( orb_j, orb_k, orb_i, orb_i, orb_l, orb_i, d4 - d5 );
491 set_dmrg_index( orb_j, orb_k, orb_i, orb_i, orb_i, orb_l, -2 * d4 );
493 if ( cnt1 + cnt2 > 0 ){
494 const double d6 = diagram4_5_6_7_8_9( denT, dm3_c_J0_doublet[cnt1][cnt2][cnt3], workmem,
'C' );
495 const double d7 = diagram4_5_6_7_8_9( denT, dm3_c_J1_doublet[cnt1][cnt2][cnt3], workmem,
'C' );
496 set_dmrg_index( orb_j, orb_l, orb_i, orb_k, orb_i, orb_i, -2 * d6 );
497 set_dmrg_index( orb_j, orb_l, orb_i, orb_i, orb_k, orb_i, d6 - d7 );
498 set_dmrg_index( orb_j, orb_l, orb_i, orb_i, orb_i, orb_k, d6 + d7 );
501 const double d8 = diagram4_5_6_7_8_9( denT, dm3_d_J0_doublet[cnt1][cnt2][cnt3], workmem,
'D' );
502 const double d9 = diagram4_5_6_7_8_9( denT, dm3_d_J1_doublet[cnt1][cnt2][cnt3], workmem,
'D' );
503 set_dmrg_index( orb_k, orb_l, orb_i, orb_j, orb_i, orb_i, -2 * d8 );
504 set_dmrg_index( orb_k, orb_l, orb_i, orb_i, orb_j, orb_i, d8 + d9 );
505 set_dmrg_index( orb_k, orb_l, orb_i, orb_i, orb_i, orb_j, d8 - d9 );
511 const int upperbound10 = upperbound1 * ( L - orb_i - 1 );
512 #ifdef CHEMPS2_MPI_COMPILATION 513 #pragma omp for schedule(dynamic) nowait 515 #pragma omp for schedule(static) nowait 517 for (
int combined = 0; combined < upperbound10; combined++){
518 const int global = combined % upperbound1;
520 const int orb_l = orb_i + 1 + ( combined / upperbound1 );
521 const int orb_j = jkl[ 0 ];
522 const int orb_k = jkl[ 1 ];
524 #ifdef CHEMPS2_MPI_COMPILATION 525 if ( MPIRANK == MPIchemps2::owner_absigma( orb_j, orb_k ) )
528 const double d10 = diagram10( denT, S0tensors[orb_i-1][orb_k-orb_j][orb_i-1-orb_k], Ltensors[orb_i][orb_l-1-orb_i], workmem, workmem2 );
529 const double d11 = (( orb_j == orb_k ) ? 0.0 :
530 diagram11( denT, S1tensors[orb_i-1][orb_k-orb_j][orb_i-1-orb_k], Ltensors[orb_i][orb_l-1-orb_i], workmem, workmem2 ));
531 set_dmrg_index( orb_j, orb_k, orb_i, orb_l, orb_i, orb_i, d10 + d11 );
532 set_dmrg_index( orb_j, orb_k, orb_i, orb_i, orb_l, orb_i, d10 - d11 );
533 set_dmrg_index( orb_j, orb_k, orb_i, orb_i, orb_i, orb_l, - 2 * d10 );
536 #ifdef CHEMPS2_MPI_COMPILATION 537 if ( MPIRANK == MPIchemps2::owner_cdf( L, orb_j, orb_k ) )
541 const double d12 = diagram12( denT, F0tensors[orb_i-1][orb_k-orb_j][orb_i-1-orb_k], Ltensors[orb_i][orb_l-1-orb_i], workmem, workmem2 );
542 const double d13 = diagram13( denT, F1tensors[orb_i-1][orb_k-orb_j][orb_i-1-orb_k], Ltensors[orb_i][orb_l-1-orb_i], workmem, workmem2 );
543 set_dmrg_index( orb_j, orb_l, orb_i, orb_k, orb_i, orb_i, - 2 * d12 );
544 set_dmrg_index( orb_j, orb_l, orb_i, orb_i, orb_k, orb_i, d12 - d13 );
545 set_dmrg_index( orb_j, orb_l, orb_i, orb_i, orb_i, orb_k, d12 + d13 );
547 if ( orb_j < orb_k ){
548 const double d14 = diagram14( denT, F0tensors[orb_i-1][orb_k-orb_j][orb_i-1-orb_k], Ltensors[orb_i][orb_l-1-orb_i], workmem, workmem2 );
549 const double d15 = diagram15( denT, F1tensors[orb_i-1][orb_k-orb_j][orb_i-1-orb_k], Ltensors[orb_i][orb_l-1-orb_i], workmem, workmem2 );
550 set_dmrg_index( orb_k, orb_l, orb_i, orb_j, orb_i, orb_i, - 2 * d14 );
551 set_dmrg_index( orb_k, orb_l, orb_i, orb_i, orb_j, orb_i, d14 - d15 );
552 set_dmrg_index( orb_k, orb_l, orb_i, orb_i, orb_i, orb_j, d14 + d15 );
558 const int upperbound16 = upperbound3 * orb_i;
559 #ifdef CHEMPS2_MPI_COMPILATION 560 #pragma omp for schedule(dynamic) nowait 562 #pragma omp for schedule(static) nowait 564 for (
int combined = 0; combined < upperbound16; combined++ ){
565 const int orb_j = combined % orb_i;
566 const int global = combined / orb_i;
568 const int orb_m = L - 1 - jkl[ 1 ];
569 const int orb_n = orb_m + jkl[ 0 ];
571 #ifdef CHEMPS2_MPI_COMPILATION 572 if ( MPIRANK == MPIchemps2::owner_absigma( orb_m, orb_n ) )
575 const double d16 = diagram16( denT, Ltensors[orb_i-1][orb_i-1-orb_j], S0tensors[orb_i][orb_n-orb_m][orb_m-1-orb_i], workmem, workmem2 );
576 const double d17 = (( orb_m == orb_n ) ? 0.0 :
577 diagram17( denT, Ltensors[orb_i-1][orb_i-1-orb_j], S1tensors[orb_i][orb_n-orb_m][orb_m-1-orb_i], workmem, workmem2 ));
578 set_dmrg_index( orb_m, orb_n, orb_i, orb_j, orb_i, orb_i, d16 - d17 );
579 set_dmrg_index( orb_m, orb_n, orb_i, orb_i, orb_j, orb_i, d16 + d17 );
580 set_dmrg_index( orb_m, orb_n, orb_i, orb_i, orb_i, orb_j, - 2 * d16 );
583 #ifdef CHEMPS2_MPI_COMPILATION 584 if ( MPIRANK == MPIchemps2::owner_cdf( L, orb_m, orb_n ) )
588 const double d18 = diagram18( denT, Ltensors[orb_i-1][orb_i-1-orb_j], F0tensors[orb_i][orb_n-orb_m][orb_m-1-orb_i], workmem, workmem2 );
589 const double d19 = diagram19( denT, Ltensors[orb_i-1][orb_i-1-orb_j], F1tensors[orb_i][orb_n-orb_m][orb_m-1-orb_i], workmem, workmem2 );
590 set_dmrg_index( orb_j, orb_m, orb_i, orb_n, orb_i, orb_i, d18 + d19 );
591 set_dmrg_index( orb_j, orb_m, orb_i, orb_i, orb_n, orb_i, - 2 * d18 );
592 set_dmrg_index( orb_j, orb_m, orb_i, orb_i, orb_i, orb_n, d18 - d19 );
594 if ( orb_m < orb_n ){
595 const double d20 = diagram20( denT, Ltensors[orb_i-1][orb_i-1-orb_j], F0tensors[orb_i][orb_n-orb_m][orb_m-1-orb_i], workmem, workmem2 );
596 const double d21 = diagram21( denT, Ltensors[orb_i-1][orb_i-1-orb_j], F1tensors[orb_i][orb_n-orb_m][orb_m-1-orb_i], workmem, workmem2 );
597 set_dmrg_index( orb_j, orb_n, orb_i, orb_m, orb_i, orb_i, d20 + d21 );
598 set_dmrg_index( orb_j, orb_n, orb_i, orb_i, orb_m, orb_i, - 2 * d20 );
599 set_dmrg_index( orb_j, orb_n, orb_i, orb_i, orb_i, orb_m, d20 - d21 );
605 for (
int orb_m = orb_i+1; orb_m < L; orb_m++ ){
606 for (
int orb_n = orb_m; orb_n < L; orb_n++ ){
621 #ifdef CHEMPS2_MPI_COMPILATION 622 #pragma omp barrier // Everyone needs to be done before tensors are created and communicated 624 if ( orb_m > orb_i + 1 ){
625 const int own_S_mn = MPIchemps2::owner_absigma( orb_m, orb_n );
626 const int own_F_mn = MPIchemps2::owner_cdf( L, orb_m, orb_n );
627 if ( MPIRANK != own_F_mn ){ F0tensors[orb_i][orb_n-orb_m][orb_m-1-orb_i] =
new TensorF0( orb_i+1, irrep_mn,
false, book );
628 F1tensors[orb_i][orb_n-orb_m][orb_m-1-orb_i] =
new TensorF1( orb_i+1, irrep_mn,
false, book ); }
629 if ( MPIRANK != own_S_mn ){ S0tensors[orb_i][orb_n-orb_m][orb_m-1-orb_i] =
new TensorS0( orb_i+1, irrep_mn,
false, book );
630 if ( orb_m != orb_n ){ S1tensors[orb_i][orb_n-orb_m][orb_m-1-orb_i] =
new TensorS1( orb_i+1, irrep_mn,
false, book ); }}
631 MPIchemps2::broadcast_tensor( F0tensors[orb_i][orb_n-orb_m][orb_m-1-orb_i], own_F_mn );
632 MPIchemps2::broadcast_tensor( F1tensors[orb_i][orb_n-orb_m][orb_m-1-orb_i], own_F_mn );
633 MPIchemps2::broadcast_tensor( S0tensors[orb_i][orb_n-orb_m][orb_m-1-orb_i], own_S_mn );
634 if ( orb_m != orb_n ){ MPIchemps2::broadcast_tensor( S1tensors[orb_i][orb_n-orb_m][orb_m-1-orb_i], own_S_mn ); }
643 for (
int global = 0; global < upperbound1; global++){
645 const int orb_j = jkl[ 0 ];
646 const int orb_k = jkl[ 1 ];
648 if ( irrep_jk == irrep_mn ){
649 #ifdef CHEMPS2_MPI_COMPILATION 650 if ( MPIRANK == MPIchemps2::owner_absigma( orb_j, orb_k ) ){ counter_Sjk++; }
651 if ( MPIRANK == MPIchemps2::owner_cdf( L, orb_j, orb_k ) ){ counter_Fjk++; }
662 if ( counter_Fjk > 0 ){
671 fill_tens_29_33( denT, tens_29_33, F0tensors[orb_i][orb_n-orb_m][orb_m-1-orb_i], workmem );
672 fill_tens_30_32( denT, tens_30_32, F1tensors[orb_i][orb_n-orb_m][orb_m-1-orb_i], workmem );
673 fill_tens_36_42( denT, tens_36_42, F0tensors[orb_i][orb_n-orb_m][orb_m-1-orb_i], workmem );
674 fill_tens_34_35_37_38( denT, tens_34_40, tens_35_41, tens_37_44, tens_38_43, F1tensors[orb_i][orb_n-orb_m][orb_m-1-orb_i], workmem, workmem2 );
676 #ifdef CHEMPS2_MPI_COMPILATION 677 #pragma omp for schedule(dynamic) nowait 679 #pragma omp for schedule(static) nowait 681 for (
int global = 0; global < upperbound1; global++ ){
683 const int orb_j = jkl[ 0 ];
684 const int orb_k = jkl[ 1 ];
686 if ( irrep_jk == irrep_mn ){
687 #ifdef CHEMPS2_MPI_COMPILATION 688 if ( MPIRANK == MPIchemps2::owner_cdf( L, orb_j, orb_k ) )
691 if ( orb_m < orb_n ){
692 const double d31 = tens_29_33->
inproduct( F0tensors[orb_i-1][orb_k-orb_j][orb_i-1-orb_k],
'T' );
693 const double d32 = tens_30_32->
inproduct( F1tensors[orb_i-1][orb_k-orb_j][orb_i-1-orb_k],
'T' );
694 const double d42 = tens_36_42->
inproduct( F1tensors[orb_i-1][orb_k-orb_j][orb_i-1-orb_k],
'T' );
695 const double d40 = tens_34_40->
inproduct( F1tensors[orb_i-1][orb_k-orb_j][orb_i-1-orb_k],
'T' );
696 const double d41 = tens_35_41->
inproduct( F0tensors[orb_i-1][orb_k-orb_j][orb_i-1-orb_k],
'T' );
697 const double d44 = tens_37_44->
inproduct( F1tensors[orb_i-1][orb_k-orb_j][orb_i-1-orb_k],
'T' );
698 const double d43 = tens_38_43->
inproduct( F1tensors[orb_i-1][orb_k-orb_j][orb_i-1-orb_k],
'T' );
699 set_dmrg_index( orb_j, orb_n, orb_i, orb_k, orb_m, orb_i, 4*d31 );
700 set_dmrg_index( orb_j, orb_n, orb_i, orb_m, orb_k, orb_i, -2*(d31 + d32 + d40) );
701 set_dmrg_index( orb_j, orb_n, orb_i, orb_k, orb_i, orb_m, -2*(d31 + d41) );
702 set_dmrg_index( orb_j, orb_n, orb_i, orb_m, orb_i, orb_k, d31 + d32 + d41 + d42 + d43 );
703 set_dmrg_index( orb_j, orb_n, orb_i, orb_i, orb_k, orb_m, d31 + d32 + d41 + d42 + d44 );
704 set_dmrg_index( orb_j, orb_n, orb_i, orb_i, orb_m, orb_k, -2*(d31 + d42) );
706 const double d29 = tens_29_33->
inproduct( F0tensors[orb_i-1][orb_k-orb_j][orb_i-1-orb_k],
'N' );
707 const double d30 = tens_30_32->
inproduct( F1tensors[orb_i-1][orb_k-orb_j][orb_i-1-orb_k],
'N' );
708 const double d36 = tens_36_42->
inproduct( F1tensors[orb_i-1][orb_k-orb_j][orb_i-1-orb_k],
'N' );
709 const double d34 = tens_34_40->
inproduct( F1tensors[orb_i-1][orb_k-orb_j][orb_i-1-orb_k],
'N' );
710 const double d35 = tens_35_41->
inproduct( F0tensors[orb_i-1][orb_k-orb_j][orb_i-1-orb_k],
'N' );
711 const double d37 = tens_37_44->
inproduct( F1tensors[orb_i-1][orb_k-orb_j][orb_i-1-orb_k],
'N' );
712 const double d38 = tens_38_43->
inproduct( F1tensors[orb_i-1][orb_k-orb_j][orb_i-1-orb_k],
'N' );
713 set_dmrg_index( orb_j, orb_m, orb_i, orb_k, orb_n, orb_i, 4*d29 );
714 set_dmrg_index( orb_j, orb_m, orb_i, orb_n, orb_k, orb_i, -2*(d29 + d30 + d34) );
715 set_dmrg_index( orb_j, orb_m, orb_i, orb_k, orb_i, orb_n, -2*(d29 + d35) );
716 set_dmrg_index( orb_j, orb_m, orb_i, orb_n, orb_i, orb_k, d29 + d30 + d35 + d36 + d37 );
717 set_dmrg_index( orb_j, orb_m, orb_i, orb_i, orb_k, orb_n, d29 + d30 + d35 + d36 + d38 );
718 set_dmrg_index( orb_j, orb_m, orb_i, orb_i, orb_n, orb_k, -2*(d29 + d36) );
736 if ( counter_Fjk > 0 ){
739 TensorF1 * tens_50_52 = (( orb_m == orb_n ) ? NULL :
new TensorF1( orb_i, irrep_mn,
true, book ));
740 fill_tens_49_51( denT, tens_49_51, S0tensors[orb_i][orb_n-orb_m][orb_m-1-orb_i], workmem );
741 if ( orb_m != orb_n ){ fill_tens_50_52( denT, tens_50_52, S1tensors[orb_i][orb_n-orb_m][orb_m-1-orb_i], workmem ); }
743 #ifdef CHEMPS2_MPI_COMPILATION 744 #pragma omp for schedule(dynamic) nowait 746 #pragma omp for schedule(static) nowait 748 for (
int global = 0; global < upperbound1; global++ ){
750 const int orb_j = jkl[ 0 ];
751 const int orb_k = jkl[ 1 ];
753 if ( irrep_jk == irrep_mn ){
754 #ifdef CHEMPS2_MPI_COMPILATION 755 if ( MPIRANK == MPIchemps2::owner_cdf( L, orb_j, orb_k ) )
758 if ( orb_j < orb_k ){
759 const double d51 = tens_49_51->
inproduct( F0tensors[orb_i-1][orb_k-orb_j][orb_i-1-orb_k],
'N' );
760 const double d52 = ((orb_m==orb_n)?0.0 : tens_50_52->
inproduct( F1tensors[orb_i-1][orb_k-orb_j][orb_i-1-orb_k],
'N' ));
761 set_dmrg_index( orb_k, orb_m, orb_n, orb_j, orb_i, orb_i, - 2 * d51 );
762 set_dmrg_index( orb_k, orb_m, orb_n, orb_i, orb_j, orb_i, d51 + d52 );
763 set_dmrg_index( orb_k, orb_m, orb_n, orb_i, orb_i, orb_j, d51 - d52 );
765 const double d49 = tens_49_51->
inproduct( F0tensors[orb_i-1][orb_k-orb_j][orb_i-1-orb_k],
'T' );
766 const double d50 = ((orb_m==orb_n)?0.0 : tens_50_52->
inproduct( F1tensors[orb_i-1][orb_k-orb_j][orb_i-1-orb_k],
'T' ));
767 set_dmrg_index( orb_j, orb_m, orb_n, orb_k, orb_i, orb_i, - 2 * d49 );
768 set_dmrg_index( orb_j, orb_m, orb_n, orb_i, orb_k, orb_i, d49 + d50 );
769 set_dmrg_index( orb_j, orb_m, orb_n, orb_i, orb_i, orb_k, d49 - d50 );
775 if ( orb_m != orb_n ){
delete tens_50_52; }
782 if ( counter_Sjk > 0 ){
785 TensorS1 * tens_23 = (( orb_m == orb_n ) ? NULL :
new TensorS1( orb_i, irrep_mn,
true, book ));
786 TensorS1 * tens_25 = (( orb_m == orb_n ) ? NULL :
new TensorS1( orb_i, irrep_mn,
true, book ));
787 TensorS1 * tens_26 = (( orb_m == orb_n ) ? NULL :
new TensorS1( orb_i, irrep_mn,
true, book ));
788 TensorS0 * tens_27 = (( orb_m == orb_n ) ? NULL :
new TensorS0( orb_i, irrep_mn,
true, book ));
790 fill_tens_22_24( denT, tens_22, S0tensors[orb_i][orb_n-orb_m][orb_m-1-orb_i], workmem );
791 fill_tens_28( denT, tens_28, S0tensors[orb_i][orb_n-orb_m][orb_m-1-orb_i], workmem );
792 if ( orb_m != orb_n ){ fill_tens_23( denT, tens_23, S1tensors[orb_i][orb_n-orb_m][orb_m-1-orb_i], workmem );
793 fill_tens_25_26_27( denT, tens_25, tens_26, tens_27, S1tensors[orb_i][orb_n-orb_m][orb_m-1-orb_i], workmem, workmem2 ); }
795 #ifdef CHEMPS2_MPI_COMPILATION 796 #pragma omp for schedule(dynamic) nowait 798 #pragma omp for schedule(static) nowait 800 for (
int global = 0; global < upperbound1; global++){
802 const int orb_j = jkl[ 0 ];
803 const int orb_k = jkl[ 1 ];
805 if ( irrep_jk == irrep_mn ){
806 #ifdef CHEMPS2_MPI_COMPILATION 807 if ( MPIRANK == MPIchemps2::owner_absigma( orb_j, orb_k ) )
810 const int cnt1 = orb_k - orb_j;
811 const double d22 = tens_22->
inproduct(S0tensors[orb_i-1][cnt1][orb_i-1-orb_k],
'N');
812 const double d23 = (((cnt1==0)||(orb_m==orb_n))?0.0: tens_23->
inproduct(S1tensors[orb_i-1][cnt1][orb_i-1-orb_k],
'N'));
813 const double d25 = (((cnt1==0)||(orb_m==orb_n))?0.0: tens_25->
inproduct(S1tensors[orb_i-1][cnt1][orb_i-1-orb_k],
'N'));
814 const double d26 = (((cnt1==0)||(orb_m==orb_n))?0.0: tens_26->
inproduct(S1tensors[orb_i-1][cnt1][orb_i-1-orb_k],
'N'));
815 const double d27 = ( (orb_m==orb_n) ?0.0: tens_27->
inproduct(S0tensors[orb_i-1][cnt1][orb_i-1-orb_k],
'N'));
816 const double d28 = ( (cnt1==0) ?0.0: tens_28->
inproduct(S1tensors[orb_i-1][cnt1][orb_i-1-orb_k],
'N'));
817 set_dmrg_index( orb_j, orb_k, orb_i, orb_m, orb_n, orb_i, 2*d22 + 2*d23 + d25 );
818 set_dmrg_index( orb_j, orb_k, orb_i, orb_n, orb_m, orb_i, 2*d22 - 2*d23 - d25 );
819 set_dmrg_index( orb_j, orb_k, orb_i, orb_m, orb_i, orb_n, -d22 - d23 + d26 + d27 + d28 );
820 set_dmrg_index( orb_j, orb_k, orb_i, orb_n, orb_i, orb_m, -d22 + d23 - d26 - d27 + d28 );
821 set_dmrg_index( orb_j, orb_k, orb_i, orb_i, orb_m, orb_n, -d22 + d23 - d26 + d27 - d28 );
822 set_dmrg_index( orb_j, orb_k, orb_i, orb_i, orb_n, orb_m, -d22 - d23 + d26 - d27 - d28 );
828 if ( orb_m != orb_n ){
delete tens_23;
839 if ( counter_Sjk > 0 ){
843 TensorS0 * tens_47 = (( orb_m == orb_n ) ? NULL :
new TensorS0( orb_i, irrep_mn,
true, book ));
844 TensorS1 * tens_48 = (( orb_m == orb_n ) ? NULL :
new TensorS1( orb_i, irrep_mn,
true, book ));
845 fill_tens_45_47( denT, tens_45, F0tensors[orb_i][orb_n-orb_m][orb_m-1-orb_i], workmem,
true );
846 fill_tens_46_48( denT, tens_46, F1tensors[orb_i][orb_n-orb_m][orb_m-1-orb_i], workmem,
true );
847 if ( orb_m != orb_n ){ fill_tens_45_47( denT, tens_47, F0tensors[orb_i][orb_n-orb_m][orb_m-1-orb_i], workmem,
false );
848 fill_tens_46_48( denT, tens_48, F1tensors[orb_i][orb_n-orb_m][orb_m-1-orb_i], workmem,
false ); }
851 #ifdef CHEMPS2_MPI_COMPILATION 852 #pragma omp for schedule(dynamic) nowait 854 #pragma omp for schedule(static) nowait 856 for (
int global = 0; global < upperbound1; global++){
858 const int orb_j = jkl[ 0 ];
859 const int orb_k = jkl[ 1 ];
861 if ( irrep_jk == irrep_mn ){
862 #ifdef CHEMPS2_MPI_COMPILATION 863 if ( MPIRANK == MPIchemps2::owner_absigma( orb_j, orb_k ) )
866 const int cnt1 = orb_k - orb_j;
867 if ( orb_m < orb_n ){
868 const double d47 = tens_47->
inproduct(S0tensors[orb_i-1][cnt1][orb_i-1-orb_k],
'N');
869 const double d48 = (( cnt1 == 0 ) ? 0.0 : tens_48->
inproduct(S1tensors[orb_i-1][cnt1][orb_i-1-orb_k],
'N'));
870 set_dmrg_index( orb_j, orb_k, orb_n, orb_m, orb_i, orb_i, d47 + d48 );
871 set_dmrg_index( orb_j, orb_k, orb_n, orb_i, orb_m, orb_i, d47 - d48 );
872 set_dmrg_index( orb_j, orb_k, orb_n, orb_i, orb_i, orb_m, -2 * d47 );
874 const double d45 = tens_45->
inproduct(S0tensors[orb_i-1][cnt1][orb_i-1-orb_k],
'N');
875 const double d46 = (( cnt1 == 0 ) ? 0.0: tens_46->
inproduct(S1tensors[orb_i-1][cnt1][orb_i-1-orb_k],
'N'));
876 set_dmrg_index( orb_j, orb_k, orb_m, orb_n, orb_i, orb_i, d45 + d46 );
877 set_dmrg_index( orb_j, orb_k, orb_m, orb_i, orb_n, orb_i, d45 - d46 );
878 set_dmrg_index( orb_j, orb_k, orb_m, orb_i, orb_i, orb_n, -2 * d45 );
885 if ( orb_m != orb_n ){
delete tens_47;
894 for (
int global = 0; global < upperbound4; global++){
896 const int orb_j = jkl[ 0 ];
897 const int orb_k = jkl[ 1 ];
898 const int orb_l = jkl[ 2 ];
900 if ( irrep_jkl == irrep_imn ){
901 #ifdef CHEMPS2_MPI_COMPILATION 902 if ( MPIchemps2::owner_3rdm_diagram( L, orb_j, orb_k, orb_l ) == MPIRANK ){ counter_jkl++; }
912 if ( counter_jkl > 0 ){
915 Tensor3RDM * a_S1_doublet = (( orb_m == orb_n ) ? NULL :
new Tensor3RDM( orb_i, -2, 1, 3, irrep_imn,
true, book ));
916 Tensor3RDM * a_S1_quartet = (( orb_m == orb_n ) ? NULL :
new Tensor3RDM( orb_i, -2, 3, 3, irrep_imn,
true, book ));
917 fill_a_S0( denT, a_S0_doublet, S0tensors[orb_i][orb_n-orb_m][orb_m-1-orb_i], workmem );
918 if ( orb_m != orb_n ){ fill_a_S1( denT, a_S1_doublet, a_S1_quartet, S1tensors[orb_i][orb_n-orb_m][orb_m-1-orb_i], workmem, workmem2 ); }
920 #ifdef CHEMPS2_MPI_COMPILATION 921 #pragma omp for schedule(dynamic) nowait 923 #pragma omp for schedule(static) nowait 925 for (
int global = 0; global < upperbound4; global++){
927 const int orb_j = jkl[ 0 ];
928 const int orb_k = jkl[ 1 ];
929 const int orb_l = jkl[ 2 ];
931 if ( irrep_jkl == irrep_imn ){
932 #ifdef CHEMPS2_MPI_COMPILATION 933 if ( MPIchemps2::owner_3rdm_diagram( L, orb_j, orb_k, orb_l ) == MPIRANK )
936 const int cnt1 = orb_k - orb_j;
937 const int cnt2 = orb_l - orb_k;
938 const int cnt3 = orb_i - 1 - orb_l;
939 if ( cnt1 + cnt2 > 0 ){
940 const double d90_95 = a_S0_doublet->
contract(dm3_a_J0_doublet[cnt1][cnt2][cnt3]);
941 const double d93_98 = ( (cnt1==0) ?0.0: sq3*a_S0_doublet->
contract(dm3_a_J1_doublet[cnt1][cnt2][cnt3]));
942 const double d91_96 = (((orb_n==orb_m)||(cnt1==0))?0.0: a_S1_doublet->
contract(dm3_a_J1_doublet[cnt1][cnt2][cnt3]));
943 const double d94_99 = ( (orb_n==orb_m) ?0.0: -sq3*a_S1_doublet->
contract(dm3_a_J0_doublet[cnt1][cnt2][cnt3]));
944 const double d92_97 = (((orb_n==orb_m)||(cnt1==0))?0.0: a_S1_quartet->
contract(dm3_a_J1_quartet[cnt1][cnt2][cnt3]));
945 set_dmrg_index( orb_j, orb_k, orb_l, orb_m, orb_n, orb_i, -2*d90_95 + 2*d91_96 + d92_97 );
946 set_dmrg_index( orb_j, orb_k, orb_l, orb_n, orb_m, orb_i, -2*d90_95 - 2*d91_96 - d92_97 );
947 set_dmrg_index( orb_j, orb_k, orb_l, orb_m, orb_i, orb_n, d90_95 + d91_96 - d92_97 + d93_98 + d94_99 );
948 set_dmrg_index( orb_j, orb_k, orb_l, orb_n, orb_i, orb_m, d90_95 - d91_96 + d92_97 + d93_98 - d94_99 );
949 set_dmrg_index( orb_j, orb_k, orb_l, orb_i, orb_m, orb_n, d90_95 - d91_96 + d92_97 - d93_98 + d94_99 );
950 set_dmrg_index( orb_j, orb_k, orb_l, orb_i, orb_n, orb_m, d90_95 + d91_96 - d92_97 - d93_98 - d94_99 );
957 if ( orb_m != orb_n ){
delete a_S1_doublet;
958 delete a_S1_quartet; }
965 if ( counter_jkl > 0 ){
968 Tensor3RDM * bcd_S1_doublet = (( orb_m == orb_n ) ? NULL :
new Tensor3RDM( orb_i, -2, 1, 1, irrep_imn,
true, book ));
969 Tensor3RDM * bcd_S1_quartet = (( orb_m == orb_n ) ? NULL :
new Tensor3RDM( orb_i, -2, 3, 1, irrep_imn,
true, book ));
970 fill_bcd_S0( denT, bcd_S0_doublet, S0tensors[orb_i][orb_n-orb_m][orb_m-1-orb_i], workmem );
971 if ( orb_m != orb_n ){ fill_bcd_S1( denT, bcd_S1_doublet, bcd_S1_quartet, S1tensors[orb_i][orb_n-orb_m][orb_m-1-orb_i], workmem, workmem2 ); }
973 #ifdef CHEMPS2_MPI_COMPILATION 974 #pragma omp for schedule(dynamic) nowait 976 #pragma omp for schedule(static) nowait 978 for (
int global = 0; global < upperbound4; global++){
980 const int orb_j = jkl[ 0 ];
981 const int orb_k = jkl[ 1 ];
982 const int orb_l = jkl[ 2 ];
984 if ( irrep_jkl == irrep_imn ){
985 #ifdef CHEMPS2_MPI_COMPILATION 986 if ( MPIchemps2::owner_3rdm_diagram( L, orb_j, orb_k, orb_l ) == MPIRANK )
989 const int cnt1 = orb_k - orb_j;
990 const int cnt2 = orb_l - orb_k;
991 const int cnt3 = orb_i - 1 - orb_l;
993 const double d120_125 = bcd_S0_doublet->
contract(dm3_b_J0_doublet[cnt1][cnt2][cnt3]);
994 const double d124_129 = ( (cnt1==0) ?0.0: sq3*bcd_S0_doublet->
contract(dm3_b_J1_doublet[cnt1][cnt2][cnt3]));
995 const double d123_128 = ( (orb_n==orb_m) ?0.0: sq3*bcd_S1_doublet->
contract(dm3_b_J0_doublet[cnt1][cnt2][cnt3]));
996 const double d121_126 = (((orb_n==orb_m)||(cnt1==0))?0.0: bcd_S1_doublet->
contract(dm3_b_J1_doublet[cnt1][cnt2][cnt3]));
997 const double d122_127 = (((orb_n==orb_m)||(cnt1==0))?0.0: bcd_S1_quartet->
contract(dm3_b_J1_quartet[cnt1][cnt2][cnt3]));
998 set_dmrg_index( orb_l, orb_m, orb_n, orb_j, orb_k, orb_i, -d120_125 + 3*d121_126 + d123_128 - d124_129 );
999 set_dmrg_index( orb_l, orb_m, orb_n, orb_k, orb_j, orb_i, -d120_125 - 3*d121_126 + d123_128 + d124_129 );
1000 set_dmrg_index( orb_l, orb_m, orb_n, orb_j, orb_i, orb_k, -d120_125 - 3*d121_126 - d123_128 - d124_129 );
1001 set_dmrg_index( orb_l, orb_m, orb_n, orb_k, orb_i, orb_j, -d120_125 + 3*d121_126 - d123_128 + d124_129 );
1002 set_dmrg_index( orb_l, orb_m, orb_n, orb_i, orb_j, orb_k, 2*d120_125 + 2*d121_126 + 2*d122_127 );
1003 set_dmrg_index( orb_l, orb_m, orb_n, orb_i, orb_k, orb_j, 2*d120_125 - 2*d121_126 - 2*d122_127 );
1005 if ( cnt1 + cnt2 > 0 ){
1006 const double d110_115 = bcd_S0_doublet->
contract(dm3_c_J0_doublet[cnt1][cnt2][cnt3]);
1007 const double d112_117 = -sq3*bcd_S0_doublet->
contract(dm3_c_J1_doublet[cnt1][cnt2][cnt3]);
1008 const double d111_116 = ((orb_n==orb_m)?0.0: -sq3*bcd_S1_doublet->
contract(dm3_c_J0_doublet[cnt1][cnt2][cnt3]));
1009 const double d113_118 = ((orb_n==orb_m)?0.0: bcd_S1_doublet->
contract(dm3_c_J1_doublet[cnt1][cnt2][cnt3]));
1010 const double d114_119 = ((orb_n==orb_m)?0.0: -2*bcd_S1_quartet->
contract(dm3_c_J1_quartet[cnt1][cnt2][cnt3]));
1011 set_dmrg_index( orb_k, orb_m, orb_n, orb_j, orb_l, orb_i, 2*d110_115 + 2*d111_116 );
1012 set_dmrg_index( orb_k, orb_m, orb_n, orb_l, orb_j, orb_i, -d110_115 - d111_116 - d112_117 - 3*d113_118 );
1013 set_dmrg_index( orb_k, orb_m, orb_n, orb_j, orb_i, orb_l, 2*d110_115 - 2*d111_116 );
1014 set_dmrg_index( orb_k, orb_m, orb_n, orb_l, orb_i, orb_j, -d110_115 + d111_116 - d112_117 + 3*d113_118 );
1015 set_dmrg_index( orb_k, orb_m, orb_n, orb_i, orb_j, orb_l, -d110_115 + d111_116 + d112_117 + d113_118 + d114_119 );
1016 set_dmrg_index( orb_k, orb_m, orb_n, orb_i, orb_l, orb_j, -d110_115 - d111_116 + d112_117 - d113_118 - d114_119 );
1019 const double d100_105 = -bcd_S0_doublet->
contract(dm3_d_J0_doublet[cnt1][cnt2][cnt3]);
1020 const double d102_107 = -sq3*bcd_S0_doublet->
contract(dm3_d_J1_doublet[cnt1][cnt2][cnt3]);
1021 const double d101_106 = ( (orb_n==orb_m) ?0.0: sq3*bcd_S1_doublet->
contract(dm3_d_J0_doublet[cnt1][cnt2][cnt3]));
1022 const double d103_108 = ( (orb_n==orb_m) ?0.0: bcd_S1_doublet->
contract(dm3_d_J1_doublet[cnt1][cnt2][cnt3]));
1023 const double d104_109 = (((orb_n==orb_m)||(cnt2==0))?0.0: 2*bcd_S1_quartet->
contract(dm3_d_J1_quartet[cnt1][cnt2][cnt3]));
1024 set_dmrg_index( orb_j, orb_m, orb_n, orb_k, orb_l, orb_i, 2*d100_105 + 2*d101_106 );
1025 set_dmrg_index( orb_j, orb_m, orb_n, orb_l, orb_k, orb_i, -d100_105 - d101_106 - d102_107 - 3*d103_108 );
1026 set_dmrg_index( orb_j, orb_m, orb_n, orb_k, orb_i, orb_l, 2*d100_105 - 2*d101_106 );
1027 set_dmrg_index( orb_j, orb_m, orb_n, orb_l, orb_i, orb_k, -d100_105 + d101_106 - d102_107 + 3*d103_108 );
1028 set_dmrg_index( orb_j, orb_m, orb_n, orb_i, orb_k, orb_l, -d100_105 + d101_106 + d102_107 + d103_108 + d104_109 );
1029 set_dmrg_index( orb_j, orb_m, orb_n, orb_i, orb_l, orb_k, -d100_105 - d101_106 + d102_107 - d103_108 - d104_109 );
1034 delete bcd_S0_doublet;
1035 if ( orb_m != orb_n ){
delete bcd_S1_doublet;
1036 delete bcd_S1_quartet; }
1043 if ( counter_jkl > 0 ){
1048 fill_F0_T( denT, F0_T_doublet, F0tensors[orb_i][orb_n-orb_m][orb_m-1-orb_i], workmem );
1049 fill_F1_T( denT, F1_T_doublet, F1_T_quartet, F1tensors[orb_i][orb_n-orb_m][orb_m-1-orb_i], workmem, workmem2 );
1051 #ifdef CHEMPS2_MPI_COMPILATION 1052 #pragma omp for schedule(dynamic) nowait 1054 #pragma omp for schedule(static) nowait 1056 for (
int global = 0; global < upperbound4; global++){
1058 const int orb_j = jkl[ 0 ];
1059 const int orb_k = jkl[ 1 ];
1060 const int orb_l = jkl[ 2 ];
1062 if ( irrep_jkl == irrep_imn ){
1063 #ifdef CHEMPS2_MPI_COMPILATION 1064 if ( MPIchemps2::owner_3rdm_diagram( L, orb_j, orb_k, orb_l ) == MPIRANK )
1067 const int cnt1 = orb_k - orb_j;
1068 const int cnt2 = orb_l - orb_k;
1069 const int cnt3 = orb_i - 1 - orb_l;
1071 const double d130_135 = F0_T_doublet->
contract(dm3_b_J0_doublet[cnt1][cnt2][cnt3]);
1072 const double d131_136 = ((cnt1==0)?0.0: sq3*F0_T_doublet->
contract(dm3_b_J1_doublet[cnt1][cnt2][cnt3]));
1073 const double d132_137 = sq3*F1_T_doublet->
contract(dm3_b_J0_doublet[cnt1][cnt2][cnt3]);
1074 const double d133_138 = ((cnt1==0)?0.0: F1_T_doublet->
contract(dm3_b_J1_doublet[cnt1][cnt2][cnt3]));
1075 const double d134_139 = ((cnt1==0)?0.0: F1_T_quartet->
contract(dm3_b_J1_quartet[cnt1][cnt2][cnt3]));
1076 set_dmrg_index( orb_j, orb_k, orb_m, orb_l, orb_n, orb_i, d130_135 + d131_136 + d132_137 + 3*d133_138 );
1077 set_dmrg_index( orb_j, orb_k, orb_m, orb_n, orb_l, orb_i, d130_135 - d131_136 + d132_137 - 3*d133_138 );
1078 set_dmrg_index( orb_j, orb_k, orb_m, orb_l, orb_i, orb_n, -2*d130_135 - 2*d131_136 );
1079 set_dmrg_index( orb_j, orb_k, orb_m, orb_n, orb_i, orb_l, d130_135 + d131_136 - d132_137 + d133_138 + 2*d134_139 );
1080 set_dmrg_index( orb_j, orb_k, orb_m, orb_i, orb_l, orb_n, -2*d130_135 + 2*d131_136 );
1081 set_dmrg_index( orb_j, orb_k, orb_m, orb_i, orb_n, orb_l, d130_135 - d131_136 - d132_137 - d133_138 - 2*d134_139 );
1083 if ( cnt1 + cnt2 > 0 ){
1084 const double d150_155 = F0_T_doublet->
contract(dm3_c_J0_doublet[cnt1][cnt2][cnt3]);
1085 const double d151_156 = -sq3*F0_T_doublet->
contract(dm3_c_J1_doublet[cnt1][cnt2][cnt3]);
1086 const double d152_157 = sq3*F1_T_doublet->
contract(dm3_c_J0_doublet[cnt1][cnt2][cnt3]);
1087 const double d153_158 = F1_T_doublet->
contract(dm3_c_J1_doublet[cnt1][cnt2][cnt3]);
1088 const double d154_159 = -F1_T_quartet->
contract(dm3_c_J1_quartet[cnt1][cnt2][cnt3]);
1089 set_dmrg_index( orb_j, orb_l, orb_m, orb_k, orb_n, orb_i, -2*d150_155 - 2*d152_157 );
1090 set_dmrg_index( orb_j, orb_l, orb_m, orb_n, orb_k, orb_i, d150_155 + d151_156 + d152_157 - 3*d153_158 );
1091 set_dmrg_index( orb_j, orb_l, orb_m, orb_k, orb_i, orb_n, 4*d150_155 );
1092 set_dmrg_index( orb_j, orb_l, orb_m, orb_n, orb_i, orb_k, -2*d150_155 + 2*d153_158 + 2*d154_159 );
1093 set_dmrg_index( orb_j, orb_l, orb_m, orb_i, orb_k, orb_n, -2*d150_155 - 2*d151_156 );
1094 set_dmrg_index( orb_j, orb_l, orb_m, orb_i, orb_n, orb_k, d150_155 + d151_156 + d152_157 + d153_158 - 2*d154_159 );
1097 const double d170_175 = -F0_T_doublet->
contract(dm3_d_J0_doublet[cnt1][cnt2][cnt3]);
1098 const double d171_176 = -sq3*F0_T_doublet->
contract(dm3_d_J1_doublet[cnt1][cnt2][cnt3]);
1099 const double d172_177 = -sq3*F1_T_doublet->
contract(dm3_d_J0_doublet[cnt1][cnt2][cnt3]);
1100 const double d173_178 = F1_T_doublet->
contract(dm3_d_J1_doublet[cnt1][cnt2][cnt3]);
1101 const double d174_179 = ((cnt2==0)?0.0: F1_T_quartet->
contract(dm3_d_J1_quartet[cnt1][cnt2][cnt3]));
1102 set_dmrg_index( orb_k, orb_l, orb_m, orb_j, orb_n, orb_i, -2*d170_175 - 2*d172_177 );
1103 set_dmrg_index( orb_k, orb_l, orb_m, orb_n, orb_j, orb_i, d170_175 + d171_176 + d172_177 - 3*d173_178 );
1104 set_dmrg_index( orb_k, orb_l, orb_m, orb_j, orb_i, orb_n, 4*d170_175 );
1105 set_dmrg_index( orb_k, orb_l, orb_m, orb_n, orb_i, orb_j, -2*d170_175 + 2*d173_178 + 2*d174_179 );
1106 set_dmrg_index( orb_k, orb_l, orb_m, orb_i, orb_j, orb_n, -2*d170_175 - 2*d171_176 );
1107 set_dmrg_index( orb_k, orb_l, orb_m, orb_i, orb_n, orb_j, d170_175 + d171_176 + d172_177 + d173_178 - 2*d174_179 );
1112 delete F0_T_doublet;
1113 delete F1_T_doublet;
1114 delete F1_T_quartet;
1121 if (( orb_m != orb_n ) && ( counter_jkl > 0 )){
1126 fill_F0( denT, F0_doublet, F0tensors[orb_i][orb_n-orb_m][orb_m-1-orb_i], workmem );
1127 fill_F1( denT, F1_doublet, F1_quartet, F1tensors[orb_i][orb_n-orb_m][orb_m-1-orb_i], workmem, workmem2 );
1129 #ifdef CHEMPS2_MPI_COMPILATION 1130 #pragma omp for schedule(dynamic) nowait 1132 #pragma omp for schedule(static) nowait 1134 for (
int global = 0; global < upperbound4; global++){
1136 const int orb_j = jkl[ 0 ];
1137 const int orb_k = jkl[ 1 ];
1138 const int orb_l = jkl[ 2 ];
1140 if ( irrep_jkl == irrep_imn ){
1141 #ifdef CHEMPS2_MPI_COMPILATION 1142 if ( MPIchemps2::owner_3rdm_diagram( L, orb_j, orb_k, orb_l ) == MPIRANK )
1145 const int cnt1 = orb_k - orb_j;
1146 const int cnt2 = orb_l - orb_k;
1147 const int cnt3 = orb_i - 1 - orb_l;
1149 const double d140_145 = F0_doublet->
contract(dm3_b_J0_doublet[cnt1][cnt2][cnt3]);
1150 const double d141_146 = ((cnt1==0)?0.0: sq3*F0_doublet->
contract(dm3_b_J1_doublet[cnt1][cnt2][cnt3]));
1151 const double d142_147 = sq3*F1_doublet->
contract(dm3_b_J0_doublet[cnt1][cnt2][cnt3]);
1152 const double d143_148 = ((cnt1==0)?0.0: F1_doublet->
contract(dm3_b_J1_doublet[cnt1][cnt2][cnt3]));
1153 const double d144_149 = ((cnt1==0)?0.0: F1_quartet->
contract(dm3_b_J1_quartet[cnt1][cnt2][cnt3]));
1154 set_dmrg_index( orb_j, orb_k, orb_n, orb_l, orb_m, orb_i, d140_145 + d141_146 + d142_147 + 3*d143_148 );
1155 set_dmrg_index( orb_j, orb_k, orb_n, orb_m, orb_l, orb_i, d140_145 - d141_146 + d142_147 - 3*d143_148 );
1156 set_dmrg_index( orb_j, orb_k, orb_n, orb_l, orb_i, orb_m, -2*d140_145 - 2*d141_146 );
1157 set_dmrg_index( orb_j, orb_k, orb_n, orb_m, orb_i, orb_l, d140_145 + d141_146 - d142_147 + d143_148 + 2*d144_149 );
1158 set_dmrg_index( orb_j, orb_k, orb_n, orb_i, orb_l, orb_m, -2*d140_145 + 2*d141_146 );
1159 set_dmrg_index( orb_j, orb_k, orb_n, orb_i, orb_m, orb_l, d140_145 - d141_146 - d142_147 - d143_148 - 2*d144_149 );
1161 if ( cnt1 + cnt2 > 0 ){
1162 const double d160_165 = F0_doublet->
contract(dm3_c_J0_doublet[cnt1][cnt2][cnt3]);
1163 const double d161_166 = -sq3*F0_doublet->
contract(dm3_c_J1_doublet[cnt1][cnt2][cnt3]);
1164 const double d162_167 = sq3*F1_doublet->
contract(dm3_c_J0_doublet[cnt1][cnt2][cnt3]);
1165 const double d163_168 = F1_doublet->
contract(dm3_c_J1_doublet[cnt1][cnt2][cnt3]);
1166 const double d164_169 = -F1_quartet->
contract(dm3_c_J1_quartet[cnt1][cnt2][cnt3]);
1167 set_dmrg_index( orb_j, orb_l, orb_n, orb_k, orb_m, orb_i, -2*d160_165 - 2*d162_167 );
1168 set_dmrg_index( orb_j, orb_l, orb_n, orb_m, orb_k, orb_i, d160_165 + d161_166 + d162_167 - 3*d163_168 );
1169 set_dmrg_index( orb_j, orb_l, orb_n, orb_k, orb_i, orb_m, 4*d160_165 );
1170 set_dmrg_index( orb_j, orb_l, orb_n, orb_m, orb_i, orb_k, -2*d160_165 + 2*d163_168 + 2*d164_169 );
1171 set_dmrg_index( orb_j, orb_l, orb_n, orb_i, orb_k, orb_m, -2*d160_165 - 2*d161_166 );
1172 set_dmrg_index( orb_j, orb_l, orb_n, orb_i, orb_m, orb_k, d160_165 + d161_166 + d162_167 + d163_168 - 2*d164_169 );
1175 const double d180_185 = -F0_doublet->
contract(dm3_d_J0_doublet[cnt1][cnt2][cnt3]);
1176 const double d181_186 = -sq3*F0_doublet->
contract(dm3_d_J1_doublet[cnt1][cnt2][cnt3]);
1177 const double d182_187 = -sq3*F1_doublet->
contract(dm3_d_J0_doublet[cnt1][cnt2][cnt3]);
1178 const double d183_188 = F1_doublet->
contract(dm3_d_J1_doublet[cnt1][cnt2][cnt3]);
1179 const double d184_189 = ((cnt2==0)?0.0: F1_quartet->
contract(dm3_d_J1_quartet[cnt1][cnt2][cnt3]));
1180 set_dmrg_index( orb_k, orb_l, orb_n, orb_j, orb_m, orb_i, -2*d180_185 - 2*d182_187 );
1181 set_dmrg_index( orb_k, orb_l, orb_n, orb_m, orb_j, orb_i, d180_185 + d181_186 + d182_187 - 3*d183_188 );
1182 set_dmrg_index( orb_k, orb_l, orb_n, orb_j, orb_i, orb_m, 4*d180_185 );
1183 set_dmrg_index( orb_k, orb_l, orb_n, orb_m, orb_i, orb_j, -2*d180_185 + 2*d183_188 + 2*d184_189 );
1184 set_dmrg_index( orb_k, orb_l, orb_n, orb_i, orb_j, orb_m, -2*d180_185 - 2*d181_186 );
1185 set_dmrg_index( orb_k, orb_l, orb_n, orb_i, orb_m, orb_j, d180_185 + d181_186 + d182_187 + d183_188 - 2*d184_189 );
1199 #ifdef CHEMPS2_MPI_COMPILATION 1200 #pragma omp barrier // Everyone needs to be done before tensors are deleted 1202 if ( orb_m > orb_i + 1 ){
1203 const int own_S_mn = MPIchemps2::owner_absigma( orb_m, orb_n );
1204 const int own_F_mn = MPIchemps2::owner_cdf( L, orb_m, orb_n );
1205 if ( MPIRANK != own_F_mn ){
delete F0tensors[orb_i][orb_n-orb_m][orb_m-1-orb_i]; F0tensors[orb_i][orb_n-orb_m][orb_m-1-orb_i] = NULL;
1206 delete F1tensors[orb_i][orb_n-orb_m][orb_m-1-orb_i]; F1tensors[orb_i][orb_n-orb_m][orb_m-1-orb_i] = NULL; }
1207 if ( MPIRANK != own_S_mn ){
delete S0tensors[orb_i][orb_n-orb_m][orb_m-1-orb_i]; S0tensors[orb_i][orb_n-orb_m][orb_m-1-orb_i] = NULL;
1208 if ( orb_m != orb_n ){
delete S1tensors[orb_i][orb_n-orb_m][orb_m-1-orb_i]; S1tensors[orb_i][orb_n-orb_m][orb_m-1-orb_i] = NULL; } }
1215 for (
int orb_m = orb_i+1; orb_m < L; orb_m++ ){
1217 const int irrep_m = book->
gIrrep( orb_m );
1222 int counter_jkl = 0;
1223 for (
int global = 0; global < upperbound4; global++){
1225 const int orb_j = jkl[ 0 ];
1226 const int orb_k = jkl[ 1 ];
1227 const int orb_l = jkl[ 2 ];
1229 if ( irrep_jkl == irrep_m ){
1230 #ifdef CHEMPS2_MPI_COMPILATION 1231 if ( MPIchemps2::owner_3rdm_diagram( L, orb_j, orb_k, orb_l ) == MPIRANK ){ counter_jkl++; }
1241 if ( counter_jkl > 0 ){
1245 fill_53_54( denT, A_T_doublet, Ltensors[orb_i][orb_m-1-orb_i], workmem );
1246 fill_55_to_60( denT, BCD_T_doublet, Ltensors[orb_i][orb_m-1-orb_i], workmem );
1248 #ifdef CHEMPS2_MPI_COMPILATION 1249 #pragma omp for schedule(dynamic) nowait 1251 #pragma omp for schedule(static) nowait 1253 for (
int global = 0; global < upperbound4; global++ ){
1255 const int orb_j = jkl[ 0 ];
1256 const int orb_k = jkl[ 1 ];
1257 const int orb_l = jkl[ 2 ];
1259 if ( irrep_jkl == irrep_m ){
1260 #ifdef CHEMPS2_MPI_COMPILATION 1261 if ( MPIchemps2::owner_3rdm_diagram( L, orb_j, orb_k, orb_l ) == MPIRANK )
1264 const int cnt1 = orb_k - orb_j;
1265 const int cnt2 = orb_l - orb_k;
1266 const int cnt3 = orb_i - 1 - orb_l;
1267 if ( cnt1 + cnt2 > 0 ){
1268 const double d53 = A_T_doublet->
contract( dm3_a_J0_doublet[cnt1][cnt2][cnt3] );
1269 const double d54 = sq3*A_T_doublet->
contract( dm3_a_J1_doublet[cnt1][cnt2][cnt3] );
1270 set_dmrg_index( orb_j, orb_k, orb_l, orb_m, orb_i, orb_i, d53 - d54 );
1271 set_dmrg_index( orb_j, orb_k, orb_l, orb_i, orb_m, orb_i, d53 + d54 );
1272 set_dmrg_index( orb_j, orb_k, orb_l, orb_i, orb_i, orb_m, - 2 * d53 );
1275 const double d55 = BCD_T_doublet->
contract( dm3_b_J0_doublet[cnt1][cnt2][cnt3] );
1276 const double d56 = sq3*BCD_T_doublet->
contract( dm3_b_J1_doublet[cnt1][cnt2][cnt3] );
1277 set_dmrg_index( orb_j, orb_k, orb_m, orb_l, orb_i, orb_i, d55 + d56 );
1278 set_dmrg_index( orb_j, orb_k, orb_m, orb_i, orb_l, orb_i, d55 - d56 );
1279 set_dmrg_index( orb_j, orb_k, orb_m, orb_i, orb_i, orb_l, - 2 * d55 );
1281 if ( cnt1 + cnt2 > 0 ){
1282 const double d57 = BCD_T_doublet->
contract( dm3_c_J0_doublet[cnt1][cnt2][cnt3] );
1283 const double d58 = sq3*BCD_T_doublet->
contract( dm3_c_J1_doublet[cnt1][cnt2][cnt3] );
1284 set_dmrg_index( orb_j, orb_l, orb_m, orb_k, orb_i, orb_i, - 2 * d57 );
1285 set_dmrg_index( orb_j, orb_l, orb_m, orb_i, orb_k, orb_i, d57 - d58 );
1286 set_dmrg_index( orb_j, orb_l, orb_m, orb_i, orb_i, orb_k, d57 + d58 );
1288 const double d59 = -BCD_T_doublet->
contract( dm3_d_J0_doublet[cnt1][cnt2][cnt3] );
1289 const double d60 = -sq3*BCD_T_doublet->
contract( dm3_d_J1_doublet[cnt1][cnt2][cnt3] );
1290 set_dmrg_index( orb_k, orb_l, orb_m, orb_j, orb_i, orb_i, - 2 * d59 );
1291 set_dmrg_index( orb_k, orb_l, orb_m, orb_i, orb_j, orb_i, d59 + d60 );
1292 set_dmrg_index( orb_k, orb_l, orb_m, orb_i, orb_i, orb_j, d59 - d60 );
1298 delete BCD_T_doublet;
1306 for (
int orb_j = 0; orb_j < orb_i; orb_j++ ){
1307 const int irrep_j = book->
gIrrep( orb_j );
1308 if ( irrep_j == irrep_m ){
1309 #ifdef CHEMPS2_MPI_COMPILATION 1310 if ( MPIRANK == MPIchemps2::owner_q( L, orb_j ) ){ counter_j++; }
1321 if (( counter_jkl > 0 ) || ( counter_j > 0 )){
1333 fill_61( denT, tens_61, Ltensors[orb_i][orb_m-1-orb_i], workmem );
1334 fill_63_65( denT, tens_63, tens_65, tens_67, tens_68, tens_76, tens_77, Ltensors[orb_i][orb_m-1-orb_i], workmem, workmem2 );
1335 fill_69_78_79( denT, tens_69, tens_78, tens_79, Ltensors[orb_i][orb_m-1-orb_i], workmem, workmem2 );
1337 #ifdef CHEMPS2_MPI_COMPILATION 1338 #pragma omp for schedule(dynamic) nowait 1340 #pragma omp for schedule(static) nowait 1342 for (
int orb_j = 0; orb_j < orb_i; orb_j++ ){
1343 const int irrep_j = book->
gIrrep( orb_j );
1344 if ( irrep_j == irrep_m ){
1345 #ifdef CHEMPS2_MPI_COMPILATION 1346 if ( MPIRANK == MPIchemps2::owner_q( L, orb_j ) )
1349 const double d2 = sqrt( 2.0 ) * tens_61->
inproduct( Ltensors[orb_i-1][orb_i-1-orb_j],
'N' );
1350 set_dmrg_index( orb_j, orb_i, orb_i, orb_m, orb_i, orb_i, 2 * d2 );
1351 set_dmrg_index( orb_j, orb_i, orb_i, orb_i, orb_m, orb_i, - d2 );
1356 #ifdef CHEMPS2_MPI_COMPILATION 1357 #pragma omp for schedule(dynamic) nowait 1359 #pragma omp for schedule(static) nowait 1361 for (
int global = 0; global < upperbound4; global++ ){
1363 const int orb_j = jkl[ 0 ];
1364 const int orb_k = jkl[ 1 ];
1365 const int orb_l = jkl[ 2 ];
1367 if ( irrep_jkl == irrep_m ){
1368 #ifdef CHEMPS2_MPI_COMPILATION 1369 if ( MPIchemps2::owner_3rdm_diagram( L, orb_j, orb_k, orb_l ) == MPIRANK )
1372 const int cnt1 = orb_k - orb_j;
1373 const int cnt2 = orb_l - orb_k;
1374 const int cnt3 = orb_i - 1 - orb_l;
1376 const double d61 = tens_61->
contract( dm3_b_J0_doublet[cnt1][cnt2][cnt3] );
1377 const double d62 = sq3*tens_61->
contract( dm3_b_J1_doublet[cnt1][cnt2][cnt3] );
1378 const double d63 = tens_63->
contract( dm3_b_J0_doublet[cnt1][cnt2][cnt3] );
1379 const double d64 = sq3*tens_63->
contract( dm3_b_J1_doublet[cnt1][cnt2][cnt3] );
1380 const double d65 = tens_65->
contract( dm3_b_J0_doublet[cnt1][cnt2][cnt3] );
1381 const double d66 = sq3*tens_65->
contract( dm3_b_J1_doublet[cnt1][cnt2][cnt3] );
1382 const double d67 = tens_67->
contract( dm3_b_J0_doublet[cnt1][cnt2][cnt3] );
1383 const double d68 = tens_68->
contract( dm3_b_J1_doublet[cnt1][cnt2][cnt3] );
1384 const double d69 = tens_69->
contract( dm3_b_J1_quartet[cnt1][cnt2][cnt3] );
1385 set_dmrg_index( orb_j, orb_k, orb_i, orb_l, orb_m, orb_i, -2*d61 - 2*d62 + d63 + d64 );
1386 set_dmrg_index( orb_j, orb_k, orb_i, orb_m, orb_l, orb_i, -2*d61 + 2*d62 + d63 - d64 );
1387 set_dmrg_index( orb_j, orb_k, orb_i, orb_l, orb_i, orb_m, d61 + d62 + d65 + d66 );
1388 set_dmrg_index( orb_j, orb_k, orb_i, orb_m, orb_i, orb_l, d61 - d62 + d67 + d68 + d69 );
1389 set_dmrg_index( orb_j, orb_k, orb_i, orb_i, orb_m, orb_l, d61 + d62 + d67 - d68 - d69 );
1390 set_dmrg_index( orb_j, orb_k, orb_i, orb_i, orb_l, orb_m, d61 - d62 + d65 - d66 );
1392 if ( cnt1 + cnt2 > 0 ){
1393 const double d70 = tens_61->
contract( dm3_c_J0_doublet[cnt1][cnt2][cnt3] );
1394 const double d71 = sq3*tens_61->
contract( dm3_c_J1_doublet[cnt1][cnt2][cnt3] );
1395 const double d72 = -tens_63->
contract( dm3_c_J0_doublet[cnt1][cnt2][cnt3] );
1396 const double d73 = -sq3*tens_63->
contract( dm3_c_J1_doublet[cnt1][cnt2][cnt3] );
1397 const double d74 = -tens_65->
contract( dm3_c_J0_doublet[cnt1][cnt2][cnt3] );
1398 const double d75 = -sq3*tens_65->
contract( dm3_c_J1_doublet[cnt1][cnt2][cnt3] );
1399 const double d76 = tens_76->
contract( dm3_c_J1_doublet[cnt1][cnt2][cnt3] );
1400 const double d77 = tens_77->
contract( dm3_c_J1_doublet[cnt1][cnt2][cnt3] );
1401 const double d78 = tens_78->
contract( dm3_c_J1_quartet[cnt1][cnt2][cnt3] );
1402 const double d79 = tens_79->
contract( dm3_c_J1_quartet[cnt1][cnt2][cnt3] );
1403 set_dmrg_index( orb_j, orb_l, orb_i, orb_k, orb_m, orb_i, 4*d70 + 2*d72 );
1404 set_dmrg_index( orb_j, orb_l, orb_i, orb_m, orb_k, orb_i, -2*d70 + 2*d71 - d72 + d73 );
1405 set_dmrg_index( orb_j, orb_l, orb_i, orb_k, orb_i, orb_m, -2*d70 + 2*d74 );
1406 set_dmrg_index( orb_j, orb_l, orb_i, orb_m, orb_i, orb_k, d70 - d71 - d74 + d76 + d78 );
1407 set_dmrg_index( orb_j, orb_l, orb_i, orb_i, orb_k, orb_m, d70 - d71 - d74 + d75 );
1408 set_dmrg_index( orb_j, orb_l, orb_i, orb_i, orb_m, orb_k, -2*d70 - d72 + d77 + d79 );
1410 const double d80 = -tens_61->
contract( dm3_d_J0_doublet[cnt1][cnt2][cnt3] );
1411 const double d81 = -sq3*tens_61->
contract( dm3_d_J1_doublet[cnt1][cnt2][cnt3] );
1412 const double d82 = tens_63->
contract( dm3_d_J0_doublet[cnt1][cnt2][cnt3] );
1413 const double d83 = sq3*tens_63->
contract( dm3_d_J1_doublet[cnt1][cnt2][cnt3] );
1414 const double d84 = tens_65->
contract( dm3_d_J0_doublet[cnt1][cnt2][cnt3] );
1415 const double d85 = sq3*tens_65->
contract( dm3_d_J1_doublet[cnt1][cnt2][cnt3] );
1416 const double d86 = tens_76->
contract( dm3_d_J1_doublet[cnt1][cnt2][cnt3] );
1417 const double d87 = tens_77->
contract( dm3_d_J1_doublet[cnt1][cnt2][cnt3] );
1418 const double d88 = -tens_78->
contract( dm3_d_J1_quartet[cnt1][cnt2][cnt3] );
1419 const double d89 = -tens_79->
contract( dm3_d_J1_quartet[cnt1][cnt2][cnt3] );
1420 set_dmrg_index( orb_j, orb_m, orb_i, orb_k, orb_l, orb_i, 4*d80 + 2*d82 );
1421 set_dmrg_index( orb_j, orb_m, orb_i, orb_l, orb_k, orb_i, -2*d80 - 2*d81 - d82 - d83 );
1422 set_dmrg_index( orb_j, orb_m, orb_i, orb_k, orb_i, orb_l, -2*d80 + 2*d84 );
1423 set_dmrg_index( orb_j, orb_m, orb_i, orb_l, orb_i, orb_k, d80 + d81 - d84 - d85 );
1424 set_dmrg_index( orb_j, orb_m, orb_i, orb_i, orb_k, orb_l, d80 + d81 - d84 + d86 + d88 );
1425 set_dmrg_index( orb_j, orb_m, orb_i, orb_i, orb_l, orb_k, -2*d80 - d82 + d87 + d89 );
1449 if (( disk ) && ( temp_disk_counter > 0 )){ flush_disk(); }
1453 double CheMPS2::ThreeDM::diagram1(
TensorT * denT,
TensorF0 * denF0,
double * workmem)
const{
1456 const int orb_i = denT->
gIndex();
1460 for (
int NL = book->
gNmin( orb_i ); NL <= book->
gNmax( orb_i ); NL++ ){
1461 for (
int TwoSL = book->
gTwoSmin( orb_i, NL ); TwoSL <= book->
gTwoSmax( orb_i, NL ); TwoSL+=2 ){
1464 int dimL = book->
gCurrentDim( orb_i, NL, TwoSL, IL );
1465 int dimR = book->
gCurrentDim( orb_i+1, NL+2, TwoSL, IL );
1467 if (( dimL > 0 ) && ( dimR > 0 )){
1469 double * Tblock = denT->
gStorage( NL, TwoSL, IL, NL+2, TwoSL, IL );
1470 double * Fblock = denF0->
gStorage( NL, TwoSL, IL, NL, TwoSL, IL );
1475 dgemm_( ¬rans, ¬rans, &dimL, &dimR, &dimL, &alpha, Fblock, &dimL, Tblock, &dimL, &beta, workmem, &dimL );
1477 int length = dimL * dimR;
1479 total += ( TwoSL + 1 ) * ddot_( &length, workmem, &inc, Tblock, &inc );
1486 total *= sqrt( 0.5 );
1491 double CheMPS2::ThreeDM::diagram3(
TensorT * denT,
TensorF0 * denF0,
double * workmem)
const{
1494 const int orb_i = denT->
gIndex();
1498 for (
int NL = book->
gNmin( orb_i ); NL <= book->
gNmax( orb_i ); NL++ ){
1499 for (
int TwoSL = book->
gTwoSmin( orb_i, NL ); TwoSL <= book->
gTwoSmax( orb_i, NL ); TwoSL+=2 ){
1502 int dimL = book->
gCurrentDim( orb_i, NL, TwoSL, IL );
1503 int dimR = book->
gCurrentDim( orb_i+1, NL+2, TwoSL, IL );
1505 if (( dimL > 0 ) && ( dimR > 0 )){
1507 double * Tblock = denT->
gStorage( NL, TwoSL, IL, NL+2, TwoSL, IL );
1508 double * Fblock = denF0->
gStorage( NL+2, TwoSL, IL, NL+2, TwoSL, IL );
1513 dgemm_( ¬rans, ¬rans, &dimL, &dimR, &dimR, &alpha, Tblock, &dimL, Fblock, &dimR, &beta, workmem, &dimL );
1515 int length = dimL * dimR;
1517 total += ( TwoSL + 1 ) * ddot_( &length, workmem, &inc, Tblock, &inc );
1524 total *= sqrt( 0.5 );
1529 double CheMPS2::ThreeDM::diagram4_5_6_7_8_9(
TensorT * denT,
Tensor3RDM * d3tens,
double * workmem,
const char type)
const{
1531 const int orb_i = denT->
gIndex();
1537 for (
int NL = book->
gNmin( orb_i ); NL <= book->
gNmax( orb_i ); NL++ ){
1538 for (
int TwoSL = book->
gTwoSmin( orb_i, NL ); TwoSL <= book->
gTwoSmax( orb_i, NL ); TwoSL+=2 ){
1541 int dimLup = book->
gCurrentDim( orb_i, NL, TwoSL, IL );
1547 for (
int TwoSLprime = TwoSL-1; TwoSLprime <= TwoSL+1; TwoSLprime+=2 ){
1549 int dimR = book->
gCurrentDim( orb_i+1, NL+1, TwoSLprime, ILdown );
1550 int dimLdown = book->
gCurrentDim( orb_i, NL-1, TwoSLprime, ILdown );
1552 if (( dimLdown > 0 ) && ( dimR > 0 )){
1554 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL+1, TwoSLprime, ILdown );
1555 double * Tdown = denT->
gStorage( NL-1, TwoSLprime, ILdown, NL+1, TwoSLprime, ILdown );
1556 double * block = d3tens->
gStorage( NL-1, TwoSLprime, ILdown, NL, TwoSL, IL );
1561 dgemm_( ¬rans, ¬rans, &dimLdown, &dimR, &dimLup, &alpha, block, &dimLdown, Tup, &dimLup, &beta, workmem, &dimLdown );
1563 int length = dimLdown * dimR;
1565 const double factor = ((type ==
'D') ? ( sqrt( 0.5 * ( d3tens->
get_two_j1() + 1 ) ) * ( TwoSLprime + 1 ) )
1567 * sqrt( 0.5 * ( d3tens->
get_two_j1() + 1 ) * ( TwoSL + 1 ) * ( TwoSLprime + 1 ) ) ));
1568 total += factor * ddot_( &length, workmem, &inc, Tdown, &inc );
1581 double CheMPS2::ThreeDM::diagram10(
TensorT * denT,
TensorS0 * denS0,
TensorL * denL,
double * workmem,
double * workmem2)
const{
1583 const int orb_i = denT->
gIndex();
1588 for (
int NL = book->
gNmin( orb_i ); NL <= book->
gNmax( orb_i ); NL++ ){
1589 for (
int TwoSL = book->
gTwoSmin( orb_i, NL ); TwoSL <= book->
gTwoSmax( orb_i, NL ); TwoSL+=2 ){
1595 int dimLup = book->
gCurrentDim( orb_i, NL, TwoSL, IL );
1596 int dimLdown = book->
gCurrentDim( orb_i, NL-2, TwoSL, ILxIixIl );
1597 int dimRdown = book->
gCurrentDim( orb_i+1, NL, TwoSL, ILxIixIl );
1599 if (( dimLup > 0 ) && ( dimLdown > 0 ) && ( dimRdown > 0 )){
1601 double * Tdown = denT->
gStorage( NL-2, TwoSL, ILxIixIl, NL, TwoSL, ILxIixIl );
1602 double * Sblock = denS0->
gStorage( NL-2, TwoSL, ILxIixIl, NL, TwoSL, IL );
1604 for (
int TwoSR = TwoSL-1; TwoSR <= TwoSL+1; TwoSR+=2 ){
1606 int dimRup = book->
gCurrentDim( orb_i+1, NL+1, TwoSR, ILxIi );
1610 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL+1, TwoSR, ILxIi );
1611 double * Lblock = denL->
gStorage( NL, TwoSL, ILxIixIl, NL+1, TwoSR, ILxIi );
1617 dgemm_( ¬rans, ¬rans, &dimLdown, &dimRup, &dimLup, &alpha, Sblock, &dimLdown, Tup, &dimLup, &beta, workmem, &dimLdown );
1618 dgemm_( ¬rans, &trans, &dimLdown, &dimRdown, &dimRup, &alpha, workmem, &dimLdown, Lblock, &dimRdown, &beta, workmem2, &dimLdown );
1620 int length = dimLdown * dimRdown;
1622 total -= ( TwoSR + 1 ) * ddot_( &length, workmem2, &inc, Tdown, &inc );
1631 total *= sqrt( 0.5 );
1636 double CheMPS2::ThreeDM::diagram11(
TensorT * denT,
TensorS1 * denS1,
TensorL * denL,
double * workmem,
double * workmem2)
const{
1638 const int orb_i = denT->
gIndex();
1643 for (
int NL = book->
gNmin( orb_i ); NL <= book->
gNmax( orb_i ); NL++ ){
1644 for (
int TwoSL = book->
gTwoSmin( orb_i, NL ); TwoSL <= book->
gTwoSmax( orb_i, NL ); TwoSL+=2 ){
1650 int dimLup = book->
gCurrentDim( orb_i, NL, TwoSL, IL );
1654 for (
int TwoSLprime = TwoSL-2; TwoSLprime <= TwoSL+2; TwoSLprime+=2 ){
1656 int dimLdown = book->
gCurrentDim( orb_i, NL-2, TwoSLprime, ILxIixIl );
1657 int dimRdown = book->
gCurrentDim( orb_i+1, NL, TwoSLprime, ILxIixIl );
1659 if (( dimLdown > 0 ) && ( dimRdown > 0 )){
1661 double * Tdown = denT->
gStorage( NL-2, TwoSLprime, ILxIixIl, NL, TwoSLprime, ILxIixIl );
1662 double * Sblock = denS1->
gStorage( NL-2, TwoSLprime, ILxIixIl, NL, TwoSL, IL );
1664 for (
int TwoSR = TwoSL-1; TwoSR <= TwoSL+1; TwoSR+=2 ){
1666 int dimRup = book->
gCurrentDim( orb_i+1, NL+1, TwoSR, ILxIi );
1668 if (( dimRup > 0 ) && ( abs( TwoSLprime - TwoSR ) == 1 )){
1670 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL+1, TwoSR, ILxIi );
1671 double * Lblock = denL->
gStorage( NL, TwoSLprime, ILxIixIl, NL+1, TwoSR, ILxIi );
1677 dgemm_( ¬rans, ¬rans, &dimLdown, &dimRup, &dimLup, &alpha, Sblock, &dimLdown, Tup, &dimLup, &beta, workmem, &dimLdown );
1678 dgemm_( ¬rans, &trans, &dimLdown, &dimRdown, &dimRup, &alpha, workmem, &dimLdown, Lblock, &dimRdown, &beta, workmem2, &dimLdown );
1680 int length = dimLdown * dimRdown;
1682 total += sqrt( 3.0 * ( TwoSL + 1 ) ) * ( TwoSR + 1 )
1685 * ddot_( &length, workmem2, &inc, Tdown, &inc );
1700 double CheMPS2::ThreeDM::diagram12(
TensorT * denT,
TensorF0 * denF0,
TensorL * denL,
double * workmem,
double * workmem2)
const{
1702 const int orb_i = denT->
gIndex();
1707 for (
int NL = book->
gNmin( orb_i ); NL <= book->
gNmax( orb_i ); NL++ ){
1708 for (
int TwoSL = book->
gTwoSmin( orb_i, NL ); TwoSL <= book->
gTwoSmax( orb_i, NL ); TwoSL+=2 ){
1714 int dimLup = book->
gCurrentDim( orb_i, NL, TwoSL, IL );
1715 int dimLdown = book->
gCurrentDim( orb_i, NL, TwoSL, ILxIixIl );
1716 int dimRdown = book->
gCurrentDim( orb_i+1, NL+2, TwoSL, ILxIixIl );
1718 if (( dimLup > 0 ) && ( dimLdown > 0 ) && ( dimRdown > 0 )){
1720 double * Tdown = denT->
gStorage( NL, TwoSL, ILxIixIl, NL+2, TwoSL, ILxIixIl );
1721 double * Fblock = denF0->
gStorage( NL, TwoSL, ILxIixIl, NL, TwoSL, IL );
1723 for (
int TwoSR = TwoSL-1; TwoSR <= TwoSL+1; TwoSR+=2 ){
1725 int dimRup = book->
gCurrentDim( orb_i+1, NL+1, TwoSR, ILxIi );
1729 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL+1, TwoSR, ILxIi );
1730 double * Lblock = denL->
gStorage( NL+1, TwoSR, ILxIi, NL+2, TwoSL, ILxIixIl );
1735 dgemm_( ¬rans, ¬rans, &dimLdown, &dimRup, &dimLup, &alpha, Fblock, &dimLdown, Tup, &dimLup, &beta, workmem, &dimLdown );
1736 dgemm_( ¬rans, ¬rans, &dimLdown, &dimRdown, &dimRup, &alpha, workmem, &dimLdown, Lblock, &dimRup, &beta, workmem2, &dimLdown );
1738 int length = dimLdown * dimRdown;
1740 total += sqrt( 0.5 * ( TwoSL + 1 ) * ( TwoSR + 1 ) )
1742 * ddot_( &length, workmem2, &inc, Tdown, &inc );
1755 double CheMPS2::ThreeDM::diagram13(
TensorT * denT,
TensorF1 * denF1,
TensorL * denL,
double * workmem,
double * workmem2)
const{
1757 const int orb_i = denT->
gIndex();
1762 for (
int NL = book->
gNmin( orb_i ); NL <= book->
gNmax( orb_i ); NL++ ){
1763 for (
int TwoSL = book->
gTwoSmin( orb_i, NL ); TwoSL <= book->
gTwoSmax( orb_i, NL ); TwoSL+=2 ){
1769 int dimLup = book->
gCurrentDim( orb_i, NL, TwoSL, IL );
1773 for (
int TwoSLprime = TwoSL-2; TwoSLprime <= TwoSL+2; TwoSLprime+=2 ){
1775 int dimLdown = book->
gCurrentDim( orb_i, NL, TwoSLprime, ILxIixIl );
1776 int dimRdown = book->
gCurrentDim( orb_i+1, NL+2, TwoSLprime, ILxIixIl );
1778 if (( dimLdown > 0 ) && ( dimRdown > 0 )){
1780 double * Tdown = denT->
gStorage( NL, TwoSLprime, ILxIixIl, NL+2, TwoSLprime, ILxIixIl );
1781 double * Fblock = denF1->
gStorage( NL, TwoSLprime, ILxIixIl, NL, TwoSL, IL );
1783 for (
int TwoSR = TwoSL-1; TwoSR <= TwoSL+1; TwoSR+=2 ){
1785 int dimRup = book->
gCurrentDim( orb_i+1, NL+1, TwoSR, ILxIi );
1787 if (( dimRup > 0 ) && ( abs( TwoSLprime - TwoSR ) == 1 )){
1789 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL+1, TwoSR, ILxIi );
1790 double * Lblock = denL->
gStorage( NL+1, TwoSR, ILxIi, NL+2, TwoSLprime, ILxIixIl );
1795 dgemm_( ¬rans, ¬rans, &dimLdown, &dimRup, &dimLup, &alpha, Fblock, &dimLdown, Tup, &dimLup, &beta, workmem, &dimLdown );
1796 dgemm_( ¬rans, ¬rans, &dimLdown, &dimRdown, &dimRup, &alpha, workmem, &dimLdown, Lblock, &dimRup, &beta, workmem2, &dimLdown );
1798 int length = dimLdown * dimRdown;
1800 total += sqrt( 3.0 * ( TwoSL + 1 ) * ( TwoSR + 1 ) * ( TwoSLprime + 1 ) )
1803 * ddot_( &length, workmem2, &inc, Tdown, &inc );
1818 double CheMPS2::ThreeDM::diagram14(
TensorT * denT,
TensorF0 * denF0,
TensorL * denL,
double * workmem,
double * workmem2)
const{
1820 const int orb_i = denT->
gIndex();
1825 for (
int NL = book->
gNmin( orb_i ); NL <= book->
gNmax( orb_i ); NL++ ){
1826 for (
int TwoSL = book->
gTwoSmin( orb_i, NL ); TwoSL <= book->
gTwoSmax( orb_i, NL ); TwoSL+=2 ){
1832 int dimLup = book->
gCurrentDim( orb_i, NL, TwoSL, IL );
1833 int dimLdown = book->
gCurrentDim( orb_i, NL, TwoSL, ILxIixIl );
1834 int dimRdown = book->
gCurrentDim( orb_i+1, NL+2, TwoSL, ILxIixIl );
1836 if (( dimLup > 0 ) && ( dimLdown > 0 ) && ( dimRdown > 0 )){
1838 double * Tdown = denT->
gStorage( NL, TwoSL, ILxIixIl, NL+2, TwoSL, ILxIixIl );
1839 double * Fblock = denF0->
gStorage( NL, TwoSL, IL, NL, TwoSL, ILxIixIl );
1841 for (
int TwoSR = TwoSL-1; TwoSR <= TwoSL+1; TwoSR+=2 ){
1843 int dimRup = book->
gCurrentDim( orb_i+1, NL+1, TwoSR, ILxIi );
1847 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL+1, TwoSR, ILxIi );
1848 double * Lblock = denL->
gStorage( NL+1, TwoSR, ILxIi, NL+2, TwoSL, ILxIixIl );
1854 dgemm_( &trans, ¬rans, &dimLdown, &dimRup, &dimLup, &alpha, Fblock, &dimLup, Tup, &dimLup, &beta, workmem, &dimLdown );
1855 dgemm_( ¬rans, ¬rans, &dimLdown, &dimRdown, &dimRup, &alpha, workmem, &dimLdown, Lblock, &dimRup, &beta, workmem2, &dimLdown );
1857 int length = dimLdown * dimRdown;
1859 total += sqrt( 0.5 * ( TwoSL + 1 ) * ( TwoSR + 1 ) )
1861 * ddot_( &length, workmem2, &inc, Tdown, &inc );
1874 double CheMPS2::ThreeDM::diagram15(
TensorT * denT,
TensorF1 * denF1,
TensorL * denL,
double * workmem,
double * workmem2)
const{
1876 const int orb_i = denT->
gIndex();
1881 for (
int NL = book->
gNmin( orb_i ); NL <= book->
gNmax( orb_i ); NL++ ){
1882 for (
int TwoSL = book->
gTwoSmin( orb_i, NL ); TwoSL <= book->
gTwoSmax( orb_i, NL ); TwoSL+=2 ){
1888 int dimLup = book->
gCurrentDim( orb_i, NL, TwoSL, IL );
1892 for (
int TwoSLprime = TwoSL-2; TwoSLprime <= TwoSL+2; TwoSLprime+=2 ){
1894 int dimLdown = book->
gCurrentDim( orb_i, NL, TwoSLprime, ILxIixIl );
1895 int dimRdown = book->
gCurrentDim( orb_i+1, NL+2, TwoSLprime, ILxIixIl );
1897 if (( dimLdown > 0 ) && ( dimRdown > 0 )){
1899 double * Tdown = denT->
gStorage( NL, TwoSLprime, ILxIixIl, NL+2, TwoSLprime, ILxIixIl );
1900 double * Fblock = denF1->
gStorage( NL, TwoSL, IL, NL, TwoSLprime, ILxIixIl );
1902 for (
int TwoSR = TwoSL-1; TwoSR <= TwoSL+1; TwoSR+=2 ){
1904 int dimRup = book->
gCurrentDim( orb_i+1, NL+1, TwoSR, ILxIi );
1906 if (( dimRup > 0 ) && ( abs( TwoSLprime - TwoSR ) == 1 )){
1908 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL+1, TwoSR, ILxIi );
1909 double * Lblock = denL->
gStorage( NL+1, TwoSR, ILxIi, NL+2, TwoSLprime, ILxIixIl );
1915 dgemm_( &trans, ¬rans, &dimLdown, &dimRup, &dimLup, &alpha, Fblock, &dimLup, Tup, &dimLup, &beta, workmem, &dimLdown );
1916 dgemm_( ¬rans, ¬rans, &dimLdown, &dimRdown, &dimRup, &alpha, workmem, &dimLdown, Lblock, &dimRup, &beta, workmem2, &dimLdown );
1918 int length = dimLdown * dimRdown;
1920 total += sqrt( 3.0 * ( TwoSR + 1 ) ) * ( TwoSLprime + 1 )
1923 * ddot_( &length, workmem2, &inc, Tdown, &inc );
1938 double CheMPS2::ThreeDM::diagram16(
TensorT * denT,
TensorL * denL,
TensorS0 * denS0,
double * workmem,
double * workmem2)
const{
1940 const int orb_i = denT->
gIndex();
1945 for (
int NL = book->
gNmin( orb_i ); NL <= book->
gNmax( orb_i ); NL++ ){
1946 for (
int TwoSL = book->
gTwoSmin( orb_i, NL ); TwoSL <= book->
gTwoSmax( orb_i, NL ); TwoSL+=2 ){
1952 int dimLup = book->
gCurrentDim( orb_i, NL, TwoSL, IL );
1956 for (
int TwoSLprime = TwoSL-1; TwoSLprime <= TwoSL+1; TwoSLprime+=2 ){
1958 int dimLdown = book->
gCurrentDim( orb_i, NL+1, TwoSLprime, ILxIj );
1959 int dimRdown = book->
gCurrentDim( orb_i+1, NL+3, TwoSLprime, ILxIj );
1960 int dimRup = book->
gCurrentDim( orb_i+1, NL+1, TwoSLprime, ILxIi );
1962 if (( dimRup > 0 ) && ( dimLdown > 0 ) && ( dimRdown > 0 )){
1964 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL+1, TwoSLprime, ILxIi );
1965 double * Tdown = denT->
gStorage( NL+1, TwoSLprime, ILxIj, NL+3, TwoSLprime, ILxIj );
1966 double * Sblock = denS0->
gStorage( NL+1, TwoSLprime, ILxIi, NL+3, TwoSLprime, ILxIj );
1967 double * Lblock = denL->
gStorage( NL, TwoSL, IL, NL+1, TwoSLprime, ILxIj );
1973 dgemm_( &trans, ¬rans, &dimLdown, &dimRup, &dimLup, &alpha, Lblock, &dimLup, Tup, &dimLup, &beta, workmem, &dimLdown );
1974 dgemm_( ¬rans, ¬rans, &dimLdown, &dimRdown, &dimRup, &alpha, workmem, &dimLdown, Sblock, &dimRup, &beta, workmem2, &dimLdown );
1976 int length = dimLdown * dimRdown;
1978 total -= ( TwoSLprime + 1 ) * ddot_( &length, workmem2, &inc, Tdown, &inc );
1987 total *= sqrt( 0.5 );
1992 double CheMPS2::ThreeDM::diagram17(
TensorT * denT,
TensorL * denL,
TensorS1 * denS1,
double * workmem,
double * workmem2)
const{
1994 const int orb_i = denT->
gIndex();
1999 for (
int NL = book->
gNmin( orb_i ); NL <= book->
gNmax( orb_i ); NL++ ){
2000 for (
int TwoSL = book->
gTwoSmin( orb_i, NL ); TwoSL <= book->
gTwoSmax( orb_i, NL ); TwoSL+=2 ){
2006 int dimLup = book->
gCurrentDim( orb_i, NL, TwoSL, IL );
2010 for (
int TwoSLprime = TwoSL-1; TwoSLprime <= TwoSL+1; TwoSLprime+=2 ){
2012 int dimLdown = book->
gCurrentDim( orb_i, NL+1, TwoSLprime, ILxIj );
2013 int dimRdown = book->
gCurrentDim( orb_i+1, NL+3, TwoSLprime, ILxIj );
2015 if (( dimLdown > 0 ) && ( dimRdown > 0 )){
2017 double * Tdown = denT->
gStorage( NL+1, TwoSLprime, ILxIj, NL+3, TwoSLprime, ILxIj );
2018 double * Lblock = denL->
gStorage( NL, TwoSL, IL, NL+1, TwoSLprime, ILxIj );
2020 for (
int TwoSR = TwoSL-1; TwoSR <= TwoSL+1; TwoSR+=2 ){
2022 int dimRup = book->
gCurrentDim( orb_i+1, NL+1, TwoSR, ILxIi );
2026 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL+1, TwoSR, ILxIi );
2027 double * Sblock = denS1->
gStorage( NL+1, TwoSR, ILxIi, NL+3, TwoSLprime, ILxIj );
2033 dgemm_( &trans, ¬rans, &dimLdown, &dimRup, &dimLup, &alpha, Lblock, &dimLup, Tup, &dimLup, &beta, workmem, &dimLdown );
2034 dgemm_( ¬rans, ¬rans, &dimLdown, &dimRdown, &dimRup, &alpha, workmem, &dimLdown, Sblock, &dimRup, &beta, workmem2, &dimLdown );
2036 int length = dimLdown * dimRdown;
2038 total += sqrt( 3.0 * ( TwoSR + 1 ) ) * ( TwoSLprime + 1 )
2041 * ddot_( &length, workmem2, &inc, Tdown, &inc );
2056 double CheMPS2::ThreeDM::diagram18(
TensorT * denT,
TensorL * denL,
TensorF0 * denF0,
double * workmem,
double * workmem2)
const{
2058 const int orb_i = denT->
gIndex();
2063 for (
int NL = book->
gNmin( orb_i ); NL <= book->
gNmax( orb_i ); NL++ ){
2064 for (
int TwoSL = book->
gTwoSmin( orb_i, NL ); TwoSL <= book->
gTwoSmax( orb_i, NL ); TwoSL+=2 ){
2070 int dimLup = book->
gCurrentDim( orb_i, NL, TwoSL, IL );
2074 for (
int TwoSLprime = TwoSL-1; TwoSLprime <= TwoSL+1; TwoSLprime+=2 ){
2076 int dimLdown = book->
gCurrentDim( orb_i, NL-1, TwoSLprime, ILxIj );
2077 int dimRdown = book->
gCurrentDim( orb_i+1, NL+1, TwoSLprime, ILxIj );
2078 int dimRup = book->
gCurrentDim( orb_i+1, NL+1, TwoSLprime, ILxIi );
2080 if (( dimRup > 0 ) && ( dimLdown > 0 ) && ( dimRdown > 0 )){
2082 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL+1, TwoSLprime, ILxIi );
2083 double * Tdown = denT->
gStorage( NL-1, TwoSLprime, ILxIj, NL+1, TwoSLprime, ILxIj );
2084 double * Fblock = denF0->
gStorage( NL+1, TwoSLprime, ILxIj, NL+1, TwoSLprime, ILxIi );
2085 double * Lblock = denL->
gStorage( NL-1, TwoSLprime, ILxIj, NL, TwoSL, IL );
2091 dgemm_( ¬rans, ¬rans, &dimLdown, &dimRup, &dimLup, &alpha, Lblock, &dimLdown, Tup, &dimLup, &beta, workmem, &dimLdown );
2092 dgemm_( ¬rans, &trans, &dimLdown, &dimRdown, &dimRup, &alpha, workmem, &dimLdown, Fblock, &dimRdown, &beta, workmem2, &dimLdown );
2094 int length = dimLdown * dimRdown;
2096 total += sqrt( 0.5 * ( TwoSL + 1 ) * ( TwoSLprime + 1 ) )
2098 * ddot_( &length, workmem2, &inc, Tdown, &inc );
2111 double CheMPS2::ThreeDM::diagram19(
TensorT * denT,
TensorL * denL,
TensorF1 * denF1,
double * workmem,
double * workmem2)
const{
2113 const int orb_i = denT->
gIndex();
2118 for (
int NL = book->
gNmin( orb_i ); NL <= book->
gNmax( orb_i ); NL++ ){
2119 for (
int TwoSL = book->
gTwoSmin( orb_i, NL ); TwoSL <= book->
gTwoSmax( orb_i, NL ); TwoSL+=2 ){
2125 int dimLup = book->
gCurrentDim( orb_i, NL, TwoSL, IL );
2129 for (
int TwoSLprime = TwoSL-1; TwoSLprime <= TwoSL+1; TwoSLprime+=2 ){
2131 int dimLdown = book->
gCurrentDim( orb_i, NL-1, TwoSLprime, ILxIj );
2132 int dimRdown = book->
gCurrentDim( orb_i+1, NL+1, TwoSLprime, ILxIj );
2134 if (( dimLdown > 0 ) && ( dimRdown > 0 )){
2136 double * Tdown = denT->
gStorage( NL-1, TwoSLprime, ILxIj, NL+1, TwoSLprime, ILxIj );
2137 double * Lblock = denL->
gStorage( NL-1, TwoSLprime, ILxIj, NL, TwoSL, IL );
2139 for (
int TwoSR = TwoSL-1; TwoSR <= TwoSL+1; TwoSR+=2 ){
2141 int dimRup = book->
gCurrentDim( orb_i+1, NL+1, TwoSR, ILxIi );
2145 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL+1, TwoSR, ILxIi );
2146 double * Fblock = denF1->
gStorage( NL+1, TwoSLprime, ILxIj, NL+1, TwoSR, ILxIi );
2152 dgemm_( ¬rans, ¬rans, &dimLdown, &dimRup, &dimLup, &alpha, Lblock, &dimLdown, Tup, &dimLup, &beta, workmem, &dimLdown );
2153 dgemm_( ¬rans, &trans, &dimLdown, &dimRdown, &dimRup, &alpha, workmem, &dimLdown, Fblock, &dimRdown, &beta, workmem2, &dimLdown );
2155 int length = dimLdown * dimRdown;
2157 total += sqrt( 3.0 * ( TwoSL + 1 ) * ( TwoSLprime + 1 ) * ( TwoSR + 1 ) )
2160 * ddot_( &length, workmem2, &inc, Tdown, &inc );
2175 double CheMPS2::ThreeDM::diagram20(
TensorT * denT,
TensorL * denL,
TensorF0 * denF0,
double * workmem,
double * workmem2)
const{
2177 const int orb_i = denT->
gIndex();
2182 for (
int NL = book->
gNmin( orb_i ); NL <= book->
gNmax( orb_i ); NL++ ){
2183 for (
int TwoSL = book->
gTwoSmin( orb_i, NL ); TwoSL <= book->
gTwoSmax( orb_i, NL ); TwoSL+=2 ){
2189 int dimLup = book->
gCurrentDim( orb_i, NL, TwoSL, IL );
2193 for (
int TwoSLprime = TwoSL-1; TwoSLprime <= TwoSL+1; TwoSLprime+=2 ){
2195 int dimLdown = book->
gCurrentDim( orb_i, NL-1, TwoSLprime, ILxIj );
2196 int dimRdown = book->
gCurrentDim( orb_i+1, NL+1, TwoSLprime, ILxIj );
2197 int dimRup = book->
gCurrentDim( orb_i+1, NL+1, TwoSLprime, ILxIi );
2199 if (( dimRup > 0 ) && ( dimLdown > 0 ) && ( dimRdown > 0 )){
2201 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL+1, TwoSLprime, ILxIi );
2202 double * Tdown = denT->
gStorage( NL-1, TwoSLprime, ILxIj, NL+1, TwoSLprime, ILxIj );
2203 double * Fblock = denF0->
gStorage( NL+1, TwoSLprime, ILxIi, NL+1, TwoSLprime, ILxIj );
2204 double * Lblock = denL->
gStorage( NL-1, TwoSLprime, ILxIj, NL, TwoSL, IL );
2209 dgemm_( ¬rans, ¬rans, &dimLdown, &dimRup, &dimLup, &alpha, Lblock, &dimLdown, Tup, &dimLup, &beta, workmem, &dimLdown );
2210 dgemm_( ¬rans, ¬rans, &dimLdown, &dimRdown, &dimRup, &alpha, workmem, &dimLdown, Fblock, &dimRup, &beta, workmem2, &dimLdown );
2212 int length = dimLdown * dimRdown;
2214 total += sqrt( 0.5 * ( TwoSL + 1 ) * ( TwoSLprime + 1 ) )
2216 * ddot_( &length, workmem2, &inc, Tdown, &inc );
2229 double CheMPS2::ThreeDM::diagram21(
TensorT * denT,
TensorL * denL,
TensorF1 * denF1,
double * workmem,
double * workmem2)
const{
2231 const int orb_i = denT->
gIndex();
2236 for (
int NL = book->
gNmin( orb_i ); NL <= book->
gNmax( orb_i ); NL++ ){
2237 for (
int TwoSL = book->
gTwoSmin( orb_i, NL ); TwoSL <= book->
gTwoSmax( orb_i, NL ); TwoSL+=2 ){
2243 int dimLup = book->
gCurrentDim( orb_i, NL, TwoSL, IL );
2247 for (
int TwoSLprime = TwoSL-1; TwoSLprime <= TwoSL+1; TwoSLprime+=2 ){
2249 int dimLdown = book->
gCurrentDim( orb_i, NL-1, TwoSLprime, ILxIj );
2250 int dimRdown = book->
gCurrentDim( orb_i+1, NL+1, TwoSLprime, ILxIj );
2252 if (( dimLdown > 0 ) && ( dimRdown > 0 )){
2254 double * Tdown = denT->
gStorage( NL-1, TwoSLprime, ILxIj, NL+1, TwoSLprime, ILxIj );
2255 double * Lblock = denL->
gStorage( NL-1, TwoSLprime, ILxIj, NL, TwoSL, IL );
2257 for (
int TwoSR = TwoSL-1; TwoSR <= TwoSL+1; TwoSR+=2 ){
2259 int dimRup = book->
gCurrentDim( orb_i+1, NL+1, TwoSR, ILxIi );
2263 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL+1, TwoSR, ILxIi );
2264 double * Fblock = denF1->
gStorage( NL+1, TwoSR, ILxIi, NL+1, TwoSLprime, ILxIj );
2269 dgemm_( ¬rans, ¬rans, &dimLdown, &dimRup, &dimLup, &alpha, Lblock, &dimLdown, Tup, &dimLup, &beta, workmem, &dimLdown );
2270 dgemm_( ¬rans, ¬rans, &dimLdown, &dimRdown, &dimRup, &alpha, workmem, &dimLdown, Fblock, &dimRup, &beta, workmem2, &dimLdown );
2272 int length = dimLdown * dimRdown;
2274 total += sqrt( 3.0 * ( TwoSL + 1 ) ) * ( TwoSR + 1 )
2277 * ddot_( &length, workmem2, &inc, Tdown, &inc );
2294 const int orb_i = denT->
gIndex();
2296 assert( tofill->
get_irrep() == ImxInxIi );
2302 for (
int NL = book->
gNmin( orb_i ); NL <= book->
gNmax( orb_i ); NL++ ){
2303 for (
int TwoSL = book->
gTwoSmin( orb_i, NL ); TwoSL <= book->
gTwoSmax( orb_i, NL ); TwoSL+=2 ){
2310 for (
int TwoSLprime = TwoSL-1; TwoSLprime <= TwoSL+1; TwoSLprime+=2 ){
2312 int dimLup = book->
gCurrentDim( orb_i, NL, TwoSL, IL );
2313 int dimLdown = book->
gCurrentDim( orb_i, NL-3, TwoSLprime, ILxImxInxIi );
2315 if (( dimLup > 0 ) && ( dimLdown > 0 )){
2317 int dimRup = book->
gCurrentDim( orb_i+1, NL, TwoSL, IL );
2318 int dimRdown = book->
gCurrentDim( orb_i+1, NL-2, TwoSL, ILxImxIn );
2320 if (( dimRup > 0 ) && ( dimRdown > 0 )){
2322 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL, TwoSL, IL );
2323 double * Tdown = denT->
gStorage( NL-3, TwoSLprime, ILxImxInxIi, NL-2, TwoSL, ILxImxIn );
2324 double * Sblock = denS0->
gStorage( NL-2, TwoSL, ILxImxIn, NL, TwoSL, IL );
2325 double * Wblock = tofill->
gStorage( NL-3, TwoSLprime, ILxImxInxIi, NL, TwoSL, IL );
2329 double alpha = -0.5 * ( TwoSL + 1 );
2331 dgemm_( ¬rans, ¬rans, &dimLdown, &dimRup, &dimRdown, &alpha, Tdown, &dimLdown, Sblock, &dimRdown, &beta, workmem, &dimLdown );
2334 dgemm_( ¬rans, &trans, &dimLdown, &dimLup, &dimRup, &alpha, workmem, &dimLdown, Tup, &dimLup, &beta, Wblock, &dimLdown );
2338 dimRup = book->
gCurrentDim( orb_i+1, NL+1, TwoSLprime, ILxIi );
2339 dimRdown = book->
gCurrentDim( orb_i+1, NL-1, TwoSLprime, ILxImxInxIi );
2341 if (( dimRup > 0 ) && ( dimRdown > 0 )){
2343 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL+1, TwoSLprime, ILxIi );
2344 double * Tdown = denT->
gStorage( NL-3, TwoSLprime, ILxImxInxIi, NL-1, TwoSLprime, ILxImxInxIi );
2345 double * Sblock = denS0->
gStorage( NL-1, TwoSLprime, ILxImxInxIi, NL+1, TwoSLprime, ILxIi );
2346 double * Wblock = tofill->
gStorage( NL-3, TwoSLprime, ILxImxInxIi, NL, TwoSL, IL );
2350 double alpha = 0.5 * sqrt( 1.0 * ( TwoSL + 1 ) * ( TwoSLprime + 1 ) ) *
Special::phase( TwoSL + 1 - TwoSLprime );
2352 dgemm_( ¬rans, ¬rans, &dimLdown, &dimRup, &dimRdown, &alpha, Tdown, &dimLdown, Sblock, &dimRdown, &beta, workmem, &dimLdown );
2355 dgemm_( ¬rans, &trans, &dimLdown, &dimLup, &dimRup, &alpha, workmem, &dimLdown, Tup, &dimLup, &beta, Wblock, &dimLdown );
2368 const int orb_i = denT->
gIndex();
2370 assert( tofill->
get_irrep() == ImxInxIi );
2376 for (
int NL = book->
gNmin( orb_i ); NL <= book->
gNmax( orb_i ); NL++ ){
2377 for (
int TwoSL = book->
gTwoSmin( orb_i, NL ); TwoSL <= book->
gTwoSmax( orb_i, NL ); TwoSL+=2 ){
2384 for (
int TwoSLprime = TwoSL-1; TwoSLprime <= TwoSL+1; TwoSLprime+=2 ){
2386 int dimLup = book->
gCurrentDim( orb_i, NL, TwoSL, IL );
2387 int dimLdown = book->
gCurrentDim( orb_i, NL+1, TwoSLprime, ILxImxInxIi );
2389 if (( dimLup > 0 ) && ( dimLdown > 0 )){
2391 int dimRup = book->
gCurrentDim( orb_i+1, NL, TwoSL, IL );
2392 int dimRdown = book->
gCurrentDim( orb_i+1, NL+2, TwoSL, ILxImxIn );
2394 if (( dimRup > 0 ) && ( dimRdown > 0 )){
2396 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL, TwoSL, IL );
2397 double * Tdown = denT->
gStorage( NL+1, TwoSLprime, ILxImxInxIi, NL+2, TwoSL, ILxImxIn );
2398 double * Sblock = denS0->
gStorage( NL, TwoSL, IL, NL+2, TwoSL, ILxImxIn );
2399 double * Wblock = tofill->
gStorage( NL, TwoSL, IL, NL+1, TwoSLprime, ILxImxInxIi );
2403 double alpha = 0.5 * sqrt( 1.0 * ( TwoSL + 1 ) * ( TwoSLprime + 1 ) ) *
Special::phase( TwoSL + 1 - TwoSLprime );
2405 dgemm_( ¬rans, ¬rans, &dimLup, &dimRdown, &dimRup, &alpha, Tup, &dimLup, Sblock, &dimRup, &beta, workmem, &dimLup );
2408 dgemm_( ¬rans, &trans, &dimLup, &dimLdown, &dimRdown, &alpha, workmem, &dimLup, Tdown, &dimLdown, &beta, Wblock, &dimLup );
2412 dimRup = book->
gCurrentDim( orb_i+1, NL+1, TwoSLprime, ILxIi );
2413 dimRdown = book->
gCurrentDim( orb_i+1, NL+3, TwoSLprime, ILxImxInxIi );
2415 if (( dimRup > 0 ) && ( dimRdown > 0 )){
2417 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL+1, TwoSLprime, ILxIi );
2418 double * Tdown = denT->
gStorage( NL+1, TwoSLprime, ILxImxInxIi, NL+3, TwoSLprime, ILxImxInxIi );
2419 double * Sblock = denS0->
gStorage( NL+1, TwoSLprime, ILxIi , NL+3, TwoSLprime, ILxImxInxIi );
2420 double * Wblock = tofill->
gStorage( NL, TwoSL, IL, NL+1, TwoSLprime, ILxImxInxIi );
2424 double alpha = - 0.5 * ( TwoSLprime + 1 );
2426 dgemm_( ¬rans, ¬rans, &dimLup, &dimRdown, &dimRup, &alpha, Tup, &dimLup, Sblock, &dimRup, &beta, workmem, &dimLup );
2429 dgemm_( ¬rans, &trans, &dimLup, &dimLdown, &dimRdown, &alpha, workmem, &dimLup, Tdown, &dimLdown, &beta, Wblock, &dimLup );
2442 const int orb_i = denT->
gIndex();
2450 for (
int NL = book->
gNmin( orb_i ); NL <= book->
gNmax( orb_i ); NL++ ){
2451 for (
int TwoSL = book->
gTwoSmin( orb_i, NL ); TwoSL <= book->
gTwoSmax( orb_i, NL ); TwoSL+=2 ){
2458 for (
int TwoSLprime = TwoSL-3; TwoSLprime <= TwoSL+3; TwoSLprime+=2 ){
2460 int dimLup = book->
gCurrentDim( orb_i, NL, TwoSL, IL );
2461 int dimLdown = book->
gCurrentDim( orb_i, NL-3, TwoSLprime, ILxImxInxIi );
2463 if (( dimLup > 0 ) && ( dimLdown > 0 )){
2465 for (
int TwoSRprime = TwoSLprime-1; TwoSRprime <= TwoSLprime+1; TwoSRprime+=2 ){
2467 int dimRup = book->
gCurrentDim( orb_i+1, NL, TwoSL, IL );
2468 int dimRdown = book->
gCurrentDim( orb_i+1, NL-2, TwoSRprime, ILxImxIn );
2470 if (( dimRup > 0 ) && ( dimRdown > 0 ) && ( abs( TwoSL - TwoSRprime ) <= 2 )){
2472 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL, TwoSL, IL );
2473 double * Tdown = denT->
gStorage( NL-3, TwoSLprime, ILxImxInxIi, NL-2, TwoSRprime, ILxImxIn );
2474 double * Sblock = denS1->
gStorage( NL-2, TwoSRprime, ILxImxIn, NL, TwoSL, IL );
2480 dgemm_( ¬rans, ¬rans, &dimLdown, &dimRup, &dimRdown, &alpha, Tdown, &dimLdown, Sblock, &dimRdown, &beta, workmem, &dimLdown );
2481 dgemm_( ¬rans, &trans, &dimLdown, &dimLup, &dimRup, &alpha, workmem, &dimLdown, Tup, &dimLup, &beta, workmem2, &dimLdown );
2483 if ( abs( TwoSL - TwoSLprime ) == 1 ){
2485 double * Wblock = doublet->
gStorage( NL-3, TwoSLprime, ILxImxInxIi, NL, TwoSL, IL );
2486 double prefactor = sqrt( 0.5 * ( TwoSRprime + 1 ) ) * ( TwoSL + 1 )
2489 int length = dimLup * dimLdown;
2491 daxpy_( &length, &prefactor, workmem2, &inc, Wblock, &inc );
2496 double * Wblock = quartet->
gStorage( NL-3, TwoSLprime, ILxImxInxIi, NL, TwoSL, IL );
2497 double prefactor = 2 * sqrt( TwoSRprime + 1.0 ) * ( TwoSL + 1 )
2500 int length = dimLup * dimLdown;
2502 daxpy_( &length, &prefactor, workmem2, &inc, Wblock, &inc );
2508 for (
int TwoSR = TwoSL-1; TwoSR <= TwoSL+1; TwoSR+=2 ){
2510 int dimRup = book->
gCurrentDim( orb_i+1, NL+1, TwoSR, ILxIi );
2511 int dimRdown = book->
gCurrentDim( orb_i+1, NL-1, TwoSLprime, ILxImxInxIi );
2513 if (( dimRup > 0 ) && ( dimRdown > 0 ) && ( abs( TwoSLprime - TwoSR ) <= 2 )){
2515 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL+1, TwoSR, ILxIi );
2516 double * Tdown = denT->
gStorage( NL-3, TwoSLprime, ILxImxInxIi, NL-1, TwoSLprime, ILxImxInxIi );
2517 double * Sblock = denS1->
gStorage( NL-1, TwoSLprime, ILxImxInxIi, NL+1, TwoSR, ILxIi );
2523 dgemm_( ¬rans, ¬rans, &dimLdown, &dimRup, &dimRdown, &alpha, Tdown, &dimLdown, Sblock, &dimRdown, &beta, workmem, &dimLdown );
2524 dgemm_( ¬rans, &trans, &dimLdown, &dimLup, &dimRup, &alpha, workmem, &dimLdown, Tup, &dimLup, &beta, workmem2, &dimLdown );
2526 if ( abs( TwoSL - TwoSLprime ) == 1 ){
2528 double * Wblock = doublet->
gStorage( NL-3, TwoSLprime, ILxImxInxIi, NL, TwoSL, IL );
2529 double prefactor = sqrt( 0.5 * ( TwoSL + 1 ) ) * ( TwoSR + 1 )
2532 int length = dimLup * dimLdown;
2534 daxpy_( &length, &prefactor, workmem2, &inc, Wblock, &inc );
2539 double * Wblock = quartet->
gStorage( NL-3, TwoSLprime, ILxImxInxIi, NL, TwoSL, IL );
2540 double prefactor = 2 * sqrt( TwoSL + 1.0 ) * ( TwoSR + 1 )
2543 int length = dimLup * dimLdown;
2545 daxpy_( &length, &prefactor, workmem2, &inc, Wblock, &inc );
2561 const int orb_i = denT->
gIndex();
2569 for (
int NL = book->
gNmin( orb_i ); NL <= book->
gNmax( orb_i ); NL++ ){
2570 for (
int TwoSL = book->
gTwoSmin( orb_i, NL ); TwoSL <= book->
gTwoSmax( orb_i, NL ); TwoSL+=2 ){
2577 for (
int TwoSLprime = TwoSL-3; TwoSLprime <= TwoSL+3; TwoSLprime+=2 ){
2579 int dimLup = book->
gCurrentDim( orb_i, NL, TwoSL, IL );
2580 int dimLdown = book->
gCurrentDim( orb_i, NL+1, TwoSLprime, ILxImxInxIi );
2582 if (( dimLup > 0 ) && ( dimLdown > 0 )){
2584 for (
int TwoSRprime = TwoSLprime-1; TwoSRprime <= TwoSLprime+1; TwoSRprime+=2 ){
2586 int dimRup = book->
gCurrentDim( orb_i+1, NL, TwoSL, IL );
2587 int dimRdown = book->
gCurrentDim( orb_i+1, NL+2, TwoSRprime, ILxImxIn );
2589 if (( dimRup > 0 ) && ( dimRdown > 0 ) && ( abs( TwoSL - TwoSRprime ) <= 2 )){
2591 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL, TwoSL, IL );
2592 double * Tdown = denT->
gStorage( NL+1, TwoSLprime, ILxImxInxIi, NL+2, TwoSRprime, ILxImxIn );
2593 double * Sblock = denS1->
gStorage( NL, TwoSL, IL, NL+2, TwoSRprime, ILxImxIn );
2599 dgemm_( ¬rans, ¬rans, &dimLup, &dimRdown, &dimRup, &alpha, Tup, &dimLup, Sblock, &dimRup, &beta, workmem, &dimLup );
2600 dgemm_( ¬rans, &trans, &dimLup, &dimLdown, &dimRdown, &alpha, workmem, &dimLup, Tdown, &dimLdown, &beta, workmem2, &dimLup );
2602 if ( abs( TwoSL - TwoSLprime ) == 1 ){
2604 double * Wblock = doublet->
gStorage( NL, TwoSL, IL, NL+1, TwoSLprime, ILxImxInxIi );
2605 double prefactor = sqrt( 0.5 * ( TwoSLprime + 1 ) ) * ( TwoSRprime + 1 )
2608 int length = dimLup * dimLdown;
2610 daxpy_( &length, &prefactor, workmem2, &inc, Wblock, &inc );
2615 double * Wblock = quartet->
gStorage( NL, TwoSL, IL, NL+1, TwoSLprime, ILxImxInxIi );
2616 double prefactor = sqrt( TwoSLprime + 1.0 ) * ( TwoSRprime + 1 )
2619 int length = dimLup * dimLdown;
2621 daxpy_( &length, &prefactor, workmem2, &inc, Wblock, &inc );
2627 for (
int TwoSR = TwoSL-1; TwoSR <= TwoSL+1; TwoSR+=2 ){
2629 int dimRup = book->
gCurrentDim( orb_i+1, NL+1, TwoSR, ILxIi );
2630 int dimRdown = book->
gCurrentDim( orb_i+1, NL+3, TwoSLprime, ILxImxInxIi );
2632 if (( dimRup > 0 ) && ( dimRdown > 0 ) && ( abs( TwoSLprime - TwoSR ) <= 2 )){
2634 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL+1, TwoSR, ILxIi );
2635 double * Tdown = denT->
gStorage( NL+1, TwoSLprime, ILxImxInxIi, NL+3, TwoSLprime, ILxImxInxIi );
2636 double * Sblock = denS1->
gStorage( NL+1, TwoSR, ILxIi , NL+3, TwoSLprime, ILxImxInxIi );
2642 dgemm_( ¬rans, ¬rans, &dimLup, &dimRdown, &dimRup, &alpha, Tup, &dimLup, Sblock, &dimRup, &beta, workmem, &dimLup );
2643 dgemm_( ¬rans, &trans, &dimLup, &dimLdown, &dimRdown, &alpha, workmem, &dimLup, Tdown, &dimLdown, &beta, workmem2, &dimLup );
2645 if ( abs( TwoSL - TwoSLprime ) == 1 ){
2647 double * Wblock = doublet->
gStorage( NL, TwoSL, IL, NL+1, TwoSLprime, ILxImxInxIi );
2648 double prefactor = sqrt( 0.5 * ( TwoSR + 1 ) ) * ( TwoSLprime + 1 )
2651 int length = dimLup * dimLdown;
2653 daxpy_( &length, &prefactor, workmem2, &inc, Wblock, &inc );
2658 double * Wblock = quartet->
gStorage( NL, TwoSL, IL, NL+1, TwoSLprime, ILxImxInxIi );
2659 double prefactor = sqrt( TwoSR + 1.0 ) * ( TwoSLprime + 1 )
2662 int length = dimLup * dimLdown;
2664 daxpy_( &length, &prefactor, workmem2, &inc, Wblock, &inc );
2680 const int orb_i = denT->
gIndex();
2682 assert( tofill->
get_irrep() == ImxInxIi );
2688 for (
int NL = book->
gNmin( orb_i ); NL <= book->
gNmax( orb_i ); NL++ ){
2689 for (
int TwoSL = book->
gTwoSmin( orb_i, NL ); TwoSL <= book->
gTwoSmax( orb_i, NL ); TwoSL+=2 ){
2696 for (
int TwoSLprime = TwoSL-1; TwoSLprime <= TwoSL+1; TwoSLprime+=2 ){
2698 int dimLup = book->
gCurrentDim( orb_i, NL, TwoSL, IL );
2699 int dimLdown = book->
gCurrentDim( orb_i, NL-1, TwoSLprime, ILxImxInxIi );
2701 if (( dimLup > 0 ) && ( dimLdown > 0 )){
2703 int dimRup = book->
gCurrentDim( orb_i+1, NL, TwoSL, IL );
2704 int dimRdown = book->
gCurrentDim( orb_i+1, NL, TwoSL, ILxImxIn );
2706 if (( dimRup > 0 ) && ( dimRdown > 0 )){
2708 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL, TwoSL, IL );
2709 double * Tdown = denT->
gStorage( NL-1, TwoSLprime, ILxImxInxIi, NL, TwoSL, ILxImxIn );
2710 double * Fblock = denF0->
gStorage( NL, TwoSL, ILxImxIn, NL, TwoSL, IL );
2711 double * Wblock = tofill->
gStorage( NL-1, TwoSLprime, ILxImxInxIi, NL, TwoSL, IL );
2715 double alpha = 0.5 * ( TwoSL + 1 );
2717 dgemm_( ¬rans, ¬rans, &dimLdown, &dimRup, &dimRdown, &alpha, Tdown, &dimLdown, Fblock, &dimRdown, &beta, workmem, &dimLdown );
2720 dgemm_( ¬rans, &trans, &dimLdown, &dimLup, &dimRup, &alpha, workmem, &dimLdown, Tup, &dimLup, &beta, Wblock, &dimLdown );
2724 dimRup = book->
gCurrentDim( orb_i+1, NL+1, TwoSLprime, ILxIi );
2725 dimRdown = book->
gCurrentDim( orb_i+1, NL+1, TwoSLprime, ILxImxInxIi );
2727 if (( dimRup > 0 ) && ( dimRdown > 0 )){
2729 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL+1, TwoSLprime, ILxIi );
2730 double * Tdown = denT->
gStorage( NL-1, TwoSLprime, ILxImxInxIi, NL+1, TwoSLprime, ILxImxInxIi );
2731 double * Fblock = denF0->
gStorage( NL+1, TwoSLprime, ILxImxInxIi, NL+1, TwoSLprime, ILxIi );
2732 double * Wblock = tofill->
gStorage( NL-1, TwoSLprime, ILxImxInxIi, NL, TwoSL, IL );
2736 double alpha = 0.5 * sqrt( 1.0 * ( TwoSL + 1 ) * ( TwoSLprime + 1 ) ) *
Special::phase( TwoSLprime + 1 - TwoSL );
2738 dgemm_( ¬rans, ¬rans, &dimLdown, &dimRup, &dimRdown, &alpha, Tdown, &dimLdown, Fblock, &dimRdown, &beta, workmem, &dimLdown );
2741 dgemm_( ¬rans, &trans, &dimLdown, &dimLup, &dimRup, &alpha, workmem, &dimLdown, Tup, &dimLup, &beta, Wblock, &dimLdown );
2754 const int orb_i = denT->
gIndex();
2762 for (
int NL = book->
gNmin( orb_i ); NL <= book->
gNmax( orb_i ); NL++ ){
2763 for (
int TwoSL = book->
gTwoSmin( orb_i, NL ); TwoSL <= book->
gTwoSmax( orb_i, NL ); TwoSL+=2 ){
2770 for (
int TwoSLprime = TwoSL-3; TwoSLprime <= TwoSL+3; TwoSLprime+=2 ){
2772 int dimLup = book->
gCurrentDim( orb_i, NL, TwoSL, IL );
2773 int dimLdown = book->
gCurrentDim( orb_i, NL-1, TwoSLprime, ILxImxInxIi );
2775 if (( dimLup > 0 ) && ( dimLdown > 0 )){
2777 for (
int TwoSRprime = TwoSLprime-1; TwoSRprime <= TwoSLprime+1; TwoSRprime+=2 ){
2779 int dimRup = book->
gCurrentDim( orb_i+1, NL, TwoSL, IL );
2780 int dimRdown = book->
gCurrentDim( orb_i+1, NL, TwoSRprime, ILxImxIn );
2782 if (( dimRup > 0 ) && ( dimRdown > 0 ) && ( abs( TwoSL - TwoSRprime ) <= 2 )){
2784 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL, TwoSL, IL );
2785 double * Tdown = denT->
gStorage( NL-1, TwoSLprime, ILxImxInxIi, NL, TwoSRprime, ILxImxIn );
2786 double * Fblock = denF1->
gStorage( NL, TwoSRprime, ILxImxIn, NL, TwoSL, IL );
2792 dgemm_( ¬rans, ¬rans, &dimLdown, &dimRup, &dimRdown, &alpha, Tdown, &dimLdown, Fblock, &dimRdown, &beta, workmem, &dimLdown );
2793 dgemm_( ¬rans, &trans, &dimLdown, &dimLup, &dimRup, &alpha, workmem, &dimLdown, Tup, &dimLup, &beta, workmem2, &dimLdown );
2795 if ( abs( TwoSL - TwoSLprime ) == 1 ){
2797 double * Wblock = doublet->
gStorage( NL-1, TwoSLprime, ILxImxInxIi, NL, TwoSL, IL );
2798 double prefactor = sqrt( 0.5 * ( TwoSL + 1 ) ) * ( TwoSRprime + 1 )
2801 int length = dimLup * dimLdown;
2803 daxpy_( &length, &prefactor, workmem2, &inc, Wblock, &inc );
2808 double * Wblock = quartet->
gStorage( NL-1, TwoSLprime, ILxImxInxIi, NL, TwoSL, IL );
2809 double prefactor = sqrt( TwoSL + 1.0 ) * ( TwoSRprime + 1 )
2812 int length = dimLup * dimLdown;
2814 daxpy_( &length, &prefactor, workmem2, &inc, Wblock, &inc );
2820 for (
int TwoSR = TwoSL-1; TwoSR <= TwoSL+1; TwoSR+=2 ){
2822 int dimRup = book->
gCurrentDim( orb_i+1, NL+1, TwoSR, ILxIi );
2823 int dimRdown = book->
gCurrentDim( orb_i+1, NL+1, TwoSLprime, ILxImxInxIi );
2825 if (( dimRup > 0 ) && ( dimRdown > 0 ) && ( abs( TwoSLprime - TwoSR ) <= 2 )){
2827 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL+1, TwoSR, ILxIi );
2828 double * Tdown = denT->
gStorage( NL-1, TwoSLprime, ILxImxInxIi, NL+1, TwoSLprime, ILxImxInxIi );
2829 double * Fblock = denF1->
gStorage( NL+1, TwoSLprime, ILxImxInxIi, NL+1, TwoSR, ILxIi );
2835 dgemm_( ¬rans, ¬rans, &dimLdown, &dimRup, &dimRdown, &alpha, Tdown, &dimLdown, Fblock, &dimRdown, &beta, workmem, &dimLdown );
2836 dgemm_( ¬rans, &trans, &dimLdown, &dimLup, &dimRup, &alpha, workmem, &dimLdown, Tup, &dimLup, &beta, workmem2, &dimLdown );
2838 if ( abs( TwoSL - TwoSLprime ) == 1 ){
2840 double * Wblock = doublet->
gStorage( NL-1, TwoSLprime, ILxImxInxIi, NL, TwoSL, IL );
2841 double prefactor = sqrt( 0.5 * ( TwoSL + 1 ) * ( TwoSLprime + 1 ) * ( TwoSR + 1 ) )
2844 int length = dimLup * dimLdown;
2846 daxpy_( &length, &prefactor, workmem2, &inc, Wblock, &inc );
2851 double * Wblock = quartet->
gStorage( NL-1, TwoSLprime, ILxImxInxIi, NL, TwoSL, IL );
2852 double prefactor = sqrt( 1.0 * ( TwoSL + 1 ) * ( TwoSLprime + 1 ) * ( TwoSR + 1 ) )
2855 int length = dimLup * dimLdown;
2857 daxpy_( &length, &prefactor, workmem2, &inc, Wblock, &inc );
2873 const int orb_i = denT->
gIndex();
2875 assert( tofill->
get_irrep() == ImxInxIi );
2881 for (
int NL = book->
gNmin( orb_i ); NL <= book->
gNmax( orb_i ); NL++ ){
2882 for (
int TwoSL = book->
gTwoSmin( orb_i, NL ); TwoSL <= book->
gTwoSmax( orb_i, NL ); TwoSL+=2 ){
2889 for (
int TwoSLprime = TwoSL-1; TwoSLprime <= TwoSL+1; TwoSLprime+=2 ){
2891 int dimLup = book->
gCurrentDim( orb_i, NL, TwoSL, IL );
2892 int dimLdown = book->
gCurrentDim( orb_i, NL-1, TwoSLprime, ILxImxInxIi );
2894 if (( dimLup > 0 ) && ( dimLdown > 0 )){
2896 int dimRup = book->
gCurrentDim( orb_i+1, NL, TwoSL, IL );
2897 int dimRdown = book->
gCurrentDim( orb_i+1, NL, TwoSL, ILxImxIn );
2899 if (( dimRup > 0 ) && ( dimRdown > 0 )){
2901 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL, TwoSL, IL );
2902 double * Tdown = denT->
gStorage( NL-1, TwoSLprime, ILxImxInxIi, NL, TwoSL, ILxImxIn );
2903 double * Fblock = denF0->
gStorage( NL, TwoSL, IL, NL, TwoSL, ILxImxIn );
2904 double * Wblock = tofill->
gStorage( NL-1, TwoSLprime, ILxImxInxIi, NL, TwoSL, IL );
2908 double alpha = 0.5 * ( TwoSL + 1 );
2910 dgemm_( ¬rans, &trans, &dimLdown, &dimRup, &dimRdown, &alpha, Tdown, &dimLdown, Fblock, &dimRup, &beta, workmem, &dimLdown );
2913 dgemm_( ¬rans, &trans, &dimLdown, &dimLup, &dimRup, &alpha, workmem, &dimLdown, Tup, &dimLup, &beta, Wblock, &dimLdown );
2917 dimRup = book->
gCurrentDim( orb_i+1, NL+1, TwoSLprime, ILxIi );
2918 dimRdown = book->
gCurrentDim( orb_i+1, NL+1, TwoSLprime, ILxImxInxIi );
2920 if (( dimRup > 0 ) && ( dimRdown > 0 )){
2922 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL+1, TwoSLprime, ILxIi );
2923 double * Tdown = denT->
gStorage( NL-1, TwoSLprime, ILxImxInxIi, NL+1, TwoSLprime, ILxImxInxIi );
2924 double * Fblock = denF0->
gStorage( NL+1, TwoSLprime, ILxIi, NL+1, TwoSLprime, ILxImxInxIi );
2925 double * Wblock = tofill->
gStorage( NL-1, TwoSLprime, ILxImxInxIi, NL, TwoSL, IL );
2929 double alpha = 0.5 * sqrt( 1.0 * ( TwoSL + 1 ) * ( TwoSLprime + 1 ) ) *
Special::phase( TwoSLprime + 1 - TwoSL );
2931 dgemm_( ¬rans, &trans, &dimLdown, &dimRup, &dimRdown, &alpha, Tdown, &dimLdown, Fblock, &dimRup, &beta, workmem, &dimLdown );
2934 dgemm_( ¬rans, &trans, &dimLdown, &dimLup, &dimRup, &alpha, workmem, &dimLdown, Tup, &dimLup, &beta, Wblock, &dimLdown );
2947 const int orb_i = denT->
gIndex();
2955 for (
int NL = book->
gNmin( orb_i ); NL <= book->
gNmax( orb_i ); NL++ ){
2956 for (
int TwoSL = book->
gTwoSmin( orb_i, NL ); TwoSL <= book->
gTwoSmax( orb_i, NL ); TwoSL+=2 ){
2963 for (
int TwoSLprime = TwoSL-3; TwoSLprime <= TwoSL+3; TwoSLprime+=2 ){
2965 int dimLup = book->
gCurrentDim( orb_i, NL, TwoSL, IL );
2966 int dimLdown = book->
gCurrentDim( orb_i, NL-1, TwoSLprime, ILxImxInxIi );
2968 if (( dimLup > 0 ) && ( dimLdown > 0 )){
2970 for (
int TwoSRprime = TwoSLprime-1; TwoSRprime <= TwoSLprime+1; TwoSRprime+=2 ){
2972 int dimRup = book->
gCurrentDim( orb_i+1, NL, TwoSL, IL );
2973 int dimRdown = book->
gCurrentDim( orb_i+1, NL, TwoSRprime, ILxImxIn );
2975 if (( dimRup > 0 ) && ( dimRdown > 0 ) && ( abs( TwoSL - TwoSRprime ) <= 2 )){
2977 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL, TwoSL, IL );
2978 double * Tdown = denT->
gStorage( NL-1, TwoSLprime, ILxImxInxIi, NL, TwoSRprime, ILxImxIn );
2979 double * Fblock = denF1->
gStorage( NL, TwoSL, IL, NL, TwoSRprime, ILxImxIn );
2985 dgemm_( ¬rans, &trans, &dimLdown, &dimRup, &dimRdown, &alpha, Tdown, &dimLdown, Fblock, &dimRup, &beta, workmem, &dimLdown );
2986 dgemm_( ¬rans, &trans, &dimLdown, &dimLup, &dimRup, &alpha, workmem, &dimLdown, Tup, &dimLup, &beta, workmem2, &dimLdown );
2988 if ( abs( TwoSL - TwoSLprime ) == 1 ){
2990 double * Wblock = doublet->
gStorage( NL-1, TwoSLprime, ILxImxInxIi, NL, TwoSL, IL );
2991 double prefactor = sqrt( 0.5 * ( TwoSRprime + 1 ) ) * ( TwoSL + 1 )
2994 int length = dimLup * dimLdown;
2996 daxpy_( &length, &prefactor, workmem2, &inc, Wblock, &inc );
3001 double * Wblock = quartet->
gStorage( NL-1, TwoSLprime, ILxImxInxIi, NL, TwoSL, IL );
3002 double prefactor = sqrt( TwoSRprime + 1.0 ) * ( TwoSL + 1 )
3005 int length = dimLup * dimLdown;
3007 daxpy_( &length, &prefactor, workmem2, &inc, Wblock, &inc );
3013 for (
int TwoSR = TwoSL-1; TwoSR <= TwoSL+1; TwoSR+=2 ){
3015 int dimRup = book->
gCurrentDim( orb_i+1, NL+1, TwoSR, ILxIi );
3016 int dimRdown = book->
gCurrentDim( orb_i+1, NL+1, TwoSLprime, ILxImxInxIi );
3018 if (( dimRup > 0 ) && ( dimRdown > 0 ) && ( abs( TwoSLprime - TwoSR ) <= 2 )){
3020 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL+1, TwoSR, ILxIi );
3021 double * Tdown = denT->
gStorage( NL-1, TwoSLprime, ILxImxInxIi, NL+1, TwoSLprime, ILxImxInxIi );
3022 double * Fblock = denF1->
gStorage( NL+1, TwoSR, ILxIi, NL+1, TwoSLprime, ILxImxInxIi );
3028 dgemm_( ¬rans, &trans, &dimLdown, &dimRup, &dimRdown, &alpha, Tdown, &dimLdown, Fblock, &dimRup, &beta, workmem, &dimLdown );
3029 dgemm_( ¬rans, &trans, &dimLdown, &dimLup, &dimRup, &alpha, workmem, &dimLdown, Tup, &dimLup, &beta, workmem2, &dimLdown );
3031 if ( abs( TwoSL - TwoSLprime ) == 1 ){
3033 double * Wblock = doublet->
gStorage( NL-1, TwoSLprime, ILxImxInxIi, NL, TwoSL, IL );
3034 double prefactor = sqrt( 0.5 * ( TwoSL + 1 ) ) * ( TwoSR + 1 )
3037 int length = dimLup * dimLdown;
3039 daxpy_( &length, &prefactor, workmem2, &inc, Wblock, &inc );
3044 double * Wblock = quartet->
gStorage( NL-1, TwoSLprime, ILxImxInxIi, NL, TwoSL, IL );
3045 double prefactor = sqrt( TwoSL + 1.0 ) * ( TwoSR + 1 )
3048 int length = dimLup * dimLdown;
3050 daxpy_( &length, &prefactor, workmem2, &inc, Wblock, &inc );
3064 void CheMPS2::ThreeDM::fill_tens_29_33(
TensorT * denT,
TensorF0 * tofill,
TensorF0 * denF0,
double * workmem)
const{
3066 const int orb_i = denT->
gIndex();
3070 for (
int NL = book->
gNmin( orb_i ); NL <= book->
gNmax( orb_i ); NL++ ){
3071 for (
int TwoSL = book->
gTwoSmin( orb_i, NL ); TwoSL <= book->
gTwoSmax( orb_i, NL ); TwoSL+=2 ){
3078 int dimLup = book->
gCurrentDim( orb_i, NL, TwoSL, IL );
3079 int dimLdown = book->
gCurrentDim( orb_i, NL, TwoSL, ILxImxIn );
3081 if (( dimLup > 0 ) && ( dimLdown > 0 )){
3084 int dimRup = book->
gCurrentDim( orb_i+1, NL+2, TwoSL, IL );
3085 int dimRdown = book->
gCurrentDim( orb_i+1, NL+2, TwoSL, ILxImxIn );
3087 if (( dimRup > 0 ) && ( dimRdown > 0 )){
3089 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL+2, TwoSL, IL );
3090 double * Tdown = denT->
gStorage( NL, TwoSL, ILxImxIn, NL+2, TwoSL, ILxImxIn );
3091 double * right = denF0->
gStorage( NL+2, TwoSL, ILxImxIn, NL+2, TwoSL, IL );
3092 double * left = tofill->
gStorage( NL, TwoSL, ILxImxIn, NL, TwoSL, IL );
3094 double factor = TwoSL + 1.0;
3099 dgemm_( ¬rans, ¬rans, &dimLdown, &dimRup, &dimRdown, &factor, Tdown, &dimLdown, right, &dimRdown, &zero, workmem, &dimLdown );
3100 dgemm_( ¬rans, &trans, &dimLdown, &dimLup, &dimRup, &one, workmem, &dimLdown, Tup, &dimLup, &one, left, &dimLdown );
3105 for (
int TwoSR = TwoSL-1; TwoSR <= TwoSL+1; TwoSR+=2 ){
3107 int dimRup = book->
gCurrentDim( orb_i+1, NL+1, TwoSR, ILxIi );
3108 int dimRdown = book->
gCurrentDim( orb_i+1, NL+1, TwoSR, ILxImxInxIi );
3110 if (( dimRup > 0 ) && ( dimRdown > 0 )){
3112 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL+1, TwoSR, ILxIi );
3113 double * Tdown = denT->
gStorage( NL, TwoSL, ILxImxIn, NL+1, TwoSR, ILxImxInxIi );
3114 double * right = denF0->
gStorage( NL+1, TwoSR, ILxImxInxIi, NL+1, TwoSR, ILxIi );
3115 double * left = tofill->
gStorage( NL, TwoSL, ILxImxIn, NL, TwoSL, IL );
3117 double factor = 0.5 * ( TwoSR + 1 );
3122 dgemm_( ¬rans, ¬rans, &dimLdown, &dimRup, &dimRdown, &factor, Tdown, &dimLdown, right, &dimRdown, &zero, workmem, &dimLdown );
3123 dgemm_( ¬rans, &trans, &dimLdown, &dimLup, &dimRup, &one, workmem, &dimLdown, Tup, &dimLup, &one, left, &dimLdown );
3134 void CheMPS2::ThreeDM::fill_tens_30_32(
TensorT * denT,
TensorF1 * tofill,
TensorF1 * denF1,
double * workmem)
const{
3136 const int orb_i = denT->
gIndex();
3140 for (
int NL = book->
gNmin( orb_i ); NL <= book->
gNmax( orb_i ); NL++ ){
3141 for (
int TwoSL = book->
gTwoSmin( orb_i, NL ); TwoSL <= book->
gTwoSmax( orb_i, NL ); TwoSL+=2 ){
3146 for (
int TwoSLprime = TwoSL-2; TwoSLprime <= TwoSL+2; TwoSLprime+=2 ){
3148 int dimLup = book->
gCurrentDim( orb_i, NL, TwoSL, IL );
3149 int dimLdown = book->
gCurrentDim( orb_i, NL, TwoSLprime, ILxImxIn );
3150 int dimRup = book->
gCurrentDim( orb_i+1, NL+2, TwoSL, IL );
3151 int dimRdown = book->
gCurrentDim( orb_i+1, NL+2, TwoSLprime, ILxImxIn );
3153 if (( dimLup > 0 ) && ( dimLdown > 0 ) && ( dimRup > 0 ) && ( dimRdown > 0 )){
3155 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL+2, TwoSL, IL );
3156 double * Tdown = denT->
gStorage( NL, TwoSLprime, ILxImxIn, NL+2, TwoSLprime, ILxImxIn );
3157 double * right = denF1->
gStorage( NL+2, TwoSLprime, ILxImxIn, NL+2, TwoSL, IL );
3158 double * left = tofill->
gStorage( NL, TwoSLprime, ILxImxIn, NL, TwoSL, IL );
3160 double factor = sqrt( 1.0 * ( TwoSL + 1 ) * ( TwoSLprime + 1 ) ) *
Special::phase( TwoSL - TwoSLprime );
3165 dgemm_( ¬rans, ¬rans, &dimLdown, &dimRup, &dimRdown, &factor, Tdown, &dimLdown, right, &dimRdown, &zero, workmem, &dimLdown );
3166 dgemm_( ¬rans, &trans, &dimLdown, &dimLup, &dimRup, &one, workmem, &dimLdown, Tup, &dimLup, &one, left, &dimLdown );
3176 void CheMPS2::ThreeDM::fill_tens_36_42(
TensorT * denT,
TensorF1 * tofill,
TensorF0 * denF0,
double * workmem)
const{
3178 const int orb_i = denT->
gIndex();
3182 for (
int NL = book->
gNmin( orb_i ); NL <= book->
gNmax( orb_i ); NL++ ){
3183 for (
int TwoSL = book->
gTwoSmin( orb_i, NL ); TwoSL <= book->
gTwoSmax( orb_i, NL ); TwoSL+=2 ){
3190 for (
int TwoSLprime = TwoSL-2; TwoSLprime <= TwoSL+2; TwoSLprime+=2 ){
3192 int dimLup = book->
gCurrentDim( orb_i, NL, TwoSL, IL );
3193 int dimLdown = book->
gCurrentDim( orb_i, NL, TwoSLprime, ILxImxIn );
3195 if (( dimLup > 0 ) && ( dimLdown > 0 )){
3197 for (
int TwoSR = TwoSL-1; TwoSR <= TwoSL+1; TwoSR+=2 ){
3199 int dimRup = book->
gCurrentDim( orb_i+1, NL+1, TwoSR, ILxIi );
3200 int dimRdown = book->
gCurrentDim( orb_i+1, NL+1, TwoSR, ILxImxInxIi );
3202 if (( dimRup > 0 ) && ( dimRdown > 0 ) && ( abs( TwoSLprime - TwoSR ) == 1 )){
3204 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL+1, TwoSR, ILxIi );
3205 double * Tdown = denT->
gStorage( NL, TwoSLprime, ILxImxIn, NL+1, TwoSR, ILxImxInxIi );
3206 double * right = denF0->
gStorage( NL+1, TwoSR, ILxImxInxIi, NL+1, TwoSR, ILxIi );
3207 double * left = tofill->
gStorage( NL, TwoSLprime, ILxImxIn, NL, TwoSL, IL );
3209 double factor = 0.5 * sqrt( 6.0 * ( TwoSL + 1 ) ) * ( TwoSR + 1 )
3216 dgemm_( ¬rans, ¬rans, &dimLdown, &dimRup, &dimRdown, &factor, Tdown, &dimLdown, right, &dimRdown, &zero, workmem, &dimLdown );
3217 dgemm_( ¬rans, &trans, &dimLdown, &dimLup, &dimRup, &one, workmem, &dimLdown, Tup, &dimLup, &one, left, &dimLdown );
3231 const int orb_i = denT->
gIndex();
3237 for (
int NL = book->
gNmin( orb_i ); NL <= book->
gNmax( orb_i ); NL++ ){
3238 for (
int TwoSL = book->
gTwoSmin( orb_i, NL ); TwoSL <= book->
gTwoSmax( orb_i, NL ); TwoSL+=2 ){
3245 for (
int TwoSLprime = TwoSL-2; TwoSLprime <= TwoSL+2; TwoSLprime+=2 ){
3247 int dimLup = book->
gCurrentDim( orb_i, NL, TwoSL, IL );
3248 int dimLdown = book->
gCurrentDim( orb_i, NL, TwoSLprime, ILxImxIn );
3250 if (( dimLup > 0 ) && ( dimLdown > 0 )){
3252 for (
int TwoSR = TwoSL-1; TwoSR <= TwoSL+1; TwoSR+=2 ){
3253 for (
int TwoSRprime = TwoSLprime-1; TwoSRprime <= TwoSLprime+1; TwoSRprime+=2 ){
3255 int dimRup = book->
gCurrentDim( orb_i+1, NL+1, TwoSR, ILxIi );
3256 int dimRdown = book->
gCurrentDim( orb_i+1, NL+1, TwoSRprime, ILxImxInxIi );
3258 if (( dimRup > 0 ) && ( dimRdown > 0 ) && ( abs( TwoSR - TwoSRprime ) <= 2 )){
3260 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL+1, TwoSR, ILxIi );
3261 double * Tdown = denT->
gStorage( NL, TwoSLprime, ILxImxIn, NL+1, TwoSRprime, ILxImxInxIi );
3262 double * right = denF1->
gStorage( NL+1, TwoSRprime, ILxImxInxIi, NL+1, TwoSR, ILxIi );
3268 dgemm_( ¬rans, ¬rans, &dimLdown, &dimRup, &dimRdown, &one, Tdown, &dimLdown, right, &dimRdown, &zero, workmem, &dimLdown );
3269 dgemm_( ¬rans, &trans, &dimLdown, &dimLup, &dimRup, &one, workmem, &dimLdown, Tup, &dimLup, &zero, workmem2, &dimLdown );
3272 double * left = fill34->
gStorage( NL, TwoSLprime, ILxImxIn, NL, TwoSL, IL );
3273 double factor = 0.5 * ( TwoSRprime + 1 ) * sqrt( 1.0 * ( TwoSR + 1 ) * ( TwoSL + 1 ) )
3276 int length = dimLup * dimLdown;
3278 daxpy_( &length, &factor, workmem2, &inc, left, &inc );
3280 if ( TwoSL == TwoSLprime ){
3281 double * left = fill35->
gStorage( NL, TwoSLprime, ILxImxIn, NL, TwoSL, IL );
3282 double factor = 0.5 * ( TwoSRprime + 1 ) * sqrt( 6.0 * ( TwoSR + 1 ) )
3285 int length = dimLup * dimLdown;
3287 daxpy_( &length, &factor, workmem2, &inc, left, &inc );
3290 double * left = fill37->
gStorage( NL, TwoSLprime, ILxImxIn, NL, TwoSL, IL );
3291 double factor = 3 * ( TwoSRprime + 1 ) * sqrt( 1.0 * ( TwoSR + 1 ) * ( TwoSL + 1 ) )
3295 int length = dimLup * dimLdown;
3297 daxpy_( &length, &factor, workmem2, &inc, left, &inc );
3300 double * left = fill38->
gStorage( NL, TwoSLprime, ILxImxIn, NL, TwoSL, IL );
3301 double factor = 3 * ( TwoSRprime + 1 ) * sqrt( 1.0 * ( TwoSR + 1 ) * ( TwoSL + 1 ) )
3305 int length = dimLup * dimLdown;
3307 daxpy_( &length, &factor, workmem2, &inc, left, &inc );
3320 void CheMPS2::ThreeDM::fill_tens_49_51(
TensorT * denT,
TensorF0 * tofill,
TensorS0 * denS0,
double * workmem)
const{
3322 const int orb_i = denT->
gIndex();
3326 for (
int NL = book->
gNmin( orb_i ); NL <= book->
gNmax( orb_i ); NL++ ){
3327 for (
int TwoSL = book->
gTwoSmin( orb_i, NL ); TwoSL <= book->
gTwoSmax( orb_i, NL ); TwoSL+=2 ){
3332 int dimLup = book->
gCurrentDim( orb_i, NL, TwoSL, IL );
3333 int dimLdown = book->
gCurrentDim( orb_i, NL, TwoSL, ILxImxIn );
3334 int dimRup = book->
gCurrentDim( orb_i+1, NL+2, TwoSL, IL );
3335 int dimRdown = book->
gCurrentDim( orb_i+1, NL, TwoSL, ILxImxIn );
3337 if (( dimLup > 0 ) && ( dimLdown > 0 ) && ( dimRup > 0 ) && ( dimRdown > 0 )){
3339 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL+2, TwoSL, IL );
3340 double * Tdown = denT->
gStorage( NL, TwoSL, ILxImxIn, NL, TwoSL, ILxImxIn );
3341 double * right = denS0->
gStorage( NL, TwoSL, ILxImxIn, NL+2, TwoSL, IL );
3342 double * left = tofill->
gStorage( NL, TwoSL, ILxImxIn, NL, TwoSL, IL );
3344 double factor = - ( TwoSL + 1.0 );
3349 dgemm_( ¬rans, ¬rans, &dimLdown, &dimRup, &dimRdown, &factor, Tdown, &dimLdown, right, &dimRdown, &zero, workmem, &dimLdown );
3350 dgemm_( ¬rans, &trans, &dimLdown, &dimLup, &dimRup, &one, workmem, &dimLdown, Tup, &dimLup, &one, left, &dimLdown );
3359 void CheMPS2::ThreeDM::fill_tens_50_52(
TensorT * denT,
TensorF1 * tofill,
TensorS1 * denS1,
double * workmem)
const{
3361 const int orb_i = denT->
gIndex();
3365 for (
int NL = book->
gNmin( orb_i ); NL <= book->
gNmax( orb_i ); NL++ ){
3366 for (
int TwoSL = book->
gTwoSmin( orb_i, NL ); TwoSL <= book->
gTwoSmax( orb_i, NL ); TwoSL+=2 ){
3371 for (
int TwoSLprime = TwoSL-2; TwoSLprime <= TwoSL+2; TwoSLprime+=2 ){
3373 int dimLup = book->
gCurrentDim( orb_i, NL, TwoSL, IL );
3374 int dimLdown = book->
gCurrentDim( orb_i, NL, TwoSLprime, ILxImxIn );
3375 int dimRup = book->
gCurrentDim( orb_i+1, NL+2, TwoSL, IL );
3376 int dimRdown = book->
gCurrentDim( orb_i+1, NL, TwoSLprime, ILxImxIn );
3378 if (( dimLup > 0 ) && ( dimLdown > 0 ) && ( dimRup > 0 ) && ( dimRdown > 0 )){
3380 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL+2, TwoSL, IL );
3381 double * Tdown = denT->
gStorage( NL, TwoSLprime, ILxImxIn, NL, TwoSLprime, ILxImxIn );
3382 double * right = denS1->
gStorage( NL, TwoSLprime, ILxImxIn, NL+2, TwoSL, IL );
3383 double * left = tofill->
gStorage( NL, TwoSLprime, ILxImxIn, NL, TwoSL, IL );
3385 double factor = - ( TwoSL + 1.0 );
3390 dgemm_( ¬rans, ¬rans, &dimLdown, &dimRup, &dimRdown, &factor, Tdown, &dimLdown, right, &dimRdown, &zero, workmem, &dimLdown );
3391 dgemm_( ¬rans, &trans, &dimLdown, &dimLup, &dimRup, &one, workmem, &dimLdown, Tup, &dimLup, &one, left, &dimLdown );
3401 void CheMPS2::ThreeDM::fill_tens_22_24(
TensorT * denT,
TensorS0 * tofill,
TensorS0 * denS0,
double * workmem)
const{
3403 const int orb_i = denT->
gIndex();
3407 for (
int NL = book->
gNmin( orb_i ); NL <= book->
gNmax( orb_i ); NL++ ){
3408 for (
int TwoSL = book->
gTwoSmin( orb_i, NL ); TwoSL <= book->
gTwoSmax( orb_i, NL ); TwoSL+=2 ){
3415 int dimLup = book->
gCurrentDim( orb_i, NL, TwoSL, IL );
3416 int dimLdown = book->
gCurrentDim( orb_i, NL-2, TwoSL, ILxImxIn );
3418 if (( dimLup > 0 ) && ( dimLdown > 0 )){
3421 int dimRup = book->
gCurrentDim( orb_i+1, NL+2, TwoSL, IL );
3422 int dimRdown = book->
gCurrentDim( orb_i+1, NL, TwoSL, ILxImxIn );
3424 if (( dimRup > 0 ) && ( dimRdown > 0 )){
3426 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL+2, TwoSL, IL );
3427 double * Tdown = denT->
gStorage( NL-2, TwoSL, ILxImxIn, NL, TwoSL, ILxImxIn );
3428 double * right = denS0->
gStorage( NL, TwoSL, ILxImxIn, NL+2, TwoSL, IL );
3429 double * left = tofill->
gStorage( NL-2, TwoSL, ILxImxIn, NL, TwoSL, IL );
3431 double factor = TwoSL + 1.0;
3436 dgemm_( ¬rans, ¬rans, &dimLdown, &dimRup, &dimRdown, &factor, Tdown, &dimLdown, right, &dimRdown, &zero, workmem, &dimLdown );
3437 dgemm_( ¬rans, &trans, &dimLdown, &dimLup, &dimRup, &one, workmem, &dimLdown, Tup, &dimLup, &one, left, &dimLdown );
3442 for (
int TwoSR = TwoSL-1; TwoSR <= TwoSL+1; TwoSR+=2 ){
3444 int dimRup = book->
gCurrentDim( orb_i+1, NL+1, TwoSR, ILxIi );
3445 int dimRdown = book->
gCurrentDim( orb_i+1, NL-1, TwoSR, ILxImxInxIi );
3447 if (( dimRup > 0 ) && ( dimRdown > 0 )){
3449 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL+1, TwoSR, ILxIi );
3450 double * Tdown = denT->
gStorage( NL-2, TwoSL, ILxImxIn, NL-1, TwoSR, ILxImxInxIi );
3451 double * right = denS0->
gStorage( NL-1, TwoSR, ILxImxInxIi, NL+1, TwoSR, ILxIi );
3452 double * left = tofill->
gStorage( NL-2, TwoSL, ILxImxIn, NL, TwoSL, IL );
3454 double factor = 0.5 * ( TwoSR + 1 );
3459 dgemm_( ¬rans, ¬rans, &dimLdown, &dimRup, &dimRdown, &factor, Tdown, &dimLdown, right, &dimRdown, &zero, workmem, &dimLdown );
3460 dgemm_( ¬rans, &trans, &dimLdown, &dimLup, &dimRup, &one, workmem, &dimLdown, Tup, &dimLup, &one, left, &dimLdown );
3471 void CheMPS2::ThreeDM::fill_tens_28(
TensorT * denT,
TensorS1 * tofill,
TensorS0 * denS0,
double * workmem)
const{
3473 const int orb_i = denT->
gIndex();
3477 for (
int NL = book->
gNmin( orb_i ); NL <= book->
gNmax( orb_i ); NL++ ){
3478 for (
int TwoSL = book->
gTwoSmin( orb_i, NL ); TwoSL <= book->
gTwoSmax( orb_i, NL ); TwoSL+=2 ){
3485 for (
int TwoSLprime = TwoSL-2; TwoSLprime <= TwoSL+2; TwoSLprime+=2 ){
3487 int dimLup = book->
gCurrentDim( orb_i, NL, TwoSL, IL );
3488 int dimLdown = book->
gCurrentDim( orb_i, NL-2, TwoSLprime, ILxImxIn );
3490 if (( dimLup > 0 ) && ( dimLdown > 0 )){
3492 for (
int TwoSR = TwoSL-1; TwoSR <= TwoSL+1; TwoSR+=2 ){
3494 int dimRup = book->
gCurrentDim( orb_i+1, NL+1, TwoSR, ILxIi );
3495 int dimRdown = book->
gCurrentDim( orb_i+1, NL-1, TwoSR, ILxImxInxIi );
3497 if (( dimRup > 0 ) && ( dimRdown > 0 ) && ( abs( TwoSLprime - TwoSR ) == 1 )){
3499 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL+1, TwoSR, ILxIi );
3500 double * Tdown = denT->
gStorage( NL-2, TwoSLprime, ILxImxIn, NL-1, TwoSR, ILxImxInxIi );
3501 double * right = denS0->
gStorage( NL-1, TwoSR, ILxImxInxIi, NL+1, TwoSR, ILxIi );
3502 double * left = tofill->
gStorage( NL-2, TwoSLprime, ILxImxIn, NL, TwoSL, IL );
3504 double factor = sqrt( 1.5 * ( TwoSL + 1 ) ) * ( TwoSR + 1 )
3511 dgemm_( ¬rans, ¬rans, &dimLdown, &dimRup, &dimRdown, &factor, Tdown, &dimLdown, right, &dimRdown, &zero, workmem, &dimLdown );
3512 dgemm_( ¬rans, &trans, &dimLdown, &dimLup, &dimRup, &one, workmem, &dimLdown, Tup, &dimLup, &one, left, &dimLdown );
3524 void CheMPS2::ThreeDM::fill_tens_23(
TensorT * denT,
TensorS1 * tofill,
TensorS1 * denS1,
double * workmem)
const{
3526 const int orb_i = denT->
gIndex();
3530 for (
int NL = book->
gNmin( orb_i ); NL <= book->
gNmax( orb_i ); NL++ ){
3531 for (
int TwoSL = book->
gTwoSmin( orb_i, NL ); TwoSL <= book->
gTwoSmax( orb_i, NL ); TwoSL+=2 ){
3536 for (
int TwoSLprime = TwoSL-2; TwoSLprime <= TwoSL+2; TwoSLprime+=2 ){
3538 int dimLup = book->
gCurrentDim( orb_i, NL, TwoSL, IL );
3539 int dimLdown = book->
gCurrentDim( orb_i, NL-2, TwoSLprime, ILxImxIn );
3540 int dimRup = book->
gCurrentDim( orb_i+1, NL+2, TwoSL, IL );
3541 int dimRdown = book->
gCurrentDim( orb_i+1, NL, TwoSLprime, ILxImxIn );
3543 if (( dimLup > 0 ) && ( dimLdown > 0 ) && ( dimRup > 0 ) && ( dimRdown > 0 )){
3545 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL+2, TwoSL, IL );
3546 double * Tdown = denT->
gStorage( NL-2, TwoSLprime, ILxImxIn, NL, TwoSLprime, ILxImxIn );
3547 double * right = denS1->
gStorage( NL, TwoSLprime, ILxImxIn, NL+2, TwoSL, IL );
3548 double * left = tofill->
gStorage( NL-2, TwoSLprime, ILxImxIn, NL, TwoSL, IL );
3550 double factor = TwoSL + 1.0;
3555 dgemm_( ¬rans, ¬rans, &dimLdown, &dimRup, &dimRdown, &factor, Tdown, &dimLdown, right, &dimRdown, &zero, workmem, &dimLdown );
3556 dgemm_( ¬rans, &trans, &dimLdown, &dimLup, &dimRup, &one, workmem, &dimLdown, Tup, &dimLup, &one, left, &dimLdown );
3568 const int orb_i = denT->
gIndex();
3573 for (
int NL = book->
gNmin( orb_i ); NL <= book->
gNmax( orb_i ); NL++ ){
3574 for (
int TwoSL = book->
gTwoSmin( orb_i, NL ); TwoSL <= book->
gTwoSmax( orb_i, NL ); TwoSL+=2 ){
3581 for (
int TwoSLprime = TwoSL-2; TwoSLprime <= TwoSL+2; TwoSLprime+=2 ){
3583 int dimLup = book->
gCurrentDim( orb_i, NL, TwoSL, IL );
3584 int dimLdown = book->
gCurrentDim( orb_i, NL-2, TwoSLprime, ILxImxIn );
3586 if (( dimLup > 0 ) && ( dimLdown > 0 )){
3588 for (
int TwoSR = TwoSL-1; TwoSR <= TwoSL+1; TwoSR+=2 ){
3589 for (
int TwoSRprime = TwoSLprime-1; TwoSRprime <= TwoSLprime+1; TwoSRprime+=2 ){
3591 int dimRup = book->
gCurrentDim( orb_i+1, NL+1, TwoSR, ILxIi );
3592 int dimRdown = book->
gCurrentDim( orb_i+1, NL-1, TwoSRprime, ILxImxInxIi );
3594 if (( dimRup > 0 ) && ( dimRdown > 0 ) && ( abs( TwoSRprime - TwoSR ) <= 2 )){
3596 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL+1, TwoSR, ILxIi );
3597 double * Tdown = denT->
gStorage( NL-2, TwoSLprime, ILxImxIn, NL-1, TwoSRprime, ILxImxInxIi );
3598 double * right = denS1->
gStorage( NL-1, TwoSRprime, ILxImxInxIi, NL+1, TwoSR, ILxIi );
3604 dgemm_( ¬rans, ¬rans, &dimLdown, &dimRup, &dimRdown, &one, Tdown, &dimLdown, right, &dimRdown, &zero, workmem, &dimLdown );
3605 dgemm_( ¬rans, &trans, &dimLdown, &dimLup, &dimRup, &one, workmem, &dimLdown, Tup, &dimLup, &zero, workmem2, &dimLdown );
3608 double * left = fill25->
gStorage( NL-2, TwoSLprime, ILxImxIn, NL, TwoSL, IL );
3609 double factor = ( TwoSR + 1 ) * sqrt( 1.0 * ( TwoSL + 1 ) * ( TwoSRprime + 1 ) )
3612 int length = dimLup * dimLdown;
3614 daxpy_( &length, &factor, workmem2, &inc, left, &inc );
3617 double * left = fill26->
gStorage( NL-2, TwoSLprime, ILxImxIn, NL, TwoSL, IL );
3618 double factor = 3 * ( TwoSR + 1 ) * sqrt( 1.0 * ( TwoSL + 1 ) * ( TwoSRprime + 1 ) )
3622 int length = dimLup * dimLdown;
3624 daxpy_( &length, &factor, workmem2, &inc, left, &inc );
3626 if ( TwoSLprime == TwoSL ){
3627 double * left = fill27->
gStorage( NL-2, TwoSLprime, ILxImxIn, NL, TwoSL, IL );
3628 double factor = ( TwoSR + 1 ) * sqrt( 1.5 * ( TwoSRprime + 1 ) )
3631 int length = dimLup * dimLdown;
3633 daxpy_( &length, &factor, workmem2, &inc, left, &inc );
3646 void CheMPS2::ThreeDM::fill_tens_45_47(
TensorT * denT,
TensorS0 * tofill,
TensorF0 * denF0,
double * workmem,
const bool first)
const{
3648 const int orb_i = denT->
gIndex();
3652 for (
int NL = book->
gNmin( orb_i ); NL <= book->
gNmax( orb_i ); NL++ ){
3653 for (
int TwoSL = book->
gTwoSmin( orb_i, NL ); TwoSL <= book->
gTwoSmax( orb_i, NL ); TwoSL+=2 ){
3658 int dimLup = book->
gCurrentDim( orb_i, NL, TwoSL, IL );
3659 int dimLdown = book->
gCurrentDim( orb_i, NL-2, TwoSL, ILxImxIn );
3660 int dimRup = book->
gCurrentDim( orb_i+1, NL, TwoSL, IL );
3661 int dimRdown = book->
gCurrentDim( orb_i+1, NL, TwoSL, ILxImxIn );
3663 if (( dimLup > 0 ) && ( dimLdown > 0 ) && ( dimRup > 0 ) && ( dimRdown > 0 )){
3665 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL, TwoSL, IL );
3666 double * Tdown = denT->
gStorage( NL-2, TwoSL, ILxImxIn, NL, TwoSL, ILxImxIn );
3667 double * left = tofill->
gStorage( NL-2, TwoSL, ILxImxIn, NL, TwoSL, IL );
3669 double factor = -( TwoSL + 1.0 );
3675 double * right = denF0->
gStorage( NL, TwoSL, ILxImxIn, NL, TwoSL, IL );
3676 dgemm_( ¬rans, ¬rans, &dimLdown, &dimRup, &dimRdown, &factor, Tdown, &dimLdown, right, &dimRdown, &zero, workmem, &dimLdown );
3677 dgemm_( ¬rans, &trans, &dimLdown, &dimLup, &dimRup, &one, workmem, &dimLdown, Tup, &dimLup, &one, left, &dimLdown );
3679 double * right = denF0->
gStorage( NL, TwoSL, IL, NL, TwoSL, ILxImxIn );
3680 dgemm_( ¬rans, &trans, &dimLdown, &dimRup, &dimRdown, &factor, Tdown, &dimLdown, right, &dimRup, &zero, workmem, &dimLdown );
3681 dgemm_( ¬rans, &trans, &dimLdown, &dimLup, &dimRup, &one, workmem, &dimLdown, Tup, &dimLup, &one, left, &dimLdown );
3690 void CheMPS2::ThreeDM::fill_tens_46_48(
TensorT * denT,
TensorS1 * tofill,
TensorF1 * denF1,
double * workmem,
const bool first)
const{
3692 const int orb_i = denT->
gIndex();
3696 for (
int NL = book->
gNmin( orb_i ); NL <= book->
gNmax( orb_i ); NL++ ){
3697 for (
int TwoSL = book->
gTwoSmin( orb_i, NL ); TwoSL <= book->
gTwoSmax( orb_i, NL ); TwoSL+=2 ){
3702 int dimLup = book->
gCurrentDim( orb_i, NL, TwoSL, IL );
3703 int dimRup = book->
gCurrentDim( orb_i+1, NL, TwoSL, IL );
3705 if (( dimLup > 0 ) && ( dimRup > 0 )){
3707 for (
int TwoSLprime = TwoSL-2; TwoSLprime <= TwoSL+2; TwoSLprime+=2 ){
3709 int dimLdown = book->
gCurrentDim( orb_i, NL-2, TwoSLprime, ILxImxIn );
3710 int dimRdown = book->
gCurrentDim( orb_i+1, NL, TwoSLprime, ILxImxIn );
3712 if (( dimLdown > 0 ) && ( dimRdown > 0 )){
3714 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL, TwoSL, IL );
3715 double * Tdown = denT->
gStorage( NL-2, TwoSLprime, ILxImxIn, NL, TwoSLprime, ILxImxIn );
3716 double * left = tofill->
gStorage( NL-2, TwoSLprime, ILxImxIn, NL, TwoSL, IL );
3723 double factor = sqrt( 1.0 * ( TwoSL + 1 ) * ( TwoSLprime + 1 ) ) *
Special::phase( TwoSL - TwoSLprime + 2 );
3724 double * right = denF1->
gStorage( NL, TwoSLprime, ILxImxIn, NL, TwoSL, IL );
3725 dgemm_( ¬rans, ¬rans, &dimLdown, &dimRup, &dimRdown, &factor, Tdown, &dimLdown, right, &dimRdown, &zero, workmem, &dimLdown );
3726 dgemm_( ¬rans, &trans, &dimLdown, &dimLup, &dimRup, &one, workmem, &dimLdown, Tup, &dimLup, &one, left, &dimLdown );
3728 double factor = - ( TwoSL + 1.0 );
3729 double * right = denF1->
gStorage( NL, TwoSL, IL, NL, TwoSLprime, ILxImxIn );
3730 dgemm_( ¬rans, &trans, &dimLdown, &dimRup, &dimRdown, &factor, Tdown, &dimLdown, right, &dimRup, &zero, workmem, &dimLdown );
3731 dgemm_( ¬rans, &trans, &dimLdown, &dimLup, &dimRup, &one, workmem, &dimLdown, Tup, &dimLup, &one, left, &dimLdown );
3744 const int orb_i = denT->
gIndex();
3747 for (
int NL = book->
gNmin( orb_i ); NL <= book->
gNmax( orb_i ); NL++ ){
3748 for (
int TwoSL = book->
gTwoSmin( orb_i, NL ); TwoSL <= book->
gTwoSmax( orb_i, NL ); TwoSL+=2 ){
3753 int dimLup = book->
gCurrentDim( orb_i, NL, TwoSL, IL );
3754 int dimRup = book->
gCurrentDim( orb_i+1, NL, TwoSL, IL );
3756 if (( dimLup > 0 ) && ( dimRup > 0 )){
3758 for (
int TwoSLprime = TwoSL-1; TwoSLprime <= TwoSL+1; TwoSLprime+=2 ){
3760 int dimLdown = book->
gCurrentDim( orb_i, NL-3, TwoSLprime, ILxIm );
3761 int dimRdown = book->
gCurrentDim( orb_i+1, NL-1, TwoSLprime, ILxIm );
3763 if (( dimLdown > 0 ) && ( dimRdown > 0 )){
3765 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL, TwoSL, IL );
3766 double * Tdown = denT->
gStorage( NL-3, TwoSLprime, ILxIm, NL-1, TwoSLprime, ILxIm );
3767 double * left = tofill->
gStorage( NL-3, TwoSLprime, ILxIm, NL, TwoSL, IL );
3768 double * right = denL->
gStorage( NL-1, TwoSLprime, ILxIm, NL, TwoSL, IL );
3774 double factor = - sqrt( 0.5 ) * ( TwoSL + 1 );
3776 dgemm_( ¬rans, ¬rans, &dimLdown, &dimRup, &dimRdown, &factor, Tdown, &dimLdown, right, &dimRdown, &zero, workmem, &dimLdown );
3777 dgemm_( ¬rans, &trans, &dimLdown, &dimLup, &dimRup, &one, workmem, &dimLdown, Tup, &dimLup, &one, left, &dimLdown );
3790 const int orb_i = denT->
gIndex();
3793 for (
int NL = book->
gNmin( orb_i ); NL <= book->
gNmax( orb_i ); NL++ ){
3794 for (
int TwoSL = book->
gTwoSmin( orb_i, NL ); TwoSL <= book->
gTwoSmax( orb_i, NL ); TwoSL+=2 ){
3799 int dimLup = book->
gCurrentDim( orb_i, NL, TwoSL, IL );
3800 int dimRup = book->
gCurrentDim( orb_i+1, NL, TwoSL, IL );
3802 if (( dimLup > 0 ) && ( dimRup > 0 )){
3804 for (
int TwoSLprime = TwoSL-1; TwoSLprime <= TwoSL+1; TwoSLprime+=2 ){
3806 int dimLdown = book->
gCurrentDim( orb_i, NL-1, TwoSLprime, ILxIm );
3807 int dimRdown = book->
gCurrentDim( orb_i+1, NL+1, TwoSLprime, ILxIm );
3809 if (( dimLdown > 0 ) && ( dimRdown > 0 )){
3811 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL, TwoSL, IL );
3812 double * Tdown = denT->
gStorage( NL-1, TwoSLprime, ILxIm, NL+1, TwoSLprime, ILxIm );
3813 double * left = tofill->
gStorage( NL-1, TwoSLprime, ILxIm, NL, TwoSL, IL );
3814 double * right = denL->
gStorage( NL, TwoSL, IL, NL+1, TwoSLprime, ILxIm );
3820 double factor = sqrt( 0.5 * ( TwoSL + 1 ) * ( TwoSLprime + 1 ) ) *
Special::phase( TwoSL + 1 - TwoSLprime );
3822 dgemm_( ¬rans, &trans, &dimLdown, &dimRup, &dimRdown, &factor, Tdown, &dimLdown, right, &dimRup, &zero, workmem, &dimLdown );
3823 dgemm_( ¬rans, &trans, &dimLdown, &dimLup, &dimRup, &one, workmem, &dimLdown, Tup, &dimLup, &one, left, &dimLdown );
3836 const int orb_i = denT->
gIndex();
3839 for (
int NL = book->
gNmin( orb_i ); NL <= book->
gNmax( orb_i ); NL++ ){
3840 for (
int TwoSL = book->
gTwoSmin( orb_i, NL ); TwoSL <= book->
gTwoSmax( orb_i, NL ); TwoSL+=2 ){
3845 int dimLup = book->
gCurrentDim( orb_i, NL, TwoSL, IL );
3846 int dimRup = book->
gCurrentDim( orb_i+1, NL+2, TwoSL, IL );
3848 if (( dimLup > 0 ) && ( dimRup > 0 )){
3850 for (
int TwoSLprime = TwoSL-1; TwoSLprime <= TwoSL+1; TwoSLprime+=2 ){
3852 int dimLdown = book->
gCurrentDim( orb_i, NL-1, TwoSLprime, ILxIm );
3853 int dimRdown = book->
gCurrentDim( orb_i+1, NL+1, TwoSLprime, ILxIm );
3855 if (( dimLdown > 0 ) && ( dimRdown > 0 )){
3857 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL+2, TwoSL, IL );
3858 double * Tdown = denT->
gStorage( NL-1, TwoSLprime, ILxIm, NL+1, TwoSLprime, ILxIm );
3859 double * left = tofill->
gStorage( NL-1, TwoSLprime, ILxIm, NL, TwoSL, IL );
3860 double * right = denL->
gStorage( NL+1, TwoSLprime, ILxIm, NL+2, TwoSL, IL );
3866 double factor = sqrt( 0.5 ) * ( TwoSL + 1 );
3868 dgemm_( ¬rans, ¬rans, &dimLdown, &dimRup, &dimRdown, &factor, Tdown, &dimLdown, right, &dimRdown, &zero, workmem, &dimLdown );
3869 dgemm_( ¬rans, &trans, &dimLdown, &dimLup, &dimRup, &one, workmem, &dimLdown, Tup, &dimLup, &one, left, &dimLdown );
3882 const int orb_i = denT->
gIndex();
3890 for (
int NL = book->
gNmin( orb_i ); NL <= book->
gNmax( orb_i ); NL++ ){
3891 for (
int TwoSL = book->
gTwoSmin( orb_i, NL ); TwoSL <= book->
gTwoSmax( orb_i, NL ); TwoSL+=2 ){
3898 for (
int TwoSR = TwoSL-1; TwoSR <= TwoSL+1; TwoSR+=2 ){
3900 int dimLup = book->
gCurrentDim( orb_i, NL, TwoSL, IL );
3901 int dimRup = book->
gCurrentDim( orb_i+1, NL+1, TwoSR, ILxIi );
3903 if (( dimLup > 0 ) && ( dimRup > 0 )){
3905 for (
int TwoSLprime = TwoSL-1; TwoSLprime <= TwoSL+1; TwoSLprime+=2 ){
3906 for (
int TwoSRprime = TwoSLprime-1; TwoSRprime <= TwoSLprime+1; TwoSRprime+=2 ){
3908 int dimLdown = book->
gCurrentDim( orb_i, NL-1, TwoSLprime, ILxIm );
3909 int dimRdown = book->
gCurrentDim( orb_i+1, NL, TwoSRprime, ILxImxIi );
3911 if (( dimLdown > 0 ) && ( dimRdown > 0 ) && ( abs( TwoSR - TwoSRprime ) == 1 )){
3913 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL+1, TwoSR, ILxIi );
3914 double * Tdown = denT->
gStorage( NL-1, TwoSLprime, ILxIm, NL, TwoSRprime, ILxImxIi );
3915 double * right = denL->
gStorage( NL, TwoSRprime, ILxImxIi, NL+1, TwoSR, ILxIi );
3921 dgemm_( ¬rans, ¬rans, &dimLdown, &dimRup, &dimRdown, &one, Tdown, &dimLdown, right, &dimRdown, &zero, workmem, &dimLdown );
3922 dgemm_( ¬rans, &trans, &dimLdown, &dimLup, &dimRup, &one, workmem, &dimLdown, Tup, &dimLup, &zero, workmem2, &dimLdown );
3925 double factor = sqrt( 0.5 * ( TwoSL + 1 ) * ( TwoSRprime + 1 ) ) * ( TwoSR + 1 )
3928 double * left = fill63->
gStorage( NL-1, TwoSLprime, ILxIm, NL, TwoSL, IL );
3929 int length = dimLup * dimLdown;
3931 daxpy_( &length, &factor, workmem2, &inc, left, &inc );
3933 if ( TwoSRprime == TwoSL ){
3934 double factor = - sqrt( 0.5 ) * ( TwoSR + 1 );
3935 double * left = fill65->
gStorage( NL-1, TwoSLprime, ILxIm, NL, TwoSL, IL );
3936 int length = dimLup * dimLdown;
3938 daxpy_( &length, &factor, workmem2, &inc, left, &inc );
3940 if ( TwoSR == TwoSLprime ){
3941 double factor = sqrt( 0.5 * ( TwoSRprime + 1 ) * ( TwoSL + 1 ) ) *
Special::phase( TwoSL - TwoSRprime );
3942 double * left = fill67->
gStorage( NL-1, TwoSLprime, ILxIm, NL, TwoSL, IL );
3943 int length = dimLup * dimLdown;
3945 daxpy_( &length, &factor, workmem2, &inc, left, &inc );
3948 double factor = sqrt( 6.0 * ( TwoSL + 1 ) * ( TwoSRprime + 1 ) ) * ( TwoSR + 1 )
3951 double * left = fill68->
gStorage( NL-1, TwoSLprime, ILxIm, NL, TwoSL, IL );
3952 int length = dimLup * dimLdown;
3954 daxpy_( &length, &factor, workmem2, &inc, left, &inc );
3957 double factor = sqrt( 6.0 * ( TwoSL + 1 ) * ( TwoSRprime + 1 ) ) * ( TwoSR + 1 )
3961 double * left = fill76->
gStorage( NL-1, TwoSLprime, ILxIm, NL, TwoSL, IL );
3962 int length = dimLup * dimLdown;
3964 daxpy_( &length, &factor, workmem2, &inc, left, &inc );
3967 double factor = - sqrt( 6.0 * ( TwoSL + 1 ) * ( TwoSRprime + 1 ) ) * ( TwoSR + 1 )
3969 double * left = fill77->
gStorage( NL-1, TwoSLprime, ILxIm, NL, TwoSL, IL );
3970 int length = dimLup * dimLdown;
3972 daxpy_( &length, &factor, workmem2, &inc, left, &inc );
3988 const int orb_i = denT->
gIndex();
3993 for (
int NL = book->
gNmin( orb_i ); NL <= book->
gNmax( orb_i ); NL++ ){
3994 for (
int TwoSL = book->
gTwoSmin( orb_i, NL ); TwoSL <= book->
gTwoSmax( orb_i, NL ); TwoSL+=2 ){
4001 for (
int TwoSR = TwoSL-1; TwoSR <= TwoSL+1; TwoSR+=2 ){
4003 int dimLup = book->
gCurrentDim( orb_i, NL, TwoSL, IL );
4004 int dimRup = book->
gCurrentDim( orb_i+1, NL+1, TwoSR, ILxIi );
4006 if (( dimLup > 0 ) && ( dimRup > 0 )){
4008 for (
int TwoSRprime = TwoSR-1; TwoSRprime <= TwoSR+1; TwoSRprime+=2 ){
4009 for (
int TwoSLprime = TwoSRprime-1; TwoSLprime <= TwoSRprime+1; TwoSLprime+=2 ){
4011 int dimLdown = book->
gCurrentDim( orb_i, NL-1, TwoSLprime, ILxIm );
4012 int dimRdown = book->
gCurrentDim( orb_i+1, NL, TwoSRprime, ILxImxIi );
4014 if (( dimLdown > 0 ) && ( dimRdown > 0 )){
4016 double * Tup = denT->
gStorage( NL, TwoSL, IL, NL+1, TwoSR, ILxIi );
4017 double * Tdown = denT->
gStorage( NL-1, TwoSLprime, ILxIm, NL, TwoSRprime, ILxImxIi );
4018 double * right = denL->
gStorage( NL, TwoSRprime, ILxImxIi, NL+1, TwoSR, ILxIi );
4024 dgemm_( ¬rans, ¬rans, &dimLdown, &dimRup, &dimRdown, &one, Tdown, &dimLdown, right, &dimRdown, &zero, workmem, &dimLdown );
4025 dgemm_( ¬rans, &trans, &dimLdown, &dimLup, &dimRup, &one, workmem, &dimLdown, Tup, &dimLup, &zero, workmem2, &dimLdown );
4027 const double prefactor = 2 * sqrt( 3.0 * ( TwoSL + 1 ) * ( TwoSRprime + 1 ) ) * ( TwoSR + 1 );
4029 double factor = prefactor *
Wigner::wigner6j( 1, 1, 2, TwoSR, TwoSLprime, TwoSRprime )
4031 double * left = fill69->
gStorage( NL-1, TwoSLprime, ILxIm, NL, TwoSL, IL );
4032 int length = dimLup * dimLdown;
4034 daxpy_( &length, &factor, workmem2, &inc, left, &inc );
4037 double factor = prefactor *
Wigner::wigner6j( 1, 1, 2, TwoSL, TwoSRprime, TwoSR )
4040 double * left = fill78->
gStorage( NL-1, TwoSLprime, ILxIm, NL, TwoSL, IL );
4041 int length = dimLup * dimLdown;
4043 daxpy_( &length, &factor, workmem2, &inc, left, &inc );
4046 double factor = - prefactor *
Wigner::wigner9j( 1, 1, 2, TwoSLprime, TwoSL, 3, TwoSRprime, TwoSR, 1 );
4047 double * left = fill79->
gStorage( NL-1, TwoSLprime, ILxIm, NL, TwoSL, IL );
4048 int length = dimLup * dimLdown;
4050 daxpy_( &length, &factor, workmem2, &inc, left, &inc );
static double wigner6j(const int two_ja, const int two_jb, const int two_jc, const int two_jd, const int two_je, const int two_jf)
Wigner-6j symbol (gsl api)
int gNmin(const int boundary) const
Get the min. possible particle number for a certain boundary.
void mpi_allreduce()
Add the 3-RDM elements of all MPI processes.
void save_HAM(const string filename) const
Save the 3-RDM to disk in Hamiltonian indices.
bool gReorder() const
Get whether the Hamiltonian orbitals are reordered for the DMRG calculation.
void correct_higher_multiplicities()
After the whole 3-RDM is filled, a prefactor for higher multiplicities should be applied.
int gIndex() const
Get the location index.
int gCurrentDim(const int boundary, const int N, const int TwoS, const int irrep) const
Get the current virtual dimensions.
int get_nelec() const
Get how many electrons there are more in the symmetry sector of the lower leg compared to the upper l...
ThreeDM(const SyBookkeeper *book_in, const Problem *prob_in, const bool disk_in)
Constructor.
static int mpi_rank()
Get the rank of this MPI process.
static void save_HAM_generic(const string filename, const int LAS, const string tag, double *array)
Generic save routine for objects of size LAS**6.
static int phase(const int power_times_two)
Phase function.
int gTwoSmin(const int boundary, const int N) const
Get the minimum possible spin value for a certain boundary and particle number.
void fill_ham_index(const double alpha, const bool add, double *storage, const int last_orb_start, const int last_orb_num)
Perform storage[ :, :, :, :, :, : ] { = or += } alpha * 3-RDM[ :, :, :, :, :, last_orb_start: last_or...
int gTwoSmax(const int boundary, const int N) const
Get the maximum possible spin value for a certain boundary and particle number.
double trace()
Return the trace (should be N(N-1)(N-2))
double contract(Tensor3RDM *buddy) const
Make the in-product of two Tensor3RDMs.
int gTwoS() const
Get twice the targeted spin.
double * gStorage()
Get the pointer to the storage.
int get_two_j1() const
Get the intermediary spin coupling value of the Tensor3RDM.
double inproduct(TensorOperator *buddy, const char trans) const
Make the in-product of two TensorOperator.
double * gStorage()
Get the pointer to the storage.
static void invert_triangle_two(const int global, int *result)
Triangle function for two variables.
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 getNumberOfIrreps() const
Get the total number of irreps.
void fill_site(TensorT *denT, TensorL ***Ltens, TensorF0 ****F0tens, TensorF1 ****F1tens, TensorS0 ****S0tens, TensorS1 ****S1tens, Tensor3RDM ****dm3_a_J0_doublet, Tensor3RDM ****dm3_a_J1_doublet, Tensor3RDM ****dm3_a_J1_quartet, Tensor3RDM ****dm3_b_J0_doublet, Tensor3RDM ****dm3_b_J1_doublet, Tensor3RDM ****dm3_b_J1_quartet, Tensor3RDM ****dm3_c_J0_doublet, Tensor3RDM ****dm3_c_J1_doublet, Tensor3RDM ****dm3_c_J1_quartet, Tensor3RDM ****dm3_d_J0_doublet, Tensor3RDM ****dm3_d_J1_doublet, Tensor3RDM ****dm3_d_J1_quartet)
Fill the 3-RDM terms corresponding to site denT->gIndex()
int gL() const
Get the number of orbitals.
int gMaxDimAtBound(const int boundary) const
Get the maximum virtual dimension at a certain boundary.
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.
int get_two_j2() const
Get the spin value of the Tensor3RDM.
int gNmax(const int boundary) const
Get the max. possible particle number for a certain boundary.
int get_irrep() const
Get the (real-valued abelian) point group irrep difference between the symmetry sectors of the lower ...
void clear()
Set all storage variables to 0.0.
static void invert_triangle_three(const int global, int *result)
Triangle function for three variables.
int gIrrep(const int orbital) const
Get an orbital irrep.
static double wigner9j(const int two_ja, const int two_jb, const int two_jc, const int two_jd, const int two_je, const int two_jf, const int two_jg, const int two_jh, const int two_ji)
Wigner-9j symbol (gsl api)
int gf2(const int DMRGOrb) const
Get the Ham index corresponding to a DMRG index.
virtual ~ThreeDM()
Destructor.