Files
lammps/lib/colvars/colvarbias_histogram.cpp
Giacomo Fiorin 377c652a83 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
2023-05-17 13:29:00 -04:00

220 lines
5.8 KiB
C++

// -*- c++ -*-
// 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
// Please update all Colvars source files before making any changes.
// If you wish to distribute your changes, please submit them to the
// Colvars repository at GitHub.
#include "colvarmodule.h"
#include "colvarproxy.h"
#include "colvar.h"
#include "colvarbias_histogram.h"
colvarbias_histogram::colvarbias_histogram(char const *key)
: colvarbias(key),
grid(NULL), out_name("")
{
provide(f_cvb_bypass_ext_lagrangian); // Allow histograms of actual cv for extended-Lagrangian
}
int colvarbias_histogram::init(std::string const &conf)
{
colvarbias::init(conf);
cvm::main()->cite_feature("Histogram colvar bias implementation");
enable(f_cvb_scalar_variables);
enable(f_cvb_history_dependent);
size_t i;
get_keyval(conf, "outputFile", out_name, "");
// Write DX file by default only in dimension >= 3
std::string default_name_dx = this->num_variables() > 2 ? "" : "none";
get_keyval(conf, "outputFileDX", out_name_dx, default_name_dx);
/// with VMD, this may not be an error
// if ( output_freq == 0 ) {
// cvm::error("User required histogram with zero output frequency");
// }
colvar_array_size = 0;
{
bool colvar_array = false;
get_keyval(conf, "gatherVectorColvars", colvar_array, colvar_array);
if (colvar_array) {
for (i = 0; i < num_variables(); i++) { // should be all vector
if (colvars[i]->value().type() != colvarvalue::type_vector) {
cvm::error("Error: used gatherVectorColvars with non-vector colvar.\n", COLVARS_INPUT_ERROR);
return COLVARS_INPUT_ERROR;
}
if (i == 0) {
colvar_array_size = colvars[i]->value().size();
if (colvar_array_size < 1) {
cvm::error("Error: vector variable has dimension less than one.\n", COLVARS_INPUT_ERROR);
return COLVARS_INPUT_ERROR;
}
} else {
if (colvar_array_size != colvars[i]->value().size()) {
cvm::error("Error: trying to combine vector colvars of different lengths.\n", COLVARS_INPUT_ERROR);
return COLVARS_INPUT_ERROR;
}
}
}
} else {
for (i = 0; i < num_variables(); i++) { // should be all scalar
if (colvars[i]->value().type() != colvarvalue::type_scalar) {
cvm::error("Error: only scalar colvars are supported when gatherVectorColvars is off.\n", COLVARS_INPUT_ERROR);
return COLVARS_INPUT_ERROR;
}
}
}
}
if (colvar_array_size > 0) {
weights.assign(colvar_array_size, 1.0);
get_keyval(conf, "weights", weights, weights);
}
for (i = 0; i < num_variables(); i++) {
colvars[i]->enable(f_cv_grid); // Could be a child dependency of a f_cvb_use_grids feature
}
grid = new colvar_grid_scalar();
grid->init_from_colvars(colvars);
if (is_enabled(f_cvb_bypass_ext_lagrangian)) {
grid->request_actual_value();
}
{
std::string grid_conf;
if (key_lookup(conf, "histogramGrid", &grid_conf)) {
grid->parse_params(grid_conf);
grid->check_keywords(grid_conf, "histogramGrid");
}
}
return COLVARS_OK;
}
colvarbias_histogram::~colvarbias_histogram()
{
if (grid) {
delete grid;
grid = NULL;
}
}
int colvarbias_histogram::update()
{
int error_code = COLVARS_OK;
// update base class
error_code |= colvarbias::update();
if (cvm::debug()) {
cvm::log("Updating histogram bias " + this->name);
}
// assign a valid bin size
bin.assign(num_variables(), 0);
if (out_name.size() == 0) {
// 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 + "\"\n");
}
}
if (out_name_dx.size() == 0) {
if (cvm::step_relative() == 0) {
out_name_dx = cvm::output_prefix() + "." + this->name + ".dx";
cvm::log("Histogram " + this->name + " will be written to file \"" + out_name_dx + "\"\n");
}
}
if (colvar_array_size == 0) {
// update indices for scalar values
size_t i;
for (i = 0; i < num_variables(); i++) {
bin[i] = grid->current_bin_scalar(i);
}
if (can_accumulate_data()) {
if (grid->index_ok(bin)) {
grid->acc_value(bin, 1.0);
}
}
} else {
// update indices for vector/array values
size_t iv, i;
for (iv = 0; iv < colvar_array_size; iv++) {
for (i = 0; i < num_variables(); i++) {
bin[i] = grid->current_bin_scalar(i, iv);
}
if (grid->index_ok(bin)) {
grid->acc_value(bin, weights[iv]);
}
}
}
error_code |= cvm::get_error();
return error_code;
}
int colvarbias_histogram::write_output_files()
{
if (!has_data) {
// nothing to write
return COLVARS_OK;
}
int error_code = COLVARS_OK;
if (out_name.size() && out_name != "none") {
cvm::log("Writing the histogram file \""+out_name+"\".\n");
error_code |= grid->write_multicol(out_name, "histogram output file");
}
if (out_name_dx.size() && out_name_dx != "none") {
cvm::log("Writing the histogram file \""+out_name_dx+"\".\n");
error_code |= grid->write_opendx(out_name_dx, "histogram DX output file");
}
return error_code;
}
std::istream & colvarbias_histogram::read_state_data(std::istream& is)
{
if (! read_state_data_key(is, "grid")) {
return is;
}
if (! grid->read_raw(is)) {
return is;
}
return is;
}
std::ostream & colvarbias_histogram::write_state_data(std::ostream& os)
{
std::ios::fmtflags flags(os.flags());
os.setf(std::ios::fmtflags(0), std::ios::floatfield);
os << "grid\n";
grid->write_raw(os, 8);
os.flags(flags);
return os;
}