示例#1
0
/* dest <- dest + sum_i eigVec[i]*H^{-1}*eigVec[i].resid, 
   resid = src - (-Dslash^2 + 4*mass^2)*dest
*/
static void initCG(su3_vector *src, su3_vector *dest, int Nvecs_curr, int Nvecs_max,
		   su3_vector **eigVec, double_complex *H, Real mass, int parity,
		   imp_ferm_links_t *fn){

  /* Constants */
  int ione = 1;
  int otherparity = (parity == EVEN) ? ODD : EVEN;
  Real msq_x4 = 4.0*mass*mass;
  double dzero = (double)0.0;
  double_complex zzero = dcmplx(dzero, dzero);

  register int i;
  int j, info;
  double_complex cc;
  double_complex *c, *H2;
  su3_vector *resid;

  c = (double_complex *)malloc(Nvecs_curr*sizeof(double_complex));
  resid = (su3_vector *)malloc(sites_on_node*sizeof(su3_vector));

  /* resid <- src - (-Dslash^2 + 4*mass^2)*dest */
  dslash_fn_field(dest, resid, otherparity, fn);
  dslash_fn_field(resid, resid, parity, fn);
  FORSOMEFIELDPARITY_OMP(i, parity, default(shared)){
    scalar_mult_sum_su3_vector(resid+i, dest+i, -msq_x4);
    add_su3_vector(resid+i, src+i, resid+i);
  } END_LOOP_OMP

  /* c[i] = eigVec[i].resid */
  for(j = 0; j < Nvecs_curr; j++){
//    c[j] = zzero;
//    FORSOMEFIELDPARITY_OMP(i, parity, private(cc) reduction(+:c[j])){
//      cc = su3_dot(eigVec[j]+i, resid+i);
//      CSUM(c[j], cc);
//    } END_LOOP_OMP

    double cctotr=0., cctoti=0.;
    FORSOMEFIELDPARITY_OMP(i, parity, private(cc) reduction(+:cctotr,cctoti)){
      cc = su3_dot(eigVec[j]+i, resid+i);
      cctotr += cc.real;
      cctoti += cc.imag;
    } END_LOOP_OMP;
    c[j].real = cctotr;
    c[j].imag = cctoti;

  }
  g_vecdcomplexsum(c, Nvecs_curr);

  free(resid);

  H2 = (double_complex *)malloc(Nvecs_curr*Nvecs_curr*sizeof(double_complex));

  /* H2 = H + 4*mass^2*I */
  for(j = 0; j < Nvecs_curr; j++){
    zcopy_(&Nvecs_curr, H+Nvecs_max*j, &ione, H2+Nvecs_curr*j, &ione);
    CSUM(H2[(Nvecs_curr+1)*j], dcmplx(msq_x4, dzero));
  }

  /* Compute H^{-1}*c = H^{-1}*eigVec.resid with Cholesky decomposition */
  zpotrf_("U", &Nvecs_curr, H2, &Nvecs_curr, &info);
  zpotrs_("U", &Nvecs_curr, &ione, H2, &Nvecs_curr, c, &Nvecs_curr, &info);

  free(H2);

  /* dest <- dest + sum_j c[i]*eigVec[i] = dest + sum_i eigVec[i]*H^{-1}*eigVec[i].resid */ 
  for(j = 0; j < Nvecs_curr; j++){
    FORSOMEFIELDPARITY_OMP(i, parity, default(shared)){
      c_scalar_mult_add_su3vec(dest+i, c+j, eigVec[j]+i);
    } END_LOOP_OMP
  }

  free(c);
}
示例#2
0
int main( int argc, char **argv ){
  register site *s;
  int i,si;
  int prompt;
  double dtime;
  su3_vector **eigVec ;
  su3_vector *tmp ;
  double *eigVal ;
  int total_R_iters ;
  double chirality ;

  initialize_machine(&argc,&argv);
#ifdef HAVE_QDP
  QDP_initialize(&argc, &argv);
#ifndef QDP_PROFILE
  QDP_profcontrol(0);
#endif
#endif
  /* Remap standard I/O */
  if(remap_stdio_from_args(argc, argv) == 1)terminate(1);

  g_sync();
  /* set up */
  prompt = setup();

  /* loop over input sets */
  while( readin(prompt) == 0){
    
    dtime = -dclock();
    invalidate_all_ferm_links(&fn_links);
    make_path_table(&ks_act_paths, &ks_act_paths_dmdu0);
    /* Load fat and long links for fermion measurements if needed */
    load_ferm_links(&fn_links, &ks_act_paths);
    /* call fermion_variable measuring routines */
    /* results are printed in output file */
    f_meas_imp( F_OFFSET(phi), F_OFFSET(xxx), mass,
		&fn_links, &fn_links_dmdu0);
    eigVal = (double *)malloc(Nvecs*sizeof(double));
    eigVec = (su3_vector **)malloc(Nvecs*sizeof(su3_vector*));
    for(i=0;i<Nvecs;i++)
      eigVec[i]=
	(su3_vector*)malloc(sites_on_node*sizeof(su3_vector));
    
    total_R_iters=Kalkreuter(eigVec, eigVal, eigenval_tol, 
			     error_decr, Nvecs, MaxIter, Restart, 
			     Kiters, EVEN, &fn_links) ;
    tmp = (su3_vector*)malloc(sites_on_node*sizeof(su3_vector));
    for(i=0;i<Nvecs;i++)
      { 
	/* Construct to odd part of the vector.                 *
	 * Note that the true odd part of the eigenvector is    *
	 *  i/sqrt(eigVal) Dslash Psi. But since I only compute *
	 * the chirality the i factor is irrelevant (-i)*i=1!!  */
	dslash_fn_field(eigVec[i], tmp, ODD, &fn_links) ;
	FORSOMEPARITY(si,s,ODD){ 
	  scalar_mult_su3_vector( &(tmp[si]),
				  1.0/sqrt(eigVal[i]), 
				  &(eigVec[i][si]) ) ;
	}
	
	measure_chirality(eigVec[i], &chirality, EVENANDODD);
	/* Here I divide by 2 since the EVEN vector is normalized to
	 * 1. The EVENANDODD vector is normalized to 2. I could have
	 * normalized the EVENANDODD vector to 1 and then not devide
	 * by to.  The measure_chirality routine assumes vectors
	 * normalized to 1.  */
	node0_printf("Chirality(%i): %g\n",i,chirality/2) ;
      }
    free(tmp);
    /**
       for(i=0;i<Nvecs;i++)
       {
       sprintf(label,"DENSITY(%i)",i) ;
       print_densities(eigVec[i], label, ny/2,nz/2,nt/2, EVEN) ;
       }
    **/
    for(i=0;i<Nvecs;i++)
      free(eigVec[i]) ;
    free(eigVec) ;
    free(eigVal) ;
#ifdef FN
    invalidate_all_ferm_links(&fn_links);
#endif
    fflush(stdout);
    
    node0_printf("RUNNING COMPLETED\n"); fflush(stdout);
    dtime += dclock();
    if(this_node==0){
      printf("Time = %e seconds\n",dtime);
      printf("total_iters = %d\n",total_iters);
      printf("total Rayleigh iters = %d\n",total_R_iters);
    }
    fflush(stdout);
  }
示例#3
0
void f_meas_imp_field( int npbp_reps, quark_invert_control *qic, Real mass,
		       int naik_term_epsilon_index, fermion_links_t *fl){

  imp_ferm_links_t* fn = get_fm_links(fl)[naik_term_epsilon_index];

#ifdef DM_DU0
  imp_ferm_links_t* fn_du0 = get_fm_du0_links(fl)[naik_term_epsilon_index];
#endif

#if ( FERM_ACTION == HISQ || FERM_ACTION == HYPISQ ) & defined(DM_DEPS)
  imp_ferm_links_t *fn_deps = get_fn_deps_links(fl);
#endif

    Real r_psi_bar_psi_even, i_psi_bar_psi_even;
    Real  r_psi_bar_psi_odd, i_psi_bar_psi_odd;
    Real r_ferm_action;
    /* local variables for accumulators */
    register int i;
    double rfaction;
    double_complex pbp_e, pbp_o;
    complex cc;

    int jpbp_reps;
    su3_vector *gr = NULL;
    su3_vector *M_gr = NULL;
    su3_vector *M_inv_gr = NULL;

#ifdef DM_DU0
    double r_pb_dMdu_p_even, r_pb_dMdu_p_odd;
    su3_vector *dMdu_x = NULL;
#endif

#if ( FERM_ACTION == HISQ || FERM_ACTION == HYPISQ ) & defined(DM_DEPS)
    double r_pb_dMdeps_p_even, r_pb_dMdeps_p_odd;
    su3_vector *dMdeps_x = NULL;
#endif

#ifdef CHEM_POT
    double_complex pb_dMdmu_p_e, pb_dMdmu_p_o;
    double_complex pb_d2Mdmu2_p_e, pb_d2Mdmu2_p_o;
    double MidM_MidM;
    su3_vector *dM_M_inv_gr = NULL;
    su3_vector *d2M_M_inv_gr = NULL;
    su3_vector *M_inv_dM_M_inv_gr = NULL;
    su3_vector *dM_M_inv_dM_M_inv_gr = NULL;
#endif

    /* Loop over random sources */
    for(jpbp_reps = 0; jpbp_reps < npbp_reps; jpbp_reps++){

      rfaction = (double)0.0;
      pbp_e = pbp_o = dcmplx((double)0.0,(double)0.0);
      
      /* Make random source, and do inversion */
      /* generate gr random; M_gr = M gr */
      gr = create_v_field();
#ifndef Z2RSOURCE
      grsource_plain_field( gr, EVENANDODD );
#else
      z2rsource_plain_field( gr, EVENANDODD );
#endif
      /* The following operation is done in the prevailing
	 precision.  The algorithm needs to be fixed! */
      M_gr = create_v_field();
      ks_dirac_adj_op( gr, M_gr, mass, EVENANDODD, fn );

      /* M_inv_gr = M^{-1} gr */

      M_inv_gr = create_v_field();
      mat_invert_uml_field( gr, M_inv_gr, qic, mass, fn );
      
#ifdef DM_DU0
      r_pb_dMdu_p_even = r_pb_dMdu_p_odd = (double)0.0;
      /* dMdu_x = dM/du0 M^{-1} gr */
      dMdu_x = create_v_field();
      dslash_fn_field( M_inv_gr, dMdu_x, EVENANDODD, fn_du0 );
#endif

#if ( FERM_ACTION == HISQ || FERM_ACTION == HYPISQ ) & defined(DM_DEPS)
      r_pb_dMdeps_p_even = r_pb_dMdeps_p_odd = (double)0.0;
      /* dMdeps_x = dM/deps0 M^{-1} gr */
      dMdeps_x = create_v_field();
      dslash_fn_field( M_inv_gr, dMdeps_x, EVENANDODD, fn_deps );
#endif

#ifdef CHEM_POT
      pb_dMdmu_p_e = pb_dMdmu_p_o = dcmplx((double)0.0,(double)0.0);
      pb_d2Mdmu2_p_e = pb_d2Mdmu2_p_o = dcmplx((double)0.0,(double)0.0);

      /* dM_M_inv_gr = dM/dmu * M_inv_gr */
      /* d2M_M_inv_gr = d2M/dmu2 * M_inv_gr */
      dM_M_inv_gr = create_v_field();
      chem_pot_tshift(fn, dM_M_inv_gr, M_inv_gr, 3., -1.);
      d2M_M_inv_gr = create_v_field();
      chem_pot_tshift(fn, d2M_M_inv_gr, M_inv_gr, 9., 1.);

#endif

      /* fermion action = M_gr.M_inv_gr */
      /* psi-bar-psi on even sites = gr.M_inv_gr */
      FOREVENFIELDSITES(i){
	rfaction += su3_rdot( M_gr+i, M_inv_gr+i );
	cc = su3_dot( gr+i, M_inv_gr+i );
	CSUM(pbp_e, cc);

#ifdef DM_DU0
	/* r_pb_dMdu_p_even = gr * dM/du0 M^{-1} gr |even*/
	r_pb_dMdu_p_even += su3_rdot( gr+i, dMdu_x+i );
#endif

#if ( FERM_ACTION == HISQ || FERM_ACTION == HYPISQ ) & defined(DM_DEPS)
	/* r_pb_dMdu_p_even = gr * dM/du0 M^{-1} gr |even*/
	r_pb_dMdeps_p_even += su3_rdot( gr+i, dMdeps_x+i );
#endif

#ifdef CHEM_POT
	/* Compute pb_dMdmu_p, pb_d2Mdmu2_p and dM_M_inv on even sites */
	cc = su3_dot( gr+i, dM_M_inv_gr+i);
	CSUM(pb_dMdmu_p_e, cc);
	cc = su3_dot( gr+i, d2M_M_inv_gr+i);
	CSUM(pb_d2Mdmu2_p_e, cc);
#endif
      }

      /* psi-bar-psi on odd sites */
      FORODDFIELDSITES(i){
	cc = su3_dot( gr+i, M_inv_gr+i );
	CSUM(pbp_o, cc);
#ifdef DM_DU0
	/* r_pb_dMdu_p_odd = gr * dM/du0 M^{-1} gr |odd*/
	r_pb_dMdu_p_odd += su3_rdot( gr+i, dMdu_x+i );
#endif

#if ( FERM_ACTION == HISQ || FERM_ACTION == HYPISQ ) & defined(DM_DEPS)
	/* r_pb_dMdu_p_odd = gr * dM/du0 M^{-1} gr |odd*/
	r_pb_dMdeps_p_odd += su3_rdot( gr+i, dMdeps_x+i );
#endif

#ifdef CHEM_POT
	/* Compute pb_dMdmu_P, pb_d2Mdmu2_p and dM_M_inv on odd sites */
	cc = su3_dot( gr+i, dM_M_inv_gr+i);
	CSUM(pb_dMdmu_p_o, cc);
	cc = su3_dot( gr+i, d2M_M_inv_gr+i);
	CSUM(pb_d2Mdmu2_p_o, cc);
#endif
      }

#ifdef CHEM_POT
      destroy_v_field(d2M_M_inv_gr); d2M_M_inv_gr = NULL;
#endif
      destroy_v_field(M_gr); M_gr = NULL;

      g_dcomplexsum( &pbp_o );
      g_dcomplexsum( &pbp_e );
      g_doublesum( &rfaction );
      
#ifdef DM_DU0
      destroy_v_field( dMdu_x ); dMdu_x = NULL;
      g_doublesum( &r_pb_dMdu_p_even );
      g_doublesum( &r_pb_dMdu_p_odd );
      r_pb_dMdu_p_even *= (2.0/(double)volume);
      r_pb_dMdu_p_odd *= (2.0/(double)volume);
      node0_printf("PB_DMDU_P: mass %e  %e  %e ( %d of %d )\n", mass,
		   r_pb_dMdu_p_even, r_pb_dMdu_p_odd, jpbp_reps+1, npbp_reps);
#endif

#if ( FERM_ACTION == HISQ || FERM_ACTION == HYPISQ ) & defined(DM_DEPS)
      destroy_v_field( dMdeps_x ); dMdeps_x = NULL;
      g_doublesum( &r_pb_dMdeps_p_even );
      g_doublesum( &r_pb_dMdeps_p_odd );
      r_pb_dMdeps_p_even *= (2.0/(double)volume);
      r_pb_dMdeps_p_odd *= (2.0/(double)volume);
      node0_printf("PB_DMDEPS_P: mass %e  %e  %e ( %d of %d )\n", mass,
		   r_pb_dMdeps_p_even, r_pb_dMdeps_p_odd, jpbp_reps+1, npbp_reps);
#endif

      r_psi_bar_psi_odd =  pbp_o.real*(2.0/(double)volume) ;
      i_psi_bar_psi_odd =  pbp_o.imag*(2.0/(double)volume) ;
      r_psi_bar_psi_even =  pbp_e.real*(2.0/(double)volume) ;
      i_psi_bar_psi_even =  pbp_e.imag*(2.0/(double)volume) ;
      r_ferm_action =  rfaction*(1.0/(double)volume) ;
      node0_printf("PBP: mass %e     %e  %e  %e  %e ( %d of %d )\n", mass,
		   r_psi_bar_psi_even, r_psi_bar_psi_odd,
		   i_psi_bar_psi_even, i_psi_bar_psi_odd,
		   jpbp_reps+1, npbp_reps);
      node0_printf("FACTION: mass = %e,  %e ( %d of %d )\n", mass,
		   r_ferm_action, jpbp_reps+1, npbp_reps);

#ifdef CHEM_POT
      /* Print results for pb_dMdmu_p and pb_d2Mdmu2_p */
      chem_pot_print1(pb_dMdmu_p_e, pb_dMdmu_p_o, pb_d2Mdmu2_p_e, pb_d2Mdmu2_p_o,
		      mass, jpbp_reps, npbp_reps);
#endif

#ifdef TR_MM_INV
      if(npbp_reps > 1){
	su3_vector *MM_inv_gr = create_v_field();
	double pbp_pbp = 0.0;

	mat_invert_uml_field( M_inv_gr, MM_inv_gr, qic, mass, fn );
	FORALLFIELDSITES(i){
	  pbp_pbp += su3_rdot( gr+i, MM_inv_gr+i );
	}
	g_doublesum( &pbp_pbp );
	pbp_pbp =  pbp_pbp*(1.0/(double)volume) ;
	node0_printf("TR_MM_INV: mass %e,  %e ( %d of %d )\n", mass,
		     pbp_pbp, jpbp_reps+1, npbp_reps);
	destroy_v_field(MM_inv_gr);
      }
#endif
      destroy_v_field(M_inv_gr); M_inv_gr = NULL;

#ifdef CHEM_POT
      /* M_inv_dM_M_inv_gr = M^{-1} dM_M_inv_gr */

      M_inv_dM_M_inv_gr = create_v_field();
      mat_invert_uml_field( dM_M_inv_gr, M_inv_dM_M_inv_gr, qic, mass, fn );
      destroy_v_field(dM_M_inv_gr); dM_M_inv_gr = NULL;

      /* dM_M_inv_dM_M_inv_gr = dM/dmu M_inv_dM_M_inv_gr */

      dM_M_inv_dM_M_inv_gr = create_v_field();
      chem_pot_tshift(fn, dM_M_inv_dM_M_inv_gr, M_inv_dM_M_inv_gr, 3., -1.);
      destroy_v_field(M_inv_dM_M_inv_gr); M_inv_dM_M_inv_gr = NULL;

      /* Compute MidM_MidM */
      MidM_MidM = (double)0.0;
      FORALLFIELDSITES(i){
	MidM_MidM += su3_rdot( gr+i, dM_M_inv_dM_M_inv_gr+i);
      }

      destroy_v_field(dM_M_inv_dM_M_inv_gr); dM_M_inv_dM_M_inv_gr = NULL;

      chem_pot_print2(MidM_MidM, jpbp_reps, npbp_reps, mass);

#endif
      destroy_v_field(gr); gr = NULL;

    } /* jpbp_reps */