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