4 * This source code is part of
8 * GROningen MAchine for Chemical Simulations
12 * Copyright (c) 1991-1999
13 * BIOSON Research Institute, Dept. of Biophysical Chemistry
14 * University of Groningen, The Netherlands
17 * GROMACS: A message-passing parallel molecular dynamics implementation
18 * H.J.C. Berendsen, D. van der Spoel and R. van Drunen
19 * Comp. Phys. Comm. 91, 43-56 (1995)
21 * Also check out our WWW page:
22 * http://md.chem.rug.nl/~gmx
27 * GRowing Old MAkes el Chrono Sweat
29 static char *SRCID_grompp_c
= "$Id$";
31 #include <sys/types.h>
67 void check_solvent(bool bVerbose
,t_molinfo msys
[],
68 int Nsim
,t_simsystem Sims
[],t_inputrec
*ir
,char *SolventOpt
)
74 if (!SolventOpt
|| strlen(SolventOpt
)==0) {
76 fprintf(stderr
,"no solvent optimizations...\n");
80 fprintf(stderr
,"checking for solvent...\n");
81 for(i
=0; (i
<Nsim
); i
++) {
82 wmol
= Sims
[i
].whichmol
;
83 if ((strcmp(SolventOpt
,*(msys
[wmol
].name
)) == 0) &&
84 (Sims
[i
].nrcopies
> 0)) {
85 nwt
= msys
[wmol
].atoms
.atom
[0].type
;
86 if (ir
->solvent_opt
== -1) {
87 if (msys
[wmol
].atoms
.nr
== 3)
90 sprintf(buf
,"Sorry, can only do solvent optimization with SPC-like models\n");
94 else if (ir
->solvent_opt
== nwt
) {
96 fprintf(debug
,"Remark: Multiple topology entries for %s\n",
99 fatal_error(0,"Multiple non-matching topology entries for %s",
104 if (ir
->solvent_opt
!= -1)
105 fprintf(stderr
,"...using solvent optimization for atomtype %d\n",
108 fprintf(stderr
,"...no solvent\n");
113 static int *shuffle_xv(char *ndx
,
114 int ntab
,int *tab
,int nmol
,t_molinfo
*mol
,
115 int natoms
,rvec
*x
,rvec
*v
,
116 int Nsim
,t_simsystem Sims
[])
120 int *nindex
,**index
,xind
,*done
,*forward
,*backward
;
121 int i
,j
,j0
,k
,mi
,nnat
;
124 /* Determine order in old x array!
125 * the index array holds for each molecule type
126 * a pointer to the position at which the coordinates start
132 /* Compute the number of copies for each molecule type */
133 for(i
=0; (i
<Nsim
); i
++) {
135 nindex
[mi
]+=Sims
[i
].nrcopies
;
138 for(i
=0; (i
<nmol
); i
++) {
139 snew(index
[i
],nindex
[i
]);
143 for(i
=0; (i
<Nsim
); i
++) {
147 /* Current number of molecules processed for this mol-type */
150 /* Number of atoms in this mol-type */
151 nnat
= mol
[mi
].atoms
.nr
;
153 for(j
=0; (j
<Sims
[i
].nrcopies
); j
++,k
++) {
159 assert(xind
== natoms
);
161 /* Buffers for x and v */
164 /* Make a forward shuffle array, i.e. the old numbers of
165 * the current order: this makes a shuffled order from the
167 * Simultaneously copy the coordinates..
169 snew(forward
,natoms
);
170 for(i
=k
=0; (i
<ntab
); i
++) {
171 /* Get the molecule type */
174 /* Determine number of atoms in thsi mol-type */
175 nnat
= mol
[mi
].atoms
.nr
;
177 /* Find the starting index in the x & v arrays */
178 j0
= index
[mi
][done
[mi
]];
180 /* Copy the coordinates */
181 for(j
=j0
; (j
<j0
+nnat
); j
++,k
++) {
182 copy_rvec(x
[j
],xbuf
[k
]);
183 copy_rvec(v
[j
],vbuf
[k
]);
184 /* Store the old index of the new one */
187 /* Increment the number of molecules processed for this type */
191 /* Now copy the buffers back to the original x and v */
192 for(i
=0; (i
<natoms
); i
++) {
193 copy_rvec(xbuf
[i
],x
[i
]);
194 copy_rvec(vbuf
[i
],v
[i
]);
201 /* Now make an inverse shuffle index:
202 * this transforms the new order into the original one...
204 snew(backward
,natoms
);
205 for(i
=0; (i
<natoms
); i
++)
206 backward
[forward
[i
]] = i
;
208 /* Make an index file for deshuffling the atoms */
210 fprintf(out
,"1 %d\nDeShuffle %d\n",natoms
,natoms
);
211 for(i
=0; (i
<natoms
); i
++)
212 fprintf(out
," %d",backward
[i
]);
217 for(i
=0; (i
<nmol
); i
++)
225 int rm_disre(int nrmols
,t_molinfo mols
[])
230 /* For all the molecule types */
231 for(i
=0; (i
<nrmols
); i
++) {
232 n
+=mols
[i
].plist
[F_DISRES
].nr
;
233 mols
[i
].plist
[F_DISRES
].nr
=0;
238 static int check_atom_names(char *fn1
, char *fn2
, t_atoms
*at1
, t_atoms
*at2
,
242 #define MAXMISMATCH 20
244 assert(at1
->nr
==at2
->nr
);
247 for(i
=0; i
< at1
->nr
; i
++) {
252 if (strcmp( *(at1
->atomname
[i
]) , *(at2
->atomname
[idx
]) ) != 0) {
253 if (nmismatch
< MAXMISMATCH
)
255 "Warning: atom names in %s and %s don't match (%s - %s)\n",
256 fn1
, fn2
, *(at1
->atomname
[i
]), *(at2
->atomname
[idx
]));
257 else if (nmismatch
== MAXMISMATCH
)
258 fprintf(stderr
,"(more than %d non-matching atom names)\n",MAXMISMATCH
);
265 static int *new_status(char *topfile
,char *topppfile
,char *confin
,
266 t_gromppopts
*opts
,t_inputrec
*ir
,
267 bool bGenVel
,bool bVerbose
,int *natoms
,
268 rvec
**x
,rvec
**v
,matrix box
,
269 t_atomtype
*atype
,t_topology
*sys
,
270 t_molinfo
*msys
,t_params plist
[],
271 int nprocs
,bool bEnsemble
,bool bMorse
,int *nerror
)
273 t_molinfo
*molinfo
=NULL
;
274 t_simsystem
*Sims
=NULL
;
277 int i
,nrmols
,Nsim
,nmismatch
;
284 /* TOPOLOGY processing */
285 msys
->name
=do_top(bVerbose
,topfile
,topppfile
,opts
,&(sys
->symtab
),
286 plist
,atype
,&nrmols
,&molinfo
,ir
,&Nsim
,&Sims
);
288 check_solvent(bVerbose
,molinfo
,Nsim
,Sims
,ir
,opts
->SolventOpt
);
293 tab
=mk_shuffle_tab(nrmols
,molinfo
,nprocs
,&ntab
,Nsim
,Sims
,bVerbose
);
295 for(i
=0; (i
<ntab
); i
++)
296 fprintf(debug
,"Mol[%5d] = %s\n",i
,*molinfo
[tab
[i
]].name
);
299 fprintf(stderr
,"Made a shuffling table with %d entries [molecules]\n",
303 convert_harmonics(nrmols
,molinfo
,atype
);
305 if (opts
->eDisre
==edrNone
) {
306 i
=rm_disre(nrmols
,molinfo
);
308 fprintf(stderr
,"removed %d distance restraints\n",i
);
311 topcat(msys
,nrmols
,molinfo
,ntab
,tab
,Nsim
,Sims
,bEnsemble
);
313 /* Copy structures from msys to sys */
316 /* COORDINATE file processing */
318 fprintf(stderr
,"processing coordinates...\n");
320 get_stx_coordnum(confin
,natoms
);
321 if (*natoms
!= sys
->atoms
.nr
)
322 fatal_error(0,"number of coordinates in coordinate file (%s, %d)\n"
323 " does not match topology (%s, %d)",
324 confin
,*natoms
,topfile
,sys
->atoms
.nr
);
326 /* make space for coordinates and velocities */
328 init_t_atoms(confat
,*natoms
,FALSE
);
331 read_stx_conf(confin
,opts
->title
,confat
,*x
,*v
,box
);
335 fprintf(stderr
,"Shuffling coordinates...\n");
336 forward
=shuffle_xv("deshuf.ndx",ntab
,tab
,nrmols
,molinfo
,
337 *natoms
,*x
,*v
,Nsim
,Sims
);
340 nmismatch
=check_atom_names(topfile
, confin
, &(sys
->atoms
), confat
,forward
);
341 free_t_atoms(confat
);
345 sprintf(buf
,"%d non-matching atom name%s\n",nmismatch
,
346 (nmismatch
== 1) ? "" : "s");
350 fprintf(stderr
,"double-checking input for internal consistency...\n");
351 double_check(ir
,box
,msys
,nerror
);
357 snew(mass
,msys
->atoms
.nr
);
358 for(i
=0; (i
<msys
->atoms
.nr
); i
++)
359 mass
[i
]=msys
->atoms
.atom
[i
].m
;
361 maxwell_speed(opts
->tempi
,sys
->atoms
.nr
*DIM
,
362 opts
->seed
,&(sys
->atoms
),*v
);
363 stop_cm(stdout
,sys
->atoms
.nr
,mass
,*x
,*v
);
366 for(i
=0; (i
<nrmols
); i
++)
367 done_mi(&(molinfo
[i
]));
374 static void cont_status(char *slog
,bool bNeedVel
,bool bGenVel
, real fr_time
,
375 t_inputrec
*ir
,int *natoms
,
376 rvec
**x
,rvec
**v
,matrix box
,
378 /* If fr_time == -1 read the last frame available which is complete */
385 "Reading Coordinates%s and Box size from old trajectory\n",
386 (!bNeedVel
|| bGenVel
) ? "" : ", Velocities");
388 fprintf(stderr
,"Will read whole trajectory\n");
390 fprintf(stderr
,"Will read till time %g\n",fr_time
);
391 if (!bNeedVel
|| bGenVel
) {
393 fprintf(stderr
,"Velocities generated: "
394 "ignoring velocities in input trajectory\n");
395 *natoms
= read_first_x(&fp
,slog
,&tt
,x
,box
);
397 *natoms
= read_first_x_v(&fp
,slog
,&tt
,x
,v
,box
);
399 if(sys
->atoms
.nr
!= *natoms
)
400 fatal_error(0,"Number of atoms in Topology "
401 "is not the same as in Trajectory");
403 /* Now scan until the last set of box, x and v (step == 0)
404 * or the ones at step step.
405 * Or only until box and x if gen_vel is set.
407 while ((!bNeedVel
|| bGenVel
) ?
408 read_next_x(fp
,&tt
,*natoms
,*x
,box
):
409 read_next_x_v(fp
,&tt
,*natoms
,*x
,*v
,box
)) {
410 if ( (fr_time
!= -1) && (tt
>= fr_time
) )
415 fprintf(stderr
,"Using frame at t = %g ps\n",tt
);
416 fprintf(stderr
,"Starting time for run is %g ps\n",ir
->init_t
);
419 static void gen_posres(t_params
*pr
,char *fn
)
428 get_stx_coordnum(fn
,&natoms
);
431 init_t_atoms(&dumat
,natoms
,FALSE
);
432 read_stx_conf(fn
,title
,&dumat
,x
,v
,box
);
434 for(i
=0; (i
<pr
->nr
); i
++) {
437 fatal_error(0,"Position restraint atom index (%d) is larger than natoms (%d)\n",
439 for(j
=0; (j
<DIM
); j
++)
440 pr
->param
[i
].c
[j
+DIM
]=x
[ai
][j
];
444 free_t_atoms(&dumat
);
449 static int search_array(int atnr
,int *n
,int map
[],int key
)
454 for(i
=0; (i
<nn
); i
++)
460 fprintf(debug
,"Renumbering atomtype %d to %d\n",key
,nn
);
462 fatal_error(0,"Atomtype horror n = %d, %s, %d",nn
,__FILE__
,__LINE__
);
471 static int renum_atype(t_params plist
[],t_topology
*top
,
472 int atnr
,t_inputrec
*ir
,bool bVerbose
)
474 int i
,j
,k
,l
,mi
,mj
,nat
,nrfp
,ftype
;
480 fprintf(stderr
,"renumbering atomtypes...\n");
481 /* Renumber atomtypes and meanwhile make a list of atomtypes */
483 for(i
=0; (i
<top
->atoms
.nr
); i
++) {
484 top
->atoms
.atom
[i
].type
=
485 search_array(atnr
,&nat
,map
,top
->atoms
.atom
[i
].type
);
486 top
->atoms
.atom
[i
].typeB
=
487 search_array(atnr
,&nat
,map
,top
->atoms
.atom
[i
].typeB
);
490 if (ir
->solvent_opt
!= -1) {
492 fprintf(debug
,"Solvent_type before: %d\n",ir
->solvent_opt
);
493 for(j
=0; (j
<nat
); j
++)
494 if (map
[j
] == ir
->solvent_opt
) {
499 fprintf(debug
,"Renumbering solvent_opt (atomtype for OW) to %d\n",
503 pr_ivec(debug
,0,"map",map
,nat
);
506 if (plist
[F_LJ
].nr
> 0)
512 snew(nbsnew
,plist
[ftype
].nr
);
515 for(i
=k
=0; (i
<nat
); i
++) {
517 for(j
=0; (j
<nat
); j
++,k
++) {
519 for(l
=0; (l
<nrfp
); l
++)
520 nbsnew
[k
].c
[l
]=plist
[ftype
].param
[atnr
*mi
+mj
].c
[l
];
523 for(i
=0; (i
<nat
*nat
); i
++) {
524 for(l
=0; (l
<nrfp
); l
++)
525 plist
[ftype
].param
[i
].c
[l
]=nbsnew
[i
].c
[l
];
535 int count_constraints(t_params plist
[])
540 for(i
=0; i
<F_NRE
; i
++)
542 count
+= 3*plist
[i
].nr
;
543 else if (interaction_function
[i
].flags
& IF_CONSTRAINT
)
544 count
+= plist
[i
].nr
;
549 int main (int argc
, char *argv
[])
551 static char *desc
[] = {
552 "The gromacs preprocessor",
553 "reads a molecular topology file, checks the validity of the",
554 "file, expands the topology from a molecular description to an atomic",
555 "description. The topology file contains information about",
556 "molecule types and the number of molecules, the preprocessor",
557 "copies each molecule as needed. ",
558 "There is no limitation on the number of molecule types. ",
559 "Bonds and bond-angles can be converted into constraints, separately",
560 "for hydrogens and heavy atoms.",
561 "Then a coordinate file is read and velocities can be generated",
562 "from a Maxwellian distribution if requested.",
563 "grompp also reads parameters for the mdrun ",
564 "(eg. number of MD steps, time step, cut-off), and others such as",
565 "NEMD parameters, which are corrected so that the net acceleration",
567 "Eventually a binary file is produced that can serve as the sole input",
568 "file for the MD program.[PAR]",
570 "grompp calls the c-preprocessor to resolve includes, macros ",
571 "etcetera. To specify a macro-preprocessor other than /lib/cpp ",
573 "you can put a line in your parameter file specifying the path",
574 "to that cpp. Specifying [TT]-pp[tt] will get the pre-processed",
575 "topology file written out.[PAR]",
577 "If your system does not have a c-preprocessor, you can still",
578 "use grompp, but you do not have access to the features ",
579 "from the cpp. Command line options to the c-preprocessor can be given",
580 "in the [TT].mdp[tt] file. See your local manual (man cpp).[PAR]",
582 "When using position restraints a file with restraint coordinates",
583 "can be supplied with [TT]-r[tt], otherwise constraining will be done",
584 "relative to the conformation from the [TT]-c[tt] option.[PAR]",
586 "Starting coordinates can be read from trajectory with [TT]-t[tt].",
587 "The last frame with coordinates and velocities will be read,",
588 "unless the [TT]-time[tt] option is used.",
589 "Note that these velocities will not be used when [TT]gen_vel = yes[tt]",
590 "in your [TT].mdp[tt] file. If you want to continue a crashed run, it is",
591 "easier to use [TT]tpbconv[tt].[PAR]",
593 "Using the [TT]-morse[tt] option grompp can convert the harmonic bonds",
594 "in your topology to morse potentials. This makes it possible to break",
595 "bonds. For this option to work you need an extra file in your $GMXLIB",
596 "with dissociation energy. Use the -debug option to get more information",
597 "on the workings of this option (look for MORSE in the grompp.log file",
598 "using less or something like that).[PAR]",
600 "By default all bonded interactions which have constant energy due to",
601 "dummy atom constructions will be removed. If this constant energy is",
602 "not zero, this will result in a shift in the total energy. All bonded",
603 "interactions can be kept by turning off [TT]-rmdumbds[tt]. Additionally,",
604 "all constraints for distances which will be constant anyway because",
605 "of dummy atom constructions will be removed. If any constraints remain",
606 "which involve dummy atoms, a fatal error will result.[PAR]"
608 "To verify your run input file, please make notice of all warnings",
609 "on the screen, and correct where necessary. Do also look at the contents",
610 "of the [TT]mdout.mdp[tt] file, this contains comment lines, as well as",
611 "the input that [TT]grompp[tt] has read. If in doubt you can start grompp",
612 "with the [TT]-debug[tt] option which will give you more information",
613 "in a file called grompp.log (along with real debug info). Finally, you",
614 "can see the contents of the run input file with the [TT]gmxdump[tt]",
617 static char *bugs
[] = {
618 "shuffling is sometimes buggy when used on systems when the number of "
619 "molecules of a certain type is smaller than the number of processors."
629 rvec
*x
=NULL
,*v
=NULL
;
632 char fn
[STRLEN
],*mdparin
;
634 bool bNeedVel
,bGenVel
;
637 { efMDP
, NULL
, NULL
, ffREAD
},
638 { efMDP
, "-po", "mdout", ffWRITE
},
639 { efSTX
, "-c", NULL
, ffREAD
},
640 { efSTX
, "-r", NULL
, ffOPTRD
},
641 { efNDX
, NULL
, NULL
, ffOPTRD
},
642 { efTOP
, NULL
, NULL
, ffREAD
},
643 { efTOP
, "-pp", "processed", ffOPTWR
},
644 { efTPX
, "-o", NULL
, ffWRITE
},
645 { efTRN
, "-t", NULL
, ffOPTRD
}
647 #define NFILE asize(fnm)
649 /* Command line options */
650 static bool bVerbose
=TRUE
,bRenum
=TRUE
,bShuffle
=FALSE
,bRmDumBds
=TRUE
;
651 static int nprocs
=1,maxwarn
=10;
652 static real fr_time
=-1;
654 { "-v", FALSE
, etBOOL
, {&bVerbose
},
655 "Be loud and noisy" },
656 { "-time", FALSE
, etREAL
, {&fr_time
},
657 "Take frame at or first after this time." },
658 { "-np", FALSE
, etINT
, {&nprocs
},
659 "Generate statusfile for # processors" },
660 { "-shuffle", FALSE
, etBOOL
, {&bShuffle
},
661 "Shuffle molecules over processors" },
662 { "-rmdumbds",FALSE
, etBOOL
, {&bRmDumBds
},
663 "Remove constant bonded interactions with dummies" },
664 { "-maxwarn", FALSE
, etINT
, {&maxwarn
},
665 "Number of warnings after which input processing stops" },
666 { "-renum", FALSE
, etBOOL
, {&bRenum
},
667 "HIDDENRenumber atomtypes and minimize number of atomtypes" },
670 CopyRight(stdout
,argv
[0]);
672 /* Initiate some variables */
678 /* Parse the command line */
679 parse_common_args(&argc
,argv
,0,FALSE
,NFILE
,fnm
,asize(pa
),pa
,
680 asize(desc
),desc
,asize(bugs
),bugs
);
682 if ((nprocs
> 0) && (nprocs
<= MAXPROC
))
683 printf("creating statusfile for %d processor%s...\n",
684 nprocs
,nprocs
==1?"":"s");
686 fatal_error(0,"invalid number of processors %d\n",nprocs
);
688 if (bShuffle
&& opt2bSet("-r",NFILE
,fnm
)) {
689 fprintf(stderr
,"Can not shuffle and do position restraints, "
690 "turning off shuffle\n");
694 init_warning(maxwarn
);
696 /* PARAMETER file processing */
697 mdparin
= opt2fn("-f",NFILE
,fnm
);
698 set_warning_line(mdparin
,-1);
699 get_ir(mdparin
,opt2fn("-po",NFILE
,fnm
),ir
,opts
,&nerror
);
702 fprintf(stderr
,"checking input for internal consistency...\n");
703 check_ir(ir
,opts
,&nerror
);
705 if (ir
->ld_seed
== -1) {
706 ir
->ld_seed
= make_seed();
707 fprintf(stderr
,"Setting the LD random seed to %d\n",ir
->ld_seed
);
710 if (bShuffle
&& (opts
->eDisre
==edrEnsemble
)) {
711 fprintf(stderr
,"Can not shuffle and do ensemble averaging, "
712 "turning off shuffle\n");
716 bNeedVel
= (ir
->eI
== eiMD
);
717 bGenVel
= (bNeedVel
&& opts
->bGenVel
);
723 pr_symtab(debug
,0,"Just opened",&sys
->symtab
);
725 strcpy(fn
,ftp2fn(efTOP
,NFILE
,fnm
));
727 fatal_error(0,"%s does not exist",fn
);
728 forward
=new_status(fn
,opt2fn_null("-pp",NFILE
,fnm
),opt2fn("-c",NFILE
,fnm
),
729 opts
,ir
,bGenVel
,bVerbose
,&natoms
,&x
,&v
,box
,
730 &atype
,sys
,&msys
,plist
,bShuffle
? nprocs
: 1,
731 (opts
->eDisre
==edrEnsemble
),opts
->bMorse
,&nerror
);
734 pr_symtab(debug
,0,"After new_status",&sys
->symtab
);
736 if (ir
->eI
== eiCG
) {
738 nc
= count_constraints(msys
.plist
);
741 "ERROR: can not do Conjugate Gradients with constraints (%d)\n",
750 fatal_error(0,"There was %d error",nerror
);
752 fatal_error(0,"There were %d errors",nerror
);
754 if (opt2bSet("-r",NFILE
,fnm
))
755 sprintf(fn
,opt2fn("-r",NFILE
,fnm
));
757 sprintf(fn
,opt2fn("-c",NFILE
,fnm
));
759 if (msys
.plist
[F_POSRES
].nr
> 0) {
761 fprintf(stderr
,"Reading position restraint coords from %s\n",fn
);
762 gen_posres(&(msys
.plist
[F_POSRES
]),fn
);
765 /* set parameters for Dummy construction */
766 ndum
=set_dummies(bVerbose
, &sys
->atoms
, atype
, msys
.plist
);
767 /* now throw away all obsolete bonds, angles and dihedrals: */
768 /* note: constraints are ALWAYS removed */
770 clean_dum_bondeds(msys
.plist
,sys
->atoms
.nr
,bRmDumBds
);
773 atype
.nr
=renum_atype(plist
, sys
, atype
.nr
, ir
, bVerbose
);
776 pr_symtab(debug
,0,"After renum_atype",&sys
->symtab
);
779 fprintf(stderr
,"converting bonded parameters...\n");
780 convert_params(atype
.nr
, plist
, msys
.plist
, &sys
->idef
);
783 pr_symtab(debug
,0,"After convert_params",&sys
->symtab
);
785 /* set ptype to Dummy for dummy atoms */
787 set_dummies_ptype(bVerbose
,&sys
->idef
,&sys
->atoms
);
789 pr_symtab(debug
,0,"After dummy",&sys
->symtab
);
793 check_mol(&(sys
->atoms
));
795 /* Now build the shakeblocks from the shakes */
796 gen_sblocks(bVerbose
,sys
->atoms
.nr
,&(sys
->idef
),&(sys
->blocks
[ebSBLOCKS
]));
798 pr_symtab(debug
,0,"After gen_sblocks",&sys
->symtab
);
801 fprintf(stderr
,"initialising group options...\n");
802 do_index(ftp2fn_null(efNDX
,NFILE
,fnm
),
803 &sys
->symtab
,&(sys
->atoms
),bVerbose
,ir
,&sys
->idef
,
806 pr_symtab(debug
,0,"After index",&sys
->symtab
);
807 triple_check(mdparin
,ir
,sys
,&nerror
);
808 close_symtab(&sys
->symtab
);
810 pr_symtab(debug
,0,"After close",&sys
->symtab
);
812 if (ftp2bSet(efTRN
,NFILE
,fnm
)) {
814 fprintf(stderr
,"getting data from old trajectory ...\n");
815 cont_status(ftp2fn(efTRN
,NFILE
,fnm
),bNeedVel
,bGenVel
,fr_time
,ir
,&natoms
,
819 if ((ir
->coulombtype
== eelPPPM
) || (ir
->coulombtype
== eelPME
)) {
820 /* Calculate the optimal grid dimensions */
821 max_spacing
= calc_grid(box
,opts
->fourierspacing
,
822 &(ir
->nkx
),&(ir
->nky
),&(ir
->nkz
),nprocs
);
823 if ((ir
->coulombtype
== eelPPPM
) && (max_spacing
> 0.1)) {
824 set_warning_line(mdparin
,-1);
825 sprintf(warn_buf
,"Grid spacing larger then 0.1 while using PPPM.");
830 /* This is also necessary for setting the multinr arrays */
831 split_top(bVerbose
,nprocs
,sys
);
834 fprintf(stderr
,"writing run input file...\n");
836 write_tpx(ftp2fn(efTPX
,NFILE
,fnm
),
837 0,ir
->init_t
,ir
->init_lambda
,ir
,box
,
838 natoms
,x
,v
,NULL
,sys
);