Don't use POSIX fnmatch() for pattern matching.
[gromacs/qmmm-gamess-us.git] / src / kernel / grompp.c
blobb3a47978b4214d30b94c6a4f377a3c973d500936
1 /* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
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.
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.
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.
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.
31 * For more info, check our website at http://www.gromacs.org
33 * And Hey:
34 * Gallium Rubidium Oxygen Manganese Argon Carbon Silicon
36 #ifdef HAVE_CONFIG_H
37 #include <config.h>
38 #endif
40 #include <sys/types.h>
41 #include <math.h>
42 #include <string.h>
43 #include <errno.h>
44 #include <limits.h>
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 "index.h"
68 #include "gmxfio.h"
69 #include "trnio.h"
70 #include "tpxio.h"
71 #include "vsite_parm.h"
72 #include "txtdump.h"
73 #include "calcgrid.h"
74 #include "add_par.h"
75 #include "enxio.h"
76 #include "perf_est.h"
77 #include "compute_io.h"
78 #include "gpp_atomtype.h"
79 #include "gpp_tomorse.h"
80 #include "mtop_util.h"
81 #include "genborn.h"
83 static int rm_interactions(int ifunc,int nrmols,t_molinfo mols[])
85 int i,n;
87 n=0;
88 /* For all the molecule types */
89 for(i=0; i<nrmols; i++) {
90 n += mols[i].plist[ifunc].nr;
91 mols[i].plist[ifunc].nr=0;
93 return n;
96 static int check_atom_names(const char *fn1, const char *fn2,
97 gmx_mtop_t *mtop, t_atoms *at)
99 int mb,m,i,j,nmismatch;
100 t_atoms *tat;
101 #define MAXMISMATCH 20
103 if (mtop->natoms != at->nr)
104 gmx_incons("comparing atom names");
106 nmismatch=0;
107 i = 0;
108 for(mb=0; mb<mtop->nmolblock; mb++) {
109 tat = &mtop->moltype[mtop->molblock[mb].type].atoms;
110 for(m=0; m<mtop->molblock[mb].nmol; m++) {
111 for(j=0; j < tat->nr; j++) {
112 if (strcmp( *(tat->atomname[j]) , *(at->atomname[i]) ) != 0) {
113 if (nmismatch < MAXMISMATCH) {
114 fprintf(stderr,
115 "Warning: atom name %d in %s and %s does not match (%s - %s)\n",
116 i+1, fn1, fn2, *(tat->atomname[j]), *(at->atomname[i]));
117 } else if (nmismatch == MAXMISMATCH) {
118 fprintf(stderr,"(more than %d non-matching atom names)\n",MAXMISMATCH);
120 nmismatch++;
122 i++;
127 return nmismatch;
130 static void check_eg_vs_cg(gmx_mtop_t *mtop)
132 int astart,mb,m,cg,j,firstj;
133 unsigned char firsteg,eg;
134 gmx_moltype_t *molt;
136 /* Go through all the charge groups and make sure all their
137 * atoms are in the same energy group.
140 astart = 0;
141 for(mb=0; mb<mtop->nmolblock; mb++) {
142 molt = &mtop->moltype[mtop->molblock[mb].type];
143 for(m=0; m<mtop->molblock[mb].nmol; m++) {
144 for(cg=0; cg<molt->cgs.nr;cg++) {
145 /* Get the energy group of the first atom in this charge group */
146 firstj = astart + molt->cgs.index[cg];
147 firsteg = ggrpnr(&mtop->groups,egcENER,firstj);
148 for(j=molt->cgs.index[cg]+1;j<molt->cgs.index[cg+1];j++) {
149 eg = ggrpnr(&mtop->groups,egcENER,astart+j);
150 if(eg != firsteg) {
151 gmx_fatal(FARGS,"atoms %d and %d in charge group %d of molecule type '%s' are in different energy groups",
152 firstj+1,astart+j+1,cg+1,*molt->name);
156 astart += molt->atoms.nr;
161 static void check_cg_sizes(const char *topfn,t_block *cgs)
163 int maxsize,cg;
165 maxsize = 0;
166 for(cg=0; cg<cgs->nr; cg++)
167 maxsize = max(maxsize,cgs->index[cg+1]-cgs->index[cg]);
169 if (maxsize > 10) {
170 set_warning_line(topfn,-1);
171 sprintf(warn_buf,
172 "The largest charge group contains %d atoms.\n"
173 "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"
174 "For efficiency and accuracy, charge group should consist of a few atoms.\n"
175 "For all-atom force fields use: CH3, CH2, CH, NH2, NH, OH, CO2, CO, etc.",
176 maxsize);
177 warning_note(warn_buf);
181 static void check_vel(gmx_mtop_t *mtop,rvec v[])
183 gmx_mtop_atomloop_all_t aloop;
184 t_atom *atom;
185 int a;
187 aloop = gmx_mtop_atomloop_all_init(mtop);
188 while (gmx_mtop_atomloop_all_next(aloop,&a,&atom)) {
189 if (atom->ptype == eptShell ||
190 atom->ptype == eptBond ||
191 atom->ptype == eptVSite) {
192 clear_rvec(v[a]);
197 static bool nint_ftype(gmx_mtop_t *mtop,t_molinfo *mi,int ftype)
199 int nint,mb;
201 nint = 0;
202 for(mb=0; mb<mtop->nmolblock; mb++) {
203 nint += mtop->molblock[mb].nmol*mi[mtop->molblock[mb].type].plist[ftype].nr;
206 return nint;
209 /* This routine reorders the molecule type array
210 * in the order of use in the molblocks,
211 * unused molecule types are deleted.
213 static void renumber_moltypes(gmx_mtop_t *sys,
214 int *nmolinfo,t_molinfo **molinfo)
216 int *order,norder,i;
217 int mb,mi;
218 t_molinfo *minew;
220 snew(order,*nmolinfo);
221 norder = 0;
222 for(mb=0; mb<sys->nmolblock; mb++) {
223 for(i=0; i<norder; i++) {
224 if (order[i] == sys->molblock[mb].type) {
225 break;
228 if (i == norder) {
229 /* This type did not occur yet, add it */
230 order[norder] = sys->molblock[mb].type;
231 /* Renumber the moltype in the topology */
232 norder++;
234 sys->molblock[mb].type = i;
237 /* We still need to reorder the molinfo structs */
238 snew(minew,norder);
239 for(mi=0; mi<*nmolinfo; mi++) {
240 for(i=0; i<norder; i++) {
241 if (order[i] == mi) {
242 break;
245 if (i == norder) {
246 done_mi(&(*molinfo)[mi]);
247 } else {
248 minew[i] = (*molinfo)[mi];
251 sfree(*molinfo);
253 *nmolinfo = norder;
254 *molinfo = minew;
257 static void molinfo2mtop(int nmi,t_molinfo *mi,gmx_mtop_t *mtop)
259 int m;
260 gmx_moltype_t *molt;
262 mtop->nmoltype = nmi;
263 snew(mtop->moltype,nmi);
264 for(m=0; m<nmi; m++) {
265 molt = &mtop->moltype[m];
266 molt->name = mi[m].name;
267 molt->atoms = mi[m].atoms;
268 /* ilists are copied later */
269 molt->cgs = mi[m].cgs;
270 molt->excls = mi[m].excls;
274 static void
275 new_status(const char *topfile,const char *topppfile,const char *confin,
276 t_gromppopts *opts,t_inputrec *ir,bool bZero,
277 bool bGenVel,bool bVerbose,t_state *state,
278 gpp_atomtype_t atype,gmx_mtop_t *sys,
279 int *nmi,t_molinfo **mi,t_params plist[],
280 int *comb,double *reppow,real *fudgeQQ,
281 bool bMorse,
282 int *nerror)
284 t_molinfo *molinfo=NULL;
285 int nmolblock;
286 gmx_molblock_t *molblock,*molbs;
287 t_atoms *confat;
288 int mb,mbs,i,nrmols,nmismatch;
289 char buf[STRLEN];
290 bool bGB=FALSE;
292 init_mtop(sys);
294 /* Set boolean for GB */
295 if(ir->implicit_solvent)
296 bGB=TRUE;
298 /* TOPOLOGY processing */
299 sys->name = do_top(bVerbose,topfile,topppfile,opts,bZero,&(sys->symtab),
300 plist,comb,reppow,fudgeQQ,
301 atype,&nrmols,&molinfo,ir,
302 &nmolblock,&molblock,bGB);
304 sys->nmolblock = 0;
305 snew(sys->molblock,nmolblock);
306 mbs;
307 sys->natoms = 0;
308 for(mb=0; mb<nmolblock; mb++) {
309 if (sys->nmolblock > 0 &&
310 molblock[mb].type == sys->molblock[sys->nmolblock-1].type) {
311 /* Merge consecutive blocks with the same molecule type */
312 sys->molblock[sys->nmolblock-1].nmol += molblock[mb].nmol;
313 sys->natoms += molblock[mb].nmol*sys->molblock[sys->nmolblock-1].natoms_mol;
314 } else if (molblock[mb].nmol > 0) {
315 /* Add a new molblock to the topology */
316 molbs = &sys->molblock[sys->nmolblock];
317 *molbs = molblock[mb];
318 molbs->natoms_mol = molinfo[molbs->type].atoms.nr;
319 molbs->nposres_xA = 0;
320 molbs->nposres_xB = 0;
321 sys->natoms += molbs->nmol*molbs->natoms_mol;
322 sys->nmolblock++;
325 if (sys->nmolblock == 0) {
326 gmx_fatal(FARGS,"No molecules were defined in the system");
329 renumber_moltypes(sys,&nrmols,&molinfo);
331 if (bMorse)
332 convert_harmonics(nrmols,molinfo,atype);
334 if (ir->eDisre == edrNone) {
335 i = rm_interactions(F_DISRES,nrmols,molinfo);
336 if (i > 0) {
337 set_warning_line("unknown",-1);
338 sprintf(warn_buf,"disre = no, removed %d distance restraints",i);
339 warning_note(NULL);
342 if (opts->bOrire == FALSE) {
343 i = rm_interactions(F_ORIRES,nrmols,molinfo);
344 if (i > 0) {
345 set_warning_line("unknown",-1);
346 sprintf(warn_buf,"orire = no, removed %d orientation restraints",i);
347 warning_note(NULL);
350 if (opts->bDihre == FALSE) {
351 i = rm_interactions(F_DIHRES,nrmols,molinfo);
352 if (i > 0) {
353 set_warning_line("unknown",-1);
354 sprintf(warn_buf,"dihre = no, removed %d dihedral restraints",i);
355 warning_note(NULL);
359 /* Copy structures from msys to sys */
360 molinfo2mtop(nrmols,molinfo,sys);
362 /* COORDINATE file processing */
363 if (bVerbose)
364 fprintf(stderr,"processing coordinates...\n");
366 get_stx_coordnum(confin,&state->natoms);
367 if (state->natoms != sys->natoms)
368 gmx_fatal(FARGS,"number of coordinates in coordinate file (%s, %d)\n"
369 " does not match topology (%s, %d)",
370 confin,state->natoms,topfile,sys->natoms);
371 else {
372 /* make space for coordinates and velocities */
373 char title[STRLEN];
374 snew(confat,1);
375 init_t_atoms(confat,state->natoms,FALSE);
376 init_state(state,state->natoms,0);
377 read_stx_conf(confin,title,confat,state->x,state->v,NULL,state->box);
378 /* This call fixes the box shape for runs with pressure scaling */
379 set_box_rel(ir,state);
381 nmismatch = check_atom_names(topfile, confin, sys, confat);
382 free_t_atoms(confat,TRUE);
383 sfree(confat);
385 if (nmismatch) {
386 sprintf(buf,"%d non-matching atom name%s\n"
387 "atom names from %s will be used\n"
388 "atom names from %s will be ignored\n",
389 nmismatch,(nmismatch == 1) ? "" : "s",topfile,confin);
390 warning(buf);
392 if (bVerbose)
393 fprintf(stderr,"double-checking input for internal consistency...\n");
394 double_check(ir,state->box,nint_ftype(sys,molinfo,F_CONSTR),nerror);
397 if (bGenVel) {
398 real *mass;
399 gmx_mtop_atomloop_all_t aloop;
400 t_atom *atom;
402 snew(mass,state->natoms);
403 aloop = gmx_mtop_atomloop_all_init(sys);
404 while (gmx_mtop_atomloop_all_next(aloop,&i,&atom)) {
405 mass[i] = atom->m;
408 if (opts->seed == -1) {
409 opts->seed = make_seed();
410 fprintf(stderr,"Setting gen_seed to %d\n",opts->seed);
412 maxwell_speed(opts->tempi,opts->seed,sys,state->v);
414 stop_cm(stdout,state->natoms,mass,state->x,state->v);
415 sfree(mass);
418 *nmi = nrmols;
419 *mi = molinfo;
422 static void cont_status(const char *slog,const char *ener,
423 bool bNeedVel,bool bGenVel, real fr_time,
424 t_inputrec *ir,t_state *state,
425 gmx_mtop_t *sys,
426 const output_env_t oenv)
427 /* If fr_time == -1 read the last frame available which is complete */
429 t_trxframe fr;
430 int fp;
432 fprintf(stderr,
433 "Reading Coordinates%s and Box size from old trajectory\n",
434 (!bNeedVel || bGenVel) ? "" : ", Velocities");
435 if (fr_time == -1)
436 fprintf(stderr,"Will read whole trajectory\n");
437 else
438 fprintf(stderr,"Will read till time %g\n",fr_time);
439 if (!bNeedVel || bGenVel) {
440 if (bGenVel)
441 fprintf(stderr,"Velocities generated: "
442 "ignoring velocities in input trajectory\n");
443 read_first_frame(oenv,&fp,slog,&fr,TRX_NEED_X);
444 } else
445 read_first_frame(oenv,&fp,slog,&fr,TRX_NEED_X | TRX_NEED_V);
447 state->natoms = fr.natoms;
449 if (sys->natoms != state->natoms)
450 gmx_fatal(FARGS,"Number of atoms in Topology "
451 "is not the same as in Trajectory");
453 /* Find the appropriate frame */
454 while ((fr_time == -1 || fr.time < fr_time) && read_next_frame(oenv,fp,&fr));
456 close_trj(fp);
458 if (fr.not_ok & FRAME_NOT_OK)
459 gmx_fatal(FARGS,"Can not start from an incomplete frame");
461 state->x = fr.x;
462 if (bNeedVel && !bGenVel)
463 state->v = fr.v;
464 copy_mat(fr.box,state->box);
465 /* Set the relative box lengths for preserving the box shape.
466 * Note that this call can lead to differences in the last bit
467 * with respect to using tpbconv to create a tpx file.
469 set_box_rel(ir,state);
471 fprintf(stderr,"Using frame at t = %g ps\n",fr.time);
472 fprintf(stderr,"Starting time for run is %g ps\n",ir->init_t);
474 if ((ir->epc != epcNO || ir->etc ==etcNOSEHOOVER) && ener) {
475 get_enx_state(ener,fr.time,&sys->groups,ir,state);
476 preserve_box_shape(ir,state->box_rel,state->boxv);
480 static void read_posres(gmx_mtop_t *mtop,t_molinfo *molinfo,bool bTopB,
481 char *fn,
482 int rc_scaling, int ePBC,
483 rvec com)
485 bool bFirst = TRUE;
486 rvec *x,*v,*xp;
487 dvec sum;
488 double totmass;
489 t_atoms dumat;
490 matrix box,invbox;
491 int natoms,npbcdim=0;
492 char title[STRLEN];
493 int a,i,ai,j,k,mb,nat_molb;
494 gmx_molblock_t *molb;
495 t_params *pr;
496 t_atom *atom;
498 get_stx_coordnum(fn,&natoms);
499 if (natoms != mtop->natoms) {
500 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);
501 warning(NULL);
503 snew(x,natoms);
504 snew(v,natoms);
505 init_t_atoms(&dumat,natoms,FALSE);
506 read_stx_conf(fn,title,&dumat,x,v,NULL,box);
508 npbcdim = ePBC2npbcdim(ePBC);
509 clear_rvec(com);
510 if (rc_scaling != erscNO) {
511 copy_mat(box,invbox);
512 for(j=npbcdim; j<DIM; j++) {
513 clear_rvec(invbox[j]);
514 invbox[j][j] = 1;
516 m_inv_ur0(invbox,invbox);
519 /* Copy the reference coordinates to mtop */
520 clear_dvec(sum);
521 totmass = 0;
522 a = 0;
523 for(mb=0; mb<mtop->nmolblock; mb++) {
524 molb = &mtop->molblock[mb];
525 nat_molb = molb->nmol*mtop->moltype[molb->type].atoms.nr;
526 pr = &(molinfo[molb->type].plist[F_POSRES]);
527 if (pr->nr > 0) {
528 atom = mtop->moltype[molb->type].atoms.atom;
529 for(i=0; (i<pr->nr); i++) {
530 ai=pr->param[i].AI;
531 if (ai >= natoms) {
532 gmx_fatal(FARGS,"Position restraint atom index (%d) in moltype '%s' is larger than number of atoms in %s (%d).\n",
533 ai+1,*molinfo[molb->type].name,fn,natoms);
535 if (rc_scaling == erscCOM) {
536 /* Determine the center of mass of the posres reference coordinates */
537 for(j=0; j<npbcdim; j++) {
538 sum[j] += atom[ai].m*x[a+ai][j];
540 totmass += atom[ai].m;
543 if (!bTopB) {
544 molb->nposres_xA = nat_molb;
545 snew(molb->posres_xA,molb->nposres_xA);
546 for(i=0; i<nat_molb; i++) {
547 copy_rvec(x[a+i],molb->posres_xA[i]);
549 } else {
550 molb->nposres_xB = nat_molb;
551 snew(molb->posres_xB,molb->nposres_xB);
552 for(i=0; i<nat_molb; i++) {
553 copy_rvec(x[a+i],molb->posres_xB[i]);
557 a += nat_molb;
559 if (rc_scaling == erscCOM) {
560 if (totmass == 0)
561 gmx_fatal(FARGS,"The total mass of the position restraint atoms is 0");
562 for(j=0; j<npbcdim; j++)
563 com[j] = sum[j]/totmass;
564 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]);
567 if (rc_scaling != erscNO) {
568 for(mb=0; mb<mtop->nmolblock; mb++) {
569 molb = &mtop->molblock[mb];
570 nat_molb = molb->nmol*mtop->moltype[molb->type].atoms.nr;
571 if (molb->nposres_xA > 0 || molb->nposres_xB > 0) {
572 xp = (!bTopB ? molb->posres_xA : molb->posres_xB);
573 for(i=0; i<nat_molb; i++) {
574 for(j=0; j<npbcdim; j++) {
575 if (rc_scaling == erscALL) {
576 /* Convert from Cartesian to crystal coordinates */
577 xp[i][j] *= invbox[j][j];
578 for(k=j+1; k<npbcdim; k++) {
579 xp[i][j] += invbox[k][j]*xp[i][k];
581 } else if (rc_scaling == erscCOM) {
582 /* Subtract the center of mass */
583 xp[i][j] -= com[j];
590 if (rc_scaling == erscCOM) {
591 /* Convert the COM from Cartesian to crystal coordinates */
592 for(j=0; j<npbcdim; j++) {
593 com[j] *= invbox[j][j];
594 for(k=j+1; k<npbcdim; k++) {
595 com[j] += invbox[k][j]*com[k];
601 free_t_atoms(&dumat,TRUE);
602 sfree(x);
603 sfree(v);
606 static void gen_posres(gmx_mtop_t *mtop,t_molinfo *mi,
607 char *fnA, char *fnB,
608 int rc_scaling, int ePBC,
609 rvec com, rvec comB)
611 int i,j;
613 read_posres (mtop,mi,FALSE,fnA,rc_scaling,ePBC,com);
614 if (strcmp(fnA,fnB) != 0) {
615 read_posres(mtop,mi,TRUE ,fnB,rc_scaling,ePBC,comB);
619 static void set_wall_atomtype(gpp_atomtype_t at,t_gromppopts *opts,
620 t_inputrec *ir)
622 int i;
624 if (ir->nwall > 0)
625 fprintf(stderr,"Searching the wall atom type(s)\n");
626 for(i=0; i<ir->nwall; i++)
627 ir->wall_atomtype[i] = get_atomtype_type(opts->wall_atomtype[i],at);
630 static int nrdf_internal(t_atoms *atoms)
632 int i,nmass,nrdf;
634 nmass = 0;
635 for(i=0; i<atoms->nr; i++) {
636 /* Vsite ptype might not be set here yet, so also check the mass */
637 if ((atoms->atom[i].ptype == eptAtom ||
638 atoms->atom[i].ptype == eptNucleus)
639 && atoms->atom[i].m > 0) {
640 nmass++;
643 switch (nmass) {
644 case 0: nrdf = 0; break;
645 case 1: nrdf = 0; break;
646 case 2: nrdf = 1; break;
647 default: nrdf = nmass*3 - 6; break;
650 return nrdf;
653 void
654 spline1d( double dx,
655 double * y,
656 int n,
657 double * u,
658 double * y2 )
660 int i;
661 double p,q;
663 y2[0] = 0.0;
664 u[0] = 0.0;
666 for(i=1;i<n-1;i++)
668 p = 0.5*y2[i-1]+2.0;
669 y2[i] = -0.5/p;
670 q = (y[i+1]-2.0*y[i]+y[i-1])/dx;
671 u[i] = (3.0*q/dx-0.5*u[i-1])/p;
674 y2[n-1] = 0.0;
676 for(i=n-2;i>=0;i--)
678 y2[i] = y2[i]*y2[i+1]+u[i];
683 void
684 interpolate1d( double xmin,
685 double dx,
686 double * ya,
687 double * y2a,
688 double x,
689 double * y,
690 double * y1)
692 int ix;
693 double a,b;
695 ix = (x-xmin)/dx;
697 a = (xmin+(ix+1)*dx-x)/dx;
698 b = (x-xmin-ix*dx)/dx;
700 *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;
701 *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];
705 void
706 setup_cmap (int grid_spacing,
707 int nc,
708 real * grid ,
709 gmx_cmap_t * cmap_grid)
711 double *tmp_u,*tmp_u2,*tmp_yy,*tmp_y1,*tmp_t2,*tmp_grid;
713 int i,j,k,ii,jj,kk,idx;
714 int offset;
715 double dx,xmin,v,v1,v2,v12;
716 double phi,psi;
718 snew(tmp_u,2*grid_spacing);
719 snew(tmp_u2,2*grid_spacing);
720 snew(tmp_yy,2*grid_spacing);
721 snew(tmp_y1,2*grid_spacing);
722 snew(tmp_t2,2*grid_spacing*2*grid_spacing);
723 snew(tmp_grid,2*grid_spacing*2*grid_spacing);
725 dx = 360.0/grid_spacing;
726 xmin = -180.0-dx*grid_spacing/2;
728 for(kk=0;kk<nc;kk++)
730 /* Compute an offset depending on which cmap we are using
731 * Offset will be the map number multiplied with the grid_spacing * grid_spacing * 2
733 offset = kk * grid_spacing * grid_spacing * 2;
735 for(i=0;i<2*grid_spacing;i++)
737 ii=(i+grid_spacing-grid_spacing/2)%grid_spacing;
739 for(j=0;j<2*grid_spacing;j++)
741 jj=(j+grid_spacing-grid_spacing/2)%grid_spacing;
742 tmp_grid[i*grid_spacing*2+j] = grid[offset+ii*grid_spacing+jj];
746 for(i=0;i<2*grid_spacing;i++)
748 spline1d(dx,&(tmp_grid[2*grid_spacing*i]),2*grid_spacing,tmp_u,&(tmp_t2[2*grid_spacing*i]));
751 for(i=grid_spacing/2;i<grid_spacing+grid_spacing/2;i++)
753 ii = i-grid_spacing/2;
754 phi = ii*dx-180.0;
756 for(j=grid_spacing/2;j<grid_spacing+grid_spacing/2;j++)
758 jj = j-grid_spacing/2;
759 psi = jj*dx-180.0;
761 for(k=0;k<2*grid_spacing;k++)
763 interpolate1d(xmin,dx,&(tmp_grid[2*grid_spacing*k]),
764 &(tmp_t2[2*grid_spacing*k]),psi,&tmp_yy[k],&tmp_y1[k]);
767 spline1d(dx,tmp_yy,2*grid_spacing,tmp_u,tmp_u2);
768 interpolate1d(xmin,dx,tmp_yy,tmp_u2,phi,&v,&v1);
769 spline1d(dx,tmp_y1,2*grid_spacing,tmp_u,tmp_u2);
770 interpolate1d(xmin,dx,tmp_y1,tmp_u2,phi,&v2,&v12);
772 idx = ii*grid_spacing+jj;
773 cmap_grid->cmapdata[kk].cmap[idx*4] = grid[offset+ii*grid_spacing+jj];
774 cmap_grid->cmapdata[kk].cmap[idx*4+1] = v1;
775 cmap_grid->cmapdata[kk].cmap[idx*4+2] = v2;
776 cmap_grid->cmapdata[kk].cmap[idx*4+3] = v12;
782 void init_cmap_grid(gmx_cmap_t *cmap_grid, int ngrid, int grid_spacing)
784 int i,k,nelem;
786 cmap_grid->ngrid = ngrid;
787 cmap_grid->grid_spacing = grid_spacing;
788 nelem = cmap_grid->grid_spacing*cmap_grid->grid_spacing;
790 snew(cmap_grid->cmapdata,ngrid);
792 for(i=0;i<cmap_grid->ngrid;i++)
794 snew(cmap_grid->cmapdata[i].cmap,4*nelem);
799 static int count_constraints(gmx_mtop_t *mtop,t_molinfo *mi)
801 int count,count_mol,i,mb;
802 gmx_molblock_t *molb;
803 t_params *plist;
804 char buf[STRLEN];
806 count = 0;
807 for(mb=0; mb<mtop->nmolblock; mb++) {
808 count_mol = 0;
809 molb = &mtop->molblock[mb];
810 plist = mi[molb->type].plist;
812 for(i=0; i<F_NRE; i++) {
813 if (i == F_SETTLE)
814 count_mol += 3*plist[i].nr;
815 else if (interaction_function[i].flags & IF_CONSTRAINT)
816 count_mol += plist[i].nr;
819 if (count_mol > nrdf_internal(&mi[molb->type].atoms)) {
820 sprintf(buf,
821 "Molecule type '%s' has %d constraints.\n"
822 "For stability and efficiency there should not be more constraints than internal number of degrees of freedom: %d.\n",
823 *mi[molb->type].name,count_mol,
824 nrdf_internal(&mi[molb->type].atoms));
825 warning(buf);
827 count += molb->nmol*count_mol;
830 return count;
833 static void check_gbsa_params(t_inputrec *ir,gpp_atomtype_t atype)
835 int nmiss,i;
837 /* If we are doing GBSA, check that we got the parameters we need
838 * This checking is to see if there are GBSA paratmeters for all
839 * atoms in the force field. To go around this for testing purposes
840 * comment out the nerror++ counter temporarily
842 nmiss = 0;
843 for(i=0;i<get_atomtype_ntypes(atype);i++)
845 if (get_atomtype_radius(i,atype) < 0 ||
846 get_atomtype_vol(i,atype) < 0 ||
847 get_atomtype_surftens(i,atype) < 0 ||
848 get_atomtype_gb_radius(i,atype) < 0 ||
849 get_atomtype_S_hct(i,atype) < 0)
851 fprintf(stderr,"GB parameter(s) missing or negative for atom type '%s'\n",
852 get_atomtype_name(i,atype));
853 nmiss++;
857 if (nmiss > 0)
859 gmx_fatal(FARGS,"Can't do GB electrostatics; the forcefield is missing %d values for\n"
860 "atomtype radii, or they might be negative\n.",nmiss);
865 int main (int argc, char *argv[])
867 static const char *desc[] = {
868 "The gromacs preprocessor",
869 "reads a molecular topology file, checks the validity of the",
870 "file, expands the topology from a molecular description to an atomic",
871 "description. The topology file contains information about",
872 "molecule types and the number of molecules, the preprocessor",
873 "copies each molecule as needed. ",
874 "There is no limitation on the number of molecule types. ",
875 "Bonds and bond-angles can be converted into constraints, separately",
876 "for hydrogens and heavy atoms.",
877 "Then a coordinate file is read and velocities can be generated",
878 "from a Maxwellian distribution if requested.",
879 "grompp also reads parameters for the mdrun ",
880 "(eg. number of MD steps, time step, cut-off), and others such as",
881 "NEMD parameters, which are corrected so that the net acceleration",
882 "is zero.",
883 "Eventually a binary file is produced that can serve as the sole input",
884 "file for the MD program.[PAR]",
886 "grompp uses the atom names from the topology file. The atom names",
887 "in the coordinate file (option [TT]-c[tt]) are only read to generate",
888 "warnings when they do not match the atom names in the topology.",
889 "Note that the atom names are irrelevant for the simulation as",
890 "only the atom types are used for generating interaction parameters.[PAR]",
892 "grompp uses a built-in preprocessor to resolve includes, macros ",
893 "etcetera. The preprocessor supports the following keywords:[BR]",
894 "#ifdef VARIABLE[BR]",
895 "#ifndef VARIABLE[BR]",
896 "#else[BR]",
897 "#endif[BR]",
898 "#define VARIABLE[BR]",
899 "#undef VARIABLE[BR]"
900 "#include \"filename\"[BR]",
901 "#include <filename>[BR]",
902 "The functioning of these statements in your topology may be modulated by",
903 "using the following two flags in your [TT]mdp[tt] file:[BR]",
904 "define = -DVARIABLE1 -DVARIABLE2[BR]",
905 "include = /home/john/doe[BR]",
906 "For further information a C-programming textbook may help you out.",
907 "Specifying the [TT]-pp[tt] flag will get the pre-processed",
908 "topology file written out so that you can verify its contents.[PAR]",
910 "If your system does not have a c-preprocessor, you can still",
911 "use grompp, but you do not have access to the features ",
912 "from the cpp. Command line options to the c-preprocessor can be given",
913 "in the [TT].mdp[tt] file. See your local manual (man cpp).[PAR]",
915 "When using position restraints a file with restraint coordinates",
916 "can be supplied with [TT]-r[tt], otherwise restraining will be done",
917 "with respect to the conformation from the [TT]-c[tt] option.",
918 "For free energy calculation the the coordinates for the B topology",
919 "can be supplied with [TT]-rb[tt], otherwise they will be equal to",
920 "those of the A topology.[PAR]",
922 "Starting coordinates can be read from trajectory with [TT]-t[tt].",
923 "The last frame with coordinates and velocities will be read,",
924 "unless the [TT]-time[tt] option is used.",
925 "Note that these velocities will not be used when [TT]gen_vel = yes[tt]",
926 "in your [TT].mdp[tt] file. An energy file can be supplied with",
927 "[TT]-e[tt] to have exact restarts when using pressure and/or",
928 "Nose-Hoover temperature coupling. For an exact restart do not forget",
929 "to turn off velocity generation and turn on unconstrained starting",
930 "when constraints are present in the system.",
931 "If you want to continue a crashed run, it is",
932 "easier to use [TT]tpbconv[tt].[PAR]",
934 "Using the [TT]-morse[tt] option grompp can convert the harmonic bonds",
935 "in your topology to morse potentials. This makes it possible to break",
936 "bonds. For this option to work you need an extra file in your $GMXLIB",
937 "with dissociation energy. Use the -debug option to get more information",
938 "on the workings of this option (look for MORSE in the grompp.log file",
939 "using less or something like that).[PAR]",
941 "By default all bonded interactions which have constant energy due to",
942 "virtual site constructions will be removed. If this constant energy is",
943 "not zero, this will result in a shift in the total energy. All bonded",
944 "interactions can be kept by turning off [TT]-rmvsbds[tt]. Additionally,",
945 "all constraints for distances which will be constant anyway because",
946 "of virtual site constructions will be removed. If any constraints remain",
947 "which involve virtual sites, a fatal error will result.[PAR]"
949 "To verify your run input file, please make notice of all warnings",
950 "on the screen, and correct where necessary. Do also look at the contents",
951 "of the [TT]mdout.mdp[tt] file, this contains comment lines, as well as",
952 "the input that [TT]grompp[tt] has read. If in doubt you can start grompp",
953 "with the [TT]-debug[tt] option which will give you more information",
954 "in a file called grompp.log (along with real debug info). Finally, you",
955 "can see the contents of the run input file with the [TT]gmxdump[tt]",
956 "program."
958 t_gromppopts *opts;
959 gmx_mtop_t *sys;
960 int nmi;
961 t_molinfo *mi;
962 gpp_atomtype_t atype;
963 t_inputrec *ir;
964 int natoms,nvsite,comb,mt;
965 t_params *plist;
966 t_state state;
967 matrix box;
968 real max_spacing,fudgeQQ;
969 double reppow;
970 char fn[STRLEN],fnB[STRLEN];
971 const char *mdparin;
972 int nerror,ntype;
973 bool bNeedVel,bGenVel;
974 bool have_atomnumber;
975 int n12,n13,n14;
976 t_params *gb_plist = NULL;
977 gmx_genborn_t *born = NULL;
978 output_env_t oenv;
980 t_filenm fnm[] = {
981 { efMDP, NULL, NULL, ffOPTRD },
982 { efMDP, "-po", "mdout", ffWRITE },
983 { efSTX, "-c", NULL, ffREAD },
984 { efSTX, "-r", NULL, ffOPTRD },
985 { efSTX, "-rb", NULL, ffOPTRD },
986 { efNDX, NULL, NULL, ffOPTRD },
987 { efTOP, NULL, NULL, ffREAD },
988 { efTOP, "-pp", "processed", ffOPTWR },
989 { efTPX, "-o", NULL, ffWRITE },
990 { efTRN, "-t", NULL, ffOPTRD },
991 { efEDR, "-e", NULL, ffOPTRD }
993 #define NFILE asize(fnm)
995 /* Command line options */
996 static bool bVerbose=TRUE,bRenum=TRUE;
997 static bool bRmVSBds=TRUE,bZero=FALSE;
998 static int i,maxwarn=0;
999 static real fr_time=-1;
1000 t_pargs pa[] = {
1001 { "-v", FALSE, etBOOL, {&bVerbose},
1002 "Be loud and noisy" },
1003 { "-time", FALSE, etREAL, {&fr_time},
1004 "Take frame at or first after this time." },
1005 { "-rmvsbds",FALSE, etBOOL, {&bRmVSBds},
1006 "Remove constant bonded interactions with virtual sites" },
1007 { "-maxwarn", FALSE, etINT, {&maxwarn},
1008 "Number of allowed warnings during input processing" },
1009 { "-zero", FALSE, etBOOL, {&bZero},
1010 "Set parameters for bonded interactions without defaults to zero instead of generating an error" },
1011 { "-renum", FALSE, etBOOL, {&bRenum},
1012 "Renumber atomtypes and minimize number of atomtypes" }
1015 CopyRight(stdout,argv[0]);
1017 /* Initiate some variables */
1018 nerror=0;
1019 snew(ir,1);
1020 snew(opts,1);
1021 init_ir(ir,opts);
1023 /* Parse the command line */
1024 parse_common_args(&argc,argv,0,NFILE,fnm,asize(pa),pa,
1025 asize(desc),desc,0,NULL,&oenv);
1027 init_warning(maxwarn);
1029 /* PARAMETER file processing */
1030 mdparin = opt2fn("-f",NFILE,fnm);
1031 set_warning_line(mdparin,-1);
1032 get_ir(mdparin,opt2fn("-po",NFILE,fnm),ir,opts,&nerror);
1034 if (bVerbose)
1035 fprintf(stderr,"checking input for internal consistency...\n");
1036 check_ir(mdparin,ir,opts,&nerror);
1038 if (ir->ld_seed == -1) {
1039 ir->ld_seed = make_seed();
1040 fprintf(stderr,"Setting the LD random seed to %d\n",ir->ld_seed);
1043 bNeedVel = EI_STATE_VELOCITY(ir->eI);
1044 bGenVel = (bNeedVel && opts->bGenVel);
1046 snew(plist,F_NRE);
1047 init_plist(plist);
1048 snew(sys,1);
1049 atype = init_atomtype();
1050 if (debug)
1051 pr_symtab(debug,0,"Just opened",&sys->symtab);
1053 strcpy(fn,ftp2fn(efTOP,NFILE,fnm));
1054 if (!gmx_fexist(fn))
1055 gmx_fatal(FARGS,"%s does not exist",fn);
1056 new_status(fn,opt2fn_null("-pp",NFILE,fnm),opt2fn("-c",NFILE,fnm),
1057 opts,ir,bZero,bGenVel,bVerbose,&state,
1058 atype,sys,&nmi,&mi,plist,&comb,&reppow,&fudgeQQ,
1059 opts->bMorse,
1060 &nerror);
1062 if (debug)
1063 pr_symtab(debug,0,"After new_status",&sys->symtab);
1065 if (count_constraints(sys,mi) && (ir->eConstrAlg == econtSHAKE)) {
1066 if (ir->eI == eiCG || ir->eI == eiLBFGS) {
1067 fprintf(stderr,
1068 "ERROR: Can not do %s with %s, use %s\n",
1069 EI(ir->eI),econstr_names[econtSHAKE],econstr_names[econtLINCS]);
1070 nerror++;
1072 if (ir->bPeriodicMols) {
1073 fprintf(stderr,
1074 "ERROR: can not do periodic molecules with %s, use %s\n",
1075 econstr_names[econtSHAKE],econstr_names[econtLINCS]);
1076 nerror++;
1080 /* If we are doing QM/MM, check that we got the atom numbers */
1081 have_atomnumber = TRUE;
1082 for (i=0; i<get_atomtype_ntypes(atype); i++) {
1083 have_atomnumber = have_atomnumber && (get_atomtype_atomnumber(i,atype) >= 0);
1085 if (!have_atomnumber && ir->bQMMM)
1087 fprintf(stderr,"\n"
1088 "It appears as if you are trying to run a QM/MM calculation, but the force\n"
1089 "field you are using does not contain atom numbers fields. This is an\n"
1090 "optional field (introduced in Gromacs 3.3) for general runs, but mandatory\n"
1091 "for QM/MM. The good news is that it is easy to add - put the atom number as\n"
1092 "an integer just before the mass column in ffXXXnb.itp.\n"
1093 "NB: United atoms have the same atom numbers as normal ones.\n\n");
1094 nerror++;
1097 if (nerror) {
1098 print_warn_num(FALSE);
1100 gmx_fatal(FARGS,"There were %d error(s) processing your input",nerror);
1102 if (opt2bSet("-r",NFILE,fnm))
1103 sprintf(fn,"%s",opt2fn("-r",NFILE,fnm));
1104 else
1105 sprintf(fn,"%s",opt2fn("-c",NFILE,fnm));
1106 if (opt2bSet("-rb",NFILE,fnm))
1107 sprintf(fnB,"%s",opt2fn("-rb",NFILE,fnm));
1108 else
1109 strcpy(fnB,fn);
1111 if (nint_ftype(sys,mi,F_POSRES) > 0) {
1112 if (bVerbose) {
1113 fprintf(stderr,"Reading position restraint coords from %s",fn);
1114 if (strcmp(fn,fnB) == 0) {
1115 fprintf(stderr,"\n");
1116 } else {
1117 fprintf(stderr," and %s\n",fnB);
1118 if (ir->efep != efepNO && ir->n_flambda > 0) {
1119 fprintf(stderr,"ERROR: can not change the position restraint reference coordinates with lambda togther with foreign lambda calculation.\n");
1120 nerror++;
1124 gen_posres(sys,mi,fn,fnB,
1125 ir->refcoord_scaling,ir->ePBC,
1126 ir->posres_com,ir->posres_comB);
1129 nvsite = 0;
1130 /* set parameters for virtual site construction (not for vsiten) */
1131 for(mt=0; mt<sys->nmoltype; mt++) {
1132 nvsite +=
1133 set_vsites(bVerbose, &sys->moltype[mt].atoms, atype, mi[mt].plist);
1135 /* now throw away all obsolete bonds, angles and dihedrals: */
1136 /* note: constraints are ALWAYS removed */
1137 if (nvsite) {
1138 for(mt=0; mt<sys->nmoltype; mt++) {
1139 clean_vsite_bondeds(mi[mt].plist,sys->moltype[mt].atoms.nr,bRmVSBds);
1143 /* If we are using CMAP, setup the pre-interpolation grid */
1144 if(plist->ncmap>0)
1146 init_cmap_grid(&sys->cmap_grid, plist->nc, plist->grid_spacing);
1147 setup_cmap(plist->grid_spacing, plist->nc, plist->cmap,&sys->cmap_grid);
1150 set_wall_atomtype(atype,opts,ir);
1151 if (bRenum) {
1152 renum_atype(plist, sys, ir->wall_atomtype, atype, bVerbose);
1153 ntype = get_atomtype_ntypes(atype);
1156 if (ir->implicit_solvent != eisNO)
1158 /* Now we have renumbered the atom types, we can check the GBSA params */
1159 check_gbsa_params(ir,atype);
1162 /* PELA: Copy the atomtype data to the topology atomtype list */
1163 copy_atomtype_atomtypes(atype,&(sys->atomtypes));
1165 if (debug)
1166 pr_symtab(debug,0,"After renum_atype",&sys->symtab);
1168 if (bVerbose)
1169 fprintf(stderr,"converting bonded parameters...\n");
1171 ntype = get_atomtype_ntypes(atype);
1172 convert_params(ntype, plist, mi, comb, reppow, fudgeQQ, sys);
1174 if (debug)
1175 pr_symtab(debug,0,"After convert_params",&sys->symtab);
1177 /* set ptype to VSite for virtual sites */
1178 for(mt=0; mt<sys->nmoltype; mt++) {
1179 set_vsites_ptype(FALSE,&sys->moltype[mt]);
1181 if (debug) {
1182 pr_symtab(debug,0,"After virtual sites",&sys->symtab);
1184 /* Check velocity for virtual sites and shells */
1185 if (bGenVel) {
1186 check_vel(sys,state.v);
1189 /* check masses */
1190 check_mol(sys);
1192 for(i=0; i<sys->nmoltype; i++) {
1193 check_cg_sizes(ftp2fn(efTOP,NFILE,fnm),&sys->moltype[i].cgs);
1196 check_warning_error(FARGS);
1198 if (bVerbose)
1199 fprintf(stderr,"initialising group options...\n");
1200 do_index(mdparin,ftp2fn_null(efNDX,NFILE,fnm),
1201 sys,bVerbose,ir,
1202 bGenVel ? state.v : NULL);
1204 /* Init the temperature coupling state */
1205 init_gtc_state(&state,ir->opts.ngtc);
1207 if (bVerbose)
1208 fprintf(stderr,"Checking consistency between energy and charge groups...\n");
1209 check_eg_vs_cg(sys);
1211 if (debug)
1212 pr_symtab(debug,0,"After index",&sys->symtab);
1213 triple_check(mdparin,ir,sys,&nerror);
1214 close_symtab(&sys->symtab);
1215 if (debug)
1216 pr_symtab(debug,0,"After close",&sys->symtab);
1218 /* make exclusions between QM atoms */
1219 if (ir->bQMMM) {
1220 generate_qmexcl(sys,ir);
1223 if (ftp2bSet(efTRN,NFILE,fnm)) {
1224 if (bVerbose)
1225 fprintf(stderr,"getting data from old trajectory ...\n");
1226 cont_status(ftp2fn(efTRN,NFILE,fnm),ftp2fn_null(efEDR,NFILE,fnm),
1227 bNeedVel,bGenVel,fr_time,ir,&state,sys,oenv);
1230 if (ir->ePBC==epbcXY && ir->nwall!=2)
1231 clear_rvec(state.box[ZZ]);
1233 if (EEL_FULL(ir->coulombtype)) {
1234 /* Calculate the optimal grid dimensions */
1235 copy_mat(state.box,box);
1236 if (ir->ePBC==epbcXY && ir->nwall==2)
1237 svmul(ir->wall_ewald_zfac,box[ZZ],box[ZZ]);
1238 max_spacing = calc_grid(stdout,box,opts->fourierspacing,
1239 &(ir->nkx),&(ir->nky),&(ir->nkz),1);
1240 if ((ir->coulombtype == eelPPPM) && (max_spacing > 0.1)) {
1241 set_warning_line(mdparin,-1);
1242 sprintf(warn_buf,"Grid spacing larger then 0.1 while using PPPM.");
1243 warning_note(NULL);
1247 if (ir->ePull != epullNO)
1248 set_pull_init(ir,sys,state.x,state.box,oenv,opts->pull_start);
1250 /* reset_multinr(sys); */
1252 if (EEL_PME(ir->coulombtype)) {
1253 float ratio = pme_load_estimate(sys,ir,state.box);
1254 fprintf(stderr,"Estimate for the relative computational load of the PME mesh part: %.2f\n",ratio);
1255 if (ratio > 0.5)
1256 warning_note("The optimal PME mesh load for parallel simulations is below 0.5\n"
1257 "and for highly parallel simulations between 0.25 and 0.33,\n"
1258 "for higher performance, increase the cut-off and the PME grid spacing");
1262 double cio = compute_io(ir,sys->natoms,&sys->groups,F_NRE,1);
1263 sprintf(warn_buf,"This run will generate roughly %.0f Mb of data",cio);
1264 if (cio > 2000) {
1265 set_warning_line(mdparin,-1);
1266 warning_note(NULL);
1267 } else {
1268 printf("%s\n",warn_buf);
1272 if (bVerbose)
1273 fprintf(stderr,"writing run input file...\n");
1275 print_warn_num(TRUE);
1276 state.lambda = ir->init_lambda;
1277 write_tpx_state(ftp2fn(efTPX,NFILE,fnm),ir,&state,sys);
1279 thanx(stderr);
1281 return 0;