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 #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
00045 if (!filename || !natoms) return NULL;
00046
00047
00048 *natoms = MOLFILE_NUMATOMS_UNKNOWN;
00049
00050 data = vasp_plugindata_malloc();
00051 if (!data) return NULL;
00052
00053
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
00064 for (i = 0; i < 5; ++i) fgets(lineptr, LINESIZE, data->file);
00065
00066
00067 fgets(lineptr, LINESIZE, data->file);
00068 data->titleline = strdup(lineptr);
00069
00070
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;
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
00119
00120
00121
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
00131 if (fgets(lineptr, LINESIZE, potcar)) sscanf(lineptr, "%*s %4[^_. 0-9]", atomtype);
00132 idx = get_pte_idx(atomtype);
00133
00134 while (fgets(lineptr, LINESIZE, potcar)) if (strstr(lineptr, "End of Dataset")) break;
00135 } else {
00136
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
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
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
00184 for (i = 0; i < 3; ++i) fgets(lineptr, LINESIZE, data->file);
00185
00186
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
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
00213
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
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
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 }