Exemplo n.º 1
0
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;
  }
}
Exemplo n.º 2
0
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;
  }
}
Exemplo n.º 3
0
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;
    }
}
Exemplo n.º 4
0
/* 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;
    }
}
Exemplo n.º 5
0
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;
    }
}
Exemplo n.º 6
0
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);
}
Exemplo n.º 7
0
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;
}
Exemplo n.º 8
0
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);
    }
}
Exemplo n.º 9
0
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;
	};
}
Exemplo n.º 10
0
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;
}
Exemplo n.º 11
0
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);
}
Exemplo n.º 12
0
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;
}
Exemplo n.º 13
0
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;
}
Exemplo n.º 14
0
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];
    }
}
Exemplo n.º 15
0
/*! \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;
}
Exemplo n.º 16
0
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;
}
Exemplo n.º 17
0
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];
    }
}
Exemplo n.º 18
0
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;
}
Exemplo n.º 19
0
/*! \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;
}