Update Colvars library to version 2023-05-01
This update consists exclusively of bugfixes or maintenance-related changes. The following is a list of pull requests in the Colvars repository since the previous update to LAMMPS: - 532 Add XYZ trajectory reading feature https://github.com/Colvars/colvars/pull/532 (@jhenin, @giacomofiorin) - 531 Delete objects quietly, unless explicitly requested via script (including VMD) https://github.com/Colvars/colvars/pull/531 (@giacomofiorin) - 530 Append newline to log and error messages if not already present https://github.com/Colvars/colvars/pull/530 (@giacomofiorin) - 528 Forward-declare OpenMP lock https://github.com/Colvars/colvars/pull/528 (@giacomofiorin) - 527 Remove unneeded STL container https://github.com/Colvars/colvars/pull/527 (@giacomofiorin) - 526 Allow collecting configuration files and strings before setting up interface https://github.com/Colvars/colvars/pull/526 (@giacomofiorin, @jhenin) - 523 Fallback to linearCombination when customFunction is missing in customColvar https://github.com/Colvars/colvars/pull/523 (@HanatoK, @giacomofiorin) - 522 Use iostream::fail() to check for I/O error https://github.com/Colvars/colvars/pull/522 (@jhenin) - 520 Fix ref count https://github.com/Colvars/colvars/pull/520 (@giacomofiorin) - 513 Set target temperature through a common code path https://github.com/Colvars/colvars/pull/513 (@giacomofiorin, @jhenin) - 509 Safer detection of Windows with recent Microsoft Visual Studio versions https://github.com/Colvars/colvars/pull/509 (@akohlmey) - 508 Update LAMMPS patching method to reflect Lepton availability https://github.com/Colvars/colvars/pull/508 (@giacomofiorin) - 497 Increase the precision of write_multicol https://github.com/Colvars/colvars/pull/497 (@HanatoK) - 496 Only perform MTS automatic enable/disable for timeStepFactor > 1 https://github.com/Colvars/colvars/pull/496 (@giacomofiorin) - 493 Remove unused branch of quaternion input function https://github.com/Colvars/colvars/pull/493 (@giacomofiorin) - 489 Ensure there are spaces between the fields in the header https://github.com/Colvars/colvars/pull/489 (@HanatoK) - 487 Use map of output streams, and return references to its elements https://github.com/Colvars/colvars/pull/487 (@giacomofiorin, @jhenin) - 486 Remember first step of moving restraint https://github.com/Colvars/colvars/pull/486 (@jhenin) - 485 Add decoupling option for moving restraints https://github.com/Colvars/colvars/pull/485 (@jhenin) - 483 Update Lepton via patching procedure https://github.com/Colvars/colvars/pull/483 (@giacomofiorin) - 481 Make file-reading operations of input data abstractable https://github.com/Colvars/colvars/pull/481 (@giacomofiorin) Authors: @akohlmey, @giacomofiorin, @HanatoK, @jhenin
This commit is contained in:
@ -7,6 +7,10 @@
|
||||
// If you wish to distribute your changes, please submit them to the
|
||||
// Colvars repository at GitHub.
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
#include "colvarmodule.h"
|
||||
#include "colvarproxy.h"
|
||||
#include "colvarvalue.h"
|
||||
@ -196,6 +200,8 @@ int colvarbias_restraint_moving::init(std::string const &conf)
|
||||
|
||||
if (b_chg_centers || b_chg_force_k) {
|
||||
|
||||
first_step = cvm::step_absolute();
|
||||
|
||||
get_keyval(conf, "targetNumSteps", target_nsteps, target_nsteps);
|
||||
if (!target_nsteps) {
|
||||
cvm::error("Error: targetNumSteps must be non-zero.\n", COLVARS_INPUT_ERROR);
|
||||
@ -335,13 +341,17 @@ int colvarbias_restraint_centers_moving::update_centers(cvm::real lambda)
|
||||
|
||||
int colvarbias_restraint_centers_moving::update()
|
||||
{
|
||||
if (!cvm::main()->proxy->simulation_running()) {
|
||||
return COLVARS_OK;
|
||||
}
|
||||
|
||||
if (b_chg_centers) {
|
||||
|
||||
if (target_nstages) {
|
||||
// Staged update
|
||||
if (stage <= target_nstages) {
|
||||
if ((cvm::step_relative() > 0) &&
|
||||
((cvm::step_absolute() % target_nsteps) == 1)) {
|
||||
(((cvm::step_absolute() - first_step) % target_nsteps) == 1)) {
|
||||
cvm::real const lambda =
|
||||
cvm::real(stage)/cvm::real(target_nstages);
|
||||
update_centers(lambda);
|
||||
@ -358,9 +368,9 @@ int colvarbias_restraint_centers_moving::update()
|
||||
}
|
||||
} else {
|
||||
// Continuous update
|
||||
if (cvm::step_absolute() <= target_nsteps) {
|
||||
if (cvm::step_absolute() - first_step <= target_nsteps) {
|
||||
cvm::real const lambda =
|
||||
cvm::real(cvm::step_absolute())/cvm::real(target_nsteps);
|
||||
cvm::real(cvm::step_absolute() - first_step)/cvm::real(target_nsteps);
|
||||
update_centers(lambda);
|
||||
} else {
|
||||
for (size_t i = 0; i < num_variables(); i++) {
|
||||
@ -389,10 +399,13 @@ int colvarbias_restraint_centers_moving::update()
|
||||
|
||||
int colvarbias_restraint_centers_moving::update_acc_work()
|
||||
{
|
||||
if (!cvm::main()->proxy->simulation_running()) {
|
||||
return COLVARS_OK;
|
||||
}
|
||||
if (b_chg_centers) {
|
||||
if (is_enabled(f_cvb_output_acc_work)) {
|
||||
if ((cvm::step_relative() > 0) &&
|
||||
(cvm::step_absolute() <= target_nsteps)) {
|
||||
(cvm::step_absolute() - first_step <= 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];
|
||||
@ -496,10 +509,11 @@ colvarbias_restraint_k_moving::colvarbias_restraint_k_moving(char const *key)
|
||||
colvarbias_restraint_moving(key)
|
||||
{
|
||||
b_chg_force_k = false;
|
||||
b_decoupling = false;
|
||||
target_equil_steps = 0;
|
||||
target_force_k = -1.0;
|
||||
starting_force_k = -1.0;
|
||||
force_k_exp = 1.0;
|
||||
lambda_exp = 1.0;
|
||||
restraint_FE = 0.0;
|
||||
force_k_incr = 0.0;
|
||||
}
|
||||
@ -509,18 +523,29 @@ int colvarbias_restraint_k_moving::init(std::string const &conf)
|
||||
{
|
||||
colvarbias_restraint_k::init(conf);
|
||||
|
||||
get_keyval(conf, "decoupling", b_decoupling, b_decoupling);
|
||||
if (b_decoupling) {
|
||||
starting_force_k = 0.0;
|
||||
target_force_k = force_k;
|
||||
b_chg_force_k = true;
|
||||
}
|
||||
|
||||
if (get_keyval(conf, "targetForceConstant", target_force_k, target_force_k)) {
|
||||
if (b_decoupling) {
|
||||
cvm::error("Error: targetForceConstant may not be specified together with decoupling.\n", COLVARS_INPUT_ERROR);
|
||||
return COLVARS_ERROR;
|
||||
}
|
||||
starting_force_k = force_k;
|
||||
b_chg_force_k = true;
|
||||
}
|
||||
|
||||
if (b_chg_force_k) {
|
||||
// parse moving restraint options
|
||||
colvarbias_restraint_moving::init(conf);
|
||||
} else {
|
||||
if (!b_chg_force_k) {
|
||||
return COLVARS_OK;
|
||||
}
|
||||
|
||||
// parse moving restraint options
|
||||
colvarbias_restraint_moving::init(conf);
|
||||
|
||||
get_keyval(conf, "targetEquilSteps", target_equil_steps, target_equil_steps);
|
||||
|
||||
if (get_keyval(conf, "lambdaSchedule", lambda_schedule, lambda_schedule) &&
|
||||
@ -534,12 +559,13 @@ int colvarbias_restraint_k_moving::init(std::string const &conf)
|
||||
target_nstages = lambda_schedule.size() - 1;
|
||||
}
|
||||
|
||||
if (get_keyval(conf, "targetForceExponent", force_k_exp, force_k_exp)) {
|
||||
if (! b_chg_force_k)
|
||||
cvm::log("Warning: not changing force constant: targetForceExponent will be ignored\n");
|
||||
if ((get_keyval(conf, "targetForceExponent", lambda_exp, lambda_exp, parse_deprecated)
|
||||
|| get_keyval(conf, "lambdaExponent", lambda_exp, lambda_exp))
|
||||
&& !b_chg_force_k) {
|
||||
cvm::error("Error: cannot set lambdaExponent unless a changing force constant is active.\n", COLVARS_INPUT_ERROR);
|
||||
}
|
||||
if (force_k_exp < 1.0) {
|
||||
cvm::log("Warning: for all practical purposes, targetForceExponent should be 1.0 or greater.\n");
|
||||
if (lambda_exp < 1.0) {
|
||||
cvm::log("Warning: for all practical purposes, lambdaExponent should be 1.0 or greater.\n");
|
||||
}
|
||||
|
||||
return COLVARS_OK;
|
||||
@ -548,24 +574,27 @@ int colvarbias_restraint_k_moving::init(std::string const &conf)
|
||||
|
||||
int colvarbias_restraint_k_moving::update()
|
||||
{
|
||||
if (!cvm::main()->proxy->simulation_running()) {
|
||||
return COLVARS_OK;
|
||||
}
|
||||
if (b_chg_force_k) {
|
||||
|
||||
cvm::real lambda;
|
||||
|
||||
if (target_nstages) {
|
||||
|
||||
if (cvm::step_absolute() == 0) {
|
||||
if (cvm::step_absolute() == first_step) {
|
||||
// Setup first stage of staged variable force constant calculation
|
||||
if (lambda_schedule.size()) {
|
||||
lambda = lambda_schedule[0];
|
||||
} else {
|
||||
lambda = 0.0;
|
||||
lambda = (b_decoupling ? 1.0 : 0.0);
|
||||
}
|
||||
force_k = starting_force_k + (target_force_k - starting_force_k)
|
||||
* cvm::pow(lambda, force_k_exp);
|
||||
* cvm::pow(lambda, lambda_exp);
|
||||
cvm::log("Restraint " + this->name + ", stage " + cvm::to_str(stage)
|
||||
+ " : lambda = " + cvm::to_str(lambda)
|
||||
+ ", k = " + cvm::to_str(force_k));
|
||||
+ ", k = " + cvm::to_str(force_k)+"\n");
|
||||
}
|
||||
|
||||
// TI calculation: estimate free energy derivative
|
||||
@ -574,9 +603,10 @@ int colvarbias_restraint_k_moving::update()
|
||||
lambda = lambda_schedule[stage];
|
||||
} else {
|
||||
lambda = cvm::real(stage) / cvm::real(target_nstages);
|
||||
if (b_decoupling) lambda = 1.0 - lambda;
|
||||
}
|
||||
|
||||
if (target_equil_steps == 0 || cvm::step_absolute() % target_nsteps >= target_equil_steps) {
|
||||
if (target_equil_steps == 0 || (cvm::step_absolute() - first_step) % target_nsteps >= target_equil_steps) {
|
||||
// Start averaging after equilibration period, if requested
|
||||
|
||||
// Derivative of energy with respect to force_k
|
||||
@ -584,17 +614,17 @@ int colvarbias_restraint_k_moving::update()
|
||||
for (size_t i = 0; i < num_variables(); i++) {
|
||||
dU_dk += d_restraint_potential_dk(i);
|
||||
}
|
||||
restraint_FE += force_k_exp * cvm::pow(lambda, force_k_exp - 1.0)
|
||||
restraint_FE += lambda_exp * cvm::pow(lambda, lambda_exp - 1.0)
|
||||
* (target_force_k - starting_force_k) * dU_dk;
|
||||
}
|
||||
|
||||
// Finish current stage...
|
||||
if (cvm::step_absolute() % target_nsteps == 0 &&
|
||||
cvm::step_absolute() > 0) {
|
||||
if ((cvm::step_absolute() - first_step) % target_nsteps == 0 &&
|
||||
cvm::step_absolute() > first_step) {
|
||||
|
||||
cvm::log("Restraint " + this->name + " Lambda= "
|
||||
+ cvm::to_str(lambda) + " dA/dLambda= "
|
||||
+ cvm::to_str(restraint_FE / cvm::real(target_nsteps - target_equil_steps)));
|
||||
+ cvm::to_str(restraint_FE / cvm::real(target_nsteps - target_equil_steps))+"\n");
|
||||
|
||||
// ...and move on to the next one
|
||||
if (stage < target_nstages) {
|
||||
@ -605,23 +635,24 @@ int colvarbias_restraint_k_moving::update()
|
||||
lambda = lambda_schedule[stage];
|
||||
} else {
|
||||
lambda = cvm::real(stage) / cvm::real(target_nstages);
|
||||
if (b_decoupling) lambda = 1.0 - lambda;
|
||||
}
|
||||
force_k = starting_force_k + (target_force_k - starting_force_k)
|
||||
* cvm::pow(lambda, force_k_exp);
|
||||
* cvm::pow(lambda, lambda_exp);
|
||||
cvm::log("Restraint " + this->name + ", stage " + cvm::to_str(stage)
|
||||
+ " : lambda = " + cvm::to_str(lambda)
|
||||
+ ", k = " + cvm::to_str(force_k));
|
||||
+ ", k = " + cvm::to_str(force_k)+"\n");
|
||||
}
|
||||
}
|
||||
|
||||
} else if (cvm::step_absolute() <= target_nsteps) {
|
||||
|
||||
} else if (cvm::step_absolute() - first_step <= target_nsteps) {
|
||||
|
||||
// update force constant (slow growth)
|
||||
lambda = cvm::real(cvm::step_absolute()) / cvm::real(target_nsteps);
|
||||
lambda = cvm::real(cvm::step_absolute() - first_step) / cvm::real(target_nsteps);
|
||||
if (b_decoupling) lambda = 1.0 - lambda;
|
||||
cvm::real const force_k_old = force_k;
|
||||
force_k = starting_force_k + (target_force_k - starting_force_k)
|
||||
* cvm::pow(lambda, force_k_exp);
|
||||
* cvm::pow(lambda, lambda_exp);
|
||||
force_k_incr = force_k - force_k_old;
|
||||
}
|
||||
}
|
||||
@ -632,6 +663,9 @@ int colvarbias_restraint_k_moving::update()
|
||||
|
||||
int colvarbias_restraint_k_moving::update_acc_work()
|
||||
{
|
||||
if (!cvm::main()->proxy->simulation_running()) {
|
||||
return COLVARS_OK;
|
||||
}
|
||||
if (b_chg_force_k) {
|
||||
if (is_enabled(f_cvb_output_acc_work)) {
|
||||
if (cvm::step_relative() > 0) {
|
||||
@ -980,7 +1014,7 @@ int colvarbias_restraint_harmonic_walls::init(std::string const &conf)
|
||||
}
|
||||
|
||||
// Initialize starting value of the force constant (in case it's changing)
|
||||
starting_force_k = force_k;
|
||||
starting_force_k = (b_decoupling ? 0.0 : force_k);
|
||||
|
||||
if (lower_walls.size() > 0) {
|
||||
for (i = 0; i < num_variables(); i++) {
|
||||
@ -1302,6 +1336,8 @@ colvarbias_restraint_histogram::colvarbias_restraint_histogram(char const *key)
|
||||
|
||||
int colvarbias_restraint_histogram::init(std::string const &conf)
|
||||
{
|
||||
int error_code = COLVARS_OK;
|
||||
|
||||
colvarbias::init(conf);
|
||||
enable(f_cvb_apply_force);
|
||||
|
||||
@ -1312,18 +1348,19 @@ int colvarbias_restraint_histogram::init(std::string const &conf)
|
||||
get_keyval(conf, "width", width, width);
|
||||
|
||||
if (width <= 0.0) {
|
||||
cvm::error("Error: \"width\" must be positive.\n", COLVARS_INPUT_ERROR);
|
||||
error_code |= cvm::error("Error: \"width\" must be positive.\n",
|
||||
COLVARS_INPUT_ERROR);
|
||||
}
|
||||
|
||||
get_keyval(conf, "gaussianWidth", gaussian_width, 2.0 * width, colvarparse::parse_silent);
|
||||
get_keyval(conf, "gaussianSigma", gaussian_width, 2.0 * width);
|
||||
|
||||
if (lower_boundary >= upper_boundary) {
|
||||
cvm::error("Error: the upper boundary, "+
|
||||
cvm::to_str(upper_boundary)+
|
||||
", is not higher than the lower boundary, "+
|
||||
cvm::to_str(lower_boundary)+".\n",
|
||||
COLVARS_INPUT_ERROR);
|
||||
error_code |= cvm::error("Error: the upper boundary, "+
|
||||
cvm::to_str(upper_boundary)+
|
||||
", is not higher than the lower boundary, "+
|
||||
cvm::to_str(lower_boundary)+".\n",
|
||||
COLVARS_INPUT_ERROR);
|
||||
}
|
||||
|
||||
cvm::real const nbins = (upper_boundary - lower_boundary) / width;
|
||||
@ -1347,22 +1384,30 @@ int colvarbias_restraint_histogram::init(std::string const &conf)
|
||||
get_keyval(conf, "refHistogramFile", ref_p_file, std::string(""));
|
||||
if (ref_p_file.size()) {
|
||||
if (inline_ref_p) {
|
||||
cvm::error("Error: cannot specify both refHistogram and refHistogramFile at the same time.\n",
|
||||
COLVARS_INPUT_ERROR);
|
||||
error_code |= cvm::error("Error: cannot specify both refHistogram and refHistogramFile at the same time.\n",
|
||||
COLVARS_INPUT_ERROR);
|
||||
} else {
|
||||
std::ifstream is(ref_p_file.c_str());
|
||||
|
||||
std::istream &is =
|
||||
cvm::main()->proxy->input_stream(ref_p_file,
|
||||
"reference histogram file");
|
||||
|
||||
std::string data_s = "";
|
||||
std::string line;
|
||||
while (getline_nocomments(is, line)) {
|
||||
data_s.append(line+"\n");
|
||||
}
|
||||
if (data_s.size() == 0) {
|
||||
cvm::error("Error: file \""+ref_p_file+"\" empty or unreadable.\n", COLVARS_FILE_ERROR);
|
||||
error_code |= cvm::error("Error: file \""+ref_p_file+
|
||||
"\" empty or unreadable.\n",
|
||||
COLVARS_FILE_ERROR);
|
||||
}
|
||||
is.close();
|
||||
error_code |= cvm::main()->proxy->close_input_stream(ref_p_file);
|
||||
|
||||
cvm::vector1d<cvm::real> data;
|
||||
if (data.from_simple_string(data_s) != 0) {
|
||||
cvm::error("Error: could not read histogram from file \""+ref_p_file+"\".\n");
|
||||
error_code |= cvm::error("Error: could not read histogram from file \""+
|
||||
ref_p_file+"\".\n");
|
||||
}
|
||||
if (data.size() == 2*ref_p.size()) {
|
||||
// file contains both x and p(x)
|
||||
@ -1373,11 +1418,13 @@ int colvarbias_restraint_histogram::init(std::string const &conf)
|
||||
} else if (data.size() == ref_p.size()) {
|
||||
ref_p = data;
|
||||
} else {
|
||||
cvm::error("Error: file \""+ref_p_file+"\" contains a histogram of different length.\n",
|
||||
COLVARS_INPUT_ERROR);
|
||||
error_code |= cvm::error("Error: file \""+ref_p_file+
|
||||
"\" contains a histogram of different length.\n",
|
||||
COLVARS_INPUT_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cvm::real const ref_integral = ref_p.sum() * width;
|
||||
if (cvm::fabs(ref_integral - 1.0) > 1.0e-03) {
|
||||
cvm::log("Reference distribution not normalized, normalizing to unity.\n");
|
||||
@ -1387,7 +1434,7 @@ int colvarbias_restraint_histogram::init(std::string const &conf)
|
||||
get_keyval(conf, "writeHistogram", b_write_histogram, false);
|
||||
get_keyval(conf, "forceConstant", force_k, 1.0);
|
||||
|
||||
return COLVARS_OK;
|
||||
return error_code;
|
||||
}
|
||||
|
||||
|
||||
@ -1492,27 +1539,29 @@ int colvarbias_restraint_histogram::update()
|
||||
int colvarbias_restraint_histogram::write_output_files()
|
||||
{
|
||||
if (b_write_histogram) {
|
||||
colvarproxy *proxy = cvm::main()->proxy;
|
||||
std::string file_name(cvm::output_prefix()+"."+this->name+".hist.dat");
|
||||
std::ostream *os = cvm::proxy->output_stream(file_name);
|
||||
*os << "# " << cvm::wrap_string(variables(0)->name, cvm::cv_width)
|
||||
<< " " << "p(" << cvm::wrap_string(variables(0)->name, cvm::cv_width-3)
|
||||
<< ")\n";
|
||||
std::ostream &os = proxy->output_stream(file_name,
|
||||
"histogram output file");
|
||||
os << "# " << cvm::wrap_string(variables(0)->name, cvm::cv_width)
|
||||
<< " " << "p(" << cvm::wrap_string(variables(0)->name, cvm::cv_width-3)
|
||||
<< ")\n";
|
||||
|
||||
os->setf(std::ios::fixed, std::ios::floatfield);
|
||||
os.setf(std::ios::fixed, std::ios::floatfield);
|
||||
|
||||
size_t igrid;
|
||||
for (igrid = 0; igrid < p.size(); igrid++) {
|
||||
cvm::real const x_grid = (lower_boundary + (igrid+1)*width);
|
||||
*os << " "
|
||||
<< std::setprecision(cvm::cv_prec)
|
||||
<< std::setw(cvm::cv_width)
|
||||
<< x_grid
|
||||
<< " "
|
||||
<< std::setprecision(cvm::cv_prec)
|
||||
<< std::setw(cvm::cv_width)
|
||||
<< p[igrid] << "\n";
|
||||
os << " "
|
||||
<< std::setprecision(cvm::cv_prec)
|
||||
<< std::setw(cvm::cv_width)
|
||||
<< x_grid
|
||||
<< " "
|
||||
<< std::setprecision(cvm::cv_prec)
|
||||
<< std::setw(cvm::cv_width)
|
||||
<< p[igrid] << "\n";
|
||||
}
|
||||
cvm::proxy->close_output_stream(file_name);
|
||||
proxy->close_output_stream(file_name);
|
||||
}
|
||||
return COLVARS_OK;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user