Пример #1
0
/** 
 * @brief A main function to calculate spectrum by Lanczos
 * 
 * @param[in,out] X CalcStruct list for getting and pushing calculation information 
 * @retval 0 normally finished
 * @retval -1 unnormally finished
 *
 * @version 1.1
 * @author Kazuyoshi Yoshimi (The University of Tokyo)
 * 
 */
int CalcSpectrumByLanczos(		 
			  struct EDMainCalStruct *X,
			  double complex *tmp_v1,
			  double dnorm,
              int Nomega,
              double complex *dcSpectrum,
              double complex *dcomega
)
{
    char sdt[D_FileNameMax];
    unsigned long int i, i_max;
    FILE *fp;
    int iret;
    unsigned long int liLanczosStp = X->Bind.Def.Lanczos_max;
    unsigned long int liLanczosStp_vec=0;

    if(X->Bind.Def.iFlgCalcSpec == RECALC_FROM_TMComponents_VEC ||
       X->Bind.Def.iFlgCalcSpec == RECALC_INOUT_TMComponents_VEC) {
      
        fprintf(stdoutMPI, "  Start: Input vectors for recalculation.\n");
        TimeKeeper(&(X->Bind), cFileNameTimeKeep, c_InputSpectrumRecalcvecStart, "a");
        StartTimer(6201);
        sprintf(sdt, cFileNameOutputRestartVec, X->Bind.Def.CDataFileHead, myrank);
        if (childfopenALL(sdt, "rb", &fp) != 0) {
            exitMPI(-1);
        }
        fread(&liLanczosStp_vec, sizeof(liLanczosStp_vec),1,fp);
        fread(&i_max, sizeof(long int), 1, fp);
        if(i_max != X->Bind.Check.idim_max){
            fprintf(stderr, "Error: A size of Inputvector is incorrect.\n");
            exitMPI(-1);
        }
        fread(v0, sizeof(complex double), X->Bind.Check.idim_max + 1, fp);
        fread(v1, sizeof(complex double), X->Bind.Check.idim_max + 1, fp);
        fclose(fp);
        StopTimer(6201);
        fprintf(stdoutMPI, "  End:   Input vectors for recalculation.\n");
        TimeKeeper(&(X->Bind), cFileNameTimeKeep, c_InputSpectrumRecalcvecEnd, "a");
    }

    //Read diagonal components
    if(X->Bind.Def.iFlgCalcSpec == RECALC_FROM_TMComponents ||
       X->Bind.Def.iFlgCalcSpec ==RECALC_FROM_TMComponents_VEC||
       X->Bind.Def.iFlgCalcSpec == RECALC_INOUT_TMComponents_VEC)
    {
      StartTimer(6202);
        iret=ReadTMComponents(X, &dnorm, &liLanczosStp);
        if(!iret ==TRUE){
            fprintf(stdoutMPI, "  Error: Fail to read TMcomponents\n");
            return FALSE;
        }

        if(X->Bind.Def.iFlgCalcSpec == RECALC_FROM_TMComponents){
            X->Bind.Def.Lanczos_restart=0;
        }
        else if(X->Bind.Def.iFlgCalcSpec == RECALC_INOUT_TMComponents_VEC||
                X->Bind.Def.iFlgCalcSpec == RECALC_FROM_TMComponents_VEC){
            if(liLanczosStp_vec !=liLanczosStp){
                fprintf(stdoutMPI, "  Error: Input files for vector and TMcomponents are incoorect.\n");
                fprintf(stdoutMPI, "  Error: Input vector %ld th stps, TMcomponents  %ld th stps.\n", liLanczosStp_vec, liLanczosStp);
                return FALSE;
            }
            X->Bind.Def.Lanczos_restart=liLanczosStp;
            liLanczosStp = liLanczosStp+X->Bind.Def.Lanczos_max;
        }
        StopTimer(6202);
    }

    // calculate ai, bi
    if (X->Bind.Def.iFlgCalcSpec == RECALC_NOT ||
        X->Bind.Def.iFlgCalcSpec == RECALC_OUTPUT_TMComponents_VEC ||
        X->Bind.Def.iFlgCalcSpec == RECALC_FROM_TMComponents_VEC ||
        X->Bind.Def.iFlgCalcSpec == RECALC_INOUT_TMComponents_VEC
        )
    {
        fprintf(stdoutMPI, "    Start: Calculate tridiagonal matrix components.\n");
        TimeKeeper(&(X->Bind), cFileNameTimeKeep, c_GetTridiagonalStart, "a");
        // Functions in Lanczos_EigenValue
        StartTimer(6203);
        iret = Lanczos_GetTridiagonalMatrixComponents(&(X->Bind), alpha, beta, tmp_v1, &(liLanczosStp));
        StopTimer(6203);
        if (iret != TRUE) {
            //Error Message will be added.
            return FALSE;
        }
        fprintf(stdoutMPI, "    End:   Calculate tridiagonal matrix components.\n\n");
        TimeKeeper(&(X->Bind), cFileNameTimeKeep, c_GetTridiagonalEnd, "a");
        StartTimer(6204);
        OutputTMComponents(X, alpha,beta, dnorm, liLanczosStp);
        StopTimer(6204);
    }//X->Bind.Def.iFlgCalcSpec == RECALC_NOT || RECALC_FROM_TMComponents_VEC

    fprintf(stdoutMPI, "    Start: Caclulate spectrum from tridiagonal matrix components.\n");
    TimeKeeper(&(X->Bind), cFileNameTimeKeep, c_CalcSpectrumFromTridiagonalStart, "a");
    StartTimer(6205);
    for( i = 0 ; i < Nomega; i++) {
        iret = GetSpectrumByTridiagonalMatrixComponents(alpha, beta, dnorm, dcomega[i], &dcSpectrum[i], liLanczosStp);
        if (iret != TRUE) {
            //ToDo: Error Message will be added.
            //ReAlloc alpha, beta and Set alpha_start and beta_start in Lanczos_EigenValue
            return FALSE;
        }
        dcSpectrum[i] = dnorm * dcSpectrum[i];
    }
    StopTimer(6205);
    fprintf(stdoutMPI, "    End:   Caclulate spectrum from tridiagonal matrix components.\n\n");
    TimeKeeper(&(X->Bind), cFileNameTimeKeep, c_CalcSpectrumFromTridiagonalEnd, "a");

    //output vectors for recalculation
    if(X->Bind.Def.iFlgCalcSpec==RECALC_OUTPUT_TMComponents_VEC ||
       X->Bind.Def.iFlgCalcSpec==RECALC_INOUT_TMComponents_VEC){
      StartTimer(6206);
        fprintf(stdoutMPI, "    Start: Output vectors for recalculation.\n");
        TimeKeeper(&(X->Bind), cFileNameTimeKeep, c_OutputSpectrumRecalcvecStart, "a");

        sprintf(sdt, cFileNameOutputRestartVec, X->Bind.Def.CDataFileHead, myrank);
        if(childfopenALL(sdt, "wb", &fp)!=0){
            exitMPI(-1);
        }
        fwrite(&liLanczosStp, sizeof(liLanczosStp),1,fp);
        fwrite(&X->Bind.Check.idim_max, sizeof(X->Bind.Check.idim_max),1,fp);
        fwrite(v0, sizeof(complex double),X->Bind.Check.idim_max+1, fp);
        fwrite(v1, sizeof(complex double),X->Bind.Check.idim_max+1, fp);
        fclose(fp);

        fprintf(stdoutMPI, "    End:   Output vectors for recalculation.\n");
        TimeKeeper(&(X->Bind), cFileNameTimeKeep, c_OutputSpectrumRecalcvecEnd, "a");
        StopTimer(6206);
    }

    return TRUE;
}
Пример #2
0
/** 
 * @brief A main function to calculate eigenvalues and eigenvectors by Lanczos method 
 * 
 * @param[in,out] X CalcStruct list for getting and pushing calculation information 
 * @retval 0 normally finished
 * @retval -1 unnormally finished
 *
 * @version 0.2
 * @date 2015/10/20 add function of using a flag of iCalcEigenVec
 * @version 0.1
 * @author Takahiro Misawa (The University of Tokyo)
 * @author Kazuyoshi Yoshimi (The University of Tokyo)
 * 
 */
int CalcByLanczos(		 
                  struct EDMainCalStruct *X
                         )
{
  char sdt[D_FileNameMax];
  double diff_ene,var;
  long int i;
  long int i_max=0;
  FILE *fp;
  
  if(X->Bind.Def.iInputEigenVec==FALSE){
    // this part will be modified
    switch(X->Bind.Def.iCalcModel){
    case HubbardGC:
    case SpinGC:
    case KondoGC:
    case SpinlessFermionGC:
      initial_mode = 1; // 1 -> random initial vector
      break;
    case Hubbard:
    case Kondo:
    case Spin:
    case SpinlessFermion:

      if(X->Bind.Def.iFlgGeneralSpin ==TRUE){
        initial_mode=1;
      }
      else{
        if(X->Bind.Def.initial_iv>0){
          initial_mode = 0; // 0 -> only v[iv] = 1
        }else{
          initial_mode = 1; // 1 -> random initial vector
        }
      }
      break;
    default:
      //fclose(fp);
      exitMPI(-1);
    }
 
    if(Lanczos_EigenValue(&(X->Bind))!=0){
      fprintf(stderr, "  Lanczos Eigenvalue is not converged in this process.\n");      
      return(FALSE);
    }

    if(X->Bind.Def.iCalcEigenVec==CALCVEC_NOT){
       fprintf(stdoutMPI, "  Lanczos EigenValue = %.10lf \n ",X->Bind.Phys.Target_energy);
      return(TRUE);
    }

    fprintf(stdoutMPI, cLogLanczos_EigenVecStart);
//    printf("debug: X->Bind.Check.idim_maxMPI=%d\n", X->Bind.Check.idim_maxMPI);

    if(X->Bind.Check.idim_maxMPI != 1){
      Lanczos_EigenVector(&(X->Bind));
      expec_energy(&(X->Bind));
      //check for the accuracy of the eigenvector
      var      = fabs(X->Bind.Phys.var-X->Bind.Phys.energy*X->Bind.Phys.energy)/fabs(X->Bind.Phys.var);
      diff_ene = fabs(X->Bind.Phys.Target_energy-X->Bind.Phys.energy)/fabs(X->Bind.Phys.Target_energy);
      
      fprintf(stdoutMPI, "\n");
      fprintf(stdoutMPI, "  Accuracy check !!!\n");
      fprintf(stdoutMPI, "  LanczosEnergy = %.14e \n  EnergyByVec   = %.14e \n  diff_ene      = %.14e \n  var           = %.14e \n",X->Bind.Phys.Target_energy,X->Bind.Phys.energy,diff_ene,var);
      if(diff_ene < eps_Energy && var< eps_Energy){
        fprintf(stdoutMPI, "  Accuracy of Lanczos vectors is enough.\n");
        fprintf(stdoutMPI, "\n");
      }
      /*
      else{
         Comment out: Power Lanczos method
           fprintf(stdoutMPI, "  Accuracy of Lanczos vectors is NOT enough\n");
           iconv=1;
           fprintf(stdoutMPI, "Eigenvector is improved by power Lanczos method \n");
           fprintf(stdoutMPI, "Power Lanczos starts\n");
           flag=PowerLanczos(&(X->Bind));
           fprintf(stdoutMPI, "Power Lanczos ends\n");
           if(flag==1){
           var      = fabs(X->Bind.Phys.var-X->Bind.Phys.energy*X->Bind.Phys.energy)/fabs(X->Bind.Phys.var);
           diff_ene = fabs(X->Bind.Phys.Target_energy-X->Bind.Phys.energy)/fabs(X->Bind.Phys.Target_energy);
           fprintf(stdoutMPI,"\n");
           fprintf(stdoutMPI,"Power Lanczos Accuracy check !!!\n");
           fprintf(stdoutMPI,"%.14e %.14e: diff_ene=%.14e var=%.14e \n ",X->Bind.Phys.Target_energy,X->Bind.Phys.energy,diff_ene,var);
           fprintf(stdoutMPI,"\n");
	
           }
     else if(X->Bind.Def.iCalcEigenVec==CALCVEC_LANCZOSCG && iconv==1){     
 */
      else if(X->Bind.Def.iCalcEigenVec==CALCVEC_LANCZOSCG){        
        fprintf(stdoutMPI, "  Accuracy of Lanczos vectors is NOT enough\n\n");
        X->Bind.Def.St=1;
        CG_EigenVector(&(X->Bind));
        expec_energy(&(X->Bind));
        var      = fabs(X->Bind.Phys.var-X->Bind.Phys.energy*X->Bind.Phys.energy)/fabs(X->Bind.Phys.var);
        diff_ene = fabs(X->Bind.Phys.Target_energy-X->Bind.Phys.energy)/fabs(X->Bind.Phys.Target_energy);
        fprintf(stdoutMPI, "\n");
        fprintf(stdoutMPI, "  CG Accuracy check !!!\n");
        fprintf(stdoutMPI, "  LanczosEnergy = %.14e\n  EnergyByVec   = %.14e\n  diff_ene      = %.14e\n  var           = %.14e \n ",X->Bind.Phys.Target_energy,X->Bind.Phys.energy,diff_ene,var);
        fprintf(stdoutMPI, "\n");
        //}
      }
    }
    else{//idim_max=1
      v0[1]=1;
      expec_energy(&(X->Bind));
    }
  }
  else{// X->Bind.Def.iInputEigenVec=false :input v1:
    fprintf(stdoutMPI, "An Eigenvector is inputted.\n");
    sprintf(sdt, cFileNameInputEigen, X->Bind.Def.CDataFileHead, X->Bind.Def.k_exct-1, myrank);
    childfopenALL(sdt, "rb", &fp);
    if(fp==NULL){
      fprintf(stderr, "Error: A file of Inputvector does not exist.\n");
      exitMPI(-1);
    }
    fread(&i_max, sizeof(long int), 1, fp);
    if(i_max != X->Bind.Check.idim_max){
      fprintf(stderr, "Error: A file of Inputvector is incorrect.\n");
      exitMPI(-1);
    }
    fread(v1, sizeof(complex double),X->Bind.Check.idim_max+1, fp);
    
    fclose(fp);
  }

  fprintf(stdoutMPI, cLogLanczos_EigenVecEnd);
  // v1 is eigen vector
    
  if(!expec_cisajs(&(X->Bind), v1)==0){
    fprintf(stderr, "Error: calc OneBodyG.\n");
    exitMPI(-1);
  }
  
  if(!expec_cisajscktaltdc(&(X->Bind), v1)==0){
    fprintf(stderr, "Error: calc TwoBodyG.\n");
    exitMPI(-1);
  }
  
  /* For ver.1.0
     if(!expec_totalspin(&(X->Bind), v1)==0){
     fprintf(stderr, "Error: calc TotalSpin.\n");
     exitMPI(-1);
     }
  */
  
  if(!expec_totalSz(&(X->Bind), v1)==0){
    fprintf(stderr, "Error: calc TotalSz.\n");
    exitMPI(-1);
  }

  if(X->Bind.Def.St==0){
    sprintf(sdt, cFileNameEnergy_Lanczos, X->Bind.Def.CDataFileHead);
  }else if(X->Bind.Def.St==1){
    sprintf(sdt, cFileNameEnergy_CG, X->Bind.Def.CDataFileHead);
  }
  
  if(childfopenMPI(sdt, "w", &fp)!=0){
    exitMPI(-1);
  }  


  fprintf(fp,"Energy  %.16lf \n",X->Bind.Phys.energy);
  fprintf(fp,"Doublon  %.16lf \n",X->Bind.Phys.doublon);
  fprintf(fp,"Sz  %.16lf \n",X->Bind.Phys.sz);
  //    fprintf(fp,"total S^2  %.10lf \n",X->Bind.Phys.s2);    
  fclose(fp);

  if(X->Bind.Def.iOutputEigenVec==TRUE){
    sprintf(sdt, cFileNameOutputEigen, X->Bind.Def.CDataFileHead, X->Bind.Def.k_exct-1, myrank);
    if(childfopenALL(sdt, "wb", &fp)!=0){
      exitMPI(-1);
    }
    fwrite(&X->Bind.Check.idim_max, sizeof(X->Bind.Check.idim_max),1,fp);
    fwrite(v1, sizeof(complex double),X->Bind.Check.idim_max+1, fp);    
    fclose(fp);
  }

  return TRUE;
}