static void get_nbparm(char *nb_str,char *comb_str,int *nb,int *comb, warninp_t wi) { int i; char warn_buf[STRLEN]; *nb = -1; for(i=1; (i<eNBF_NR); i++) if (gmx_strcasecmp(nb_str,enbf_names[i]) == 0) *nb = i; if (*nb == -1) *nb = strtol(nb_str,NULL,10); if ((*nb < 1) || (*nb >= eNBF_NR)) { sprintf(warn_buf,"Invalid nonbond function selector '%s' using %s", nb_str,enbf_names[1]); warning_error(wi,warn_buf); *nb = 1; } *comb = -1; for(i=1; (i<eCOMB_NR); i++) if (gmx_strcasecmp(comb_str,ecomb_names[i]) == 0) *comb = i; if (*comb == -1) *comb = strtol(comb_str,NULL,10); if ((*comb < 1) || (*comb >= eCOMB_NR)) { sprintf(warn_buf,"Invalid combination rule selector '%s' using %s", comb_str,ecomb_names[1]); warning_error(wi,warn_buf); *comb = 1; } }
static void get_nbparm(char *nb_str,char *comb_str,int *nb,int *comb) { int i; *nb = -1; for(i=1; (i<eNBF_NR); i++) if (strcasecmp(nb_str,enbf_names[i]) == 0) *nb = i; if (*nb == -1) *nb = atoi(nb_str); if ((*nb < 1) || (*nb >= eNBF_NR)) { sprintf(warn_buf,"Invalid nonbond function selector '%s' using %s", nb_str,enbf_names[1]); warning_error(NULL); *nb = 1; } *comb = -1; for(i=1; (i<eCOMB_NR); i++) if (strcasecmp(comb_str,ecomb_names[i]) == 0) *comb = i; if (*comb == -1) *comb = atoi(comb_str); if ((*comb < 1) || (*comb >= eCOMB_NR)) { sprintf(warn_buf,"Invalid combination rule selector '%s' using %s", comb_str,ecomb_names[1]); warning_error(NULL); *comb = 1; } }
double get_ereal(int *ninp, t_inpfile **inp, const char *name, double def, warninp_t wi) { char buf[32], *ptr, warn_buf[STRLEN]; int ii; double ret; ii = get_einp(ninp, inp, name); if (ii == -1) { sprintf(buf, "%g", def); (*inp)[(*ninp)-1].value = strdup(buf); return def; } else { ret = strtod((*inp)[ii].value, &ptr); if (ptr == (*inp)[ii].value) { sprintf(warn_buf, "Right hand side '%s' for parameter '%s' in parameter file is not a real value\n", (*inp)[ii].value, (*inp)[ii].name); warning_error(wi, warn_buf); } return ret; } }
/* Note that sanitizing the trailing part of (*inp)[ii].value was the responsibility of read_inpfile() */ int get_eint(int *ninp, t_inpfile **inp, const char *name, int def, warninp_t wi) { char buf[32], *ptr, warn_buf[STRLEN]; int ii; int ret; ii = get_einp(ninp, inp, name); if (ii == -1) { sprintf(buf, "%d", def); (*inp)[(*ninp)-1].value = gmx_strdup(buf); return def; } else { ret = strtol((*inp)[ii].value, &ptr, 10); if (*ptr != '\0') { sprintf(warn_buf, "Right hand side '%s' for parameter '%s' in parameter file is not an integer value\n", (*inp)[ii].value, (*inp)[ii].name); warning_error(wi, warn_buf); } return ret; } }
gmx_large_int_t get_egmx_large_int(int *ninp, t_inpfile **inp, const char *name, gmx_large_int_t def, warninp_t wi) { char buf[32], *ptr, warn_buf[STRLEN]; int ii; gmx_large_int_t ret; ii = get_einp(ninp, inp, name); if (ii == -1) { sprintf(buf, gmx_large_int_pfmt, def); (*inp)[(*ninp)-1].value = strdup(buf); return def; } else { ret = str_to_large_int_t((*inp)[ii].value, &ptr); if (ptr == (*inp)[ii].value) { sprintf(warn_buf, "Right hand side '%s' for parameter '%s' in parameter file is not an integer value\n", (*inp)[ii].value, (*inp)[ii].name); warning_error(wi, warn_buf); } return ret; } }
void write_inpfile(const char *fn,int ninp,t_inpfile inp[],gmx_bool bHaltOnUnknown, warninp_t wi) { FILE *out; int i; char warn_buf[STRLEN]; sort_inp(ninp,inp); out=gmx_fio_fopen(fn,"w"); nice_header(out,fn); for(i=0; (i<ninp); i++) { if (inp[i].bSet) { if(inp[i].name[0]==';' || (strlen(inp[i].name)>2 && inp[i].name[1]==';')) fprintf(out,"%-24s\n",inp[i].name); else fprintf(out,"%-24s = %s\n",inp[i].name,inp[i].value ? inp[i].value : ""); } else if (!inp[i].bObsolete) { sprintf(warn_buf,"Unknown left-hand '%s' in parameter file\n", inp[i].name); if (bHaltOnUnknown) { warning_error(wi,warn_buf); } else { warning(wi,warn_buf); } } } gmx_fio_fclose(out); check_warning_error(wi,FARGS); }
double check_mol(gmx_mtop_t *mtop,warninp_t wi) { char buf[256]; int i,mb,nmol,ri,pt; double q; real m; t_atoms *atoms; /* Check mass and charge */ q=0.0; for(mb=0; mb<mtop->nmoltype; mb++) { atoms = &mtop->moltype[mtop->molblock[mb].type].atoms; nmol = mtop->molblock[mb].nmol; for (i=0; (i<atoms->nr); i++) { q += nmol*atoms->atom[i].q; m = atoms->atom[i].m; pt = atoms->atom[i].ptype; /* If the particle is an atom or a nucleus it must have a mass, * else, if it is a shell, a vsite or a bondshell it can have mass zero */ if ((m <= 0.0) && ((pt == eptAtom) || (pt == eptNucleus))) { ri = atoms->atom[i].resind; sprintf(buf,"atom %s (Res %s-%d) has mass %g\n", *(atoms->atomname[i]), *(atoms->resinfo[ri].name), atoms->resinfo[ri].nr, m); warning_error(wi,buf); } else if ((m!=0) && (pt == eptVSite)) { ri = atoms->atom[i].resind; sprintf(buf,"virtual site %s (Res %s-%d) has non-zero mass %g\n" " Check your topology.\n", *(atoms->atomname[i]), *(atoms->resinfo[ri].name), atoms->resinfo[ri].nr, m); warning_error(wi,buf); /* The following statements make LINCS break! */ /* atoms->atom[i].m=0; */ } } } return q; }
void warning(warninp_t wi, const char *s) { if (wi->bAllowWarnings) { wi->nwarn_warn++; low_warning(wi, "WARNING", wi->nwarn_warn, s); } else { warning_error(wi, s); } }
void WTConnection::disconnect(void) { if(!this->connecting && !this->connected) { return; }; this->connecting = false; this->connected = false; if(this->socket != 0) close_portable(this->socket); #ifndef NO_SSL if(this->ssl_socket != NULL) { if(BIO_reset(this->ssl_socket) != 0) warning_error("failed to reset socket"); BIO_free_all(this->ssl_socket); this->ssl_socket = NULL; this->ssl = NULL; }; if(this->ssl_ctx != NULL) { SSL_CTX_free(this->ssl_ctx); this->ssl_ctx = NULL; }; #endif delegate_status(WTHTTP_Closed); if(this->addr_info != NULL) { freeaddrinfo(this->addr_info); this->addr_info = NULL; }; if(this->uri != NULL) { free(this->uri); this->uri = NULL; }; if(this->domain != NULL) { free(this->domain); this->domain = NULL; }; if(this->protocol != NULL) { free(this->protocol); this->protocol = NULL; }; }
int get_eeenum(int *ninp, t_inpfile **inp, const char *name, const char **defs, warninp_t wi) { int ii, i, j; int n = 0; char buf[STRLEN]; ii = get_einp(ninp, inp, name); if (ii == -1) { (*inp)[(*ninp)-1].value = strdup(defs[0]); return 0; } for (i = 0; (defs[i] != NULL); i++) { if (gmx_strcasecmp_min(defs[i], (*inp)[ii].value) == 0) { break; } } if (defs[i] == NULL) { n += sprintf(buf, "Invalid enum '%s' for variable %s, using '%s'\n", (*inp)[ii].value, name, defs[0]); n += sprintf(buf+n, "Next time use one of:"); j = 0; while (defs[j]) { n += sprintf(buf+n, " '%s'", defs[j]); j++; } if (wi != NULL) { warning_error(wi, buf); } else { fprintf(stderr, "%s\n", buf); } (*inp)[ii].value = strdup(defs[0]); return 0; } return i; }
void write_inpfile(const char *fn, int ninp, t_inpfile inp[], gmx_bool bHaltOnUnknown, warninp_t wi) { FILE *out; int i; char warn_buf[STRLEN]; sort_inp(ninp, inp); out = gmx_fio_fopen(fn, "w"); nice_header(out, fn); try { gmx::BinaryInformationSettings settings; settings.generatedByHeader(true); settings.linePrefix(";\t"); gmx::printBinaryInformation(out, gmx::getProgramContext(), settings); } GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; for (i = 0; (i < ninp); i++) { if (inp[i].bSet) { if (inp[i].name[0] == ';' || (strlen(inp[i].name) > 2 && inp[i].name[1] == ';')) { fprintf(out, "%-24s\n", inp[i].name); } else { fprintf(out, "%-24s = %s\n", inp[i].name, inp[i].value ? inp[i].value : ""); } } else if (!inp[i].bObsolete) { sprintf(warn_buf, "Unknown left-hand '%s' in parameter file\n", inp[i].name); if (bHaltOnUnknown) { warning_error(wi, warn_buf); } else { warning(wi, warn_buf); } } } gmx_fio_fclose(out); check_warning_error(wi, FARGS); }
AwhParams *readAndCheckAwhParams(int *ninp_p, t_inpfile **inp_p, const t_inputrec *ir, warninp_t wi) { char opt[STRLEN], prefix[STRLEN], prefixawh[STRLEN]; AwhParams *awhParams; snew(awhParams, 1); int ninp = *ninp_p; t_inpfile *inp = *inp_p; sprintf(prefix, "%s", "awh"); /* Parameters common for all biases */ CTYPE("The way to apply the biasing potential: convolved or umbrella"); sprintf(opt, "%s-potential", prefix); EETYPE(opt, awhParams->ePotential, eawhpotential_names); CTYPE("The random seed used for sampling the umbrella center in the case of umbrella type potential"); sprintf(opt, "%s-seed", prefix); ITYPE(opt, awhParams->seed, -1); if (awhParams->seed == -1) { awhParams->seed = static_cast<int>(gmx::makeRandomSeed()); fprintf(stderr, "Setting the AWH bias MC random seed to %" GMX_PRId64 "\n", awhParams->seed); } CTYPE("Data output interval in number of steps"); sprintf(opt, "%s-nstout", prefix); ITYPE(opt, awhParams->nstOut, 100000); if (awhParams->nstOut <= 0) { char buf[STRLEN]; sprintf(buf, "Not writing AWH output with AWH (%s = %d) does not make sense", opt, awhParams->nstOut); warning_error(wi, buf); } /* This restriction can be removed by changing a flag of print_ebin() */ if (ir->nstenergy == 0 || awhParams->nstOut % ir->nstenergy != 0) { char buf[STRLEN]; sprintf(buf, "%s (%d) should be a multiple of nstenergy (%d)", opt, awhParams->nstOut, ir->nstenergy); warning_error(wi, buf); } CTYPE("Coordinate sampling interval in number of steps"); sprintf(opt, "%s-nstsample", prefix); ITYPE(opt, awhParams->nstSampleCoord, 10); CTYPE("Free energy and bias update interval in number of samples"); sprintf(opt, "%s-nsamples-update", prefix); ITYPE(opt, awhParams->numSamplesUpdateFreeEnergy, 10); CTYPE("When true, biases with share-group>0 are shared between multiple simulations"); sprintf(opt, "%s-share-multisim", prefix); EETYPE(opt, awhParams->shareBiasMultisim, yesno_names); CTYPE("The number of independent AWH biases"); sprintf(opt, "%s-nbias", prefix); ITYPE(opt, awhParams->numBias, 1); if (awhParams->numBias <= 0) { gmx_fatal(FARGS, "%s needs to be an integer > 0", opt); } /* Read the parameters specific to each AWH bias */ snew(awhParams->awhBiasParams, awhParams->numBias); for (int k = 0; k < awhParams->numBias; k++) { bool bComment = (k == 0); sprintf(prefixawh, "%s%d", prefix, k + 1); read_bias_params(&ninp, &inp, &awhParams->awhBiasParams[k], prefixawh, ir, wi, bComment); } /* Do a final consistency check before returning */ checkInputConsistencyAwh(*awhParams, wi); if (ir->init_step != 0) { warning_error(wi, "With AWH init-step should be 0"); } *ninp_p = ninp; *inp_p = inp; return awhParams; }
pull_t *set_pull_init(t_inputrec *ir, const gmx_mtop_t *mtop, rvec *x, matrix box, real lambda, warninp_t wi) { pull_params_t *pull; pull_t *pull_work; t_pbc pbc; int c; double t_start; pull = ir->pull; gmx::LocalAtomSetManager atomSets; pull_work = init_pull(nullptr, pull, ir, mtop, nullptr, &atomSets, lambda); auto mdAtoms = gmx::makeMDAtoms(nullptr, *mtop, *ir, false); auto md = mdAtoms->mdatoms(); atoms2md(mtop, ir, -1, nullptr, mtop->natoms, mdAtoms.get()); if (ir->efep) { update_mdatoms(md, lambda); } set_pbc(&pbc, ir->ePBC, box); t_start = ir->init_t + ir->init_step*ir->delta_t; if (pull->bSetPbcRefToPrevStepCOM) { initPullComFromPrevStep(nullptr, pull_work, md, &pbc, x); } pull_calc_coms(nullptr, pull_work, md, &pbc, t_start, x, nullptr); for (int g = 0; g < pull->ngroup; g++) { bool groupObeysPbc = pullCheckPbcWithinGroup(*pull_work, gmx::arrayRefFromArray(reinterpret_cast<gmx::RVec *>(x), mtop->natoms), pbc, g, c_pullGroupSmallGroupThreshold); if (!groupObeysPbc) { char buf[STRLEN]; if (pull->group[g].pbcatom_input == 0) { sprintf(buf, "When the maximum distance from a pull group reference atom to other atoms in the " "group is larger than %g times half the box size a centrally placed " "atom should be chosen as pbcatom. Pull group %d is larger than that and does not have " "a specific atom selected as reference atom.", c_pullGroupSmallGroupThreshold, g); warning_error(wi, buf); } else if (!pull->bSetPbcRefToPrevStepCOM) { sprintf(buf, "The maximum distance from the chosen PBC atom (%d) of pull group %d to other " "atoms in the group is larger than %g times half the box size. " "Set the pull-pbc-ref-prev-step-com option to yes.", pull->group[g].pbcatom + 1, g, c_pullGroupSmallGroupThreshold); warning_error(wi, buf); } } if (groupObeysPbc) { groupObeysPbc = pullCheckPbcWithinGroup(*pull_work, gmx::arrayRefFromArray(reinterpret_cast<gmx::RVec *>(x), mtop->natoms), pbc, g, c_pullGroupPbcMargin); if (!groupObeysPbc) { char buf[STRLEN]; sprintf(buf, "Pull group %d has atoms at a distance larger than %g times half the box size from the PBC atom (%d). " "If atoms are or will more beyond half the box size from the PBC atom, the COM will be ill defined.", g, c_pullGroupPbcMargin, pull->group[g].pbcatom + 1); set_warning_line(wi, nullptr, -1); warning(wi, buf); } } } fprintf(stderr, "Pull group natoms pbc atom distance at start reference at t=0\n"); for (c = 0; c < pull->ncoord; c++) { t_pull_coord *pcrd; t_pull_group *pgrp0, *pgrp1; double value; real init = 0; pcrd = &pull->coord[c]; pgrp0 = &pull->group[pcrd->group[0]]; pgrp1 = &pull->group[pcrd->group[1]]; fprintf(stderr, "%8d %8d %8d\n", pcrd->group[0], pgrp0->nat, pgrp0->pbcatom+1); fprintf(stderr, "%8d %8d %8d ", pcrd->group[1], pgrp1->nat, pgrp1->pbcatom+1); if (pcrd->bStart) { init = pcrd->init; pcrd->init = 0; } value = get_pull_coord_value(pull_work, c, &pbc); value *= pull_conversion_factor_internal2userinput(pcrd); fprintf(stderr, " %10.3f %s", value, pull_coordinate_units(pcrd)); if (pcrd->bStart) { pcrd->init = value + init; } if (pcrd->eGeom == epullgDIST) { if (pcrd->init < 0) { gmx_fatal(FARGS, "The initial pull distance (%g) needs to be non-negative with geometry %s. If you want a signed distance, use geometry %s instead.", pcrd->init, EPULLGEOM(pcrd->eGeom), EPULLGEOM(epullgDIR)); } /* TODO: With a positive init but a negative rate things could still * go wrong, but it might be fine if you don't pull too far. * We should give a warning or note when there is only one pull dim * active, since that is usually the problematic case when you should * be using direction. We will do this later, since an already planned * generalization of the pull code makes pull dim available here. */ } else if (pcrd->eGeom == epullgANGLE || pcrd->eGeom == epullgANGLEAXIS) { if (pcrd->init < 0 || pcrd->init > 180) { gmx_fatal(FARGS, "The initial pull reference angle (%g) is outside of the allowed range [0, 180] degrees.", pcrd->init); } } else if (pcrd->eGeom == epullgDIHEDRAL) { if (pcrd->init < -180 || pcrd->init > 180) { gmx_fatal(FARGS, "The initial pull reference angle (%g) is outside of the allowed range [-180, 180] degrees.", pcrd->init); } } fprintf(stderr, " %10.3f %s\n", pcrd->init, pull_coordinate_units(pcrd)); } return pull_work; }
static void init_pull_coord(t_pull_coord *pcrd, int coord_index_for_output, char *dim_buf, const char *origin_buf, const char *vec_buf, warninp_t wi) { int m; dvec origin, vec; char buf[STRLEN]; if (pcrd->eType == epullCONSTRAINT && (pcrd->eGeom == epullgCYL || pcrd->eGeom == epullgDIRRELATIVE || pcrd->eGeom == epullgANGLE || pcrd->eGeom == epullgANGLEAXIS || pcrd->eGeom == epullgDIHEDRAL)) { gmx_fatal(FARGS, "Pulling of type %s can not be combined with geometry %s. Consider using pull type %s.", epull_names[pcrd->eType], epullg_names[pcrd->eGeom], epull_names[epullUMBRELLA]); } if (pcrd->eType == epullEXTERNAL) { if (pcrd->externalPotentialProvider[0] == '\0') { sprintf(buf, "The use of pull type '%s' for pull coordinate %d requires that the name of the module providing the potential external is set with the option %s%d%s", epull_names[pcrd->eType], coord_index_for_output, "pull-coord", coord_index_for_output, "-potential-provider"); warning_error(wi, buf); } if (pcrd->rate != 0) { sprintf(buf, "The use of pull type '%s' for pull coordinate %d requires that the pull rate is zero", epull_names[pcrd->eType], coord_index_for_output); warning_error(wi, buf); } if (pcrd->eGeom == epullgCYL) { /* Warn the user of a PBC restriction, caused by the fact that * there is no reference value with an external pull potential. */ sprintf(buf, "With pull type '%s' and geometry '%s', the distance component along the cylinder axis between atoms in the cylinder group and the COM of the pull group should be smaller than half the box length", epull_names[pcrd->eType], epullg_names[pcrd->eGeom]); warning_note(wi, buf); } } process_pull_dim(dim_buf, pcrd->dim, pcrd); string2dvec(origin_buf, origin); if (pcrd->group[0] != 0 && dnorm(origin) > 0) { gmx_fatal(FARGS, "The pull origin can only be set with an absolute reference"); } /* Check the given initial reference value and warn for dangerous values */ if (pcrd->eGeom == epullgDIST) { if (pcrd->bStart && pcrd->init < 0) { sprintf(buf, "The initial reference distance set by pull-coord-init is set to a negative value (%g) with geometry %s while distances need to be non-negative. " "This may work, since you have set pull-coord-start to 'yes' which modifies this value, but only for certain starting distances. " "If this is a mistake you may want to use geometry %s instead.", pcrd->init, EPULLGEOM(pcrd->eGeom), EPULLGEOM(epullgDIR)); warning(wi, buf); } } else if (pcrd->eGeom == epullgANGLE || pcrd->eGeom == epullgANGLEAXIS) { if (pcrd->bStart && (pcrd->init < 0 || pcrd->init > 180)) { /* This value of pcrd->init may be ok depending on pcrd->bStart which modifies pcrd->init later on */ sprintf(buf, "The initial reference angle set by pull-coord-init (%g) is outside of the allowed range [0, 180] degrees for geometry (%s). " "This may work, since you have set pull-coord-start to 'yes' which modifies this value, but only for certain starting angles.", pcrd->init, EPULLGEOM(pcrd->eGeom)); warning(wi, buf); } } else if (pcrd->eGeom == epullgDIHEDRAL) { if (pcrd->bStart && (pcrd->init < -180 || pcrd->init > 180)) { sprintf(buf, "The initial reference angle set by pull-coord-init (%g) is outside of the allowed range [-180, 180] degrees for geometry (%s). " "This may work, since you have set pull-coord-start to 'yes' which modifies this value, but only for certain starting angles.", pcrd->init, EPULLGEOM(pcrd->eGeom)); warning(wi, buf); } } /* Check and set the pull vector */ clear_dvec(vec); string2dvec(vec_buf, vec); if (pcrd->eGeom == epullgDIR || pcrd->eGeom == epullgCYL || pcrd->eGeom == epullgDIRPBC || pcrd->eGeom == epullgANGLEAXIS) { if (dnorm2(vec) == 0) { gmx_fatal(FARGS, "With pull geometry %s the pull vector can not be 0,0,0", epullg_names[pcrd->eGeom]); } for (int d = 0; d < DIM; d++) { if (vec[d] != 0 && pcrd->dim[d] == 0) { gmx_fatal(FARGS, "pull-coord-vec has non-zero %c-component while pull_dim for the %c-dimension is set to N", 'x'+d, 'x'+d); } } /* Normalize the direction vector */ dsvmul(1/dnorm(vec), vec, vec); } else /* This case is for are all the geometries where the pull vector is not used */ { if (dnorm2(vec) > 0) { sprintf(buf, "A pull vector is given (%g %g %g) but will not be used with geometry %s. If you really want to use this " "vector, consider using geometry %s instead.", vec[0], vec[1], vec[2], EPULLGEOM(pcrd->eGeom), pcrd->eGeom == epullgANGLE ? EPULLGEOM(epullgANGLEAXIS) : EPULLGEOM(epullgDIR)); warning(wi, buf); } } for (m = 0; m < DIM; m++) { pcrd->origin[m] = origin[m]; pcrd->vec[m] = vec[m]; } }
/*! \brief * Read parameters of an AWH bias. * * \param[in,out] ninp_p Number of read input file entries. * \param[in,out] inp_p Input file entries. * \param[in,out] awhBiasParams AWH dimensional parameters. * \param[in] prefix Prefix for bias parameters. * \param[in] ir Input parameter struct. * \param[in,out] wi Struct for bookeeping warnings. * \param[in] bComment True if comments should be printed. */ static void read_bias_params(int *ninp_p, t_inpfile **inp_p, AwhBiasParams *awhBiasParams, const char *prefix, const t_inputrec *ir, warninp_t wi, bool bComment) { int ninp; t_inpfile *inp; char opt[STRLEN], prefixdim[STRLEN]; char warningmsg[STRLEN]; /* These are assumed to be declared by the gromacs reading functions */ ninp = *ninp_p; inp = *inp_p; if (bComment) { CTYPE("Estimated initial PMF error (kJ/mol)"); } sprintf(opt, "%s-error-init", prefix); /* We allow using a default value here without warning (but warn the user if the diffusion constant is not set). */ RTYPE(opt, awhBiasParams->errorInitial, 10); if (awhBiasParams->errorInitial <= 0) { gmx_fatal(FARGS, "%s (%d) needs to be > 0.", opt); } if (bComment) { CTYPE("Growth rate of the reference histogram determining the bias update size: exp-linear or linear"); } sprintf(opt, "%s-growth", prefix); EETYPE(opt, awhBiasParams->eGrowth, eawhgrowth_names); if (bComment) { CTYPE("Start the simulation by equilibrating histogram towards the target distribution: no or yes"); } sprintf(opt, "%s-equilibrate-histogram", prefix); EETYPE(opt, awhBiasParams->equilibrateHistogram, yesno_names); if (awhBiasParams->equilibrateHistogram && awhBiasParams->eGrowth != eawhgrowthEXP_LINEAR) { sprintf(warningmsg, "Option %s will only have an effect for histogram growth type '%s'.", opt, EAWHGROWTH(eawhgrowthEXP_LINEAR)); warning(wi, warningmsg); } if (bComment) { CTYPE("Target distribution type: constant, cutoff, boltzmann or local-boltzmann"); } sprintf(opt, "%s-target", prefix); EETYPE(opt, awhBiasParams->eTarget, eawhtarget_names); if ((awhBiasParams->eTarget == eawhtargetLOCALBOLTZMANN) && (awhBiasParams->eGrowth == eawhgrowthEXP_LINEAR)) { sprintf(warningmsg, "Target type '%s' combined with histogram growth type '%s' is not " "expected to give stable bias updates. You probably want to use growth type " "'%s' instead.", EAWHTARGET(eawhtargetLOCALBOLTZMANN), EAWHGROWTH(eawhgrowthEXP_LINEAR), EAWHGROWTH(eawhgrowthLINEAR)); warning(wi, warningmsg); } if (bComment) { CTYPE("Boltzmann beta scaling factor for target distribution types 'boltzmann' and 'boltzmann-local'"); } sprintf(opt, "%s-target-beta-scaling", prefix); RTYPE(opt, awhBiasParams->targetBetaScaling, 0); switch (awhBiasParams->eTarget) { case eawhtargetBOLTZMANN: case eawhtargetLOCALBOLTZMANN: if (awhBiasParams->targetBetaScaling < 0 || awhBiasParams->targetBetaScaling > 1) { gmx_fatal(FARGS, "%s = %g is not useful for target type %s.", opt, awhBiasParams->targetBetaScaling, EAWHTARGET(awhBiasParams->eTarget)); } break; default: if (awhBiasParams->targetBetaScaling != 0) { gmx_fatal(FARGS, "Value for %s (%g) set explicitly but will not be used for target type %s.", opt, awhBiasParams->targetBetaScaling, EAWHTARGET(awhBiasParams->eTarget)); } break; } if (bComment) { CTYPE("Free energy cutoff value for target distribution type 'cutoff'"); } sprintf(opt, "%s-target-cutoff", prefix); RTYPE(opt, awhBiasParams->targetCutoff, 0); switch (awhBiasParams->eTarget) { case eawhtargetCUTOFF: if (awhBiasParams->targetCutoff <= 0) { gmx_fatal(FARGS, "%s = %g is not useful for target type %s.", opt, awhBiasParams->targetCutoff, EAWHTARGET(awhBiasParams->eTarget)); } break; default: if (awhBiasParams->targetCutoff != 0) { gmx_fatal(FARGS, "Value for %s (%g) set explicitly but will not be used for target type %s.", opt, awhBiasParams->targetCutoff, EAWHTARGET(awhBiasParams->eTarget)); } break; } if (bComment) { CTYPE("Initialize PMF and target with user data: no or yes"); } sprintf(opt, "%s-user-data", prefix); EETYPE(opt, awhBiasParams->bUserData, yesno_names); if (bComment) { CTYPE("Group index to share the bias with, 0 means not shared"); } sprintf(opt, "%s-share-group", prefix); ITYPE(opt, awhBiasParams->shareGroup, 0); if (awhBiasParams->shareGroup < 0) { warning_error(wi, "AWH bias share-group should be >= 0"); } if (bComment) { CTYPE("Dimensionality of the coordinate"); } sprintf(opt, "%s-ndim", prefix); ITYPE(opt, awhBiasParams->ndim, 0); if (awhBiasParams->ndim <= 0 || awhBiasParams->ndim > c_biasMaxNumDim) { gmx_fatal(FARGS, "%s-ndim (%d) needs to be > 0 and at most %d\n", prefix, awhBiasParams->ndim, c_biasMaxNumDim); } if (awhBiasParams->ndim > 2) { warning_note(wi, "For awh-dim > 2 the estimate based on the diffusion and the initial error is currently only a rough guideline." " You should verify its usefulness for your system before production runs!"); } snew(awhBiasParams->dimParams, awhBiasParams->ndim); for (int d = 0; d < awhBiasParams->ndim; d++) { bComment = bComment && d == 0; sprintf(prefixdim, "%s-dim%d", prefix, d + 1); readDimParams(&ninp, &inp, prefixdim, &awhBiasParams->dimParams[d], ir->pull, wi, bComment); } /* Check consistencies here that cannot be checked at read time at a lower level. */ checkInputConsistencyAwhBias(*awhBiasParams, wi); *ninp_p = ninp; *inp_p = inp; }
bool WTConnection::connect(const char *url) { int addr_result; struct addrinfo hint; #ifdef _WIN32 DWORD timeout_msec; #else struct timeval tv; #endif char ports[6]; if(this->connecting) { return false; }; if(this->connected) { this->disconnect(); }; this->connecting = true; if(!this->parse_url(url)) { fprintf(stderr, "can't parse URL %s\n", url); last_error = "unparsable URL"; delegate_status(WTHTTP_Error); this->connecting = false; return false; }; if(strcmp("https", this->protocol) == 0) { return connect_https(); }; /* Ensure cleanliness */ memset(&hint, 0, sizeof(struct addrinfo)); hint.ai_family = AF_UNSPEC; hint.ai_socktype = SOCK_STREAM; delegate_status(WTHTTP_Resolving); snprintf(ports, 6, "%d", this->port); if( (addr_result = getaddrinfo(this->domain, ports, &hint, &(this->addr_info))) != 0) { last_error = gai_strerror(addr_result); fprintf(stderr, "can't resolve %s: %s\n", this->domain, last_error); delegate_status(WTHTTP_Error); free(this->uri); free(this->domain); free(this->protocol); this->connecting = false; return false; }; delegate_status(WTHTTP_Connecting); this->socket = ::socket(this->addr_info->ai_family, this->addr_info->ai_socktype, this->addr_info->ai_protocol); #ifdef _WIN32 timeout_msec = 30000; if(::setsockopt(this->socket, SOL_SOCKET, SO_RCVTIMEO, reinterpret_cast<char *>(&timeout_msec), sizeof(DWORD)) == -1) #else tv.tv_sec = 30; tv.tv_usec = 0; if(::setsockopt(this->socket, SOL_SOCKET, SO_RCVTIMEO, reinterpret_cast<char *>(&tv), sizeof(tv)) == -1) #endif { warning_error("couldn't set recv timeout -- expect delays"); } if(::connect(this->socket, this->addr_info->ai_addr, this->addr_info->ai_addrlen) == -1) { last_error = strerror(errno); fprintf(stderr, "can't connect to %s: %s\n", this->domain, last_error); delegate_status(WTHTTP_Error); close_portable(this->socket); freeaddrinfo(this->addr_info); free(this->uri); free(this->domain); free(this->protocol); this->connecting = false; return false; }; this->connected = true; this->connecting = false; delegate_status(WTHTTP_Connected); return true; }
static void init_pull_coord(t_pull_coord *pcrd, char *dim_buf, const char *origin_buf, const char *vec_buf, warninp_t wi) { int m; dvec origin, vec; char buf[STRLEN]; if (pcrd->eType == epullCONSTRAINT && (pcrd->eGeom == epullgCYL || pcrd->eGeom == epullgDIRRELATIVE)) { gmx_fatal(FARGS, "Pulling of type %s can not be combined with geometry %s. Consider using pull type %s.", epull_names[pcrd->eType], epullg_names[pcrd->eGeom], epull_names[epullUMBRELLA]); } process_pull_dim(dim_buf, pcrd->dim); string2dvec(origin_buf, origin); if (pcrd->group[0] != 0 && dnorm(origin) > 0) { gmx_fatal(FARGS, "The pull origin can only be set with an absolute reference"); } /* Check and set the pull vector */ clear_dvec(vec); if (pcrd->eGeom == epullgDIST) { if (pcrd->init < 0) { sprintf(buf, "The initial pull distance is negative with geometry %s, while a distance can not be negative. Use geometry %s instead.", EPULLGEOM(pcrd->eGeom), EPULLGEOM(epullgDIR)); warning_error(wi, buf); } /* TODO: With a positive init but a negative rate things could still * go wrong, but it might be fine if you don't pull too far. * We should give a warning or note when there is only one pull dim * active, since that is usually the problematic case when you should * be using direction. We will do this later, since an already planned * generalization of the pull code makes pull dim available here. */ } else if (pcrd->eGeom != epullgDIRRELATIVE) { string2dvec(vec_buf, vec); if (dnorm2(vec) == 0) { gmx_fatal(FARGS, "With pull geometry %s the pull vector can not be 0,0,0", epullg_names[pcrd->eGeom]); } if (pcrd->eGeom == epullgDIR || pcrd->eGeom == epullgCYL) { /* Normalize the direction vector */ dsvmul(1/dnorm(vec), vec, vec); } } for (m = 0; m < DIM; m++) { pcrd->origin[m] = origin[m]; pcrd->vec[m] = vec[m]; } }
t_inpfile *read_inpfile(const char *fn, int *ninp, char **cppopts, warninp_t wi) { FILE *in; char buf[STRLEN], lbuf[STRLEN], rbuf[STRLEN], warn_buf[STRLEN]; char *ptr, *cptr; t_inpfile *inp = NULL; int nin, lc, i, j, k; /* setting cppopts from command-line options would be cooler */ gmx_bool allow_override = FALSE; if (debug) { fprintf(debug, "Reading MDP file %s\n", fn); } in = ffopen(fn, "r"); nin = lc = 0; do { ptr = fgets2(buf, STRLEN-1, in); lc++; set_warning_line(wi, fn, lc); if (ptr) { /* Strip comment */ if ((cptr = strchr(buf, COMMENTSIGN)) != NULL) { *cptr = '\0'; } /* Strip spaces */ trim(buf); for (j = 0; (buf[j] != '=') && (buf[j] != '\0'); j++) { ; } if (buf[j] == '\0') { if (j > 0) { if (debug) { fprintf(debug, "No = on line %d in file %s, ignored\n", lc, fn); } } } else { for (i = 0; (i < j); i++) { lbuf[i] = buf[i]; } lbuf[i] = '\0'; trim(lbuf); if (lbuf[0] == '\0') { if (debug) { fprintf(debug, "Empty left hand side on line %d in file %s, ignored\n", lc, fn); } } else { for (i = j+1, k = 0; (buf[i] != '\0'); i++, k++) { rbuf[k] = buf[i]; } rbuf[k] = '\0'; trim(rbuf); if (rbuf[0] == '\0') { if (debug) { fprintf(debug, "Empty right hand side on line %d in file %s, ignored\n", lc, fn); } } else { /* Now finally something sensible */ int found_index; /* first check whether we hit the 'multiple_entries' option */ if (gmx_strcasecmp_min(eMultentOpt_names[eMultentOptName], lbuf) == 0) { /* we now check whether to allow overrides from here or not */ if (gmx_strcasecmp_min(eMultentOpt_names[eMultentOptNo], rbuf) == 0) { allow_override = FALSE; } else if (gmx_strcasecmp_min(eMultentOpt_names[eMultentOptLast], rbuf) == 0) { allow_override = TRUE; } else { sprintf(warn_buf, "Parameter \"%s\" should either be %s or %s\n", lbuf, eMultentOpt_names[eMultentOptNo], eMultentOpt_names[eMultentOptLast]); warning_error(wi, warn_buf); } } else { /* it is a regular option; check for duplicates */ found_index = search_einp(nin, inp, lbuf); if (found_index == -1) { /* add a new item */ srenew(inp, ++nin); inp[nin-1].inp_count = 1; inp[nin-1].count = 0; inp[nin-1].bObsolete = FALSE; inp[nin-1].bSet = FALSE; inp[nin-1].name = strdup(lbuf); inp[nin-1].value = strdup(rbuf); } else { if (!allow_override) { sprintf(warn_buf, "Parameter \"%s\" doubly defined (and multiple assignments not allowed)\n", lbuf); warning_error(wi, warn_buf); } else { /* override */ sfree(inp[found_index].value); inp[found_index].value = strdup(rbuf); sprintf(warn_buf, "Overriding existing parameter \"%s\" with value \"%s\"\n", lbuf, rbuf); warning_note(wi, warn_buf); } } } } } } } } while (ptr); ffclose(in); if (debug) { fprintf(debug, "Done reading MDP file, there were %d entries in there\n", nin); } *ninp = nin; return inp; }
/*! \brief * Read parameters of an AWH bias dimension. * * \param[in,out] ninp_p Number of read input file entries. * \param[in,out] inp_p Input file entries. * \param[in] prefix Prefix for dimension parameters. * \param[in,out] dimParams AWH dimensional parameters. * \param[in] pull_params Pull parameters. * \param[in,out] wi Struct for bookeeping warnings. * \param[in] bComment True if comments should be printed. */ static void readDimParams(int *ninp_p, t_inpfile **inp_p, const char *prefix, AwhDimParams *dimParams, const pull_params_t *pull_params, warninp_t wi, bool bComment) { char warningmsg[STRLEN]; int ninp = *ninp_p; t_inpfile *inp = *inp_p; if (bComment) { CTYPE("The provider of the reaction coordinate, currently only pull is supported"); } char opt[STRLEN]; sprintf(opt, "%s-coord-provider", prefix); EETYPE(opt, dimParams->eCoordProvider, eawhcoordprovider_names); if (bComment) { CTYPE("The coordinate index for this dimension"); } sprintf(opt, "%s-coord-index", prefix); int coordIndexInput; ITYPE(opt, coordIndexInput, 1); if (coordIndexInput < 1) { gmx_fatal(FARGS, "Failed to read a valid coordinate index for %s. " "Note that the pull coordinate indexing starts at 1.", opt); } /* The pull coordinate indices start at 1 in the input file, at 0 internally */ dimParams->coordIndex = coordIndexInput - 1; /* The pull settings need to be consistent with the AWH settings */ if (!(pull_params->coord[dimParams->coordIndex].eType == epullEXTERNAL) ) { gmx_fatal(FARGS, "AWH biasing can only be applied to pull type %s", EPULLTYPE(epullEXTERNAL)); } if (dimParams->coordIndex >= pull_params->ncoord) { gmx_fatal(FARGS, "The given AWH coordinate index (%d) is larger than the number of pull coordinates (%d)", coordIndexInput, pull_params->ncoord); } if (pull_params->coord[dimParams->coordIndex].rate != 0) { sprintf(warningmsg, "Setting pull-coord%d-rate (%g) is incompatible with AWH biasing this coordinate", coordIndexInput, pull_params->coord[dimParams->coordIndex].rate); warning_error(wi, warningmsg); } /* Grid params for each axis */ int eGeom = pull_params->coord[dimParams->coordIndex].eGeom; if (bComment) { CTYPE("Start and end values for each coordinate dimension"); } sprintf(opt, "%s-start", prefix); RTYPE(opt, dimParams->origin, 0.); sprintf(opt, "%s-end", prefix); RTYPE(opt, dimParams->end, 0.); if (gmx_within_tol(dimParams->end - dimParams->origin, 0, GMX_REAL_EPS)) { sprintf(warningmsg, "The given interval length given by %s-start (%g) and %s-end (%g) is zero. " "This will result in only one point along this axis in the coordinate value grid.", prefix, dimParams->origin, prefix, dimParams->end); warning(wi, warningmsg); } /* Check that the requested interval is in allowed range */ if (eGeom == epullgDIST) { if (dimParams->origin < 0 || dimParams->end < 0) { gmx_fatal(FARGS, "%s-start (%g) or %s-end (%g) set to a negative value. With pull geometry distance coordinate values are non-negative. " "Perhaps you want to use geometry %s instead?", prefix, dimParams->origin, prefix, dimParams->end, EPULLGEOM(epullgDIR)); } } else if (eGeom == epullgANGLE || eGeom == epullgANGLEAXIS) { if (dimParams->origin < 0 || dimParams->end > 180) { gmx_fatal(FARGS, "%s-start (%g) and %s-end (%g) are outside of the allowed range 0 to 180 deg for pull geometries %s and %s ", prefix, dimParams->origin, prefix, dimParams->end, EPULLGEOM(epullgANGLE), EPULLGEOM(epullgANGLEAXIS)); } } else if (eGeom == epullgDIHEDRAL) { if (dimParams->origin < -180 || dimParams->end > 180) { gmx_fatal(FARGS, "%s-start (%g) and %s-end (%g) are outside of the allowed range -180 to 180 deg for pull geometry %s. ", prefix, dimParams->origin, prefix, dimParams->end, EPULLGEOM(epullgDIHEDRAL)); } } if (bComment) { CTYPE("The force constant for this coordinate (kJ/mol/nm^2 or kJ/mol/rad^2)"); } sprintf(opt, "%s-force-constant", prefix); RTYPE(opt, dimParams->forceConstant, 0); if (dimParams->forceConstant <= 0) { warning_error(wi, "The force AWH bias force constant should be > 0"); } if (bComment) { CTYPE("Estimated diffusion constant (nm^2/ps or rad^2/ps)"); } sprintf(opt, "%s-diffusion", prefix); RTYPE(opt, dimParams->diffusion, 0); if (dimParams->diffusion <= 0) { const double diffusion_default = 1e-5; sprintf(warningmsg, "%s not explicitly set by user." " You can choose to use a default value (%g nm^2/ps or rad^2/ps) but this may very well be non-optimal for your system!", opt, diffusion_default); warning(wi, warningmsg); dimParams->diffusion = diffusion_default; } if (bComment) { CTYPE("Diameter that needs to be sampled around a point before it is considered covered."); } sprintf(opt, "%s-cover-diameter", prefix); RTYPE(opt, dimParams->coverDiameter, 0); if (dimParams->coverDiameter < 0) { gmx_fatal(FARGS, "%s (%g) cannot be negative.", opt, dimParams->coverDiameter); } *ninp_p = ninp; *inp_p = inp; }