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) );
    }
Example #2
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));
  }
Example #3
0
void dslashRef() {

  // FIXME: remove once reference clover is finished
  if (inv_param.matpc_type == QUDA_MATPC_EVEN_EVEN_ASYMMETRIC) {
    inv_param.matpc_type = QUDA_MATPC_EVEN_EVEN;
  } else if (inv_param.matpc_type == QUDA_MATPC_ODD_ODD_ASYMMETRIC) {
    inv_param.matpc_type = QUDA_MATPC_ODD_ODD;
  }

  // compare to dslash reference implementation
  printf("Calculating reference implementation...");
  fflush(stdout);
  switch (test_type) {
  case 0:
    dslash(spinorRef->V(), hostGauge, spinor->V(), parity, dagger, 
	   inv_param.cpu_prec, gauge_param.cpu_prec, inv_param.mass);
    break;
  case 1:    
    matpc(spinorRef->V(), hostGauge, spinor->V(), kappa5, inv_param.matpc_type, dagger, 
	  inv_param.cpu_prec, gauge_param.cpu_prec, inv_param.mass);
    break;
  case 2:
    mat(spinorRef->V(), hostGauge, spinor->V(), kappa5, dagger, 
	inv_param.cpu_prec, gauge_param.cpu_prec, inv_param.mass);
    break;
  default:
    printf("Test type not defined\n");
    exit(-1);
  }

  printf("done.\n");
    
}
/* 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);
}
Example #5
0
/* 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");
    }
Example #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);
}
Example #7
0
/* "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 */