2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5 * Copyright (c) 2001-2004, The GROMACS development team,
6 * check out http://www.gromacs.org for more information.
7 * Copyright (c) 2012,2013, by the GROMACS development team, led by
8 * David van der Spoel, Berk Hess, Erik Lindahl, and including many
9 * others, as listed in the AUTHORS file in the top-level source
10 * directory and at http://www.gromacs.org.
12 * GROMACS is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public License
14 * as published by the Free Software Foundation; either version 2.1
15 * of the License, or (at your option) any later version.
17 * GROMACS is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with GROMACS; if not, see
24 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
25 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 * If you want to redistribute modifications to GROMACS, please
28 * consider that scientific software is very special. Version
29 * control is crucial - bugs must be traceable. We will be happy to
30 * consider code for inclusion in the official distribution, but
31 * derived work must not be called official GROMACS. Details are found
32 * in the README & COPYING files - if they are missing, get the
33 * official version at http://www.gromacs.org.
35 * To help us fund GROMACS development, we humbly ask that you cite
36 * the research papers on the package. Check out http://www.gromacs.org.
58 #include "gmx_fatal.h"
68 void print_stat(rvec *x,int natoms,matrix box)
72 for(m=0;(m<DIM);m++) {
76 for(i=0;(i<natoms);i++) {
78 xmin[m]=min(xmin[m],x[i][m]);
79 xmax[m]=max(xmax[m],x[i][m]);
83 fprintf(stderr,"DIM %d XMIN %8.3f XMAX %8.3f BOX %8.3f\n",
84 m,xmin[m],xmax[m],box[m][m]);
88 static gmx_bool in_box(t_pbc *pbc,rvec x)
93 /* pbc_dx_aiuc only works correctly with the rectangular box center */
94 calc_box_center(ecenterRECT,pbc->box,box_center);
96 shift = pbc_dx_aiuc(pbc,x,box_center,dx);
98 return (shift == CENTRAL);
101 static void mk_vdw(t_atoms *a,real rvdw[],gmx_atomprop_t aps,
106 /* initialise van der waals arrays of configuration */
107 fprintf(stderr,"Initialising van der waals distances...\n");
108 for(i=0; (i < a->nr); i++)
109 if (!gmx_atomprop_query(aps,epropVDW,
110 *(a->resinfo[a->atom[i].resind].name),
111 *(a->atomname[i]),&(rvdw[i])))
112 rvdw[i] = r_distance;
123 void sort_molecule(t_atoms **atoms_solvt,rvec *x,rvec *v,real *r)
125 int atnr,i,j,moltp=0,nrmoltypes,resi_o,resi_n,resnr;
126 t_moltypes *moltypes;
127 t_atoms *atoms,*newatoms;
128 rvec *newx, *newv=NULL;
131 fprintf(stderr,"Sorting configuration\n");
133 atoms = *atoms_solvt;
135 /* copy each residue from *atoms to a molecule in *molecule */
139 for (i=0; i<atoms->nr; i++) {
140 if ( (i==0) || (atoms->atom[i].resind != atoms->atom[i-1].resind) ) {
141 /* see if this was a molecule type we haven't had yet: */
143 for (j=0; (j<nrmoltypes) && (moltp==NOTSET); j++)
144 if (strcmp(*(atoms->resinfo[atoms->atom[i].resind].name),
145 moltypes[j].name)==0)
150 srenew(moltypes,nrmoltypes);
151 moltypes[moltp].name=*(atoms->resinfo[atoms->atom[i].resind].name);
153 while ((i+atnr<atoms->nr) &&
154 (atoms->atom[i].resind == atoms->atom[i+atnr].resind))
156 moltypes[moltp].natoms=atnr;
157 moltypes[moltp].nmol=0;
159 moltypes[moltp].nmol++;
163 fprintf(stderr,"Found %d%s molecule type%s:\n",
164 nrmoltypes,nrmoltypes==1?"":" different",nrmoltypes==1?"":"s");
165 for(j=0; j<nrmoltypes; j++) {
167 moltypes[j].res0 = 0;
169 moltypes[j].res0 = moltypes[j-1].res0+moltypes[j-1].nmol;
170 fprintf(stderr,"%7s (%4d atoms): %5d residues\n",
171 moltypes[j].name,moltypes[j].natoms,moltypes[j].nmol);
174 /* if we have only 1 moleculetype, we don't have to sort */
176 /* find out which molecules should go where: */
177 moltypes[0].i = moltypes[0].i0 = 0;
178 for(j=1; j<nrmoltypes; j++) {
181 moltypes[j-1].i0+moltypes[j-1].natoms*moltypes[j-1].nmol;
184 /* now put them there: */
186 init_t_atoms(newatoms,atoms->nr,FALSE);
187 newatoms->nres=atoms->nres;
188 snew(newatoms->resinfo,atoms->nres);
189 snew(newx,atoms->nr);
190 if (v) snew(newv,atoms->nr);
191 snew(newr,atoms->nr);
196 for(moltp=0; moltp<nrmoltypes; moltp++) {
198 while (i < atoms->nr) {
199 resi_o = atoms->atom[i].resind;
200 if (strcmp(*atoms->resinfo[resi_o].name,moltypes[moltp].name) == 0) {
201 /* Copy the residue info */
202 newatoms->resinfo[resi_n] = atoms->resinfo[resi_o];
203 newatoms->resinfo[resi_n].nr = resnr;
204 /* Copy the atom info */
206 newatoms->atom[j] = atoms->atom[i];
207 newatoms->atomname[j] = atoms->atomname[i];
208 newatoms->atom[j].resind = resi_n;
209 copy_rvec(x[i],newx[j]);
211 copy_rvec(v[i],newv[j]);
216 } while (i < atoms->nr && atoms->atom[i].resind == resi_o);
217 /* Increase the new residue counters */
221 /* Skip this residue */
224 } while (i < atoms->nr && atoms->atom[i].resind == resi_o);
229 /* put them back into the original arrays and throw away temporary arrays */
230 sfree(atoms->atomname);
231 sfree(atoms->resinfo);
234 *atoms_solvt = newatoms;
235 for (i=0; i<(*atoms_solvt)->nr; i++) {
236 copy_rvec(newx[i],x[i]);
237 if (v) copy_rvec(newv[i],v[i]);
247 void rm_res_pbc(t_atoms *atoms, rvec *x, matrix box)
255 for(n=0; n<atoms->nr; n++) {
256 if (!is_hydrogen(*(atoms->atomname[n]))) {
260 if ( (n+1 == atoms->nr) ||
261 (atoms->atom[n+1].resind != atoms->atom[n].resind) ) {
262 /* if nat==0 we have only hydrogens in the solvent,
263 we take last coordinate as cg */
268 svmul(1.0/nat,xcg,xcg);
269 for(d=0; d<DIM; d++) {
271 for(i=start; i<=n; i++)
275 while (xcg[d]>=box[d][d]) {
276 for(i=start; i<=n; i++)
288 static char *insert_mols(const char *mol_insrt,int nmol_insrt,int ntry,int seed,
289 t_atoms *atoms,rvec **x,real **r,int ePBC,matrix box,
290 gmx_atomprop_t aps,real r_distance,real rshell,
291 const output_env_t oenv)
294 static char *title_insrt;
301 real alfa,beta,gamma;
305 set_pbc(&pbc,ePBC,box);
307 /* read number of atoms of insert molecules */
308 get_stx_coordnum(mol_insrt,&atoms_insrt.nr);
309 if (atoms_insrt.nr == 0)
310 gmx_fatal(FARGS,"No molecule in %s, please check your input\n",mol_insrt);
311 /* allocate memory for atom coordinates of insert molecules */
312 snew(x_insrt,atoms_insrt.nr);
313 snew(r_insrt,atoms_insrt.nr);
314 snew(atoms_insrt.resinfo,atoms_insrt.nr);
315 snew(atoms_insrt.atomname,atoms_insrt.nr);
316 snew(atoms_insrt.atom,atoms_insrt.nr);
317 atoms_insrt.pdbinfo = NULL;
318 snew(x_n,atoms_insrt.nr);
319 snew(title_insrt,STRLEN);
321 /* read residue number, residue names, atomnames, coordinates etc. */
322 fprintf(stderr,"Reading molecule configuration \n");
323 read_stx_conf(mol_insrt,title_insrt,&atoms_insrt,x_insrt,NULL,
324 &ePBC_insrt,box_insrt);
325 fprintf(stderr,"%s\nContaining %d atoms in %d residue\n",
326 title_insrt,atoms_insrt.nr,atoms_insrt.nres);
327 srenew(atoms_insrt.resinfo,atoms_insrt.nres);
329 /* initialise van der waals arrays of insert molecules */
330 mk_vdw(&atoms_insrt,r_insrt,aps,r_distance);
332 srenew(atoms->resinfo,(atoms->nres+nmol_insrt*atoms_insrt.nres));
333 srenew(atoms->atomname,(atoms->nr+atoms_insrt.nr*nmol_insrt));
334 srenew(atoms->atom,(atoms->nr+atoms_insrt.nr*nmol_insrt));
335 srenew(*x,(atoms->nr+atoms_insrt.nr*nmol_insrt));
336 srenew(*r,(atoms->nr+atoms_insrt.nr*nmol_insrt));
339 while ((mol < nmol_insrt) && (trial < ntry*nmol_insrt)) {
340 fprintf(stderr,"\rTry %d",trial++);
341 for (i=0;(i<atoms_insrt.nr);i++) {
342 copy_rvec(x_insrt[i],x_n[i]);
344 alfa=2*M_PI*rando(&seed);
345 beta=2*M_PI*rando(&seed);
346 gamma=2*M_PI*rando(&seed);
347 rotate_conf(atoms_insrt.nr,x_n,NULL,alfa,beta,gamma);
348 offset_x[XX]=box[XX][XX]*rando(&seed);
349 offset_x[YY]=box[YY][YY]*rando(&seed);
350 offset_x[ZZ]=box[ZZ][ZZ]*rando(&seed);
351 gen_box(0,atoms_insrt.nr,x_n,box_insrt,offset_x,TRUE);
352 if (!in_box(&pbc,x_n[0]) || !in_box(&pbc,x_n[atoms_insrt.nr-1]))
356 add_conf(atoms,x,NULL,r,FALSE,ePBC,box,TRUE,
357 &atoms_insrt,x_n,NULL,r_insrt,FALSE,rshell,0,oenv);
359 if (atoms->nr==(atoms_insrt.nr+onr)) {
361 fprintf(stderr," success (now %d atoms)!",atoms->nr);
364 srenew(atoms->resinfo, atoms->nres);
365 srenew(atoms->atomname, atoms->nr);
366 srenew(atoms->atom, atoms->nr);
367 srenew(*x, atoms->nr);
368 srenew(*r, atoms->nr);
370 fprintf(stderr,"\n");
371 /* print number of molecules added */
372 fprintf(stderr,"Added %d molecules (out of %d requested) of %s\n",
373 mol,nmol_insrt,*atoms_insrt.resinfo[0].name);
378 static void add_solv(const char *fn,t_atoms *atoms,rvec **x,rvec **v,real **r,
380 gmx_atomprop_t aps,real r_distance,int *atoms_added,
381 int *residues_added,real rshell,int max_sol,
382 const output_env_t oenv)
386 char filename[STRLEN];
387 char title_solvt[STRLEN];
388 t_atoms *atoms_solvt;
389 rvec *x_solvt,*v_solvt=NULL;
397 strncpy(filename,lfn,STRLEN);
400 get_stx_coordnum(filename,&(atoms_solvt->nr));
401 if (atoms_solvt->nr == 0)
402 gmx_fatal(FARGS,"No solvent in %s, please check your input\n",filename);
403 snew(x_solvt,atoms_solvt->nr);
404 if (v) snew(v_solvt,atoms_solvt->nr);
405 snew(r_solvt,atoms_solvt->nr);
406 snew(atoms_solvt->resinfo,atoms_solvt->nr);
407 snew(atoms_solvt->atomname,atoms_solvt->nr);
408 snew(atoms_solvt->atom,atoms_solvt->nr);
409 atoms_solvt->pdbinfo = NULL;
410 fprintf(stderr,"Reading solvent configuration%s\n",
411 v_solvt?" and velocities":"");
412 read_stx_conf(filename,title_solvt,atoms_solvt,x_solvt,v_solvt,
413 &ePBC_solvt,box_solvt);
414 fprintf(stderr,"\"%s\"\n",title_solvt);
415 fprintf(stderr,"solvent configuration contains %d atoms in %d residues\n",
416 atoms_solvt->nr,atoms_solvt->nres);
417 fprintf(stderr,"\n");
419 /* apply pbc for solvent configuration for whole molecules */
420 rm_res_pbc(atoms_solvt,x_solvt,box_solvt);
422 /* initialise van der waals arrays of solvent configuration */
423 mk_vdw(atoms_solvt,r_solvt,aps,r_distance);
425 /* calculate the box multiplication factors n_box[0...DIM] */
427 for (i=0; (i < DIM);i++) {
429 while (n_box[i]*box_solvt[i][i] < box[i][i])
433 fprintf(stderr,"Will generate new solvent configuration of %dx%dx%d boxes\n",
434 n_box[XX],n_box[YY],n_box[ZZ]);
436 /* realloc atoms_solvt for the new solvent configuration */
437 srenew(atoms_solvt->resinfo,atoms_solvt->nres*nmol);
438 srenew(atoms_solvt->atomname,atoms_solvt->nr*nmol);
439 srenew(atoms_solvt->atom,atoms_solvt->nr*nmol);
440 srenew(x_solvt,atoms_solvt->nr*nmol);
441 if (v_solvt) srenew(v_solvt,atoms_solvt->nr*nmol);
442 srenew(r_solvt,atoms_solvt->nr*nmol);
444 /* generate a new solvent configuration */
445 genconf(atoms_solvt,x_solvt,v_solvt,r_solvt,box_solvt,n_box);
448 print_stat(x_solvt,atoms_solvt->nr,box_solvt);
452 print_stat(x_solvt,atoms_solvt->nr,box_solvt);
454 /* Sort the solvent mixture, not the protein... */
455 sort_molecule(&atoms_solvt,x_solvt,v_solvt,r_solvt);
457 /* add the two configurations */
460 add_conf(atoms,x,v,r,TRUE,ePBC,box,FALSE,
461 atoms_solvt,x_solvt,v_solvt,r_solvt,TRUE,rshell,max_sol,oenv);
462 *atoms_added=atoms->nr-onr;
463 *residues_added=atoms->nres-onres;
468 fprintf(stderr,"Generated solvent containing %d atoms in %d residues\n",
469 *atoms_added,*residues_added);
472 static char *read_prot(const char *confin,t_atoms *atoms,rvec **x,rvec **v,
473 real **r, int *ePBC,matrix box,gmx_atomprop_t aps,
480 get_stx_coordnum(confin,&natoms);
482 /* allocate memory for atom coordinates of configuration 1 */
484 if (v) snew(*v,natoms);
486 init_t_atoms(atoms,natoms,FALSE);
488 /* read residue number, residue names, atomnames, coordinates etc. */
489 fprintf(stderr,"Reading solute configuration%s\n",v?" and velocities":"");
490 read_stx_conf(confin,title,atoms,*x,v?*v:NULL,ePBC,box);
491 fprintf(stderr,"%s\nContaining %d atoms in %d residues\n",
492 title,atoms->nr,atoms->nres);
494 /* initialise van der waals arrays of configuration 1 */
495 mk_vdw(atoms,*r,aps,r_distance);
500 static void update_top(t_atoms *atoms,matrix box,int NFILE,t_filenm fnm[],
503 #define TEMP_FILENM "temp.top"
505 char buf[STRLEN],buf2[STRLEN],*temp;
506 const char *topinout;
508 gmx_bool bSystem,bMolecules,bSkip;
513 for(i=0; (i<atoms->nres); i++) {
514 /* calculate number of SOLvent molecules */
515 if ( (strcmp(*atoms->resinfo[i].name,"SOL")==0) ||
516 (strcmp(*atoms->resinfo[i].name,"WAT")==0) ||
517 (strcmp(*atoms->resinfo[i].name,"HOH")==0) )
521 for(i=0; (i<atoms->nr); i++) {
522 gmx_atomprop_query(aps,epropMass,
523 *atoms->resinfo[atoms->atom[i].resind].name,
524 *atoms->atomname[i],&mm);
530 fprintf(stderr,"Volume : %10g (nm^3)\n",vol);
531 fprintf(stderr,"Density : %10g (g/l)\n",
532 (mtot*1e24)/(AVOGADRO*vol));
533 fprintf(stderr,"Number of SOL molecules: %5d \n\n",nsol);
535 /* open topology file and append sol molecules */
536 topinout = ftp2fn(efTOP,NFILE,fnm);
537 if ( ftp2bSet(efTOP,NFILE,fnm) ) {
538 fprintf(stderr,"Processing topology\n");
539 fpin = ffopen(topinout,"r");
540 fpout= ffopen(TEMP_FILENM,"w");
542 bSystem = bMolecules = FALSE;
543 while (fgets(buf, STRLEN, fpin)) {
547 if ((temp=strchr(buf2,'\n')) != NULL)
552 if ((temp=strchr(buf2,'\n')) != NULL)
555 if (buf2[strlen(buf2)-1]==']') {
556 buf2[strlen(buf2)-1]='\0';
559 bSystem=(gmx_strcasecmp(buf2,"system")==0);
560 bMolecules=(gmx_strcasecmp(buf2,"molecules")==0);
562 } else if (bSystem && nsol && (buf[0]!=';') ) {
563 /* if sol present, append "in water" to system name */
565 if (buf2[0] && (!strstr(buf2," water")) ) {
566 sprintf(buf,"%s in water\n",buf2);
569 } else if (bMolecules) {
570 /* check if this is a line with solvent molecules */
571 sscanf(buf,"%s",buf2);
572 if (strcmp(buf2,"SOL")==0) {
573 sscanf(buf,"%*s %d",&i);
582 if ((temp=strchr(buf,'\n')) != NULL)
584 fprintf(stdout,"Removing line #%d '%s' from topology file (%s)\n",
587 fprintf(fpout,"%s",buf);
591 fprintf(stdout,"Adding line for %d solvent molecules to "
592 "topology file (%s)\n",nsol,topinout);
593 fprintf(fpout,"%-15s %5d\n","SOL",nsol);
596 /* use ffopen to generate backup of topinout */
597 fpout=ffopen(topinout,"w");
599 rename(TEMP_FILENM,topinout);
604 int gmx_genbox(int argc,char *argv[])
606 const char *desc[] = {
607 "[TT]genbox[tt] can do one of 3 things:[PAR]",
609 "1) Generate a box of solvent. Specify [TT]-cs[tt] and [TT]-box[tt]. Or specify [TT]-cs[tt] and",
610 "[TT]-cp[tt] with a structure file with a box, but without atoms.[PAR]",
612 "2) Solvate a solute configuration, e.g. a protein, in a bath of solvent ",
613 "molecules. Specify [TT]-cp[tt] (solute) and [TT]-cs[tt] (solvent). ",
614 "The box specified in the solute coordinate file ([TT]-cp[tt]) is used,",
615 "unless [TT]-box[tt] is set.",
616 "If you want the solute to be centered in the box,",
617 "the program [TT]editconf[tt] has sophisticated options",
618 "to change the box dimensions and center the solute.",
619 "Solvent molecules are removed from the box where the ",
620 "distance between any atom of the solute molecule(s) and any atom of ",
621 "the solvent molecule is less than the sum of the van der Waals radii of ",
622 "both atoms. A database ([TT]vdwradii.dat[tt]) of van der Waals radii is ",
623 "read by the program, and atoms not in the database are ",
624 "assigned a default distance [TT]-vdwd[tt].",
625 "Note that this option will also influence the distances between",
626 "solvent molecules if they contain atoms that are not in the database.",
629 "3) Insert a number ([TT]-nmol[tt]) of extra molecules ([TT]-ci[tt]) ",
630 "at random positions.",
631 "The program iterates until [TT]nmol[tt] molecules",
632 "have been inserted in the box. To test whether an insertion is ",
633 "successful the same van der Waals criterium is used as for removal of ",
634 "solvent molecules. When no appropriately-sized ",
635 "holes (holes that can hold an extra molecule) are available, the ",
636 "program tries for [TT]-nmol[tt] * [TT]-try[tt] times before giving up. ",
637 "Increase [TT]-try[tt] if you have several small holes to fill.[PAR]",
639 "If you need to do more than one of the above operations, it can be",
640 "best to call [TT]genbox[tt] separately for each operation, so that",
641 "you are sure of the order in which the operations occur.[PAR]",
643 "The default solvent is Simple Point Charge water (SPC), with coordinates ",
644 "from [TT]$GMXLIB/spc216.gro[tt]. These coordinates can also be used",
645 "for other 3-site water models, since a short equibilibration will remove",
646 "the small differences between the models.",
647 "Other solvents are also supported, as well as mixed solvents. The",
648 "only restriction to solvent types is that a solvent molecule consists",
649 "of exactly one residue. The residue information in the coordinate",
650 "files is used, and should therefore be more or less consistent.",
651 "In practice this means that two subsequent solvent molecules in the ",
652 "solvent coordinate file should have different residue number.",
653 "The box of solute is built by stacking the coordinates read from",
654 "the coordinate file. This means that these coordinates should be ",
655 "equlibrated in periodic boundary conditions to ensure a good",
656 "alignment of molecules on the stacking interfaces.",
657 "The [TT]-maxsol[tt] option simply adds only the first [TT]-maxsol[tt]",
658 "solvent molecules and leaves out the rest that would have fitted",
659 "into the box. This can create a void that can cause problems later.",
660 "Choose your volume wisely.[PAR]",
662 "The program can optionally rotate the solute molecule to align the",
663 "longest molecule axis along a box edge. This way the amount of solvent",
664 "molecules necessary is reduced.",
665 "It should be kept in mind that this only works for",
666 "short simulations, as e.g. an alpha-helical peptide in solution can ",
667 "rotate over 90 degrees, within 500 ps. In general it is therefore ",
668 "better to make a more or less cubic box.[PAR]",
670 "Setting [TT]-shell[tt] larger than zero will place a layer of water of",
671 "the specified thickness (nm) around the solute. Hint: it is a good",
672 "idea to put the protein in the center of a box first (using [TT]editconf[tt]).",
675 "Finally, [TT]genbox[tt] will optionally remove lines from your topology file in ",
676 "which a number of solvent molecules is already added, and adds a ",
677 "line with the total number of solvent molecules in your coordinate file."
680 const char *bugs[] = {
681 "Molecules must be whole in the initial configurations.",
685 gmx_bool bSol,bProt,bBox;
686 const char *conf_prot,*confout;
692 /* protein configuration data */
700 /* other data types */
701 int atoms_added,residues_added;
704 { efSTX, "-cp", "protein", ffOPTRD },
705 { efSTX, "-cs", "spc216", ffLIBOPTRD},
706 { efSTX, "-ci", "insert", ffOPTRD},
707 { efSTO, NULL, NULL, ffWRITE},
708 { efTOP, NULL, NULL, ffOPTRW},
710 #define NFILE asize(fnm)
712 static int nmol_ins=0,nmol_try=10,seed=1997;
713 static real r_distance=0.105,r_shell=0;
714 static rvec new_box={0.0,0.0,0.0};
715 static gmx_bool bReadV=FALSE;
716 static int max_sol = 0;
719 { "-box", FALSE, etRVEC, {new_box},
721 { "-nmol", FALSE, etINT , {&nmol_ins},
722 "Number of extra molecules to insert" },
723 { "-try", FALSE, etINT , {&nmol_try},
724 "Try inserting [TT]-nmol[tt] times [TT]-try[tt] times" },
725 { "-seed", FALSE, etINT , {&seed},
726 "Random generator seed"},
727 { "-vdwd", FALSE, etREAL, {&r_distance},
728 "Default van der Waals distance"},
729 { "-shell", FALSE, etREAL, {&r_shell},
730 "Thickness of optional water layer around solute" },
731 { "-maxsol", FALSE, etINT, {&max_sol},
732 "Maximum number of solvent molecules to add if they fit in the box. If zero (default) this is ignored" },
733 { "-vel", FALSE, etBOOL, {&bReadV},
734 "Keep velocities from input solute and solvent" }
737 CopyRight(stderr,argv[0]);
738 parse_common_args(&argc,argv, PCA_BE_NICE,NFILE,fnm,asize(pa),pa,
739 asize(desc),desc,asize(bugs),bugs,&oenv);
741 bInsert = opt2bSet("-ci",NFILE,fnm) && (nmol_ins > 0);
742 bSol = opt2bSet("-cs",NFILE,fnm);
743 bProt = opt2bSet("-cp",NFILE,fnm);
744 bBox = opt2parg_bSet("-box",asize(pa),pa);
747 if (bInsert && nmol_ins<=0)
748 gmx_fatal(FARGS,"When specifying inserted molecules (-ci), "
749 "-nmol must be larger than 0");
750 if (!bInsert && nmol_ins > 0)
753 "You tried to insert molecules with -nmol, but did not supply "
754 "a molecule to insert with -ci.");
757 gmx_fatal(FARGS,"When no solute (-cp) is specified, "
758 "a box size (-box) must be specified");
760 aps = gmx_atomprop_init();
763 /*generate a solute configuration */
764 conf_prot = opt2fn("-cp",NFILE,fnm);
765 title = read_prot(conf_prot,&atoms,&x,bReadV?&v:NULL,&r,&ePBC,box,
768 fprintf(stderr,"Note: no velocities found\n");
770 fprintf(stderr,"Note: no atoms in %s\n",conf_prot);
787 box[XX][XX]=new_box[XX];
788 box[YY][YY]=new_box[YY];
789 box[ZZ][ZZ]=new_box[ZZ];
792 gmx_fatal(FARGS,"Undefined solute box.\nCreate one with editconf "
793 "or give explicit -box command line option");
795 /* add nmol_ins molecules of atoms_ins
796 in random orientation at random place */
798 title_ins = insert_mols(opt2fn("-ci",NFILE,fnm),nmol_ins,nmol_try,seed,
799 &atoms,&x,&r,ePBC,box,aps,r_distance,r_shell,
802 title_ins = strdup("Generated by genbox");
806 add_solv(opt2fn("-cs",NFILE,fnm),&atoms,&x,v?&v:NULL,&r,ePBC,box,
807 aps,r_distance,&atoms_added,&residues_added,r_shell,max_sol,
810 /* write new configuration 1 to file confout */
811 confout = ftp2fn(efSTO,NFILE,fnm);
812 fprintf(stderr,"Writing generated configuration to %s\n",confout);
814 write_sto_conf(confout,title,&atoms,x,v,ePBC,box);
815 /* print box sizes and box type to stderr */
816 fprintf(stderr,"%s\n",title);
818 write_sto_conf(confout,title_ins,&atoms,x,v,ePBC,box);
820 /* print size of generated configuration */
821 fprintf(stderr,"\nOutput configuration contains %d atoms in %d residues\n",
822 atoms.nr,atoms.nres);
823 update_top(&atoms,box,NFILE,fnm,aps);
825 gmx_atomprop_destroy(aps);