1 /* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
4 * This source code is part of
8 * GROningen MAchine for Chemical Simulations
10 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
11 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
12 * Copyright (c) 2001-2010, The GROMACS development team,
13 * check out http://www.gromacs.org for more information.
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
20 * If you want to redistribute modifications, please consider that
21 * scientific software is very special. Version control is crucial -
22 * bugs must be traceable. We will be happy to consider code for
23 * inclusion in the official distribution, but derived work must not
24 * be called official GROMACS. Details are found in the README & COPYING
25 * files - if they are missing, get the official version at www.gromacs.org.
27 * To help us fund GROMACS development, we humbly ask that you cite
28 * the papers on the package - you can find them in the top README file.
30 * For more info, check our website at http://www.gromacs.org
33 * Gallium Rubidium Oxygen Manganese Argon Carbon Silicon
43 #if ((defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64) && !defined __CYGWIN__ && !defined __CYGWIN32__)
79 #include "mpelogging.h"
85 #include "compute_io.h"
87 #include "checkpoint.h"
88 #include "mtop_util.h"
89 #include "sighandler.h"
93 #include "gmx_membed.h"
99 /* include even when OpenMM not used to force compilation of do_md_openmm */
100 #include "openmm_wrapper.h"
102 /* simulation conditions to transmit */
103 enum { eglsNABNSB
, eglsCHKPT
, eglsSTOPCOND
, eglsRESETCOUNTERS
, eglsNR
};
107 int nstms
; /* The frequency for intersimulation communication */
108 int sig
[eglsNR
]; /* The signal set by one process in do_md */
109 int set
[eglsNR
]; /* The communicated signal, equal for all processes */
113 static int multisim_min(const gmx_multisim_t
*ms
,int nmin
,int n
)
116 gmx_bool bPos
,bEqual
;
121 gmx_sumi_sim(ms
->nsim
,buf
,ms
);
124 for (s
=0; s
<ms
->nsim
; s
++)
126 bPos
= bPos
&& (buf
[s
] > 0);
127 bEqual
= bEqual
&& (buf
[s
] == buf
[0]);
133 nmin
= min(nmin
,buf
[0]);
137 /* Find the least common multiple */
138 for (d
=2; d
<nmin
; d
++)
141 while (s
< ms
->nsim
&& d
% buf
[s
] == 0)
147 /* We found the LCM and it is less than nmin */
159 static int multisim_nstsimsync(const t_commrec
*cr
,
160 const t_inputrec
*ir
,int repl_ex_nst
)
167 nmin
= multisim_min(cr
->ms
,nmin
,ir
->nstlist
);
168 nmin
= multisim_min(cr
->ms
,nmin
,ir
->nstcalcenergy
);
169 nmin
= multisim_min(cr
->ms
,nmin
,repl_ex_nst
);
172 gmx_fatal(FARGS
,"Can not find an appropriate interval for inter-simulation communication, since nstlist, nstcalcenergy and -replex are all <= 0");
174 /* Avoid inter-simulation communication at every (second) step */
181 gmx_bcast(sizeof(int),&nmin
,cr
);
186 static void init_global_signals(globsig_t
*gs
,const t_commrec
*cr
,
187 const t_inputrec
*ir
,int repl_ex_nst
)
193 for (i
=0; i
<eglsNR
; i
++)
201 double do_md_openmm(FILE *fplog
,t_commrec
*cr
,int nfile
,const t_filenm fnm
[],
202 const output_env_t oenv
, gmx_bool bVerbose
,gmx_bool bCompact
,
204 gmx_vsite_t
*vsite
,gmx_constr_t constr
,
205 int stepout
,t_inputrec
*ir
,
206 gmx_mtop_t
*top_global
,
208 t_state
*state_global
,
210 t_nrnb
*nrnb
,gmx_wallcycle_t wcycle
,
211 gmx_edsam_t ed
,t_forcerec
*fr
,
212 int repl_ex_nst
,int repl_ex_seed
,
213 gmx_membed_t
*membed
,
214 real cpt_period
,real max_hours
,
215 const char *deviceOptions
,
217 gmx_runtime_t
*runtime
)
220 gmx_large_int_t step
,step_rel
;
224 bFirstStep
,bStateFromTPX
,bLastStep
,bStartingFromCpt
;
225 gmx_bool bInitStep
=TRUE
;
226 gmx_bool do_ene
,do_log
, do_verbose
,
228 tensor force_vir
,shake_vir
,total_vir
,pres
;
235 t_mdebin
*mdebin
=NULL
;
240 gmx_enerdata_t
*enerd
;
242 gmx_global_stat_t gstat
;
243 gmx_update_t upd
=NULL
;
247 gmx_groups_t
*groups
;
248 gmx_ekindata_t
*ekind
, *ekind_save
;
252 real reset_counters
=0,reset_counters_now
=0;
253 char sbuf
[STEPSTRSIZE
],sbuf2
[STEPSTRSIZE
];
254 int handled_stop_condition
=gmx_stop_cond_none
;
256 const char *ommOptions
= NULL
;
259 bAppend
= (Flags
& MD_APPENDFILES
);
260 check_ir_old_tpx_versions(cr
,fplog
,ir
,top_global
);
262 groups
= &top_global
->groups
;
265 init_md(fplog
,cr
,ir
,oenv
,&t
,&t0
,&state_global
->lambda
,&lam0
,
266 nrnb
,top_global
,&upd
,
267 nfile
,fnm
,&outf
,&mdebin
,
268 force_vir
,shake_vir
,mu_tot
,&bSimAnn
,&vcm
,state_global
,Flags
);
270 clear_mat(total_vir
);
272 /* Energy terms and groups */
274 init_enerdata(top_global
->groups
.grps
[egcENER
].nr
,ir
->n_flambda
,enerd
);
275 snew(f
,top_global
->natoms
);
277 /* Kinetic energy data */
279 init_ekindata(fplog
,top_global
,&(ir
->opts
),ekind
);
280 /* needed for iteration of constraints */
282 init_ekindata(fplog
,top_global
,&(ir
->opts
),ekind_save
);
283 /* Copy the cos acceleration to the groups struct */
284 ekind
->cosacc
.cos_accel
= ir
->cos_accel
;
286 gstat
= global_stat_init(ir
);
290 double io
= compute_io(ir
,top_global
->natoms
,groups
,mdebin
->ebin
->nener
,1);
291 if ((io
> 2000) && MASTER(cr
))
293 "\nWARNING: This run will generate roughly %.0f Mb of data\n\n",
297 top
= gmx_mtop_generate_local_top(top_global
,ir
);
300 a1
= top_global
->natoms
;
302 state
= partdec_init_local_state(cr
,state_global
);
305 atoms2md(top_global
,ir
,0,NULL
,a0
,a1
-a0
,mdatoms
);
309 set_vsite_top(vsite
,top
,mdatoms
,cr
);
312 if (ir
->ePBC
!= epbcNONE
&& !ir
->bPeriodicMols
)
314 graph
= mk_graph(fplog
,&(top
->idef
),0,top_global
->natoms
,FALSE
,FALSE
);
317 update_mdatoms(mdatoms
,state
->lambda
);
319 if (deviceOptions
[0]=='\0')
321 /* empty options, which should default to OpenMM in this build */
322 ommOptions
=deviceOptions
;
326 if (gmx_strncasecmp(deviceOptions
,"OpenMM",6)!=0)
328 gmx_fatal(FARGS
, "This Gromacs version currently only works with OpenMM. Use -device \"OpenMM:<options>\"");
332 ommOptions
=strchr(deviceOptions
,':');
333 if (NULL
!=ommOptions
)
335 /* Increase the pointer to skip the colon */
341 openmmData
= openmm_init(fplog
, ommOptions
, ir
, top_global
, top
, mdatoms
, fr
, state
);
342 please_cite(fplog
,"Friedrichs2009");
346 /* Update mdebin with energy history if appending to output files */
347 if ( Flags
& MD_APPENDFILES
)
349 restore_energyhistory_from_state(mdebin
,&state_global
->enerhist
);
351 /* Set the initial energy history in state to zero by updating once */
352 update_energyhistory(&state_global
->enerhist
,mdebin
);
357 set_constraints(constr
,top
,ir
,mdatoms
,cr
);
360 if (!ir
->bContinuation
)
362 if (mdatoms
->cFREEZE
&& (state
->flags
& (1<<estV
)))
364 /* Set the velocities of frozen particles to zero */
365 for (i
=mdatoms
->start
; i
<mdatoms
->start
+mdatoms
->homenr
; i
++)
367 for (m
=0; m
<DIM
; m
++)
369 if (ir
->opts
.nFreeze
[mdatoms
->cFREEZE
[i
]][m
])
379 /* Constrain the initial coordinates and velocities */
380 do_constrain_first(fplog
,constr
,ir
,mdatoms
,state
,f
,
381 graph
,cr
,nrnb
,fr
,top
,shake_vir
);
385 /* Construct the virtual sites for the initial configuration */
386 construct_vsites(fplog
,vsite
,state
->x
,nrnb
,ir
->delta_t
,NULL
,
387 top
->idef
.iparams
,top
->idef
.il
,
388 fr
->ePBC
,fr
->bMolPBC
,graph
,cr
,state
->box
);
397 fprintf(fplog
,"Initial temperature: %g K\n",enerd
->term
[F_TEMP
]);
398 fprintf(stderr
,"starting mdrun '%s'\n",
399 *(top_global
->name
));
402 sprintf(tbuf
,"%8.1f",(ir
->init_step
+ir
->nsteps
)*ir
->delta_t
);
406 sprintf(tbuf
,"%s","infinite");
408 if (ir
->init_step
> 0)
410 fprintf(stderr
,"%s steps, %s ps (continuing from step %s, %8.1f ps).\n",
411 gmx_step_str(ir
->init_step
+ir
->nsteps
,sbuf
),tbuf
,
412 gmx_step_str(ir
->init_step
,sbuf2
),
413 ir
->init_step
*ir
->delta_t
);
417 fprintf(stderr
,"%s steps, %s ps.\n",
418 gmx_step_str(ir
->nsteps
,sbuf
),tbuf
);
424 /* Set and write start time */
425 runtime_start(runtime
);
426 print_date_and_time(fplog
,cr
->nodeid
,"Started mdrun",runtime
);
427 wallcycle_start(wcycle
,ewcRUN
);
431 /* safest point to do file checkpointing is here. More general point would be immediately before integrator call */
434 /***********************************************************
438 ************************************************************/
440 /* loop over MD steps or if rerunMD to end of input trajectory */
442 /* Skip the first Nose-Hoover integration when we get the state from tpx */
443 bStateFromTPX
= !opt2bSet("-cpi",nfile
,fnm
);
444 bInitStep
= bFirstStep
&& bStateFromTPX
;
445 bStartingFromCpt
= (Flags
& MD_STARTFROMCPT
) && bInitStep
;
448 init_global_signals(&gs
,cr
,ir
,repl_ex_nst
);
450 step
= ir
->init_step
;
455 wallcycle_start(wcycle
,ewcSTEP
);
457 GMX_MPE_LOG(ev_timestep1
);
459 bLastStep
= (step_rel
== ir
->nsteps
);
460 t
= t0
+ step
*ir
->delta_t
;
462 if (gs
.set
[eglsSTOPCOND
] != 0)
467 do_log
= do_per_step(step
,ir
->nstlog
) || bFirstStep
|| bLastStep
;
468 do_verbose
= bVerbose
&&
469 (step
% stepout
== 0 || bFirstStep
|| bLastStep
);
471 if (MASTER(cr
) && do_log
)
473 print_ebin_header(fplog
,step
,t
,state
->lambda
);
476 clear_mat(force_vir
);
477 GMX_MPE_LOG(ev_timestep2
);
479 /* We write a checkpoint at this MD step when:
480 * either when we signalled through gs (in OpenMM NS works different),
481 * or at the last step (but not when we do not want confout),
482 * but never at the first step.
484 bCPT
= ((gs
.set
[eglsCHKPT
] ||
485 (bLastStep
&& (Flags
& MD_CONFOUT
))) &&
486 step
> ir
->init_step
);
489 gs
.set
[eglsCHKPT
] = 0;
492 /* Now we have the energies and forces corresponding to the
493 * coordinates at time t. We must output all of this before
495 * for RerunMD t is read from input trajectory
497 GMX_MPE_LOG(ev_output_start
);
500 if (do_per_step(step
,ir
->nstxout
))
502 mdof_flags
|= MDOF_X
;
504 if (do_per_step(step
,ir
->nstvout
))
506 mdof_flags
|= MDOF_V
;
508 if (do_per_step(step
,ir
->nstfout
))
510 mdof_flags
|= MDOF_F
;
512 if (do_per_step(step
,ir
->nstxtcout
))
514 mdof_flags
|= MDOF_XTC
;
518 mdof_flags
|= MDOF_CPT
;
520 do_ene
= (do_per_step(step
,ir
->nstenergy
) || bLastStep
);
522 if (mdof_flags
!= 0 || do_ene
|| do_log
)
524 wallcycle_start(wcycle
,ewcTRAJ
);
525 bF
= (mdof_flags
& MDOF_F
);
526 bX
= (mdof_flags
& (MDOF_X
| MDOF_XTC
| MDOF_CPT
));
527 bV
= (mdof_flags
& (MDOF_V
| MDOF_CPT
));
529 openmm_copy_state(openmmData
, state
, &t
, f
, enerd
, bX
, bV
, bF
, do_ene
);
531 upd_mdebin(mdebin
, FALSE
,TRUE
,
532 t
,mdatoms
->tmass
,enerd
,state
,lastbox
,
533 shake_vir
,force_vir
,total_vir
,pres
,
534 ekind
,mu_tot
,constr
);
535 print_ebin(outf
->fp_ene
,do_ene
,FALSE
,FALSE
,do_log
?fplog
:NULL
,
537 eprNORMAL
,bCompact
,mdebin
,fcd
,groups
,&(ir
->opts
));
538 write_traj(fplog
,cr
,outf
,mdof_flags
,top_global
,
539 step
,t
,state
,state_global
,f
,f_global
,&n_xtc
,&x_xtc
);
546 if (bLastStep
&& step_rel
== ir
->nsteps
&&
547 (Flags
& MD_CONFOUT
) && MASTER(cr
))
549 /* x and v have been collected in write_traj,
550 * because a checkpoint file will always be written
553 fprintf(stderr
,"\nWriting final coordinates.\n");
554 if (ir
->ePBC
!= epbcNONE
&& !ir
->bPeriodicMols
)
556 /* Make molecules whole only for confout writing */
557 do_pbc_mtop(fplog
,ir
->ePBC
,state
->box
,top_global
,state_global
->x
);
559 write_sto_conf_mtop(ftp2fn(efSTO
,nfile
,fnm
),
560 *top_global
->name
,top_global
,
561 state_global
->x
,state_global
->v
,
562 ir
->ePBC
,state
->box
);
565 wallcycle_stop(wcycle
,ewcTRAJ
);
567 GMX_MPE_LOG(ev_output_finish
);
570 /* Determine the wallclock run time up till now */
571 run_time
= gmx_gettime() - (double)runtime
->real
;
573 /* Check whether everything is still allright */
574 if (((int)gmx_get_stop_condition() > handled_stop_condition
)
580 /* this is just make gs.sig compatible with the hack
581 of sending signals around by MPI_Reduce with together with
583 /* NOTE: this only works for serial code. For code that allows
584 MPI nodes to propagate their condition, see kernel/md.c*/
585 if ( gmx_get_stop_condition() == gmx_stop_cond_next_ns
)
586 gs
.set
[eglsSTOPCOND
]=1;
587 if ( gmx_get_stop_condition() == gmx_stop_cond_next
)
588 gs
.set
[eglsSTOPCOND
]=1;
589 /* < 0 means stop at next step, > 0 means stop at next NS step */
593 "\n\nReceived the %s signal, stopping at the next %sstep\n\n",
594 gmx_get_signal_name(),
595 gs
.sig
[eglsSTOPCOND
]==1 ? "NS " : "");
599 "\n\nReceived the %s signal, stopping at the next %sstep\n\n",
600 gmx_get_signal_name(),
601 gs
.sig
[eglsSTOPCOND
]==1 ? "NS " : "");
603 handled_stop_condition
=(int)gmx_get_stop_condition();
605 else if (MASTER(cr
) &&
606 (max_hours
> 0 && run_time
> max_hours
*60.0*60.0*0.99) &&
607 gs
.set
[eglsSTOPCOND
] == 0)
609 /* Signal to terminate the run */
610 gs
.set
[eglsSTOPCOND
] = 1;
613 fprintf(fplog
,"\nStep %s: Run time exceeded %.3f hours, will terminate the run\n",gmx_step_str(step
,sbuf
),max_hours
*0.99);
615 fprintf(stderr
, "\nStep %s: Run time exceeded %.3f hours, will terminate the run\n",gmx_step_str(step
,sbuf
),max_hours
*0.99);
619 if (MASTER(cr
) && (cpt_period
>= 0 &&
621 run_time
>= nchkpt
*cpt_period
*60.0)) &&
622 gs
.set
[eglsCHKPT
] == 0)
624 gs
.set
[eglsCHKPT
] = 1;
627 /* Time for performance */
628 if (((step
% stepout
) == 0) || bLastStep
)
630 runtime_upd_proc(runtime
);
633 if (do_per_step(step
,ir
->nstlog
))
635 if (fflush(fplog
) != 0)
637 gmx_fatal(FARGS
,"Cannot flush logfile - maybe you are out of quota?");
641 /* Remaining runtime */
642 if (MULTIMASTER(cr
) && (do_verbose
|| gmx_got_usr_signal() ))
644 print_time(stderr
,runtime
,step
,ir
,cr
);
649 bStartingFromCpt
= FALSE
;
653 openmm_take_one_step(openmmData
);
655 /* End of main MD loop */
659 runtime_end(runtime
);
663 if (ir
->nstcalcenergy
> 0)
665 print_ebin(outf
->fp_ene
,FALSE
,FALSE
,FALSE
,fplog
,step
,t
,
666 eprAVER
,FALSE
,mdebin
,fcd
,groups
,&(ir
->opts
));
670 openmm_cleanup(fplog
, openmmData
);
676 runtime
->nsteps_done
= step_rel
;