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 #include <stdlib.h>
00031 #include <string.h>
00032 #include <ctype.h>
00033 #include <errno.h>
00034 #include <time.h>
00035 #include <math.h>
00036
00037 #include "qmplugin.h"
00038 #include "unit_conversion.h"
00039
00040 #define ANGSTROM 0
00041 #define BOHR 1
00042 #define SPIN_ALPHA 0
00043 #define SPIN_BETA 1
00044
00045
00046
00047
00048 #ifdef GAMESS_DEBUG
00049 #define PRINTERR fprintf(stderr, "\n In file %s, line %d: \n %s \n \n", \
00050 __FILE__, __LINE__, strerror(errno))
00051 #else
00052 #define PRINTERR (void)(0)
00053 #endif
00054
00055
00056
00057
00058
00059 #define GET_LINE(x,y) if (!fgets(x, sizeof(x), y)) return FALSE
00060
00061 #define UNK_SHELL -666
00062 #define SPD_D_SHELL -5
00063 #define SPD_P_SHELL -4
00064 #define SPD_S_SHELL -3
00065 #define SP_S_SHELL -2
00066 #define SP_P_SHELL -1
00067 #define S_SHELL 0
00068 #define P_SHELL 1
00069 #define D_SHELL 2
00070 #define F_SHELL 3
00071 #define G_SHELL 4
00072 #define H_SHELL 5
00073
00074 #define FOUND 1
00075 #define STOPPED 2
00076
00077 #define NUM_ELEMENTS 109
00078
00079
00080
00081 static const char *elements[] = {
00082 "(unknown)", "HYDROGEN", "HELIUM", "LITHIUM", "BERYLLIUM", "BORON",
00083 "CARBON", "NITROGEN", "OXYGEN", "FLUORINE", "NEON",
00084 "SODIUM", "MAGNESIUM", "ALUMINUM", "SILICON", "PHOSPHOROUS",
00085 "SULFUR", "CHLORINE", "ARGON", "POTASSIUM", "CALCIUM", "SCANDIUM",
00086 "TITANIUM", "VANADIUM", "CHROMIUM", "MANGANESE", "IRON", "COBALT",
00087 "NICKEL", "COPPER", "ZINC", "GALLIUM", "GERMANIUM", "ARSENIC",
00088 "SELENIUM", "BROMINE", "KRYPTON",
00089 "RUBIDIUM", "STRONTIUM", "YTTRIUM", "ZIRCONIUM", "NIOBIUM",
00090 "MOLYBDENUM", "TECHNETIUM", "RUTHENIUM", "RHODIUM", "PALLADIUM",
00091 "SILVER", "CADMIUM", "INDIUM", "TIN", "ANTIMONY", "TELLURIUM",
00092 "IODINE", "XENON",
00093 "CESIUM", "BARIUM", "LANTHANUM", "CER", "PRASEODYMIUM", "NEODYMIUM",
00094 "PROMETIUM", "SAMARIUM", "EUROPIUM", "GADOLIUM", "TERBIUM",
00095 "DYSPROSIUM", "HOLMIUM", "ERBIUM", "THULIUM", "YTTERBIUM",
00096 "LUTETIUM", "HAFNIUM", "TANTALUM", "TUNGSTEN", "RHENIUM", "OSMIUM",
00097 "IRIDIUM", "PLATINUM", "GOLD", "MERCURY", "THALLIUM", "LEAD",
00098 "BISMUTH", "POLONIUM", "ASTATINE", "RADON",
00099 "FRANCIUM", "RADIUM", "ACTINIUM", "THORIUM", "PROTACTINIUM",
00100 "URANIUM", "NEPTUNIUM", "PLUTONIUM", "AMERICIUM", "CURIUM",
00101 "BERKELIUM", "CALIFORNIUM", "EINSTEINIUM", "FERMIUM", "MENDELEVIUM",
00102 "NOBELIUM", "LAWRENCIUM", "RUTHERFORDIUM", "DUBNIUM", "SEABORGIUM",
00103 "BOHRIUM", "HASSIUM", "MEITNERIUM"};
00104
00105
00106
00107
00108
00109
00110
00111 static void print_input_data(qmdata_t *);
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121 static int get_basis (qmdata_t *);
00122
00123
00124
00125 static int read_shell_primitives(qmdata_t *, prim_t **prim,
00126 char *shellsymm, int icoeff);
00127
00128
00129 static int shelltype_int(char type);
00130
00131
00132 static int fill_basis_arrays(qmdata_t *);
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 static void *open_basis_read(const char *filename,
00148 const char *filetype, int *natoms) {
00149
00150 FILE *fd;
00151 qmdata_t *data;
00152
00153
00154
00155 fd = fopen(filename, "rb");
00156
00157 if (!fd) {
00158 PRINTERR;
00159 return NULL;
00160 }
00161
00162
00163 data = (qmdata_t *)calloc(1,sizeof(qmdata_t));
00164
00165
00166 if (data == NULL) {
00167 PRINTERR;
00168 return NULL;
00169 }
00170
00171 data->num_shells = 0;
00172 data->num_basis_funcs = 0;
00173 data->num_basis_atoms = 0;
00174
00175
00176 memset(data->basis_string,0,sizeof(data->basis_string));
00177
00178
00179 data->file = fd;
00180
00181
00182 if (!get_basis(data)) return NULL;
00183
00184
00185
00186 *natoms = 0;
00187
00188
00189 print_input_data(data);
00190
00191 return data;
00192 }
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204 static int read_basis_metadata(void *mydata,
00205 molfile_qm_metadata_t *metadata) {
00206
00207 qmdata_t *data = (qmdata_t *)mydata;
00208
00209 metadata->ncart = 0;
00210 metadata->nimag = 0;
00211 metadata->nintcoords = 0;
00212
00213 metadata->have_sysinfo = 0;
00214 metadata->have_carthessian = 0;
00215 metadata->have_inthessian = 0;
00216 metadata->have_normalmodes = 0;
00217
00218
00219 metadata->num_basis_funcs = data->num_basis_funcs;
00220 metadata->num_basis_atoms = data->num_basis_atoms;
00221 metadata->num_shells = data->num_shells;
00222 metadata->wavef_size = 0;
00223
00224 return MOLFILE_SUCCESS;
00225 }
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235 static int read_basis_rundata(void *mydata,
00236 molfile_qm_t *qm_data) {
00237
00238 qmdata_t *data = (qmdata_t *)mydata;
00239 int i;
00240 molfile_qm_basis_t *basis_data = &qm_data->basis;
00241
00242
00243
00244
00245
00246 #if vmdplugin_ABIVERSION > 11
00247
00248 if (data->num_basis_funcs) {
00249 for (i=0; i<data->num_basis_atoms; i++) {
00250 basis_data->num_shells_per_atom[i] = data->num_shells_per_atom[i];
00251 basis_data->atomic_number[i] = data->atomicnum_per_basisatom[i];
00252 }
00253
00254 for (i=0; i<data->num_shells; i++) {
00255 basis_data->num_prim_per_shell[i] = data->num_prim_per_shell[i];
00256 basis_data->shell_types[i] = data->shell_types[i];
00257 }
00258
00259 for (i=0; i<2*data->num_basis_funcs; i++) {
00260 basis_data->basis[i] = data->basis[i];
00261 }
00262 }
00263 #endif
00264
00265 return MOLFILE_SUCCESS;
00266 }
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276 static void close_basis_read(void *mydata) {
00277
00278 qmdata_t *data = (qmdata_t *)mydata;
00279 int i, j;
00280 fclose(data->file);
00281
00282 free(data->basis);
00283 free(data->shell_types);
00284 free(data->atomicnum_per_basisatom);
00285 free(data->num_shells_per_atom);
00286 free(data->num_prim_per_shell);
00287 free(data->angular_momentum);
00288 free(data->filepos_array);
00289
00290 if (data->basis_set) {
00291 for(i=0; i<data->num_basis_atoms; i++) {
00292 for (j=0; j<data->basis_set[i].numshells; j++) {
00293 free(data->basis_set[i].shell[j].prim);
00294 }
00295 free(data->basis_set[i].shell);
00296 }
00297 free(data->basis_set);
00298 }
00299
00300 free(data);
00301 }
00302
00303
00304
00305
00306
00307
00308
00309 #define TORF(x) (x ? "T" : "F")
00310
00311 static void print_input_data(qmdata_t *data) {
00312 int i, j, k;
00313 int primcount=0;
00314 int shellcount=0;
00315
00316
00317
00318
00319
00320
00321 printf("\n");
00322 printf(" ATOMIC BASIS SET\n");
00323 printf(" ----------------\n");
00324 printf(" THE CONTRACTED PRIMITIVE FUNCTIONS HAVE BEEN UNNORMALIZED\n");
00325 printf(" THE CONTRACTED BASIS FUNCTIONS ARE NOW NORMALIZED TO UNITY\n");
00326 printf("\n");
00327 printf(" SHELL TYPE PRIMITIVE EXPONENT CONTRACTION COEFFICIENT(S)\n");
00328 printf("\n");
00329
00330 printf(" =================================================================\n");
00331 for (i=0; i<data->num_basis_atoms; i++) {
00332 printf("%-8d (%10s)\n\n", data->basis_set[i].atomicnum, data->basis_set[i].name);
00333 printf("\n");
00334
00335 for (j=0; j<data->basis_set[i].numshells; j++) {
00336
00337 for (k=0; k<data->basis_set[i].shell[j].numprims; k++) {
00338 printf("%6d %d %7d %22f%22f\n", j,
00339 data->basis_set[i].shell[j].type,
00340 primcount+1,
00341 data->basis_set[i].shell[j].prim[k].exponent,
00342 data->basis_set[i].shell[j].prim[k].contraction_coeff);
00343 primcount++;
00344 }
00345
00346 printf("\n");
00347 shellcount++;
00348 }
00349 }
00350 printf("\n");
00351 printf(" TOTAL NUMBER OF BASIS SET SHELLS =%5d\n", data->num_shells);
00352 printf(" TOTAL NUMBER OF ATOMS =%5i\n", data->numatoms);
00353 printf("\n");
00354 }
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364 int get_basis(qmdata_t *data) {
00365
00366 char buffer[BUFSIZ];
00367 char word[4][BUFSIZ];
00368 int i = 0;
00369 int success = 0;
00370 int numread, numshells;
00371 shell_t *shell;
00372 long filepos;
00373
00374
00375 buffer[0] = '\0';
00376 for (i=0; i<3; i++) word[i][0] = '\0';
00377
00378 if (!pass_keyline(data->file, "$DATA", NULL))
00379 printf("basissetplugin) No basis set found!\n");
00380
00381
00382
00383
00384
00385 data->basis_set = (basis_atom_t*)calloc(1, sizeof(basis_atom_t));
00386
00387
00388 i = 0;
00389
00390 do {
00391 prim_t *prim = NULL;
00392 char shelltype;
00393 int numprim = 0;
00394 int icoeff = 0;
00395 filepos = ftell(data->file);
00396 GET_LINE(buffer, data->file);
00397
00398
00399 numread = sscanf(buffer,"%s %s %s %s",&word[0][0], &word[1][0],
00400 &word[2][0], &word[3][0]);
00401
00402 if (!strcmp(&word[0][0], "$END")) break;
00403
00404 switch (numread) {
00405 case 1:
00406
00407 if (i>0) {
00408 data->basis_set = (basis_atom_t*)realloc(data->basis_set, (i+1)*sizeof(basis_atom_t));
00409 }
00410
00411 strcpy(data->basis_set[i].name, &word[0][0]);
00412
00413
00414
00415 shell = (shell_t*)calloc(1, sizeof(shell_t));
00416 numshells = 0;
00417
00418 do {
00419 filepos = ftell(data->file);
00420 numprim = read_shell_primitives(data, &prim, &shelltype, icoeff);
00421
00422 if (numprim>0) {
00423
00424 if ( (shelltype!='S' && shelltype!='L' && shelltype!='P' &&
00425 shelltype!='D' && shelltype!='F' && shelltype!='G') ) {
00426 printf("basissetplugin) WARNING ... %c shells are not supported \n", shelltype);
00427 }
00428
00429
00430 if (numshells) {
00431 shell = (shell_t*)realloc(shell, (numshells+1)*sizeof(shell_t));
00432 }
00433 shell[numshells].numprims = numprim;
00434 shell[numshells].type = shelltype_int(shelltype);
00435 shell[numshells].prim = prim;
00436 data->num_basis_funcs += numprim;
00437
00438
00439
00440
00441 if (shelltype=='L' && !icoeff) {
00442 fseek(data->file, filepos, SEEK_SET);
00443 icoeff++;
00444 } else if (shelltype=='L' && icoeff) {
00445 shell[numshells].type = SP_P_SHELL;
00446 icoeff = 0;
00447 }
00448
00449 numshells++;
00450 }
00451 } while (numprim);
00452
00453
00454 data->basis_set[i].numshells = numshells;
00455 data->basis_set[i].shell = shell;
00456
00457
00458 data->num_shells += numshells;
00459 i++;
00460
00461
00462
00463 fseek(data->file, filepos, SEEK_SET);
00464
00465 break;
00466
00467 }
00468
00469 } while (!success);
00470
00471
00472 printf("basissetplugin) Parsed %d uncontracted basis functions for %d atoms.\n",
00473 data->num_basis_funcs, i);
00474
00475 data->num_basis_atoms = i;
00476
00477
00478 return fill_basis_arrays(data);
00479 }
00480
00481
00482
00483
00484
00485
00486
00487 static int shelltype_int(char type) {
00488 int shelltype;
00489
00490 switch (type) {
00491 case 'L':
00492 shelltype = SP_S_SHELL;
00493 break;
00494 case 'M':
00495 shelltype = SP_P_SHELL;
00496 break;
00497 case 'S':
00498 shelltype = S_SHELL;
00499 break;
00500 case 'P':
00501 shelltype = P_SHELL;
00502 break;
00503 case 'D':
00504 shelltype = D_SHELL;
00505 break;
00506 case 'F':
00507 shelltype = F_SHELL;
00508 break;
00509 case 'G':
00510 shelltype = G_SHELL;
00511 break;
00512 default:
00513 shelltype = UNK_SHELL;
00514 break;
00515 }
00516
00517 return shelltype;
00518 }
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528 static int fill_basis_arrays(qmdata_t *data) {
00529 int i, j, k;
00530 int shellcount = 0;
00531 int primcount = 0;
00532 float *basis;
00533 int *num_shells_per_atom;
00534 int *num_prim_per_shell;
00535 int *shell_types;
00536 int *atomicnum_per_basisatom;
00537
00538
00539
00540 for(i=0; i<data->num_basis_atoms; i++) {
00541 for (j=0; j<data->basis_set[i].numshells; j++) {
00542 primcount += data->basis_set[i].shell[j].numprims;
00543 }
00544 }
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554 basis = (float *)calloc(2*primcount,sizeof(float));
00555
00556
00557 if (basis == NULL) {
00558 PRINTERR;
00559 return MOLFILE_ERROR;
00560 }
00561
00562 shell_types = (int *)calloc(data->num_shells, sizeof(int));
00563
00564
00565 if (shell_types == NULL) {
00566 PRINTERR;
00567 return MOLFILE_ERROR;
00568 }
00569
00570 num_shells_per_atom = (int *)calloc(data->num_basis_atoms, sizeof(int));
00571
00572
00573 if (num_shells_per_atom == NULL) {
00574 PRINTERR;
00575 return MOLFILE_ERROR;
00576 }
00577
00578 num_prim_per_shell = (int *)calloc(data->num_shells, sizeof(int));
00579
00580
00581 if (num_prim_per_shell == NULL) {
00582 PRINTERR;
00583 return MOLFILE_ERROR;
00584 }
00585
00586 atomicnum_per_basisatom = (int *)calloc(data->num_basis_atoms, sizeof(int));
00587
00588
00589 if (atomicnum_per_basisatom == NULL) {
00590 PRINTERR;
00591 return MOLFILE_ERROR;
00592 }
00593
00594
00595
00596 data->basis = basis;
00597 data->shell_types = shell_types;
00598 data->num_shells_per_atom = num_shells_per_atom;
00599 data->num_prim_per_shell = num_prim_per_shell;
00600 data->atomicnum_per_basisatom = atomicnum_per_basisatom;
00601
00602 primcount = 0;
00603 for (i=0; i<data->num_basis_atoms; i++) {
00604 int j;
00605
00606 data->basis_set[i].atomicnum = 0;
00607 for (j=0; j<NUM_ELEMENTS; j++) {
00608 if (!strcmp(elements[j], data->basis_set[i].name)) {
00609 data->basis_set[i].atomicnum = j;
00610 break;
00611 }
00612 }
00613 atomicnum_per_basisatom[i] = data->basis_set[i].atomicnum;
00614
00615 num_shells_per_atom[i] = data->basis_set[i].numshells;
00616
00617 for (j=0; j<data->basis_set[i].numshells; j++) {
00618 shell_types[shellcount] = data->basis_set[i].shell[j].type;
00619 num_prim_per_shell[shellcount] = data->basis_set[i].shell[j].numprims;
00620
00621 for (k=0; k<data->basis_set[i].shell[j].numprims; k++) {
00622 basis[2*primcount ] = data->basis_set[i].shell[j].prim[k].exponent;
00623 basis[2*primcount+1] = data->basis_set[i].shell[j].prim[k].contraction_coeff;
00624 primcount++;
00625 }
00626 shellcount++;
00627 }
00628 }
00629
00630 return TRUE;
00631 }
00632
00633
00634
00635
00636
00637
00638
00639 static int read_shell_primitives(qmdata_t *data, prim_t **prim, char *shelltype,
00640 int icoeff) {
00641 char buffer[BUFSIZ];
00642 float exponent = 0.0;
00643 float contract[2] = {0.0, 0.0};
00644 int i, success;
00645 int primcounter = 0, nprim = 0;;
00646
00647 GET_LINE(buffer, data->file);
00648 success = sscanf(buffer,"%c %d", shelltype, &nprim);
00649
00650 (*prim) = (prim_t*)calloc(nprim, sizeof(prim_t));
00651
00652 for (i=0; i<nprim; i++) {
00653 GET_LINE(buffer, data->file);
00654 success = sscanf(buffer,"%*d %f %f %f",
00655 &exponent, &contract[0], &contract[1]);
00656
00657
00658 switch (success) {
00659 case 2:
00660
00661 (*prim)[i].exponent = exponent;
00662
00663
00664 (*prim)[i].contraction_coeff = contract[0];
00665
00666 primcounter++;
00667 break;
00668
00669 case 3:
00670
00671 (*prim)[i].exponent = exponent;
00672
00673
00674 (*prim)[i].contraction_coeff = contract[icoeff];
00675
00676 primcounter++;
00677 break;
00678
00679 case -1:
00680
00681 break;
00682
00683 case 1:
00684
00685 break;
00686 }
00687
00688 }
00689
00690 if (!primcounter) free(*prim);
00691
00692 return primcounter;
00693 }
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703 static molfile_plugin_t plugin;
00704
00705 VMDPLUGIN_API int VMDPLUGIN_init(void) {
00706 memset(&plugin, 0, sizeof(molfile_plugin_t));
00707 plugin.abiversion = vmdplugin_ABIVERSION;
00708 plugin.type = MOLFILE_PLUGIN_TYPE;
00709 plugin.name = "basisset";
00710 plugin.prettyname = "Basis Set";
00711 plugin.author = "Jan Saam";
00712 plugin.majorv = 0;
00713 plugin.minorv = 1;
00714 plugin.is_reentrant = VMDPLUGIN_THREADUNSAFE;
00715 plugin.filename_extension = "basis";
00716 plugin.open_file_read = open_basis_read;
00717 plugin.close_file_read = close_basis_read;
00718 plugin.read_structure = NULL;
00719
00720 plugin.read_qm_metadata = read_basis_metadata;
00721 plugin.read_qm_rundata = read_basis_rundata;
00722
00723 #if vmdplugin_ABIVERSION > 11
00724 plugin.read_timestep_metadata = NULL;
00725 plugin.read_qm_timestep_metadata = NULL;
00726 plugin.read_timestep = NULL;
00727 #endif
00728
00729 return VMDPLUGIN_SUCCESS;
00730 }
00731
00732 VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
00733 (*cb)(v, (vmdplugin_t *)&plugin);
00734 return VMDPLUGIN_SUCCESS;
00735 }
00736
00737 VMDPLUGIN_API int VMDPLUGIN_fini(void) {
00738 return VMDPLUGIN_SUCCESS;
00739 }