void test_poisson(FILE *log, bool bVerbose, t_atoms *atoms, t_inputrec *ir, rvec x[], rvec f[], real charge[], rvec box, real phi[], real phi_s[], int nmol, t_commrec *cr, bool bFour, rvec f_four[], real phi_f[], bool bOld) { char buf[256]; real ener; rvec beta; int i,nit; t_nrnb nrnb; init_nrnb(&nrnb); /* First time only setup is done! */ if (bFour) { for(i=0; (i<atoms->nr); i++) phi_f[i] -= phi_s[i]; ener = do_optimize_poisson(log,bVerbose,ir,atoms->nr,x,f,charge, box,phi,cr,&nrnb,f_four,phi_f,beta,bOld); for(i=0; (i<atoms->nr); i++) phi_f[i] += phi_s[i]; nit = 0; } else { ener = do_poisson(log,bVerbose,ir,atoms->nr,x,f,charge,box,phi, cr,&nrnb,&nit,bOld); } fprintf(log,"Vpoisson = %g, nit = %d\n",ener,nit); sprintf(buf,"POISSON-%d.pdb",ir->nkx); write_pqr(buf,atoms,x,phi,0); pr_f("poisson-force",atoms->nr,f); calc_ener(log,buf,FALSE,nmol,atoms->nr,phi,charge,&atoms->excl); for(i=0; (i<atoms->nr); i++) phi[i]+=phi_s[i]; sprintf(buf,"POISSON-%d+SR",ir->nkx); calc_ener(log,buf,FALSE,nmol,atoms->nr,phi,charge,&atoms->excl); strcat(buf,".pdb"); write_pqr(buf,atoms,x,phi,0); }
static void reset_pmeonly_counters(gmx_wallcycle_t wcycle, gmx_walltime_accounting_t walltime_accounting, t_nrnb *nrnb, t_inputrec *ir, gmx_int64_t step) { /* Reset all the counters related to performance over the run */ wallcycle_stop(wcycle, ewcRUN); wallcycle_reset_all(wcycle); init_nrnb(nrnb); if (ir->nsteps >= 0) { /* ir->nsteps is not used here, but we update it for consistency */ ir->nsteps -= step - ir->init_step; } ir->init_step = step; wallcycle_start(wcycle, ewcRUN); walltime_accounting_start(walltime_accounting); }
static void reset_pmeonly_counters(gmx_wallcycle_t wcycle, gmx_walltime_accounting_t walltime_accounting, t_nrnb *nrnb, int64_t step, bool useGpuForPme) { /* Reset all the counters related to performance over the run */ wallcycle_stop(wcycle, ewcRUN); wallcycle_reset_all(wcycle); init_nrnb(nrnb); wallcycle_start(wcycle, ewcRUN); walltime_accounting_reset_time(walltime_accounting, step); if (useGpuForPme) { resetGpuProfiler(); } }
void test_pppm(FILE *log, bool bVerbose, bool bGenerGhat, char *ghatfn, t_atoms *atoms, t_inputrec *ir, rvec x[], rvec f[], real charge[], rvec box, real phi[], real phi_s[], int nmol, t_commrec *cr, bool bOld, t_block *cgs) { char buf[256]; real ener; int i; t_nrnb nrnb; t_nsborder nsb; init_nrnb(&nrnb); calc_nsb(cgs,1,&nsb,0); /* First time only setup is done! */ init_pppm(log,cr,&nsb,bVerbose,bOld,box,ghatfn,ir); ener = do_pppm(log,bVerbose,x,f,charge,box,phi,cr,&nsb,&nrnb); fprintf(log,"Vpppm = %g\n",ener); sprintf(buf,"PPPM-%d.pdb",ir->nkx); write_pqr(buf,atoms,x,phi,0); pr_f("pppm-force",atoms->nr,f); calc_ener(log,buf,FALSE,nmol,atoms->nr,phi,charge,&atoms->excl); for(i=0; (i<atoms->nr); i++) phi[i]+=phi_s[i]; sprintf(buf,"PPPM-%d+SR",ir->nkx); calc_ener(log,buf,FALSE,nmol,atoms->nr,phi,charge,&atoms->excl); strcat(buf,".pdb"); write_pqr(buf,atoms,x,phi,0); }
void global_stat(FILE *log, t_commrec *cr,real ener[], tensor fvir,tensor svir, t_grpopts *opts,t_groups *grps, t_nrnb *mynrnb,t_nrnb nrnb[], t_vcm *vcm,real *terminate) { static t_bin *rb=NULL; static int *itc; int iterminate,imu,ie,ifv,isv,icm,imass,ica; int icj=-1,ici=-1,icx=-1; int in[MAXNODES]; int inn[egNR]; int j; if (rb==NULL) { rb=mk_bin(); snew(itc,opts->ngtc); } else reset_bin(rb); /* Reset nrnb stuff */ for(j=0; (j<cr->nnodes); j++) init_nrnb(&(nrnb[j])); cp_nrnb(&(nrnb[cr->nodeid]),mynrnb); /* This routine copies all the data to be summed to one big buffer * using the t_bin struct. */ where(); ie = add_binr(log,rb,F_NRE,ener); where(); ifv = add_binr(log,rb,DIM*DIM,fvir[0]); where(); isv = add_binr(log,rb,DIM*DIM,svir[0]); where(); for(j=0; (j<cr->nnodes); j++) in[j] = add_bind(log,rb,eNRNB,nrnb[j].n); where(); for(j=0; (j<opts->ngtc); j++) itc[j]=add_binr(log,rb,DIM*DIM,grps->tcstat[j].ekin[0]); where(); for(j=0; (j<egNR); j++) inn[j]=add_binr(log,rb,grps->estat.nn,grps->estat.ee[j]); where(); icm = add_binr(log,rb,DIM*vcm->nr,vcm->group_p[0]); where(); imass = add_binr(log,rb,vcm->nr,vcm->group_mass); where(); if (vcm->mode == ecmANGULAR) { icj = add_binr(log,rb,DIM*vcm->nr,vcm->group_j[0]); where(); icx = add_binr(log,rb,DIM*vcm->nr,vcm->group_x[0]); where(); ici = add_binr(log,rb,DIM*DIM*vcm->nr,vcm->group_i[0][0]); where(); } ica = add_binr(log,rb,1,&(grps->cosacc.mvcos)); where(); iterminate = add_binr(log,rb,1,terminate); /* Global sum it all */ sum_bin(rb,cr); where(); /* Extract all the data locally */ extract_binr(rb,ie ,F_NRE,ener); extract_binr(rb,ifv ,DIM*DIM,fvir[0]); extract_binr(rb,isv ,DIM*DIM,svir[0]); for(j=0; (j<cr->nnodes); j++) extract_bind(rb,in[j],eNRNB,nrnb[j].n); for(j=0; (j<opts->ngtc); j++) extract_binr(rb,itc[j],DIM*DIM,grps->tcstat[j].ekin[0]); for(j=0; (j<egNR); j++) extract_binr(rb,inn[j],grps->estat.nn,grps->estat.ee[j]); extract_binr(rb,icm,DIM*vcm->nr,vcm->group_p[0]); where(); extract_binr(rb,imass,vcm->nr,vcm->group_mass); where(); if (vcm->mode == ecmANGULAR) { extract_binr(rb,icj,DIM*vcm->nr,vcm->group_j[0]); where(); extract_binr(rb,icx,DIM*vcm->nr,vcm->group_x[0]); where(); extract_binr(rb,ici,DIM*DIM*vcm->nr,vcm->group_i[0][0]); where(); } extract_binr(rb,ica,1,&(grps->cosacc.mvcos)); where(); extract_binr(rb,iterminate,1,terminate); where(); /* Small hack for temp only */ ener[F_TEMP]/=cr->nnodes; }
void pr_load(FILE *log, t_commrec *cr, t_nrnb nrnb[]) { int i, j, perc; double dperc, unb, uf, us; double *ftot, fav; double *stot, sav; t_nrnb *av; snew(av, 1); snew(ftot, cr->nnodes); snew(stot, cr->nnodes); init_nrnb(av); for (i = 0; (i < cr->nnodes); i++) { add_nrnb(av, av, &(nrnb[i])); /* Cost due to forces */ for (j = 0; (j < eNR_NBKERNEL_ALLVSALLGB); j++) { ftot[i] += nrnb[i].n[j]*cost_nrnb(j); } for (j = 0; (j < NFORCE_INDEX); j++) { ftot[i] += nrnb[i].n[force_index[j]]*cost_nrnb(force_index[j]); } /* Due to shake */ for (j = 0; (j < NCONSTR_INDEX); j++) { stot[i] += nrnb[i].n[constr_index[j]]*cost_nrnb(constr_index[j]); } } for (j = 0; (j < eNRNB); j++) { av->n[j] = av->n[j]/static_cast<double>(cr->nnodes - cr->npmenodes); } fprintf(log, "\nDetailed load balancing info in percentage of average\n"); fprintf(log, " Type RANK:"); for (i = 0; (i < cr->nnodes); i++) { fprintf(log, "%3d ", i); } fprintf(log, "Scaling\n"); fprintf(log, "---------------------------"); for (i = 0; (i < cr->nnodes); i++) { fprintf(log, "----"); } fprintf(log, "-------\n"); for (j = 0; (j < eNRNB); j++) { unb = 100.0; if (av->n[j] > 0) { fprintf(log, " %-26s", nrnb_str(j)); for (i = 0; (i < cr->nnodes); i++) { dperc = (100.0*nrnb[i].n[j])/av->n[j]; unb = std::max(unb, dperc); perc = static_cast<int>(dperc); fprintf(log, "%3d ", perc); } if (unb > 0) { perc = static_cast<int>(10000.0/unb); fprintf(log, "%6d%%\n", perc); } else { fprintf(log, "\n"); } } } fav = sav = 0; for (i = 0; (i < cr->nnodes); i++) { fav += ftot[i]; sav += stot[i]; } uf = pr_av(log, cr, fav, ftot, "Total Force"); us = pr_av(log, cr, sav, stot, "Total Constr."); unb = (uf*fav+us*sav)/(fav+sav); if (unb > 0) { unb = 10000.0/unb; fprintf(log, "\nTotal Scaling: %.0f%% of max performance\n\n", unb); } }
int main(int argc,char *argv[]) { static char *desc[] = { "The [TT]pmetest[tt] program tests the scaling of the PME code. When only given", "a [TT].tpr[tt] file it will compute PME for one frame. When given a trajectory", "it will do so for all the frames in the trajectory. Before the PME", "routine is called the coordinates are sorted along the X-axis.[PAR]", "As an extra service to the public the program can also compute", "long-range Coulomb energies for components of the system. When the", "[TT]-groups[tt] flag is given to the program the energy groups", "from the [TT].tpr[tt] file will be read, and half an energy matrix computed." }; t_commrec *cr,*mcr; static t_filenm fnm[] = { { efTPX, NULL, NULL, ffREAD }, { efTRN, "-o", NULL, ffWRITE }, { efLOG, "-g", "pme", ffWRITE }, { efTRX, "-f", NULL, ffOPTRD }, { efXVG, "-x", "ener-pme", ffWRITE } }; #define NFILE asize(fnm) /* Command line options ! */ static gmx_bool bVerbose=FALSE; static gmx_bool bOptFFT=FALSE; static gmx_bool bSort=FALSE; static int ewald_geometry=eewg3D; static int nnodes=1; static int pme_order=0; static rvec grid = { -1, -1, -1 }; static real rc = 0.0; static real dtol = 0.0; static gmx_bool bGroups = FALSE; static t_pargs pa[] = { { "-np", FALSE, etINT, {&nnodes}, "Number of nodes, must be the same as used for [TT]grompp[tt]" }, { "-v", FALSE, etBOOL,{&bVerbose}, "Be loud and noisy" }, { "-sort", FALSE, etBOOL,{&bSort}, "Sort coordinates. Crucial for domain decomposition." }, { "-grid", FALSE, etRVEC,{&grid}, "Number of grid cells in X, Y, Z dimension (if -1 use from [TT].tpr[tt])" }, { "-order", FALSE, etINT, {&pme_order}, "Order of the PME spreading algorithm" }, { "-groups", FALSE, etBOOL, {&bGroups}, "Compute half an energy matrix based on the energy groups in your [TT].tpr[tt] file" }, { "-rc", FALSE, etREAL, {&rc}, "Rcoulomb for Ewald summation" }, { "-tol", FALSE, etREAL, {&dtol}, "Tolerance for Ewald summation" } }; FILE *fp; t_inputrec *ir; t_topology top; t_tpxheader tpx; t_nrnb nrnb; t_nsborder *nsb; t_forcerec *fr; t_mdatoms *mdatoms; char title[STRLEN]; int natoms,step,status,i,ncg,root; real t,lambda,ewaldcoeff,qtot; rvec *x,*f,*xbuf; int *index; gmx_bool bCont; real *charge,*qbuf,*qqbuf; matrix box; /* Start the actual parallel code if necessary */ cr = init_par(&argc,&argv); root = 0; if (MASTER(cr)) CopyRight(stderr,argv[0]); /* Parse command line on all processors, arguments are passed on in * init_par (see above) */ parse_common_args(&argc,argv, PCA_KEEP_ARGS | PCA_NOEXIT_ON_ARGS | PCA_BE_NICE | PCA_CAN_SET_DEFFNM | (MASTER(cr) ? 0 : PCA_QUIET), NFILE,fnm,asize(pa),pa,asize(desc),desc,0,NULL); #ifndef GMX_MPI if (nnodes > 1) gmx_fatal(FARGS,"GROMACS compiled without MPI support - can't do parallel runs"); #endif /* Open log files on all processors */ open_log(ftp2fn(efLOG,NFILE,fnm),cr); snew(ir,1); if (MASTER(cr)) { /* Read tpr file etc. */ read_tpxheader(ftp2fn(efTPX,NFILE,fnm),&tpx,FALSE,NULL,NULL); snew(x,tpx.natoms); read_tpx(ftp2fn(efTPX,NFILE,fnm),&step,&t,&lambda,ir, box,&natoms,x,NULL,NULL,&top); /* Charges */ qtot = 0; snew(charge,natoms); for(i=0; (i<natoms); i++) { charge[i] = top.atoms.atom[i].q; qtot += charge[i]; } /* Grid stuff */ if (opt2parg_bSet("-grid",asize(pa),pa)) { ir->nkx = grid[XX]; ir->nky = grid[YY]; ir->nkz = grid[ZZ]; } /* Check command line parameters for consistency */ if ((ir->nkx <= 0) || (ir->nky <= 0) || (ir->nkz <= 0)) gmx_fatal(FARGS,"PME grid = %d %d %d",ir->nkx,ir->nky,ir->nkz); if (opt2parg_bSet("-rc",asize(pa),pa)) ir->rcoulomb = rc; if (ir->rcoulomb <= 0) gmx_fatal(FARGS,"rcoulomb should be > 0 (not %f)",ir->rcoulomb); if (opt2parg_bSet("-order",asize(pa),pa)) ir->pme_order = pme_order; if (ir->pme_order <= 0) gmx_fatal(FARGS,"pme_order should be > 0 (not %d)",ir->pme_order); if (opt2parg_bSet("-tol",asize(pa),pa)) ir->ewald_rtol = dtol; if (ir->ewald_rtol <= 0) gmx_fatal(FARGS,"ewald_tol should be > 0 (not %f)",ir->ewald_rtol); } else { init_top(&top); } /* Add parallellization code here */ snew(nsb,1); if (MASTER(cr)) { ncg = top.blocks[ebCGS].multinr[0]; for(i=0; (i<cr->nnodes-1); i++) top.blocks[ebCGS].multinr[i] = min(ncg,(ncg*(i+1))/cr->nnodes); for( ; (i<MAXNODES); i++) top.blocks[ebCGS].multinr[i] = ncg; } if (PAR(cr)) { /* Set some variables to zero to avoid core dumps */ ir->opts.ngtc = ir->opts.ngacc = ir->opts.ngfrz = ir->opts.ngener = 0; #ifdef GMX_MPI /* Distribute the data over processors */ MPI_Bcast(&natoms,1,MPI_INT,root,MPI_COMM_WORLD); MPI_Bcast(ir,sizeof(*ir),MPI_BYTE,root,MPI_COMM_WORLD); MPI_Bcast(&qtot,1,GMX_MPI_REAL,root,MPI_COMM_WORLD); #endif /* Call some dedicated communication routines, master sends n-1 times */ if (MASTER(cr)) { for(i=1; (i<cr->nnodes); i++) { mv_block(i,&(top.blocks[ebCGS])); mv_block(i,&(top.atoms.excl)); } } else { ld_block(root,&(top.blocks[ebCGS])); ld_block(root,&(top.atoms.excl)); } if (!MASTER(cr)) { snew(charge,natoms); snew(x,natoms); } #ifdef GMX_MPI MPI_Bcast(charge,natoms,GMX_MPI_REAL,root,MPI_COMM_WORLD); #endif } ewaldcoeff = calc_ewaldcoeff(ir->rcoulomb,ir->ewald_rtol); if (bVerbose) pr_inputrec(stdlog,0,"Inputrec",ir); /* Allocate memory for temp arrays etc. */ snew(xbuf,natoms); snew(f,natoms); snew(qbuf,natoms); snew(qqbuf,natoms); snew(index,natoms); /* Initialize the PME code */ init_pme(stdlog,cr,ir->nkx,ir->nky,ir->nkz,ir->pme_order, natoms,FALSE,bOptFFT,ewald_geometry); /* MFlops accounting */ init_nrnb(&nrnb); /* Initialize the work division */ calc_nsb(stdlog,&(top.blocks[ebCGS]),cr->nnodes,nsb,0); nsb->nodeid = cr->nodeid; print_nsb(stdlog,"pmetest",nsb); /* Initiate forcerec */ mdatoms = atoms2md(stdlog,&top.atoms,ir->opts.nFreeze,ir->eI, ir->delta_t,0,ir->opts.tau_t,FALSE,FALSE); snew(fr,1); init_forcerec(stdlog,fr,ir,&top,cr,mdatoms,nsb,box,FALSE,NULL,NULL,FALSE); /* First do PME based on coordinates in tpr file, send them to * other processors if needed. */ if (MASTER(cr)) fprintf(stdlog,"-----\n" "Results based on tpr file %s\n",ftp2fn(efTPX,NFILE,fnm)); #ifdef GMX_MPI if (PAR(cr)) { MPI_Bcast(x[0],natoms*DIM,GMX_MPI_REAL,root,MPI_COMM_WORLD); MPI_Bcast(box[0],DIM*DIM,GMX_MPI_REAL,root,MPI_COMM_WORLD); MPI_Bcast(&t,1,GMX_MPI_REAL,root,MPI_COMM_WORLD); } #endif do_my_pme(stdlog,0,bVerbose,ir,x,xbuf,f,charge,qbuf,qqbuf,box,bSort, cr,nsb,&nrnb,&(top.atoms.excl),qtot,fr,index,NULL, bGroups ? ir->opts.ngener : 1,mdatoms->cENER); /* If we have a trajectry file, we will read the frames in it and compute * the PME energy. */ if (ftp2bSet(efTRX,NFILE,fnm)) { fprintf(stdlog,"-----\n" "Results based on trx file %s\n",ftp2fn(efTRX,NFILE,fnm)); if (MASTER(cr)) { sfree(x); natoms = read_first_x(&status,ftp2fn(efTRX,NFILE,fnm),&t,&x,box); if (natoms != top.atoms.nr) gmx_fatal(FARGS,"natoms in trx = %d, in tpr = %d",natoms,top.atoms.nr); fp = xvgropen(ftp2fn(efXVG,NFILE,fnm),"PME Energy","Time (ps)","E (kJ/mol)"); } else fp = NULL; do { /* Send coordinates, box and time to the other nodes */ #ifdef GMX_MPI if (PAR(cr)) { MPI_Bcast(x[0],natoms*DIM,GMX_MPI_REAL,root,MPI_COMM_WORLD); MPI_Bcast(box[0],DIM*DIM,GMX_MPI_REAL,root,MPI_COMM_WORLD); MPI_Bcast(&t,1,GMX_MPI_REAL,root,MPI_COMM_WORLD); } #endif rm_pbc(&top.idef,nsb->natoms,box,x,x); /* Call the PME wrapper function */ do_my_pme(stdlog,t,bVerbose,ir,x,xbuf,f,charge,qbuf,qqbuf,box,bSort,cr, nsb,&nrnb,&(top.atoms.excl),qtot,fr,index,fp, bGroups ? ir->opts.ngener : 1,mdatoms->cENER); /* Only the master processor reads more data */ if (MASTER(cr)) bCont = read_next_x(status,&t,natoms,x,box); /* Check whether we need to continue */ #ifdef GMX_MPI if (PAR(cr)) MPI_Bcast(&bCont,1,MPI_INT,root,MPI_COMM_WORLD); #endif } while (bCont); /* Finish I/O, close files */ if (MASTER(cr)) { close_trx(status); ffclose(fp); } } if (bVerbose) { /* Do some final I/O about performance, might be useful in debugging */ fprintf(stdlog,"-----\n"); print_nrnb(stdlog,&nrnb); } /* Finish the parallel stuff */ if (gmx_parallel_env_initialized()) gmx_finalize(cr); /* Thank the audience, as usual */ if (MASTER(cr)) thanx(stderr); return 0; }
void do_nsgrid(FILE *fp, gmx_bool bVerbose, matrix box, rvec x[], t_atoms *atoms, real rlong, const output_env_t oenv) { gmx_mtop_t *mtop; gmx_localtop_t *top; t_mdatoms *md; t_block *cgs; t_inputrec *ir; t_nrnb nrnb; t_commrec *cr; int *cg_index; gmx_moltype_t *molt; gmx_ffparams_t *ffp; ivec *nFreeze; int i, m, natoms; rvec box_size; real *lambda, *dvdl; natoms = atoms->nr; /* Charge group index */ snew(cg_index, natoms); for (i = 0; (i < natoms); i++) { cg_index[i] = i; } /* Topology needs charge groups and exclusions */ snew(mtop, 1); init_mtop(mtop); mtop->natoms = natoms; /* Make one moltype that contains the whol system */ mtop->nmoltype = 1; snew(mtop->moltype, mtop->nmoltype); molt = &mtop->moltype[0]; molt->name = mtop->name; molt->atoms = *atoms; stupid_fill_block(&molt->cgs, mtop->natoms, FALSE); stupid_fill_blocka(&molt->excls, natoms); /* Make one molblock for the whole system */ mtop->nmolblock = 1; snew(mtop->molblock, mtop->nmolblock); mtop->molblock[0].type = 0; mtop->molblock[0].nmol = 1; mtop->molblock[0].natoms_mol = natoms; /* Initialize a single energy group */ mtop->groups.grps[egcENER].nr = 1; mtop->groups.ngrpnr[egcENER] = 0; mtop->groups.grpnr[egcENER] = NULL; ffp = &mtop->ffparams; ffp->ntypes = 1; ffp->atnr = 1; ffp->reppow = 12; snew(ffp->functype, 1); snew(ffp->iparams, 1); ffp->iparams[0].lj.c6 = 1; ffp->iparams[0].lj.c12 = 1; /* inputrec structure */ snew(ir, 1); ir->coulombtype = eelCUT; ir->vdwtype = evdwCUT; ir->ndelta = 2; ir->ns_type = ensGRID; snew(ir->opts.egp_flags, 1); top = gmx_mtop_generate_local_top(mtop, ir); /* Some nasty shortcuts */ cgs = &(top->cgs); /* mdatoms structure */ snew(nFreeze, 2); snew(md, 1); md = init_mdatoms(fp, mtop, FALSE); atoms2md(mtop, ir, 0, NULL, 0, mtop->natoms, md); sfree(nFreeze); /* forcerec structure */ if (fr == NULL) { fr = mk_forcerec(); } snew(cr, 1); cr->nnodes = 1; /* cr->nthreads = 1; */ /* ir->rlist = ir->rcoulomb = ir->rvdw = rlong; printf("Neighborsearching with a cut-off of %g\n",rlong); init_forcerec(stdout,fr,ir,top,cr,md,box,FALSE,NULL,NULL,NULL,TRUE);*/ fr->cg0 = 0; fr->hcg = top->cgs.nr; fr->nWatMol = 0; /* Prepare for neighboursearching */ init_nrnb(&nrnb); /* Init things dependent on parameters */ ir->rlistlong = ir->rlist = ir->rcoulomb = ir->rvdw = rlong; /* create free energy data to avoid NULLs */ snew(ir->fepvals, 1); printf("Neighborsearching with a cut-off of %g\n", rlong); init_forcerec(stdout, oenv, fr, NULL, ir, mtop, cr, box, FALSE, NULL, NULL, NULL, NULL, NULL, TRUE, -1); if (debug) { pr_forcerec(debug, fr, cr); } /* Calculate new stuff dependent on coords and box */ for (m = 0; (m < DIM); m++) { box_size[m] = box[m][m]; } calc_shifts(box, fr->shift_vec); put_charge_groups_in_box(fp, 0, cgs->nr, fr->ePBC, box, cgs, x, fr->cg_cm); /* Do the actual neighboursearching */ snew(lambda, efptNR); snew(dvdl, efptNR); init_neighbor_list(fp, fr, md->homenr); search_neighbours(fp, fr, x, box, top, &mtop->groups, cr, &nrnb, md, lambda, dvdl, NULL, TRUE, FALSE, FALSE); if (debug) { dump_nblist(debug, cr, fr, 0); } if (bVerbose) { fprintf(stderr, "Successfully made neighbourlist\n"); } }
int gmx_pmeonly(struct gmx_pme_t *pme, t_commrec *cr, t_nrnb *mynrnb, gmx_wallcycle_t wcycle, gmx_walltime_accounting_t walltime_accounting, real ewaldcoeff_q, real ewaldcoeff_lj, t_inputrec *ir) { int npmedata; struct gmx_pme_t **pmedata; gmx_pme_pp_t pme_pp; int ret; int natoms; matrix box; rvec *x_pp = NULL, *f_pp = NULL; real *chargeA = NULL, *chargeB = NULL; real *c6A = NULL, *c6B = NULL; real *sigmaA = NULL, *sigmaB = NULL; real lambda_q = 0; real lambda_lj = 0; int maxshift_x = 0, maxshift_y = 0; real energy_q, energy_lj, dvdlambda_q, dvdlambda_lj; matrix vir_q, vir_lj; float cycles; int count; gmx_bool bEnerVir; int pme_flags; gmx_int64_t step, step_rel; ivec grid_switch; /* This data will only use with PME tuning, i.e. switching PME grids */ npmedata = 1; snew(pmedata, npmedata); pmedata[0] = pme; pme_pp = gmx_pme_pp_init(cr); init_nrnb(mynrnb); count = 0; do /****** this is a quasi-loop over time steps! */ { /* The reason for having a loop here is PME grid tuning/switching */ do { /* Domain decomposition */ ret = gmx_pme_recv_coeffs_coords(pme_pp, &natoms, &chargeA, &chargeB, &c6A, &c6B, &sigmaA, &sigmaB, box, &x_pp, &f_pp, &maxshift_x, &maxshift_y, &pme->bFEP_q, &pme->bFEP_lj, &lambda_q, &lambda_lj, &bEnerVir, &pme_flags, &step, grid_switch, &ewaldcoeff_q, &ewaldcoeff_lj); if (ret == pmerecvqxSWITCHGRID) { /* Switch the PME grid to grid_switch */ gmx_pmeonly_switch(&npmedata, &pmedata, grid_switch, cr, ir, &pme); } if (ret == pmerecvqxRESETCOUNTERS) { /* Reset the cycle and flop counters */ reset_pmeonly_counters(wcycle, walltime_accounting, mynrnb, ir, step); } } while (ret == pmerecvqxSWITCHGRID || ret == pmerecvqxRESETCOUNTERS); if (ret == pmerecvqxFINISH) { /* We should stop: break out of the loop */ break; } step_rel = step - ir->init_step; if (count == 0) { wallcycle_start(wcycle, ewcRUN); walltime_accounting_start(walltime_accounting); } wallcycle_start(wcycle, ewcPMEMESH); dvdlambda_q = 0; dvdlambda_lj = 0; clear_mat(vir_q); clear_mat(vir_lj); gmx_pme_do(pme, 0, natoms, x_pp, f_pp, chargeA, chargeB, c6A, c6B, sigmaA, sigmaB, box, cr, maxshift_x, maxshift_y, mynrnb, wcycle, vir_q, ewaldcoeff_q, vir_lj, ewaldcoeff_lj, &energy_q, &energy_lj, lambda_q, lambda_lj, &dvdlambda_q, &dvdlambda_lj, pme_flags | GMX_PME_DO_ALL_F | (bEnerVir ? GMX_PME_CALC_ENER_VIR : 0)); cycles = wallcycle_stop(wcycle, ewcPMEMESH); gmx_pme_send_force_vir_ener(pme_pp, f_pp, vir_q, energy_q, vir_lj, energy_lj, dvdlambda_q, dvdlambda_lj, cycles); count++; } /***** end of quasi-loop, we stop with the break above */ while (TRUE); walltime_accounting_end(walltime_accounting); return 0; }
int gmx_disre(int argc,char *argv[]) { const char *desc[] = { "g_disre computes violations of distance restraints.", "If necessary all protons can be added to a protein molecule ", "using the protonate program.[PAR]", "The program always", "computes the instantaneous violations rather than time-averaged,", "because this analysis is done from a trajectory file afterwards", "it does not make sense to use time averaging. However,", "the time averaged values per restraint are given in the log file.[PAR]", "An index file may be used to select specific restraints for", "printing.[PAR]", "When the optional[TT]-q[tt] flag is given a pdb file coloured by the", "amount of average violations.[PAR]", "When the [TT]-c[tt] option is given, an index file will be read", "containing the frames in your trajectory corresponding to the clusters", "(defined in another manner) that you want to analyze. For these clusters", "the program will compute average violations using the third power", "averaging algorithm and print them in the log file." }; static int ntop = 0; static int nlevels = 20; static real max_dr = 0; static gmx_bool bThird = TRUE; t_pargs pa[] = { { "-ntop", FALSE, etINT, {&ntop}, "Number of large violations that are stored in the log file every step" }, { "-maxdr", FALSE, etREAL, {&max_dr}, "Maximum distance violation in matrix output. If less than or equal to 0 the maximum will be determined by the data." }, { "-nlevels", FALSE, etINT, {&nlevels}, "Number of levels in the matrix output" }, { "-third", FALSE, etBOOL, {&bThird}, "Use inverse third power averaging or linear for matrix output" } }; FILE *out=NULL,*aver=NULL,*numv=NULL,*maxxv=NULL,*xvg=NULL; t_tpxheader header; t_inputrec ir; gmx_mtop_t mtop; rvec *xtop; gmx_localtop_t *top; t_atoms *atoms=NULL; t_forcerec *fr; t_fcdata fcd; t_nrnb nrnb; t_commrec *cr; t_graph *g; int ntopatoms,natoms,i,j,kkk; t_trxstatus *status; real t; rvec *x,*f,*xav=NULL; matrix box; gmx_bool bPDB; int isize; atom_id *index=NULL,*ind_fit=NULL; char *grpname; t_cluster_ndx *clust=NULL; t_dr_result dr,*dr_clust=NULL; char **leg; real *vvindex=NULL,*w_rls=NULL; t_mdatoms *mdatoms; t_pbc pbc,*pbc_null; int my_clust; FILE *fplog; output_env_t oenv; gmx_rmpbc_t gpbc=NULL; t_filenm fnm[] = { { efTPX, NULL, NULL, ffREAD }, { efTRX, "-f", NULL, ffREAD }, { efXVG, "-ds", "drsum", ffWRITE }, { efXVG, "-da", "draver", ffWRITE }, { efXVG, "-dn", "drnum", ffWRITE }, { efXVG, "-dm", "drmax", ffWRITE }, { efXVG, "-dr", "restr", ffWRITE }, { efLOG, "-l", "disres", ffWRITE }, { efNDX, NULL, "viol", ffOPTRD }, { efPDB, "-q", "viol", ffOPTWR }, { efNDX, "-c", "clust", ffOPTRD }, { efXPM, "-x", "matrix", ffOPTWR } }; #define NFILE asize(fnm) cr = init_par(&argc,&argv); CopyRight(stderr,argv[0]); parse_common_args(&argc,argv,PCA_CAN_TIME | PCA_CAN_VIEW | PCA_BE_NICE, NFILE,fnm,asize(pa),pa,asize(desc),desc,0,NULL,&oenv); gmx_log_open(ftp2fn(efLOG,NFILE,fnm),cr,FALSE,0,&fplog); if (ntop) init5(ntop); read_tpxheader(ftp2fn(efTPX,NFILE,fnm),&header,FALSE,NULL,NULL); snew(xtop,header.natoms); read_tpx(ftp2fn(efTPX,NFILE,fnm),&ir,box,&ntopatoms,xtop,NULL,NULL,&mtop); bPDB = opt2bSet("-q",NFILE,fnm); if (bPDB) { snew(xav,ntopatoms); snew(ind_fit,ntopatoms); snew(w_rls,ntopatoms); for(kkk=0; (kkk<ntopatoms); kkk++) { w_rls[kkk] = 1; ind_fit[kkk] = kkk; } snew(atoms,1); *atoms = gmx_mtop_global_atoms(&mtop); if (atoms->pdbinfo == NULL) { snew(atoms->pdbinfo,atoms->nr); } } top = gmx_mtop_generate_local_top(&mtop,&ir); g = NULL; pbc_null = NULL; if (ir.ePBC != epbcNONE) { if (ir.bPeriodicMols) pbc_null = &pbc; else g = mk_graph(fplog,&top->idef,0,mtop.natoms,FALSE,FALSE); } if (ftp2bSet(efNDX,NFILE,fnm)) { rd_index(ftp2fn(efNDX,NFILE,fnm),1,&isize,&index,&grpname); xvg=xvgropen(opt2fn("-dr",NFILE,fnm),"Inidividual Restraints","Time (ps)", "nm",oenv); snew(vvindex,isize); snew(leg,isize); for(i=0; (i<isize); i++) { index[i]++; snew(leg[i],12); sprintf(leg[i],"index %d",index[i]); } xvgr_legend(xvg,isize,(const char**)leg,oenv); } else isize=0; ir.dr_tau=0.0; init_disres(fplog,&mtop,&ir,NULL,FALSE,&fcd,NULL); natoms=read_first_x(oenv,&status,ftp2fn(efTRX,NFILE,fnm),&t,&x,box); snew(f,5*natoms); init_dr_res(&dr,fcd.disres.nres); if (opt2bSet("-c",NFILE,fnm)) { clust = cluster_index(fplog,opt2fn("-c",NFILE,fnm)); snew(dr_clust,clust->clust->nr+1); for(i=0; (i<=clust->clust->nr); i++) init_dr_res(&dr_clust[i],fcd.disres.nres); } else { out =xvgropen(opt2fn("-ds",NFILE,fnm), "Sum of Violations","Time (ps)","nm",oenv); aver=xvgropen(opt2fn("-da",NFILE,fnm), "Average Violation","Time (ps)","nm",oenv); numv=xvgropen(opt2fn("-dn",NFILE,fnm), "# Violations","Time (ps)","#",oenv); maxxv=xvgropen(opt2fn("-dm",NFILE,fnm), "Largest Violation","Time (ps)","nm",oenv); } mdatoms = init_mdatoms(fplog,&mtop,ir.efep!=efepNO); atoms2md(&mtop,&ir,0,NULL,0,mtop.natoms,mdatoms); update_mdatoms(mdatoms,ir.init_lambda); fr = mk_forcerec(); fprintf(fplog,"Made forcerec\n"); init_forcerec(fplog,oenv,fr,NULL,&ir,&mtop,cr,box,FALSE,NULL,NULL,NULL, FALSE,-1); init_nrnb(&nrnb); if (ir.ePBC != epbcNONE) gpbc = gmx_rmpbc_init(&top->idef,ir.ePBC,natoms,box); j=0; do { if (ir.ePBC != epbcNONE) { if (ir.bPeriodicMols) set_pbc(&pbc,ir.ePBC,box); else gmx_rmpbc(gpbc,natoms,box,x); } if (clust) { if (j > clust->maxframe) gmx_fatal(FARGS,"There are more frames in the trajectory than in the cluster index file. t = %8f\n",t); my_clust = clust->inv_clust[j]; range_check(my_clust,0,clust->clust->nr); check_viol(fplog,cr,&(top->idef.il[F_DISRES]), top->idef.iparams,top->idef.functype, x,f,fr,pbc_null,g,dr_clust,my_clust,isize,index,vvindex,&fcd); } else check_viol(fplog,cr,&(top->idef.il[F_DISRES]), top->idef.iparams,top->idef.functype, x,f,fr,pbc_null,g,&dr,0,isize,index,vvindex,&fcd); if (bPDB) { reset_x(atoms->nr,ind_fit,atoms->nr,NULL,x,w_rls); do_fit(atoms->nr,w_rls,x,x); if (j == 0) { /* Store the first frame of the trajectory as 'characteristic' * for colouring with violations. */ for(kkk=0; (kkk<atoms->nr); kkk++) copy_rvec(x[kkk],xav[kkk]); } } if (!clust) { if (isize > 0) { fprintf(xvg,"%10g",t); for(i=0; (i<isize); i++) fprintf(xvg," %10g",vvindex[i]); fprintf(xvg,"\n"); } fprintf(out, "%10g %10g\n",t,dr.sumv); fprintf(aver, "%10g %10g\n",t,dr.averv); fprintf(maxxv,"%10g %10g\n",t,dr.maxv); fprintf(numv, "%10g %10d\n",t,dr.nv); } j++; } while (read_next_x(oenv,status,&t,natoms,x,box)); close_trj(status); if (ir.ePBC != epbcNONE) gmx_rmpbc_done(gpbc); if (clust) { dump_clust_stats(fplog,fcd.disres.nres,&(top->idef.il[F_DISRES]), top->idef.iparams,clust->clust,dr_clust, clust->grpname,isize,index); } else { dump_stats(fplog,j,fcd.disres.nres,&(top->idef.il[F_DISRES]), top->idef.iparams,&dr,isize,index, bPDB ? atoms : NULL); if (bPDB) { write_sto_conf(opt2fn("-q",NFILE,fnm), "Coloured by average violation in Angstrom", atoms,xav,NULL,ir.ePBC,box); } dump_disre_matrix(opt2fn_null("-x",NFILE,fnm),&dr,fcd.disres.nres, j,&top->idef,&mtop,max_dr,nlevels,bThird); ffclose(out); ffclose(aver); ffclose(numv); ffclose(maxxv); if (isize > 0) { ffclose(xvg); do_view(oenv,opt2fn("-dr",NFILE,fnm),"-nxy"); } do_view(oenv,opt2fn("-dn",NFILE,fnm),"-nxy"); do_view(oenv,opt2fn("-da",NFILE,fnm),"-nxy"); do_view(oenv,opt2fn("-ds",NFILE,fnm),"-nxy"); do_view(oenv,opt2fn("-dm",NFILE,fnm),"-nxy"); } thanx(stderr); if (gmx_parallel_env_initialized()) gmx_finalize(); gmx_log_close(fplog); return 0; }
int gmx_pmeonly(struct gmx_pme_t *pme, const t_commrec *cr, t_nrnb *mynrnb, gmx_wallcycle *wcycle, gmx_walltime_accounting_t walltime_accounting, t_inputrec *ir, PmeRunMode runMode) { int ret; int natoms = 0; matrix box; real lambda_q = 0; real lambda_lj = 0; int maxshift_x = 0, maxshift_y = 0; real energy_q, energy_lj, dvdlambda_q, dvdlambda_lj; matrix vir_q, vir_lj; float cycles; int count; gmx_bool bEnerVir = FALSE; int64_t step; /* This data will only use with PME tuning, i.e. switching PME grids */ std::vector<gmx_pme_t *> pmedata; pmedata.push_back(pme); auto pme_pp = gmx_pme_pp_init(cr); //TODO the variable below should be queried from the task assignment info const bool useGpuForPme = (runMode == PmeRunMode::GPU) || (runMode == PmeRunMode::Mixed); if (useGpuForPme) { changePinningPolicy(&pme_pp->chargeA, pme_get_pinning_policy()); changePinningPolicy(&pme_pp->x, pme_get_pinning_policy()); } init_nrnb(mynrnb); count = 0; do /****** this is a quasi-loop over time steps! */ { /* The reason for having a loop here is PME grid tuning/switching */ do { /* Domain decomposition */ ivec newGridSize; bool atomSetChanged = false; real ewaldcoeff_q = 0, ewaldcoeff_lj = 0; ret = gmx_pme_recv_coeffs_coords(pme_pp.get(), &natoms, box, &maxshift_x, &maxshift_y, &lambda_q, &lambda_lj, &bEnerVir, &step, &newGridSize, &ewaldcoeff_q, &ewaldcoeff_lj, &atomSetChanged); if (ret == pmerecvqxSWITCHGRID) { /* Switch the PME grid to newGridSize */ pme = gmx_pmeonly_switch(&pmedata, newGridSize, ewaldcoeff_q, ewaldcoeff_lj, cr, ir); } if (atomSetChanged) { gmx_pme_reinit_atoms(pme, natoms, pme_pp->chargeA.data()); } if (ret == pmerecvqxRESETCOUNTERS) { /* Reset the cycle and flop counters */ reset_pmeonly_counters(wcycle, walltime_accounting, mynrnb, step, useGpuForPme); } } while (ret == pmerecvqxSWITCHGRID || ret == pmerecvqxRESETCOUNTERS); if (ret == pmerecvqxFINISH) { /* We should stop: break out of the loop */ break; } if (count == 0) { wallcycle_start(wcycle, ewcRUN); walltime_accounting_start_time(walltime_accounting); } wallcycle_start(wcycle, ewcPMEMESH); dvdlambda_q = 0; dvdlambda_lj = 0; clear_mat(vir_q); clear_mat(vir_lj); energy_q = 0; energy_lj = 0; // TODO Make a struct of array refs onto these per-atom fields // of pme_pp (maybe box, energy and virial, too; and likewise // from mdatoms for the other call to gmx_pme_do), so we have // fewer lines of code and less parameter passing. const int pmeFlags = GMX_PME_DO_ALL_F | (bEnerVir ? GMX_PME_CALC_ENER_VIR : 0); gmx::ArrayRef<const gmx::RVec> forces; if (useGpuForPme) { const bool boxChanged = false; //TODO this should be set properly by gmx_pme_recv_coeffs_coords, // or maybe use inputrecDynamicBox(ir), at the very least - change this when this codepath is tested! pme_gpu_prepare_computation(pme, boxChanged, box, wcycle, pmeFlags); pme_gpu_launch_spread(pme, pme_pp->x.rvec_array(), wcycle); pme_gpu_launch_complex_transforms(pme, wcycle); pme_gpu_launch_gather(pme, wcycle, PmeForceOutputHandling::Set); pme_gpu_wait_finish_task(pme, wcycle, &forces, vir_q, &energy_q); pme_gpu_reinit_computation(pme, wcycle); } else { gmx_pme_do(pme, 0, natoms, pme_pp->x.rvec_array(), as_rvec_array(pme_pp->f.data()), pme_pp->chargeA.data(), pme_pp->chargeB.data(), pme_pp->sqrt_c6A.data(), pme_pp->sqrt_c6B.data(), pme_pp->sigmaA.data(), pme_pp->sigmaB.data(), box, cr, maxshift_x, maxshift_y, mynrnb, wcycle, vir_q, vir_lj, &energy_q, &energy_lj, lambda_q, lambda_lj, &dvdlambda_q, &dvdlambda_lj, pmeFlags); forces = pme_pp->f; } cycles = wallcycle_stop(wcycle, ewcPMEMESH); gmx_pme_send_force_vir_ener(pme_pp.get(), as_rvec_array(forces.data()), vir_q, energy_q, vir_lj, energy_lj, dvdlambda_q, dvdlambda_lj, cycles); count++; } /***** end of quasi-loop, we stop with the break above */ while (TRUE); walltime_accounting_end_time(walltime_accounting); return 0; }
void init_md(FILE *fplog, t_commrec *cr,t_inputrec *ir,real *t,real *t0, real *lambda,real *lam0, t_nrnb *nrnb,gmx_mtop_t *mtop, gmx_stochd_t *sd, int nfile,t_filenm fnm[], int *fp_trn,int *fp_xtc,int *fp_ene,char **fn_cpt, FILE **fp_dgdl,FILE **fp_field, t_mdebin **mdebin, tensor force_vir,tensor shake_vir,rvec mu_tot, bool *bNEMD,bool *bSimAnn,t_vcm **vcm, unsigned long Flags) { int i,j,n; real tmpt,mod; char filemode[2]; sprintf(filemode, (Flags & MD_APPENDFILES) ? "a" : "w"); /* Initial values */ *t = *t0 = ir->init_t; if (ir->efep != efepNO) { *lam0 = ir->init_lambda; *lambda = *lam0 + ir->init_step*ir->delta_lambda; } else { *lambda = *lam0 = 0.0; } *bSimAnn=FALSE; for(i=0;i<ir->opts.ngtc;i++) { /* set bSimAnn if any group is being annealed */ if(ir->opts.annealing[i]!=eannNO) *bSimAnn = TRUE; } if (*bSimAnn) { update_annealing_target_temp(&(ir->opts),ir->init_t); } *bNEMD = (ir->opts.ngacc > 1) || (norm(ir->opts.acc[0]) > 0); if (sd && (ir->eI == eiBD || EI_SD(ir->eI) || ir->etc == etcVRESCALE)) { *sd = init_stochd(fplog,ir); } if (vcm) { *vcm = init_vcm(fplog,&mtop->groups,ir); } if (EI_DYNAMICS(ir->eI) && !(Flags & MD_APPENDFILES)) { if (ir->etc == etcBERENDSEN) { please_cite(fplog,"Berendsen84a"); } if (ir->etc == etcVRESCALE) { please_cite(fplog,"Bussi2007a"); } } init_nrnb(nrnb); if (nfile != -1) { *fp_trn = -1; *fp_ene = -1; *fp_xtc = -1; if (MASTER(cr)) { *fp_trn = open_trn(ftp2fn(efTRN,nfile,fnm), filemode); if (ir->nstxtcout > 0) { *fp_xtc = open_xtc(ftp2fn(efXTC,nfile,fnm), filemode); } *fp_ene = open_enx(ftp2fn(efENX,nfile,fnm), filemode); *fn_cpt = opt2fn("-cpo",nfile,fnm); if ((fp_dgdl != NULL) && ir->efep!=efepNO) { if(Flags & MD_APPENDFILES) { *fp_dgdl= gmx_fio_fopen(opt2fn("-dgdl",nfile,fnm),filemode); } else { *fp_dgdl = xvgropen(opt2fn("-dgdl",nfile,fnm), "dG/d\\8l\\4","Time (ps)", "dG/d\\8l\\4 (kJ mol\\S-1\\N [\\8l\\4]\\S-1\\N)"); } } if ((fp_field != NULL) && (ir->ex[XX].n || ir->ex[YY].n ||ir->ex[ZZ].n)) { if(Flags & MD_APPENDFILES) { *fp_field = gmx_fio_fopen(opt2fn("-field",nfile,fnm),filemode); } else { *fp_field = xvgropen(opt2fn("-field",nfile,fnm), "Applied electric field","Time (ps)", "E (V/nm)"); } } } *mdebin = init_mdebin( (Flags & MD_APPENDFILES) ? -1 : *fp_ene,mtop,ir); } /* Initiate variables */ clear_mat(force_vir); clear_mat(shake_vir); clear_rvec(mu_tot); debug_gmx(); }
void init_md(t_commrec *cr,t_inputrec *ir,tensor box,real *t,real *t0, real *lambda,real *lam0,real *SAfactor, t_nrnb *mynrnb,bool *bTYZ,t_topology *top, int nfile,t_filenm fnm[],char **traj, char **xtc_traj,int *fp_ene, FILE **fp_dgdl,t_mdebin **mdebin,t_groups *grps, tensor force_vir,tensor pme_vir, tensor shake_vir,t_mdatoms *mdatoms,rvec mu_tot, bool *bNEMD,t_vcm **vcm,t_nsborder *nsb) { bool bBHAM,b14,bLR,bLJLR; int i; /* Initial values */ *t = *t0 = ir->init_t; if (ir->efep != efepNO) { *lambda = *lam0 = ir->init_lambda; } else { *lambda = *lam0 = 0.0; } if (ir->bSimAnn) { *SAfactor = 1.0 - *t0/ir->zero_temp_time; if (*SAfactor < 0) *SAfactor = 0; } else *SAfactor = 1.0; init_nrnb(mynrnb); /* Check Environment variables & other booleans */ #ifdef SPEC_CPU *bTYZ = FALSE; #else *bTYZ=getenv("TYZ") != NULL; #endif set_pot_bools(ir,top,&bLR,&bLJLR,&bBHAM,&b14); if (nfile != -1) { /* Filenames */ *traj = ftp2fn(efTRN,nfile,fnm); *xtc_traj = ftp2fn(efXTC,nfile,fnm); #ifndef SPEC_CPU if (MASTER(cr)) { *fp_ene = open_enx(ftp2fn(efENX,nfile,fnm),"w"); if ((fp_dgdl != NULL) && ir->efep!=efepNO) *fp_dgdl = xvgropen(opt2fn("-dgdl",nfile,fnm), "dG/d\\8l\\4","Time (ps)", "dG/d\\8l\\4 (kJ mol\\S-1\\N nm\\S-2\\N \\8l\\4\\S-1\\N)"); } else #endif *fp_ene = -1; *mdebin = init_mdebin(*fp_ene,grps,&(top->atoms),&(top->idef), bLR,bLJLR,bBHAM,b14,ir->efep!=efepNO,ir->epc, ir->eDispCorr,(TRICLINIC(ir->compress) || TRICLINIC(box)), (ir->etc==etcNOSEHOOVER),cr); } /* Initiate variables */ clear_mat(force_vir); clear_mat(pme_vir); clear_mat(shake_vir); clear_rvec(mu_tot); /* Set initial values for invmass etc. */ init_mdatoms(mdatoms,*lambda,TRUE); *vcm = init_vcm(stdlog,top,cr,mdatoms,START(nsb),HOMENR(nsb),ir->nstcomm); debug_gmx(); *bNEMD = (ir->opts.ngacc > 1) || (norm(ir->opts.acc[0]) > 0); if (ir->eI == eiSD) init_sd_consts(ir->opts.ngtc,ir->opts.tau_t,ir->delta_t); }