1 #ifndef __DMRG_BLOCK_CONTAINER_HPP__ 2 #define __DMRG_BLOCK_CONTAINER_HPP__ 11 #include <petsctime.h> 22 #include "DMRGKron.hpp" 23 #include "MiscTools.hpp" 26 PETSC_EXTERN PetscErrorCode
Makedir(
27 const std::string& dir_name
31 #define CheckInitialization(init,mpi_comm) \ 33 if(!init) SETERRQ(mpi_comm,1,"DMRGBlockContainer object not initialized."\ 34 "Call Initialize() first.");\ 38 #define PrintLines() \ 40 printf("-----------------------------------------\n"); \ 44 #define PRINTLINES() \ 46 printf("=========================================\n"); \ 50 #define PrintBlocks(LEFT,RIGHT) \ 52 printf(" [%lld]-* *-[%lld]\n", LLD(LEFT), LLD(RIGHT)); \ 56 #define ASSIGN_VAR(MAP,VAR) \ 58 const auto it = MAP.find(#VAR); \ 63 SETERRQ2(PETSC_COMM_SELF,1,"Key %s not found in %s",#VAR,#MAP); \ 67 #define PRINT_VAR(VAR) \ 68 std::cout << " " << std::setw(20) << #VAR << " = " << VAR << std::endl; 71 #define OpIdxToStr(OPTYPE,IDX) \ 72 (OpToStr(OPTYPE)+std::to_string(IDX)) 75 #define GetOpMats(OPMATS,CORRSIDEOPS,OPID) \ 76 (OPMATS.at(OpIdxToStr(CORRSIDEOPS.at(OPID).OpType,CORRSIDEOPS.at(OPID).idx))) 79 #define MAX_SWEEP_IDX 10000 103 std::cout <<
" Op" <<
OpIdxToStr(OpType, idx) << std::endl;
232 std::cout <<
" Correlator " << idx <<
": " << name << std::endl;
233 std::cout <<
" " << desc1 << std::endl;
234 std::cout <<
" " << desc2 << std::endl;
235 std::cout <<
" " << desc3 << std::endl;
251 PetscErrorCode ierr = 0;
252 for(
auto& rdmd: rdmd_list){
253 ierr = MatDestroy(&(rdmd.second)); CPP_CHKERR(ierr);
255 ierr = MatDestroy(&RotMatT); CPP_CHKERR(ierr);
267 PetscErrorCode ierr = Destroy(); CPP_CHKERR(ierr);
274 if(init) SETERRQ(mpi_comm,1,
"DMRG object has already been initialized.");
275 PetscErrorCode ierr = 0;
276 char path[PETSC_MAX_PATH_LEN];
279 ierr = MPI_Comm_size(mpi_comm, &mpi_size); CHKERRQ(ierr);
280 ierr = MPI_Comm_rank(mpi_comm, &mpi_rank); CHKERRQ(ierr);
285 ierr = PetscOptionsGetString(NULL,NULL,
"-restart_dir",path,PETSC_MAX_PATH_LEN,&restart); CHKERRQ(ierr);
286 ierr = PetscOptionsGetBool(NULL,NULL,
"-restart_options",&restart_options,NULL); CHKERRQ(ierr);
289 restart_dir = std::string(path);
290 if(restart_dir.back()!=
'/') restart_dir +=
"/";
302 file = restart_dir + SweepDir(ridx);
303 ierr = PetscTestDirectory(file.c_str(),
'r', &flg); CHKERRQ(ierr);
310 SETERRQ1(PETSC_COMM_SELF,1,
"No Sweep directory was found in %s",
311 restart_dir.c_str());
315 file = restart_dir + SweepDir(ridx+1) +
"Sweep.dat";
316 ierr = PetscTestFile(file.c_str(),
'r', &flg); CHKERRQ(ierr);
321 ierr = MPI_Bcast(&ridx, 1, MPIU_INT, 0, mpi_comm); CHKERRQ(ierr);
324 restart_dir = restart_dir + SweepDir(ridx);
330 std::string filename = restart_dir +
"Sweep.dat";
331 ierr = RetrieveInfoFile<PetscInt>(mpi_comm,filename,restart_sweep_dict); CHKERRQ(ierr);
336 ASSIGN_VAR(restart_sweep_dict, num_sys_blocks );
337 ASSIGN_VAR(restart_sweep_dict, num_env_blocks );
346 std::cout <<
"WARNING:\nThe following variables have been" 347 <<
" forcefully set:" << std::endl;
357 if(restart && restart_options) {
359 if(!mpi_rank) std::cout <<
"since the -restart_options flag was enabled." << std::endl;
364 ierr = Ham.SetFromOptions(); CHKERRQ(ierr);
367 ierr = SingleSite.Initialize(mpi_comm, 1, PETSC_DEFAULT); CHKERRQ(ierr);
369 num_sites = Ham.NumSites();
371 if((num_sites) < 2) SETERRQ1(mpi_comm,1,
"There must be at least two total sites. Got %lld.", LLD(num_sites));
372 if((num_sites) % 2) SETERRQ1(mpi_comm,1,
"Total number of sites must be even. Got %lld.", LLD(num_sites));
375 ierr = PetscOptionsGetBool(NULL,NULL,
"-verbose",&verbose,NULL); CHKERRQ(ierr);
376 ierr = PetscOptionsGetBool(NULL,NULL,
"-no_symm",&no_symm,NULL); CHKERRQ(ierr);
377 ierr = PetscOptionsGetBool(NULL,NULL,
"-do_shell",&do_shell,NULL); CHKERRQ(ierr);
378 ierr = PetscOptionsGetBool(NULL,NULL,
"-dry_run",&dry_run,NULL); CHKERRQ(ierr);
379 ierr = PetscOptionsGetReal(NULL,NULL,
"-qn_sector",&qn_sector,NULL); CHKERRQ(ierr);
382 PetscBool opt_do_scratch_dir = PETSC_FALSE;
383 ierr = PetscOptionsGetString(NULL,NULL,
"-scratch_dir",path,PETSC_MAX_PATH_LEN,&opt_do_scratch_dir); CHKERRQ(ierr);
384 if(opt_do_scratch_dir){
385 scratch_dir = std::string(path);
386 if(scratch_dir.back()!=
'/') scratch_dir +=
'/';
388 scratch_dir =
"./scratch_dir/";
390 ierr =
Makedir(scratch_dir); CHKERRQ(ierr);
394 do_scratch_dir = PETSC_TRUE;
398 std::string data_dir;
399 PetscBool opt_data_dir = PETSC_FALSE;
400 ierr = PetscOptionsGetString(NULL,NULL,
"-data_dir",path,PETSC_MAX_PATH_LEN,&opt_data_dir); CHKERRQ(ierr);
402 data_dir = std::string(path);
403 if(data_dir.back()!=
'/') data_dir +=
'/';
405 data_dir =
"./data_dir/";
407 ierr =
Makedir(data_dir); CHKERRQ(ierr);
410 ierr = PetscFOpen(mpi_comm, (data_dir+std::string(
"DMRGSteps.json")).c_str(),
"w", &fp_step); CHKERRQ(ierr);
411 ierr = SaveStepHeaders(); CHKERRQ(ierr);
412 if(!mpi_rank) fprintf(fp_step,
"[\n");
414 ierr = PetscFOpen(mpi_comm, (data_dir+std::string(
"Timings.json")).c_str(),
"w", &fp_timings); CHKERRQ(ierr);
415 ierr = SaveTimingsHeaders(); CHKERRQ(ierr);
416 if(!mpi_rank) fprintf(fp_timings,
"[\n");
418 ierr = PetscFOpen(mpi_comm, (data_dir+std::string(
"EntanglementSpectra.json")).c_str(),
"w", &fp_entanglement); CHKERRQ(ierr);
419 if(!mpi_rank) fprintf(fp_entanglement,
"[\n");
421 ierr = PetscFOpen(mpi_comm, (data_dir+std::string(
"DMRGRun.json")).c_str(),
"w", &fp_data); CHKERRQ(ierr);
423 fprintf(fp_data,
"{\n");
424 Ham.SaveOut(fp_data);
425 fprintf(fp_data,
",\n");
426 fprintf(fp_data,
" \"QNSector\": %g", qn_sector);
430 ierr = PetscFOpen(mpi_comm, (data_dir+std::string(
"Correlations.json")).c_str(),
"w", &fp_corr); CHKERRQ(ierr);
433 ierr = PetscOptionsGetBool(NULL,NULL,
"-do_save_prealloc",&do_save_prealloc,NULL); CHKERRQ(ierr);
434 if(do_save_prealloc){
435 ierr = PetscFOpen(mpi_comm, (data_dir+std::string(
"HamiltonianPrealloc.json")).c_str(),
"w", &fp_prealloc); CHKERRQ(ierr);
436 if(!mpi_rank) fprintf(fp_prealloc,
"[\n");
441 printf(
"=========================================\n" 442 "DENSITY MATRIX RENORMALIZATION GROUP\n" 443 "-----------------------------------------\n");
445 printf(
"-----------------------------------------\n");
446 printf(
"DIRECTORIES\n");
447 if(do_scratch_dir) printf(
448 " Scratch: %s\n", scratch_dir.c_str());
449 printf(
" Data: %s\n", data_dir.c_str());
451 " Restart: %s\n", restart_dir.c_str());
452 printf(
"=========================================\n");
457 PetscBool opt_mstates = PETSC_FALSE,
458 opt_mwarmup = PETSC_FALSE,
459 opt_nsweeps = PETSC_FALSE,
460 opt_msweeps = PETSC_FALSE,
461 opt_maxnsweeps = PETSC_FALSE;
462 PetscInt mstates, num_msweeps=1000;
463 msweeps.resize(num_msweeps);
465 ierr = PetscOptionsGetInt(NULL,NULL,
"-mstates",&mstates,&opt_mstates); CHKERRQ(ierr);
466 ierr = PetscOptionsGetInt(NULL,NULL,
"-mwarmup",&mwarmup,&opt_mwarmup); CHKERRQ(ierr);
467 ierr = PetscOptionsGetInt(NULL,NULL,
"-nsweeps",&nsweeps,&opt_nsweeps); CHKERRQ(ierr);
468 ierr = PetscOptionsGetIntArray(NULL,NULL,
"-msweeps",&msweeps.at(0),&num_msweeps,&opt_msweeps); CHKERRQ(ierr);
469 msweeps.resize(num_msweeps);
471 PetscInt num_maxnsweeps = 1000;
472 maxnsweeps.resize(num_maxnsweeps);
473 ierr = PetscOptionsGetIntArray(NULL,NULL,
"-maxnsweeps",&maxnsweeps.at(0),&num_maxnsweeps,&opt_maxnsweeps); CHKERRQ(ierr);
474 maxnsweeps.resize(num_maxnsweeps);
487 if(opt_mstates && !opt_mwarmup)
493 if(opt_nsweeps && opt_msweeps)
494 SETERRQ(mpi_comm,1,
"-msweeps and -nsweeps cannot both be specified at the same time.");
499 if(opt_nsweeps && opt_msweeps)
500 SETERRQ(mpi_comm,1,
"-nsweeps and -maxnsweeps cannot both be specified at the same time.");
505 if(opt_maxnsweeps && (num_maxnsweeps != num_msweeps))
506 SETERRQ2(mpi_comm,1,
"-msweeps and -maxnsweeps must have the same number of items. " 507 "Got %lld and %lld, respectively.", num_msweeps, num_maxnsweeps);
514 if(opt_nsweeps && !opt_msweeps)
516 sweep_mode = SWEEP_MODE_NSWEEPS;
518 else if(opt_msweeps && !opt_nsweeps)
525 sweep_mode = SWEEP_MODE_TOLERANCE_TEST;
532 sweep_mode = SWEEP_MODE_MSWEEPS;
535 else if(!opt_msweeps && !opt_nsweeps)
537 sweep_mode = SWEEP_MODE_NULL;
541 SETERRQ(mpi_comm,1,
"Invalid parameters specified for choosing sweep mode.");
545 if(!mpi_rank && !restart){
548 <<
" NumStates to keep: " << mwarmup <<
"\n";
556 <<
" Sweep mode: " << SweepModeToString.at(sweep_mode)
559 if(sweep_mode==SWEEP_MODE_NSWEEPS)
561 std::cout <<
" Number of sweeps: " << nsweeps << std::endl;
563 else if(sweep_mode==SWEEP_MODE_MSWEEPS)
565 std::cout <<
" NumStates to keep: ";
566 for(
const PetscInt& mstates: msweeps) std::cout <<
" " << mstates;
567 std::cout << std::endl;
569 else if(sweep_mode==SWEEP_MODE_TOLERANCE_TEST)
571 std::cout <<
" NumStates to keep, maxiter: ";
572 for(
size_t i = 0; i < msweeps.size(); ++i)
573 std::cout <<
" (" << msweeps.at(i) <<
"," << maxnsweeps.at(i) <<
")";
574 std::cout << std::endl;
576 else if(sweep_mode==SWEEP_MODE_NULL)
584 LoopType = WarmupStep;
594 ierr = SingleSite.Destroy(); CHKERRQ(ierr);
595 for(
Block blk: sys_blocks) { ierr = blk.Destroy(); CHKERRQ(ierr); }
596 for(
Block blk: env_blocks) { ierr = blk.Destroy(); CHKERRQ(ierr); }
598 if(!mpi_rank && !data_tabular) fprintf(fp_step,
"\n]\n");
599 if(!mpi_rank && data_tabular) fprintf(fp_step,
"\n ]\n}\n");
600 ierr = PetscFClose(mpi_comm, fp_step); CHKERRQ(ierr);
602 if(!mpi_rank && !data_tabular) fprintf(fp_timings,
"\n]\n");
603 if(!mpi_rank && data_tabular) fprintf(fp_timings,
"\n ]\n}\n");
604 ierr = PetscFClose(mpi_comm, fp_timings); CHKERRQ(ierr);
606 if(!mpi_rank) fprintf(fp_entanglement,
"\n]\n");
607 ierr = PetscFClose(mpi_comm, fp_entanglement); CHKERRQ(ierr);
609 ierr = SaveLoopsData();
610 if(!mpi_rank) fprintf(fp_data,
"\n}\n");
611 ierr = PetscFClose(mpi_comm, fp_data); CHKERRQ(ierr);
613 if(!mpi_rank) fprintf(fp_corr,
"\n ]\n}\n");
614 ierr = PetscFClose(mpi_comm, fp_corr); CHKERRQ(ierr);
616 if(do_save_prealloc){
617 if(!mpi_rank) fprintf(fp_prealloc,
"\n]\n");
618 ierr = PetscFClose(mpi_comm, fp_prealloc); CHKERRQ(ierr);
628 const std::vector< Op >& OpList,
629 const std::string& name,
630 const std::string& desc
636 if(LoopType==SweepStep)
637 SETERRQ(mpi_comm,1,
"Setup correlation functions should be called before starting the sweeps.");
641 m.
idx = measurements.size();
645 for(
const Op& op: OpList) m.
desc2 +=
OpToStr(op.OpType) +
"_{" + std::to_string(op.idx) +
"} ";
649 for(
const Op& op: OpList){
650 if(0 <= op.idx && op.idx < num_sites/2){
653 else if(num_sites/2 <= op.idx && op.idx < num_sites ){
654 m.
EnvOps.push_back({op.OpType, num_sites - 1 - op.idx});
657 SETERRQ2(mpi_comm,1,
"Operator index must be in the range [0,%D). Got %D.", num_sites, op.idx);
672 m.
desc3 +=
") ⊗ ( ";
680 measurements.push_back(m);
690 if(dry_run)
return(0);
692 if(mwarmup==0 && !restart) {
693 if(!mpi_rank) std::cout
694 <<
"WARNING: Nothing left to do since mwarmup is zero." << std::endl;
698 PetscErrorCode ierr = 0;
701 ierr = PetscTime(&t0abs); CHKERRQ(ierr);
703 if(warmed_up) SETERRQ(mpi_comm,1,
"Warmup has already been called, and it can only be called once.");
704 if(!mpi_rank) printf(
"WARMUP\n");
707 num_sys_blocks = num_sites - 1;
708 sys_blocks.resize(num_sys_blocks);
714 ierr = PetscTestDirectory(scratch_dir.c_str(),
'r', &flg); CHKERRQ(ierr);
715 if(!flg) SETERRQ1(mpi_comm,1,
"Directory %s does not exist. " 716 "Please verify that -scratch_dir is specified correctly.",scratch_dir.c_str());
722 ierr =
Makedir(scratch_dir +
"EnlSys/"); CHKERRQ(ierr);
723 ierr =
Makedir(scratch_dir +
"EnlEnv/"); CHKERRQ(ierr);
726 ierr =
Makedir(scratch_dir + SweepDir(LoopIdx)); CHKERRQ(ierr);
727 for(PetscInt iblock = 0; iblock < num_sys_blocks; ++iblock)
729 std::string path = scratch_dir + SweepDir(LoopIdx) + BlockDir(
"Sys",iblock);
730 ierr =
Makedir(path); CHKERRQ(ierr);
739 if(!mpi_rank) std::cout <<
"Loading blocks from file..." << std::endl;
740 for(PetscInt iblock = 0; iblock < sys_ninit; ++iblock){
741 std::string path_read = restart_dir + BlockDir(
"Sys",iblock);
742 std::string path_write = scratch_dir + SweepDir(LoopIdx) + BlockDir(
"Sys",iblock);
744 std::cout <<
" Reading Block " << iblock <<
" from: " 745 << path_read << std::endl;
746 ierr = sys_blocks[iblock].InitializeFromDisk(mpi_comm, path_read); CHKERRQ(ierr);
747 ierr = sys_blocks[iblock].SetDiskStorage(path_read, path_write); CHKERRQ(ierr);
749 for(PetscInt iblock = sys_ninit; iblock < num_sys_blocks; ++iblock){
750 std::string path = scratch_dir + SweepDir(LoopIdx) + BlockDir(
"Sys",iblock);
751 ierr = sys_blocks[iblock].Initialize(mpi_comm); CHKERRQ(ierr);
752 ierr = sys_blocks[iblock].SetDiskStorage(path, path); CHKERRQ(ierr);
755 warmed_up = PETSC_TRUE;
762 for(PetscInt iblock = 0; iblock < num_sys_blocks; ++iblock){
763 std::string path = scratch_dir + SweepDir(LoopIdx) + BlockDir(
"Sys",iblock);
764 ierr = sys_blocks[iblock].Initialize(mpi_comm); CHKERRQ(ierr);
765 ierr = sys_blocks[iblock].SetDiskStorage(path, path); CHKERRQ(ierr);
770 ierr = sys_blocks[sys_ninit++].Initialize(mpi_comm, 1, PETSC_DEFAULT); CHKERRQ(ierr);
774 if(num_sites % 2) SETERRQ1(mpi_comm,1,
"Total number of sites must be even. Got %d.", num_sites);
775 if(AddSite.NumSites() != 1) SETERRQ1(mpi_comm,1,
"Routine assumes an additional site of 1. Got %d.", AddSite.NumSites());
778 PetscInt nsites_cluster = Ham.NumEnvSites();
779 if (nsites_cluster % 2) nsites_cluster *= 2;
784 printf(
" Preparing initial blocks.\n");
786 while(sys_ninit < nsites_cluster){
787 PetscInt NumSitesTotal = sys_blocks[sys_ninit-1].NumSites() + AddSite.NumSites();
788 ierr =
KronEye_Explicit(sys_blocks[sys_ninit-1], AddSite, Ham.H(NumSitesTotal), sys_blocks[sys_ninit]); CHKERRQ(ierr);
793 if(!mpi_rank && verbose) printf(
" sys_ninit: %lld\n", LLD(sys_ninit));
794 for(PetscInt isys = 0; isys < sys_ninit; ++isys){
795 if(!mpi_rank && verbose) printf(
" block %lld, num_sites %lld\n", LLD(isys), LLD(sys_blocks[isys].NumSites()));
799 if(sys_ninit >= num_sites/2)
801 SETERRQ(mpi_comm,1,
"No DMRG Steps were performed since all site operators were created exactly. " 802 " Please change the system dimensions.");
807 LoopType = WarmupStep;
809 while(sys_ninit < num_sites/2)
811 PetscInt full_cluster = (((sys_ninit+2) / nsites_cluster)+1) * nsites_cluster;
812 PetscInt env_numsites = full_cluster - sys_ninit - 2;
815 PetscInt env_add = ((sys_ninit - env_numsites) / nsites_cluster) * nsites_cluster;
816 env_numsites += env_add;
817 full_cluster += env_add;
819 if(env_numsites < 1 || env_numsites > sys_ninit)
820 SETERRQ1(mpi_comm,1,
"Incorrect number of sites. Got %lld.", LLD(env_numsites));
824 printf(
" %s %lld/%lld/%lld\n",
"WARMUP", LLD(LoopIdx), LLD(StepIdx), LLD(GlobIdx));
828 std::set< PetscInt > SysIdx = {sys_ninit-1, env_numsites-1};
829 ierr = SysBlocksActive(SysIdx); CHKERRQ(ierr);
831 ierr = SingleDMRGStep(
832 sys_blocks[sys_ninit-1], sys_blocks[env_numsites-1], mwarmup,
833 sys_blocks[sys_ninit], sys_blocks[env_numsites], PetscBool(sys_ninit+1==num_sites/2)); CHKERRQ(ierr);
837 #if defined(PETSC_USE_DEBUG) 838 if(!mpi_rank && verbose) printf(
" Number of system blocks: %lld\n", LLD(sys_ninit));
843 if(sys_ninit != num_sites/2)
844 SETERRQ2(mpi_comm,1,
"Expected sys_ninit = num_sites/2 = %lld. Got %lld.",LLD(num_sites/2), LLD(sys_ninit));
846 for(PetscInt ienv = 0; ienv < env_ninit; ++ienv){
847 ierr = env_blocks[0].Destroy(); CHKERRQ(ierr);
850 warmed_up = PETSC_TRUE;
853 PetscPrintf(mpi_comm,
854 " Initialized system blocks: %lld\n" 855 " Target number of sites: %lld\n\n", LLD(sys_ninit), LLD(num_sites));
857 ierr = SaveSweepsData(); CHKERRQ(ierr);
866 if(dry_run || (mwarmup==0 && !restart))
return(0);
872 PetscInt start_idx = 0;
874 if(restart && restart_options)
878 const auto it = restart_sweep_dict.find(
"msweep_idx");
879 if(it!=restart_sweep_dict.end())
880 start_idx = it->second;
882 SETERRQ(PETSC_COMM_SELF,1,
"msweep_idx not found.");
885 if(sweep_mode==SWEEP_MODE_NSWEEPS || sweep_mode==SWEEP_MODE_MSWEEPS) {
889 else if(sweep_mode==SWEEP_MODE_TOLERANCE_TEST) {
892 const auto it = restart_sweep_dict.find(
"cont");
894 if(it!=restart_sweep_dict.end())
895 cont_prev = PetscBool(it->second);
896 else if(start_idx==-1)
899 cont_prev = PETSC_FALSE;
901 SETERRQ(PETSC_COMM_SELF,1,
"cont not found.");
902 if(!cont_prev) start_idx++;
905 std::cout <<
"WARNING: Sweeps will start at idx = " 906 << start_idx << std::endl;
907 if(((sweep_mode==SWEEP_MODE_NSWEEPS &&
908 start_idx>=nsweeps) ||
909 (sweep_mode==SWEEP_MODE_MSWEEPS &&
910 start_idx>=PetscInt(msweeps.size())) ||
911 (sweep_mode==SWEEP_MODE_TOLERANCE_TEST &&
912 start_idx>=PetscInt(msweeps.size())) ))
913 std::cout <<
"WARNING: Nothing left to do with restart." << std::endl;
917 if(sweep_mode==SWEEP_MODE_NSWEEPS)
919 for(msweep_idx=start_idx; msweep_idx < nsweeps; ++msweep_idx)
921 ierr = SingleSweep(mwarmup); CHKERRQ(ierr);
924 else if(sweep_mode==SWEEP_MODE_MSWEEPS)
926 for(msweep_idx=start_idx; msweep_idx < PetscInt(msweeps.size()); ++msweep_idx)
928 ierr = SingleSweep(msweeps.at(msweep_idx)); CHKERRQ(ierr);
931 else if(sweep_mode==SWEEP_MODE_TOLERANCE_TEST)
933 for(msweep_idx=start_idx; msweep_idx < PetscInt(msweeps.size()); ++msweep_idx)
935 PetscInt mstates = msweeps.at(msweep_idx);
936 PetscInt max_iter = maxnsweeps.at(msweep_idx);
938 if(max_iter==0)
continue;
940 PetscScalar prev_gse;
948 ierr = SingleSweep(mstates); CHKERRQ(ierr);
949 diff_gse = PetscAbsScalar(gse-prev_gse);
950 max_trn = *std::max_element(trunc_err.begin(), trunc_err.end());
951 max_trn = std::max(max_trn,0.0);
953 cont = (iter<max_iter) && (diff_gse > max_trn);
958 <<
"SWEEP_MODE_TOLERANCE_TEST\n" 959 <<
" Iterations / Max Iterations: " 960 << iter <<
"/" << max_iter <<
"\n" 961 <<
" Difference in ground state energy: " 963 <<
" Largest truncation error: " 965 <<
" " << (cont?
"CONTINUE":
"BREAK")
974 std::string sweep_data_fn = scratch_dir + SweepDir(LoopIdx-1) +
"Sweep.dat";
975 std::ofstream sweep_data_file(sweep_data_fn, std::ios_base::app);
976 sweep_data_file << std::setw(20) <<
"cont" <<
" " << int(cont) <<
"\n";
977 sweep_data_file.close();
983 else if(sweep_mode==SWEEP_MODE_NULL)
989 SETERRQ(mpi_comm,1,
"Invalid sweep mode.");
997 const PetscInt& MStates,
998 const PetscInt& MinBlock = PETSC_DEFAULT
1003 PetscErrorCode ierr;
1004 if(!warmed_up) SETERRQ(mpi_comm,1,
"Warmup must be called first before performing sweeps.");
1005 if(!mpi_rank) printf(
"SWEEP MStates=%lld\n", LLD(MStates));
1012 PetscInt min_block = MinBlock==PETSC_DEFAULT ? 1 : MinBlock;
1013 if(min_block < 1) SETERRQ1(mpi_comm,1,
"MinBlock must at least be 1. Got %d.", min_block);
1022 ierr =
Makedir(scratch_dir + SweepDir(LoopIdx)); CHKERRQ(ierr);
1023 for(PetscInt iblock = 0; iblock < num_sys_blocks; ++iblock)
1025 std::string path = scratch_dir + SweepDir(LoopIdx) + BlockDir(
"Sys",iblock);
1026 ierr =
Makedir(path); CHKERRQ(ierr);
1029 for(PetscInt iblock = 0; iblock < num_sys_blocks; ++iblock)
1031 std::string read_path = scratch_dir + SweepDir(LoopIdx-1) + BlockDir(
"Sys",iblock);
1032 std::string write_path = scratch_dir + SweepDir(LoopIdx) + BlockDir(
"Sys",iblock);
1033 ierr = sys_blocks[iblock].SetDiskStorage(read_path, write_path); CHKERRQ(ierr);
1038 LoopType = SweepStep;
1040 for(PetscInt iblock = num_sites/2; iblock < num_sites - min_block - 2; ++iblock)
1042 const PetscInt insys = iblock-1, inenv = num_sites - iblock - 3;
1043 const PetscInt outsys = iblock, outenv = num_sites - iblock - 2;
1046 printf(
" %s %lld/%lld/%lld\n",
"SWEEP", LLD(LoopIdx), LLD(StepIdx), LLD(GlobIdx));
1050 std::set< PetscInt > SysIdx = {insys, inenv};
1051 ierr = SysBlocksActive(SysIdx); CHKERRQ(ierr);
1053 ierr = SingleDMRGStep(sys_blocks[insys], sys_blocks[inenv], MStates,
1054 sys_blocks[outsys], sys_blocks[outenv]); CHKERRQ(ierr);
1059 for(PetscInt iblock = min_block; iblock < num_sites/2; ++iblock)
1061 const PetscInt insys = num_sites - iblock - 3, inenv = iblock-1;
1062 const PetscInt outsys = num_sites - iblock - 2, outenv = iblock;
1065 printf(
" %s %lld/%lld/%lld\n",
"SWEEP", LLD(LoopIdx), LLD(StepIdx), LLD(GlobIdx));
1069 std::set< PetscInt > SysIdx = {insys, inenv};
1070 ierr = SysBlocksActive(SysIdx); CHKERRQ(ierr);
1072 ierr = SingleDMRGStep(sys_blocks[insys], sys_blocks[inenv], MStates,
1073 sys_blocks[outsys], sys_blocks[outenv], PetscBool(outsys==outenv)); CHKERRQ(ierr);
1075 sweeps_mstates.push_back(MStates);
1080 for(PetscInt iblock = 0; iblock < num_sys_blocks; ++iblock)
1082 ierr = sys_blocks[iblock].EnsureSaved(); CHKERRQ(ierr);
1084 ierr = SaveSweepsData(); CHKERRQ(ierr);
1092 if(BlockIdx >= sys_ninit)
throw std::runtime_error(
"Attempted to access uninitialized system block.");
1093 return sys_blocks[BlockIdx];
1098 if(BlockIdx >= env_ninit)
throw std::runtime_error(
"Attempted to access uninitialized environment block.");
1099 return env_blocks[BlockIdx];
1122 SWEEP_MODE_TOLERANCE_TEST
1127 const std::map< SweepMode_t, std::string > SweepModeToString = {
1128 {SWEEP_MODE_NULL,
"SWEEP_MODE_NULL"},
1129 {SWEEP_MODE_NSWEEPS,
"SWEEP_MODE_NSWEEPS"},
1130 {SWEEP_MODE_MSWEEPS,
"SWEEP_MODE_MSWEEPS"},
1131 {SWEEP_MODE_TOLERANCE_TEST,
"SWEEP_MODE_TOLERANCE_TEST"}
1135 MPI_Comm mpi_comm = PETSC_COMM_SELF;
1144 PetscBool init = PETSC_FALSE;
1147 PetscBool verbose = PETSC_FALSE;
1150 PetscBool restart = PETSC_FALSE;
1157 PetscBool restart_options = PETSC_FALSE;
1167 PetscBool dry_run = PETSC_FALSE;
1170 PetscBool warmed_up = PETSC_FALSE;
1173 PetscBool no_symm = PETSC_FALSE;
1176 PetscReal qn_sector = 0.0;
1179 SweepMode_t sweep_mode = SWEEP_MODE_NULL;
1182 PetscInt mwarmup = 0;
1185 PetscInt nsweeps = 0;
1200 PetscInt msweep_idx = -1;
1211 PetscInt num_env_blocks = 1;
1218 PetscInt sys_ninit = 0;
1226 PetscInt env_ninit = 0;
1239 std::string scratch_dir =
".";
1243 PetscBool do_scratch_dir = PETSC_TRUE;
1246 PetscBool data_tabular = PETSC_TRUE;
1249 PetscBool do_save_prealloc = PETSC_FALSE;
1252 PetscBool do_shell = PETSC_TRUE;
1255 FILE *fp_step = NULL;
1258 FILE *fp_timings = NULL;
1261 FILE *fp_entanglement = NULL;
1264 FILE *fp_data = NULL;
1267 FILE *fp_prealloc = NULL;
1270 FILE *fp_corr = NULL;
1273 PetscInt GlobIdx = 0;
1279 PetscInt LoopIdx = 0;
1282 PetscInt StepIdx = 0;
1288 PetscBool corr_headers_printed = PETSC_FALSE;
1291 PetscBool corr_printed_first = PETSC_FALSE;
1294 PetscScalar gse = 0.0;
1300 PetscLogDouble t0abs = 0.0;
1307 const PetscInt& MStates,
1310 PetscBool do_measurements=PETSC_FALSE
1313 PetscErrorCode ierr;
1314 PetscLogDouble t0, tenlr, tkron, tdiag, trdms, trotb;
1327 const PetscBool flg = PetscBool(&SysBlock==&EnvBlock);
1330 Block SysBlockEnl, EnvBlockEnl;
1331 PetscInt NumSitesSysEnl = SysBlock.NumSites() + AddSite.NumSites();
1332 const std::vector< Hamiltonians::Term > TermsSys = Ham.H(NumSitesSysEnl);
1333 ierr =
KronEye_Explicit(SysBlock, AddSite, TermsSys, SysBlockEnl); CHKERRQ(ierr);
1334 ierr = SysBlock.EnsureSaved(); CHKERRQ(ierr);
1336 PetscInt NumSitesEnvEnl = EnvBlock.NumSites() + AddSite.NumSites();
1337 const std::vector< Hamiltonians::Term > TermsEnv = Ham.H(NumSitesEnvEnl);
1338 ierr =
KronEye_Explicit(EnvBlock, AddSite, TermsEnv, EnvBlockEnl); CHKERRQ(ierr);
1339 ierr = EnvBlock.EnsureSaved(); CHKERRQ(ierr);
1340 ierr = EnvBlockEnl.InitializeSave(scratch_dir +
"EnlEnv/"); CHKERRQ(ierr);
1342 EnvBlockEnl = SysBlockEnl;
1344 ierr = SysBlockEnl.InitializeSave(scratch_dir +
"EnlSys/"); CHKERRQ(ierr);
1346 ierr = PetscTime(&tenlr); CHKERRQ(ierr);
1347 timings_data.
tEnlr = tenlr-t0;
1348 if(!mpi_rank && verbose) printf(
"* Add One Site: %12.6f s\n", timings_data.
tEnlr);
1355 #if defined(PETSC_USE_DEBUG) 1357 PetscBool flg = PETSC_FALSE;
1358 ierr = PetscOptionsGetBool(NULL,NULL,
"-print_qn",&flg,NULL); CHKERRQ(ierr);
1361 ierr = PetscPrintf(mpi_comm,
" SysBlockEnl "); CHKERRQ(ierr);
1362 ierr = SysBlockEnl.Magnetization.PrintQNs(); CHKERRQ(ierr);
1363 ierr = PetscPrintf(mpi_comm,
" EnvBlockEnl "); CHKERRQ(ierr);
1364 ierr = EnvBlockEnl.Magnetization.PrintQNs(); CHKERRQ(ierr);
1370 PetscInt NumSitesTotal = SysBlockEnl.NumSites() + EnvBlockEnl.NumSites();
1371 const std::vector< Hamiltonians::Term > Terms = Ham.H(NumSitesTotal);
1373 std::vector<PetscReal> QNSectors = {qn_sector};
1377 KronBlocks_t KronBlocks(SysBlockEnl, EnvBlockEnl, QNSectors, fp_prealloc, GlobIdx);
1379 #if defined(PETSC_USE_DEBUG) 1381 PetscBool flg = PETSC_FALSE;
1382 ierr = PetscOptionsGetBool(NULL,NULL,
"-print_H_kron",&flg,NULL); CHKERRQ(ierr);
1383 if(flg && !mpi_rank){
1384 std::cout <<
"***** Kron_Explicit *****" << std::endl;
1385 std::cout <<
"SysBlockEnl qn_list: ";
1386 for(
auto i: SysBlockEnl.Magnetization.List()) std::cout << i <<
" ";
1387 std::cout << std::endl;
1389 std::cout <<
"SysBlockEnl qn_size: ";
1390 for(
auto i: SysBlockEnl.Magnetization.Sizes()) std::cout << i <<
" ";
1391 std::cout << std::endl;
1393 std::cout <<
"SysBlockEnl qn_offset: ";
1394 for(
auto i: SysBlockEnl.Magnetization.Offsets()) std::cout << i <<
" ";
1395 std::cout << std::endl;
1397 std::cout << std::endl;
1399 std::cout <<
"EnvBlockEnl qn_list: ";
1400 for(
auto i: EnvBlockEnl.Magnetization.List()) std::cout << i <<
" ";
1401 std::cout << std::endl;
1403 std::cout <<
"EnvBlockEnl qn_size: ";
1404 for(
auto i: EnvBlockEnl.Magnetization.Sizes()) std::cout << i <<
" ";
1405 std::cout << std::endl;
1407 std::cout <<
"EnvBlockEnl qn_offset: ";
1408 for(
auto i: EnvBlockEnl.Magnetization.Offsets()) std::cout << i <<
" ";
1409 std::cout << std::endl;
1412 std::cout <<
"KronBlocks: \n";
1416 << std::get<0>(kb) <<
", " 1417 << std::get<1>(kb) <<
", " 1418 << std::get<2>(kb) <<
", " 1419 << std::get<3>(kb) <<
", " 1420 << KronBlocks.
Offsets()[i++] <<
" )\n";
1422 std::cout <<
"*************************" << std::endl;
1425 if(!mpi_rank){std::cout <<
"***** SysBlockEnl *****" << std::endl;}
1426 for(
const Mat& mat: SysBlockEnl.Sz())
1430 for(
const Mat& mat: SysBlockEnl.Sp())
1434 if(!mpi_rank){std::cout <<
"***** EnvBlockEnl *****" << std::endl;}
1435 for(
const Mat& mat: EnvBlockEnl.Sz())
1439 for(
const Mat& mat: EnvBlockEnl.Sp())
1443 if(!mpi_rank){std::cout <<
"***********************" << std::endl;}
1448 ierr = KronBlocks.KronSumSetRedistribute(PETSC_TRUE); CHKERRQ(ierr);
1449 ierr = KronBlocks.KronSumSetToleranceFromOptions(); CHKERRQ(ierr);
1452 if(!H) SETERRQ(mpi_comm,1,
"H is null.");
1454 ierr = PetscTime(&tkron); CHKERRQ(ierr);
1455 timings_data.
tKron = tkron-tenlr;
1456 if(!mpi_rank && verbose) printf(
"* Build Superblock H: %12.6f s\n", timings_data.
tKron);
1458 #if defined(PETSC_USE_DEBUG) 1460 PetscBool flg = PETSC_FALSE;
1461 ierr = PetscOptionsGetBool(NULL,NULL,
"-print_H",&flg,NULL); CHKERRQ(ierr);
1462 if(flg){ ierr = MatPeek(H,
"H"); CHKERRQ(ierr); }
1464 ierr = PetscOptionsGetBool(NULL,NULL,
"-print_H_terms",&flg,NULL); CHKERRQ(ierr);
1466 if(!mpi_rank) printf(
" H(%lld)\n", LLD(NumSitesTotal));
1469 if(!mpi_rank) printf(
"%.2f %2s(%2lld) %2s(%2lld)\n", term.a, (OpString.find(term.Iop)->second).c_str(), LLD(term.Isite),
1470 (OpString.find(term.Jop)->second).c_str(), LLD(term.Jsite) );
1473 ierr = MPI_Barrier(mpi_comm); CHKERRQ(ierr);
1479 #if defined(PETSC_USE_COMPLEX) 1480 SETERRQ(mpi_comm,PETSC_ERR_SUP,
"This function is only implemented for scalar-type=real.");
1485 PetscScalar gse_r, gse_i;
1486 ierr = MatCreateVecs(H, &gsv_r,
nullptr); CHKERRQ(ierr);
1487 ierr = MatCreateVecs(H, &gsv_i,
nullptr); CHKERRQ(ierr);
1490 ierr = EPSCreate(mpi_comm, &eps); CHKERRQ(ierr);
1491 ierr = EPSSetOperators(eps, H,
nullptr); CHKERRQ(ierr);
1492 ierr = EPSSetProblemType(eps, EPS_HEP); CHKERRQ(ierr);
1493 ierr = EPSSetWhichEigenpairs(eps, EPS_SMALLEST_REAL); CHKERRQ(ierr);
1494 ierr = EPSSetOptionsPrefix(eps,
"H_"); CHKERRQ(ierr);
1495 ierr = EPSSetFromOptions(eps); CHKERRQ(ierr);
1496 ierr = EPSSolve(eps); CHKERRQ(ierr);
1497 ierr = EPSGetEigenpair(eps, 0, &gse_r, &gse_i, gsv_r, gsv_i); CHKERRQ(ierr);
1498 ierr = EPSDestroy(&eps); CHKERRQ(ierr);
1503 ierr = MatDestroy_KronSumShell(&H); CHKERRQ(ierr);
1505 ierr = MatDestroy(&H); CHKERRQ(ierr);
1507 ierr = PetscTime(&tdiag); CHKERRQ(ierr);
1508 timings_data.
tDiag = tdiag-tkron;
1509 if(!mpi_rank && verbose) printf(
"* Solve Ground State: %12.6f s\n", timings_data.
tDiag);
1511 #if defined(PETSC_USE_DEBUG) 1513 PetscBool flg = PETSC_FALSE;
1514 ierr = PetscOptionsGetBool(NULL,NULL,
"-print_H_gs",&flg,NULL); CHKERRQ(ierr);
1516 ierr = PetscPrintf(mpi_comm,
"\n Ground State Energy: %g + %gj\n", gse_r, gse_i); CHKERRQ(ierr);
1517 ierr = VecPeek(gsv_r,
" gsv_r"); CHKERRQ(ierr);
1523 ierr = MPI_Barrier(mpi_comm); CHKERRQ(ierr);
1524 SETERRQ(mpi_comm,PETSC_ERR_SUP,
"Unsupported option: no_symm.");
1532 ierr = GetTruncation(KronBlocks, gsv_r, MStates, *BT_L, *BT_R); CHKERRQ(ierr);
1540 PetscLogDouble tcorr0,tcorr1;
1541 ierr = PetscTime(&tcorr0); CHKERRQ(ierr);
1543 ierr = CalculateCorrelations_BlockDiag(KronBlocks, gsv_r, *BT_L, do_measurements); CHKERRQ(ierr);
1545 ierr = PetscTime(&tcorr1); CHKERRQ(ierr);
1546 if(do_measurements && !mpi_rank && verbose)
1547 printf(
" * Calc. of Correlators %12.6f s\n", tcorr1-tcorr0);
1549 ierr = VecDestroy(&gsv_r); CHKERRQ(ierr);
1550 ierr = VecDestroy(&gsv_i); CHKERRQ(ierr);
1554 ierr = SysBlockOut.Destroy(); CHKERRQ(ierr);
1555 ierr = EnvBlockOut.Destroy(); CHKERRQ(ierr);
1557 ierr = PetscTime(&trdms); CHKERRQ(ierr);
1558 timings_data.
tRdms = trdms-tdiag;
1559 if(!mpi_rank && verbose) printf(
"* Eigendec. of RDMs: %12.6f s\n", timings_data.
tRdms);
1561 ierr = SysBlockOut.Initialize(SysBlockEnl.NumSites(), BT_L->
QN); CHKERRQ(ierr);
1562 ierr = SysBlockOut.RotateOperators(SysBlockEnl, BT_L->
RotMatT); CHKERRQ(ierr);
1563 ierr = SysBlockEnl.Destroy(); CHKERRQ(ierr);
1565 ierr = EnvBlockOut.Initialize(EnvBlockEnl.NumSites(), BT_R->
QN); CHKERRQ(ierr);
1566 ierr = EnvBlockOut.RotateOperators(EnvBlockEnl, BT_R->
RotMatT); CHKERRQ(ierr);
1567 ierr = EnvBlockEnl.Destroy(); CHKERRQ(ierr);
1575 #if defined(PETSC_USE_DEBUG) 1577 PetscBool flg = PETSC_FALSE;
1578 ierr = PetscOptionsGetBool(NULL,NULL,
"-print_qn",&flg,NULL); CHKERRQ(ierr);
1581 ierr = PetscPrintf(mpi_comm,
" SysBlockOut "); CHKERRQ(ierr);
1582 ierr = SysBlockOut.Magnetization.PrintQNs(); CHKERRQ(ierr);
1583 ierr = PetscPrintf(mpi_comm,
" EnvBlockOut "); CHKERRQ(ierr);
1584 ierr = EnvBlockOut.Magnetization.PrintQNs(); CHKERRQ(ierr);
1589 ierr = PetscTime(&trotb); CHKERRQ(ierr);
1590 timings_data.
tRotb = trotb-trdms;
1591 if(!mpi_rank && verbose) printf(
"* Rotation of Operators: %12.6f s\n", timings_data.
tRotb);
1593 timings_data.
Total = trotb - t0;
1594 ierr = PetscTime(&t0abs); CHKERRQ(ierr);
1596 if(!mpi_rank && verbose){
1597 const PetscReal pEnlr = 100*(timings_data.
tEnlr)/timings_data.
Total;
1598 const PetscReal pKron = 100*(timings_data.
tKron)/timings_data.
Total;
1599 const PetscReal pDiag = 100*(timings_data.
tDiag)/timings_data.
Total;
1600 const PetscReal pRdms = 100*(timings_data.
tRdms)/timings_data.
Total;
1601 const PetscReal pRotb = 100*(timings_data.
tRotb)/timings_data.
Total;
1603 printf(
" Sys Block In:\n");
1604 printf(
" NumStates: %lld\n", LLD(SysBlock.Magnetization.NumStates()));
1605 printf(
" NumSites: %lld\n", LLD(SysBlock.NumSites()));
1606 printf(
" Env Block In:\n");
1607 printf(
" NumStates: %lld\n", LLD(EnvBlock.Magnetization.NumStates()));
1608 printf(
" NumSites: %lld\n", LLD(EnvBlock.NumSites()));
1609 printf(
" Sys Block Enl:\n");
1610 printf(
" NumStates: %lld\n", LLD(SysBlockEnl.Magnetization.NumStates()));
1611 printf(
" NumSites: %lld\n", LLD(SysBlockEnl.NumSites()));
1612 printf(
" Env Block Enl:\n");
1613 printf(
" NumStates: %lld\n", LLD(EnvBlockEnl.Magnetization.NumStates()));
1614 printf(
" NumSites: %lld\n", LLD(EnvBlockEnl.NumSites()));
1615 printf(
" Superblock:\n");
1616 printf(
" NumStates: %lld\n", LLD(KronBlocks.
NumStates()));
1617 printf(
" NumSites: %lld\n", LLD(NumSitesTotal));
1618 printf(
" QNSector: %-10.10g\n", qn_sector);
1619 printf(
" Energy: %-10.10g\n", gse_r);
1620 printf(
" Energy/site: %-10.10g\n", gse_r/PetscReal(NumSitesTotal));
1621 printf(
" Sys Block Out\n" 1622 " NumStates: %lld\n" 1624 printf(
" Env Block Out\n" 1625 " NumStates: %lld\n" 1628 printf(
" Total Time: %12.6f s\n", timings_data.
Total);
1629 printf(
" Add One Site: %12.6f s \t%6.2f %%\n", timings_data.
tEnlr, pEnlr);
1630 printf(
" Build Superblock H: %12.6f s \t%6.2f %%\n", timings_data.
tKron, pKron);
1631 printf(
" Solve Ground State: %12.6f s \t%6.2f %%\n", timings_data.
tDiag, pDiag);
1632 printf(
" Eigendec. of RDMs: %12.6f s \t%6.2f %%\n", timings_data.
tRdms, pRdms);
1633 printf(
" Rotation of Operators: %12.6f s \t%6.2f %%\n", timings_data.
tRotb, pRotb);
1639 trunc_err.push_back(BT_L->
TruncErr);
1642 ierr = SaveStepData(step_data); CHKERRQ(ierr);
1643 ierr = SaveTimingsData(timings_data); CHKERRQ(ierr);
1659 const PetscInt& MStates,
1664 PetscErrorCode ierr;
1666 if(no_symm) SETERRQ(mpi_comm,PETSC_ERR_SUP,
"Unsupported option: no_symm.");
1667 #if defined(PETSC_USE_COMPLEX) 1668 SETERRQ(mpi_comm,PETSC_ERR_SUP,
"This function is only implemented for scalar-type=real.");
1675 ierr = VecScatterCreateToZero(gsv_r, &ctx, &gsv_r_loc); CHKERRQ(ierr);
1676 ierr = VecScatterBegin(ctx, gsv_r, gsv_r_loc, INSERT_VALUES, SCATTER_FORWARD); CHKERRQ(ierr);
1677 ierr = VecScatterEnd(ctx, gsv_r, gsv_r_loc, INSERT_VALUES, SCATTER_FORWARD); CHKERRQ(ierr);
1679 #if defined(PETSC_USE_DEBUG) 1680 PetscBool flg = PETSC_FALSE;
1681 ierr = PetscOptionsGetBool(NULL,NULL,
"-print_trunc",&flg,NULL); CHKERRQ(ierr);
1683 for(PetscMPIInt irank = 0; irank < mpi_size; ++irank){
1684 if(irank==mpi_rank){std::cout <<
"[" << mpi_rank <<
"]<<" << std::endl;
1686 ierr = PetscPrintf(PETSC_COMM_SELF,
"gsv_r_loc\n"); CHKERRQ(ierr);
1687 ierr = VecView(gsv_r_loc, PETSC_VIEWER_STDOUT_SELF); CHKERRQ(ierr);
1689 std::cout <<
">>[" << mpi_rank <<
"]" << std::endl;}\
1690 ierr = MPI_Barrier(mpi_comm); CHKERRQ(ierr);}
1694 std::vector< Eigen_t > eigen_L, eigen_R;
1695 std::vector< EPS > eps_list_L, eps_list_R;
1696 std::vector< Vec > rdmd_vecs_L, rdmd_vecs_R;
1703 ierr = VecGetSize(gsv_r_loc, &size);
1704 if(KronBlocks.
NumStates() != size) SETERRQ2(PETSC_COMM_SELF,1,
"Incorrect vector length. " 1705 "Expected %d. Got %d.", KronBlocks.
NumStates(), size);
1707 #if defined(PETSC_USE_DEBUG) 1708 if(flg) printf(
"\n\n");
1712 ierr = VecGetArray(gsv_r_loc, &v); CHKERRQ(ierr);
1715 for(PetscInt idx = 0; idx < KronBlocks.
size(); ++idx)
1717 const PetscInt Istart = KronBlocks.
Offsets(idx);
1718 const PetscInt Iend = KronBlocks.
Offsets(idx+1);
1719 const PetscInt Idx_L = KronBlocks.
LeftIdx(idx);
1720 const PetscInt Idx_R = KronBlocks.
RightIdx(idx);
1725 if(Iend - Istart != N_L * N_R) SETERRQ2(PETSC_COMM_SELF,1,
"Incorrect segment length. " 1726 "Expected %d. Got %d.", N_L * N_R, Iend - Istart);
1730 Mat Psi, PsiT, rdmd_L, rdmd_R;
1731 ierr = MatCreateSeqDense(PETSC_COMM_SELF, N_R, N_L, &v[Istart], &PsiT); CHKERRQ(ierr);
1732 ierr = MatHermitianTranspose(PsiT, MAT_INITIAL_MATRIX, &Psi); CHKERRQ(ierr);
1733 ierr = MatMatMult(Psi, PsiT, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &rdmd_L);
1734 ierr = MatMatMult(PsiT, Psi, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &rdmd_R);
1736 ierr = MatDestroy(&Psi); CHKERRQ(ierr);
1737 ierr = MatDestroy(&PsiT); CHKERRQ(ierr);
1741 PetscInt Nrows, Ncols;
1742 ierr = MatGetSize(rdmd_L, &Nrows, &Ncols); CHKERRQ(ierr);
1743 if(Nrows != N_L) SETERRQ2(PETSC_COMM_SELF,1,
"Incorrect Nrows in L. Expected %d. Got %d.", N_L, Nrows);
1744 if(Ncols != N_L) SETERRQ2(PETSC_COMM_SELF,1,
"Incorrect Ncols in L. Expected %d. Got %d.", N_L, Ncols);
1745 ierr = MatGetSize(rdmd_R, &Nrows, &Ncols); CHKERRQ(ierr);
1746 if(Nrows != N_R) SETERRQ2(PETSC_COMM_SELF,1,
"Incorrect Nrows in R. Expected %d. Got %d.", N_R, Nrows);
1747 if(Ncols != N_R) SETERRQ2(PETSC_COMM_SELF,1,
"Incorrect Ncols in R. Expected %d. Got %d.", N_R, Ncols);
1752 ierr = EigRDM_BlockDiag(rdmd_L, idx, Idx_L, eigen_L, eps_L); CHKERRQ(ierr);
1753 ierr = EigRDM_BlockDiag(rdmd_R, idx, Idx_R, eigen_R, eps_R); CHKERRQ(ierr);
1755 #if defined(PETSC_USE_DEBUG) 1757 printf(
" KB QN: %-6g Left :%3lld Right: %3lld\n", KronBlocks.
QN(idx), LLD(Idx_L), LLD(Idx_R)) ;
1758 ierr = MatPeek(rdmd_L,
"rdmd_L"); CHKERRQ(ierr);
1759 ierr = MatPeek(rdmd_R,
"rdmd_R"); CHKERRQ(ierr);
1764 eps_list_L.push_back(eps_L);
1765 eps_list_R.push_back(eps_R);
1771 ierr = MatCreateVecs(rdmd_L, NULL, &v_L); CHKERRQ(ierr);
1772 rdmd_vecs_L.push_back(v_L);
1773 ierr = MatCreateVecs(rdmd_R, NULL, &v_R); CHKERRQ(ierr);
1774 rdmd_vecs_R.push_back(v_R);
1777 #if defined(PETSC_USE_DEBUG) 1779 printf(
"\nBefore sorting\n");
1780 for(
const Eigen_t& eig: eigen_L) printf(
" L: %-16.10g seq: %-5lld eps: %-5lld blk: %-5lld\n",
1781 eig.eigval, LLD(eig.seqIdx), LLD(eig.epsIdx), LLD(eig.blkIdx));
1783 for(
const Eigen_t& eig: eigen_R) printf(
" R: %-16.10g seq: %-5lld eps: %-5lld blk: %-5lld\n",
1784 eig.eigval, LLD(eig.seqIdx), LLD(eig.epsIdx), LLD(eig.blkIdx));
1790 ierr = SaveEntanglementSpectra(
1795 std::stable_sort(eigen_L.begin(), eigen_L.end(),
greater_eigval);
1796 std::stable_sort(eigen_R.begin(), eigen_R.end(),
greater_eigval);
1798 #if defined(PETSC_USE_DEBUG) 1800 printf(
"\nAfter sorting\n");
1801 for(
const Eigen_t& eig: eigen_L) printf(
" L: %-16.10g seq: %-5lld eps: %-5lld blk: %-5lld\n",
1802 eig.eigval, LLD(eig.seqIdx), LLD(eig.epsIdx), LLD(eig.blkIdx));
1804 for(
const Eigen_t& eig: eigen_R) printf(
" R: %-16.10g seq: %-5lld eps: %-5lld blk: %-5lld\n",
1805 eig.eigval, LLD(eig.seqIdx), LLD(eig.epsIdx), LLD(eig.blkIdx));
1809 ierr = VecRestoreArray(gsv_r_loc, &v); CHKERRQ(ierr);
1813 PetscInt NEigenStates_L = eigen_L.size();
1814 PetscInt NEigenStates_R = eigen_R.size();
1815 ierr = MPI_Bcast(&NEigenStates_L, 1, MPIU_INT, 0, PETSC_COMM_WORLD); CHKERRQ(ierr);
1816 ierr = MPI_Bcast(&NEigenStates_R, 1, MPIU_INT, 0, PETSC_COMM_WORLD); CHKERRQ(ierr);
1819 const PetscInt m_L = PetscMin(MStates, NEigenStates_L);
1820 const PetscInt m_R = PetscMin(MStates, NEigenStates_R);
1827 ierr = MatCreate(mpi_comm, &BT_L.
RotMatT); CHKERRQ(ierr);
1828 ierr = MatCreate(mpi_comm, &BT_R.
RotMatT); CHKERRQ(ierr);
1829 Mat& RotMatT_L = BT_L.
RotMatT;
1830 Mat& RotMatT_R = BT_R.
RotMatT;
1831 ierr = MatSetSizes(RotMatT_L, PETSC_DECIDE, PETSC_DECIDE, m_L, NStates_L); CHKERRQ(ierr);
1832 ierr = MatSetSizes(RotMatT_R, PETSC_DECIDE, PETSC_DECIDE, m_R, NStates_R); CHKERRQ(ierr);
1833 ierr = MatSetFromOptions(RotMatT_L); CHKERRQ(ierr);
1834 ierr = MatSetFromOptions(RotMatT_R); CHKERRQ(ierr);
1835 ierr = MatSetUp(RotMatT_L); CHKERRQ(ierr);
1836 ierr = MatSetUp(RotMatT_R); CHKERRQ(ierr);
1838 #if defined(PETSC_USE_DEBUG) 1839 if(flg && !mpi_rank) printf(
" m_L: %-lld m_R: %-lld\n\n", LLD(m_L), LLD(m_R));
1842 std::vector< PetscReal > qn_list_L, qn_list_R;
1843 std::vector< PetscInt > qn_size_L, qn_size_R;
1844 PetscInt numBlocks_L, numBlocks_R;
1845 PetscReal& TruncErr_L = BT_L.
TruncErr;
1846 PetscReal& TruncErr_R = BT_R.
TruncErr;
1850 eigen_L.resize(m_L);
1851 eigen_R.resize(m_R);
1852 std::stable_sort(eigen_L.begin(), eigen_L.end(),
less_blkIdx);
1853 std::stable_sort(eigen_R.begin(), eigen_R.end(),
less_blkIdx);
1855 #if defined(PETSC_USE_DEBUG) 1858 for(
const Eigen_t& eig: eigen_L) printf(
" L: %-16.10g seq: %-5lld eps: %-5lld blk: %-5lld\n",
1859 eig.eigval, LLD(eig.seqIdx), LLD(eig.epsIdx), LLD(eig.blkIdx));
1861 for(
const Eigen_t& eig: eigen_R) printf(
" R: %-16.10g seq: %-5lld eps: %-5lld blk: %-5lld\n",
1862 eig.eigval, LLD(eig.seqIdx), LLD(eig.epsIdx), LLD(eig.blkIdx));
1868 ierr = FillRotation_BlockDiag(eigen_L, eps_list_L, rdmd_vecs_L, KronBlocks.
LeftBlockRef(), RotMatT_L); CHKERRQ(ierr);
1869 ierr = FillRotation_BlockDiag(eigen_R, eps_list_R, rdmd_vecs_R, KronBlocks.
RightBlockRef(), RotMatT_R); CHKERRQ(ierr);
1873 for(
const Eigen_t &eig: eigen_L) TruncErr_L -= (eig.eigval > 0) * eig.eigval;
1875 for(
const Eigen_t &eig: eigen_R) TruncErr_R -= (eig.eigval > 0) * eig.eigval;
1879 std::map< PetscReal, PetscInt > BlockIdxs;
1880 for(
const Eigen_t &eig: eigen_L) BlockIdxs[ eig.blkIdx ] += 1;
1882 for(
const auto& idx: BlockIdxs) qn_size_L.push_back( idx.second );
1883 numBlocks_L = qn_list_L.size();
1887 std::map< PetscReal, PetscInt > BlockIdxs;
1888 for(
const Eigen_t &eig: eigen_R) BlockIdxs[ eig.blkIdx ] += 1;
1890 for(
const auto& idx: BlockIdxs) qn_size_R.push_back( idx.second );
1891 numBlocks_R = qn_list_R.size();
1894 #if defined(PETSC_USE_DEBUG) 1896 for(PetscInt i = 0; i < numBlocks_L; ++i) printf(
" %g %lld\n", qn_list_L[i], LLD(qn_size_L[i]));
1898 for(PetscInt i = 0; i < numBlocks_R; ++i) printf(
" %g %lld\n", qn_list_R[i], LLD(qn_size_R[i]));
1904 ierr = MPI_Bcast(&TruncErr_L, 1, MPIU_SCALAR, 0, PETSC_COMM_WORLD); CHKERRQ(ierr);
1905 ierr = MPI_Bcast(&TruncErr_R, 1, MPIU_SCALAR, 0, PETSC_COMM_WORLD); CHKERRQ(ierr);
1908 ierr = MPI_Bcast(&numBlocks_L, 1, MPIU_INT, 0, PETSC_COMM_WORLD); CHKERRQ(ierr);
1909 ierr = MPI_Bcast(&numBlocks_R, 1, MPIU_INT, 0, PETSC_COMM_WORLD); CHKERRQ(ierr);
1912 if(mpi_rank) qn_list_L.resize(numBlocks_L);
1913 if(mpi_rank) qn_size_L.resize(numBlocks_L);
1914 ierr = MPI_Bcast(qn_list_L.data(), numBlocks_L, MPIU_REAL, 0, PETSC_COMM_WORLD); CHKERRQ(ierr);
1915 ierr = MPI_Bcast(qn_size_L.data(), numBlocks_L, MPIU_INT, 0, PETSC_COMM_WORLD); CHKERRQ(ierr);
1916 if(mpi_rank) qn_list_R.resize(numBlocks_R);
1917 if(mpi_rank) qn_size_R.resize(numBlocks_R);
1918 ierr = MPI_Bcast(qn_list_R.data(), numBlocks_R, MPIU_REAL, 0, PETSC_COMM_WORLD); CHKERRQ(ierr);
1919 ierr = MPI_Bcast(qn_size_R.data(), numBlocks_R, MPIU_INT, 0, PETSC_COMM_WORLD); CHKERRQ(ierr);
1922 ierr = MatAssemblyBegin(RotMatT_L, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
1923 ierr = MatAssemblyBegin(RotMatT_R, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
1924 ierr = MatAssemblyEnd(RotMatT_L, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
1925 ierr = MatAssemblyEnd(RotMatT_R, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
1927 #if defined(PETSC_USE_DEBUG) 1929 ierr = MatPeek(RotMatT_L,
"RotMatT_L"); CHKERRQ(ierr);
1930 ierr = MatPeek(RotMatT_R,
"RotMatT_R"); CHKERRQ(ierr);
1934 ierr = BT_L.QN.Initialize(mpi_comm, qn_list_L, qn_size_L); CHKERRQ(ierr);
1935 ierr = BT_R.QN.Initialize(mpi_comm, qn_list_R, qn_size_R); CHKERRQ(ierr);
1937 for(EPS& eps: eps_list_L){
1938 ierr = EPSDestroy(&eps); CHKERRQ(ierr);
1940 for(EPS& eps: eps_list_R){
1941 ierr = EPSDestroy(&eps); CHKERRQ(ierr);
1949 for(Vec& vec: rdmd_vecs_L){
1950 ierr = VecDestroy(&vec); CHKERRQ(ierr);
1952 for(Vec& vec: rdmd_vecs_R){
1953 ierr = VecDestroy(&vec); CHKERRQ(ierr);
1955 ierr = VecScatterDestroy(&ctx); CHKERRQ(ierr);
1956 ierr = VecDestroy(&gsv_r_loc); CHKERRQ(ierr);
1966 std::vector< Eigen_t >& eigList,
1970 PetscErrorCode ierr;
1972 PetscInt Nrows, Ncols;
1973 ierr = MatGetSize(matin, &Nrows, &Ncols); CHKERRQ(ierr);
1974 if(Nrows!=Ncols) SETERRQ2(PETSC_COMM_SELF,1,
"Input must be square matrix. Got size %d x %d.", Nrows, Ncols);
1976 ierr = EPSCreate(PETSC_COMM_SELF, &eps); CHKERRQ(ierr);
1977 ierr = EPSSetOperators(eps, matin,
nullptr); CHKERRQ(ierr);
1978 ierr = EPSSetProblemType(eps, EPS_HEP); CHKERRQ(ierr);
1979 ierr = EPSSetWhichEigenpairs(eps, EPS_LARGEST_REAL); CHKERRQ(ierr);
1980 ierr = EPSSetType(eps, EPSLAPACK);
1981 ierr = EPSSetTolerances(eps, 1.0e-16, PETSC_DEFAULT); CHKERRQ(ierr);
1982 ierr = EPSSolve(eps); CHKERRQ(ierr);
1986 ierr = EPSGetConverged(eps, &nconv); CHKERRQ(ierr);
1987 if(nconv != Nrows) SETERRQ2(PETSC_COMM_SELF,1,
"Incorrect number of converged eigenpairs. " 1988 "Expected %d. Got %d.", Nrows, nconv); CHKERRQ(ierr);
1993 PetscScalar eigr=0.0, eigi=0.0;
1994 ierr = EPSGetEigenvalue(eps,
epsIdx, &eigr, &eigi); CHKERRQ(ierr);
1997 if(eigi != 0.0) SETERRQ1(PETSC_COMM_SELF,1,
"Imaginary part of eigenvalue must be zero. " 2007 const std::vector< Eigen_t >& eigen_list,
2008 const std::vector< EPS >& eps_list,
2009 const std::vector< Vec >& rdmd_vecs,
2010 const Block& BlockRef,
2014 PetscErrorCode ierr;
2016 #if defined(PETSC_USE_COMPLEX) 2017 SETERRQ(mpi_comm,PETSC_ERR_SUP,
"This function is only implemented for scalar-type=real.");
2021 std::vector< PetscInt> qnsize = BlockRef.Magnetization.Sizes();
2022 std::vector< PetscInt>::iterator it = std::max_element(qnsize.begin(), qnsize.end());
2023 PetscInt max_qnsize = PetscInt(*it);
2025 ierr = PetscCalloc1(max_qnsize+1, &idx); CHKERRQ(ierr);
2027 PetscScalar eigr, eigi, *vals;
2028 PetscInt prev_blkIdx = -1;
2029 PetscInt startIdx = 0;
2030 PetscInt numStates = 0;
2031 PetscInt rowCtr = 0;
2032 for(
const Eigen_t &eig: eigen_list)
2035 const PetscInt
seqIdx = eig.seqIdx;
2036 ierr = EPSGetEigenpair(eps_list[seqIdx], eig.epsIdx, &eigr, &eigi, rdmd_vecs[seqIdx],
nullptr); CHKERRQ(ierr);
2037 ierr = VecGetArray(rdmd_vecs[seqIdx], &vals); CHKERRQ(ierr);
2039 if(eigr != eig.eigval) SETERRQ2(PETSC_COMM_SELF,1,
"Incorrect eigenvalue. Expected %g. Got %g.", eig.eigval, eigr);
2042 if(prev_blkIdx != eig.blkIdx){
2043 startIdx = BlockRef.Magnetization.Offsets(eig.blkIdx); assert(startIdx!=-1);
2044 numStates = BlockRef.Magnetization.Sizes(eig.blkIdx); assert(numStates!=-1);
2045 for(PetscInt i = 0; i < numStates+1; ++i) idx[i] = startIdx + i;
2046 prev_blkIdx = eig.blkIdx;
2050 ierr = MatSetValues(RotMatT, 1, &rowCtr, numStates, idx, vals, INSERT_VALUES); CHKERRQ(ierr);
2052 ierr = VecRestoreArray(rdmd_vecs[seqIdx], &vals); CHKERRQ(ierr);
2055 ierr = PetscFree(idx); CHKERRQ(ierr);
2066 const PetscBool flg=PETSC_TRUE
2071 if(!corr_headers_printed)
2073 fprintf(fp_corr,
"{\n");
2074 fprintf(fp_corr,
" \"info\" :\n");
2075 fprintf(fp_corr,
" [\n");
2077 for(
size_t icorr=0; icorr<measurements.size(); ++icorr){
2078 if(icorr) fprintf(fp_corr,
",\n");
2080 fprintf(fp_corr,
" {\n");
2081 fprintf(fp_corr,
" \"corrIdx\" : %lld,\n", LLD(c.
idx));
2082 fprintf(fp_corr,
" \"name\" : \"%s\",\n", c.
name.c_str());
2083 fprintf(fp_corr,
" \"desc1\" : \"%s\",\n", c.
desc1.c_str());
2084 fprintf(fp_corr,
" \"desc2\" : \"%s\",\n", c.
desc2.c_str());
2085 fprintf(fp_corr,
" \"desc3\" : \"%s\"\n", c.
desc3.c_str());
2086 fprintf(fp_corr,
" }");
2089 fprintf(fp_corr,
"\n");
2090 fprintf(fp_corr,
" ],\n");
2091 fprintf(fp_corr,
" \"values\" :\n");
2092 fprintf(fp_corr,
" [\n");
2095 corr_headers_printed = PETSC_TRUE;
2100 PetscErrorCode ierr;
2101 std::vector< PetscScalar > CorrValues(measurements.size());
2103 PetscBool debug = PETSC_FALSE;
2104 if(debug && !mpi_rank) std::cout <<
"\n\n====" << __FUNCTION__ <<
"====" << std::endl;
2108 std::vector< Correlator > CorrSysEnv = measurements;
2112 std::vector< Correlator > CorrSys;
2113 std::vector< Correlator > CorrSysEnv;
2116 if(m.SysOps.size()!=0 && m.EnvOps.size()==0){
2117 CorrSys.push_back(m);
2119 else if (m.SysOps.size()==0 && m.EnvOps.size()!=0){
2120 SETERRQ(mpi_comm,1,
"Reflection symmetry is imposed. Empty SysOps and non-empty EnvOps not permitted.");
2122 else if (m.SysOps.size()!=0 && m.EnvOps.size()!=0){
2123 CorrSysEnv.push_back(m);
2134 if(CorrSys.size() > 0)
2144 for(PetscInt i=0; i<NumSectors; ++i){
2147 ierr = MatGetSize(BT.
rdmd_list.at(i), &M, &N); CHKERRQ(ierr);
2149 SETERRQ2(PETSC_COMM_SELF,1,
"Matrix must be square. Got %D x %D instead.",M,N);
2151 SETERRQ2(mpi_comm,1,
"Incorrect size. Expected %D. Got %D.", M, Sizes.at(i));
2159 MPI_Comm& sub_comm = mpi_comm;
2161 PetscMPIInt sub_rank, sub_size;
2162 ierr = MPI_Comm_rank(sub_comm, &sub_rank); CHKERRQ(ierr);
2163 ierr = MPI_Comm_size(sub_comm, &sub_size); CHKERRQ(ierr);
2167 ierr = MatCreateDense(sub_comm,PETSC_DECIDE,PETSC_DECIDE,NumStates,NumStates,NULL,&rho); CHKERRQ(ierr);
2168 ierr = MatSetOption(rho,MAT_ROW_ORIENTED,PETSC_TRUE); CHKERRQ(ierr);
2172 PetscInt *idx, max_size = 0;
2173 for(
const PetscInt& s: Sizes) max_size = (max_size < s) ? s : max_size;
2174 ierr = PetscCalloc1(max_size,&idx); CHKERRQ(ierr);
2175 for(PetscInt iblk=0; iblk<NumSectors; ++iblk)
2180 PetscInt size = Sizes[iblk];
2181 PetscInt shift = Offsets[iblk];
2182 for(PetscInt is=0; is<size; ++is)
2184 idx[is] = is + shift;
2186 ierr = MatDenseGetArray(BT.
rdmd_list.at(iblk), &v); CHKERRQ(ierr);
2187 for(PetscInt is=0; is<size; ++is)
2189 PetscInt row = is + shift;
2190 ierr = MatSetValues(rho,1,&row,size,idx,v+is*size,INSERT_VALUES); CHKERRQ(ierr);
2192 ierr = MatDenseRestoreArray(BT.
rdmd_list.at(iblk), &v); CHKERRQ(ierr);
2194 ierr = PetscFree(idx); CHKERRQ(ierr);
2196 ierr = MatAssemblyBegin(rho, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
2197 ierr = MatAssemblyEnd(rho, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
2199 std::map< std::string, Mat > OpMats;
2200 std::vector< Mat > AllOpProds;
2201 std::vector< Mat > OpProds;
2203 ierr = CalculateOperatorProducts(sub_comm,CorrSys,BlockSys,
2204 KronBlocks.
LeftBlockRefMod(),OpMats,AllOpProds,OpProds); CHKERRQ(ierr);
2207 PetscScalar *tr_rho;
2208 ierr = PetscCalloc1(CorrSys.size(),&tr_rho); CHKERRQ(ierr);
2211 PetscInt ncols_rho, ncols_corr, rstart, rend;
2212 const PetscScalar *vals_rho, *vals_corr;
2213 const PetscInt *cols_corr;
2214 ierr = MatGetOwnershipRange(rho,&rstart,&rend); CHKERRQ(ierr);
2215 for(PetscInt irow=rstart; irow<rend; ++irow)
2217 ierr = MatGetRow(rho,irow,&ncols_rho,NULL,&vals_rho); CHKERRQ(ierr);
2218 for(
size_t icorr=0; icorr<CorrSys.size(); ++icorr)
2220 ierr = MatGetRow(OpProds.at(icorr),irow,&ncols_corr,&cols_corr,&vals_corr); CHKERRQ(ierr);
2222 for(PetscInt icol=0; icol<ncols_corr; ++icol)
2224 y += vals_corr[icol]*vals_rho[cols_corr[icol]];
2227 ierr = MatRestoreRow(OpProds.at(icorr),irow,&ncols_corr,&cols_corr,&vals_corr); CHKERRQ(ierr);
2229 ierr = MatRestoreRow(rho,irow,&ncols_rho,NULL,&vals_rho); CHKERRQ(ierr);
2233 ierr = MPI_Allreduce(MPI_IN_PLACE, tr_rho, PetscMPIInt(CorrSys.size()), MPIU_SCALAR, MPI_SUM, sub_comm); CHKERRQ(ierr);
2235 for(
size_t icorr=0; icorr<CorrSys.size(); ++icorr)
2237 CorrValues[CorrSys[icorr].idx] = tr_rho[icorr];
2240 ierr = PetscFree(tr_rho); CHKERRQ(ierr);
2241 for(Mat& op_prod: AllOpProds){
2242 ierr = MatDestroy(&op_prod); CHKERRQ(ierr);
2244 for(
auto& op_mat: OpMats){
2245 ierr = MatDestroy(&(op_mat.second)); CHKERRQ(ierr);
2248 ierr = MatDestroy(&rho); CHKERRQ(ierr);
2255 if(CorrSysEnv.size() > 0)
2257 if(debug && !mpi_rank) std::cout <<
"\nCorrSysEnv" << std::endl;
2258 if(debug && !mpi_rank)
for(
const Correlator& m: CorrSysEnv) m.PrintInfo();
2261 std::map< std::string, Mat > OpMats;
2262 std::vector< Mat > AllOpProds;
2263 std::vector< Mat > OpProdsSys, OpProdsEnv;
2268 ierr = CalculateOperatorProducts(MPI_COMM_NULL, CorrSysEnv, BlockSys,
2269 KronBlocks.
LeftBlockRefMod(), OpMats, AllOpProds, OpProdsSys); CHKERRQ(ierr);
2271 ierr = CalculateOperatorProducts(MPI_COMM_NULL, CorrSysEnv, BlockEnv,
2272 KronBlocks.
RightBlockRefMod(), OpMats, AllOpProds, OpProdsEnv); CHKERRQ(ierr);
2274 for(
size_t icorr=0; icorr < CorrSysEnv.size(); ++icorr)
2282 PetscScalar Vec_Op_Vec;
2283 int OpTypeSys =
OpSz;
2284 int OpTypeEnv =
OpSz;
2285 for(
const Op& op : CorrSysEnv[icorr].SysOps) OpTypeSys += int(op.OpType);
2286 for(
const Op& op : CorrSysEnv[icorr].EnvOps) OpTypeEnv += int(op.OpType);
2288 OpProdsEnv.at(icorr),
Op_t(OpTypeEnv), KronOp); CHKERRQ(ierr);
2289 ierr = MatCreateVecs(KronOp, NULL, &Op_Vec); CHKERRQ(ierr);
2290 ierr = MatMult(KronOp, gsv_r, Op_Vec); CHKERRQ(ierr);
2291 ierr = VecDot(Op_Vec, gsv_r, &Vec_Op_Vec); CHKERRQ(ierr);
2292 ierr = MatDestroy_KronSumShell(&KronOp); CHKERRQ(ierr);
2293 ierr = MatDestroy(&KronOp); CHKERRQ(ierr);
2294 ierr = VecDestroy(&Op_Vec); CHKERRQ(ierr);
2296 CorrValues[CorrSysEnv[icorr].idx] = Vec_Op_Vec;
2299 for(Mat& op_prod: AllOpProds){
2300 ierr = MatDestroy(&op_prod); CHKERRQ(ierr);
2302 for(
auto& op_mat: OpMats){
2303 ierr = MatDestroy(&(op_mat.second)); CHKERRQ(ierr);
2307 if(debug && !mpi_rank){
2308 std::cout <<
"\nValues" << std::endl;
2309 for(
size_t icorr=0; icorr<measurements.size(); ++icorr){
2310 measurements[icorr].PrintInfo();
2311 std::cout <<
" = " << CorrValues[icorr] << std::endl << std::endl;
2318 if(!corr_printed_first)
2320 corr_printed_first = PETSC_TRUE;
2324 fprintf(fp_corr,
",\n");
2326 fprintf(fp_corr,
" [");
2327 for(
size_t icorr=0; icorr<measurements.size(); ++icorr){
2328 if(icorr) fprintf(fp_corr,
",");
2329 fprintf(fp_corr,
" %g", CorrValues[icorr]);
2331 fprintf(fp_corr,
" ]");
2335 if(debug && !mpi_rank) std::cout <<
"\n\n" << std::endl;
2341 const MPI_Comm& comm_in,
2342 const std::vector< Correlator >& Corr,
2346 std::map< std::string, Mat >& OpMats,
2347 std::vector< Mat >& AllOpProds,
2348 std::vector< Mat >& OpProds
2351 PetscErrorCode ierr;
2352 MPI_Comm comm = (comm_in==MPI_COMM_NULL) ? mpi_comm : comm_in;
2354 for(
size_t icorr=0; icorr<Corr.size(); ++icorr)
2357 const std::vector< Op >& OpsList = (BlockType == BlockSys)?c.
SysOps:c.
EnvOps;
2358 for(
const Op& o : OpsList)
2360 std::string key =
OpIdxToStr(o.OpType,o.idx);
2361 if(OpMats.find(key)==OpMats.end())
2364 ierr = BlockRef.RetrieveOperator(
2365 OpToStr(o.OpType), o.idx, OpMats[key], comm); CHKERRQ(ierr);
2370 std::string key =
"eye";
2371 if(OpMats.find(key)==OpMats.end())
2374 PetscInt nstates = BlockRef.NumStates();
2375 ierr = MatEyeCreate(comm, eye, nstates); CHKERRQ(ierr);
2382 OpProds.resize(Corr.size());
2383 for(
size_t icorr=0; icorr<Corr.size(); ++icorr)
2386 const std::vector< Op >& OpsList = (BlockType == BlockSys)?c.
SysOps:c.
EnvOps;
2387 if(OpsList.size()==1)
2390 OpProds.at(icorr) =
GetOpMats(OpMats,OpsList,0);
2392 else if(OpsList.size()>1)
2395 Mat Prod0=NULL, Prod1=NULL;
2398 MAT_INITIAL_MATRIX,PETSC_DEFAULT,&Prod1); CHKERRQ(ierr);
2401 PetscInt nmults = OpsList.size()-1;
2402 for(PetscInt imult=1; imult<nmults; ++imult)
2404 ierr = MatDestroy(&Prod0); CHKERRQ(ierr);
2407 ierr = MatMatMult(Prod0,
GetOpMats(OpMats,OpsList,imult+1),MAT_INITIAL_MATRIX,PETSC_DEFAULT,&Prod1); CHKERRQ(ierr);
2409 ierr = MatDestroy(&Prod0); CHKERRQ(ierr);
2410 AllOpProds.push_back(Prod1);
2411 OpProds.at(icorr) = Prod1;
2413 else if(OpsList.empty())
2416 OpProds.at(icorr) = OpMats[
"eye"];
2420 SETERRQ1(mpi_comm,1,
"%s should be non-empty.",(BlockType == BlockSys)?
"SysOps":
"EnvOps");
2430 PetscErrorCode ierr;
2431 PetscInt sys_idx = 0;
2432 std::set< PetscInt >::iterator act_it;
2433 for(act_it = SysIdx.begin(); act_it != SysIdx.end(); ++act_it){
2434 for(PetscInt idx = sys_idx; idx < *act_it; ++idx){
2435 ierr = sys_blocks[idx].EnsureSaved(); CHKERRQ(ierr);
2437 ierr = sys_blocks[*act_it].EnsureRetrieved(); CHKERRQ(ierr);
2438 sys_idx = *act_it+1;
2440 for(PetscInt idx = sys_idx; idx < sys_ninit; ++idx){
2441 ierr = sys_blocks[idx].EnsureSaved(); CHKERRQ(ierr);
2457 const std::string& BlockType,
2458 const PetscInt& iblock
2461 std::ostringstream oss;
2462 oss << BlockType <<
"_" << std::setfill(
'0') << std::setw(9) << iblock <<
"/";
2475 const PetscInt& isweep
2478 std::ostringstream oss;
2479 oss <<
"Sweep_" << std::setfill(
'0') << std::setw(9) << isweep <<
"/";
2484 PetscErrorCode SaveStepHeaders()
2486 if(mpi_rank || !data_tabular)
return(0);
2487 fprintf(fp_step,
"{\n");
2488 fprintf(fp_step,
" \"headers\" : [");
2489 fprintf(fp_step,
"\"GlobIdx\", ");
2490 fprintf(fp_step,
"\"LoopType\", ");
2491 fprintf(fp_step,
"\"LoopIdx\", ");
2492 fprintf(fp_step,
"\"StepIdx\", ");
2493 fprintf(fp_step,
"\"NSites_Sys\", ");
2494 fprintf(fp_step,
"\"NSites_Env\", ");
2495 fprintf(fp_step,
"\"NSites_SysEnl\", ");
2496 fprintf(fp_step,
"\"NSites_EnvEnl\", ");
2497 fprintf(fp_step,
"\"NStates_Sys\", ");
2498 fprintf(fp_step,
"\"NStates_Env\", ");
2499 fprintf(fp_step,
"\"NStates_SysEnl\", ");
2500 fprintf(fp_step,
"\"NStates_EnvEnl\", ");
2501 fprintf(fp_step,
"\"NStates_SysRot\", ");
2502 fprintf(fp_step,
"\"NStates_EnvRot\", ");
2503 fprintf(fp_step,
"\"NumStates_H\", ");
2504 fprintf(fp_step,
"\"TruncErr_Sys\", ");
2505 fprintf(fp_step,
"\"TruncErr_Env\", ");
2506 fprintf(fp_step,
"\"GSEnergy\"");
2507 fprintf(fp_step,
" ],\n");
2508 fprintf(fp_step,
" \"table\" : ");
2518 if(mpi_rank)
return(0);
2519 fprintf(fp_step,
"%s", GlobIdx ?
",\n" :
"");
2521 fprintf(fp_step,
" [ ");
2522 fprintf(fp_step,
"%lld, ", LLD(GlobIdx));
2523 fprintf(fp_step,
"%s, ", LoopType ?
"\"Sweep\"" :
"\"Warmup\"");
2524 fprintf(fp_step,
"%lld, ", LLD(LoopIdx));
2525 fprintf(fp_step,
"%lld, ", LLD(StepIdx));
2539 fprintf(fp_step,
"%.12g", data.
GSEnergy);
2540 fprintf(fp_step,
"]");
2544 fprintf(fp_step,
" {\n");
2545 fprintf(fp_step,
" \"GlobIdx\": %lld,\n", LLD(GlobIdx));
2546 fprintf(fp_step,
" \"LoopType\": \"%s\",\n", LoopType ?
"Sweep" :
"Warmup");
2547 fprintf(fp_step,
" \"LoopIdx\": %lld,\n", LLD(LoopIdx));
2548 fprintf(fp_step,
" \"StepIdx\": %lld,\n", LLD(StepIdx));
2549 fprintf(fp_step,
" \"NSites_Sys\": %lld,\n", LLD(data.
NumSites_Sys));
2550 fprintf(fp_step,
" \"NSites_Env\": %lld,\n", LLD(data.
NumSites_Env));
2551 fprintf(fp_step,
" \"NSites_SysEnl\": %lld,\n", LLD(data.
NumSites_SysEnl));
2552 fprintf(fp_step,
" \"NSites_EnvEnl\": %lld,\n", LLD(data.
NumSites_EnvEnl));
2553 fprintf(fp_step,
" \"NStates_Sys\": %lld,\n", LLD(data.
NumStates_Sys));
2554 fprintf(fp_step,
" \"NStates_Env\": %lld,\n", LLD(data.
NumStates_Env));
2555 fprintf(fp_step,
" \"NStates_SysEnl\": %lld,\n", LLD(data.
NumStates_SysEnl));
2556 fprintf(fp_step,
" \"NStates_EnvEnl\": %lld,\n", LLD(data.
NumStates_EnvEnl));
2557 fprintf(fp_step,
" \"NStates_SysRot\": %lld,\n", LLD(data.
NumStates_SysRot));
2558 fprintf(fp_step,
" \"NStates_EnvRot\": %lld,\n", LLD(data.
NumStates_EnvRot));
2559 fprintf(fp_step,
" \"TruncErr_Sys\": %.20g,\n", data.
TruncErr_Sys);
2560 fprintf(fp_step,
" \"TruncErr_Env\": %.20g,\n", data.
TruncErr_Env);
2561 fprintf(fp_step,
" \"GSEnergy\": %.20g\n", data.
GSEnergy);
2562 fprintf(fp_step,
" }");
2568 PetscErrorCode SaveTimingsHeaders()
2570 if(mpi_rank || !data_tabular)
return(0);
2571 fprintf(fp_timings,
"{\n");
2572 fprintf(fp_timings,
" \"headers\" : [");
2573 fprintf(fp_timings,
"\"GlobIdx\", ");
2574 fprintf(fp_timings,
"\"Total\", ");
2575 fprintf(fp_timings,
"\"Enlr\", ");
2576 fprintf(fp_timings,
"\"Kron\", ");
2577 fprintf(fp_timings,
"\"Diag\", ");
2578 fprintf(fp_timings,
"\"Rdms\", ");
2579 fprintf(fp_timings,
"\"Rotb\" ");
2580 fprintf(fp_timings,
"],\n");
2581 fprintf(fp_timings,
" \"table\" : ");
2591 if(mpi_rank)
return(0);
2592 fprintf(fp_timings,
"%s", GlobIdx ?
",\n" :
"");
2594 fprintf(fp_timings,
" [ ");
2595 fprintf(fp_timings,
"%lld, ", LLD(GlobIdx));
2596 fprintf(fp_timings,
"%.9g, ", data.
Total);
2597 fprintf(fp_timings,
"%.9g, ", data.
tEnlr);
2598 fprintf(fp_timings,
"%.9g, ", data.
tKron);
2599 fprintf(fp_timings,
"%.9g, ", data.
tDiag);
2600 fprintf(fp_timings,
"%.9g, ", data.
tRdms);
2601 fprintf(fp_timings,
"%.9g ", data.
tRotb);
2602 fprintf(fp_timings,
"]");
2606 fprintf(fp_timings,
" {\n");
2607 fprintf(fp_timings,
" \"Total\": %.9g,\n", data.
Total);
2608 fprintf(fp_timings,
" \"Enlr\": %.9g,\n", data.
tEnlr);
2609 fprintf(fp_timings,
" \"Kron\": %.9g,\n", data.
tKron);
2610 fprintf(fp_timings,
" \"Diag\": %.9g,\n", data.
tDiag);
2611 fprintf(fp_timings,
" \"Rdms\": %.9g,\n", data.
tRdms);
2612 fprintf(fp_timings,
" \"Rotb\": %.9g\n", data.
tRotb);
2613 fprintf(fp_timings,
" }");
2620 const std::vector< Eigen_t >& eigen_L,
2621 const std::vector< PetscReal >& qn_L,
2622 const std::vector< Eigen_t >& eigen_R,
2623 const std::vector< PetscReal >& qn_R
2626 if(mpi_rank)
return(0);
2627 fprintf(fp_entanglement,
"%s", GlobIdx ?
",\n" :
"");
2628 fprintf(fp_entanglement,
" {\n");
2629 fprintf(fp_entanglement,
" \"GlobIdx\": %lld,\n", LLD(GlobIdx));
2630 fprintf(fp_entanglement,
" \"Sys\": [\n");
2632 PetscInt idx_prev = 999999999;
2633 for(
const Eigen_t &eig: eigen_L){
2634 if(idx_prev!=eig.blkIdx){
2635 if(idx_prev != 999999999) fprintf(fp_entanglement,
" ]},\n");
2636 fprintf(fp_entanglement,
" {");
2637 fprintf(fp_entanglement,
"\"sector\": %g, \"vals\": [ %g",qn_L[eig.blkIdx], eig.eigval);
2639 fprintf(fp_entanglement,
", %g", eig.eigval);
2641 idx_prev = eig.blkIdx;
2643 fprintf(fp_entanglement,
" ]}\n");
2645 fprintf(fp_entanglement,
" ],\n");
2646 fprintf(fp_entanglement,
" \"Env\": [\n");
2648 PetscInt idx_prev = 999999999;
2649 for(
const Eigen_t &eig: eigen_R){
2650 if(idx_prev!=eig.blkIdx){
2651 if(idx_prev != 999999999) fprintf(fp_entanglement,
" ]},\n");
2652 fprintf(fp_entanglement,
" {");
2653 fprintf(fp_entanglement,
"\"sector\": %g, \"vals\": [ %g",qn_R[eig.blkIdx], eig.eigval);
2655 fprintf(fp_entanglement,
", %g", eig.eigval);
2657 idx_prev = eig.blkIdx;
2659 fprintf(fp_entanglement,
" ]}\n");
2661 fprintf(fp_entanglement,
" ]\n");
2662 fprintf(fp_entanglement,
" }");
2663 fflush(fp_entanglement);
2670 if(mpi_rank)
return(0);
2671 fprintf(fp_data,
",\n");
2672 fprintf(fp_data,
" \"Warmup\": {\n");
2673 fprintf(fp_data,
" \"MStates\": %lld\n", LLD(mwarmup));
2674 fprintf(fp_data,
" },\n");
2675 fprintf(fp_data,
" \"Sweeps\": {\n");
2676 fprintf(fp_data,
" \"MStates\": [");
2678 PetscInt nsweeps = sweeps_mstates.size();
2679 if(nsweeps>0) fprintf(fp_data,
" %lld", LLD(sweeps_mstates[0]));
2680 for(PetscInt i=1;i<nsweeps;++i) fprintf(fp_data,
", %lld", LLD(sweeps_mstates[i]));
2682 fprintf(fp_data,
" ]\n");
2683 fprintf(fp_data,
" }");
2691 if(mpi_rank)
return(0);
2692 PetscErrorCode ierr;
2695 std::vector< std::string > keys = {
2708 std::ostringstream oss;
2709 for(std::string& key: keys) {
2710 ierr = PetscOptionsGetString(NULL,NULL,key.c_str(),val,4096,&
set); CHKERRQ(ierr);
2712 std::string val_str(val);
2713 if(val_str.empty()) val_str =
"yes";
2714 oss << key <<
" " << val_str << std::endl;
2719 ierr = PetscFOpen(PETSC_COMM_SELF,filename.c_str(),
"w", &fp); CHKERRQ(ierr);
2720 ierr = PetscFPrintf(PETSC_COMM_SELF,fp,
"%s",oss.str().c_str()); CHKERRQ(ierr);
2721 ierr = PetscFClose(PETSC_COMM_SELF,fp); CHKERRQ(ierr);
2730 if(mpi_rank)
return(0);
2731 PetscErrorCode ierr;
2734 std::string ham_data_fn = scratch_dir + SweepDir(LoopIdx) +
"Hamiltonian.dat";
2735 ierr = Ham.SaveAsOptions(ham_data_fn); CHKERRQ(ierr);
2738 std::string dmrg_data_fn = scratch_dir + SweepDir(LoopIdx) +
"PetscOptions.dat";
2739 ierr = SaveAsOptions(dmrg_data_fn); CHKERRQ(ierr);
2742 std::string sweep_data_fn = scratch_dir + SweepDir(LoopIdx) +
"Sweep.dat";
2743 std::ofstream sweep_data_file(sweep_data_fn);
2745 #define SWEEP_DUMP(VAR) \ 2746 sweep_data_file << std::setw(20) << (#VAR) << " " << (VAR) << "\n"; 2749 SWEEP_DUMP(GlobIdx );
2750 SWEEP_DUMP(LoopIdx );
2751 SWEEP_DUMP(num_sys_blocks );
2752 SWEEP_DUMP(num_env_blocks );
2753 SWEEP_DUMP(sys_ninit );
2754 SWEEP_DUMP(env_ninit );
2756 SWEEP_DUMP(num_sites );
2758 SWEEP_DUMP(sweep_mode );
2759 SWEEP_DUMP(msweep_idx );
2762 sweep_data_file.close();
2771 #undef MAX_SWEEP_IDX 2777 #endif // __DMRG_BLOCK_CONTAINER_HPP__ PetscInt seqIdx
Index of the EPS and matrix objects in the vector sequence.
PetscErrorCode SaveSweepsData()
Save data at the end of a completed sweep into the sweep directory in the scratch.
PetscMPIInt mpi_rank
MPI rank in mpi_comm.
PetscErrorCode SaveEntanglementSpectra(const std::vector< Eigen_t > &eigen_L, const std::vector< PetscReal > &qn_L, const std::vector< Eigen_t > &eigen_R, const std::vector< PetscReal > &qn_R)
Save the entanglement spectra to file.
PetscErrorCode CalculateCorrelations_BlockDiag(KronBlocks_t &KronBlocks, const Vec &gsv_r, const BasisTransformation &BT, const PetscBool flg=PETSC_TRUE)
Calculates the correlation functions.
Storage for basic data to be saved corresponding to a call of SingleDMRGStep()
PetscErrorCode SysBlocksActive(const std::set< PetscInt > &SysIdx)
Ensure that required blocks are loaded while unrequired blocks are saved.
Contains information on quantum numbers and associated index ranges.
std::string restart_dir
Path to sweep directory for performing restart.
PetscErrorCode SaveTimingsData(const TimingsData &data)
Save timings data to file.
Block::SpinBase & RightBlockRefMod()
Returns a non-const reference to the right block object.
std::vector< Op > SysOps
List of operators residing on the system block.
PetscInt NumSites_Env
Number of sites in the input env block.
PETSC_EXTERN PetscErrorCode Makedir(const std::string &dir_name)
Creates a directory named dir_name.
PetscErrorCode Warmup()
Performs the warmup stage of DMRG or loads blocks for the restart stage.
Step_t
Lists the types of steps that can be performed.
PetscLogDouble Total
Total time.
PetscErrorCode Initialize()
Initializes the container object with blocks of one site on each of the system and environment...
std::vector< Block > env_blocks
Environment blocks to be used only during warmup.
std::vector< PetscReal > trunc_err
Stores the truncation error at the end of a single dmrg step.
std::vector< Correlator > measurements
Stores the measurements to be performed at the end of each sweep.
bool less_blkIdx(const Eigen_t &e1, const Eigen_t &e2)
Comparison operator for sorting Eigen_t objects by increasing blkIdx (decreasing qn's) ...
PetscErrorCode SingleDMRGStep(Block &SysBlock, Block &EnvBlock, const PetscInt &MStates, Block &SysBlockOut, Block &EnvBlockOut, PetscBool do_measurements=PETSC_FALSE)
Performs a single DMRG iteration taking in a system and environment block, adding one site to each an...
Block::SpinBase & LeftBlockRefMod()
Returns a non-const reference to the left block object.
PetscErrorCode SetUpCorrelation(const std::vector< Op > &OpList, const std::string &name, const std::string &desc)
Sets up measurement of correlation functions at the end of each sweep.
std::vector< Block > sys_blocks
Array of system blocks each of which will be kept all throughout the simulation.
PetscInt NumSites_SysEnl
Number of sites in the enlarged sys block.
const Block & EnvBlock(const PetscInt &BlockIdx) const
Accesses the specified environment block.
PetscInt size() const
Returns the total number blocks.
PetscErrorCode CalculateOperatorProducts(const MPI_Comm &comm_in, const std::vector< Correlator > &Corr, const Block_t &BlockType, Block &BlockRef, std::map< std::string, Mat > &OpMats, std::vector< Mat > &AllOpProds, std::vector< Mat > &OpProds)
Calculates the products of operators that belong to a single block represented by the same basis...
const std::vector< PetscReal > & ListRef() const
Returns the list of quantum numbers as a const reference.
std::string BlockDir(const std::string &BlockType, const PetscInt &iblock)
Returns the relative path to the directory for the storage of a specific system block.
#define GetOpMats(OPMATS, CORRSIDEOPS, OPID)
Get the operator matrix corresponding to the given type, size and index.
std::string SweepDir(const PetscInt &isweep)
Returns the relative path to the directory for the storage of a specific sweep / loop index...
#define MAX_SWEEP_IDX
Hardcoded maximum number of sweeps to be searched.
PetscInt RightIdx(const PetscInt &idx) const
Returns the left quantum number index (KronBlocks 1st endtry) for a given KronBlock index...
#define ASSIGN_VAR(MAP, VAR)
Assign a value into key-variable and throw a proper PETSc error when lookup fails.
Perform sweeps with a varying number of kept states.
Block SingleSite
Single site that is added to each block during the block enlargement procedure.
PetscBool Verbose() const
Returns whether verbose printing is active.
PetscInt NumStates_Sys
Number of states in the input sys block.
PetscErrorCode EnsureSaved()
Ensures that the block matrices have been saved if the block is initialized, otherwise does nothing...
PetscLogDouble tEnlr
Enlargement of each block.
PetscErrorCode KronEye_Explicit(Block::SpinBase &LeftBlock, Block::SpinBase &RightBlock, const std::vector< Hamiltonians::Term > &Terms, Block::SpinBase &BlockOut)
Calculates a new block combining two spin-1/2 blocks.
#define PrintBlocks(LEFT, RIGHT)
Printout the number of sites in each of the input blocks.
PetscInt NumSites_EnvEnl
Number of sites in the enlarged env block.
Op_t
Identifies the three possible spin operators and also represents the shift associated to its action o...
PetscErrorCode SaveAsOptions(const std::string &filename)
Dumps significant keys and values to file to be retrieved for restart.
PetscReal TruncErr_Sys
Truncation error for the system block.
PetscErrorCode PrintInfo() const
Print out information regarding this operator.
#define PRINT_VAR(VAR)
Print the value of a given variable name.
std::string desc1
Descriptor 1: Using 2d indices.
PetscInt NumStates_Env
Number of states in the input env block.
std::string desc3
Descriptor 3: Using 1d indices separated into sys and env blocks.
PetscErrorCode KronConstruct(const Mat &Mat_L, const Op_t &OpType_L, const Mat &Mat_R, const Op_t &OpType_R, Mat &MatOut)
Constructs the explicit sum of Kronecker products of two matrices provided that they follow a fixed K...
PetscErrorCode Destroy()
Destroys the container object.
std::vector< PetscReal > List() const
Returns the list of quantum numbers.
Storage for information on resulting eigenpairs of the reduced density matrices.
#define PrintLines()
Print out horizontal lines of - characters.
PetscInt NumStates_SysEnl
Number of states in the enlarged sys block.
#define PRINTLINES()
Print out horizontal lines of = characters.
Contains the definitions for blocks of spin sites.
PetscErrorCode GetTruncation(const KronBlocks_t &KronBlocks, const Vec &gsv_r, const PetscInt &MStates, BasisTransformation &BT_L, BasisTransformation &BT_R)
Obtain the rotation matrix for the truncation step from the ground state vector.
A single interaction term on a one-dimensional lattice.
PetscInt NumStates_H
Number of states used in constructing the superblock Hamiltonian.
PetscInt NumSites_Sys
Number of sites in the input sys block.
std::vector< PetscInt > maxnsweeps
Maximum number of sweeps for each state in msweeps (for SWEEP_MODE_TOLERANCE_TEST only) ...
PetscErrorCode PrintInfo() const
Prints some information regarding the correlator.
PetscInt num_sites
Total number of sites.
Op_t OpType
Operator type.
Perform N sweeps with a fixed number of kept states.
Do not perform any sweep.
PetscReal QN(const PetscInt &idx) const
Returns the left quantum number index (KronBlocks 1st endtry) for a given KronBlock index...
std::vector< PetscInt > Sizes() const
Returns the number of basis states in each quantum number block.
PetscMPIInt mpi_size
MPI size of mpi_comm.
Describes an n-point correlator whose expectation value will be measured at the end of each sweep...
std::vector< PetscInt > Offsets() const
Returns the offsets for each quantum number block.
PetscScalar eigval
Eigenvalue.
const Block::SpinBase & LeftBlockRef() const
Returns a const reference to the left block object.
PetscInt NumSites() const
Returns that number of sites recorded in the Hamiltonian object.
PetscLogDouble tKron
Construction of the Hamiltonian using Kronecker product routines.
std::vector< PetscInt > sweeps_mstates
Records the number of states requested for each sweep, where each entry is a single call to Sweep() ...
PetscErrorCode SingleSweep(const PetscInt &MStates, const PetscInt &MinBlock=PETSC_DEFAULT)
Performs a single sweep from center to right, and back to center.
PetscInt NumStates_EnvRot
Number of states in the rotated env block.
PetscErrorCode KronSumConstruct(const std::vector< Hamiltonians::Term > &Terms, Mat &MatOut)
Constructs the explicit sum of Kronecker products of matrices from the blocks.
PetscInt blkIdx
Index in the block's magnetization sectors.
const std::vector< KronBlock_t > & data() const
Returns a const reference to the KronBlocks object.
#define OpToStr(OP)
Convert the input Op_t to a C++ string.
PetscErrorCode Sweeps()
Performs the sweep stage of DMRG.
PetscErrorCode KronSumSetShellMatrix(const PetscBool &do_shell_in)
Decide whether to create an implicit MATSHELL matrix.
std::string name
Short name of the correlator.
PetscInt NumSectors() const
Returns the number of quantum number sectors.
std::vector< PetscInt > Offsets() const
Returns the offsets for each quantum number block.
std::tuple< PetscReal, PetscInt, PetscInt, PetscInt > KronBlock_t
Storage for information on resulting blocks of quantum numbers stored as a tuple for quick sorting...
PetscReal TruncErr_Env
Truncation error for the environment block.
std::map< std::string, PetscInt > restart_sweep_dict
Contents of the Sweep.dat file which will be read when restarting.
PetscInt NumStates_EnvEnl
Number of states in the enlarged env block.
PetscLogDouble tRotb
Rotation of the block operators.
std::string desc2
Descriptor 2: Using 1d indices.
const Block::SpinBase & RightBlockRef() const
Returns a const reference to the right block object.
#define OpIdxToStr(OPTYPE, IDX)
Convert the input operator type and index to string.
PetscInt LeftIdx(const PetscInt &idx) const
Returns the left quantum number index (KronBlocks 1st endtry) for a given KronBlock index...
Block_t
Provides an alias of Side_t to follow the Sys-Env convention.
#define CheckInitialization(init, mpi_comm)
Returns an error if DMRGBlockContainer object is not initialized.
const Hamiltonian & HamiltonianRef() const
Const reference to the Hamiltonian object for extracting its parameters.
Contains and manipulates the system and environment blocks used in a single DMRG run.
const Block & SysBlock(const PetscInt &BlockIdx) const
Accesses the specified system block.
A container of ordered KronBlock_t objects representing a Kronecker product structure.
QuantumNumbers Magnetization
Stores the information on the magnetization Sectors.
PetscInt epsIdx
Index in the EPS object.
PetscLogDouble tRdms
Construction of the reduced density matrices from the ground state vector.
PetscInt NumStates_SysRot
Number of states in the rotated sys block.
PetscErrorCode EigRDM_BlockDiag(const Mat &matin, const PetscInt &seqIdx, const PetscInt &blkIdx, std::vector< Eigen_t > &eigList, EPS &eps)
Obtain the eigenspectrum of a diagonal block of the reduced density matrix through an interface to a ...
PetscErrorCode FillRotation_BlockDiag(const std::vector< Eigen_t > &eigen_list, const std::vector< EPS > &eps_list, const std::vector< Vec > &rdmd_vecs, const Block &BlockRef, Mat &RotMatT)
Fills the rotation matrix assumming that the reduced density matrix has a block diagonal structure...
PetscInt num_sys_blocks
Number of system blocks to be stored.
std::vector< Op > EnvOps
List of operators residing on the environment block.
~DMRGBlockContainer()
Calls the Destroy() method and deallocates container object.
PetscScalar GSEnergy
Ground state energy.
PetscErrorCode SaveLoopsData()
Save data regarding warmup/sweeps into the data directory.
bool greater_eigval(const Eigen_t &e1, const Eigen_t &e2)
Comparison operator for sorting Eigen_t objects by decreasing eigenvalues.
PetscLogDouble tDiag
Diagonalization of the Hamiltonian using EPS routines.
SweepMode_t
Determines the type of sweep to be performed.
PetscInt NumStates() const
Returns the total number of states.
Defines a single operator to be used for performing measurements.
std::vector< PetscInt > msweeps
Number of states for each sweep (for SWEEP_MODE_MSWEEPS and SWEEP_MODE_TOLERANCE_TEST only) ...
const Block & EnvBlock() const
Accesses the 0th environment block.
Hamiltonian Ham
Container for the Hamiltonian and geometry.
PetscInt idx
Index of the correlator in the sequence.
Storage for timings to be saved corresponding to a call of SingleDMRGStep()
DMRGBlockContainer(const MPI_Comm &mpi_comm)
The constructor only takes in the MPI communicator; Initialize() has to be called explicitly next...
PetscErrorCode SaveStepData(const StepData &data)
Save step data to file.
PetscInt NumStates() const
Returns the total number of states.