4 * This source code is part of
8 * GROningen MAchine for Chemical Simulations
11 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
12 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
13 * Copyright (c) 2001-2004, The GROMACS development team,
14 * check out http://www.gromacs.org for more information.
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
21 * If you want to redistribute modifications, please consider that
22 * scientific software is very special. Version control is crucial -
23 * bugs must be traceable. We will be happy to consider code for
24 * inclusion in the official distribution, but derived work must not
25 * be called official GROMACS. Details are found in the README & COPYING
26 * files - if they are missing, get the official version at www.gromacs.org.
28 * To help us fund GROMACS development, we humbly ask that you cite
29 * the papers on the package - you can find them in the top README file.
31 * For more info, check our website at http://www.gromacs.org
34 * GROwing Monsters And Cloning Shrimps
69 #define difftime(end,start) ((double)(end)-(double)(start))
71 void print_time(FILE *out
,time_t start
,int step
,t_inputrec
*ir
)
73 static real time_per_step
;
79 fprintf(out
,"\rstep %d",step
- ir
->init_step
);
80 if ((step
>= ir
->nstlist
)) {
81 if ((ir
->nstlist
== 0) || ((step
% ir
->nstlist
) == 0)) {
82 /* We have done a full cycle let's update time_per_step */
84 dt
=difftime(end
,start
);
85 time_per_step
=dt
/(step
- ir
->init_step
+ 1);
87 dt
=(ir
->nsteps
+ ir
->init_step
- step
)*time_per_step
;
90 finish
= end
+(time_t)dt
;
91 sprintf(buf
,"%s",ctime(&finish
));
92 buf
[strlen(buf
)-1]='\0';
93 fprintf(out
,", will finish at %s",buf
);
96 fprintf(out
,", remaining runtime: %5d s ",(int)dt
);
104 time_t print_date_and_time(FILE *log
,int nodeid
,char *title
)
107 char *ts
,time_string
[STRLEN
];
112 for (i
=0; ts
[i
]>=' '; i
++) time_string
[i
]=ts
[i
];
114 fprintf(log
,"%s on node %d %s\n",title
,nodeid
,time_string
);
118 static void pr_commrec(FILE *log
,t_commrec
*cr
)
120 fprintf(log
,"commrec: nodeid=%d, nnodes=%d, left=%d, right=%d, threadid=%d, nthreads=%d\n",
121 cr
->nodeid
,cr
->nnodes
,cr
->left
,cr
->right
,cr
->threadid
,cr
->nthreads
);
124 static void sum_forces(int start
,int end
,rvec f
[],rvec flr
[])
129 pr_rvecs(debug
,0,"fsr",f
+start
,end
-start
);
130 pr_rvecs(debug
,0,"flr",flr
+start
,end
-start
);
132 for(i
=start
; (i
<end
); i
++)
133 rvec_inc(f
[i
],flr
[i
]);
136 static void reset_energies(t_grpopts
*opts
,t_groups
*grp
,
137 t_forcerec
*fr
,bool bNS
,real epot
[])
141 /* First reset all energy components but the Long Range, except in
142 * some special cases.
144 for(i
=0; (i
<egNR
); i
++)
145 if (((i
!= egLR
) && (i
!= egLJLR
)) ||
146 (fr
->bTwinRange
&& bNS
) || (!fr
->bTwinRange
))
147 for(j
=0; (j
<grp
->estat
.nn
); j
++)
148 grp
->estat
.ee
[i
][j
]=0.0;
150 /* Normal potential energy components */
151 for(i
=0; (i
<=F_EPOT
); i
++)
154 epot
[F_DVDLKIN
] = 0.0;
158 * calc_f_el calculates forces due to an electric field.
160 * force is kJ mol^-1 nm^-1 = e * kJ mol^-1 nm^-1 / e
162 * Et[] contains the parameters for the time dependent
163 * part of the field (not yet used).
164 * Ex[] contains the parameters for
165 * the spatial dependent part of the field. You can have cool periodic
166 * fields in principle, but only a constant field is supported
168 * The function should return the energy due to the electric field
169 * (if any) but for now returns 0.
171 static void calc_f_el(FILE *fp
,int start
,int homenr
,
172 real charge
[],rvec x
[],rvec f
[],
173 t_cosines Ex
[],t_cosines Et
[],real t
)
179 for(m
=0; (m
<DIM
); m
++) {
183 Ext
[m
] = cos(Et
[m
].a
[0]*(t
-t0
))*exp(-sqr(t
-t0
)/(2.0*sqr(Et
[m
].a
[2])));
186 Ext
[m
] = cos(Et
[m
].a
[0]*t
);
191 /* Convert the field strength from V/nm to MD-units */
192 Ext
[m
] *= Ex
[m
].a
[0]*FIELDFAC
;
193 for(i
=start
; (i
<start
+homenr
); i
++)
194 f
[i
][m
] += charge
[i
]*Ext
[m
];
200 fprintf(fp
,"%10g %10g %10g %10g #FIELD\n",t
,
201 Ext
[XX
]/FIELDFAC
,Ext
[YY
]/FIELDFAC
,Ext
[ZZ
]/FIELDFAC
);
204 void do_force(FILE *log
,t_commrec
*cr
,t_commrec
*mcr
,
205 t_parm
*parm
,t_nsborder
*nsb
,tensor vir_part
,tensor pme_vir
,
206 int step
,t_nrnb
*nrnb
,t_topology
*top
,t_groups
*grps
,
207 matrix box
,rvec x
[],rvec f
[],rvec buf
[],
208 t_mdatoms
*mdatoms
,real ener
[],t_fcdata
*fcd
,bool bVerbose
,
209 real lambda
,t_graph
*graph
,
210 bool bNS
,bool bNBFonly
,t_forcerec
*fr
, rvec mu_tot
,
211 bool bGatherOnly
,real t
,FILE *field
)
213 static rvec box_size
;
214 static real dvdl_lr
= 0;
217 static real mu_and_q
[DIM
+1];
221 homenr
= HOMENR(nsb
);
225 update_forcerec(log
,fr
,box
);
227 /* Calculate total (local) dipole moment in a temporary common array.
228 * This makes it possible to sum them over nodes faster.
230 calc_mu_and_q(nsb
,x
,mdatoms
->chargeT
,mu_and_q
,mu_and_q
+DIM
);
232 if (fr
->ePBC
!= epbcNONE
) {
233 /* Compute shift vectors every step, because of pressure coupling! */
234 if (parm
->ir
.epc
!= epcNO
)
235 calc_shifts(box
,box_size
,fr
->shift_vec
);
238 put_charge_groups_in_box(log
,cg0
,cg1
,box
,box_size
,
239 &(top
->blocks
[ebCGS
]),x
,fr
->cg_cm
);
240 inc_nrnb(nrnb
,eNR_RESETX
,homenr
);
242 else if ((parm
->ir
.eI
==eiSteep
|| parm
->ir
.eI
==eiCG
) && graph
)
243 unshift_self(graph
,box
,x
);
247 calc_cgcm(log
,cg0
,cg1
,&(top
->blocks
[ebCGS
]),x
,fr
->cg_cm
);
250 inc_nrnb(nrnb
,eNR_CGCM
,cg1
-cg0
);
252 move_cgcm(log
,cr
,fr
->cg_cm
,nsb
->workload
);
254 pr_rvecs(debug
,0,"cgcm",fr
->cg_cm
,nsb
->cgtotal
);
257 /* Communicate coordinates and sum dipole and net charge if necessary */
259 move_x(log
,cr
->left
,cr
->right
,x
,nsb
,nrnb
);
260 gmx_sum(DIM
+1,mu_and_q
,cr
);
263 mu_tot
[i
]=mu_and_q
[i
];
267 reset_energies(&(parm
->ir
.opts
),grps
,fr
,bNS
,ener
);
269 if (fr
->ePBC
== epbcXYZ
)
270 /* Calculate intramolecular shift vectors to make molecules whole */
271 mk_mshift(log
,graph
,box
,x
);
273 /* Reset long range forces if necessary */
274 if (fr
->bTwinRange
) {
275 clear_rvecs(nsb
->natoms
,fr
->f_twin
);
276 clear_rvecs(SHIFTS
,fr
->fshift_twin
);
278 /* Do the actual neighbour searching and if twin range electrostatics
279 * also do the calculation of long range forces and energies.
283 ns(log
,fr
,x
,f
,box
,grps
,&(parm
->ir
.opts
),top
,mdatoms
,
284 cr
,nrnb
,nsb
,step
,lambda
,&dvdl_lr
);
286 /* Reset PME/Ewald forces if necessary */
287 if (EEL_LR(fr
->eeltype
))
288 clear_rvecs(homenr
,fr
->f_pme
+start
);
290 /* Copy long range forces into normal buffers */
291 if (fr
->bTwinRange
) {
292 for(i
=0; i
<nsb
->natoms
; i
++)
293 copy_rvec(fr
->f_twin
[i
],f
[i
]);
294 for(i
=0; i
<SHIFTS
; i
++)
295 copy_rvec(fr
->fshift_twin
[i
],fr
->fshift
[i
]);
298 clear_rvecs(nsb
->natoms
,f
);
299 clear_rvecs(SHIFTS
,fr
->fshift
);
302 /* Compute the forces */
303 force(log
,step
,fr
,&(parm
->ir
),&(top
->idef
),nsb
,cr
,mcr
,nrnb
,grps
,mdatoms
,
304 top
->atoms
.grps
[egcENER
].nr
,&(parm
->ir
.opts
),
305 x
,f
,ener
,fcd
,bVerbose
,box
,lambda
,graph
,&(top
->atoms
.excl
),
306 bNBFonly
,pme_vir
,mu_tot
,qsum
,bGatherOnly
);
308 /* Take long range contribution to free energy into account */
309 ener
[F_DVDL
] += dvdl_lr
;
313 print_nrnb(log
,nrnb
);
316 /* The short-range virial from surrounding boxes */
318 calc_vir(log
,SHIFTS
,fr
->shift_vec
,fr
->fshift
,vir_part
);
319 inc_nrnb(nrnb
,eNR_VIRIAL
,SHIFTS
);
322 pr_rvecs(debug
,0,"vir_shifts",vir_part
,DIM
);
324 /* Compute forces due to electric field */
325 calc_f_el(MASTER(cr
) ? field
: NULL
,
326 start
,homenr
,mdatoms
->chargeT
,x
,f
,parm
->ir
.ex
,parm
->ir
.et
,t
);
328 /* When using PME/Ewald we compute the long range virial (pme_vir) there.
329 * otherwise we do it based on long range forces from twin range
330 * cut-off based calculation (or not at all).
333 /* Communicate the forces */
335 move_f(log
,cr
->left
,cr
->right
,f
,buf
,nsb
,nrnb
);
338 void sum_lrforces(rvec f
[],t_forcerec
*fr
,int start
,int homenr
)
340 /* Now add the forces from the PME calculation. Since this only produces
341 * forces on the local atoms, this can be safely done after the
342 * communication step.
344 if (EEL_LR(fr
->eeltype
))
345 sum_forces(start
,start
+homenr
,f
,fr
->f_pme
);
348 void calc_virial(FILE *log
,int start
,int homenr
,rvec x
[],rvec f
[],
349 tensor vir_part
,tensor pme_vir
,
350 t_graph
*graph
,matrix box
,
351 t_nrnb
*nrnb
,t_forcerec
*fr
,bool bTweak
)
356 /* Now it is time for the short range virial. At this timepoint vir_part
357 * already contains the virial from surrounding boxes.
358 * Calculate partial virial, for local atoms only, based on short range.
359 * Total virial is computed in global_stat, called from do_md
361 f_calc_vir(log
,start
,start
+homenr
,x
,f
,vir_part
,graph
,box
);
362 inc_nrnb(nrnb
,eNR_VIRIAL
,homenr
);
364 /* Add up the long range forces if necessary */
366 sum_lrforces(f,fr,start,homenr);
369 /* Add up virial if necessary */
370 if (EEL_LR(fr
->eeltype
) && (fr
->eeltype
!= eelPPPM
)) {
371 if (debug
&& bTweak
) {
373 f_calc_vir(log
,start
,start
+homenr
,x
,fr
->f_pme
,virtest
,graph
,box
);
374 pr_rvecs(debug
,0,"virtest",virtest
,DIM
);
375 pr_rvecs(debug
,0,"pme_vir",pme_vir
,DIM
);
377 /* PPPM virial sucks */
379 for(i
=0; (i
<DIM
); i
++)
380 for(j
=0; (j
<DIM
); j
++)
381 vir_part
[i
][j
]+=pme_vir
[i
][j
];
384 pr_rvecs(debug
,0,"vir_part",vir_part
,DIM
);
390 static double runtime
=0;
391 static clock_t cprev
;
393 void start_time(void)
399 void update_time(void)
404 runtime
+= (c
-cprev
)/(double)CLOCKS_PER_SEC
;
408 double node_time(void)
413 void do_shakefirst(FILE *log
,bool bTYZ
,real ener
[],
414 t_parm
*parm
,t_nsborder
*nsb
,t_mdatoms
*md
,
415 t_state
*state
,rvec vold
[],rvec buf
[],rvec f
[],
416 t_graph
*graph
,t_commrec
*cr
,t_nrnb
*nrnb
,
417 t_groups
*grps
,t_forcerec
*fr
,t_topology
*top
,
418 t_edsamyn
*edyn
,t_pull
*pulldata
)
420 int i
,m
,start
,homenr
,end
,step
;
422 double mass
,tmass
,vcm
[4];
423 real dt
=parm
->ir
.delta_t
;
427 if (count_constraints(top
,cr
)) {
429 homenr
= HOMENR(nsb
);
432 fprintf(debug
,"vcm: start=%d, homenr=%d, end=%d\n",start
,homenr
,end
);
433 /* Do a first SHAKE to reset particles... */
435 fprintf(log
,"\nConstraining the starting coordinates (step %d)\n",step
);
436 clear_mat(shake_vir
);
437 update(nsb
->natoms
,start
,homenr
,step
,&ener
[F_DVDL
],
439 NULL
,NULL
,vold
,top
,grps
,shake_vir
,cr
,nrnb
,bTYZ
,
440 edyn
,pulldata
,FALSE
,FALSE
,FALSE
,state
->x
);
441 /* Compute coordinates at t=-dt, store them in buf */
442 /* for(i=0; (i<nsb->natoms); i++) {*/
443 for(i
=start
; (i
<end
); i
++) {
444 for(m
=0; (m
<DIM
); m
++) {
445 buf
[i
][m
] = state
->x
[i
][m
] - dt
*state
->v
[i
][m
];
449 /* Shake the positions at t=-dt with the positions at t=0
450 * as reference coordinates.
453 fprintf(log
,"\nConstraining the coordinates at t0-dt (step %d)\n",step
);
454 clear_mat(shake_vir
);
455 update(nsb
->natoms
,start
,homenr
,step
,&ener
[F_DVDL
],
457 NULL
,NULL
,vold
,top
,grps
,shake_vir
,cr
,nrnb
,bTYZ
,
458 edyn
,pulldata
,FALSE
,FALSE
,FALSE
,buf
);
460 /* Compute the velocities at t=-dt/2 using the coordinates at
462 * Compute velocity of center of mass and total mass
467 for(i
=start
; (i
<end
); i
++) {
468 /*for(i=0; (i<nsb->natoms); i++) {*/
470 for(m
=0; (m
<DIM
); m
++) {
471 state
->v
[i
][m
] = (state
->x
[i
][m
] - buf
[i
][m
])*dt_1
;
472 vcm
[m
] += state
->v
[i
][m
]*mass
;
476 /* Compute the global sum of vcm */
478 fprintf(debug
,"vcm: %8.3f %8.3f %8.3f,"
479 " total mass = %12.5e\n",vcm
[XX
],vcm
[YY
],vcm
[ZZ
],vcm
[3]);
483 for(m
=0; (m
<DIM
); m
++)
486 fprintf(debug
,"vcm: %8.3f %8.3f %8.3f,"
487 " total mass = %12.5e\n",vcm
[XX
],vcm
[YY
],vcm
[ZZ
],tmass
);
488 /* Now we have the velocity of center of mass, let's remove it */
489 for(i
=start
; (i
<end
); i
++) {
490 for(m
=0; (m
<DIM
); m
++)
491 state
->v
[i
][m
] -= vcm
[m
];
496 void calc_dispcorr(FILE *log
,int eDispCorr
,t_forcerec
*fr
,int natoms
,
497 matrix box
,tensor pres
,tensor virial
,real ener
[])
499 /* modified for switched VdW corrections Michael R. Shirts 2/21/03 */
500 static bool bFirst
=TRUE
;
502 real vol
,rc3
,rc9
,spres
=0,svir
=0;
505 /* variables for switched VdW correction */
507 double eners
,press
,enersum
,pressum
,y0
,f
,g
,h
;
508 double rswitch
,roff
,ea
,eb
,ec
,pa
,pb
,pc
,pd
;
509 double scale
,scale2
,scale3
;
514 ener
[F_DISPCORR
] = 0.0;
515 ener
[F_PRES
] = trace(pres
)/3.0;
517 if (eDispCorr
!= edispcNO
) {
519 if (fr
->vdwtype
== evdwSWITCH
) {
520 rc3
= fr
->rvdw_switch
*fr
->rvdw_switch
*fr
->rvdw_switch
;
522 eners
= 0.0; press
=0.0;
523 rswitch
= fr
->rvdw_switch
;
525 scale
= 1.0/(fr
->tabscale
);
526 scale2
= scale
*scale
;
527 scale3
= scale
*scale2
;
530 /* following summation derived from cubic spline definition,
531 Numerical Recipies in C, second edition, p. 113-116. Exact
532 for the cubic spline. We first calculate the negative of
533 the energy from rvdw to rvdw_switch, assuming that g(r)=1,
534 and then add the more standard, abrupt cutoff correction to
535 that result, yielding the long-range correction for a
536 switched function. We perform both the pressure and energy
537 loops at the same time for simplicity, as the computational
540 eners
= 0.0; press
= 0.0;
544 enersum
= 0.0; pressum
= 0.0;
545 if (i
==0) {offstart
= 0; multf
= fr
->avcsix
;}
546 if (i
==1) {offstart
= 4; multf
= fr
->avctwelve
;}
547 /* the second time through, we are doing the r12 correction,which we only need to do
548 * if the user selects the "All" variants.
550 if ((i
==1) && (!((eDispCorr
== edispcAllEner
) || (eDispCorr
== edispcAllEnerPres
)))) {break;}
551 for (r
=rswitch
;r
<roff
;r
+=scale
) {
561 /* this "8" is from the packing in the vdwtab array - perhaps
562 should be #define'ed? */
563 offset
= (int)(8*(floor(r
/scale
)+1)) + offstart
;
565 f
= vdwtab
[offset
+1];
566 g
= vdwtab
[offset
+2];
567 h
= vdwtab
[offset
+3];
569 enersum
+= y0
*(ea
/3 + eb
/2 + ec
) + f
*(ea
/4 + eb
/3 + ec
/2)+
570 g
*(ea
/5 + eb
/4 + ec
/3) + h
*(ea
/6 + eb
/5 + ec
/4);
571 pressum
+= f
*(pa
/4 + pb
/3 + pc
/2 + pd
) +
572 2*g
*(pa
/5 + pb
/4 + pc
/3 + pd
/2) + 3*h
*(pa
/6 + pb
/5 + pc
/4 + pd
/3);
575 enersum
*= -2.0*multf
;
576 pressum
*= (2.0/3.0)*multf
;
581 /* now add the correction for vdw_switch to infinity */
583 eners
+= -2.0*(fr
->avcsix
/(3.0*rc3
));
584 if ((eDispCorr
== edispcAllEner
) || (eDispCorr
== edispcAllEnerPres
)) {
585 eners
+= 2.0*(fr
->avctwelve
/(9.0*rc9
));
588 eners
*= natoms
*natoms
*M_PI
*(1/vol
);
589 ener
[F_DISPCORR
] = (real
)eners
;
591 if ((eDispCorr
== edispcEnerPres
) || (eDispCorr
== edispcAllEnerPres
)) {
592 press
+= -4.0*(fr
->avcsix
/(3.0*rc3
));
594 if ((eDispCorr
== edispcAllEnerPres
)) {
595 press
+= 8.0*(fr
->avctwelve
/(9.0*rc9
));
597 press
*= natoms
*natoms
*M_PI
*(1/vol
)*PRESFAC
/vol
;
600 svir
= -3*(vol
/PRESFAC
)*spres
;
601 ener
[F_PRES
] += spres
;
602 for(m
=0; (m
<DIM
); m
++) {
604 virial
[m
][m
] += svir
;
610 } else if (fr
->vdwtype
== evdwCUT
) {
611 rc3
= fr
->rvdw
*fr
->rvdw
*fr
->rvdw
;
614 eners
= -2.0*fr
->avcsix
/(3.0*rc3
);
615 if ((eDispCorr
== edispcAllEner
) || (eDispCorr
== edispcAllEnerPres
)) {
616 eners
+= 2.0* fr
->avctwelve
/(9.0*rc9
);
618 eners
*= natoms
*natoms
*M_PI
*(1/vol
);
619 ener
[F_DISPCORR
] = (real
)eners
;
621 if ((eDispCorr
== edispcEnerPres
) || (eDispCorr
== edispcAllEnerPres
)) {
622 spres
= -4.0*fr
->avcsix
/(3.0*rc3
);
623 if (eDispCorr
== edispcAllEnerPres
) {
624 spres
+= 8.0*fr
->avctwelve
/(9.0*rc9
);
627 spres
*= natoms
*natoms
*M_PI
*(1/vol
)*PRESFAC
/vol
;
628 svir
= -3*(vol
/PRESFAC
)*spres
;
629 ener
[F_PRES
] += spres
;
630 for(m
=0; (m
<DIM
); m
++) {
632 virial
[m
][m
] += svir
;
641 if ((eDispCorr
== edispcEner
) || (eDispCorr
== edispcAllEner
))
642 fprintf(log
,"Long Range LJ corr. to Epot: %10g\n",ener
[F_DISPCORR
]);
643 else if ((eDispCorr
== edispcEnerPres
) || (eDispCorr
== edispcAllEnerPres
))
644 fprintf(log
,"Long Range LJ corr. to Epot: %10g, Pres: %10g, Vir: %10g\n",
645 ener
[F_DISPCORR
],spres
,svir
);
650 ener
[F_EPOT
] += ener
[F_DISPCORR
];
651 ener
[F_ETOT
] += ener
[F_DISPCORR
];
655 void do_pbc_first(FILE *log
,matrix box
,rvec box_size
,t_forcerec
*fr
,
656 t_graph
*graph
,rvec x
[])
658 fprintf(log
,"Removing pbc first time\n");
659 calc_shifts(box
,box_size
,fr
->shift_vec
);
661 mk_mshift(log
,graph
,box
,x
);
662 if (getenv ("NOPBC") == NULL
)
663 shift_self(graph
,box
,x
);
665 fprintf(log
,"Not doing first shift_self\n");
667 fprintf(log
,"Done rmpbc\n");
670 void set_pot_bools(t_inputrec
*ir
,t_topology
*top
,
671 bool *bLR
,bool *bLJLR
,bool *bBHAM
,bool *b14
)
673 *bLR
= (ir
->rcoulomb
> ir
->rlist
) || EEL_LR(ir
->coulombtype
);
674 *bLJLR
= (ir
->rvdw
> ir
->rlist
);
675 *bBHAM
= (top
->idef
.functype
[0]==F_BHAM
);
676 *b14
= (top
->idef
.il
[F_LJ14
].nr
> 0);
679 void finish_run(FILE *log
,t_commrec
*cr
,char *confout
,
680 t_nsborder
*nsb
,t_topology
*top
,t_parm
*parm
,
681 t_nrnb nrnb
[],double nodetime
,double realtime
,int step
,
687 for(i
=0; (i
<eNRNB
); i
++)
689 for(i
=0; (i
<nsb
->nnodes
); i
++)
690 for(j
=0; (j
<eNRNB
); j
++)
691 ntot
.n
[j
]+=nrnb
[i
].n
[j
];
694 runtime
=parm
->ir
.nsteps
*parm
->ir
.delta_t
;
696 fprintf(stderr
,"\n\n");
697 print_perf(stderr
,nodetime
,realtime
,runtime
,&ntot
,nsb
->nnodes
);
700 print_nrnb(log
,&(nrnb
[nsb
->nodeid
]));
704 print_perf(log
,nodetime
,realtime
,runtime
,&ntot
,nsb
->nnodes
);
706 pr_load(log
,nsb
->nnodes
,nrnb
);
710 void init_md(t_commrec
*cr
,t_inputrec
*ir
,tensor box
,real
*t
,real
*t0
,
711 real
*lambda
,real
*lam0
,
712 t_nrnb
*mynrnb
,bool *bTYZ
,t_topology
*top
,
713 int nfile
,t_filenm fnm
[],char **traj
,
714 char **xtc_traj
,int *fp_ene
,
715 FILE **fp_dgdl
,FILE **fp_field
,t_mdebin
**mdebin
,t_groups
*grps
,
716 tensor force_vir
,tensor pme_vir
,
717 tensor shake_vir
,t_mdatoms
*mdatoms
,rvec mu_tot
,
718 bool *bNEMD
,bool *bSimAnn
,t_vcm
**vcm
,t_nsborder
*nsb
)
720 bool bBHAM
,b14
,bLR
,bLJLR
;
725 *t
= *t0
= ir
->init_t
;
726 if (ir
->efep
!= efepNO
) {
727 *lam0
= ir
->init_lambda
;
728 *lambda
= *lam0
+ ir
->init_step
*ir
->delta_lambda
;
731 *lambda
= *lam0
= 0.0;
735 for(i
=0;i
<ir
->opts
.ngtc
;i
++) {
736 /* set bSimAnn if any group is being annealed */
737 if(ir
->opts
.annealing
[i
]!=eannNO
)
741 update_annealing_target_temp(&(ir
->opts
),ir
->init_t
);
745 /* Check Environment variables & other booleans */
746 *bTYZ
=getenv("TYZ") != NULL
;
747 set_pot_bools(ir
,top
,&bLR
,&bLJLR
,&bBHAM
,&b14
);
751 *traj
= ftp2fn(efTRN
,nfile
,fnm
);
752 *xtc_traj
= ftp2fn(efXTC
,nfile
,fnm
);
755 *fp_ene
= open_enx(ftp2fn(efENX
,nfile
,fnm
),"w");
756 if ((fp_dgdl
!= NULL
) && ir
->efep
!=efepNO
)
758 xvgropen(opt2fn("-dgdl",nfile
,fnm
),
759 "dG/d\\8l\\4","Time (ps)",
760 "dG/d\\8l\\4 (kJ mol\\S-1\\N nm\\S-2\\N \\8l\\4\\S-1\\N)");
761 if ((fp_field
!= NULL
) && (ir
->ex
[XX
].n
|| ir
->ex
[YY
].n
||ir
->ex
[ZZ
].n
))
762 *fp_field
= xvgropen(opt2fn("-field",nfile
,fnm
),
763 "Applied electric field","Time (ps)",
768 *mdebin
= init_mdebin(*fp_ene
,grps
,&(top
->atoms
),&(top
->idef
),
769 bLR
,bLJLR
,bBHAM
,b14
,ir
->efep
!=efepNO
,ir
->epc
,
770 ir
->eDispCorr
,(TRICLINIC(ir
->compress
) || TRICLINIC(box
)),
774 /* Initiate variables */
775 clear_mat(force_vir
);
777 clear_mat(shake_vir
);
780 /* Set initial values for invmass etc. */
781 update_mdatoms(mdatoms
,*lambda
,TRUE
);
783 *vcm
= init_vcm(stdlog
,top
,cr
,mdatoms
,START(nsb
),HOMENR(nsb
),ir
->nstcomm
);
787 *bNEMD
= (ir
->opts
.ngacc
> 1) || (norm(ir
->opts
.acc
[0]) > 0);
790 init_sd_consts(ir
->opts
.ngtc
,ir
->opts
.tau_t
,ir
->delta_t
);