Merge release-4-6 into master
[alexxy/gromacs.git] / src / gromacs / mdlib / tpi.c
1 /* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
2  *
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.
15
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.
20  *
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.
27  *
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.
30  *
31  * For more info, check our website at http://www.gromacs.org
32  *
33  * And Hey:
34  * GROwing Monsters And Cloning Shrimps
35  */
36 #ifdef HAVE_CONFIG_H
37 #include <config.h>
38 #endif
39
40 #include <string.h>
41 #include <time.h>
42 #include <math.h>
43 #include "sysstuff.h"
44 #include "string2.h"
45 #include "network.h"
46 #include "confio.h"
47 #include "copyrite.h"
48 #include "smalloc.h"
49 #include "nrnb.h"
50 #include "main.h"
51 #include "chargegroup.h"
52 #include "force.h"
53 #include "macros.h"
54 #include "random.h"
55 #include "names.h"
56 #include "gmx_fatal.h"
57 #include "txtdump.h"
58 #include "typedefs.h"
59 #include "update.h"
60 #include "random.h"
61 #include "constr.h"
62 #include "vec.h"
63 #include "statutil.h"
64 #include "tgroup.h"
65 #include "mdebin.h"
66 #include "vsite.h"
67 #include "force.h"
68 #include "mdrun.h"
69 #include "domdec.h"
70 #include "partdec.h"
71 #include "gmx_random.h"
72 #include "physics.h"
73 #include "xvgr.h"
74 #include "mdatoms.h"
75 #include "ns.h"
76 #include "gmx_wallcycle.h"
77 #include "mtop_util.h"
78 #include "gmxfio.h"
79 #include "pme.h"
80 #include "gbutil.h"
81
82 #ifdef GMX_X86_SSE2
83 #include "gmx_x86_sse2.h"
84 #endif
85
86
87 static void global_max(t_commrec *cr, int *n)
88 {
89     int *sum, i;
90
91     snew(sum, cr->nnodes);
92     sum[cr->nodeid] = *n;
93     gmx_sumi(cr->nnodes, sum, cr);
94     for (i = 0; i < cr->nnodes; i++)
95     {
96         *n = max(*n, sum[i]);
97     }
98
99     sfree(sum);
100 }
101
102 static void realloc_bins(double **bin, int *nbin, int nbin_new)
103 {
104     int i;
105
106     if (nbin_new != *nbin)
107     {
108         srenew(*bin, nbin_new);
109         for (i = *nbin; i < nbin_new; i++)
110         {
111             (*bin)[i] = 0;
112         }
113         *nbin = nbin_new;
114     }
115 }
116
117 double do_tpi(FILE *fplog, t_commrec *cr,
118               int nfile, const t_filenm fnm[],
119               const output_env_t oenv, gmx_bool bVerbose, gmx_bool bCompact,
120               int nstglobalcomm,
121               gmx_vsite_t *vsite, gmx_constr_t constr,
122               int stepout,
123               t_inputrec *inputrec,
124               gmx_mtop_t *top_global, t_fcdata *fcd,
125               t_state *state,
126               t_mdatoms *mdatoms,
127               t_nrnb *nrnb, gmx_wallcycle_t wcycle,
128               gmx_edsam_t ed,
129               t_forcerec *fr,
130               int repl_ex_nst, int repl_ex_nex, int repl_ex_seed,
131               gmx_membed_t membed,
132               real cpt_period, real max_hours,
133               const char *deviceOptions,
134               unsigned long Flags,
135               gmx_runtime_t *runtime)
136 {
137     const char     *TPI = "Test Particle Insertion";
138     gmx_localtop_t *top;
139     gmx_groups_t   *groups;
140     gmx_enerdata_t *enerd;
141     rvec           *f;
142     real            lambda, t, temp, beta, drmax, epot;
143     double          embU, sum_embU, *sum_UgembU, V, V_all, VembU_all;
144     t_trxstatus    *status;
145     t_trxframe      rerun_fr;
146     gmx_bool        bDispCorr, bCharge, bRFExcl, bNotLastFrame, bStateChanged, bNS, bOurStep;
147     tensor          force_vir, shake_vir, vir, pres;
148     int             cg_tp, a_tp0, a_tp1, ngid, gid_tp, nener, e;
149     rvec           *x_mol;
150     rvec            mu_tot, x_init, dx, x_tp;
151     int             nnodes, frame, nsteps, step;
152     int             i, start, end;
153     gmx_rng_t       tpi_rand;
154     FILE           *fp_tpi = NULL;
155     char           *ptr, *dump_pdb, **leg, str[STRLEN], str2[STRLEN];
156     double          dbl, dump_ener;
157     gmx_bool        bCavity;
158     int             nat_cavity  = 0, d;
159     real           *mass_cavity = NULL, mass_tot;
160     int             nbin;
161     double          invbinw, *bin, refvolshift, logV, bUlogV;
162     real            dvdl, prescorr, enercorr, dvdlcorr;
163     gmx_bool        bEnergyOutOfBounds;
164     const char     *tpid_leg[2] = {"direct", "reweighted"};
165
166     /* Since there is no upper limit to the insertion energies,
167      * we need to set an upper limit for the distribution output.
168      */
169     real bU_bin_limit      = 50;
170     real bU_logV_bin_limit = bU_bin_limit + 10;
171
172     nnodes = cr->nnodes;
173
174     top = gmx_mtop_generate_local_top(top_global, inputrec);
175
176     groups = &top_global->groups;
177
178     bCavity = (inputrec->eI == eiTPIC);
179     if (bCavity)
180     {
181         ptr = getenv("GMX_TPIC_MASSES");
182         if (ptr == NULL)
183         {
184             nat_cavity = 1;
185         }
186         else
187         {
188             /* Read (multiple) masses from env var GMX_TPIC_MASSES,
189              * The center of mass of the last atoms is then used for TPIC.
190              */
191             nat_cavity = 0;
192             while (sscanf(ptr, "%lf%n", &dbl, &i) > 0)
193             {
194                 srenew(mass_cavity, nat_cavity+1);
195                 mass_cavity[nat_cavity] = dbl;
196                 fprintf(fplog, "mass[%d] = %f\n",
197                         nat_cavity+1, mass_cavity[nat_cavity]);
198                 nat_cavity++;
199                 ptr += i;
200             }
201             if (nat_cavity == 0)
202             {
203                 gmx_fatal(FARGS, "Found %d masses in GMX_TPIC_MASSES", nat_cavity);
204             }
205         }
206     }
207
208     /*
209        init_em(fplog,TPI,inputrec,&lambda,nrnb,mu_tot,
210        state->box,fr,mdatoms,top,cr,nfile,fnm,NULL,NULL);*/
211     /* We never need full pbc for TPI */
212     fr->ePBC = epbcXYZ;
213     /* Determine the temperature for the Boltzmann weighting */
214     temp = inputrec->opts.ref_t[0];
215     if (fplog)
216     {
217         for (i = 1; (i < inputrec->opts.ngtc); i++)
218         {
219             if (inputrec->opts.ref_t[i] != temp)
220             {
221                 fprintf(fplog, "\nWARNING: The temperatures of the different temperature coupling groups are not identical\n\n");
222                 fprintf(stderr, "\nWARNING: The temperatures of the different temperature coupling groups are not identical\n\n");
223             }
224         }
225         fprintf(fplog,
226                 "\n  The temperature for test particle insertion is %.3f K\n\n",
227                 temp);
228     }
229     beta = 1.0/(BOLTZ*temp);
230
231     /* Number of insertions per frame */
232     nsteps = inputrec->nsteps;
233
234     /* Use the same neighborlist with more insertions points
235      * in a sphere of radius drmax around the initial point
236      */
237     /* This should be a proper mdp parameter */
238     drmax = inputrec->rtpi;
239
240     /* An environment variable can be set to dump all configurations
241      * to pdb with an insertion energy <= this value.
242      */
243     dump_pdb  = getenv("GMX_TPI_DUMP");
244     dump_ener = 0;
245     if (dump_pdb)
246     {
247         sscanf(dump_pdb, "%lf", &dump_ener);
248     }
249
250     atoms2md(top_global, inputrec, 0, NULL, 0, top_global->natoms, mdatoms);
251     update_mdatoms(mdatoms, inputrec->fepvals->init_lambda);
252
253     snew(enerd, 1);
254     init_enerdata(groups->grps[egcENER].nr, inputrec->fepvals->n_lambda, enerd);
255     snew(f, top_global->natoms);
256
257     /* Print to log file  */
258     runtime_start(runtime);
259     print_date_and_time(fplog, cr->nodeid,
260                         "Started Test Particle Insertion", runtime);
261     wallcycle_start(wcycle, ewcRUN);
262
263     /* The last charge group is the group to be inserted */
264     cg_tp = top->cgs.nr - 1;
265     a_tp0 = top->cgs.index[cg_tp];
266     a_tp1 = top->cgs.index[cg_tp+1];
267     if (debug)
268     {
269         fprintf(debug, "TPI cg %d, atoms %d-%d\n", cg_tp, a_tp0, a_tp1);
270     }
271     if (a_tp1 - a_tp0 > 1 &&
272         (inputrec->rlist < inputrec->rcoulomb ||
273          inputrec->rlist < inputrec->rvdw))
274     {
275         gmx_fatal(FARGS, "Can not do TPI for multi-atom molecule with a twin-range cut-off");
276     }
277     snew(x_mol, a_tp1-a_tp0);
278
279     bDispCorr = (inputrec->eDispCorr != edispcNO);
280     bCharge   = FALSE;
281     for (i = a_tp0; i < a_tp1; i++)
282     {
283         /* Copy the coordinates of the molecule to be insterted */
284         copy_rvec(state->x[i], x_mol[i-a_tp0]);
285         /* Check if we need to print electrostatic energies */
286         bCharge |= (mdatoms->chargeA[i] != 0 ||
287                     (mdatoms->chargeB && mdatoms->chargeB[i] != 0));
288     }
289     bRFExcl = (bCharge && EEL_RF(fr->eeltype) && fr->eeltype != eelRF_NEC);
290
291     calc_cgcm(fplog, cg_tp, cg_tp+1, &(top->cgs), state->x, fr->cg_cm);
292     if (bCavity)
293     {
294         if (norm(fr->cg_cm[cg_tp]) > 0.5*inputrec->rlist && fplog)
295         {
296             fprintf(fplog, "WARNING: Your TPI molecule is not centered at 0,0,0\n");
297             fprintf(stderr, "WARNING: Your TPI molecule is not centered at 0,0,0\n");
298         }
299     }
300     else
301     {
302         /* Center the molecule to be inserted at zero */
303         for (i = 0; i < a_tp1-a_tp0; i++)
304         {
305             rvec_dec(x_mol[i], fr->cg_cm[cg_tp]);
306         }
307     }
308
309     if (fplog)
310     {
311         fprintf(fplog, "\nWill insert %d atoms %s partial charges\n",
312                 a_tp1-a_tp0, bCharge ? "with" : "without");
313
314         fprintf(fplog, "\nWill insert %d times in each frame of %s\n",
315                 nsteps, opt2fn("-rerun", nfile, fnm));
316     }
317
318     if (!bCavity)
319     {
320         if (inputrec->nstlist > 1)
321         {
322             if (drmax == 0 && a_tp1-a_tp0 == 1)
323             {
324                 gmx_fatal(FARGS, "Re-using the neighborlist %d times for insertions of a single atom in a sphere of radius %f does not make sense", inputrec->nstlist, drmax);
325             }
326             if (fplog)
327             {
328                 fprintf(fplog, "Will use the same neighborlist for %d insertions in a sphere of radius %f\n", inputrec->nstlist, drmax);
329             }
330         }
331     }
332     else
333     {
334         if (fplog)
335         {
336             fprintf(fplog, "Will insert randomly in a sphere of radius %f around the center of the cavity\n", drmax);
337         }
338     }
339
340     ngid   = groups->grps[egcENER].nr;
341     gid_tp = GET_CGINFO_GID(fr->cginfo[cg_tp]);
342     nener  = 1 + ngid;
343     if (bDispCorr)
344     {
345         nener += 1;
346     }
347     if (bCharge)
348     {
349         nener += ngid;
350         if (bRFExcl)
351         {
352             nener += 1;
353         }
354         if (EEL_FULL(fr->eeltype))
355         {
356             nener += 1;
357         }
358     }
359     snew(sum_UgembU, nener);
360
361     /* Initialize random generator */
362     tpi_rand = gmx_rng_init(inputrec->ld_seed);
363
364     if (MASTER(cr))
365     {
366         fp_tpi = xvgropen(opt2fn("-tpi", nfile, fnm),
367                           "TPI energies", "Time (ps)",
368                           "(kJ mol\\S-1\\N) / (nm\\S3\\N)", oenv);
369         xvgr_subtitle(fp_tpi, "f. are averages over one frame", oenv);
370         snew(leg, 4+nener);
371         e = 0;
372         sprintf(str, "-kT log(<Ve\\S-\\betaU\\N>/<V>)");
373         leg[e++] = strdup(str);
374         sprintf(str, "f. -kT log<e\\S-\\betaU\\N>");
375         leg[e++] = strdup(str);
376         sprintf(str, "f. <e\\S-\\betaU\\N>");
377         leg[e++] = strdup(str);
378         sprintf(str, "f. V");
379         leg[e++] = strdup(str);
380         sprintf(str, "f. <Ue\\S-\\betaU\\N>");
381         leg[e++] = strdup(str);
382         for (i = 0; i < ngid; i++)
383         {
384             sprintf(str, "f. <U\\sVdW %s\\Ne\\S-\\betaU\\N>",
385                     *(groups->grpname[groups->grps[egcENER].nm_ind[i]]));
386             leg[e++] = strdup(str);
387         }
388         if (bDispCorr)
389         {
390             sprintf(str, "f. <U\\sdisp c\\Ne\\S-\\betaU\\N>");
391             leg[e++] = strdup(str);
392         }
393         if (bCharge)
394         {
395             for (i = 0; i < ngid; i++)
396             {
397                 sprintf(str, "f. <U\\sCoul %s\\Ne\\S-\\betaU\\N>",
398                         *(groups->grpname[groups->grps[egcENER].nm_ind[i]]));
399                 leg[e++] = strdup(str);
400             }
401             if (bRFExcl)
402             {
403                 sprintf(str, "f. <U\\sRF excl\\Ne\\S-\\betaU\\N>");
404                 leg[e++] = strdup(str);
405             }
406             if (EEL_FULL(fr->eeltype))
407             {
408                 sprintf(str, "f. <U\\sCoul recip\\Ne\\S-\\betaU\\N>");
409                 leg[e++] = strdup(str);
410             }
411         }
412         xvgr_legend(fp_tpi, 4+nener, (const char**)leg, oenv);
413         for (i = 0; i < 4+nener; i++)
414         {
415             sfree(leg[i]);
416         }
417         sfree(leg);
418     }
419     clear_rvec(x_init);
420     V_all     = 0;
421     VembU_all = 0;
422
423     invbinw = 10;
424     nbin    = 10;
425     snew(bin, nbin);
426
427     bNotLastFrame = read_first_frame(oenv, &status, opt2fn("-rerun", nfile, fnm),
428                                      &rerun_fr, TRX_NEED_X);
429     frame = 0;
430
431     if (rerun_fr.natoms - (bCavity ? nat_cavity : 0) !=
432         mdatoms->nr - (a_tp1 - a_tp0))
433     {
434         gmx_fatal(FARGS, "Number of atoms in trajectory (%d)%s "
435                   "is not equal the number in the run input file (%d) "
436                   "minus the number of atoms to insert (%d)\n",
437                   rerun_fr.natoms, bCavity ? " minus one" : "",
438                   mdatoms->nr, a_tp1-a_tp0);
439     }
440
441     refvolshift = log(det(rerun_fr.box));
442
443 #ifdef GMX_X86_SSE2
444     /* Make sure we don't detect SSE overflow generated before this point */
445     gmx_mm_check_and_reset_overflow();
446 #endif
447
448     while (bNotLastFrame)
449     {
450         lambda = rerun_fr.lambda;
451         t      = rerun_fr.time;
452
453         sum_embU = 0;
454         for (e = 0; e < nener; e++)
455         {
456             sum_UgembU[e] = 0;
457         }
458
459         /* Copy the coordinates from the input trajectory */
460         for (i = 0; i < rerun_fr.natoms; i++)
461         {
462             copy_rvec(rerun_fr.x[i], state->x[i]);
463         }
464         copy_mat(rerun_fr.box, state->box);
465
466         V    = det(state->box);
467         logV = log(V);
468
469         bStateChanged = TRUE;
470         bNS           = TRUE;
471         for (step = 0; step < nsteps; step++)
472         {
473             /* In parallel all nodes generate all random configurations.
474              * In that way the result is identical to a single cpu tpi run.
475              */
476             if (!bCavity)
477             {
478                 /* Random insertion in the whole volume */
479                 bNS = (step % inputrec->nstlist == 0);
480                 if (bNS)
481                 {
482                     /* Generate a random position in the box */
483                     x_init[XX] = gmx_rng_uniform_real(tpi_rand)*state->box[XX][XX];
484                     x_init[YY] = gmx_rng_uniform_real(tpi_rand)*state->box[YY][YY];
485                     x_init[ZZ] = gmx_rng_uniform_real(tpi_rand)*state->box[ZZ][ZZ];
486                 }
487                 if (inputrec->nstlist == 1)
488                 {
489                     copy_rvec(x_init, x_tp);
490                 }
491                 else
492                 {
493                     /* Generate coordinates within |dx|=drmax of x_init */
494                     do
495                     {
496                         dx[XX] = (2*gmx_rng_uniform_real(tpi_rand) - 1)*drmax;
497                         dx[YY] = (2*gmx_rng_uniform_real(tpi_rand) - 1)*drmax;
498                         dx[ZZ] = (2*gmx_rng_uniform_real(tpi_rand) - 1)*drmax;
499                     }
500                     while (norm2(dx) > drmax*drmax);
501                     rvec_add(x_init, dx, x_tp);
502                 }
503             }
504             else
505             {
506                 /* Random insertion around a cavity location
507                  * given by the last coordinate of the trajectory.
508                  */
509                 if (step == 0)
510                 {
511                     if (nat_cavity == 1)
512                     {
513                         /* Copy the location of the cavity */
514                         copy_rvec(rerun_fr.x[rerun_fr.natoms-1], x_init);
515                     }
516                     else
517                     {
518                         /* Determine the center of mass of the last molecule */
519                         clear_rvec(x_init);
520                         mass_tot = 0;
521                         for (i = 0; i < nat_cavity; i++)
522                         {
523                             for (d = 0; d < DIM; d++)
524                             {
525                                 x_init[d] +=
526                                     mass_cavity[i]*rerun_fr.x[rerun_fr.natoms-nat_cavity+i][d];
527                             }
528                             mass_tot += mass_cavity[i];
529                         }
530                         for (d = 0; d < DIM; d++)
531                         {
532                             x_init[d] /= mass_tot;
533                         }
534                     }
535                 }
536                 /* Generate coordinates within |dx|=drmax of x_init */
537                 do
538                 {
539                     dx[XX] = (2*gmx_rng_uniform_real(tpi_rand) - 1)*drmax;
540                     dx[YY] = (2*gmx_rng_uniform_real(tpi_rand) - 1)*drmax;
541                     dx[ZZ] = (2*gmx_rng_uniform_real(tpi_rand) - 1)*drmax;
542                 }
543                 while (norm2(dx) > drmax*drmax);
544                 rvec_add(x_init, dx, x_tp);
545             }
546
547             if (a_tp1 - a_tp0 == 1)
548             {
549                 /* Insert a single atom, just copy the insertion location */
550                 copy_rvec(x_tp, state->x[a_tp0]);
551             }
552             else
553             {
554                 /* Copy the coordinates from the top file */
555                 for (i = a_tp0; i < a_tp1; i++)
556                 {
557                     copy_rvec(x_mol[i-a_tp0], state->x[i]);
558                 }
559                 /* Rotate the molecule randomly */
560                 rotate_conf(a_tp1-a_tp0, state->x+a_tp0, NULL,
561                             2*M_PI*gmx_rng_uniform_real(tpi_rand),
562                             2*M_PI*gmx_rng_uniform_real(tpi_rand),
563                             2*M_PI*gmx_rng_uniform_real(tpi_rand));
564                 /* Shift to the insertion location */
565                 for (i = a_tp0; i < a_tp1; i++)
566                 {
567                     rvec_inc(state->x[i], x_tp);
568                 }
569             }
570
571             /* Check if this insertion belongs to this node */
572             bOurStep = TRUE;
573             if (PAR(cr))
574             {
575                 switch (inputrec->eI)
576                 {
577                     case eiTPI:
578                         bOurStep = ((step / inputrec->nstlist) % nnodes == cr->nodeid);
579                         break;
580                     case eiTPIC:
581                         bOurStep = (step % nnodes == cr->nodeid);
582                         break;
583                     default:
584                         gmx_fatal(FARGS, "Unknown integrator %s", ei_names[inputrec->eI]);
585                 }
586             }
587             if (bOurStep)
588             {
589                 /* Clear some matrix variables  */
590                 clear_mat(force_vir);
591                 clear_mat(shake_vir);
592                 clear_mat(vir);
593                 clear_mat(pres);
594
595                 /* Set the charge group center of mass of the test particle */
596                 copy_rvec(x_init, fr->cg_cm[top->cgs.nr-1]);
597
598                 /* Calc energy (no forces) on new positions.
599                  * Since we only need the intermolecular energy
600                  * and the RF exclusion terms of the inserted molecule occur
601                  * within a single charge group we can pass NULL for the graph.
602                  * This also avoids shifts that would move charge groups
603                  * out of the box.
604                  *
605                  * Some checks above ensure than we can not have
606                  * twin-range interactions together with nstlist > 1,
607                  * therefore we do not need to remember the LR energies.
608                  */
609                 /* Make do_force do a single node force calculation */
610                 cr->nnodes = 1;
611                 do_force(fplog, cr, inputrec,
612                          step, nrnb, wcycle, top, top_global, &top_global->groups,
613                          state->box, state->x, &state->hist,
614                          f, force_vir, mdatoms, enerd, fcd,
615                          state->lambda,
616                          NULL, fr, NULL, mu_tot, t, NULL, NULL, FALSE,
617                          GMX_FORCE_NONBONDED | GMX_FORCE_ENERGY |
618                          (bNS ? GMX_FORCE_DYNAMICBOX | GMX_FORCE_NS | GMX_FORCE_DO_LR : 0) |
619                          (bStateChanged ? GMX_FORCE_STATECHANGED : 0));
620                 cr->nnodes    = nnodes;
621                 bStateChanged = FALSE;
622                 bNS           = FALSE;
623
624                 /* Calculate long range corrections to pressure and energy */
625                 calc_dispcorr(fplog, inputrec, fr, step, top_global->natoms, state->box,
626                               lambda, pres, vir, &prescorr, &enercorr, &dvdlcorr);
627                 /* figure out how to rearrange the next 4 lines MRS 8/4/2009 */
628                 enerd->term[F_DISPCORR]  = enercorr;
629                 enerd->term[F_EPOT]     += enercorr;
630                 enerd->term[F_PRES]     += prescorr;
631                 enerd->term[F_DVDL_VDW] += dvdlcorr;
632
633                 epot               = enerd->term[F_EPOT];
634                 bEnergyOutOfBounds = FALSE;
635 #ifdef GMX_X86_SSE2
636                 /* With SSE the energy can overflow, check for this */
637                 if (gmx_mm_check_and_reset_overflow())
638                 {
639                     if (debug)
640                     {
641                         fprintf(debug, "Found an SSE overflow, assuming the energy is out of bounds\n");
642                     }
643                     bEnergyOutOfBounds = TRUE;
644                 }
645 #endif
646                 /* If the compiler doesn't optimize this check away
647                  * we catch the NAN energies.
648                  * The epot>GMX_REAL_MAX check catches inf values,
649                  * which should nicely result in embU=0 through the exp below,
650                  * but it does not hurt to check anyhow.
651                  */
652                 /* Non-bonded Interaction usually diverge at r=0.
653                  * With tabulated interaction functions the first few entries
654                  * should be capped in a consistent fashion between
655                  * repulsion, dispersion and Coulomb to avoid accidental
656                  * negative values in the total energy.
657                  * The table generation code in tables.c does this.
658                  * With user tbales the user should take care of this.
659                  */
660                 if (epot != epot || epot > GMX_REAL_MAX)
661                 {
662                     bEnergyOutOfBounds = TRUE;
663                 }
664                 if (bEnergyOutOfBounds)
665                 {
666                     if (debug)
667                     {
668                         fprintf(debug, "\n  time %.3f, step %d: non-finite energy %f, using exp(-bU)=0\n", t, step, epot);
669                     }
670                     embU = 0;
671                 }
672                 else
673                 {
674                     embU      = exp(-beta*epot);
675                     sum_embU += embU;
676                     /* Determine the weighted energy contributions of each energy group */
677                     e                = 0;
678                     sum_UgembU[e++] += epot*embU;
679                     if (fr->bBHAM)
680                     {
681                         for (i = 0; i < ngid; i++)
682                         {
683                             sum_UgembU[e++] +=
684                                 (enerd->grpp.ener[egBHAMSR][GID(i, gid_tp, ngid)] +
685                                  enerd->grpp.ener[egBHAMLR][GID(i, gid_tp, ngid)])*embU;
686                         }
687                     }
688                     else
689                     {
690                         for (i = 0; i < ngid; i++)
691                         {
692                             sum_UgembU[e++] +=
693                                 (enerd->grpp.ener[egLJSR][GID(i, gid_tp, ngid)] +
694                                  enerd->grpp.ener[egLJLR][GID(i, gid_tp, ngid)])*embU;
695                         }
696                     }
697                     if (bDispCorr)
698                     {
699                         sum_UgembU[e++] += enerd->term[F_DISPCORR]*embU;
700                     }
701                     if (bCharge)
702                     {
703                         for (i = 0; i < ngid; i++)
704                         {
705                             sum_UgembU[e++] +=
706                                 (enerd->grpp.ener[egCOULSR][GID(i, gid_tp, ngid)] +
707                                  enerd->grpp.ener[egCOULLR][GID(i, gid_tp, ngid)])*embU;
708                         }
709                         if (bRFExcl)
710                         {
711                             sum_UgembU[e++] += enerd->term[F_RF_EXCL]*embU;
712                         }
713                         if (EEL_FULL(fr->eeltype))
714                         {
715                             sum_UgembU[e++] += enerd->term[F_COUL_RECIP]*embU;
716                         }
717                     }
718                 }
719
720                 if (embU == 0 || beta*epot > bU_bin_limit)
721                 {
722                     bin[0]++;
723                 }
724                 else
725                 {
726                     i = (int)((bU_logV_bin_limit
727                                - (beta*epot - logV + refvolshift))*invbinw
728                               + 0.5);
729                     if (i < 0)
730                     {
731                         i = 0;
732                     }
733                     if (i >= nbin)
734                     {
735                         realloc_bins(&bin, &nbin, i+10);
736                     }
737                     bin[i]++;
738                 }
739
740                 if (debug)
741                 {
742                     fprintf(debug, "TPI %7d %12.5e %12.5f %12.5f %12.5f\n",
743                             step, epot, x_tp[XX], x_tp[YY], x_tp[ZZ]);
744                 }
745
746                 if (dump_pdb && epot <= dump_ener)
747                 {
748                     sprintf(str, "t%g_step%d.pdb", t, step);
749                     sprintf(str2, "t: %f step %d ener: %f", t, step, epot);
750                     write_sto_conf_mtop(str, str2, top_global, state->x, state->v,
751                                         inputrec->ePBC, state->box);
752                 }
753             }
754         }
755
756         if (PAR(cr))
757         {
758             /* When running in parallel sum the energies over the processes */
759             gmx_sumd(1,    &sum_embU, cr);
760             gmx_sumd(nener, sum_UgembU, cr);
761         }
762
763         frame++;
764         V_all     += V;
765         VembU_all += V*sum_embU/nsteps;
766
767         if (fp_tpi)
768         {
769             if (bVerbose || frame%10 == 0 || frame < 10)
770             {
771                 fprintf(stderr, "mu %10.3e <mu> %10.3e\n",
772                         -log(sum_embU/nsteps)/beta, -log(VembU_all/V_all)/beta);
773             }
774
775             fprintf(fp_tpi, "%10.3f %12.5e %12.5e %12.5e %12.5e",
776                     t,
777                     VembU_all == 0 ? 20/beta : -log(VembU_all/V_all)/beta,
778                     sum_embU == 0  ? 20/beta : -log(sum_embU/nsteps)/beta,
779                     sum_embU/nsteps, V);
780             for (e = 0; e < nener; e++)
781             {
782                 fprintf(fp_tpi, " %12.5e", sum_UgembU[e]/nsteps);
783             }
784             fprintf(fp_tpi, "\n");
785             fflush(fp_tpi);
786         }
787
788         bNotLastFrame = read_next_frame(oenv, status, &rerun_fr);
789     } /* End of the loop  */
790     runtime_end(runtime);
791
792     close_trj(status);
793
794     if (fp_tpi != NULL)
795     {
796         gmx_fio_fclose(fp_tpi);
797     }
798
799     if (fplog != NULL)
800     {
801         fprintf(fplog, "\n");
802         fprintf(fplog, "  <V>  = %12.5e nm^3\n", V_all/frame);
803         fprintf(fplog, "  <mu> = %12.5e kJ/mol\n", -log(VembU_all/V_all)/beta);
804     }
805
806     /* Write the Boltzmann factor histogram */
807     if (PAR(cr))
808     {
809         /* When running in parallel sum the bins over the processes */
810         i = nbin;
811         global_max(cr, &i);
812         realloc_bins(&bin, &nbin, i);
813         gmx_sumd(nbin, bin, cr);
814     }
815     if (MASTER(cr))
816     {
817         fp_tpi = xvgropen(opt2fn("-tpid", nfile, fnm),
818                           "TPI energy distribution",
819                           "\\betaU - log(V/<V>)", "count", oenv);
820         sprintf(str, "number \\betaU > %g: %9.3e", bU_bin_limit, bin[0]);
821         xvgr_subtitle(fp_tpi, str, oenv);
822         xvgr_legend(fp_tpi, 2, (const char **)tpid_leg, oenv);
823         for (i = nbin-1; i > 0; i--)
824         {
825             bUlogV = -i/invbinw + bU_logV_bin_limit - refvolshift + log(V_all/frame);
826             fprintf(fp_tpi, "%6.2f %10d %12.5e\n",
827                     bUlogV,
828                     (int)(bin[i]+0.5),
829                     bin[i]*exp(-bUlogV)*V_all/VembU_all);
830         }
831         gmx_fio_fclose(fp_tpi);
832     }
833     sfree(bin);
834
835     sfree(sum_UgembU);
836
837     runtime->nsteps_done = frame*inputrec->nsteps;
838
839     return 0;
840 }