Update Colvars library to version 2024-06-04
This commit is contained in:
@ -19,45 +19,40 @@
|
||||
colvar::cvc::cvc()
|
||||
{
|
||||
description = "uninitialized colvar component";
|
||||
b_try_scalable = true;
|
||||
sup_coeff = 1.0;
|
||||
sup_np = 1;
|
||||
period = 0.0;
|
||||
wrap_center = 0.0;
|
||||
width = 0.0;
|
||||
cvc::init_dependencies();
|
||||
}
|
||||
|
||||
|
||||
colvar::cvc::cvc(std::string const &conf)
|
||||
int colvar::cvc::update_description()
|
||||
{
|
||||
description = "uninitialized colvar component";
|
||||
b_try_scalable = true;
|
||||
sup_coeff = 1.0;
|
||||
sup_np = 1;
|
||||
period = 0.0;
|
||||
wrap_center = 0.0;
|
||||
width = 0.0;
|
||||
init_dependencies();
|
||||
colvar::cvc::init(conf);
|
||||
if (name.size() > 0) {
|
||||
description = "cvc \"" + name + "\"";
|
||||
} else {
|
||||
description = "unnamed cvc";
|
||||
}
|
||||
description += " of type \"" + function_type() + "\"";
|
||||
return COLVARS_OK;
|
||||
}
|
||||
|
||||
|
||||
std::string colvar::cvc::function_type() const
|
||||
{
|
||||
if (function_types.empty()) {
|
||||
return "unset";
|
||||
}
|
||||
return function_types.back();
|
||||
}
|
||||
|
||||
|
||||
int colvar::cvc::set_function_type(std::string const &type)
|
||||
{
|
||||
function_type = type;
|
||||
if (function_types.size() == 0) {
|
||||
function_types.push_back(function_type);
|
||||
} else {
|
||||
if (function_types.back() != function_type) {
|
||||
function_types.push_back(function_type);
|
||||
}
|
||||
}
|
||||
function_types.push_back(type);
|
||||
update_description();
|
||||
cvm::main()->cite_feature(function_types[0]+" colvar component");
|
||||
for (size_t i = function_types.size()-1; i > 0; i--) {
|
||||
cvm::main()->cite_feature(function_types[i]+" colvar component"+
|
||||
" (derived from "+function_types[i-1]+")");
|
||||
}
|
||||
cvm::main()->cite_feature(function_types[0]+" colvar component");
|
||||
return COLVARS_OK;
|
||||
}
|
||||
|
||||
@ -67,6 +62,8 @@ int colvar::cvc::init(std::string const &conf)
|
||||
if (cvm::debug())
|
||||
cvm::log("Initializing cvc base object.\n");
|
||||
|
||||
int error_code = COLVARS_OK;
|
||||
|
||||
std::string const old_name(name);
|
||||
|
||||
if (name.size() > 0) {
|
||||
@ -74,18 +71,14 @@ int colvar::cvc::init(std::string const &conf)
|
||||
}
|
||||
|
||||
if (get_keyval(conf, "name", name, name)) {
|
||||
if (name.size() > 0) {
|
||||
description = "cvc \"" + name + "\" of type " + function_type;
|
||||
} else {
|
||||
description = "unnamed cvc";
|
||||
}
|
||||
if ((name != old_name) && (old_name.size() > 0)) {
|
||||
cvm::error("Error: cannot rename component \""+old_name+
|
||||
"\" after initialization (new name = \""+name+"\")",
|
||||
COLVARS_INPUT_ERROR);
|
||||
error_code |= cvm::error("Error: cannot rename component \"" + old_name +
|
||||
"\" after initialization (new name = \"" + name + "\")",
|
||||
COLVARS_INPUT_ERROR);
|
||||
name = old_name;
|
||||
}
|
||||
}
|
||||
update_description();
|
||||
|
||||
get_keyval(conf, "componentCoeff", sup_coeff, sup_coeff);
|
||||
get_keyval(conf, "componentExp", sup_np, sup_np);
|
||||
@ -102,6 +95,24 @@ int colvar::cvc::init(std::string const &conf)
|
||||
register_param("period", reinterpret_cast<void *>(&period));
|
||||
register_param("wrapAround", reinterpret_cast<void *>(&wrap_center));
|
||||
|
||||
if (period != 0.0) {
|
||||
if (!is_available(f_cvc_periodic)) {
|
||||
error_code |=
|
||||
cvm::error("Error: invalid use of period and/or "
|
||||
"wrapAround in a \"" +
|
||||
function_type() + "\" component.\n" + "Period: " + cvm::to_str(period) +
|
||||
" wrapAround: " + cvm::to_str(wrap_center),
|
||||
COLVARS_INPUT_ERROR);
|
||||
} else {
|
||||
enable(f_cvc_periodic);
|
||||
}
|
||||
}
|
||||
|
||||
if ((wrap_center != 0.0) && !is_enabled(f_cvc_periodic)) {
|
||||
error_code |= cvm::error("Error: wrapAround was defined for a non-periodic component.\n",
|
||||
COLVARS_INPUT_ERROR);
|
||||
}
|
||||
|
||||
get_keyval_feature(this, conf, "debugGradients",
|
||||
f_cvc_debug_gradient, false, parse_silent);
|
||||
|
||||
@ -119,7 +130,7 @@ int colvar::cvc::init(std::string const &conf)
|
||||
if (cvm::debug())
|
||||
cvm::log("Done initializing cvc base object.\n");
|
||||
|
||||
return cvm::get_error();
|
||||
return error_code;
|
||||
}
|
||||
|
||||
|
||||
@ -157,10 +168,13 @@ cvm::atom_group *colvar::cvc::parse_group(std::string const &conf,
|
||||
char const *group_key,
|
||||
bool optional)
|
||||
{
|
||||
cvm::atom_group *group = NULL;
|
||||
int error_code = COLVARS_OK;
|
||||
|
||||
cvm::atom_group *group = nullptr;
|
||||
std::string group_conf;
|
||||
|
||||
if (key_lookup(conf, group_key, &group_conf)) {
|
||||
|
||||
group = new cvm::atom_group(group_key);
|
||||
|
||||
if (b_try_scalable) {
|
||||
@ -177,31 +191,42 @@ cvm::atom_group *colvar::cvc::parse_group(std::string const &conf,
|
||||
// TODO check for other types of parallelism here
|
||||
}
|
||||
|
||||
if (group_conf.size() == 0) {
|
||||
cvm::error("Error: atom group \""+group->key+
|
||||
"\" is set, but has no definition.\n",
|
||||
COLVARS_INPUT_ERROR);
|
||||
if (group_conf.empty()) {
|
||||
error_code |= cvm::error("Error: atom group \"" + group->key + "\" has no definition.\n",
|
||||
COLVARS_INPUT_ERROR);
|
||||
delete group;
|
||||
group = nullptr;
|
||||
// Silence unused variable warning; TODO stop returning a pointer
|
||||
(void) error_code;
|
||||
return group;
|
||||
}
|
||||
|
||||
cvm::increase_depth();
|
||||
if (group->parse(group_conf) == COLVARS_OK) {
|
||||
error_code |= group->parse(group_conf);
|
||||
if (error_code != COLVARS_OK) {
|
||||
error_code |=
|
||||
cvm::error("Error: in definition of atom group \"" + std::string(group_key) + "\".",
|
||||
COLVARS_INPUT_ERROR);
|
||||
delete group;
|
||||
group = nullptr;
|
||||
} else {
|
||||
register_atom_group(group);
|
||||
}
|
||||
group->check_keywords(group_conf, group_key);
|
||||
if (cvm::get_error()) {
|
||||
cvm::error("Error parsing definition for atom group \""+
|
||||
std::string(group_key)+"\".", COLVARS_INPUT_ERROR);
|
||||
error_code |= group->check_keywords(group_conf, group_key);
|
||||
}
|
||||
cvm::decrease_depth();
|
||||
|
||||
} else {
|
||||
if (! optional) {
|
||||
cvm::error("Error: definition for atom group \""+
|
||||
std::string(group_key)+"\" not found.\n");
|
||||
|
||||
if (!optional) {
|
||||
error_code |=
|
||||
cvm::error("Error: atom group \"" + std::string(group_key) + "\" is required.\n",
|
||||
COLVARS_INPUT_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
// Silence unused variable warning; TODO stop returning a pointer
|
||||
(void) error_code;
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
@ -228,6 +253,8 @@ int colvar::cvc::init_dependencies() {
|
||||
|
||||
init_feature(f_cvc_upper_boundary, "defined_upper_boundary", f_type_static);
|
||||
|
||||
init_feature(f_cvc_explicit_atom_groups, "explicit_atom_groups", f_type_static);
|
||||
|
||||
init_feature(f_cvc_gradient, "gradient", f_type_dynamic);
|
||||
|
||||
init_feature(f_cvc_explicit_gradient, "explicit_gradient", f_type_static);
|
||||
@ -264,6 +291,7 @@ int colvar::cvc::init_dependencies() {
|
||||
|
||||
init_feature(f_cvc_collect_atom_ids, "collect_atom_ids", f_type_dynamic);
|
||||
require_feature_children(f_cvc_collect_atom_ids, f_ag_collect_atom_ids);
|
||||
require_feature_self(f_cvc_collect_atom_ids, f_cvc_explicit_atom_groups);
|
||||
|
||||
// TODO only enable this when f_ag_scalable can be turned on for a pre-initialized group
|
||||
// require_feature_children(f_cvc_scalable, f_ag_scalable);
|
||||
@ -281,7 +309,7 @@ int colvar::cvc::init_dependencies() {
|
||||
// default as available, not enabled
|
||||
// except dynamic features which default as unavailable
|
||||
feature_states.reserve(f_cvc_ntot);
|
||||
for (i = 0; i < colvardeps::f_cvc_ntot; i++) {
|
||||
for (i = feature_states.size(); i < colvardeps::f_cvc_ntot; i++) {
|
||||
bool avail = is_dynamic(i) ? false : true;
|
||||
feature_states.push_back(feature_state(avail, false));
|
||||
}
|
||||
@ -292,6 +320,8 @@ int colvar::cvc::init_dependencies() {
|
||||
feature_states[f_cvc_gradient].available = true;
|
||||
feature_states[f_cvc_collect_atom_ids].available = true;
|
||||
|
||||
feature_states[f_cvc_periodic].available = false;
|
||||
|
||||
// CVCs are enabled from the start - get disabled based on flags
|
||||
enable(f_cvc_active);
|
||||
|
||||
@ -314,7 +344,7 @@ int colvar::cvc::init_dependencies() {
|
||||
|
||||
int colvar::cvc::setup()
|
||||
{
|
||||
description = "cvc " + name;
|
||||
update_description();
|
||||
return COLVARS_OK;
|
||||
}
|
||||
|
||||
@ -349,6 +379,7 @@ void colvar::cvc::init_as_angle()
|
||||
void colvar::cvc::init_as_periodic_angle()
|
||||
{
|
||||
x.type(colvarvalue::type_scalar);
|
||||
provide(f_cvc_periodic);
|
||||
enable(f_cvc_periodic);
|
||||
period = 360.0;
|
||||
init_scalar_boundaries(-180.0, 180.0);
|
||||
@ -372,6 +403,7 @@ void colvar::cvc::register_atom_group(cvm::atom_group *ag)
|
||||
{
|
||||
atom_groups.push_back(ag);
|
||||
add_child(ag);
|
||||
enable(f_cvc_explicit_atom_groups);
|
||||
}
|
||||
|
||||
|
||||
@ -411,29 +443,21 @@ int colvar::cvc::set_param(std::string const ¶m_name,
|
||||
|
||||
void colvar::cvc::read_data()
|
||||
{
|
||||
size_t ig;
|
||||
for (ig = 0; ig < atom_groups.size(); ig++) {
|
||||
cvm::atom_group &atoms = *(atom_groups[ig]);
|
||||
atoms.reset_atoms_data();
|
||||
atoms.read_positions();
|
||||
atoms.calc_required_properties();
|
||||
// each atom group will take care of its own fitting_group, if defined
|
||||
if (is_enabled(f_cvc_explicit_atom_groups)) {
|
||||
for (auto agi = atom_groups.begin(); agi != atom_groups.end(); agi++) {
|
||||
cvm::atom_group &atoms = *(*agi);
|
||||
atoms.reset_atoms_data();
|
||||
atoms.read_positions();
|
||||
atoms.calc_required_properties();
|
||||
// each atom group will take care of its own fitting_group, if defined
|
||||
}
|
||||
}
|
||||
|
||||
//// Don't try to get atom velocities, as no back-end currently implements it
|
||||
// if (tasks[task_output_velocity] && !tasks[task_fdiff_velocity]) {
|
||||
// for (i = 0; i < cvcs.size(); i++) {
|
||||
// for (ig = 0; ig < cvcs[i]->atom_groups.size(); ig++) {
|
||||
// cvcs[i]->atom_groups[ig]->read_velocities();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
std::vector<std::vector<int> > colvar::cvc::get_atom_lists()
|
||||
std::vector<std::vector<int>> colvar::cvc::get_atom_lists()
|
||||
{
|
||||
std::vector<std::vector<int> > lists;
|
||||
std::vector<std::vector<int>> lists;
|
||||
|
||||
std::vector<cvm::atom_group *>::iterator agi = atom_groups.begin();
|
||||
for ( ; agi != atom_groups.end(); ++agi) {
|
||||
@ -462,12 +486,12 @@ void colvar::cvc::collect_gradients(std::vector<int> const &atom_ids, std::vecto
|
||||
// If necessary, apply inverse rotation to get atomic
|
||||
// gradient in the laboratory frame
|
||||
if (ag.is_enabled(f_ag_rotate)) {
|
||||
cvm::rotation const rot_inv = ag.rot.inverse();
|
||||
const auto rot_inv = ag.rot.inverse().matrix();
|
||||
|
||||
for (size_t k = 0; k < ag.size(); k++) {
|
||||
size_t a = std::lower_bound(atom_ids.begin(), atom_ids.end(),
|
||||
ag[k].id) - atom_ids.begin();
|
||||
atomic_gradients[a] += coeff * rot_inv.rotate(ag[k].grad);
|
||||
atomic_gradients[a] += coeff * (rot_inv * ag[k].grad);
|
||||
}
|
||||
|
||||
} else {
|
||||
@ -494,7 +518,7 @@ void colvar::cvc::collect_gradients(std::vector<int> const &atom_ids, std::vecto
|
||||
void colvar::cvc::calc_force_invgrads()
|
||||
{
|
||||
cvm::error("Error: calculation of inverse gradients is not implemented "
|
||||
"for colvar components of type \""+function_type+"\".\n",
|
||||
"for colvar components of type \""+function_type()+"\".\n",
|
||||
COLVARS_NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
@ -502,7 +526,7 @@ void colvar::cvc::calc_force_invgrads()
|
||||
void colvar::cvc::calc_Jacobian_derivative()
|
||||
{
|
||||
cvm::error("Error: calculation of inverse gradients is not implemented "
|
||||
"for colvar components of type \""+function_type+"\".\n",
|
||||
"for colvar components of type \""+function_type()+"\".\n",
|
||||
COLVARS_NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
@ -515,6 +539,18 @@ void colvar::cvc::calc_fit_gradients()
|
||||
}
|
||||
|
||||
|
||||
void colvar::cvc::apply_force(colvarvalue const &cvforce)
|
||||
{
|
||||
if (is_enabled(f_cvc_explicit_atom_groups)) {
|
||||
for (auto agi = atom_groups.begin(); agi != atom_groups.end(); agi++) {
|
||||
if (!(*agi)->noforce) {
|
||||
(*agi)->apply_colvar_force(cvforce);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void colvar::cvc::debug_gradients()
|
||||
{
|
||||
// this function should work for any scalar cvc:
|
||||
@ -528,8 +564,8 @@ void colvar::cvc::debug_gradients()
|
||||
cvm::atom_group *group = atom_groups[ig];
|
||||
if (group->b_dummy) continue;
|
||||
|
||||
cvm::rotation const rot_0 = group->rot;
|
||||
cvm::rotation const rot_inv = group->rot.inverse();
|
||||
const auto rot_0 = group->rot.matrix();
|
||||
const auto rot_inv = group->rot.inverse().matrix();
|
||||
|
||||
cvm::real x_0 = x.real_value;
|
||||
if ((x.type() == colvarvalue::type_vector) && (x.size() == 1)) x_0 = x[0];
|
||||
@ -550,7 +586,7 @@ void colvar::cvc::debug_gradients()
|
||||
cvm::log((group->fitting_group ? std::string("refPosGroup") : group->key) +
|
||||
"[" + cvm::to_str(j) + "] = " +
|
||||
(group->is_enabled(f_ag_rotate) ?
|
||||
cvm::to_str(rot_0.rotate(group_for_fit->fit_gradients[j])) :
|
||||
cvm::to_str(rot_0 * (group_for_fit->fit_gradients[j])) :
|
||||
cvm::to_str(group_for_fit->fit_gradients[j])));
|
||||
}
|
||||
}
|
||||
@ -561,7 +597,7 @@ void colvar::cvc::debug_gradients()
|
||||
|
||||
// tests are best conducted in the unrotated (simulation) frame
|
||||
cvm::rvector const atom_grad = (group->is_enabled(f_ag_rotate) ?
|
||||
rot_inv.rotate((*group)[ia].grad) :
|
||||
rot_inv * ((*group)[ia].grad) :
|
||||
(*group)[ia].grad);
|
||||
gradient_sum += atom_grad;
|
||||
|
||||
@ -634,34 +670,43 @@ void colvar::cvc::debug_gradients()
|
||||
}
|
||||
|
||||
|
||||
cvm::real colvar::cvc::dist2(colvarvalue const &x1,
|
||||
colvarvalue const &x2) const
|
||||
cvm::real colvar::cvc::dist2(colvarvalue const &x1, colvarvalue const &x2) const
|
||||
{
|
||||
return x1.dist2(x2);
|
||||
cvm::real diff = x1.real_value - x2.real_value;
|
||||
if (is_enabled(f_cvc_periodic)) {
|
||||
cvm::real const shift = cvm::floor(diff / period + 0.5);
|
||||
diff -= shift * period;
|
||||
}
|
||||
return diff * diff;
|
||||
}
|
||||
|
||||
|
||||
colvarvalue colvar::cvc::dist2_lgrad(colvarvalue const &x1,
|
||||
colvarvalue const &x2) const
|
||||
colvarvalue colvar::cvc::dist2_lgrad(colvarvalue const &x1, colvarvalue const &x2) const
|
||||
{
|
||||
return x1.dist2_grad(x2);
|
||||
cvm::real diff = x1.real_value - x2.real_value;
|
||||
if (is_enabled(f_cvc_periodic)) {
|
||||
cvm::real const shift = cvm::floor(diff / period + 0.5);
|
||||
diff -= shift * period;
|
||||
}
|
||||
return 2.0 * diff;
|
||||
}
|
||||
|
||||
|
||||
colvarvalue colvar::cvc::dist2_rgrad(colvarvalue const &x1,
|
||||
colvarvalue const &x2) const
|
||||
colvarvalue colvar::cvc::dist2_rgrad(colvarvalue const &x1, colvarvalue const &x2) const
|
||||
{
|
||||
return x2.dist2_grad(x1);
|
||||
return cvc::dist2_lgrad(x1, x2);
|
||||
}
|
||||
|
||||
|
||||
void colvar::cvc::wrap(colvarvalue & /* x_unwrapped */) const
|
||||
void colvar::cvc::wrap(colvarvalue &x_unwrapped) const
|
||||
{
|
||||
return;
|
||||
if (is_enabled(f_cvc_periodic)) {
|
||||
cvm::real const shift = cvm::floor((x_unwrapped.real_value - wrap_center) / period + 0.5);
|
||||
x_unwrapped.real_value -= shift * period;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Static members
|
||||
|
||||
std::vector<colvardeps::feature *> colvar::cvc::cvc_features;
|
||||
|
||||
Reference in New Issue
Block a user