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)); }