vector< vector<int> > SpinAdapted::CSFUTIL::generate_partitions(int n) { //n is the irrep of the symmetry element. if (Symmetry::sizeofIrrep(n) == 1) { pout << "cannot generate partition of irrep which a single row "<<endl; exit(0); } vector<int> thispartition(1, n); vector< vector<int> > result(1, thispartition); if (n == 4 || n==5) { return result; } else { for (int irrep = 4; irrep <n ; irrep++) { int remainder = (IrrepSpace(n)+IrrepSpace(irrep))[0].getirrep(); vector< vector<int> > partitions = generate_partitions(irrep); for (int i=0; i<partitions.size(); i ++) { vector<int> ithpartition = partitions[i]; if (ithpartition[0] <= remainder) { vector<int>::iterator it = ithpartition.begin(); ithpartition.insert(it, remainder); result.push_back(ithpartition); } } } return result; } }
template<> void Op_component<Ham>::build_iterators(SpinBlock& b) { m_op.set_indices(); m_op(0).resize(1); m_op(0)[0]=boost::shared_ptr<Ham>(new Ham); m_op(0)[0]->set_orbs() = std::vector<int>(); m_op(0)[0]->set_initialised() = true; m_op(0)[0]->set_fermion() = false; if (dmrginp.hamiltonian() == BCS) { m_op(0)[0]->resize_deltaQuantum(5); for (int i = 0; i <5; ++i) { m_op(0)[0]->set_deltaQuantum(i) = SpinQuantum(2*(i-2), SpinSpace(0), IrrepSpace(0) ); } } else { m_op(0)[0]->set_deltaQuantum(1, SpinQuantum(0, SpinSpace(0), IrrepSpace(0))); } }
std::vector<IrrepSpace> IrrepSpace::operator+=(IrrepSpace rhs) { std::vector<int> irreps = Symmetry::add(irrep, rhs.irrep); std::vector<IrrepSpace> vec; for (int i=0; i<irreps.size(); i++) { vec.push_back(IrrepSpace(irreps[i])); } return vec; }
void SparseMatrix::CleanUp () { built = false; initialised = false; fermion = 0; deltaQuantum = SpinQuantum (0, 0, IrrepSpace(0)); orbs.resize(0); allowedQuantaMatrix.ReSize (0,0); operatorMatrix.ReSize (0,0); }
template<> void Op_component<Overlap>::build_iterators(SpinBlock& b) { m_op.set_indices(); m_op(0).resize(1); m_op(0)[0]=boost::shared_ptr<Overlap>(new Overlap); m_op(0)[0]->set_orbs() = std::vector<int>(); m_op(0)[0]->set_initialised() = true; m_op(0)[0]->set_fermion() = false; m_op(0)[0]->set_deltaQuantum(1, SpinQuantum(0, SpinSpace(0), IrrepSpace(0))); }
Csf SpinAdapted::CSFUTIL::applyTensorOp(const TensorOp& newop, int spinL) { //for (int k=0; k<newop.Szops[newop.Szops.size()-1-newop.Spin].size(); k++) { map<Slater, double> m; SpinQuantum sq(newop.optypes.size(), SpinSpace(newop.Spin), IrrepSpace(newop.irrep)); for (int k=0; k<newop.Szops[spinL].size(); k++) { if (fabs(newop.Szops[spinL][k]) > 1e-10) { std::vector<bool> occ_rep(Slater().size(), 0); Slater s(occ_rep,1); for (int k2=newop.opindices[k].size()-1; k2>=0; k2--) { s.c(newop.opindices[k][k2]); } if (s.isempty()) { continue; } map<Slater, double>::iterator itout = m.find(s); if (itout == m.end()) { int sign = s.alpha.getSign(); s.setSign(1); m[s] = sign*newop.Szops[spinL][k]; } else m[s] += s.alpha.getSign()*newop.Szops[spinL][k]; } } int irreprow = spinL/(newop.Spin+1); int sz = -2*(spinL%(newop.Spin+1)) + newop.Spin; Csf csf = Csf(m,sq.particleNumber, sq.totalSpin, sz, IrrepVector(sq.get_symm().getirrep(),irreprow)) ; if (!csf.isempty() && fabs(csf.norm()) > 1e-14) csf.normalize(); return csf; }
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); } }
std::vector<SpinAdapted::Csf > SpinAdapted::CSFUTIL::spinfockstrings(const std::vector<int>& orbs, std::vector< std::vector<Csf> >& ladders) { std::vector<Csf > singleSiteCsf; std::vector<int> numcsfs; std::vector< std::vector<Csf> > singleSiteLadder; int numCsfSoFar = 0; for (int i=0; i<orbs.size(); i++) { std::vector< Csf> thisSiteCsf; int I = orbs[i]; std::vector<TensorOp> tensorops(1, TensorOp(I, 1)); IrrepSpace Irrep = SymmetryOfSpatialOrb(orbs[i]); SpinQuantum sQ(1, SpinSpace(1), Irrep); int irrepsize = Symmetry::sizeofIrrep(Irrep.getirrep()); std::vector<Csf> ladderentry; std::map<Csf, std::vector<Csf> > laddermap; std::vector<bool> occ_rep1(Slater().size(),0), occ_rep2(Slater().size(),0); occ_rep2[dmrginp.spatial_to_spin()[I]+2*irrepsize-2] = 1; Slater s1(occ_rep1, 1), s2(occ_rep2, 1); map<Slater, double > m1, m2; m1[s1]= 1.0; m2[s2] = 1.0; if ( (dmrginp.calc_type() != RESPONSELCC && dmrginp.calc_type() != RESPONSEAAAV && dmrginp.calc_type() != RESPONSEAAAC) && find(dmrginp.get_openorbs().begin(), dmrginp.get_openorbs().end(), I) != dmrginp.get_openorbs().end() ) { thisSiteCsf.push_back( Csf(m1, 0, SpinSpace(0), 0, IrrepVector(0,0))); //0,0,0 ladderentry.push_back(Csf(m1, 0, SpinSpace(0), 0, IrrepVector(0,0))); singleSiteLadder.push_back(ladderentry); numcsfs.push_back(thisSiteCsf.size()); for (int i=0; i<thisSiteCsf.size(); i++) singleSiteCsf.push_back( thisSiteCsf[i]); continue; } else if ( (dmrginp.calc_type() != RESPONSELCC && dmrginp.calc_type() != RESPONSEAAAV && dmrginp.calc_type() != RESPONSEAAAC)&& find(dmrginp.get_closedorbs().begin(), dmrginp.get_closedorbs().end(), I) != dmrginp.get_closedorbs().end()) { std::vector<bool> occ_rep(Slater().size(),0); occ_rep[dmrginp.spatial_to_spin()[I]+2*irrepsize-2] = 1; occ_rep[dmrginp.spatial_to_spin()[I]+2*irrepsize-1] = 1; Slater s(occ_rep, 1); map<Slater, double > m; m[s]= 1.0; thisSiteCsf.push_back( Csf(m, 2, SpinSpace(0), 0, IrrepVector(0,0))); //2,0,0 ladderentry.push_back(Csf(m, 2, SpinSpace(0), 0, IrrepVector(0,0))); singleSiteLadder.push_back(ladderentry); numcsfs.push_back(thisSiteCsf.size()); for (int i=0; i<thisSiteCsf.size(); i++) singleSiteCsf.push_back( thisSiteCsf[i]); continue; } else if(dmrginp.hamiltonian() == HEISENBERG) { thisSiteCsf.push_back( Csf(m2, 1, SpinSpace(1), 1, IrrepVector(Irrep.getirrep(), irrepsize-1))); //1,1,L for (int i=tensorops[0].Szops.size(); i> 0; i--) ladderentry.push_back(applyTensorOp(tensorops[0], i-1)); singleSiteLadder.push_back(ladderentry); numcsfs.push_back(thisSiteCsf.size()); for (int i=0; i<thisSiteCsf.size(); i++) singleSiteCsf.push_back( thisSiteCsf[i]); continue; } thisSiteCsf.push_back( Csf(m1, 0, SpinSpace(0), 0, IrrepVector(0,0))); //0,0,0 thisSiteCsf.push_back( Csf(m2, 1, SpinSpace(1), 1, IrrepVector(Irrep.getirrep(), irrepsize-1))); //1,1,L ladderentry.push_back(Csf(m1, 0, SpinSpace(0), 0, IrrepVector(0,0))); singleSiteLadder.push_back(ladderentry); ladderentry.clear(); for (int i=tensorops[0].Szops.size(); i> 0; i--) ladderentry.push_back(applyTensorOp(tensorops[0], i-1)); singleSiteLadder.push_back(ladderentry); //laddermap[singleSiteCsf.back()] = ladderentry; for (int nele = 2; nele < 2*irrepsize+1; nele++) { std::vector<SpinQuantum> quanta; std::vector<TensorOp> newtensorops; for (int i=0; i<tensorops.size(); i++) { quanta = SpinQuantum(nele-1, SpinSpace(tensorops[i].Spin), IrrepSpace(tensorops[i].irrep)) + sQ; for (int j=0; j<quanta.size(); j++) { TensorOp newop = TensorOp(I,1).product(tensorops[i], quanta[j].totalSpin.getirrep(), quanta[j].get_symm().getirrep()); Csf csf = applyTensorOp(newop, newop.Szops.size()-1-newop.Spin); if (!csf.isempty() && csf.norm() >1e-10) { csf.normalize(); if (find(thisSiteCsf.begin(), thisSiteCsf.end(), csf) == thisSiteCsf.end()) { thisSiteCsf.push_back( csf); newtensorops.push_back(newop); std::vector<Csf> ladderentry; for (int k=newop.Szops.size(); k>0 ; k--) ladderentry.push_back(applyTensorOp(newop, k-1)); singleSiteLadder.push_back(ladderentry); //laddermap[csf] = ladderentry; } } } } tensorops = newtensorops; } numcsfs.push_back(thisSiteCsf.size()); for (int i=0; i<thisSiteCsf.size(); i++) singleSiteCsf.push_back( thisSiteCsf[i]); } std::vector<Csf> prevoutput, output; std::vector< std::vector<Csf> > prevladder, ladder; for (int i=0; i<numcsfs[0]; i++) { output.push_back(singleSiteCsf[i]); ladder.push_back(singleSiteLadder[i]); } int csfindex = numcsfs[0]; for (int i2=1; i2<orbs.size(); i2++) { for (int i=0; i<output.size(); i++) { prevoutput.push_back(output[i]); prevladder.push_back(ladder[i]); } output.clear(); ladder.clear(); for (int j=0; j<prevoutput.size(); j++) { for (int k=0; k<numcsfs[i2]; k++) { CSFUTIL::TensorProduct(prevoutput[j], prevladder[j], singleSiteCsf[csfindex+k], singleSiteLadder[csfindex+k], output, ladder); } } prevoutput.clear(); prevladder.clear(); csfindex += numcsfs[i2]; } std::vector<int> sortvec(output.size()); for (int i=0; i<output.size(); i++) sortvec[i] = i; std::sort(sortvec.begin(), sortvec.end(), sorter<Csf>(output)); std::sort(output.begin(), output.end()); for (int i=0; i<output.size(); i++) ladders.push_back(ladder[sortvec[i]]); return output; }