static void init_pull_coord(t_pull_coord *pcrd, int eGeom, const char *origin_buf, const char *vec_buf) { int m; dvec origin, vec; 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"); } if (eGeom == epullgDIST) { clear_dvec(vec); } else { string2dvec(vec_buf, vec); if (eGeom == epullgDIR || 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]; } }
static void init_pullgrp(t_pullgrp *pg,char *wbuf, bool bRef,int eGeom,char *s_vec) { double d; int n,m; dvec vec; pg->nweight = 0; while (sscanf(wbuf,"%lf %n",&d,&n) == 1) { if (pg->nweight % 100 == 0) { srenew(pg->weight,pg->nweight+100); } pg->weight[pg->nweight++] = d; wbuf += n; } if (!bRef) { if (eGeom == epullgDIST) { clear_dvec(vec); } else { string2dvec(s_vec,vec); if (eGeom == epullgDIR || eGeom == epullgCYL || (eGeom == epullgPOS && dnorm(vec) != 0)) /* Normalize the direction vector */ dsvmul(1/dnorm(vec),vec,vec); } for(m=0; m<DIM; m++) pg->vec[m] = vec[m]; } }
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]; } }
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]; } }