void SpinAdapted::InitBlocks::InitNewSystemBlock(SpinBlock &system, SpinBlock &systemDot, SpinBlock &newSystem, int leftState, int rightState, const int& sys_add, const bool &direct, int integralIndex, const Storagetype &storage, bool haveNormops, bool haveCompops, int constraint) { newSystem.set_integralIndex() = integralIndex; newSystem.default_op_components(direct, system, systemDot, haveNormops, haveCompops, leftState==rightState); newSystem.setstoragetype(storage); newSystem.BuildSumBlock (constraint, system, systemDot); p2out << "\t\t\t NewSystem block " << endl << newSystem << endl; newSystem.printOperatorSummary(); }
void SpinAdapted::InitBlocks::InitNewSystemBlock(SpinBlock &system, SpinBlock &systemDot, SpinBlock &newSystem, int leftState, int rightState, const int& sys_add, const bool &direct, int integralIndex, const Storagetype &storage, bool haveNormops, bool haveCompops, int constraint, const std::vector<SpinQuantum>& braquanta, const std::vector<SpinQuantum>& ketquanta) { newSystem.set_integralIndex() = integralIndex; newSystem.default_op_components(direct, system, systemDot, haveNormops, haveCompops, leftState==rightState); newSystem.setstoragetype(storage); newSystem.BuildSumBlock (constraint, system, systemDot,braquanta,ketquanta); if (dmrginp.outputlevel() > 0) { pout << "\t\t\t NewSystem block " << endl << newSystem << endl; newSystem.printOperatorSummary(); } }
void SpinAdapted::InitBlocks::InitBigBlock(SpinBlock &leftBlock, SpinBlock &rightBlock, SpinBlock &big, const std::vector<SpinQuantum>& braquanta, const std::vector<SpinQuantum>& ketquanta) { //set big block components big.set_integralIndex() = leftBlock.get_integralIndex(); big.nonactive_orb() = leftBlock.nonactive_orb(); big.set_big_components(); // build the big block if (dmrginp.hamiltonian() == BCS) { if(braquanta.size()!=0) big.BuildSumBlock(SPIN_NUMBER_CONSTRAINT, leftBlock, rightBlock,braquanta,ketquanta); else big.BuildSumBlock(SPIN_NUMBER_CONSTRAINT, leftBlock, rightBlock); } else { if(braquanta.size()!=0) big.BuildSumBlock(PARTICLE_SPIN_NUMBER_CONSTRAINT, leftBlock, rightBlock,braquanta,ketquanta); else big.BuildSumBlock(PARTICLE_SPIN_NUMBER_CONSTRAINT, leftBlock, rightBlock); } }
//before you start optimizing each state you want to initalize all the overlap matrices void Sweep::InitializeOverlapSpinBlocks(SweepParams &sweepParams, const bool &forward, int stateA, int stateB) { SpinBlock system; sweepParams.set_sweep_parameters(); if (forward) pout << "\t\t\t Starting sweep "<< sweepParams.set_sweep_iter()<<" in forwards direction"<<endl; else pout << "\t\t\t Starting sweep "<< sweepParams.set_sweep_iter()<<" in backwards direction" << endl; pout << "\t\t\t ============================================================================ " << endl; int restartSize = 0; bool restart = false, warmUp = false; InitBlocks::InitStartingBlock (system,forward, stateA, stateB, sweepParams.get_forward_starting_size(), sweepParams.get_backward_starting_size(), restartSize, restart, warmUp); sweepParams.set_block_iter() = 0; if (dmrginp.outputlevel() > 0) pout << "\t\t\t Starting block is :: " << endl << system << endl; SpinBlock::store (forward, system.get_sites(), system, stateA, stateB); // if restart, just restoring an existing block -- sweepParams.savestate(forward, system.get_sites().size()); bool dot_with_sys = true; vector<int> syssites = system.get_sites(); if (dmrginp.outputlevel() > 0) mcheck("at the very start of sweep"); // just timer for (; sweepParams.get_block_iter() < sweepParams.get_n_iters(); ) // get_n_iters() returns the number of blocking iterations needed in one sweep { pout << "\t\t\t Block Iteration :: " << sweepParams.get_block_iter() << endl; pout << "\t\t\t ----------------------------" << endl; if (dmrginp.outputlevel() > 0) { if (forward) pout << "\t\t\t Current direction is :: Forwards " << endl; else pout << "\t\t\t Current direction is :: Backwards " << endl; } SpinBlock systemDot, environmentDot; int systemDotStart, systemDotEnd; int systemDotSize = sweepParams.get_sys_add() - 1; if (forward) { systemDotStart = dmrginp.spinAdapted() ? *system.get_sites().rbegin () + 1 : (*system.get_sites().rbegin ())/2 + 1 ; systemDotEnd = systemDotStart + systemDotSize; } else { systemDotStart = dmrginp.spinAdapted() ? system.get_sites()[0] - 1 : (system.get_sites()[0])/2 - 1 ; systemDotEnd = systemDotStart - systemDotSize; } systemDot = SpinBlock(systemDotStart, systemDotEnd, true); SpinBlock newSystem; // new system after blocking and decimating newSystem.initialise_op_array(OVERLAP, false); newSystem.setstoragetype(DISTRIBUTED_STORAGE); newSystem.BuildSumBlock (NO_PARTICLE_SPIN_NUMBER_CONSTRAINT, system, systemDot); std::vector<Matrix> brarotateMatrix, ketrotateMatrix; LoadRotationMatrix(newSystem.get_sites(), brarotateMatrix, stateA); LoadRotationMatrix(newSystem.get_sites(), ketrotateMatrix, stateB); newSystem.transform_operators(brarotateMatrix, ketrotateMatrix); system = newSystem; if (dmrginp.outputlevel() > 0){ pout << system<<endl; } SpinBlock::store (forward, system.get_sites(), system, stateA, stateB); ++sweepParams.set_block_iter(); sweepParams.savestate(forward, syssites.size()); if (dmrginp.outputlevel() > 0) mcheck("at the end of sweep iteration"); } pout << "\t\t\t ============================================================================ " << endl; // update the static number of iterations return ; }
void SpinAdapted::InitBlocks::InitNewOverlapEnvironmentBlock(SpinBlock &environment, SpinBlock& environmentDot, SpinBlock &newEnvironment, const SpinBlock &system, SpinBlock &systemDot, int leftState, int rightState, const int &sys_add, const int &env_add, const bool &forward, int integralIndex, const bool &onedot, const bool& dot_with_sys, int constraint) { // now initialise environment Dot int systemDotStart, systemDotEnd, environmentDotStart, environmentDotEnd, environmentStart, environmentEnd; int systemDotSize = sys_add - 1; int environmentDotSize = env_add - 1; if (forward) { systemDotStart = dmrginp.spinAdapted() ? *system.get_sites().rbegin () + 1 : (*system.get_sites().rbegin ())/2 + 1 ; systemDotEnd = systemDotStart + systemDotSize; environmentDotStart = systemDotEnd + 1; environmentDotEnd = environmentDotStart + environmentDotSize; environmentStart = environmentDotEnd + 1; environmentEnd = dmrginp.spinAdapted() ? dmrginp.last_site() - 1 : dmrginp.last_site()/2 - 1; } else { systemDotStart = dmrginp.spinAdapted() ? system.get_sites()[0] - 1 : (system.get_sites()[0])/2 - 1 ; systemDotEnd = systemDotStart - systemDotSize; environmentDotStart = systemDotEnd - 1; environmentDotEnd = environmentDotStart - environmentDotSize; environmentStart = environmentDotEnd - 1; environmentEnd = 0; } std::vector<int> environmentSites; environmentSites.resize(abs(environmentEnd - environmentStart) + 1); for (int i = 0; i < abs(environmentEnd - environmentStart) + 1; ++i) *(environmentSites.begin () + i) = min(environmentStart,environmentEnd) + i; p2out << "\t\t\t Restoring block of size " << environmentSites.size () << " from previous iteration" << endl; if(dot_with_sys && onedot) { newEnvironment.set_integralIndex() = integralIndex; SpinBlock::restore (!forward, environmentSites, newEnvironment, leftState, rightState); } else { environment.set_integralIndex() = integralIndex; SpinBlock::restore (!forward, environmentSites, environment, leftState, rightState); } if (dmrginp.outputlevel() > 0) mcheck(""); // now initialise newEnvironment if (!dot_with_sys || !onedot) { newEnvironment.set_integralIndex() = integralIndex; newEnvironment.initialise_op_array(OVERLAP, false); //newEnvironment.set_op_array(OVERLAP) = boost::shared_ptr<Op_component<Overlap> >(new Op_component<Overlap>(false)); newEnvironment.setstoragetype(DISTRIBUTED_STORAGE); newEnvironment.BuildSumBlock (constraint, environment, environmentDot); p2out << "\t\t\t Environment block " << endl << environment << endl; environment.printOperatorSummary(); p2out << "\t\t\t NewEnvironment block " << endl << newEnvironment << endl; newEnvironment.printOperatorSummary(); } else { p2out << "\t\t\t Environment block " << endl << newEnvironment << endl; newEnvironment.printOperatorSummary(); } }
void SpinAdapted::InitBlocks::InitNewEnvironmentBlock(SpinBlock &environment, SpinBlock& environmentDot, SpinBlock &newEnvironment, const SpinBlock &system, SpinBlock &systemDot, int leftState, int rightState, const int &sys_add, const int &env_add, const bool &forward, const bool &direct, const bool &onedot, const bool &nexact, const bool &useSlater, int integralIndex, bool haveNormops, bool haveCompops, const bool& dot_with_sys, int constraint, const std::vector<SpinQuantum>& braquanta, const std::vector<SpinQuantum>& ketquanta) { // now initialise environment Dot int systemDotStart, systemDotEnd, environmentDotStart, environmentDotEnd, environmentStart, environmentEnd; int systemDotSize = sys_add - 1; int environmentDotSize = env_add - 1; if (forward) { systemDotStart = dmrginp.spinAdapted() ? *system.get_sites().rbegin () + 1 : (*system.get_sites().rbegin ())/2 + 1 ; systemDotEnd = systemDotStart + systemDotSize; environmentDotStart = systemDotEnd + 1; environmentDotEnd = environmentDotStart + environmentDotSize; environmentStart = environmentDotEnd + 1; environmentEnd = dmrginp.spinAdapted() ? dmrginp.last_site() - 1 : dmrginp.last_site()/2 - 1; } else { systemDotStart = dmrginp.spinAdapted() ? system.get_sites()[0] - 1 : (system.get_sites()[0])/2 - 1 ; systemDotEnd = systemDotStart - systemDotSize; environmentDotStart = systemDotEnd - 1; environmentDotEnd = environmentDotStart - environmentDotSize; environmentStart = environmentDotEnd - 1; environmentEnd = 0; } std::vector<int> environmentSites; environmentSites.resize(abs(environmentEnd - environmentStart) + 1); for (int i = 0; i < abs(environmentEnd - environmentStart) + 1; ++i) *(environmentSites.begin () + i) = min(environmentStart,environmentEnd) + i; // now initialise environment if (useSlater) { // for FCI StateInfo system_stateinfo = system.get_stateInfo(); StateInfo sysdot_stateinfo = systemDot.get_stateInfo(); StateInfo tmp; TensorProduct (system_stateinfo, sysdot_stateinfo, tmp, NO_PARTICLE_SPIN_NUMBER_CONSTRAINT); // tmp has the system+dot quantum numbers tmp.CollectQuanta (); // exact environment if (dmrginp.do_fci() || environmentSites.size() == nexact) { if ((!dot_with_sys && onedot) || !onedot) { // environment has dot environment.set_integralIndex() = integralIndex; environment.default_op_components(!forward, leftState==rightState); environment.setstoragetype(DISTRIBUTED_STORAGE); environment.BuildTensorProductBlock(environmentSites); // exact block SpinBlock::store (true, environmentSites, environment, leftState, rightState); } else { // environment has no dot, so newEnv = Env newEnvironment.set_integralIndex() = integralIndex; newEnvironment.default_op_components(!forward, leftState==rightState); newEnvironment.setstoragetype(DISTRIBUTED_STORAGE); newEnvironment.BuildTensorProductBlock(environmentSites); SpinBlock::store (true, environmentSites, newEnvironment, leftState, rightState); } } else if (dmrginp.warmup() == LOCAL2 || dmrginp.warmup() == LOCAL3 || dmrginp.warmup() == LOCAL4) { int nactiveSites, ncoreSites; if (dmrginp.warmup() == LOCAL2) { nactiveSites = 1; } else if (dmrginp.warmup() == LOCAL3) { nactiveSites = 2; } else if (dmrginp.warmup() == LOCAL4) { nactiveSites = 3; } if (dot_with_sys && onedot) { nactiveSites += 1; } if (nactiveSites > environmentSites.size()) { nactiveSites = environmentSites.size(); } ncoreSites = environmentSites.size() - nactiveSites; // figure out what sites are in the active and core sites int environmentActiveEnd = forward ? environmentStart + nactiveSites - 1 : environmentStart - nactiveSites + 1; int environmentCoreStart = forward ? environmentActiveEnd + 1 : environmentActiveEnd - 1; std::vector<int> activeSites(nactiveSites), coreSites(ncoreSites); for (int i = 0; i < nactiveSites; ++i) { activeSites[i] = min(environmentStart,environmentActiveEnd) + i; } for (int i = 0; i < ncoreSites; ++i) { coreSites[i] = min(environmentCoreStart,environmentEnd) + i; } SpinBlock environmentActive, environmentCore; environmentActive.nonactive_orb() = system.nonactive_orb(); environmentCore.nonactive_orb() = system.nonactive_orb(); if (coreSites.size() > 0) { environmentActive.set_integralIndex() = integralIndex; environmentCore.set_integralIndex() = integralIndex; environmentActive.default_op_components(!forward, leftState==rightState); environmentActive.setstoragetype(DISTRIBUTED_STORAGE); environmentCore.default_op_components(!forward, leftState==rightState); environmentCore.setstoragetype(DISTRIBUTED_STORAGE); environmentActive.BuildTensorProductBlock(activeSites); environmentCore.BuildSingleSlaterBlock(coreSites); dmrginp.datatransfer -> start(); environmentCore.addAdditionalCompOps(); environmentActive.addAdditionalCompOps(); dmrginp.datatransfer -> stop(); if ((!dot_with_sys && onedot) || !onedot) { environment.set_integralIndex() = integralIndex; environment.default_op_components(!forward, leftState == rightState); environment.setstoragetype(DISTRIBUTED_STORAGE); environment.BuildSumBlock(constraint, environmentCore, environmentActive,braquanta,ketquanta); } else { newEnvironment.set_integralIndex() = integralIndex; newEnvironment.default_op_components(direct, environmentCore, environmentActive, haveNormops, haveCompops, leftState == rightState); newEnvironment.setstoragetype(DISTRIBUTED_STORAGE); newEnvironment.BuildSumBlock(constraint, environmentCore, environmentActive,braquanta,ketquanta); if (dmrginp.outputlevel() > 0) { pout << "\t\t\t NewEnvironment block " << endl << newEnvironment << endl; newEnvironment.printOperatorSummary(); } } } else { // no core if ((!dot_with_sys && onedot) || !onedot) { environment.set_integralIndex() = integralIndex; environment.default_op_components(!forward, leftState==rightState); environment.setstoragetype(DISTRIBUTED_STORAGE); environment.BuildTensorProductBlock(environmentSites); // exact block } else { newEnvironment.set_integralIndex() = integralIndex; newEnvironment.default_op_components(!forward, leftState==rightState); newEnvironment.setstoragetype(DISTRIBUTED_STORAGE); newEnvironment.BuildTensorProductBlock(environmentSites); } } } else { //used for warmup guess environemnt std::vector<SpinQuantum> quantumNumbers; std::vector<int> distribution; std::map<SpinQuantum, int> quantaDist; std::map<SpinQuantum, int>::iterator quantaIterator; bool environmentComplementary = !forward; StateInfo tmp2; // tmp is the quantum numbers of newSystem (sys + sysdot) if (onedot) tmp.quanta_distribution (quantumNumbers, distribution, true); else { StateInfo environmentdot_stateinfo = environmentDot.get_stateInfo(); TensorProduct (tmp, environmentdot_stateinfo, tmp2, constraint); tmp2.CollectQuanta (); tmp2.quanta_distribution (quantumNumbers, distribution, true); } for (int i = 0; i < distribution.size (); ++i) { quantaIterator = quantaDist.find(quantumNumbers[i]); if (quantaIterator != quantaDist.end()) distribution[i] += quantaIterator->second; distribution [i] /= 4; distribution [i] += 1; if (distribution [i] > dmrginp.nquanta()) distribution [i] = dmrginp.nquanta(); if(quantaIterator != quantaDist.end()) { quantaIterator->second = distribution[i]; } else { quantaDist[quantumNumbers[i]] = distribution[i]; } } if (dmrginp.outputlevel() > 0) pout << "\t\t\t Quantum numbers and states used for warm up :: " << endl << "\t\t\t "; quantumNumbers.clear(); quantumNumbers.reserve(distribution.size()); distribution.clear();distribution.reserve(quantumNumbers.size()); std::map<SpinQuantum, int>::iterator qit = quantaDist.begin(); for (; qit != quantaDist.end(); qit++) { quantumNumbers.push_back( qit->first); distribution.push_back(qit->second); if (dmrginp.outputlevel() > 0) { pout << quantumNumbers.back() << " = " << distribution.back() << ", "; if (! (quantumNumbers.size() - 6) % 6) pout << endl << "\t\t\t "; } } pout << endl; if(dot_with_sys && onedot) { newEnvironment.set_integralIndex() = integralIndex; newEnvironment.BuildSlaterBlock (environmentSites, quantumNumbers, distribution, false, false); } else { environment.set_integralIndex() = integralIndex; environment.BuildSlaterBlock (environmentSites, quantumNumbers, distribution, false, haveNormops); } } } else { if (dmrginp.outputlevel() > 0) pout << "\t\t\t Restoring block of size " << environmentSites.size () << " from previous iteration" << endl; if(dot_with_sys && onedot) { newEnvironment.set_integralIndex() = integralIndex; SpinBlock::restore (!forward, environmentSites, newEnvironment, leftState, rightState); } else { environment.set_integralIndex() = integralIndex; SpinBlock::restore (!forward, environmentSites, environment, leftState, rightState); } if (dmrginp.outputlevel() > 0) mcheck(""); } // now initialise newEnvironment if (!dot_with_sys || !onedot) { dmrginp.datatransfer -> start(); environment.addAdditionalCompOps(); dmrginp.datatransfer -> stop(); newEnvironment.set_integralIndex() = integralIndex; newEnvironment.default_op_components(direct, environment, environmentDot, haveNormops, haveCompops, leftState==rightState); newEnvironment.setstoragetype(DISTRIBUTED_STORAGE); newEnvironment.BuildSumBlock (constraint, environment, environmentDot,braquanta,ketquanta); if (dmrginp.outputlevel() > -1) { pout << "\t\t\t Environment block " << endl << environment << endl; environment.printOperatorSummary(); pout << "\t\t\t NewEnvironment block " << endl << newEnvironment << endl; newEnvironment.printOperatorSummary(); } } else if (dmrginp.outputlevel() > 0) { pout << "\t\t\t Environment block " << endl << newEnvironment << endl; newEnvironment.printOperatorSummary(); } }
void SpinAdapted::InitBlocks::InitStartingBlock (SpinBlock& startingBlock, const bool &forward, int leftState, int rightState, const int & forward_starting_size, const int &backward_starting_size, const int& restartSize, const bool &restart, const bool& warmUp, int integralIndex, const vector<SpinQuantum>& braquanta, const vector<SpinQuantum>& ketquanta) { if (restart && restartSize != 1) { int len = restart? restartSize : forward_starting_size; vector<int> sites(len); if (forward) for (int i=0; i<len; i++) sites[i] = i; else for (int i=0; i<len; i++) sites[i] = dmrginp.last_site() - len +i ; if (restart) SpinBlock::restore (forward, sites, startingBlock, leftState, rightState); else SpinBlock::restore (true, sites, startingBlock, leftState, rightState); } else if (forward) { if(startingBlock.nonactive_orb().size()!=0) startingBlock = SpinBlock(0, forward_starting_size - 1,startingBlock.nonactive_orb() , true); else startingBlock = SpinBlock(0, forward_starting_size - 1, integralIndex, leftState==rightState, true); if (dmrginp.add_noninteracting_orbs() && dmrginp.molecule_quantum().get_s().getirrep() != 0 && dmrginp.spinAdapted()) { SpinQuantum s = dmrginp.molecule_quantum(); s = SpinQuantum(s.get_s().getirrep(), s.get_s(), IrrepSpace(0)); int qs = 1, ns = 1; StateInfo addstate(ns, &s, &qs); SpinBlock dummyblock(addstate, integralIndex); SpinBlock newstartingBlock; newstartingBlock.set_integralIndex() = integralIndex; newstartingBlock.default_op_components(false, startingBlock, dummyblock, true, true, leftState==rightState); newstartingBlock.setstoragetype(LOCAL_STORAGE); if( braquanta.size()!= 0) newstartingBlock.BuildSumBlock(NO_PARTICLE_SPIN_NUMBER_CONSTRAINT, startingBlock, dummyblock,braquanta,ketquanta); else newstartingBlock.BuildSumBlock(NO_PARTICLE_SPIN_NUMBER_CONSTRAINT, startingBlock, dummyblock); startingBlock.clear(); startingBlock = newstartingBlock; } } else { std::vector<int> backwardSites; if(dmrginp.spinAdapted()) { for (int i = 0; i < backward_starting_size; ++i) backwardSites.push_back (dmrginp.last_site() - i - 1); } else { for (int i = 0; i < backward_starting_size; ++i) backwardSites.push_back (dmrginp.last_site()/2 - i - 1); } sort (backwardSites.begin (), backwardSites.end ()); startingBlock.set_integralIndex() = integralIndex; startingBlock.default_op_components(false, leftState==rightState); startingBlock.BuildTensorProductBlock (backwardSites); } }
void SpinAdapted::mps_nevpt::type1::Startup(const SweepParams &sweepParams, const bool &forward, perturber& pb, int baseState) { #ifndef SERIAL mpi::communicator world; #endif assert(forward); SpinBlock system; system.nonactive_orb() =pb.orb(); bool restart=false, warmUp = false; int forward_starting_size=1, backward_starting_size=0, restartSize =0; InitBlocks::InitStartingBlock(system, forward, pb.wavenumber(), baseState, forward_starting_size, backward_starting_size, restartSize, restart, warmUp, 0,pb.braquanta, pb.ketquanta); SpinBlock::store (forward, system.get_sites(), system, pb.wavenumber(), baseState); // if restart, just restoring an existing block -- for (int i=0; i<mps_nevpt::sweepIters; i++) { SpinBlock newSystem; SpinBlock dotSystem(i+1,i+1,pb.orb(),false); system.addAdditionalCompOps(); //newSystem.default_op_components(true, system, dotSystem, true, true, false); newSystem.perturb_op_components(false, system, dotSystem, pb); newSystem.setstoragetype(DISTRIBUTED_STORAGE); newSystem.BuildSumBlock(LessThanQ, system, dotSystem, pb.braquanta, pb.ketquanta); newSystem.printOperatorSummary(); //SpinBlock Environment, big; //SpinBlock::restore (!forward, newSystem.get_complementary_sites() , Environment, baseState, baseState); //TODO //SpinBlock::restore (!forward, newSystem.get_complementary_sites() , Environment,sweepParams.current_root(),sweepParams.current_root()); //big.BuildSumBlock(PARTICLE_SPIN_NUMBER_CONSTRAINT, newSystem, Environment, pb.braquanta, pb.ketquanta); //StateInfo envStateInfo; StateInfo ketStateInfo; StateInfo braStateInfo; StateInfo halfbraStateInfo;// It has the same left and right StateInfo as braStateInfo. However, its total quanta is pb.ketquanta. // It is used to project solution into to braStateInfo. std::vector<Wavefunction> solution; solution.resize(1); std::vector<Wavefunction> outputState; outputState.resize(1); std::vector<Wavefunction> solutionprojector; solutionprojector.resize(1); solution[0].LoadWavefunctionInfo(ketStateInfo, newSystem.get_sites(), baseState); #ifndef SERIAL broadcast(world, ketStateInfo, 0); broadcast(world, solution, 0); #endif outputState[0].AllowQuantaFor(newSystem.get_braStateInfo(), *(ketStateInfo.rightStateInfo), pb.braquanta); outputState[0].set_onedot(solution[0].get_onedot()); outputState[0].Clear(); solutionprojector[0].AllowQuantaFor(newSystem.get_braStateInfo(), *(ketStateInfo.rightStateInfo), pb.ketquanta); solutionprojector[0].set_onedot(solution[0].get_onedot()); solutionprojector[0].Clear(); //TensorProduct (newSystem.get_braStateInfo(), *(ketStateInfo.rightStateInfo), pb.braquanta[0], EqualQ, braStateInfo); //TODO //TensorProduct do not support const StateInfo& TensorProduct (newSystem.set_braStateInfo(), *(ketStateInfo.rightStateInfo), pb.braquanta[0], EqualQ, braStateInfo); TensorProduct (newSystem.set_braStateInfo(), *(ketStateInfo.rightStateInfo), pb.ketquanta[0], EqualQ, halfbraStateInfo); //StateInfo::restore(forward, environmentsites, envStateInfo, baseState); //DiagonalMatrix e; //if(i == 0) // GuessWave::guess_wavefunctions(solution, e, big, TRANSPOSE, true, true, 0.0, baseState); //else // GuessWave::guess_wavefunctions(solution, e, big, TRANSFORM, true, true, 0.0, baseState); //SpinAdapted::operatorfunctions::Product(&newSystem, ccd, solution[0], &ketStateInfo, stateb.getw(), temp, SpinQuantum(0, SpinSpace(0), IrrepSpace(0)), true, 1.0); boost::shared_ptr<SparseMatrix> O; if (pb.type() == TwoPerturbType::Va) O = newSystem.get_op_array(CDD_SUM).get_local_element(0)[0]->getworkingrepresentation(&newSystem); if (pb.type() == TwoPerturbType::Vi) O = newSystem.get_op_array(CCD_SUM).get_local_element(0)[0]->getworkingrepresentation(&newSystem); boost::shared_ptr<SparseMatrix> overlap = newSystem.get_op_array(OVERLAP).get_local_element(0)[0]->getworkingrepresentation(&newSystem); SpinAdapted::operatorfunctions::TensorMultiply(*O, &braStateInfo, &ketStateInfo , solution[0], outputState[0], pb.delta, true, 1.0); SpinAdapted::operatorfunctions::TensorMultiply(*overlap, &halfbraStateInfo, &ketStateInfo , solution[0], solutionprojector[0], overlap->get_deltaQuantum(0), true, 1.0); DensityMatrix bratracedMatrix(newSystem.get_braStateInfo()); bratracedMatrix.allocate(newSystem.get_braStateInfo()); double norm = DotProduct(outputState[0], outputState[0]); if(norm > NUMERICAL_ZERO) SpinAdapted::operatorfunctions::MultiplyProduct(outputState[0], Transpose(const_cast<Wavefunction&> (outputState[0])), bratracedMatrix, 0.5/norm); SpinAdapted::operatorfunctions::MultiplyProduct(solutionprojector[0], Transpose(const_cast<Wavefunction&> (solutionprojector[0])), bratracedMatrix, 0.5); std::vector<Matrix> brarotateMatrix, ketrotateMatrix; LoadRotationMatrix (newSystem.get_sites(), ketrotateMatrix, baseState); double error; if (!mpigetrank()) error = makeRotateMatrix(bratracedMatrix, brarotateMatrix, sweepParams.get_keep_states(), sweepParams.get_keep_qstates()); #ifndef SERIAL broadcast(world, ketrotateMatrix, 0); broadcast(world, brarotateMatrix, 0); #endif SaveRotationMatrix (newSystem.get_sites(), brarotateMatrix, pb.wavenumber()); newSystem.transform_operators(brarotateMatrix,ketrotateMatrix); SpinBlock::store (forward, newSystem.get_sites(), newSystem, pb.wavenumber(), baseState); // if restart, just restoring an existing block -- system=newSystem; } //TODO //It seems that there is no need to do Last Step of Sweep. }
void SweepOnepdm::BlockAndDecimate (SweepParams &sweepParams, SpinBlock& system, SpinBlock& newSystem, const bool &useSlater, const bool& dot_with_sys, int state) { //mcheck("at the start of block and decimate"); // figure out if we are going forward or backwards dmrginp.guessgenT -> start(); bool forward = (system.get_sites() [0] == 0); SpinBlock systemDot; SpinBlock envDot; int systemDotStart, systemDotEnd; int systemDotSize = sweepParams.get_sys_add() - 1; if (forward) { systemDotStart = dmrginp.spinAdapted() ? *system.get_sites().rbegin () + 1 : (*system.get_sites().rbegin ())/2 + 1 ; systemDotEnd = systemDotStart + systemDotSize; } else { systemDotStart = dmrginp.spinAdapted() ? system.get_sites()[0] - 1 : (system.get_sites()[0])/2 - 1 ; systemDotEnd = systemDotStart - systemDotSize; } vector<int> spindotsites(2); spindotsites[0] = systemDotStart; spindotsites[1] = systemDotEnd; systemDot = SpinBlock(systemDotStart, systemDotEnd, system.get_integralIndex(), true); SpinBlock environment, environmentDot, newEnvironment; int environmentDotStart, environmentDotEnd, environmentStart, environmentEnd; const int nexact = forward ? sweepParams.get_forward_starting_size() : sweepParams.get_backward_starting_size(); newSystem.set_integralIndex() = system.get_integralIndex(); newSystem.default_op_components(dmrginp.direct(), system, systemDot, false, false, true); newSystem.erase(CRE_CRE_DESCOMP); newSystem.erase(CRE_CRE); newSystem.erase(HAM); newSystem.setstoragetype(DISTRIBUTED_STORAGE_FOR_ONEPDM); newSystem.BuildSumBlock (NO_PARTICLE_SPIN_NUMBER_CONSTRAINT, system, systemDot); if (dmrginp.outputlevel() > 0) { pout << "\t\t\t NewSystem block " << endl << newSystem << endl; newSystem.printOperatorSummary(); } InitBlocks::InitNewEnvironmentBlock(environment, systemDot, newEnvironment, system, systemDot, sweepParams.current_root(), sweepParams.current_root(), sweepParams.get_sys_add(), sweepParams.get_env_add(), forward, dmrginp.direct(), sweepParams.get_onedot(), nexact, useSlater, system.get_integralIndex(), false, false, true); SpinBlock big; newSystem.set_loopblock(true); system.set_loopblock(false); newEnvironment.set_loopblock(false); InitBlocks::InitBigBlock(newSystem, newEnvironment, big); const int nroots = dmrginp.nroots(); std::vector<Wavefunction> solution(1); DiagonalMatrix e; GuessWave::guess_wavefunctions(solution[0], e, big, sweepParams.get_guesstype(), true, state, true, 0.0); #ifndef SERIAL mpi::communicator world; mpi::broadcast(world, solution, 0); #endif std::vector<Matrix> rotateMatrix; DensityMatrix tracedMatrix(newSystem.get_stateInfo()); tracedMatrix.allocate(newSystem.get_stateInfo()); tracedMatrix.makedensitymatrix(solution, big, std::vector<double>(1,1.0), 0.0, 0.0, false); rotateMatrix.clear(); if (!mpigetrank()) double error = makeRotateMatrix(tracedMatrix, rotateMatrix, sweepParams.get_keep_states(), sweepParams.get_keep_qstates()); #ifndef SERIAL mpi::broadcast(world,rotateMatrix,0); #endif #ifdef SERIAL const int numprocs = 1; #endif #ifndef SERIAL const int numprocs = world.size(); #endif Matrix onepdm; load_onepdm_binary(onepdm, state ,state); Matrix pairmat; if (dmrginp.hamiltonian() == BCS) load_pairmat_binary(pairmat, state ,state); if (sweepParams.get_block_iter() == 0) { //this is inface a combination of 2_0_0, 1_1_0 and 0_2_0 p2out << "\t\t\t compute 2_0_0"<<endl; compute_one_pdm_2_0_0(solution[0], solution[0], big, onepdm); if (dmrginp.hamiltonian() == BCS) compute_pair_2_0_0(solution[0], solution[0], big, pairmat); p2out << "\t\t\t compute 1_1_0"<<endl; compute_one_pdm_1_1_0(solution[0], solution[0], big, onepdm); if (dmrginp.hamiltonian() == BCS) compute_pair_1_1_0(solution[0], solution[0], big, pairmat); } p2out << "\t\t\t compute 0_2_0"<<endl; compute_one_pdm_0_2_0(solution[0], solution[0], big, onepdm); if (dmrginp.hamiltonian() == BCS) compute_pair_0_2_0(solution[0], solution[0], big, pairmat); p2out << "\t\t\t compute 1_1"<<endl; compute_one_pdm_1_1(solution[0], solution[0], big, onepdm); if (dmrginp.hamiltonian() == BCS) compute_pair_1_1(solution[0], solution[0], big, pairmat); if (sweepParams.get_block_iter() == sweepParams.get_n_iters() - 1) { p2out << "\t\t\t compute 0_2"<<endl; compute_one_pdm_0_2(solution[0], solution[0], big, onepdm); if (dmrginp.hamiltonian() == BCS) compute_pair_0_2(solution[0], solution[0], big, pairmat); } accumulate_onepdm(onepdm); save_onepdm_binary(onepdm, state, state); if (dmrginp.hamiltonian() == BCS) { accumulate_onepdm(pairmat); save_pairmat_binary(pairmat, state, state); } SaveRotationMatrix (newSystem.get_sites(), rotateMatrix, state); solution[0].SaveWavefunctionInfo (big.get_stateInfo(), big.get_leftBlock()->get_sites(), state); newSystem.transform_operators(rotateMatrix); }