33 #include "MPIchemps2.h" 42 #ifdef CHEMPS2_MPI_COMPILATION 45 const bool am_i_master =
true;
49 for (
int timecnt = 0; timecnt < CHEMPS2_TIME_VECLENGTH; timecnt++ ){ timings[ timecnt ] = 0.0; }
50 num_double_write_disk = 0;
51 num_double_read_disk = 0;
52 struct timeval start_global, end_global, start_part, end_part;
53 gettimeofday( &start_global, NULL );
56 gettimeofday( &start_part, NULL );
57 left_normalize( MPS[ L - 2 ], MPS[ L - 1 ] );
58 left_normalize( MPS[ L - 1 ], NULL );
59 gettimeofday( &end_part, NULL );
60 timings[ CHEMPS2_TIME_S_SPLIT ] += ( end_part.tv_sec - start_part.tv_sec ) + 1e-6 * ( end_part.tv_usec - start_part.tv_usec );
64 cout <<
"****************************************************" << endl;
65 cout <<
"*** 2-RDM, 3-RDM, and Correlations calculation ***" << endl;
66 cout <<
"****************************************************" << endl;
68 cout <<
"********************************************" << endl;
69 cout <<
"*** 2-RDM and Correlations calculation ***" << endl;
70 cout <<
"********************************************" << endl;
75 gettimeofday( &start_part, NULL );
76 updateMovingRightSafe( L - 2 );
77 gettimeofday( &end_part, NULL );
78 timings[ CHEMPS2_TIME_TENS_TOTAL ] += ( end_part.tv_sec - start_part.tv_sec ) + 1e-6 * ( end_part.tv_usec - start_part.tv_usec );
81 if ( the2DM != NULL ){
delete the2DM; the2DM = NULL; }
82 the2DM =
new TwoDM( denBK, Prob );
84 for (
int siteindex = L - 1; siteindex >= 0; siteindex-- ){
86 gettimeofday( &start_part, NULL );
88 the2DM->
FillSite( MPS[ siteindex ], Ltensors, F0tensors, F1tensors, S0tensors, S1tensors );
89 gettimeofday( &end_part, NULL );
90 timings[ CHEMPS2_TIME_S_SOLVE ] += ( end_part.tv_sec - start_part.tv_sec ) + 1e-6 * ( end_part.tv_usec - start_part.tv_usec );
94 gettimeofday( &start_part, NULL );
95 right_normalize( MPS[ siteindex - 1 ], MPS[ siteindex ] );
96 gettimeofday( &end_part, NULL );
97 timings[ CHEMPS2_TIME_S_SPLIT ] += ( end_part.tv_sec - start_part.tv_sec ) + 1e-6 * ( end_part.tv_usec - start_part.tv_usec );
99 gettimeofday( &start_part, NULL );
100 updateMovingLeftSafe2DM( siteindex - 1 );
101 gettimeofday( &end_part, NULL );
102 timings[ CHEMPS2_TIME_TENS_TOTAL ] += ( end_part.tv_sec - start_part.tv_sec ) + 1e-6 * ( end_part.tv_usec - start_part.tv_usec );
106 #ifdef CHEMPS2_MPI_COMPILATION 107 gettimeofday( &start_part, NULL );
109 gettimeofday( &end_part, NULL );
110 timings[ CHEMPS2_TIME_S_SOLVE ] += ( end_part.tv_sec - start_part.tv_sec ) + 1e-6 * ( end_part.tv_usec - start_part.tv_usec );
117 cout <<
" N(N-1) = " << denBK->
gN() * ( denBK->
gN() - 1 ) << endl;
118 cout <<
" Double trace of DMRG 2-RDM = " << the2DM->
trace() << endl;
119 cout <<
" Econst + 0.5 * trace(2DM-A * Ham) = " << the2DM->
energy() << endl;
124 if ( the3DM != NULL ){
delete the3DM; the3DM = NULL; }
125 if ( theCorr != NULL ){
delete theCorr; theCorr = NULL; }
126 if ( do_3rdm ){ the3DM =
new ThreeDM( denBK, Prob, disk_3rdm ); }
136 tensor_3rdm_a_J0_doublet =
new Tensor3RDM****[ L - 1 ];
137 tensor_3rdm_a_J1_doublet =
new Tensor3RDM****[ L - 1 ];
138 tensor_3rdm_a_J1_quartet =
new Tensor3RDM****[ L - 1 ];
139 tensor_3rdm_b_J0_doublet =
new Tensor3RDM****[ L - 1 ];
140 tensor_3rdm_b_J1_doublet =
new Tensor3RDM****[ L - 1 ];
141 tensor_3rdm_b_J1_quartet =
new Tensor3RDM****[ L - 1 ];
142 tensor_3rdm_c_J0_doublet =
new Tensor3RDM****[ L - 1 ];
143 tensor_3rdm_c_J1_doublet =
new Tensor3RDM****[ L - 1 ];
144 tensor_3rdm_c_J1_quartet =
new Tensor3RDM****[ L - 1 ];
145 tensor_3rdm_d_J0_doublet =
new Tensor3RDM****[ L - 1 ];
146 tensor_3rdm_d_J1_doublet =
new Tensor3RDM****[ L - 1 ];
147 tensor_3rdm_d_J1_quartet =
new Tensor3RDM****[ L - 1 ];
150 gettimeofday( &start_part, NULL );
151 the3DM->
fill_site( MPS[ 0 ], Ltensors, F0tensors, F1tensors, S0tensors, S1tensors,
152 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL );
153 gettimeofday( &end_part, NULL );
154 timings[ CHEMPS2_TIME_S_SOLVE ] += ( end_part.tv_sec - start_part.tv_sec ) + 1e-6 * ( end_part.tv_usec - start_part.tv_usec );
157 for (
int siteindex = 1; siteindex < L; siteindex++ ){
160 gettimeofday( &start_part, NULL );
161 left_normalize( MPS[ siteindex - 1 ], MPS[ siteindex ] );
162 gettimeofday( &end_part, NULL );
163 timings[ CHEMPS2_TIME_S_SPLIT ] += ( end_part.tv_sec - start_part.tv_sec ) + 1e-6 * ( end_part.tv_usec - start_part.tv_usec );
166 gettimeofday( &start_part, NULL );
167 if ( do_3rdm ){ update_safe_3rdm_operators( siteindex ); }
168 updateMovingRightSafe2DM( siteindex - 1 );
169 if ( am_i_master ){ update_correlations_tensors( siteindex ); }
170 gettimeofday( &end_part, NULL );
171 timings[ CHEMPS2_TIME_TENS_TOTAL ] += ( end_part.tv_sec - start_part.tv_sec ) + 1e-6 * ( end_part.tv_usec - start_part.tv_usec );
174 gettimeofday( &start_part, NULL );
175 if ( am_i_master ){ theCorr->
FillSite( MPS[ siteindex ], Gtensors, Ytensors, Ztensors, Ktensors, Mtensors ); }
176 if ( do_3rdm ){ the3DM->
fill_site( MPS[ siteindex ], Ltensors, F0tensors, F1tensors, S0tensors, S1tensors,
177 tensor_3rdm_a_J0_doublet[ siteindex - 1 ], tensor_3rdm_a_J1_doublet[ siteindex - 1 ], tensor_3rdm_a_J1_quartet[ siteindex - 1 ],
178 tensor_3rdm_b_J0_doublet[ siteindex - 1 ], tensor_3rdm_b_J1_doublet[ siteindex - 1 ], tensor_3rdm_b_J1_quartet[ siteindex - 1 ],
179 tensor_3rdm_c_J0_doublet[ siteindex - 1 ], tensor_3rdm_c_J1_doublet[ siteindex - 1 ], tensor_3rdm_c_J1_quartet[ siteindex - 1 ],
180 tensor_3rdm_d_J0_doublet[ siteindex - 1 ], tensor_3rdm_d_J1_doublet[ siteindex - 1 ], tensor_3rdm_d_J1_quartet[ siteindex - 1 ] ); }
181 gettimeofday( &end_part, NULL );
182 timings[ CHEMPS2_TIME_S_SOLVE ] += ( end_part.tv_sec - start_part.tv_sec ) + 1e-6 * ( end_part.tv_usec - start_part.tv_usec );
186 gettimeofday( &start_part, NULL );
187 assert( isAllocated[ L - 2 ] == 1 );
188 assert( isAllocated[ L - 3 ] == 0 );
189 deleteTensors( L - 2,
true ); isAllocated[ L - 2 ] = 0;
190 allocateTensors( L - 3,
true ); isAllocated[ L - 3 ] = 1;
191 OperatorsOnDisk( L - 3,
true,
false );
192 gettimeofday( &end_part, NULL );
193 timings[ CHEMPS2_TIME_TENS_TOTAL ] += ( end_part.tv_sec - start_part.tv_sec ) + 1e-6 * ( end_part.tv_usec - start_part.tv_usec );
195 #ifdef CHEMPS2_MPI_COMPILATION 196 gettimeofday( &start_part, NULL );
199 gettimeofday( &end_part, NULL );
200 timings[ CHEMPS2_TIME_S_SOLVE ] += ( end_part.tv_sec - start_part.tv_sec ) + 1e-6 * ( end_part.tv_usec - start_part.tv_usec );
205 delete_3rdm_operators( L - 1 );
206 delete [] tensor_3rdm_a_J0_doublet;
207 delete [] tensor_3rdm_a_J1_doublet;
208 delete [] tensor_3rdm_a_J1_quartet;
209 delete [] tensor_3rdm_b_J0_doublet;
210 delete [] tensor_3rdm_b_J1_doublet;
211 delete [] tensor_3rdm_b_J1_quartet;
212 delete [] tensor_3rdm_c_J0_doublet;
213 delete [] tensor_3rdm_c_J1_doublet;
214 delete [] tensor_3rdm_c_J1_quartet;
215 delete [] tensor_3rdm_d_J0_doublet;
216 delete [] tensor_3rdm_d_J1_doublet;
217 delete [] tensor_3rdm_d_J1_quartet;
221 for (
int previousindex = 0; previousindex < L - 1; previousindex++ ){
222 delete Gtensors[ previousindex ];
223 delete Ytensors[ previousindex ];
224 delete Ztensors[ previousindex ];
225 delete Ktensors[ previousindex ];
226 delete Mtensors[ previousindex ];
235 gettimeofday( &end_global, NULL );
236 const double elapsed_global = ( end_global.tv_sec - start_global.tv_sec ) + 1e-6 * ( end_global.tv_usec - start_global.tv_usec );
239 cout <<
" Single-orbital entropies (Hamiltonian index order is used!) = [ ";
242 for (
int power = 0; power <= 2; power++ ){
245 if ( do_3rdm ){ cout <<
" N(N-1)(N-2) = " << denBK->
gN() * ( denBK->
gN() - 1 ) * ( denBK->
gN() - 2 ) << endl;
246 cout <<
" Triple trace of DMRG 3-RDM = " << the3DM->
trace() << endl;
247 cout <<
"***********************************************************" << endl;
248 cout <<
"*** Timing information 2-RDM, 3-RDM, and Correlations ***" << endl;
249 cout <<
"***********************************************************" << endl; }
250 else { cout <<
"***************************************************" << endl;
251 cout <<
"*** Timing information 2-RDM and Correlations ***" << endl;
252 cout <<
"***************************************************" << endl; }
253 cout <<
"*** Elapsed wall time = " << elapsed_global <<
" seconds" << endl;
254 cout <<
"*** |--> MPS gauge change = " << timings[ CHEMPS2_TIME_S_SPLIT ] <<
" seconds" << endl;
255 cout <<
"*** |--> Diagram calc = " << timings[ CHEMPS2_TIME_S_SOLVE ] <<
" seconds" << endl;
256 print_tensor_update_performance();
257 if ( do_3rdm ){ cout <<
"***********************************************************" << endl; }
258 else { cout <<
"***************************************************" << endl; }
263 void CheMPS2::DMRG::print_tensor_update_performance()
const{
265 cout <<
"*** |--> Tensor update = " << timings[ CHEMPS2_TIME_TENS_TOTAL ] <<
" seconds" << endl;
266 cout <<
"*** |--> create = " << timings[ CHEMPS2_TIME_TENS_ALLOC ] <<
" seconds" << endl;
267 cout <<
"*** |--> destroy = " << timings[ CHEMPS2_TIME_TENS_FREE ] <<
" seconds" << endl;
268 cout <<
"*** |--> disk write = " << timings[ CHEMPS2_TIME_DISK_WRITE ] <<
" seconds" << endl;
269 cout <<
"*** |--> disk read = " << timings[ CHEMPS2_TIME_DISK_READ ] <<
" seconds" << endl;
270 cout <<
"*** |--> calc = " << timings[ CHEMPS2_TIME_TENS_CALC ] <<
" seconds" << endl;
271 cout <<
"*** Disk write bandwidth = " << num_double_write_disk *
sizeof(double) / ( timings[ CHEMPS2_TIME_DISK_WRITE ] * 1048576 ) <<
" MB/s" << endl;
272 cout <<
"*** Disk read bandwidth = " << num_double_read_disk *
sizeof(double) / ( timings[ CHEMPS2_TIME_DISK_READ ] * 1048576 ) <<
" MB/s" << endl;
276 void CheMPS2::DMRG::left_normalize(
TensorT * left_mps,
TensorT * right_mps ){
278 #ifdef CHEMPS2_MPI_COMPILATION 281 const bool am_i_master =
true;
285 const int siteindex = left_mps->
gIndex();
289 left_mps->
QR( temp );
290 if ( right_mps != NULL ){ right_mps->
LeftMultiply( temp ); }
293 #ifdef CHEMPS2_MPI_COMPILATION 294 MPIchemps2::broadcast_tensor( left_mps, MPI_CHEMPS2_MASTER );
295 if ( right_mps != NULL ){ MPIchemps2::broadcast_tensor( right_mps, MPI_CHEMPS2_MASTER ); }
300 void CheMPS2::DMRG::right_normalize(
TensorT * left_mps,
TensorT * right_mps ){
302 #ifdef CHEMPS2_MPI_COMPILATION 305 const bool am_i_master =
true;
309 const int siteindex = right_mps->
gIndex();
313 right_mps->
LQ( temp );
317 #ifdef CHEMPS2_MPI_COMPILATION 318 MPIchemps2::broadcast_tensor( right_mps, MPI_CHEMPS2_MASTER );
319 if ( left_mps != NULL ){ MPIchemps2::broadcast_tensor( left_mps, MPI_CHEMPS2_MASTER ); }
326 int * alpha =
new int[ L ];
327 int * beta =
new int[ L ];
328 for (
int orb=0; orb<L; orb++ ){
329 assert( ( coeff[orb] >= 0 ) && ( coeff[orb] <= 2 ) );
330 if ( coeff[orb] == 0 ){ alpha[orb] = 0; beta[orb] = 0; }
331 if ( coeff[orb] == 1 ){ alpha[orb] = 1; beta[orb] = 0; }
332 if ( coeff[orb] == 2 ){ alpha[orb] = 1; beta[orb] = 1; }
350 for (
int DMRGindex=0; DMRGindex<L; DMRGindex++){
351 const int HamIndex = (Prob->
gReorder()) ? Prob->
gf2(DMRGindex) : DMRGindex;
352 assert( ( alpha[HamIndex] == 0 ) || ( alpha[HamIndex] == 1 ) );
353 assert( ( beta[HamIndex] == 0 ) || ( beta[HamIndex] == 1 ) );
354 nTot += alpha[HamIndex] + beta[HamIndex];
355 twoSz += alpha[HamIndex] - beta[HamIndex];
358 if ( Prob->
gN() != nTot ){
359 cout <<
"DMRG::getFCIcoefficient : Ndesired = " << Prob->
gN() <<
" and Ntotal in alpha and beta strings = " << nTot << endl;
363 if ( ( Prob->
gTwoS() < twoSz ) || ( twoSz < -Prob->gTwoS() ) || ( ( Prob->
gTwoS() - twoSz ) % 2 != 0 ) ){
364 cout <<
"DMRG::getFCIcoefficient : 2Sdesired = " << Prob->
gTwoS() <<
" and 2Sz in alpha and beta strings = " << twoSz << endl;
367 if ( Prob->
gIrrep() != iTot ){
368 cout <<
"DMRG::getFCIcoefficient : Idesired = " << Prob->
gIrrep() <<
" and Irrep of alpha and beta strings = " << iTot << endl;
373 double theCoeff = 2.0;
374 #ifdef CHEMPS2_MPI_COMPILATION 381 for (
int DMRGindex=1; DMRGindex<L; DMRGindex++){
383 if (DtotBound>Dmax){ Dmax = DtotBound; }
385 double * arrayL =
new double[Dmax];
386 double * arrayR =
new double[Dmax];
387 int * twoSL =
new int[L];
388 int * twoSR =
new int[L];
389 int * jumpL =
new int[L+1];
390 int * jumpR =
new int[L+1];
396 jumpL[num_SL+1] = jumpL[num_SL] + dimFirst;
404 for (
int DMRGindex=0; DMRGindex<L; DMRGindex++){
407 for (
int count = 0; count < Dmax; count++){ arrayR[count] = 0.0; }
410 const int HamIndex = (Prob->
gReorder()) ? Prob->
gf2(DMRGindex) : DMRGindex;
411 const int Nlocal = alpha[HamIndex] + beta[HamIndex];
412 const int twoSzloc = alpha[HamIndex] - beta[HamIndex];
415 const int NR = NL + Nlocal;
416 const int twoSRz = twoSLz + twoSzloc;
421 const int spread = ( ( Nlocal == 1 ) ? 1 : 0 );
422 for (
int cntSL = 0; cntSL < num_SL; cntSL++ ){
423 for (
int TwoSRattempt = twoSL[cntSL] - spread; TwoSRattempt <= twoSL[cntSL] + spread; TwoSRattempt+=2 ){
424 bool encountered =
false;
425 for (
int cntSR = 0; cntSR < num_SR; cntSR++ ){
426 if ( twoSR[cntSR] == TwoSRattempt ){
430 if ( encountered ==
false ){
431 const int dimR = denBK->
gCurrentDim(DMRGindex+1,NR,TwoSRattempt,IR);
433 jumpR[num_SR+1] = jumpR[num_SR] + dimR;
434 twoSR[num_SR] = TwoSRattempt;
440 assert( jumpR[num_SR] <= Dmax );
442 for (
int cntSR = 0; cntSR < num_SR; cntSR++ ){
443 int TwoSRvalue = twoSR[ cntSR ];
444 int dimR = jumpR[ cntSR+1 ] - jumpR[ cntSR ];
445 for (
int TwoSLvalue = TwoSRvalue - spread; TwoSLvalue <= TwoSRvalue + spread; TwoSLvalue += 2 ){
448 for (
int cntSL = 0; cntSL < num_SL; cntSL++ ){
449 if ( twoSL[cntSL] == TwoSLvalue ){
454 if ( indexSL != -1 ){
455 int dimL = jumpL[ indexSL+1 ] - jumpL[ indexSL ];
456 double * Tblock = MPS[DMRGindex]->
gStorage(NL,TwoSLvalue,IL,NR,TwoSRvalue,IR);
457 double prefactor = sqrt( TwoSRvalue + 1 )
458 *
Wigner::wigner3j(TwoSLvalue, spread, TwoSRvalue, twoSLz, twoSzloc, -twoSRz)
460 double add2array = 1.0;
462 dgemm_( ¬rans, ¬rans, &dimFirst, &dimR, &dimL, &prefactor, arrayL + jumpL[indexSL], &dimFirst, Tblock, &dimL, &add2array, arrayR + jumpR[cntSR], &dimFirst);
469 double * temp = arrayR;
485 theCoeff = arrayL[0];
487 assert( num_SL == 1 );
488 assert( jumpL[1] == 1 );
489 assert( twoSL[0] == Prob->
gTwoS() );
490 assert( NL == Prob->
gN() );
491 assert( IL == Prob->
gIrrep() );
502 #ifdef CHEMPS2_MPI_COMPILATION 503 if ( mpi_chemps2_master_only ){ MPIchemps2::broadcast_array_double( &theCoeff, 1, MPI_CHEMPS2_MASTER ); }
509 double ** CheMPS2::DMRG::prepare_excitations(
Sobject * denS){
511 double ** VeffTilde =
new double*[nStates-1];
512 for (
int state=0; state<nStates-1; state++){
513 #ifdef CHEMPS2_MPI_COMPILATION 517 calcVeffTilde(VeffTilde[state], denS, state);
518 #ifdef CHEMPS2_MPI_COMPILATION 519 }
else { VeffTilde[state] = NULL; }
526 void CheMPS2::DMRG::cleanup_excitations(
double ** VeffTilde)
const{
528 for (
int state=0; state<nStates-1; state++){
529 #ifdef CHEMPS2_MPI_COMPILATION 533 delete [] VeffTilde[state];
540 void CheMPS2::DMRG::calcVeffTilde(
double * result,
Sobject * currentS,
int state_number){
543 for (
int cnt=0; cnt<dimTot; cnt++){ result[cnt] = 0.0; }
544 int index = currentS->
gIndex();
548 double * workmem =
new double[dimL * dimR];
552 Sup->
Join(Exc_MPSs[state_number][index],Exc_MPSs[state_number][index+1]);
555 const double prefactor = sqrt(Exc_Eshifts[state_number]) / (Prob->
gTwoS() + 1.0);
556 for (
int ikappa=0; ikappa<currentS->
gNKappa(); ikappa++){
557 int NL = currentS->
gNL(ikappa);
558 int TwoSL = currentS->
gTwoSL(ikappa);
559 int IL = currentS->
gIL(ikappa);
560 int N1 = currentS->
gN1(ikappa);
561 int N2 = currentS->
gN2(ikappa);
562 int TwoJ = currentS->
gTwoJ(ikappa);
563 int NR = currentS->
gNR(ikappa);
564 int TwoSR = currentS->
gTwoSR(ikappa);
565 int IR = currentS->
gIR(ikappa);
568 int kappaSup = Sup->
gKappa(NL, TwoSL, IL, N1, N2, TwoJ, NR, TwoSR, IR);
571 int dimLdown = denBK->
gCurrentDim(index, NL,TwoSL,IL);
572 int dimLup = Exc_BKs[state_number]->
gCurrentDim(index, NL,TwoSL,IL);
573 int dimRdown = denBK->
gCurrentDim(index+2,NR,TwoSR,IR);
574 int dimRup = Exc_BKs[state_number]->
gCurrentDim(index+2,NR,TwoSR,IR);
578 double alpha = prefactor * sqrt(TwoSR+1.0);
581 int dimBlock = dimLup * dimRup;
583 dcopy_(&dimBlock,SupPart,&inc,workmem,&inc);
584 dscal_(&dimBlock,&alpha,workmem,&inc);
590 double * Opart = Exc_Overlaps[state_number][index-1]->
gStorage(NL,TwoSL,IL,NL,TwoSL,IL);
591 dgemm_(¬rans,¬rans,&dimLdown,&dimRup,&dimLup,&alpha,Opart,&dimLdown,SupPart,&dimLup,&beta,workmem,&dimLdown);
599 int dimBlock = dimLdown * dimRdown;
601 dcopy_(&dimBlock, workmem, &inc, result + jumpCurrentS, &inc);
609 double * Opart = Exc_Overlaps[state_number][index+1]->
gStorage(NR,TwoSR,IR,NR,TwoSR,IR);
610 dgemm_(¬rans,&trans,&dimLdown,&dimRdown,&dimRup,&alpha,workmem,&dimLdown,Opart,&dimRdown,&beta,result+jumpCurrentS,&dimLdown);
622 void CheMPS2::DMRG::calc_overlaps(
const bool moving_right ){
624 for (
int state = 0; state < nStates - 1; state++ ){
627 #ifdef CHEMPS2_MPI_COMPILATION 628 const int OWNER = MPIchemps2::owner_specific_excitation( L, state );
632 TensorO * first =
new TensorO( L - 1, moving_right, denBK, Exc_BKs[ state ] );
633 TensorO * second =
new TensorO( L, moving_right, denBK, Exc_BKs[ state ] );
634 first->
update_ownmem( MPS[ L - 2 ], Exc_MPSs[ state ][ L - 2 ], Exc_Overlaps[ state ][ L - 3 ] );
635 second->
update_ownmem( MPS[ L - 1 ], Exc_MPSs[ state ][ L - 1 ], first );
640 TensorO * first =
new TensorO( 1, moving_right, denBK, Exc_BKs[ state ] );
641 TensorO * second =
new TensorO( 0, moving_right, denBK, Exc_BKs[ state ] );
642 first->
update_ownmem( MPS[ 1 ], Exc_MPSs[ state ][ 1 ], Exc_Overlaps[ state ][ 1 ] );
643 second->
update_ownmem( MPS[ 0 ], Exc_MPSs[ state ][ 0 ], first );
648 #ifdef CHEMPS2_MPI_COMPILATION 650 MPIchemps2::broadcast_array_double( &overlap, 1, OWNER );
654 { cout <<
"*** The overlap < " << nStates-1 <<
" | " << state <<
" > = " << overlap << endl; }
int gTwoSL(const int ikappa) const
Get the left spin symmetry of block ikappa.
void FillSite(TensorT *denT, TensorL ***Ltens, TensorF0 ****F0tens, TensorF1 ****F1tens, TensorS0 ****S0tens, TensorS1 ****S1tens)
Fill the 2DM terms with as second site index denT->gIndex()
void mpi_allreduce()
Add the 3-RDM elements of all MPI processes.
int gTotDimAtBound(const int boundary) const
Get the total reduced virtual dimension at a certain boundary.
void RightMultiply(Tensor *Mx)
Multiply at the right with a diagonal TensorOperator.
void LQ(Tensor *Lstorage)
Right-normalization.
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.
void FillSite(TensorT *denT, TensorGYZ **Gtensors, TensorGYZ **Ytensors, TensorGYZ **Ztensors, TensorKM **Ktensors, TensorKM **Mtensors)
Fill at the current step of the iterations the two-orbital mutual information and the remaining part ...
int gCurrentDim(const int boundary, const int N, const int TwoS, const int irrep) const
Get the current virtual dimensions.
int gKappa2index(const int kappa) const
Get the storage jump corresponding to a certain symmetry block.
static int mpi_rank()
Get the rank of this MPI process.
double SingleOrbitalEntropy_HAM(const int index) const
Get the single-orbital entropy for a certain site, using hte HAM indices.
static int phase(const int power_times_two)
Phase function.
void mpi_broadcast()
Broadcast the diradical correlation function and the two-orbital mutual information.
int gTwoJ(const int ikappa) const
Get the central spin symmetry of block ikappa.
double energy() const
Calculate the energy based on the 2DM-A.
double trace()
Return the trace (should be N(N-1)(N-2))
void correct_higher_multiplicities()
After the whole 2-RDM is filled, a prefactor for higher multiplicities should be applied.
void update_ownmem(TensorT *mps_tensor_up, TensorT *mps_tensor_down, TensorO *previous)
Update the previous TensorO.
int gN() const
Get the targeted particle number.
int gNKappa() const
Get the number of symmetry blocks.
int gTwoS() const
Get twice the targeted spin.
double * gStorage()
Get the pointer to the storage.
double getFCIcoefficient(int *alpha, int *beta, const bool mpi_chemps2_master_only=true) const
Get a specific FCI coefficient. The arrays alpha and beta contain the alpha and beta occupation numbe...
int gIL(const int ikappa) const
Get the left irrep symmetry of block ikappa.
double * gStorage()
Get the pointer to the storage.
int gIrrep(const int nOrb) const
Get an orbital irrep.
double trace() const
Return the double trace of 2DM-A (should be N(N-1))
double * gStorage()
Get the pointer to the storage.
static double wigner3j(const int two_ja, const int two_jb, const int two_jc, const int two_ma, const int two_mb, const int two_mc)
Wigner-3j symbol (gsl api)
double MutualInformationDistance(const double power) const
Return Idistance(power) (see return for definition)
int gKappa(const int NL, const int TwoSL, const int IL, const int N1, const int N2, const int TwoJ, const int NR, const int TwoSR, const int IR) const
Get the index corresponding to a certain symmetry block.
void Join(TensorT *Tleft, TensorT *Tright)
Join two sites to form a composite S-object.
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...
void QR(Tensor *Rstorage)
Left-normalization.
void LeftMultiply(Tensor *Mx)
Multiply at the left with a diagonal TensorOperator.
const SyBookkeeper * gBK() const
Get the pointer to the symmetry bookkeeper.
void mpi_allreduce()
Add the 2-RDM elements of all MPI processes.
double getSpecificCoefficient(int *coeff) const
Get a specific FCI coefficient. The array coeff contains the occupation numbers of the L Hamiltonian ...
void print_noon() const
Print the natural orbital occupation numbers.
int gNL(const int ikappa) const
Get the left particle number symmetry of block ikappa.
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 gIR(const int ikappa) const
Get the right irrep symmetry of block ikappa.
int gTwoSR(const int ikappa) const
Get the right spin symmetry of block ikappa.
int gIndex() const
Get the location index.
int gMaxDimAtBound(const int boundary) const
Get the maximum virtual dimension at a certain boundary.
void calc_rdms_and_correlations(const bool do_3rdm, const bool disk_3rdm=false)
Calculate the reduced density matrices and correlations. Afterwards the MPS is again in LLLLLLLC gaug...
int gNR(const int ikappa) const
Get the right particle number symmetry of block ikappa.
int gIrrep(const int orbital) const
Get an orbital irrep.
int gN1(const int ikappa) const
Get the left local particle number symmetry of block ikappa.
int gN() const
Get the targeted particle number.
int gf2(const int DMRGOrb) const
Get the Ham index corresponding to a DMRG index.
int gN2(const int ikappa) const
Get the right local particle number symmetry of block ikappa.