예제 #1
0
파일: slater.C 프로젝트: junyang4711/Block
void SpinAdapted::Slater::outerProd(const Slater& s, Slater& output) const
{
  vector<bool> occ(Slater().size());

  for (int i=0; i<Slater().size(); i++)
  {
    if (s.alpha.get_occ_rep()[i] == 1 && alpha.get_occ_rep()[i]==1) {
      cout <<"cannot get outerprod of slater determinants\ndet1: "<<s<<"\ndet2: "<<*this<<endl;
      throw 20;
    }
    occ[i] = s.alpha.get_occ_rep()[i] + alpha.get_occ_rep()[i];
  }
  Orbstring o(occ, s.alpha.getSign()*alpha.getSign());
  Slater temp(o);
  output = temp;
}
예제 #2
0
파일: csf.C 프로젝트: sanshar/StackBlock
void SpinAdapted::Csf::applySminus(Csf& output)
{
  map<Slater, double>::iterator itout, it = det_rep.begin();
  map<Slater, double> detsout;
  for ( ; it!= det_rep.end(); it++)
    for (int i=0; i<Slater().size(); i+=2) {
      Slater s = (*it).first;
      s.d(i).c(i+1);
      if ( !s.isempty()) {
	itout = detsout.find(s);
	if (itout == detsout.end())
	  detsout[s] = (*it).second;
	else
	  detsout[s] += (*it).second;
      }
    }
  output.set_det_rep(detsout, S, irrep);
  output.set_S(S);
  output.set_Sz(Sz-2);
  output.set_n(n);
  output.normalize();
}
예제 #3
0
파일: csf.C 프로젝트: sanshar/StackBlock
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;
}
예제 #4
0
파일: csf.C 프로젝트: sanshar/StackBlock
std::vector<Csf> Csf::distributeNonSpinAdapted (const int n, const int sp, const IrrepVector &sym, const int left, const int right, const int edge, int integralIndex)
{
  std::vector<Csf> s;
  
  int na = 0;
  int nb = 0;
  na = (n + sp) / 2;
  nb = (n - sp) / 2;

  // let's count how many left and right orbitals there actually are
  int actualOrbs = right - left;
  int actualNA, actualNB;
  actualNA = actualNB = 0;
  for (int i=left; i<right; ++i)
    {
      if((SpinOf(i) == 1))
	++actualNA;
      else
	++actualNB;
    }

  // cannot form this combination
  if (na > actualNA || nb > actualNB || na < 0 || nb < 0) 
    {
      return s;
    }

  // now make orbital occupancies
  std::vector<int> alphaSeed (actualNA);
  std::vector<int> betaSeed (actualNB);
  for (int i = 0; i < na; ++i)
    alphaSeed [i] = -1;
  for (int i = 0; i < nb; ++i)
    betaSeed [i] = -1;

  // okay now make some permutations (at most GUESS_PERMUTATIONS)
  std::vector< std::vector<int> > alphaList; alphaList.push_back (alphaSeed);
  std::vector< std::vector<int> > betaList; betaList.push_back (betaSeed);
  int numberOfGuesses = dmrginp.guess_permutations();
  while (next_permutation (alphaSeed.begin (), alphaSeed.end ()) && numberOfGuesses--)      
    alphaList.push_back (alphaSeed);
  numberOfGuesses = dmrginp.guess_permutations();;
  while (next_permutation (betaSeed.begin (), betaSeed.end ()) && numberOfGuesses--)
    betaList.push_back (betaSeed);
  

  // okay - we have all the permutations. 
  // make list of available alpha and beta orbitals in energy ordering.
  std::vector<int> orbitalAlphaList;
  std::vector<int> orbitalBetaList;

  multimap <double, int> alphaMap;
  multimap <double, int> betaMap;

  int alphaIndex = 0;
  int betaIndex = 0;

  // scan orbitals from left to right, pick out orbitals which are occupied in the hartree-fock reference
  for (int i=left; i<right; ++i)
  {
    if (dmrginp.hf_occupancy()[i])
    {
      if ((SpinOf(i) == 1)) // 0 to take into account case of nospin
      {
	orbitalAlphaList.push_back(alphaIndex);
	++alphaIndex;
      }
      else
      {
	orbitalBetaList.push_back(betaIndex);
	++betaIndex;
      }
    }
    else if ((SpinOf(i) == 1)) // not HF orb, but alpha orb
    {
      alphaMap.insert(pair<double, int>(v_1[integralIndex](i, i), alphaIndex));
      ++alphaIndex;
    }
    else // beta orb
    {
      betaMap.insert(pair<double, int>(v_1[integralIndex](i, i), betaIndex));
      ++betaIndex;
    }
  }

  for (multimap<double, int>::iterator m=alphaMap.begin (); m!=alphaMap.end (); ++m)
    orbitalAlphaList.push_back(m->second);
  for (multimap<double, int>::iterator m=betaMap.begin (); m!=betaMap.end (); ++m)
    orbitalBetaList.push_back(m->second);

  // Now convert permutation lists to energy ordered form
  for (int i=0; i<alphaList.size (); ++i)
    ConvertList (alphaList[i], orbitalAlphaList);
  for (int i=0; i<betaList.size (); ++i)
    ConvertList (betaList[i], orbitalBetaList);
  // Now catenate to make Slaters
  for (int i=0; i<alphaList.size(); ++i)
    for (int j=0; j<betaList.size(); ++j)
    {
      std::vector<bool> lbuffer(left, 0);
      std::vector<bool> rbuffer(edge - right, 0);
      
      std::vector<bool> orbs(right - left);
      int alphaI = 0;
      int betaI = 0;
      for (int orbI=0; orbI<right-left; ++orbI)
      {
	if (SpinOf(orbI + left) == 1)
	{
	  if (alphaList[i][alphaI]) orbs[orbI] = 1;
	  ++alphaI;
	}
	else
	{
	  if (betaList[j][betaI]) orbs[orbI] = 1;
	  ++betaI;
	}
      }
      std::vector<bool> tmp = lbuffer;
      for (std::vector<bool>::iterator it = orbs.begin(); it!=orbs.end(); ++it) tmp.push_back(*it);
      for (std::vector<bool>::iterator it = rbuffer.begin(); it!=rbuffer.end(); ++it) tmp.push_back(*it);
      Slater new_det = Slater (Orbstring (tmp));
      map<Slater, double> m;
      m[new_det] = 1.0;
      if(sym.getirrep() == AbelianSymmetryOf(new_det).getirrep())
	s.push_back (Csf(m,n,SpinSpace(sp), sp, IrrepVector(sym.getirrep(),0)));
    }
  return s;
}
예제 #5
0
파일: csf.C 프로젝트: sanshar/StackBlock
std::vector< SpinAdapted::Csf > SpinAdapted::Csf::distribute (const int n, const int sp, const IrrepVector &sym, const int left, const int right, const int edge, int integralIndex)
{
  std::vector< Csf > s;

  int na = 0;
  int nb = 0;
  na = (n + sp) / 2;
  nb = (n - sp) / 2;

  if(dmrginp.hamiltonian() == HEISENBERG && nb != 0) return s;
  // let's count how many left and right orbitals there actually are                                                                      
  int actualOrbs = dmrginp.spatial_to_spin()[right] - dmrginp.spatial_to_spin()[left];
  int actualNA, actualNB;
  actualNA = actualOrbs/2;
  actualNB = actualOrbs/2;

  // cannot form this combination 

  if (na > actualNA || nb > actualNB || na < 0 || nb < 0)
    {
      return s;
    }

  // now make orbital occupancies                                                                                                         
  std::vector<int> abSeed (right-left);
  for (int i = 0; i < max(na, nb); ++i)
    abSeed [i] = -1;

  // okay now make some permutations (at most GUESS_PERMUTATIONS)  
  std::vector< std::vector<int> > abList; abList.push_back (abSeed);

  int numberOfGuesses = dmrginp.guess_permutations();
  bool doAgain = true;
  int numtries = 0;
  while(doAgain && numtries <500)
  {
    while (next_permutation (abSeed.begin (), abSeed.end ()) && numberOfGuesses--) 
      abList.push_back (abSeed);

    // make list of available alpha and beta orbitals in energy ordering.
    std::vector<int> orbitalList;
    
    multimap <double, int> orbMap;
    
    int alphaIndex = 0;
    
    // scan orbitals from left to right, pick out orbitals which have smallest v_1(i, i) integrals
    
    for (int i=left; i<right; ++i)
      {
	if (dmrginp.hf_occupancy()[dmrginp.spatial_to_spin()[i]]) {
	  orbitalList.push_back(alphaIndex);
	  alphaIndex++;
	  continue;
	}
	orbMap.insert(pair<double, int>(v_1[integralIndex](2*i, 2*i), alphaIndex));
	++alphaIndex;
      }
    
    for (multimap<double, int>::iterator m=orbMap.begin (); m!=orbMap.end (); ++m)
      orbitalList.push_back(m->second);
    

    // Now convert permutation lists to energy ordered form
    for (int i=0; i<abList.size (); ++i)
      ConvertList (abList[i], orbitalList);
    
    
    Slater last_det;
    // Now catenate to make Slaters
    for (int i=0; i<abList.size(); ++i)
      {
	std::vector<bool> lbuffer(dmrginp.spatial_to_spin()[left], 0);
	std::vector<bool> rbuffer(dmrginp.spatial_to_spin()[edge] - dmrginp.spatial_to_spin()[right], 0);
	
	std::vector<bool> orbs(dmrginp.spatial_to_spin()[right] - dmrginp.spatial_to_spin()[left], 0);
	int alphaI = 0;
	int betaI = 0;
	
	for (int orbI=0; orbI<(right-left); orbI++)
	{
	  if (abList[i][alphaI]) {
	    orbs[dmrginp.spatial_to_spin()[orbI]] = 1;
	    if (betaI < min(na, nb)) {
	      orbs[ dmrginp.spatial_to_spin()[orbI]+1] = 1;
	      ++betaI;
	    }
	  }
	  ++alphaI;
	}
	
	std::vector<bool> tmp = lbuffer;
	for (std::vector<bool>::iterator it = orbs.begin(); it!=orbs.end(); ++it) tmp.push_back(*it);
	for (std::vector<bool>::iterator it = rbuffer.begin(); it!=rbuffer.end(); ++it) tmp.push_back(*it);
	Slater new_det = Slater (Orbstring (tmp));
	map<Slater, double> m;
	m[new_det] = 1.0;
	last_det = new_det;

	if(sym.getirrep() == AbelianSymmetryOf(new_det).getirrep())
	  s.push_back ( Csf(m, n, SpinSpace(sp), sp, IrrepVector(sym.getirrep(), 0)) );
      }
    
    if (s.size() == 0) {
      numtries++;
      doAgain = true;
      abList.clear();
      numberOfGuesses = dmrginp.guess_permutations();
    }
    else
      doAgain = false;
  }
  
  return s;
}
예제 #6
0
파일: csf.C 프로젝트: sanshar/StackBlock
//this version of the code is used when DMRG is no spin adapted
std::vector<SpinAdapted::Csf > SpinAdapted::CSFUTIL::spinfockstrings(const std::vector<int>& orbs)
{

  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];  

    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_rep3(Slater().size(), 0), occ_rep4(Slater().size(), 0);
    occ_rep2[dmrginp.spatial_to_spin()[I]] = 1;
    occ_rep3[dmrginp.spatial_to_spin()[I]+1] = 1;
    occ_rep4[dmrginp.spatial_to_spin()[I]] = 1;occ_rep4[dmrginp.spatial_to_spin()[I]+1] = 1;
    
    Slater s1(occ_rep1, 1), s2(occ_rep2, 1), s3(occ_rep3, 1), s4(occ_rep4, 1); map<Slater, double > m1, m2, m3, m4;
    m1[s1]= 1.0; m2[s2] = 1.0;  m3[s3]= 1.0; m4[s4] = 1.0;
    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
    thisSiteCsf.push_back( Csf(m3, 1, SpinSpace(-1), -1, IrrepVector(Irrep.getirrep(), irrepsize-1))); //1,1,L
    thisSiteCsf.push_back( Csf(m4, 2, SpinSpace(0), 0, IrrepVector(0, 0))); //2,0,0

    
    numcsfs.push_back(thisSiteCsf.size());

    
    for (int i=0; i<thisSiteCsf.size(); i++)
      singleSiteCsf.push_back( thisSiteCsf[i]);
    
  }
  
  std::vector<Csf> prevoutput, output;

  for (int i=0; i<numcsfs[0]; i++) 
    output.push_back(singleSiteCsf[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]);
    }
    output.clear();

    for (int j=0; j<prevoutput.size(); j++) {
      for (int k=0; k<numcsfs[i2]; k++) {
	CSFUTIL::TensorProduct(prevoutput[j], singleSiteCsf[csfindex+k], output);
      }
    }    
    

    prevoutput.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());

  return output;
   
}
예제 #7
0
파일: csf.C 프로젝트: sanshar/StackBlock
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;
   
}