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