Changed C++ comments to C-style
[gromacs.git] / src / mdlib / sim_util.c
blobb739d582f73bf257cdfd74d3de2934e8e4c4cce9
1 /*
2 * $Id$
3 *
4 * This source code is part of
5 *
6 * G R O M A C S
7 *
8 * GROningen MAchine for Chemical Simulations
9 *
10 * VERSION 3.2.0
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
33 * And Hey:
34 * GROwing Monsters And Cloning Shrimps
36 #ifdef HAVE_CONFIG_H
37 #include <config.h>
38 #endif
40 #include <stdio.h>
41 #include <time.h>
42 #include <math.h>
43 #include "typedefs.h"
44 #include "string2.h"
45 #include "smalloc.h"
46 #include "names.h"
47 #include "confio.h"
48 #include "mvdata.h"
49 #include "txtdump.h"
50 #include "pbc.h"
51 #include "vec.h"
52 #include "time.h"
53 #include "nrnb.h"
54 #include "mshift.h"
55 #include "mdrun.h"
56 #include "update.h"
57 #include "physics.h"
58 #include "main.h"
59 #include "mdatoms.h"
60 #include "pme.h"
61 #include "pppm.h"
62 #include "disre.h"
63 #include "orires.h"
64 #include "network.h"
65 #include "calcmu.h"
66 #include "constr.h"
67 #include "xvgr.h"
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;
74 static time_t end;
75 time_t finish;
76 double dt;
77 char buf[48];
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 */
83 end=time(NULL);
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;
89 if (dt >= 300) {
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);
95 else
96 fprintf(out,", remaining runtime: %5d s ",(int)dt);
98 if (gmx_parallel_env)
99 fprintf(out,"\n");
101 fflush(out);
104 time_t print_date_and_time(FILE *log,int nodeid,char *title)
106 int i;
107 char *ts,time_string[STRLEN];
108 time_t now;
110 now=time(NULL);
111 ts=ctime(&now);
112 for (i=0; ts[i]>=' '; i++) time_string[i]=ts[i];
113 time_string[i]='\0';
114 fprintf(log,"%s on node %d %s\n",title,nodeid,time_string);
115 return now;
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[])
126 int i;
128 if (debug) {
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[])
139 int i,j;
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++)
152 epot[i] = 0.0;
153 epot[F_DVDL] = 0.0;
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
167 * now.
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)
175 rvec Ext;
176 real t0;
177 int i,m;
179 for(m=0; (m<DIM); m++) {
180 if (Et[m].n) {
181 if (Et[m].n == 3) {
182 t0 = Et[m].a[1];
183 Ext[m] = cos(Et[m].a[0]*(t-t0))*exp(-sqr(t-t0)/(2.0*sqr(Et[m].a[2])));
185 else
186 Ext[m] = cos(Et[m].a[0]*t);
188 else
189 Ext[m] = 1.0;
190 if (Ex[m].n) {
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];
196 else
197 Ext[m] = 0;
199 if (fp)
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;
215 int cg0,cg1,i,j;
216 int start,homenr;
217 static real mu_and_q[DIM+1];
218 real qsum;
220 start = START(nsb);
221 homenr = HOMENR(nsb);
222 cg0 = CG0(nsb);
223 cg1 = CG1(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);
237 if (bNS) {
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);
246 else if (bNS)
247 calc_cgcm(log,cg0,cg1,&(top->blocks[ebCGS]),x,fr->cg_cm);
249 if (bNS) {
250 inc_nrnb(nrnb,eNR_CGCM,cg1-cg0);
251 if (PAR(cr))
252 move_cgcm(log,cr,fr->cg_cm,nsb->workload);
253 if (debug)
254 pr_rvecs(debug,0,"cgcm",fr->cg_cm,nsb->cgtotal);
257 /* Communicate coordinates and sum dipole and net charge if necessary */
258 if (PAR(cr)) {
259 move_x(log,cr->left,cr->right,x,nsb,nrnb);
260 gmx_sum(DIM+1,mu_and_q,cr);
262 for(i=0;i<DIM;i++)
263 mu_tot[i]=mu_and_q[i];
264 qsum=mu_and_q[DIM];
266 /* Reset energies */
267 reset_energies(&(parm->ir.opts),grps,fr,bNS,ener);
268 if (bNS) {
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.
281 dvdl_lr = 0;
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]);
297 else {
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;
311 #ifdef DEBUG
312 if (bNS)
313 print_nrnb(log,nrnb);
314 #endif
316 /* The short-range virial from surrounding boxes */
317 clear_mat(vir_part);
318 calc_vir(log,SHIFTS,fr->shift_vec,fr->fshift,vir_part);
319 inc_nrnb(nrnb,eNR_VIRIAL,SHIFTS);
321 if (debug)
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 */
334 if (PAR(cr))
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)
353 int i,j;
354 tensor virtest;
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 */
365 /* if (!bTweak) {
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) {
372 clear_mat(virtest);
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 */
378 if (!bTweak)
379 for(i=0; (i<DIM); i++)
380 for(j=0; (j<DIM); j++)
381 vir_part[i][j]+=pme_vir[i][j];
383 if (debug)
384 pr_rvecs(debug,0,"vir_part",vir_part,DIM);
387 #ifdef NO_CLOCK
388 #define clock() -1
389 #endif
390 static double runtime=0;
391 static clock_t cprev;
393 void start_time(void)
395 cprev = clock();
396 runtime = 0.0;
399 void update_time(void)
401 clock_t c;
403 c = clock();
404 runtime += (c-cprev)/(double)CLOCKS_PER_SEC;
405 cprev = c;
408 double node_time(void)
410 return runtime;
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;
421 tensor shake_vir;
422 double mass,tmass,vcm[4];
423 real dt=parm->ir.delta_t;
424 real dt_1;
425 rvec *xptr;
427 if (count_constraints(top,cr)) {
428 start = START(nsb);
429 homenr = HOMENR(nsb);
430 end = start+homenr;
431 if (debug)
432 fprintf(debug,"vcm: start=%d, homenr=%d, end=%d\n",start,homenr,end);
433 /* Do a first SHAKE to reset particles... */
434 step = -2;
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],
438 parm,md,state,graph,
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.
452 step = -1;
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],
456 parm,md,state,graph,
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
461 * t=-dt and t=0
462 * Compute velocity of center of mass and total mass
464 for(m=0; (m<4); m++)
465 vcm[m] = 0;
466 dt_1=1.0/dt;
467 for(i=start; (i<end); i++) {
468 /*for(i=0; (i<nsb->natoms); i++) {*/
469 mass = md->massA[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;
474 vcm[3] += mass;
476 /* Compute the global sum of vcm */
477 if (debug)
478 fprintf(debug,"vcm: %8.3f %8.3f %8.3f,"
479 " total mass = %12.5e\n",vcm[XX],vcm[YY],vcm[ZZ],vcm[3]);
480 if (PAR(cr))
481 gmx_sumd(4,vcm,cr);
482 tmass = vcm[3];
483 for(m=0; (m<DIM); m++)
484 vcm[m] /= tmass;
485 if (debug)
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;
501 double dnatoms;
502 real vol,rc3,rc9,spres=0,svir=0;
503 int m,offset;
505 /* variables for switched VdW correction */
506 double r;
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;
510 int i, offstart=0;
511 real multf=0;
512 real *vdwtab;
514 ener[F_DISPCORR] = 0.0;
515 ener[F_PRES] = trace(pres)/3.0;
517 if (eDispCorr != edispcNO) {
518 vol = det(box);
519 if (fr->vdwtype == evdwSWITCH) {
520 rc3 = fr->rvdw_switch*fr->rvdw_switch*fr->rvdw_switch;
521 rc9 = rc3*rc3*rc3;
522 eners = 0.0; press=0.0;
523 rswitch = fr->rvdw_switch;
524 roff = fr->rvdw;
525 scale = 1.0/(fr->tabscale);
526 scale2 = scale*scale;
527 scale3 = scale*scale2;
528 vdwtab = fr->vdwtab;
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
538 cost is low. */
540 eners = 0.0; press = 0.0;
543 for (i=0;i<2;i++) {
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) {
552 ea = scale3;
553 eb = 2.0*scale2*r;
554 ec = scale*r*r;
556 pa = scale3;
557 pb = 3.0*scale2*r;
558 pc = 3.0*scale*r*r;
559 pd = r*r*r;
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;
564 y0 = vdwtab[offset];
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;
577 eners += enersum;
578 press += pressum;
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;
599 spres = (real)press;
600 svir = -3*(vol/PRESFAC)*spres;
601 ener[F_PRES] += spres;
602 for(m=0; (m<DIM); m++) {
603 pres[m][m] += spres;
604 virial[m][m] += svir;
606 } else {
607 spres = 0;
608 svir = 0;
610 } else if (fr->vdwtype == evdwCUT) {
611 rc3 = fr->rvdw*fr->rvdw*fr->rvdw;
612 rc9 = rc3*rc3*rc3;
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++) {
631 pres[m][m] += spres;
632 virial[m][m] += svir;
634 } else {
635 spres = 0;
636 svir = 0;
640 if (bFirst) {
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);
646 bFirst = FALSE;
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);
660 if (graph) {
661 mk_mshift(log,graph,box,x);
662 if (getenv ("NOPBC") == NULL)
663 shift_self(graph,box,x);
664 else
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,
682 bool bWriteStat)
684 int i,j;
685 t_nrnb ntot;
686 real runtime;
687 for(i=0; (i<eNRNB); i++)
688 ntot.n[i]=0;
689 for(i=0; (i<nsb->nnodes); i++)
690 for(j=0; (j<eNRNB); j++)
691 ntot.n[j]+=nrnb[i].n[j];
692 runtime=0;
693 if (bWriteStat) {
694 runtime=parm->ir.nsteps*parm->ir.delta_t;
695 if (MASTER(cr)) {
696 fprintf(stderr,"\n\n");
697 print_perf(stderr,nodetime,realtime,runtime,&ntot,nsb->nnodes);
699 else
700 print_nrnb(log,&(nrnb[nsb->nodeid]));
703 if (MASTER(cr)) {
704 print_perf(log,nodetime,realtime,runtime,&ntot,nsb->nnodes);
705 if (nsb->nnodes > 1)
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;
721 int i,j,n;
722 real tmpt,mod;
724 /* Initial values */
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;
730 else {
731 *lambda = *lam0 = 0.0;
734 *bSimAnn=FALSE;
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)
738 *bSimAnn = TRUE;
740 if(*bSimAnn)
741 update_annealing_target_temp(&(ir->opts),ir->init_t);
743 init_nrnb(mynrnb);
745 /* Check Environment variables & other booleans */
746 *bTYZ=getenv("TYZ") != NULL;
747 set_pot_bools(ir,top,&bLR,&bLJLR,&bBHAM,&b14);
749 if (nfile != -1) {
750 /* Filenames */
751 *traj = ftp2fn(efTRN,nfile,fnm);
752 *xtc_traj = ftp2fn(efXTC,nfile,fnm);
754 if (MASTER(cr)) {
755 *fp_ene = open_enx(ftp2fn(efENX,nfile,fnm),"w");
756 if ((fp_dgdl != NULL) && ir->efep!=efepNO)
757 *fp_dgdl =
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)",
764 "E (V/nm)");
765 } else
766 *fp_ene = -1;
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)),
771 ir->etc,cr);
774 /* Initiate variables */
775 clear_mat(force_vir);
776 clear_mat(pme_vir);
777 clear_mat(shake_vir);
778 clear_rvec(mu_tot);
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);
785 debug_gmx();
787 *bNEMD = (ir->opts.ngacc > 1) || (norm(ir->opts.acc[0]) > 0);
789 if (ir->eI == eiSD)
790 init_sd_consts(ir->opts.ngtc,ir->opts.tau_t,ir->delta_t);