Moved random number generator code to separate dir.
[alexxy/gromacs.git] / src / gromacs / gmxpreprocess / grompp.c
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5  * Copyright (c) 2001-2004, The GROMACS development team.
6  * Copyright (c) 2013,2014, by the GROMACS development team, led by
7  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
8  * and including many others, as listed in the AUTHORS file in the
9  * top-level source directory and at http://www.gromacs.org.
10  *
11  * GROMACS is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public License
13  * as published by the Free Software Foundation; either version 2.1
14  * of the License, or (at your option) any later version.
15  *
16  * GROMACS is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with GROMACS; if not, see
23  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
24  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
25  *
26  * If you want to redistribute modifications to GROMACS, please
27  * consider that scientific software is very special. Version
28  * control is crucial - bugs must be traceable. We will be happy to
29  * consider code for inclusion in the official distribution, but
30  * derived work must not be called official GROMACS. Details are found
31  * in the README & COPYING files - if they are missing, get the
32  * official version at http://www.gromacs.org.
33  *
34  * To help us fund GROMACS development, we humbly ask that you cite
35  * the research papers on the package. Check out http://www.gromacs.org.
36  */
37 #include "grompp.h"
38
39 #ifdef HAVE_CONFIG_H
40 #include <config.h>
41 #endif
42
43 #include <sys/types.h>
44 #include <math.h>
45 #include <string.h>
46 #include <errno.h>
47 #include <limits.h>
48
49 #include "sysstuff.h"
50 #include "smalloc.h"
51 #include "macros.h"
52 #include "string2.h"
53 #include "readir.h"
54 #include "toputil.h"
55 #include "topio.h"
56 #include "gromacs/fileio/confio.h"
57 #include "readir.h"
58 #include "symtab.h"
59 #include "names.h"
60 #include "grompp-impl.h"
61 #include "gromacs/random/random.h"
62 #include "gromacs/gmxpreprocess/gen_maxwell_velocities.h"
63 #include "vec.h"
64 #include "gromacs/fileio/futil.h"
65 #include "gromacs/commandline/pargs.h"
66 #include "splitter.h"
67 #include "gromacs/gmxana/sortwater.h"
68 #include "convparm.h"
69 #include "gmx_fatal.h"
70 #include "warninp.h"
71 #include "index.h"
72 #include "gromacs/fileio/gmxfio.h"
73 #include "gromacs/fileio/trnio.h"
74 #include "gromacs/fileio/tpxio.h"
75 #include "gromacs/fileio/trxio.h"
76 #include "vsite_parm.h"
77 #include "txtdump.h"
78 #include "calcgrid.h"
79 #include "add_par.h"
80 #include "gromacs/fileio/enxio.h"
81 #include "perf_est.h"
82 #include "compute_io.h"
83 #include "gpp_atomtype.h"
84 #include "mtop_util.h"
85 #include "genborn.h"
86 #include "calc_verletbuf.h"
87
88 #include "tomorse.h"
89
90 static int rm_interactions(int ifunc, int nrmols, t_molinfo mols[])
91 {
92     int  i, n;
93
94     n = 0;
95     /* For all the molecule types */
96     for (i = 0; i < nrmols; i++)
97     {
98         n += mols[i].plist[ifunc].nr;
99         mols[i].plist[ifunc].nr = 0;
100     }
101     return n;
102 }
103
104 static int check_atom_names(const char *fn1, const char *fn2,
105                             gmx_mtop_t *mtop, t_atoms *at)
106 {
107     int      mb, m, i, j, nmismatch;
108     t_atoms *tat;
109 #define MAXMISMATCH 20
110
111     if (mtop->natoms != at->nr)
112     {
113         gmx_incons("comparing atom names");
114     }
115
116     nmismatch = 0;
117     i         = 0;
118     for (mb = 0; mb < mtop->nmolblock; mb++)
119     {
120         tat = &mtop->moltype[mtop->molblock[mb].type].atoms;
121         for (m = 0; m < mtop->molblock[mb].nmol; m++)
122         {
123             for (j = 0; j < tat->nr; j++)
124             {
125                 if (strcmp( *(tat->atomname[j]), *(at->atomname[i]) ) != 0)
126                 {
127                     if (nmismatch < MAXMISMATCH)
128                     {
129                         fprintf(stderr,
130                                 "Warning: atom name %d in %s and %s does not match (%s - %s)\n",
131                                 i+1, fn1, fn2, *(tat->atomname[j]), *(at->atomname[i]));
132                     }
133                     else if (nmismatch == MAXMISMATCH)
134                     {
135                         fprintf(stderr, "(more than %d non-matching atom names)\n", MAXMISMATCH);
136                     }
137                     nmismatch++;
138                 }
139                 i++;
140             }
141         }
142     }
143
144     return nmismatch;
145 }
146
147 static void check_eg_vs_cg(gmx_mtop_t *mtop)
148 {
149     int            astart, mb, m, cg, j, firstj;
150     unsigned char  firsteg, eg;
151     gmx_moltype_t *molt;
152
153     /* Go through all the charge groups and make sure all their
154      * atoms are in the same energy group.
155      */
156
157     astart = 0;
158     for (mb = 0; mb < mtop->nmolblock; mb++)
159     {
160         molt = &mtop->moltype[mtop->molblock[mb].type];
161         for (m = 0; m < mtop->molblock[mb].nmol; m++)
162         {
163             for (cg = 0; cg < molt->cgs.nr; cg++)
164             {
165                 /* Get the energy group of the first atom in this charge group */
166                 firstj  = astart + molt->cgs.index[cg];
167                 firsteg = ggrpnr(&mtop->groups, egcENER, firstj);
168                 for (j = molt->cgs.index[cg]+1; j < molt->cgs.index[cg+1]; j++)
169                 {
170                     eg = ggrpnr(&mtop->groups, egcENER, astart+j);
171                     if (eg != firsteg)
172                     {
173                         gmx_fatal(FARGS, "atoms %d and %d in charge group %d of molecule type '%s' are in different energy groups",
174                                   firstj+1, astart+j+1, cg+1, *molt->name);
175                     }
176                 }
177             }
178             astart += molt->atoms.nr;
179         }
180     }
181 }
182
183 static void check_cg_sizes(const char *topfn, t_block *cgs, warninp_t wi)
184 {
185     int  maxsize, cg;
186     char warn_buf[STRLEN];
187
188     maxsize = 0;
189     for (cg = 0; cg < cgs->nr; cg++)
190     {
191         maxsize = max(maxsize, cgs->index[cg+1]-cgs->index[cg]);
192     }
193
194     if (maxsize > MAX_CHARGEGROUP_SIZE)
195     {
196         gmx_fatal(FARGS, "The largest charge group contains %d atoms. The maximum is %d.", maxsize, MAX_CHARGEGROUP_SIZE);
197     }
198     else if (maxsize > 10)
199     {
200         set_warning_line(wi, topfn, -1);
201         sprintf(warn_buf,
202                 "The largest charge group contains %d atoms.\n"
203                 "Since atoms only see each other when the centers of geometry of the charge groups they belong to are within the cut-off distance, too large charge groups can lead to serious cut-off artifacts.\n"
204                 "For efficiency and accuracy, charge group should consist of a few atoms.\n"
205                 "For all-atom force fields use: CH3, CH2, CH, NH2, NH, OH, CO2, CO, etc.",
206                 maxsize);
207         warning_note(wi, warn_buf);
208     }
209 }
210
211 static void check_bonds_timestep(gmx_mtop_t *mtop, double dt, warninp_t wi)
212 {
213     /* This check is not intended to ensure accurate integration,
214      * rather it is to signal mistakes in the mdp settings.
215      * A common mistake is to forget to turn on constraints
216      * for MD after energy minimization with flexible bonds.
217      * This check can also detect too large time steps for flexible water
218      * models, but such errors will often be masked by the constraints
219      * mdp options, which turns flexible water into water with bond constraints,
220      * but without an angle constraint. Unfortunately such incorrect use
221      * of water models can not easily be detected without checking
222      * for specific model names.
223      *
224      * The stability limit of leap-frog or velocity verlet is 4.44 steps
225      * per oscillational period.
226      * But accurate bonds distributions are lost far before that limit.
227      * To allow relatively common schemes (although not common with Gromacs)
228      * of dt=1 fs without constraints and dt=2 fs with only H-bond constraints
229      * we set the note limit to 10.
230      */
231     int            min_steps_warn = 5;
232     int            min_steps_note = 10;
233     t_iparams     *ip;
234     int            molt;
235     gmx_moltype_t *moltype, *w_moltype;
236     t_atom        *atom;
237     t_ilist       *ilist, *ilb, *ilc, *ils;
238     int            ftype;
239     int            i, a1, a2, w_a1, w_a2, j;
240     real           twopi2, limit2, fc, re, m1, m2, period2, w_period2;
241     gmx_bool       bFound, bWater, bWarn;
242     char           warn_buf[STRLEN];
243
244     ip = mtop->ffparams.iparams;
245
246     twopi2 = sqr(2*M_PI);
247
248     limit2 = sqr(min_steps_note*dt);
249
250     w_a1      = w_a2 = -1;
251     w_period2 = -1.0;
252
253     w_moltype = NULL;
254     for (molt = 0; molt < mtop->nmoltype; molt++)
255     {
256         moltype = &mtop->moltype[molt];
257         atom    = moltype->atoms.atom;
258         ilist   = moltype->ilist;
259         ilc     = &ilist[F_CONSTR];
260         ils     = &ilist[F_SETTLE];
261         for (ftype = 0; ftype < F_NRE; ftype++)
262         {
263             if (!(ftype == F_BONDS || ftype == F_G96BONDS || ftype == F_HARMONIC))
264             {
265                 continue;
266             }
267
268             ilb = &ilist[ftype];
269             for (i = 0; i < ilb->nr; i += 3)
270             {
271                 fc = ip[ilb->iatoms[i]].harmonic.krA;
272                 re = ip[ilb->iatoms[i]].harmonic.rA;
273                 if (ftype == F_G96BONDS)
274                 {
275                     /* Convert squared sqaure fc to harmonic fc */
276                     fc = 2*fc*re;
277                 }
278                 a1 = ilb->iatoms[i+1];
279                 a2 = ilb->iatoms[i+2];
280                 m1 = atom[a1].m;
281                 m2 = atom[a2].m;
282                 if (fc > 0 && m1 > 0 && m2 > 0)
283                 {
284                     period2 = twopi2*m1*m2/((m1 + m2)*fc);
285                 }
286                 else
287                 {
288                     period2 = GMX_FLOAT_MAX;
289                 }
290                 if (debug)
291                 {
292                     fprintf(debug, "fc %g m1 %g m2 %g period %g\n",
293                             fc, m1, m2, sqrt(period2));
294                 }
295                 if (period2 < limit2)
296                 {
297                     bFound = FALSE;
298                     for (j = 0; j < ilc->nr; j += 3)
299                     {
300                         if ((ilc->iatoms[j+1] == a1 && ilc->iatoms[j+2] == a2) ||
301                             (ilc->iatoms[j+1] == a2 && ilc->iatoms[j+2] == a1))
302                         {
303                             bFound = TRUE;
304                         }
305                     }
306                     for (j = 0; j < ils->nr; j += 4)
307                     {
308                         if ((a1 == ils->iatoms[j+1] || a1 == ils->iatoms[j+2] || a1 == ils->iatoms[j+3]) &&
309                             (a2 == ils->iatoms[j+1] || a2 == ils->iatoms[j+2] || a2 == ils->iatoms[j+3]))
310                         {
311                             bFound = TRUE;
312                         }
313                     }
314                     if (!bFound &&
315                         (w_moltype == NULL || period2 < w_period2))
316                     {
317                         w_moltype = moltype;
318                         w_a1      = a1;
319                         w_a2      = a2;
320                         w_period2 = period2;
321                     }
322                 }
323             }
324         }
325     }
326
327     if (w_moltype != NULL)
328     {
329         bWarn = (w_period2 < sqr(min_steps_warn*dt));
330         /* A check that would recognize most water models */
331         bWater = ((*w_moltype->atoms.atomname[0])[0] == 'O' &&
332                   w_moltype->atoms.nr <= 5);
333         sprintf(warn_buf, "The bond in molecule-type %s between atoms %d %s and %d %s has an estimated oscillational period of %.1e ps, which is less than %d times the time step of %.1e ps.\n"
334                 "%s",
335                 *w_moltype->name,
336                 w_a1+1, *w_moltype->atoms.atomname[w_a1],
337                 w_a2+1, *w_moltype->atoms.atomname[w_a2],
338                 sqrt(w_period2), bWarn ? min_steps_warn : min_steps_note, dt,
339                 bWater ?
340                 "Maybe you asked for fexible water." :
341                 "Maybe you forgot to change the constraints mdp option.");
342         if (bWarn)
343         {
344             warning(wi, warn_buf);
345         }
346         else
347         {
348             warning_note(wi, warn_buf);
349         }
350     }
351 }
352
353 static void check_vel(gmx_mtop_t *mtop, rvec v[])
354 {
355     gmx_mtop_atomloop_all_t aloop;
356     t_atom                 *atom;
357     int                     a;
358
359     aloop = gmx_mtop_atomloop_all_init(mtop);
360     while (gmx_mtop_atomloop_all_next(aloop, &a, &atom))
361     {
362         if (atom->ptype == eptShell ||
363             atom->ptype == eptBond  ||
364             atom->ptype == eptVSite)
365         {
366             clear_rvec(v[a]);
367         }
368     }
369 }
370
371 static gmx_bool nint_ftype(gmx_mtop_t *mtop, t_molinfo *mi, int ftype)
372 {
373     int nint, mb;
374
375     nint = 0;
376     for (mb = 0; mb < mtop->nmolblock; mb++)
377     {
378         nint += mtop->molblock[mb].nmol*mi[mtop->molblock[mb].type].plist[ftype].nr;
379     }
380
381     return nint;
382 }
383
384 /* This routine reorders the molecule type array
385  * in the order of use in the molblocks,
386  * unused molecule types are deleted.
387  */
388 static void renumber_moltypes(gmx_mtop_t *sys,
389                               int *nmolinfo, t_molinfo **molinfo)
390 {
391     int       *order, norder, i;
392     int        mb, mi;
393     t_molinfo *minew;
394
395     snew(order, *nmolinfo);
396     norder = 0;
397     for (mb = 0; mb < sys->nmolblock; mb++)
398     {
399         for (i = 0; i < norder; i++)
400         {
401             if (order[i] == sys->molblock[mb].type)
402             {
403                 break;
404             }
405         }
406         if (i == norder)
407         {
408             /* This type did not occur yet, add it */
409             order[norder] = sys->molblock[mb].type;
410             /* Renumber the moltype in the topology */
411             norder++;
412         }
413         sys->molblock[mb].type = i;
414     }
415
416     /* We still need to reorder the molinfo structs */
417     snew(minew, norder);
418     for (mi = 0; mi < *nmolinfo; mi++)
419     {
420         for (i = 0; i < norder; i++)
421         {
422             if (order[i] == mi)
423             {
424                 break;
425             }
426         }
427         if (i == norder)
428         {
429             done_mi(&(*molinfo)[mi]);
430         }
431         else
432         {
433             minew[i] = (*molinfo)[mi];
434         }
435     }
436     sfree(*molinfo);
437
438     *nmolinfo = norder;
439     *molinfo  = minew;
440 }
441
442 static void molinfo2mtop(int nmi, t_molinfo *mi, gmx_mtop_t *mtop)
443 {
444     int            m;
445     gmx_moltype_t *molt;
446
447     mtop->nmoltype = nmi;
448     snew(mtop->moltype, nmi);
449     for (m = 0; m < nmi; m++)
450     {
451         molt        = &mtop->moltype[m];
452         molt->name  = mi[m].name;
453         molt->atoms = mi[m].atoms;
454         /* ilists are copied later */
455         molt->cgs   = mi[m].cgs;
456         molt->excls = mi[m].excls;
457     }
458 }
459
460 static void
461 new_status(const char *topfile, const char *topppfile, const char *confin,
462            t_gromppopts *opts, t_inputrec *ir, gmx_bool bZero,
463            gmx_bool bGenVel, gmx_bool bVerbose, t_state *state,
464            gpp_atomtype_t atype, gmx_mtop_t *sys,
465            int *nmi, t_molinfo **mi, t_params plist[],
466            int *comb, double *reppow, real *fudgeQQ,
467            gmx_bool bMorse,
468            warninp_t wi)
469 {
470     t_molinfo      *molinfo = NULL;
471     int             nmolblock;
472     gmx_molblock_t *molblock, *molbs;
473     t_atoms        *confat;
474     int             mb, i, nrmols, nmismatch;
475     char            buf[STRLEN];
476     gmx_bool        bGB = FALSE;
477     char            warn_buf[STRLEN];
478
479     init_mtop(sys);
480
481     /* Set gmx_boolean for GB */
482     if (ir->implicit_solvent)
483     {
484         bGB = TRUE;
485     }
486
487     /* TOPOLOGY processing */
488     sys->name = do_top(bVerbose, topfile, topppfile, opts, bZero, &(sys->symtab),
489                        plist, comb, reppow, fudgeQQ,
490                        atype, &nrmols, &molinfo, ir,
491                        &nmolblock, &molblock, bGB,
492                        wi);
493
494     sys->nmolblock = 0;
495     snew(sys->molblock, nmolblock);
496
497     sys->natoms = 0;
498     for (mb = 0; mb < nmolblock; mb++)
499     {
500         if (sys->nmolblock > 0 &&
501             molblock[mb].type == sys->molblock[sys->nmolblock-1].type)
502         {
503             /* Merge consecutive blocks with the same molecule type */
504             sys->molblock[sys->nmolblock-1].nmol += molblock[mb].nmol;
505             sys->natoms += molblock[mb].nmol*sys->molblock[sys->nmolblock-1].natoms_mol;
506         }
507         else if (molblock[mb].nmol > 0)
508         {
509             /* Add a new molblock to the topology */
510             molbs             = &sys->molblock[sys->nmolblock];
511             *molbs            = molblock[mb];
512             molbs->natoms_mol = molinfo[molbs->type].atoms.nr;
513             molbs->nposres_xA = 0;
514             molbs->nposres_xB = 0;
515             sys->natoms      += molbs->nmol*molbs->natoms_mol;
516             sys->nmolblock++;
517         }
518     }
519     if (sys->nmolblock == 0)
520     {
521         gmx_fatal(FARGS, "No molecules were defined in the system");
522     }
523
524     renumber_moltypes(sys, &nrmols, &molinfo);
525
526     if (bMorse)
527     {
528         convert_harmonics(nrmols, molinfo, atype);
529     }
530
531     if (ir->eDisre == edrNone)
532     {
533         i = rm_interactions(F_DISRES, nrmols, molinfo);
534         if (i > 0)
535         {
536             set_warning_line(wi, "unknown", -1);
537             sprintf(warn_buf, "disre = no, removed %d distance restraints", i);
538             warning_note(wi, warn_buf);
539         }
540     }
541     if (opts->bOrire == FALSE)
542     {
543         i = rm_interactions(F_ORIRES, nrmols, molinfo);
544         if (i > 0)
545         {
546             set_warning_line(wi, "unknown", -1);
547             sprintf(warn_buf, "orire = no, removed %d orientation restraints", i);
548             warning_note(wi, warn_buf);
549         }
550     }
551
552     /* Copy structures from msys to sys */
553     molinfo2mtop(nrmols, molinfo, sys);
554
555     gmx_mtop_finalize(sys);
556
557     /* COORDINATE file processing */
558     if (bVerbose)
559     {
560         fprintf(stderr, "processing coordinates...\n");
561     }
562
563     get_stx_coordnum(confin, &state->natoms);
564     if (state->natoms != sys->natoms)
565     {
566         gmx_fatal(FARGS, "number of coordinates in coordinate file (%s, %d)\n"
567                   "             does not match topology (%s, %d)",
568                   confin, state->natoms, topfile, sys->natoms);
569     }
570     else
571     {
572         /* make space for coordinates and velocities */
573         char title[STRLEN];
574         snew(confat, 1);
575         init_t_atoms(confat, state->natoms, FALSE);
576         init_state(state, state->natoms, 0, 0, 0, 0);
577         read_stx_conf(confin, title, confat, state->x, state->v, NULL, state->box);
578         /* This call fixes the box shape for runs with pressure scaling */
579         set_box_rel(ir, state);
580
581         nmismatch = check_atom_names(topfile, confin, sys, confat);
582         free_t_atoms(confat, TRUE);
583         sfree(confat);
584
585         if (nmismatch)
586         {
587             sprintf(buf, "%d non-matching atom name%s\n"
588                     "atom names from %s will be used\n"
589                     "atom names from %s will be ignored\n",
590                     nmismatch, (nmismatch == 1) ? "" : "s", topfile, confin);
591             warning(wi, buf);
592         }
593         if (bVerbose)
594         {
595             fprintf(stderr, "double-checking input for internal consistency...\n");
596         }
597         double_check(ir, state->box, nint_ftype(sys, molinfo, F_CONSTR), wi);
598     }
599
600     if (bGenVel)
601     {
602         real                   *mass;
603         gmx_mtop_atomloop_all_t aloop;
604         t_atom                 *atom;
605         unsigned int            useed;
606
607         snew(mass, state->natoms);
608         aloop = gmx_mtop_atomloop_all_init(sys);
609         while (gmx_mtop_atomloop_all_next(aloop, &i, &atom))
610         {
611             mass[i] = atom->m;
612         }
613
614         useed = opts->seed;
615         if (opts->seed == -1)
616         {
617             useed = (int)gmx_rng_make_seed();
618             fprintf(stderr, "Setting gen_seed to %u\n", useed);
619         }
620         maxwell_speed(opts->tempi, useed, sys, state->v);
621
622         stop_cm(stdout, state->natoms, mass, state->x, state->v);
623         sfree(mass);
624     }
625
626     *nmi = nrmols;
627     *mi  = molinfo;
628 }
629
630 static void copy_state(const char *slog, t_trxframe *fr,
631                        gmx_bool bReadVel, t_state *state,
632                        double *use_time)
633 {
634     int i;
635
636     if (fr->not_ok & FRAME_NOT_OK)
637     {
638         gmx_fatal(FARGS, "Can not start from an incomplete frame");
639     }
640     if (!fr->bX)
641     {
642         gmx_fatal(FARGS, "Did not find a frame with coordinates in file %s",
643                   slog);
644     }
645
646     for (i = 0; i < state->natoms; i++)
647     {
648         copy_rvec(fr->x[i], state->x[i]);
649     }
650     if (bReadVel)
651     {
652         if (!fr->bV)
653         {
654             gmx_incons("Trajecory frame unexpectedly does not contain velocities");
655         }
656         for (i = 0; i < state->natoms; i++)
657         {
658             copy_rvec(fr->v[i], state->v[i]);
659         }
660     }
661     if (fr->bBox)
662     {
663         copy_mat(fr->box, state->box);
664     }
665
666     *use_time = fr->time;
667 }
668
669 static void cont_status(const char *slog, const char *ener,
670                         gmx_bool bNeedVel, gmx_bool bGenVel, real fr_time,
671                         t_inputrec *ir, t_state *state,
672                         gmx_mtop_t *sys,
673                         const output_env_t oenv)
674 /* If fr_time == -1 read the last frame available which is complete */
675 {
676     gmx_bool     bReadVel;
677     t_trxframe   fr;
678     t_trxstatus *fp;
679     int          i;
680     double       use_time;
681
682     bReadVel = (bNeedVel && !bGenVel);
683
684     fprintf(stderr,
685             "Reading Coordinates%s and Box size from old trajectory\n",
686             bReadVel ? ", Velocities" : "");
687     if (fr_time == -1)
688     {
689         fprintf(stderr, "Will read whole trajectory\n");
690     }
691     else
692     {
693         fprintf(stderr, "Will read till time %g\n", fr_time);
694     }
695     if (!bReadVel)
696     {
697         if (bGenVel)
698         {
699             fprintf(stderr, "Velocities generated: "
700                     "ignoring velocities in input trajectory\n");
701         }
702         read_first_frame(oenv, &fp, slog, &fr, TRX_NEED_X);
703     }
704     else
705     {
706         read_first_frame(oenv, &fp, slog, &fr, TRX_NEED_X | TRX_NEED_V);
707
708         if (!fr.bV)
709         {
710             fprintf(stderr,
711                     "\n"
712                     "WARNING: Did not find a frame with velocities in file %s,\n"
713                     "         all velocities will be set to zero!\n\n", slog);
714             for (i = 0; i < sys->natoms; i++)
715             {
716                 clear_rvec(state->v[i]);
717             }
718             close_trj(fp);
719             /* Search for a frame without velocities */
720             bReadVel = FALSE;
721             read_first_frame(oenv, &fp, slog, &fr, TRX_NEED_X);
722         }
723     }
724
725     state->natoms = fr.natoms;
726
727     if (sys->natoms != state->natoms)
728     {
729         gmx_fatal(FARGS, "Number of atoms in Topology "
730                   "is not the same as in Trajectory");
731     }
732     copy_state(slog, &fr, bReadVel, state, &use_time);
733
734     /* Find the appropriate frame */
735     while ((fr_time == -1 || fr.time < fr_time) &&
736            read_next_frame(oenv, fp, &fr))
737     {
738         copy_state(slog, &fr, bReadVel, state, &use_time);
739     }
740
741     close_trj(fp);
742
743     /* Set the relative box lengths for preserving the box shape.
744      * Note that this call can lead to differences in the last bit
745      * with respect to using gmx convert-tpr to create a [TT].tpx[tt] file.
746      */
747     set_box_rel(ir, state);
748
749     fprintf(stderr, "Using frame at t = %g ps\n", use_time);
750     fprintf(stderr, "Starting time for run is %g ps\n", ir->init_t);
751
752     if ((ir->epc != epcNO  || ir->etc == etcNOSEHOOVER) && ener)
753     {
754         get_enx_state(ener, use_time, &sys->groups, ir, state);
755         preserve_box_shape(ir, state->box_rel, state->boxv);
756     }
757 }
758
759 static void read_posres(gmx_mtop_t *mtop, t_molinfo *molinfo, gmx_bool bTopB,
760                         char *fn,
761                         int rc_scaling, int ePBC,
762                         rvec com,
763                         warninp_t wi)
764 {
765     gmx_bool        bFirst = TRUE, *hadAtom;
766     rvec           *x, *v, *xp;
767     dvec            sum;
768     double          totmass;
769     t_atoms         dumat;
770     matrix          box, invbox;
771     int             natoms, npbcdim = 0;
772     char            warn_buf[STRLEN], title[STRLEN];
773     int             a, i, ai, j, k, mb, nat_molb;
774     gmx_molblock_t *molb;
775     t_params       *pr, *prfb;
776     t_atom         *atom;
777
778     get_stx_coordnum(fn, &natoms);
779     if (natoms != mtop->natoms)
780     {
781         sprintf(warn_buf, "The number of atoms in %s (%d) does not match the number of atoms in the topology (%d). Will assume that the first %d atoms in the topology and %s match.", fn, natoms, mtop->natoms, min(mtop->natoms, natoms), fn);
782         warning(wi, warn_buf);
783     }
784     snew(x, natoms);
785     snew(v, natoms);
786     init_t_atoms(&dumat, natoms, FALSE);
787     read_stx_conf(fn, title, &dumat, x, v, NULL, box);
788
789     npbcdim = ePBC2npbcdim(ePBC);
790     clear_rvec(com);
791     if (rc_scaling != erscNO)
792     {
793         copy_mat(box, invbox);
794         for (j = npbcdim; j < DIM; j++)
795         {
796             clear_rvec(invbox[j]);
797             invbox[j][j] = 1;
798         }
799         m_inv_ur0(invbox, invbox);
800     }
801
802     /* Copy the reference coordinates to mtop */
803     clear_dvec(sum);
804     totmass = 0;
805     a       = 0;
806     snew(hadAtom, natoms);
807     for (mb = 0; mb < mtop->nmolblock; mb++)
808     {
809         molb     = &mtop->molblock[mb];
810         nat_molb = molb->nmol*mtop->moltype[molb->type].atoms.nr;
811         pr       = &(molinfo[molb->type].plist[F_POSRES]);
812         prfb     = &(molinfo[molb->type].plist[F_FBPOSRES]);
813         if (pr->nr > 0 || prfb->nr > 0)
814         {
815             atom = mtop->moltype[molb->type].atoms.atom;
816             for (i = 0; (i < pr->nr); i++)
817             {
818                 ai = pr->param[i].AI;
819                 if (ai >= natoms)
820                 {
821                     gmx_fatal(FARGS, "Position restraint atom index (%d) in moltype '%s' is larger than number of atoms in %s (%d).\n",
822                               ai+1, *molinfo[molb->type].name, fn, natoms);
823                 }
824                 hadAtom[ai] = TRUE;
825                 if (rc_scaling == erscCOM)
826                 {
827                     /* Determine the center of mass of the posres reference coordinates */
828                     for (j = 0; j < npbcdim; j++)
829                     {
830                         sum[j] += atom[ai].m*x[a+ai][j];
831                     }
832                     totmass  += atom[ai].m;
833                 }
834             }
835             /* Same for flat-bottomed posres, but do not count an atom twice for COM */
836             for (i = 0; (i < prfb->nr); i++)
837             {
838                 ai = prfb->param[i].AI;
839                 if (ai >= natoms)
840                 {
841                     gmx_fatal(FARGS, "Position restraint atom index (%d) in moltype '%s' is larger than number of atoms in %s (%d).\n",
842                               ai+1, *molinfo[molb->type].name, fn, natoms);
843                 }
844                 if (rc_scaling == erscCOM && hadAtom[ai] == FALSE)
845                 {
846                     /* Determine the center of mass of the posres reference coordinates */
847                     for (j = 0; j < npbcdim; j++)
848                     {
849                         sum[j] += atom[ai].m*x[a+ai][j];
850                     }
851                     totmass  += atom[ai].m;
852                 }
853             }
854             if (!bTopB)
855             {
856                 molb->nposres_xA = nat_molb;
857                 snew(molb->posres_xA, molb->nposres_xA);
858                 for (i = 0; i < nat_molb; i++)
859                 {
860                     copy_rvec(x[a+i], molb->posres_xA[i]);
861                 }
862             }
863             else
864             {
865                 molb->nposres_xB = nat_molb;
866                 snew(molb->posres_xB, molb->nposres_xB);
867                 for (i = 0; i < nat_molb; i++)
868                 {
869                     copy_rvec(x[a+i], molb->posres_xB[i]);
870                 }
871             }
872         }
873         a += nat_molb;
874     }
875     if (rc_scaling == erscCOM)
876     {
877         if (totmass == 0)
878         {
879             gmx_fatal(FARGS, "The total mass of the position restraint atoms is 0");
880         }
881         for (j = 0; j < npbcdim; j++)
882         {
883             com[j] = sum[j]/totmass;
884         }
885         fprintf(stderr, "The center of mass of the position restraint coord's is %6.3f %6.3f %6.3f\n", com[XX], com[YY], com[ZZ]);
886     }
887
888     if (rc_scaling != erscNO)
889     {
890         for (mb = 0; mb < mtop->nmolblock; mb++)
891         {
892             molb     = &mtop->molblock[mb];
893             nat_molb = molb->nmol*mtop->moltype[molb->type].atoms.nr;
894             if (molb->nposres_xA > 0 || molb->nposres_xB > 0)
895             {
896                 xp = (!bTopB ? molb->posres_xA : molb->posres_xB);
897                 for (i = 0; i < nat_molb; i++)
898                 {
899                     for (j = 0; j < npbcdim; j++)
900                     {
901                         if (rc_scaling == erscALL)
902                         {
903                             /* Convert from Cartesian to crystal coordinates */
904                             xp[i][j] *= invbox[j][j];
905                             for (k = j+1; k < npbcdim; k++)
906                             {
907                                 xp[i][j] += invbox[k][j]*xp[i][k];
908                             }
909                         }
910                         else if (rc_scaling == erscCOM)
911                         {
912                             /* Subtract the center of mass */
913                             xp[i][j] -= com[j];
914                         }
915                     }
916                 }
917             }
918         }
919
920         if (rc_scaling == erscCOM)
921         {
922             /* Convert the COM from Cartesian to crystal coordinates */
923             for (j = 0; j < npbcdim; j++)
924             {
925                 com[j] *= invbox[j][j];
926                 for (k = j+1; k < npbcdim; k++)
927                 {
928                     com[j] += invbox[k][j]*com[k];
929                 }
930             }
931         }
932     }
933
934     free_t_atoms(&dumat, TRUE);
935     sfree(x);
936     sfree(v);
937     sfree(hadAtom);
938 }
939
940 static void gen_posres(gmx_mtop_t *mtop, t_molinfo *mi,
941                        char *fnA, char *fnB,
942                        int rc_scaling, int ePBC,
943                        rvec com, rvec comB,
944                        warninp_t wi)
945 {
946     int i, j;
947
948     read_posres  (mtop, mi, FALSE, fnA, rc_scaling, ePBC, com, wi);
949     if (strcmp(fnA, fnB) != 0)
950     {
951         read_posres(mtop, mi, TRUE, fnB, rc_scaling, ePBC, comB, wi);
952     }
953 }
954
955 static void set_wall_atomtype(gpp_atomtype_t at, t_gromppopts *opts,
956                               t_inputrec *ir, warninp_t wi)
957 {
958     int  i;
959     char warn_buf[STRLEN];
960
961     if (ir->nwall > 0)
962     {
963         fprintf(stderr, "Searching the wall atom type(s)\n");
964     }
965     for (i = 0; i < ir->nwall; i++)
966     {
967         ir->wall_atomtype[i] = get_atomtype_type(opts->wall_atomtype[i], at);
968         if (ir->wall_atomtype[i] == NOTSET)
969         {
970             sprintf(warn_buf, "Specified wall atom type %s is not defined", opts->wall_atomtype[i]);
971             warning_error(wi, warn_buf);
972         }
973     }
974 }
975
976 static int nrdf_internal(t_atoms *atoms)
977 {
978     int i, nmass, nrdf;
979
980     nmass = 0;
981     for (i = 0; i < atoms->nr; i++)
982     {
983         /* Vsite ptype might not be set here yet, so also check the mass */
984         if ((atoms->atom[i].ptype == eptAtom ||
985              atoms->atom[i].ptype == eptNucleus)
986             && atoms->atom[i].m > 0)
987         {
988             nmass++;
989         }
990     }
991     switch (nmass)
992     {
993         case 0:  nrdf = 0; break;
994         case 1:  nrdf = 0; break;
995         case 2:  nrdf = 1; break;
996         default: nrdf = nmass*3 - 6; break;
997     }
998
999     return nrdf;
1000 }
1001
1002 void
1003 spline1d( double        dx,
1004           double *      y,
1005           int           n,
1006           double *      u,
1007           double *      y2 )
1008 {
1009     int    i;
1010     double p, q;
1011
1012     y2[0] = 0.0;
1013     u[0]  = 0.0;
1014
1015     for (i = 1; i < n-1; i++)
1016     {
1017         p     = 0.5*y2[i-1]+2.0;
1018         y2[i] = -0.5/p;
1019         q     = (y[i+1]-2.0*y[i]+y[i-1])/dx;
1020         u[i]  = (3.0*q/dx-0.5*u[i-1])/p;
1021     }
1022
1023     y2[n-1] = 0.0;
1024
1025     for (i = n-2; i >= 0; i--)
1026     {
1027         y2[i] = y2[i]*y2[i+1]+u[i];
1028     }
1029 }
1030
1031
1032 void
1033 interpolate1d( double     xmin,
1034                double     dx,
1035                double *   ya,
1036                double *   y2a,
1037                double     x,
1038                double *   y,
1039                double *   y1)
1040 {
1041     int    ix;
1042     double a, b;
1043
1044     ix = (x-xmin)/dx;
1045
1046     a = (xmin+(ix+1)*dx-x)/dx;
1047     b = (x-xmin-ix*dx)/dx;
1048
1049     *y  = a*ya[ix]+b*ya[ix+1]+((a*a*a-a)*y2a[ix]+(b*b*b-b)*y2a[ix+1])*(dx*dx)/6.0;
1050     *y1 = (ya[ix+1]-ya[ix])/dx-(3.0*a*a-1.0)/6.0*dx*y2a[ix]+(3.0*b*b-1.0)/6.0*dx*y2a[ix+1];
1051 }
1052
1053
1054 void
1055 setup_cmap (int              grid_spacing,
1056             int              nc,
1057             real *           grid,
1058             gmx_cmap_t *     cmap_grid)
1059 {
1060     double *tmp_u, *tmp_u2, *tmp_yy, *tmp_y1, *tmp_t2, *tmp_grid;
1061
1062     int     i, j, k, ii, jj, kk, idx;
1063     int     offset;
1064     double  dx, xmin, v, v1, v2, v12;
1065     double  phi, psi;
1066
1067     snew(tmp_u, 2*grid_spacing);
1068     snew(tmp_u2, 2*grid_spacing);
1069     snew(tmp_yy, 2*grid_spacing);
1070     snew(tmp_y1, 2*grid_spacing);
1071     snew(tmp_t2, 2*grid_spacing*2*grid_spacing);
1072     snew(tmp_grid, 2*grid_spacing*2*grid_spacing);
1073
1074     dx   = 360.0/grid_spacing;
1075     xmin = -180.0-dx*grid_spacing/2;
1076
1077     for (kk = 0; kk < nc; kk++)
1078     {
1079         /* Compute an offset depending on which cmap we are using
1080          * Offset will be the map number multiplied with the
1081          * grid_spacing * grid_spacing * 2
1082          */
1083         offset = kk * grid_spacing * grid_spacing * 2;
1084
1085         for (i = 0; i < 2*grid_spacing; i++)
1086         {
1087             ii = (i+grid_spacing-grid_spacing/2)%grid_spacing;
1088
1089             for (j = 0; j < 2*grid_spacing; j++)
1090             {
1091                 jj = (j+grid_spacing-grid_spacing/2)%grid_spacing;
1092                 tmp_grid[i*grid_spacing*2+j] = grid[offset+ii*grid_spacing+jj];
1093             }
1094         }
1095
1096         for (i = 0; i < 2*grid_spacing; i++)
1097         {
1098             spline1d(dx, &(tmp_grid[2*grid_spacing*i]), 2*grid_spacing, tmp_u, &(tmp_t2[2*grid_spacing*i]));
1099         }
1100
1101         for (i = grid_spacing/2; i < grid_spacing+grid_spacing/2; i++)
1102         {
1103             ii  = i-grid_spacing/2;
1104             phi = ii*dx-180.0;
1105
1106             for (j = grid_spacing/2; j < grid_spacing+grid_spacing/2; j++)
1107             {
1108                 jj  = j-grid_spacing/2;
1109                 psi = jj*dx-180.0;
1110
1111                 for (k = 0; k < 2*grid_spacing; k++)
1112                 {
1113                     interpolate1d(xmin, dx, &(tmp_grid[2*grid_spacing*k]),
1114                                   &(tmp_t2[2*grid_spacing*k]), psi, &tmp_yy[k], &tmp_y1[k]);
1115                 }
1116
1117                 spline1d(dx, tmp_yy, 2*grid_spacing, tmp_u, tmp_u2);
1118                 interpolate1d(xmin, dx, tmp_yy, tmp_u2, phi, &v, &v1);
1119                 spline1d(dx, tmp_y1, 2*grid_spacing, tmp_u, tmp_u2);
1120                 interpolate1d(xmin, dx, tmp_y1, tmp_u2, phi, &v2, &v12);
1121
1122                 idx = ii*grid_spacing+jj;
1123                 cmap_grid->cmapdata[kk].cmap[idx*4]   = grid[offset+ii*grid_spacing+jj];
1124                 cmap_grid->cmapdata[kk].cmap[idx*4+1] = v1;
1125                 cmap_grid->cmapdata[kk].cmap[idx*4+2] = v2;
1126                 cmap_grid->cmapdata[kk].cmap[idx*4+3] = v12;
1127             }
1128         }
1129     }
1130 }
1131
1132 void init_cmap_grid(gmx_cmap_t *cmap_grid, int ngrid, int grid_spacing)
1133 {
1134     int i, k, nelem;
1135
1136     cmap_grid->ngrid        = ngrid;
1137     cmap_grid->grid_spacing = grid_spacing;
1138     nelem                   = cmap_grid->grid_spacing*cmap_grid->grid_spacing;
1139
1140     snew(cmap_grid->cmapdata, ngrid);
1141
1142     for (i = 0; i < cmap_grid->ngrid; i++)
1143     {
1144         snew(cmap_grid->cmapdata[i].cmap, 4*nelem);
1145     }
1146 }
1147
1148
1149 static int count_constraints(gmx_mtop_t *mtop, t_molinfo *mi, warninp_t wi)
1150 {
1151     int             count, count_mol, i, mb;
1152     gmx_molblock_t *molb;
1153     t_params       *plist;
1154     char            buf[STRLEN];
1155
1156     count = 0;
1157     for (mb = 0; mb < mtop->nmolblock; mb++)
1158     {
1159         count_mol = 0;
1160         molb      = &mtop->molblock[mb];
1161         plist     = mi[molb->type].plist;
1162
1163         for (i = 0; i < F_NRE; i++)
1164         {
1165             if (i == F_SETTLE)
1166             {
1167                 count_mol += 3*plist[i].nr;
1168             }
1169             else if (interaction_function[i].flags & IF_CONSTRAINT)
1170             {
1171                 count_mol += plist[i].nr;
1172             }
1173         }
1174
1175         if (count_mol > nrdf_internal(&mi[molb->type].atoms))
1176         {
1177             sprintf(buf,
1178                     "Molecule type '%s' has %d constraints.\n"
1179                     "For stability and efficiency there should not be more constraints than internal number of degrees of freedom: %d.\n",
1180                     *mi[molb->type].name, count_mol,
1181                     nrdf_internal(&mi[molb->type].atoms));
1182             warning(wi, buf);
1183         }
1184         count += molb->nmol*count_mol;
1185     }
1186
1187     return count;
1188 }
1189
1190 static void check_gbsa_params_charged(gmx_mtop_t *sys, gpp_atomtype_t atype)
1191 {
1192     int            i, nmiss, natoms, mt;
1193     real           q;
1194     const t_atoms *atoms;
1195
1196     nmiss = 0;
1197     for (mt = 0; mt < sys->nmoltype; mt++)
1198     {
1199         atoms  = &sys->moltype[mt].atoms;
1200         natoms = atoms->nr;
1201
1202         for (i = 0; i < natoms; i++)
1203         {
1204             q = atoms->atom[i].q;
1205             if ((get_atomtype_radius(atoms->atom[i].type, atype)    == 0  ||
1206                  get_atomtype_vol(atoms->atom[i].type, atype)       == 0  ||
1207                  get_atomtype_surftens(atoms->atom[i].type, atype)  == 0  ||
1208                  get_atomtype_gb_radius(atoms->atom[i].type, atype) == 0  ||
1209                  get_atomtype_S_hct(atoms->atom[i].type, atype)     == 0) &&
1210                 q != 0)
1211             {
1212                 fprintf(stderr, "\nGB parameter(s) zero for atom type '%s' while charge is %g\n",
1213                         get_atomtype_name(atoms->atom[i].type, atype), q);
1214                 nmiss++;
1215             }
1216         }
1217     }
1218
1219     if (nmiss > 0)
1220     {
1221         gmx_fatal(FARGS, "Can't do GB electrostatics; the implicit_genborn_params section of the forcefield has parameters with value zero for %d atomtypes that occur as charged atoms.", nmiss);
1222     }
1223 }
1224
1225
1226 static void check_gbsa_params(gpp_atomtype_t atype)
1227 {
1228     int  nmiss, i;
1229
1230     /* If we are doing GBSA, check that we got the parameters we need
1231      * This checking is to see if there are GBSA paratmeters for all
1232      * atoms in the force field. To go around this for testing purposes
1233      * comment out the nerror++ counter temporarily
1234      */
1235     nmiss = 0;
1236     for (i = 0; i < get_atomtype_ntypes(atype); i++)
1237     {
1238         if (get_atomtype_radius(i, atype)    < 0 ||
1239             get_atomtype_vol(i, atype)       < 0 ||
1240             get_atomtype_surftens(i, atype)  < 0 ||
1241             get_atomtype_gb_radius(i, atype) < 0 ||
1242             get_atomtype_S_hct(i, atype)     < 0)
1243         {
1244             fprintf(stderr, "\nGB parameter(s) missing or negative for atom type '%s'\n",
1245                     get_atomtype_name(i, atype));
1246             nmiss++;
1247         }
1248     }
1249
1250     if (nmiss > 0)
1251     {
1252         gmx_fatal(FARGS, "Can't do GB electrostatics; the implicit_genborn_params section of the forcefield is missing parameters for %d atomtypes or they might be negative.", nmiss);
1253     }
1254
1255 }
1256
1257 static void set_verlet_buffer(const gmx_mtop_t *mtop,
1258                               t_inputrec       *ir,
1259                               matrix            box,
1260                               warninp_t         wi)
1261 {
1262     real                   ref_T;
1263     int                    i;
1264     verletbuf_list_setup_t ls;
1265     real                   rlist_1x1;
1266     int                    n_nonlin_vsite;
1267     char                   warn_buf[STRLEN];
1268
1269     ref_T = 0;
1270     for (i = 0; i < ir->opts.ngtc; i++)
1271     {
1272         if (ir->opts.ref_t[i] < 0)
1273         {
1274             warning(wi, "Some atom groups do not use temperature coupling. This cannot be accounted for in the energy error estimation for the Verlet buffer size. The energy error and the Verlet buffer might be underestimated.");
1275         }
1276         else
1277         {
1278             ref_T = max(ref_T, ir->opts.ref_t[i]);
1279         }
1280     }
1281
1282     printf("Determining Verlet buffer for a tolerance of %g kJ/mol/ps at %g K\n", ir->verletbuf_tol, ref_T);
1283
1284     for (i = 0; i < ir->opts.ngtc; i++)
1285     {
1286         if (ir->opts.ref_t[i] >= 0 && ir->opts.ref_t[i] != ref_T)
1287         {
1288             sprintf(warn_buf, "ref_T for group of %.1f DOFs is %g K, which is smaller than the maximum of %g K used for the buffer size calculation. The buffer size might be on the conservative (large) side.",
1289                     ir->opts.nrdf[i], ir->opts.ref_t[i], ref_T);
1290             warning_note(wi, warn_buf);
1291         }
1292     }
1293
1294     /* Calculate the buffer size for simple atom vs atoms list */
1295     ls.cluster_size_i = 1;
1296     ls.cluster_size_j = 1;
1297     calc_verlet_buffer_size(mtop, det(box), ir,
1298                             &ls, &n_nonlin_vsite, &rlist_1x1);
1299
1300     /* Set the pair-list buffer size in ir */
1301     verletbuf_get_list_setup(FALSE, &ls);
1302     calc_verlet_buffer_size(mtop, det(box), ir,
1303                             &ls, &n_nonlin_vsite, &ir->rlist);
1304
1305     if (n_nonlin_vsite > 0)
1306     {
1307         sprintf(warn_buf, "There are %d non-linear virtual site constructions. Their contribution to the energy error is approximated. In most cases this does not affect the error significantly.", n_nonlin_vsite);
1308         warning_note(wi, warn_buf);
1309     }
1310
1311     printf("Calculated rlist for %dx%d atom pair-list as %.3f nm, buffer size %.3f nm\n",
1312            1, 1, rlist_1x1, rlist_1x1-max(ir->rvdw, ir->rcoulomb));
1313
1314     ir->rlistlong = ir->rlist;
1315     printf("Set rlist, assuming %dx%d atom pair-list, to %.3f nm, buffer size %.3f nm\n",
1316            ls.cluster_size_i, ls.cluster_size_j,
1317            ir->rlist, ir->rlist-max(ir->rvdw, ir->rcoulomb));
1318
1319     if (sqr(ir->rlistlong) >= max_cutoff2(ir->ePBC, box))
1320     {
1321         gmx_fatal(FARGS, "The pair-list cut-off (%g nm) is longer than half the shortest box vector or longer than the smallest box diagonal element (%g nm). Increase the box size or decrease nstlist or increase verlet-buffer-tolerance.", ir->rlistlong, sqrt(max_cutoff2(ir->ePBC, box)));
1322     }
1323 }
1324
1325 int gmx_grompp(int argc, char *argv[])
1326 {
1327     static const char *desc[] = {
1328         "[THISMODULE] (the gromacs preprocessor)",
1329         "reads a molecular topology file, checks the validity of the",
1330         "file, expands the topology from a molecular description to an atomic",
1331         "description. The topology file contains information about",
1332         "molecule types and the number of molecules, the preprocessor",
1333         "copies each molecule as needed. ",
1334         "There is no limitation on the number of molecule types. ",
1335         "Bonds and bond-angles can be converted into constraints, separately",
1336         "for hydrogens and heavy atoms.",
1337         "Then a coordinate file is read and velocities can be generated",
1338         "from a Maxwellian distribution if requested.",
1339         "[THISMODULE] also reads parameters for [gmx-mdrun] ",
1340         "(eg. number of MD steps, time step, cut-off), and others such as",
1341         "NEMD parameters, which are corrected so that the net acceleration",
1342         "is zero.",
1343         "Eventually a binary file is produced that can serve as the sole input",
1344         "file for the MD program.[PAR]",
1345
1346         "[THISMODULE] uses the atom names from the topology file. The atom names",
1347         "in the coordinate file (option [TT]-c[tt]) are only read to generate",
1348         "warnings when they do not match the atom names in the topology.",
1349         "Note that the atom names are irrelevant for the simulation as",
1350         "only the atom types are used for generating interaction parameters.[PAR]",
1351
1352         "[THISMODULE] uses a built-in preprocessor to resolve includes, macros, ",
1353         "etc. The preprocessor supports the following keywords:[PAR]",
1354         "#ifdef VARIABLE[BR]",
1355         "#ifndef VARIABLE[BR]",
1356         "#else[BR]",
1357         "#endif[BR]",
1358         "#define VARIABLE[BR]",
1359         "#undef VARIABLE[BR]"
1360         "#include \"filename\"[BR]",
1361         "#include <filename>[PAR]",
1362         "The functioning of these statements in your topology may be modulated by",
1363         "using the following two flags in your [TT].mdp[tt] file:[PAR]",
1364         "[TT]define = -DVARIABLE1 -DVARIABLE2[BR]",
1365         "include = -I/home/john/doe[tt][BR]",
1366         "For further information a C-programming textbook may help you out.",
1367         "Specifying the [TT]-pp[tt] flag will get the pre-processed",
1368         "topology file written out so that you can verify its contents.[PAR]",
1369
1370         /* cpp has been unnecessary for some time, hasn't it?
1371             "If your system does not have a C-preprocessor, you can still",
1372             "use [TT]grompp[tt], but you do not have access to the features ",
1373             "from the cpp. Command line options to the C-preprocessor can be given",
1374             "in the [TT].mdp[tt] file. See your local manual (man cpp).[PAR]",
1375          */
1376
1377         "When using position restraints a file with restraint coordinates",
1378         "can be supplied with [TT]-r[tt], otherwise restraining will be done",
1379         "with respect to the conformation from the [TT]-c[tt] option.",
1380         "For free energy calculation the the coordinates for the B topology",
1381         "can be supplied with [TT]-rb[tt], otherwise they will be equal to",
1382         "those of the A topology.[PAR]",
1383
1384         "Starting coordinates can be read from trajectory with [TT]-t[tt].",
1385         "The last frame with coordinates and velocities will be read,",
1386         "unless the [TT]-time[tt] option is used. Only if this information",
1387         "is absent will the coordinates in the [TT]-c[tt] file be used.",
1388         "Note that these velocities will not be used when [TT]gen_vel = yes[tt]",
1389         "in your [TT].mdp[tt] file. An energy file can be supplied with",
1390         "[TT]-e[tt] to read Nose-Hoover and/or Parrinello-Rahman coupling",
1391         "variables.[PAR]",
1392
1393         "[THISMODULE] can be used to restart simulations (preserving",
1394         "continuity) by supplying just a checkpoint file with [TT]-t[tt].",
1395         "However, for simply changing the number of run steps to extend",
1396         "a run, using [gmx-convert-tpr] is more convenient than [THISMODULE].",
1397         "You then supply the old checkpoint file directly to [gmx-mdrun]",
1398         "with [TT]-cpi[tt]. If you wish to change the ensemble or things",
1399         "like output frequency, then supplying the checkpoint file to",
1400         "[THISMODULE] with [TT]-t[tt] along with a new [TT].mdp[tt] file",
1401         "with [TT]-f[tt] is the recommended procedure.[PAR]",
1402
1403         "By default, all bonded interactions which have constant energy due to",
1404         "virtual site constructions will be removed. If this constant energy is",
1405         "not zero, this will result in a shift in the total energy. All bonded",
1406         "interactions can be kept by turning off [TT]-rmvsbds[tt]. Additionally,",
1407         "all constraints for distances which will be constant anyway because",
1408         "of virtual site constructions will be removed. If any constraints remain",
1409         "which involve virtual sites, a fatal error will result.[PAR]"
1410
1411         "To verify your run input file, please take note of all warnings",
1412         "on the screen, and correct where necessary. Do also look at the contents",
1413         "of the [TT]mdout.mdp[tt] file; this contains comment lines, as well as",
1414         "the input that [THISMODULE] has read. If in doubt, you can start [THISMODULE]",
1415         "with the [TT]-debug[tt] option which will give you more information",
1416         "in a file called [TT]grompp.log[tt] (along with real debug info). You",
1417         "can see the contents of the run input file with the [gmx-dump]",
1418         "program. [gmx-check] can be used to compare the contents of two",
1419         "run input files.[PAR]"
1420
1421         "The [TT]-maxwarn[tt] option can be used to override warnings printed",
1422         "by [THISMODULE] that otherwise halt output. In some cases, warnings are",
1423         "harmless, but usually they are not. The user is advised to carefully",
1424         "interpret the output messages before attempting to bypass them with",
1425         "this option."
1426     };
1427     t_gromppopts      *opts;
1428     gmx_mtop_t        *sys;
1429     int                nmi;
1430     t_molinfo         *mi;
1431     gpp_atomtype_t     atype;
1432     t_inputrec        *ir;
1433     int                natoms, nvsite, comb, mt;
1434     t_params          *plist;
1435     t_state            state;
1436     matrix             box;
1437     real               max_spacing, fudgeQQ;
1438     double             reppow;
1439     char               fn[STRLEN], fnB[STRLEN];
1440     const char        *mdparin;
1441     int                ntype;
1442     gmx_bool           bNeedVel, bGenVel;
1443     gmx_bool           have_atomnumber;
1444     int                n12, n13, n14;
1445     t_params          *gb_plist = NULL;
1446     gmx_genborn_t     *born     = NULL;
1447     output_env_t       oenv;
1448     gmx_bool           bVerbose = FALSE;
1449     warninp_t          wi;
1450     char               warn_buf[STRLEN];
1451     unsigned int       useed;
1452
1453     t_filenm           fnm[] = {
1454         { efMDP, NULL,  NULL,        ffREAD  },
1455         { efMDP, "-po", "mdout",     ffWRITE },
1456         { efSTX, "-c",  NULL,        ffREAD  },
1457         { efSTX, "-r",  NULL,        ffOPTRD },
1458         { efSTX, "-rb", NULL,        ffOPTRD },
1459         { efNDX, NULL,  NULL,        ffOPTRD },
1460         { efTOP, NULL,  NULL,        ffREAD  },
1461         { efTOP, "-pp", "processed", ffOPTWR },
1462         { efTPX, "-o",  NULL,        ffWRITE },
1463         { efTRN, "-t",  NULL,        ffOPTRD },
1464         { efEDR, "-e",  NULL,        ffOPTRD },
1465         { efTRN, "-ref", "rotref",    ffOPTRW }
1466     };
1467 #define NFILE asize(fnm)
1468
1469     /* Command line options */
1470     static gmx_bool bRenum   = TRUE;
1471     static gmx_bool bRmVSBds = TRUE, bZero = FALSE;
1472     static int      i, maxwarn = 0;
1473     static real     fr_time = -1;
1474     t_pargs         pa[]    = {
1475         { "-v",       FALSE, etBOOL, {&bVerbose},
1476           "Be loud and noisy" },
1477         { "-time",    FALSE, etREAL, {&fr_time},
1478           "Take frame at or first after this time." },
1479         { "-rmvsbds", FALSE, etBOOL, {&bRmVSBds},
1480           "Remove constant bonded interactions with virtual sites" },
1481         { "-maxwarn", FALSE, etINT,  {&maxwarn},
1482           "Number of allowed warnings during input processing. Not for normal use and may generate unstable systems" },
1483         { "-zero",    FALSE, etBOOL, {&bZero},
1484           "Set parameters for bonded interactions without defaults to zero instead of generating an error" },
1485         { "-renum",   FALSE, etBOOL, {&bRenum},
1486           "Renumber atomtypes and minimize number of atomtypes" }
1487     };
1488
1489     /* Initiate some variables */
1490     snew(ir, 1);
1491     snew(opts, 1);
1492     init_ir(ir, opts);
1493
1494     /* Parse the command line */
1495     if (!parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa), pa,
1496                            asize(desc), desc, 0, NULL, &oenv))
1497     {
1498         return 0;
1499     }
1500
1501     wi = init_warning(TRUE, maxwarn);
1502
1503     /* PARAMETER file processing */
1504     mdparin = opt2fn("-f", NFILE, fnm);
1505     set_warning_line(wi, mdparin, -1);
1506     get_ir(mdparin, opt2fn("-po", NFILE, fnm), ir, opts, wi);
1507
1508     if (bVerbose)
1509     {
1510         fprintf(stderr, "checking input for internal consistency...\n");
1511     }
1512     check_ir(mdparin, ir, opts, wi);
1513
1514     if (ir->ld_seed == -1)
1515     {
1516         ir->ld_seed = (int)gmx_rng_make_seed();
1517         fprintf(stderr, "Setting the LD random seed to %d\n", ir->ld_seed);
1518     }
1519
1520     if (ir->expandedvals->lmc_seed == -1)
1521     {
1522         ir->expandedvals->lmc_seed = (int)gmx_rng_make_seed();
1523         fprintf(stderr, "Setting the lambda MC random seed to %d\n", ir->expandedvals->lmc_seed);
1524     }
1525
1526     bNeedVel = EI_STATE_VELOCITY(ir->eI);
1527     bGenVel  = (bNeedVel && opts->bGenVel);
1528     if (bGenVel && ir->bContinuation)
1529     {
1530         sprintf(warn_buf,
1531                 "Generating velocities is inconsistent with attempting "
1532                 "to continue a previous run. Choose only one of "
1533                 "gen-vel = yes and continuation = yes.");
1534         warning_error(wi, warn_buf);
1535     }
1536
1537     snew(plist, F_NRE);
1538     init_plist(plist);
1539     snew(sys, 1);
1540     atype = init_atomtype();
1541     if (debug)
1542     {
1543         pr_symtab(debug, 0, "Just opened", &sys->symtab);
1544     }
1545
1546     strcpy(fn, ftp2fn(efTOP, NFILE, fnm));
1547     if (!gmx_fexist(fn))
1548     {
1549         gmx_fatal(FARGS, "%s does not exist", fn);
1550     }
1551     new_status(fn, opt2fn_null("-pp", NFILE, fnm), opt2fn("-c", NFILE, fnm),
1552                opts, ir, bZero, bGenVel, bVerbose, &state,
1553                atype, sys, &nmi, &mi, plist, &comb, &reppow, &fudgeQQ,
1554                opts->bMorse,
1555                wi);
1556
1557     if (debug)
1558     {
1559         pr_symtab(debug, 0, "After new_status", &sys->symtab);
1560     }
1561
1562     nvsite = 0;
1563     /* set parameters for virtual site construction (not for vsiten) */
1564     for (mt = 0; mt < sys->nmoltype; mt++)
1565     {
1566         nvsite +=
1567             set_vsites(bVerbose, &sys->moltype[mt].atoms, atype, mi[mt].plist);
1568     }
1569     /* now throw away all obsolete bonds, angles and dihedrals: */
1570     /* note: constraints are ALWAYS removed */
1571     if (nvsite)
1572     {
1573         for (mt = 0; mt < sys->nmoltype; mt++)
1574         {
1575             clean_vsite_bondeds(mi[mt].plist, sys->moltype[mt].atoms.nr, bRmVSBds);
1576         }
1577     }
1578
1579     if (ir->cutoff_scheme == ecutsVERLET)
1580     {
1581         fprintf(stderr, "Removing all charge groups because cutoff-scheme=%s\n",
1582                 ecutscheme_names[ir->cutoff_scheme]);
1583
1584         /* Remove all charge groups */
1585         gmx_mtop_remove_chargegroups(sys);
1586
1587         if (EVDW_PME(ir->vdwtype))
1588         {
1589             gmx_fatal(FARGS, "LJ-PME not implemented together with verlet-scheme!");
1590         }
1591     }
1592
1593     if (count_constraints(sys, mi, wi) && (ir->eConstrAlg == econtSHAKE))
1594     {
1595         if (ir->eI == eiCG || ir->eI == eiLBFGS)
1596         {
1597             sprintf(warn_buf, "Can not do %s with %s, use %s",
1598                     EI(ir->eI), econstr_names[econtSHAKE], econstr_names[econtLINCS]);
1599             warning_error(wi, warn_buf);
1600         }
1601         if (ir->bPeriodicMols)
1602         {
1603             sprintf(warn_buf, "Can not do periodic molecules with %s, use %s",
1604                     econstr_names[econtSHAKE], econstr_names[econtLINCS]);
1605             warning_error(wi, warn_buf);
1606         }
1607     }
1608
1609     if (EI_SD (ir->eI) &&  ir->etc != etcNO)
1610     {
1611         warning_note(wi, "Temperature coupling is ignored with SD integrators.");
1612     }
1613
1614     /* If we are doing QM/MM, check that we got the atom numbers */
1615     have_atomnumber = TRUE;
1616     for (i = 0; i < get_atomtype_ntypes(atype); i++)
1617     {
1618         have_atomnumber = have_atomnumber && (get_atomtype_atomnumber(i, atype) >= 0);
1619     }
1620     if (!have_atomnumber && ir->bQMMM)
1621     {
1622         warning_error(wi,
1623                       "\n"
1624                       "It appears as if you are trying to run a QM/MM calculation, but the force\n"
1625                       "field you are using does not contain atom numbers fields. This is an\n"
1626                       "optional field (introduced in Gromacs 3.3) for general runs, but mandatory\n"
1627                       "for QM/MM. The good news is that it is easy to add - put the atom number as\n"
1628                       "an integer just before the mass column in ffXXXnb.itp.\n"
1629                       "NB: United atoms have the same atom numbers as normal ones.\n\n");
1630     }
1631
1632     if (ir->bAdress)
1633     {
1634         if ((ir->adress->const_wf > 1) || (ir->adress->const_wf < 0))
1635         {
1636             warning_error(wi, "AdResS contant weighting function should be between 0 and 1\n\n");
1637         }
1638         /** \TODO check size of ex+hy width against box size */
1639     }
1640
1641     /* Check for errors in the input now, since they might cause problems
1642      * during processing further down.
1643      */
1644     check_warning_error(wi, FARGS);
1645
1646     if (opt2bSet("-r", NFILE, fnm))
1647     {
1648         sprintf(fn, "%s", opt2fn("-r", NFILE, fnm));
1649     }
1650     else
1651     {
1652         sprintf(fn, "%s", opt2fn("-c", NFILE, fnm));
1653     }
1654     if (opt2bSet("-rb", NFILE, fnm))
1655     {
1656         sprintf(fnB, "%s", opt2fn("-rb", NFILE, fnm));
1657     }
1658     else
1659     {
1660         strcpy(fnB, fn);
1661     }
1662
1663     if (nint_ftype(sys, mi, F_POSRES) > 0 || nint_ftype(sys, mi, F_FBPOSRES) > 0)
1664     {
1665         if (bVerbose)
1666         {
1667             fprintf(stderr, "Reading position restraint coords from %s", fn);
1668             if (strcmp(fn, fnB) == 0)
1669             {
1670                 fprintf(stderr, "\n");
1671             }
1672             else
1673             {
1674                 fprintf(stderr, " and %s\n", fnB);
1675             }
1676         }
1677         gen_posres(sys, mi, fn, fnB,
1678                    ir->refcoord_scaling, ir->ePBC,
1679                    ir->posres_com, ir->posres_comB,
1680                    wi);
1681     }
1682
1683     /* If we are using CMAP, setup the pre-interpolation grid */
1684     if (plist->ncmap > 0)
1685     {
1686         init_cmap_grid(&sys->ffparams.cmap_grid, plist->nc, plist->grid_spacing);
1687         setup_cmap(plist->grid_spacing, plist->nc, plist->cmap, &sys->ffparams.cmap_grid);
1688     }
1689
1690     set_wall_atomtype(atype, opts, ir, wi);
1691     if (bRenum)
1692     {
1693         renum_atype(plist, sys, ir->wall_atomtype, atype, bVerbose);
1694         ntype = get_atomtype_ntypes(atype);
1695     }
1696
1697     if (ir->implicit_solvent != eisNO)
1698     {
1699         /* Now we have renumbered the atom types, we can check the GBSA params */
1700         check_gbsa_params(atype);
1701
1702         /* Check that all atoms that have charge and/or LJ-parameters also have
1703          * sensible GB-parameters
1704          */
1705         check_gbsa_params_charged(sys, atype);
1706     }
1707
1708     /* PELA: Copy the atomtype data to the topology atomtype list */
1709     copy_atomtype_atomtypes(atype, &(sys->atomtypes));
1710
1711     if (debug)
1712     {
1713         pr_symtab(debug, 0, "After renum_atype", &sys->symtab);
1714     }
1715
1716     if (bVerbose)
1717     {
1718         fprintf(stderr, "converting bonded parameters...\n");
1719     }
1720
1721     ntype = get_atomtype_ntypes(atype);
1722     convert_params(ntype, plist, mi, comb, reppow, fudgeQQ, sys);
1723
1724     if (debug)
1725     {
1726         pr_symtab(debug, 0, "After convert_params", &sys->symtab);
1727     }
1728
1729     /* set ptype to VSite for virtual sites */
1730     for (mt = 0; mt < sys->nmoltype; mt++)
1731     {
1732         set_vsites_ptype(FALSE, &sys->moltype[mt]);
1733     }
1734     if (debug)
1735     {
1736         pr_symtab(debug, 0, "After virtual sites", &sys->symtab);
1737     }
1738     /* Check velocity for virtual sites and shells */
1739     if (bGenVel)
1740     {
1741         check_vel(sys, state.v);
1742     }
1743
1744     /* check masses */
1745     check_mol(sys, wi);
1746
1747     for (i = 0; i < sys->nmoltype; i++)
1748     {
1749         check_cg_sizes(ftp2fn(efTOP, NFILE, fnm), &sys->moltype[i].cgs, wi);
1750     }
1751
1752     if (EI_DYNAMICS(ir->eI) && ir->eI != eiBD)
1753     {
1754         check_bonds_timestep(sys, ir->delta_t, wi);
1755     }
1756
1757     if (EI_ENERGY_MINIMIZATION(ir->eI) && 0 == ir->nsteps)
1758     {
1759         warning_note(wi, "Zero-step energy minimization will alter the coordinates before calculating the energy. If you just want the energy of a single point, try zero-step MD (with unconstrained_start = yes). To do multiple single-point energy evaluations of different configurations of the same topology, use mdrun -rerun.");
1760     }
1761
1762     check_warning_error(wi, FARGS);
1763
1764     if (bVerbose)
1765     {
1766         fprintf(stderr, "initialising group options...\n");
1767     }
1768     do_index(mdparin, ftp2fn_null(efNDX, NFILE, fnm),
1769              sys, bVerbose, ir,
1770              bGenVel ? state.v : NULL,
1771              wi);
1772
1773     if (ir->cutoff_scheme == ecutsVERLET && ir->verletbuf_tol > 0 &&
1774         ir->nstlist > 1)
1775     {
1776         if (EI_DYNAMICS(ir->eI) &&
1777             !(EI_MD(ir->eI) && ir->etc == etcNO) &&
1778             inputrec2nboundeddim(ir) == 3)
1779         {
1780             set_verlet_buffer(sys, ir, state.box, wi);
1781         }
1782     }
1783
1784     /* Init the temperature coupling state */
1785     init_gtc_state(&state, ir->opts.ngtc, 0, ir->opts.nhchainlength); /* need to add nnhpres here? */
1786
1787     if (bVerbose)
1788     {
1789         fprintf(stderr, "Checking consistency between energy and charge groups...\n");
1790     }
1791     check_eg_vs_cg(sys);
1792
1793     if (debug)
1794     {
1795         pr_symtab(debug, 0, "After index", &sys->symtab);
1796     }
1797
1798     triple_check(mdparin, ir, sys, wi);
1799     close_symtab(&sys->symtab);
1800     if (debug)
1801     {
1802         pr_symtab(debug, 0, "After close", &sys->symtab);
1803     }
1804
1805     /* make exclusions between QM atoms */
1806     if (ir->bQMMM)
1807     {
1808         if (ir->QMMMscheme == eQMMMschemenormal && ir->ns_type == ensSIMPLE)
1809         {
1810             gmx_fatal(FARGS, "electrostatic embedding only works with grid neighboursearching, use ns-type=grid instead\n");
1811         }
1812         else
1813         {
1814             generate_qmexcl(sys, ir, wi);
1815         }
1816     }
1817
1818     if (ftp2bSet(efTRN, NFILE, fnm))
1819     {
1820         if (bVerbose)
1821         {
1822             fprintf(stderr, "getting data from old trajectory ...\n");
1823         }
1824         cont_status(ftp2fn(efTRN, NFILE, fnm), ftp2fn_null(efEDR, NFILE, fnm),
1825                     bNeedVel, bGenVel, fr_time, ir, &state, sys, oenv);
1826     }
1827
1828     if (ir->ePBC == epbcXY && ir->nwall != 2)
1829     {
1830         clear_rvec(state.box[ZZ]);
1831     }
1832
1833     if (ir->cutoff_scheme != ecutsVERLET && ir->rlist > 0)
1834     {
1835         set_warning_line(wi, mdparin, -1);
1836         check_chargegroup_radii(sys, ir, state.x, wi);
1837     }
1838
1839     if (EEL_FULL(ir->coulombtype) || EVDW_PME(ir->vdwtype))
1840     {
1841         /* Calculate the optimal grid dimensions */
1842         copy_mat(state.box, box);
1843         if (ir->ePBC == epbcXY && ir->nwall == 2)
1844         {
1845             svmul(ir->wall_ewald_zfac, box[ZZ], box[ZZ]);
1846         }
1847         if (ir->nkx > 0 && ir->nky > 0 && ir->nkz > 0)
1848         {
1849             /* Mark fourier_spacing as not used */
1850             ir->fourier_spacing = 0;
1851         }
1852         else if (ir->nkx != 0 && ir->nky != 0 && ir->nkz != 0)
1853         {
1854             set_warning_line(wi, mdparin, -1);
1855             warning_error(wi, "Some of the Fourier grid sizes are set, but all of them need to be set.");
1856         }
1857         max_spacing = calc_grid(stdout, box, ir->fourier_spacing,
1858                                 &(ir->nkx), &(ir->nky), &(ir->nkz));
1859     }
1860
1861     /* MRS: eventually figure out better logic for initializing the fep
1862        values that makes declaring the lambda and declaring the state not
1863        potentially conflict if not handled correctly. */
1864     if (ir->efep != efepNO)
1865     {
1866         if (EVDW_PME(ir->vdwtype))
1867         {
1868             gmx_fatal(FARGS, "LJ-PME not implemented together with free energy calculations!");
1869         }
1870
1871         state.fep_state = ir->fepvals->init_fep_state;
1872         for (i = 0; i < efptNR; i++)
1873         {
1874             /* init_lambda trumps state definitions*/
1875             if (ir->fepvals->init_lambda >= 0)
1876             {
1877                 state.lambda[i] = ir->fepvals->init_lambda;
1878             }
1879             else
1880             {
1881                 if (ir->fepvals->all_lambda[i] == NULL)
1882                 {
1883                     gmx_fatal(FARGS, "Values of lambda not set for a free energy calculation!");
1884                 }
1885                 else
1886                 {
1887                     state.lambda[i] = ir->fepvals->all_lambda[i][state.fep_state];
1888                 }
1889             }
1890         }
1891     }
1892
1893     if (ir->ePull != epullNO)
1894     {
1895         set_pull_init(ir, sys, state.x, state.box, state.lambda[efptMASS], oenv, opts->pull_start);
1896     }
1897
1898     if (ir->bRot)
1899     {
1900         set_reference_positions(ir->rot, state.x, state.box,
1901                                 opt2fn("-ref", NFILE, fnm), opt2bSet("-ref", NFILE, fnm),
1902                                 wi);
1903     }
1904
1905     /*  reset_multinr(sys); */
1906
1907     if (EEL_PME(ir->coulombtype))
1908     {
1909         float ratio = pme_load_estimate(sys, ir, state.box);
1910         fprintf(stderr, "Estimate for the relative computational load of the PME mesh part: %.2f\n", ratio);
1911         /* With free energy we might need to do PME both for the A and B state
1912          * charges. This will double the cost, but the optimal performance will
1913          * then probably be at a slightly larger cut-off and grid spacing.
1914          */
1915         if ((ir->efep == efepNO && ratio > 1.0/2.0) ||
1916             (ir->efep != efepNO && ratio > 2.0/3.0))
1917         {
1918             warning_note(wi,
1919                          "The optimal PME mesh load for parallel simulations is below 0.5\n"
1920                          "and for highly parallel simulations between 0.25 and 0.33,\n"
1921                          "for higher performance, increase the cut-off and the PME grid spacing.\n");
1922             if (ir->efep != efepNO)
1923             {
1924                 warning_note(wi,
1925                              "For free energy simulations, the optimal load limit increases from 0.5 to 0.667\n");
1926             }
1927         }
1928     }
1929
1930     {
1931         char   warn_buf[STRLEN];
1932         double cio = compute_io(ir, sys->natoms, &sys->groups, F_NRE, 1);
1933         sprintf(warn_buf, "This run will generate roughly %.0f Mb of data", cio);
1934         if (cio > 2000)
1935         {
1936             set_warning_line(wi, mdparin, -1);
1937             warning_note(wi, warn_buf);
1938         }
1939         else
1940         {
1941             printf("%s\n", warn_buf);
1942         }
1943     }
1944
1945     if (bVerbose)
1946     {
1947         fprintf(stderr, "writing run input file...\n");
1948     }
1949
1950     done_warning(wi, FARGS);
1951     write_tpx_state(ftp2fn(efTPX, NFILE, fnm), ir, &state, sys);
1952
1953     done_atomtype(atype);
1954     done_mtop(sys, TRUE);
1955     done_inputrec_strings();
1956
1957     return 0;
1958 }