Beispiel #1
0
dcomplex pl_base1_triT<tiny_cpx<T> >::atan(value_type x)
{
#if _MSC_VER>1600
	return std::atan(k(x));
#else
	dcomplex _tmp =pl_log::g(dcomplex(1.0+x.imag(),-x.real()))-pl_log::g(dcomplex(1.0-x.imag(),x.real()));
	return dcomplex(-0.5*_tmp.imag(),0.5*_tmp.real());
#endif
}
Beispiel #2
0
dcomplex pl_base1_triT<tiny_cpx<T> >::asin(value_type x)
{
#if _MSC_VER>1600
	return std::asin(k(x));
#else
	dcomplex _tmp=pl_log::g(dcomplex(-x.imag(),x.real())+pl_sqrt::g(-pl_pow::g(x,2)+1.0));
	return dcomplex(_tmp.imag(),-_tmp.real());
#endif
}
log_value<dcomplex>
TransposeInverseMatrix(const Array2 < complex <doublevar> > & a, 
                       Array2 < complex <doublevar> > & a1, 
                       const int n)
{
  Array2 <complex <doublevar> >  temp(n,n);
  Array1 <int> indx(n);
  doublevar d;

  // a(i,j) first index i is row index (convention)
  // elements of column vectors are stored contiguous in memory in C style arrays
  // a(i) refers to a column vector

  // calculate the inverse of the transposed matrix because this
  // allows to pass a column vector to lubksb() instead of a row

  // put the transposed matrix in temp
  //cout << "temp " << endl;
  for(int i=0;i<n;++i)
  {
    for(int j=0;j<n;++j)
    {
      temp(i,j)=a(i,j);
      a1(i,j)=complex <doublevar> (0.0,0.0);
    }
    a1(i,i)=complex <doublevar> (1.0,0.0);
  }

  //cout << "ludcmp" << endl;
  //if the matrix is singular, the determinant is zero.
  if(ludcmp(temp,n,indx,d)==0) { 
#ifdef SUPERDEBUG
    cout << "log_value<dcomplex>TransposeInverseMatrix:zero determinant " << endl;
#endif
    return dcomplex(0.0,0.0);
  }

  //cout << "lubksb" << endl;

  for(int j=0;j<n;++j)
  {
    // get column vector
    Array1 <complex <doublevar> > yy;//(a1(j));
    yy.refer(a1(j));
    lubksb(temp,n,indx,yy);
  }


  //complex <doublevar> det(d,0);
  log_value<dcomplex> det=dcomplex(d,0);
  for(int j=0;j<n;++j) {
    det *= temp(j,j);
  }
  return det;
}
void Wf_return::mpiRecieve(int node) {
#ifdef USE_MPI
  int nwf, nst;
  MPI_Status status;
  
  MPI_Recv(&nwf, 1, MPI_INT, node, 0, MPI_Comm_grp, &status);
  MPI_Recv(&nst, 1, MPI_INT, node, 0, MPI_Comm_grp, &status);
  MPI_Recv(&is_complex, 1, MPI_INT, node, 0, MPI_Comm_grp, &status);
  
  Resize(nwf, nst);
  MPI_Recv(amp.v, nwf*nst, MPI_DOUBLE, node, 0, MPI_Comm_grp, & status);
  MPI_Recv(phase.v, nwf*nst, MPI_DOUBLE, node, 0, MPI_Comm_grp, &status);
  if(is_complex) {
    for(int w=0; w < nwf; w++) {
      for(int i=0; i < nst; i++) {
        doublevar tmp1, tmp2;
        MPI_Recv(&tmp1, 1, MPI_DOUBLE, node, 0, MPI_Comm_grp, &status);
        MPI_Recv(&tmp2, 1, MPI_DOUBLE, node, 0, MPI_Comm_grp, &status);
        cvals(w,i)=dcomplex(tmp1, tmp2);
      }
    }
  }  
  
#endif
}
dcomplex
PatchFaceDataNormOpsComplex::dot(
   const std::shared_ptr<pdat::FaceData<dcomplex> >& data1,
   const std::shared_ptr<pdat::FaceData<dcomplex> >& data2,
   const hier::Box& box,
   const std::shared_ptr<pdat::FaceData<double> >& cvol) const
{
   TBOX_ASSERT(data1 && data2);

   tbox::Dimension::dir_t dimVal = box.getDim().getValue();

   dcomplex retval = dcomplex(0.0, 0.0);
   if (!cvol) {
      for (tbox::Dimension::dir_t d = 0; d < dimVal; ++d) {
         const hier::Box face_box = pdat::FaceGeometry::toFaceBox(box, d);
         retval += d_array_ops.dot(data1->getArrayData(d),
               data2->getArrayData(d),
               face_box);
      }
   } else {
      for (tbox::Dimension::dir_t d = 0; d < dimVal; ++d) {
         const hier::Box face_box = pdat::FaceGeometry::toFaceBox(box, d);
         retval += d_array_ops.dotWithControlVolume(
               data1->getArrayData(d),
               data2->getArrayData(d),
               cvol->getArrayData(d),
               face_box);
      }
   }
   return retval;
}
dcomplex
PatchSideDataNormOpsComplex::integral(
   const boost::shared_ptr<pdat::SideData<dcomplex> >& data,
   const hier::Box& box,
   const boost::shared_ptr<pdat::SideData<double> >& vol) const
{
   TBOX_ASSERT(data);

   int dimVal = box.getDim().getValue();
   dcomplex retval = dcomplex(0.0, 0.0);
   const hier::IntVector& directions = data->getDirectionVector();

   TBOX_ASSERT(directions ==
      hier::IntVector::min(directions, vol->getDirectionVector()));

   for (tbox::Dimension::dir_t d = 0; d < dimVal; ++d) {
      if (directions(d)) {
         retval += d_array_ops.integral(
               data->getArrayData(d),
               vol->getArrayData(d),
               pdat::SideGeometry::toSideBox(box, d));
      }
   }
   return retval;
}
Beispiel #7
0
/*! Complex band solver using ZGBSV
 * 
 * n      Size of the matrix (number of equations)
 * kl     Number of subdiagonals
 * ku     Number of superdiagonals
 * nrhs   Number of RHS vectors to solve
 * ab     Array values (2D array)
 * ldab   Leading dim. size of ab = 2*KL+KU+1
 * ipiv   output integer array containing pivot permutation
 * b      RHS vectors, and solution
 * ldb    length of b (= n)
 * info   output status
 *
 * This code is about 25% faster than NR
 * Timing for 260 points (s): NR: 5.698204e-05, LAPACK: 4.410744e-05
 */
void cband_solve(dcomplex **a, int n, int m1, int m2, dcomplex *b)
{
  int kl, ku, nrhs;
  int ldab, ldb;
  int info;
  
  nrhs = 1;
  kl = m1;
  ku = m2;
  ldab = 2*kl + ku + 1;
  ldb = n;

  static int *ipiv;
  static int len = 0, alen = 0;
  static fcmplx *x, *AB; 

  if(alen < ldab*n) {
    if(alen > 0)
      delete[] AB;
    AB = new fcmplx[ldab*n];
    alen = ldab*n;
  }
  if(len < n) {
    if(len > 0) {
      delete[] ipiv;
      delete[] x;
    }
    
    ipiv = new int[n];
    x = new fcmplx[n];
    len = n;
  }

  // Copy RHS data
  for(int i=0;i<n;i++) {
    x[i].r = b[i].Real();
    x[i].i = b[i].Imag();
  }

  // Put matrix elements into AB(ldab, N) (FORTRAN -> loops over ldab fastest)
  // A is organised into rows, but AB is in columns. First kl not set
  for(int j=0;j<n;j++) {
    for(int i=0;i<=(ku+kl); i++) {
      // AB(kl + i, j) = A[j - ku + i][kl+ku - i]
      
      if( ((j - ku + i) >= 0) && ((j - ku + i) < n) ) {
	AB[j*ldab + kl + i].r = a[j - ku + i][kl+ku - i].Real();
	AB[j*ldab + kl + i].i = a[j - ku + i][kl+ku - i].Imag();
      }
    }
  }

  zgbsv_(&n, &kl, &ku, &nrhs, AB, &ldab, ipiv, x, &ldb, &info);
  
  // Copy result back
  for(int i=0;i<n;i++) {
    b[i] = dcomplex(x[i].r, x[i].i);
  }
}
void EigenSystemSolverRealSymmetricMatrix(const Array2 <doublevar > & Ain, Array1 <doublevar> & evals, Array2 <doublevar> & evecs){
  //returns eigenvalues from largest to lowest and
  //eigenvectors, where for i-th eigenvalue, the eigenvector components are evecs(*,i)
#ifdef USE_LAPACK //if LAPACK
  int N=Ain.dim[0];
  Array2 <doublevar> Ain2(N,N);
  //need to copy the array!!
  Ain2=Ain;
  /* allocate and initialise the matrix */
  Array1 <doublevar> W, Z, WORK;
  Array1 <int> ISUPPZ, IWORK;
  int  M;
  
  /* allocate space for the output parameters and workspace arrays */
  W.Resize(N);
  Z.Resize(N*N);
  ISUPPZ.Resize(2*N);
  WORK.Resize(26*N);
  IWORK.Resize(10*N);

  int info;
  /* get the eigenvalues and eigenvectors */
  info=dsyevr('V', 'A', 'L', N, Ain2.v, N, 0.0, 0.0, 0, 0, dlamch('S'), &M,
         W.v, Z.v, N, ISUPPZ.v, WORK.v, 26*N, IWORK.v, 10*N);
  if(info>0)
    error("Internal error in the LAPACK routine dsyevr");
  if(info<0)
    error("Problem with the input parameter of LAPACK routine dsyevr in position "-info);

  for (int i=0; i<N; i++)
    evals(i)=W[N-1-i];
  for (int i=0; i<N; i++) {
    for (int j=0; j<N; j++) {
      evecs(j,i)=Z[j+(N-1-i)*N];
    }
  }
 //END OF LAPACK 
#else //IF NO LAPACK
  const int n = Ain.dim[0];
  Array2 < dcomplex > Ain_complex(n,n);
  Array2 <dcomplex> evecs_complex(n,n);
  for (int i=0; i < n; i++)
    for (int j=0; j < n; j++) {
      Ain_complex(i,j)=dcomplex(Ain(i,j),0.0);
    }
  Jacobi(Ain_complex, evals, evecs_complex);
   for (int i=0; i < n; i++)
     for (int j=0; j < n; j++){
       evecs(i,j)=real(evecs_complex(i,j));
     }
#endif //END OF NO LAPACK
}
dcomplex
PatchFaceDataNormOpsComplex::integral(
   const std::shared_ptr<pdat::FaceData<dcomplex> >& data,
   const hier::Box& box,
   const std::shared_ptr<pdat::FaceData<double> >& vol) const
{
   TBOX_ASSERT(data);

   tbox::Dimension::dir_t dimVal = box.getDim().getValue();
   dcomplex retval = dcomplex(0.0, 0.0);
   for (tbox::Dimension::dir_t d = 0; d < dimVal; ++d) {
      retval += d_array_ops.integral(data->getArrayData(d),
            vol->getArrayData(d),
            pdat::FaceGeometry::toFaceBox(box, d));
   }
   return retval;
}
void GeneralizedEigenSystemSolverRealGeneralMatrices(Array2 < doublevar > & Ain, 
         Array1 <dcomplex> & W, Array2 <doublevar> & VL, Array2 <doublevar> & VR) { 
#ifdef USE_LAPACK //if LAPACK
  int N=Ain.dim[0];
  
  Array2 <doublevar> A_temp=Ain; //,VL(N,N),VR(N,N);
  Array1 <doublevar> WORK,RWORK(2*N),WI(N),WR(N);
  WI.Resize(N);
  VL.Resize(N,N);
  VR.Resize(N,N);

  int info;
  int NB=64;
  int NMAX=N;
  int lda=NMAX;
  int ldb=NMAX;
  int LWORK=5*NMAX;
  WORK.Resize(LWORK);


  info=  dgeev('V','V',N,A_temp.v, lda,WR.v,WI.v,VL.v,lda,VR.v,lda,WORK.v,LWORK);

  if(info>0)
    error("Internal error in the LAPACK routine dgeev",info);
  if(info<0)
    error("Problem with the input parameter of LAPACK routine dgeev in position ",-info);
  W.Resize(N);
  for(int i=0; i< N; i++) { 
    W(i)=dcomplex(WR(i),WI(i));
  }

//  for (int i=0; i<N; i++)
//    evals(i)=W[N-1-i];

 // for (int i=0; i<N; i++) {
 //   for (int j=0; j<N; j++) {
 //     evecs(j,i)=A_temp(N-1-i,j);
 //   }
 // }
 //END OF LAPACK 
#else //IF NO LAPACK
  error("need LAPACK for eigensystem solver for general matrices");
#endif //END OF NO LAPACK
}
dcomplex
PatchSideDataNormOpsComplex::dot(
   const boost::shared_ptr<pdat::SideData<dcomplex> >& data1,
   const boost::shared_ptr<pdat::SideData<dcomplex> >& data2,
   const hier::Box& box,
   const boost::shared_ptr<pdat::SideData<double> >& cvol) const
{
   TBOX_ASSERT(data1 && data2);
   TBOX_ASSERT(data1->getDirectionVector() == data2->getDirectionVector());

   int dimVal = box.getDim().getValue();

   dcomplex retval = dcomplex(0.0, 0.0);
   const hier::IntVector& directions = data1->getDirectionVector();
   if (!cvol) {
      for (tbox::Dimension::dir_t d = 0; d < dimVal; ++d) {
         if (directions(d)) {
            const hier::Box side_box = pdat::SideGeometry::toSideBox(box, d);
            retval += d_array_ops.dot(data1->getArrayData(d),
                  data2->getArrayData(d),
                  side_box);
         }
      }
   } else {
      TBOX_ASSERT(directions ==
         hier::IntVector::min(directions, cvol->getDirectionVector()));

      for (tbox::Dimension::dir_t d = 0; d < dimVal; ++d) {
         if (directions(d)) {
            const hier::Box side_box = pdat::SideGeometry::toSideBox(box, d);
            retval += d_array_ops.dotWithControlVolume(
                  data1->getArrayData(d),
                  data2->getArrayData(d),
                  cvol->getArrayData(d),
                  side_box);
         }
      }
   }
   return retval;
}
Beispiel #12
0
    //*************************************************TERM 1*************************************************
    //brute force sum
    dcomplex Zetafunc::term1full(const double q2){
        dcomplex result(0.,0.),tmpcomp;
        double fact,rsq,theta,phi;
        threevec<double> nvec,npar,nperp,rvec;
            
        double resultre=0.,resultim=0.;
#pragma omp parallel for reduction(+:resultre) reduction(+:resultim) private(rvec,rsq,theta,phi,nvec,fact,tmpcomp,npar,nperp)
        for(int z=-MAXRUN; z<=MAXRUN; z++){
            for(int y=-MAXRUN; y<=MAXRUN; y++){
                for(int x=-MAXRUN; x<=MAXRUN; x++){
                    nvec(static_cast<double>(x),static_cast<double>(y),static_cast<double>(z));
                    
                    //compute r:
                    if(!is_zeroboost){
                        orthogonal_projection(nvec,boost,npar,nperp);
                        rvec=npar/gamma-boost/(2.*gamma)+nperp;
                    }
                    else{
                        rvec=nvec;
                    }
                    rvec.get_spherical_coordinates(rsq,theta,phi);
                    if(l!=0)fact=::std::pow(rsq,l); //compute |r|^l
                    else fact=1.;
                    rsq*=rsq; //compute r^2
                    
                    //compute prefact:
                    fact*=::std::exp(-lambda*(rsq-q2))/(rsq-q2); //compute the ratio
                    tmpcomp=fact*spherical_harmonicy(l,m,theta,phi); //multiply with spherical harmonics
                    resultre+=tmpcomp.re();
                    resultim+=tmpcomp.im();
                    //result+=tmpcomp;
                }
            }
        }
        result=dcomplex(resultre,resultim);
        
        return result;
    }
Beispiel #13
0
bool trianglematrix1(dyn_matrix& A, dcomplex *x, int n){
	for(int i = 0 ; i < n ; i++){
		transf1(A,x,i,n);
		dcomplex A_d = A[i][i];
		if(abs(A_d) < 1E-20) return false;

		for(int p = i; p < n; p++){
			A[i][p] /= A_d;
		}
		x[i] /= A_d;

		for(int j = i + 1; j < n; j++){
			dcomplex A_j = A[j][i];
			if(A_j != dcomplex(0, 0)){
				for(int k = i; k < n; k++)
					A[j][k] -= A[i][k]*A_j;
				x[j] -= x[i]*A_j;

			}
		}
	}
	return true;
}
Beispiel #14
0
//----------------------------------------------------------------------
void Average_ekt::write_summary(Average_return &avg,Average_return &err, ostream & os) { 

  Array2 <dcomplex> obdm_up(nmo,nmo),obdm_down(nmo,nmo), 
         obdm_up_err(nmo,nmo),obdm_down_err(nmo,nmo), 
         cndc_up(nmo, nmo), cndc_down(nmo, nmo),
         vlnc_up(nmo, nmo), vlnc_down(nmo, nmo), 
         cndc_up_err(nmo, nmo), cndc_down_err(nmo, nmo), 
         vlnc_up_err(nmo, nmo), vlnc_down_err(nmo, nmo); 
  //Array4 <dcomplex>
  //       tbdm_uu(nmo,nmo),tbdm_uu_err(nmo,nmo),
  //      tbdm_ud(nmo,nmo),tbdm_ud_err(nmo,nmo),
  //      tbdm_du(nmo,nmo),tbdm_du_err(nmo,nmo),
  //      tbdm_dd(nmo,nmo),tbdm_dd_err(nmo,nmo);

  os << "EKT: nmo " << nmo << endl;
  os << "EKT: states { ";
  for(int i=0; i< nmo; i++) { 
    os << occupations[0][i]+1 << " " ;
  }
  os << " } \n";
  os << "Orbital normalization " << endl;
  for(int i=0; i< nmo; i++) { 
    os << avg.vals(i) << " +/- " << err.vals(i) << endl;
  }

  // for(int i=0; i < nmo; i++) { 
  //   avg.vals(i)=1.0/nmo; //assume that the orbitals are normalized.
  // }

  if (eval_obdm) {
    dcomplex i_c(0.,1.);
    int place=0;
    for(int i=0; i < nmo; i++) { 
      for(int j=0; j < nmo; j++)  { 
        doublevar norm=sqrt(avg.vals(i)*avg.vals(j));
        int index=nmo + place;
        obdm_up(i,j)=dcomplex(avg.vals(index),avg.vals(index+1))/norm;
        obdm_up_err(i,j)=dcomplex(err.vals(index),err.vals(index+1))/norm;

        index+=2*nmo*nmo;
        obdm_down(i,j)=dcomplex(avg.vals(index),avg.vals(index+1))/norm;
        obdm_down_err(i,j)=dcomplex(err.vals(index),err.vals(index+1))/norm;
        place+=2;
      }
    }

    os << "One-body density matrix " << endl;
    int colwidth=40;
    if(!complex_orbitals) colwidth=20;
    os << setw(10) << " " << setw(10) << " "
      << setw(colwidth) << "up" << setw(colwidth) << "up err"
      << setw(colwidth) << "down" << setw(colwidth) << "down err"
      << endl;
    for(int i=0; i< nmo ; i++) { 
      for(int j=0; j<nmo; j++) { 
        if(complex_orbitals) { 
          os << setw(10) << i << setw(10) << j
            << setw(colwidth) << obdm_up(i,j) << setw(colwidth) << obdm_up_err(i,j)
            << setw(colwidth) << obdm_down(i,j) << setw(colwidth) << obdm_down_err(i,j)
            << endl;
        }
        else { 
          os << setw(10) << i << setw(10) << j
            << setw(colwidth) << obdm_up(i,j).real() 
            << setw(colwidth) << obdm_up_err(i,j).real()
            << setw(colwidth) << obdm_down(i,j).real() 
            << setw(colwidth) << obdm_down_err(i,j).real()
            << endl;

        }
      }

    }
  }

  if (eval_valence) {
    dcomplex i_c(0.,1.);
    int place=0;
    for(int i=0; i < nmo; i++) { 
      for(int j=0; j < nmo; j++)  { 
        doublevar norm=sqrt(avg.vals(i)*avg.vals(j));
        int index=nmo+4*nmo*nmo + place;
        vlnc_up(i,j)=dcomplex(avg.vals(index),avg.vals(index+1))/norm;
        vlnc_up_err(i,j)=dcomplex(err.vals(index),err.vals(index+1))/norm;

        index+=2*nmo*nmo;
        vlnc_down(i,j)=dcomplex(avg.vals(index),avg.vals(index+1))/norm;
        vlnc_down_err(i,j)=dcomplex(err.vals(index),err.vals(index+1))/norm;
        place+=2;
      }
    }

    os << "Valence band matrix " << endl;
    int colwidth=40;
    if(!complex_orbitals) colwidth=20;
    os << setw(10) << " " << setw(10) << " "
      << setw(colwidth) << "up" << setw(colwidth) << "up err"
      << setw(colwidth) << "down" << setw(colwidth) << "down err"
      << endl;
    for(int i=0; i< nmo ; i++) { 
      for(int j=0; j<nmo; j++) { 
        if(complex_orbitals) { 
          os << setw(10) << i << setw(10) << j
            << setw(colwidth) << vlnc_up(i,j) << setw(colwidth) << vlnc_up_err(i,j)
            << setw(colwidth) << vlnc_down(i,j) << setw(colwidth) << vlnc_down_err(i,j)
            << endl;
        }
        else { 
          os << setw(10) << i << setw(10) << j
            << setw(colwidth) << vlnc_up(i,j).real() 
            << setw(colwidth) << vlnc_up_err(i,j).real()
            << setw(colwidth) << vlnc_down(i,j).real() 
            << setw(colwidth) << vlnc_down_err(i,j).real()
            << endl;

        }
      }

    }
  }

  if (eval_conduction) {
    dcomplex i_c(0.,1.);
    int place=0;
    for(int i=0; i < nmo; i++) { 
      for(int j=0; j < nmo; j++)  { 
        doublevar norm=sqrt(avg.vals(i)*avg.vals(j));
        int index=nmo + 8*nmo*nmo + place;
        cndc_up(i,j)=dcomplex(avg.vals(index),avg.vals(index+1))/norm;
        cndc_up_err(i,j)=dcomplex(err.vals(index),err.vals(index+1))/norm;

        index+=2*nmo*nmo;
        cndc_down(i,j)=dcomplex(avg.vals(index),avg.vals(index+1))/norm;
        cndc_down_err(i,j)=dcomplex(err.vals(index),err.vals(index+1))/norm;
        place+=2;
      }
    }

    os << "Conduction band matrix " << endl;
    int colwidth=40;
    if(!complex_orbitals) colwidth=20;
    os << setw(10) << " " << setw(10) << " "
      << setw(colwidth) << "up" << setw(colwidth) << "up err"
      << setw(colwidth) << "down" << setw(colwidth) << "down err"
      << endl;
    for(int i=0; i< nmo ; i++) { 
      for(int j=0; j<nmo; j++) { 
        if(complex_orbitals) { 
          os << setw(10) << i << setw(10) << j
            << setw(colwidth) << cndc_up(i,j) << setw(colwidth) << cndc_up_err(i,j)
            << setw(colwidth) << cndc_down(i,j) << setw(colwidth) << cndc_down_err(i,j)
            << endl;
        }
        else { 
          os << setw(10) << i << setw(10) << j
            << setw(colwidth) << cndc_up(i,j).real() 
            << setw(colwidth) << cndc_up_err(i,j).real()
            << setw(colwidth) << cndc_down(i,j).real() 
            << setw(colwidth) << cndc_down_err(i,j).real()
            << endl;

        }
      }

    }
  }
  /*
     totnelectrons = 2; 
     cout << "Ntot: " << totnelectrons << endl; 
     for(int i=0; i < totnelectrons; i++) { 
     cout << "Kin: " << i << " " << avg.vals(nmo + 12*nmo*nmo + i) << "+/-" << err.vals(nmo + 12*nmo*nmo + i) << endl; 
     cout << "Pot: " << i << " " << avg.vals(nmo + 12*nmo*nmo + totnelectrons + i) << "+/-" << err.vals(nmo + 12*nmo*nmo + totnelectrons + i) << endl; 
     }*/


  dcomplex trace=0;
  for(int i=0;i< nmo; i++) trace+=obdm_up(i,i);
  os << "Trace of the obdm: up: " << trace;
  trace=0;
  for(int i=0; i< nmo; i++) trace+=obdm_down(i,i);
  os << " down: " << trace << endl;
}
Beispiel #15
0
void Average_ekt::evaluate_obdm(Wavefunction_data * wfdata, Wavefunction * wf,
    System * sys, Sample_point * sample, Average_return & avg) { 


  wf->updateVal(wfdata,sample);
  Wf_return wfval_base(wf->nfunc(),2);
  wf->getVal(wfdata,0,wfval_base);
  int nup=sys->nelectrons(0);
  int ndown=sys->nelectrons(1);
  int nelectrons=nup+ndown;

  Array1 <Array2 <dcomplex> > movals1_base(nelectrons);
  for(int e=0; e< nelectrons; e++) { 
    movals1_base(e).Resize(nmo,1);
    calc_mos(sample,e,movals1_base(e));
    /*! Huihuo
      Here, permutation symmetry has been applied, the real evaluation quantity is 
      sum_(e=1)^N phi_i* (r_e) phi_j(r') psi(r_1,... r',...r_N)/psi(r_1, ..., r_n, ..., r_N)
      Therefore, movals1_base[e, i] = phi_i(r_e), where e is the index of the electron. 
      !!!One need to be careful about the off-gamma point 1 RDM 
      */
  }
  //  avg.vals.Resize(nmo+4*nmo*nmo);
  //  avg.vals=0;

  Array2 <dcomplex> movals1(nmo,1);
  Array1 <Wf_return> wfs(nelectrons);

  Wavefunction_storage * store;
  wf->generateStorage(store);
  for(int i=0; i< npoints_eval; i++) { 
    Array1 <doublevar> oldpos(3);
    sample->getElectronPos(0,oldpos);
    sample->setElectronPosNoNotify(0,saved_r(i));
    calc_mos(sample,0,movals1);
    /*!
      This is simply to calculate phi_j(r'): Noted that r' has been given, therefore, movals1 is a one dimentional array, with matrix element to be 
      phi_j(r') -- j is the index 
      */
    sample->setElectronPosNoNotify(0,oldpos);

    Array1 <Wf_return> wf_eval;
    wf->evalTestPos(saved_r(i),sample,wfs);

    //Testing the evalTestPos
    //for(int e=0; e< nelectrons; e++) { 
    //  Wf_return test_wf(wf->nfunc(),2);
    //  sample->getElectronPos(e,oldpos);
    //  wf->saveUpdate(sample,e,store);
    //  sample->setElectronPos(e,saved_r(i));
    //  wf->updateVal(wfdata,sample);
    //  wf->getVal(wfdata,e,test_wf);
    //  sample->setElectronPos(e,oldpos);
    //  wf->restoreUpdate(sample,e,store);
    //  cout << "e " << e << " test " << test_wf.amp(0,0) << " evalTestPos " << wfs(e).amp(0,0) << endl;
    //}

    doublevar dist1=0;
    for(int m=0; m < nmo; m++) 
      dist1+=norm(movals1(m,0));

    for(int orbnum=0; orbnum < nmo; orbnum++) { 
      avg.vals(orbnum)+=norm(movals1(orbnum,0))/(dist1*npoints_eval);
    }

    for(int e=0; e< nelectrons; e++) { 
      dcomplex psiratio_1b=exp(dcomplex(wfs(e).amp(0,0)-wfval_base.amp(0,0),
            wfs(e).phase(0,0)-wfval_base.phase(0,0)));
      /*!
        psi(r_1,...,r',...,r_N)/psi(r_1,...,r_e,...,r_N), the ratio of the new with respect to the old if one change the position of the e-th electron from 
        r_e to r'
        */
      int which_obdm=0;
      if(e >= nup) { which_obdm=1;  } 
      dcomplex tmp;
      int place=0;
      dcomplex prefactor=psiratio_1b/(dist1*npoints_eval);
      for(int orbnum=0; orbnum < nmo; orbnum++) { 
        for(int orbnum2=0; orbnum2 < nmo; orbnum2++) { 
          //tmp=movals1(orbnum,0)*conj(movals1_base(e)(orbnum2,0))*prefactor;
          /*! Huihuo Zheng
            This is to based on my new definition: 
            \rho(r, r') = N\int dR psi*(r, R) psi(r', R) = \sum rho_{ij} phi_i*(r) phi_j(r')
            in this way, one will find that, the phase factor is cancelled
            */
          tmp=conj(movals1(orbnum,0))*movals1_base(e)(orbnum2,0)*prefactor;
          avg.vals(nmo+2*which_obdm*nmo*nmo+place)+=tmp.real();
          avg.vals(nmo+2*which_obdm*nmo*nmo+place+1)+=tmp.imag();

          place+=2;
        }
      }

    }
  }
  delete store;
}
Beispiel #16
0
void Average_ekt::evaluate_valence(Wavefunction_data * wfdata, Wavefunction * wf,
    System * sys, Pseudopotential *psp, Sample_point * sample, Average_return & avg) { 
  /*
     This is to evaluate the v_ij in extended Koopmans' theorem -- for valence bands
     */
  wf->updateVal(wfdata,sample);
  Wf_return wfval_base(wf->nfunc(),2);
  wf->getVal(wfdata,0,wfval_base);
  int nup=sys->nelectrons(0);
  int ndown=sys->nelectrons(1);
  int nelectrons=nup+ndown;

  Array1 <doublevar> rn(3), rnp(3), rnpp(3); 
  Array1 <Array2 <dcomplex> > movals1_base(nelectrons);
  Array2 <dcomplex> movals_p(nmo, 1); 
  Array1 <doublevar> VLoc(nelectrons); 
  Array1 <doublevar> VLoc0(nelectrons);
  Array1 <doublevar> Vtest(nelectrons+1);
  Array1 <dcomplex> pseudo_t(nmo); 
  /***************************************
    Routines to get Kin and Vloc
   ****************************************/
  Array2<doublevar> Kin(nelectrons, wf->nfunc());
  //Array2<doublevar> Kin0(nelectrons, wf->nfunc());
  Array2<dcomplex> movals_lap(nmo, 5);
  for(int e=0; e< nelectrons; e++) { 
    movals1_base(e).Resize(nmo,1);
    //Kin(e).Resize(1); //The Kinetic energy 
    calc_mos(sample, e, movals1_base(e));
  }
//  sys->calcKineticSeparated(sample,saved_r(i),Kin);

  //***** calculate kinetic energy and potential energy
  sys->calcKineticSeparated(wfdata, sample, wf, Kin); 
  sys->calcLocSeparated(sample, VLoc);

  Array1 <Wf_return> wfs(nelectrons);

  Wavefunction_storage * store;
  wf->generateStorage(store);
  for(int i=0; i< npoints_eval; i++) {
    Array1 <doublevar> oldpos(3);
    sample->getElectronPos(0,oldpos);
    sample->setElectronPosNoNotify(0, saved_r(i));
    calc_mosLap(sample, 0, movals_lap);
    int nrandvar=psp->nTest();
    Array1 <doublevar> rand_num(nrandvar);
    for(int l=0; l< nrandvar; l++) 
      rand_num(l)=rng.ulec();
    calc_mos(sample,0,movals_p);

    calcPseudoMo(sys, sample, psp, rand_num, pseudo_t);
    sample->setElectronPosNoNotify(0,oldpos);
    Array1 <Wf_return> wf_eval;
    wf->evalTestPos(saved_r(i),sample,wfs);
    sys->calcLocWithTestPos(sample, saved_r(i), Vtest);

    doublevar vtot = 0.0;
    for (int e=0; e<nelectrons; e++) {
      vtot += Vtest(e);
    }
    doublevar dist1=0;
    for(int m=0; m < nmo; m++)
      dist1+=norm(movals_p(m,0));
    
    for(int orbnum=0; orbnum < nmo; orbnum++) {
      avg.vals(orbnum)+=norm(movals_p(orbnum,0))/(dist1*npoints_eval);//this is the normalization
    }
    
    Array2<doublevar> totalv(nelectrons, wf->nfunc());
    totalv = 0.0;
    psp->calcNonlocSeparated(wfdata, sys, sample, wf, totalv);
    
    int place = 0;
    for (int orbnum = 0; orbnum < nmo; orbnum++ ) {
      for (int orbnum2 = 0; orbnum2 < nmo; orbnum2++ ) {
        dcomplex tmp3=conj(movals_p(orbnum, 0))*
                    (pseudo_t(orbnum2) +
                     Vtest(nelectrons)*movals_p(orbnum2, 0)
                      -0.5*movals_lap(orbnum2, 4)
                     +movals_p(orbnum2, 0)*vtot)
                /(dist1*npoints_eval);
        //	tmp3=conj(movals_p(orbnum, 0))*(movals_p(orbnum2, 0))/(dist1*npoints_eval);
        //dcomplex tmp3=conj(movals_p(orbnum, 0))*(pseudo_t(orbnum2))/(dist1*npoints_eval);
        int which_obdm = 0;
        avg.vals(nmo+8*nmo*nmo + 2*which_obdm*nmo*nmo+place) += tmp3.real();
        avg.vals(nmo+8*nmo*nmo + 2*which_obdm*nmo*nmo+place+1) += tmp3.imag();
        
        which_obdm = 1;
        //tmp3=conj(movals_p(orbnum, 0))*(-0.5*movals_lap(orbnum2, 4))/(dist1*npoints_eval);
        avg.vals(nmo+8*nmo*nmo + 2*which_obdm*nmo*nmo+place) += tmp3.real();
        avg.vals(nmo+8*nmo*nmo + 2*which_obdm*nmo*nmo+place+1) += tmp3.imag();
        place += 2;
      }
    }
    ofstream dump;
    if(dump_data) {
      dump.open("EKT_DUMP",ios::app);
    }
    for(int e=0; e< nelectrons; e++) {
      dcomplex psiratio_1b=conj(exp(dcomplex(wfs(e).amp(0,0)
                                             -wfval_base.amp(0,0),
                                             wfs(e).phase(0,0)
                                             -wfval_base.phase(0,0))));
      int which_obdm=0;
      if(e >= nup) { which_obdm=1;  }
      dcomplex tmp, tmp2, tmp3;
      int place=0;
      dcomplex prefactor=psiratio_1b/(dist1*npoints_eval);
      //cout << "Local potential" << "   Kinetic" << "   Pseudo" << endl;
      //      cout << VLoc(e) << "  " << Kin(e, 0) << "  " << totalv(e, 0) << endl;
      
      for(int orbnum=0; orbnum < nmo; orbnum++) {
        for(int orbnum2=0; orbnum2 < nmo; orbnum2++) {
          //	  assert(wf->nfunc()==1);
          tmp = 0.5*(movals_p(orbnum,0)*conj(movals1_base(e)(orbnum2,0))*prefactor
                     + movals1_base(e)(orbnum, 0)*conj(movals_p(orbnum2, 0))*conj(prefactor));
          tmp2 = tmp*(VLoc(e) + Kin(e, 0) + totalv(e, 0));
          //rho_ij part the one body reduced density matrix
          doublevar tmp2_mag=abs(tmp2);
          if(tmp2_mag > ekt_cutoff) {
            tmp2*=ekt_cutoff/tmp2_mag;
          }
          avg.vals(nmo+2*which_obdm*nmo*nmo+place) += tmp.real();
          avg.vals(nmo+2*which_obdm*nmo*nmo+place+1) += tmp.imag();
          //v_ij^v part
          //tmp3 = 0.0;
          avg.vals(nmo+4*nmo*nmo + 2*which_obdm*nmo*nmo+place)+=tmp2.real();
          avg.vals(nmo+4*nmo*nmo + 2*which_obdm*nmo*nmo+place+1)+=tmp2.imag();
          if(dump_data) {
            if(orbnum==orbnum2 and orbnum==0) {
              sample->getElectronPos(e,oldpos);
              dump << which_obdm << "," << tmp2.real() << "," << tmp.real() << ","
                 << VLoc(e) << "," << Kin(e,0) << "," << totalv(e,0) <<
               "," << oldpos(0) << "," << oldpos(1) << "," << oldpos(2) << endl;
            }
          }
          if (eval_conduction) {
            //tmp3 = -1.0*psiratio_1b*conj(movals1_base(e)(orbnum, 0))*(vtot*movals_lap(orbnum2, 0)
            //						 + pseudo_t(orbnum2) - 0.5*movals_lap(orbnum2, 4) + Vtest(nelectrons)*movals_lap(orbnum2, 0))/(dist1*npoints_eval);
            tmp3 = -1.0*conj(movals1_base(e)(orbnum, 0))*movals_p(orbnum2, 0)*prefactor*(VLoc(e) + Kin(e, 0) + totalv(e, 0) + Vtest(e));
            doublevar tmp3_mag=abs(tmp3);
            if(tmp3_mag > ekt_cutoff) {
              tmp3*=ekt_cutoff/tmp3_mag;
            }
            avg.vals(nmo+8*nmo*nmo + 2*which_obdm*nmo*nmo+place) += tmp3.real();
            avg.vals(nmo+8*nmo*nmo + 2*which_obdm*nmo*nmo+place+1) += tmp3.imag();
          }
          place+=2;
        }
      }
    }
  }
  delete store;
}
Beispiel #17
0
    dcomplex Zetafunc::term3noboost(const double q2){
        dcomplex result(0.,0.),sphfact,tmpcomp;
        double tmp,r,theta,phi;
        
        //zero term is zero:
        result=dcomplex(0.,0.);
        
        //line terms
        //x>0, y=z=0 and y>0, x=z=0 and z>0, x=y=0:
        //note that z->-z is equivalent to theta->pi-theta, similar to this: x->-x yields phi->pi-phi and y->-y is phi->2pi-phi
        sphfact=    spherical_harmonicy(l,m,pimath/2.   ,   0.);                                //x>0
        sphfact+=   spherical_harmonicy(l,m,pimath/2.   ,   pimath);                            //x<0
        sphfact+=   spherical_harmonicy(l,m,pimath/2.   ,   pimath/2.);                         //y>0
        sphfact+=   spherical_harmonicy(l,m,pimath/2.   ,   3.*pimath/2.);                      //y<0
        sphfact+=   spherical_harmonicy(l,m,0.          ,   0.);                                //z>0
        sphfact+=   spherical_harmonicy(l,m,pimath      ,   0.);                                //z<0
        
        double resultre=0., resultim=0.;
#pragma omp parallel
        {
            Zetafuncint integrand2;
#pragma omp parallel for reduction(+:resultre) private(tmp)
            for(int x=1; x<=MAXRUN; x++){
                integrand2.set(q2,x,l);
                Midpnt<TFunctor> int2(integrand2,0.,lambda);
                tmp=qromo(int2);
                if(l!=0) tmp*=::std::pow(x,static_cast<double>(l));
                resultre+=tmp;
            }
        }
        result+=resultre*sphfact;
        
        
        //plane-terms
        resultre=0.;
        resultim=0.;
        double* integrals=new double[MAXRUN*MAXRUN];
#pragma omp parallel
        {
            Zetafuncint integrand2;
            //do integrals first:
#pragma omp parallel for shared(integrals) private(r,theta,phi,tmp)
            for(int y=1; y<=MAXRUN; y++){
                for(int x=y; x<=MAXRUN; x++){
                    threevec<int>(x,y,0).get_spherical_coordinates(r,theta,phi);
                    
                    //integral
                    integrand2.set(q2,r,l);
                    Midpnt<TFunctor> int2(integrand2,0.,lambda);
                    tmp=qromo(int2);
                    if(l!=0) tmp*=::std::pow(r,static_cast<double>(l));
                    
                    //store results: it is symmetrc in x and y:
                    integrals[x-1+MAXRUN*(y-1)]=tmp;
                    integrals[y-1+MAXRUN*(x-1)]=tmp;
                }
            }
            
            //angular parts
            //x,y!>0, z=0:
            //the four ylm account for the possibilities +/+, +/-, -/+, -/-:
#pragma omp parallel for reduction(+:resultre) reduction(+:resultim) shared(integrals) private(r,theta,phi,tmp,tmpcomp)
            for(int y=1; y<=MAXRUN; y++){
                for(int x=1; x<=MAXRUN; x++){
                    threevec<int>(x,y,0).get_spherical_coordinates(r,theta,phi);
                    
                    //z=0:
                    sphfact=    spherical_harmonicy(l,m,theta   ,   phi);                           //x,y>0
                    sphfact+=   spherical_harmonicy(l,m,theta   ,   pimath-phi);                    //x<0,y>0
                    sphfact+=   spherical_harmonicy(l,m,theta   ,   pimath+phi);                    //x,y<0
                    sphfact+=   spherical_harmonicy(l,m,theta   ,   2.*pimath-phi);                 //x>0,y<0
                    
                    //result
                    tmpcomp=integrals[y-1+MAXRUN*(x-1)]*sphfact;
                    resultre+=tmpcomp.re();
                    resultre+=tmpcomp.im();
                }
            }
        
            //x,z>0, y=0 and y,z>0, x=0:
#pragma omp parallel for reduction(+:resultre) reduction(+:resultim) shared(integrals) private(r,theta,phi,tmp,tmpcomp)
            for(int z=1; z<=MAXRUN; z++){
                for(int x=1; x<=MAXRUN; x++){
                    threevec<int>(x,0,z).get_spherical_coordinates(r,theta,phi);
                    
                    //y=0:
                    sphfact=    spherical_harmonicy(l,m,theta          ,    0);                    //x,z>0
                    sphfact+=   spherical_harmonicy(l,m,pimath-theta   ,    0);                    //x>0,z<0
                    sphfact+=   spherical_harmonicy(l,m,theta          ,    pimath);               //x<0,z>0
                    sphfact+=   spherical_harmonicy(l,m,pimath-theta   ,    pimath);               //x,z<0
                    //x=0:
                    sphfact+=   spherical_harmonicy(l,m,theta          ,    pimath/2.);            //y,z>0
                    sphfact+=   spherical_harmonicy(l,m,pimath-theta   ,    pimath/2.);            //y>0,z<0
                    sphfact+=   spherical_harmonicy(l,m,theta          ,    3.*pimath/2.);         //y<0,z>0
                    sphfact+=   spherical_harmonicy(l,m,pimath-theta   ,    3.*pimath/2.);         //y,z<0
                    
                    //result:
                    tmpcomp=integrals[z-1+MAXRUN*(x-1)]*sphfact;
                    resultre+=tmpcomp.re();
                    resultre+=tmpcomp.im();
                }
            }
        }
        delete [] integrals;
        result+=dcomplex(resultre,resultim);
        
        
        //cubic terms:
        resultre=0.;
        resultim=0.;
        integrals=new double[MAXRUN*MAXRUN*MAXRUN];
#pragma omp parallel
        {
            //do integrals first
            Zetafuncint integrand2;
#pragma omp parallel for shared(integrals) private(r,theta,phi,tmp)
            for(int z=1; z<=MAXRUN; z++){
                for(int y=z; y<=MAXRUN; y++){
                    for(int x=y; x<=MAXRUN; x++){
                        threevec<int>(x,y,z).get_spherical_coordinates(r,theta,phi);
                        
                        //integral
                        integrand2.set(q2,r,l);
                        Midpnt<TFunctor> int2(integrand2,0.,lambda);
                        tmp=qromo(int2);
                        if(l!=0) tmp*=::std::pow(r,static_cast<double>(l));
                        
                        //store results: it is symmetrc in x and y:
                        integrals[x-1+MAXRUN*((y-1)+MAXRUN*(z-1))]=tmp;
                        integrals[z-1+MAXRUN*((x-1)+MAXRUN*(y-1))]=tmp;
                        integrals[y-1+MAXRUN*((z-1)+MAXRUN*(x-1))]=tmp;
                    }
                }
            }

#pragma omp parallel for reduction(+:resultre) reduction(+:resultim) shared(integrals) private(r,theta,phi,tmpcomp)
            for(int z=1; z<=MAXRUN; z++){
                for(int y=1; y<=MAXRUN; y++){
                    for(int x=1; x<=MAXRUN; x++){
                        threevec<int>(x,y,z).get_spherical_coordinates(r,theta,phi);
                        
                        //compute sphfact: account for all possible orientations
                        sphfact=dcomplex(0.,0.);
                        for(unsigned int thetaa=0; thetaa<2; thetaa++){
                            sphfact+=spherical_harmonicy(l,m,static_cast<double>(thetaa)*pimath-theta,phi);            //x,y>0
                            sphfact+=spherical_harmonicy(l,m,static_cast<double>(thetaa)*pimath-theta,pimath-phi);     //x<0,y>0
                            sphfact+=spherical_harmonicy(l,m,static_cast<double>(thetaa)*pimath-theta,pimath+phi);     //x,y<0
                            sphfact+=spherical_harmonicy(l,m,static_cast<double>(thetaa)*pimath-theta,2.*pimath-phi);  //x>0,y<0
                        }
                        
                        //compute the result:
                        tmpcomp=integrals[x-1+MAXRUN*((y-1)+MAXRUN*(z-1))]*sphfact; //integral * ylm factor
                        resultre+=tmpcomp.re();
                        resultim+=tmpcomp.im();
                    }
                }
            }
        }
        delete [] integrals;
        result+=dcomplex(resultre,resultim);
        
        //multiply result by factor:
        result*=::std::pow(pimath,static_cast<double>(1.5+l));
        
        return result;
    }
Beispiel #18
0
/// Use LAPACK routine ZGTSV. About 25% slower than the simple NR routine for 260 points
int tridag(const dcomplex *a, const dcomplex *b, const dcomplex *c, const dcomplex *r, dcomplex *u, int n)
{
  int nrhs = 1;
  int info;

  // Lapack routines overwrite their inputs, so need to copy
  static int len = 0;
  static fcmplx *dl, *d, *du, *x;

  if(n > len) {
    // Allocate more memory (as a single block)
    if(len > 0)
      delete[] dl;

    dl = new fcmplx[4*n];
    d = dl + n;
    du = d + n;
    x = du + n;
    
    len = n;
  }

  for(int i=0;i<n;i++) {
    // Diagonal
    d[i].r = b[i].Real();
    d[i].i = b[i].Imag();
    
    // Off-diagonal terms
    if(i != (n-1)) {
      dl[i].r = a[i+1].Real();
      dl[i].i = a[i+1].Imag();
      
      du[i].r = c[i].Real();
      du[i].i = c[i].Imag();
    }

    x[i].r = r[i].Real();
    x[i].i = r[i].Imag();
  }

  /* LAPACK ZGTSV routine.
     
     n - Size of the array 
     nrhs - Number of RHS vectors to solve
     dl - lower band
     d - diagonal values
     du - upper band
     x  - input and output values
     info - output status
  */

  zgtsv_(&n, &nrhs, dl, d, du, x, &n, &info);

  if(info != 0) {
    // Some sort of problem
    output.write("Problem in LAPACK ZGTSV routine\n");
    return 1;
  }

  // Copy result back
  for(int i=0;i<n;i++) {
    u[i] = dcomplex(x[i].r, x[i].i);
  }

  return 0;
}
//----------------------------------------------------------------------
void Wannier_method::calculate_overlap(Array1 <int> & orb_list,
                                       Array3 <dcomplex> & eikr, Array2 <doublevar> & phi2phi2) {


    Array1 <Array1 <int> > tmp_list(1);
    tmp_list(0)=orb_list;
    mymomat->buildLists(tmp_list);
    int list=0;

    Array2 <doublevar>  gvec(3,3);
    if(!sys->getPrimRecipLattice(gvec) ) error("Need getPrimRecipLattice");

    int norb=orb_list.GetDim(0);
    eikr.Resize(3,norb,norb);
    phi2phi2.Resize(norb,norb);
    eikr=0.0;
    phi2phi2=0.0;

    Array1 <doublevar> prop(3);
    Array1 <doublevar> n_lat(3);
    n_lat=0.0;
    for(int d=0; d < 3; d++) {
        for(int d1=0; d1 < 3; d1++)
            n_lat(d)+=LatticeVec(d,d1)*LatticeVec(d,d1);
        n_lat(d)=sqrt(n_lat(d));
        prop(d)=resolution/double(n_lat(d));
        //cout << "prop " << prop(d) <<  " res " << resolution << " norm " << n_lat(d) << endl;
    }

    cout << "calculating...." << endl;
    mymovals.Resize(norb,1);
    Array1 <doublevar> r(3),x(3);
    Array1 <doublevar> norm_orb(norb);
    norm_orb=0.0;
    int totpts=0;
    for(r(0)=origin(0); r(0) < 1.0; r(0)+=prop(0)) {
        cout << "percent done: " << r(0)*100 << endl;
        for(r(1)=origin(1); r(1) < 1.0; r(1)+=prop(1)) {
            for(r(2)=origin(2); r(2) < 1.0; r(2)+=prop(2)) {

                totpts++;
                for(int d=0; d< 3; d++) {
                    x(d)=0.0;
                    for(int d1=0; d1 < 3; d1++) {
                        x(d)+=r(d1)*LatticeVec(d1,d);
                    }
                }

                mywalker->setElectronPos(0,x);
                mymomat->updateVal(mywalker,0,list,mymovals);
                for(int i=0; i < norb; i++) norm_orb(i)+=mymovals(i,0)*mymovals(i,0);
                for(int d=0; d< 3; d++) {
                    doublevar gdotr=0;
                    for(int d1=0; d1 < 3; d1++) {
                        gdotr+=gvec(d,d1)*x(d1);
                    }
                    dcomplex exp_tmp=exp(dcomplex(0,-1)*2.*pi*gdotr);
                    for(int i=0; i< norb; i++) {
                        for(int j=0; j< norb; j++) {
                            eikr(d,i,j)+=exp_tmp*mymovals(i,0)*mymovals(j,0);
                        }
                    }
                }
                for(int i=0; i< norb; i++) {
                    for(int j=0; j< norb; j++) {
                        phi2phi2(i,j)+=mymovals(i,0)*mymovals(i,0)*mymovals(j,0)*mymovals(j,0);
                    }
                }
            }
        }
    }

    for(int i=0; i< norb; i++) norm_orb(i)=sqrt(norm_orb(i));

    for(int d=0; d< 3; d++) {
        for(int i=0; i < norb; i++) {
            for(int j=0; j< norb; j++) {
                eikr(d,i,j)/=norm_orb(i)*norm_orb(j);
                //cout << d << " " << i << " " <<  j << " " << eikr(d,i,j) << endl;
            }
        }
    }
    cout << "square overlap " << endl;
    for(int i=0; i < norb; i++) {
        for(int j=0; j< norb; j++) {
            phi2phi2(i,j)/=(norm_orb(i)*norm_orb(i)*norm_orb(j)*norm_orb(j));
            cout << sqrt(phi2phi2(i,j)) << " ";
        }
        cout << endl;
    }


}
//A is an antisymmetric matrix and B is the output rotation matrix
void make_rotation_matrix_notworking(const Array2 <doublevar> & A,
                                     Array2 <doublevar> & B) {
    int n=A.GetDim(0);
    assert(A.GetDim(1)==n);
    B.Resize(n,n);

    Array2 <dcomplex> skew(n,n),VL(n,n),VR(n,n);
    Array1 <dcomplex> evals(n);
    for(int i=0; i< n; i++) {
        for(int j=0; j < n; j++) {
            skew(i,j)=A(i,j);
        }
    }
    GeneralizedEigenSystemSolverComplexGeneralMatrices(skew,evals,VL,VR);

    cout << "evals " << endl;
    for(int i=0; i< n; i++) cout << evals(i) << " ";
    cout << endl;
    cout << "VR " << endl;
    for(int i=0; i< n; i++) {
        for(int j=0; j< n; j++) {
            cout << VR(i,j) << " ";
        }
        cout << endl;
    }
    cout << "VL " << endl;
    for(int i=0; i< n; i++) {
        for(int j=0; j< n; j++) {
            cout << VL(i,j) << " ";
        }
        cout << endl;
    }
    //this is horribly inefficient,most likely

    skew=dcomplex(0.0,0.); //we don't need that any more so we reuse it
    Array2 <dcomplex> work(n,n);
    work=dcomplex(0.0,0.);
    for(int i=0; i< n; i++) {
        skew(i,i)=exp(evals(i));
    }
    for(int i=0; i< n; i++) {
        for(int j=0; j<n; j++) {
            for(int k=0; k< n; k++) {
                work(i,k)+=skew(i,j)*VR(j,k);
            }
        }
    }
    skew=dcomplex(0.,0.);
    for(int i=0; i< n; i++) {
        for(int j=0; j<n; j++) {
            for(int k=0; k< n; k++) {
//skew(i,k)+=conj(VL(i,j))*work(j,k);
                skew(i,k)=conj(VR(j,i))*work(j,k);
            }
        }
    }


    cout << "rotation " << endl;
    for(int i=0; i< n; i++) {
        for(int j=0; j< n; j++) {
            cout << skew(i,j) << " ";
        }
        cout << endl;
    }


}
void RealTime<double>::formUTrans() {
//
// Form the unitary transformation matrix:
// U = exp(-i*dT*F)
//

    auto NTCSxNBASIS = this->nTCS_*this->nBasis_;
    // Set up Eigen Maps
    ComplexMap uTransA(this->uTransAMem_,NTCSxNBASIS,NTCSxNBASIS);
    ComplexMap scratch(this->scratchMem_,NTCSxNBASIS,NTCSxNBASIS);

    ComplexMap uTransB(this->uTransBMem_,0,0);

    if(!this->isClosedShell_ && this->Ref_ != SingleSlater<double>::TCS) {
        new (&uTransB) ComplexMap(this->uTransBMem_,NTCSxNBASIS,NTCSxNBASIS);
    }
    // FIXME: Eigen's Eigensolver is terrible, replace with LAPACK routines
    if (this->methFormU_ == EigenDecomp) {
        //  Eigen-decomposition

        char JOBZ = 'V';
        char UPLO = 'L';
        int INFO;

        dcomplex *A     = this->scratchMem_;
        double   *W     = this->REAL_LAPACK_SCR;
        double   *RWORK = W + std::max(1,3*NTCSxNBASIS-2);
        dcomplex *WORK  = this->CMPLX_LAPACK_SCR;

        RealVecMap E(W,NTCSxNBASIS);
        ComplexMap V(A,NTCSxNBASIS,NTCSxNBASIS);
        ComplexMap S(WORK,NTCSxNBASIS,NTCSxNBASIS);

        E.setZero();
        V.setZero();
        S.setZero();

        std::memcpy(A,this->ssPropagator_->fockA()->data(),
                    NTCSxNBASIS*NTCSxNBASIS*sizeof(dcomplex));

        V.transposeInPlace(); // BC Col major
        zheev_(&JOBZ,&UPLO,&NTCSxNBASIS,A,&NTCSxNBASIS,W,WORK,&this->lWORK,RWORK,
               &INFO);

        V.transposeInPlace(); // BC Col major
        std::memcpy(WORK,A,NTCSxNBASIS*NTCSxNBASIS*sizeof(dcomplex));


        for(auto i = 0; i < NTCSxNBASIS; i++) {
            S.col(i) *= dcomplex(std::cos(this->deltaT_ * W[i]),
                                 -std::sin(this->deltaT_ * W[i]));
        }

        uTransA = S * V.adjoint();

        if(!this->isClosedShell_ && this->Ref_ != SingleSlater<dcomplex>::TCS) {
            E.setZero();
            V.setZero();
            S.setZero();

            std::memcpy(A,this->ssPropagator_->fockB()->data(),
                        NTCSxNBASIS*NTCSxNBASIS*sizeof(dcomplex));

            V.transposeInPlace(); // BC Col major
            zheev_(&JOBZ,&UPLO,&NTCSxNBASIS,A,&NTCSxNBASIS,W,WORK,&this->lWORK,RWORK,
                   &INFO);

            V.transposeInPlace(); // BC Col major
            std::memcpy(WORK,A,NTCSxNBASIS*NTCSxNBASIS*sizeof(dcomplex));


            for(auto i = 0; i < NTCSxNBASIS; i++) {
                S.col(i) *= dcomplex(std::cos(this->deltaT_ * W[i]),
                                     -std::sin(this->deltaT_ * W[i]));
            }
            uTransB = S * V.adjoint();
        }
    } else if (this->methFormU_ == Taylor) {
        // Taylor expansion
        CErr("Taylor expansion NYI",this->fileio_->out);

        /*  This is not taylor and breaks with the new memory scheme

            scratch = -math.ii * deltaT_ * (*this->ssPropagator_->fockA());
            uTransA = scratch.exp(); // FIXME
            if(!this->isClosedShell_ && this->Ref_ != SingleSlater<double>::TCS) {
              scratch = -math.ii * deltaT_ * (*this->ssPropagator_->fockB());
              uTransB = scratch.exp(); // FIXME
            }
        */
    }
//    prettyPrint(this->fileio_->out,(*this->uTransA_),"uTransA");
//    if(!this->isClosedShell_ && this->Ref_ != SingleSlater<double>::TCS) prettyPrint(this->fileio_->out,(*this->uTransB_),"uTransB");
};
Beispiel #22
0
void Average_ekt::jsonOutput(Average_return &avg,Average_return &err, ostream & os) {
    
  Array2 <dcomplex> obdm_up(nmo,nmo),obdm_down(nmo,nmo),
         obdm_up_err(nmo,nmo),obdm_down_err(nmo,nmo),
         cndc_up(nmo, nmo), cndc_down(nmo, nmo),
         vlnc_up(nmo, nmo), vlnc_down(nmo, nmo),
         cndc_up_err(nmo, nmo), cndc_down_err(nmo, nmo),
         vlnc_up_err(nmo, nmo), vlnc_down_err(nmo, nmo);
    
  os <<"\""<< avg.type << "\":{" << endl;
  os << "\"nmo\":" << nmo <<","<< endl;
  os << "\"states\":[";
  for(int i=0; i< nmo; i++) {
    if(i==nmo-1) os << occupations[0][i]+1 ;
    else os << occupations[0][i]+1 << "," ;
  }
  os << "]," << endl;
  os << "\"normalization\":{" << endl;
  os << "\"value\":[";
  for(int i=0; i< nmo; i++) {
    if(i< nmo-1) os << avg.vals(i) << ",";
    else os << avg.vals(i);
  }
  os << "],"<< endl;
  os << "\"error\":[";
  for(int i=0; i< nmo; i++) {
    if(i< nmo-1) os << err.vals(i) << ",";
    else os << err.vals(i);
  }
  os << "]"<< endl;
  os << "}," << endl;
  
  if(eval_obdm) {
    dcomplex i_c(0.,1.);
    int place=0;
    for(int i=0; i < nmo; i++) {
      for(int j=0; j < nmo; j++)  {
        doublevar norm=sqrt(avg.vals(i)*avg.vals(j));
        int index=nmo + place;
        obdm_up(i,j)=dcomplex(avg.vals(index),avg.vals(index+1))/norm;
        obdm_up_err(i,j)=dcomplex(err.vals(index),err.vals(index+1))/norm;
                
        index+=2*nmo*nmo;
        obdm_down(i,j)=dcomplex(avg.vals(index),avg.vals(index+1))/norm;
        obdm_down_err(i,j)=dcomplex(err.vals(index),err.vals(index+1))/norm;
        place+=2;
        }
    }
    os << "\"obdm\":{" << endl;
    int colwidth=40;
    if(!complex_orbitals) colwidth=20;
    os << "\"up\":["<< endl;
    for(int i=0; i< nmo ; i++) {
      os << "[";
      for(int j=0; j<nmo; j++) {
        if(complex_orbitals) {
          if(j==nmo-1) os << "["<< obdm_up(i,j).real() <<","<< obdm_up(i,j).imag()<<"]";
          else  os << "["<< obdm_up(i,j).real() <<","<< obdm_up(i,j).imag()<<"],";
        }
        else {
          if(j==nmo-1) os << obdm_up(i,j).real();
          else os << obdm_up(i,j).real() << ",";
        }
      }
      if(i==nmo-1) os << "]" << endl;
      else os <<"]," << endl;
    }
    os << "]," << endl;
    
    os << "\"up_err\":["<< endl;
    for(int i=0; i< nmo ; i++) {
      os << "[";
      for(int j=0; j<nmo; j++) {
        if(complex_orbitals) {
          if(j==nmo-1) os <<"["<<obdm_up_err(i,j).real() <<","<< obdm_up_err(i,j).imag()<<"]";
          else os <<"["<< obdm_up_err(i,j).real() <<","<< obdm_up_err(i,j).imag()<<"],";
        }
        else {
          if(j==nmo-1) os << obdm_up_err(i,j).real();
          else os << obdm_up_err(i,j).real() << ",";
        }
      }
      if(i==nmo-1) os << "]" << endl;
      else os <<"]," << endl;
    }
    os << "]," << endl;
    
    os << "\"down\":["<< endl;
    for(int i=0; i< nmo ; i++) {
      os << "[";
      for(int j=0; j<nmo; j++) {
        if(complex_orbitals) {
          if(j==nmo-1) os << "["<< obdm_down(i,j).real() <<","<< obdm_down(i,j).imag()<<"]";
          else  os << "["<< obdm_down(i,j).real() <<","<< obdm_down(i,j).imag()<<"],";
        }
        else {
          if(j==nmo-1) os << obdm_down(i,j).real();
          else os << obdm_down(i,j).real() << ",";
        }
      }
      if(i==nmo-1) os << "]" << endl;
      else os <<"]," << endl;
    }
    os << "]," << endl;
    
    os << "\"down_err\":["<< endl;
    for(int i=0; i< nmo ; i++) {
      os << "[";
      for(int j=0; j<nmo; j++) {
        if(complex_orbitals) {
          if(j==nmo-1) os <<"["<< obdm_down_err(i,j).real() <<","<< obdm_down_err(i,j).imag()<<"]";
          else os << "[" << obdm_down_err(i,j).real() <<","<< obdm_down_err(i,j).imag()<<"],";
        }
        else {
          if(j==nmo-1) os << obdm_down_err(i,j).real();
          else os << obdm_down_err(i,j).real() << ",";
        }
      }
      if(i==nmo-1) os << "]" << endl;
      else os <<"]," << endl;
    }
    os << "]" << endl;
    os << "}," << endl;
  }
    
  if (eval_valence) {
    dcomplex i_c(0.,1.);
    int place=0;
    for(int i=0; i < nmo; i++) {
      for(int j=0; j < nmo; j++)  {
        doublevar norm=sqrt(avg.vals(i)*avg.vals(j));
        int index=nmo+4*nmo*nmo + place;
        vlnc_up(i,j)=dcomplex(avg.vals(index),avg.vals(index+1))/norm;
        vlnc_up_err(i,j)=dcomplex(err.vals(index),err.vals(index+1))/norm;
                
        index+=2*nmo*nmo;
        vlnc_down(i,j)=dcomplex(avg.vals(index),avg.vals(index+1))/norm;
        vlnc_down_err(i,j)=dcomplex(err.vals(index),err.vals(index+1))/norm;
        place+=2;
        }
    }
        
    os << "\"valence\":{" << endl;
    int colwidth=40;
    if(!complex_orbitals) colwidth=20;
    
    os << "\"up\":["<< endl;
    for(int i=0; i< nmo ; i++) {
      os << "[";
      for(int j=0; j<nmo; j++) {
        if(complex_orbitals) {
          if(j==nmo-1) os << "["<< vlnc_up(i,j).real() <<","<< vlnc_up(i,j).imag()<<"]";
          else  os << "["<< vlnc_up(i,j).real() <<","<< vlnc_up(i,j).imag()<<"],";
        }
        else {
          if(j==nmo-1) os << vlnc_up(i,j).real();
          else os << vlnc_up(i,j).real() << ",";
        }
      }
      if(i==nmo-1) os << "]" << endl;
      else os <<"]," << endl;
    }
    os << "]," << endl;
    
    os << "\"up_err\":["<< endl;
    for(int i=0; i< nmo ; i++) {
      os << "[";
      for(int j=0; j<nmo; j++) {
        if(complex_orbitals) {
          if(j==nmo-1) os <<"["<<vlnc_up_err(i,j).real() <<","<< vlnc_up_err(i,j).imag()<<"]";
          else os <<"["<< vlnc_up_err(i,j).real() <<","<< vlnc_up_err(i,j).imag()<<"],";
        }
        else {
          if(j==nmo-1) os << vlnc_up_err(i,j).real();
          else os << vlnc_up_err(i,j).real() << ",";
        }
      }
      if(i==nmo-1) os << "]" << endl;
      else os <<"]," << endl;
    }
    os << "]," << endl;
        
    os << "\"down\":["<< endl;
    for(int i=0; i< nmo ; i++) {
      os << "[";
      for(int j=0; j<nmo; j++) {
        if(complex_orbitals) {
          if(j==nmo-1) os << "["<< vlnc_down(i,j).real() <<","<< vlnc_down(i,j).imag()<<"]";
          else  os << "["<< vlnc_down(i,j).real() <<","<< vlnc_down(i,j).imag()<<"],";
        }
        else {
          if(j==nmo-1) os << vlnc_down(i,j).real();
          else os << vlnc_down(i,j).real() << ",";
        }
      }
      if(i==nmo-1) os << "]" << endl;
      else os <<"]," << endl;
    }
    os << "]," << endl;
        
    os << "\"down_err\":["<< endl;
    for(int i=0; i< nmo ; i++) {
      os << "[";
      for(int j=0; j<nmo; j++) {
        if(complex_orbitals) {
          if(j==nmo-1) os <<"["<< vlnc_down_err(i,j).real() <<","<< vlnc_down_err(i,j).imag()<<"]";
          else os << "[" << vlnc_down_err(i,j).real() <<","<< vlnc_down_err(i,j).imag()<<"],";
        }
        else {
          if(j==nmo-1) os << vlnc_down_err(i,j).real();
          else os << vlnc_down_err(i,j).real() << ",";
        }
      }
      if(i==nmo-1) os << "]" << endl;
      else os <<"]," << endl;
    }
    os << "]" << endl;
    os << "}," << endl;
  }
    
  if (eval_conduction) {
    dcomplex i_c(0.,1.);
    int place=0;
    for(int i=0; i < nmo; i++) {
      for(int j=0; j < nmo; j++)  {
        doublevar norm=sqrt(avg.vals(i)*avg.vals(j));
        int index=nmo + 8*nmo*nmo + place;
        cndc_up(i,j)=dcomplex(avg.vals(index),avg.vals(index+1))/norm;
        cndc_up_err(i,j)=dcomplex(err.vals(index),err.vals(index+1))/norm;
                
        index+=2*nmo*nmo;
        cndc_down(i,j)=dcomplex(avg.vals(index),avg.vals(index+1))/norm;
        cndc_down_err(i,j)=dcomplex(err.vals(index),err.vals(index+1))/norm;
        place+=2;
        }
    }
        
    os << "\"conduction\":{" << endl;
    int colwidth=40;
    if(!complex_orbitals) colwidth=20;
       
    os << "\"up\":["<< endl;
    for(int i=0; i< nmo ; i++) {
      os << "[";
      for(int j=0; j<nmo; j++) {
        if(complex_orbitals) {
          if(j==nmo-1) os << "["<< cndc_up(i,j).real() <<","<< cndc_up(i,j).imag()<<"]";
          else  os << "["<< cndc_up(i,j).real() <<","<< cndc_up(i,j).imag()<<"],";
        }
        else {
          if(j==nmo-1) os << cndc_up(i,j).real();
          else os << cndc_up(i,j).real() << ",";
        }
      }
      if(i==nmo-1) os << "]" << endl;
      else os <<"]," << endl;
    }
    os << "]," << endl;
        
    os << "\"up_err\":["<< endl;
    for(int i=0; i< nmo ; i++) {
      os << "[";
      for(int j=0; j<nmo; j++) {
        if(complex_orbitals) {
          if(j==nmo-1) os <<"["<<cndc_up_err(i,j).real() <<","<< cndc_up_err(i,j).imag()<<"]";
          else os <<"["<< cndc_up_err(i,j).real() <<","<< cndc_up_err(i,j).imag()<<"],";
        }
        else {
          if(j==nmo-1) os << cndc_up_err(i,j).real();
          else os << cndc_up_err(i,j).real() << ",";
        }
      }
      if(i==nmo-1) os << "]" << endl;
      else os <<"]," << endl;
    }
    os << "]," << endl;
        
        
    os << "\"down\":["<< endl;
    for(int i=0; i< nmo ; i++) {
      os << "[";
      for(int j=0; j<nmo; j++) {
        if(complex_orbitals) {
          if(j==nmo-1) os << "["<< cndc_down(i,j).real() <<","<< cndc_down(i,j).imag()<<"]";
          else  os << "["<< cndc_down(i,j).real() <<","<< cndc_down(i,j).imag()<<"],";
        }
        else {
          if(j==nmo-1) os << cndc_down(i,j).real();
          else os << cndc_down(i,j).real() << ",";
        }
      }
      if(i==nmo-1) os << "]" << endl;
      else os <<"]," << endl;
    }
    os << "]," << endl;
    
    os << "\"down_err\":["<< endl;
    for(int i=0; i< nmo ; i++) {
      os << "[";
      for(int j=0; j<nmo; j++) {
        if(complex_orbitals) {
          if(j==nmo-1) os <<"["<< cndc_down_err(i,j).real() <<","<< cndc_down_err(i,j).imag()<<"]";
          else os << "[" << cndc_down_err(i,j).real() <<","<< cndc_down_err(i,j).imag()<<"],";
        }
        else {
          if(j==nmo-1) os << cndc_down_err(i,j).real();
          else os << cndc_down_err(i,j).real() << ",";
        }
      }
      if(i==nmo-1) os << "]" << endl;
      else os <<"]," << endl;
    }
    os << "]" << endl;
    os << "}" << endl;
  }
 
  //dcomplex trace=0;
  //for(int i=0;i< nmo; i++) trace+=obdm_up(i,i);
  //os << "\"Trace of the obdm\":{" << endl;
  //os << "\"up\":[" << trace.real()<< "," << trace.imag()<<"]" << "," << endl;
  //trace=0;
  //for(int i=0; i< nmo; i++) trace+=obdm_down(i,i);
  //os << "\"down\":[" << trace.real()<< "," << trace.imag()<<"]" << endl;
  //os << "}" << endl;
  os << "}" << endl;
}
Beispiel #23
0
const Field3D DDZ(const Field3D &f, CELL_LOC outloc, DIFF_METHOD method, bool inc_xbndry)
{
    deriv_func func = fDDZ; // Set to default function
    DiffLookup *table = FirstDerivTable;

    CELL_LOC inloc = f.getLocation(); // Input location
    CELL_LOC diffloc = inloc; // Location of differential result

    if(StaggerGrids && (outloc == CELL_DEFAULT)) {
        // Take care of CELL_DEFAULT case
        outloc = diffloc; // No shift (i.e. same as no stagger case)
    }

    if(StaggerGrids && (outloc != inloc)) {
        // Shifting to a new location

        if(((inloc == CELL_CENTRE) && (outloc == CELL_ZLOW)) ||
                ((inloc == CELL_ZLOW) && (outloc == CELL_CENTRE))) {
            // Shifting in Z. Centre -> Zlow, or Zlow -> Centre

            func = sfDDZ; // Set default
            table = FirstStagDerivTable; // Set table for others
            diffloc = (inloc == CELL_CENTRE) ? CELL_ZLOW : CELL_CENTRE;

        } else {
            // A more complicated shift. Get a result at cell centre, then shift.
            if(inloc == CELL_ZLOW) {
                // Shifting

                func = sfDDZ; // Set default
                table = FirstStagDerivTable; // Set table for others
                diffloc = CELL_CENTRE;

            } else if(inloc != CELL_CENTRE) {
                // Interpolate then (centre -> centre) then interpolate
                return DDZ(interp_to(f, CELL_CENTRE), outloc, method);
            }
        }
    }

    if(method != DIFF_DEFAULT) {
        // Lookup function
        func = lookupFunc(table, method);
    }

    Field3D result;

    if(func == NULL) {
        // Use FFT

        real shift = 0.; // Shifting result in Z?
        if(StaggerGrids) {
            if((inloc == CELL_CENTRE) && (diffloc == CELL_ZLOW)) {
                // Shifting down - multiply by exp(-0.5*i*k*dz)
                shift = -1.;
            } else if((inloc == CELL_ZLOW) && (diffloc == CELL_CENTRE)) {
                // Shifting up
                shift = 1.;
            }
        }

        result.Allocate(); // Make sure data allocated

        static dcomplex *cv = (dcomplex*) NULL;
        int jx, jy, jz;
        real kwave;
        real flt;

        int xge = MXG, xlt = ngx-MXG;
        if(inc_xbndry) { // Include x boundary region (for mixed XZ derivatives)
            xge = 0;
            xlt = ngx;
        }

        if(cv == (dcomplex*) NULL)
            cv = new dcomplex[ncz/2 + 1];

        for(jx=xge; jx<xlt; jx++) {
            for(jy=0; jy<ngy; jy++) {

                rfft(f[jx][jy], ncz, cv); // Forward FFT

                for(jz=0; jz<=ncz/2; jz++) {
                    kwave=jz*2.0*PI/zlength; // wave number is 1/[rad]

                    if (jz>0.4*ncz) flt=1e-10;
                    else flt=1.0;
                    cv[jz] *= dcomplex(0.0, kwave) * flt;
                    if(StaggerGrids)
                        cv[jz] *= exp(Im * (shift * kwave * dz));
                }

                irfft(cv, ncz, result[jx][jy]); // Reverse FFT

                result[jx][jy][ncz] = result[jx][jy][0];

            }
        }

#ifdef CHECK
        // Mark boundaries as invalid
        result.bndry_xin = result.bndry_xout = result.bndry_yup = result.bndry_ydown = false;
#endif

    } else {
        // All other (non-FFT) functions
        result = applyZdiff(f, func, dz);
    }

    result.setLocation(diffloc);

    return interp_to(result, outloc);
}
Beispiel #24
0
//---------------------------------------------------------------------
// Computes NY N-point complex-to-complex FFTs of X using an algorithm due
// to Swarztrauber.  X is both the input and the output array, while Y is a 
// scratch array.  It is assumed that N = 2^M.  Before calling 
// Swarztrauber to 
// perform FFTs
//---------------------------------------------------------------------
static void Swarztrauber(int is, int m, int vlen, int n, int xd1,
                         void *ox, dcomplex exponent[n])
{
  dcomplex (*x)[xd1] = (dcomplex (*)[xd1])ox;

  int i, j, l;
  dcomplex u1, x11, x21;
  int k, n1, li, lj, lk, ku, i11, i12, i21, i22;

  if (timers_enabled) timer_start(4);
  //---------------------------------------------------------------------
  // Perform one variant of the Stockham FFT.
  //---------------------------------------------------------------------
  n1 = n / 2;
  lj = 1;
  li = 1 << m;
  for (l = 1; l <= m; l += 2) {
    lk = lj;
    lj = 2 * lk;
    li = li / 2;
    ku = li;

    for (i = 0; i <= li - 1; i++) {
      i11 = i * lk;
      i12 = i11 + n1;
      i21 = i * lj;
      i22 = i21 + lk;

      if (is >= 1) {
        u1 = exponent[ku+i];
      } else {
        u1 = dconjg(exponent[ku+i]);
      }
      for (k = 0; k <= lk - 1; k++) {
        for (j = 0; j < vlen; j++) {
          x11 = x[i11+k][j];
          x21 = x[i12+k][j];
          scr[i21+k][j] = dcmplx_add(x11, x21);
          scr[i22+k][j] = dcmplx_mul(u1, dcmplx_sub(x11, x21));
        }
      }
    }

    if (l == m) {
      for (k = 0; k < n; k++) {
        for (j = 0; j < vlen; j++) {
          x[k][j] = scr[k][j];
        }
      }
    } else {
      lk = lj;
      lj = 2 * lk;
      li = li / 2;
      ku = li;

      for (i = 0; i <= li - 1; i++) {
        i11 = i * lk;
        i12 = i11 + n1;
        i21 = i * lj;
        i22 = i21 + lk;

        if (is >= 1) {
          u1 = exponent[ku+i];
        } else {
          u1 = dconjg(exponent[ku+i]);
        }
        for (k = 0; k <= lk - 1; k++) {
          for (j = 0; j < vlen; j++) {
            x11 = scr[i11+k][j];
            x21 = scr[i12+k][j];
            x[i21+k][j] = dcmplx_add(x11, x21);
            x[i22+k][j] = dcmplx_mul(u1, dcmplx_sub(x11, x21));
          }
        }
      }
    }
  }
  if (timers_enabled) timer_stop(4);
}
/**
 * 1D crystal
 * Randomize the on-site energies to be between 0 an 1
 * Fix the hopping terms to be 1 for the nearest neighbours and decaying as 1/r^3
 * Fix the dynamical terms to be 1 for the nearest neighbours and decaying as 1/r^3
 *
 * calculate
 * 1/two_particle_localization_length
 * = - lim_{|n-m|--> infty} << ln|<m, m+a|G(z)|n, n+a>| >> / |n-m|
 * where << ... >> represents the average over different configurations of disorder
 *
 * In the current case, we let a = 1 and
 * we want z.real to be at the center of the band
 */
TEST(LocalizationTest, RandomOnSiteEnergy) {
	LatticeShape lattice1D(1);
	int xmax;
	READ_INPUT("input.txt", "int", xmax);


	lattice1D.setXmax(xmax); //xsite = xmax + 1
	int initialSeperation=1; //default value is 1

	/* set up interaction data */
	double onsiteE, hop, dyn;
	bool randomOnsite, randomHop, randomDyn;
	int maxDistance;
	unsigned seed;
	bool longRangeHop, longRangeDyn;
	READ_INPUT("input.txt", "double", onsiteE);
	READ_INPUT("input.txt", "double", hop);
	READ_INPUT("input.txt", "double", dyn);
	READ_INPUT("input.txt", "bool", randomOnsite);
	READ_INPUT("input.txt", "bool", randomHop);
	READ_INPUT("input.txt", "bool", randomDyn);
	READ_INPUT("input.txt", "int", maxDistance);
	READ_INPUT("input.txt", "unsigned", seed);
	READ_INPUT("input.txt", "bool", longRangeHop);
	READ_INPUT("input.txt", "bool", longRangeDyn);
	READ_INPUT("input.txt", "int", initialSeperation);

	int n = xmax/2;
	int nPlusa = n + initialSeperation;
	Basis initialSites(n, nPlusa);

	InteractionData interactionData = { onsiteE, hop, dyn,
			                            randomOnsite, randomHop, randomDyn,
			                            maxDistance, seed,
	                                    longRangeHop, longRangeDyn};

	setUpIndexInteractions(lattice1D, interactionData);

	std::vector< dcomplex > zList;

	double E;
	READ_INPUT("input.txt", "double", E);


	double eta;
	READ_INPUT("input.txt", "double", eta);


	zList.push_back(dcomplex(E, eta));

	std::vector<std::string> fileList;
	//fileList.push_back("GF.txt");
	fileList.push_back("GF.bin");

	calculateAllGreenFunc(lattice1D,  initialSites,
			              interactionData, zList,
	                       fileList);
	// extract Green's function from the file
	CDMatrix gf;
	loadMatrix(fileList[0], gf);

	std::ofstream myFile;
	std::string output = "a_" + itos(initialSeperation)+".txt";

	myFile.open(output.c_str());
	for (int m=n; m<=xmax-initialSeperation; ++m ) {
		dcomplex element = gf(m, m+initialSeperation);
		double G_n_m = std::log( std::abs( element ) );
		myFile << (m-n) << "\t"<< G_n_m << std::endl;
	}
	myFile.close();

	EXPECT_TRUE(true);
}
Beispiel #26
0
    //can be used if boost is zero:
    dcomplex Zetafunc::term1noboost(const double q2){
        dcomplex result(0.,0.),sphfact,tmpcomp;
        double fact,rsq,r,theta,phi,resultre,resultim;
        threevec<double> nvec;
        
        //zero term is zero:
        result=dcomplex(0.,0.);
        
        //line terms
        //x>0, y=z=0 and y>0, x=z=0 and z>0, x=y=0:
        //note that z->-z is equivalent to theta->pi-theta, similar to this: x->-x yields phi->pi-phi and y->-y is phi->2pi-phi
        sphfact=    spherical_harmonicy(l,m,pimath/2.   ,   0.);                                //x>0
        sphfact+=   spherical_harmonicy(l,m,pimath/2.   ,   pimath);                            //x<0
        sphfact+=   spherical_harmonicy(l,m,pimath/2.   ,   pimath/2.);                         //y>0
        sphfact+=   spherical_harmonicy(l,m,pimath/2.   ,   3.*pimath/2.);                      //y<0
        sphfact+=   spherical_harmonicy(l,m,0.          ,   0.);                                //z>0
        sphfact+=   spherical_harmonicy(l,m,pimath      ,   0.);                                //z<0
        //reduce
        resultre=0.,resultim=0.;
#pragma omp parallel for reduction(+:resultre) reduction(+:resultim) firstprivate(q2,sphfact) private(rsq,r,tmpcomp) schedule(static)
        for(int x=1; x<=MAXRUN; x++){
            rsq=x*x;
            tmpcomp=dcomplex(::std::exp(-lambda*(rsq-q2))*::std::pow(static_cast<double>(x),l)/(rsq-q2),0.)*sphfact;
            resultre+=tmpcomp.re();
            resultim+=tmpcomp.im();
        }
        result+=dcomplex(resultre,resultim);
        
        
        //plane terms
        //x,y!>0, z=0:
        //the four ylm account for the possibilities +/+, +/-, -/+, -/-:
        resultre=0.,resultim=0.;
#pragma omp parallel for reduction(+:resultre) reduction(+:resultim) firstprivate(q2) private(rsq,r,theta,phi,sphfact,tmpcomp) schedule(static)
        for(int y=1; y<=MAXRUN; y++){
            for(int x=1; x<=MAXRUN; x++){
                threevec<int>(x,y,0).get_spherical_coordinates(r,theta,phi);
                rsq=r*r;
                //z=0:
                sphfact=    spherical_harmonicy(l,m,theta   ,   phi);                           //x,y>0
                sphfact+=   spherical_harmonicy(l,m,theta   ,   pimath-phi);                    //x<0,y>0
                sphfact+=   spherical_harmonicy(l,m,theta   ,   pimath+phi);                    //x,y<0
                sphfact+=   spherical_harmonicy(l,m,theta   ,   2.*pimath-phi);                 //x>0,y<0
                
                //result
                tmpcomp=dcomplex(::std::exp(-lambda*(rsq-q2))*::std::pow(r,l)/(rsq-q2),0.)*sphfact;
                resultre+=tmpcomp.re();
                resultim+=tmpcomp.im();
            }
        }
        result+=dcomplex(resultre,resultim);
        
        
        //x,z>0, y=0 and y,z>0, x=0:
        resultre=0.,resultim=0.;
#pragma omp parallel for reduction(+:resultre) reduction(+:resultim) firstprivate(q2) private(rsq,r,theta,phi,sphfact,tmpcomp) schedule(static)
        for(int z=1; z<=MAXRUN; z++){
            for(int x=1; x<=MAXRUN; x++){
                threevec<int>(x,0,z).get_spherical_coordinates(r,theta,phi);
                rsq=r*r;
                
                //y=0:
                sphfact=    spherical_harmonicy(l,m,theta          ,    0);                    //x,z>0
                sphfact+=   spherical_harmonicy(l,m,pimath-theta   ,    0);                    //x>0,z<0
                sphfact+=   spherical_harmonicy(l,m,theta          ,    pimath);               //x<0,z>0
                sphfact+=   spherical_harmonicy(l,m,pimath-theta   ,    pimath);               //x,z<0
                //x=0:
                sphfact+=   spherical_harmonicy(l,m,theta          ,    pimath/2.);            //y,z>0
                sphfact+=   spherical_harmonicy(l,m,pimath-theta   ,    pimath/2.);            //y>0,z<0
                sphfact+=   spherical_harmonicy(l,m,theta          ,    3.*pimath/2.);         //y<0,z>0
                sphfact+=   spherical_harmonicy(l,m,pimath-theta   ,    3.*pimath/2.);         //y,z<0
                
                //result:
                tmpcomp=dcomplex(::std::exp(-lambda*(rsq-q2))*::std::pow(r,l)/(rsq-q2),0.)*sphfact;
                resultre+=tmpcomp.re();
                resultim+=tmpcomp.im();
            }
        }
        result+=dcomplex(resultre,resultim);
        
        
        //cubic terms
        //x,y,z>0
        resultre=0., resultim=0.;
#pragma omp parallel for reduction(+:resultre) reduction(+:resultim) firstprivate(q2) private(nvec,rsq,r,theta,phi,fact,tmpcomp) schedule(static)
        for(int z=1; z<=MAXRUN; z++){
            for(int y=1; y<=MAXRUN; y++){
                for(int x=1; x<=MAXRUN; x++){
                    nvec(static_cast<double>(x),static_cast<double>(y),static_cast<double>(z));
                    nvec.get_spherical_coordinates(r,theta,phi);
                    fact=::std::pow(r,l); //compute |r|^l
                    rsq=r*r; //compute r^2
                    fact*=::std::exp(-lambda*(rsq-q2))/(rsq-q2); //compute the ratio
                    
                    //compute sphfact: account for all possible orientations
                    sphfact=dcomplex(0.,0.);
                    for(unsigned int thetaa=0; thetaa<2; thetaa++){
                        sphfact+=spherical_harmonicy(l,m,static_cast<double>(thetaa)*pimath-theta,phi);            //x,y>0
                        sphfact+=spherical_harmonicy(l,m,static_cast<double>(thetaa)*pimath-theta,pimath-phi);     //x<0,y>0
                        sphfact+=spherical_harmonicy(l,m,static_cast<double>(thetaa)*pimath-theta,pimath+phi);     //x,y<0
                        sphfact+=spherical_harmonicy(l,m,static_cast<double>(thetaa)*pimath-theta,2.*pimath-phi);  //x>0,y<0
                    }

                    //compute the result:
                    tmpcomp=fact*sphfact; //ratio * ylm factor
                    resultre+=tmpcomp.re();
                    resultim+=tmpcomp.im();
                }
            }
        }
        result+=dcomplex(resultre,resultim);
        
        return result;
    }