/* Copyright (C) 2003 by Andrew Lloyd Rohl andrew@ivec.org This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. The GNU GPL can also be found at http://www.gnu.org */ #include #include #include #include "gdis.h" #include "gamess.h" #include "coords.h" #include "model.h" #include "edit.h" #include "file.h" #include "parse.h" #include "matrix.h" #include "interface.h" #define BOHR_TO_ANGS 0.52917724928 #define HARTREE_TO_EV 27.21162 #define GMS_NGAUSS_TXT "ngauss=" #define GMS_NUM_P_TXT "npfunc=" #define GMS_NUM_D_TXT "ndfunc=" #define GMS_NUM_F_TXT "nffunc=" #define GMS_DIFFSP_TXT "diffsp=.true." #define GMS_DIFFS_TXT "diffs=.true." /* TODO: POLAR and split */ #define GMS_MPLEVEL_TXT "mplevl=" #define GMS_CITYP_TXT "cityp=" #define GMS_CCTYP_TXT "cctyp=" #define GMS_MAXIT_TXT "maxit=" #define GMS_TOTAL_Q_TXT "icharg=" #define GMS_MULT_TXT "mult=" #define GMS_WIDE_OUTPUT_TXT "nprint=" #define GMS_COORD_TXT "coord=cart" #define GMS_TIMLIM_TXT "timlim=" #define GMS_MWORDS_TXT "mwords=" #define GMS_NSTEP_TXT "nstep=" #define GMS_UNITS_TXT "units=" struct GMS_keyword_pak units[] = { {"angs", GMS_ANGS}, {"bohr", GMS_BOHR}, {NULL, 0} }; #define GMS_EXETYPE_TXT "exetyp=" struct GMS_keyword_pak exe_types[] = { {"run", GMS_RUN}, {"check", GMS_CHECK}, {"debug", GMS_DEBUG}, {NULL, 0} }; #define GMS_RUNTYPE_TXT "runtyp=" struct GMS_keyword_pak run_types[] = { {"energy", GMS_ENERGY}, {"gradient", GMS_GRADIENT}, {"hessian", GMS_HESSIAN}, {"prop", GMS_PROP}, {"morokuma", GMS_MOROKUMA}, {"transitn", GMS_TRANSITN}, {"ffield", GMS_FFIELD}, {"tdhf", GMS_TDHF}, {"makefp", GMS_MAKEFP}, {"optimize", GMS_OPTIMIZE}, {"trudge", GMS_TRUDGE}, {"sadpoint", GMS_SADPOINT}, {"irc", GMS_IRC}, {"vscf", GMS_VSCF}, {"drc", GMS_DRC}, {"globop", GMS_GLOBOP}, {"gradextr", GMS_GRADEXTR}, {"surface", GMS_SURFACE}, {NULL, 0} }; #define GMS_SCFTYPE_TXT "scftyp=" struct GMS_keyword_pak scf_types[] = { {"rhf", GMS_RHF}, {"uhf", GMS_UHF}, {"rohf", GMS_ROHF}, {NULL, 0} }; #define GMS_METHOD_TXT "method=" struct GMS_keyword_pak method_types[] = { {"qa", GMS_QA}, {"nr", GMS_NR}, {"rfo", GMS_RFO}, {"schlegel", GMS_SCHLEGEL}, {NULL, 0} }; #define GMS_BASIS_TXT "gbasis=" struct GMS_keyword_pak basis_types[] = { {"user defined", GMS_USER}, {"mndo", GMS_MNDO}, {"am1", GMS_AM1}, {"pm3", GMS_PM3}, {"mini", GMS_MINI}, {"midi", GMS_MIDI}, {"sto", GMS_STO}, {"n21", GMS_N21}, {"n31", GMS_N31}, {"n311", GMS_N311}, {"dzv", GMS_DZV}, {"dh", GMS_DH}, {"tzv", GMS_TZV}, {"mc", GMS_MC}, {NULL, 0} }; /* main structures */ extern struct sysenv_pak sysenv; extern struct elem_pak elements[]; /* structures for gamess */ extern struct basis_pak basis_sets[]; /****************/ /* file writing */ /****************/ void write_keyword(FILE *fp, gchar *keyword, gint id, struct GMS_keyword_pak *values) { gint i=0; while (values[i].label) { if (values[i].id == id) fprintf(fp, " %s%s", keyword, values[i].label); i++; } } gint write_gms(gchar *filename, struct model_pak *model) { gdouble x[3]; GSList *list; struct core_pak *core; FILE *fp; /* checks */ g_return_val_if_fail(model != NULL, 1); g_return_val_if_fail(filename != NULL, 2); /* open the file */ fp = fopen(filename,"wb"); if (!fp) return(3); /* TODO - enforce lines < 80 chars? */ /* print control keywords */ fprintf(fp, " $contrl coord=unique"); write_keyword(fp, GMS_EXETYPE_TXT, model->gamess.exe_type, exe_types); write_keyword(fp, GMS_SCFTYPE_TXT, model->gamess.scf_type, scf_types); write_keyword(fp, GMS_RUNTYPE_TXT, model->gamess.run_type, run_types); /* FIXME - put in to try & keep the lines below 80 chars */ fprintf(fp, "\n "); write_keyword(fp, GMS_UNITS_TXT, model->gamess.units, units); fprintf(fp, " %s%d", GMS_MAXIT_TXT, (gint) model->gamess.maxit); if (model->gamess.total_charge != 0.0) fprintf(fp, " %s%d", GMS_TOTAL_Q_TXT, (gint) model->gamess.total_charge); if (model->gamess.multiplicity > 1) fprintf(fp, " %s%d", GMS_MULT_TXT, (gint) model->gamess.multiplicity); if (model->gamess.wide_output) fprintf(fp, " %s6", GMS_WIDE_OUTPUT_TXT); fprintf(fp, " $end\n"); /* NEW - dft calc */ if (model->gamess.dft) { fprintf(fp, " $dft"); switch (model->gamess.dft_functional) { case SVWN: fprintf(fp, " dfttyp=SVWN"); break; case BLYP: fprintf(fp, " dfttyp=BLYP"); break; case B3LYP: fprintf(fp, " dfttyp=B3LYP"); break; } fprintf(fp, " $end\n"); } /* TODO: electron correlation stuff */ /* print size and memory */ fprintf(fp, " $system %s%d %s%d $end\x0a", GMS_TIMLIM_TXT, (gint) model->gamess.time_limit, GMS_MWORDS_TXT, (gint) model->gamess.mwords); /* print optimiser data */ if (model->gamess.run_type >= GMS_OPTIMIZE) { fprintf(fp, " $statpt %s%d ", GMS_NSTEP_TXT, (gint) model->gamess.nstep); write_keyword(fp, GMS_METHOD_TXT, model->gamess.opt_type, method_types); fprintf(fp, "$end\n"); } /* print basis set if one of the standard ones */ if (model->gamess.basis != GMS_USER) { fprintf(fp, " $basis "); write_keyword(fp, GMS_BASIS_TXT, model->gamess.basis, basis_types); if (model->gamess.ngauss) fprintf(fp, " %s%d", GMS_NGAUSS_TXT, model->gamess.ngauss); if (model->gamess.num_p) fprintf(fp, " %s%d", GMS_NUM_P_TXT, (gint) model->gamess.num_p); if (model->gamess.num_d) fprintf(fp, " %s%d", GMS_NUM_D_TXT, (gint) model->gamess.num_d); if (model->gamess.num_f) fprintf(fp, " %s%d", GMS_NUM_F_TXT, (gint) model->gamess.num_f); if (model->gamess.have_heavy_diffuse) fprintf(fp, " %s", GMS_DIFFSP_TXT); if (model->gamess.have_hydrogen_diffuse) fprintf(fp, " %s", GMS_DIFFS_TXT); fprintf(fp, " $end\n"); } /* print data */ fprintf(fp, " $DATA\n"); /* print data header */ fprintf(fp, "%s\n", model->gamess.title); /* print symmetry */ fprintf(fp, "c1\n"); for (list=model->cores ; list ; list=g_slist_next(list)) { core = list->data; if (core->status & DELETED) continue; /* everything is cartesian after latmat mult */ ARR3SET(x, core->x); vecmat(model->latmat, x); if (model->gamess.units == GMS_ANGS) fprintf(fp,"%-7s %d %14.9f %14.9f %14.9f\n", elements[core->atom_code].symbol, elements[core->atom_code].number, x[0], x[1], x[2]); else fprintf(fp,"%-7s %d %14.9f %14.9f %14.9f\n", elements[core->atom_code].symbol, elements[core->atom_code].number, x[0]/BOHR_TO_ANGS, x[1]/BOHR_TO_ANGS, x[2]/BOHR_TO_ANGS); } fprintf(fp, " $END\n"); fclose(fp); return(0); } gchar *get_next_keyword(FILE *fp, gchar *line, gint newline, gint *ret) { static int i; int num_tokens; gchar *text; static gchar **buff; gchar *keyword; if (newline) { buff = tokenize(line, &num_tokens); i = 0; } while (buff[i] == NULL) { /* TODO skip comment lines? */ text = file_read_line(fp); if (!text) { *ret = 2; return(NULL); } else { /* TODO free array of pointers */ /* g_strfreev(buff); */ buff = tokenize(text, &num_tokens); i = 0; } g_free(text); } *ret = 0; keyword = buff[i]; i++; return(keyword); } GSList *get_gamess_keywords(FILE *fp, gchar *line, gint *ret) { gchar *keyword; GSList *keywords=NULL; keyword = get_next_keyword(fp, line, TRUE, ret); while ((g_ascii_strncasecmp(keyword, "$end", 4) != 0) && (*ret == 0)) { keywords = g_slist_append(keywords, keyword); keyword = get_next_keyword(fp, line, FALSE, ret); } if (g_ascii_strncasecmp(keyword, "$end", 4) == 0) g_free(keyword); return(keywords); } gint read_keyword(gchar *value, struct GMS_keyword_pak *values, gint *id) { gint i=0, found=FALSE; while (values[i].label) { if (g_ascii_strcasecmp(values[i].label, value) == 0) { *id = values[i].id; found=TRUE; } i++; } if (found) return(0); else return(1); } gint get_data(FILE *fp, struct model_pak *model, gint have_basis) { gchar **buff, *line; gint num_tokens; struct core_pak *core; /* process title line */ line = file_read_line(fp); if (!line) { gui_text_show(ERROR, "unexpected end of file reading title\n"); return(2); } model->gamess.title = g_strstrip(line); /* process symmetry line */ line = file_read_line(fp); if (!line) { gui_text_show(ERROR, "unexpected end of file reading symmetry\n"); return(2); } if (g_ascii_strncasecmp(line, "c1", 2) != 0) { /* TODO handle symmetry! */ gui_text_show(WARNING, "only C1 symmetry understood at present\n"); } g_free(line); /* process coordinates */ line = file_read_line(fp); if (!line) { gui_text_show(ERROR, "unexpected end of file reading coordinates\n"); return(2); } while (g_ascii_strncasecmp(line, " $end", 5) != 0) { buff = tokenize(line, &num_tokens); /* TODO Store GAMESS label and use in .inp files */ if (num_tokens > 4) { core = new_core(elements[(int) str_to_float(*(buff+1))].symbol, model); if (model->gamess.units == GMS_ANGS) { core->x[0] = str_to_float(*(buff+2)); core->x[1] = str_to_float(*(buff+3)); core->x[2] = str_to_float(*(buff+4)); } else { core->x[0] = str_to_float(*(buff+2)) * BOHR_TO_ANGS; core->x[1] = str_to_float(*(buff+3)) * BOHR_TO_ANGS; core->x[2] = str_to_float(*(buff+4)) * BOHR_TO_ANGS; } model->cores = g_slist_append(model->cores, core); g_strfreev(buff); if (!have_basis) { model->gamess.basis = GMS_USER; /* TODO - read instead of skipping */ for(;;) { line = file_read_line(fp); if (!line) break; buff = tokenize(line, &num_tokens); g_strfreev(buff); if (!num_tokens) break; } } } /* get the next line */ g_free(line); line = file_read_line(fp); if (!line) { gui_text_show(ERROR, "unexpected end of file reading coordinates\n"); return(2); } } g_free(line); return(0); } gint get_basis(gchar *keyword, struct model_pak *model) { gint len, basis; if (g_ascii_strncasecmp(GMS_BASIS_TXT, keyword, len=strlen(GMS_BASIS_TXT)) == 0) { if (read_keyword(&keyword[len], basis_types, &basis) > 0) { gui_text_show(ERROR, " unknown basis "); gui_text_show(ERROR, &keyword[len]); gui_text_show(ERROR, " "); return(1); } model->gamess.basis = basis; return(0); } else if (g_ascii_strncasecmp(keyword, GMS_NGAUSS_TXT, len=strlen(GMS_NGAUSS_TXT)) == 0) model->gamess.ngauss = (gint) (str_to_float(&keyword[len])); else if (g_ascii_strncasecmp(keyword, GMS_NUM_P_TXT, len=strlen(GMS_NUM_P_TXT)) == 0) model->gamess.num_p = str_to_float(&keyword[len]); else if (g_ascii_strncasecmp(keyword, GMS_NUM_D_TXT, len=strlen(GMS_NUM_D_TXT)) == 0) model->gamess.num_d = str_to_float(&keyword[len]); else if (g_ascii_strncasecmp(keyword, GMS_NUM_F_TXT, len=strlen(GMS_NUM_F_TXT)) == 0) model->gamess.num_f = str_to_float(&keyword[len]); else if (g_ascii_strncasecmp(keyword, GMS_DIFFSP_TXT, len=strlen(GMS_DIFFSP_TXT)) == 0) model->gamess.have_heavy_diffuse = TRUE; else if (g_ascii_strncasecmp(keyword, GMS_DIFFS_TXT, len=strlen(GMS_DIFFS_TXT)) == 0) model->gamess.have_hydrogen_diffuse = TRUE; else { gui_text_show(ERROR, " unknown keyword "); gui_text_show(ERROR, keyword); gui_text_show(ERROR, " "); return(1); } return(0); } gint get_control(gchar *keyword, struct model_pak *model) { gint len, bad_andrew; if (g_ascii_strncasecmp(GMS_UNITS_TXT, keyword, len=strlen(GMS_UNITS_TXT)) == 0) { if (read_keyword(&keyword[len], units, &bad_andrew) > 0) { gui_text_show(ERROR, " unknown units "); gui_text_show(ERROR, &keyword[len]); gui_text_show(ERROR, " "); return(1); } model->gamess.units = bad_andrew; return(0); } if (g_ascii_strncasecmp(GMS_EXETYPE_TXT, keyword, len=strlen(GMS_EXETYPE_TXT)) == 0) { if (read_keyword(&keyword[len], exe_types, &bad_andrew) > 0) { gui_text_show(ERROR, " unknown exetyp "); gui_text_show(ERROR, &keyword[len]); gui_text_show(ERROR, " "); return(1); } model->gamess.exe_type = bad_andrew; return(0); } if (g_ascii_strncasecmp(GMS_RUNTYPE_TXT, keyword, len=strlen(GMS_RUNTYPE_TXT)) == 0) { if (read_keyword(&keyword[len], run_types, &bad_andrew) > 0) { gui_text_show(ERROR, " unknown runtyp "); gui_text_show(ERROR, &keyword[len]); gui_text_show(ERROR, " "); return(1); } model->gamess.run_type = bad_andrew; return(0); } if (g_ascii_strncasecmp(GMS_SCFTYPE_TXT, keyword, len=strlen(GMS_SCFTYPE_TXT)) == 0) { if (read_keyword(&keyword[len], scf_types, &bad_andrew) > 0) { gui_text_show(ERROR, " unknown scftyp "); gui_text_show(ERROR, &keyword[len]); gui_text_show(ERROR, " "); return(1); } model->gamess.scf_type = bad_andrew; return(0); } else if (g_ascii_strncasecmp(keyword, GMS_MAXIT_TXT, len=strlen(GMS_MAXIT_TXT)) == 0) model->gamess.maxit = (gint) (str_to_float(&keyword[len])); else if (g_ascii_strncasecmp(keyword, GMS_TOTAL_Q_TXT, len=strlen(GMS_TOTAL_Q_TXT)) == 0) model->gamess.total_charge = (gint) (str_to_float(&keyword[len])); else if (g_ascii_strncasecmp(keyword, GMS_MULT_TXT, len=strlen(GMS_MULT_TXT)) == 0) model->gamess.multiplicity = (gint) (str_to_float(&keyword[len])); else if (g_ascii_strncasecmp(keyword, GMS_WIDE_OUTPUT_TXT, len=strlen(GMS_WIDE_OUTPUT_TXT)) == 0) model->gamess.wide_output = (((gint) (str_to_float(&keyword[len]))) == 6); else if (g_ascii_strncasecmp(keyword, GMS_COORD_TXT, len=strlen(GMS_COORD_TXT)) == 0) ; /* TODO handle different coordinate types */ else { gui_text_show(ERROR, " unknown keyword "); gui_text_show(ERROR, keyword); gui_text_show(ERROR, " "); return(1); } return(0); } gint get_system(gchar *keyword, struct model_pak *model) { int len; if (g_ascii_strncasecmp(keyword, GMS_TIMLIM_TXT, len=strlen(GMS_TIMLIM_TXT)) == 0) model->gamess.time_limit = (gint) (str_to_float(&keyword[len])); else if (g_ascii_strncasecmp(keyword, GMS_MWORDS_TXT, len=strlen(GMS_MWORDS_TXT)) == 0) model->gamess.mwords = (gint) (str_to_float(&keyword[len])); else { gui_text_show(ERROR, " unknown keyword "); gui_text_show(ERROR, keyword); gui_text_show(ERROR, " "); return(1); } return(0); } gint get_statpt(gchar *keyword, struct model_pak *model) { int len, tmp; if (g_ascii_strncasecmp(GMS_METHOD_TXT, keyword, len=strlen(GMS_METHOD_TXT)) == 0) { tmp = model->gamess.opt_type; if (read_keyword(&keyword[len], method_types, &tmp) > 0) { gui_text_show(ERROR, " unknown method "); gui_text_show(ERROR, &keyword[len]); gui_text_show(ERROR, " "); return(1); } return(0); } else if (g_ascii_strncasecmp(keyword, GMS_NSTEP_TXT, len=strlen(GMS_NSTEP_TXT)) == 0) model->gamess.nstep = str_to_float(&keyword[len]); else { gui_text_show(ERROR, " unknown keyword "); gui_text_show(ERROR, keyword); gui_text_show(ERROR, " "); return(1); } return(0); } gint get_next_group(FILE *fp, struct model_pak *model, gint *have_basis) { gchar *line, *keyword; gint ret; GSList *keywords = NULL, *list; line = file_read_line(fp); if (!line) return(FALSE); /* TODO not a valid keyword so for the moment skip but could store */ if (g_ascii_strncasecmp(line, " $", 2) != 0) return(TRUE); if (g_ascii_strncasecmp(line, " $data", 6) == 0) { ret = get_data(fp, model, *have_basis); } else if (g_ascii_strncasecmp(line, " $basis", 7) == 0) { *have_basis = TRUE; keywords = get_gamess_keywords(fp, line+7, &ret); for (list=keywords ; list ; list=g_slist_next(list)) { keyword = (gchar *) list->data; ret = get_basis(keyword, model); } } else if (g_ascii_strncasecmp(line, " $contrl", 8) == 0) { keywords = get_gamess_keywords(fp, line+8, &ret); for (list=keywords; list ; list=g_slist_next(list)) { keyword = (gchar *) list->data; ret = get_control(keyword, model); } } else if (g_ascii_strncasecmp(line, " $system", 8) == 0) { keywords = get_gamess_keywords(fp, line+8, &ret); for (list=keywords; list ; list=g_slist_next(list)) { keyword = (gchar *) list->data; ret = get_system(keyword, model); } } else if (g_ascii_strncasecmp(line, " $statpt", 8) == 0) { keywords = get_gamess_keywords(fp, line+8, &ret); for (list=keywords; list ; list=g_slist_next(list)) { keyword = (gchar *) list->data; ret = get_statpt(keyword, model); } } else if (g_ascii_strncasecmp(line, " $dft", 5) == 0) { model->gamess.dft = TRUE; /* TODO - process functional */ } else { /* TODO - Unknown keyword, just pass through */ } free_slist(keywords); g_free(line); return(TRUE); } gint read_gms(gchar *filename, struct model_pak *model) { FILE *fp; gchar line[LINELEN], *name; gint have_basis = FALSE; fp = fopen(filename, "rt"); if (!fp) { sprintf(line, "Unable to open file %s\n", filename); gui_text_show(ERROR, line); return(1); } else { name = g_path_get_basename(filename); sprintf(line, "Opening %s: \n", name); g_free(name); gui_text_show(STANDARD, line); } while (get_next_group(fp, model, &have_basis)); gui_text_show(STANDARD, "\n"); strcpy(model->filename, filename); g_free(model->basename); model->basename = strdup_basename(filename); model_prep(model); return(0); } /*******************************************/ /* read single GAMESS output configuration */ /*******************************************/ #define DEBUG_READ_GMS_OUT 1 gint read_gms_out_block(FILE *fp, struct model_pak *model, gint num_skip, gint bohr) { gint i, num_tokens; gchar **buff, line[LINELEN]; GString *title, *energy_string, *grad_string; GSList *clist; struct core_pak *core; clist = model->cores; /* ignore first num_skip lines */ for (i=0 ; iconstruct_pbc = FALSE; model->fractional = FALSE; /* get 1st line of coords */ if (fgetline(fp, line)) { gui_text_show(ERROR, "unexpected end of file reading coordinates\n"); return(11); } buff = tokenize(line, &num_tokens); while (num_tokens > 4) { if (clist) { core = clist->data; clist = g_slist_next(clist); } else { core = new_core(elements[(int) str_to_float(*(buff+1))].symbol, model); model->cores = g_slist_append(model->cores, core); } if (bohr) { core->x[0] = BOHR_TO_ANGS*str_to_float(*(buff+2)); core->x[1] = BOHR_TO_ANGS*str_to_float(*(buff+3)); core->x[2] = BOHR_TO_ANGS*str_to_float(*(buff+4)); } else { core->x[0] = str_to_float(*(buff+2)); core->x[1] = str_to_float(*(buff+3)); core->x[2] = str_to_float(*(buff+4)); } /* get next line */ g_strfreev(buff); if (fgetline(fp, line)) { gui_text_show(ERROR, "unexpected end of file reading coordinates\n"); return(11); } buff = tokenize(line, &num_tokens); } g_strfreev(buff); /* search for energy */ while (!fgetline(fp, line)) { if (g_ascii_strncasecmp(line, " FINAL", 6) == 0) { buff = tokenize(line, &num_tokens); if (g_ascii_strncasecmp(*(buff+1), "ENERGY", 6) == 0) model->gamess.energy = str_to_float(*(buff+3)); else model->gamess.energy = str_to_float(*(buff+4)); model->gamess.have_energy = TRUE; g_strfreev(buff); break; } } /* update for MP? */ if (model->gamess.MP_level > 0) { while (!fgetline(fp, line)) { if (g_strrstr(line ,"E(MP2)") != NULL) { buff = tokenize(line, &num_tokens); model->gamess.energy = str_to_float(*(buff+1)); model->gamess.have_energy = TRUE; g_strfreev(buff); break; } } } /* search for gradient and read any properties */ while (!fgetline(fp, line)) { if (g_ascii_strncasecmp(line, " NET CHARGES:", 13) == 0) { clist = model->cores; /* skip forward four lines */ for (i=0 ; i<4; i++) if (fgetline(fp, line)) { gui_text_show(ERROR, "unexpected end of file reading fitted charges\n"); return(11); } while (clist != NULL) { buff = tokenize(line, &num_tokens); core = clist->data; core->lookup_charge = FALSE; core->charge = str_to_float(*(buff+1)); g_strfreev(buff); clist = g_slist_next(clist); if (fgetline(fp, line)) { gui_text_show(ERROR, "unexpected end of file reading fitted charges\n"); return(11); } } } if (g_ascii_strncasecmp(line, " MAXIMUM GRADIENT", 26) == 0) { buff = tokenize(line, &num_tokens); model->gamess.max_grad = str_to_float(*(buff+3)); model->gamess.have_max_grad = TRUE; model->gamess.rms_grad = str_to_float(*(buff+7)); model->gamess.have_rms_grad = TRUE; g_strfreev(buff); /* check next line to see if converged */ if (fgetline(fp, line)) { gui_text_show(ERROR, "unexpected end of file reading equilibrium status\n"); return(11); } if (g_ascii_strncasecmp(line, "1 ***** EQUILIBRIUM GEOMETRY LOCATED *****", 46) == 0) model->gamess.converged = TRUE; break; } } g_free(model->title); title = g_string_new(""); if (model->gamess.have_energy) { energy_string = g_string_new(""); g_string_append_printf(energy_string, "%.5f H", model->gamess.energy); property_add_ranked(3, "Energy", energy_string->str, model); g_string_free(energy_string, TRUE); g_string_append_printf(title, "E"); if (model->gamess.MP_level > 0) g_string_append_printf(title, "(MP%d)", model->gamess.MP_level); g_string_append_printf(title, " = %.5f H", model->gamess.energy); } if (model->gamess.have_rms_grad) { grad_string = g_string_new(""); g_string_append_printf(grad_string, "%.4f H/B", model->gamess.rms_grad); property_add_ranked(4, "RMS Gradient", grad_string->str, model); g_string_free(grad_string, TRUE); g_string_append_printf(title, ", grad = %.5f", model->gamess.rms_grad); } if (model->gamess.have_max_grad) { grad_string = g_string_new(""); g_string_append_printf(grad_string, "%.4f H/B", model->gamess.max_grad); property_add_ranked(4, "Maximum Gradient", grad_string->str, model); g_string_free(grad_string, TRUE); } model->title = g_strdup(title->str); g_string_free(title, TRUE); return(0); } /*******************************/ /* GAMESS output frame reading */ /*******************************/ gint read_gms_out_frame(FILE *fp, struct model_pak *model) { /* replace all data */ return(read_gms_out_block(fp, model, 2, FALSE)); } /********************************/ /* Read in a GAMESS output file */ /********************************/ gint read_gms_out(gchar *filename, struct model_pak *model) { gint flag, frame, num_tokens, len, i, index, bad_andrew; gchar **buff, line[LINELEN], *keyword, *option; GString *property_string; FILE *fp; fp = fopen(filename, "rt"); if (!fp) { sprintf(line, "Unable to open file %s\n", filename); gui_text_show(ERROR, line); return(1); } model->periodic = 0; flag=frame=0; /* read in BASIS OPTIONS */ while (!fgetline(fp, line)) { if (g_ascii_strncasecmp(line, " BASIS OPTIONS", 18) == 0) { /* skip line */ if (fgetline(fp, line)) { gui_text_show(ERROR, "unexpected end of file reading basis options\n"); return(2); } if (fgetline(fp, line)) { gui_text_show(ERROR, "unexpected end of file reading basis options\n"); return(2); } /* get first line of options i.e. basis set */ buff = tokenize(line, &num_tokens); /* GBASIS=STO IGAUSS= 3 POLAR=NONE */ keyword = *(buff+0); if (g_ascii_strncasecmp(keyword, GMS_BASIS_TXT, len = strlen(GMS_BASIS_TXT)) == 0) { if (read_keyword(&keyword[len], basis_types, &bad_andrew) > 0) { sprintf(line, "invalid basis %s\n", &keyword[len]); gui_text_show(ERROR, line); return(3); } model->gamess.basis = bad_andrew; } model->gamess.ngauss = (gint) str_to_float(*(buff+2)); g_strfreev(buff); /* get 2nd line of options i.e. NDFUNC and DIFFSP */ if (fgetline(fp, line)) { gui_text_show(ERROR, "unexpected end of file reading basis options\n"); return(2); } buff = tokenize(line, &num_tokens); /* NDFUNC= 0 DIFFSP= F */ model->gamess.num_d = str_to_float(*(buff+1)); if (g_ascii_strncasecmp(*(buff+3), "F", 1) == 0) model->gamess.have_heavy_diffuse = FALSE; else model->gamess.have_heavy_diffuse = TRUE; g_strfreev(buff); /* get 3rd line of options i.e. MULT and ICHARG */ if (fgetline(fp, line)) { gui_text_show(ERROR, "unexpected end of file reading basis options\n"); return(2); } buff = tokenize(line, &num_tokens); /* NPFUNC= 0 DIFFS= F */ model->gamess.num_p = (gint) str_to_float(*(buff+1)); if (g_ascii_strncasecmp(*(buff+3), "F", 1) == 0) model->gamess.have_hydrogen_diffuse = FALSE; else model->gamess.have_hydrogen_diffuse = TRUE; g_strfreev(buff); /* TODO f functions */ flag++; break; } } if (!flag) { /* no basis present so set to user defined and rewind file */ model->gamess.basis = GMS_USER; rewind(fp); } flag=0; /* read in RUN TITLE */ while (!fgetline(fp, line)) { if (g_ascii_strncasecmp(line, " RUN TITLE", 14) == 0) { if (fgetline(fp, line)) { gui_text_show(ERROR, "unexpected end of file reading title\n"); return(2); } if (fgetline(fp, line)) { gui_text_show(ERROR, "unexpected end of file reading title\n"); return(2); } model->gamess.title = g_strdup(g_strstrip(line)); flag++; break; } } if (!flag) { gui_text_show(ERROR, "RUN TITLE not found\n"); return(2); } flag=0; /* read in $CONTRL OPTIONS */ while (!fgetline(fp, line)) { if (g_ascii_strncasecmp(line, " $CONTRL OPTIONS", 20) == 0) { flag++; if (fgetline(fp, line)) /* skip line of dashes */ { gui_text_show(ERROR, "unexpected end of file reading contrl options\n"); return(3); } while (TRUE) { if (fgetline(fp, line)) { gui_text_show(ERROR, "unexpected end of file reading contrl options\n"); return(3); } /* is the line the blank line signalling end of control options? */ if (strlen(g_strchug(line)) == 0) break; /* break up line into option pairs */ /* each pair takes 15 characters with 5 characters between them */ /* note that we have already removed the single space in front of the lines with the g_strchug */ index = 0; while (index+15 <= strlen(line)) { option = g_strndup(line+index, 15); /* split into pair */ buff = g_strsplit(option, "=", 2); g_free(option); /* remove whitespace */ g_strstrip(buff[0]); g_strstrip(buff[1]); /* the compare strings end in = which we have stripped off so compare on strlen-1 */ if (g_ascii_strncasecmp(buff[0], GMS_SCFTYPE_TXT, strlen(GMS_SCFTYPE_TXT) - 1) == 0) { if (read_keyword(buff[1], scf_types, &bad_andrew) > 0) { sprintf(line, "invalid scf type %s\n", buff[1]); gui_text_show(ERROR, line); return(3); } model->gamess.scf_type = bad_andrew; } else if (g_ascii_strncasecmp(buff[0], GMS_RUNTYPE_TXT, strlen(GMS_RUNTYPE_TXT) - 1) == 0) { if (read_keyword(buff[1], run_types, &bad_andrew) > 0) { sprintf(line, "invalid run type %s\n", buff[1]); gui_text_show(ERROR, line); return(3); } model->gamess.run_type = bad_andrew; property_string = g_string_new(""); i=0; while (run_types[i].label) { if (model->gamess.run_type == run_types[i].id) g_string_append_printf(property_string, "%s", run_types[i].label); i++; } property_string->str[0] = g_ascii_toupper(property_string->str[0]); property_add_ranked(2, "Calculation", property_string->str, model); g_string_free(property_string, TRUE); } else if (g_ascii_strncasecmp(buff[0], GMS_EXETYPE_TXT, strlen(GMS_EXETYPE_TXT) - 1) == 0) { if (read_keyword(buff[1], exe_types, &bad_andrew) > 0) { sprintf(line, "invalid execution type %s\n", buff[1]); gui_text_show(ERROR, line); return(3); } model->gamess.exe_type = bad_andrew; } else if (g_ascii_strncasecmp(buff[0], GMS_MPLEVEL_TXT, strlen(GMS_MPLEVEL_TXT) - 1) == 0) model->gamess.MP_level = (gint) str_to_float(buff[1]); else if (g_ascii_strncasecmp(buff[0], GMS_CITYP_TXT, strlen(GMS_CITYP_TXT) - 1) == 0) if (g_ascii_strncasecmp(buff[1], "none", 4) == 0) model->gamess.have_CI = FALSE; else model->gamess.have_CI = TRUE; else if (g_ascii_strncasecmp(buff[0], GMS_CCTYP_TXT, strlen(GMS_CCTYP_TXT) - 1) == 0) if (g_ascii_strncasecmp(buff[1], "none", 4) == 0) model->gamess.have_CC = FALSE; else model->gamess.have_CC = TRUE; else if (g_ascii_strncasecmp(buff[0], GMS_TOTAL_Q_TXT, strlen(GMS_TOTAL_Q_TXT) - 1) == 0) model->gamess.total_charge = (gint) str_to_float(buff[1]); else if (g_ascii_strncasecmp(buff[0], GMS_MULT_TXT, strlen(GMS_MULT_TXT) - 1) == 0) model->gamess.multiplicity = (gint) str_to_float(buff[1]); else if (g_ascii_strncasecmp(buff[0], GMS_MAXIT_TXT, strlen(GMS_MAXIT_TXT) - 1) == 0) model->gamess.maxit = ((gint) str_to_float(buff[1])); else if (g_ascii_strncasecmp(buff[0], GMS_WIDE_OUTPUT_TXT, strlen(GMS_WIDE_OUTPUT_TXT) - 1) == 0) model->gamess.wide_output = ((gint) str_to_float(buff[1]) == 6); g_strfreev(buff); index += 20; } } break; } } if (!flag) { /* don't return... model_prep() needs to be called to avoid crashing */ gui_text_show(WARNING, "$CONTRL OPTIONS not found\n"); } flag=0; /* read in $SYSTEM OPTIONS */ while (!fgetline(fp, line)) { if (g_ascii_strncasecmp(line, " $SYSTEM OPTIONS", 20) == 0) { if (fgetline(fp, line)) { gui_text_show(ERROR, "unexpected end of file reading system options\n"); return(4); } if (fgetline(fp, line)) { gui_text_show(ERROR, "unexpected end of file reading system options\n"); return(4); } buff = tokenize(line, &num_tokens); model->gamess.mwords = (gint) (str_to_float(*(buff+2))/1000000); g_strfreev(buff); for (i=0; i<4; i++) { if (fgetline(fp, line)) { gui_text_show(ERROR, "unexpected end of file reading system options\n"); return(4); } } buff = tokenize(line, &num_tokens); model->gamess.time_limit = (gint) (str_to_float(*(buff+1))/60.0); g_strfreev(buff); flag++; break; } } if (!flag) { /* don't return... model_prep() needs to be called to avoid crashing */ gui_text_show(WARNING, "$SYSTEM OPTIONS not found\n"); } flag=0; /* anything else to find ? */ while (!fgetline(fp, line)) { if (g_ascii_strncasecmp(line, " GRADIENT OF THE ENERGY", 47) == 0) { if (fgetline(fp, line)) { gui_text_show(ERROR, "unexpected end of file reading gradient\n"); return(5); } while (g_ascii_strncasecmp(line, " MAXIMUM GRADIENT", 35) != 0) { if (fgetline(fp, line)) { gui_text_show(ERROR, "unexpected end of file reading gradient\n"); return(5); } } buff = tokenize(line, &num_tokens); model->gamess.max_grad = str_to_float(*(buff+3)); model->gamess.have_max_grad = TRUE; g_strfreev(buff); if (fgetline(fp, line)) { gui_text_show(ERROR, "unexpected end of file reading gradient\n"); return(5); } buff = tokenize(line, &num_tokens); model->gamess.rms_grad = str_to_float(*(buff+3)); model->gamess.have_rms_grad = TRUE; g_strfreev(buff); } } rewind(fp); /* Read the input coordinates - single frame has different format to multiframe */ if (model->gamess.run_type < GMS_OPTIMIZE) { /* is it a single frame job? */ while (!fgetline(fp, line)) { if (g_ascii_strncasecmp(line, " ATOM ATOMIC COORDINATES (BOHR)", 57) == 0) { read_gms_out_block(fp, model, 1, TRUE); flag++; break; } } } else { /* get optimisation parameters */ while (!fgetline(fp, line)) { if (g_ascii_strncasecmp(line, " STATIONARY POINT LOCATION RUN", 39) == 0) { for (i=0; i<7; i++) { if (fgetline(fp, line)) { gui_text_show(ERROR, "unexpected end of file reading optimizer options\n"); return(5); } } if (model->gamess.exe_type == GMS_CHECK) if (fgetline(fp, line)) { gui_text_show(ERROR, "unexpected end of file reading optimizer options\n"); return(5); } buff = tokenize(line, &num_tokens); if (read_keyword(&(*(buff+1))[1], method_types, &bad_andrew) > 0) { sprintf(line, "invalid method %s\n",&(*(buff+1))[1]); gui_text_show(ERROR, line); return(5); } model->gamess.opt_type = bad_andrew; g_strfreev(buff); flag++; if (fgetline(fp, line)) { gui_text_show(ERROR, "unexpected end of file reading optimizer options\n"); return(5); } if (fgetline(fp, line)) { gui_text_show(ERROR, "unexpected end of file reading optimizer options\n"); return(5); } buff = tokenize(line, &num_tokens); model->gamess.nstep = str_to_float(*(buff+2)); g_strfreev(buff); flag++; break; } } if (!flag) { gui_text_show(ERROR, "optimizer options not found\n"); return(5); } /* Are there any coordinates from a minimisation? */ flag=0; while (!fgetline(fp, line) && !model->gamess.converged) { /* coordinates */ if (g_ascii_strncasecmp(line, " COORDINATES OF ALL ATOMS ARE", 29) == 0) { /* go through all frames to count them */ add_frame_offset(fp, model); read_gms_out_block(fp, model, 2, FALSE); flag++; frame++; } } } /* property_string = g_string_new(""); g_string_append_printf(property_string, "%.0f", model->gamess.total_charge); property_add_ranked(2, "Total Charge", property_string->str, model); g_string_free(property_string, TRUE); property_string = g_string_new(""); g_string_append_printf(property_string, "%.0f", model->gamess.multiplicity); property_add_ranked(3, "Multiplicity", property_string->str, model); g_string_free(property_string, TRUE); */ property_string = g_string_new(""); i=0; while (basis_sets[i].label) { if ((basis_sets[i].basis == model->gamess.basis) && (basis_sets[i].ngauss == model->gamess.ngauss)) g_string_append_printf(property_string, "%s", basis_sets[i].label); i++; } property_add_ranked(7, "Basis", property_string->str, model); g_string_free(property_string, TRUE); /* done */ if (flag) { /* set frame if don't want last? */ strcpy(model->filename, filename); g_free(model->basename); model->basename = strdup_basename(filename); model->num_frames = model->cur_frame = frame; model->cur_frame--; model_prep(model); } else return(2); return(0); }