static void bc_groups(const t_commrec *cr,t_symtab *symtab, int natoms,gmx_groups_t *groups) { int dummy; int g,n; bc_grps(cr,groups->grps); block_bc(cr,groups->ngrpname); bc_strings(cr,symtab,groups->ngrpname,&groups->grpname); for(g=0; g<egcNR; g++) { if (MASTER(cr)) { if (groups->grpnr[g]) { n = natoms; } else { n = 0; } } block_bc(cr,n); if (n == 0) { groups->grpnr[g] = NULL; } else { snew_bc(cr,groups->grpnr[g],n); nblock_bc(cr,n,groups->grpnr[g]); } } if (debug) fprintf(debug,"after bc_groups\n"); }
static void bc_atoms(const t_commrec *cr,t_symtab *symtab,t_atoms *atoms) { int dummy; block_bc(cr,atoms->nr); snew_bc(cr,atoms->atom,atoms->nr); nblock_bc(cr,atoms->nr,atoms->atom); bc_strings(cr,symtab,atoms->nr,&atoms->atomname); block_bc(cr,atoms->nres); snew_bc(cr,atoms->resinfo,atoms->nres); nblock_bc(cr,atoms->nres,atoms->resinfo); bc_strings_resinfo(cr,symtab,atoms->nres,atoms->resinfo); /* QMMM requires atomtypes to be known on all nodes as well */ bc_strings(cr,symtab,atoms->nr,&atoms->atomtype); bc_strings(cr,symtab,atoms->nr,&atoms->atomtypeB); }
static void bc_imd(const t_commrec *cr, t_IMD *imd) { int g; block_bc(cr, *imd); snew_bc(cr, imd->ind, imd->nat); nblock_bc(cr, imd->nat, imd->ind); }
static void bc_molblock(const t_commrec *cr, gmx_molblock_t *molb) { block_bc(cr, *molb); if (molb->nposres_xA > 0) { snew_bc(cr, molb->posres_xA, molb->nposres_xA); nblock_bc(cr, molb->nposres_xA*DIM, molb->posres_xA[0]); } if (molb->nposres_xB > 0) { snew_bc(cr, molb->posres_xB, molb->nposres_xB); nblock_bc(cr, molb->nposres_xB*DIM, molb->posres_xB[0]); } if (debug) { fprintf(debug, "after bc_molblock\n"); } }
/* Allocate and fill an array with coordinates and charges, * returns the number of charges found */ static int prepare_x_q(real *q[], rvec *x[], gmx_mtop_t *mtop, rvec x_orig[], t_commrec *cr) { int i; int nq; /* number of charged particles */ gmx_mtop_atomloop_all_t aloop; t_atom *atom; if (MASTER(cr)) { snew(*q, mtop->natoms); snew(*x, mtop->natoms); nq = 0; aloop = gmx_mtop_atomloop_all_init(mtop); while (gmx_mtop_atomloop_all_next(aloop, &i, &atom)) { if (is_charge(atom->q)) { (*q)[nq] = atom->q; (*x)[nq][XX] = x_orig[i][XX]; (*x)[nq][YY] = x_orig[i][YY]; (*x)[nq][ZZ] = x_orig[i][ZZ]; nq++; } } /* Give back some unneeded memory */ srenew(*q, nq); srenew(*x, nq); } /* Broadcast x and q in the parallel case */ if (PAR(cr)) { /* Transfer the number of charges */ block_bc(cr, nq); snew_bc(cr, *x, nq); snew_bc(cr, *q, nq); nblock_bc(cr, nq, *x); nblock_bc(cr, nq, *q); } return nq; }
static void bc_molblock(const t_commrec *cr,gmx_molblock_t *molb) { bool bAlloc=TRUE; block_bc(cr,molb->type); block_bc(cr,molb->nmol); block_bc(cr,molb->natoms_mol); block_bc(cr,molb->nposres_xA); if (molb->nposres_xA > 0) { snew_bc(cr,molb->posres_xA,molb->nposres_xA); nblock_bc(cr,molb->nposres_xA*DIM,molb->posres_xA[0]); } block_bc(cr,molb->nposres_xB); if (molb->nposres_xB > 0) { snew_bc(cr,molb->posres_xB,molb->nposres_xB); nblock_bc(cr,molb->nposres_xB*DIM,molb->posres_xB[0]); } if (debug) fprintf(debug,"after bc_molblock\n"); }
static void bc_ilists(const t_commrec *cr, t_ilist *ilist) { int ftype; /* Here we only communicate the non-zero length ilists */ if (MASTER(cr)) { for (ftype = 0; ftype < F_NRE; ftype++) { if (ilist[ftype].nr > 0) { block_bc(cr, ftype); block_bc(cr, ilist[ftype].nr); nblock_bc(cr, ilist[ftype].nr, ilist[ftype].iatoms); } } ftype = -1; block_bc(cr, ftype); } else { for (ftype = 0; ftype < F_NRE; ftype++) { ilist[ftype].nr = 0; } do { block_bc(cr, ftype); if (ftype >= 0) { block_bc(cr, ilist[ftype].nr); snew_bc(cr, ilist[ftype].iatoms, ilist[ftype].nr); nblock_bc(cr, ilist[ftype].nr, ilist[ftype].iatoms); } } while (ftype >= 0); } if (debug) { fprintf(debug, "after bc_ilists\n"); } }
static void bc_grps(const t_commrec *cr,t_grps grps[]) { int i; for(i=0; (i<egcNR); i++) { block_bc(cr,grps[i].nr); snew_bc(cr,grps[i].nm_ind,grps[i].nr); nblock_bc(cr,grps[i].nr,grps[i].nm_ind); } }
/* Allocate and fill an array with coordinates and charges, * returns the number of charges found */ static int prepare_x_q(real *q[], rvec *x[], gmx_mtop_t *mtop, rvec x_orig[], t_commrec *cr) { int i,anr_global; int nq; /* number of charged particles */ t_atom *atom; if (MASTER(cr)) { snew(*q, mtop->natoms); snew(*x, mtop->natoms); nq=0; for (i=0; i<mtop->natoms; i++) { anr_global = i; gmx_mtop_atomnr_to_atom(mtop,anr_global,&atom); if (is_charge(atom->q)) { (*q)[nq] = atom->q; (*x)[nq][XX] = x_orig[i][XX]; (*x)[nq][YY] = x_orig[i][YY]; (*x)[nq][ZZ] = x_orig[i][ZZ]; nq++; } } /* Give back some unneeded memory */ srenew(*q, nq); srenew(*x, nq); } /* Broadcast x and q in the parallel case */ if (PAR(cr)) { /* Transfer the number of charges */ block_bc(cr,nq); snew_bc(cr, *x, nq); snew_bc(cr, *q, nq); nblock_bc(cr,nq,*x); nblock_bc(cr,nq,*q); } return nq; }
static void bc_atomtypes(const t_commrec *cr, t_atomtypes *atomtypes) { int nr; block_bc(cr, atomtypes->nr); nr = atomtypes->nr; snew_bc(cr, atomtypes->radius, nr); snew_bc(cr, atomtypes->vol, nr); snew_bc(cr, atomtypes->surftens, nr); snew_bc(cr, atomtypes->gb_radius, nr); snew_bc(cr, atomtypes->S_hct, nr); nblock_bc(cr, nr, atomtypes->radius); nblock_bc(cr, nr, atomtypes->vol); nblock_bc(cr, nr, atomtypes->surftens); nblock_bc(cr, nr, atomtypes->gb_radius); nblock_bc(cr, nr, atomtypes->S_hct); }
static void bc_simtempvals(const t_commrec *cr, t_simtemp *simtemp, int n_lambda) { block_bc(cr, simtemp->simtemp_low); block_bc(cr, simtemp->simtemp_high); block_bc(cr, simtemp->eSimTempScale); snew_bc(cr, simtemp->temperatures, n_lambda); nblock_bc(cr, n_lambda, simtemp->temperatures); if (debug) { fprintf(debug, "after bc_simtempvals\n"); } }
static void bc_swapions(const t_commrec *cr, t_swapcoords *swap) { int i; block_bc(cr, *swap); /* Broadcast ion group atom indices */ snew_bc(cr, swap->ind, swap->nat); nblock_bc(cr, swap->nat, swap->ind); /* Broadcast split groups atom indices */ for (i = 0; i < 2; i++) { snew_bc(cr, swap->ind_split[i], swap->nat_split[i]); nblock_bc(cr, swap->nat_split[i], swap->ind_split[i]); } /* Broadcast solvent group atom indices */ snew_bc(cr, swap->ind_sol, swap->nat_sol); nblock_bc(cr, swap->nat_sol, swap->ind_sol); }
static void bc_pull(const t_commrec *cr, t_pull *pull) { int g; block_bc(cr, *pull); snew_bc(cr, pull->group, pull->ngroup); for (g = 0; g < pull->ngroup; g++) { bc_pull_group(cr, &pull->group[g]); } snew_bc(cr, pull->coord, pull->ncoord); nblock_bc(cr, pull->ncoord, pull->coord); }
static void bc_fepvals(const t_commrec *cr, t_lambda *fep) { gmx_bool bAlloc = TRUE; int i; block_bc(cr, fep->nstdhdl); block_bc(cr, fep->init_lambda); block_bc(cr, fep->init_fep_state); block_bc(cr, fep->delta_lambda); block_bc(cr, fep->bPrintEnergy); block_bc(cr, fep->n_lambda); if (fep->n_lambda > 0) { snew_bc(cr, fep->all_lambda, efptNR); nblock_bc(cr, efptNR, fep->all_lambda); for (i = 0; i < efptNR; i++) { snew_bc(cr, fep->all_lambda[i], fep->n_lambda); nblock_bc(cr, fep->n_lambda, fep->all_lambda[i]); } } block_bc(cr, fep->sc_alpha); block_bc(cr, fep->sc_power); block_bc(cr, fep->sc_r_power); block_bc(cr, fep->sc_sigma); block_bc(cr, fep->sc_sigma_min); block_bc(cr, fep->bScCoul); nblock_bc(cr, efptNR, &(fep->separate_dvdl[0])); block_bc(cr, fep->dhdl_derivatives); block_bc(cr, fep->dh_hist_size); block_bc(cr, fep->dh_hist_spacing); if (debug) { fprintf(debug, "after bc_fepvals\n"); } }
static void bc_swapions(const t_commrec *cr, t_swapcoords *swap) { block_bc(cr, *swap); /* Broadcast atom indices for split groups, solvent group, and for all user-defined swap groups */ snew_bc(cr, swap->grp, swap->ngrp); for (int i = 0; i < swap->ngrp; i++) { t_swapGroup *g = &swap->grp[i]; block_bc(cr, *g); snew_bc(cr, g->ind, g->nat); nblock_bc(cr, g->nat, g->ind); int len = 0; if (MASTER(cr)) { len = strlen(g->molname); } block_bc(cr, len); snew_bc(cr, g->molname, len); nblock_bc(cr, len, g->molname); } }
static void bc_inputrec(const t_commrec *cr,t_inputrec *inputrec) { bool bAlloc=TRUE; int i; block_bc(cr,*inputrec); snew_bc(cr,inputrec->flambda,inputrec->n_flambda); nblock_bc(cr,inputrec->n_flambda,inputrec->flambda); bc_grpopts(cr,&(inputrec->opts)); if (inputrec->ePull != epullNO) { snew_bc(cr,inputrec->pull,1); bc_pull(cr,inputrec->pull); } for(i=0; (i<DIM); i++) { bc_cosines(cr,&(inputrec->ex[i])); bc_cosines(cr,&(inputrec->et[i])); } }
/* Transfer what we need for parallelizing the reciprocal error estimate */ static void bcast_info(t_inputinfo *info, t_commrec *cr) { nblock_bc(cr, info->n_entries, info->nkx); nblock_bc(cr, info->n_entries, info->nky); nblock_bc(cr, info->n_entries, info->nkz); nblock_bc(cr, info->n_entries, info->ewald_beta); nblock_bc(cr, info->n_entries, info->pme_order); nblock_bc(cr, info->n_entries, info->e_dir); nblock_bc(cr, info->n_entries, info->e_rec); block_bc(cr, info->volume); block_bc(cr, info->recipbox); block_bc(cr, info->natoms); block_bc(cr, info->fracself); block_bc(cr, info->bTUNE); block_bc(cr, info->q2all); block_bc(cr, info->q2allnr); }
static void bc_strings_resinfo(const t_commrec *cr,t_symtab *symtab, int nr,t_resinfo *resinfo) { int i; int *handle; snew(handle,nr); if (MASTER(cr)) { for(i=0; (i<nr); i++) handle[i] = lookup_symtab(symtab,resinfo[i].name); } nblock_bc(cr,nr,handle); if (!MASTER(cr)) { for (i=0; (i<nr); i++) resinfo[i].name = get_symtab_handle(symtab,handle[i]); } sfree(handle); }
static void bc_symtab(const t_commrec *cr,t_symtab *symtab) { int i,nr,len; t_symbuf *symbuf; block_bc(cr,symtab->nr); nr = symtab->nr; snew_bc(cr,symtab->symbuf,1); symbuf = symtab->symbuf; symbuf->bufsize = nr; snew_bc(cr,symbuf->buf,nr); for (i=0; i<nr; i++) { if (MASTER(cr)) len = strlen(symbuf->buf[i]) + 1; block_bc(cr,len); snew_bc(cr,symbuf->buf[i],len); nblock_bc(cr,len,symbuf->buf[i]); } }
static void bc_cmap(const t_commrec *cr, gmx_cmap_t *cmap_grid) { int i, j, nelem, ngrid; block_bc(cr, cmap_grid->ngrid); block_bc(cr, cmap_grid->grid_spacing); ngrid = cmap_grid->ngrid; nelem = cmap_grid->grid_spacing * cmap_grid->grid_spacing; if (ngrid > 0) { snew_bc(cr, cmap_grid->cmapdata, ngrid); for (i = 0; i < ngrid; i++) { snew_bc(cr, cmap_grid->cmapdata[i].cmap, 4*nelem); nblock_bc(cr, 4*nelem, cmap_grid->cmapdata[i].cmap); } } }
static void bc_strings(const t_commrec *cr,t_symtab *symtab,int nr,char ****nm) { int i; int *handle; char ***NM; snew(handle,nr); if (MASTER(cr)) { NM = *nm; for(i=0; (i<nr); i++) handle[i] = lookup_symtab(symtab,NM[i]); } nblock_bc(cr,nr,handle); if (!MASTER(cr)) { snew_bc(cr,*nm,nr); NM = *nm; for (i=0; (i<nr); i++) (*nm)[i] = get_symtab_handle(symtab,handle[i]); } sfree(handle); }
static void bc_cstring(const t_commrec *cr, char **s) { int size = 0; if (MASTER(cr) && *s != NULL) { /* Size of the char buffer is string length + 1 for '\0' */ size = strlen(*s) + 1; } block_bc(cr, size); if (size > 0) { if (!MASTER(cr)) { srenew(*s, size); } nblock_bc(cr, size, *s); } else if (!MASTER(cr) && *s != NULL) { sfree(*s); *s = NULL; } }
static void bc_pull(const t_commrec *cr, pull_params_t *pull) { int g; block_bc(cr, *pull); snew_bc(cr, pull->group, pull->ngroup); for (g = 0; g < pull->ngroup; g++) { bc_pull_group(cr, &pull->group[g]); } snew_bc(cr, pull->coord, pull->ncoord); nblock_bc(cr, pull->ncoord, pull->coord); for (int c = 0; c < pull->ncoord; c++) { if (!MASTER(cr)) { pull->coord[c].externalPotentialProvider = NULL; } if (pull->coord[c].eType == epullEXTERNAL) { bc_cstring(cr, &pull->coord[c].externalPotentialProvider); } } }
static void bc_grpopts(const t_commrec *cr, t_grpopts *g) { int i, n; block_bc(cr, g->ngtc); block_bc(cr, g->ngacc); block_bc(cr, g->ngfrz); block_bc(cr, g->ngener); snew_bc(cr, g->nrdf, g->ngtc); snew_bc(cr, g->tau_t, g->ngtc); snew_bc(cr, g->ref_t, g->ngtc); snew_bc(cr, g->acc, g->ngacc); snew_bc(cr, g->nFreeze, g->ngfrz); snew_bc(cr, g->egp_flags, g->ngener*g->ngener); nblock_bc(cr, g->ngtc, g->nrdf); nblock_bc(cr, g->ngtc, g->tau_t); nblock_bc(cr, g->ngtc, g->ref_t); nblock_bc(cr, g->ngacc, g->acc); nblock_bc(cr, g->ngfrz, g->nFreeze); nblock_bc(cr, g->ngener*g->ngener, g->egp_flags); snew_bc(cr, g->annealing, g->ngtc); snew_bc(cr, g->anneal_npoints, g->ngtc); snew_bc(cr, g->anneal_time, g->ngtc); snew_bc(cr, g->anneal_temp, g->ngtc); nblock_bc(cr, g->ngtc, g->annealing); nblock_bc(cr, g->ngtc, g->anneal_npoints); for (i = 0; (i < g->ngtc); i++) { n = g->anneal_npoints[i]; if (n > 0) { snew_bc(cr, g->anneal_time[i], n); snew_bc(cr, g->anneal_temp[i], n); nblock_bc(cr, n, g->anneal_time[i]); nblock_bc(cr, n, g->anneal_temp[i]); } } /* QMMM stuff, see inputrec */ block_bc(cr, g->ngQM); snew_bc(cr, g->QMmethod, g->ngQM); snew_bc(cr, g->QMbasis, g->ngQM); snew_bc(cr, g->QMcharge, g->ngQM); snew_bc(cr, g->QMmult, g->ngQM); snew_bc(cr, g->bSH, g->ngQM); snew_bc(cr, g->CASorbitals, g->ngQM); snew_bc(cr, g->CASelectrons, g->ngQM); snew_bc(cr, g->SAon, g->ngQM); snew_bc(cr, g->SAoff, g->ngQM); snew_bc(cr, g->SAsteps, g->ngQM); if (g->ngQM) { nblock_bc(cr, g->ngQM, g->QMmethod); nblock_bc(cr, g->ngQM, g->QMbasis); nblock_bc(cr, g->ngQM, g->QMcharge); nblock_bc(cr, g->ngQM, g->QMmult); nblock_bc(cr, g->ngQM, g->bSH); nblock_bc(cr, g->ngQM, g->CASorbitals); nblock_bc(cr, g->ngQM, g->CASelectrons); nblock_bc(cr, g->ngQM, g->SAon); nblock_bc(cr, g->ngQM, g->SAoff); nblock_bc(cr, g->ngQM, g->SAsteps); /* end of QMMM stuff */ } }
static void bcastPaddedRVecVector(const t_commrec *cr, PaddedRVecVector *v, unsigned int n) { (*v).resize(n + 1); nblock_bc(cr, n, as_rvec_array(v->data())); }
/* Estimate the reciprocal space part error of the SPME Ewald sum. */ static real estimate_reciprocal( t_inputinfo *info, rvec x[], /* array of particles */ real q[], /* array of charges */ int nr, /* number of charges = size of the charge array */ FILE *fp_out, gmx_bool bVerbose, unsigned int seed, /* The seed for the random number generator */ int *nsamples, /* Return the number of samples used if Monte Carlo * algorithm is used for self energy error estimate */ t_commrec *cr) { real e_rec=0; /* reciprocal error estimate */ real e_rec1=0; /* Error estimate term 1*/ real e_rec2=0; /* Error estimate term 2*/ real e_rec3=0; /* Error estimate term 3 */ real e_rec3x=0; /* part of Error estimate term 3 in x */ real e_rec3y=0; /* part of Error estimate term 3 in y */ real e_rec3z=0; /* part of Error estimate term 3 in z */ int i,ci; int nx,ny,nz; /* grid coordinates */ real q2_all=0; /* sum of squared charges */ rvec gridpx; /* reciprocal grid point in x direction*/ rvec gridpxy; /* reciprocal grid point in x and y direction*/ rvec gridp; /* complete reciprocal grid point in 3 directions*/ rvec tmpvec; /* template to create points from basis vectors */ rvec tmpvec2; /* template to create points from basis vectors */ real coeff=0; /* variable to compute coefficients of the error estimate */ real coeff2=0; /* variable to compute coefficients of the error estimate */ real tmp=0; /* variables to compute different factors from vectors */ real tmp1=0; real tmp2=0; gmx_bool bFraction; /* Random number generator */ gmx_rng_t rng=NULL; int *numbers=NULL; /* Index variables for parallel work distribution */ int startglobal,stopglobal; int startlocal, stoplocal; int x_per_core; int xtot; #ifdef TAKETIME double t0=0.0; double t1=0.0; #endif rng=gmx_rng_init(seed); clear_rvec(gridpx); clear_rvec(gridpxy); clear_rvec(gridp); clear_rvec(tmpvec); clear_rvec(tmpvec2); for(i=0;i<nr;i++) { q2_all += q[i]*q[i]; } /* Calculate indices for work distribution */ startglobal=-info->nkx[0]/2; stopglobal = info->nkx[0]/2; xtot = stopglobal*2+1; if (PAR(cr)) { x_per_core = ceil((real)xtot / (real)cr->nnodes); startlocal = startglobal + x_per_core*cr->nodeid; stoplocal = startlocal + x_per_core -1; if (stoplocal > stopglobal) stoplocal = stopglobal; } else { startlocal = startglobal; stoplocal = stopglobal; x_per_core = xtot; } /* #ifdef GMX_LIB_MPI MPI_Barrier(MPI_COMM_WORLD); #endif */ #ifdef GMX_LIB_MPI #ifdef TAKETIME if (MASTER(cr)) t0 = MPI_Wtime(); #endif #endif if (MASTER(cr)){ fprintf(stderr, "Calculating reciprocal error part 1 ..."); } for(nx=startlocal; nx<=stoplocal; nx++) { svmul(nx,info->recipbox[XX],gridpx); for(ny=-info->nky[0]/2; ny<info->nky[0]/2+1; ny++) { svmul(ny,info->recipbox[YY],tmpvec); rvec_add(gridpx,tmpvec,gridpxy); for(nz=-info->nkz[0]/2; nz<info->nkz[0]/2+1; nz++) { if ( 0 == nx && 0 == ny && 0 == nz ) continue; svmul(nz,info->recipbox[ZZ],tmpvec); rvec_add(gridpxy,tmpvec,gridp); tmp=norm2(gridp); coeff=exp(-1.0 * M_PI * M_PI * tmp / info->ewald_beta[0] / info->ewald_beta[0] ) ; coeff/= 2.0 * M_PI * info->volume * tmp; coeff2=tmp ; tmp=eps_poly2(nx,info->nkx[0],info->pme_order[0]); tmp+=eps_poly2(ny,info->nkx[0],info->pme_order[0]); tmp+=eps_poly2(nz,info->nkx[0],info->pme_order[0]); tmp1=eps_poly1(nx,info->nkx[0],info->pme_order[0]); tmp2=eps_poly1(ny,info->nky[0],info->pme_order[0]); tmp+=2.0 * tmp1 * tmp2; tmp1=eps_poly1(nz,info->nkz[0],info->pme_order[0]); tmp2=eps_poly1(ny,info->nky[0],info->pme_order[0]); tmp+=2.0 * tmp1 * tmp2; tmp1=eps_poly1(nz,info->nkz[0],info->pme_order[0]); tmp2=eps_poly1(nx,info->nkx[0],info->pme_order[0]); tmp+=2.0 * tmp1 * tmp2; tmp1=eps_poly1(nx,info->nkx[0],info->pme_order[0]); tmp1+=eps_poly1(ny,info->nky[0],info->pme_order[0]); tmp1+=eps_poly1(nz,info->nkz[0],info->pme_order[0]); tmp+= tmp1 * tmp1; e_rec1+= 32.0 * M_PI * M_PI * coeff * coeff * coeff2 * tmp * q2_all * q2_all / nr ; tmp1=eps_poly3(nx,info->nkx[0],info->pme_order[0]); tmp1*=info->nkx[0]; tmp2=iprod(gridp,info->recipbox[XX]); tmp=tmp1*tmp2; tmp1=eps_poly3(ny,info->nky[0],info->pme_order[0]); tmp1*=info->nky[0]; tmp2=iprod(gridp,info->recipbox[YY]); tmp+=tmp1*tmp2; tmp1=eps_poly3(nz,info->nkz[0],info->pme_order[0]); tmp1*=info->nkz[0]; tmp2=iprod(gridp,info->recipbox[ZZ]); tmp+=tmp1*tmp2; tmp*=4.0 * M_PI; tmp1=eps_poly4(nx,info->nkx[0],info->pme_order[0]); tmp1*=norm2(info->recipbox[XX]); tmp1*=info->nkx[0] * info->nkx[0]; tmp+=tmp1; tmp1=eps_poly4(ny,info->nky[0],info->pme_order[0]); tmp1*=norm2(info->recipbox[YY]); tmp1*=info->nky[0] * info->nky[0]; tmp+=tmp1; tmp1=eps_poly4(nz,info->nkz[0],info->pme_order[0]); tmp1*=norm2(info->recipbox[ZZ]); tmp1*=info->nkz[0] * info->nkz[0]; tmp+=tmp1; e_rec2+= 4.0 * coeff * coeff * tmp * q2_all * q2_all / nr ; } } if (MASTER(cr)) fprintf(stderr, "\rCalculating reciprocal error part 1 ... %3.0f%%", 100.0*(nx-startlocal+1)/(x_per_core)); } if (MASTER(cr)) fprintf(stderr, "\n"); /* Use just a fraction of all charges to estimate the self energy error term? */ bFraction = (info->fracself > 0.0) && (info->fracself < 1.0); if (bFraction) { /* Here xtot is the number of samples taken for the Monte Carlo calculation * of the average of term IV of equation 35 in Wang2010. Round up to a * number of samples that is divisible by the number of nodes */ x_per_core = ceil(info->fracself * nr / (real)cr->nnodes); xtot = x_per_core * cr->nnodes; } else { /* In this case we use all nr particle positions */ xtot = nr; x_per_core = ceil( (real)xtot / (real)cr->nnodes ); } startlocal = x_per_core * cr->nodeid; stoplocal = min(startlocal + x_per_core, xtot); /* min needed if xtot == nr */ if (bFraction) { /* Make shure we get identical results in serial and parallel. Therefore, * take the sample indices from a single, global random number array that * is constructed on the master node and that only depends on the seed */ snew(numbers, xtot); if (MASTER(cr)) { for (i=0; i<xtot; i++) { numbers[i] = floor(gmx_rng_uniform_real(rng) * nr ); } } /* Broadcast the random number array to the other nodes */ if (PAR(cr)) { nblock_bc(cr,xtot,numbers); } if (bVerbose && MASTER(cr)) { fprintf(stdout, "Using %d sample%s to approximate the self interaction error term", xtot, xtot==1?"":"s"); if (PAR(cr)) fprintf(stdout, " (%d sample%s per node)", x_per_core, x_per_core==1?"":"s"); fprintf(stdout, ".\n"); } } /* Return the number of positions used for the Monte Carlo algorithm */ *nsamples = xtot; for(i=startlocal;i<stoplocal;i++) { e_rec3x=0; e_rec3y=0; e_rec3z=0; if (bFraction) { /* Randomly pick a charge */ ci = numbers[i]; } else { /* Use all charges */ ci = i; } /* for(nx=startlocal; nx<=stoplocal; nx++)*/ for(nx=-info->nkx[0]/2; nx<info->nkx[0]/2+1; nx++) { svmul(nx,info->recipbox[XX],gridpx); for(ny=-info->nky[0]/2; ny<info->nky[0]/2+1; ny++) { svmul(ny,info->recipbox[YY],tmpvec); rvec_add(gridpx,tmpvec,gridpxy); for(nz=-info->nkz[0]/2; nz<info->nkz[0]/2+1; nz++) { if ( 0 == nx && 0 == ny && 0 == nz) continue; svmul(nz,info->recipbox[ZZ],tmpvec); rvec_add(gridpxy,tmpvec,gridp); tmp=norm2(gridp); coeff=exp(-1.0 * M_PI * M_PI * tmp / info->ewald_beta[0] / info->ewald_beta[0] ); coeff/= tmp ; e_rec3x+=coeff*eps_self(nx,info->nkx[0],info->recipbox[XX],info->pme_order[0],x[ci]); e_rec3y+=coeff*eps_self(ny,info->nky[0],info->recipbox[YY],info->pme_order[0],x[ci]); e_rec3z+=coeff*eps_self(nz,info->nkz[0],info->recipbox[ZZ],info->pme_order[0],x[ci]); } } } clear_rvec(tmpvec2); svmul(e_rec3x,info->recipbox[XX],tmpvec); rvec_inc(tmpvec2,tmpvec); svmul(e_rec3y,info->recipbox[YY],tmpvec); rvec_inc(tmpvec2,tmpvec); svmul(e_rec3z,info->recipbox[ZZ],tmpvec); rvec_inc(tmpvec2,tmpvec); e_rec3 += q[ci]*q[ci]*q[ci]*q[ci]*norm2(tmpvec2) / ( xtot * M_PI * info->volume * M_PI * info->volume); if (MASTER(cr)){ fprintf(stderr, "\rCalculating reciprocal error part 2 ... %3.0f%%", 100.0*(i+1)/stoplocal); } } if (MASTER(cr)) fprintf(stderr, "\n"); #ifdef GMX_LIB_MPI #ifdef TAKETIME if (MASTER(cr)) { t1= MPI_Wtime() - t0; fprintf(fp_out, "Recip. err. est. took : %lf s\n", t1); } #endif #endif #ifdef DEBUG if (PAR(cr)) { fprintf(stderr, "Node %3d: nx=[%3d...%3d] e_rec3=%e\n", cr->nodeid, startlocal, stoplocal, e_rec3); } #endif if (PAR(cr)) { gmx_sum(1,&e_rec1,cr); gmx_sum(1,&e_rec2,cr); gmx_sum(1,&e_rec3,cr); } /* e_rec1*=8.0 * q2_all / info->volume / info->volume / nr ; e_rec2*= q2_all / M_PI / M_PI / info->volume / info->volume / nr ; e_rec3/= M_PI * M_PI * info->volume * info->volume * nr ; */ e_rec=sqrt(e_rec1+e_rec2+e_rec3); return ONE_4PI_EPS0 * e_rec; }
void bcast_state(const t_commrec *cr, t_state *state) { int i, nnht, nnhtp; if (!PAR(cr) || (cr->nnodes - cr->npmenodes <= 1)) { return; } /* Broadcasts the state sizes and flags from the master to all nodes * in cr->mpi_comm_mygroup. The arrays are not broadcasted. */ block_bc(cr, state->natoms); block_bc(cr, state->ngtc); block_bc(cr, state->nnhpres); block_bc(cr, state->nhchainlength); block_bc(cr, state->flags); state->lambda.resize(efptNR); if (cr->dd) { /* We allocate dynamically in dd_partition_system. */ return; } /* The code below is reachable only by TPI and NM, so it is not tested by anything. */ nnht = (state->ngtc)*(state->nhchainlength); nnhtp = (state->nnhpres)*(state->nhchainlength); for (i = 0; i < estNR; i++) { if (state->flags & (1<<i)) { switch (i) { case estLAMBDA: nblock_bc(cr, efptNR, state->lambda.data()); break; case estFEPSTATE: block_bc(cr, state->fep_state); break; case estBOX: block_bc(cr, state->box); break; case estBOX_REL: block_bc(cr, state->box_rel); break; case estBOXV: block_bc(cr, state->boxv); break; case estPRES_PREV: block_bc(cr, state->pres_prev); break; case estSVIR_PREV: block_bc(cr, state->svir_prev); break; case estFVIR_PREV: block_bc(cr, state->fvir_prev); break; case estNH_XI: nblock_abc(cr, nnht, &state->nosehoover_xi); break; case estNH_VXI: nblock_abc(cr, nnht, &state->nosehoover_vxi); break; case estNHPRES_XI: nblock_abc(cr, nnhtp, &state->nhpres_xi); break; case estNHPRES_VXI: nblock_abc(cr, nnhtp, &state->nhpres_vxi); break; case estTC_INT: nblock_abc(cr, state->ngtc, &state->therm_integral); break; case estVETA: block_bc(cr, state->veta); break; case estVOL0: block_bc(cr, state->vol0); break; case estX: bcastPaddedRVecVector(cr, &state->x, state->natoms); case estV: bcastPaddedRVecVector(cr, &state->v, state->natoms); case estCGP: bcastPaddedRVecVector(cr, &state->cg_p, state->natoms); case estDISRE_INITF: block_bc(cr, state->hist.disre_initf); break; case estDISRE_RM3TAV: block_bc(cr, state->hist.ndisrepairs); nblock_abc(cr, state->hist.ndisrepairs, &state->hist.disre_rm3tav); break; case estORIRE_INITF: block_bc(cr, state->hist.orire_initf); break; case estORIRE_DTAV: block_bc(cr, state->hist.norire_Dtav); nblock_abc(cr, state->hist.norire_Dtav, &state->hist.orire_Dtav); break; default: gmx_fatal(FARGS, "Communication is not implemented for %s in bcast_state", est_names[i]); } } } }
static void bc_block(const t_commrec *cr, t_block *block) { block_bc(cr, block->nr); snew_bc(cr, block->index, block->nr+1); nblock_bc(cr, block->nr+1, block->index); }
void bcast_state(const t_commrec *cr, t_state *state) { int i, nnht, nnhtp; gmx_bool bAlloc; if (!PAR(cr)) { return; } /* Broadcasts the state sizes and flags from the master to all nodes * in cr->mpi_comm_mygroup. The arrays are not broadcasted. */ block_bc(cr, state->natoms); block_bc(cr, state->ngtc); block_bc(cr, state->nnhpres); block_bc(cr, state->nhchainlength); block_bc(cr, state->flags); if (state->lambda == NULL) { snew_bc(cr, state->lambda, efptNR) } if (cr->dd) { /* We allocate dynamically in dd_partition_system. */ return; } /* The code below is reachable only by TPI and NM, so it is not tested by anything. */ nnht = (state->ngtc)*(state->nhchainlength); nnhtp = (state->nnhpres)*(state->nhchainlength); /* We still need to allocate the arrays in state for non-master * ranks, which is done (implicitly via bAlloc) in the dirty, * dirty nblock_abc macro. */ bAlloc = !MASTER(cr); if (bAlloc) { state->nalloc = state->natoms; } for (i = 0; i < estNR; i++) { if (state->flags & (1<<i)) { switch (i) { case estLAMBDA: nblock_bc(cr, efptNR, state->lambda); break; case estFEPSTATE: block_bc(cr, state->fep_state); break; case estBOX: block_bc(cr, state->box); break; case estBOX_REL: block_bc(cr, state->box_rel); break; case estBOXV: block_bc(cr, state->boxv); break; case estPRES_PREV: block_bc(cr, state->pres_prev); break; case estSVIR_PREV: block_bc(cr, state->svir_prev); break; case estFVIR_PREV: block_bc(cr, state->fvir_prev); break; case estNH_XI: nblock_abc(cr, nnht, state->nosehoover_xi); break; case estNH_VXI: nblock_abc(cr, nnht, state->nosehoover_vxi); break; case estNHPRES_XI: nblock_abc(cr, nnhtp, state->nhpres_xi); break; case estNHPRES_VXI: nblock_abc(cr, nnhtp, state->nhpres_vxi); break; case estTC_INT: nblock_abc(cr, state->ngtc, state->therm_integral); break; case estVETA: block_bc(cr, state->veta); break; case estVOL0: block_bc(cr, state->vol0); break; case estX: nblock_abc(cr, state->natoms, state->x); break; case estV: nblock_abc(cr, state->natoms, state->v); break; case estSDX: nblock_abc(cr, state->natoms, state->sd_X); break; case estCGP: nblock_abc(cr, state->natoms, state->cg_p); break; case estDISRE_INITF: block_bc(cr, state->hist.disre_initf); break; case estDISRE_RM3TAV: block_bc(cr, state->hist.ndisrepairs); nblock_abc(cr, state->hist.ndisrepairs, state->hist.disre_rm3tav); break; case estORIRE_INITF: block_bc(cr, state->hist.orire_initf); break; case estORIRE_DTAV: block_bc(cr, state->hist.norire_Dtav); nblock_abc(cr, state->hist.norire_Dtav, state->hist.orire_Dtav); break; default: gmx_fatal(FARGS, "Communication is not implemented for %s in bcast_state", est_names[i]); } } } }