00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include "largefiles.h"
00035
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 #include <string.h>
00039 #include <ctype.h>
00040 #include <math.h>
00041 #include "molfile_plugin.h"
00042
00043 #ifndef M_PI_2
00044 #define M_PI_2 1.57079632679489661922
00045 #endif
00046
00047 typedef struct {
00048 FILE *file;
00049 int numatoms;
00050 char *file_name;
00051 molfile_atom_t *atomlist;
00052 } lammpsdata;
00053
00054 static void *open_lammps_read(const char *filename, const char *filetype,
00055 int *natoms) {
00056 FILE *fd;
00057 lammpsdata *data;
00058 int i;
00059
00060 fd = fopen(filename, "rb");
00061 if (!fd) return NULL;
00062
00063 data = (lammpsdata *)malloc(sizeof(lammpsdata));
00064 data->file = fd;
00065 data->file_name = strdup(filename);
00066
00067
00068
00069 while (getc(fd) != '\n');
00070 while (getc(fd) != '\n');
00071 while (getc(fd) != '\n');
00072
00073 i = fscanf(data->file, "%d", natoms);
00074 if (i < 1) {
00075 fprintf(stderr, "\n\nread) ERROR: lammps dump file '%s' should have the number of atoms in the third line.\n", filename);
00076 return NULL;
00077 }
00078 data->numatoms=*natoms;
00079
00080 rewind(data->file);
00081
00082 return data;
00083 }
00084
00085 static int read_lammps_timestep(void *mydata, int natoms, molfile_timestep_t *ts) {
00086 int i, j;
00087 char atom_name[1025], fbuffer[1025], *k;
00088 float x, y, z;
00089 float alpha, beta, gamma, a, b, c;
00090 int atomid;
00091
00092 lammpsdata *data = (lammpsdata *)mydata;
00093
00094
00095 if (NULL == fgets(fbuffer, 1024, data->file)) return MOLFILE_ERROR;
00096
00097 if (NULL == fgets(fbuffer, 1024, data->file)) return MOLFILE_ERROR;
00098
00099 if (NULL == fgets(fbuffer, 1024, data->file)) return MOLFILE_ERROR;
00100
00101 if (NULL == fgets(fbuffer, 1024, data->file)) return MOLFILE_ERROR;
00102
00103
00104
00105 if (NULL == fgets(fbuffer, 1024, data->file)) return MOLFILE_ERROR;
00106 if (NULL == fgets(fbuffer, 1024, data->file)) return MOLFILE_ERROR;
00107 sscanf(fbuffer, "%f %f", &alpha, &a);
00108 if (NULL == fgets(fbuffer, 1024, data->file)) return MOLFILE_ERROR;
00109 sscanf(fbuffer, "%f %f", &beta, &b);
00110 if (NULL == fgets(fbuffer, 1024, data->file)) return MOLFILE_ERROR;
00111 sscanf(fbuffer, "%f %f", &gamma, &c);
00112
00113 if (ts != NULL) {
00114 ts->A = a;
00115 ts->B = b;
00116 ts->C = c;
00117 ts->alpha = 90.0 - asin(alpha) * 90.0 / M_PI_2;
00118 ts->beta = 90.0 - asin(beta) * 90.0 / M_PI_2;
00119 ts->gamma = 90.0 - asin(gamma) * 90.0 / M_PI_2;
00120 }
00121
00122
00123 if (NULL == fgets(fbuffer, 1024, data->file)) return MOLFILE_ERROR;
00124
00125
00126 for (i=0; i<natoms; i++) {
00127 k = fgets(fbuffer, 1024, data->file);
00128
00129
00130 j = sscanf(fbuffer, "%d %s %f %f %f", &atomid, atom_name, &x, &y, &z);
00131 if (k == NULL) {
00132 return MOLFILE_ERROR;
00133 } else if (j < 5) {
00134 fprintf(stderr, "lammps timestep) missing type or coordinate(s) in file '%s' for atom '%d'\n",data->file_name,i+1);
00135 return MOLFILE_ERROR;
00136 } else if (j == 5) {
00137
00138
00139 if (ts != NULL) {
00140 if (atomid > 0 && atomid <= natoms) {
00141 int addr = 3 * (atomid - 1);
00142
00143
00144 ts->coords[addr ] = x * a;
00145 ts->coords[addr + 1] = y * b;
00146 ts->coords[addr + 2] = z * c;
00147 } else {
00148 fprintf(stderr, "lammps timestep) ignoring illegal atom index %d\n", atomid);
00149 }
00150 }
00151 }
00152 }
00153
00154 return MOLFILE_SUCCESS;
00155 }
00156
00157 static void close_lammps_read(void *mydata) {
00158 lammpsdata *data = (lammpsdata *)mydata;
00159 fclose(data->file);
00160 free(data->file_name);
00161 free(data);
00162 }
00163
00164
00165
00166 static molfile_plugin_t lammpsplugin = {
00167 vmdplugin_ABIVERSION,
00168 MOLFILE_PLUGIN_TYPE,
00169 "lammpstrj",
00170 "LAMMPS Trajectory",
00171 "John E. Stone",
00172 0,
00173 3,
00174 VMDPLUGIN_THREADSAFE,
00175 "lammpstrj",
00176 open_lammps_read,
00177 0,
00178 0,
00179 read_lammps_timestep,
00180 close_lammps_read,
00181 0,
00182 0,
00183 0,
00184 0,
00185 0,
00186 0,
00187 0
00188 };
00189
00190 VMDPLUGIN_API int VMDPLUGIN_init() {
00191 return VMDPLUGIN_SUCCESS;
00192 }
00193
00194 VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
00195 (*cb)(v, (vmdplugin_t *)&lammpsplugin);
00196 return VMDPLUGIN_SUCCESS;
00197 }
00198
00199 VMDPLUGIN_API int VMDPLUGIN_fini() {
00200 return VMDPLUGIN_SUCCESS;
00201 }
00202
00203
00204 #ifdef TEST_PLUGIN
00205
00206 int main(int argc, char *argv[]) {
00207 molfile_timestep_t timestep;
00208 void *v;
00209 int natoms;
00210 int i, nsets, set;
00211
00212 while (--argc) {
00213 ++argv;
00214 v = open_lammps_read(*argv, "lammps", &natoms);
00215 if (!v) {
00216 fprintf(stderr, "open_lammps_read failed for file %s\n", *argv);
00217 return 1;
00218 }
00219 fprintf(stderr, "open_lammps_read succeeded for file %s\n", *argv);
00220 fprintf(stderr, "number of atoms: %d\n", natoms);
00221
00222 i = 0;
00223 timestep.coords = (float *)malloc(3*sizeof(float)*natoms);
00224 while (!read_lammps_timestep(v, natoms, ×tep)) {
00225 i++;
00226 }
00227 fprintf(stderr, "ended read_next_timestep on frame %d\n", i);
00228
00229 close_lammps_read(v);
00230 }
00231 return 0;
00232 }
00233
00234 #endif
00235