static QOP_FermionLinksWilson * create_qop_wilson_fermion_links( Real clov ){ clover *milc_clov = gen_clov; MYSU3_MATRIX **raw_links; MYREAL *raw_clov; QOP_FermionLinksWilson *qop_links; /* Construct raw QOP clover term from MILC clover term */ if(clov == 0){ raw_clov = NULL; } else{ raw_clov = (MYREAL *)malloc(72*sites_on_node*sizeof(MYREAL)); if(raw_clov == NULL){ printf("create_qop_wilson_fermion_links(%d): no room for raw_clov\n", this_node); terminate(1); } // milc_clov = create_clov(); /* Note Real clov has no kappa factor! */ if(milc_clov == NULL) terminate(1); compute_clov(milc_clov,clov); map_milc_clov_to_qop_raw(raw_clov, milc_clov); //free_this_clov(milc_clov); } raw_links = CREATE_RAW4_G_FROM_SITE(F_OFFSET(link), EVENANDODD); if(raw_links == NULL)terminate(1); /* Map QOP/QDP raw to QOP/QDP structure */ qop_links = QOP_wilson_create_L_from_raw((MYREAL **)raw_links, raw_clov, QOP_EVENODD); DESTROY_RAW4_G(raw_links); raw_links = NULL; free(raw_clov); return qop_links; }
static QOP_FermionLinksWilson * create_qop_wilson_fermion_links( Real clov ){ clover *milc_clov = gen_clov; dsu3_matrix **raw_links; double *raw_clov; QOP_FermionLinksWilson *qop_links; /* Construct raw QOP clover term from MILC clover term */ if(clov == 0){ raw_clov = NULL; } else{ raw_clov = (double *)malloc(72*sites_on_node*sizeof(double)); if(raw_clov == NULL){ printf("create_qop_wilson_fermion_links(%d): no room for raw_clov\n", this_node); terminate(1); } // milc_clov = create_clov(); /* Note Real clov has no kappa factor! */ if(milc_clov == NULL) terminate(1); compute_clov(milc_clov,clov); map_milc_clov_to_qop_raw(raw_clov, milc_clov); //free_this_clov(milc_clov); } raw_links = create_raw4_D_G_from_site(F_OFFSET(link), EVENANDODD); if(raw_links == NULL)terminate(1); /* Map QOP/QDP raw to QOP/QDP structure */ qop_links = QOP_wilson_create_L_from_raw((double **)raw_links, raw_clov, QOP_EVENODD); destroy_raw4_D_G(raw_links); raw_links = NULL; free(raw_clov); return qop_links; }
int bicgilu_cl_field_cpu( /* Return value is number of iterations taken */ wilson_vector *src, /* type wilson_vector (source vector - OVERWRITTEN!)*/ wilson_vector *dest, /* type wilson_vector (answer and initial guess )*/ quark_invert_control *qic, /* parameters controlling inversion */ void *dmp /* parameters defining the Dirac matrix */ ) { /* Unpack required members of the structures */ int max_restarts = qic->nrestart; /* Number of restarts */ int nrestart = 0; int restart = qic->max; /* Restart interval */ int MaxCG = restart*qic->max; /* maximum number of iterations */ Real RsdCG = qic->resid * qic->resid; /* desired residual - normalized as (r*r)/(src_e*src_e) */ Real RRsdCG = qic->relresid * qic->relresid; /* desired relative residual - */ int flag = qic->start_flag; /* 0: use a zero initial guess; 1: use dest */ dirac_clover_param *dcp = (dirac_clover_param *)dmp; /* Cast pass-through pointer */ Real Kappa = dcp->Kappa; /* hopping */ Real Clov_c = dcp->Clov_c; /* Perturbative clover coeff */ Real U0 = dcp->U0; /* Tadpole correction to Clov_c */ /* End of unpacking required members of structures */ wilson_vector *tmp=NULL,*mp=NULL,*rv=NULL,*sss=NULL,*r=NULL, *p=NULL,*ttt=NULL; int N_iter; register int i; register site *s; Real size_src, size_src2; double rsq, tsq; complex ctmp, a, b; complex omega, omegam; double_complex tdots,rvro,rvv,rvr; register Real MKsq = -Kappa*Kappa; Real CKU0 = Kappa*Clov_c/(U0*U0*U0); #ifdef CGTIME double dtime; #endif msg_tag *tago[8],*tage[8]; int is_startedo, is_startede; is_startedo = is_startede = 0; qic->size_r = 0; qic->size_relr = 0; qic->final_rsq = 0; qic->final_relrsq = 0; qic->final_iters = 0; qic->final_restart = 0; /* Handle trivial case */ if(Kappa == 0.){ copy_wv_field(dest,src); return 0; } // if(even_sites_on_node!=odd_sites_on_node){ // printf("Need same number of even and odd sites on each node\n"); // terminate(1); // } /* Compute R_e and R_o and put in "clov" and "clov_diag" */ compute_clov(gen_clov, CKU0); /* Invert R_o only, leaving R_e on even sites and 1/R_o on odd sites in "clov" and "clov_diag" */ compute_clovinv(gen_clov, ODD); /* now we can allocate temporary variables and copy them */ /* PAD may be used to avoid cache trashing */ #define PAD 0 tmp = (wilson_vector *) malloc((sites_on_node+PAD)*sizeof(wilson_vector)); mp = (wilson_vector *) malloc((sites_on_node+PAD)*sizeof(wilson_vector)); rv = (wilson_vector *) malloc((sites_on_node+PAD)*sizeof(wilson_vector)); sss = (wilson_vector *) malloc((sites_on_node+PAD)*sizeof(wilson_vector)); r = (wilson_vector *) malloc((sites_on_node+PAD)*sizeof(wilson_vector)); p = (wilson_vector *) malloc((sites_on_node+PAD)*sizeof(wilson_vector)); ttt = (wilson_vector *) malloc((sites_on_node+PAD)*sizeof(wilson_vector)); if(tmp == NULL || mp == NULL || mp == NULL || rv == NULL || sss == NULL || r == NULL ){ printf("bicgilu_cl_field(%d): No room for temporaries\n",this_node); terminate(1); } /* BiCGstab_ILU: */ /* Transform source - result is in r (even) - and dest (odd) */ #ifdef CGTIME dtime = -dclock(); #endif /* now we copy src to temporaries */ FORALLSITES(i,s) { r[i] = src[i]; } /* src = L^(-1)*src */ size_src = ilu_xfm_source(dest, r, mp, Kappa, &is_startede, tage); size_src2 = size_src*size_src; #if 0 mult_this_ldu_field(gen_clov, r, mp, ODD); dslash_w_field_special(mp, mp, PLUS, EVEN, tage, is_startede); is_startede = 1; /* Normalization */ rsq = 0.0; FOREVENSITESDOMAIN(i,s) { scalar_mult_add_wvec( &(r[i]), &(mp[i]), Kappa, &(r[i]) ); rsq += (double)magsq_wvec( &(r[i]) ); /* Save transformed source: Overwrite src on even sites */ copy_wvec( &(r[i]), &(src[i]) ); }