30 #include "DMRGSCFrotations.h" 31 #include "EdmistonRuedenberg.h" 34 #include "MPIchemps2.h" 42 void CheMPS2::CASSCF::delete_file(
const string filename ){
44 struct stat file_info;
45 const int thestat = stat( filename.c_str(), &file_info );
47 const string temp =
"rm " + filename;
48 int info = system( temp.c_str() );
49 cout <<
"Info on system( " << temp <<
" ) = " << info << endl;
51 cout <<
"No file " << filename <<
" found." << endl;
58 #ifdef CHEMPS2_MPI_COMPILATION 61 const bool am_i_master =
true;
64 const int num_elec = Nelectrons - 2 * iHandler->
getNOCCsum();
65 assert( num_elec >= 0 );
66 assert(( OptScheme != NULL ) || ( rootNum == 1 ));
69 double gradNorm = 1.0;
70 double updateNorm = 1.0;
71 double * gradient = NULL;
74 for (
int cnt = 0; cnt < unitary->
getNumVariablesX(); cnt++ ){ gradient[ cnt ] = 0.0; }
76 double * diis_vec = NULL;
82 Prob->SetupReorderD2h();
86 const long long fullsize = ((
long long) maxlinsize ) * ((
long long) maxlinsize ) * ((
long long) maxlinsize ) * ((
long long) maxlinsize );
87 const string tmp_filename = tmp_folder +
"/" + CheMPS2::DMRGSCF_eri_storage_name;
88 const int dmrgsize_power4 = nOrbDMRG * nOrbDMRG * nOrbDMRG * nOrbDMRG;
92 const int temp_work_size = (( fullsize > CheMPS2::DMRGSCF_max_mem_eri_tfo ) ? CheMPS2::DMRGSCF_max_mem_eri_tfo : fullsize );
93 const int work_mem_size = max( max( temp_work_size , maxlinsize * maxlinsize * 4 ) , dmrgsize_power4 );
94 double * mem1 =
new double[ work_mem_size ];
95 double * mem2 =
new double[ work_mem_size ];
104 struct stat file_info;
108 #ifdef CHEMPS2_MPI_COMPILATION 109 unitary->broadcast( MPI_CHEMPS2_MASTER );
116 struct stat file_info;
118 if ( master_stat == 0 ){
122 diis_vec =
new double[ diis_vec_size ];
131 while (( gradNorm > scf_options->
getGradientThreshold() ) && ( nIterations < scf_options->getMaxIterations() )){
140 if (( scf_options->
getDoDIIS() ) && ( updateNorm <= scf_options->getDIISGradientBranch() )){
142 cout <<
"DMRGSCF::solve : DIIS has started. Active space not rotated to NOs anymore!" << endl;
145 cout <<
"DMRGSCF::solve : DIIS has started. Active space not rotated to localized orbitals anymore!" << endl;
148 cout <<
"DMRGSCF::solve : DIIS has started. Active space not ordered according to the Fiedler vector of the exchange matrix anymore!" << endl;
153 diis_vec =
new double[ diis_vec_size ];
156 unitary->
getLog( diis_vec, mem1, mem2 );
159 unitary->
updateUnitary( mem1, mem2, diis_vec,
false,
false );
164 int master_diis = (( diis != NULL ) ? 1 : 0 );
165 #ifdef CHEMPS2_MPI_COMPILATION 166 MPIchemps2::broadcast_array_int( &master_diis, 1, MPI_CHEMPS2_MASTER );
167 unitary->broadcast( MPI_CHEMPS2_MASTER );
173 fillConstAndTmatDMRG( HamDMRG );
175 DMRGSCFrotations::rotate( VMAT_ORIG, HamDMRG->
getVmat(), NULL,
'A',
'A',
'A',
'A', iHandler, unitary, mem1, mem2, work_mem_size, tmp_filename );
177 #ifdef CHEMPS2_MPI_COMPILATION 178 HamDMRG->
getVmat()->broadcast( MPI_CHEMPS2_MASTER );
189 #ifdef CHEMPS2_MPI_COMPILATION 190 unitary->broadcast( MPI_CHEMPS2_MASTER );
194 fillConstAndTmatDMRG( HamDMRG );
196 DMRGSCFrotations::rotate( VMAT_ORIG, HamDMRG->
getVmat(), NULL,
'A',
'A',
'A',
'A', iHandler, unitary, mem1, mem2, work_mem_size, tmp_filename );
197 cout <<
"DMRGSCF::solve : Rotated the active space to localized orbitals, sorted according to the exchange matrix." << endl;
199 #ifdef CHEMPS2_MPI_COMPILATION 200 HamDMRG->
getVmat()->broadcast( MPI_CHEMPS2_MASTER );
206 int * dmrg2ham =
new int[ nOrbDMRG ];
210 #ifdef CHEMPS2_MPI_COMPILATION 211 MPIchemps2::broadcast_array_int( dmrg2ham, nOrbDMRG, MPI_CHEMPS2_MASTER );
213 Prob->setup_reorder_custom( dmrg2ham );
217 if (( OptScheme == NULL ) && ( rootNum == 1 )){
220 const int nalpha = ( num_elec + TwoS ) / 2;
221 const int nbeta = ( num_elec - TwoS ) / 2;
222 const double workmem = 1000.0;
223 const int verbose = 2;
225 double * inoutput =
new double[ theFCI->
getVecLength(0) ];
229 theFCI->
Fill2RDM( inoutput, DMRG2DM );
233 #ifdef CHEMPS2_MPI_COMPILATION 234 MPIchemps2::broadcast_array_double( &Energy, 1, MPI_CHEMPS2_MASTER );
235 MPIchemps2::broadcast_array_double( DMRG2DM, dmrgsize_power4, MPI_CHEMPS2_MASTER );
240 assert( OptScheme != NULL );
241 for (
int cnt = 0; cnt < dmrgsize_power4; cnt++ ){ DMRG2DM[ cnt ] = 0.0; }
242 DMRG * theDMRG =
new DMRG( Prob, OptScheme, CheMPS2::DMRG_storeMpsOnDisk, tmp_folder );
243 for (
int state = 0; state < rootNum; state++ ){
244 if ( state > 0 ){ theDMRG->
newExcitation( fabs( Energy ) ); }
245 Energy = theDMRG->
Solve();
261 const double averagingfactor = 1.0 / rootNum;
262 for (
int cnt = 0; cnt < dmrgsize_power4; cnt++ ){ DMRG2DM[ cnt ] *= averagingfactor; }
266 setDMRG1DM( num_elec, nOrbDMRG, DMRG1DM, DMRG2DM );
270 copy_active( DMRG1DM, theQmatWORK, iHandler,
true );
271 block_diagonalize(
'A', theQmatWORK, unitary, mem1, mem2, iHandler,
true, DMRG2DM, NULL, NULL );
272 setDMRG1DM( num_elec, nOrbDMRG, DMRG1DM, DMRG2DM );
275 if ( am_i_master ){ cout <<
"DMRGSCF::solve : Rotated the active space to natural orbitals, sorted according to the NOON." << endl; }
285 DMRGSCFrotations::rotate( VMAT_ORIG, NULL, theRotatedTEI,
'C',
'C',
'F',
'F', iHandler, unitary, mem1, mem2, work_mem_size, tmp_filename );
286 DMRGSCFrotations::rotate( VMAT_ORIG, NULL, theRotatedTEI,
'C',
'V',
'C',
'V', iHandler, unitary, mem1, mem2, work_mem_size, tmp_filename );
287 buildFmat( theFmatrix, theTmatrix, theQmatOCC, theQmatACT, iHandler, theRotatedTEI, DMRG2DM, DMRG1DM );
288 buildWtilde( wmattilde, theTmatrix, theQmatOCC, theQmatACT, iHandler, theRotatedTEI, DMRG2DM, DMRG1DM );
289 augmentedHessianNR( theFmatrix, wmattilde, iHandler, unitary, gradient, &updateNorm, &gradNorm );
291 #ifdef CHEMPS2_MPI_COMPILATION 292 MPIchemps2::broadcast_array_double( &updateNorm, 1, MPI_CHEMPS2_MASTER );
293 MPIchemps2::broadcast_array_double( &gradNorm, 1, MPI_CHEMPS2_MASTER );
300 delete theRotatedTEI;
302 if ( am_i_master ){ delete_file( tmp_filename ); }
306 if ( gradient != NULL ){
delete [] gradient; }
307 if ( diis_vec != NULL ){
delete [] diis_vec; }
308 if ( diis != NULL ){
delete diis; }
309 if ( theLocalizer != NULL ){
delete theLocalizer; }
311 successful_solve =
true;
327 gradNorm[ 0 ] = construct_gradient( localFmat, localIdx, theupdate );
331 Davidson deBoskabouter( x_linearlength + 1, CheMPS2::DAVIDSON_NUM_VEC,
332 CheMPS2::DAVIDSON_NUM_VEC_KEEP,
333 CheMPS2::DAVIDSON_FCI_RTOL,
334 CheMPS2::DAVIDSON_PRECOND_CUTOFF,
false );
335 double ** whichpointers =
new double*[ 2 ];
337 assert( instruction ==
'A' );
338 diag_hessian( localFmat, localwtilde, localIdx, whichpointers[ 1 ] );
339 whichpointers[ 1 ][ x_linearlength ] = 0.0;
340 for (
int cnt = 0; cnt < x_linearlength; cnt++ ){
341 const double denom = ( whichpointers[ 1 ][ cnt ] > CheMPS2::DAVIDSON_PRECOND_CUTOFF ) ? whichpointers[ 1 ][ cnt ] : CheMPS2::DAVIDSON_PRECOND_CUTOFF;
342 whichpointers[ 0 ][ cnt ] = - theupdate[ cnt ] / denom;
344 whichpointers[ 0 ][ x_linearlength ] = 1.0;
346 while ( instruction ==
'B' ){
347 augmented_hessian( localFmat, localwtilde, localIdx, whichpointers[ 0 ], whichpointers[ 1 ], theupdate, x_linearlength );
350 assert( instruction ==
'C' );
351 double scalar = 1.0 / whichpointers[ 0 ][ x_linearlength ];
352 cout <<
"DMRGSCF::augmentedHessianNR : Augmented Hessian update found with " << deBoskabouter.
GetNumMultiplications() <<
" Davidson iterations." << endl;
353 if ( CheMPS2::DMRGSCF_debugPrint ){
354 cout <<
"DMRGSCF::augmentedHessianNR : Lowest eigenvalue = " << whichpointers[ 1 ][ 0 ] << endl;
355 cout <<
"DMRGSCF::augmentedHessianNR : The last number of the eigenvector (which will be rescaled to one) = " << scalar << endl;
357 for (
int cnt = 0; cnt < x_linearlength; cnt++ ){ theupdate[ cnt ] = scalar * whichpointers[ 0 ][ cnt ]; }
358 delete [] whichpointers;
362 updateNorm[ 0 ] = 0.0;
363 for (
int cnt = 0; cnt < x_linearlength; cnt++ ){ updateNorm[ 0 ] += theupdate[ cnt ] * theupdate[ cnt ]; }
364 updateNorm[ 0 ] = sqrt( updateNorm[ 0 ] );
365 cout <<
"DMRGSCF::augmentedHessianNR : Norm of the update = " << updateNorm[ 0 ] << endl;
374 for (
int irrep = 0; irrep < n_irreps; irrep++ ){
376 const int NORB = idx->
getNORB( irrep );
377 const int NOCC = idx->
getNOCC( irrep );
378 const int NACT = idx->
getNDMRG( irrep );
379 const int NVIR = idx->
getNVIRT( irrep );
380 const int N_OA = NOCC + NACT;
381 double * FMAT = Fmatrix->
getBlock( irrep );
384 for (
int occ = 0; occ < NOCC; occ++ ){
385 for (
int act = 0; act < NACT; act++ ){
386 gradient[ jump + act + NACT * occ ] = 2 * ( FMAT[ NOCC + act + NORB * occ ] - FMAT[ occ + NORB * ( NOCC + act ) ] );
392 for (
int act = 0; act < NACT; act++ ){
393 for (
int vir = 0; vir < NVIR; vir++ ){
394 gradient[ jump + vir + NVIR * act ] = 2 * ( FMAT[ N_OA + vir + NORB * ( NOCC + act ) ] - FMAT[ NOCC + act + NORB * ( N_OA + vir ) ] );
400 for (
int occ = 0; occ < NOCC; occ++ ){
401 for (
int vir = 0; vir < NVIR; vir++ ){
402 gradient[ jump + vir + NVIR * occ ] = 2 * ( FMAT[ N_OA + vir + NORB * occ ] - FMAT[ occ + NORB * ( N_OA + vir ) ] );
408 double gradient_norm = 0.0;
409 for (
int cnt = 0; cnt < jump; cnt++ ){ gradient_norm += gradient[ cnt ] * gradient[ cnt ]; }
410 gradient_norm = sqrt( gradient_norm );
411 cout <<
"DMRGSCF::construct_gradient : Norm of the gradient = " << gradient_norm << endl;
412 return gradient_norm;
418 for (
int cnt = 0; cnt < linsize; cnt++ ){
419 target[ cnt ] = gradient[ cnt ] * origin[ linsize ];
421 add_hessian( Fmatrix, Wtilde, idx, origin, target );
422 target[ linsize ] = 0.0;
423 for (
int cnt = 0; cnt < linsize; cnt++ ){
424 target[ linsize ] += gradient[ cnt ] * origin[ cnt ];
434 for (
int irrep = 0; irrep < n_irreps; irrep++ ){
436 const int NORB = idx->
getNORB( irrep );
437 const int NOCC = idx->
getNOCC( irrep );
438 const int NACT = idx->
getNDMRG( irrep );
439 const int NVIR = idx->
getNVIRT( irrep );
440 const int N_OA = NOCC + NACT;
441 double * FMAT = Fmatrix->
getBlock( irrep );
443 for (
int occ = 0; occ < NOCC; occ++ ){
444 const double F_occ = FMAT[ occ * ( NORB + 1 ) ];
445 for (
int act = 0; act < NACT; act++ ){
446 const double F_act = FMAT[ ( NOCC + act ) * ( NORB + 1 ) ];
447 diagonal[ jump + act + NACT * occ ] = - 2 * ( F_occ + F_act ) + ( Wtilde->
get( irrep, irrep, NOCC + act, occ, NOCC + act, occ )
448 - Wtilde->
get( irrep, irrep, NOCC + act, occ, occ, NOCC + act )
449 - Wtilde->
get( irrep, irrep, occ, NOCC + act, NOCC + act, occ )
450 + Wtilde->
get( irrep, irrep, occ, NOCC + act, occ, NOCC + act ) );
455 for (
int act = 0; act < NACT; act++ ){
456 const double F_act = FMAT[ ( NOCC + act ) * ( NORB + 1 ) ];
457 for (
int vir = 0; vir < NVIR; vir++ ){
458 const double F_vir = FMAT[ ( N_OA + vir ) * ( NORB + 1 ) ];
459 diagonal[ jump + vir + NVIR * act ] = - 2 * ( F_act + F_vir ) + Wtilde->
get( irrep, irrep, NOCC + act, N_OA + vir, NOCC + act, N_OA + vir );
464 for (
int occ = 0; occ < NOCC; occ++ ){
465 const double F_occ = FMAT[ occ * ( NORB + 1 ) ];
466 for (
int vir = 0; vir < NVIR; vir++ ){
467 const double F_vir = FMAT[ ( N_OA + vir ) * ( NORB + 1 ) ];
468 diagonal[ jump + vir + NVIR * occ ] = - 2 * ( F_occ + F_vir ) + Wtilde->
get( irrep, irrep, occ, N_OA + vir, occ, N_OA + vir );
481 for (
int irrep = 0; irrep < n_irreps; irrep++ ){
483 const int NORB = idx->
getNORB( irrep );
484 const int NOCC = idx->
getNOCC( irrep );
485 const int NACT = idx->
getNDMRG( irrep );
486 const int NVIR = idx->
getNVIRT( irrep );
487 const int N_OA = NOCC + NACT;
488 double * FMAT = Fmatrix->
getBlock( irrep );
489 const int ptr_AO = jump;
490 const int ptr_VA = jump + NACT * NOCC;
491 const int ptr_VO = jump + NACT * NOCC + NVIR * NACT;
495 DGEMM_WRAP( +1.0,
'T',
'N', origin + ptr_VA, FMAT + N_OA, target + ptr_AO, NACT, NOCC, NVIR, NVIR, NORB, NACT );
496 DGEMM_WRAP( +1.0,
'T',
'T', origin + ptr_VA, FMAT + NORB * N_OA, target + ptr_AO, NACT, NOCC, NVIR, NVIR, NORB, NACT );
497 DGEMM_WRAP( -1.0,
'N',
'N', origin + ptr_AO, FMAT, target + ptr_AO, NACT, NOCC, NOCC, NACT, NORB, NACT );
498 DGEMM_WRAP( -1.0,
'N',
'T', origin + ptr_AO, FMAT, target + ptr_AO, NACT, NOCC, NOCC, NACT, NORB, NACT );
499 DGEMM_WRAP( -1.0,
'N',
'N', FMAT + NOCC + NORB * NOCC, origin + ptr_AO, target + ptr_AO, NACT, NOCC, NACT, NORB, NACT, NACT );
500 DGEMM_WRAP( -1.0,
'T',
'N', FMAT + NOCC + NORB * NOCC, origin + ptr_AO, target + ptr_AO, NACT, NOCC, NACT, NORB, NACT, NACT );
501 DGEMM_WRAP( -1.0,
'N',
'N', FMAT + NOCC + NORB * N_OA, origin + ptr_VO, target + ptr_AO, NACT, NOCC, NVIR, NORB, NVIR, NACT );
502 DGEMM_WRAP( -1.0,
'T',
'N', FMAT + N_OA + NORB * NOCC, origin + ptr_VO, target + ptr_AO, NACT, NOCC, NVIR, NORB, NVIR, NACT );
504 DGEMM_WRAP( +1.0,
'N',
'T', FMAT + N_OA, origin + ptr_AO, target + ptr_VA, NVIR, NACT, NOCC, NORB, NACT, NVIR );
505 DGEMM_WRAP( +1.0,
'T',
'T', FMAT + NORB * N_OA, origin + ptr_AO, target + ptr_VA, NVIR, NACT, NOCC, NORB, NACT, NVIR );
506 DGEMM_WRAP( -1.0,
'N',
'N', origin + ptr_VO, FMAT + NORB * NOCC, target + ptr_VA, NVIR, NACT, NOCC, NVIR, NORB, NVIR );
507 DGEMM_WRAP( -1.0,
'N',
'T', origin + ptr_VO, FMAT + NOCC, target + ptr_VA, NVIR, NACT, NOCC, NVIR, NORB, NVIR );
508 DGEMM_WRAP( -1.0,
'N',
'N', origin + ptr_VA, FMAT + NOCC + NORB * NOCC, target + ptr_VA, NVIR, NACT, NACT, NVIR, NORB, NVIR );
509 DGEMM_WRAP( -1.0,
'N',
'T', origin + ptr_VA, FMAT + NOCC + NORB * NOCC, target + ptr_VA, NVIR, NACT, NACT, NVIR, NORB, NVIR );
510 DGEMM_WRAP( -1.0,
'N',
'N', FMAT + N_OA + NORB * N_OA, origin + ptr_VA, target + ptr_VA, NVIR, NACT, NVIR, NORB, NVIR, NVIR );
511 DGEMM_WRAP( -1.0,
'T',
'N', FMAT + N_OA + NORB * N_OA, origin + ptr_VA, target + ptr_VA, NVIR, NACT, NVIR, NORB, NVIR, NVIR );
513 DGEMM_WRAP( -1.0,
'N',
'N', origin + ptr_VO, FMAT, target + ptr_VO, NVIR, NOCC, NOCC, NVIR, NORB, NVIR );
514 DGEMM_WRAP( -1.0,
'N',
'T', origin + ptr_VO, FMAT, target + ptr_VO, NVIR, NOCC, NOCC, NVIR, NORB, NVIR );
515 DGEMM_WRAP( -1.0,
'N',
'N', origin + ptr_VA, FMAT + NOCC, target + ptr_VO, NVIR, NOCC, NACT, NVIR, NORB, NVIR );
516 DGEMM_WRAP( -1.0,
'N',
'T', origin + ptr_VA, FMAT + NORB * NOCC, target + ptr_VO, NVIR, NOCC, NACT, NVIR, NORB, NVIR );
517 DGEMM_WRAP( -1.0,
'N',
'N', FMAT + N_OA + NORB * N_OA, origin + ptr_VO, target + ptr_VO, NVIR, NOCC, NVIR, NORB, NVIR, NVIR );
518 DGEMM_WRAP( -1.0,
'T',
'N', FMAT + N_OA + NORB * N_OA, origin + ptr_VO, target + ptr_VO, NVIR, NOCC, NVIR, NORB, NVIR, NVIR );
519 DGEMM_WRAP( -1.0,
'N',
'N', FMAT + N_OA + NORB * NOCC, origin + ptr_AO, target + ptr_VO, NVIR, NOCC, NACT, NORB, NACT, NVIR );
520 DGEMM_WRAP( -1.0,
'T',
'N', FMAT + NOCC + NORB * N_OA, origin + ptr_AO, target + ptr_VO, NVIR, NOCC, NACT, NORB, NACT, NVIR );
522 jump += NACT * NOCC + NVIR * NACT + NVIR * NOCC;
529 for (
int irrep_row = 0; irrep_row < n_irreps; irrep_row++ ){
531 const int NORB_row = idx->
getNORB( irrep_row );
532 const int NOCC_row = idx->
getNOCC( irrep_row );
533 const int NACT_row = idx->
getNDMRG( irrep_row );
534 const int NVIR_row = idx->
getNVIRT( irrep_row );
535 const int N_OA_row = NOCC_row + NACT_row;
536 double * resAO = target + jump_row;
537 double * resVA = resAO + NACT_row * NOCC_row;
538 double * resVO = resVA + NVIR_row * NACT_row;
541 for (
int irrep_col = 0; irrep_col < n_irreps; irrep_col++ ){
543 const int NOCC_col = idx->
getNOCC( irrep_col );
544 const int NACT_col = idx->
getNDMRG( irrep_col );
545 const int NVIR_col = idx->
getNVIRT( irrep_col );
546 const int N_OA_col = NOCC_col + NACT_col;
547 double * vecAO = origin + jump_col;
548 double * vecVA = vecAO + NACT_col * NOCC_col;
549 double * vecVO = vecVA + NVIR_col * NACT_col;
551 #pragma omp for schedule(static) 552 for (
int act_row = 0; act_row < NACT_row; act_row++ ){
553 for (
int occ_col = 0; occ_col < NOCC_col; occ_col++ ){
554 double * mat = Wtilde->
getBlock( irrep_row, irrep_col, NOCC_row + act_row, occ_col );
555 DGEMV_WRAP( -1.0, mat + NORB_row * NOCC_col, resAO + act_row, vecAO + NACT_col * occ_col, NOCC_row, NACT_col, NORB_row, NACT_row, 1 );
556 DGEMV_WRAP( -1.0, mat + NORB_row * N_OA_col, resAO + act_row, vecVO + NVIR_col * occ_col, NOCC_row, NVIR_col, NORB_row, NACT_row, 1 );
557 DGEMV_WRAP( 1.0, mat + N_OA_row + NORB_row * NOCC_col, resVA + NVIR_row * act_row, vecAO + NACT_col * occ_col, NVIR_row, NACT_col, NORB_row, 1, 1 );
558 DGEMV_WRAP( 1.0, mat + N_OA_row + NORB_row * N_OA_col, resVA + NVIR_row * act_row, vecVO + NVIR_col * occ_col, NVIR_row, NVIR_col, NORB_row, 1, 1 );
560 for (
int act_col = 0; act_col < NACT_col; act_col++ ){
561 double * mat = Wtilde->
getBlock( irrep_row, irrep_col, NOCC_row + act_row, NOCC_col + act_col );
562 DGEMV_WRAP( 1.0, mat, resAO + act_row, vecAO + act_col, NOCC_row, NOCC_col, NORB_row, NACT_row, NACT_col );
563 DGEMV_WRAP( -1.0, mat + NORB_row * N_OA_col, resAO + act_row, vecVA + NVIR_col * act_col, NOCC_row, NVIR_col, NORB_row, NACT_row, 1 );
564 DGEMV_WRAP( -1.0, mat + N_OA_row, resVA + NVIR_row * act_row, vecAO + act_col, NVIR_row, NOCC_col, NORB_row, 1, NACT_col );
565 DGEMV_WRAP( 1.0, mat + N_OA_row + NORB_row * N_OA_col, resVA + NVIR_row * act_row, vecVA + NVIR_col * act_col, NVIR_row, NVIR_col, NORB_row, 1, 1 );
569 #pragma omp for schedule(static) 570 for (
int occ_row = 0; occ_row < NOCC_row; occ_row++ ){
571 for (
int occ_col = 0; occ_col < NOCC_col; occ_col++ ){
572 double * mat = Wtilde->
getBlock( irrep_row, irrep_col, occ_row, occ_col );
573 DGEMV_WRAP( 1.0, mat + NOCC_row + NORB_row * NOCC_col, resAO + NACT_row * occ_row, vecAO + NACT_col * occ_col, NACT_row, NACT_col, NORB_row, 1, 1 );
574 DGEMV_WRAP( 1.0, mat + NOCC_row + NORB_row * N_OA_col, resAO + NACT_row * occ_row, vecVO + NVIR_col * occ_col, NACT_row, NVIR_col, NORB_row, 1, 1 );
575 DGEMV_WRAP( 1.0, mat + N_OA_row + NORB_row * NOCC_col, resVO + NVIR_row * occ_row, vecAO + NACT_col * occ_col, NVIR_row, NACT_col, NORB_row, 1, 1 );
576 DGEMV_WRAP( 1.0, mat + N_OA_row + NORB_row * N_OA_col, resVO + NVIR_row * occ_row, vecVO + NVIR_col * occ_col, NVIR_row, NVIR_col, NORB_row, 1, 1 );
578 for (
int act_col = 0; act_col < NACT_col; act_col++ ){
579 double * mat = Wtilde->
getBlock( irrep_row, irrep_col, occ_row, NOCC_col + act_col );
580 DGEMV_WRAP( -1.0, mat + NOCC_row, resAO + NACT_row * occ_row, vecAO + act_col, NACT_row, NOCC_col, NORB_row, 1, NACT_col );
581 DGEMV_WRAP( 1.0, mat + NOCC_row + NORB_row * N_OA_col, resAO + NACT_row * occ_row, vecVA + NVIR_col * act_col, NACT_row, NVIR_col, NORB_row, 1, 1 );
582 DGEMV_WRAP( -1.0, mat + N_OA_row, resVO + NVIR_row * occ_row, vecAO + act_col, NVIR_row, NOCC_col, NORB_row, 1, NACT_col );
583 DGEMV_WRAP( 1.0, mat + N_OA_row + NORB_row * N_OA_col, resVO + NVIR_row * occ_row, vecVA + NVIR_col * act_col, NVIR_row, NVIR_col, NORB_row, 1, 1 );
586 jump_col += NACT_col * NOCC_col + NVIR_col * NACT_col + NVIR_col * NOCC_col;
588 jump_row += NACT_row * NOCC_row + NVIR_row * NACT_row + NVIR_row * NOCC_row;
594 void CheMPS2::CASSCF::DGEMM_WRAP(
double prefactor,
char transA,
char transB,
double * A,
double * B,
double * C,
int m,
int n,
int k,
int lda,
int ldb,
int ldc ){
596 if ( m * k * n == 0 ){
return; }
598 dgemm_( &transA, &transB, &m, &n, &k, &prefactor, A, &lda, B, &ldb, &add, C, &ldc );
602 void CheMPS2::CASSCF::DGEMV_WRAP(
double prefactor,
double * matrix,
double * result,
double * vector,
int rowdim,
int coldim,
int ldmat,
int incres,
int incvec ){
604 if ( rowdim * coldim == 0 ){
return; }
607 dgemv_( ¬rans, &rowdim, &coldim, &prefactor, matrix, &ldmat, vector, &incvec, &add, result, &incres );
613 localwtilde->
clear();
616 for (
int irrep_pq = 0; irrep_pq < numIrreps; irrep_pq++){
618 const int NumOCCpq = localIdx->
getNOCC( irrep_pq );
619 const int NumDMRGpq = localIdx->
getNDMRG( irrep_pq );
620 const int NumORBpq = localIdx->
getNORB( irrep_pq );
621 const int NumCOREpq = NumOCCpq + NumDMRGpq;
624 #pragma omp parallel for schedule(static) 625 for (
int relindexP = 0; relindexP < NumOCCpq; relindexP++){
626 double * subblock = localwtilde->
getBlock( irrep_pq, irrep_pq, relindexP, relindexP);
627 for (
int relindexS = NumOCCpq; relindexS < NumORBpq; relindexS++){
628 for (
int relindexQ = NumOCCpq; relindexQ < NumORBpq; relindexQ++){
629 subblock[ relindexQ + NumORBpq * relindexS ] += 4 * ( localTmat->
get( irrep_pq, relindexQ, relindexS)
630 + localJKocc->
get(irrep_pq, relindexQ, relindexS)
631 + localJKact->
get(irrep_pq, relindexQ, relindexS) );
637 #pragma omp parallel for schedule(static) 638 for (
int combined = 0; combined < NumDMRGpq*NumDMRGpq; combined++){
640 const int relindexP = NumOCCpq + ( combined % NumDMRGpq );
641 const int relindexR = NumOCCpq + ( combined / NumDMRGpq );
642 double * subblock = localwtilde->
getBlock( irrep_pq, irrep_pq, relindexP, relindexR );
643 const int DMRGindexP = relindexP - NumOCCpq + localIdx->
getDMRGcumulative( irrep_pq );
644 const int DMRGindexR = relindexR - NumOCCpq + localIdx->
getDMRGcumulative( irrep_pq );
645 const double OneDMvalue = local1DM[ DMRGindexP + totOrbDMRG * DMRGindexR ];
647 for (
int relindexS = 0; relindexS < NumOCCpq; relindexS++){
648 for (
int relindexQ = 0; relindexQ < NumOCCpq; relindexQ++){
649 subblock[ relindexQ + NumORBpq * relindexS ] += 2 * OneDMvalue * ( localTmat->
get( irrep_pq, relindexQ, relindexS)
650 + localJKocc->
get(irrep_pq, relindexQ, relindexS) );
652 for (
int relindexQ = NumCOREpq; relindexQ < NumORBpq; relindexQ++){
653 subblock[ relindexQ + NumORBpq * relindexS ] += 2 * OneDMvalue * ( localTmat->
get( irrep_pq, relindexQ, relindexS)
654 + localJKocc->
get(irrep_pq, relindexQ, relindexS) );
657 for (
int relindexS = NumCOREpq; relindexS < NumORBpq; relindexS++){
658 for (
int relindexQ = 0; relindexQ < NumOCCpq; relindexQ++){
659 subblock[ relindexQ + NumORBpq * relindexS ] += 2 * OneDMvalue * ( localTmat->
get( irrep_pq, relindexQ, relindexS)
660 + localJKocc->
get(irrep_pq, relindexQ, relindexS) );
662 for (
int relindexQ = NumCOREpq; relindexQ < NumORBpq; relindexQ++){
663 subblock[ relindexQ + NumORBpq * relindexS ] += 2 * OneDMvalue * ( localTmat->
get( irrep_pq, relindexQ, relindexS)
664 + localJKocc->
get(irrep_pq, relindexQ, relindexS) );
669 for (
int irrep_rs = 0; irrep_rs < numIrreps; irrep_rs++){
671 const int NumOCCrs = localIdx->
getNOCC( irrep_rs );
672 const int NumDMRGrs = localIdx->
getNDMRG( irrep_rs );
673 const int NumORBrs = localIdx->
getNORB( irrep_rs );
674 const int NumCORErs = NumOCCrs + NumDMRGrs;
678 #pragma omp parallel for schedule(static) 679 for (
int combined = 0; combined < NumOCCpq*NumOCCrs; combined++){
681 const int relindexP = combined % NumOCCpq;
682 const int relindexR = combined / NumOCCpq;
683 double * subblock = localwtilde->
getBlock( irrep_pq, irrep_rs, relindexP, relindexR);
685 for (
int relindexS = NumOCCrs; relindexS < NumORBrs; relindexS++){
686 for (
int relindexQ = NumOCCpq; relindexQ < NumORBpq; relindexQ++){
687 subblock[ relindexQ + NumORBpq * relindexS ] +=
688 4 * ( 4 * theInts->
FourIndexAPI(irrep_pq, irrep_rs, irrep_pq, irrep_rs, relindexQ, relindexS, relindexP, relindexR)
689 - theInts->
FourIndexAPI(irrep_pq, irrep_pq, irrep_rs, irrep_rs, relindexQ, relindexP, relindexS, relindexR)
690 - theInts->
FourIndexAPI(irrep_pq, irrep_rs, irrep_rs, irrep_pq, relindexQ, relindexS, relindexR, relindexP) );
696 #pragma omp parallel for schedule(static) 697 for (
int combined = 0; combined < NumDMRGpq*NumDMRGrs; combined++){
699 const int relindexP = NumOCCpq + ( combined % NumDMRGpq );
700 const int relindexR = NumOCCrs + ( combined / NumDMRGpq );
701 double * subblock = localwtilde->
getBlock( irrep_pq, irrep_rs, relindexP, relindexR );
702 const int DMRGindexP = relindexP - NumOCCpq + localIdx->
getDMRGcumulative( irrep_pq );
703 const int DMRGindexR = relindexR - NumOCCrs + localIdx->
getDMRGcumulative( irrep_rs );
705 for (
int irrep_alpha = 0; irrep_alpha < numIrreps; irrep_alpha++){
708 const int NumDMRGalpha = localIdx->
getNDMRG( irrep_alpha );
709 const int NumDMRGbeta = localIdx->
getNDMRG( irrep_beta );
711 for (
int alpha = 0; alpha < NumDMRGalpha; alpha++){
714 const int relalpha = localIdx->
getNOCC( irrep_alpha ) + alpha;
716 for (
int beta = 0; beta < NumDMRGbeta; beta++){
719 const int relbeta = localIdx->
getNOCC( irrep_beta ) + beta;
721 const double TwoDMvalue1 = local2DM[ DMRGindexR + totOrbDMRG * ( DMRGalpha + totOrbDMRG * ( DMRGindexP + totOrbDMRG * DMRGbeta ) ) ];
722 const double TwoDMvalue23 = local2DM[ DMRGindexR + totOrbDMRG * ( DMRGalpha + totOrbDMRG * ( DMRGbeta + totOrbDMRG * DMRGindexP ) ) ]
723 + local2DM[ DMRGindexR + totOrbDMRG * ( DMRGindexP + totOrbDMRG * ( DMRGbeta + totOrbDMRG * DMRGalpha ) ) ];
725 for (
int relindexS = 0; relindexS < NumOCCrs; relindexS++){
726 for (
int relindexQ = 0; relindexQ < NumOCCpq; relindexQ++){
727 subblock[ relindexQ + NumORBpq * relindexS ] +=
728 2 * ( TwoDMvalue1 * theInts->
FourIndexAPI( irrep_pq, irrep_alpha, irrep_rs, irrep_beta, relindexQ, relalpha, relindexS, relbeta)
729 + TwoDMvalue23 * theInts->
FourIndexAPI( irrep_pq, irrep_rs, irrep_alpha, irrep_beta, relindexQ, relindexS, relalpha, relbeta) );
731 for (
int relindexQ = NumCOREpq; relindexQ < NumORBpq; relindexQ++){
732 subblock[ relindexQ + NumORBpq * relindexS ] +=
733 2 * ( TwoDMvalue1 * theInts->
FourIndexAPI( irrep_pq, irrep_alpha, irrep_rs, irrep_beta, relindexQ, relalpha, relindexS, relbeta)
734 + TwoDMvalue23 * theInts->
FourIndexAPI( irrep_pq, irrep_rs, irrep_alpha, irrep_beta, relindexQ, relindexS, relalpha, relbeta) );
737 for (
int relindexS = NumCORErs; relindexS < NumORBrs; relindexS++){
738 for (
int relindexQ = 0; relindexQ < NumOCCpq; relindexQ++){
739 subblock[ relindexQ + NumORBpq * relindexS ] +=
740 2 * ( TwoDMvalue1 * theInts->
FourIndexAPI( irrep_pq, irrep_alpha, irrep_rs, irrep_beta, relindexQ, relalpha, relindexS, relbeta)
741 + TwoDMvalue23 * theInts->
FourIndexAPI( irrep_pq, irrep_rs, irrep_alpha, irrep_beta, relindexQ, relindexS, relalpha, relbeta) );
743 for (
int relindexQ = NumCOREpq; relindexQ < NumORBpq; relindexQ++){
744 subblock[ relindexQ + NumORBpq * relindexS ] +=
745 2 * ( TwoDMvalue1 * theInts->
FourIndexAPI( irrep_pq, irrep_alpha, irrep_rs, irrep_beta, relindexQ, relalpha, relindexS, relbeta)
746 + TwoDMvalue23 * theInts->
FourIndexAPI( irrep_pq, irrep_rs, irrep_alpha, irrep_beta, relindexQ, relindexS, relalpha, relbeta) );
755 #pragma omp parallel for schedule(static) 756 for (
int combined = 0; combined < NumDMRGpq*NumOCCrs; combined++){
758 const int relindexP = NumOCCpq + ( combined % NumDMRGpq );
759 const int relindexR = combined / NumDMRGpq;
760 double * subblock = localwtilde->
getBlock( irrep_pq, irrep_rs, relindexP, relindexR );
761 const int DMRGindexP = relindexP - NumOCCpq + localIdx->
getDMRGcumulative( irrep_pq );
763 for (
int alpha = 0; alpha < NumDMRGpq; alpha++){
766 const int relalpha = localIdx->
getNOCC( irrep_pq ) + alpha;
767 const double OneDMvalue = local1DM[ DMRGalpha + totOrbDMRG * DMRGindexP ];
769 for (
int relindexS = NumOCCrs; relindexS < NumORBrs; relindexS++){
770 for (
int relindexQ = 0; relindexQ < NumOCCpq; relindexQ++){
771 subblock[ relindexQ + NumORBpq * relindexS ] += 2 * OneDMvalue *
772 ( 4 * theInts->
FourIndexAPI( irrep_pq, irrep_rs, irrep_pq, irrep_rs, relindexQ, relindexS, relalpha, relindexR)
773 - theInts->
FourIndexAPI( irrep_pq, irrep_pq, irrep_rs, irrep_rs, relindexQ, relalpha, relindexS, relindexR)
774 - theInts->
FourIndexAPI( irrep_pq, irrep_rs, irrep_rs, irrep_pq, relindexQ, relindexS, relindexR, relalpha) );
776 for (
int relindexQ = NumCOREpq; relindexQ < NumORBpq; relindexQ++){
777 subblock[ relindexQ + NumORBpq * relindexS ] += 2 * OneDMvalue *
778 ( 4 * theInts->
FourIndexAPI( irrep_pq, irrep_rs, irrep_pq, irrep_rs, relindexQ, relindexS, relalpha, relindexR)
779 - theInts->
FourIndexAPI( irrep_pq, irrep_pq, irrep_rs, irrep_rs, relindexQ, relalpha, relindexS, relindexR)
780 - theInts->
FourIndexAPI( irrep_pq, irrep_rs, irrep_rs, irrep_pq, relindexQ, relindexS, relindexR, relalpha) );
787 #pragma omp parallel for schedule(static) 788 for (
int combined = 0; combined < NumOCCpq*NumDMRGrs; combined++){
790 const int relindexP = combined % NumOCCpq;
791 const int relindexR = NumOCCrs + ( combined / NumOCCpq );
792 double * subblock = localwtilde->
getBlock( irrep_pq, irrep_rs, relindexP, relindexR );
793 const int DMRGindexR = relindexR - NumOCCrs + localIdx->
getDMRGcumulative( irrep_rs );
795 for (
int beta = 0; beta < NumDMRGrs; beta++){
798 const int relbeta = localIdx->
getNOCC( irrep_rs ) + beta;
799 const double OneDMvalue = local1DM[ DMRGindexR + totOrbDMRG * DMRGbeta ];
801 for (
int relindexQ = NumOCCpq; relindexQ < NumORBpq; relindexQ++){
802 for (
int relindexS = 0; relindexS < NumOCCrs; relindexS++){
803 subblock[ relindexQ + NumORBpq * relindexS ] += 2 * OneDMvalue *
804 ( 4 * theInts->
FourIndexAPI( irrep_pq, irrep_rs, irrep_pq, irrep_rs, relindexQ, relindexS, relindexP, relbeta)
805 - theInts->
FourIndexAPI( irrep_pq, irrep_pq, irrep_rs, irrep_rs, relindexQ, relindexP, relindexS, relbeta)
806 - theInts->
FourIndexAPI( irrep_pq, irrep_rs, irrep_rs, irrep_pq, relindexQ, relindexS, relbeta, relindexP) );
808 for (
int relindexS = NumCORErs; relindexS < NumORBrs; relindexS++){
809 subblock[ relindexQ + NumORBpq * relindexS ] += 2 * OneDMvalue *
810 ( 4 * theInts->
FourIndexAPI( irrep_pq, irrep_rs, irrep_pq, irrep_rs, relindexQ, relindexS, relindexP, relbeta)
811 - theInts->
FourIndexAPI( irrep_pq, irrep_pq, irrep_rs, irrep_rs, relindexQ, relindexP, relindexS, relbeta)
812 - theInts->
FourIndexAPI( irrep_pq, irrep_rs, irrep_rs, irrep_pq, relindexQ, relindexS, relbeta, relindexP) );
828 for (
int irrep_pq = 0; irrep_pq < numIrreps; irrep_pq++){
830 const int NumORB = localIdx->
getNORB( irrep_pq );
831 const int NumOCC = localIdx->
getNOCC( irrep_pq );
832 const int NumDMRG = localIdx->
getNDMRG( irrep_pq );
833 const int NumOCCDMRG = NumOCC + NumDMRG;
835 #pragma omp parallel for schedule(static) 836 for (
int p = 0; p < NumOCC; p++){
837 for (
int q = 0; q < NumORB; q++){
838 localFmat->
set( irrep_pq, p, q, 2 * ( localTmat->
get( irrep_pq, q, p )
839 + localJKocc->
get( irrep_pq, q, p )
840 + localJKact->
get( irrep_pq, q, p ) ) );
844 #pragma omp parallel for schedule(static) 845 for (
int p = NumOCC; p < NumOCCDMRG; p++){
849 for (
int r = NumOCC; r < NumOCCDMRG; r++){
850 const double OneDMvalue = local1DM[ DMRGindex_p + totOrbDMRG * ( DMRGindex_p + r - p ) ];
851 for (
int q = 0; q < NumORB; q++){
852 localFmat->
getBlock(irrep_pq)[ p + NumORB * q ] += OneDMvalue * ( localTmat->
get( irrep_pq, q, r ) + localJKocc->
get( irrep_pq, q, r) );
857 for (
int irrep_r = 0; irrep_r < numIrreps; irrep_r++){
859 for (
int irrep_s = 0; irrep_s < numIrreps; irrep_s++){
861 for (
int r = localIdx->
getNOCC(irrep_r); r < localIdx->
getNOCC(irrep_r) + localIdx->
getNDMRG(irrep_r); r++){
863 for (
int s = localIdx->
getNOCC(irrep_s); s < localIdx->
getNOCC(irrep_s) + localIdx->
getNDMRG(irrep_s); s++){
865 for (
int t = localIdx->
getNOCC(irrep_t); t < localIdx->
getNOCC(irrep_t) + localIdx->
getNDMRG(irrep_t); t++){
867 const double TwoDMvalue = local2DM[ DMRGindex_p + totOrbDMRG * ( DMRGindex_r + totOrbDMRG * ( DMRGindex_s + totOrbDMRG * DMRGindex_t ) ) ];
868 for (
int q = 0; q < NumORB; q++){
869 localFmat->
getBlock(irrep_pq)[ p + NumORB * q ] += TwoDMvalue * theInts->
FourIndexAPI(irrep_pq, irrep_r, irrep_s, irrep_t, q, r, s, t);
int getMaxIterations() const
Get the maximum number of DMRGSCF iterations.
int getNORB(const int irrep) const
Get the number of orbitals for an irrep.
double * getBlock(const int irrep)
Get a matrix block.
int getNOCCsum() const
Get the total number of occupied orbitals.
static void rotate(const FourIndex *ORIG_VMAT, FourIndex *NEW_VMAT, DMRGSCFintegrals *ROT_TEI, const char space1, const char space2, const char space3, const char space4, DMRGSCFindices *idx, DMRGSCFunitary *umat, double *mem1, double *mem2, const int mem_size, const string filename)
Fill the rotated two-body matrix elements for the space. If the blocks become too large...
int getROTparamsize() const
Get the orbital rotation parameter space size.
int GetNumMultiplications() const
Get the number of matrix vector multiplications which have been performed.
void rotateActiveSpaceVectors(double *eigenvecs, double *work)
Rotate the unitary matrix.
double GSDavidson(double *inoutput=NULL, const int DVDSN_NUM_VEC=CheMPS2::DAVIDSON_NUM_VEC) const
Calculates the FCI ground state with Davidson's algorithm.
static void buildWtilde(DMRGSCFwtilde *localwtilde, const DMRGSCFmatrix *localTmat, const DMRGSCFmatrix *localJKocc, const DMRGSCFmatrix *localJKact, const DMRGSCFindices *localIdx, const DMRGSCFintegrals *theInts, double *local2DM, double *local1DM)
Build the Wtilde-matrix (Eq. (20b) in the Siegbahn paper [CAS3])
void appendNew(double *newError, double *newParam)
Append a new error and parameter vector.
static void copy_active(double *origin, DMRGSCFmatrix *result, const DMRGSCFindices *idx, const bool one_rdm)
Copy a one-orbital quantity from array format to DMRGSCFmatrix format.
void loadDIIS(const string filename=DMRGSCF_diis_storage_name)
Load the DIIS object from disk.
void deleteStoredMPS()
Call "rm " + CheMPS2::DMRG_MPS_storage_prefix + "*.h5".
int getGroupNumber() const
Get the group number.
static void augmentedHessianNR(DMRGSCFmatrix *localFmat, DMRGSCFwtilde *localwtilde, const DMRGSCFindices *localIdx, const DMRGSCFunitary *localUmat, double *theupdate, double *updateNorm, double *gradNorm)
Calculate the augmented Hessian Newton-Raphson update for the orthogonal orbital rotation matrix...
void loadU(const string filename=DMRGSCF_unitary_storage_name)
Load the unitary from disk.
int * getIrrepOfEachDMRGorbital()
Get an array with the irreps of each DMRG orbital.
void Print(const int precision=6, const int columnsPerLine=8) const
Print the correlation functions and two-orbital mutual information.
static int mpi_rank()
Get the rank of this MPI process.
double getVmat(const int index1, const int index2, const int index3, const int index4) const
Get a Vmat element.
int getDMRGcumulative(const int irrep) const
Get the cumulative number of active orbitals for an irrep.
Correlations * getCorrelations()
Get the pointer to the Correlations.
TwoDM * get2DM()
Get the pointer to the 2-RDM.
void getLog(double *vector, double *temp1, double *temp2) const
Obtain the logarithm of the unitary matrix.
int getGroupNumber() const
Get the group number.
void saveDIIS(const string filename=DMRGSCF_diis_storage_name) const
Save the DIIS object to disk.
void set(const int irrep, const int p, const int q, const double val)
Set an element.
int getNORBmax() const
Get the maximum NORB.
unsigned int LowestEnergyDeterminant() const
Return the global counter of the Slater determinant with the lowest energy.
void saveU(const string filename=DMRGSCF_unitary_storage_name) const
Save the unitary to disk.
bool getDumpCorrelations() const
Get whether the correlations and two-orbital mutual information should be printed.
static void copy2DMover(TwoDM *theDMRG2DM, const int LAS, double *two_dm)
Copy over the DMRG 2-RDM.
int getWhichActiveSpace() const
Get which active space should be considered in the DMRG routine.
static void block_diagonalize(const char space, const DMRGSCFmatrix *Mat, DMRGSCFunitary *Umat, double *work1, double *work2, const DMRGSCFindices *idx, const bool invert, double *two_dm, double *three_dm, double *contract)
Block-diagonalize Mat.
double FourIndexAPI(const int I1, const int I2, const int I3, const int I4, const int index1, const int index2, const int index3, const int index4) const
Get a two-body matrix element with at most 2 virtual indices, using the FourIndex API...
int getNumDIISVecs() const
Get the number of DIIS update vectors which should be kept.
void FiedlerGlobal(int *dmrg2ham) const
Permute the orbitals so that the bandwidth of the exchange matrix is (approximately) minimized...
string getDIISStorageName() const
Get the DIIS checkpoint filename.
static void fillLocalizedOrbitalRotations(DMRGSCFunitary *umat, DMRGSCFindices *idx, double *eigenvecs)
From an Edmiston-Ruedenberg active space rotation, fetch the eigenvectors and store them in eigenvecs...
void newExcitation(const double EshiftIn)
Push back current calculation and set everything up to calculate a (new) excitation.
bool getDoDIIS() const
Get whether DIIS should be performed.
DMRGSCFunitary * getUnitary()
Get the pointer to the unitary to use in DMRGSCF.
void FiedlerExchange(const int maxlinsize, double *temp1, double *temp2)
Permute the orbitals so that the bandwidth of the exchange matrix is (approximately) minimized (per i...
bool getStartLocRandom() const
Get whether the localization procedure should start from a random unitary.
double Optimize(double *temp1, double *temp2, const bool startFromRandomUnitary, const double gradThreshold=EDMISTONRUED_gradThreshold, const int maxIter=EDMISTONRUED_maxIter)
Maximize the Edmiston-Ruedenberg cost function.
double solve(const int Nelectrons, const int TwoS, const int Irrep, ConvergenceScheme *OptScheme, const int rootNum, DMRGSCFoptions *scf_options)
Do the CASSCF cycles with the augmented Hessian Newton-Raphson method.
double get(const int irrep, const int p, const int q) const
Get an element.
bool getStoreDIIS() const
Get whether the DIIS checkpoint should be stored to disk.
void makeSureAllBlocksDetOne(double *temp1, double *temp2)
Orbitals are defined up to a phase factor. Make sure that the logarithm of each block of the unitary ...
int getNumVariablesX() const
Get the number of variables in the x-parametrization of the unitary update.
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...
bool getStoreUnitary() const
Get whether the Orbital Rotation checkpoint should be stored to disk.
unsigned int getVecLength(const int irrep_center) const
Getter for the number of variables in the vector " E_ij | FCI vector > " ; where irrep_center = I_i x...
static void setDMRG1DM(const int num_elec, const int LAS, double *one_dm, double *two_dm)
Construct the 1-RDM from the 2-RDM.
void calculateParam(double *newParam)
Calculate the new parameter vector, based on the just appended error and parameter vectors...
double get(const int irrep_pq, const int irrep_rs, const int p, const int q, const int r, const int s) const
Get an element of w_tilde_pqrs.
bool getStateAveraging() const
Get whether state-averaging or state-specific DMRGSCF should be performed.
static void ClearVector(const unsigned int vecLength, double *vec)
Set the entries of a vector to zero.
void updateUnitary(double *workmem1, double *workmem2, double *vector, const bool multiply, const bool compact)
Update the unitary transformation.
void activateExcitations(const int maxExcIn)
Activate the necessary storage and machinery to handle excitations.
int getNDMRG(const int irrep) const
Get the number of active orbitals for an irrep.
int getNOCC(const int irrep) const
Get the number of occupied orbitals for an irrep.
char FetchInstruction(double **pointers)
The iterator to converge the ground state vector.
void deleteStoredOperators()
Call "rm " + tempfolder + "/" + CheMPS2::DMRG_OPERATOR_storage_prefix + string(thePID) + "*...
void calc2DMandCorrelations()
Calculate the 2-RDM and correlations. Afterwards the MPS is again in LLLLLLLC gauge.
double Fill2RDM(double *vector, double *TwoRDM) const
Construct the (spin-summed) 2-RDM of a FCI vector: Gamma^2(i,j,k,l) = sum_sigma,tau < a^+_i...
int getNVIRT(const int irrep) const
Get the number of virtual orbitals for an irrep.
double getGradientThreshold() const
Get the threshold for DMRGSCF convergence.
void clear()
Clear the matrix.
double * getBlock(const int irrep_pq, const int irrep_rs, const int p, const int r)
Get the (pr) subblock of w_tilde_pqrs, which is stored as w_tilde[ I_pq ][ I_rs ][ p + ( Nocc[I_pq] +...
static void buildFmat(DMRGSCFmatrix *localFmat, const DMRGSCFmatrix *localTmat, const DMRGSCFmatrix *localJKocc, const DMRGSCFmatrix *localJKact, const DMRGSCFindices *localIdx, const DMRGSCFintegrals *theInts, double *local2DM, double *local1DM)
Build the F-matrix (Eq. (11) in the Siegbahn paper [CAS3])
string getUnitaryStorageName() const
Get the Orbital Rotation checkpoint filename.
int getNirreps() const
Get the number of irreps.