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: gamessplugin.h,v $ 00013 * $Author: saam $ $Locker: $ $State: Exp $ 00014 * $Revision: 1.36 $ $Date: 2008/06/16 17:24:48 $ 00015 * 00016 ***************************************************************************/ 00017 /******************************************************************* 00018 * 00019 * headerfile for the gamessplugin 00020 * 00021 * 00022 ******************************************************************/ 00023 00024 #ifndef GAMESSPLUGIN_H 00025 #define GAMESSPLUGIN_H 00026 00027 #include <stdio.h> 00028 #include <stdlib.h> 00029 #include <string.h> 00030 #include <ctype.h> 00031 #include <errno.h> 00032 #include <time.h> 00033 #include <math.h> 00034 #include "molfile_plugin.h" 00035 00036 00037 /* in order to be able to reserve the proper 00038 * amount of temporary arrays I have to define an 00039 * upper limit for the number of atoms in the QM 00040 * system; 1000 atoms should be sufficient for all 00041 * but abnoxiously large systems; hopefully there will 00042 * eventually be a more elegant way to circumvent 00043 * this */ 00044 #define MAXQMATOMS 1000 00045 00046 00047 /* maximum number of Gaussian basis functions; 00048 * 1000 seems to be a proper upper limit for now; 00049 * state-of-the-art simulation could do more, hence 00050 * maybe increase to 5000 later */ 00051 #define MAXBASISFUNCTIONS 1000 00052 00053 00054 /* numerical representation of pi, from math.h */ 00055 #define MY_PI 3.1415926535897932384626433832795029L 00056 00057 00058 /* convert Bohr to Angstrom */ 00059 #define BOHR_TO_ANGS 0.52917724924 00060 #define ANGS_TO_BOHR 1.8897259877218677 00061 00062 00063 /* convert Hartree into kcal/mol */ 00064 #define HARTREE_TO_KCAL 627.503 00065 00066 00067 /* maximum number of points for the orbital 00068 * grid that the grid optimization code is 00069 * allowed to generate */ 00070 #define MAX_GRIDPOINTS 20000 00071 00072 00073 /* define macros for true/false to make code 00074 * look somewhat nicer; the macro DONE signals 00075 * that we're done with reading an should return 00076 * with what we have */ 00077 #define FALSE 0 00078 #define TRUE 1 00079 00080 00081 /* macros describing the RUNTYP */ 00082 #define ENERGY 1 00083 #define OPTIMIZE 2 00084 #define SADPOINT 3 00085 #define HESSIAN 4 00086 00087 00088 /* macros defining the SCFTYP */ 00089 #define RHF 1 00090 #define UHF 2 00091 #define ROHF 3 00092 #define GVB 4 00093 #define MCSCF 5 00094 00095 00096 /* this routine is the main gamess log file 00097 * parser responsible for static, i.e. 00098 * non-trajectory information */ 00099 static int parse_gamess_log_static(void *, int *); 00100 00101 static void print_input_data(void *); 00102 00103 /* this routine checks if the current run is an 00104 * actual GAMESS run; returns true/false */ 00105 static int have_gamess(void *); 00106 00107 00108 /* this routine extracts the GBASIS; returns 00109 * true/false */ 00110 static int get_gbasis(void *); 00111 00112 00113 /* this routine reads the contrl group and 00114 * checks the RUNTYP terminating the plugin 00115 * if it encounters an unsupported one */ 00116 static int check_contrl(void *); 00117 00118 00119 /* this routine prints the current date and time, 00120 * always useful to have that available, in my 00121 * opinion at least. */ 00122 static void get_time(char *); 00123 00124 00125 /* helper routine to chop spaces/newlines off 00126 * a C character string 00127 * 00128 * TODO: This function is horrible and should 00129 * be replaced by a cleaner solutions */ 00130 static char* chop_string_all(char *); 00131 00132 00133 /* helper routine to chop newlines off 00134 * a C character string 00135 * 00136 * TODO: This function is horrible and should 00137 * be replaced by a cleaner solutions */ 00138 static char* chop_string_nl(char *); 00139 00140 00141 /* this routine renormalizes the orbital 00142 * coefficients read in from the input file */ 00143 static float renorm_coefficient(float, float, char); 00144 00145 00146 /* routine to determine the run title of the 00147 * GAMESS run */ 00148 static int get_runtitle(void *); 00149 00150 00151 /* the function get_initial_info provides the atom number, 00152 * coordinates, and atom types and stores them 00153 * temporarily. */ 00154 static int get_initial_info (void *); 00155 00156 00157 /* the function get_basis we also parse the basis function section to 00158 * determine the number of basis functions, contraction 00159 * coefficients. For Pople/Huzinga style basis sets 00160 * this numbers are in principle fixed, and could hence 00161 * be provided by the the plugin itself; however, the user might 00162 * define his own basis/contraction coeffients and hence reading 00163 * them from the input file seem to be somewhat more general. */ 00164 static int get_basis (void *); 00165 00166 00167 /* this function reads the number of processors requested */ 00168 static int get_proc_mem(void *); 00169 00170 00171 /* read in the guess options */ 00172 static int get_guess(void *); 00173 00174 00175 /* this function reads the Gaussian Basis Set information 00176 * for an individual atom in the output file */ 00177 static int atomic_basis(int, void *, float *, char *, int *, int*); 00178 00179 00180 /* this function parses the input file for the final 00181 * wavefunction and stores it in the appropriate arrays; */ 00182 static int get_wavefunction(void *); 00183 00184 00185 /* this function parses the input file and reads the 00186 * number of orbitals; in the case of UHF this might 00187 * be two numbers, namely the number of A and B orbitals; 00188 * it also read the number of GAUSSIAN basis functions */ 00189 static int get_num_orbitals(void *); 00190 00191 00192 /* this function is the main driver for computing and 00193 * handling orbital grid data 00194 */ 00195 static int orbital_grid_driver(void *); 00196 00197 00198 /* this short test routine checks if the 00199 * wavefunction/orbital stuff is supported/possible for 00200 * the current GBASIS */ 00201 static int have_supported_gbasis(void *); 00202 00203 00204 /* this function parses all the stored wavefunctions 00205 * for the HOMO which is the orbital with the smallest 00206 * negative energy; NOTE: selecting the HOMO in such 00207 * a manner might fail for some reasons, but simply is 00208 * currently the easiest way to implement this. 00209 * In the future we probably need some sort of GUI such 00210 * that the user can select whatever orbital they want 00211 * to look at not just the HOMO !! */ 00212 static int find_homo(void *); 00213 00214 00215 /* this subroutine determines the cartesian origin 00216 * and the dimensions of the system under consideration */ 00217 static int get_system_dimensions(void *); 00218 00219 00220 /* given the system dimensions as determined by the 00221 * get_system_dimension call it evaluates the value 00222 * of the orbital at the points determined by the 00223 * computational grid */ 00224 static int calculate_orbital(void *); 00225 00226 00227 /* this subroutine scans the output file for 00228 * the trajectory information */ 00229 static int get_trajectory(void *, molfile_timestep_t *, int); 00230 00231 00232 /* For runtyp=HESSIAN, this subroutine scans the file for 00233 * the hessian matrix in internal coordinates 00234 * as well as the internal coordinate information */ 00235 static int get_int_coords(void *); 00236 00237 00238 /* For runtyp=HESSIAN, this subroutine scans the file for 00239 * the cartesian hessian matrix */ 00240 static int get_cart_hessian(void *); 00241 00242 00243 /* For runtyp=HESSIAN, this subroutine reads the frequencies 00244 * and intensities of the normal modes */ 00245 static int get_normal_modes(void *); 00246 00247 00248 /* this function calculates the value of the wavefunction 00249 * * corresponding to a particular orbital at grid point 00250 * * grid_x, grid_y, grid_z */ 00251 static float orbital_at_grid_xyz(void*, float*, float, float, 00252 float, float); 00253 00254 00255 /* this function animates a given normal mode by means of 00256 * generating mod_num_frames frames away from the equilibrium 00257 * structure in a direction given by the hessiane */ 00258 static int animate_normal_mode(void*, unsigned int); 00259 00260 00261 /* this function generates animated frames for normal 00262 * mode mode_to_animate */ 00263 static int initialize_animated_mode(void*); 00264 00265 00266 /* structure for storing temporary values read in 00267 * from the gamess output file */ 00268 typedef struct 00269 { 00270 char type [8]; /* atom type H,N,O ..... */ 00271 00272 float charge; /* array containing charge of atom i */ 00273 00274 float x,y,z; /* array containing the coordinate of 00275 * atom i*/ 00276 } gamess_temp; 00277 00278 00279 /* structure for storing an animated normal mode */ 00280 typedef struct 00281 { 00282 double *mode_frames; /* coordinate array containing 00283 frames of an animated normal mode */ 00284 00285 unsigned int mode_num_frames; /* number of frames when animating 00286 modes */ 00287 00288 unsigned int current_mode_frame; /* tracker of current frame 00289 of an animated mode */ 00290 00291 double mode_scaling; /* scaling factor used for animated modes */ 00292 } mode_data; 00293 00294 00295 /* main gamess plugin data structure */ 00296 typedef struct 00297 { 00298 FILE *file; 00299 int numatoms; 00300 int runtyp; /* RUNTYP of GAMESS as int for internal use */ 00301 char runtyp_string[BUFSIZ]; /* RUNTYP as string */ 00302 char gbasis[10]; /* GBASIS of GAMESS run */ 00303 00304 char basis_string[BUFSIZ]; /* basis name as "nice" string */ 00305 int ngauss; /* number of gaussian function for 00306 pople style and STO basis */ 00307 int npfunc; /* number of p,d,f and diffuse funtions used */ 00308 int ndfunc; 00309 int nffunc; 00310 int diffs; 00311 int diffsp; 00312 00313 char runtitle[BUFSIZ]; /* title of gamess run */ 00314 00315 char geometry[BUFSIZ]; /* either UNIQUE, CART or ZMP/ZMTMPC */ 00316 char guess[BUFSIZ]; /* type of guess method used */ 00317 00318 char version_string[BUFSIZ]; /* GAMESS version used for run */ 00319 int version; /* here we track the GAMESS versions, since the 00320 * file format has changed with 00321 * version 27 JUN 2005 (R2); 00322 * version = 1 : pre-27 JUN 2005 (R2) 00323 * version = 2 : 27 JUN 2005 (R2) 00324 * version = 0 : this we might set if we 00325 * detect an unsupported 00326 * version and then bomb out */ 00327 int have_pcgamess; /* this flag is set to 1 if the output 00328 * file is recognized as a PC Gamess output 00329 * file; we might need to introduce a few 00330 * switches in the code depending on if 00331 * the log file is plain Gamess or PC Gamess 00332 */ 00333 00334 char *file_name; 00335 00336 /****************************************************** 00337 * new API functions 00338 *****************************************************/ 00339 00340 int scftyp; /* UHF, RHF, ROHF, as in for 00341 internal use*/ 00342 char scftyp_string[BUFSIZ]; /* scftyp as string */ 00343 int *atomic_number; /* atomic numbers of molecule elements */ 00344 /* char usertitle[80]; */ /* 80 chars for an user comment */ 00345 /* char fromcheckfile[80]; */ /* mother checkpoint file */ 00346 int totalcharge; /* Total charge of the system */ 00347 int multiplicity; /* Multiplicity of the system */ 00348 int num_electrons; /* Number of electrons */ 00349 int nimag; /* Number of imaginary frequencies */ 00350 int *nimag_modes; /* List of imaginary modes */ 00351 00352 int num_scfenergies; /* number of SCF energies */ 00353 double *scfenergies; /* Converged SCF energies */ 00354 00355 double *wavenumbers; /* rotational and translational DoF 00356 are included, but can be removed due 00357 to their zero frequencies */ 00358 double *intensities; /* Intensities of spectral lines */ 00359 00360 double *normal_modes; /* the normal modes themselves */ 00361 00362 int nproc; /* Number processors used */ 00363 char memory[256]; /* Amount of memory used, e.g. 1Gb */ 00364 /* char checkfile[256]; */ /* The checkpoint file */ 00365 00366 /* GAUSSIAN specific */ 00367 /* char route[1000]; */ /* line: "#..." */ 00368 /* char geometry[256]; *//* options of the Geom keyword */ 00369 /* char guess[256]; */ /* options of the Guess keyword */ 00370 00371 /* arrays with atom charges */ 00372 double *mulliken_charges; 00373 /* float *mullikengroup; */ 00374 double *esp_charges; 00375 /* float *npacharges; */ 00376 int have_mulliken; 00377 int have_esp; 00378 /* int have_npa; */ 00379 00380 /****************************************************** 00381 * internal coordinate stuff 00382 *****************************************************/ 00383 00384 int have_internals; /* TRUE/FALSE flag indicating if we 00385 * could properly read the internal 00386 * coordinates + internal hessian */ 00387 00388 int have_cart_hessian; /* TRUE/FALSE flag indicating if the 00389 * cartesian Hessian matrix could 00390 * be read from the output file */ 00391 00392 int nintcoords; /* Number of internal coordinates */ 00393 int nbonds; /* Number of bonds */ 00394 int nangles; /* Number of angles */ 00395 int ndiheds; /* Number of dihedrals */ 00396 int nimprops; /* Number of impropers */ 00397 00398 int *bonds; /* bond list (atom tuples) */ 00399 int *angles; /* angle list (atom triples) */ 00400 int *dihedrals; /* dihedral list (atom quadrupels) */ 00401 int *impropers; /* improper list (atom quadrupels) */ 00402 00403 double *internal_coordinates; /* value of internal coordinates */ 00404 00405 /* the order of force constants has to match the internal 00406 * coordinates in *bonds, *angles, *dihedrals */ 00407 00408 double *bond_force_const; /* force constant for bonds */ 00409 double *angle_force_const; /* force constant for angles */ 00410 double *dihedral_force_const; /* force constant for dihedrals */ 00411 double *improper_force_const; /* force constant for impropers */ 00412 00413 /******************************************************* 00414 * end internal coordinate stuff 00415 *******************************************************/ 00416 00417 double *carthessian; /* Hessian matrix in cartesian coordinates, 00418 * dimension (3*numatoms)*(3*numatoms), 00419 * single array of floats 00420 * (row(1),row(2),...,row(numatoms)) 00421 */ 00422 00423 double *inthessian; /* Hessian matrix in internal coordinates, 00424 * dimension nintcoords*nintcoords, 00425 * single array of floats 00426 * (row(1),row(2),...,row(nintcoords)) 00427 */ 00428 00429 /* float** get_cartesian_hessian(units); 00430 float** get_internal_hessian(units); 00431 char* get_elements(); 00432 char* get_names(); */ 00433 00434 /* NBO stuff */ 00435 /* alpha and beta 00436 int have_nbo; 00437 int** lonepairs; 00438 int** singlebonds; 00439 int** doublebonds; 00440 int** triplebonds; */ 00441 00442 00443 /********************************************************* 00444 * END OF NEW API data members 00445 *********************************************************/ 00446 00447 float *system_dimensions; /* stores the minmax xyz dimensions 00448 of the system */ 00449 float *system_center; /* stores the geometric center of the 00450 * system */ 00451 float *orbital_grid; /*this is a large array storing the 00452 * value of the orbitals at each grid 00453 * point; the values are arranged as 00454 * {xmin,ymin,zmin,xmin,ymin,zmin+i, 00455 * ....xmin,ymin+i,zmin,.....} 00456 * were i is distance between grid 00457 * points */ 00458 int num_gridpoints; /* number of gridpoints in the orbital 00459 * grid */ 00460 00461 00462 /* this variable flags the presence (1) or 00463 * absence (!=1) of volumetric data */ 00464 int have_volumetric; 00465 00466 00467 /* this struct holds the volumetric metadata 00468 * for the grid used to display the orbitals */ 00469 molfile_volumetric_t *vol; 00470 00471 00472 /* this array of floats stores the contraction coefficients 00473 * and exponents for the basis functions: 00474 * { exp(1), c-coeff(1), exp(2), c-coeff(2), .... } 00475 * This holds also for double-zeta basis functions with 00476 * exp(i) = exp(j) and c-coeff(i) != c-coeff(j). 00477 * The array basis_counter holds the number of basis functions 00478 * per atom i, in order for them to be assignable to the 00479 * proper real space positions later on. 00480 * the integer num_basis_funcs holds the number of elementary 00481 * basis functions present in the basis array */ 00482 float *basis; 00483 int *basis_counter; 00484 int num_basis_funcs; 00485 00486 00487 /* the array atom_shells stores the number of shells per 00488 * atom i */ 00489 int *atomic_shells; 00490 00491 00492 /* the total number of atomic shells */ 00493 int num_shells; 00494 00495 00496 /* the array shell_primitives contains the number of 00497 * primitives in shell i */ 00498 int *shell_primitives; 00499 00500 00501 /* the array orbital_symmetry stores the symmetry type 00502 * (S,L,D,..) of each (exponent, c-coeff) couple */ 00503 char *orbital_symmetry; 00504 00505 00506 /* the array wave_function contains the expansion coefficients 00507 * for the wavefunction in the form: 00508 * orbital1(c1,c2,c3,...),orbital2(c1,c2,c3,....) ...... */ 00509 float *wave_function; 00510 00511 00512 /* the array orbital_energy contains the energies of 00513 * all orbitals */ 00514 float *orbital_energy; 00515 00516 00517 /* these two variable store the number of A and B orbitals */ 00518 int num_orbitals_A; 00519 int num_orbitals_B; 00520 00521 00522 /* here we store the orbital index of the HOMO */ 00523 int homo_index; 00524 00525 /* this variable stores the number of GAUSSIAN basis functions */ 00526 int num_gauss_basis_funcs; 00527 00528 00529 /* this flags signals if we were successful in reading in 00530 * wavefunction information ( got_wavefunction = 1) or 00531 * not ( got_wavefunction = 0). This will help to avoid 00532 * doing wavefunction type analysis on arrays that have 00533 * not been properly initialized with useful data */ 00534 int got_wavefunction; 00535 00536 00537 /* this variable stores the number of orbital read from the 00538 * output file */ 00539 int orbital_counter; 00540 00541 00542 /* the structure gamess_temp was defined to read in data from 00543 * the GAMESS output file and store it temporarily; 00544 * it is then copied into the VMD specific arrays at the 00545 * appropriate point in time; 00546 * this was partially implemented since the output file does 00547 * not, e.g., contain the number of atoms per se. One rather 00548 * has to count them by hand - at that point one could as 00549 * well already read in the initial coordinates, atom types ... 00550 * which is not really supported by the way the VMD provided 00551 * function are arranged....this implementation could of 00552 * course be changed later..... */ 00553 gamess_temp *temporary; 00554 00555 00556 /* pointer to a structure that keeps track-of an animated 00557 * normal mode */ 00558 mode_data *animated_mode; 00559 00560 00561 /* flag to indicate wether to read a single point or 00562 * a trajectory */ 00563 int have_trajectory; 00564 00565 /* number of trajectory points; single point corresponds 00566 * to 1 */ 00567 int num_traj_points; 00568 00569 00570 } gamessdata; 00571 00572 /* this is currently a hack and provides a 00573 * way to access the data read by the 00574 * plugin from the tcl interface */ 00575 /*gamessdata* tcl_pointer; */ 00576 00577 00578 /* this will skip one line at a time */ 00579 static void eatline(FILE * fd) 00580 { 00581 char readbuf[1025]; 00582 fgets(readbuf, 1024, fd); 00583 } 00584 00585 static float calculate_wavefunction(void*, float*, float, float, 00586 float, float); 00587 00588 #endif
1.2.14 written by Dimitri van Heesch,
© 1997-2002