예제 #1
0
void fermion_forwardstep(field_offset flow_vec){
  Real eps = epsilon;
  register int i;
  register site *s;
  int j, off[4];
  for (j = 0; j < 4; j++) off[j] = flow_vec + j*sizeof(su3_vector);

  // Step ODD sites

  // Obtain lambda1
  fdslash(off[0], F_OFFSET(W0), off[1], EVEN);
  fdslash(off[1], F_OFFSET(W0), off[1], ODD);
  scalar_mult_add_latvec(off[0], off[1], eps/4,
      off[1], ODD);
  
  // Obtain lambda2
  fdslash(off[1], F_OFFSET(W1), off[2], EVEN);
  fdslash(off[2], F_OFFSET(W1), off[2], ODD);
  scalar_mult_latvec(off[2], 8*eps/9, off[2], ODD);
  scalar_mult_add_latvec(off[2], off[1], -8/9, 
      off[2], ODD);
  scalar_mult_add_latvec(off[2], off[0], 17/9, 
      off[2], ODD);

  // Obtain lambda3
  fdslash(off[2], F_OFFSET(W2), off[3], EVEN);
  fdslash(off[3], F_OFFSET(W2), off[3], ODD);
  scalar_mult_add_latvec(off[1], off[3], 3*eps/4, 
      off[3], ODD);

  // copy odd sites of lambda3
  FORODDSITES(i,s){
    su3vec_copy((su3_vector *)F_PT(s,off[3]), &(s->tempvec0));
  }
int mat_invert_uml(field_offset src, field_offset dest, field_offset temp,
		   double mass ){
    int cgn;
    double finalrsq;
    register int i;
    register site *s;

    if( src==temp ){
	printf("BOTCH\n"); exit(0);
    }
    /* multiply by U - even sites only */
    dslash( src, F_OFFSET(ttt), EVEN);
    scalar_mult_add_latvec( F_OFFSET(ttt), src,
       -2.0*mass, temp, EVEN);
    scalar_mult_latvec( temp, -1.0, temp, EVEN);
    /* invert with M_adj M even */
    cgn = ks_congrad( temp, dest, mass, niter, rsqprop,
	EVEN, &finalrsq );
    /* multiply by (1/2m)L, does nothing to even sites */
    /* fix up odd sites , 1/2m (Dslash_oe*dest_e + phi_odd) */
    dslash( dest, F_OFFSET(ttt), ODD );
    FORODDSITES(i,s){
	sub_su3_vector( (su3_vector *)F_PT(s,src), &(s->ttt), 
	    (su3_vector *)F_PT(s,dest) );
	scalar_mult_su3_vector( (su3_vector *)F_PT(s,dest), 1.0/(2.0*mass),
	    (su3_vector *)F_PT(s,dest) );
    }
예제 #3
0
// -----------------------------------------------------------------
// dest <-- M^(-1) src
int mat_invert_uml(field_offset src, field_offset dest,
                   field_offset temp, Real mass) {

  register int i;
  register site *s;
  int cgn;
  Real norm = 1.0 / (2.0 * mass);

  if (src == temp) {
    printf("MAT_INVERT_UML: src = temp\n");
    exit(0);
  }

  // "Precondition" both even and odd sites
  // temp <-- M^dag src
  dslash(src, F_OFFSET(ttt), EVENANDODD);
  scalar_mult_add_latvec(F_OFFSET(ttt), src,
                         -2.0 * mass, temp, EVENANDODD);
  scalar_mult_latvec(temp, -1.0, temp, EVENANDODD);

  // dest_e <-- (M^dag M)^-1 temp_e  (even sites only)
  cgn = ks_congrad(temp, dest, mass, EVEN);

  // Reconstruct odd site solution
  // dest_o <-- 1/2m (Dslash_oe * dest_e + src_o)
  dslash(dest, F_OFFSET(ttt), ODD);
  FORODDSITES(i, s) {
    sub_vector((vector *)F_PT(s, src), &(s->ttt),
                   (vector *)F_PT(s, dest));
    scalar_mult_vector((vector *)F_PT(s, dest), norm,
                           (vector *)F_PT(s, dest));
  }
/* Compute M^-1 * phi, answer in dest
  Uses phi, ttt, resid, xxx, and cg_p as workspace */
int mat_invert_cg( field_offset src, field_offset dest, field_offset temp,
		   double mass ){
    int cgn;
    double finalrsq;
    clear_latvec( dest, EVENANDODD );
    cgn = ks_congrad( src, dest, mass,
        niter,rsqprop,EVENANDODD,&finalrsq);
    /* Multiply by Madjoint */
    dslash( dest, F_OFFSET(ttt), EVENANDODD);
    scalar_mult_add_latvec( F_OFFSET(ttt), dest,
       -2.0*mass, F_OFFSET(ttt), EVENANDODD);
    scalar_mult_latvec( F_OFFSET(ttt), -1.0, dest, EVENANDODD );
    return(cgn);
}
예제 #5
0
파일: grsource.c 프로젝트: goyalankit/milc
/* Before calling checkmul() you should call grsource(EVENANDODD) and
   congrad(...,EVENANDODD) */
void checkmul() {
register int i,j;
register site *s;
    dslash( F_OFFSET(xxx), F_OFFSET(ttt), EVENANDODD);
    scalar_mult_add_latvec( F_OFFSET(ttt), F_OFFSET(xxx), 2.0*mass,
	F_OFFSET(ttt), EVENANDODD );
    FORALLSITESDOMAIN(i,s){
	printf("Site %d %d %d %d\n",s->x,s->y,s->z,s->t);
	for(j=0;j<3;j++){
	    printf("%d %d\t%e\t%e\t%e\n",i,j,(double)s->g_rand.c[j].real,
		(double)s->ttt.c[j].real,(double)s->g_rand.c[j].real - (double)s->ttt.c[j].real);
	    printf("%d %d\t%e\t%e\t%e\n",i,j,(double)s->g_rand.c[j].imag,
		(double)s->ttt.c[j].imag,(double)s->g_rand.c[j].imag - (double)s->ttt.c[j].imag);
	}
	printf("\n");
    }
예제 #6
0
// -----------------------------------------------------------------
// For single pseudofermion or inner Hasenbusch pseudofermion
// dest = M^dag g_rand
void grsource_imp(field_offset dest, Real M, int parity) {
  register int i, j;
  register site *s;
  FORALLSITES(i, s) {
    for (j = 0; j < 3; j++) {
#ifdef SITERAND
      s->g_rand.c[j].real = gaussian_rand_no(&(s->site_prn));
      s->g_rand.c[j].imag = gaussian_rand_no(&(s->site_prn));
#else
      s->g_rand.c[j].real = gaussian_rand_no(&node_prn);
      s->g_rand.c[j].imag = gaussian_rand_no(&node_prn);
#endif
    }
  }
  // Hit g_rand with M^dag
  dslash(F_OFFSET(g_rand), dest, parity);
  scalar_mult_latvec(dest, -1.0, dest, parity);
  scalar_mult_add_latvec(dest, F_OFFSET(g_rand), 2.0 * M, dest, parity);
}
예제 #7
0
파일: grsource.c 프로젝트: goyalankit/milc
/* "parity" is EVEN, ODD, or EVENANDODD.  The parity is the parity at
    which phi is computed.  g_rand must always be computed at all sites. */
void grsource(int parity) {
register int i,j;
register site *s;
    FORALLSITES(i,s){
#ifdef SCHROED_FUN
	if(s->t > 0){
#endif
	    for(j=0;j<3;j++){
#ifdef SITERAND
		s->g_rand.c[j].real = gaussian_rand_no(&(s->site_prn));
		s->g_rand.c[j].imag = gaussian_rand_no(&(s->site_prn));
#else
		s->g_rand.c[j].real = gaussian_rand_no(&node_prn);
		s->g_rand.c[j].imag = gaussian_rand_no(&node_prn);
#endif
	    }
#ifdef SCHROED_FUN
	}
	else{	/* Set all fermion vectors to zero at t=0 */
	    for(j=0;j<3;j++){
		s->phi.c[j].real = s->phi.c[j].imag = 0.0;
		s->resid.c[j].real = s->resid.c[j].imag = 0.0;
		s->cg_p.c[j].real = s->cg_p.c[j].imag = 0.0;
		s->xxx.c[j].real = s->xxx.c[j].imag = 0.0;
		s->ttt.c[j].real = s->ttt.c[j].imag = 0.0;
		s->g_rand.c[j].real = s->g_rand.c[j].imag = 0.0;
	    }
	}
#endif
    }
    clear_latvec( F_OFFSET(xxx), EVENANDODD );
    dslash( F_OFFSET(g_rand), F_OFFSET(phi), parity);
    scalar_mult_latvec( F_OFFSET(phi), -1.0, F_OFFSET(phi), parity );
    scalar_mult_add_latvec( F_OFFSET(phi), F_OFFSET(g_rand), 2.0*mass,
	F_OFFSET(phi), parity );
}/* grsource */