#include #include #include #include #include #include "simfront.h" int main(int argc, char **argv) { SimFront sf; /* check command line parameters */ #ifdef MD_STATIC if (argc != 2) { fprintf(stderr,"Incorrect use, syntax: %s configfile\n", argv[0]); exit(1); } #else if (argc < 2 || argc > 3) { fprintf(stderr,"Incorrect use, syntax: %s configfile [engine]\n", argv[0]); exit(1); } #endif /* initialize SimFront */ if (init(&sf, argc, argv)) { ABORT(&sf, sf.errmsg); } /* read in config file, set simulation parameters */ if (setup_config(&sf)) { ABORT(&sf, sf.errmsg); } /* read in force field parameter file(s), initialize sim */ if (setup_params(&sf)) { ABORT(&sf, sf.errmsg); } /* read in topology file, initialize sim */ if (setup_topology(&sf)) { ABORT(&sf, sf.errmsg); } /* read in trajectory files, initialize sim */ if (setup_trajectory(&sf)) { ABORT(&sf, sf.errmsg); } /* establish callbacks if allowed by engine */ if (setup_callbacks(&sf)) { ABORT(&sf, sf.errmsg); } /* run the simulation */ if (run_simulation(&sf)) { ABORT(&sf, sf.errmsg); } /* cleanup SimFront */ cleanup(&sf); return 0; } /* * routines to init, cleanup, terminate, and report errors */ int init(SimFront *sf, int argc, char **argv) { extern const ConfigKeywd config_keywd_list[]; extern const int config_keywd_list_num; Ihash *ptable = &(sf->kwdtable); int k; Param *param = &(sf->param); Pbuf *pbuf = &(sf->pbuf); Topo *topo = &(sf->topo); Tbuf *tbuf = &(sf->tbuf); Pdb *pdb = &(sf->pdb); Binres *binres = &(sf->binres); MD_Sim *sim; /* zero the memory (NULL all pointers) */ memset(sf, 0, sizeof(SimFront)); /* set config file and engine from command line arguments */ sf->simfront = argv[0]; sf->configfile = argv[1]; #ifdef MD_STATIC sf->create = deven_create_engine; sf->destroy = deven_destroy_engine; #else if (argc == 2) { sf->create = deven_create_engine; sf->destroy = deven_destroy_engine; } else { sf->engine = argv[2]; } #endif /* initialize IO library */ mdio_startup(); /* * setup for configuration file */ /* initialize hash table for SimFront parameter keywords */ sf->cfkwd = config_keywd_list; sf->cfkwdnum = config_keywd_list_num; if (ihash_init(ptable, 2 * sf->cfkwdnum)) { ERRMSG(sf, "call to ihash_init failed"); return -1; } for (k = 0; k < sf->cfkwdnum; k++) { if (ihash_insert(ptable, sf->cfkwd[k].keywd, k) >= 0) { ERRMSG(sf, "call to ihash_insert failed"); return -1; } } /* allocate starting space for list of force field param files */ sf->paramfilelist = (char **) malloc(sizeof(char *)); if (sf->paramfilelist == NULL) { ERRMSG(sf, strerror(errno)); return -1; } sf->paramfilelistmax = 1; /* initial values */ sf->isoutputbin = TRUE; sf->isrestartbin = TRUE; sf->energyfreq = 1; /* * setup for force field parameters */ /* initialize Param */ if (param_init(param, pbuf)) { ERRMSG(sf, "call to param_init failed"); return -1; } /* allocate buffer space for Pbuf to use */ pbuf->atomp = (MD_Atom_Param *) malloc(INITLEN * sizeof(MD_Atom_Param)); if (pbuf->atomp == NULL) { ERRMSG(sf, strerror(errno)); return -1; } pbuf->atomp_len = INITLEN; pbuf->atomp_num = 0; pbuf->bondp = (MD_Bond_Param *) malloc(INITLEN * sizeof(MD_Bond_Param)); if (pbuf->bondp == NULL) { ERRMSG(sf, strerror(errno)); return -1; } pbuf->bondp_len = INITLEN; pbuf->bondp_num = 0; pbuf->anglep = (MD_Angle_Param *) malloc(INITLEN * sizeof(MD_Angle_Param)); if (pbuf->anglep == NULL) { ERRMSG(sf, strerror(errno)); return -1; } pbuf->anglep_len = INITLEN; pbuf->anglep_num = 0; pbuf->dihedp = (MD_Dihed_Param *) malloc(INITLEN * sizeof(MD_Dihed_Param)); if (pbuf->dihedp == NULL) { ERRMSG(sf, strerror(errno)); return -1; } pbuf->dihedp_len = INITLEN; pbuf->dihedp_num = 0; pbuf->imprp = (MD_Impr_Param *) malloc(INITLEN * sizeof(MD_Impr_Param)); if (pbuf->imprp == NULL) { ERRMSG(sf, strerror(errno)); return -1; } pbuf->imprp_len = INITLEN; pbuf->imprp_num = 0; pbuf->nbfixp = (MD_Nbfix_Param *) malloc(INITLEN * sizeof(MD_Nbfix_Param)); if (pbuf->nbfixp == NULL) { ERRMSG(sf, strerror(errno)); return -1; } pbuf->nbfixp_len = INITLEN; pbuf->nbfixp_num = 0; /* * setup for topology data */ /* initialize Topo */ if (topo_init(topo, tbuf, param)) { ERRMSG(sf, "call to topo_init failed"); return -1; } /* setup buffer space for Tbuf to use */ tbuf->atom = sf->atom; tbuf->atom_len = TBUFLEN; tbuf->atom_num = 0; tbuf->atom_max = 0; tbuf->bond = sf->bond; tbuf->bond_len = TBUFLEN; tbuf->bond_num = 0; tbuf->bond_max = 0; tbuf->angle = sf->angle; tbuf->angle_len = TBUFLEN; tbuf->angle_num = 0; tbuf->angle_max = 0; tbuf->dihed = sf->dihed; tbuf->dihed_len = TBUFLEN; tbuf->dihed_num = 0; tbuf->dihed_max = 0; tbuf->impr = sf->impr; tbuf->impr_len = TBUFLEN; tbuf->impr_num = 0; tbuf->impr_max = 0; tbuf->excl = sf->excl; tbuf->excl_len = TBUFLEN; tbuf->excl_num = 0; tbuf->excl_max = 0; /* * setup for trajectory data */ /* initialize Pdb */ if (pdb_init(pdb)) { ERRMSG(sf, "call to pdb_init failed"); return -1; } /* initialize Binres */ if (binres_init(binres)) { ERRMSG(sf, "call to binres_init failed"); return -1; } /* * setup engine */ /* start engine through MDAPI */ if ((sim = sf->sim = MD_create(sf->engine,sf->create,sf->destroy)) == NULL) { ERRMSG(sf, "unable to create engine"); return -1; } else if (MD_wait(sim)) { ERRMSG(sf, MD_errmsg(sim)); return -1; } /* get IDs for engine force field data arrays */ if ((sf->id_atomparam = MD_lookup(sim, "AtomParam")) < 0 || MD_getattr(sim, sf->id_atomparam).typenum != MD_ATOM_PARAM) { ERRMSG(sf, "data array \"AtomParam\" unavailable"); return -1; } if ((sf->id_bondparam = MD_lookup(sim, "BondParam")) < 0 || MD_getattr(sim, sf->id_bondparam).typenum != MD_BOND_PARAM) { ERRMSG(sf, "data array \"BondParam\" unavailable"); return -1; } if ((sf->id_angleparam = MD_lookup(sim, "AngleParam")) < 0 || MD_getattr(sim, sf->id_angleparam).typenum != MD_ANGLE_PARAM) { ERRMSG(sf, "data array \"AngleParam\" unavailable"); return -1; } if ((sf->id_dihedparam = MD_lookup(sim, "DihedralParam")) < 0 || MD_getattr(sim, sf->id_dihedparam).typenum != MD_DIHED_PARAM) { ERRMSG(sf, "data array \"DihedralParam\" unavailable"); return -1; } if ((sf->id_imprparam = MD_lookup(sim, "ImproperParam")) < 0 || MD_getattr(sim, sf->id_imprparam).typenum != MD_IMPR_PARAM) { ERRMSG(sf, "data array \"ImproperParam\" unavailable"); return -1; } if ((sf->id_nbfixparam = MD_lookup(sim, "NbfixParam")) < 0 || MD_getattr(sim, sf->id_nbfixparam).typenum != MD_NBFIX_PARAM) { ERRMSG(sf, "data array \"NbfixParam\" unavailable"); return -1; } /* get IDs for engine topology data arrays */ if ((sf->id_atom = MD_lookup(sim, "Atom")) < 0 || MD_getattr(sim, sf->id_atom).typenum != MD_ATOM) { ERRMSG(sf, "data array \"Atom\" unavailable"); return -1; } if ((sf->id_bond = MD_lookup(sim, "Bond")) < 0 || MD_getattr(sim, sf->id_bond).typenum != MD_BOND) { ERRMSG(sf, "data array \"Bond\" unavailable"); return -1; } if ((sf->id_angle = MD_lookup(sim, "Angle")) < 0 || MD_getattr(sim, sf->id_angle).typenum != MD_ANGLE) { ERRMSG(sf, "data array \"Angle\" unavailable"); return -1; } if ((sf->id_dihed = MD_lookup(sim, "Dihedral")) < 0 || MD_getattr(sim, sf->id_dihed).typenum != MD_DIHED) { ERRMSG(sf, "data array \"Dihedral\" unavailable"); return -1; } if ((sf->id_impr = MD_lookup(sim, "Improper")) < 0 || MD_getattr(sim, sf->id_impr).typenum != MD_IMPR) { ERRMSG(sf, "data array \"Improper\" unavailable"); return -1; } if ((sf->id_excl = MD_lookup(sim, "Exclusion")) < 0 || MD_getattr(sim, sf->id_excl).typenum != MD_EXCL) { ERRMSG(sf, "data array \"Exclusion\" unavailable"); return -1; } /* get IDs for engine trajectory data arrays */ if ((sf->id_pos = MD_lookup(sim, "Position")) < 0 || MD_getattr(sim, sf->id_pos).typenum != MD_DVEC) { ERRMSG(sf, "data array \"Position\" unavailable"); return -1; } if ((sf->id_vel = MD_lookup(sim, "Velocity")) < 0 || MD_getattr(sim, sf->id_vel).typenum != MD_DVEC) { ERRMSG(sf, "data array \"Velocity\" unavailable"); return -1; } return 0; } void cleanup(SimFront *sf) { int k; /* cleanup the engine through MDAPI */ if (sf->sim) MD_destroy(sf->sim); /* cleanup for binary trajectory files */ binres_destroy(&(sf->binres)); /* cleanup for PDB trajectory files */ pdb_destroy(&(sf->pdb)); /* cleanup for topology */ topo_destroy(&(sf->topo)); /* cleanup for force field parameters */ param_destroy(&(sf->param)); free(sf->pbuf.atomp); free(sf->pbuf.bondp); free(sf->pbuf.anglep); free(sf->pbuf.dihedp); free(sf->pbuf.imprp); free(sf->pbuf.nbfixp); /* cleanup IO library */ mdio_shutdown(); /* cleanup for configuration file parameters */ for (k = 0; k < sf->paramfilelistnum; k++) { free(sf->paramfilelist[k]); } free(sf->paramfilelist); free(sf->topofile); free(sf->coorfile); free(sf->bincoorfile); free(sf->velfile); free(sf->binvelfile); free(sf->cwd); free(sf->outputfile); free(sf->restartfile); ihash_destroy(&(sf->kwdtable)); } /* * called through ABORT() macro */ void terminate(SimFront *sf, const char *msg, const char *file, int line) { if (msg) { fprintf(stderr, "Exception caught in file %s, line %d\n%s\n" "Terminating %s\n", file, line, msg, sf->simfront); } else { fprintf(stderr, "Exception caught in file %s, line %d\nTerminating %s\n", file, line, sf->simfront); } cleanup(sf); exit(1); } /* * called through ERRMSG() macro */ void errmsg(SimFront *sf, const char *msg, const char *file, int line) { if (msg) { sprintf(sf->errmsg, "SimFront error: %.*s, file %.*s, line %d", ERRMSG_MSG_PREC, msg, ERRMSG_FILE_PREC, file, line); } else { sprintf(sf->errmsg, "SimFront error: file %.*s, line %d", ERRMSG_FILE_PREC, file, line); } } /* * print a warning message to stderr */ void warning(SimFront *sf, const char *fmt, ...) { va_list v; va_start(v, fmt); (void) fprintf(stderr, "WARNING: "); (void) vfprintf(stderr, fmt, v); va_end(v); }