8 #if ((defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64) && !defined __CYGWIN__ && !defined __CYGWIN32__)
45 #include "mpelogging.h"
52 #include "compute_io.h"
54 #include "checkpoint.h"
55 #include "mtop_util.h"
64 #include "openmm_wrapper.h"
67 double do_md_openmm(FILE *fplog
,t_commrec
*cr
,int nfile
,const t_filenm fnm
[],
68 const output_env_t oenv
, bool bVerbose
,bool bCompact
,
70 gmx_vsite_t
*vsite
,gmx_constr_t constr
,
71 int stepout
,t_inputrec
*ir
,
72 gmx_mtop_t
*top_global
,
74 t_state
*state_global
,
76 t_nrnb
*nrnb
,gmx_wallcycle_t wcycle
,
77 gmx_edsam_t ed
,t_forcerec
*fr
,
78 int repl_ex_nst
,int repl_ex_seed
,
79 real cpt_period
,real max_hours
,
80 const char *deviceOptions
,
82 gmx_runtime_t
*runtime
)
84 int fp_trn
=0,fp_xtc
=0;
85 ener_file_t fp_ene
=NULL
;
86 gmx_large_int_t step
,step_rel
;
88 FILE *fp_dhdl
=NULL
,*fp_field
=NULL
;
91 bool bGStatEveryStep
,bGStat
,bNstEner
,bCalcPres
,bCalcEner
;
92 bool bNS
,bNStList
,bSimAnn
,bStopCM
,bRerunMD
,bNotLastFrame
=FALSE
,
93 bFirstStep
,bStateFromTPX
,bInitStep
,bLastStep
,
94 bBornRadii
,bStartingFromCpt
;
96 bool bNEMD
,do_ene
,do_log
,do_verbose
,bRerunWarnNoV
=TRUE
,
97 bForceUpdate
=FALSE
,bX
,bV
,bF
,bXTC
,bCPT
=FALSE
;
99 int force_flags
,cglo_flags
;
100 tensor force_vir
,shake_vir
,total_vir
,tmp_vir
,pres
;
104 t_state
*bufstate
=NULL
;
105 matrix
*scale_tot
,pcoupl_mu
,M
,ebox
;
108 gmx_repl_ex_t repl_ex
=NULL
;
110 /* Booleans (disguised as a reals) to checkpoint and terminate mdrun */
111 real chkpt
=0,terminate
=0,terminate_now
=0;
114 t_mdebin
*mdebin
=NULL
;
119 gmx_enerdata_t
*enerd
;
121 gmx_global_stat_t gstat
;
122 gmx_update_t upd
=NULL
;
126 gmx_groups_t
*groups
;
127 gmx_ekindata_t
*ekind
, *ekind_save
;
128 gmx_shellfc_t shellfc
;
129 int count
,nconverged
=0;
133 bool bTCR
=FALSE
,bConverged
=TRUE
,bOK
,bSumEkinhOld
,bExchanged
;
135 bool bResetCountersHalfMaxH
=FALSE
;
136 bool bVV
,bIterations
,bIterate
,bFirstIterate
,bTemp
,bPres
,bTrotter
;
137 real temp0
,mu_aver
=0,dvdl
;
139 atom_id
*grpindex
=NULL
;
141 t_coupl_rec
*tcr
=NULL
;
142 rvec
*xcopy
=NULL
,*vcopy
=NULL
,*cbuf
=NULL
;
143 matrix boxcopy
={{0}},lastbox
;
145 real fom
,oldfom
,veta_save
,pcurr
,scalevir
,tracevir
;
148 real reset_counters
=0,reset_counters_now
=0;
149 real last_conserved
= 0;
154 char sbuf
[22],sbuf2
[22];
155 bool bHandledSignal
=FALSE
;
156 // gmx_iterate_t iterate;
158 const char *ommOptions
= NULL
;
161 /* Check for special mdrun options */
162 bRerunMD
= (Flags
& MD_RERUN
);
163 bIonize
= (Flags
& MD_IONIZE
);
164 bFFscan
= (Flags
& MD_FFSCAN
);
165 bAppend
= (Flags
& MD_APPENDFILES
);
166 if (Flags
& MD_RESETCOUNTERSHALFWAY
)
170 /* Signal to reset the counters half the simulation steps. */
171 wcycle_set_reset_counters(wcycle
,ir
->nsteps
/2);
173 /* Signal to reset the counters halfway the simulation time. */
174 bResetCountersHalfMaxH
= (max_hours
> 0);
177 /* md-vv uses averaged full step velocities for T-control
178 md-vv2 uses averaged half step velocities for T-control (but full step ekin for P control)
179 md uses averaged half step kinetic energies to determine temperature unless defined otherwise by GMX_EKIN_AVE_VEL; */
181 if (bVV
) /* to store the initial velocities while computing virial */
183 snew(cbuf
,top_global
->natoms
);
185 /* all the iteratative cases - only if there are constraints */
186 bIterations
= ((IR_NPT_TROTTER(ir
)) && (constr
) && (!bRerunMD
));
187 bTrotter
= (bVV
&& (IR_NPT_TROTTER(ir
) || (IR_NVT_TROTTER(ir
))));
191 /* Since we don't know if the frames read are related in any way,
192 * rebuild the neighborlist at every step.
195 ir
->nstcalcenergy
= 1;
199 check_ir_old_tpx_versions(cr
,fplog
,ir
,top_global
);
201 //**** nstglobalcomm = check_nstglobalcomm(fplog,cr,nstglobalcomm,ir);
202 bGStatEveryStep
= (nstglobalcomm
== 1);
204 if (!bGStatEveryStep
&& ir
->nstlist
== -1 && fplog
!= NULL
)
207 "To reduce the energy communication with nstlist = -1\n"
208 "the neighbor list validity should not be checked at every step,\n"
209 "this means that exact integration is not guaranteed.\n"
210 "The neighbor list validity is checked after:\n"
211 " <n.list life time> - 2*std.dev.(n.list life time) steps.\n"
212 "In most cases this will result in exact integration.\n"
213 "This reduces the energy communication by a factor of 2 to 3.\n"
214 "If you want less energy communication, set nstlist > 3.\n\n");
217 if (bRerunMD
|| bFFscan
)
221 groups
= &top_global
->groups
;
224 init_md(fplog
,cr
,ir
,oenv
,&t
,&t0
,&state_global
->lambda
,&lam0
,
225 nrnb
,top_global
,&upd
,
226 nfile
,fnm
,&fp_trn
,&fp_xtc
,&fp_ene
,&fn_cpt
,
227 &fp_dhdl
,&fp_field
,&mdebin
,
228 force_vir
,shake_vir
,mu_tot
,&bNEMD
,&bSimAnn
,&vcm
,state_global
,Flags
);
230 clear_mat(total_vir
);
232 /* Energy terms and groups */
234 init_enerdata(top_global
->groups
.grps
[egcENER
].nr
,ir
->n_flambda
,enerd
);
235 if (DOMAINDECOMP(cr
))
241 snew(f
,top_global
->natoms
);
244 /* Kinetic energy data */
246 init_ekindata(fplog
,top_global
,&(ir
->opts
),ekind
);
247 /* needed for iteration of constraints */
249 init_ekindata(fplog
,top_global
,&(ir
->opts
),ekind_save
);
250 /* Copy the cos acceleration to the groups struct */
251 ekind
->cosacc
.cos_accel
= ir
->cos_accel
;
253 gstat
= global_stat_init(ir
);
256 /* Check for polarizable models and flexible constraints */
257 shellfc
= init_shell_flexcon(fplog
,
258 top_global
,n_flexible_constraints(constr
),
259 (ir
->bContinuation
||
260 (DOMAINDECOMP(cr
) && !MASTER(cr
))) ?
261 NULL
: state_global
->x
);
266 tMPI_Thread_mutex_lock(&deform_init_box_mutex
);
268 set_deform_reference_box(upd
,
269 deform_init_init_step_tpx
,
270 deform_init_box_tpx
);
272 tMPI_Thread_mutex_unlock(&deform_init_box_mutex
);
277 double io
= compute_io(ir
,top_global
->natoms
,groups
,mdebin
->ebin
->nener
,1);
278 if ((io
> 2000) && MASTER(cr
))
280 "\nWARNING: This run will generate roughly %.0f Mb of data\n\n",
284 if (DOMAINDECOMP(cr
)) {
285 top
= dd_init_local_top(top_global
);
288 dd_init_local_state(cr
->dd
,state_global
,state
);
290 if (DDMASTER(cr
->dd
) && ir
->nstfout
) {
291 snew(f_global
,state_global
->natoms
);
295 /* Initialize the particle decomposition and split the topology */
296 top
= split_system(fplog
,top_global
,ir
,cr
);
298 pd_cg_range(cr
,&fr
->cg0
,&fr
->hcg
);
299 pd_at_range(cr
,&a0
,&a1
);
301 top
= gmx_mtop_generate_local_top(top_global
,ir
);
304 a1
= top_global
->natoms
;
307 state
= partdec_init_local_state(cr
,state_global
);
310 atoms2md(top_global
,ir
,0,NULL
,a0
,a1
-a0
,mdatoms
);
313 set_vsite_top(vsite
,top
,mdatoms
,cr
);
316 if (ir
->ePBC
!= epbcNONE
&& !ir
->bPeriodicMols
) {
317 graph
= mk_graph(fplog
,&(top
->idef
),0,top_global
->natoms
,FALSE
,FALSE
);
321 make_local_shells(cr
,mdatoms
,shellfc
);
324 if (ir
->pull
&& PAR(cr
)) {
325 dd_make_local_pull_groups(NULL
,ir
->pull
,mdatoms
);
329 if (DOMAINDECOMP(cr
))
331 /* Distribute the charge groups over the nodes from the master node */
332 dd_partition_system(fplog
,ir
->init_step
,cr
,TRUE
,1,
333 state_global
,top_global
,ir
,
334 state
,&f
,mdatoms
,top
,fr
,
335 vsite
,shellfc
,constr
,
339 /* If not DD, copy gb data */
340 if(ir
->implicit_solvent
&& !DOMAINDECOMP(cr
))
342 make_local_gb(cr
,fr
->born
,ir
->gb_algorithm
);
345 update_mdatoms(mdatoms
,state
->lambda
);
348 if(deviceOptions
[0]=='\0')
350 /* empty options, which should default to OpenMM in this build */
351 ommOptions
=deviceOptions
;
355 if(gmx_strncasecmp(deviceOptions
,"OpenMM",6)!=0)
357 gmx_fatal(FARGS
, "This Gromacs version currently only works with OpenMM. Use -device \"OpenMM:<options>\"");
361 ommOptions
=strchr(deviceOptions
,':');
364 /* Increase the pointer to skip the colon */
369 openmmData
= openmm_init(fplog
, ommOptions
, cr
, ir
, top_global
, top
, mdatoms
, fr
, state
);
374 /* Update mdebin with energy history if appending to output files */
375 if ( Flags
& MD_APPENDFILES
)
377 restore_energyhistory_from_state(mdebin
,&state_global
->enerhist
);
379 /* Set the initial energy history in state to zero by updating once */
380 update_energyhistory(&state_global
->enerhist
,mdebin
);
383 if ((state
->flags
& (1<<estLD_RNG
)) && (Flags
& MD_READ_RNG
)) {
384 /* Set the random state if we read a checkpoint file */
385 set_stochd_state(upd
,state
);
388 /* Initialize constraints */
390 if (!DOMAINDECOMP(cr
))
391 set_constraints(constr
,top
,ir
,mdatoms
,cr
);
394 /* Check whether we have to GCT stuff */
395 bTCR
= ftp2bSet(efGCT
,nfile
,fnm
);
398 fprintf(stderr
,"Will do General Coupling Theory!\n");
400 gnx
= top_global
->mols
.nr
;
402 for(i
=0; (i
<gnx
); i
++) {
407 if (repl_ex_nst
> 0 && MASTER(cr
))
408 repl_ex
= init_replica_exchange(fplog
,cr
->ms
,state_global
,ir
,
409 repl_ex_nst
,repl_ex_seed
);
411 if (!ir
->bContinuation
&& !bRerunMD
)
413 if (mdatoms
->cFREEZE
&& (state
->flags
& (1<<estV
)))
415 /* Set the velocities of frozen particles to zero */
416 for(i
=mdatoms
->start
; i
<mdatoms
->start
+mdatoms
->homenr
; i
++)
420 if (ir
->opts
.nFreeze
[mdatoms
->cFREEZE
[i
]][m
])
430 /* Constrain the initial coordinates and velocities */
431 do_constrain_first(fplog
,constr
,ir
,mdatoms
,state
,f
,
432 graph
,cr
,nrnb
,fr
,top
,shake_vir
);
436 /* Construct the virtual sites for the initial configuration */
437 construct_vsites(fplog
,vsite
,state
->x
,nrnb
,ir
->delta_t
,NULL
,
438 top
->idef
.iparams
,top
->idef
.il
,
439 fr
->ePBC
,fr
->bMolPBC
,graph
,cr
,state
->box
);
445 /* I'm assuming we need global communication the first time! MRS */
447 // cglo_flags = (CGLO_TEMPERATURE | CGLO_GSTAT
448 // | (bVV ? CGLO_PRESSURE:0)
449 // | (bVV ? CGLO_CONSTRAINT:0)
450 // | (bRerunMD ? CGLO_RERUNMD:0)
451 // | ((Flags & MD_READ_EKIN) ? CGLO_READEKIN:0));
453 // bSumEkinhOld = FALSE;
454 // compute_globals(fplog,gstat,cr,ir,fr,ekind,state,state_global,mdatoms,nrnb,vcm,
455 // wcycle,enerd,force_vir,shake_vir,total_vir,pres,mu_tot,
456 // constr,NULL,NULL,NULL,NULL,NULL,
458 // top_global,&pcurr,top_global->natoms,&bSumEkinhOld,cglo_flags);
459 // if (ir->eI == eiVVAK) {
460 // /* a second call to get the half step temperature initialized as well */
461 // /* we do the same call as above, but turn the pressure off -- internally, this
462 // is recognized as a velocity verlet half-step kinetic energy calculation.
463 // This minimized excess variables, but perhaps loses some logic?*/
465 // compute_globals(fplog,gstat,cr,ir,fr,ekind,state,state_global,mdatoms,nrnb,vcm,
466 // wcycle,enerd,force_vir,shake_vir,total_vir,pres,mu_tot,
467 // constr,NULL,NULL,NULL,NULL,NULL,NULL,state->box,
468 // top_global,&pcurr,top_global->natoms,&bSumEkinhOld,
469 // cglo_flags &~ CGLO_PRESSURE);
472 /* Calculate the initial half step temperature, and save the ekinh_old */
473 if (!(Flags
& MD_STARTFROMCPT
))
475 for(i
=0; (i
<ir
->opts
.ngtc
); i
++)
477 copy_mat(ekind
->tcstat
[i
].ekinh
,ekind
->tcstat
[i
].ekinh_old
);
480 temp0
= enerd
->term
[F_TEMP
];
482 /* if using an iterative algorithm, we need to create a working directory for the state. */
485 bufstate
= init_bufstate(state
);
489 snew(xcopy
,state
->natoms
);
490 snew(vcopy
,state
->natoms
);
491 copy_rvecn(state
->x
,xcopy
,0,state
->natoms
);
492 copy_rvecn(state
->v
,vcopy
,0,state
->natoms
);
493 copy_mat(state
->box
,boxcopy
);
496 /* need to make an initiation call to get the Trotter variables set, as well as other constants for non-trotter
497 temperature control */
498 trotter_seq
= init_npt_vars(ir
,state
,&MassQ
,bTrotter
);
502 if (constr
&& !ir
->bContinuation
&& ir
->eConstrAlg
== econtLINCS
)
505 "RMS relative constraint deviation after constraining: %.2e\n",
506 constr_rmsd(constr
,FALSE
));
510 enerd
->term
[F_TEMP
] *= 2; /* result of averages being done over previous and current step,
511 and there is no previous step */
513 fprintf(fplog
,"Initial temperature: %g K\n",enerd
->term
[F_TEMP
]);
516 fprintf(stderr
,"starting md rerun '%s', reading coordinates from"
517 " input trajectory '%s'\n\n",
518 *(top_global
->name
),opt2fn("-rerun",nfile
,fnm
));
521 fprintf(stderr
,"Calculated time to finish depends on nsteps from "
522 "run input file,\nwhich may not correspond to the time "
523 "needed to process input trajectory.\n\n");
529 fprintf(stderr
,"starting mdrun '%s'\n",
530 *(top_global
->name
));
533 sprintf(tbuf
,"%8.1f",(ir
->init_step
+ir
->nsteps
)*ir
->delta_t
);
537 sprintf(tbuf
,"%s","infinite");
539 if (ir
->init_step
> 0)
541 fprintf(stderr
,"%s steps, %s ps (continuing from step %s, %8.1f ps).\n",
542 gmx_step_str(ir
->init_step
+ir
->nsteps
,sbuf
),tbuf
,
543 gmx_step_str(ir
->init_step
,sbuf2
),
544 ir
->init_step
*ir
->delta_t
);
548 fprintf(stderr
,"%s steps, %s ps.\n",
549 gmx_step_str(ir
->nsteps
,sbuf
),tbuf
);
555 /* Set and write start time */
556 runtime_start(runtime
);
557 print_date_and_time(fplog
,cr
->nodeid
,"Started mdrun",runtime
);
558 wallcycle_start(wcycle
,ewcRUN
);
562 /* safest point to do file checkpointing is here. More general point would be immediately before integrator call */
565 /***********************************************************
569 ************************************************************/
571 /* if rerunMD then read coordinates and velocities from input trajectory */
574 if (getenv("GMX_FORCE_UPDATE"))
579 bNotLastFrame
= read_first_frame(oenv
,&status
,
580 opt2fn("-rerun",nfile
,fnm
),
581 &rerun_fr
,TRX_NEED_X
| TRX_READ_V
);
582 if (rerun_fr
.natoms
!= top_global
->natoms
)
585 "Number of atoms in trajectory (%d) does not match the "
586 "run input file (%d)\n",
587 rerun_fr
.natoms
,top_global
->natoms
);
589 if (ir
->ePBC
!= epbcNONE
)
593 gmx_fatal(FARGS
,"Rerun trajectory frame step %d time %f does not contain a box, while pbc is used",rerun_fr
.step
,rerun_fr
.time
);
595 if (max_cutoff2(ir
->ePBC
,rerun_fr
.box
) < sqr(fr
->rlistlong
))
597 gmx_fatal(FARGS
,"Rerun trajectory frame step %d time %f has too small box dimensions",rerun_fr
.step
,rerun_fr
.time
);
600 /* Set the shift vectors.
601 * Necessary here when have a static box different from the tpr box.
603 calc_shifts(rerun_fr
.box
,fr
->shift_vec
);
607 /* loop over MD steps or if rerunMD to end of input trajectory */
609 /* Skip the first Nose-Hoover integration when we get the state from tpx */
610 bStateFromTPX
= !opt2bSet("-cpi",nfile
,fnm
);
611 bInitStep
= bFirstStep
&& (bStateFromTPX
|| bVV
);
612 bStartingFromCpt
= (Flags
& MD_STARTFROMCPT
) && bInitStep
;
614 bSumEkinhOld
= FALSE
;
617 step
= ir
->init_step
;
620 // if (ir->nstlist == -1)
622 // init_nlistheuristics(&nlh,bGStatEveryStep,step);
625 bLastStep
= (bRerunMD
|| (ir
->nsteps
>= 0 && step_rel
> ir
->nsteps
));
626 while (!bLastStep
|| (bRerunMD
&& bNotLastFrame
)) {
628 wallcycle_start(wcycle
,ewcSTEP
);
630 GMX_MPE_LOG(ev_timestep1
);
632 /* Now we have the energies and forces corresponding to the
633 * coordinates at time t. We must output all of this before
635 * for RerunMD t is read from input trajectory
637 GMX_MPE_LOG(ev_output_start
);
639 bX
= do_per_step(step
,ir
->nstxout
) || (bLastStep
&& ir
->nstxout
);
640 bV
= do_per_step(step
,ir
->nstvout
) || (bLastStep
&& ir
->nstvout
);
641 bF
= do_per_step(step
,ir
->nstfout
) || (bLastStep
&& ir
->nstfout
);
642 bXTC
= do_per_step(step
,ir
->nstxtcout
) || (bLastStep
&& ir
->nstxtcout
);
643 do_ene
= do_per_step(step
,ir
->nstenergy
) || (bLastStep
&& ir
->nstenergy
);
647 if( bX
|| bXTC
|| bV
){
648 wallcycle_start(wcycle
,ewcTRAJ
);
649 openmm_copy_state(openmmData
, state
, &t
, f
, enerd
, bX
||bXTC
, bV
, 0, 0);
650 wallcycle_stop(wcycle
,ewcTRAJ
);
653 openmm_take_one_step(openmmData
);
654 bLastStep
= (step_rel
== ir
->nsteps
);
655 if (bX
|| bV
|| bF
|| bXTC
|| do_ene
) {
656 wallcycle_start(wcycle
,ewcTRAJ
);
658 openmm_copy_state(openmmData
, state
, &t
, f
, enerd
, 0, 0, bF
, do_ene
);
660 upd_mdebin(mdebin
,fp_dhdl
,bGStatEveryStep
&& !bRerunMD
,
661 t
,mdatoms
->tmass
,enerd
,state
,lastbox
,
662 shake_vir
,force_vir
,total_vir
,pres
,
663 ekind
,mu_tot
,constr
);
664 print_ebin(fp_ene
,do_ene
,FALSE
,FALSE
,do_log
?fplog
:NULL
,step
,t
,
665 eprNORMAL
,bCompact
,mdebin
,fcd
,groups
,&(ir
->opts
)); // XXX check this do_log stuff!
668 write_traj(fplog
,cr
,fp_trn
,bX
,bV
,bF
,fp_xtc
,bXTC
,ir
->xtcprec
,
669 fn_cpt
,bCPT
,top_global
,ir
->eI
,ir
->simulation_part
,
670 step
,t
,state
,state_global
,f
,f_global
,&n_xtc
,&x_xtc
);
672 if (bLastStep
&& step_rel
== ir
->nsteps
&&
673 (Flags
& MD_CONFOUT
) && MASTER(cr
) &&
674 !bRerunMD
&& !bFFscan
)
676 /* x and v have been collected in write_traj */
677 fprintf(stderr
,"\nWriting final coordinates.\n");
678 if (ir
->ePBC
!= epbcNONE
&& !ir
->bPeriodicMols
&&
681 /* Make molecules whole only for confout writing */
682 do_pbc_mtop(fplog
,ir
->ePBC
,state
->box
,top_global
,state_global
->x
);
684 write_sto_conf_mtop(ftp2fn(efSTO
,nfile
,fnm
),
685 *top_global
->name
,top_global
,
686 state_global
->x
,state_global
->v
,
687 ir
->ePBC
,state
->box
);
690 wallcycle_stop(wcycle
,ewcTRAJ
);
692 GMX_MPE_LOG(ev_output_finish
);
699 /* End of main MD loop */
703 openmm_cleanup(fplog
, openmmData
);
707 runtime_end(runtime
);
714 if (!(cr
->duty
& DUTY_PME
))
716 /* Tell the PME only node to finish */
722 if (bGStatEveryStep
&& !bRerunMD
)
724 print_ebin(fp_ene
,FALSE
,FALSE
,FALSE
,fplog
,step
,t
,
725 eprAVER
,FALSE
,mdebin
,fcd
,groups
,&(ir
->opts
));
735 gmx_fio_fclose(fp_dhdl
);
739 gmx_fio_fclose(fp_field
);
744 // if (ir->nstlist == -1 && nlh.nns > 0 && fplog)
746 // fprintf(fplog,"Average neighborlist lifetime: %.1f steps, std.dev.: %.1f steps\n",nlh.s1/nlh.nns,sqrt(nlh.s2/nlh.nns - sqr(nlh.s1/nlh.nns)));
747 // fprintf(fplog,"Average number of atoms that crossed the half buffer length: %.1f\n\n",nlh.ab/nlh.nns);
750 if (shellfc
&& fplog
)
752 fprintf(fplog
,"Fraction of iterations that converged: %.2f %%\n",
753 (nconverged
*100.0)/step_rel
);
754 fprintf(fplog
,"Average number of force evaluations per MD step: %.2f\n\n",
758 if (repl_ex_nst
> 0 && MASTER(cr
))
760 print_replica_exchange_statistics(fplog
,repl_ex
);
763 runtime
->nsteps_done
= step_rel
;