31 #include "MPIchemps2.h" 38 #ifdef CHEMPS2_MPI_COMPILATION 47 Prob->construct_mxelem();
48 OptScheme = OptSchemeIn;
52 Ltensors =
new TensorL ** [ L - 1 ];
53 F0tensors =
new TensorF0 *** [ L - 1 ];
54 F1tensors =
new TensorF1 *** [ L - 1 ];
55 S0tensors =
new TensorS0 *** [ L - 1 ];
56 S1tensors =
new TensorS1 *** [ L - 1 ];
61 Qtensors =
new TensorQ ** [ L - 1 ];
62 Xtensors =
new TensorX * [ L - 1 ];
63 isAllocated =
new int[ L - 1 ];
65 tensor_3rdm_a_J0_doublet = NULL;
66 tensor_3rdm_a_J1_doublet = NULL;
67 tensor_3rdm_a_J1_quartet = NULL;
68 tensor_3rdm_b_J0_doublet = NULL;
69 tensor_3rdm_b_J1_doublet = NULL;
70 tensor_3rdm_b_J1_quartet = NULL;
71 tensor_3rdm_c_J0_doublet = NULL;
72 tensor_3rdm_c_J1_doublet = NULL;
73 tensor_3rdm_c_J1_quartet = NULL;
74 tensor_3rdm_d_J0_doublet = NULL;
75 tensor_3rdm_d_J1_doublet = NULL;
76 tensor_3rdm_d_J1_quartet = NULL;
84 for (
int cnt = 0; cnt < L - 1; cnt++ ){ isAllocated[ cnt ] = 0; }
85 for (
int timecnt = 0; timecnt < CHEMPS2_TIME_VECLENGTH; timecnt++ ){ timings[ timecnt ] = 0.0; }
86 num_double_write_disk = 0;
87 num_double_read_disk = 0;
92 Exc_activated =
false;
93 makecheckpoints = makechkpt;
94 tempfolder = tmpfolder;
96 setupBookkeeperAndMPS();
101 void CheMPS2::DMRG::setupBookkeeperAndMPS(){
106 std::stringstream sstream;
107 sstream << CheMPS2::DMRG_MPS_storage_prefix << nStates-1 <<
".h5";
108 MPSstoragename.assign( sstream.str() );
109 struct stat stFileInfo;
110 int intStat = stat( MPSstoragename.c_str(), &stFileInfo );
111 loadedMPS = (( makecheckpoints ) && ( intStat==0 )) ?
true :
false;
112 #ifdef CHEMPS2_MPI_COMPILATION 113 assert( MPIchemps2::all_booleans_equal( loadedMPS ) );
116 if ( loadedMPS ){ loadDIM( MPSstoragename, denBK ); }
119 for (
int cnt = 0; cnt < L; cnt++ ){ MPS[ cnt ] =
new TensorT( cnt, denBK ); }
123 loadMPS( MPSstoragename, MPS, &isConverged );
124 #ifdef CHEMPS2_MPI_COMPILATION 127 { cout <<
"Loaded MPS " << MPSstoragename <<
" converged y/n? : " << isConverged << endl; }
129 #ifdef CHEMPS2_MPI_COMPILATION 132 const bool am_i_master =
true;
134 for (
int site = 0; site < L; site++ ){
135 if ( am_i_master ){ MPS[ site ]->
random(); }
136 left_normalize( MPS[ site ], NULL );
144 if ( the2DM != NULL ){
delete the2DM; }
145 if ( the3DM != NULL ){
delete the3DM; }
146 if ( theCorr != NULL ){
delete theCorr; }
148 deleteAllBoundaryOperators();
161 delete [] isAllocated;
163 for (
int site = 0; site < L; site++ ){
delete MPS[ site ]; }
166 if ( Exc_activated ){
167 delete [] Exc_Eshifts;
168 for (
int state = 0; state < nStates - 1; state++ ){
169 #ifdef CHEMPS2_MPI_COMPILATION 173 for (
int orb = 0; orb < L; orb++ ){
delete Exc_MPSs[ state ][ orb ]; }
174 delete [] Exc_MPSs[ state ];
175 delete Exc_BKs[ state ];
176 delete [] Exc_Overlaps[ state ];
181 delete [] Exc_Overlaps;
190 deleteAllBoundaryOperators();
192 for (
int cnt = 0; cnt < L - 2; cnt++ ){ updateMovingRightSafeFirstTime( cnt ); }
194 TotalMinEnergy = 1e8;
195 MaxDiscWeightLastSweep = 0.0;
201 bool change = ( TotalMinEnergy < 1e8 ) ?
true :
false;
205 #ifdef CHEMPS2_MPI_COMPILATION 208 const bool am_i_master =
true;
211 for (
int instruction = 0; instruction < OptScheme->
get_number(); instruction++ ){
214 double EnergyPrevious = Energy + 10 * OptScheme->
get_energy_conv( instruction );
216 while (( fabs( Energy - EnergyPrevious ) > OptScheme->
get_energy_conv( instruction ) ) && ( nIterations < OptScheme->get_max_sweeps( instruction ) )){
218 for (
int timecnt = 0; timecnt < CHEMPS2_TIME_VECLENGTH; timecnt++ ){ timings[ timecnt ] = 0.0; }
219 num_double_write_disk = 0;
220 num_double_read_disk = 0;
221 struct timeval start, end;
222 EnergyPrevious = Energy;
223 gettimeofday( &start, NULL );
224 Energy = sweepleft( change, instruction, am_i_master );
225 gettimeofday( &end, NULL );
226 double elapsed = ( end.tv_sec - start.tv_sec ) + 1e-6 * ( end.tv_usec - start.tv_usec );
228 cout <<
"******************************************************************" << endl;
229 cout <<
"*** Information on left sweep " << nIterations <<
" of instruction " << instruction <<
":" << endl;
230 cout <<
"*** Elapsed wall time = " << elapsed <<
" seconds" << endl;
231 cout <<
"*** |--> S.join = " << timings[ CHEMPS2_TIME_S_JOIN ] <<
" seconds" << endl;
232 cout <<
"*** |--> S.solve = " << timings[ CHEMPS2_TIME_S_SOLVE ] <<
" seconds" << endl;
233 cout <<
"*** |--> S.split = " << timings[ CHEMPS2_TIME_S_SPLIT ] <<
" seconds" << endl;
234 print_tensor_update_performance();
235 cout <<
"*** Minimum energy = " << LastMinEnergy << endl;
236 cout <<
"*** Maximum discarded weight = " << MaxDiscWeightLastSweep << endl;
238 if ( Exc_activated ){ calc_overlaps(
false ); }
240 cout <<
"******************************************************************" << endl;
243 for (
int timecnt = 0; timecnt < CHEMPS2_TIME_VECLENGTH; timecnt++ ){ timings[ timecnt ] = 0.0; }
244 num_double_write_disk = 0;
245 num_double_read_disk = 0;
246 gettimeofday( &start, NULL );
247 Energy = sweepright( change, instruction, am_i_master );
248 gettimeofday( &end, NULL );
249 elapsed = ( end.tv_sec - start.tv_sec ) + 1e-6 * ( end.tv_usec - start.tv_usec );
251 cout <<
"******************************************************************" << endl;
252 cout <<
"*** Information on right sweep " << nIterations <<
" of instruction " << instruction <<
":" << endl;
253 cout <<
"*** Elapsed wall time = " << elapsed <<
" seconds" << endl;
254 cout <<
"*** |--> S.join = " << timings[ CHEMPS2_TIME_S_JOIN ] <<
" seconds" << endl;
255 cout <<
"*** |--> S.solve = " << timings[ CHEMPS2_TIME_S_SOLVE ] <<
" seconds" << endl;
256 cout <<
"*** |--> S.split = " << timings[ CHEMPS2_TIME_S_SPLIT ] <<
" seconds" << endl;
257 print_tensor_update_performance();
258 cout <<
"*** Minimum energy = " << LastMinEnergy << endl;
259 cout <<
"*** Maximum discarded weight = " << MaxDiscWeightLastSweep << endl;
260 cout <<
"*** Energy difference with respect to previous leftright sweep = " << fabs(Energy-EnergyPrevious) << endl;
262 if ( Exc_activated ){ calc_overlaps(
true ); }
264 cout <<
"******************************************************************" << endl;
265 if ( makecheckpoints ){ saveMPS( MPSstoragename, MPS, denBK,
false ); }
273 cout <<
"*** Information on completed instruction " << instruction <<
":" << endl;
274 cout <<
"*** The reduced virtual dimension DSU(2) = " << OptScheme->
get_D(instruction) << endl;
275 cout <<
"*** Minimum energy encountered during all instructions = " << TotalMinEnergy << endl;
276 cout <<
"*** Minimum energy encountered during the last sweep = " << LastMinEnergy << endl;
277 cout <<
"*** Maximum discarded weight during the last sweep = " << MaxDiscWeightLastSweep << endl;
278 cout <<
"******************************************************************" << endl;
283 return TotalMinEnergy;
287 double CheMPS2::DMRG::sweepleft(
const bool change,
const int instruction,
const bool am_i_master ){
290 const double noise_level = fabs( OptScheme->
get_noise_prefactor( instruction ) ) * MaxDiscWeightLastSweep;
292 const int vir_dimension = OptScheme->
get_D( instruction );
293 MaxDiscWeightLastSweep = 0.0;
296 for (
int index = L - 2; index > 0; index-- ){
298 Energy = solve_site( index, dvdson_rtol, noise_level, vir_dimension, am_i_master,
false, change );
299 if ( Energy < TotalMinEnergy ){ TotalMinEnergy = Energy; }
300 if ( Energy < LastMinEnergy ){ LastMinEnergy = Energy; }
302 cout <<
"Energy at sites (" << index <<
", " << index + 1 <<
") is " << Energy << endl;
306 struct timeval start, end;
307 gettimeofday( &start, NULL );
308 updateMovingLeftSafe( index );
309 gettimeofday( &end, NULL );
310 timings[ CHEMPS2_TIME_TENS_TOTAL ] += ( end.tv_sec - start.tv_sec ) + 1e-6 * ( end.tv_usec - start.tv_usec );
318 double CheMPS2::DMRG::sweepright(
const bool change,
const int instruction,
const bool am_i_master ){
321 const double noise_level = fabs( OptScheme->
get_noise_prefactor( instruction ) ) * MaxDiscWeightLastSweep;
323 const int vir_dimension = OptScheme->
get_D( instruction );
324 MaxDiscWeightLastSweep = 0.0;
327 for (
int index = 0; index < L - 2; index++ ){
329 Energy = solve_site( index, dvdson_rtol, noise_level, vir_dimension, am_i_master,
true, change );
330 if ( Energy < TotalMinEnergy ){ TotalMinEnergy = Energy; }
331 if ( Energy < LastMinEnergy ){ LastMinEnergy = Energy; }
333 cout <<
"Energy at sites (" << index <<
", " << index + 1 <<
") is " << Energy << endl;
337 struct timeval start, end;
338 gettimeofday( &start, NULL );
339 updateMovingRightSafe( index );
340 gettimeofday( &end, NULL );
341 timings[ CHEMPS2_TIME_TENS_TOTAL ] += ( end.tv_sec - start.tv_sec ) + 1e-6 * ( end.tv_usec - start.tv_usec );
349 double CheMPS2::DMRG::solve_site(
const int index,
const double dvdson_rtol,
const double noise_level,
const int virtual_dimension,
const bool am_i_master,
const bool moving_right,
const bool change ){
351 struct timeval start, end;
354 gettimeofday( &start, NULL );
356 denS->
Join( MPS[ index ], MPS[ index + 1 ] );
357 gettimeofday( &end, NULL );
358 timings[ CHEMPS2_TIME_S_JOIN ] += ( end.tv_sec - start.tv_sec ) + 1e-6 * ( end.tv_usec - start.tv_usec );
361 gettimeofday( &start, NULL );
362 Heff Solver( denBK, Prob, dvdson_rtol );
363 double ** VeffTilde = NULL;
364 if ( Exc_activated ){ VeffTilde = prepare_excitations( denS ); }
365 double Energy = Solver.
SolveDAVIDSON( denS, Ltensors, Atensors, Btensors, Ctensors, Dtensors, S0tensors, S1tensors, F0tensors, F1tensors, Qtensors, Xtensors, nStates - 1, VeffTilde );
367 if ( Exc_activated ){ cleanup_excitations( VeffTilde ); }
368 gettimeofday( &end, NULL );
369 timings[ CHEMPS2_TIME_S_SOLVE ] += ( end.tv_sec - start.tv_sec ) + 1e-6 * ( end.tv_usec - start.tv_usec );
372 gettimeofday( &start, NULL );
373 if (( noise_level > 0.0 ) && ( am_i_master )){ denS->
addNoise( noise_level ); }
374 const double discWeight = denS->
Split( MPS[ index ], MPS[ index + 1 ], virtual_dimension, moving_right, change );
376 if ( discWeight > MaxDiscWeightLastSweep ){ MaxDiscWeightLastSweep = discWeight; }
377 gettimeofday( &end, NULL );
378 timings[ CHEMPS2_TIME_S_SPLIT ] += ( end.tv_sec - start.tv_sec ) + 1e-6 * ( end.tv_usec - start.tv_usec );
386 Exc_activated =
true;
388 Exc_Eshifts =
new double[ maxExc ];
389 Exc_MPSs =
new TensorT ** [ maxExc ];
391 Exc_Overlaps =
new TensorO ** [ maxExc ];
397 assert( Exc_activated );
398 assert( nStates - 1 < maxExc );
400 if ( the2DM != NULL ){
delete the2DM; the2DM = NULL; }
401 if ( the3DM != NULL ){
delete the3DM; the3DM = NULL; }
402 if ( theCorr != NULL ){
delete theCorr; theCorr = NULL; }
403 deleteAllBoundaryOperators();
405 Exc_Eshifts[ nStates - 1 ] = EshiftIn;
406 #ifdef CHEMPS2_MPI_COMPILATION 409 Exc_MPSs[ nStates - 1 ] = MPS;
410 Exc_BKs[ nStates - 1 ] = denBK;
411 Exc_Overlaps[ nStates - 1 ] =
new TensorO*[ L - 1 ];
412 #ifdef CHEMPS2_MPI_COMPILATION 414 for (
int site = 0; site < L; site++ ){
delete MPS[ site ]; }
422 setupBookkeeperAndMPS();
double get_energy_conv(const int instruction) const
Get the energy convergence threshold for a particular instruction.
void random()
Fill storage with random numbers 0 < val < 1.
double get_noise_prefactor(const int instruction) const
Get the noise prefactor for a particular instruction.
DMRG(Problem *Probin, ConvergenceScheme *OptSchemeIn, const bool makechkpt=CheMPS2::DMRG_storeMpsOnDisk, const string tmpfolder=CheMPS2::defaultTMPpath)
Constructor.
double Split(TensorT *Tleft, TensorT *Tright, const int virtualdimensionD, const bool movingright, const bool change)
SVD an S-object into 2 TensorT's.
static int mpi_rank()
Get the rank of this MPI process.
bool checkConsistency() const
Check whether the given parameters L, N, and TwoS are not inconsistent and whether 0<=Irrep<nIrreps...
int get_D(const int instruction) const
Get the number of renormalized states for a particular instruction.
int get_number() const
Get the number of instructions.
void PreSolve()
Reconstruct the renormalized operators when you overwrite the matrix elements with Prob->setMxElement...
void newExcitation(const double EshiftIn)
Push back current calculation and set everything up to calculate a (new) excitation.
bool IsPossible() const
Get whether the desired symmetry sector is possible.
void Join(TensorT *Tleft, TensorT *Tright)
Join two sites to form a composite S-object.
static void PrintLicense()
Print the license.
double get_dvdson_rtol(const int instruction) const
Get the Davidson residual tolerance for a particular instruction.
void activateExcitations(const int maxExcIn)
Activate the necessary storage and machinery to handle excitations.
virtual ~DMRG()
Destructor.
double SolveDAVIDSON(Sobject *denS, TensorL ***Ltensors, TensorOperator ****Atensors, TensorOperator ****Btensors, TensorOperator ****Ctensors, TensorOperator ****Dtensors, TensorS0 ****S0tensors, TensorS1 ****S1tensors, TensorF0 ****F0tensors, TensorF1 ****F1tensors, TensorQ ***Qtensors, TensorX **Xtensors, int nLower=0, double **VeffTilde=NULL) const
Davidson Solver.
double gEconst() const
Get the constant part of the Hamiltonian.
void addNoise(const double NoiseLevel)
Add noise to the current S-object.