Example #1
0
void SplitOp1D::propagateITP(Array2D<cplx> &States, double tolerance)
{
  assert(States.Ny() >= 1 && States.Nx() == nx);
  double enprev = 1.0;
  double encurr = 1.0;
  double enconv = encurr/enprev;
  int nv        = States.Ny();
  int steps     = 0;
  vector<shared_ptr<wvfxn1D>> TestVecs;

  for (int ii = 0; ii < nv; ii++)
    TestVecs.push_back(make_shared<wvfxn1D>(nx,0.0,xstep));

  initializeGuess(TestVecs);

//Get the ground state vector
  copy_n(TestVecs[0]->data(),nx,wvfxn->data());
  wvfxn->normalize();
  while (enconv > tolerance)
  {
    propagateStep(1);
    steps  += 1;
    enprev = encurr;
    wvfxn->normalize();
    encurr = getEnergy();
    enconv = abs(1.0 - (encurr/enprev));
    if (steps > 1000)
    {
      steps = 0;
      itpdt *= 10.0;
      updateITP();
    }
  }
  copy_n(wvfxn->data(),nx,TestVecs[0]->data());

//Reset variables, get excited states
  if (nv > 1)
  {
    for (int ii = 0; ii < nv; ii++)
    {
      copy_n(TestVecs[ii]->data(),nx,wvfxn->data());
      steps  = 0;
      encurr = 1.0;
      enprev = 1.0;
      enconv = encurr/enprev;
      while (enconv > tolerance)
      {
        for (int jj = 0; jj < ii; jj++)
          *wvfxn -= (*TestVecs[jj] * (*TestVecs[jj]|*wvfxn).integrate_rect());

        propagateStep(1);
        steps += 1;
        enprev = encurr;
        wvfxn->normalize();
        encurr = getEnergy();
        enconv = abs(1.0 - (encurr/enprev));

        if (steps > 1000)
        {
          steps = 0;
          itpdt *= 2.0;
          updateITP();
        }
      }
      copy_n(wvfxn->data(),nx,TestVecs[ii]->data());
    }
  }
  //Copy excited states to provided array
  for (int ii = 0; ii < nv; ii++)
    copy_n(TestVecs[ii]->data(),nx,&States(0,ii));
}