| version 1.14 | version 1.15 |
|---|
| |
| /// -*- c++ -*- | // -*- c++ -*- |
| | |
| #ifndef COLVARGRID_H | #ifndef COLVARGRID_H |
| #define COLVARGRID_H | #define COLVARGRID_H |
| |
| return mult; | return mult; |
| } | } |
| | |
| | /// \brief Request grid to use actual values of extended coords |
| | inline void request_actual_value(bool b = true) |
| | { |
| | size_t i; |
| | for (i = 0; i < actual_value.size(); i++) { |
| | actual_value[i] = b; |
| | } |
| | } |
| | |
| /// \brief Allocate data | /// \brief Allocate data |
| int setup(std::vector<int> const &nx_i, | int setup(std::vector<int> const &nx_i, |
| T const &t = T(), | T const &t = T(), |
| |
| | |
| size_t i; | size_t i; |
| | |
| for (i = 0; i < cv.size(); i++) { | |
| if (!cv[i]->tasks[colvar::task_lower_boundary] || | |
| !cv[i]->tasks[colvar::task_upper_boundary]) { | |
| cvm::error("Tried to initialize a grid on a " | |
| "variable with undefined boundaries.\n", INPUT_ERROR); | |
| return COLVARS_ERROR; | |
| } | |
| } | |
| | |
| if (cvm::debug()) { | if (cvm::debug()) { |
| cvm::log("Allocating a grid for "+cvm::to_str(colvars.size())+ | cvm::log("Allocating a grid for "+cvm::to_str(colvars.size())+ |
| " collective variables, multiplicity = "+cvm::to_str(mult_i)+".\n"); | " collective variables, multiplicity = "+cvm::to_str(mult_i)+".\n"); |
| |
| | |
| // except if a colvar is specified twice in a row | // except if a colvar is specified twice in a row |
| // then the first instance is the actual value | // then the first instance is the actual value |
| | // For histograms of extended-system coordinates |
| if (i > 0 && cv[i-1] == cv[i]) { | if (i > 0 && cv[i-1] == cv[i]) { |
| actual_value[i-1] = true; | actual_value[i-1] = true; |
| } | } |
| |
| return value_to_bin_scalar(actual_value[i] ? cv[i]->actual_value() : cv[i]->value(), i); | return value_to_bin_scalar(actual_value[i] ? cv[i]->actual_value() : cv[i]->value(), i); |
| } | } |
| | |
| | /// \brief Report the bin corresponding to the current value of item iv in variable i |
| | inline int current_bin_scalar(int const i, int const iv) const |
| | { |
| | return value_to_bin_scalar(actual_value[i] ? |
| | cv[i]->actual_value().vector1d_value[iv] : |
| | cv[i]->value().vector1d_value[iv], i); |
| | } |
| | |
| /// \brief Use the lower boundary and the width to report which bin | /// \brief Use the lower boundary and the width to report which bin |
| /// the provided value is in | /// the provided value is in |
| inline int value_to_bin_scalar(colvarvalue const &value, const int i) const | inline int value_to_bin_scalar(colvarvalue const &value, const int i) const |
| |
| } | } |
| | |
| /// Read a grid definition from a config string | /// Read a grid definition from a config string |
| int parse_params(std::string const &conf) | int parse_params(std::string const &conf, |
| | colvarparse::Parse_Mode const parse_mode = colvarparse::parse_normal) |
| { | { |
| if (cvm::debug()) cvm::log("Reading grid configuration from string.\n"); | if (cvm::debug()) cvm::log("Reading grid configuration from string.\n"); |
| | |
| |
| | |
| { | { |
| size_t nd_in = 0; | size_t nd_in = 0; |
| | // this is only used in state files |
| colvarparse::get_keyval(conf, "n_colvars", nd_in, nd, colvarparse::parse_silent); | colvarparse::get_keyval(conf, "n_colvars", nd_in, nd, colvarparse::parse_silent); |
| if (nd_in != nd) { | if (nd_in != nd) { |
| cvm::error("Error: trying to read data for a grid " | cvm::error("Error: trying to read data for a grid " |
| |
| } | } |
| } | } |
| | |
| | // underscore keywords are used in state file |
| colvarparse::get_keyval(conf, "lower_boundaries", | colvarparse::get_keyval(conf, "lower_boundaries", |
| lower_boundaries, lower_boundaries, colvarparse::parse_silent); | lower_boundaries, lower_boundaries, colvarparse::parse_silent); |
| colvarparse::get_keyval(conf, "upper_boundaries", | colvarparse::get_keyval(conf, "upper_boundaries", |
| upper_boundaries, upper_boundaries, colvarparse::parse_silent); | upper_boundaries, upper_boundaries, colvarparse::parse_silent); |
| | |
| // support also camel case | // camel case keywords are used in config file |
| colvarparse::get_keyval(conf, "lowerBoundaries", | colvarparse::get_keyval(conf, "lowerBoundaries", |
| lower_boundaries, lower_boundaries, colvarparse::parse_silent); | lower_boundaries, lower_boundaries, parse_mode); |
| colvarparse::get_keyval(conf, "upperBoundaries", | colvarparse::get_keyval(conf, "upperBoundaries", |
| upper_boundaries, upper_boundaries, colvarparse::parse_silent); | upper_boundaries, upper_boundaries, parse_mode); |
| | |
| colvarparse::get_keyval(conf, "widths", widths, widths, colvarparse::parse_silent); | colvarparse::get_keyval(conf, "widths", widths, widths, parse_mode); |
| | |
| | // only used in state file |
| colvarparse::get_keyval(conf, "sizes", nx, nx, colvarparse::parse_silent); | colvarparse::get_keyval(conf, "sizes", nx, nx, colvarparse::parse_silent); |
| | |
| if (nd < lower_boundaries.size()) nd = lower_boundaries.size(); | if (nd < lower_boundaries.size()) nd = lower_boundaries.size(); |
| |
| if ((is >> key) && (key == std::string("grid_parameters"))) { | if ((is >> key) && (key == std::string("grid_parameters"))) { |
| is.seekg(start_pos, std::ios::beg); | is.seekg(start_pos, std::ios::beg); |
| is >> colvarparse::read_block("grid_parameters", conf); | is >> colvarparse::read_block("grid_parameters", conf); |
| parse_params(conf); | parse_params(conf, colvarparse::parse_silent); |
| } else { | } else { |
| cvm::log("Grid parameters are missing in the restart file, using those from the configuration.\n"); | cvm::log("Grid parameters are missing in the restart file, using those from the configuration.\n"); |
| is.seekg(start_pos, std::ios::beg); | is.seekg(start_pos, std::ios::beg); |
| |
| | |
| /// \brief Write the grid data without labels, as they are | /// \brief Write the grid data without labels, as they are |
| /// represented in memory | /// represented in memory |
| /// \param buf_size Number of values per line | |
| std::ostream & write_opendx(std::ostream &os) | std::ostream & write_opendx(std::ostream &os) |
| { | { |
| // write the header | // write the header |
| |
| } | } |
| has_data = true; | has_data = true; |
| } | } |
| | |
| | /// \brief Return the log-gradient from finite differences |
| | /// on the *same* grid for dimension n |
| | inline const cvm::real log_gradient_finite_diff( const std::vector<int> &ix0, |
| | int n = 0) |
| | { |
| | cvm::real A0, A1; |
| | std::vector<int> ix; |
| | |
| | // factor for mesh width, 2.0 for central finite difference |
| | // but only 1.0 on edges for non-PBC coordinates |
| | cvm::real factor; |
| | |
| | if (periodic[n]) { |
| | factor = 2.; |
| | ix = ix0; |
| | ix[n]--; wrap(ix); |
| | A0 = data[address(ix)]; |
| | ix = ix0; |
| | ix[n]++; wrap(ix); |
| | A1 = data[address(ix)]; |
| | } else { |
| | factor = 0.; |
| | ix = ix0; |
| | if (ix[n] > 0) { // not left edge |
| | ix[n]--; |
| | factor += 1.; |
| | } |
| | A0 = data[address(ix)]; |
| | ix = ix0; |
| | if (ix[n]+1 < nx[n]) { // not right edge |
| | ix[n]++; |
| | factor += 1.; |
| | } |
| | A1 = data[address(ix)]; |
| | } |
| | if (A0 == 0 || A1 == 0) { |
| | // can't handle empty bins |
| | return 0.; |
| | } else { |
| | return (std::log((cvm::real)A1) - std::log((cvm::real)A0)) |
| | / (widths[n] * factor); |
| | } |
| | } |
| }; | }; |
| | |
| | |