//Canonicalize wavefunction, takes the wavefunction and does a sweep to update all the roation matrices so that we get a consistent wavefunction along the whole sweep void SpinAdapted::Sweep::CanonicalizeWavefunction(SweepParams &sweepParams, const bool &forward, int currentstate) { sweepParams.set_sweep_parameters(); sweepParams.set_block_iter() = 0; std::vector<int> sites; int new_site, wave_site; if (forward) { pout << "\t\t\t Starting sweep "<< sweepParams.set_sweep_iter()<<" in forwards direction"<<endl; new_site = 0; } else { pout << "\t\t\t Starting sweep "<< sweepParams.set_sweep_iter()<<" in backwards direction" << endl; new_site = dmrginp.spinAdapted() ? dmrginp.last_site()-1 : dmrginp.last_site()/2-1; } pout << "\t\t\t ============================================================================ " << endl; if (dmrginp.spinAdapted()) sites.push_back(new_site); else { sites.push_back(2*new_site); sites.push_back(2*new_site+1); std::sort(sites.begin(), sites.end()); } //only need statinfos StateInfo stateInfo1; makeStateInfo(stateInfo1, new_site); for (; sweepParams.get_block_iter() < sweepParams.get_n_iters(); ) { pout << "\t\t\t Block Iteration :: " << sweepParams.get_block_iter() << endl; pout << "\t\t\t ----------------------------" << endl; if (forward) { new_site++; wave_site = new_site+1; pout << "\t\t\t Current direction is :: Forwards " << endl; } else { new_site--; wave_site = new_site-1; pout << "\t\t\t Current direction is :: Backwards " << endl; } std::vector<int> complementarySites, spindotsites(1, new_site), oldsites = sites, oldcomplement; if (dmrginp.spinAdapted()) sites.push_back(new_site); else { sites.push_back(2*new_site); sites.push_back(2*new_site+1); std::sort(sites.begin(), sites.end()); } getComplementarySites(sites, complementarySites); getComplementarySites(oldsites, oldcomplement); StateInfo siteState, newState1, bigstate, envstate; makeStateInfo(siteState, new_site); TensorProduct(stateInfo1, siteState, newState1, NO_PARTICLE_SPIN_NUMBER_CONSTRAINT); newState1.CollectQuanta(); Wavefunction w; w.set_deltaQuantum() = dmrginp.effective_molecule_quantum_vec(); w.set_onedot(true); if (!dmrginp.spinAdapted()) { std::vector<int> spinSites(complementarySites.size()/2, 0); for (int s=0; s<spinSites.size(); s++) spinSites[s] = complementarySites[2*s]/2; StateInfo::restore(!forward, spinSites, envstate, currentstate); } else StateInfo::restore(!forward, complementarySites, envstate, currentstate); TensorProduct(newState1, envstate, bigstate, PARTICLE_SPIN_NUMBER_CONSTRAINT); if (sweepParams.get_block_iter() == 0) GuessWave::transpose_previous_wavefunction(w, bigstate, complementarySites, spindotsites, currentstate, true, true); else GuessWave::transform_previous_wavefunction(w, bigstate, oldsites, oldcomplement, currentstate, true, true); w.SaveWavefunctionInfo(bigstate, sites, currentstate); //make the newstate std::vector<Matrix> rotation1; DensityMatrix tracedMatrix; tracedMatrix.allocate(*bigstate.leftStateInfo); operatorfunctions::MultiplyProduct(w, Transpose(const_cast<Wavefunction&> (w)), tracedMatrix, 1.0); int largeNumber = 1000000; if (!mpigetrank()) double error = makeRotateMatrix(tracedMatrix, rotation1, largeNumber, sweepParams.get_keep_qstates()); SaveRotationMatrix (sites, rotation1, currentstate); StateInfo renormState1; SpinAdapted::StateInfo::transform_state(rotation1, newState1, renormState1); StateInfo::store(forward, sites, renormState1, currentstate); stateInfo1 = renormState1; ++sweepParams.set_block_iter(); } }
void SweepGenblock::BlockAndDecimate (SweepParams &sweepParams, SpinBlock& system, SpinBlock& newSystem, const bool &useSlater, const bool& dot_with_sys, int state) { if (dmrginp.outputlevel() > 0) mcheck("at the start of block and decimate"); // figure out if we are going forward or backwards pout << "\t\t\t Performing Blocking"<<endl; dmrginp.guessgenT -> start(); bool forward = (system.get_sites() [0] == 0); SpinBlock systemDot; int systemDotStart, systemDotEnd; int systemDotSize = sweepParams.get_sys_add() - 1; if (forward) { systemDotStart = *system.get_sites().rbegin () + 1; systemDotEnd = systemDotStart + systemDotSize; } else { systemDotStart = system.get_sites() [0] - 1; systemDotEnd = systemDotStart - systemDotSize; } vector<int> spindotsites(2); spindotsites[0] = systemDotStart; spindotsites[1] = systemDotEnd; systemDot = SpinBlock(systemDotStart, systemDotEnd); const int nexact = forward ? sweepParams.get_forward_starting_size() : sweepParams.get_backward_starting_size(); system.addAdditionalCompOps(); InitBlocks::InitNewSystemBlock(system, systemDot, newSystem, sweepParams.get_sys_add(), dmrginp.direct(), DISTRIBUTED_STORAGE, dot_with_sys, true); pout << "\t\t\t System Block"<<newSystem; if (dmrginp.outputlevel() > 0) newSystem.printOperatorSummary(); std::vector<Matrix> rotateMatrix; if (!dmrginp.get_fullrestart()) { //this should be done when we actually have wavefunctions stored, otherwise not!! SpinBlock environment, environmentDot, newEnvironment; int environmentDotStart, environmentDotEnd, environmentStart, environmentEnd; InitBlocks::InitNewEnvironmentBlock(environment, systemDot, newEnvironment, system, systemDot, sweepParams.get_sys_add(), sweepParams.get_env_add(), forward, dmrginp.direct(), sweepParams.get_onedot(), nexact, useSlater, true, true, true); SpinBlock big; InitBlocks::InitBigBlock(newSystem, newEnvironment, big); DiagonalMatrix e; std::vector<Wavefunction> solution(1); GuessWave::guess_wavefunctions(solution[0], e, big, sweepParams.get_guesstype(), true, state, true, 0.0); solution[0].SaveWavefunctionInfo (big.get_stateInfo(), big.get_leftBlock()->get_sites(), state); DensityMatrix tracedMatrix; 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 = newSystem.makeRotateMatrix(tracedMatrix, rotateMatrix, sweepParams.get_keep_states(), sweepParams.get_keep_qstates()); } else LoadRotationMatrix (newSystem.get_sites(), rotateMatrix, state); #ifndef SERIAL mpi::communicator world; broadcast(world, rotateMatrix, 0); #endif if (!dmrginp.get_fullrestart()) SaveRotationMatrix (newSystem.get_sites(), rotateMatrix, state); pout <<"\t\t\t Performing Renormalization "<<endl<<endl; newSystem.transform_operators(rotateMatrix); if (dmrginp.outputlevel() > 0) mcheck("after rotation and transformation of block"); if (dmrginp.outputlevel() > 0) pout <<newSystem<<endl; if (dmrginp.outputlevel() > 0) newSystem.printOperatorSummary(); //mcheck("After renorm transform"); }