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