29 #include "MPIchemps2.h" 35 dvdson_rtol = dvdson_rtol_in;
43 void CheMPS2::Heff::makeHeff(
double * memS,
double * memHeff,
const 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,
double ** VeffTilde)
const{
45 const int indexS = denS->
gIndex();
46 const bool atLeft = (indexS==0)?
true:
false;
47 const bool atRight = (indexS==Prob->
gL()-2)?
true:
false;
49 #ifdef CHEMPS2_MPI_COMPILATION 57 double * temp =
new double[DIM*DIM];
58 double * temp2 =
new double[DIM*DIM];
60 #pragma omp for schedule(dynamic) 61 for (
int ikappaBIS=0; ikappaBIS<denS->
gNKappa(); ikappaBIS++){
63 const int ikappa = denS->
gReorder(ikappaBIS);
66 #ifdef CHEMPS2_MPI_COMPILATION 67 if ( MPIchemps2::owner_1cd2d3eh() == MPIRANK )
70 addDiagram1C(ikappa, memS,memHeff,denS,Prob->
gMxElement(indexS,indexS,indexS,indexS));
71 addDiagram1D(ikappa, memS,memHeff,denS,Prob->
gMxElement(indexS+1,indexS+1,indexS+1,indexS+1));
72 addDiagram2dall(ikappa, memS, memHeff, denS);
73 addDiagram3Eand3H(ikappa, memS, memHeff, denS);
75 addDiagramExcitations(ikappa, memS, memHeff, denS, nLower, VeffTilde);
82 #ifdef CHEMPS2_MPI_COMPILATION 83 if ( MPIchemps2::owner_x() == MPIRANK )
85 { addDiagram1A(ikappa, memS, memHeff, denS, Xtensors[indexS-1]); }
90 #ifdef CHEMPS2_MPI_COMPILATION 91 if ( MPIchemps2::owner_absigma( indexS, indexS ) == MPIRANK )
93 { addDiagram2b1and2b2(ikappa, memS, memHeff, denS, Atensors[indexS-1][0][0]); }
94 #ifdef CHEMPS2_MPI_COMPILATION 95 if ( MPIchemps2::owner_absigma( indexS+1, indexS+1 ) == MPIRANK )
97 { addDiagram2c1and2c2(ikappa, memS, memHeff, denS, Atensors[indexS-1][0][1]); }
98 #ifdef CHEMPS2_MPI_COMPILATION 99 if ( MPIchemps2::owner_cdf( Prob->
gL(), indexS, indexS ) == MPIRANK )
101 { addDiagram2b3spin0(ikappa, memS, memHeff, denS, Ctensors[indexS-1][0][0]);
102 addDiagram2b3spin1(ikappa, memS, memHeff, denS, Dtensors[indexS-1][0][0]); }
103 #ifdef CHEMPS2_MPI_COMPILATION 104 if ( MPIchemps2::owner_cdf( Prob->
gL(), indexS+1, indexS+1 ) == MPIRANK )
106 { addDiagram2c3spin0(ikappa, memS, memHeff, denS, Ctensors[indexS-1][0][1]);
107 addDiagram2c3spin1(ikappa, memS, memHeff, denS, Dtensors[indexS-1][0][1]); }
112 #ifdef CHEMPS2_MPI_COMPILATION 113 if ( MPIchemps2::owner_q( Prob->
gL(), indexS ) == MPIRANK )
115 { addDiagram3Aand3D(ikappa, memS, memHeff, denS, Qtensors[indexS-1][0], Ltensors[indexS-1], temp); }
116 #ifdef CHEMPS2_MPI_COMPILATION 117 if ( MPIchemps2::owner_q( Prob->
gL(), indexS+1 ) == MPIRANK )
119 { addDiagram3Band3I(ikappa, memS, memHeff, denS, Qtensors[indexS-1][1], Ltensors[indexS-1], temp); }
124 #ifdef CHEMPS2_MPI_COMPILATION 125 if ( MPIchemps2::owner_absigma( indexS, indexS+1 ) == MPIRANK )
127 { addDiagram4A1and4A2spin0(ikappa, memS, memHeff, denS, Atensors[indexS-1][1][0]);
128 addDiagram4A1and4A2spin1(ikappa, memS, memHeff, denS, Btensors[indexS-1][1][0]); }
129 #ifdef CHEMPS2_MPI_COMPILATION 130 if ( MPIchemps2::owner_cdf( Prob->
gL(), indexS, indexS+1 ) == MPIRANK )
132 { addDiagram4A3and4A4spin0(ikappa, memS, memHeff, denS, Ctensors[indexS-1][1][0]);
133 addDiagram4A3and4A4spin1(ikappa, memS, memHeff, denS, Dtensors[indexS-1][1][0]); }
134 addDiagram4D(ikappa, memS, memHeff, denS, Ltensors[indexS-1], temp);
135 addDiagram4I(ikappa, memS, memHeff, denS, Ltensors[indexS-1], temp);
144 #ifdef CHEMPS2_MPI_COMPILATION 145 if ( MPIchemps2::owner_x() == MPIRANK )
147 { addDiagram1B(ikappa, memS, memHeff, denS, Xtensors[indexS+1]); }
152 #ifdef CHEMPS2_MPI_COMPILATION 153 if ( MPIchemps2::owner_absigma( indexS, indexS ) == MPIRANK )
155 { addDiagram2e1and2e2(ikappa, memS, memHeff, denS, Atensors[indexS+1][0][1]); }
156 #ifdef CHEMPS2_MPI_COMPILATION 157 if ( MPIchemps2::owner_absigma( indexS+1, indexS+1 ) == MPIRANK )
159 { addDiagram2f1and2f2(ikappa, memS, memHeff, denS, Atensors[indexS+1][0][0]); }
160 #ifdef CHEMPS2_MPI_COMPILATION 161 if ( MPIchemps2::owner_cdf( Prob->
gL(), indexS, indexS ) == MPIRANK )
163 { addDiagram2e3spin0(ikappa, memS, memHeff, denS, Ctensors[indexS+1][0][1]);
164 addDiagram2e3spin1(ikappa, memS, memHeff, denS, Dtensors[indexS+1][0][1]); }
165 #ifdef CHEMPS2_MPI_COMPILATION 166 if ( MPIchemps2::owner_cdf( Prob->
gL(), indexS+1, indexS+1 ) == MPIRANK )
168 { addDiagram2f3spin0(ikappa, memS, memHeff, denS, Ctensors[indexS+1][0][0]);
169 addDiagram2f3spin1(ikappa, memS, memHeff, denS, Dtensors[indexS+1][0][0]); }
174 #ifdef CHEMPS2_MPI_COMPILATION 175 if ( MPIchemps2::owner_q( Prob->
gL(), indexS ) == MPIRANK )
177 { addDiagram3Kand3F(ikappa, memS, memHeff, denS, Qtensors[indexS+1][1], Ltensors[indexS+1], temp); }
178 #ifdef CHEMPS2_MPI_COMPILATION 179 if ( MPIchemps2::owner_q( Prob->
gL(), indexS+1 ) == MPIRANK )
181 { addDiagram3Land3G(ikappa, memS, memHeff, denS, Qtensors[indexS+1][0], Ltensors[indexS+1], temp); }
186 #ifdef CHEMPS2_MPI_COMPILATION 187 if ( MPIchemps2::owner_absigma( indexS, indexS+1 ) == MPIRANK )
189 { addDiagram4J1and4J2spin0(ikappa, memS, memHeff, denS, Atensors[indexS+1][1][0]);
190 addDiagram4J1and4J2spin1(ikappa, memS, memHeff, denS, Btensors[indexS+1][1][0]); }
191 #ifdef CHEMPS2_MPI_COMPILATION 192 if ( MPIchemps2::owner_cdf( Prob->
gL(), indexS, indexS+1 ) == MPIRANK )
194 { addDiagram4J3and4J4spin0(ikappa, memS, memHeff, denS, Ctensors[indexS+1][1][0]);
195 addDiagram4J3and4J4spin1(ikappa, memS, memHeff, denS, Dtensors[indexS+1][1][0]); }
196 addDiagram4F(ikappa, memS, memHeff, denS, Ltensors[indexS+1], temp);
197 addDiagram4G(ikappa, memS, memHeff, denS, Ltensors[indexS+1], temp);
201 if ((!atLeft) && (!atRight)){
203 addDiagram2a1spin0(ikappa, memS, memHeff, denS, Atensors, S0tensors, temp);
204 addDiagram2a2spin0(ikappa, memS, memHeff, denS, Atensors, S0tensors, temp);
205 addDiagram2a1spin1(ikappa, memS, memHeff, denS, Btensors, S1tensors, temp);
206 addDiagram2a2spin1(ikappa, memS, memHeff, denS, Btensors, S1tensors, temp);
207 addDiagram2a3spin0(ikappa, memS, memHeff, denS, Ctensors, F0tensors, temp);
208 addDiagram2a3spin1(ikappa, memS, memHeff, denS, Dtensors, F1tensors, temp);
210 addDiagram3C(ikappa, memS, memHeff, denS, Qtensors[indexS-1], Ltensors[indexS+1], temp);
211 addDiagram3J(ikappa, memS, memHeff, denS, Qtensors[indexS+1], Ltensors[indexS-1], temp);
213 addDiagram4B1and4B2spin0(ikappa, memS, memHeff, denS, Atensors[indexS-1], Ltensors[indexS+1], temp);
214 addDiagram4B1and4B2spin1(ikappa, memS, memHeff, denS, Btensors[indexS-1], Ltensors[indexS+1], temp);
215 addDiagram4B3and4B4spin0(ikappa, memS, memHeff, denS, Ctensors[indexS-1], Ltensors[indexS+1], temp);
216 addDiagram4B3and4B4spin1(ikappa, memS, memHeff, denS, Dtensors[indexS-1], Ltensors[indexS+1], temp);
217 addDiagram4C1and4C2spin0(ikappa, memS, memHeff, denS, Atensors[indexS-1], Ltensors[indexS+1], temp);
218 addDiagram4C1and4C2spin1(ikappa, memS, memHeff, denS, Btensors[indexS-1], Ltensors[indexS+1], temp);
219 addDiagram4C3and4C4spin0(ikappa, memS, memHeff, denS, Ctensors[indexS-1], Ltensors[indexS+1], temp);
220 addDiagram4C3and4C4spin1(ikappa, memS, memHeff, denS, Dtensors[indexS-1], Ltensors[indexS+1], temp);
221 addDiagram4E(ikappa, memS, memHeff, denS, Ltensors[indexS-1], Ltensors[indexS+1], temp, temp2);
222 addDiagram4H(ikappa, memS, memHeff, denS, Ltensors[indexS-1], Ltensors[indexS+1], temp, temp2);
223 addDiagram4K1and4K2spin0(ikappa, memS, memHeff, denS, Ltensors[indexS-1], Atensors[indexS+1], temp);
224 addDiagram4L1and4L2spin0(ikappa, memS, memHeff, denS, Ltensors[indexS-1], Atensors[indexS+1], temp);
225 addDiagram4K1and4K2spin1(ikappa, memS, memHeff, denS, Ltensors[indexS-1], Btensors[indexS+1], temp);
226 addDiagram4L1and4L2spin1(ikappa, memS, memHeff, denS, Ltensors[indexS-1], Btensors[indexS+1], temp);
227 addDiagram4K3and4K4spin0(ikappa, memS, memHeff, denS, Ltensors[indexS-1], Ctensors[indexS+1], temp);
228 addDiagram4L3and4L4spin0(ikappa, memS, memHeff, denS, Ltensors[indexS-1], Ctensors[indexS+1], temp);
229 addDiagram4K3and4K4spin1(ikappa, memS, memHeff, denS, Ltensors[indexS-1], Dtensors[indexS+1], temp);
230 addDiagram4L3and4L4spin1(ikappa, memS, memHeff, denS, Ltensors[indexS-1], Dtensors[indexS+1], temp);
232 addDiagram5A(ikappa, memS, memHeff, denS, Ltensors[indexS-1], Ltensors[indexS+1], temp, temp2);
233 addDiagram5B(ikappa, memS, memHeff, denS, Ltensors[indexS-1], Ltensors[indexS+1], temp, temp2);
234 addDiagram5C(ikappa, memS, memHeff, denS, Ltensors[indexS-1], Ltensors[indexS+1], temp, temp2);
235 addDiagram5D(ikappa, memS, memHeff, denS, Ltensors[indexS-1], Ltensors[indexS+1], temp, temp2);
236 addDiagram5E(ikappa, memS, memHeff, denS, Ltensors[indexS-1], Ltensors[indexS+1], temp, temp2);
237 addDiagram5F(ikappa, memS, memHeff, denS, Ltensors[indexS-1], Ltensors[indexS+1], temp, temp2);
252 const int indexS = denS->
gIndex();
253 const bool atLeft = (indexS==0)?
true:
false;
254 const bool atRight = (indexS==Prob->
gL()-2)?
true:
false;
255 #ifdef CHEMPS2_MPI_COMPILATION 260 #pragma omp parallel for schedule(dynamic) 261 for (
int ikappaBIS=0; ikappaBIS<denS->
gNKappa(); ikappaBIS++){
263 const int ikappa = denS->
gReorder(ikappaBIS);
266 #ifdef CHEMPS2_MPI_COMPILATION 267 if ( MPIchemps2::owner_1cd2d3eh() == MPIRANK )
269 { addDiagonal1C(ikappa, memHeffDiag,denS,Prob->
gMxElement(indexS,indexS,indexS,indexS));
270 addDiagonal1D(ikappa, memHeffDiag,denS,Prob->
gMxElement(indexS+1,indexS+1,indexS+1,indexS+1));
271 addDiagonal2d3all(ikappa, memHeffDiag, denS); }
272 if (nLower>0){ addDiagonalExcitations(ikappa, memHeffDiag, denS, nLower, VeffTilde); }
275 #ifdef CHEMPS2_MPI_COMPILATION 276 if ( MPIchemps2::owner_x() == MPIRANK )
278 { addDiagonal1A(ikappa, memHeffDiag, denS, Xtensors[indexS-1]); }
279 #ifdef CHEMPS2_MPI_COMPILATION 280 if ( MPIchemps2::owner_cdf( Prob->
gL(), indexS, indexS ) == MPIRANK )
282 { addDiagonal2b3spin0(ikappa, memHeffDiag, denS, Ctensors[indexS-1][0][0]);
283 addDiagonal2b3spin1(ikappa, memHeffDiag, denS, Dtensors[indexS-1][0][0]); }
284 #ifdef CHEMPS2_MPI_COMPILATION 285 if ( MPIchemps2::owner_cdf( Prob->
gL(), indexS+1, indexS+1 ) == MPIRANK )
287 { addDiagonal2c3spin0(ikappa, memHeffDiag, denS, Ctensors[indexS-1][0][1]);
288 addDiagonal2c3spin1(ikappa, memHeffDiag, denS, Dtensors[indexS-1][0][1]); }
292 #ifdef CHEMPS2_MPI_COMPILATION 293 if ( MPIchemps2::owner_x() == MPIRANK )
295 { addDiagonal1B(ikappa, memHeffDiag, denS, Xtensors[indexS+1]); }
296 #ifdef CHEMPS2_MPI_COMPILATION 297 if ( MPIchemps2::owner_cdf( Prob->
gL(), indexS, indexS ) == MPIRANK )
299 { addDiagonal2e3spin0(ikappa, memHeffDiag, denS, Ctensors[indexS+1][0][1]);
300 addDiagonal2e3spin1(ikappa, memHeffDiag, denS, Dtensors[indexS+1][0][1]); }
301 #ifdef CHEMPS2_MPI_COMPILATION 302 if ( MPIchemps2::owner_cdf( Prob->
gL(), indexS+1, indexS+1 ) == MPIRANK )
304 { addDiagonal2f3spin0(ikappa, memHeffDiag, denS, Ctensors[indexS+1][0][0]);
305 addDiagonal2f3spin1(ikappa, memHeffDiag, denS, Dtensors[indexS+1][0][0]); }
308 if ((!atLeft) && (!atRight)){
309 addDiagonal2a3spin0(ikappa, memHeffDiag, denS, Ctensors, F0tensors);
310 addDiagonal2a3spin1(ikappa, memHeffDiag, denS, Dtensors, F1tensors);
317 double CheMPS2::Heff::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,
double ** VeffTilde)
const{
319 #ifdef CHEMPS2_MPI_COMPILATION 321 return SolveDAVIDSON_main(denS, Ltensors, Atensors, Btensors, Ctensors, Dtensors, S0tensors, S1tensors, F0tensors, F1tensors, Qtensors, Xtensors, nLower, VeffTilde);
323 return SolveDAVIDSON_help(denS, Ltensors, Atensors, Btensors, Ctensors, Dtensors, S0tensors, S1tensors, F0tensors, F1tensors, Qtensors, Xtensors, nLower, VeffTilde);
326 return SolveDAVIDSON_main(denS, Ltensors, Atensors, Btensors, Ctensors, Dtensors, S0tensors, S1tensors, F0tensors, F1tensors, Qtensors, Xtensors, nLower, VeffTilde);
331 double CheMPS2::Heff::SolveDAVIDSON_main(
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,
double ** VeffTilde)
const{
336 Davidson deBoskabouter( veclength, CheMPS2::DAVIDSON_NUM_VEC,
337 CheMPS2::DAVIDSON_NUM_VEC_KEEP,
340 CheMPS2::DAVIDSON_PRECOND_CUTOFF, CheMPS2::HEFF_debugPrint );
341 double ** whichpointers =
new double*[2];
344 assert( instruction ==
'A' );
346 dcopy_(&veclength, denS->
gStorage(), &inc1, whichpointers[0], &inc1);
347 #ifdef CHEMPS2_MPI_COMPILATION 348 double * workspace =
new double[ veclength ];
349 fillHeffDiag(workspace, denS, Ctensors, Dtensors, F0tensors, F1tensors, Xtensors, nLower, VeffTilde);
350 MPIchemps2::reduce_array_double( workspace, whichpointers[1], veclength, MPI_CHEMPS2_MASTER );
352 fillHeffDiag(whichpointers[1], denS, Ctensors, Dtensors, F0tensors, F1tensors, Xtensors, nLower, VeffTilde);
356 while ( instruction ==
'B' ){
358 #ifdef CHEMPS2_MPI_COMPILATION 360 int mpi_instruction = 2;
361 MPIchemps2::broadcast_array_int( &mpi_instruction, 1, MPI_CHEMPS2_MASTER );
362 MPIchemps2::broadcast_array_double( whichpointers[0], veclength, MPI_CHEMPS2_MASTER );
363 makeHeff(whichpointers[0], workspace, denS, Ltensors, Atensors, Btensors, Ctensors, Dtensors, S0tensors, S1tensors, F0tensors, F1tensors, Qtensors, Xtensors, nLower, VeffTilde);
364 MPIchemps2::reduce_array_double( workspace, whichpointers[1], veclength, MPI_CHEMPS2_MASTER );
367 makeHeff(whichpointers[0], whichpointers[1], denS, Ltensors, Atensors, Btensors, Ctensors, Dtensors, S0tensors, S1tensors, F0tensors, F1tensors, Qtensors, Xtensors, nLower, VeffTilde);
372 assert( instruction ==
'C' );
373 dcopy_( &veclength, whichpointers[0], &inc1, denS->
gStorage(), &inc1 );
375 double eigenvalue = whichpointers[1][0];
376 if (CheMPS2::HEFF_debugPrint){ std::cout <<
" Stats: nIt(DAVIDSON) = " << deBoskabouter.
GetNumMultiplications() << std::endl; }
377 delete [] whichpointers;
378 #ifdef CHEMPS2_MPI_COMPILATION 380 int mpi_instruction = 3;
381 MPIchemps2::broadcast_array_int( &mpi_instruction, 1, MPI_CHEMPS2_MASTER );
382 MPIchemps2::broadcast_array_double( &eigenvalue, 1, MPI_CHEMPS2_MASTER );
388 #ifdef CHEMPS2_MPI_COMPILATION 389 double CheMPS2::Heff::SolveDAVIDSON_help(
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,
double ** VeffTilde)
const{
392 double * vecin =
new double[ veclength ];
393 double * vecout =
new double[ veclength ];
394 int mpi_instruction = -1;
396 fillHeffDiag( vecout, denS, Ctensors, Dtensors, F0tensors, F1tensors, Xtensors, nLower, VeffTilde );
397 MPIchemps2::reduce_array_double( vecout, vecin, veclength, MPI_CHEMPS2_MASTER );
398 MPIchemps2::broadcast_array_int( &mpi_instruction, 1, MPI_CHEMPS2_MASTER );
400 while ( mpi_instruction == 2 ){
402 MPIchemps2::broadcast_array_double( vecin, veclength, MPI_CHEMPS2_MASTER );
403 makeHeff(vecin, vecout, denS, Ltensors, Atensors, Btensors, Ctensors, Dtensors, S0tensors, S1tensors, F0tensors, F1tensors, Qtensors, Xtensors, nLower, VeffTilde);
404 MPIchemps2::reduce_array_double( vecout, vecin, veclength, MPI_CHEMPS2_MASTER );
405 MPIchemps2::broadcast_array_int( &mpi_instruction, 1, MPI_CHEMPS2_MASTER );
409 assert( mpi_instruction == 3 );
410 double eigenvalue = 0.0;
411 MPIchemps2::broadcast_array_double( &eigenvalue, 1, MPI_CHEMPS2_MASTER );
int GetNumMultiplications() const
Get the number of matrix vector multiplications which have been performed.
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.
void symm2prog()
Convert the storage from symmetric Hamiltonian convention to diagram convention.
int gNKappa() const
Get the number of symmetry blocks.
Heff(const SyBookkeeper *denBKIn, const Problem *ProbIn, const double dvdson_rtol_in)
Constructor.
virtual ~Heff()
Destructor.
double * gStorage()
Get the pointer to the storage.
double gMxElement(const int alpha, const int beta, const int gamma, const int delta) const
Get a specific interaction matrix element.
void prog2symm()
Convert the storage from diagram convention to symmetric Hamiltonian convention.
int gL() const
Get the number of orbitals.
int gIndex() const
Get the location index.
int gMaxDimAtBound(const int boundary) const
Get the maximum virtual dimension at a certain boundary.
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.
char FetchInstruction(double **pointers)
The iterator to converge the ground state vector.
int gReorder(const int ikappa) const
Get the blocks from large to small: blocksize(reorder[i])>=blocksize(reorder[i+1]) ...