static real ektrans(rvec v[], real mass[], int isize, int index[]) { dvec mvcom; double mtot; int i, j, d; clear_dvec(mvcom); mtot = 0; for (i = 0; i < isize; i++) { j = index[i]; for (d = 0; d < DIM; d++) { mvcom[d] += mass[j]*v[j][d]; } mtot += mass[j]; } return dnorm2(mvcom)/(mtot*2); }
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]; } }