More robust change from initial to target restraint centers in Colvars
This commit is contained in:
Binary file not shown.
@ -32,7 +32,7 @@ where Makefile.g++ uses the GNU C++ compiler and is a good template to start.
|
||||
|
||||
**Optional**: if you use the Install.py script provided in this folder, you
|
||||
can give the machine name as the '-m' argument. This can be the suffix of one
|
||||
of the files from either this folder, or from src/MAKE.
|
||||
of the files from either this folder, or from src/MAKE/MACHINES.
|
||||
*This is only supported by the Install.py within the lib/colvars folder*.
|
||||
|
||||
When you are done building this library, two files should
|
||||
@ -53,10 +53,10 @@ settings in Makefile.common should work.
|
||||
For the reference manual see:
|
||||
http://colvars.github.io/colvars-refman-lammps
|
||||
|
||||
A copy of reference manual is also in:
|
||||
A copy of the reference manual is also in:
|
||||
doc/PDF/colvars-refman-lammps.pdf
|
||||
|
||||
Also included is a Doxygen-based developer documentation:
|
||||
Also available is a Doxygen-based developer documentation:
|
||||
http://colvars.github.io/doxygen/html/
|
||||
|
||||
The reference article is:
|
||||
|
||||
@ -88,7 +88,12 @@ public:
|
||||
static std::vector<feature *> cv_features;
|
||||
|
||||
/// \brief Implementation of the feature list accessor for colvar
|
||||
std::vector<feature *> &features() {
|
||||
virtual const std::vector<feature *> &features()
|
||||
{
|
||||
return cv_features;
|
||||
}
|
||||
virtual std::vector<feature *> &modify_features()
|
||||
{
|
||||
return cv_features;
|
||||
}
|
||||
|
||||
|
||||
@ -206,7 +206,12 @@ public:
|
||||
static std::vector<feature *> ag_features;
|
||||
|
||||
/// \brief Implementation of the feature list accessor for atom group
|
||||
virtual std::vector<feature *> &features() {
|
||||
virtual const std::vector<feature *> &features()
|
||||
{
|
||||
return ag_features;
|
||||
}
|
||||
virtual std::vector<feature *> &modify_features()
|
||||
{
|
||||
return ag_features;
|
||||
}
|
||||
|
||||
|
||||
@ -384,6 +384,7 @@ std::ostream & colvarbias::write_traj(std::ostream &os)
|
||||
os << " ";
|
||||
if (b_output_energy)
|
||||
os << " "
|
||||
<< std::setprecision(cvm::en_prec) << std::setw(cvm::en_width)
|
||||
<< bias_energy;
|
||||
return os;
|
||||
}
|
||||
|
||||
@ -175,7 +175,11 @@ public:
|
||||
static std::vector<feature *> cvb_features;
|
||||
|
||||
/// \brief Implementation of the feature list accessor for colvarbias
|
||||
virtual std::vector<feature *> &features()
|
||||
virtual const std::vector<feature *> &features()
|
||||
{
|
||||
return cvb_features;
|
||||
}
|
||||
virtual std::vector<feature *> &modify_features()
|
||||
{
|
||||
return cvb_features;
|
||||
}
|
||||
|
||||
@ -99,12 +99,9 @@ int colvarbias_restraint_centers::init(std::string const &conf)
|
||||
if (null_centers) {
|
||||
// try to initialize the restraint centers for the first time
|
||||
colvar_centers.resize(num_variables());
|
||||
colvar_centers_raw.resize(num_variables());
|
||||
for (i = 0; i < num_variables(); i++) {
|
||||
colvar_centers[i].type(variables(i)->value());
|
||||
colvar_centers[i].reset();
|
||||
colvar_centers_raw[i].type(variables(i)->value());
|
||||
colvar_centers_raw[i].reset();
|
||||
}
|
||||
}
|
||||
|
||||
@ -113,7 +110,6 @@ int colvarbias_restraint_centers::init(std::string const &conf)
|
||||
if (cvm::debug()) {
|
||||
cvm::log("colvarbias_restraint: parsing initial centers, i = "+cvm::to_str(i)+".\n");
|
||||
}
|
||||
colvar_centers_raw[i] = colvar_centers[i];
|
||||
colvar_centers[i].apply_constraints();
|
||||
}
|
||||
null_centers = false;
|
||||
@ -141,8 +137,6 @@ int colvarbias_restraint_centers::change_configuration(std::string const &conf)
|
||||
for (size_t i = 0; i < num_variables(); i++) {
|
||||
colvar_centers[i].type(variables(i)->value());
|
||||
colvar_centers[i].apply_constraints();
|
||||
colvar_centers_raw[i].type(variables(i)->value());
|
||||
colvar_centers_raw[i] = colvar_centers[i];
|
||||
}
|
||||
}
|
||||
return COLVARS_OK;
|
||||
@ -232,7 +226,6 @@ int colvarbias_restraint_moving::set_state_params(std::string const &conf)
|
||||
{
|
||||
if (b_chg_centers || b_chg_force_k) {
|
||||
if (target_nstages) {
|
||||
// cvm::log ("Reading current stage from the restart.\n");
|
||||
if (!get_keyval(conf, "stage", stage))
|
||||
cvm::error("Error: current stage is missing from the restart.\n");
|
||||
}
|
||||
@ -265,100 +258,127 @@ int colvarbias_restraint_centers_moving::init(std::string const &conf)
|
||||
|
||||
size_t i;
|
||||
if (get_keyval(conf, "targetCenters", target_centers, colvar_centers)) {
|
||||
if (colvar_centers.size() != num_variables()) {
|
||||
if (target_centers.size() != num_variables()) {
|
||||
cvm::error("Error: number of target centers does not match "
|
||||
"that of collective variables.\n");
|
||||
"that of collective variables.\n", INPUT_ERROR);
|
||||
}
|
||||
b_chg_centers = true;
|
||||
for (i = 0; i < target_centers.size(); i++) {
|
||||
target_centers[i].apply_constraints();
|
||||
centers_incr.push_back(colvar_centers[i]);
|
||||
centers_incr[i].reset();
|
||||
}
|
||||
}
|
||||
|
||||
if (b_chg_centers) {
|
||||
// parse moving restraint options
|
||||
// parse moving schedule options
|
||||
colvarbias_restraint_moving::init(conf);
|
||||
if (initial_centers.size() == 0) {
|
||||
// One-time init
|
||||
initial_centers = colvar_centers;
|
||||
}
|
||||
// Call to check that the definition is correct
|
||||
for (i = 0; i < num_variables(); i++) {
|
||||
colvarvalue const midpoint =
|
||||
colvarvalue::interpolate(initial_centers[i],
|
||||
target_centers[i],
|
||||
0.5);
|
||||
}
|
||||
} else {
|
||||
target_centers.clear();
|
||||
return COLVARS_OK;
|
||||
}
|
||||
|
||||
get_keyval(conf, "outputCenters", b_output_centers, b_output_centers);
|
||||
get_keyval(conf, "outputAccumulatedWork", b_output_acc_work, b_output_acc_work);
|
||||
get_keyval(conf, "outputAccumulatedWork", b_output_acc_work,
|
||||
b_output_acc_work); // TODO this conflicts with stages
|
||||
|
||||
return COLVARS_OK;
|
||||
}
|
||||
|
||||
|
||||
int colvarbias_restraint_centers_moving::update_centers(cvm::real lambda)
|
||||
{
|
||||
if (cvm::debug()) {
|
||||
cvm::log("Updating centers for the restraint bias \""+
|
||||
this->name+"\": "+cvm::to_str(colvar_centers)+".\n");
|
||||
}
|
||||
size_t i;
|
||||
for (i = 0; i < num_variables(); i++) {
|
||||
colvarvalue const c_new = colvarvalue::interpolate(initial_centers[i],
|
||||
target_centers[i],
|
||||
lambda);
|
||||
centers_incr[i] = (c_new).dist2_grad(colvar_centers[i]);
|
||||
colvar_centers[i] = c_new;
|
||||
variables(i)->wrap(colvar_centers[i]);
|
||||
}
|
||||
if (cvm::debug()) {
|
||||
cvm::log("New centers for the restraint bias \""+
|
||||
this->name+"\": "+cvm::to_str(colvar_centers)+".\n");
|
||||
}
|
||||
return cvm::get_error();
|
||||
}
|
||||
|
||||
|
||||
int colvarbias_restraint_centers_moving::update()
|
||||
{
|
||||
if (b_chg_centers) {
|
||||
|
||||
if (cvm::debug()) {
|
||||
cvm::log("Updating centers for the restraint bias \""+
|
||||
this->name+"\": "+cvm::to_str(colvar_centers)+".\n");
|
||||
}
|
||||
|
||||
if (!centers_incr.size()) {
|
||||
// if this is the first calculation, calculate the advancement
|
||||
// at each simulation step (or stage, if applicable)
|
||||
// (take current stage into account: it can be non-zero
|
||||
// if we are restarting a staged calculation)
|
||||
centers_incr.resize(num_variables());
|
||||
for (size_t i = 0; i < num_variables(); i++) {
|
||||
centers_incr[i].type(variables(i)->value());
|
||||
centers_incr[i] = (target_centers[i] - colvar_centers_raw[i]) /
|
||||
cvm::real( target_nstages ? (target_nstages - stage) :
|
||||
(target_nsteps - cvm::step_absolute()));
|
||||
}
|
||||
if (cvm::debug()) {
|
||||
cvm::log("Center increment for the restraint bias \""+
|
||||
this->name+"\": "+cvm::to_str(centers_incr)+" at stage "+cvm::to_str(stage)+ ".\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (target_nstages) {
|
||||
if ((cvm::step_relative() > 0)
|
||||
&& (cvm::step_absolute() % target_nsteps) == 0
|
||||
&& stage < target_nstages) {
|
||||
|
||||
for (size_t i = 0; i < num_variables(); i++) {
|
||||
colvar_centers_raw[i] += centers_incr[i];
|
||||
colvar_centers[i] = colvar_centers_raw[i];
|
||||
variables(i)->wrap(colvar_centers[i]);
|
||||
colvar_centers[i].apply_constraints();
|
||||
}
|
||||
// Staged update
|
||||
if (stage <= target_nstages) {
|
||||
if ((cvm::step_relative() > 0) &&
|
||||
((cvm::step_absolute() % target_nsteps) == 1)) {
|
||||
cvm::real const lambda =
|
||||
cvm::real(stage)/cvm::real(target_nstages);
|
||||
update_centers(lambda);
|
||||
stage++;
|
||||
cvm::log("Moving restraint \"" + this->name +
|
||||
"\" stage " + cvm::to_str(stage) +
|
||||
" : setting centers to " + cvm::to_str(colvar_centers) +
|
||||
" at step " + cvm::to_str(cvm::step_absolute()));
|
||||
}
|
||||
} else if ((cvm::step_relative() > 0) && (cvm::step_absolute() <= target_nsteps)) {
|
||||
// move the restraint centers in the direction of the targets
|
||||
// (slow growth)
|
||||
} else {
|
||||
for (size_t i = 0; i < num_variables(); i++) {
|
||||
colvar_centers_raw[i] += centers_incr[i];
|
||||
colvar_centers[i] = colvar_centers_raw[i];
|
||||
variables(i)->wrap(colvar_centers[i]);
|
||||
colvar_centers[i].apply_constraints();
|
||||
centers_incr[i].reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Continuous update
|
||||
if (cvm::step_absolute() <= target_nsteps) {
|
||||
cvm::real const lambda =
|
||||
cvm::real(cvm::step_absolute())/cvm::real(target_nsteps);
|
||||
update_centers(lambda);
|
||||
} else {
|
||||
for (size_t i = 0; i < num_variables(); i++) {
|
||||
centers_incr[i].reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cvm::step_relative() == 0) {
|
||||
for (size_t i = 0; i < num_variables(); i++) {
|
||||
// finite differences are undefined when restarting
|
||||
centers_incr[i].reset();
|
||||
}
|
||||
}
|
||||
|
||||
if (cvm::debug()) {
|
||||
cvm::log("New centers for the restraint bias \""+
|
||||
this->name+"\": "+cvm::to_str(colvar_centers)+".\n");
|
||||
cvm::log("Center increment for the restraint bias \""+
|
||||
this->name+"\": "+cvm::to_str(centers_incr)+
|
||||
" at stage "+cvm::to_str(stage)+ ".\n");
|
||||
}
|
||||
}
|
||||
|
||||
return COLVARS_OK;
|
||||
return cvm::get_error();
|
||||
}
|
||||
|
||||
|
||||
int colvarbias_restraint_centers_moving::update_acc_work()
|
||||
{
|
||||
if (b_output_acc_work) {
|
||||
if ((cvm::step_relative() > 0) || (cvm::step_absolute() == 0)) {
|
||||
if ((cvm::step_relative() > 0) &&
|
||||
(cvm::step_absolute() <= target_nsteps)) {
|
||||
for (size_t i = 0; i < num_variables(); i++) {
|
||||
// project forces on the calculated increments at this step
|
||||
acc_work += colvar_forces[i] * centers_incr[i];
|
||||
@ -383,13 +403,6 @@ std::string const colvarbias_restraint_centers_moving::get_state_params() const
|
||||
<< colvar_centers[i];
|
||||
}
|
||||
os << "\n";
|
||||
os << "centers_raw ";
|
||||
for (i = 0; i < num_variables(); i++) {
|
||||
os << " "
|
||||
<< std::setprecision(cvm::cv_prec) << std::setw(cvm::cv_width)
|
||||
<< colvar_centers_raw[i];
|
||||
}
|
||||
os << "\n";
|
||||
|
||||
if (b_output_acc_work) {
|
||||
os << "accumulatedWork "
|
||||
@ -398,7 +411,7 @@ std::string const colvarbias_restraint_centers_moving::get_state_params() const
|
||||
}
|
||||
}
|
||||
|
||||
return colvarbias_restraint_moving::get_state_params() + os.str();
|
||||
return os.str();
|
||||
}
|
||||
|
||||
|
||||
@ -410,8 +423,6 @@ int colvarbias_restraint_centers_moving::set_state_params(std::string const &con
|
||||
// cvm::log ("Reading the updated restraint centers from the restart.\n");
|
||||
if (!get_keyval(conf, "centers", colvar_centers))
|
||||
cvm::error("Error: restraint centers are missing from the restart.\n");
|
||||
if (!get_keyval(conf, "centers_raw", colvar_centers_raw))
|
||||
cvm::error("Error: \"raw\" restraint centers are missing from the restart.\n");
|
||||
if (b_output_acc_work) {
|
||||
if (!get_keyval(conf, "accumulatedWork", acc_work))
|
||||
cvm::error("Error: accumulatedWork is missing from the restart.\n");
|
||||
@ -609,7 +620,7 @@ std::string const colvarbias_restraint_k_moving::get_state_params() const
|
||||
<< std::setprecision(cvm::en_prec)
|
||||
<< std::setw(cvm::en_width) << force_k << "\n";
|
||||
}
|
||||
return colvarbias_restraint_moving::get_state_params() + os.str();
|
||||
return os.str();
|
||||
}
|
||||
|
||||
|
||||
@ -770,6 +781,7 @@ cvm::real colvarbias_restraint_harmonic::d_restraint_potential_dk(size_t i) cons
|
||||
std::string const colvarbias_restraint_harmonic::get_state_params() const
|
||||
{
|
||||
return colvarbias_restraint::get_state_params() +
|
||||
colvarbias_restraint_moving::get_state_params() +
|
||||
colvarbias_restraint_centers_moving::get_state_params() +
|
||||
colvarbias_restraint_k_moving::get_state_params();
|
||||
}
|
||||
@ -779,6 +791,7 @@ int colvarbias_restraint_harmonic::set_state_params(std::string const &conf)
|
||||
{
|
||||
int error_code = COLVARS_OK;
|
||||
error_code |= colvarbias_restraint::set_state_params(conf);
|
||||
error_code |= colvarbias_restraint_moving::set_state_params(conf);
|
||||
error_code |= colvarbias_restraint_centers_moving::set_state_params(conf);
|
||||
error_code |= colvarbias_restraint_k_moving::set_state_params(conf);
|
||||
return error_code;
|
||||
@ -1037,6 +1050,7 @@ cvm::real colvarbias_restraint_harmonic_walls::d_restraint_potential_dk(size_t i
|
||||
std::string const colvarbias_restraint_harmonic_walls::get_state_params() const
|
||||
{
|
||||
return colvarbias_restraint::get_state_params() +
|
||||
colvarbias_restraint_moving::get_state_params() +
|
||||
colvarbias_restraint_k_moving::get_state_params();
|
||||
}
|
||||
|
||||
@ -1045,6 +1059,7 @@ int colvarbias_restraint_harmonic_walls::set_state_params(std::string const &con
|
||||
{
|
||||
int error_code = COLVARS_OK;
|
||||
error_code |= colvarbias_restraint::set_state_params(conf);
|
||||
error_code |= colvarbias_restraint_moving::set_state_params(conf);
|
||||
error_code |= colvarbias_restraint_k_moving::set_state_params(conf);
|
||||
return error_code;
|
||||
}
|
||||
@ -1164,6 +1179,7 @@ cvm::real colvarbias_restraint_linear::d_restraint_potential_dk(size_t i) const
|
||||
std::string const colvarbias_restraint_linear::get_state_params() const
|
||||
{
|
||||
return colvarbias_restraint::get_state_params() +
|
||||
colvarbias_restraint_moving::get_state_params() +
|
||||
colvarbias_restraint_centers_moving::get_state_params() +
|
||||
colvarbias_restraint_k_moving::get_state_params();
|
||||
}
|
||||
@ -1173,6 +1189,7 @@ int colvarbias_restraint_linear::set_state_params(std::string const &conf)
|
||||
{
|
||||
int error_code = COLVARS_OK;
|
||||
error_code |= colvarbias_restraint::set_state_params(conf);
|
||||
error_code |= colvarbias_restraint_moving::set_state_params(conf);
|
||||
error_code |= colvarbias_restraint_centers_moving::set_state_params(conf);
|
||||
error_code |= colvarbias_restraint_k_moving::set_state_params(conf);
|
||||
return error_code;
|
||||
|
||||
@ -74,9 +74,6 @@ protected:
|
||||
|
||||
/// \brief Restraint centers
|
||||
std::vector<colvarvalue> colvar_centers;
|
||||
|
||||
/// \brief Restraint centers outside the domain of the colvars (no wrapping or constraints applied)
|
||||
std::vector<colvarvalue> colvar_centers_raw;
|
||||
};
|
||||
|
||||
|
||||
@ -156,10 +153,16 @@ protected:
|
||||
/// \brief New restraint centers
|
||||
std::vector<colvarvalue> target_centers;
|
||||
|
||||
/// \brief Initial value of the restraint centers
|
||||
std::vector<colvarvalue> initial_centers;
|
||||
|
||||
/// \brief Amplitude of the restraint centers' increment at each step
|
||||
/// (or stage) towards the new values (calculated from target_nsteps)
|
||||
/// towards the new values (calculated from target_nsteps)
|
||||
std::vector<colvarvalue> centers_incr;
|
||||
|
||||
/// \brief Update the centers by interpolating between initial and target
|
||||
virtual int update_centers(cvm::real lambda);
|
||||
|
||||
/// Whether to write the current restraint centers to the trajectory file
|
||||
bool b_output_centers;
|
||||
|
||||
|
||||
@ -132,9 +132,15 @@ public:
|
||||
static std::vector<feature *> cvc_features;
|
||||
|
||||
/// \brief Implementation of the feature list accessor for colvar
|
||||
virtual std::vector<feature *> &features() {
|
||||
virtual const std::vector<feature *> &features()
|
||||
{
|
||||
return cvc_features;
|
||||
}
|
||||
virtual std::vector<feature *> &modify_features()
|
||||
{
|
||||
return cvc_features;
|
||||
}
|
||||
|
||||
|
||||
/// \brief Obtain data needed for the calculation for the backend
|
||||
virtual void read_data();
|
||||
|
||||
@ -374,8 +374,8 @@ int colvardeps::decr_ref_count(int feature_id) {
|
||||
}
|
||||
|
||||
void colvardeps::init_feature(int feature_id, const char *description, feature_type type) {
|
||||
features()[feature_id]->description = description;
|
||||
features()[feature_id]->type = type;
|
||||
modify_features()[feature_id]->description = description;
|
||||
modify_features()[feature_id]->type = type;
|
||||
}
|
||||
|
||||
// Shorthand macros for describing dependencies
|
||||
@ -401,7 +401,7 @@ void colvardeps::init_cvb_requires() {
|
||||
int i;
|
||||
if (features().size() == 0) {
|
||||
for (i = 0; i < f_cvb_ntot; i++) {
|
||||
features().push_back(new feature);
|
||||
modify_features().push_back(new feature);
|
||||
}
|
||||
|
||||
init_feature(f_cvb_active, "active", f_type_dynamic);
|
||||
@ -438,7 +438,7 @@ void colvardeps::init_cv_requires() {
|
||||
size_t i;
|
||||
if (features().size() == 0) {
|
||||
for (i = 0; i < f_cv_ntot; i++) {
|
||||
features().push_back(new feature);
|
||||
modify_features().push_back(new feature);
|
||||
}
|
||||
|
||||
init_feature(f_cv_active, "active", f_type_dynamic);
|
||||
@ -554,7 +554,7 @@ void colvardeps::init_cvc_requires() {
|
||||
// Initialize static array once and for all
|
||||
if (features().size() == 0) {
|
||||
for (i = 0; i < colvardeps::f_cvc_ntot; i++) {
|
||||
features().push_back(new feature);
|
||||
modify_features().push_back(new feature);
|
||||
}
|
||||
|
||||
init_feature(f_cvc_active, "active", f_type_dynamic);
|
||||
@ -633,7 +633,7 @@ void colvardeps::init_ag_requires() {
|
||||
// Initialize static array once and for all
|
||||
if (features().size() == 0) {
|
||||
for (i = 0; i < f_ag_ntot; i++) {
|
||||
features().push_back(new feature);
|
||||
modify_features().push_back(new feature);
|
||||
}
|
||||
|
||||
init_feature(f_ag_active, "active", f_type_dynamic);
|
||||
|
||||
@ -135,7 +135,8 @@ public:
|
||||
// with a non-static array
|
||||
// Intermediate classes (colvarbias and colvarcomp, which are also base classes)
|
||||
// implement this as virtual to allow overriding
|
||||
virtual std::vector<feature *>&features() = 0;
|
||||
virtual const std::vector<feature *>&features() = 0;
|
||||
virtual std::vector<feature *>&modify_features() = 0;
|
||||
|
||||
void add_child(colvardeps *child);
|
||||
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
#define COLVARS_VERSION "2017-07-15"
|
||||
#ifndef COLVARS_VERSION
|
||||
#define COLVARS_VERSION "2017-08-06"
|
||||
// This file is part of the Collective Variables module (Colvars).
|
||||
// The original version of Colvars and its updates are located at:
|
||||
// https://github.com/colvars/colvars
|
||||
@ -6,3 +7,4 @@
|
||||
// If you wish to distribute your changes, please submit them to the
|
||||
// Colvars repository at GitHub.
|
||||
|
||||
#endif
|
||||
|
||||
@ -472,7 +472,7 @@ int colvarscript::proc_features(colvardeps *obj,
|
||||
}
|
||||
|
||||
if ((subcmd == "get") || (subcmd == "set")) {
|
||||
std::vector<colvardeps::feature *> &features = obj->features();
|
||||
std::vector<colvardeps::feature *> const &features = obj->features();
|
||||
std::string const req_feature(obj_to_str(objv[3]));
|
||||
colvardeps::feature *f = NULL;
|
||||
int fid = 0;
|
||||
|
||||
@ -19,6 +19,17 @@ bool colvarmodule::rotation::monitor_crossings = false;
|
||||
cvm::real colvarmodule::rotation::crossing_threshold = 1.0E-02;
|
||||
|
||||
|
||||
/// Numerical recipes diagonalization
|
||||
static int jacobi(cvm::real **a, cvm::real *d, cvm::real **v, int *nrot);
|
||||
|
||||
/// Eigenvector sort
|
||||
static int eigsrt(cvm::real *d, cvm::real **v);
|
||||
|
||||
/// Transpose the matrix
|
||||
static int transpose(cvm::real **v);
|
||||
|
||||
|
||||
|
||||
std::string cvm::rvector::to_simple_string() const
|
||||
{
|
||||
std::ostringstream os;
|
||||
@ -286,7 +297,12 @@ void colvarmodule::rotation::diagonalize_matrix(cvm::matrix2d<cvm::real> &S,
|
||||
|
||||
// diagonalize
|
||||
int jac_nrot = 0;
|
||||
jacobi(S.c_array(), S_eigval.c_array(), S_eigvec.c_array(), &jac_nrot);
|
||||
if (jacobi(S.c_array(), S_eigval.c_array(), S_eigvec.c_array(), &jac_nrot) !=
|
||||
COLVARS_OK) {
|
||||
cvm::error("Too many iterations in routine jacobi.\n"
|
||||
"This is usually the result of an ill-defined set of atoms for "
|
||||
"rotational alignment (RMSD, rotateReference, etc).\n");
|
||||
}
|
||||
eigsrt(S_eigval.c_array(), S_eigvec.c_array());
|
||||
// jacobi saves eigenvectors by columns
|
||||
transpose(S_eigvec.c_array());
|
||||
@ -528,7 +544,7 @@ void colvarmodule::rotation::calc_optimal_rotation(std::vector<cvm::atom_pos> co
|
||||
|
||||
#define n 4
|
||||
|
||||
void jacobi(cvm::real **a, cvm::real *d, cvm::real **v, int *nrot)
|
||||
int 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;
|
||||
@ -554,7 +570,7 @@ void jacobi(cvm::real **a, cvm::real *d, cvm::real **v, int *nrot)
|
||||
sm += std::fabs(a[ip][iq]);
|
||||
}
|
||||
if (sm == 0.0) {
|
||||
return;
|
||||
return COLVARS_OK;
|
||||
}
|
||||
if (i < 4)
|
||||
tresh=0.2*sm/(n*n);
|
||||
@ -606,10 +622,11 @@ void jacobi(cvm::real **a, cvm::real *d, cvm::real **v, int *nrot)
|
||||
z[ip]=0.0;
|
||||
}
|
||||
}
|
||||
cvm::error("Too many iterations in routine jacobi.\n");
|
||||
return COLVARS_ERROR;
|
||||
}
|
||||
|
||||
void eigsrt(cvm::real *d, cvm::real **v)
|
||||
|
||||
int eigsrt(cvm::real *d, cvm::real **v)
|
||||
{
|
||||
int k,j,i;
|
||||
cvm::real p;
|
||||
@ -628,9 +645,11 @@ void eigsrt(cvm::real *d, cvm::real **v)
|
||||
}
|
||||
}
|
||||
}
|
||||
return COLVARS_OK;
|
||||
}
|
||||
|
||||
void transpose(cvm::real **v)
|
||||
|
||||
int transpose(cvm::real **v)
|
||||
{
|
||||
cvm::real p;
|
||||
int i,j;
|
||||
@ -641,6 +660,7 @@ void transpose(cvm::real **v)
|
||||
v[j][i]=p;
|
||||
}
|
||||
}
|
||||
return COLVARS_OK;
|
||||
}
|
||||
|
||||
#undef n
|
||||
|
||||
@ -1020,16 +1020,6 @@ inline cvm::rvector operator * (cvm::rmatrix const &m,
|
||||
}
|
||||
|
||||
|
||||
/// Numerical recipes diagonalization
|
||||
void jacobi(cvm::real **a, cvm::real *d, cvm::real **v, int *nrot);
|
||||
|
||||
/// Eigenvector sort
|
||||
void eigsrt(cvm::real *d, cvm::real **v);
|
||||
|
||||
/// Transpose the matrix
|
||||
void transpose(cvm::real **v);
|
||||
|
||||
|
||||
|
||||
|
||||
/// \brief 1-dimensional vector of real numbers with four components and
|
||||
|
||||
@ -570,6 +570,50 @@ colvarvalue colvarvalue::dist2_grad(colvarvalue const &x2) const
|
||||
}
|
||||
|
||||
|
||||
/// Return the midpoint between x1 and x2, optionally weighted by lambda
|
||||
/// (which must be between 0.0 and 1.0)
|
||||
colvarvalue const colvarvalue::interpolate(colvarvalue const &x1,
|
||||
colvarvalue const &x2,
|
||||
cvm::real const lambda)
|
||||
{
|
||||
colvarvalue::check_types(x1, x2);
|
||||
|
||||
if ((lambda < 0.0) || (lambda > 1.0)) {
|
||||
cvm::error("Error: trying to interpolate between two colvarvalues with a "
|
||||
"lamdba outside [0:1].\n", BUG_ERROR);
|
||||
}
|
||||
|
||||
colvarvalue interp = ((1.0-lambda)*x1 + lambda*x2);
|
||||
cvm::real const d2 = x1.dist2(x2);
|
||||
|
||||
switch (x1.type()) {
|
||||
case colvarvalue::type_scalar:
|
||||
case colvarvalue::type_3vector:
|
||||
case colvarvalue::type_vector:
|
||||
case colvarvalue::type_unit3vectorderiv:
|
||||
case colvarvalue::type_quaternionderiv:
|
||||
return interp;
|
||||
break;
|
||||
case colvarvalue::type_unit3vector:
|
||||
case colvarvalue::type_quaternion:
|
||||
if (interp.norm()/std::sqrt(d2) < 1.0e-6) {
|
||||
cvm::error("Error: interpolation between "+cvm::to_str(x1)+" and "+
|
||||
cvm::to_str(x2)+" with lambda = "+cvm::to_str(lambda)+
|
||||
" is undefined: result = "+cvm::to_str(interp)+"\n",
|
||||
INPUT_ERROR);
|
||||
}
|
||||
interp.apply_constraints();
|
||||
return interp;
|
||||
break;
|
||||
case colvarvalue::type_notset:
|
||||
default:
|
||||
x1.undef_op();
|
||||
break;
|
||||
}
|
||||
return colvarvalue(colvarvalue::type_notset);
|
||||
}
|
||||
|
||||
|
||||
std::string colvarvalue::to_simple_string() const
|
||||
{
|
||||
switch (type()) {
|
||||
|
||||
@ -193,6 +193,12 @@ public:
|
||||
/// Derivative with respect to this \link colvarvalue \endlink of the square distance
|
||||
colvarvalue dist2_grad(colvarvalue const &x2) const;
|
||||
|
||||
/// Return the midpoint between x1 and x2, optionally weighted by lambda
|
||||
/// (which must be between 0.0 and 1.0)
|
||||
static colvarvalue const interpolate(colvarvalue const &x1,
|
||||
colvarvalue const &x2,
|
||||
cvm::real const lambda = 0.5);
|
||||
|
||||
/// Assignment operator (type of x is checked)
|
||||
colvarvalue & operator = (colvarvalue const &x);
|
||||
|
||||
@ -285,10 +291,10 @@ public:
|
||||
cvm::real & operator [] (int const i);
|
||||
|
||||
/// Ensure that the two types are the same within a binary operator
|
||||
int static check_types(colvarvalue const &x1, colvarvalue const &x2);
|
||||
static int check_types(colvarvalue const &x1, colvarvalue const &x2);
|
||||
|
||||
/// Ensure that the two types are the same within an assignment, or that the left side is type_notset
|
||||
int static check_types_assign(Type const &vt1, Type const &vt2);
|
||||
static int check_types_assign(Type const &vt1, Type const &vt2);
|
||||
|
||||
/// Undefined operation
|
||||
void undef_op() const;
|
||||
@ -317,14 +323,14 @@ public:
|
||||
|
||||
/// \brief Optimized routine for the inner product of one collective
|
||||
/// variable with an array
|
||||
void static inner_opt(colvarvalue const &x,
|
||||
static void inner_opt(colvarvalue const &x,
|
||||
std::vector<colvarvalue>::iterator &xv,
|
||||
std::vector<colvarvalue>::iterator const &xv_end,
|
||||
std::vector<cvm::real>::iterator &result);
|
||||
|
||||
/// \brief Optimized routine for the inner product of one collective
|
||||
/// variable with an array
|
||||
void static inner_opt(colvarvalue const &x,
|
||||
static void inner_opt(colvarvalue const &x,
|
||||
std::list<colvarvalue>::iterator &xv,
|
||||
std::list<colvarvalue>::iterator const &xv_end,
|
||||
std::vector<cvm::real>::iterator &result);
|
||||
@ -332,14 +338,14 @@ public:
|
||||
/// \brief Optimized routine for the second order Legendre
|
||||
/// polynomial, (3cos^2(w)-1)/2, of one collective variable with an
|
||||
/// array
|
||||
void static p2leg_opt(colvarvalue const &x,
|
||||
static void p2leg_opt(colvarvalue const &x,
|
||||
std::vector<colvarvalue>::iterator &xv,
|
||||
std::vector<colvarvalue>::iterator const &xv_end,
|
||||
std::vector<cvm::real>::iterator &result);
|
||||
|
||||
/// \brief Optimized routine for the second order Legendre
|
||||
/// polynomial of one collective variable with an array
|
||||
void static p2leg_opt(colvarvalue const &x,
|
||||
static void p2leg_opt(colvarvalue const &x,
|
||||
std::list<colvarvalue>::iterator &xv,
|
||||
std::list<colvarvalue>::iterator const &xv_end,
|
||||
std::vector<cvm::real>::iterator &result);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#ifndef COLVARPROXY_VERSION
|
||||
#define COLVARPROXY_VERSION "2017-07-15"
|
||||
#define COLVARPROXY_VERSION "2017-07-19"
|
||||
// This file is part of the Collective Variables module (Colvars).
|
||||
// The original version of Colvars and its updates are located at:
|
||||
// https://github.com/colvars/colvars
|
||||
|
||||
Reference in New Issue
Block a user