/* Developed by Sandeep Sharma, Roberto Olivares-Amaya and Garnet K.-L. Chan, 2012 Copyright (c) 2012, Garnet K.-L. Chan This program is integrated in Molpro with the permission of Sandeep Sharma, Roberto Olivares-Amaya and Garnet K.-L. Chan */ #include #include #include #include "Symmetry.h" #include "global.h" #include "MatrixBLAS.h" #include "Stackspinblock.h" #include "StateInfo.h" #include "couplingCoeffs.h" #include "genetic/GAOptimize.h" #include "genetic/ReadIntegral.h" #include #include #include #include #ifndef SERIAL #include #include "mpi.h" #endif #include #include "fiedler.h" #include "pario.h" #include "IntegralMatrix.h" #include "newmatutils.h" using namespace std; namespace SpinAdapted { string sym; bool NonabelianSym; } void CheckFileExistence(string filename, string filetype); void CheckFileInexistence(string filename, string filetype); void SpinAdapted::Input::ReadMeaningfulLine(ifstream& input, string& msg, int msgsize) { bool readmore = true; while (readmore && !input.eof()) { char msgctr[msgsize]; input.getline(msgctr, msgsize+1); msg=string(msgctr); if(msg.size() == msgsize) { pout << "in the process of reading line beginning with "<(world.size(),1); m_calc_procs = vector(world.size(), 0); for (int i=0; i(1,1); m_calc_procs = vector(1, 0); #endif m_quanta_thrds = 1; m_mkl_thrds = 1; m_ham_type = QUANTUM_CHEMISTRY; m_algorithm_type = TWODOT_TO_ONEDOT; m_sweep_type = FULL; m_noise_type = RANDOM; m_calc_type = DMRG; m_solve_type = DAVIDSON; m_stateSpecific = false; m_implicitTranspose = true; //dont make DD just use CC^T to evaluate it m_occupied_orbitals = -1; m_num_Integrals = 1; v_2.resize(1, TwoElectronArray(TwoElectronArray::restrictedNonPermSymm)); v_1.resize(1); v_cc.resize(1); v_cccc.resize(1); v_cccd.resize(1); coreEnergy.resize(1); m_baseState.resize(1,0); m_projectorState.resize(0); m_targetState = -1; m_guessState = 1; m_permSymm = 2; m_lowMemoryAlgorithm = true; m_performResponseSolution = true; m_memory = 2e9/sizeof(double); //about 2GB of memory by default m_useSharedMemory = true; m_IntegralMemoryStart = NULL; m_openorbs.resize(0); m_closedorbs.resize(0); m_spinAdapted = true; m_Bogoliubov = false; m_sys_add = 1; m_env_add = 1; m_twodot_to_onedot_iter = 0; m_integral_disk_storage_thresh = 1000; m_max_lanczos_dimension = 5000; m_norbs = 0; m_partialSweep = 0; m_alpha = 0; m_beta = 0; m_hf_occ_user = ""; m_outputlevel = 0; m_nquanta = 2; m_total_symmetry_number = IrrepSpace( 0 ); m_total_spin = 0; m_guess_permutations = 10; m_direct = true; m_nroots = 1; m_weights.resize(m_nroots); m_weights[0] = 1.; m_deflation_min_size = 2; m_deflation_max_size = 20; m_add_noninteracting_orbs = true; m_no_transform = false; m_do_fci = false; m_do_npdm_ops = false; m_do_npdm_in_core = false; m_new_npdm_code = false; m_do_pdm = false; m_store_spinpdm = false; m_spatpdm_disk_dump = false; m_store_nonredundant_pdm =false; m_pdm_unsorted = false; m_npdm_intermediate= true; m_npdm_multinode= true; m_nevpt_state_num = 0; m_maxiter = 10; m_oneindex_screen_tol = NUMERICAL_ZERO; m_twoindex_screen_tol = NUMERICAL_ZERO; m_load_prefix = "."; m_save_prefix = "."; m_maxj = 15; m_ninej.init(m_maxj); m_set_Sz = false; n_twodot_noise = 0; m_twodot_noise = 1.0e-4; m_twodot_gamma = 3.0e-1; m_sweep_tol = 1.0e-5; m_restart = false; m_fullrestart = false; m_restart_warm = false; m_backward = false; m_reset_iterations = false; m_do_diis = false; m_diis_error = 1e-2; m_start_diis_iter = 8; m_diis_keep_states = 6; m_diis_error_tol = 1e-8; m_num_spatial_orbs = 0; m_schedule_type_default = false; m_schedule_type_backward = false; m_maxM = 0; m_lastM = 500; m_startM = 250; m_bra_M = 0; m_calc_ri_4pdm=false; m_store_ripdm_readable=false; m_nevpt2 = false; m_conventional_nevpt2 = false; m_kept_nevpt2_states = -1; NevPrint.first=false; NevPrint.second=0; //reorder options, by default it does fiedler m_reorderType = FIEDLER; m_reorderfile = ""; m_gaconffile = "default"; m_orbformat=MOLPROFORM; m_warmup = LOCAL0; } void SpinAdapted::Input::usedkey_error(string& key, string& line) { pout << "keyword "< usedkey(NUMKEYWORDS, -1); int n_elec = -1; int n_spin = -1; sym = "c1"; NonabelianSym = false; std::vector orbitalfile; int rank = 0; #ifndef SERIAL boost::mpi::communicator world; rank = world.rank(); #endif if(rank == 0) { pout << "Reading input file"< tok; boost::split(tok, msg, is_any_of(", \t"), token_compress_on); string keyword = *tok.begin(); if (boost::iequals(keyword, "orbs") || boost::iequals(keyword, "orbitals") || boost::iequals(keyword, " orbitals")) { if(usedkey[ORBS] == 0) usedkey_error(keyword, msg); usedkey[ORBS] = 0; if (tok.size() < 2) { pout << "keyword orbs should be followed by atleast a single filename and then an end line"<= world.size()) { #endif pout << "calcprocessor number is greater than total number of processors"< schd_tok; boost::split(schd_tok, msg, is_any_of(" \t"), token_compress_on); if (tok.size() != 1) { if (boost::iequals(tok[1], "default")) { m_schedule_type_default = true; continue; } } m_sweep_iter_schedule.resize(0); m_sweep_state_schedule.resize(0); m_sweep_qstate_schedule.resize(0); m_sweep_tol_schedule.resize(0); m_sweep_noise_schedule.resize(0); m_sweep_additional_noise_schedule.resize(0); int i = 0; while(!boost::iequals(schd_tok[0], "END")) { if (schd_tok.size() != 4) { pout << "Each line of the schedule contain four entries sweep_iteration #retained states Davidson tolerance noise"<0 && m_sweep_iter_schedule[i] <= m_sweep_iter_schedule[i-1]) { pout << "Sweep iteration at a given line should be higher than the previous sweep iteration"<(1, atoi(tok[1].c_str())); } else if (boost::iequals(keyword, "mps_nevpt")) { m_calc_type = MPS_NEVPT; if (tok.size() !=4){ pout << "keyword mps_nevpt should be followed by three numbers and then an end line"<(i)]= OneElectronArray(); // } for(int i= 0; i< TwoPertEnd; i++){ //vpt_2[static_cast(i)]= TwoElectronArray(TwoElectronArray::restrictedNonPermSymm); vpt_2[static_cast(i)]= PerturbTwoElectronArray(); // vpt_2[i].rhf = true; } } else if (boost::iequals(keyword, "restart_mps_nevpt")) { m_calc_type = RESTART_MPS_NEVPT; if (tok.size() !=4){ pout << "keyword mps_nevpt should be followed by three numbers and then an end line"<(i)]= OneElectronArray(); // } for(int i= 0; i< TwoPertEnd; i++){ //vpt_2[static_cast(i)]= TwoElectronArray(TwoElectronArray::restrictedNonPermSymm); vpt_2[static_cast(i)]= PerturbTwoElectronArray(); } } else if (boost::iequals(keyword, "nevpt_state_num" )) { if (tok.size() != 2) { pout << "keyword nevpt_state_num should be followed by a single integer than then an end line."< :: iterator it = ++tok.begin(); // the occupancies start from the second element of the tok string if (tok.size() == 2 ) { m_hf_occ_user = (*it).c_str(); } else{ m_hf_occ_user = "manual"; for( ; it != tok.end(); ++it ){ int occ_i = atoi( (*it).c_str() ); m_hf_occupancy.push_back( occ_i ); } } pout << "m_hf_occ_user " << m_hf_occ_user << endl; } else if(boost::iequals(keyword, "open")) { vector :: iterator it = ++tok.begin(); m_openorbs.resize(tok.size()-1,-1); int ii = 0; for( ; it != tok.end(); ++it ){ int openorb = atoi( (*it).c_str() ); m_openorbs[ii] = openorb-1 ; //pout << openorb<<" "; ii++; } //pout << endl; } else if(boost::iequals(keyword, "closed")) { vector :: iterator it = ++tok.begin(); m_closedorbs.resize(tok.size()-1,-1); //pout << "closed orbs :"; int ii=0; for( ; it != tok.end(); ++it ){ int closedorb = atoi( (*it).c_str() ); m_closedorbs[ii] = closedorb -1; //pout << closedorb<<" "; ii++; } //pout << endl; } else if(boost::iequals(keyword, "nroots")) { if(usedkey[NROOTS] == 0) usedkey_error(keyword, msg); usedkey[NROOTS] = 0; std::string nroots_str; if (tok.size() != 2) { pout << "keyword nroots should be followed by a single integer and then an end line."< weighttoken; boost::split(weighttoken, msg, is_any_of(" \t"), token_compress_on); if (!boost::iequals(weighttoken[0], "weights")) { //manually make all the weights equal m_weights.resize(m_nroots); for (int i=0; i1 ) { pout << "Currently the response code does not work with non-particle number conserving hamiltonians!!"; abort(); } //if (sym != "c1") // must be initialized even if c1 sym. Symmetry::InitialiseTable(sym); if (mpigetrank() == 0) { for (int l=0; l reorder; reorder.resize(m_norbs/2); for (int i=0; i& oldtonew) { string msg; int msgsize = 5000; ReadMeaningfulLine(dumpFile, msg, msgsize); vector tok; std::vector diff; boost::split(tok, msg, is_any_of(", \t"), token_compress_on); while(msg.size() != 0) { for (int i=0; im_norbs || oldtonew.back() < 0) { pout << "Illegal orbital index "< tok; int offset = m_orbformat == DMRGFORM ? 0 : 1; std::ofstream ReorderFileOutput; std::ifstream ReorderFileInput; char ReorderFileName[5000]; std::vector reorder; int rank = 0; #ifndef SERIAL boost::mpi::communicator world; rank = world.rank(); #endif if (rank == 0) { ReadMeaningfulLine(dumpFile, msg, msgsize); boost::split(tok, msg, is_any_of("=, \t"), token_compress_on); if(offset != 0) m_norbs = 2*atoi(tok[2].c_str()); else m_norbs = 2*atoi(tok[1].c_str()); if (m_partialSweep == 0) m_partialSweep = m_norbs; m_num_spatial_orbs = 0; m_spin_orbs_symmetry.resize(m_norbs); m_spin_to_spatial.resize(m_norbs); //this is the file to which the reordering is written sprintf(ReorderFileName, "%s%s", save_prefix().c_str(), "/RestartReorder.dat"); } //boost::filesystem::path p(ReorderFileName); #ifndef SERIAL mpi::broadcast(world,m_norbs,0); mpi::broadcast(world,m_restart,0); mpi::broadcast(world,m_fullrestart,0); #endif //do the reordering only if it is not a restart calculation //if it is then just read the reorder.dat from the scratch space if (integralIndex == 0) { if(get_restart() || get_fullrestart() || m_calc_type == COMPRESS || m_calc_type == RESPONSE || m_calc_type == RESPONSEBW) { if (rank == 0) { ReorderFileInput.open(ReorderFileName); boost::filesystem::path ReorderFilePath(ReorderFileName); if(!boost::filesystem::exists(ReorderFilePath)) { pout << "==============="<> m_reorder[i]; ReorderFileInput.close(); } } } else { if (rank == 0) { ReorderFileOutput.open(ReorderFileName); } // read the reorder file or calculate the reordering using one of the many options if (m_reorderType == FIEDLER) { if (rank == 0){ m_reorder=get_fiedler(orbitalfile); pout << "Fiedler-vector orbital ordering: "; } } else if (m_reorderType == GAOPT) { ifstream gaconfFile; if (rank == 0) { if(m_gaconffile != "default") gaconfFile.open(m_gaconffile.c_str(), ios::in); m_reorder = get_fiedler(orbitalfile); } //to provide as initial guess to gaopt m_reorder = getgaorder(gaconfFile, orbitalfile, m_reorder); pout << "Genetic algorithm orbital ordering: "; } else if (m_reorderType == MANUAL) { if (rank == 0) { ifstream reorderFile(m_reorderfile.c_str()); CheckFileExistence(m_reorderfile, "Reorder file "); readreorderfile(reorderFile, m_reorder); pout << "Manually provided orbital ordering: "; } } else { //this is the no-reorder case if (rank == 0) { m_reorder.resize(m_norbs/2); for (int i=0; i O_unreordered(2,3) (the former is stored internally and the latter is what is given during input) // but for this m_reorder the reorder vector below would be 3 1 2 4 and O_unreordered(1,2) -> O_reorder(3, 1) bool RHF = true; int AOrbOffset = 0, BOrbOffset = 0; if (rank == 0) { reorder.resize(m_norbs/2); for (int i=0; i= 0 ) ir = atoi(tok[i].c_str()) - offset; else if (atoi(tok[i].c_str()) < -1) ir = atoi(tok[i].c_str()) + offset; if (sym == "trans") ir += 1; //for translational symmetry the lowest irrep is 0 if (sym == "lzsym") ir = atoi(tok[i].c_str()); m_spin_orbs_symmetry[2*reorderOrbInd] = ir; m_spin_orbs_symmetry[2*reorderOrbInd+1] = ir; if (readLine == numRead) { m_num_spatial_orbs++; m_spatial_to_spin.push_back(orbindex); numRead = Symmetry::sizeofIrrep(ir); readLine = 0; } m_spin_to_spatial[orbindex] = m_num_spatial_orbs-1; m_spin_to_spatial[orbindex+1] = m_num_spatial_orbs-1; orbindex +=2; readLine++; } msg.resize(0); ReadMeaningfulLine(dumpFile, msg, msgsize); boost::split(tok, msg, is_any_of("=, \t"), token_compress_on); if(boost::iequals(tok[0], "IUHF")) RHF=false; } if(sym == "dinfh" ) { m_spatial_to_spin.clear(); for (int i=0; i(region.get_address()) + (oneIntegralMem+twoIntegralMem)*integralIndex; v2.set_data() = static_cast(region.get_address()) + oneIntegralMem + (oneIntegralMem+twoIntegralMem)*integralIndex; } else { long integralMemorySize = (oneIntegralMem+twoIntegralMem)*m_num_Integrals; m_IntegralMemoryStart = Stackmem[0].allocate(integralMemorySize); v1.set_data() = (m_IntegralMemoryStart) + (oneIntegralMem+twoIntegralMem)*integralIndex; v2.set_data() = (m_IntegralMemoryStart) + oneIntegralMem + (oneIntegralMem+twoIntegralMem)*integralIndex; } if (rank == 0) { msg.resize(0); ReadMeaningfulLine(dumpFile, msg, msgsize); //this if the first line with integrals int i, j, k, l; double value; while(msg.size() != 0) { boost::split(tok, msg, is_any_of(" \t"), token_compress_on); if (tok.size() != 5) { pout << "error in reading orbital file"<= m_integral_disk_storage_thresh) // { for (int i=0; i orb; for (int j=m_spatial_to_spin[i]; j tok; std::ofstream ReorderFileOutput; std::ifstream ReorderFileInput; char ReorderFileName[5000]; std::vector reorder; int offset = m_orbformat == DMRGFORM ? 0 : 1; int rank = 0; #ifndef SERIAL boost::mpi::communicator world; rank = world.rank(); #endif if (rank == 0) { ReadMeaningfulLine(dumpFile, msg, msgsize); boost::split(tok, msg, is_any_of("=, \t"), token_compress_on); if(offset != 0) m_norbs = 2*atoi(tok[2].c_str()); else m_norbs = 2*atoi(tok[1].c_str()); if (m_partialSweep == 0) m_partialSweep = m_norbs; m_num_spatial_orbs = 0; m_spin_orbs_symmetry.resize(m_norbs); m_spin_to_spatial.resize(m_norbs); sprintf(ReorderFileName, "%s%s", save_prefix().c_str(), "/RestartReorder.dat"); } boost::filesystem::path p(ReorderFileName); #ifndef SERIAL mpi::broadcast(world,m_norbs,0); mpi::broadcast(world,m_restart,0); mpi::broadcast(world,m_fullrestart,0); #endif //do the reordering only if it is not a restart calculation //if it is then just read the reorder.dat from the scratch space if (integralIndex == 0) { if(get_restart() || get_fullrestart() || m_calc_type == COMPRESS || m_calc_type == RESPONSE || m_calc_type == RESPONSEBW) { if (rank == 0) { ReorderFileInput.open(ReorderFileName); boost::filesystem::path ReorderFilePath(ReorderFileName); if(!boost::filesystem::exists(ReorderFilePath)) { pout << "==============="<> m_reorder[i]; ReorderFileInput.close(); } } } else { if (rank == 0) { ReorderFileOutput.open(ReorderFileName); } // read the reorder file or calculate the reordering using one of the many options if (m_reorderType == FIEDLER) { if (rank == 0) { m_reorder=get_fiedler_bcs(orbitalfile); pout << "Fiedler-vector orbital ordering: "; } } else if (m_reorderType == GAOPT) { ifstream gaconfFile; if (rank == 0) { if (m_gaconffile != "default") gaconfFile.open(m_gaconffile.c_str(), ios::in); m_reorder = get_fiedler_bcs(orbitalfile); } //to provide as initial guess to gaopt m_reorder = getgaorder_bcs(gaconfFile, orbitalfile, m_reorder); pout << "Genetic algorithm orbital ordering: "; } else if (m_reorderType == MANUAL) { if (rank == 0) { ifstream reorderFile(m_reorderfile.c_str()); CheckFileExistence(m_reorderfile, "Reorder file "); readreorderfile(reorderFile, m_reorder); pout << "Manually provided orbital ordering: "; } } else { //this is the no-reorder case if (rank == 0) { m_reorder.resize(m_norbs/2); for (int i=0; i O_unreordered(2,3) (the former is stored internally and the latter is what is given during input) // but for this m_reorder the reorder vector below would be 3 1 2 4 and O_unreordered(1,2) -> O_reorder(3, 1) if (rank == 0) { reorder.resize(m_norbs/2); for (int i=0; i= 0 ) ir = atoi(tok[i].c_str()) - offset; else if (atoi(tok[i].c_str()) < -1) ir = atoi(tok[i].c_str()) + offset; if (sym == "trans") ir += 1; //for translational symmetry the lowest irrep is 0 if (sym == "lzsym") ir = atoi(tok[i].c_str()); m_spin_orbs_symmetry[2*reorderOrbInd] = ir; m_spin_orbs_symmetry[2*reorderOrbInd+1] = ir; if (readLine == numRead) { m_num_spatial_orbs++; m_spatial_to_spin.push_back(orbindex); numRead = Symmetry::sizeofIrrep(ir); readLine = 0; } m_spin_to_spatial[orbindex] = m_num_spatial_orbs-1; m_spin_to_spatial[orbindex+1] = m_num_spatial_orbs-1; orbindex +=2; readLine++; } msg.resize(0); ReadMeaningfulLine(dumpFile, msg, msgsize); boost::split(tok, msg, is_any_of("=, \t"), token_compress_on); if(boost::iequals(tok[0], "IUHF")) RHF=false; } if(sym == "dinfh" ) { m_spatial_to_spin.clear(); for (int i=0; i(region.get_address()) + intdim*integralIndex; vcc.set_data() = static_cast(region.get_address()) + oneIntegralMem + intdim*integralIndex; v2.set_data() = static_cast(region.get_address()) + oneIntegralMem + vccIntegralMem + intdim*integralIndex; vcccc.set_data() = static_cast(region.get_address()) + oneIntegralMem + vccIntegralMem + twoIntegralMem + intdim*integralIndex; vcccd.set_data() = static_cast(region.get_address()) + oneIntegralMem + vccIntegralMem + twoIntegralMem + vccccIntegralMem + intdim*integralIndex; if (rank == 0) { int section = 0; msg.resize(0); ReadMeaningfulLine(dumpFile, msg, msgsize); //this if the first line with integrals int i, j, k, l; double value; while(msg.size() != 0) { boost::split(tok, msg, is_any_of(" \t"), token_compress_on); if (tok.size() != 5) { pout << "error in reading orbital file"<= m_integral_disk_storage_thresh) { for (int i=0; i orb; for (int j=m_spatial_to_spin[i]; j& vpt2, double& coreEnergy) { //TODO //Reorder is not supported. ifstream dumpFile; dumpFile.open(orbitalfile.c_str(), ios::in); string msg; int msgsize = 5000; vector tok; int offset = m_orbformat == DMRGFORM ? 0 : 1; std::ofstream ReorderFileOutput; std::ifstream ReorderFileInput; char ReorderFileName[5000]; std::vector reorder(m_total_orbs); if (mpigetrank() == 0) { ReadMeaningfulLine(dumpFile, msg, msgsize); boost::split(tok, msg, is_any_of("=, \t"), token_compress_on); m_norbs =m_act_size*2; m_num_spatial_orbs = m_act_size; m_spin_orbs_symmetry.resize(m_total_orbs*2); m_spin_to_spatial.resize(m_total_orbs*2); m_total_spin_orbs_symmetry.resize(m_total_orbs*2); m_total_spin_to_spatial.resize(m_total_orbs*2); //this is the file to which the reordering is written sprintf(ReorderFileName, "%s%s", save_prefix().c_str(), "/RestartReorder.dat"); } #ifndef SERIAL boost::mpi::communicator world; mpi::broadcast(world,m_restart,0); mpi::broadcast(world,m_fullrestart,0); #endif //do the reordering only if it is not a restart calculation //if it is then just read the reorder.dat from the scratch space if(get_restart() || get_fullrestart()) { if (mpigetrank() == 0) { ReorderFileInput.open(ReorderFileName); boost::filesystem::path ReorderFilePath(ReorderFileName); if(!boost::filesystem::exists(ReorderFilePath)) { pout << "==============="<> m_reorder[i]; ReorderFileInput.close(); } } } else { if (mpigetrank() == 0) { ReorderFileOutput.open(ReorderFileName); } // read the reorder file or calculate the reordering using one of the many options if (m_reorderType == FIEDLER) { if (mpigetrank() == 0){ m_reorder=get_fiedler_nevpt(orbitalfile, m_act_size); pout << "Fiedler-vector orbital ordering: "; } } else if (m_reorderType == MANUAL) { if (mpigetrank() == 0) { ifstream reorderFile(m_reorderfile.c_str()); CheckFileExistence(m_reorderfile, "Reorder file "); readreorderfile(reorderFile, m_reorder); pout << "Manually provided orbital ordering: "; } } else { //this is the no-reorder case if (mpigetrank() == 0) { m_reorder.resize(m_act_size); for (int i=0; i O_unreordered(2,3) (the former is stored internally and the latter is what is given during input) // but for this m_reorder the reorder vector below would be 3 1 2 4 and O_unreordered(1,2) -> O_reorder(3, 1) bool RHF = true; if (mpigetrank() == 0) { reorder.resize(m_total_orbs); for (int i=0; i= 0 ) ir = atoi(tok[i].c_str()) - offset; else if (atoi(tok[i].c_str()) < -1) ir = atoi(tok[i].c_str()) + offset; if (sym == "trans") ir += 1; //for translational symmetry the lowest irrep is 0 if (sym == "lzsym") ir = atoi(tok[i].c_str()); m_total_spin_orbs_symmetry[2*reorderOrbInd] = ir; m_total_spin_orbs_symmetry[2*reorderOrbInd+1] = ir; if (readLine == numRead) { m_total_spatial_to_spin.push_back(orbindex); numRead = Symmetry::sizeofIrrep(ir); readLine = 0; } m_total_spin_to_spatial[orbindex] = orbindex/2; m_total_spin_to_spatial[orbindex+1] = orbindex/2; orbindex +=2; readLine++; } msg.resize(0); ReadMeaningfulLine(dumpFile, msg, msgsize); boost::split(tok, msg, is_any_of("=, \t"), token_compress_on); if(boost::iequals(tok[0], "IUHF")) RHF=false; } if(sym == "dinfh" ) { m_total_spatial_to_spin.clear(); for (int i=0; i(m_total_spin_to_spatial.begin(),m_total_spin_to_spatial.begin()+m_act_size*2); // m_spatial_to_spin=std::vector(m_total_spatial_to_spin.begin(),m_total_spatial_to_spin.begin()+m_act_size); // m_spin_orbs_symmetry=std::vector(m_total_spin_orbs_symmetry.begin(),m_total_spin_orbs_symmetry.begin()+m_act_size*2); // // m_spatial_to_spin.push_back(m_act_size*2); // m_spin_to_spatial.push_back(m_act_size*2); m_spin_to_spatial=m_total_spin_to_spatial; m_spatial_to_spin=m_total_spatial_to_spin; m_spin_orbs_symmetry=m_total_spin_orbs_symmetry; while (!((boost::iequals(tok[0], "&END")) || (boost::iequals(tok[0], "/")))) { int temp; msg.resize(0); ReadMeaningfulLine(dumpFile, msg, msgsize); boost::split(tok, msg, is_any_of("=, \t"), token_compress_on); if(boost::iequals(tok[0], "IUHF")) RHF=false; } int AOrbOffset = 0, BOrbOffset = 0; if(!RHF) { v1.rhf = false; v2.rhf = false; //for(auto i: vpt1) // i.second.rhf = false; vpt1.rhf = false; // for(auto i: vpt2) // i.second.rhf = false; // fock.rhf = false; } else{ v1.rhf = true; v2.rhf = true; vpt1.rhf = true; } v1.ReSize(m_total_orbs*2); v2.ReSize(m_act_size*2); vpt1.ReSize(m_total_orbs*2); //for(auto i: vpt1) // i.second.ReSize(m_total_orbs*2); vpt2[Va].ReSize(m_total_orbs*2,m_act_size*2,m_act_size*2,m_act_size*2); vpt2[Vi].ReSize(m_act_size*2,m_act_size*2,m_total_orbs*2,m_act_size*2); } // for(auto& i: vpt2) // i.second.ReSize(m_total_orbs*2,m_total_orbs*2,m_total_orbs*2,m_total_orbs*2); //fock.ReSize(m_total_orbs*2); #ifndef SERIAL mpi::broadcast(world,RHF,0); mpi::broadcast(world,v1,0); mpi::broadcast(world,v2,0); mpi::broadcast(world,vpt1,0); mpi::broadcast(world,vpt2,0); #endif long oneIntegralMem, twoIntegralMem, PerturboneIntegralMem; long twoedim = v2.matDim; if (RHF) { oneIntegralMem = (m_total_orbs*(m_total_orbs+1))/2; twoIntegralMem = twoedim*(twoedim+1)/2; PerturboneIntegralMem = (m_total_orbs*(m_total_orbs+1))/2; } else { oneIntegralMem = m_total_orbs*(m_total_orbs+1); twoIntegralMem = twoedim*(twoedim+1)/2; PerturboneIntegralMem = m_total_orbs*(m_total_orbs+1); } #ifndef SERIAL mpi::broadcast(world,oneIntegralMem,0); mpi::broadcast(world,twoIntegralMem,0); mpi::broadcast(world,PerturboneIntegralMem,0); #endif #ifndef SERIAL segment.truncate((oneIntegralMem+twoIntegralMem+PerturboneIntegralMem)*m_num_Integrals*sizeof(double)); region = boost::interprocess::mapped_region{segment, boost::interprocess::read_write}; memset(region.get_address(), 0., (oneIntegralMem+twoIntegralMem+PerturboneIntegralMem)*m_num_Integrals*sizeof(double)); //wait for all procs to zero out the memory MPI::COMM_WORLD.Barrier(); v1.set_data() = static_cast(region.get_address()); v2.set_data() = static_cast(region.get_address()) + oneIntegralMem; vpt1.set_data() = static_cast(region.get_address()) + oneIntegralMem + twoIntegralMem; #else //TODO //For MPS-SC-NEVPT, different MPS perturbers are calculated independently, through calling block through mpi. Block is serial by itself. v1.set_data() = new double[(oneIntegralMem+twoIntegralMem+PerturboneIntegralMem)*m_num_Integrals]; v2.set_data() = v1.set_data() + oneIntegralMem; vpt1.set_data() = v1.set_data() + oneIntegralMem + twoIntegralMem; #endif if (mpigetrank() == 0) { msg.resize(0); ReadMeaningfulLine(dumpFile, msg, msgsize); //this if the first line with integrals if(m_total_orbs >= m_integral_disk_storage_thresh) // { assert(false && "Partial integral file for mps_nevpt2 is not implemented."); } int i, j, k, l; double value; //Read zero order integral in active space; while(msg.size() != 0) { boost::split(tok, msg, is_any_of(" \t"), token_compress_on); if (tok.size() != 5) { pout << "error in reading orbital file"<(type)](2*I,2*K,2*J,2*L) = value; } msg.resize(0); ReadMeaningfulLine(dumpFile, msg, msgsize); //this if the first line with integrals } } for(int type=0; type< 3 ; type++){ msg.resize(0); ReadMeaningfulLine(dumpFile, msg, msgsize); //this if the first line with integrals while(msg.size() != 0) { boost::split(tok, msg, is_any_of(" \t"), token_compress_on); if (tok.size() != 5) { pout << "error in reading orbital file"< SpinAdapted::Input::get_fiedler(string& dumpname){ Matrix fiedler; ifstream dumpFile; dumpFile.open(dumpname.c_str(), ios::in); genetic::ReadIntegral(dumpFile, fiedler); dumpFile.close(); SymmetricMatrix fiedler_sym; fiedler_sym << fiedler; std::vector findices = fiedler_reorder(fiedler_sym); return findices; } std::vector SpinAdapted::Input::get_fiedler_nevpt(string& dumpname, int nact){ Matrix fiedler; ifstream dumpFile; dumpFile.open(dumpname.c_str(), ios::in); genetic::ReadIntegral_nevpt(dumpFile, fiedler, nact); dumpFile.close(); SymmetricMatrix fiedler_sym; fiedler_sym << fiedler; std::vector findices = fiedler_reorder(fiedler_sym); return findices; } std::vector SpinAdapted::Input::get_fiedler_bcs(string& dumpname) { Matrix fiedler; ifstream dumpFile; dumpFile.open(dumpname.c_str(), ios::in); genetic::ReadIntegral_BCS(dumpFile, fiedler); dumpFile.close(); SymmetricMatrix fiedler_sym; fiedler_sym << fiedler; std::vector findices = fiedler_reorder(fiedler_sym); return findices; } std::vector SpinAdapted::Input::getgaorder(ifstream& gaconfFile, string& orbitalfile, std::vector& fiedlerorder) { ifstream dumpFile; dumpFile.open(orbitalfile.c_str()); return genetic::gaordering(gaconfFile, dumpFile, fiedlerorder).Gen().Sequence(); } std::vector SpinAdapted::Input::getgaorder_bcs(ifstream& gaconfFile, string& orbitalfile, std::vector& fiedlerorder) { ifstream dumpFile; dumpFile.open(orbitalfile.c_str()); return genetic::gaordering_bcs(gaconfFile, dumpFile, fiedlerorder).Gen().Sequence(); } #ifdef MOLPRO void SpinAdapted::Input::writeSummaryForMolpro() { pout << setw(50) << "Total number of orbitals : " ; pout << m_norbs/2 << endl; pout << setw(50) << "Symmetry of targeted wavefunctions : " ; pout << m_alpha + m_beta << ":" << m_alpha-m_beta << ":" << m_total_symmetry_number.getirrep()+1 << endl; pout << setw(50) << "Number of wavefunctions targeted : " ; pout << m_nroots << endl; if (m_nroots >1) { pout << setw(50) << "The weights of the wavefunctions : "; for (int i=0; i1) { // printf("%-50s : ", "The weights of the wavefunctions"); // for (int i=0; i 1) { pout << setw(50) << left << "The weights of the wavefunctions" << " : "; for (int i = 0; i < m_nroots; ++i) pout << left << setprecision(2) << setw(10) << scientific << m_weights[i]; pout << endl; } pout << setw(50) << left << "Symmetry of the molecule" << " : " << sym.c_str() << endl; if (sym != "c1") { pout << setw(50) << left << "Irreducible representations of the orbitals" << " : "; for (int i = 0; i < m_spin_orbs_symmetry.size(); i+=2) { pout << Symmetry::stringOfIrrep(m_spin_orbs_symmetry[i]) << " "; } pout << endl; } pout << endl << "Schedule" << endl; pout << "--------" << endl; pout << setw(10) << left << "Iter" << " : " << setw(20) << left << "# States" << " " << setw(20) << left << "Davidson_tol" << " " << setw(20) << left << "Random_noise" << endl; for (int i = 0; i < m_sweep_iter_schedule.size(); ++i) { pout << setw(10) << left << m_sweep_iter_schedule[i] << " : " << setw(20) << left << m_sweep_state_schedule[i] << " " << setw(20) << left << scientific << m_sweep_tol_schedule[i] << " " << setw(20) << left << scientific << m_sweep_noise_schedule[i] << endl; } if (m_algorithm_type == TWODOT_TO_ONEDOT) { pout << setw(50) << left << "Switching from twodot to onedot algorithm" << " : " << m_twodot_to_onedot_iter << endl; } pout << setw(50) << left << "Maximum sweep iterations" << " : " << m_maxiter << endl; #ifndef SERIAL } #endif } void SpinAdapted::Input::performSanityTest() { #ifndef SERIAL boost::mpi::communicator world; int rank = world.rank(); if (rank == 0) { #endif if (m_norbs <= 0) { pout << "total number of orbitals has to be a positive number"< 200) { pout << "Number of orbitals cannot be greater than 130"< 10000) { pout << "default schedule only works for maxM less than 10000"< m_startM) { pout << "lastM is larger than startM" << endl; pout << "Make sure you specify a lastM larger than " << lastM << endl; pout << "or specify a larger startM " << endl; abort(); } } else { // This needs to go at the end of sanity check, or move up schedule if (m_maxM != 0) { pout << "With detailed schedule a non-zero maxM should not be specified"<= m_maxiter) { pout << "Switch from twodot to onedot algorithm cannot happen after maxiter"< openCopy, closedCopy, reorder; openCopy.resize(m_openorbs.size(), -1); closedCopy.resize(m_closedorbs.size(), -1); for (int i=0; i hf_occupancy_tmp(m_norbs,0); if (m_Bogoliubov) { // overwrite hf_occ_user option, since initial guess is always vacuum in BCS case m_hf_occupancy.assign(m_norbs, 0); } else if (m_hf_occ_user == "manual") { //check if n_orbs is correct and if n_elec is correct if (m_hf_occupancy.size() != m_norbs/2 ) { pout << "ERROR: The length of user-defined HF occupancies does not match the number of orbitals " << endl; pout << "Length of occupancies is: " << m_hf_occupancy.size() << ", and the number of orbitals is: " << m_norbs/2 << endl; abort(); } int UserElectrons = 0; for (int i=0; i ele_map; // for( int i = 0; i < m_norbs/2; ++i ){ // ele_map.insert( pair( v_1[0](2*i, 2*i), i ) ); // } // multimap :: iterator it_alpha = ele_map.begin(); // for( int i = 0; i < m_alpha; ++i ){ // int ia = it_alpha->second; // hf_occupancy_tmp.at( 2*ia ) = 1; // if (i < m_beta) // hf_occupancy_tmp.at( 2*ia+1 ) = 1; // ++it_alpha; // } hf_occupancy_tmp = this->hfOccGenerator_(); } else { pout << "currently other options besides manual, integral and canonical are not implemented."< reorder(m_norbs/2); for (int i=0; i= dmrginp.sweep_iter_schedule()[iter]) current = iter; } int nroots = m_nroots; if (m_noise_type == EXCITEDSTATE && m_sweep_additional_noise_schedule[current] != 0.0 && nroots == 1) nroots++; if (setStateSpecific()) return 1; return nroots; } std::vector SpinAdapted::Input::weights(int sweep_iter) const { int iter; int current = 0; for (iter = 0; iter < dmrginp.sweep_iter_schedule().size(); ++iter) { if (sweep_iter >= dmrginp.sweep_iter_schedule()[iter]) current = iter; } if (setStateSpecific()) return std::vector(1,1.0); int nroots = this->nroots(sweep_iter); std::vector weights(nroots); for (int i=0; i< m_nroots; i++) weights[i] = m_weights[i]; if (nroots == m_nroots+1) weights[nroots-1] = m_sweep_additional_noise_schedule[current]; if (nroots != m_nroots+1 && nroots != m_nroots) { pout << "Something wrong with the number of weights of wavefunctions!"<& sites = b.get_sites(); int n=0, s=0; for (int i=0; i