int main(int argc,char *argv[]) { static char *desc[] = { "[TT]mkice[tt] generates an ice crystal in the Ih crystal form which is the", "most stable form. The rectangular unitcell contains eight molecules", "and all oxygens are tetrahedrally coordinated.[PAR]", "If an input file is given it is interpreted as a series of oxygen", "coordinates the distance between which can be scaled by the odist flag.", "The program then adds hydrogens to the oxygens in random orientation", "but with proper OH distances and HOH angle. This feature allows to", "build water clusters based on oxygen coordinates only." }; static int nx=1,ny=1,nz=1; static gmx_bool bYaw=FALSE,bLJ=TRUE,bFull=TRUE,bSeries=FALSE; static gmx_bool bOrdered=TRUE,bDiamond=FALSE,bPBC=TRUE; static real rcut=0.3,odist=0.274,hdist=0.09572; t_pargs pa[] = { { "-nx", FALSE, etINT, {&nx}, "nx" }, { "-ny", FALSE, etINT, {&ny}, "ny" }, { "-nz", FALSE, etINT, {&nz}, "nz" }, { "-yaw", FALSE, etBOOL, {&bYaw}, "Generate virtual sites and shell positions" }, { "-lj", FALSE, etBOOL, {&bLJ}, "Use LJ as well as coulomb for virial calculation" }, { "-rcut", FALSE,etREAL, {&rcut},"Cut-off for virial calculations" }, { "-full", FALSE,etBOOL, {&bFull},"Full virial output" }, { "-odist", FALSE, etREAL, {&odist}, "Distance (nm) between oxygens" }, { "-hdist", FALSE, etREAL, {&hdist}, "Bondlength (nm) for OH bond" }, { "-diamond",FALSE,etBOOL, {&bDiamond}, "Make a diamond instead" }, { "-pbc", FALSE, etBOOL, {&bPBC}, "Make a periodic diamond" }, { "-order", FALSE,etBOOL, {&bOrdered}, "Make a proton-ordered ice lattice" }, { "-series",FALSE, etBOOL, {&bSeries}, "Do a series of virial calculations with different cut-off (from 0.3 up till the specified one)" } }; t_filenm fnm[] = { { efSTO, "-p", "ice", ffWRITE }, { efSTO, "-c", NULL, ffOPTRD }, { efDAT, "-f", NULL, ffOPTRD }, { efTRN, "-o", "ice", ffOPTWR } }; #define NFILE asize(fnm) FILE *fp; char *fn,quote[256]; int i,j,k,n,nmax,m,natom,natmol; t_atoms *pdba; t_atoms atoms; t_symtab symtab; rvec box,tmp,*xx; matrix boxje; CopyRight(stdout,argv[0]); parse_common_args(&argc,argv,0,NFILE,fnm,asize(pa),pa,asize(desc), desc,0,NULL); if (debug) { fprintf(debug,"nx = %3d, ny = %3d, nz = %3d\n",nx,ny,nz); fprintf(debug,"YAW = %3s, LJ = %3s, rcut = %g\n",yesno_names[bYaw], yesno_names[bLJ],rcut); } if (bYaw) natmol = 5; else if (bDiamond) natmol = 1; else natmol = 3; if (opt2bSet("-f",NFILE,fnm)) { natom = read_rel_coords(opt2fn("-f",NFILE,fnm),&xx,natmol); nmax = natom; } else { natom = natmol*8; nmax = natom*nx*ny*nz; snew(xx,nmax); } snew(pdba,1); init_t_atoms(pdba,nmax,TRUE); pdba->nr = nmax; open_symtab(&symtab); for(n=0; (n<nmax); n++) { pdba->pdbinfo[n].type = epdbATOM; pdba->pdbinfo[n].atomnr = 1+n; pdba->atom[n].resnr = 1+(n/natmol); pdba->atomname[n] = put_symtab(&symtab, bDiamond ? diamname[(n % natmol)] : watname[(n % natmol)]); if (bDiamond) pdba->resname[n] = put_symtab(&symtab,"DIA"); else pdba->resname[n] = put_symtab(&symtab,"SOL"); sprintf(pdba->pdbinfo[n].pdbresnr,"%d",n); pdba->atom[n].chain = ' '; } /* Generate the unit cell */ if (bDiamond) unitcell_d(xx,box,odist); else if (opt2bSet("-f",NFILE,fnm)) { random_h_coords(natmol,natom/natmol,xx,box,bYaw,odist,hdist); } else unitcell(xx,box,bYaw,odist,hdist); if (debug) { clear_mat(boxje); boxje[XX][XX] = box[XX]; boxje[YY][YY] = box[YY]; boxje[ZZ][ZZ] = box[ZZ]; } n=0; for(i=0; (i<nx); i++) { tmp[XX] = i*box[XX]; for(j=0; (j<ny); j++) { tmp[YY] = j*box[YY]; for(k=0; (k<nz); k++) { tmp[ZZ] = k*box[ZZ]; for(m=0; (m<natom); m++,n++) { if ((!bOrdered && ((m % natmol) == 0)) || bOrdered) rvec_add(xx[n % natom],tmp,xx[n]); else ; } } } } clear_mat(boxje); boxje[XX][XX] = box[XX]*nx; boxje[YY][YY] = box[YY]*ny; boxje[ZZ][ZZ] = box[ZZ]*nz; printf("Crystal: %10.5f %10.5f %10.5f\n", nx*box[XX],ny*box[YY],nz*box[ZZ]); if (debug && !bDiamond) { if (bSeries) for(i=3; (i<=10*rcut); i++) { fprintf(debug,"This is with rcut = %g\n",i*0.1); virial(debug,bFull,nmax/natmol,xx,boxje, 0.1*i,bYaw,bYaw ? qyaw : qspc,bLJ); } else virial(debug,bFull,nmax/natmol,xx,boxje, rcut,bYaw,bYaw ? qyaw : qspc,bLJ); } if (bDiamond) mk_diamond(pdba,xx,odist,&symtab,bPBC,boxje); fn = ftp2fn(efSTO,NFILE,fnm); if (fn2ftp(fn) == efPDB) { fp = gmx_ffopen(fn,"w"); if (bDiamond) fprintf(fp,"HEADER This is a *diamond*\n"); else fprintf(fp,"HEADER A beautiful Ice Ih crystal\n"); fprintf(fp,"REMARK Generated by mkice with the following options:\n" "REMARK nx = %d, ny = %d, nz = %d, odist = %g, hdist = %g\n", nx,ny,nz,odist,hdist); bromacs(quote,255); write_pdbfile(fp,quote,pdba,xx,boxje,' ',-1); gmx_ffclose(fp); } else { bromacs(quote,255); write_sto_conf(fn,quote,pdba,xx,NULL,boxje); } if (ftp2bSet(efTRN,NFILE,fnm)) write_trn(ftp2fn(efTRN,NFILE,fnm),0,0,0,boxje,nmax,xx,NULL,NULL); return 0; }
int main (int argc, char *argv[]) { static char usage[] = { "Calculate positions of pseudo-atoms in a model for a transmembrane channel and\n" "write output to FILE or pore.pdb and pore.itp.\n\n" " -h\t\t show help\n" " -v\t\t be verbose (= -debuglevel 30 )\n" " -debug <NUM>\t set debuglevel (0..100)\n" " -spec <NUM>\t default species id\n" " -showspec\t show hard coded species\n\n" " -o FILE\t pdb coordinate file\n" " -s FILE\t itp topology file\n" "\n" " -f <file>\t read pore description from file (see below)\n" " -R <r>\t Outer radius of the model\n" " -P <r> <l>\t Pore region: inner radius and length\n" " -M <r> <l>\t Mouth region: largest inner radius and length\n" " -b dmin dmax g_min g_max (repeatable)\n" "\t\tform bonds with angle gamma when atoms are no further apart\n" "\t\tthan dmax Ang and g_min <= gamma <= g_max, g from [0°..90°] )\n" " -c\t\t only write connectivity to output, no bond length or kB, kA\n" " -x\t\t neither connectivity nor bond length to output (isolated atoms)\n" " -kB <c>\t Force constant of bonds, in kJ mol^-1 nm^-2\n" " -kA <c>\t Force constant of angles, in kJ mol^-1 rad^-2\n" " -cc\t\t Center ccordinates on cavitybox, not on unitcell\n" "\n" "Pore volume calculation (setting any of these switches on profile calculation):\n" "In order to enable volume calculation, set -volume explicitly!\n" "ATTENTION: all these LENGTHs are in NANO METRE not Angstrom !\n" " -profile [<file>] calculate the profile in addition to the volume\n" " -z1, -z2 <z> profile between z1 and z2\n" " -Rmax <r> integrate out to Rmax (also use for the total volume\n" " integration if -profile is set)\n" " -npoints <N> number of points per dimension in the integrals\n" " -T temp Temperature in Kelvin [300]\n" " -wca If set, only use the repulsive part of the Lennard-Jones\n" " potential (split after Weeks, Chandler & Andersen [1971])\n" " -plot xfarbe output of the potential in z slices\n" " -nzplot number of plot slices \n" "\nDescription of the input file:\n" "------------------------------\n" "Instead of using -R (RADIUS), -M (MOUTH), and -P (PORE) one can describe the system\n" "in a more flexible manner with a geometry in put file. It can contain up to " "MAXDOMAINS domains (i.e. MOUTH and PORE lines). Allowed lines:\n" "# comment (skipped)\n" "# RADIUS is the global outer radius (in Angstrom) of the cylinder\n" "RADIUS r_outer\n" "# domain type and radius at the upper and lower end of the domain;\n" "# r_lower of domain i and r_upper of domain i+1 are typically identical\n" "MOUTH r_upper r_lower length [species]\n" "PORE r_upper r_lower length [species]\n" }; int i, n_atoms, n_bonds, n_angles, n_bc; int error; real vol; FILE *fp; /* segmentation fault if arrays to large --->> now that I have learned to calloc I should rewrite this on purely aesthetical grounds ! <<---- */ struct pdb_ATOM model[TOTALSITES]; struct itp_bond bonds[MAXBONDS]; struct itp_angle angles[MAXANGLES]; struct geom geometry; struct std_input in; struct potpars potential = { NULL, TEMPERATURE, NFREEDOM_SPC, CSIX_OW_MTH, CTWELVE_OW_MTH, 0.0, 0, NULL, NULL, N_GAUSSLEG }; struct pprofile profile = { "LJprofile.dat", FALSE, FALSE, POT_PLOT_SLICES, NULL, NZPROF, 1.5, -2,2, NULL }; /* argument processing */ /* *** no sanity checks *** */ n_atoms = 0; /* number of sites ('atoms') in the model */ n_bonds = 0; /* number of bonds */ n_angles = 0; /* number of angles between bonds */ n_bc = 0; /* number of constraint conditions for generating bonds */ if (argc < 2) { printf("Running with default values.\n\nType %s -h for help.\n", argv[0]); debuglevel = IMPORTANT; }; /* initialize defaults */ in = default_input (); potential.u1 = vljcyl; /* use the full Lennard-Jones potential in the configurational volume calculations by default */ profile.pp = &potential; /* rudimentary opt-processing.. yarch */ for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "-debug")) { debuglevel = atoi(argv[++i]); } else if (!strcmp(argv[i], "-v")) { debuglevel = VERBOSE; } else if (!strcmp(argv[i], "-h")) { print_usage(argv[0],usage); exit(1); } else if (!strcmp(argv[i], "-showspec")) { print_species (); exit(1); } else if (!strcmp(argv[i], "-o")) { in.coordfile = argv[++i]; } else if (!strcmp(argv[i], "-s")) { in.topofile = argv[++i]; } else if (!strcmp(argv[i], "-f")) { in.datafile = argv[++i]; } else if (!strcmp(argv[i], "-R")) { in.r_outer = atof(argv[++i]); } else if (!strcmp(argv[i], "-M")) { in.r_mouth = atof(argv[++i]); in.l_mouth = atof(argv[++i]); } else if (!strcmp(argv[i], "-P")) { in.r_pore = atof(argv[++i]); in.l_pore = atof(argv[++i]); } else if (!strcmp(argv[i], "-spec")) { in.specid = atoi(argv[++i]); } else if (!strcmp(argv[i], "-b")) { if (n_bc > MAXBONDCONSTRAINTS) { fatal_error (1, "Error: too many bond constraints, maximum is %d.\n", MAXBONDCONSTRAINTS); } in.bc[n_bc].serial = n_bc; in.bc[n_bc].dmin = atof(argv[++i]); in.bc[n_bc].dmax = atof(argv[++i]); in.bc[n_bc].gamma_min = atof(argv[++i]); in.bc[n_bc].gamma_max = atof(argv[++i]); in.n_bc = ++n_bc; } else if (!strcmp(argv[i], "-c")) { in.connectonly = TRUE; } else if (!strcmp(argv[i], "-x")) { in.atomsonly = TRUE; } else if (!strcmp(argv[i], "-cc")) { in.shiftcbox = TRUE; } else if (!strcmp(argv[i], "-kB")) { in.k_bond = atof(argv[++i]); } else if (!strcmp(argv[i], "-kA")) { in.k_angle = atof(argv[++i]); } else if (!strcmp(argv[i], "-volume")) { profile.bSet = TRUE; } else if (!strcmp(argv[i], "-z1")) { profile.bSet = TRUE; profile.z1 = atof(argv[++i]); } else if (!strcmp(argv[i], "-z2")) { profile.bSet = TRUE; profile.z2 = atof(argv[++i]); } else if (!strcmp(argv[i], "-Rmax")) { profile.bSet = TRUE; profile.Rmax = atof(argv[++i]); } else if (!strcmp(argv[i], "-profile")) { profile.bSet = TRUE; if (i < argc-1 && argv[i+1][0] != '-') strncpy(profile.fn,argv[++i],STRLEN); } else if (!strcmp(argv[i], "-npoints")) { potential.ngaussleg = atof(argv[++i]); } else if (!strcmp(argv[i], "-T")) { potential.Temp = atof(argv[++i]); } else if (!strcmp(argv[i], "-wca")) { potential.u1 = vRljcyl; } else if (!strcmp(argv[i], "-plot")) { profile.bPlot = TRUE; } else if (!strcmp(argv[i], "-nzplot")) { profile.bPlot = TRUE; profile.nzplot = atoi(argv[++i]); } else { mesg(OFF,"Unknown option: %s",argv[i]); }; }; mesg (ALL, "TOTALSITES %d\n", TOTALSITES); mesg (ALL, "MAXBONDS %d\nsizeof struct bond %d, sizeof bonds[] %d\n", MAXBONDS, sizeof (struct itp_bond), sizeof (bonds)); mesg (ALL, "MAXANGLES %d\nsizeof struct angle %d, sizeof angles[] %d\n", MAXANGLES, sizeof (struct itp_angle), sizeof (angles)); error = input_geom (&in, &geometry); setup_domain (&geometry); unitcell (&geometry); cavitybox (&geometry); n_atoms = do_coordinates (model, &geometry); if (!geometry.atomsonly) { n_bonds = do_bonds (bonds, model, &geometry); n_angles = do_angles (angles, bonds, &geometry); } else { n_bonds = n_angles = 0; } print_geom (&geometry); mesg (WARN, "\nNumber of sites: %d", n_atoms); if (!geometry.atomsonly) { mesg (WARN, "Number of bonds: %d within max cut-off %5.2f Ang (no double-counting)", n_bonds, find_dmax (geometry.bc, geometry.nbc)); mesg (WARN, "Number of angles: %d (no double-counting)\n", n_angles); } center (model, &geometry); error = write_topology (model, bonds, angles, &geometry); error = write_pdb (model, bonds, &geometry); /* calculate pore volume, based on J. S. Rowlinson, J Chem Soc, Faraday Trans. 2, 82 (1986), 1801, (which didnt really work), and discussion with Andrew Horsefield. */ if (profile.bSet) { vol = volume(&potential,model,geometry.domain[1],&profile); /* pore profile (already calculated in volume ) */ fp=fopen(profile.fn,"w"); if (fp) { for(i=0;i<NZPROF;i++) { fprintf(fp,"%f %f\n",profile.r[i][0],profile.r[i][1]); } fclose(fp); } free(profile.r); } return error < 0 ? 1 : 0; };