static t_graph *gmx_rmpbc_get_graph(gmx_rmpbc_t gpbc, int ePBC, int natoms) { int i; rmpbc_graph_t *gr; if (ePBC == epbcNONE || NULL == gpbc || NULL == gpbc->idef || gpbc->idef->ntypes <= 0) { return NULL; } gr = NULL; for (i = 0; i < gpbc->ngraph; i++) { if (natoms == gpbc->graph[i].natoms) { gr = &gpbc->graph[i]; } } if (gr == NULL) { /* We'd like to check with the number of atoms in the topology, * but we don't have that available. * So we check against the number of atoms that gmx_rmpbc_init * was called with. */ if (natoms > gpbc->natoms_init) { gmx_fatal(FARGS, "Structure or trajectory file has more atoms (%d) than the topology (%d)", natoms, gpbc->natoms_init); } gpbc->ngraph++; srenew(gpbc->graph, gpbc->ngraph); gr = &gpbc->graph[gpbc->ngraph-1]; gr->natoms = natoms; gr->gr = mk_graph(NULL, gpbc->idef, 0, natoms, FALSE, FALSE); } return gr->gr; }
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; }
void mdAlgorithmsSetupAtomData(t_commrec *cr, const t_inputrec *ir, const gmx_mtop_t *top_global, gmx_localtop_t *top, t_forcerec *fr, t_graph **graph, t_mdatoms *mdatoms, gmx_vsite_t *vsite, gmx_shellfc_t *shellfc) { bool usingDomDec = DOMAINDECOMP(cr); int numAtomIndex, numHomeAtoms; int *atomIndex; if (usingDomDec) { numAtomIndex = dd_natoms_mdatoms(cr->dd); atomIndex = cr->dd->gatindex; numHomeAtoms = cr->dd->nat_home; } else { numAtomIndex = -1; atomIndex = NULL; numHomeAtoms = top_global->natoms; } atoms2md(top_global, ir, numAtomIndex, atomIndex, numHomeAtoms, mdatoms); if (usingDomDec) { dd_sort_local_top(cr->dd, mdatoms, top); } else { /* Currently gmx_generate_local_top allocates and returns a pointer. * We should implement a more elegant solution. */ gmx_localtop_t *tmpTop; tmpTop = gmx_mtop_generate_local_top(top_global, ir->efep != efepNO); *top = *tmpTop; sfree(tmpTop); } if (vsite) { if (usingDomDec) { /* The vsites were already assigned by the domdec topology code. * We only need to do the thread division here. */ split_vsites_over_threads(top->idef.il, top->idef.iparams, mdatoms, FALSE, vsite); } else { set_vsite_top(vsite, top, mdatoms, cr); } } if (!usingDomDec && ir->ePBC != epbcNONE && !fr->bMolPBC) { GMX_ASSERT(graph != NULL, "We use a graph with PBC (no periodic mols) and without DD"); *graph = mk_graph(NULL, &(top->idef), 0, top_global->natoms, FALSE, FALSE); } else if (graph != NULL) { *graph = NULL; } /* Note that with DD only flexible constraints, not shells, are supported * and these don't require setup in make_local_shells(). */ if (!usingDomDec && shellfc) { make_local_shells(cr, mdatoms, shellfc); } setup_bonded_threading(fr, &top->idef); }
double do_md_openmm(FILE *fplog,t_commrec *cr,int nfile,const t_filenm fnm[], const output_env_t oenv, gmx_bool bVerbose,gmx_bool bCompact, int nstglobalcomm, gmx_vsite_t *vsite,gmx_constr_t constr, int stepout,t_inputrec *ir, gmx_mtop_t *top_global, t_fcdata *fcd, t_state *state_global, t_mdatoms *mdatoms, t_nrnb *nrnb,gmx_wallcycle_t wcycle, gmx_edsam_t ed,t_forcerec *fr, int repl_ex_nst,int repl_ex_seed, real cpt_period,real max_hours, const char *deviceOptions, unsigned long Flags, gmx_runtime_t *runtime) { gmx_mdoutf_t *outf; gmx_large_int_t step,step_rel; double run_time; double t,t0,lam0; gmx_bool bSimAnn, bFirstStep,bStateFromTPX,bLastStep,bStartingFromCpt; gmx_bool bInitStep=TRUE; gmx_bool do_ene,do_log, do_verbose, bX,bV,bF,bCPT; tensor force_vir,shake_vir,total_vir,pres; int i,m; int mdof_flags; rvec mu_tot; t_vcm *vcm; int nchkpt=1; gmx_localtop_t *top; t_mdebin *mdebin=NULL; t_state *state=NULL; rvec *f_global=NULL; int n_xtc=-1; rvec *x_xtc=NULL; gmx_enerdata_t *enerd; rvec *f=NULL; gmx_global_stat_t gstat; gmx_update_t upd=NULL; t_graph *graph=NULL; globsig_t gs; gmx_groups_t *groups; gmx_ekindata_t *ekind, *ekind_save; gmx_bool bAppend; int a0,a1; matrix lastbox; real reset_counters=0,reset_counters_now=0; char sbuf[STEPSTRSIZE],sbuf2[STEPSTRSIZE]; int handled_stop_condition=gmx_stop_cond_none; const char *ommOptions = NULL; void *openmmData; bAppend = (Flags & MD_APPENDFILES); check_ir_old_tpx_versions(cr,fplog,ir,top_global); groups = &top_global->groups; /* Initial values */ init_md(fplog,cr,ir,oenv,&t,&t0,&state_global->lambda,&lam0, nrnb,top_global,&upd, nfile,fnm,&outf,&mdebin, force_vir,shake_vir,mu_tot,&bSimAnn,&vcm,state_global,Flags); clear_mat(total_vir); clear_mat(pres); /* Energy terms and groups */ snew(enerd,1); init_enerdata(top_global->groups.grps[egcENER].nr,ir->n_flambda,enerd); snew(f,top_global->natoms); /* Kinetic energy data */ snew(ekind,1); init_ekindata(fplog,top_global,&(ir->opts),ekind); /* needed for iteration of constraints */ snew(ekind_save,1); init_ekindata(fplog,top_global,&(ir->opts),ekind_save); /* Copy the cos acceleration to the groups struct */ ekind->cosacc.cos_accel = ir->cos_accel; gstat = global_stat_init(ir); debug_gmx(); { double io = compute_io(ir,top_global->natoms,groups,mdebin->ebin->nener,1); if ((io > 2000) && MASTER(cr)) fprintf(stderr, "\nWARNING: This run will generate roughly %.0f Mb of data\n\n", io); } top = gmx_mtop_generate_local_top(top_global,ir); a0 = 0; a1 = top_global->natoms; state = partdec_init_local_state(cr,state_global); f_global = f; atoms2md(top_global,ir,0,NULL,a0,a1-a0,mdatoms); if (vsite) { set_vsite_top(vsite,top,mdatoms,cr); } if (ir->ePBC != epbcNONE && !ir->bPeriodicMols) { graph = mk_graph(fplog,&(top->idef),0,top_global->natoms,FALSE,FALSE); } update_mdatoms(mdatoms,state->lambda); if (deviceOptions[0]=='\0') { /* empty options, which should default to OpenMM in this build */ ommOptions=deviceOptions; } else { if (gmx_strncasecmp(deviceOptions,"OpenMM",6)!=0) { gmx_fatal(FARGS, "This Gromacs version currently only works with OpenMM. Use -device \"OpenMM:<options>\""); } else { ommOptions=strchr(deviceOptions,':'); if (NULL!=ommOptions) { /* Increase the pointer to skip the colon */ ommOptions++; } } } openmmData = openmm_init(fplog, ommOptions, ir, top_global, top, mdatoms, fr, state); please_cite(fplog,"Friedrichs2009"); if (MASTER(cr)) { /* Update mdebin with energy history if appending to output files */ if ( Flags & MD_APPENDFILES ) { restore_energyhistory_from_state(mdebin,&state_global->enerhist); } /* Set the initial energy history in state to zero by updating once */ update_energyhistory(&state_global->enerhist,mdebin); } if (constr) { set_constraints(constr,top,ir,mdatoms,cr); } if (!ir->bContinuation) { if (mdatoms->cFREEZE && (state->flags & (1<<estV))) { /* Set the velocities of frozen particles to zero */ for (i=mdatoms->start; i<mdatoms->start+mdatoms->homenr; i++) { for (m=0; m<DIM; m++) { if (ir->opts.nFreeze[mdatoms->cFREEZE[i]][m]) { state->v[i][m] = 0; } } } } if (constr) { /* Constrain the initial coordinates and velocities */ do_constrain_first(fplog,constr,ir,mdatoms,state,f, graph,cr,nrnb,fr,top,shake_vir); } if (vsite) { /* Construct the virtual sites for the initial configuration */ construct_vsites(fplog,vsite,state->x,nrnb,ir->delta_t,NULL, top->idef.iparams,top->idef.il, fr->ePBC,fr->bMolPBC,graph,cr,state->box); } } debug_gmx(); if (MASTER(cr)) { char tbuf[20]; fprintf(fplog,"Initial temperature: %g K\n",enerd->term[F_TEMP]); fprintf(stderr,"starting mdrun '%s'\n", *(top_global->name)); if (ir->nsteps >= 0) { sprintf(tbuf,"%8.1f",(ir->init_step+ir->nsteps)*ir->delta_t); } else { sprintf(tbuf,"%s","infinite"); } if (ir->init_step > 0) { fprintf(stderr,"%s steps, %s ps (continuing from step %s, %8.1f ps).\n", gmx_step_str(ir->init_step+ir->nsteps,sbuf),tbuf, gmx_step_str(ir->init_step,sbuf2), ir->init_step*ir->delta_t); } else { fprintf(stderr,"%s steps, %s ps.\n", gmx_step_str(ir->nsteps,sbuf),tbuf); } } fprintf(fplog,"\n"); /* Set and write start time */ runtime_start(runtime); print_date_and_time(fplog,cr->nodeid,"Started mdrun",runtime); wallcycle_start(wcycle,ewcRUN); if (fplog) fprintf(fplog,"\n"); /* safest point to do file checkpointing is here. More general point would be immediately before integrator call */ debug_gmx(); /*********************************************************** * * Loop over MD steps * ************************************************************/ /* loop over MD steps or if rerunMD to end of input trajectory */ bFirstStep = TRUE; /* Skip the first Nose-Hoover integration when we get the state from tpx */ bStateFromTPX = !opt2bSet("-cpi",nfile,fnm); bInitStep = bFirstStep && bStateFromTPX; bStartingFromCpt = (Flags & MD_STARTFROMCPT) && bInitStep; bLastStep = FALSE; init_global_signals(&gs,cr,ir,repl_ex_nst); step = ir->init_step; step_rel = 0; while (!bLastStep) { wallcycle_start(wcycle,ewcSTEP); GMX_MPE_LOG(ev_timestep1); bLastStep = (step_rel == ir->nsteps); t = t0 + step*ir->delta_t; if (gs.set[eglsSTOPCOND] != 0) { bLastStep = TRUE; } do_log = do_per_step(step,ir->nstlog) || bFirstStep || bLastStep; do_verbose = bVerbose && (step % stepout == 0 || bFirstStep || bLastStep); if (MASTER(cr) && do_log) { print_ebin_header(fplog,step,t,state->lambda); } clear_mat(force_vir); GMX_MPE_LOG(ev_timestep2); /* We write a checkpoint at this MD step when: * either when we signalled through gs (in OpenMM NS works different), * or at the last step (but not when we do not want confout), * but never at the first step. */ bCPT = ((gs.set[eglsCHKPT] || (bLastStep && (Flags & MD_CONFOUT))) && step > ir->init_step ); if (bCPT) { gs.set[eglsCHKPT] = 0; } /* Now we have the energies and forces corresponding to the * coordinates at time t. We must output all of this before * the update. * for RerunMD t is read from input trajectory */ GMX_MPE_LOG(ev_output_start); mdof_flags = 0; if (do_per_step(step,ir->nstxout)) { mdof_flags |= MDOF_X; } if (do_per_step(step,ir->nstvout)) { mdof_flags |= MDOF_V; } if (do_per_step(step,ir->nstfout)) { mdof_flags |= MDOF_F; } if (do_per_step(step,ir->nstxtcout)) { mdof_flags |= MDOF_XTC; } if (bCPT) { mdof_flags |= MDOF_CPT; }; do_ene = (do_per_step(step,ir->nstenergy) || bLastStep); if (mdof_flags != 0 || do_ene || do_log) { wallcycle_start(wcycle,ewcTRAJ); bF = (mdof_flags & MDOF_F); bX = (mdof_flags & (MDOF_X | MDOF_XTC | MDOF_CPT)); bV = (mdof_flags & (MDOF_V | MDOF_CPT)); openmm_copy_state(openmmData, state, &t, f, enerd, bX, bV, bF, do_ene); upd_mdebin(mdebin, FALSE,TRUE, t,mdatoms->tmass,enerd,state,lastbox, shake_vir,force_vir,total_vir,pres, ekind,mu_tot,constr); print_ebin(outf->fp_ene,do_ene,FALSE,FALSE,do_log?fplog:NULL, step,t, eprNORMAL,bCompact,mdebin,fcd,groups,&(ir->opts)); write_traj(fplog,cr,outf,mdof_flags,top_global, step,t,state,state_global,f,f_global,&n_xtc,&x_xtc); if (bCPT) { nchkpt++; bCPT = FALSE; } debug_gmx(); if (bLastStep && step_rel == ir->nsteps && (Flags & MD_CONFOUT) && MASTER(cr)) { /* x and v have been collected in write_traj, * because a checkpoint file will always be written * at the last step. */ fprintf(stderr,"\nWriting final coordinates.\n"); if (ir->ePBC != epbcNONE && !ir->bPeriodicMols) { /* Make molecules whole only for confout writing */ do_pbc_mtop(fplog,ir->ePBC,state->box,top_global,state_global->x); } write_sto_conf_mtop(ftp2fn(efSTO,nfile,fnm), *top_global->name,top_global, state_global->x,state_global->v, ir->ePBC,state->box); debug_gmx(); } wallcycle_stop(wcycle,ewcTRAJ); } GMX_MPE_LOG(ev_output_finish); /* Determine the wallclock run time up till now */ run_time = gmx_gettime() - (double)runtime->real; /* Check whether everything is still allright */ if (((int)gmx_get_stop_condition() > handled_stop_condition) #ifdef GMX_THREADS && MASTER(cr) #endif ) { /* this is just make gs.sig compatible with the hack of sending signals around by MPI_Reduce with together with other floats */ /* NOTE: this only works for serial code. For code that allows MPI nodes to propagate their condition, see kernel/md.c*/ if ( gmx_get_stop_condition() == gmx_stop_cond_next_ns ) gs.set[eglsSTOPCOND]=1; if ( gmx_get_stop_condition() == gmx_stop_cond_next ) gs.set[eglsSTOPCOND]=1; /* < 0 means stop at next step, > 0 means stop at next NS step */ if (fplog) { fprintf(fplog, "\n\nReceived the %s signal, stopping at the next %sstep\n\n", gmx_get_signal_name(), gs.sig[eglsSTOPCOND]==1 ? "NS " : ""); fflush(fplog); } fprintf(stderr, "\n\nReceived the %s signal, stopping at the next %sstep\n\n", gmx_get_signal_name(), gs.sig[eglsSTOPCOND]==1 ? "NS " : ""); fflush(stderr); handled_stop_condition=(int)gmx_get_stop_condition(); } else if (MASTER(cr) && (max_hours > 0 && run_time > max_hours*60.0*60.0*0.99) && gs.set[eglsSTOPCOND] == 0) { /* Signal to terminate the run */ gs.set[eglsSTOPCOND] = 1; if (fplog) { fprintf(fplog,"\nStep %s: Run time exceeded %.3f hours, will terminate the run\n",gmx_step_str(step,sbuf),max_hours*0.99); } fprintf(stderr, "\nStep %s: Run time exceeded %.3f hours, will terminate the run\n",gmx_step_str(step,sbuf),max_hours*0.99); } /* checkpoints */ if (MASTER(cr) && (cpt_period >= 0 && (cpt_period == 0 || run_time >= nchkpt*cpt_period*60.0)) && gs.set[eglsCHKPT] == 0) { gs.set[eglsCHKPT] = 1; } /* Time for performance */ if (((step % stepout) == 0) || bLastStep) { runtime_upd_proc(runtime); } if (do_per_step(step,ir->nstlog)) { if (fflush(fplog) != 0) { gmx_fatal(FARGS,"Cannot flush logfile - maybe you are out of quota?"); } } /* Remaining runtime */ if (MULTIMASTER(cr) && (do_verbose || gmx_got_usr_signal() )) { print_time(stderr,runtime,step,ir,cr); } bFirstStep = FALSE; bInitStep = FALSE; bStartingFromCpt = FALSE; step++; step_rel++; openmm_take_one_step(openmmData); } /* End of main MD loop */ debug_gmx(); /* Stop the time */ runtime_end(runtime); if (MASTER(cr)) { if (ir->nstcalcenergy > 0) { print_ebin(outf->fp_ene,FALSE,FALSE,FALSE,fplog,step,t, eprAVER,FALSE,mdebin,fcd,groups,&(ir->opts)); } } openmm_cleanup(fplog, openmmData); done_mdoutf(outf); debug_gmx(); runtime->nsteps_done = step_rel; return 0; }
void gen_sblocks(FILE *fp, int at_start, int at_end, t_idef *idef, t_blocka *sblock, gmx_bool bSettle) { t_graph *g; int i, i0, j, k, istart, n; t_sid *sid; int isid, nsid; g = mk_graph(NULL, idef, at_start, at_end, TRUE, bSettle); if (debug) { p_graph(debug, "Graaf Dracula", g); } snew(sid, at_end); for (i = at_start; (i < at_end); i++) { sid[i].atom = i; sid[i].sid = -1; } nsid = mk_sblocks(fp, g, at_end, sid); if (!nsid) { return; } /* Now sort the shake blocks... */ qsort(sid+at_start, at_end-at_start, (size_t)sizeof(sid[0]), sid_comp); if (debug) { fprintf(debug, "Sorted shake block\n"); for (i = at_start; (i < at_end); i++) { fprintf(debug, "sid[%5d] = atom:%5d sid:%5d\n", i, sid[i].atom, sid[i].sid); } } /* Now check how many are NOT -1, i.e. how many have to be shaken */ for (i0 = at_start; (i0 < at_end); i0++) { if (sid[i0].sid > -1) { break; } } /* Now we have the sids that have to be shaken. We'll check the min and * max atom numbers and this determines the shake block. DvdS 2007-07-19. * For the purpose of making boundaries all atoms in between need to be * part of the shake block too. There may be cases where blocks overlap * and they will have to be merged. */ nsid = merge_sid(at_start, at_end, nsid, sid, sblock); /* Now sort the shake blocks again... */ /*qsort(sid,natoms,(size_t)sizeof(sid[0]),sid_comp);*/ /* Fill the sblock struct */ /* sblock->nr = nsid; sblock->nra = natoms; srenew(sblock->a,sblock->nra); srenew(sblock->index,sblock->nr+1); i = i0; isid = sid[i].sid; n = k = 0; sblock->index[n++]=k; while (i < natoms) { istart = sid[i].atom; while ((i<natoms-1) && (sid[i+1].sid == isid)) i++;*/ /* After while: we found a new block, or are thru with the atoms */ /* for(j=istart; (j<=sid[i].atom); j++,k++) sblock->a[k]=j; sblock->index[n] = k; if (i < natoms-1) n++; if (n > nsid) gmx_fatal(FARGS,"Death Horror: nsid = %d, n= %d",nsid,n); i++; isid = sid[i].sid; } */ sfree(sid); /* Due to unknown reason this free generates a problem sometimes */ done_graph(g); sfree(g); if (debug) { fprintf(debug, "Done gen_sblocks\n"); } }
int main(int argc,char *argv[]) { static char *desc[] = { "testlr tests the PPPM and Ewald method for the", "long range electrostatics problem." }; static t_filenm fnm[] = { { efTPX, NULL, NULL, ffREAD }, { efHAT, "-g", "ghat", ffOPTRD }, { efOUT, "-o", "rho", ffOPTWR }, { efOUT, "-op", "lr-pb", ffOPTWR }, { efOUT, "-of", "lr-four", ffOPTWR }, { efOUT, "-opt", "tot-pb", ffOPTWR }, { efOUT, "-oft", "tot-four", ffOPTWR }, { efOUT, "-fin", "lr-four", ffOPTWR }, { efEPS, "-es", "sr", ffOPTWR }, { efEPS, "-elf", "lr-four", ffOPTWR }, { efEPS, "-etf", "tot-four", ffOPTWR }, { efEPS, "-qr", "qk-real", ffOPTWR }, { efEPS, "-qi", "qk-im", ffOPTWR }, { efEPS, "-elp", "lr-pb", ffOPTWR }, { efEPS, "-etp", "tot-pb", ffOPTWR }, { efEPS, "-rho", "rho", ffOPTWR }, { efEPS, "-qq", "charge", ffOPTWR }, { efXVG, "-gt", "gk-tab", ffOPTWR }, { efXVG, "-fcorr","fcorr", ffWRITE }, { efXVG, "-pcorr","pcorr", ffWRITE }, { efXVG, "-ftotcorr","ftotcorr", ffWRITE }, { efXVG, "-ptotcorr","ptotcorr", ffWRITE }, { efLOG, "-l", "fptest", ffWRITE }, { efXVG, "-gr", "spread", ffOPTWR }, { efPDB, "-pf", "pqr-four", ffOPTWR }, { efPDB, "-phitot", "pppm-phitot", ffOPTWR } }; #define NFILE asize(fnm) FILE *log; t_topology top; t_tpxheader stath; t_inputrec ir; t_block *excl; t_forcerec *fr; t_commrec *cr; t_mdatoms *mdatoms; t_graph *graph; int i,step,nre,natoms,nmol; rvec *x,*f_sr,*f_excl,*f_four,*f_pppm,*f_pois,box_size,hbox; matrix box; real t,lambda,vsr,*charge,*phi_f,*phi_pois,*phi_s,*phi_p3m,*rho; static bool bFour=FALSE,bVerbose=FALSE,bGGhat=FALSE,bPPPM=TRUE, bPoisson=FALSE,bOld=FALSE,bOldEwald=TRUE; static int nprocs = 1; static t_pargs pa[] = { { "-np", FALSE, etINT, &nprocs, "Do it in parallel" }, { "-ewald", FALSE, etBOOL, &bFour, "Do an Ewald solution"}, { "-pppm", FALSE, etBOOL, &bPPPM, "Do a PPPM solution" }, { "-poisson",FALSE, etBOOL, &bPoisson,"Do a Poisson solution" }, { "-v", FALSE, etBOOL, &bVerbose,"Verbose on"}, { "-ghat", FALSE, etBOOL, &bGGhat, "Generate Ghat function"}, { "-old", FALSE, etBOOL, &bOld, "Use old function types"}, { "-oldewald",FALSE,etBOOL, &bOldEwald,"Use old Ewald code"} }; CopyRight(stderr,argv[0]); parse_common_args(&argc,argv,PCA_CAN_TIME | PCA_CAN_VIEW, NFILE,fnm,asize(pa),pa,asize(desc),desc,0,NULL); if (nprocs > 1) { cr = init_par(&argc,argv); open_log(ftp2fn(efLOG,NFILE,fnm),cr); log = stdlog; } else { cr = init_par(&argc,argv); log = ftp2FILE(efLOG,NFILE,fnm,"w"); stdlog = log; } /* Read topology and coordinates */ read_tpxheader(ftp2fn(efTPX,NFILE,fnm),&stath,FALSE); snew(x,stath.natoms); snew(f_sr,stath.natoms); snew(f_excl,stath.natoms); snew(f_four,stath.natoms); snew(f_pppm,stath.natoms); snew(f_pois,stath.natoms); read_tpx(ftp2fn(efTPX,NFILE,fnm),&step,&t,&lambda,&ir, box,&natoms,x,NULL,NULL,&top); excl=&(top.atoms.excl); nmol=top.blocks[ebMOLS].nr; /* Allocate space for potential, charges and rho (charge density) */ snew(charge,stath.natoms); snew(phi_f,stath.natoms); snew(phi_p3m,stath.natoms); snew(phi_pois,stath.natoms); snew(phi_s,stath.natoms); snew(rho,stath.natoms); /* Set the charges */ for(i=0; (i<natoms); i++) charge[i]=top.atoms.atom[i].q; /* Make a simple box vector instead of tensor */ for(i=0; (i<DIM); i++) box_size[i]=box[i][i]; /* Set some constants */ fr = mk_forcerec(); mdatoms = atoms2md(&(top.atoms),FALSE,FALSE); set_LRconsts(log,ir.rcoulomb_switch,ir.rcoulomb,box_size,fr); init_forcerec(log,fr,&ir,&(top.blocks[ebMOLS]),cr, &(top.blocks[ebCGS]),&(top.idef),mdatoms,box,FALSE); calc_shifts(box,box_size,fr->shift_vec,FALSE); /* Periodicity stuff */ graph = mk_graph(&(top.idef),top.atoms.nr,FALSE,FALSE); shift_self(graph,fr->shift_vec,x); calc_LRcorrections(log,0,natoms,ir.rcoulomb_switch, ir.rcoulomb,charge,excl,x,f_excl,bOld); pr_f("f_excl.dat",natoms,f_excl); /* Compute the short range potential */ put_atoms_in_box(natoms,box,x); vsr=phi_sr(log,natoms,x,charge,ir.rcoulomb, ir.rcoulomb_switch,box_size,phi_s,excl,f_sr,bOld); pr_f("f_sr.dat",natoms,f_sr); /* Plot the short range potential in a matrix */ calc_ener(log,"Short Range",TRUE,nmol,natoms,phi_s,charge,excl); if (bFour) test_four(log,NFILE,fnm,&(top.atoms),&ir,x,f_four,box_size,charge,phi_f, phi_s,nmol,cr,bOld,bOldEwald); if (bPPPM) test_pppm(log,bVerbose,bGGhat,opt2fn("-g",NFILE,fnm), &(top.atoms),&ir,x,f_pppm,charge,box_size,phi_p3m,phi_s,nmol, cr,bOld,&(top.blocks[ebCGS])); if (bPoisson) test_poisson(log,bVerbose, &(top.atoms),&ir,x,f_pois,charge,box_size,phi_pois, phi_s,nmol,cr,bFour,f_four,phi_f,bOld); if (bPPPM && bFour) analyse_diff(log,"PPPM", top.atoms.nr,f_four,f_pppm,phi_f,phi_p3m,phi_s, opt2fn("-fcorr",NFILE,fnm), opt2fn("-pcorr",NFILE,fnm), opt2fn("-ftotcorr",NFILE,fnm), opt2fn("-ptotcorr",NFILE,fnm)); if (bPoisson && bFour) analyse_diff(log,"Poisson", top.atoms.nr,f_four,f_pois,phi_f,phi_pois,phi_s, opt2fn("-fcorr",NFILE,fnm), opt2fn("-pcorr",NFILE,fnm), opt2fn("-ftotcorr",NFILE,fnm), opt2fn("-ptotcorr",NFILE,fnm)); gmx_fio_fclose(log); thanx(stderr); return 0; }