コード例 #1
0
ファイル: Dov_psi.c プロジェクト: palao/tmLQCD
void Q_over_sqrt_Q_sqr(spinor * const R, double * const c, 
		       const int n, spinor * const S,
		       const double rnorm, const double minev) {
  
  int j;
  double fact1, fact2, temp1, temp2, temp3, temp4, maxev, tnorm;
  spinor  *sv, *d,  *dd,  *aux,  *aux3;
  double ap_eps_sq = 0.;

  sv=lock_Dov_WS_spinor(2);
  d=lock_Dov_WS_spinor(3);
  dd=lock_Dov_WS_spinor(4);
  aux=lock_Dov_WS_spinor(5);
  aux3=lock_Dov_WS_spinor(6);


  eigenvalues_for_cg_computed = no_eigenvalues - 1;
  if(eigenvalues_for_cg_computed < 0) eigenvalues_for_cg_computed = 0;
  maxev=1.0;
  
  fact1=4/(maxev-minev);
  fact2=-2*(maxev+minev)/(maxev-minev);
  
  zero_spinor_field(d, VOLUME);
  zero_spinor_field(dd, VOLUME); 
  
  if(1) assign_sub_lowest_eigenvalues(aux3, S, no_eigenvalues-1, VOLUME);
  else assign(aux3, S, VOLUME);
  
  /* Check whether switch for adaptive precision is on */
  /* this might be implemented again in the future */
  /* Use the 'old' version using Clenshaw's recursion for the 
     Chebysheff polynomial 
  */
  if(1) {
    for (j = n-1; j >= 1; j--) {
      assign(sv, d, VOLUME); 
      
      if ( (j%10) == 0 ) {
	assign_sub_lowest_eigenvalues(aux, d, no_eigenvalues-1, VOLUME);
      }
      else {
	assign(aux, d, VOLUME);
      }
      
      norm_Q_sqr_psi(R, aux, rnorm);
/*       printf("%d %e %e\n", j, R[0].s0.c0.re, R[0].s0.c0.im); */
/*       printf("%e %e\n", R[0].s1.c0.re, R[0].s1.c0.im); */
      temp1=-1.0;
      temp2=c[j];
      assign_mul_add_mul_add_mul_add_mul_r(d, R, dd, aux3, fact2, fact1, temp1, temp2, VOLUME);
      assign(dd, sv, VOLUME);
    } 
    
    if(1) assign_sub_lowest_eigenvalues(R, d, no_eigenvalues-1, VOLUME);
    else assign(R, d, VOLUME);
    
    norm_Q_sqr_psi(aux, R, rnorm);
    temp1=-1.0;
    temp2=c[0]/2.;
    temp3=fact1/2.;
    temp4=fact2/2.;
    assign_mul_add_mul_add_mul_add_mul_r(aux, d, dd, aux3, temp3, temp4, temp1, temp2, VOLUME);
    norm_Q_n_psi(R, aux, 1, rnorm);
  }
  else {
    /* Use the adaptive precision version using the forward recursion 
       for the Chebysheff polynomial 
    */
    
    /* d = T_0(Q^2) */
    assign(d, aux3, VOLUME);
    /* dd = T_1(Q^2) */
    norm_Q_sqr_psi(dd, d, rnorm);
    temp3 = fact1/2.;
    temp4 = fact2/2.;  
    assign_mul_add_mul_r(dd, d, temp3, temp4, VOLUME);
    /* r = c_1 T_1(Q^2) + 1./2 c_0 */
    temp1 = c[1];
    temp2 = c[0]/2.;
    mul_add_mul_r(R, dd, d, temp1, temp2, VOLUME);
    
    temp1=-1.0;
    for (j = 2; j <= n-1; j++) {
      /* aux = T_j(Q^2) = 2 Q^2 T_{j-1}(Q^2) - T_{j-2}(Q^2) */
      norm_Q_sqr_psi(aux, dd, rnorm);
      assign_mul_add_mul_add_mul_r(aux, dd, d, fact1, fact2, temp1, VOLUME);
      /* r = r + c_j T_j(Q^2) */
      temp2 = c[j];
      assign_add_mul_r(R, aux, temp2, VOLUME);
      /* The stoppping criterio tnorm = |T_j(Q^2)| */
      tnorm=square_norm(aux, VOLUME, 1);
      tnorm*=(temp2*temp2);
      
      /*
	auxnorm=square_norm(R);
	if(g_proc_id == g_stdio_proc){printf("j= %d\t|c T|^2= %g\t c_j= %g\t|r|^2= %g\n",j,tnorm,temp2,auxnorm); fflush( stdout);};
      */
      
      if(tnorm < ap_eps_sq) break; 
       /* d = T_{j-1}(Q^2) */
      assign(d, dd, VOLUME);
      /* dd = T_{j}(Q^2) */
      assign(dd, aux, VOLUME);
    }
    if(g_proc_id == g_stdio_proc && g_debug_level > 0) {
      printf("Order of Chebysheff approximation = %d\n",j); 
      fflush( stdout);
    }
     
    /* r = Q r */
    assign(aux, R, VOLUME); 
    norm_Q_n_psi(R, aux, 1, rnorm);

  }
  /* add in piece from projected subspace */
  addproj_q_invsqrt(R, S, no_eigenvalues-1, VOLUME);
  
  unlock_Dov_WS_spinor(2);
  unlock_Dov_WS_spinor(3);
  unlock_Dov_WS_spinor(4);
  unlock_Dov_WS_spinor(5);
  unlock_Dov_WS_spinor(6);
  return;
}
コード例 #2
0
ファイル: Ptilde_nd.c プロジェクト: LorenzoRiggio/tmLQCD
void Ptilde_ndpsi(spinor *R_s, spinor *R_c, double *dd, int n, 
		  spinor *S_s, spinor *S_c, matrix_mult_nd Qsq) {
  
  int j;
  double fact1, fact2, temp1, temp2, temp3, temp4;
  
  spinor *svs_=NULL, *svs=NULL, *ds_=NULL, *ds=NULL, *dds_=NULL, *dds=NULL, 
    *auxs_=NULL, *auxs=NULL, *aux2s_=NULL, *aux2s=NULL, *aux3s_=NULL, 
    *aux3s=NULL;
  spinor *svc_=NULL, *svc=NULL, *dc_=NULL, *dc=NULL, *ddc_=NULL, 
    *ddc=NULL, *auxc_=NULL, *auxc=NULL, *aux2c_=NULL, *aux2c=NULL, 
    *aux3c_=NULL, *aux3c=NULL;
  
  
  svs_  = calloc(VOLUMEPLUSRAND+1, sizeof(spinor));
  svs   = (spinor *)(((unsigned long int)(svs_)+ALIGN_BASE)&~ALIGN_BASE);
  ds_   = calloc(VOLUMEPLUSRAND+1, sizeof(spinor));
  ds    = (spinor *)(((unsigned long int)(ds_)+ALIGN_BASE)&~ALIGN_BASE);
  dds_  = calloc(VOLUMEPLUSRAND+1, sizeof(spinor));
  dds   = (spinor *)(((unsigned long int)(dds_)+ALIGN_BASE)&~ALIGN_BASE);
  auxs_ = calloc(VOLUMEPLUSRAND+1, sizeof(spinor));
  auxs  = (spinor *)(((unsigned long int)(auxs_)+ALIGN_BASE)&~ALIGN_BASE);
  aux2s_= calloc(VOLUMEPLUSRAND+1, sizeof(spinor));
  aux2s = (spinor *)(((unsigned long int)(aux2s_)+ALIGN_BASE)&~ALIGN_BASE);
  aux3s_= calloc(VOLUMEPLUSRAND+1, sizeof(spinor));
  aux3s = (spinor *)(((unsigned long int)(aux3s_)+ALIGN_BASE)&~ALIGN_BASE);
  svc_  = calloc(VOLUMEPLUSRAND+1, sizeof(spinor));
  svc   = (spinor *)(((unsigned long int)(svc_)+ALIGN_BASE)&~ALIGN_BASE);
  dc_   = calloc(VOLUMEPLUSRAND+1, sizeof(spinor));
  dc    = (spinor *)(((unsigned long int)(dc_)+ALIGN_BASE)&~ALIGN_BASE);
  ddc_  = calloc(VOLUMEPLUSRAND+1, sizeof(spinor));
  ddc   = (spinor *)(((unsigned long int)(ddc_)+ALIGN_BASE)&~ALIGN_BASE);
  auxc_ = calloc(VOLUMEPLUSRAND+1, sizeof(spinor));
  auxc  = (spinor *)(((unsigned long int)(auxc_)+ALIGN_BASE)&~ALIGN_BASE);
  aux2c_= calloc(VOLUMEPLUSRAND+1, sizeof(spinor));
  aux2c = (spinor *)(((unsigned long int)(aux2c_)+ALIGN_BASE)&~ALIGN_BASE);
  aux3c_= calloc(VOLUMEPLUSRAND+1, sizeof(spinor));
  aux3c = (spinor *)(((unsigned long int)(aux3c_)+ALIGN_BASE)&~ALIGN_BASE);
  
  fact1=4/(phmc_cheb_evmax-phmc_cheb_evmin);
  fact2=-2*(phmc_cheb_evmax+phmc_cheb_evmin)/(phmc_cheb_evmax-phmc_cheb_evmin);
  
  zero_spinor_field(&ds[0],VOLUME/2);
  zero_spinor_field(&dds[0],VOLUME/2); 
  zero_spinor_field(&dc[0],VOLUME/2);
  zero_spinor_field(&ddc[0],VOLUME/2); 
  
  /*   sub_low_ev(&aux3[0], &S[0]);  */
  assign(&aux3s[0], &S_s[0],VOLUME/2);  
  assign(&aux3c[0], &S_c[0],VOLUME/2);  
  
  /*  Use the Clenshaw's recursion for the Chebysheff polynomial */
  for (j=n-1; j>=1; j--) {
    assign(&svs[0],&ds[0],VOLUME/2);
    assign(&svc[0],&dc[0],VOLUME/2); 
    
    /*
     * if ( (j%10) == 0 ) {
     *   sub_low_ev(&aux[0], &d[0]);
     * } else { */
    assign(&auxs[0], &ds[0], VOLUME/2);
    assign(&auxc[0], &dc[0], VOLUME/2);
    /*   } */


    Qsq(&R_s[0], &R_c[0], &auxs[0], &auxc[0]);

    temp1=-1.0;
    temp2=dd[j];
    assign_mul_add_mul_add_mul_add_mul_r(&ds[0] , &R_s[0], &dds[0], &aux3s[0], fact2, fact1, temp1, temp2,VOLUME/2);
    assign_mul_add_mul_add_mul_add_mul_r(&dc[0] , &R_c[0], &ddc[0], &aux3c[0], fact2, fact1, temp1, temp2,VOLUME/2);
    assign(&dds[0], &svs[0],VOLUME/2);
    assign(&ddc[0], &svc[0],VOLUME/2);
  }

  assign(&R_s[0], &ds[0],VOLUME/2);
  assign(&R_c[0], &dc[0],VOLUME/2);

  Qsq(&auxs[0], &auxc[0], &R_s[0], &R_c[0]);

  temp1=-1.0;
  temp2=dd[0]/2;
  temp3=fact1/2;
  temp4=fact2/2;
  assign_mul_add_mul_add_mul_add_mul_r(&auxs[0], &ds[0], &dds[0], &aux3s[0], temp3, temp4, temp1, temp2,VOLUME/2);
  assign_mul_add_mul_add_mul_add_mul_r(&auxc[0], &dc[0], &ddc[0], &aux3c[0], temp3, temp4, temp1, temp2,VOLUME/2);
  assign(&R_s[0], &auxs[0],VOLUME/2);
  assign(&R_c[0], &auxc[0],VOLUME/2);

  free(svs_);
  free(ds_);
  free(dds_);
  free(auxs_);
  free(aux2s_);
  free(aux3s_);
  free(svc_);
  free(dc_);
  free(ddc_);
  free(auxc_);
  free(aux2c_);
  free(aux3c_);
}