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