Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

vasp5xdatcarplugin.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  * RCS INFORMATION:
00003  *
00004  *      $RCSfile: vasp5xdatcarplugin.c,v $
00005  *      $Author: johns $       $Locker:  $             $State: Exp $
00006  *      $Revision: 1.3 $       $Date: 2014/10/10 14:41:01 $
00007  *
00008  ***************************************************************************/
00009 
00010 /*
00011  *  VASP plugins for VMD
00012  *  Sung Sakong, Dept. of Phys., Univsity Duisburg-Essen
00013  *  
00014  *  VASP manual   
00015  *  http://cms.mpi.univie.ac.at/vasp/
00016  * 
00017  *  LINUX
00018  *  g++ -O2 -Wall -fPIC -I. -I$VMDBASEDIR/plugins/include -c vasp5xdatcarplugin.c
00019  *  ld -shared -o vasp5xdatcarplugin.so vasp5xdatcarplugin.o
00020  *
00021  *  MACOSX
00022  *  c++ -O2 -Wall -I. -I$VMDBASEDIR/plugins/include -c vasp5xdatcarplugin.c
00023  *  c++ -bundle -o vasp5xdatcarplugin.so vasp5xdatcarplugin.o
00024  *
00025  *  Install
00026  *  copy vasp5xdatcarplugin.so $VMDBASEDIR/plugins/$ARCH/molfile
00027  */
00028 
00029 #include <stdio.h>
00030 #include <stdlib.h>
00031 #include <string.h>
00032 
00033 #include "molfile_plugin.h"
00034 #include "vaspplugin.h"
00035 #include "periodic_table.h"
00036 
00037 
00038 static void *open_vasp5xdatcar_read(const char *filename, const char *filetype, int *natoms)
00039 {
00040   vasp_plugindata_t *data;
00041   char lineptr[LINESIZE];
00042   int i;
00043 
00044   /* Verify that input is OK */
00045   if (!filename || !natoms) return NULL;
00046 
00047   /* Start with undefined value; set it after successful read */
00048   *natoms = MOLFILE_NUMATOMS_UNKNOWN;
00049 
00050   data = vasp_plugindata_malloc();
00051   if (!data) return NULL;
00052 
00053   /* VASP5 is assumed in default */
00054   data->version = 5;
00055   data->file = fopen(filename, "rb");
00056   if (!data->file) {
00057     vasp_plugindata_free(data);
00058     return NULL;
00059   }
00060 
00061   data->filename = strdup(filename);
00062 
00063   /* Ignore rest of header up to the line with atom numbers */
00064   for (i = 0; i < 5; ++i) fgets(lineptr, LINESIZE, data->file);
00065 
00066   /* Read title line */
00067   fgets(lineptr, LINESIZE, data->file);
00068   data->titleline = strdup(lineptr);
00069 
00070   /* Read the number of atoms per atom type */
00071   data->numatoms = 0;
00072   fgets(lineptr, LINESIZE, data->file);
00073   for (i = 0; i < MAXATOMTYPES; ++i) {
00074     char const *token = (i == 0 ? strtok(lineptr, " ") : strtok(NULL, " "));
00075     int const n = (token ? atoi(token) : -1);
00076     
00077     if (n <= 0) break;
00078     
00079     data->eachatom[i] = n;
00080     data->numatoms += n;
00081   }
00082 
00083 
00084   if (data->numatoms == 0) {
00085     vasp_plugindata_free(data);
00086     fprintf(stderr, "\n\nVASP5 XDATCAR read) ERROR: file '%s' does not have list of atom numbers.\n", filename);
00087     return NULL;
00088   }
00089 
00090   *natoms = data->numatoms;
00091   rewind(data->file);
00092 
00093   return data;
00094 }
00095 
00096 
00097 static int read_vasp5xdatcar_structure(void *mydata, int *optflags, molfile_atom_t *atoms)
00098 {
00099   vasp_plugindata_t *data = (vasp_plugindata_t *)mydata;
00100   FILE *potcar = NULL;
00101   int atomcount, i;
00102   char lineptr[LINESIZE], potcarfile[1000], *cp;
00103   float lc;
00104  
00105   if (!data || !optflags || !atoms) return MOLFILE_ERROR;
00106 
00107   *optflags = MOLFILE_MASS; /* we set atom mass from the PTE. */
00108   *optflags |= MOLFILE_ATOMICNUMBER | MOLFILE_RADIUS; 
00109 
00110   strcpy(potcarfile, data->filename);
00111   cp = strstr(potcarfile, "XDATCAR");
00112 
00113   if (cp) {
00114     strcpy(cp, "POTCAR");
00115     potcar = fopen(potcarfile, "r");
00116   }
00117 
00118   /* Read POTCAR file to determine atom types.
00119    * Each atom type section in POTCAR starts with a line
00120    * that contains the name of the element (H, He, C etc.).
00121    * Otherwise try the title line instead.
00122    */
00123   for (atomcount = i = 0; atomcount < data->numatoms; ++i) {
00124     int idx, j;
00125     char const *label;
00126     float mass, radius;
00127 
00128     if (potcar) {
00129        char atomtype[5] = "X";
00130        /* Obtain atom types from POTCAR file */
00131        if (fgets(lineptr, LINESIZE, potcar)) sscanf(lineptr, "%*s %4[^_. 0-9]", atomtype);
00132        idx = get_pte_idx(atomtype);
00133        /* Skip lines in potcar file until next element */
00134        while (fgets(lineptr, LINESIZE, potcar)) if (strstr(lineptr, "End of Dataset")) break;
00135     } else {
00136        /* Try to obtain atom types from title line */
00137        char const *token = (i == 0 ? strtok(data->titleline, " ") : strtok(NULL, " "));
00138        idx = get_pte_idx(token);
00139     }
00140 
00141     label = get_pte_label(idx);
00142     mass = get_pte_mass(idx);
00143     radius = get_pte_vdw_radius(idx);
00144     for (j = 0; j < data->eachatom[i]; ++j, ++atomcount) {
00145       molfile_atom_t *const atom = &(atoms[atomcount]);
00146 
00147       /* Required settings */
00148       strncpy(atom->name, label, sizeof(atom->name));
00149       strncpy(atom->type, atom->name, sizeof(atom->type));
00150       atom->resname[0] = '\0';
00151       atom->resid = 1;
00152       atom->segid[0]='\0';
00153       atom->chain[0]='\0';
00154 
00155 
00156       /* Optional flags (as defined in *optflags) */
00157       atom->mass = mass;
00158       atom->radius = radius;
00159       atom->atomicnumber = idx;
00160     }
00161   }
00162   if (potcar) fclose(potcar);
00163 
00164   if (atomcount != data->numatoms) {
00165     fprintf(stderr, "\n\nVASP5 XDATCAR read) ERROR: file '%s' doesn't seem to have list of atoms.\n", data->filename);
00166     return MOLFILE_ERROR;
00167   }
00168 
00169   for (i = 0; i < 2; ++i) fgets(lineptr, LINESIZE, data->file);
00170   sscanf(lineptr, "%f", &lc);
00171    fprintf(stderr, "%f\n", lc);
00172 
00173   for (i = 0; i < 3; ++i) {
00174     float x, y, z;
00175     fgets(lineptr, LINESIZE, data->file);
00176     sscanf(lineptr, "%f %f %f", &x, &y, &z);
00177     data->cell[i][0] = x*lc;
00178     data->cell[i][1] = y*lc;
00179     data->cell[i][2] = z*lc;
00180   }
00181   vasp_buildrotmat(data);
00182 
00183  /* Ignore header until X,Y,Z-coordinates */
00184  for (i = 0; i < 3; ++i) fgets(lineptr, LINESIZE, data->file);
00185 
00186  /* Check whether all coordinates are present in the file */
00187  for (i = 0; i < data->numatoms; ++i) {
00188    float coord;
00189    fgets(lineptr, LINESIZE, data->file);
00190    if (3 != sscanf(lineptr, "%f %f %f", &coord, &coord, &coord)) {
00191      fprintf(stderr, "\n\nVASP5 XDATCAR read) ERROR: structure is missing type or coordinate(s) in file '%s' for atom '%d'\n", data->filename, i+1);
00192      return MOLFILE_ERROR;
00193    }
00194  }
00195 
00196  rewind(data->file);
00197 
00198  /* Ignore header until X,Y,Z-coordinates */
00199  for (i = 0; i < 8; ++i) fgets(lineptr, LINESIZE, data->file);
00200 
00201  return MOLFILE_SUCCESS;
00202 }
00203 
00204 
00205 static int read_vasp5xdatcar_timestep(void *mydata, int natoms, molfile_timestep_t *ts)
00206 {
00207   int i;
00208   char lineptr[LINESIZE];
00209   
00210   vasp_plugindata_t *data = (vasp_plugindata_t *)mydata;
00211 
00212   /* Save coords only if we're given a timestep pointer,
00213    * otherwise assume that VMD wants us to skip past it.
00214    */
00215   if (!ts || !data) return MOLFILE_EOF;
00216 
00217   for (i = 0; i < data->numatoms; ++i) {
00218     float x, y, z, rotx, roty, rotz;
00219     fgets(lineptr, LINESIZE, data->file);
00220     if (3 != sscanf(lineptr, "%f %f %f", &x, &y, &z)) {
00221       fprintf(stderr, "VASP5 XDATCAR read) missing type or coordinate(s) in file '%s' for atom '%d'\n", data->filename, i+1);
00222       return MOLFILE_EOF;
00223     }
00224 
00225     rotx = x*data->cell[0][0]+y*data->cell[1][0]+z*data->cell[2][0];
00226     roty = x*data->cell[0][1]+y*data->cell[1][1]+z*data->cell[2][1];
00227     rotz = x*data->cell[0][2]+y*data->cell[1][2]+z*data->cell[2][2];
00228 
00229     ts->coords[3*i  ] = data->rotmat[0][0]*rotx+data->rotmat[0][1]*roty+data->rotmat[0][2]*rotz;
00230     ts->coords[3*i+1] = data->rotmat[1][0]*rotx+data->rotmat[1][1]*roty+data->rotmat[1][2]*rotz;
00231     ts->coords[3*i+2] = data->rotmat[2][0]*rotx+data->rotmat[2][1]*roty+data->rotmat[2][2]*rotz;
00232   }
00233 
00234   vasp_timestep_unitcell(ts, data);
00235 
00236   /* VMD keeps calling for a next timestep, until we reach End-Of-File here */
00237   if (fgets(lineptr, LINESIZE, data->file) == NULL) return MOLFILE_EOF;
00238 
00239   return MOLFILE_SUCCESS;
00240 }
00241 
00242 
00243 static void close_vasp5xdatcar_read(void *mydata)
00244 {
00245   vasp_plugindata_t *data = (vasp_plugindata_t *)mydata;
00246 
00247   vasp_plugindata_free(data);
00248 }
00249 
00250 
00251 /* registration stuff */
00252 static molfile_plugin_t plugin;
00253 
00254 int VMDPLUGIN_init() {
00255   memset(&plugin, 0, sizeof(molfile_plugin_t));
00256   plugin.abiversion = vmdplugin_ABIVERSION;
00257   plugin.type = MOLFILE_PLUGIN_TYPE;
00258   plugin.name = "VASP_XDATCAR5";
00259   plugin.prettyname = "VASP_XDATCAR5";
00260   plugin.author = "Sung Sakong";
00261   plugin.majorv = 0;
00262   plugin.minorv = 7;
00263   plugin.is_reentrant = VMDPLUGIN_THREADUNSAFE;
00264   plugin.filename_extension = "VASP_XDATCAR5";
00265   plugin.open_file_read = open_vasp5xdatcar_read;
00266   plugin.read_structure = read_vasp5xdatcar_structure;
00267   plugin.read_next_timestep = read_vasp5xdatcar_timestep;
00268   plugin.close_file_read = close_vasp5xdatcar_read;
00269   return VMDPLUGIN_SUCCESS;
00270 }
00271 
00272 int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
00273   (*cb)(v, (vmdplugin_t *)&plugin);
00274   return VMDPLUGIN_SUCCESS;
00275 }
00276 
00277 int VMDPLUGIN_fini() {
00278   return VMDPLUGIN_SUCCESS;
00279 }

Generated on Wed Nov 11 03:06:35 2020 for VMD Plugins (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002