Main Page   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

lammpsplugin.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr
00003  *cr            (C) Copyright 1995-2006 The Board of Trustees of the
00004  *cr                        University of Illinois
00005  *cr                         All Rights Reserved
00006  *cr
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  * RCS INFORMATION:
00011  *
00012  *      $RCSfile: lammpsplugin.c,v $
00013  *      $Author: johns $       $Locker:  $             $State: Exp $
00014  *      $Revision: 1.14 $       $Date: 2006/02/23 19:36:45 $
00015  *
00016  ***************************************************************************/
00017 
00018 /*
00019  *  LAMMPS dump file format:
00020  *    ITEM: TIMESTEP
00021  *      %d (timestep number)
00022  *    ITEM: NUMBER OF ATOMS
00023  *      %d (number of atoms)
00024  *    ITEM: BOX BOUNDS
00025  *      %f %f (alpha, a)
00026  *      %f %f (beta,  b)
00027  *      %f %f (gamma, c)
00028  *    ITEM: ATOMS
00029  *      %d %d %f %f %f  (atomid, atomtype, x, y, z)
00030  *      ...
00031  *
00032  */
00033 
00034 #include "largefiles.h"   /* platform dependent 64-bit file I/O defines */
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   /* skip past first 3 lines */
00069   while (getc(fd) != '\n');
00070   while (getc(fd) != '\n');
00071   while (getc(fd) != '\n');
00072   /* Fourth line is the number of atoms   */
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); /* prepare for first read_timestep call */
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   /* skip ITEM: TIMESTEP text */
00095   if (NULL == fgets(fbuffer, 1024, data->file))  return MOLFILE_ERROR;
00096   /* skip timestep value */
00097   if (NULL == fgets(fbuffer, 1024, data->file))  return MOLFILE_ERROR;
00098   /* skip ITEM: NUMBER OF ATOMS text */
00099   if (NULL == fgets(fbuffer, 1024, data->file))  return MOLFILE_ERROR;
00100   /* skip atom count value */
00101   if (NULL == fgets(fbuffer, 1024, data->file))  return MOLFILE_ERROR;
00102 
00103   /* read unit cell information */
00104   /* skip ITEM: BOX BOUNDS text */
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   /* skip ITEM: ATOMS text */
00123   if (NULL == fgets(fbuffer, 1024, data->file))  return MOLFILE_ERROR;
00124 
00125   /* read the coordinates */
00126   for (i=0; i<natoms; i++) {
00127     k = fgets(fbuffer, 1024, data->file);
00128 
00129     /* Read in atom type, X, Y, Z, skipping any remaining data fields */
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       /* only save coords if we're given a timestep pointer, */
00138       /* otherwise assume that VMD wants us to skip past it. */
00139       if (ts != NULL) { 
00140         if (atomid > 0 && atomid <= natoms) {
00141           int addr = 3 * (atomid - 1);
00142           /* LAMMPS coordinates are fractional unit cell coords, */
00143           /* so they need to be scaled by a/b/c etc              */
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 /* registration stuff */
00166 static molfile_plugin_t lammpsplugin = {
00167   vmdplugin_ABIVERSION,
00168   MOLFILE_PLUGIN_TYPE,                         /* type */
00169   "lammpstrj",                                 /* short name */
00170   "LAMMPS Trajectory",                         /* pretty name */
00171   "John E. Stone",                             /* author */
00172   0,                                           /* major version */
00173   3,                                           /* minor version */
00174   VMDPLUGIN_THREADSAFE,                        /* is reentrant */
00175   "lammpstrj",
00176   open_lammps_read,
00177   0,
00178   0,
00179   read_lammps_timestep,
00180   close_lammps_read,
00181   0,                            /* write... */
00182   0,
00183   0,
00184   0,
00185   0,                            /* read_volumetric_metadata */
00186   0,                            /* read_volumetric_data */
00187   0                             /* read_rawgraphics */
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, &timestep)) {
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 

Generated on Wed Mar 22 13:15:30 2006 for VMD Plugins (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002