diff --git a/tools/restart2data.cpp b/tools/restart2data.cpp index fd7ae62f15..cffaa67590 100644 --- a/tools/restart2data.cpp +++ b/tools/restart2data.cpp @@ -13,7 +13,11 @@ // Convert a LAMMPS binary restart file into an ASCII text data file // -// Syntax: restart2data restart-file data-file +// Syntax: restart2data restart-file data-file (parameter-file) +// parameter-file is optional +// if specified it will contain LAMMPS input script commands +// for mass and force field info +// only a few force field styles support this option // // this serial code must be compiled on a platform that can read the binary // restart file since binary formats are not compatible across all platforms @@ -45,6 +49,9 @@ enum{VERSION,UNITS,NTIMESTEP,DIMENSION,NPROCS,PROCGRID_0,PROCGRID_1,PROCGRID_2, enum{MASS,SHAPE,DIPOLE}; enum{PAIR,BOND,ANGLE,DIHEDRAL,IMPROPER}; +static const char * const cg_type_list[] = + {"none", "lj9_6", "lj12_4", "lj12_6"}; + // --------------------------------------------------------------------- // Data class to hold problem // --------------------------------------------------------------------- @@ -73,9 +80,13 @@ class Data { int ntypes,nbondtypes,nangletypes,ndihedraltypes,nimpropertypes; int bond_per_atom,angle_per_atom,dihedral_per_atom,improper_per_atom; int triclinic; + double xlo,xhi,ylo,yhi,zlo,zhi,xy,xz,yz; double special_lj[4],special_coul[4]; + double cut_lj_global,cut_coul_global,kappa; + int offset_flag,mix_flag; + // force fields char *pair_style,*bond_style,*angle_style,*dihedral_style,*improper_style; @@ -91,6 +102,9 @@ class Data { double *pair_gb_epsilon,*pair_gb_sigma; double *pair_gb_epsa,*pair_gb_epsb,*pair_gb_epsc; double *pair_lj_epsilon,*pair_lj_sigma; + double **pair_cg_epsilon,**pair_cg_sigma; + int **pair_cg_cmm_type, **pair_setflag; + double **pair_cut_coul, **pair_cut_lj; double *pair_ljexpand_epsilon,*pair_ljexpand_sigma,*pair_ljexpand_shift; double *pair_ljsmooth_epsilon,*pair_ljsmooth_sigma; double *pair_morse_d0,*pair_morse_alpha,*pair_morse_r0; @@ -116,6 +130,8 @@ class Data { double *angle_cosine_k; double *angle_cosine_squared_k,*angle_cosine_squared_theta0; double *angle_harmonic_k,*angle_harmonic_theta0; + double *angle_cg_cmm_epsilon,*angle_cg_cmm_sigma; + int *angle_cg_cmm_type; double *dihedral_charmm_k,*dihedral_charmm_weight; int *dihedral_charmm_multiplicity,*dihedral_charmm_sign; @@ -172,7 +188,7 @@ class Data { Data(); void stats(); - void write(FILE *); + void write(FILE *fp, FILE *fp2=NULL); void write_atom_angle(FILE *, int, int, int, int); void write_atom_atomic(FILE *, int, int, int, int); @@ -266,13 +282,13 @@ char *read_char(FILE *fp); // main program // --------------------------------------------------------------------- -main (int argc, char **argv) +int main (int argc, char **argv) { // syntax error check - if (argc != 3) { - printf("Syntax: restart2data restart-file data-file\n"); - exit(1); + if ((argc != 3) && (argc !=4)) { + printf("Syntax: restart2data restart-file data-file [parameter-file]\n"); + return 1; } // if restart file contains '%', file = filename with % replaced by "base" @@ -297,7 +313,7 @@ main (int argc, char **argv) FILE *fp = fopen(file,"rb"); if (fp == NULL) { printf("ERROR: Cannot open restart file %s\n",file); - exit(1); + return 1; } // read beginning of restart file @@ -324,8 +340,8 @@ main (int argc, char **argv) sprintf(file,"%s%d%s",argv[1],iproc,ptr+1); fp = fopen(file,"rb"); if (fp == NULL) { - printf("ERROR: Cannot open restart file %s\n",file); - exit(1); + printf("ERROR: Cannot open restart file %s\n",file); + return 1; } } n = read_int(fp); @@ -348,17 +364,40 @@ main (int argc, char **argv) data.stats(); - // write out data file + // write out data file and no parameter file - printf("Writing data file ...\n"); - fp = fopen(argv[2],"w"); - if (fp == NULL) { - printf("ERROR: Cannot open data file %s\n",argv[2]); - exit(1); + if (argc == 3) { + printf("Writing data file ...\n"); + fp = fopen(argv[2],"w"); + if (fp == NULL) { + printf("ERROR: Cannot open data file %s\n",argv[2]); + return 1; + } + data.write(fp); + fclose(fp); + + // write out data file and parameter file + + } else { + printf("Writing data file ...\n"); + fp = fopen(argv[2],"w"); + if (fp == NULL) { + printf("ERROR: Cannot open data file %s\n",argv[2]); + return 1; + } + printf("Writing parameter file ...\n"); + FILE *fp2 = fopen(argv[3],"w"); + if (fp2 == NULL) { + printf("ERROR: Cannot open parameter file %s\n",argv[3]); + return 1; + } + + data.write(fp,fp2); + fclose(fp); + fclose(fp2); } - - data.write(fp); - fclose(fp); + + return 0; } // --------------------------------------------------------------------- @@ -1768,6 +1807,61 @@ void pair(FILE *fp, Data &data, char *style, int flag) } } + } else if ((strcmp(style,"cg/cmm") == 0) || + (strcmp(style,"cg/cmm/coul/cut") == 0) || + (strcmp(style,"cg/cmm/coul/long") == 0) ) { + m = 0; + data.cut_lj_global = read_double(fp); + data.cut_coul_global = read_double(fp); + data.kappa = read_double(fp); + data.offset_flag = read_int(fp); + data.mix_flag = read_int(fp); + + if (!flag) return; + + const int numtyp=data.ntypes+1; + data.pair_cg_cmm_type = new int*[numtyp]; + data.pair_setflag = new int*[numtyp]; + data.pair_cg_epsilon = new double*[numtyp]; + data.pair_cg_sigma = new double*[numtyp]; + data.pair_cut_lj = new double*[numtyp]; + if ((strcmp(style,"cg/cmm/coul/cut") == 0) || + (strcmp(style,"cg/cmm/coul/long") == 0) ) { + data.pair_cut_coul = new double*[numtyp]; + m=1; + } else { + data.pair_cut_coul = NULL; + m=0; + } + + for (i = 1; i <= data.ntypes; i++) { + data.pair_cg_cmm_type[i] = new int[numtyp]; + data.pair_setflag[i] = new int[numtyp]; + data.pair_cg_epsilon[i] = new double[numtyp]; + data.pair_cg_sigma[i] = new double[numtyp]; + data.pair_cut_lj[i] = new double[numtyp]; + if ((strcmp(style,"cg/cmm/coul/cut") == 0) || + (strcmp(style,"cg/cmm/coul/long") == 0) ) { + data.pair_cut_coul[i] = new double[numtyp]; + } + + for (j = i; j <= data.ntypes; j++) { + itmp = read_int(fp); + data.pair_setflag[i][j] = itmp; + if (i == j && itmp == 0) { + printf("ERROR: Pair coeff %d,%d is not in restart file\n",i,j); + exit(1); + } + if (itmp) { + data.pair_cg_cmm_type[i][j] = read_int(fp); + data.pair_cg_epsilon[i][j] = read_double(fp); + data.pair_cg_sigma[i][j] = read_double(fp); + data.pair_cut_lj[i][j] = read_double(fp); + if (m) data.pair_cut_coul[i][j] = read_double(fp); + } + } + } + } else if (strcmp(style,"hybrid") == 0) { // for each substyle of hybrid, @@ -1922,7 +2016,8 @@ void angle(FILE *fp, Data &data) data.angle_cosine_k = new double[data.nangletypes+1]; fread(&data.angle_cosine_k[1],sizeof(double),data.nangletypes,fp); - } else if (strcmp(data.angle_style,"cosine/squared") == 0) { + } else if ((strcmp(data.angle_style,"cosine/squared") == 0) || + (strcmp(data.angle_style,"cosine/delta") == 0)) { data.angle_cosine_squared_k = new double[data.nangletypes+1]; data.angle_cosine_squared_theta0 = new double[data.nangletypes+1]; @@ -1937,6 +2032,22 @@ void angle(FILE *fp, Data &data) fread(&data.angle_harmonic_k[1],sizeof(double),data.nangletypes,fp); fread(&data.angle_harmonic_theta0[1],sizeof(double),data.nangletypes,fp); + } else if (strcmp(data.angle_style,"cg/cmm") == 0) { + + data.angle_harmonic_k = new double[data.nangletypes+1]; + data.angle_harmonic_theta0 = new double[data.nangletypes+1]; + data.angle_cg_cmm_epsilon = new double[data.nangletypes+1]; + data.angle_cg_cmm_sigma = new double[data.nangletypes+1]; + double *angle_cg_cmm_rcut = new double[data.nangletypes+1]; + data.angle_cg_cmm_type = new int[data.nangletypes+1]; + + fread(&data.angle_harmonic_k[1],sizeof(double),data.nangletypes,fp); + fread(&data.angle_harmonic_theta0[1],sizeof(double),data.nangletypes,fp); + fread(&data.angle_cg_cmm_epsilon[1],sizeof(double),data.nangletypes,fp); + fread(&data.angle_cg_cmm_sigma[1],sizeof(double),data.nangletypes,fp); + fread(angle_cg_cmm_rcut,sizeof(double),data.nangletypes,fp); + fread(&data.angle_cg_cmm_type[1],sizeof(int),data.nangletypes,fp); + } else if (strcmp(data.angle_style,"hybrid") == 0) { int nstyles = read_int(fp); @@ -2243,7 +2354,7 @@ void Data::stats() // write the data file // --------------------------------------------------------------------- -void Data::write(FILE *fp) +void Data::write(FILE *fp, FILE *fp2) { fprintf(fp,"LAMMPS data file from restart file: timestep = %d, procs = %d\n", ntimestep,nprocs); @@ -2271,9 +2382,33 @@ void Data::write(FILE *fp) fprintf(fp,"%g %g zlo zhi\n",zlo,zhi); if (triclinic) fprintf(fp,"%g %g %g xy xz yz\n",xy,xz,yz); + // write ff styles to parameter file + + if (fp2) { + fprintf(fp2,"# LAMMPS parameter file from restart file: timestep = %d, procs = %d\n\n", + ntimestep,nprocs); + if (pair_style) fprintf(fp2,"pair_style %s\n",pair_style); + if (bond_style) fprintf(fp2,"bond_style %s\n",bond_style); + if (angle_style) fprintf(fp2,"angle_style %s\n",angle_style); + if (dihedral_style) fprintf(fp2,"dihedral_style %s\n",dihedral_style); + if (improper_style) fprintf(fp2,"improper_style %s\n",improper_style); + fprintf(fp2,"special_bonds %g %g %g %g %g %g\n", + special_lj[1],special_lj[2],special_lj[3], + special_lj[1],special_coul[2],special_coul[3]); + fprintf(fp2,"\n"); + } + + // mass to either data file or parameter file + if (mass) { - fprintf(fp,"\nMasses\n\n"); - for (int i = 1; i <= ntypes; i++) fprintf(fp,"%d %g\n",i,mass[i]); + if (fp2) { + fprintf(fp2,"\n"); + for (int i = 1; i <= ntypes; i++) fprintf(fp2,"mass %d %g\n",i,mass[i]); + fprintf(fp2,"\n"); + } else { + fprintf(fp,"\nMasses\n\n"); + for (int i = 1; i <= ntypes; i++) fprintf(fp,"%d %g\n",i,mass[i]); + } } if (shape) { @@ -2286,8 +2421,10 @@ void Data::write(FILE *fp) fprintf(fp,"\nDipoles\n\n"); for (int i = 1; i <= ntypes; i++) fprintf(fp,"%d %g\n",i,dipole[i]); } - - if (pair_style) { + + // pair coeffs to data file + + if (pair_style && fp2 == NULL) { if ((strcmp(pair_style,"none") != 0) && (strcmp(pair_style,"eam") != 0) && (strcmp(pair_style,"eam/opt") != 0) && @@ -2389,10 +2526,41 @@ void Data::write(FILE *fp) for (int i = 1; i <= ntypes; i++) fprintf(fp,"%d %g\n",i, pair_yukawa_A[i]); + + } else if ((strcmp(pair_style,"cg/cmm") == 0) || + (strcmp(pair_style,"cg/cmm/coul/cut") == 0) || + (strcmp(pair_style,"cg/cmm/coul/long") == 0)) { + printf("ERROR: Cannot write pair_style %s to data file\n", + pair_style); + exit(1); } } - if (bond_style) { + // pair coeffs to parameter file + // only supported styles = cg/cmm + + if (pair_style && fp2) { + if ((strcmp(pair_style,"cg/cmm") == 0) || + (strcmp(pair_style,"cg/cmm/coul/cut") == 0) || + (strcmp(pair_style,"cg/cmm/coul/long") == 0)) { + for (int i = 1; i <= ntypes; i++) { + for (int j = i; j <= ntypes; j++) { + fprintf(fp2,"pair_coeff %d %d %s %g %g\n",i,j, + cg_type_list[pair_cg_cmm_type[i][j]], + pair_cg_epsilon[i][j],pair_cg_sigma[i][j]); + } + } + + } else { + printf("ERROR: Cannot write pair_style %s to parameter file\n", + pair_style); + exit(1); + } + } + + // bond coeffs to data file + + if (bond_style && fp2 == NULL) { if ((strcmp(bond_style,"none") != 0) && (strcmp(bond_style,"hybrid") != 0)) fprintf(fp,"\nBond Coeffs\n\n"); @@ -2434,7 +2602,25 @@ void Data::write(FILE *fp) } } - if (angle_style) { + // bond coeffs to parameter file + // only supported styles = harmonic + + if (bond_style && fp2) { + if (strcmp(bond_style,"harmonic") == 0) { + for (int i = 1; i <= nbondtypes; i++) + fprintf(fp2,"bond_coeff %d %g %g\n",i, + bond_harmonic_k[i],bond_harmonic_r0[i]); + + } else { + printf("ERROR: Cannot write bond_style %s to parameter file\n", + bond_style); + exit(1); + } + } + + // angle coeffs to data file + + if (angle_style && fp2 == NULL) { double PI = 3.1415926; // convert back to degrees if ((strcmp(angle_style,"none") != 0) && @@ -2452,13 +2638,13 @@ void Data::write(FILE *fp) fprintf(fp,"%d %g %g %g %g\n",i, angle_class2_theta0[i]/PI*180.0,angle_class2_k2[i], angle_class2_k3[i],angle_class2_k4[i]); - + fprintf(fp,"\nBondBond Coeffs\n\n"); for (int i = 1; i <= nangletypes; i++) fprintf(fp,"%d %g %g %g\n",i, angle_class2_bb_k[i], angle_class2_bb_r1[i],angle_class2_bb_r2[i]); - + fprintf(fp,"\nBondAngle Coeffs\n\n"); for (int i = 1; i <= nangletypes; i++) fprintf(fp,"%d %g %g %g %g\n",i, @@ -2467,13 +2653,56 @@ void Data::write(FILE *fp) } else if (strcmp(angle_style,"cosine") == 0) { for (int i = 1; i <= nangletypes; i++) - fprintf(fp,"%d %g\n",i, - angle_cosine_k[i]); - - } if (strcmp(angle_style,"harmonic") == 0) { + fprintf(fp,"%d %g\n",i,angle_cosine_k[i]); + + } else if (strcmp(angle_style,"cosine/squared") == 0) { + for (int i = 1; i <= nangletypes; i++) + fprintf(fp,"%d %g %g\n",i, + angle_cosine_squared_k[i], + angle_cosine_squared_theta0[i]/PI*180.0); + + } else if (strcmp(angle_style,"harmonic") == 0) { for (int i = 1; i <= nangletypes; i++) fprintf(fp,"%d %g %g\n",i, angle_harmonic_k[i],angle_harmonic_theta0[i]/PI*180.0); + + } else if (strcmp(angle_style,"cg/cmm") == 0) { + for (int i = 1; i <= nangletypes; i++) + fprintf(fp,"%d %g %g %s %g %g\n",i, + angle_harmonic_k[i],angle_harmonic_theta0[i]/PI*180.0, + cg_type_list[angle_cg_cmm_type[i]],angle_cg_cmm_epsilon[i], + angle_cg_cmm_sigma[i]); + } + } + + // angle coeffs to parameter file + // only supported styles = cosine/squared, harmonic, cg/cmm + + if (angle_style && fp2) { + double PI = 3.1415926; // convert back to degrees + + if (strcmp(angle_style,"cosine/squared") == 0) { + for (int i = 1; i <= nangletypes; i++) + fprintf(fp2,"angle_coeffs %d %g %g\n",i, + angle_cosine_squared_k[i], + angle_cosine_squared_theta0[i]/PI*180.0); + + } else if (strcmp(angle_style,"harmonic") == 0) { + for (int i = 1; i <= nangletypes; i++) + fprintf(fp2,"angle_coeffs %d %g %g\n",i, + angle_harmonic_k[i],angle_harmonic_theta0[i]/PI*180.0); + + } else if (strcmp(angle_style,"cg/cmm") == 0) { + for (int i = 1; i <= nangletypes; i++) + fprintf(fp2,"angle_coeffs %d %g %g %s %g %g\n",i, + angle_harmonic_k[i],angle_harmonic_theta0[i]/PI*180.0, + cg_type_list[angle_cg_cmm_type[i]],angle_cg_cmm_epsilon[i], + angle_cg_cmm_sigma[i]); + + } else { + printf("ERROR: Cannot write angle_style %s to parameter file\n", + angle_style); + exit(1); } }