git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@12811 f3b2605a-c512-4ea7-a41b-209d697bcdaa
This commit is contained in:
@ -99,6 +99,7 @@ colvar::colvar (std::string const &conf)
|
||||
|
||||
initialize_components("distance", "distance", distance);
|
||||
initialize_components("distance vector", "distanceVec", distance_vec);
|
||||
initialize_components("Cartesian coordinates", "cartesian", cartesian);
|
||||
initialize_components("distance vector "
|
||||
"direction", "distanceDir", distance_dir);
|
||||
initialize_components("distance projection "
|
||||
@ -107,6 +108,8 @@ colvar::colvar (std::string const &conf)
|
||||
"on a plane", "distanceXY", distance_xy);
|
||||
initialize_components("average distance weighted by inverse power",
|
||||
"distanceInv", distance_inv);
|
||||
initialize_components("N1xN2-long vector of pairwise distances",
|
||||
"distancePairs", distance_pairs);
|
||||
|
||||
initialize_components("coordination "
|
||||
"number", "coordNum", coordnum);
|
||||
@ -159,11 +162,33 @@ colvar::colvar (std::string const &conf)
|
||||
enable(task_scripted);
|
||||
cvm::log("This colvar uses scripted function \"" + scripted_function + "\".");
|
||||
|
||||
// Only accept scalar scripted colvars
|
||||
// might accept other types when the infrastructure is in place
|
||||
// for derivatives of vectors wrt vectors
|
||||
x.type(colvarvalue::type_scalar);
|
||||
std::string type_str;
|
||||
get_keyval(conf, "scriptedFunctionType", type_str, "scalar");
|
||||
|
||||
x.type(colvarvalue::type_notset);
|
||||
int t;
|
||||
for (t = 0; t < colvarvalue::type_all; t++) {
|
||||
if (type_str == colvarvalue::type_keyword(colvarvalue::Type(t))) {
|
||||
x.type(colvarvalue::Type(t));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (x.type() == colvarvalue::type_notset) {
|
||||
cvm::error("Could not parse scripted colvar type.");
|
||||
return;
|
||||
}
|
||||
x_reported.type (x.type());
|
||||
cvm::log(std::string("Expecting colvar value of type ")
|
||||
+ colvarvalue::type_desc(x.type()));
|
||||
|
||||
if (x.type() == colvarvalue::type_vector) {
|
||||
int size;
|
||||
if (!get_keyval(conf, "scriptedFunctionVectorSize", size)) {
|
||||
cvm::error("Error: no size specified for vector scripted function.");
|
||||
return;
|
||||
}
|
||||
x.vector1d_value.resize(size);
|
||||
}
|
||||
|
||||
// Sort array of cvcs based on values of componentExp
|
||||
std::vector<cvc *> temp_vec;
|
||||
@ -185,41 +210,39 @@ colvar::colvar (std::string const &conf)
|
||||
// Build ordered list of component values that will be
|
||||
// passed to the script
|
||||
for (j = 0; j < cvcs.size(); j++) {
|
||||
sorted_cvc_values.push_back(cvcs[j]->p_value());
|
||||
sorted_cvc_values.push_back(&(cvcs[j]->value()));
|
||||
}
|
||||
|
||||
b_homogeneous = false;
|
||||
// Scripted functions are deemed non-periodic
|
||||
b_periodic = false;
|
||||
period = 0.0;
|
||||
b_inverse_gradients = false;
|
||||
b_Jacobian_force = false;
|
||||
}
|
||||
|
||||
if (!tasks[task_scripted]) {
|
||||
// this is set false if any of the components has an exponent
|
||||
// different from 1 in the polynomial
|
||||
b_linear = true;
|
||||
// these will be set to false if any of the cvcs has them false
|
||||
b_inverse_gradients = true;
|
||||
b_Jacobian_force = true;
|
||||
colvarvalue const &cvc_value = (cvcs[0])->value();
|
||||
if (cvm::debug())
|
||||
cvm::log ("This collective variable is a "+
|
||||
colvarvalue::type_desc(cvc_value.type())+
|
||||
((cvc_value.size() > 1) ? " with "+
|
||||
cvm::to_str(cvc_value.size())+" individual components.\n" :
|
||||
".\n"));
|
||||
x.type(cvc_value);
|
||||
x_reported.type(cvc_value);
|
||||
}
|
||||
|
||||
// Test whether this is a single-component variable
|
||||
// Decide whether the colvar is periodic
|
||||
// Used to wrap extended DOF if extendedLagrangian is on
|
||||
if (cvcs.size() == 1 && (cvcs[0])->sup_np == 1
|
||||
&& (cvcs[0])->sup_coeff == 1.0
|
||||
&& !tasks[task_scripted]) {
|
||||
|
||||
b_single_cvc = true;
|
||||
b_periodic = (cvcs[0])->b_periodic;
|
||||
period = (cvcs[0])->period;
|
||||
// TODO write explicit wrap() function for colvars to allow for
|
||||
// sup_coeff different from 1
|
||||
// this->period = (cvcs[0])->period * (cvcs[0])->sup_coeff;
|
||||
} else {
|
||||
b_single_cvc = false;
|
||||
b_periodic = false;
|
||||
period = 0.0;
|
||||
// If using scripted biases, any colvar may receive bias forces
|
||||
// and will need its gradient
|
||||
if (cvm::scripted_forces()) {
|
||||
enable(task_gradients);
|
||||
}
|
||||
|
||||
// check the available features of each cvc
|
||||
// check for linear combinations
|
||||
|
||||
b_linear = !tasks[task_scripted];
|
||||
for (i = 0; i < cvcs.size(); i++) {
|
||||
|
||||
if ((cvcs[i])->b_debug_gradients)
|
||||
enable(task_gradients);
|
||||
|
||||
@ -237,7 +260,41 @@ colvar::colvar (std::string const &conf)
|
||||
(cvcs[i])->function_type+"\" approaches zero.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Colvar is homogeneous iff:
|
||||
// - it is not scripted
|
||||
// - it is linear
|
||||
// - all cvcs have coefficient 1 or -1
|
||||
// i.e. sum or difference of cvcs
|
||||
|
||||
b_homogeneous = !tasks[task_scripted] && b_linear;
|
||||
for (i = 0; i < cvcs.size(); i++) {
|
||||
if ((std::fabs(cvcs[i]->sup_coeff) - 1.0) > 1.0e-10) {
|
||||
b_homogeneous = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Colvar is deemed periodic iff:
|
||||
// - it is homogeneous
|
||||
// - all cvcs are periodic
|
||||
// - all cvcs have the same period
|
||||
|
||||
b_periodic = cvcs[0]->b_periodic && b_homogeneous;
|
||||
period = cvcs[0]->period;
|
||||
for (i = 1; i < cvcs.size(); i++) {
|
||||
if (!cvcs[i]->b_periodic || cvcs[i]->period != period) {
|
||||
b_periodic = false;
|
||||
period = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
// these will be set to false if any of the cvcs has them false
|
||||
b_inverse_gradients = !tasks[task_scripted];
|
||||
b_Jacobian_force = !tasks[task_scripted];
|
||||
|
||||
// check the available features of each cvc
|
||||
for (i = 0; i < cvcs.size(); i++) {
|
||||
if ((cvcs[i])->b_periodic && !b_periodic) {
|
||||
cvm::log("Warning: although this component is periodic, the colvar will "
|
||||
"not be treated as periodic, either because the exponent is not "
|
||||
@ -251,48 +308,29 @@ colvar::colvar (std::string const &conf)
|
||||
if (! (cvcs[i])->b_Jacobian_derivative)
|
||||
b_Jacobian_force = false;
|
||||
|
||||
if (!tasks[task_scripted]) {
|
||||
// If the combination of components is a scripted function,
|
||||
// the components may have different types
|
||||
for (size_t j = i; j < cvcs.size(); j++) {
|
||||
if ( (cvcs[i])->type() != (cvcs[j])->type() ) {
|
||||
cvm::log ("ERROR: you are definining this collective variable "
|
||||
"by using components of different types, \""+
|
||||
colvarvalue::type_desc[(cvcs[i])->type()]+
|
||||
"\" and \""+
|
||||
colvarvalue::type_desc[(cvcs[j])->type()]+
|
||||
"\". "
|
||||
// components may have different types only for scripted functions
|
||||
if (!tasks[task_scripted] && (colvarvalue::check_types(cvcs[i]->value(),
|
||||
cvcs[0]->value())) ) {
|
||||
cvm::error("ERROR: you are definining this collective variable "
|
||||
"by using components of different types. "
|
||||
"You must use the same type in order to "
|
||||
" sum them together.\n");
|
||||
cvm::set_error_bits(INPUT_ERROR);
|
||||
" sum them together.\n", INPUT_ERROR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!tasks[task_scripted]) {
|
||||
colvarvalue::Type const value_type = (cvcs[0])->type();
|
||||
if (cvm::debug())
|
||||
cvm::log ("This collective variable is a "+
|
||||
colvarvalue::type_desc[value_type]+", corresponding to "+
|
||||
cvm::to_str (colvarvalue::dof_num[value_type])+
|
||||
" internal degrees of freedom.\n");
|
||||
x.type (value_type);
|
||||
x_reported.type (value_type);
|
||||
}
|
||||
|
||||
get_keyval(conf, "width", width, 1.0);
|
||||
if (width <= 0.0) {
|
||||
cvm::error("Error: \"width\" must be positive.\n", INPUT_ERROR);
|
||||
}
|
||||
|
||||
lower_boundary.type (this->type());
|
||||
lower_wall.type (this->type());
|
||||
lower_boundary.type(value());
|
||||
lower_wall.type(value());
|
||||
|
||||
upper_boundary.type (this->type());
|
||||
upper_wall.type (this->type());
|
||||
upper_boundary.type(value());
|
||||
upper_wall.type(value());
|
||||
|
||||
if (this->type() == colvarvalue::type_scalar) {
|
||||
if (value().type() == colvarvalue::type_scalar) {
|
||||
|
||||
if (get_keyval(conf, "lowerBoundary", lower_boundary, lower_boundary)) {
|
||||
enable(task_lower_boundary);
|
||||
@ -375,14 +413,14 @@ colvar::colvar (std::string const &conf)
|
||||
|
||||
enable(task_extended_lagrangian);
|
||||
|
||||
xr.type (this->type());
|
||||
vr.type (this->type());
|
||||
fr.type (this->type());
|
||||
xr.type(value());
|
||||
vr.type(value());
|
||||
fr.type(value());
|
||||
|
||||
const bool found = get_keyval(conf, "extendedTemp", temp, cvm::temperature());
|
||||
if (temp <= 0.0) {
|
||||
if (found)
|
||||
cvm::log ("Error: \"extendedTemp\" must be positive.\n");
|
||||
cvm::error("Error: \"extendedTemp\" must be positive.\n", INPUT_ERROR);
|
||||
else
|
||||
cvm::error("Error: a positive temperature must be provided, either "
|
||||
"by enabling a thermostat, or through \"extendedTemp\".\n",
|
||||
@ -621,7 +659,7 @@ int colvar::enable (colvar::task const &t)
|
||||
cvm::log("Enabling calculation of the Jacobian force "
|
||||
"on this colvar.\n");
|
||||
}
|
||||
fj.type (this->type());
|
||||
fj.type(value());
|
||||
break;
|
||||
|
||||
case task_system_force:
|
||||
@ -634,8 +672,8 @@ int colvar::enable (colvar::task const &t)
|
||||
}
|
||||
cvm::request_system_force();
|
||||
}
|
||||
ft.type (this->type());
|
||||
ft_reported.type (this->type());
|
||||
ft.type(value());
|
||||
ft_reported.type(value());
|
||||
break;
|
||||
|
||||
case task_output_applied_force:
|
||||
@ -646,9 +684,9 @@ int colvar::enable (colvar::task const &t)
|
||||
break;
|
||||
|
||||
case task_fdiff_velocity:
|
||||
x_old.type (this->type());
|
||||
v_fdiff.type (this->type());
|
||||
v_reported.type (this->type());
|
||||
x_old.type(value());
|
||||
v_fdiff.type(value());
|
||||
v_reported.type(value());
|
||||
break;
|
||||
|
||||
case task_output_velocity:
|
||||
@ -656,7 +694,7 @@ int colvar::enable (colvar::task const &t)
|
||||
break;
|
||||
|
||||
case task_grid:
|
||||
if (this->type() != colvarvalue::type_scalar) {
|
||||
if (value().type() != colvarvalue::type_scalar) {
|
||||
cvm::error("Cannot calculate a grid for collective variable, \""+
|
||||
this->name+"\", because its value is not a scalar number.\n",
|
||||
INPUT_ERROR);
|
||||
@ -665,12 +703,12 @@ int colvar::enable (colvar::task const &t)
|
||||
|
||||
case task_extended_lagrangian:
|
||||
enable(task_gradients);
|
||||
v_reported.type (this->type());
|
||||
v_reported.type(value());
|
||||
break;
|
||||
|
||||
case task_lower_boundary:
|
||||
case task_upper_boundary:
|
||||
if (this->type() != colvarvalue::type_scalar) {
|
||||
if (value().type() != colvarvalue::type_scalar) {
|
||||
cvm::error("Error: this colvar is not a scalar value "
|
||||
"and cannot produce a grid.\n",
|
||||
INPUT_ERROR);
|
||||
@ -687,12 +725,12 @@ int colvar::enable (colvar::task const &t)
|
||||
break;
|
||||
|
||||
case task_gradients:
|
||||
f.type (this->type());
|
||||
fb.type (this->type());
|
||||
f.type(value());
|
||||
fb.type(value());
|
||||
break;
|
||||
|
||||
case task_collect_gradients:
|
||||
if (this->type() != colvarvalue::type_scalar) {
|
||||
if (value().type() != colvarvalue::type_scalar) {
|
||||
cvm::error("Collecting atomic gradients for non-scalar collective variable \""+
|
||||
this->name+"\" is not yet implemented.\n",
|
||||
INPUT_ERROR);
|
||||
@ -1032,8 +1070,8 @@ cvm::real colvar::update()
|
||||
if (cvm::debug())
|
||||
cvm::log("Updating colvar \""+this->name+"\".\n");
|
||||
|
||||
|
||||
// set to zero the applied force
|
||||
f.type(value());
|
||||
f.reset();
|
||||
|
||||
// add the biases' force, which at this point should already have
|
||||
@ -1044,7 +1082,11 @@ cvm::real colvar::update()
|
||||
if (tasks[task_lower_wall] || tasks[task_upper_wall]) {
|
||||
|
||||
// wall force
|
||||
colvarvalue fw (this->type());
|
||||
colvarvalue fw(value());
|
||||
fw.reset();
|
||||
|
||||
if (cvm::debug())
|
||||
cvm::log("Calculating wall forces for colvar \""+this->name+"\".\n");
|
||||
|
||||
// if the two walls are applied concurrently, decide which is the
|
||||
// closer one (on a periodic colvar, both walls may be applicable
|
||||
@ -1148,25 +1190,28 @@ void colvar::communicate_forces()
|
||||
cvm::log("Communicating forces from colvar \""+this->name+"\".\n");
|
||||
|
||||
if (tasks[task_scripted]) {
|
||||
std::vector<colvarvalue> func_grads(cvcs.size());
|
||||
std::vector<cvm::matrix2d<cvm::real> > func_grads;
|
||||
for (i = 0; i < cvcs.size(); i++) {
|
||||
func_grads.push_back(cvm::matrix2d<cvm::real> (x.size(),
|
||||
cvcs[i]->value().size()));
|
||||
}
|
||||
int res = cvm::proxy->run_colvar_gradient_callback(scripted_function, sorted_cvc_values, func_grads);
|
||||
|
||||
if (res != COLVARS_OK) {
|
||||
if (res == COLVARS_NOT_IMPLEMENTED) {
|
||||
cvm::error("Colvar gradient scripts are not implemented.");
|
||||
return;
|
||||
}
|
||||
if (res != COLVARS_OK) {
|
||||
} else {
|
||||
cvm::error("Error running colvar gradient script");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < cvcs.size(); i++) {
|
||||
cvm::increase_depth();
|
||||
// Force is scalar times colvarvalue (scalar or vector)
|
||||
// Note: this can only handle scalar colvars (scalar values of f)
|
||||
// A non-scalar colvar would need the gradient to be expressed
|
||||
// as an order-2 tensor
|
||||
(cvcs[i])->apply_force (f.real_value * func_grads[i]);
|
||||
// cvc force is colvar force times colvar/cvc Jacobian
|
||||
// (vector-matrix product)
|
||||
(cvcs[i])->apply_force(colvarvalue(f.as_vector() * func_grads[i],
|
||||
cvcs[i]->value().type()));
|
||||
cvm::decrease_depth();
|
||||
}
|
||||
} else if (x.type() == colvarvalue::type_scalar) {
|
||||
@ -1235,7 +1280,7 @@ bool colvar::periodic_boundaries() const
|
||||
cvm::real colvar::dist2(colvarvalue const &x1,
|
||||
colvarvalue const &x2) const
|
||||
{
|
||||
if (b_single_cvc) {
|
||||
if (b_homogeneous) {
|
||||
return (cvcs[0])->dist2(x1, x2);
|
||||
} else {
|
||||
return x1.dist2(x2);
|
||||
@ -1245,7 +1290,7 @@ cvm::real colvar::dist2 (colvarvalue const &x1,
|
||||
colvarvalue colvar::dist2_lgrad(colvarvalue const &x1,
|
||||
colvarvalue const &x2) const
|
||||
{
|
||||
if (b_single_cvc) {
|
||||
if (b_homogeneous) {
|
||||
return (cvcs[0])->dist2_lgrad(x1, x2);
|
||||
} else {
|
||||
return x1.dist2_grad(x2);
|
||||
@ -1255,7 +1300,7 @@ colvarvalue colvar::dist2_lgrad (colvarvalue const &x1,
|
||||
colvarvalue colvar::dist2_rgrad(colvarvalue const &x1,
|
||||
colvarvalue const &x2) const
|
||||
{
|
||||
if (b_single_cvc) {
|
||||
if (b_homogeneous) {
|
||||
return (cvcs[0])->dist2_rgrad(x1, x2);
|
||||
} else {
|
||||
return x2.dist2_grad(x1);
|
||||
@ -1264,7 +1309,7 @@ colvarvalue colvar::dist2_rgrad (colvarvalue const &x1,
|
||||
|
||||
void colvar::wrap(colvarvalue &x) const
|
||||
{
|
||||
if (b_single_cvc) {
|
||||
if (b_homogeneous) {
|
||||
(cvcs[0])->wrap(x);
|
||||
}
|
||||
return;
|
||||
@ -1612,7 +1657,7 @@ int colvar::calc_acf()
|
||||
colvar *cfcv = (acf_colvar_name.size() ?
|
||||
cvm::colvar_by_name(acf_colvar_name) :
|
||||
this);
|
||||
if (cfcv->type() != this->type()) {
|
||||
if (colvarvalue::check_types(cfcv->value(), value())) {
|
||||
cvm::error("Error: correlation function between \""+cfcv->name+
|
||||
"\" and \""+this->name+"\" cannot be calculated, "
|
||||
"because their value types are different.\n",
|
||||
@ -1799,7 +1844,7 @@ void colvar::calc_runave()
|
||||
{
|
||||
if (x_history.empty()) {
|
||||
|
||||
runave.type (x.type());
|
||||
runave.type(value().type());
|
||||
runave.reset();
|
||||
|
||||
// first-step operations
|
||||
|
||||
@ -31,9 +31,8 @@
|
||||
///
|
||||
/// Please note that most of its members are \link colvarvalue
|
||||
/// \endlink objects, i.e. they can handle different data types
|
||||
/// together, and must all be set to the same type of colvar::x by
|
||||
/// using the colvarvalue::type() member function before using them
|
||||
/// together in assignments or other operations; this is usually done
|
||||
/// together, and must all be set to the same type of colvar::value()
|
||||
/// before using them together in assignments or other operations; this is usually done
|
||||
/// automatically in the constructor. If you add a new member of
|
||||
/// \link colvarvalue \endlink type, you should also add its
|
||||
/// initialization line in the \link colvar \endlink constructor.
|
||||
@ -45,16 +44,13 @@ public:
|
||||
/// Name
|
||||
std::string name;
|
||||
|
||||
/// Type of value
|
||||
colvarvalue::Type type() const;
|
||||
|
||||
/// \brief Current value (previously obtained from calc() or read_traj())
|
||||
/// \brief Current value (previously set by calc() or by read_traj())
|
||||
colvarvalue const & value() const;
|
||||
|
||||
/// \brief Current actual value (not extended DOF)
|
||||
colvarvalue const & actual_value() const;
|
||||
|
||||
/// \brief Current velocity (previously obtained from calc() or read_traj())
|
||||
/// \brief Current velocity (previously set by calc() or by read_traj())
|
||||
colvarvalue const & velocity() const;
|
||||
|
||||
/// \brief Current system force (previously obtained from calc() or
|
||||
@ -83,9 +79,9 @@ public:
|
||||
/// combination of \link cvc \endlink elements
|
||||
bool b_linear;
|
||||
|
||||
/// \brief True if this \link colvar \endlink is equal to
|
||||
/// its only constituent cvc
|
||||
bool b_single_cvc;
|
||||
/// \brief True if this \link colvar \endlink is a linear
|
||||
/// combination of cvcs with coefficients 1 or -1
|
||||
bool b_homogeneous;
|
||||
|
||||
/// \brief True if all \link cvc \endlink objects are capable
|
||||
/// of calculating inverse gradients
|
||||
@ -190,6 +186,13 @@ protected:
|
||||
/// Value of the colvar
|
||||
colvarvalue x;
|
||||
|
||||
// TODO: implement functionality to treat these
|
||||
// /// Vector of individual values from CVCs
|
||||
// colvarvalue x_cvc;
|
||||
|
||||
// /// Jacobian matrix of individual values from CVCs
|
||||
// colvarvalue dx_cvc;
|
||||
|
||||
/// Cached reported value (x may be manipulated)
|
||||
colvarvalue x_reported;
|
||||
|
||||
@ -479,6 +482,7 @@ public:
|
||||
class distance_z;
|
||||
class distance_xy;
|
||||
class distance_inv;
|
||||
class distance_pairs;
|
||||
class angle;
|
||||
class dihedral;
|
||||
class coordnum;
|
||||
@ -500,6 +504,7 @@ public:
|
||||
// non-scalar components
|
||||
class distance_vec;
|
||||
class distance_dir;
|
||||
class cartesian;
|
||||
class orientation;
|
||||
|
||||
protected:
|
||||
@ -533,11 +538,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
inline colvarvalue::Type colvar::type() const
|
||||
{
|
||||
return x.type();
|
||||
}
|
||||
|
||||
|
||||
inline colvarvalue const & colvar::value() const
|
||||
{
|
||||
@ -570,6 +570,7 @@ inline void colvar::add_bias_force (colvarvalue const &force)
|
||||
|
||||
|
||||
inline void colvar::reset_bias_force() {
|
||||
fb.type(value());
|
||||
fb.reset();
|
||||
}
|
||||
|
||||
|
||||
@ -83,14 +83,16 @@ colvarbias::~colvarbias()
|
||||
|
||||
void colvarbias::add_colvar(std::string const &cv_name)
|
||||
{
|
||||
if (colvar *cvp = cvm::colvar_by_name (cv_name)) {
|
||||
cvp->enable (colvar::task_gradients);
|
||||
if (colvar *cv = cvm::colvar_by_name(cv_name)) {
|
||||
cv->enable(colvar::task_gradients);
|
||||
if (cvm::debug())
|
||||
cvm::log("Applying this bias to collective variable \""+
|
||||
cvp->name+"\".\n");
|
||||
colvars.push_back (cvp);
|
||||
colvar_forces.push_back (colvarvalue (cvp->type()));
|
||||
cvp->biases.push_back (this); // add back-reference to this bias to colvar
|
||||
cv->name+"\".\n");
|
||||
colvars.push_back(cv);
|
||||
colvar_forces.push_back(colvarvalue());
|
||||
colvar_forces.back().type(cv->value()); // make sure each forces is initialized to zero
|
||||
colvar_forces.back().reset();
|
||||
cv->biases.push_back(this); // add back-reference to this bias to colvar
|
||||
} else {
|
||||
cvm::error("Error: cannot find a colvar named \""+
|
||||
cv_name+"\".\n");
|
||||
@ -103,8 +105,7 @@ void colvarbias::communicate_forces()
|
||||
for (size_t i = 0; i < colvars.size(); i++) {
|
||||
if (cvm::debug()) {
|
||||
cvm::log("Communicating a force to colvar \""+
|
||||
colvars[i]->name+"\", of type \""+
|
||||
colvarvalue::type_desc[colvars[i]->type()]+"\".\n");
|
||||
colvars[i]->name+"\".\n");
|
||||
}
|
||||
colvars[i]->add_bias_force(colvar_forces[i]);
|
||||
}
|
||||
@ -128,19 +129,23 @@ cvm::real colvarbias::energy_difference(std::string const &conf)
|
||||
int colvarbias::bin_num()
|
||||
{
|
||||
cvm::error("Error: bin_num() not implemented.\n");
|
||||
return -1;
|
||||
return COLVARS_NOT_IMPLEMENTED;
|
||||
}
|
||||
int colvarbias::current_bin()
|
||||
{
|
||||
cvm::error("Error: current_bin() not implemented.\n");
|
||||
return -1;
|
||||
return COLVARS_NOT_IMPLEMENTED;
|
||||
}
|
||||
int colvarbias::bin_count(int bin_index)
|
||||
{
|
||||
cvm::error("Error: bin_count() not implemented.\n");
|
||||
return -1;
|
||||
return COLVARS_NOT_IMPLEMENTED;
|
||||
}
|
||||
int colvarbias::replica_share()
|
||||
{
|
||||
cvm::error("Error: replica_share() not implemented.\n");
|
||||
return COLVARS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
std::ostream & colvarbias::write_traj_label(std::ostream &os)
|
||||
{
|
||||
|
||||
@ -36,7 +36,7 @@ public:
|
||||
//// Give the count at a given bin index.
|
||||
virtual int bin_count(int bin_index);
|
||||
//// Share information between replicas, whatever it may be.
|
||||
virtual void replica_share() {};
|
||||
virtual int replica_share();
|
||||
|
||||
/// Perform analysis tasks
|
||||
virtual inline void analyse() {}
|
||||
|
||||
@ -64,7 +64,7 @@ colvarbias_abf::colvarbias_abf (std::string const &conf, char const *key)
|
||||
|
||||
for (size_t i = 0; i < colvars.size(); i++) {
|
||||
|
||||
if (colvars[i]->type() != colvarvalue::type_scalar) {
|
||||
if (colvars[i]->value().type() != colvarvalue::type_scalar) {
|
||||
cvm::error("Error: ABF bias can only use scalar-type variables.\n");
|
||||
}
|
||||
|
||||
@ -282,17 +282,17 @@ cvm::real colvarbias_abf::update()
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
void colvarbias_abf::replica_share () {
|
||||
int colvarbias_abf::replica_share() {
|
||||
int p;
|
||||
|
||||
if ( !cvm::replica_enabled() ) {
|
||||
cvm::error("Error: shared ABF: No replicas.\n");
|
||||
return;
|
||||
return COLVARS_ERROR;
|
||||
}
|
||||
// We must have stored the last_gradients and last_samples.
|
||||
if (shared_last_step < 0 ) {
|
||||
cvm::error("Error: shared ABF: Tried to apply shared ABF before any sampling had occurred.\n");
|
||||
return;
|
||||
return COLVARS_ERROR;
|
||||
}
|
||||
|
||||
// Share gradients for shared ABF.
|
||||
@ -355,6 +355,8 @@ void colvarbias_abf::replica_share () {
|
||||
last_gradients->copy_grid(*gradients);
|
||||
last_samples->copy_grid(*samples);
|
||||
shared_last_step = cvm::step_absolute();
|
||||
|
||||
return COLVARS_OK;
|
||||
}
|
||||
|
||||
void colvarbias_abf::write_gradients_samples(const std::string &prefix, bool append)
|
||||
@ -546,7 +548,7 @@ std::istream & colvarbias_abf::read_restart (std::istream& is)
|
||||
|
||||
colvarbias_histogram::colvarbias_histogram(std::string const &conf, char const *key)
|
||||
: colvarbias(conf, key),
|
||||
grid (NULL)
|
||||
grid(NULL), out_name("")
|
||||
{
|
||||
get_keyval(conf, "outputfreq", output_freq, cvm::restart_out_freq);
|
||||
|
||||
@ -557,9 +559,6 @@ colvarbias_histogram::colvarbias_histogram (std::string const &conf, char const
|
||||
grid = new colvar_grid_count (colvars);
|
||||
bin.assign(colvars.size(), 0);
|
||||
|
||||
out_name = cvm::output_prefix + "." + this->name + ".dat";
|
||||
cvm::log ("Histogram will be written to file " + out_name);
|
||||
|
||||
cvm::log("Finished histogram setup.\n");
|
||||
}
|
||||
|
||||
@ -582,6 +581,14 @@ cvm::real colvarbias_histogram::update()
|
||||
{
|
||||
if (cvm::debug()) cvm::log("Updating Grid bias " + this->name);
|
||||
|
||||
// At the first timestep, we need to assign out_name since
|
||||
// output_prefix is unset during the constructor
|
||||
|
||||
if (cvm::step_relative() == 0) {
|
||||
out_name = cvm::output_prefix + "." + this->name + ".dat";
|
||||
cvm::log("Histogram " + this->name + " will be written to file \"" + out_name + "\"");
|
||||
}
|
||||
|
||||
for (size_t i=0; i<colvars.size(); i++) {
|
||||
bin[i] = grid->current_bin_scalar(i);
|
||||
}
|
||||
|
||||
@ -64,7 +64,7 @@ private:
|
||||
size_t shared_freq;
|
||||
int shared_last_step;
|
||||
// Share between replicas -- may be called independently of update
|
||||
virtual void replica_share();
|
||||
virtual int replica_share();
|
||||
|
||||
// Store the last set for shared ABF
|
||||
colvar_grid_gradient *last_gradients;
|
||||
|
||||
@ -1,8 +1,20 @@
|
||||
// -*- c++ -*-
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "colvarmodule.h"
|
||||
#include "colvarbias_alb.h"
|
||||
#include "colvarbias.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#if _MSC_VER <= 1700
|
||||
#define copysign(A,B) _copysign(A,B)
|
||||
double fmax(double A, double B) { return ( A > B ? A : B ); }
|
||||
double fmin(double A, double B) { return ( A < B ? A : B ); }
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Note about nomenclature. Force constant is called a coupling
|
||||
* constant here to emphasize its changing in the code. Outwards,
|
||||
@ -31,7 +43,7 @@ colvarbias_alb::colvarbias_alb(std::string const &conf, char const *key) :
|
||||
|
||||
|
||||
for (i = 0; i < colvars.size(); i++) {
|
||||
colvar_centers[i].type (colvars[i]->type());
|
||||
colvar_centers[i].type(colvars[i]->value());
|
||||
//zero moments
|
||||
means[i] = ssd[i] = 0;
|
||||
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
// -*- c++ -*-
|
||||
|
||||
#ifndef COLVARBIAS_ALB_H
|
||||
#define COLVARBIAS_ALB_H
|
||||
|
||||
|
||||
@ -646,7 +646,7 @@ void colvarbias_meta::calc_hills (colvarbias_meta::hill_iter h_first,
|
||||
{
|
||||
std::vector<colvarvalue> curr_values(colvars.size());
|
||||
for (size_t i = 0; i < colvars.size(); i++) {
|
||||
curr_values[i].type (colvars[i]->type());
|
||||
curr_values[i].type(colvars[i]->value());
|
||||
}
|
||||
|
||||
if (colvar_values.size()) {
|
||||
@ -689,15 +689,14 @@ void colvarbias_meta::calc_hills_force (size_t const &i,
|
||||
std::vector<colvarvalue> const &values)
|
||||
{
|
||||
// Retrieve the value of the colvar
|
||||
colvarvalue x (values.size() ? values[i].type() : colvars[i]->type());
|
||||
x = (values.size() ? values[i] : colvars[i]->value());
|
||||
colvarvalue const x(values.size() ? values[i] : colvars[i]->value());
|
||||
|
||||
// do the type check only once (all colvarvalues in the hills series
|
||||
// were already saved with their types matching those in the
|
||||
// colvars)
|
||||
|
||||
hill_iter h;
|
||||
switch (colvars[i]->type()) {
|
||||
switch (colvars[i]->value().type()) {
|
||||
|
||||
case colvarvalue::type_scalar:
|
||||
for (h = h_first; h != h_last; h++) {
|
||||
@ -710,9 +709,9 @@ void colvarbias_meta::calc_hills_force (size_t const &i,
|
||||
}
|
||||
break;
|
||||
|
||||
case colvarvalue::type_vector:
|
||||
case colvarvalue::type_unitvector:
|
||||
case colvarvalue::type_unitvectorderiv:
|
||||
case colvarvalue::type_3vector:
|
||||
case colvarvalue::type_unit3vector:
|
||||
case colvarvalue::type_unit3vectorderiv:
|
||||
for (h = h_first; h != h_last; h++) {
|
||||
if (h->value() == 0.0) continue;
|
||||
colvarvalue const ¢er = h->centers[i];
|
||||
@ -735,8 +734,18 @@ void colvarbias_meta::calc_hills_force (size_t const &i,
|
||||
}
|
||||
break;
|
||||
|
||||
case colvarvalue::type_vector:
|
||||
for (h = h_first; h != h_last; h++) {
|
||||
if (h->value() == 0.0) continue;
|
||||
colvarvalue const ¢er = h->centers[i];
|
||||
cvm::real const half_width = 0.5 * h->widths[i];
|
||||
forces[i].vector1d_value +=
|
||||
( h->weight() * h->value() * (0.5 / (half_width*half_width)) *
|
||||
(colvars[i]->dist2_lgrad(x, center)).vector1d_value );
|
||||
}
|
||||
break;
|
||||
|
||||
case colvarvalue::type_notset:
|
||||
case colvarvalue::type_all:
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1423,7 +1432,7 @@ std::istream & colvarbias_meta::read_hill (std::istream &is)
|
||||
|
||||
std::vector<colvarvalue> h_centers(colvars.size());
|
||||
for (size_t i = 0; i < colvars.size(); i++) {
|
||||
h_centers[i].type ((colvars[i]->value()).type());
|
||||
h_centers[i].type(colvars[i]->value());
|
||||
}
|
||||
{
|
||||
// it is safer to read colvarvalue objects one at a time;
|
||||
@ -1732,3 +1741,5 @@ std::ostream & operator << (std::ostream &os, colvarbias_meta::hill const &h)
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -280,7 +280,7 @@ public:
|
||||
replica(replica_in)
|
||||
{
|
||||
for (size_t i = 0; i < cv.size(); i++) {
|
||||
centers[i].type (cv[i]->type());
|
||||
centers[i].type(cv[i]->value());
|
||||
centers[i] = cv[i]->value();
|
||||
widths[i] = cv[i]->width * hill_width;
|
||||
}
|
||||
|
||||
@ -13,15 +13,25 @@ colvarbias_restraint::colvarbias_restraint (std::string const &conf,
|
||||
{
|
||||
get_keyval(conf, "forceConstant", force_k, 1.0);
|
||||
|
||||
{
|
||||
// get the initial restraint centers
|
||||
colvar_centers.resize(colvars.size());
|
||||
colvar_centers_raw.resize(colvars.size());
|
||||
for (size_t i = 0; i < colvars.size(); i++) {
|
||||
colvar_centers[i].type (colvars[i]->type());
|
||||
colvar_centers_raw[i].type (colvars[i]->type());
|
||||
size_t i;
|
||||
for (i = 0; i < colvars.size(); i++) {
|
||||
colvar_centers[i].type(colvars[i]->value());
|
||||
colvar_centers_raw[i].type(colvars[i]->value());
|
||||
if (cvm::debug()) {
|
||||
cvm::log("colvarbias_restraint: center size = "+
|
||||
cvm::to_str(colvar_centers[i].vector1d_value.size())+"\n");
|
||||
}
|
||||
}
|
||||
if (get_keyval(conf, "centers", colvar_centers, colvar_centers)) {
|
||||
for (size_t i = 0; i < colvars.size(); i++) {
|
||||
for (i = 0; i < colvars.size(); i++) {
|
||||
if (cvm::debug()) {
|
||||
cvm::log("colvarbias_restraint: parsing initial centers, i = "+cvm::to_str(i)+".\n");
|
||||
}
|
||||
|
||||
colvar_centers[i].apply_constraints();
|
||||
colvar_centers_raw[i] = colvar_centers[i];
|
||||
}
|
||||
@ -30,19 +40,28 @@ colvarbias_restraint::colvarbias_restraint (std::string const &conf,
|
||||
cvm::error("Error: must define the initial centers of the restraints.\n");
|
||||
}
|
||||
|
||||
if (colvar_centers.size() != colvars.size())
|
||||
if (colvar_centers.size() != colvars.size()) {
|
||||
cvm::error("Error: number of centers does not match "
|
||||
"that of collective variables.\n");
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
if (cvm::debug()) {
|
||||
cvm::log("colvarbias_restraint: parsing target centers.\n");
|
||||
}
|
||||
|
||||
size_t i;
|
||||
if (get_keyval(conf, "targetCenters", target_centers, colvar_centers)) {
|
||||
b_chg_centers = true;
|
||||
for (size_t i = 0; i < target_centers.size(); i++) {
|
||||
for (i = 0; i < target_centers.size(); i++) {
|
||||
target_centers[i].apply_constraints();
|
||||
}
|
||||
} else {
|
||||
b_chg_centers = false;
|
||||
target_centers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
if (get_keyval(conf, "targetForceConstant", target_force_k, 0.0)) {
|
||||
if (b_chg_centers)
|
||||
@ -110,7 +129,9 @@ void colvarbias_restraint::change_configuration (std::string const &conf)
|
||||
get_keyval(conf, "forceConstant", force_k, force_k);
|
||||
if (get_keyval(conf, "centers", colvar_centers, colvar_centers)) {
|
||||
for (size_t i = 0; i < colvars.size(); i++) {
|
||||
colvar_centers[i].type(colvars[i]->value());
|
||||
colvar_centers[i].apply_constraints();
|
||||
colvar_centers_raw[i].type(colvars[i]->value());
|
||||
colvar_centers_raw[i] = colvar_centers[i];
|
||||
}
|
||||
}
|
||||
@ -128,10 +149,11 @@ cvm::real colvarbias_restraint::energy_difference (std::string const &conf)
|
||||
alt_colvar_centers.resize(colvars.size());
|
||||
size_t i;
|
||||
for (i = 0; i < colvars.size(); i++) {
|
||||
alt_colvar_centers[i].type (colvars[i]->type());
|
||||
alt_colvar_centers[i].type(colvars[i]->value());
|
||||
}
|
||||
if (get_keyval(conf, "centers", alt_colvar_centers, colvar_centers)) {
|
||||
for (i = 0; i < colvars.size(); i++) {
|
||||
colvar_centers[i].type(colvars[i]->value());
|
||||
colvar_centers[i].apply_constraints();
|
||||
}
|
||||
}
|
||||
@ -177,7 +199,7 @@ cvm::real colvarbias_restraint::update()
|
||||
// if we are restarting a staged calculation)
|
||||
centers_incr.resize(colvars.size());
|
||||
for (size_t i = 0; i < colvars.size(); i++) {
|
||||
centers_incr[i].type (colvars[i]->type());
|
||||
centers_incr[i].type(colvars[i]->value());
|
||||
centers_incr[i] = (target_centers[i] - colvar_centers_raw[i]) /
|
||||
cvm::real( target_nstages ? (target_nstages - stage) :
|
||||
(target_nsteps - cvm::step_absolute()));
|
||||
@ -285,6 +307,7 @@ cvm::real colvarbias_restraint::update()
|
||||
|
||||
// Force and energy calculation
|
||||
for (size_t i = 0; i < colvars.size(); i++) {
|
||||
colvar_forces[i].type(colvars[i]->value());
|
||||
colvar_forces[i] = -1.0 * restraint_force(restraint_convert_k(force_k, colvars[i]->width),
|
||||
colvars[i],
|
||||
colvar_centers[i]);
|
||||
|
||||
@ -90,7 +90,8 @@ void colvar::cvc::debug_gradients (cvm::atom_group &group)
|
||||
cvm::rotation const rot_0 = group.rot;
|
||||
cvm::rotation const rot_inv = group.rot.inverse();
|
||||
|
||||
cvm::real const x_0 = x.real_value;
|
||||
cvm::real x_0 = x.real_value;
|
||||
if ((x.type() == colvarvalue::type_vector) && (x.size() == 1)) x_0 = x[0];
|
||||
|
||||
// cvm::log("gradients = "+cvm::to_str (gradients)+"\n");
|
||||
|
||||
@ -130,7 +131,8 @@ void colvar::cvc::debug_gradients (cvm::atom_group &group)
|
||||
group.calc_apply_roto_translation();
|
||||
}
|
||||
calc_value();
|
||||
cvm::real const x_1 = x.real_value;
|
||||
cvm::real x_1 = x.real_value;
|
||||
if ((x.type() == colvarvalue::type_vector) && (x.size() == 1)) x_1 = x[0];
|
||||
cvm::log("Atom "+cvm::to_str(ia)+", component "+cvm::to_str(id)+":\n");
|
||||
cvm::log("dx(actual) = "+cvm::to_str(x_1 - x_0,
|
||||
21, 14)+"\n");
|
||||
|
||||
@ -79,10 +79,6 @@ public:
|
||||
/// this variable definition should be set within the constructor.
|
||||
std::string function_type;
|
||||
|
||||
/// \brief Type of \link colvarvalue \endlink that this cvc
|
||||
/// provides
|
||||
colvarvalue::Type type() const;
|
||||
|
||||
/// \brief Coefficient in the polynomial combination (default: 1.0)
|
||||
cvm::real sup_coeff;
|
||||
/// \brief Exponent in the polynomial combination (default: 1)
|
||||
@ -153,17 +149,17 @@ public:
|
||||
|
||||
|
||||
/// \brief Return the previously calculated value
|
||||
virtual colvarvalue value() const;
|
||||
virtual colvarvalue const & value() const;
|
||||
|
||||
/// \brief Return const pointer to the previously calculated value
|
||||
virtual const colvarvalue *p_value() const;
|
||||
// /// \brief Return const pointer to the previously calculated value
|
||||
// virtual const colvarvalue *p_value() const;
|
||||
|
||||
/// \brief Return the previously calculated system force
|
||||
virtual colvarvalue system_force() const;
|
||||
virtual colvarvalue const & system_force() const;
|
||||
|
||||
/// \brief Return the previously calculated divergence of the
|
||||
/// inverse atomic gradients
|
||||
virtual colvarvalue Jacobian_derivative() const;
|
||||
virtual colvarvalue const & Jacobian_derivative() const;
|
||||
|
||||
/// \brief Apply the collective variable force, by communicating the
|
||||
/// atomic forces to the simulation program (\b Note: the \link ft
|
||||
@ -248,27 +244,22 @@ protected:
|
||||
|
||||
|
||||
|
||||
inline colvarvalue::Type colvar::cvc::type() const
|
||||
{
|
||||
return x.type();
|
||||
}
|
||||
|
||||
inline colvarvalue colvar::cvc::value() const
|
||||
inline colvarvalue const & colvar::cvc::value() const
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
inline const colvarvalue * colvar::cvc::p_value() const
|
||||
{
|
||||
return &x;
|
||||
}
|
||||
// inline const colvarvalue * colvar::cvc::p_value() const
|
||||
// {
|
||||
// return &x;
|
||||
// }
|
||||
|
||||
inline colvarvalue colvar::cvc::system_force() const
|
||||
inline colvarvalue const & colvar::cvc::system_force() const
|
||||
{
|
||||
return ft;
|
||||
}
|
||||
|
||||
inline colvarvalue colvar::cvc::Jacobian_derivative() const
|
||||
inline colvarvalue const & colvar::cvc::Jacobian_derivative() const
|
||||
{
|
||||
return jd;
|
||||
}
|
||||
@ -340,7 +331,7 @@ public:
|
||||
|
||||
|
||||
// \brief Colvar component: distance vector between centers of mass
|
||||
// of two groups (\link colvarvalue::type_vector \endlink type,
|
||||
// of two groups (\link colvarvalue::type_3vector \endlink type,
|
||||
// range (-*:*)x(-*:*)x(-*:*))
|
||||
class colvar::distance_vec
|
||||
: public colvar::distance
|
||||
@ -365,7 +356,7 @@ public:
|
||||
|
||||
|
||||
/// \brief Colvar component: distance unit vector (direction) between
|
||||
/// centers of mass of two groups (colvarvalue::type_unitvector type,
|
||||
/// centers of mass of two groups (colvarvalue::type_unit3vector type,
|
||||
/// range [-1:1]x[-1:1]x[-1:1])
|
||||
class colvar::distance_dir
|
||||
: public colvar::distance
|
||||
@ -483,6 +474,34 @@ public:
|
||||
};
|
||||
|
||||
|
||||
/// \brief Colvar component: N1xN2 vector of pairwise distances
|
||||
/// (colvarvalue::type_vector type, range (0:*) for each component)
|
||||
class colvar::distance_pairs
|
||||
: public colvar::cvc
|
||||
{
|
||||
protected:
|
||||
/// First atom group
|
||||
cvm::atom_group group1;
|
||||
/// Second atom group
|
||||
cvm::atom_group group2;
|
||||
/// Use absolute positions, ignoring PBCs when present
|
||||
bool b_no_PBC;
|
||||
public:
|
||||
distance_pairs(std::string const &conf);
|
||||
distance_pairs();
|
||||
virtual inline ~distance_pairs() {}
|
||||
virtual void calc_value();
|
||||
virtual void calc_gradients();
|
||||
virtual void apply_force(colvarvalue const &force);
|
||||
virtual cvm::real dist2(colvarvalue const &x1,
|
||||
colvarvalue const &x2) const;
|
||||
virtual colvarvalue dist2_lgrad(colvarvalue const &x1,
|
||||
colvarvalue const &x2) const;
|
||||
virtual colvarvalue dist2_rgrad(colvarvalue const &x1,
|
||||
colvarvalue const &x2) const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/// \brief Colvar component: Radius of gyration of an atom group
|
||||
/// (colvarvalue::type_scalar type, range [0:*))
|
||||
@ -1114,6 +1133,23 @@ public:
|
||||
};
|
||||
|
||||
|
||||
// \brief Colvar component: flat vector of Cartesian coordinates
|
||||
// Mostly useful to compute scripted colvar values
|
||||
class colvar::cartesian
|
||||
: public colvar::cvc
|
||||
{
|
||||
protected:
|
||||
/// Atom group
|
||||
cvm::atom_group atoms;
|
||||
public:
|
||||
cartesian(std::string const &conf);
|
||||
cartesian();
|
||||
virtual inline ~cartesian() {}
|
||||
virtual void calc_value();
|
||||
virtual void calc_gradients();
|
||||
virtual void apply_force(colvarvalue const &force);
|
||||
};
|
||||
|
||||
|
||||
// metrics functions for cvc implementations
|
||||
|
||||
@ -1326,15 +1362,34 @@ inline cvm::real colvar::distance_dir::dist2 (colvarvalue const &x1,
|
||||
inline colvarvalue colvar::distance_dir::dist2_lgrad(colvarvalue const &x1,
|
||||
colvarvalue const &x2) const
|
||||
{
|
||||
return colvarvalue ((x1.rvector_value - x2.rvector_value), colvarvalue::type_unitvector);
|
||||
return colvarvalue((x1.rvector_value - x2.rvector_value), colvarvalue::type_unit3vector);
|
||||
}
|
||||
|
||||
inline colvarvalue colvar::distance_dir::dist2_rgrad(colvarvalue const &x1,
|
||||
colvarvalue const &x2) const
|
||||
{
|
||||
return colvarvalue ((x2.rvector_value - x1.rvector_value), colvarvalue::type_unitvector);
|
||||
return colvarvalue((x2.rvector_value - x1.rvector_value), colvarvalue::type_unit3vector);
|
||||
}
|
||||
|
||||
inline cvm::real colvar::distance_pairs::dist2(colvarvalue const &x1,
|
||||
colvarvalue const &x2) const
|
||||
{
|
||||
return (x1.vector1d_value - x2.vector1d_value).norm2();
|
||||
}
|
||||
|
||||
inline colvarvalue colvar::distance_pairs::dist2_lgrad(colvarvalue const &x1,
|
||||
colvarvalue const &x2) const
|
||||
{
|
||||
return colvarvalue((x1.vector1d_value - x2.vector1d_value), colvarvalue::type_vector);
|
||||
}
|
||||
|
||||
inline colvarvalue colvar::distance_pairs::dist2_rgrad(colvarvalue const &x1,
|
||||
colvarvalue const &x2) const
|
||||
{
|
||||
return colvarvalue((x2.vector1d_value - x1.vector1d_value), colvarvalue::type_vector);
|
||||
}
|
||||
|
||||
|
||||
// distance between quaternions
|
||||
|
||||
inline cvm::real colvar::orientation::dist2(colvarvalue const &x1,
|
||||
|
||||
@ -95,14 +95,14 @@ colvar::distance_vec::distance_vec (std::string const &conf)
|
||||
: distance(conf)
|
||||
{
|
||||
function_type = "distance_vec";
|
||||
x.type (colvarvalue::type_vector);
|
||||
x.type(colvarvalue::type_3vector);
|
||||
}
|
||||
|
||||
colvar::distance_vec::distance_vec()
|
||||
: distance()
|
||||
{
|
||||
function_type = "distance_vec";
|
||||
x.type (colvarvalue::type_vector);
|
||||
x.type(colvarvalue::type_3vector);
|
||||
}
|
||||
|
||||
void colvar::distance_vec::calc_value()
|
||||
@ -384,7 +384,7 @@ colvar::distance_dir::distance_dir (std::string const &conf)
|
||||
: distance(conf)
|
||||
{
|
||||
function_type = "distance_dir";
|
||||
x.type (colvarvalue::type_unitvector);
|
||||
x.type(colvarvalue::type_unit3vector);
|
||||
}
|
||||
|
||||
|
||||
@ -392,7 +392,7 @@ colvar::distance_dir::distance_dir()
|
||||
: distance()
|
||||
{
|
||||
function_type = "distance_dir";
|
||||
x.type (colvarvalue::type_unitvector);
|
||||
x.type(colvarvalue::type_unit3vector);
|
||||
}
|
||||
|
||||
|
||||
@ -527,6 +527,99 @@ void colvar::distance_inv::apply_force (colvarvalue const &force)
|
||||
|
||||
|
||||
|
||||
colvar::distance_pairs::distance_pairs(std::string const &conf)
|
||||
: cvc(conf)
|
||||
{
|
||||
function_type = "distance_pairs";
|
||||
b_inverse_gradients = false;
|
||||
b_Jacobian_derivative = false;
|
||||
|
||||
if (get_keyval(conf, "forceNoPBC", b_no_PBC, false)) {
|
||||
cvm::log("Computing distance using absolute positions (not minimal-image)");
|
||||
}
|
||||
|
||||
parse_group(conf, "group1", group1);
|
||||
atom_groups.push_back(&group1);
|
||||
|
||||
parse_group(conf, "group2", group2);
|
||||
atom_groups.push_back(&group2);
|
||||
|
||||
x.type(colvarvalue::type_vector);
|
||||
x.vector1d_value.resize(group1.size() * group2.size());
|
||||
}
|
||||
|
||||
|
||||
colvar::distance_pairs::distance_pairs()
|
||||
{
|
||||
function_type = "distance_pairs";
|
||||
b_inverse_gradients = false;
|
||||
b_Jacobian_derivative = false;
|
||||
x.type(colvarvalue::type_vector);
|
||||
}
|
||||
|
||||
|
||||
void colvar::distance_pairs::calc_value()
|
||||
{
|
||||
x.vector1d_value.resize(group1.size() * group2.size());
|
||||
|
||||
if (b_no_PBC) {
|
||||
size_t i1, i2;
|
||||
for (i1 = 0; i1 < group1.size(); i1++) {
|
||||
for (i2 = 0; i2 < group2.size(); i2++) {
|
||||
cvm::rvector const dv = group2[i2].pos - group1[i1].pos;
|
||||
cvm::real const d = dv.norm();
|
||||
x.vector1d_value[i1*group2.size() + i2] = d;
|
||||
group1[i1].grad = -1.0 * dv.unit();
|
||||
group2[i2].grad = dv.unit();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
size_t i1, i2;
|
||||
for (i1 = 0; i1 < group1.size(); i1++) {
|
||||
for (i2 = 0; i2 < group2.size(); i2++) {
|
||||
cvm::rvector const dv = cvm::position_distance(group1[i1].pos, group2[i2].pos);
|
||||
cvm::real const d = dv.norm();
|
||||
x.vector1d_value[i1*group2.size() + i2] = d;
|
||||
group1[i1].grad = -1.0 * dv.unit();
|
||||
group2[i2].grad = dv.unit();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void colvar::distance_pairs::calc_gradients()
|
||||
{
|
||||
// will be calculated on the fly in apply_force()
|
||||
if (b_debug_gradients) {
|
||||
cvm::log("Debugging gradients:\n");
|
||||
debug_gradients(group1);
|
||||
}
|
||||
}
|
||||
|
||||
void colvar::distance_pairs::apply_force(colvarvalue const &force)
|
||||
{
|
||||
if (b_no_PBC) {
|
||||
size_t i1, i2;
|
||||
for (i1 = 0; i1 < group1.size(); i1++) {
|
||||
for (i2 = 0; i2 < group2.size(); i2++) {
|
||||
cvm::rvector const dv = group2[i2].pos - group1[i1].pos;
|
||||
group1[i1].apply_force(force[i1*group2.size() + i2] * (-1.0) * dv.unit());
|
||||
group2[i2].apply_force(force[i1*group2.size() + i2] * dv.unit());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
size_t i1, i2;
|
||||
for (i1 = 0; i1 < group1.size(); i1++) {
|
||||
for (i2 = 0; i2 < group2.size(); i2++) {
|
||||
cvm::rvector const dv = cvm::position_distance(group1[i1].pos, group2[i2].pos);
|
||||
group1[i1].apply_force(force[i1*group2.size() + i2] * (-1.0) * dv.unit());
|
||||
group2[i2].apply_force(force[i1*group2.size() + i2] * dv.unit());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
colvar::gyration::gyration(std::string const &conf)
|
||||
: cvc(conf)
|
||||
{
|
||||
@ -867,13 +960,13 @@ void colvar::rmsd::calc_Jacobian_derivative()
|
||||
if (atoms.b_rotate) {
|
||||
|
||||
// gradient of the rotation matrix
|
||||
cvm::matrix2d <cvm::rvector, 3, 3> grad_rot_mat;
|
||||
cvm::matrix2d<cvm::rvector> grad_rot_mat(3, 3);
|
||||
// gradients of products of 2 quaternion components
|
||||
cvm::rvector g11, g22, g33, g01, g02, g03, g12, g13, g23;
|
||||
for (size_t ia = 0; ia < atoms.size(); ia++) {
|
||||
|
||||
// Gradient of optimal quaternion wrt current Cartesian position
|
||||
cvm::vector1d< cvm::rvector, 4 > &dq = atoms.rot.dQ0_1[ia];
|
||||
cvm::vector1d<cvm::rvector> &dq = atoms.rot.dQ0_1[ia];
|
||||
|
||||
g11 = 2.0 * (atoms.rot.q)[1]*dq[1];
|
||||
g22 = 2.0 * (atoms.rot.q)[2]*dq[2];
|
||||
@ -1143,7 +1236,7 @@ void colvar::eigenvector::calc_force_invgrads()
|
||||
void colvar::eigenvector::calc_Jacobian_derivative()
|
||||
{
|
||||
// gradient of the rotation matrix
|
||||
cvm::matrix2d <cvm::rvector, 3, 3> grad_rot_mat;
|
||||
cvm::matrix2d<cvm::rvector> grad_rot_mat(3, 3);
|
||||
cvm::quaternion &quat0 = atoms.rot.q;
|
||||
|
||||
// gradients of products of 2 quaternion components
|
||||
@ -1156,7 +1249,7 @@ void colvar::eigenvector::calc_Jacobian_derivative()
|
||||
// Gradient of optimal quaternion wrt current Cartesian position
|
||||
// trick: d(R^-1)/dx = d(R^t)/dx = (dR/dx)^t
|
||||
// we can just transpose the derivatives of the direct matrix
|
||||
cvm::vector1d< cvm::rvector, 4 > &dq_1 = atoms.rot.dQ0_1[ia];
|
||||
cvm::vector1d<cvm::rvector> &dq_1 = atoms.rot.dQ0_1[ia];
|
||||
|
||||
g11 = 2.0 * quat0[1]*dq_1[1];
|
||||
g22 = 2.0 * quat0[2]*dq_1[2];
|
||||
@ -1191,5 +1284,51 @@ void colvar::eigenvector::calc_Jacobian_derivative()
|
||||
}
|
||||
|
||||
|
||||
colvar::cartesian::cartesian(std::string const &conf)
|
||||
: cvc(conf)
|
||||
{
|
||||
b_inverse_gradients = false;
|
||||
b_Jacobian_derivative = false;
|
||||
function_type = "cartesian";
|
||||
|
||||
parse_group(conf, "atoms", atoms);
|
||||
atom_groups.push_back(&atoms);
|
||||
|
||||
x.type(colvarvalue::type_vector);
|
||||
x.vector1d_value.resize(atoms.size() * 3);
|
||||
}
|
||||
|
||||
|
||||
void colvar::cartesian::calc_value()
|
||||
{
|
||||
int ia, j;
|
||||
for (ia = 0; ia < atoms.size(); ia++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
x.vector1d_value[3*ia + j] = atoms[ia].pos[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void colvar::cartesian::calc_gradients()
|
||||
{
|
||||
// we're not using the "grad" member of each
|
||||
// atom object, because it only can represent the gradient of a
|
||||
// scalar colvar
|
||||
}
|
||||
|
||||
|
||||
void colvar::cartesian::apply_force(colvarvalue const &force)
|
||||
{
|
||||
int ia, j;
|
||||
if (!atoms.noforce) {
|
||||
cvm::rvector f;
|
||||
for (ia = 0; ia < atoms.size(); ia++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
f[j] = force.vector1d_value[3*ia + j];
|
||||
}
|
||||
atoms[ia].apply_force(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -193,25 +193,3 @@ void colvar_grid_gradient::write_1D_integral (std::ostream &os)
|
||||
|
||||
|
||||
|
||||
|
||||
// quaternion_grid::quaternion_grid (std::vector<colvar *> const &cv_i,
|
||||
// std::vector<std::string> const &grid_str)
|
||||
// {
|
||||
// cv = cv_i;
|
||||
|
||||
// std::istringstream is (grid_str[0]);
|
||||
// is >> grid_size;
|
||||
|
||||
// min.assign (3, -1.0);
|
||||
// max.assign (3, 1.0);
|
||||
// np.assign (3, grid_size);
|
||||
// dx.assign (3, 2.0/(cvm::real (grid_size)));
|
||||
|
||||
// // assumes a uniform grid in the three directions; change
|
||||
// // get_value() if you want to use different sizes
|
||||
// cvm::log ("Allocating quaternion grid ("+cvm::to_str (np.size())+" dimensional)...");
|
||||
// data.create (np, 0.0);
|
||||
// cvm::log ("done.\n");
|
||||
// if (cvm::debug()) cvm::log ("Grid size = "+data.size());
|
||||
// }
|
||||
|
||||
|
||||
@ -30,7 +30,7 @@ protected:
|
||||
std::vector<int> nxc;
|
||||
|
||||
/// \brief Multiplicity of each datum (allow the binning of
|
||||
/// non-scalar types)
|
||||
/// non-scalar types such as atomic gradients)
|
||||
size_t mult;
|
||||
|
||||
/// Total number of grid points
|
||||
@ -223,7 +223,7 @@ public:
|
||||
|
||||
for (size_t i = 0; i < cv.size(); i++) {
|
||||
|
||||
if (cv[i]->type() != colvarvalue::type_scalar) {
|
||||
if (cv[i]->value().type() != colvarvalue::type_scalar) {
|
||||
cvm::error("Colvar grids can only be automatically "
|
||||
"constructed for scalar variables. "
|
||||
"ABF and histogram can not be used; metadynamics "
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
/// -*- c++ -*-
|
||||
|
||||
#include <sstream>
|
||||
#include <string.h>
|
||||
|
||||
#include "colvarmodule.h"
|
||||
#include "colvarparse.h"
|
||||
#include "colvarproxy.h"
|
||||
@ -169,7 +171,7 @@ int colvarmodule::parse_global_params (std::string const &conf)
|
||||
colvarparse::parse_silent);
|
||||
|
||||
if (use_scripted_forces && !proxy->force_script_defined) {
|
||||
cvm::fatal_error("User script for scripted colvars forces not found.");
|
||||
cvm::fatal_error("User script for scripted colvar forces not found.");
|
||||
}
|
||||
|
||||
return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK);
|
||||
@ -230,143 +232,57 @@ bool colvarmodule::check_new_bias(std::string &conf, char const *key)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
template <class bias_type>
|
||||
int colvarmodule::parse_biases_type(std::string const &conf,
|
||||
char const *keyword,
|
||||
size_t &bias_count)
|
||||
{
|
||||
std::string bias_conf = "";
|
||||
size_t conf_saved_pos = 0;
|
||||
while (parse->key_lookup(conf, keyword, bias_conf, conf_saved_pos)) {
|
||||
if (bias_conf.size()) {
|
||||
cvm::log(cvm::line_marker);
|
||||
cvm::increase_depth();
|
||||
biases.push_back(new bias_type(bias_conf, keyword));
|
||||
if (cvm::check_new_bias(bias_conf, keyword)) {
|
||||
return COLVARS_ERROR;
|
||||
}
|
||||
cvm::decrease_depth();
|
||||
bias_count++;
|
||||
} else {
|
||||
cvm::error("Error: keyword \""+std::string(keyword)+"\" found without configuration.\n",
|
||||
INPUT_ERROR);
|
||||
return COLVARS_ERROR;
|
||||
}
|
||||
bias_conf = "";
|
||||
}
|
||||
return COLVARS_OK;
|
||||
}
|
||||
|
||||
|
||||
int colvarmodule::parse_biases(std::string const &conf)
|
||||
{
|
||||
if (cvm::debug())
|
||||
cvm::log("Initializing the collective variables biases.\n");
|
||||
|
||||
{
|
||||
/// initialize ABF instances
|
||||
std::string abf_conf = "";
|
||||
size_t abf_pos = 0;
|
||||
while (parse->key_lookup (conf, "abf", abf_conf, abf_pos)) {
|
||||
if (abf_conf.size()) {
|
||||
cvm::log (cvm::line_marker);
|
||||
cvm::increase_depth();
|
||||
biases.push_back (new colvarbias_abf (abf_conf, "abf"));
|
||||
if (cvm::check_new_bias(abf_conf, "abf")) {
|
||||
return COLVARS_ERROR;
|
||||
}
|
||||
cvm::decrease_depth();
|
||||
n_abf_biases++;
|
||||
} else {
|
||||
cvm::error("Error: \"abf\" keyword found without configuration.\n", INPUT_ERROR);
|
||||
return COLVARS_ERROR;
|
||||
}
|
||||
abf_conf = "";
|
||||
}
|
||||
}
|
||||
parse_biases_type<colvarbias_abf>(conf, "abf", n_abf_biases);
|
||||
|
||||
{
|
||||
/// initialize harmonic restraints
|
||||
std::string harm_conf = "";
|
||||
size_t harm_pos = 0;
|
||||
while (parse->key_lookup (conf, "harmonic", harm_conf, harm_pos)) {
|
||||
if (harm_conf.size()) {
|
||||
cvm::log (cvm::line_marker);
|
||||
cvm::increase_depth();
|
||||
biases.push_back (new colvarbias_restraint_harmonic (harm_conf, "harmonic"));
|
||||
if (cvm::check_new_bias(harm_conf, "harmonic")) {
|
||||
return COLVARS_ERROR;
|
||||
}
|
||||
cvm::decrease_depth();
|
||||
n_rest_biases++;
|
||||
} else {
|
||||
cvm::error("Error: \"harmonic\" keyword found without configuration.\n", INPUT_ERROR);
|
||||
return COLVARS_ERROR;
|
||||
}
|
||||
harm_conf = "";
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
/// initialize linear restraints
|
||||
std::string lin_conf = "";
|
||||
size_t lin_pos = 0;
|
||||
while (parse->key_lookup (conf, "linear", lin_conf, lin_pos)) {
|
||||
if (lin_conf.size()) {
|
||||
cvm::log (cvm::line_marker);
|
||||
cvm::increase_depth();
|
||||
biases.push_back (new colvarbias_restraint_linear (lin_conf, "linear"));
|
||||
if (cvm::check_new_bias(lin_conf, "linear")) {
|
||||
return COLVARS_ERROR;
|
||||
}
|
||||
cvm::decrease_depth();
|
||||
n_rest_biases++;
|
||||
} else {
|
||||
cvm::error("Error: \"linear\" keyword found without configuration.\n", INPUT_ERROR);
|
||||
return COLVARS_ERROR;
|
||||
}
|
||||
lin_conf = "";
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
/// initialize adaptive linear biases
|
||||
std::string alb_conf = "";
|
||||
size_t alb_pos = 0;
|
||||
while (parse->key_lookup (conf, "ALB", alb_conf, alb_pos)) {
|
||||
if (alb_conf.size()) {
|
||||
cvm::log (cvm::line_marker);
|
||||
cvm::increase_depth();
|
||||
biases.push_back (new colvarbias_alb (alb_conf, "ALB"));
|
||||
if (cvm::check_new_bias(alb_conf, "ALB")) {
|
||||
return COLVARS_ERROR;
|
||||
}
|
||||
cvm::decrease_depth();
|
||||
n_rest_biases++;
|
||||
} else {
|
||||
cvm::error("Error: \"ALB\" keyword found without configuration.\n", INPUT_ERROR);
|
||||
return COLVARS_ERROR;
|
||||
}
|
||||
alb_conf = "";
|
||||
}
|
||||
}
|
||||
parse_biases_type<colvarbias_alb>(conf, "ALB", n_rest_biases);
|
||||
|
||||
/// initialize harmonic restraints
|
||||
parse_biases_type<colvarbias_restraint_harmonic>(conf, "harmonic", n_rest_biases);
|
||||
|
||||
{
|
||||
/// initialize histograms
|
||||
std::string histo_conf = "";
|
||||
size_t histo_pos = 0;
|
||||
while (parse->key_lookup (conf, "histogram", histo_conf, histo_pos)) {
|
||||
if (histo_conf.size()) {
|
||||
cvm::log (cvm::line_marker);
|
||||
cvm::increase_depth();
|
||||
biases.push_back (new colvarbias_histogram (histo_conf, "histogram"));
|
||||
if (cvm::check_new_bias(histo_conf, "histogram")) {
|
||||
return COLVARS_ERROR;
|
||||
}
|
||||
cvm::decrease_depth();
|
||||
n_histo_biases++;
|
||||
} else {
|
||||
cvm::error("Error: \"histogram\" keyword found without configuration.\n", INPUT_ERROR);
|
||||
return COLVARS_ERROR;
|
||||
}
|
||||
histo_conf = "";
|
||||
}
|
||||
}
|
||||
parse_biases_type<colvarbias_histogram>(conf, "histogram", n_histo_biases);
|
||||
|
||||
/// initialize linear restraints
|
||||
parse_biases_type<colvarbias_restraint_linear>(conf, "linear", n_rest_biases);
|
||||
|
||||
{
|
||||
/// initialize metadynamics instances
|
||||
std::string meta_conf = "";
|
||||
size_t meta_pos = 0;
|
||||
while (parse->key_lookup (conf, "metadynamics", meta_conf, meta_pos)) {
|
||||
if (meta_conf.size()) {
|
||||
cvm::log (cvm::line_marker);
|
||||
cvm::increase_depth();
|
||||
biases.push_back (new colvarbias_meta (meta_conf, "metadynamics"));
|
||||
if (cvm::check_new_bias(meta_conf, "metadynamics")) {
|
||||
return COLVARS_ERROR;
|
||||
}
|
||||
cvm::decrease_depth();
|
||||
n_meta_biases++;
|
||||
} else {
|
||||
cvm::error("Error: \"metadynamics\" keyword found without configuration.\n", INPUT_ERROR);
|
||||
return COLVARS_ERROR;
|
||||
}
|
||||
meta_conf = "";
|
||||
}
|
||||
}
|
||||
parse_biases_type<colvarbias_meta>(conf, "metadynamics", n_meta_biases);
|
||||
|
||||
if (use_scripted_forces) {
|
||||
cvm::log(cvm::line_marker);
|
||||
@ -375,10 +291,15 @@ int colvarmodule::parse_biases (std::string const &conf)
|
||||
cvm::decrease_depth();
|
||||
}
|
||||
|
||||
if (biases.size() || use_scripted_forces)
|
||||
if (biases.size() || use_scripted_forces) {
|
||||
cvm::log(cvm::line_marker);
|
||||
cvm::log("Collective variables biases initialized, "+
|
||||
cvm::to_str(biases.size())+" in total.\n");
|
||||
} else {
|
||||
if (!use_scripted_forces) {
|
||||
cvm::log("No collective variables biases were defined.\n");
|
||||
}
|
||||
}
|
||||
|
||||
return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK);
|
||||
}
|
||||
@ -448,124 +369,73 @@ cvm::real colvarmodule::energy_difference (std::string const &bias_name,
|
||||
return energy_diff;
|
||||
}
|
||||
|
||||
// For shared ABF
|
||||
cvm::real colvarmodule::read_width(std::string const &name)
|
||||
int colvarmodule::bias_current_bin(std::string const &bias_name)
|
||||
{
|
||||
cvm::increase_depth();
|
||||
int found = 0;
|
||||
real width = -1.0;
|
||||
for (std::vector<colvar *>::iterator cvi = colvars.begin();
|
||||
cvi != colvars.end();
|
||||
cvi++) {
|
||||
if ( (*cvi)->name == name ) {
|
||||
++found;
|
||||
width = (*cvi)->width;
|
||||
}
|
||||
}
|
||||
if (found < 1) {
|
||||
cvm::error ("Error: bias not found.\n");
|
||||
} else if (found > 1) {
|
||||
cvm::error ("Error: duplicate bias name.\n");
|
||||
int ret;
|
||||
colvarbias *b = bias_by_name(bias_name);
|
||||
|
||||
if (b != NULL) {
|
||||
ret = b->current_bin();
|
||||
} else {
|
||||
cvm::decrease_depth();
|
||||
}
|
||||
return width;
|
||||
cvm::error("Error: bias not found.\n");
|
||||
ret = COLVARS_ERROR;
|
||||
}
|
||||
|
||||
size_t colvarmodule::bias_current_bin (std::string const &bias_name)
|
||||
{
|
||||
cvm::increase_depth();
|
||||
int found = 0;
|
||||
size_t ret = 0; // N.B.: size_t is unsigned, so returning -1 would be a problem.
|
||||
|
||||
for (std::vector<colvarbias *>::iterator bi = biases.begin();
|
||||
bi != biases.end();
|
||||
bi++) {
|
||||
if ( (*bi)->name == bias_name ) {
|
||||
++found;
|
||||
ret = (*bi)->current_bin ();
|
||||
}
|
||||
}
|
||||
if (found < 1) {
|
||||
cvm::error ("Error: bias not found.\n");
|
||||
} else if (found > 1) {
|
||||
cvm::error ("Error: duplicate bias name.\n");
|
||||
} else {
|
||||
cvm::decrease_depth();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t colvarmodule::bias_bin_num (std::string const &bias_name)
|
||||
int colvarmodule::bias_bin_num(std::string const &bias_name)
|
||||
{
|
||||
cvm::increase_depth();
|
||||
int found = 0;
|
||||
size_t ret = 0; // N.B.: size_t is unsigned, so returning -1 would be a problem.
|
||||
int ret;
|
||||
colvarbias *b = bias_by_name(bias_name);
|
||||
|
||||
for (std::vector<colvarbias *>::iterator bi = biases.begin();
|
||||
bi != biases.end();
|
||||
bi++) {
|
||||
if ( (*bi)->name == bias_name ) {
|
||||
++found;
|
||||
ret = (*bi)->bin_num ();
|
||||
}
|
||||
}
|
||||
if (found < 1) {
|
||||
cvm::error ("Error: bias not found.\n");
|
||||
} else if (found > 1) {
|
||||
cvm::error ("Error: duplicate bias name.\n");
|
||||
if (b != NULL) {
|
||||
ret = b->bin_num();
|
||||
} else {
|
||||
cvm::decrease_depth();
|
||||
cvm::error("Error: bias not found.\n");
|
||||
ret = COLVARS_ERROR;
|
||||
}
|
||||
|
||||
cvm::decrease_depth();
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t colvarmodule::bias_bin_count (std::string const &bias_name, size_t bin_index)
|
||||
int colvarmodule::bias_bin_count(std::string const &bias_name, size_t bin_index)
|
||||
{
|
||||
cvm::increase_depth();
|
||||
int found = 0;
|
||||
size_t ret = 0; // N.B.: size_t is unsigned, so returning -1 would be a problem.
|
||||
int ret;
|
||||
colvarbias *b = bias_by_name(bias_name);
|
||||
|
||||
for (std::vector<colvarbias *>::iterator bi = biases.begin();
|
||||
bi != biases.end();
|
||||
bi++) {
|
||||
if ( (*bi)->name == bias_name ) {
|
||||
++found;
|
||||
ret = (*bi)->bin_count (bin_index);
|
||||
}
|
||||
}
|
||||
if (found < 1) {
|
||||
cvm::error ("Error: bias not found.\n");
|
||||
} else if (found > 1) {
|
||||
cvm::error ("Error: duplicate bias name.\n");
|
||||
if (b != NULL) {
|
||||
ret = b->bin_count(bin_index);
|
||||
} else {
|
||||
cvm::decrease_depth();
|
||||
cvm::error("Error: bias not found.\n");
|
||||
ret = COLVARS_ERROR;
|
||||
}
|
||||
|
||||
cvm::decrease_depth();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void colvarmodule::bias_share (std::string const &bias_name)
|
||||
int colvarmodule::bias_share(std::string const &bias_name)
|
||||
{
|
||||
cvm::increase_depth();
|
||||
int found = 0;
|
||||
int ret;
|
||||
colvarbias *b = bias_by_name(bias_name);
|
||||
|
||||
for (std::vector<colvarbias *>::iterator bi = biases.begin();
|
||||
bi != biases.end();
|
||||
bi++) {
|
||||
if ( (*bi)->name == bias_name ) {
|
||||
++found;
|
||||
(*bi)->replica_share ();
|
||||
}
|
||||
}
|
||||
if (found < 1) {
|
||||
if (b != NULL) {
|
||||
b->replica_share();
|
||||
ret = COLVARS_OK;
|
||||
} else {
|
||||
cvm::error("Error: bias not found.\n");
|
||||
return;
|
||||
}
|
||||
if (found > 1) {
|
||||
cvm::error ("Error: duplicate bias name.\n");
|
||||
return;
|
||||
ret = COLVARS_ERROR;
|
||||
}
|
||||
|
||||
cvm::decrease_depth();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@ -706,7 +576,7 @@ int colvarmodule::calc() {
|
||||
// write trajectory file, if needed
|
||||
if (cv_traj_freq && cv_traj_name.size()) {
|
||||
|
||||
if (!cv_traj_os.good()) {
|
||||
if (!cv_traj_os.is_open()) {
|
||||
open_traj_file(cv_traj_name);
|
||||
}
|
||||
|
||||
@ -867,21 +737,10 @@ int colvarmodule::setup_output()
|
||||
std::string(""));
|
||||
|
||||
if (cv_traj_freq && cv_traj_name.size()) {
|
||||
// open trajectory file
|
||||
if (cv_traj_append) {
|
||||
cvm::log ("Appending to colvar trajectory file \""+cv_traj_name+
|
||||
"\".\n");
|
||||
cv_traj_os.open (cv_traj_name.c_str(), std::ios::app);
|
||||
} else {
|
||||
cvm::log ("Writing to colvar trajectory file \""+cv_traj_name+
|
||||
"\".\n");
|
||||
proxy->backup_file (cv_traj_name.c_str());
|
||||
cv_traj_os.open (cv_traj_name.c_str(), std::ios::out);
|
||||
open_traj_file(cv_traj_name);
|
||||
}
|
||||
cv_traj_os.setf (std::ios::scientific, std::ios::floatfield);
|
||||
}
|
||||
return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK);
|
||||
|
||||
return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK);
|
||||
}
|
||||
|
||||
|
||||
@ -1061,21 +920,27 @@ std::ostream & colvarmodule::write_restart (std::ostream &os)
|
||||
|
||||
int colvarmodule::open_traj_file(std::string const &file_name)
|
||||
{
|
||||
if (cv_traj_os.is_open()) {
|
||||
return COLVARS_OK;
|
||||
}
|
||||
|
||||
// (re)open trajectory file
|
||||
if (cv_traj_append) {
|
||||
cvm::log("Appending to colvar trajectory file \""+file_name+
|
||||
"\".\n");
|
||||
cv_traj_os.open(file_name.c_str(), std::ios::app);
|
||||
} else {
|
||||
cvm::log ("Overwriting colvar trajectory file \""+file_name+
|
||||
cvm::log("Writing to colvar trajectory file \""+file_name+
|
||||
"\".\n");
|
||||
proxy->backup_file(file_name.c_str());
|
||||
cv_traj_os.open(file_name.c_str(), std::ios::out);
|
||||
}
|
||||
if (!cv_traj_os.good()) {
|
||||
|
||||
if (!cv_traj_os.is_open()) {
|
||||
cvm::error("Error: cannot write to file \""+file_name+"\".\n",
|
||||
FILE_ERROR);
|
||||
}
|
||||
|
||||
return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK);
|
||||
}
|
||||
|
||||
@ -1330,7 +1195,7 @@ bool colvarmodule::b_analysis = false;
|
||||
cvm::real colvarmodule::rotation::crossing_threshold = 1.0E-04;
|
||||
std::list<std::string> colvarmodule::index_group_names;
|
||||
std::list<std::vector<int> > colvarmodule::index_groups;
|
||||
|
||||
bool colvarmodule::use_scripted_forces = false;
|
||||
|
||||
// file name prefixes
|
||||
std::string colvarmodule::output_prefix = "";
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
#define COLVARMODULE_H
|
||||
|
||||
#ifndef COLVARS_VERSION
|
||||
#define COLVARS_VERSION "2014-10-21"
|
||||
#define COLVARS_VERSION "2014-11-21"
|
||||
#endif
|
||||
|
||||
#ifndef COLVARS_DEBUG
|
||||
@ -21,6 +21,7 @@
|
||||
/// objects.
|
||||
|
||||
// Internal method return codes
|
||||
#define COLVARS_NOT_IMPLEMENTED -2
|
||||
#define COLVARS_ERROR -1
|
||||
#define COLVARS_OK 0
|
||||
|
||||
@ -80,11 +81,8 @@ public:
|
||||
typedef int residue_id;
|
||||
|
||||
class rvector;
|
||||
template <class T,
|
||||
size_t const length> class vector1d;
|
||||
template <class T,
|
||||
size_t const outer_length,
|
||||
size_t const inner_length> class matrix2d;
|
||||
template <class T> class vector1d;
|
||||
template <class T> class matrix2d;
|
||||
class quaternion;
|
||||
class rotation;
|
||||
|
||||
@ -219,6 +217,10 @@ public:
|
||||
/// Parse and initialize collective variable biases
|
||||
int parse_biases(std::string const &conf);
|
||||
|
||||
/// Parse and initialize collective variable biases of a specific type
|
||||
template <class bias_type>
|
||||
int parse_biases_type(std::string const &conf, char const *keyword, size_t &bias_count);
|
||||
|
||||
/// Test error condition and keyword parsing
|
||||
/// on error, delete new bias
|
||||
bool check_new_bias(std::string &conf, char const *key);
|
||||
@ -273,16 +275,14 @@ public:
|
||||
/// currently works for harmonic (force constant and/or centers)
|
||||
real energy_difference(std::string const &bias_name, std::string const &conf);
|
||||
|
||||
/// Give the bin width in the units of the colvar.
|
||||
real read_width(std::string const &name);
|
||||
/// Give the total number of bins for a given bias.
|
||||
size_t bias_bin_num(std::string const &bias_name);
|
||||
int bias_bin_num(std::string const &bias_name);
|
||||
/// Calculate the bin index for a given bias.
|
||||
size_t bias_current_bin(std::string const &bias_name);
|
||||
int bias_current_bin(std::string const &bias_name);
|
||||
//// Give the count at a given bin index.
|
||||
size_t bias_bin_count(std::string const &bias_name, size_t bin_index);
|
||||
int bias_bin_count(std::string const &bias_name, size_t bin_index);
|
||||
//// Share among replicas.
|
||||
void bias_share(std::string const &bias_name);
|
||||
int bias_share(std::string const &bias_name);
|
||||
|
||||
/// Calculate collective variables and biases
|
||||
int calc();
|
||||
@ -467,7 +467,7 @@ protected:
|
||||
static size_t depth;
|
||||
|
||||
/// Use scripted colvars forces?
|
||||
bool use_scripted_forces;
|
||||
static bool use_scripted_forces;
|
||||
|
||||
public:
|
||||
/// \brief Pointer to the proxy object, used to retrieve atomic data
|
||||
@ -481,6 +481,8 @@ public:
|
||||
|
||||
/// Decrease the depth (number of indentations in the output)
|
||||
static void decrease_depth();
|
||||
|
||||
static inline bool scripted_forces() { return use_scripted_forces; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -4,18 +4,11 @@
|
||||
#define COLVARPROXY_H
|
||||
|
||||
|
||||
#ifndef COLVARPROXY_VERSION
|
||||
#define COLVARPROXY_VERSION "2014-10-21"
|
||||
#endif
|
||||
|
||||
|
||||
#include "colvarmodule.h"
|
||||
#include "colvarvalue.h"
|
||||
|
||||
|
||||
// return values for the frame() routine
|
||||
#define COLVARS_NO_SUCH_FRAME -1
|
||||
#define COLVARS_NOT_IMPLEMENTED -2
|
||||
|
||||
// forward declarations
|
||||
class colvarscript;
|
||||
@ -177,7 +170,7 @@ public:
|
||||
|
||||
virtual int run_colvar_gradient_callback(std::string const &name,
|
||||
std::vector<const colvarvalue *> const &cvcs,
|
||||
std::vector<colvarvalue> &gradient)
|
||||
std::vector<cvm::matrix2d<cvm::real> > &gradient)
|
||||
{ return COLVARS_NOT_IMPLEMENTED; }
|
||||
|
||||
// **************** INPUT/OUTPUT ****************
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
// -*- c++ -*-
|
||||
|
||||
#include <cstdlib>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "colvarscript.h"
|
||||
|
||||
|
||||
@ -209,14 +212,19 @@ int colvarscript::proc_colvar (int argc, char const *argv[]) {
|
||||
std::string subcmd = argv[2];
|
||||
|
||||
if (subcmd == "value") {
|
||||
result = cvm::to_str(cv->value(), 0, cvm::cv_prec);
|
||||
result = (cv->value()).to_simple_string();
|
||||
return COLVARSCRIPT_OK;
|
||||
}
|
||||
|
||||
if (subcmd == "width") {
|
||||
result = cvm::to_str(cv->width, 0, cvm::cv_prec);
|
||||
return COLVARSCRIPT_OK;
|
||||
}
|
||||
|
||||
if (subcmd == "update") {
|
||||
cv->calc();
|
||||
cv->update();
|
||||
result = cvm::to_str(cv->value(), 0, cvm::cv_prec);
|
||||
result = (cv->value()).to_simple_string();
|
||||
return COLVARSCRIPT_OK;
|
||||
}
|
||||
|
||||
@ -234,21 +242,21 @@ int colvarscript::proc_colvar (int argc, char const *argv[]) {
|
||||
|
||||
if (subcmd == "addforce") {
|
||||
if (argc < 4) {
|
||||
result = "Missing parameter: force value";
|
||||
result = "addforce: missing parameter: force value";
|
||||
return COLVARSCRIPT_ERROR;
|
||||
}
|
||||
std::string f_str = argv[3];
|
||||
std::istringstream is(f_str);
|
||||
is.width(cvm::cv_width);
|
||||
is.precision(cvm::cv_prec);
|
||||
colvarvalue force (cv->type());
|
||||
colvarvalue force(cv->value());
|
||||
force.is_derivative();
|
||||
if (!(is >> force)) {
|
||||
result = "Error parsing force value";
|
||||
if (force.from_simple_string(is.str()) != COLVARS_OK) {
|
||||
result = "addforce : error parsing force value";
|
||||
return COLVARSCRIPT_ERROR;
|
||||
}
|
||||
cv->add_bias_force(force);
|
||||
result = cvm::to_str(force, cvm::cv_width, cvm::cv_prec);
|
||||
result = force.to_simple_string();
|
||||
return COLVARSCRIPT_OK;
|
||||
}
|
||||
|
||||
@ -282,6 +290,34 @@ int colvarscript::proc_bias (int argc, char const *argv[]) {
|
||||
return COLVARSCRIPT_OK;
|
||||
}
|
||||
|
||||
// Subcommands for MW ABF
|
||||
if (subcmd == "bin") {
|
||||
int r = b->current_bin();
|
||||
result = cvm::to_str(r);
|
||||
return COLVARSCRIPT_OK;
|
||||
}
|
||||
|
||||
if (subcmd == "binnum") {
|
||||
int r = b->bin_num();
|
||||
if (r < 0) {
|
||||
result = "Error: calling bin_num() for bias " + b->name;
|
||||
return COLVARSCRIPT_ERROR;
|
||||
}
|
||||
result = cvm::to_str(r);
|
||||
return COLVARSCRIPT_OK;
|
||||
}
|
||||
|
||||
if (subcmd == "share") {
|
||||
int r = b->replica_share();
|
||||
if (r < 0) {
|
||||
result = "Error: calling replica_share() for bias " + b->name;
|
||||
return COLVARSCRIPT_ERROR;
|
||||
}
|
||||
result = cvm::to_str(r);
|
||||
return COLVARSCRIPT_OK;
|
||||
}
|
||||
// End commands for MW ABF
|
||||
|
||||
if (subcmd == "delete") {
|
||||
// the bias destructor takes care of the cleanup at cvm level
|
||||
delete b;
|
||||
@ -291,7 +327,16 @@ int colvarscript::proc_bias (int argc, char const *argv[]) {
|
||||
}
|
||||
|
||||
if (argc >= 4) {
|
||||
// std::string param = argv[3];
|
||||
std::string param = argv[3];
|
||||
if (subcmd == "count") {
|
||||
int index;
|
||||
if (!(std::istringstream(param) >> index)) {
|
||||
result = "bin_count: error parsing bin index";
|
||||
return COLVARSCRIPT_ERROR;
|
||||
}
|
||||
result = cvm::to_str(b->bin_count(index));
|
||||
return COLVARSCRIPT_OK;
|
||||
}
|
||||
|
||||
result = "Syntax error";
|
||||
return COLVARSCRIPT_ERROR;
|
||||
|
||||
@ -1,10 +1,35 @@
|
||||
/// -*- c++ -*-
|
||||
// -*- c++ -*-
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "colvarmodule.h"
|
||||
#include "colvartypes.h"
|
||||
#include "colvarparse.h"
|
||||
|
||||
|
||||
std::string cvm::rvector::to_simple_string() const
|
||||
{
|
||||
std::ostringstream os;
|
||||
os.setf(std::ios::scientific, std::ios::floatfield);
|
||||
os.precision(cvm::cv_prec);
|
||||
os << x << " " << y << " " << z;
|
||||
return os.str();
|
||||
}
|
||||
|
||||
|
||||
int cvm::rvector::from_simple_string(std::string const &s)
|
||||
{
|
||||
std::stringstream stream(s);
|
||||
if ( !(stream >> x) ||
|
||||
!(stream >> y) ||
|
||||
!(stream >> z) ) {
|
||||
return COLVARS_ERROR;
|
||||
}
|
||||
return COLVARS_OK;
|
||||
}
|
||||
|
||||
|
||||
std::ostream & operator << (std::ostream &os, colvarmodule::rvector const &v)
|
||||
{
|
||||
std::streamsize const w = os.width();
|
||||
@ -38,7 +63,26 @@ std::istream & operator >> (std::istream &is, colvarmodule::rvector &v)
|
||||
return is;
|
||||
}
|
||||
|
||||
std::string cvm::quaternion::to_simple_string() const
|
||||
{
|
||||
std::ostringstream os;
|
||||
os.setf(std::ios::scientific, std::ios::floatfield);
|
||||
os.precision(cvm::cv_prec);
|
||||
os << q0 << " " << q1 << " " << q2 << " " << q3;
|
||||
return os.str();
|
||||
}
|
||||
|
||||
int cvm::quaternion::from_simple_string(std::string const &s)
|
||||
{
|
||||
std::stringstream stream(s);
|
||||
if ( !(stream >> q0) ||
|
||||
!(stream >> q1) ||
|
||||
!(stream >> q2) ||
|
||||
!(stream >> q3) ) {
|
||||
return COLVARS_ERROR;
|
||||
}
|
||||
return COLVARS_OK;
|
||||
}
|
||||
|
||||
std::ostream & operator << (std::ostream &os, colvarmodule::quaternion const &q)
|
||||
{
|
||||
@ -174,8 +218,6 @@ cvm::quaternion::position_derivative_inner (cvm::rvector const &pos,
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Calculate the optimal rotation between two groups, and implement it
|
||||
// as a quaternion. Uses the method documented in: Coutsias EA,
|
||||
// Seok C, Dill KA. Using quaternions to calculate RMSD. J Comput
|
||||
@ -183,13 +225,13 @@ cvm::quaternion::position_derivative_inner (cvm::rvector const &pos,
|
||||
|
||||
void colvarmodule::rotation::build_matrix(std::vector<cvm::atom_pos> const &pos1,
|
||||
std::vector<cvm::atom_pos> const &pos2,
|
||||
matrix2d<cvm::real, 4, 4> &S)
|
||||
cvm::matrix2d<cvm::real> &S)
|
||||
{
|
||||
cvm::rmatrix C;
|
||||
|
||||
// build the correlation matrix
|
||||
C.resize(3, 3);
|
||||
C.reset();
|
||||
for (size_t i = 0; i < pos1.size(); i++) {
|
||||
size_t i;
|
||||
for (i = 0; i < pos1.size(); i++) {
|
||||
C.xx() += pos1[i].x * pos2[i].x;
|
||||
C.xy() += pos1[i].x * pos2[i].y;
|
||||
C.xz() += pos1[i].x * pos2[i].z;
|
||||
@ -219,70 +261,51 @@ void colvarmodule::rotation::build_matrix (std::vector<cvm::atom_pos> const &pos
|
||||
S[3][2] = C.yz() + C.zy();
|
||||
S[2][3] = S[3][2];
|
||||
S[3][3] = - C.xx() - C.yy() + C.zz();
|
||||
|
||||
// if (cvm::debug()) {
|
||||
// for (size_t i = 0; i < 4; i++) {
|
||||
// std::string line ("");
|
||||
// for (size_t j = 0; j < 4; j++) {
|
||||
// line += std::string (" S["+cvm::to_str (i)+
|
||||
// "]["+cvm::to_str (j)+"] ="+cvm::to_str (S[i][j]));
|
||||
// }
|
||||
// cvm::log (line+"\n");
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
void colvarmodule::rotation::diagonalize_matrix (matrix2d<cvm::real, 4, 4> &S,
|
||||
cvm::real S_eigval[4],
|
||||
matrix2d<cvm::real, 4, 4> &S_eigvec)
|
||||
void colvarmodule::rotation::diagonalize_matrix(cvm::matrix2d<cvm::real> &S,
|
||||
cvm::vector1d<cvm::real> &S_eigval,
|
||||
cvm::matrix2d<cvm::real> &S_eigvec)
|
||||
{
|
||||
S_eigval.resize(4);
|
||||
S_eigval.reset();
|
||||
S_eigvec.resize(4,4);
|
||||
S_eigvec.reset();
|
||||
|
||||
// diagonalize
|
||||
int jac_nrot = 0;
|
||||
jacobi (S, S_eigval, S_eigvec, &jac_nrot);
|
||||
eigsrt (S_eigval, S_eigvec);
|
||||
jacobi(S.c_array(), S_eigval.c_array(), S_eigvec.c_array(), &jac_nrot);
|
||||
eigsrt(S_eigval.c_array(), S_eigvec.c_array());
|
||||
// jacobi saves eigenvectors by columns
|
||||
transpose (S_eigvec);
|
||||
transpose(S_eigvec.c_array());
|
||||
|
||||
// normalize eigenvectors
|
||||
for (size_t ie = 0; ie < 4; ie++) {
|
||||
cvm::real norm2 = 0.0;
|
||||
size_t i;
|
||||
for (i = 0; i < 4; i++) norm2 += std::pow (S_eigvec[ie][i], int (2));
|
||||
for (i = 0; i < 4; i++) {
|
||||
norm2 += std::pow(S_eigvec[ie][i], int(2));
|
||||
}
|
||||
cvm::real const norm = std::sqrt(norm2);
|
||||
for (i = 0; i < 4; i++) S_eigvec[ie][i] /= norm;
|
||||
for (i = 0; i < 4; i++) {
|
||||
S_eigvec[ie][i] /= norm;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Calculate the rotation, plus its derivatives
|
||||
|
||||
void colvarmodule::rotation::calc_optimal_rotation
|
||||
(std::vector<cvm::atom_pos> const &pos1,
|
||||
void colvarmodule::rotation::calc_optimal_rotation(std::vector<cvm::atom_pos> const &pos1,
|
||||
std::vector<cvm::atom_pos> const &pos2)
|
||||
{
|
||||
matrix2d<cvm::real, 4, 4> S;
|
||||
matrix2d<cvm::real, 4, 4> S_backup;
|
||||
cvm::real S_eigval[4];
|
||||
matrix2d<cvm::real, 4, 4> S_eigvec;
|
||||
|
||||
// if (cvm::debug()) {
|
||||
// cvm::atom_pos cog1 (0.0, 0.0, 0.0);
|
||||
// for (size_t i = 0; i < pos1.size(); i++) {
|
||||
// cog1 += pos1[i];
|
||||
// }
|
||||
// cog1 /= cvm::real (pos1.size());
|
||||
// cvm::atom_pos cog2 (0.0, 0.0, 0.0);
|
||||
// for (size_t i = 0; i < pos2.size(); i++) {
|
||||
// cog2 += pos2[i];
|
||||
// }
|
||||
// cog2 /= cvm::real (pos1.size());
|
||||
// cvm::log ("calc_optimal_rotation: centers of geometry are: "+
|
||||
// cvm::to_str (cog1, cvm::cv_width, cvm::cv_prec)+
|
||||
// " and "+cvm::to_str (cog2, cvm::cv_width, cvm::cv_prec)+".\n");
|
||||
// }
|
||||
S.resize(4,4);
|
||||
S.reset();
|
||||
|
||||
build_matrix(pos1, pos2, S);
|
||||
|
||||
S_backup.resize(4,4);
|
||||
S_backup = S;
|
||||
|
||||
if (cvm::debug()) {
|
||||
@ -294,17 +317,17 @@ void colvarmodule::rotation::calc_optimal_rotation
|
||||
diagonalize_matrix(S, S_eigval, S_eigvec);
|
||||
|
||||
// eigenvalues and eigenvectors
|
||||
cvm::real const &L0 = S_eigval[0];
|
||||
cvm::real const &L1 = S_eigval[1];
|
||||
cvm::real const &L2 = S_eigval[2];
|
||||
cvm::real const &L3 = S_eigval[3];
|
||||
cvm::real const *Q0 = S_eigvec[0];
|
||||
cvm::real const *Q1 = S_eigvec[1];
|
||||
cvm::real const *Q2 = S_eigvec[2];
|
||||
cvm::real const *Q3 = S_eigvec[3];
|
||||
cvm::real const L0 = S_eigval[0];
|
||||
cvm::real const L1 = S_eigval[1];
|
||||
cvm::real const L2 = S_eigval[2];
|
||||
cvm::real const L3 = S_eigval[3];
|
||||
cvm::quaternion const Q0(S_eigvec[0]);
|
||||
cvm::quaternion const Q1(S_eigvec[1]);
|
||||
cvm::quaternion const Q2(S_eigvec[2]);
|
||||
cvm::quaternion const Q3(S_eigvec[3]);
|
||||
|
||||
lambda = L0;
|
||||
q = cvm::quaternion (Q0);
|
||||
q = Q0;
|
||||
|
||||
if (q_old.norm2() > 0.0) {
|
||||
q.match(q_old);
|
||||
@ -318,20 +341,20 @@ void colvarmodule::rotation::calc_optimal_rotation
|
||||
if (cvm::debug()) {
|
||||
if (b_debug_gradients) {
|
||||
cvm::log("L0 = "+cvm::to_str(L0, cvm::cv_width, cvm::cv_prec)+
|
||||
", Q0 = "+cvm::to_str (cvm::quaternion (Q0), cvm::cv_width, cvm::cv_prec)+
|
||||
", Q0*Q0 = "+cvm::to_str (cvm::quaternion (Q0).inner (cvm::quaternion (Q0)), cvm::cv_width, cvm::cv_prec)+
|
||||
", Q0 = "+cvm::to_str(Q0, cvm::cv_width, cvm::cv_prec)+
|
||||
", Q0*Q0 = "+cvm::to_str(Q0.inner(Q0), cvm::cv_width, cvm::cv_prec)+
|
||||
"\n");
|
||||
cvm::log("L1 = "+cvm::to_str(L1, cvm::cv_width, cvm::cv_prec)+
|
||||
", Q1 = "+cvm::to_str (cvm::quaternion (Q1), cvm::cv_width, cvm::cv_prec)+
|
||||
", Q0*Q1 = "+cvm::to_str (cvm::quaternion (Q0).inner (cvm::quaternion (Q1)), cvm::cv_width, cvm::cv_prec)+
|
||||
", Q1 = "+cvm::to_str(Q1, cvm::cv_width, cvm::cv_prec)+
|
||||
", Q0*Q1 = "+cvm::to_str(Q0.inner(Q1), cvm::cv_width, cvm::cv_prec)+
|
||||
"\n");
|
||||
cvm::log("L2 = "+cvm::to_str(L2, cvm::cv_width, cvm::cv_prec)+
|
||||
", Q2 = "+cvm::to_str (cvm::quaternion (Q2), cvm::cv_width, cvm::cv_prec)+
|
||||
", Q0*Q2 = "+cvm::to_str (cvm::quaternion (Q0).inner (cvm::quaternion (Q2)), cvm::cv_width, cvm::cv_prec)+
|
||||
", Q2 = "+cvm::to_str(Q2, cvm::cv_width, cvm::cv_prec)+
|
||||
", Q0*Q2 = "+cvm::to_str(Q0.inner(Q2), cvm::cv_width, cvm::cv_prec)+
|
||||
"\n");
|
||||
cvm::log("L3 = "+cvm::to_str(L3, cvm::cv_width, cvm::cv_prec)+
|
||||
", Q3 = "+cvm::to_str (cvm::quaternion (Q3), cvm::cv_width, cvm::cv_prec)+
|
||||
", Q0*Q3 = "+cvm::to_str (cvm::quaternion (Q0).inner (cvm::quaternion (Q3)), cvm::cv_width, cvm::cv_prec)+
|
||||
", Q3 = "+cvm::to_str(Q3, cvm::cv_width, cvm::cv_prec)+
|
||||
", Q0*Q3 = "+cvm::to_str(Q0.inner(Q3), cvm::cv_width, cvm::cv_prec)+
|
||||
"\n");
|
||||
}
|
||||
}
|
||||
@ -346,7 +369,7 @@ void colvarmodule::rotation::calc_optimal_rotation
|
||||
cvm::real const &a2y = pos2[ia].y;
|
||||
cvm::real const &a2z = pos2[ia].z;
|
||||
|
||||
matrix2d<cvm::rvector, 4, 4> &ds_1 = dS_1[ia];
|
||||
cvm::matrix2d<cvm::rvector> &ds_1 = dS_1[ia];
|
||||
|
||||
// derivative of the S matrix
|
||||
ds_1.reset();
|
||||
@ -368,7 +391,7 @@ void colvarmodule::rotation::calc_optimal_rotation
|
||||
ds_1[3][3].set(-a2x, -a2y, a2z);
|
||||
|
||||
cvm::rvector &dl0_1 = dL0_1[ia];
|
||||
vector1d<cvm::rvector, 4> &dq0_1 = dQ0_1[ia];
|
||||
cvm::vector1d<cvm::rvector> &dq0_1 = dQ0_1[ia];
|
||||
|
||||
// matrix multiplications; derivatives of L_0 and Q_0 are
|
||||
// calculated using Hellmann-Feynman theorem (i.e. exploiting the
|
||||
@ -401,7 +424,7 @@ void colvarmodule::rotation::calc_optimal_rotation
|
||||
cvm::real const &a1y = pos1[ia].y;
|
||||
cvm::real const &a1z = pos1[ia].z;
|
||||
|
||||
matrix2d<cvm::rvector, 4, 4> &ds_2 = dS_2[ia];
|
||||
cvm::matrix2d<cvm::rvector> &ds_2 = dS_2[ia];
|
||||
|
||||
ds_2.reset();
|
||||
ds_2[0][0].set( a1x, a1y, a1z);
|
||||
@ -422,7 +445,7 @@ void colvarmodule::rotation::calc_optimal_rotation
|
||||
ds_2[3][3].set(-a1x, -a1y, a1z);
|
||||
|
||||
cvm::rvector &dl0_2 = dL0_2[ia];
|
||||
vector1d<cvm::rvector, 4> &dq0_2 = dQ0_2[ia];
|
||||
cvm::vector1d<cvm::rvector> &dq0_2 = dQ0_2[ia];
|
||||
|
||||
dl0_2.reset();
|
||||
for (size_t i = 0; i < 4; i++) {
|
||||
@ -447,9 +470,9 @@ void colvarmodule::rotation::calc_optimal_rotation
|
||||
|
||||
if (b_debug_gradients) {
|
||||
|
||||
matrix2d<cvm::real, 4, 4> S_new;
|
||||
cvm::real S_new_eigval[4];
|
||||
matrix2d<cvm::real, 4, 4> S_new_eigvec;
|
||||
cvm::matrix2d<cvm::real> S_new(4, 4);
|
||||
cvm::vector1d<cvm::real> S_new_eigval(4);
|
||||
cvm::matrix2d<cvm::real> S_new_eigvec(4, 4);
|
||||
|
||||
// make an infitesimal move along each cartesian coordinate of
|
||||
// this atom, and solve again the eigenvector problem
|
||||
@ -469,7 +492,7 @@ void colvarmodule::rotation::calc_optimal_rotation
|
||||
diagonalize_matrix(S_new, S_new_eigval, S_new_eigvec);
|
||||
|
||||
cvm::real const &L0_new = S_new_eigval[0];
|
||||
cvm::real const *Q0_new = S_new_eigvec[0];
|
||||
cvm::quaternion const Q0_new(S_new_eigvec[0]);
|
||||
|
||||
cvm::real const DL0 = (dl0_2[comp]) * colvarmodule::debug_gradients_step_size;
|
||||
cvm::quaternion const q0(Q0);
|
||||
@ -497,18 +520,21 @@ void colvarmodule::rotation::calc_optimal_rotation
|
||||
h=a[k][l]; \
|
||||
a[i][j]=g-s*(h+g*tau); \
|
||||
a[k][l]=h+s*(g-h*tau);
|
||||
|
||||
#define n 4
|
||||
|
||||
void jacobi(cvm::real **a, cvm::real d[], cvm::real **v, int *nrot)
|
||||
void jacobi(cvm::real **a, cvm::real *d, cvm::real **v, int *nrot)
|
||||
{
|
||||
int j,iq,ip,i;
|
||||
cvm::real tresh,theta,tau,t,sm,s,h,g,c;
|
||||
|
||||
std::vector<cvm::real> b (n, 0.0);
|
||||
std::vector<cvm::real> z (n, 0.0);
|
||||
cvm::vector1d<cvm::real> b(n);
|
||||
cvm::vector1d<cvm::real> z(n);
|
||||
|
||||
for (ip=0;ip<n;ip++) {
|
||||
for (iq=0;iq<n;iq++) v[ip][iq]=0.0;
|
||||
for (iq=0;iq<n;iq++) {
|
||||
v[ip][iq]=0.0;
|
||||
}
|
||||
v[ip][ip]=1.0;
|
||||
}
|
||||
for (ip=0;ip<n;ip++) {
|
||||
@ -578,7 +604,7 @@ void jacobi(cvm::real **a, cvm::real d[], cvm::real **v, int *nrot)
|
||||
cvm::error("Too many iterations in routine jacobi.\n");
|
||||
}
|
||||
|
||||
void eigsrt(cvm::real d[], cvm::real **v)
|
||||
void eigsrt(cvm::real *d, cvm::real **v)
|
||||
{
|
||||
int k,j,i;
|
||||
cvm::real p;
|
||||
@ -602,8 +628,9 @@ void eigsrt(cvm::real d[], cvm::real **v)
|
||||
void transpose(cvm::real **v)
|
||||
{
|
||||
cvm::real p;
|
||||
for (int i=0;i<n;i++) {
|
||||
for (int j=i+1;j<n;j++) {
|
||||
int i,j;
|
||||
for (i=0;i<n;i++) {
|
||||
for (j=i+1;j<n;j++) {
|
||||
p=v[i][j];
|
||||
v[i][j]=v[j][i];
|
||||
v[j][i]=p;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,237 +1,385 @@
|
||||
/// -*- c++ -*-
|
||||
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
#include "colvarmodule.h"
|
||||
#include "colvarvalue.h"
|
||||
|
||||
|
||||
|
||||
std::string const colvarvalue::type_desc[colvarvalue::type_all+1] =
|
||||
{ "not_set",
|
||||
"scalar number",
|
||||
"3-dimensional vector",
|
||||
"3-dimensional unit vector",
|
||||
"3-dimensional tangent vector",
|
||||
"4-dimensional unit quaternion",
|
||||
"4-dimensional tangent vector",
|
||||
};
|
||||
|
||||
std::string const colvarvalue::type_keyword[colvarvalue::type_all+1] =
|
||||
{ "not_set",
|
||||
"scalar",
|
||||
"vector",
|
||||
"unit_vector",
|
||||
"",
|
||||
"unit_quaternion",
|
||||
"",
|
||||
};
|
||||
|
||||
size_t const colvarvalue::dof_num[ colvarvalue::type_all+1] =
|
||||
{ 0, 1, 3, 2, 2, 3, 3 };
|
||||
|
||||
|
||||
void colvarvalue::undef_op() const
|
||||
void colvarvalue::add_elem(colvarvalue const &x)
|
||||
{
|
||||
cvm::error ("Error: Undefined operation on a colvar of type \""+
|
||||
colvarvalue::type_desc[this->value_type]+"\".\n");
|
||||
}
|
||||
|
||||
void colvarvalue::error_rside
|
||||
(colvarvalue::Type const &vt) const
|
||||
{
|
||||
cvm::error("Trying to assign a colvar value with type \""+
|
||||
type_desc[this->value_type]+"\" to one with type \""+
|
||||
type_desc[vt]+"\".\n");
|
||||
}
|
||||
|
||||
void colvarvalue::error_lside(colvarvalue::Type const &vt) const
|
||||
{
|
||||
cvm::error("Trying to use a colvar value with type \""+
|
||||
type_desc[vt]+"\" as one of type \""+
|
||||
type_desc[this->value_type]+"\".\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void colvarvalue::inner_opt(colvarvalue const &x,
|
||||
std::vector<colvarvalue>::iterator &xv,
|
||||
std::vector<colvarvalue>::iterator const &xv_end,
|
||||
std::vector<cvm::real>::iterator &inner)
|
||||
{
|
||||
// doing type check only once, here
|
||||
colvarvalue::check_types(x, *xv);
|
||||
|
||||
std::vector<colvarvalue>::iterator &xvi = xv;
|
||||
std::vector<cvm::real>::iterator &ii = inner;
|
||||
|
||||
switch (x.value_type) {
|
||||
case colvarvalue::type_scalar:
|
||||
while (xvi != xv_end) {
|
||||
*(ii++) += (xvi++)->real_value * x.real_value;
|
||||
}
|
||||
break;
|
||||
case colvarvalue::type_vector:
|
||||
case colvarvalue::type_unitvector:
|
||||
case colvarvalue::type_unitvectorderiv:
|
||||
while (xvi != xv_end) {
|
||||
*(ii++) += (xvi++)->rvector_value * x.rvector_value;
|
||||
}
|
||||
break;
|
||||
case colvarvalue::type_quaternion:
|
||||
case colvarvalue::type_quaternionderiv:
|
||||
while (xvi != xv_end) {
|
||||
*(ii++) += ((xvi++)->quaternion_value).cosine (x.quaternion_value);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
x.undef_op();
|
||||
};
|
||||
}
|
||||
|
||||
void colvarvalue::inner_opt(colvarvalue const &x,
|
||||
std::list<colvarvalue>::iterator &xv,
|
||||
std::list<colvarvalue>::iterator const &xv_end,
|
||||
std::vector<cvm::real>::iterator &inner)
|
||||
{
|
||||
// doing type check only once, here
|
||||
colvarvalue::check_types(x, *xv);
|
||||
|
||||
std::list<colvarvalue>::iterator &xvi = xv;
|
||||
std::vector<cvm::real>::iterator &ii = inner;
|
||||
|
||||
switch (x.value_type) {
|
||||
case colvarvalue::type_scalar:
|
||||
while (xvi != xv_end) {
|
||||
*(ii++) += (xvi++)->real_value * x.real_value;
|
||||
}
|
||||
break;
|
||||
case colvarvalue::type_vector:
|
||||
case colvarvalue::type_unitvector:
|
||||
case colvarvalue::type_unitvectorderiv:
|
||||
while (xvi != xv_end) {
|
||||
*(ii++) += (xvi++)->rvector_value * x.rvector_value;
|
||||
}
|
||||
break;
|
||||
case colvarvalue::type_quaternion:
|
||||
case colvarvalue::type_quaternionderiv:
|
||||
while (xvi != xv_end) {
|
||||
*(ii++) += ((xvi++)->quaternion_value).cosine (x.quaternion_value);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
x.undef_op();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
void colvarvalue::p2leg_opt(colvarvalue const &x,
|
||||
std::vector<colvarvalue>::iterator &xv,
|
||||
std::vector<colvarvalue>::iterator const &xv_end,
|
||||
std::vector<cvm::real>::iterator &inner)
|
||||
{
|
||||
// doing type check only once, here
|
||||
colvarvalue::check_types(x, *xv);
|
||||
|
||||
std::vector<colvarvalue>::iterator &xvi = xv;
|
||||
std::vector<cvm::real>::iterator &ii = inner;
|
||||
|
||||
switch (x.value_type) {
|
||||
case colvarvalue::type_scalar:
|
||||
cvm::error("Error: cannot calculate Legendre polynomials "
|
||||
"for scalar variables.\n");
|
||||
if (this->value_type != type_vector) {
|
||||
cvm::error("Error: trying to set an element for a variable that is not set to be a vector.\n");
|
||||
return;
|
||||
break;
|
||||
case colvarvalue::type_vector:
|
||||
while (xvi != xv_end) {
|
||||
cvm::real const cosine =
|
||||
((xvi)->rvector_value * x.rvector_value) /
|
||||
((xvi)->rvector_value.norm() * x.rvector_value.norm());
|
||||
xvi++;
|
||||
*(ii++) += 1.5*cosine*cosine - 0.5;
|
||||
}
|
||||
break;
|
||||
case colvarvalue::type_unitvector:
|
||||
case colvarvalue::type_unitvectorderiv:
|
||||
while (xvi != xv_end) {
|
||||
cvm::real const cosine = (xvi++)->rvector_value * x.rvector_value;
|
||||
*(ii++) += 1.5*cosine*cosine - 0.5;
|
||||
size_t const n = vector1d_value.size();
|
||||
size_t const nd = num_dimensions(x.value_type);
|
||||
elem_types.push_back(x.value_type);
|
||||
elem_indices.push_back(n);
|
||||
elem_sizes.push_back(nd);
|
||||
vector1d_value.resize(n + nd);
|
||||
set_elem(n, x);
|
||||
}
|
||||
|
||||
|
||||
colvarvalue const colvarvalue::get_elem(int const i_begin, int const i_end, Type const vt) const
|
||||
{
|
||||
if (vector1d_value.size() > 0) {
|
||||
cvm::vector1d<cvm::real> const v(vector1d_value.slice(i_begin, i_end));
|
||||
return colvarvalue(v, vt);
|
||||
} else {
|
||||
cvm::error("Error: trying to get an element from a variable that is not a vector.\n");
|
||||
return colvarvalue(type_notset);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void colvarvalue::set_elem(int const i_begin, int const i_end, colvarvalue const &x)
|
||||
{
|
||||
if (vector1d_value.size() > 0) {
|
||||
vector1d_value.sliceassign(i_begin, i_end, x.as_vector());
|
||||
} else {
|
||||
cvm::error("Error: trying to set an element for a variable that is not a vector.\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
colvarvalue const colvarvalue::get_elem(int const icv) const
|
||||
{
|
||||
if (elem_types.size() > 0) {
|
||||
return get_elem(elem_indices[icv], elem_indices[icv] + elem_sizes[icv],
|
||||
elem_types[icv]);
|
||||
} else {
|
||||
cvm::error("Error: trying to get a colvarvalue element from a vector colvarvalue that was initialized as a plain array.\n");
|
||||
return colvarvalue(type_notset);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void colvarvalue::set_elem(int const icv, colvarvalue const &x)
|
||||
{
|
||||
if (elem_types.size() > 0) {
|
||||
check_types_assign(elem_types[icv], x.value_type);
|
||||
set_elem(elem_indices[icv], elem_indices[icv] + elem_sizes[icv], x);
|
||||
} else {
|
||||
cvm::error("Error: trying to set a colvarvalue element for a colvarvalue that was initialized as a plain array.\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
colvarvalue colvarvalue::inverse() const
|
||||
{
|
||||
switch (value_type) {
|
||||
case colvarvalue::type_scalar:
|
||||
return colvarvalue(1.0/real_value);
|
||||
break;
|
||||
case colvarvalue::type_3vector:
|
||||
case colvarvalue::type_unit3vector:
|
||||
case colvarvalue::type_unit3vectorderiv:
|
||||
return colvarvalue(cvm::rvector(1.0/rvector_value.x,
|
||||
1.0/rvector_value.y,
|
||||
1.0/rvector_value.z));
|
||||
break;
|
||||
case colvarvalue::type_quaternion:
|
||||
case colvarvalue::type_quaternionderiv:
|
||||
while (xvi != xv_end) {
|
||||
cvm::real const cosine = (xvi++)->quaternion_value.cosine (x.quaternion_value);
|
||||
*(ii++) += 1.5*cosine*cosine - 0.5;
|
||||
return colvarvalue(cvm::quaternion(1.0/quaternion_value.q0,
|
||||
1.0/quaternion_value.q1,
|
||||
1.0/quaternion_value.q2,
|
||||
1.0/quaternion_value.q3));
|
||||
break;
|
||||
case colvarvalue::type_vector:
|
||||
{
|
||||
cvm::vector1d<cvm::real> result(vector1d_value);
|
||||
if (elem_types.size() > 0) {
|
||||
// if we have information about non-scalar types, use it
|
||||
size_t i;
|
||||
for (i = 0; i < elem_types.size(); i++) {
|
||||
result.sliceassign(elem_indices[i], elem_indices[i]+elem_sizes[i],
|
||||
cvm::vector1d<cvm::real>((this->get_elem(i)).inverse()));
|
||||
}
|
||||
} else {
|
||||
size_t i;
|
||||
for (i = 0; i < result.size(); i++) {
|
||||
if (result[i] != 0.0) {
|
||||
result = 1.0/result[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
return colvarvalue(result, type_vector);
|
||||
}
|
||||
break;
|
||||
case colvarvalue::type_notset:
|
||||
default:
|
||||
x.undef_op();
|
||||
undef_op();
|
||||
break;
|
||||
}
|
||||
return colvarvalue();
|
||||
}
|
||||
|
||||
|
||||
// binary operations between two colvarvalues
|
||||
|
||||
colvarvalue operator + (colvarvalue const &x1,
|
||||
colvarvalue const &x2)
|
||||
{
|
||||
colvarvalue::check_types(x1, x2);
|
||||
|
||||
switch (x1.value_type) {
|
||||
case colvarvalue::type_scalar:
|
||||
return colvarvalue(x1.real_value + x2.real_value);
|
||||
case colvarvalue::type_3vector:
|
||||
return colvarvalue(x1.rvector_value + x2.rvector_value);
|
||||
case colvarvalue::type_unit3vector:
|
||||
case colvarvalue::type_unit3vectorderiv:
|
||||
return colvarvalue(x1.rvector_value + x2.rvector_value,
|
||||
colvarvalue::type_unit3vector);
|
||||
case colvarvalue::type_quaternion:
|
||||
case colvarvalue::type_quaternionderiv:
|
||||
return colvarvalue(x1.quaternion_value + x2.quaternion_value);
|
||||
case colvarvalue::type_vector:
|
||||
return colvarvalue(x1.vector1d_value + x2.vector1d_value, colvarvalue::type_vector);
|
||||
case colvarvalue::type_notset:
|
||||
default:
|
||||
x1.undef_op();
|
||||
return colvarvalue(colvarvalue::type_notset);
|
||||
};
|
||||
}
|
||||
|
||||
void colvarvalue::p2leg_opt(colvarvalue const &x,
|
||||
std::list<colvarvalue>::iterator &xv,
|
||||
std::list<colvarvalue>::iterator const &xv_end,
|
||||
std::vector<cvm::real>::iterator &inner)
|
||||
|
||||
colvarvalue operator - (colvarvalue const &x1,
|
||||
colvarvalue const &x2)
|
||||
{
|
||||
// doing type check only once, here
|
||||
colvarvalue::check_types(x, *xv);
|
||||
colvarvalue::check_types(x1, x2);
|
||||
|
||||
std::list<colvarvalue>::iterator &xvi = xv;
|
||||
std::vector<cvm::real>::iterator &ii = inner;
|
||||
switch (x1.value_type) {
|
||||
case colvarvalue::type_scalar:
|
||||
return colvarvalue(x1.real_value - x2.real_value);
|
||||
case colvarvalue::type_3vector:
|
||||
return colvarvalue(x1.rvector_value - x2.rvector_value);
|
||||
case colvarvalue::type_unit3vector:
|
||||
case colvarvalue::type_unit3vectorderiv:
|
||||
return colvarvalue(x1.rvector_value - x2.rvector_value,
|
||||
colvarvalue::type_unit3vector);
|
||||
case colvarvalue::type_quaternion:
|
||||
case colvarvalue::type_quaternionderiv:
|
||||
return colvarvalue(x1.quaternion_value - x2.quaternion_value);
|
||||
case colvarvalue::type_vector:
|
||||
return colvarvalue(x1.vector1d_value - x2.vector1d_value, colvarvalue::type_vector);
|
||||
case colvarvalue::type_notset:
|
||||
default:
|
||||
x1.undef_op();
|
||||
return colvarvalue(colvarvalue::type_notset);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// binary operations with real numbers
|
||||
|
||||
colvarvalue operator * (cvm::real const &a,
|
||||
colvarvalue const &x)
|
||||
{
|
||||
switch (x.value_type) {
|
||||
case colvarvalue::type_scalar:
|
||||
cvm::error("Error: cannot calculate Legendre polynomials "
|
||||
"for scalar variables.\n");
|
||||
break;
|
||||
case colvarvalue::type_vector:
|
||||
while (xvi != xv_end) {
|
||||
cvm::real const cosine =
|
||||
((xvi)->rvector_value * x.rvector_value) /
|
||||
((xvi)->rvector_value.norm() * x.rvector_value.norm());
|
||||
xvi++;
|
||||
*(ii++) += 1.5*cosine*cosine - 0.5;
|
||||
}
|
||||
break;
|
||||
case colvarvalue::type_unitvector:
|
||||
case colvarvalue::type_unitvectorderiv:
|
||||
while (xvi != xv_end) {
|
||||
cvm::real const cosine = (xvi++)->rvector_value * x.rvector_value;
|
||||
*(ii++) += 1.5*cosine*cosine - 0.5;
|
||||
}
|
||||
break;
|
||||
return colvarvalue(a * x.real_value);
|
||||
case colvarvalue::type_3vector:
|
||||
return colvarvalue(a * x.rvector_value);
|
||||
case colvarvalue::type_unit3vector:
|
||||
case colvarvalue::type_unit3vectorderiv:
|
||||
return colvarvalue(a * x.rvector_value,
|
||||
colvarvalue::type_unit3vector);
|
||||
case colvarvalue::type_quaternion:
|
||||
case colvarvalue::type_quaternionderiv:
|
||||
while (xvi != xv_end) {
|
||||
cvm::real const cosine = (xvi++)->quaternion_value.cosine (x.quaternion_value);
|
||||
*(ii++) += 1.5*cosine*cosine - 0.5;
|
||||
}
|
||||
break;
|
||||
return colvarvalue(a * x.quaternion_value);
|
||||
case colvarvalue::type_vector:
|
||||
return colvarvalue(x.vector1d_value * a, colvarvalue::type_vector);
|
||||
case colvarvalue::type_notset:
|
||||
default:
|
||||
x.undef_op();
|
||||
return colvarvalue(colvarvalue::type_notset);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
colvarvalue operator * (colvarvalue const &x,
|
||||
cvm::real const &a)
|
||||
{
|
||||
return a * x;
|
||||
}
|
||||
|
||||
|
||||
colvarvalue operator / (colvarvalue const &x,
|
||||
cvm::real const &a)
|
||||
{
|
||||
switch (x.value_type) {
|
||||
case colvarvalue::type_scalar:
|
||||
return colvarvalue(x.real_value / a);
|
||||
case colvarvalue::type_3vector:
|
||||
return colvarvalue(x.rvector_value / a);
|
||||
case colvarvalue::type_unit3vector:
|
||||
case colvarvalue::type_unit3vectorderiv:
|
||||
return colvarvalue(x.rvector_value / a,
|
||||
colvarvalue::type_unit3vector);
|
||||
case colvarvalue::type_quaternion:
|
||||
case colvarvalue::type_quaternionderiv:
|
||||
return colvarvalue(x.quaternion_value / a);
|
||||
case colvarvalue::type_vector:
|
||||
return colvarvalue(x.vector1d_value / a, colvarvalue::type_vector);
|
||||
case colvarvalue::type_notset:
|
||||
default:
|
||||
x.undef_op();
|
||||
return colvarvalue(colvarvalue::type_notset);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// inner product between two colvarvalues
|
||||
|
||||
cvm::real operator * (colvarvalue const &x1,
|
||||
colvarvalue const &x2)
|
||||
{
|
||||
colvarvalue::check_types(x1, x2);
|
||||
|
||||
switch (x1.value_type) {
|
||||
case colvarvalue::type_scalar:
|
||||
return (x1.real_value * x2.real_value);
|
||||
case colvarvalue::type_3vector:
|
||||
case colvarvalue::type_unit3vector:
|
||||
case colvarvalue::type_unit3vectorderiv:
|
||||
return (x1.rvector_value * x2.rvector_value);
|
||||
case colvarvalue::type_quaternion:
|
||||
case colvarvalue::type_quaternionderiv:
|
||||
// the "*" product is the quaternion product, here the inner
|
||||
// member function is used instead
|
||||
return (x1.quaternion_value.inner(x2.quaternion_value));
|
||||
case colvarvalue::type_vector:
|
||||
return (x1.vector1d_value * x2.vector1d_value);
|
||||
case colvarvalue::type_notset:
|
||||
default:
|
||||
x1.undef_op();
|
||||
return 0.0;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
colvarvalue colvarvalue::dist2_grad(colvarvalue const &x2) const
|
||||
{
|
||||
colvarvalue::check_types(*this, x2);
|
||||
|
||||
switch (this->value_type) {
|
||||
case colvarvalue::type_scalar:
|
||||
return 2.0 * (this->real_value - x2.real_value);
|
||||
case colvarvalue::type_3vector:
|
||||
return 2.0 * (this->rvector_value - x2.rvector_value);
|
||||
case colvarvalue::type_unit3vector:
|
||||
case colvarvalue::type_unit3vectorderiv:
|
||||
{
|
||||
cvm::rvector const &v1 = this->rvector_value;
|
||||
cvm::rvector const &v2 = x2.rvector_value;
|
||||
cvm::real const cos_t = v1 * v2;
|
||||
cvm::real const sin_t = std::sqrt(1.0 - cos_t*cos_t);
|
||||
return colvarvalue( 2.0 * sin_t *
|
||||
cvm::rvector((-1.0) * sin_t * v2.x +
|
||||
cos_t/sin_t * (v1.x - cos_t*v2.x),
|
||||
(-1.0) * sin_t * v2.y +
|
||||
cos_t/sin_t * (v1.y - cos_t*v2.y),
|
||||
(-1.0) * sin_t * v2.z +
|
||||
cos_t/sin_t * (v1.z - cos_t*v2.z)
|
||||
),
|
||||
colvarvalue::type_unit3vector );
|
||||
}
|
||||
case colvarvalue::type_quaternion:
|
||||
case colvarvalue::type_quaternionderiv:
|
||||
return this->quaternion_value.dist2_grad(x2.quaternion_value);
|
||||
case colvarvalue::type_vector:
|
||||
return colvarvalue(2.0 * (this->vector1d_value - x2.vector1d_value), colvarvalue::type_vector);
|
||||
break;
|
||||
case colvarvalue::type_notset:
|
||||
default:
|
||||
this->undef_op();
|
||||
return colvarvalue(colvarvalue::type_notset);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
std::string colvarvalue::to_simple_string() const
|
||||
{
|
||||
switch (type()) {
|
||||
case colvarvalue::type_scalar:
|
||||
return cvm::to_str(real_value, 0, cvm::cv_prec);
|
||||
break;
|
||||
case colvarvalue::type_3vector:
|
||||
case colvarvalue::type_unit3vector:
|
||||
case colvarvalue::type_unit3vectorderiv:
|
||||
return rvector_value.to_simple_string();
|
||||
break;
|
||||
case colvarvalue::type_quaternion:
|
||||
case colvarvalue::type_quaternionderiv:
|
||||
return quaternion_value.to_simple_string();
|
||||
break;
|
||||
case colvarvalue::type_vector:
|
||||
return vector1d_value.to_simple_string();
|
||||
break;
|
||||
case colvarvalue::type_notset:
|
||||
default:
|
||||
undef_op();
|
||||
break;
|
||||
}
|
||||
return std::string();
|
||||
}
|
||||
|
||||
|
||||
int colvarvalue::from_simple_string(std::string const &s)
|
||||
{
|
||||
switch (type()) {
|
||||
case colvarvalue::type_scalar:
|
||||
return ((std::istringstream(s) >> real_value)
|
||||
? COLVARS_OK : COLVARS_ERROR);
|
||||
break;
|
||||
case colvarvalue::type_3vector:
|
||||
case colvarvalue::type_unit3vector:
|
||||
case colvarvalue::type_unit3vectorderiv:
|
||||
return rvector_value.from_simple_string(s);
|
||||
break;
|
||||
case colvarvalue::type_quaternion:
|
||||
case colvarvalue::type_quaternionderiv:
|
||||
return quaternion_value.from_simple_string(s);
|
||||
break;
|
||||
case colvarvalue::type_vector:
|
||||
return vector1d_value.from_simple_string(s);
|
||||
break;
|
||||
case colvarvalue::type_notset:
|
||||
default:
|
||||
undef_op();
|
||||
break;
|
||||
}
|
||||
return COLVARS_ERROR;
|
||||
}
|
||||
|
||||
std::ostream & operator << (std::ostream &os, colvarvalue const &x)
|
||||
{
|
||||
switch (x.type()) {
|
||||
case colvarvalue::type_scalar:
|
||||
os << x.real_value;
|
||||
break;
|
||||
case colvarvalue::type_vector:
|
||||
case colvarvalue::type_unitvector:
|
||||
case colvarvalue::type_unitvectorderiv:
|
||||
case colvarvalue::type_3vector:
|
||||
case colvarvalue::type_unit3vector:
|
||||
case colvarvalue::type_unit3vectorderiv:
|
||||
os << x.rvector_value;
|
||||
break;
|
||||
case colvarvalue::type_quaternion:
|
||||
case colvarvalue::type_quaternionderiv:
|
||||
os << x.quaternion_value;
|
||||
break;
|
||||
case colvarvalue::type_vector:
|
||||
os << x.vector1d_value;
|
||||
break;
|
||||
case colvarvalue::type_notset:
|
||||
os << "not set"; break;
|
||||
default:
|
||||
os << "not set";
|
||||
break;
|
||||
}
|
||||
return os;
|
||||
}
|
||||
@ -239,7 +387,8 @@ std::ostream & operator << (std::ostream &os, colvarvalue const &x)
|
||||
|
||||
std::ostream & operator << (std::ostream &os, std::vector<colvarvalue> const &v)
|
||||
{
|
||||
for (size_t i = 0; i < v.size(); i++) {
|
||||
size_t i;
|
||||
for (i = 0; i < v.size(); i++) {
|
||||
os << v[i];
|
||||
}
|
||||
return os;
|
||||
@ -258,11 +407,11 @@ std::istream & operator >> (std::istream &is, colvarvalue &x)
|
||||
case colvarvalue::type_scalar:
|
||||
is >> x.real_value;
|
||||
break;
|
||||
case colvarvalue::type_vector:
|
||||
case colvarvalue::type_unitvectorderiv:
|
||||
case colvarvalue::type_3vector:
|
||||
case colvarvalue::type_unit3vectorderiv:
|
||||
is >> x.rvector_value;
|
||||
break;
|
||||
case colvarvalue::type_unitvector:
|
||||
case colvarvalue::type_unit3vector:
|
||||
is >> x.rvector_value;
|
||||
x.apply_constraints();
|
||||
break;
|
||||
@ -273,6 +422,10 @@ std::istream & operator >> (std::istream &is, colvarvalue &x)
|
||||
case colvarvalue::type_quaternionderiv:
|
||||
is >> x.quaternion_value;
|
||||
break;
|
||||
case colvarvalue::type_vector:
|
||||
is >> x.vector1d_value;
|
||||
break;
|
||||
case colvarvalue::type_notset:
|
||||
default:
|
||||
x.undef_op();
|
||||
}
|
||||
@ -285,13 +438,16 @@ size_t colvarvalue::output_width(size_t const &real_width) const
|
||||
switch (this->value_type) {
|
||||
case colvarvalue::type_scalar:
|
||||
return real_width;
|
||||
case colvarvalue::type_vector:
|
||||
case colvarvalue::type_unitvector:
|
||||
case colvarvalue::type_unitvectorderiv:
|
||||
case colvarvalue::type_3vector:
|
||||
case colvarvalue::type_unit3vector:
|
||||
case colvarvalue::type_unit3vectorderiv:
|
||||
return cvm::rvector::output_width(real_width);
|
||||
case colvarvalue::type_quaternion:
|
||||
case colvarvalue::type_quaternionderiv:
|
||||
return cvm::quaternion::output_width(real_width);
|
||||
case colvarvalue::type_vector:
|
||||
// note how this depends on the vector's size
|
||||
return vector1d_value.output_width(real_width);
|
||||
case colvarvalue::type_notset:
|
||||
default:
|
||||
return 0;
|
||||
@ -299,3 +455,186 @@ size_t colvarvalue::output_width(size_t const &real_width) const
|
||||
}
|
||||
|
||||
|
||||
void colvarvalue::inner_opt(colvarvalue const &x,
|
||||
std::vector<colvarvalue>::iterator &xv,
|
||||
std::vector<colvarvalue>::iterator const &xv_end,
|
||||
std::vector<cvm::real>::iterator &result)
|
||||
{
|
||||
// doing type check only once, here
|
||||
colvarvalue::check_types(x, *xv);
|
||||
|
||||
std::vector<colvarvalue>::iterator &xvi = xv;
|
||||
std::vector<cvm::real>::iterator &ii = result;
|
||||
|
||||
switch (x.value_type) {
|
||||
case colvarvalue::type_scalar:
|
||||
while (xvi != xv_end) {
|
||||
*(ii++) += (xvi++)->real_value * x.real_value;
|
||||
}
|
||||
break;
|
||||
case colvarvalue::type_3vector:
|
||||
case colvarvalue::type_unit3vector:
|
||||
case colvarvalue::type_unit3vectorderiv:
|
||||
while (xvi != xv_end) {
|
||||
*(ii++) += (xvi++)->rvector_value * x.rvector_value;
|
||||
}
|
||||
break;
|
||||
case colvarvalue::type_quaternion:
|
||||
case colvarvalue::type_quaternionderiv:
|
||||
while (xvi != xv_end) {
|
||||
*(ii++) += ((xvi++)->quaternion_value).cosine(x.quaternion_value);
|
||||
}
|
||||
break;
|
||||
case colvarvalue::type_vector:
|
||||
while (xvi != xv_end) {
|
||||
*(ii++) += (xvi++)->vector1d_value * x.vector1d_value;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
x.undef_op();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
void colvarvalue::inner_opt(colvarvalue const &x,
|
||||
std::list<colvarvalue>::iterator &xv,
|
||||
std::list<colvarvalue>::iterator const &xv_end,
|
||||
std::vector<cvm::real>::iterator &result)
|
||||
{
|
||||
// doing type check only once, here
|
||||
colvarvalue::check_types(x, *xv);
|
||||
|
||||
std::list<colvarvalue>::iterator &xvi = xv;
|
||||
std::vector<cvm::real>::iterator &ii = result;
|
||||
|
||||
switch (x.value_type) {
|
||||
case colvarvalue::type_scalar:
|
||||
while (xvi != xv_end) {
|
||||
*(ii++) += (xvi++)->real_value * x.real_value;
|
||||
}
|
||||
break;
|
||||
case colvarvalue::type_3vector:
|
||||
case colvarvalue::type_unit3vector:
|
||||
case colvarvalue::type_unit3vectorderiv:
|
||||
while (xvi != xv_end) {
|
||||
*(ii++) += (xvi++)->rvector_value * x.rvector_value;
|
||||
}
|
||||
break;
|
||||
case colvarvalue::type_quaternion:
|
||||
case colvarvalue::type_quaternionderiv:
|
||||
while (xvi != xv_end) {
|
||||
*(ii++) += ((xvi++)->quaternion_value).cosine(x.quaternion_value);
|
||||
}
|
||||
break;
|
||||
case colvarvalue::type_vector:
|
||||
while (xvi != xv_end) {
|
||||
*(ii++) += (xvi++)->vector1d_value * x.vector1d_value;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
x.undef_op();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
void colvarvalue::p2leg_opt(colvarvalue const &x,
|
||||
std::vector<colvarvalue>::iterator &xv,
|
||||
std::vector<colvarvalue>::iterator const &xv_end,
|
||||
std::vector<cvm::real>::iterator &result)
|
||||
{
|
||||
// doing type check only once, here
|
||||
colvarvalue::check_types(x, *xv);
|
||||
|
||||
std::vector<colvarvalue>::iterator &xvi = xv;
|
||||
std::vector<cvm::real>::iterator &ii = result;
|
||||
|
||||
switch (x.value_type) {
|
||||
case colvarvalue::type_scalar:
|
||||
cvm::error("Error: cannot calculate Legendre polynomials "
|
||||
"for scalar variables.\n");
|
||||
return;
|
||||
break;
|
||||
case colvarvalue::type_3vector:
|
||||
while (xvi != xv_end) {
|
||||
cvm::real const cosine =
|
||||
((xvi)->rvector_value * x.rvector_value) /
|
||||
((xvi)->rvector_value.norm() * x.rvector_value.norm());
|
||||
xvi++;
|
||||
*(ii++) += 1.5*cosine*cosine - 0.5;
|
||||
}
|
||||
break;
|
||||
case colvarvalue::type_unit3vector:
|
||||
case colvarvalue::type_unit3vectorderiv:
|
||||
while (xvi != xv_end) {
|
||||
cvm::real const cosine = (xvi++)->rvector_value * x.rvector_value;
|
||||
*(ii++) += 1.5*cosine*cosine - 0.5;
|
||||
}
|
||||
break;
|
||||
case colvarvalue::type_quaternion:
|
||||
case colvarvalue::type_quaternionderiv:
|
||||
while (xvi != xv_end) {
|
||||
cvm::real const cosine = (xvi++)->quaternion_value.cosine(x.quaternion_value);
|
||||
*(ii++) += 1.5*cosine*cosine - 0.5;
|
||||
}
|
||||
break;
|
||||
case colvarvalue::type_vector:
|
||||
while (xvi != xv_end) {
|
||||
cvm::real const cosine =
|
||||
((xvi)->vector1d_value * x.vector1d_value) /
|
||||
((xvi)->vector1d_value.norm() * x.rvector_value.norm());
|
||||
xvi++;
|
||||
*(ii++) += 1.5*cosine*cosine - 0.5;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
x.undef_op();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
void colvarvalue::p2leg_opt(colvarvalue const &x,
|
||||
std::list<colvarvalue>::iterator &xv,
|
||||
std::list<colvarvalue>::iterator const &xv_end,
|
||||
std::vector<cvm::real>::iterator &result)
|
||||
{
|
||||
// doing type check only once, here
|
||||
colvarvalue::check_types(x, *xv);
|
||||
|
||||
std::list<colvarvalue>::iterator &xvi = xv;
|
||||
std::vector<cvm::real>::iterator &ii = result;
|
||||
|
||||
switch (x.value_type) {
|
||||
case colvarvalue::type_scalar:
|
||||
cvm::error("Error: cannot calculate Legendre polynomials "
|
||||
"for scalar variables.\n");
|
||||
break;
|
||||
case colvarvalue::type_3vector:
|
||||
while (xvi != xv_end) {
|
||||
cvm::real const cosine =
|
||||
((xvi)->rvector_value * x.rvector_value) /
|
||||
((xvi)->rvector_value.norm() * x.rvector_value.norm());
|
||||
xvi++;
|
||||
*(ii++) += 1.5*cosine*cosine - 0.5;
|
||||
}
|
||||
break;
|
||||
case colvarvalue::type_unit3vector:
|
||||
case colvarvalue::type_unit3vectorderiv:
|
||||
while (xvi != xv_end) {
|
||||
cvm::real const cosine = (xvi++)->rvector_value * x.rvector_value;
|
||||
*(ii++) += 1.5*cosine*cosine - 0.5;
|
||||
}
|
||||
break;
|
||||
case colvarvalue::type_quaternion:
|
||||
case colvarvalue::type_quaternionderiv:
|
||||
while (xvi != xv_end) {
|
||||
cvm::real const cosine = (xvi++)->quaternion_value.cosine(x.quaternion_value);
|
||||
*(ii++) += 1.5*cosine*cosine - 0.5;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
x.undef_op();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user