2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5 * Copyright (c) 2001-2010, The GROMACS development team,
6 * check out http://www.gromacs.org for more information.
7 * Copyright (c) 2012, by the GROMACS development team, led by
8 * David van der Spoel, Berk Hess, Erik Lindahl, and including many
9 * others, as listed in the AUTHORS file in the top-level source
10 * directory and at http://www.gromacs.org.
12 * GROMACS is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public License
14 * as published by the Free Software Foundation; either version 2.1
15 * of the License, or (at your option) any later version.
17 * GROMACS is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with GROMACS; if not, see
24 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
25 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 * If you want to redistribute modifications to GROMACS, please
28 * consider that scientific software is very special. Version
29 * control is crucial - bugs must be traceable. We will be happy to
30 * consider code for inclusion in the official distribution, but
31 * derived work must not be called official GROMACS. Details are found
32 * in the README & COPYING files - if they are missing, get the
33 * official version at http://www.gromacs.org.
35 * To help us fund GROMACS development, we humbly ask that you cite
36 * the research papers on the package. Check out http://www.gromacs.org.
62 #include "md_support.h"
76 #include "mpelogging.h"
82 #include "compute_io.h"
84 #include "checkpoint.h"
85 #include "mtop_util.h"
86 #include "sighandler.h"
96 /* include even when OpenMM not used to force compilation of do_md_openmm */
97 #include "openmm_wrapper.h"
99 double do_md_openmm(FILE *fplog,t_commrec *cr,int nfile,const t_filenm fnm[],
100 const output_env_t oenv, gmx_bool bVerbose,gmx_bool bCompact,
102 gmx_vsite_t *vsite,gmx_constr_t constr,
103 int stepout,t_inputrec *ir,
104 gmx_mtop_t *top_global,
106 t_state *state_global,
108 t_nrnb *nrnb,gmx_wallcycle_t wcycle,
109 gmx_edsam_t ed,t_forcerec *fr,
110 int repl_ex_nst, int repl_ex_nex, int repl_ex_seed,
112 real cpt_period,real max_hours,
113 const char *deviceOptions,
115 gmx_runtime_t *runtime)
118 gmx_large_int_t step,step_rel;
122 bFirstStep,bStateFromTPX,bLastStep,bStartingFromCpt;
123 gmx_bool bInitStep=TRUE;
124 gmx_bool do_ene,do_log, do_verbose,
126 tensor force_vir,shake_vir,total_vir,pres;
138 gmx_enerdata_t *enerd;
140 gmx_global_stat_t gstat;
141 gmx_update_t upd=NULL;
145 gmx_groups_t *groups;
146 gmx_ekindata_t *ekind, *ekind_save;
150 real reset_counters=0,reset_counters_now=0;
151 char sbuf[STEPSTRSIZE],sbuf2[STEPSTRSIZE];
152 int handled_stop_condition=gmx_stop_cond_none;
154 const char *ommOptions = NULL;
158 /* Checks in cmake should prevent the compilation in double precision
159 * with OpenMM, but just to be sure we check here.
161 gmx_fatal(FARGS,"Compilation was performed in double precision, but OpenMM only supports single precision. If you want to use to OpenMM, compile in single precision.");
164 bAppend = (Flags & MD_APPENDFILES);
165 check_ir_old_tpx_versions(cr,fplog,ir,top_global);
167 groups = &top_global->groups;
170 init_md(fplog,cr,ir,oenv,&t,&t0,state_global->lambda,
171 &(state_global->fep_state),&lam0,
172 nrnb,top_global,&upd,
173 nfile,fnm,&outf,&mdebin,
174 force_vir,shake_vir,mu_tot,&bSimAnn,&vcm,state_global,Flags);
176 clear_mat(total_vir);
178 /* Energy terms and groups */
180 init_enerdata(top_global->groups.grps[egcENER].nr,ir->fepvals->n_lambda,
182 snew(f,top_global->natoms);
184 /* Kinetic energy data */
186 init_ekindata(fplog,top_global,&(ir->opts),ekind);
187 /* needed for iteration of constraints */
189 init_ekindata(fplog,top_global,&(ir->opts),ekind_save);
190 /* Copy the cos acceleration to the groups struct */
191 ekind->cosacc.cos_accel = ir->cos_accel;
193 gstat = global_stat_init(ir);
197 double io = compute_io(ir,top_global->natoms,groups,mdebin->ebin->nener,1);
198 if ((io > 2000) && MASTER(cr))
200 "\nWARNING: This run will generate roughly %.0f Mb of data\n\n",
204 top = gmx_mtop_generate_local_top(top_global,ir);
207 a1 = top_global->natoms;
209 state = partdec_init_local_state(cr,state_global);
212 atoms2md(top_global,ir,0,NULL,a0,a1-a0,mdatoms);
216 set_vsite_top(vsite,top,mdatoms,cr);
219 if (ir->ePBC != epbcNONE && !ir->bPeriodicMols)
221 graph = mk_graph(fplog,&(top->idef),0,top_global->natoms,FALSE,FALSE);
224 update_mdatoms(mdatoms,state->lambda[efptMASS]);
226 if (deviceOptions[0]=='\0')
228 /* empty options, which should default to OpenMM in this build */
229 ommOptions=deviceOptions;
233 if (gmx_strncasecmp(deviceOptions,"OpenMM",6)!=0)
235 gmx_fatal(FARGS, "This Gromacs version currently only works with OpenMM. Use -device \"OpenMM:<options>\"");
239 ommOptions=strchr(deviceOptions,':');
240 if (NULL!=ommOptions)
242 /* Increase the pointer to skip the colon */
248 openmmData = openmm_init(fplog, ommOptions, ir, top_global, top, mdatoms, fr, state);
249 please_cite(fplog,"Friedrichs2009");
253 /* Update mdebin with energy history if appending to output files */
254 if ( Flags & MD_APPENDFILES )
256 restore_energyhistory_from_state(mdebin,&state_global->enerhist);
258 /* Set the initial energy history in state to zero by updating once */
259 update_energyhistory(&state_global->enerhist,mdebin);
264 set_constraints(constr,top,ir,mdatoms,cr);
267 if (!ir->bContinuation)
269 if (mdatoms->cFREEZE && (state->flags & (1<<estV)))
271 /* Set the velocities of frozen particles to zero */
272 for (i=mdatoms->start; i<mdatoms->start+mdatoms->homenr; i++)
274 for (m=0; m<DIM; m++)
276 if (ir->opts.nFreeze[mdatoms->cFREEZE[i]][m])
286 /* Constrain the initial coordinates and velocities */
287 do_constrain_first(fplog,constr,ir,mdatoms,state,f,
288 graph,cr,nrnb,fr,top,shake_vir);
292 /* Construct the virtual sites for the initial configuration */
293 construct_vsites(fplog,vsite,state->x,nrnb,ir->delta_t,NULL,
294 top->idef.iparams,top->idef.il,
295 fr->ePBC,fr->bMolPBC,graph,cr,state->box);
304 fprintf(stderr,"starting mdrun '%s'\n",
305 *(top_global->name));
308 sprintf(tbuf,"%8.1f",(ir->init_step+ir->nsteps)*ir->delta_t);
312 sprintf(tbuf,"%s","infinite");
314 if (ir->init_step > 0)
316 fprintf(stderr,"%s steps, %s ps (continuing from step %s, %8.1f ps).\n",
317 gmx_step_str(ir->init_step+ir->nsteps,sbuf),tbuf,
318 gmx_step_str(ir->init_step,sbuf2),
319 ir->init_step*ir->delta_t);
323 fprintf(stderr,"%s steps, %s ps.\n",
324 gmx_step_str(ir->nsteps,sbuf),tbuf);
330 /* Set and write start time */
331 runtime_start(runtime);
332 print_date_and_time(fplog,cr->nodeid,"Started mdrun",runtime);
333 wallcycle_start(wcycle,ewcRUN);
337 /* safest point to do file checkpointing is here. More general point would be immediately before integrator call */
340 /***********************************************************
344 ************************************************************/
346 /* loop over MD steps or if rerunMD to end of input trajectory */
348 /* Skip the first Nose-Hoover integration when we get the state from tpx */
349 bStateFromTPX = !opt2bSet("-cpi",nfile,fnm);
350 bInitStep = bFirstStep && bStateFromTPX;
351 bStartingFromCpt = (Flags & MD_STARTFROMCPT) && bInitStep;
354 init_global_signals(&gs,cr,ir,repl_ex_nst);
356 step = ir->init_step;
361 wallcycle_start(wcycle,ewcSTEP);
363 GMX_MPE_LOG(ev_timestep1);
365 bLastStep = (step_rel == ir->nsteps);
366 t = t0 + step*ir->delta_t;
368 if (gs.set[eglsSTOPCOND] != 0)
373 do_log = do_per_step(step,ir->nstlog) || bFirstStep || bLastStep;
374 do_verbose = bVerbose &&
375 (step % stepout == 0 || bFirstStep || bLastStep);
377 if (MASTER(cr) && do_log)
379 print_ebin_header(fplog,step,t,state->lambda[efptFEP]);
382 clear_mat(force_vir);
383 GMX_MPE_LOG(ev_timestep2);
385 /* We write a checkpoint at this MD step when:
386 * either when we signalled through gs (in OpenMM NS works different),
387 * or at the last step (but not when we do not want confout),
388 * but never at the first step.
390 bCPT = ((gs.set[eglsCHKPT] ||
391 (bLastStep && (Flags & MD_CONFOUT))) &&
392 step > ir->init_step );
395 gs.set[eglsCHKPT] = 0;
398 /* Now we have the energies and forces corresponding to the
399 * coordinates at time t. We must output all of this before
401 * for RerunMD t is read from input trajectory
403 GMX_MPE_LOG(ev_output_start);
406 if (do_per_step(step,ir->nstxout))
408 mdof_flags |= MDOF_X;
410 if (do_per_step(step,ir->nstvout))
412 mdof_flags |= MDOF_V;
414 if (do_per_step(step,ir->nstfout))
416 mdof_flags |= MDOF_F;
418 if (do_per_step(step,ir->nstxtcout))
420 mdof_flags |= MDOF_XTC;
424 mdof_flags |= MDOF_CPT;
426 do_ene = (do_per_step(step,ir->nstenergy) || bLastStep);
428 if (mdof_flags != 0 || do_ene || do_log)
430 wallcycle_start(wcycle,ewcTRAJ);
431 bF = (mdof_flags & MDOF_F);
432 bX = (mdof_flags & (MDOF_X | MDOF_XTC | MDOF_CPT));
433 bV = (mdof_flags & (MDOF_V | MDOF_CPT));
435 openmm_copy_state(openmmData, state, &t, f, enerd, bX, bV, bF, do_ene);
437 upd_mdebin(mdebin,FALSE,TRUE,
438 t,mdatoms->tmass,enerd,state,ir->fepvals,ir->expandedvals,lastbox,
439 shake_vir,force_vir,total_vir,pres,
440 ekind,mu_tot,constr);
441 print_ebin(outf->fp_ene,do_ene,FALSE,FALSE,do_log?fplog:NULL,
443 eprNORMAL,bCompact,mdebin,fcd,groups,&(ir->opts));
444 write_traj(fplog,cr,outf,mdof_flags,top_global,
445 step,t,state,state_global,f,f_global,&n_xtc,&x_xtc);
452 if (bLastStep && step_rel == ir->nsteps &&
453 (Flags & MD_CONFOUT) && MASTER(cr))
455 /* x and v have been collected in write_traj,
456 * because a checkpoint file will always be written
459 fprintf(stderr,"\nWriting final coordinates.\n");
460 if (ir->ePBC != epbcNONE && !ir->bPeriodicMols)
462 /* Make molecules whole only for confout writing */
463 do_pbc_mtop(fplog,ir->ePBC,state->box,top_global,state_global->x);
465 write_sto_conf_mtop(ftp2fn(efSTO,nfile,fnm),
466 *top_global->name,top_global,
467 state_global->x,state_global->v,
468 ir->ePBC,state->box);
471 wallcycle_stop(wcycle,ewcTRAJ);
473 GMX_MPE_LOG(ev_output_finish);
476 /* Determine the wallclock run time up till now */
477 run_time = gmx_gettime() - (double)runtime->real;
479 /* Check whether everything is still allright */
480 if (((int)gmx_get_stop_condition() > handled_stop_condition)
481 #ifdef GMX_THREAD_MPI
486 /* this is just make gs.sig compatible with the hack
487 of sending signals around by MPI_Reduce with together with
489 /* NOTE: this only works for serial code. For code that allows
490 MPI nodes to propagate their condition, see kernel/md.c*/
491 if ( gmx_get_stop_condition() == gmx_stop_cond_next_ns )
492 gs.set[eglsSTOPCOND]=1;
493 if ( gmx_get_stop_condition() == gmx_stop_cond_next )
494 gs.set[eglsSTOPCOND]=1;
495 /* < 0 means stop at next step, > 0 means stop at next NS step */
499 "\n\nReceived the %s signal, stopping at the next %sstep\n\n",
500 gmx_get_signal_name(),
501 gs.sig[eglsSTOPCOND]==1 ? "NS " : "");
505 "\n\nReceived the %s signal, stopping at the next %sstep\n\n",
506 gmx_get_signal_name(),
507 gs.sig[eglsSTOPCOND]==1 ? "NS " : "");
509 handled_stop_condition=(int)gmx_get_stop_condition();
511 else if (MASTER(cr) &&
512 (max_hours > 0 && run_time > max_hours*60.0*60.0*0.99) &&
513 gs.set[eglsSTOPCOND] == 0)
515 /* Signal to terminate the run */
516 gs.set[eglsSTOPCOND] = 1;
519 fprintf(fplog,"\nStep %s: Run time exceeded %.3f hours, will terminate the run\n",gmx_step_str(step,sbuf),max_hours*0.99);
521 fprintf(stderr, "\nStep %s: Run time exceeded %.3f hours, will terminate the run\n",gmx_step_str(step,sbuf),max_hours*0.99);
525 if (MASTER(cr) && (cpt_period >= 0 &&
527 run_time >= nchkpt*cpt_period*60.0)) &&
528 gs.set[eglsCHKPT] == 0)
530 gs.set[eglsCHKPT] = 1;
533 /* Time for performance */
534 if (((step % stepout) == 0) || bLastStep)
536 runtime_upd_proc(runtime);
539 if (do_per_step(step,ir->nstlog))
541 if (fflush(fplog) != 0)
543 gmx_fatal(FARGS,"Cannot flush logfile - maybe you are out of disk space?");
547 /* Remaining runtime */
548 if (MULTIMASTER(cr) && (do_verbose || gmx_got_usr_signal() ))
550 print_time(stderr,runtime,step,ir,cr);
555 bStartingFromCpt = FALSE;
559 openmm_take_one_step(openmmData);
561 /* End of main MD loop */
565 runtime_end(runtime);
569 if (ir->nstcalcenergy > 0)
571 print_ebin(outf->fp_ene,FALSE,FALSE,FALSE,fplog,step,t,
572 eprAVER,FALSE,mdebin,fcd,groups,&(ir->opts));
576 openmm_cleanup(fplog, openmmData);
582 runtime->nsteps_done = step_rel;