1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439
|
// -*- 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.
#ifndef COLVARBIAS_META_H
#define COLVARBIAS_META_H
#include <vector>
#include <list>
#include <iosfwd>
#include "colvarbias.h"
#include "colvargrid.h"
/// Metadynamics bias (implementation of \link colvarbias \endlink)
class colvarbias_meta
: public virtual colvarbias,
public virtual colvarbias_ti
{
public:
/// Communication between different replicas
enum Communication {
/// One replica (default)
single_replica,
/// Hills added concurrently by several replicas
multiple_replicas
};
/// Communication between different replicas
Communication comm;
colvarbias_meta(char const *key);
virtual ~colvarbias_meta();
virtual int init(std::string const &conf);
virtual int init_replicas_params(std::string const &conf);
virtual int init_well_tempered_params(std::string const &conf);
virtual int init_ebmeta_params(std::string const &conf);
virtual int clear_state_data();
virtual int update();
virtual int update_grid_params();
virtual int update_bias();
virtual int update_grid_data();
virtual int replica_share();
virtual size_t replica_share_freq() const;
virtual int calc_energy(std::vector<colvarvalue> const *values);
virtual int calc_forces(std::vector<colvarvalue> const *values);
virtual std::string const get_state_params() const;
virtual int set_state_params(std::string const &state_conf);
virtual std::ostream &write_state_data(std::ostream &os);
virtual cvm::memory_stream &write_state_data(cvm::memory_stream &os);
virtual std::istream &read_state_data(std::istream &is);
virtual cvm::memory_stream &read_state_data(cvm::memory_stream &is);
private:
template <typename IST, typename GT>
IST &read_grid_data_template_(IST &is, std::string const &key, GT *grid, GT *backup_grid);
template <typename IST> IST &read_state_data_template_(IST &is);
template <typename OST> OST &write_state_data_template_(OST &os);
public:
/// Function called by read_state_data() to execute rebinning (if requested)
void rebin_grids_after_restart();
virtual int setup_output();
virtual int write_output_files();
virtual void write_pmf();
virtual int write_state_to_replicas();
class hill;
typedef std::list<hill>::iterator hill_iter;
protected:
/// Width of a hill in number of grid points
///
/// The local width of each collective variable, multiplied by this
/// number, provides the hill width along that direction
cvm::real hill_width;
/// The sigma parameters of the Gaussian hills
std::vector<cvm::real> colvar_sigmas;
/// \brief Number of simulation steps between two hills
size_t new_hill_freq;
/// Write the hill logfile
bool b_hills_traj;
/// Name of the hill logfile
std::string const hills_traj_file_name() const;
/// \brief List of hills used on this bias (total); if a grid is
/// employed, these don't need to be updated at every time step
std::list<hill> hills;
/// \brief Iterator to the first of the "newest" hills (when using
/// grids, those who haven't been mapped yet)
hill_iter new_hills_begin;
/// \brief List of hills used on this bias that are on the boundary
/// edges; these are updated regardless of whether hills are used
std::list<hill> hills_off_grid;
/// \brief Same as new_hills_begin, but for the off-grid ones
hill_iter new_hills_off_grid_begin;
/// Regenerate the hills_off_grid list
void recount_hills_off_grid(hill_iter h_first, hill_iter h_last,
colvar_grid_scalar *ge);
template <typename OST> OST &write_hill_template_(OST &os, colvarbias_meta::hill const &h);
/// Write a hill to a formatted stream
std::ostream &write_hill(std::ostream &os, hill const &h);
/// Write a hill to an unformatted stream
cvm::memory_stream &write_hill(cvm::memory_stream &os, hill const &h);
template <typename IST> IST &read_hill_template_(IST &is);
/// Read a new hill from a formatted stream
std::istream & read_hill(std::istream &is);
/// Read a new hill from an unformatted stream
cvm::memory_stream & read_hill(cvm::memory_stream &is);
/// \brief Add a new hill; if a .hills trajectory is written,
/// write it there; if there is more than one replica, communicate
/// it to the others
std::list<hill>::const_iterator add_hill(hill const &h);
/// \brief Remove a previously saved hill (returns an iterator for
/// the next hill in the list)
std::list<hill>::const_iterator delete_hill(hill_iter &h);
/// \brief Calculate the values of the hills, incrementing
/// bias_energy
virtual void calc_hills(hill_iter h_first,
hill_iter h_last,
cvm::real &energy,
std::vector<colvarvalue> const *values);
/// \brief Calculate the forces acting on the i-th colvar,
/// incrementing colvar_forces[i]; must be called after calc_hills
/// each time the values of the colvars are changed
virtual void calc_hills_force(size_t const &i,
hill_iter h_first,
hill_iter h_last,
std::vector<colvarvalue> &forces,
std::vector<colvarvalue> const *values);
/// Height of new hills
cvm::real hill_weight;
/// \brief Bin the hills on grids of energy and forces, and use them
/// to force the colvars (as opposed to deriving the hills analytically)
bool use_grids;
/// \brief Rebin the hills upon restarting
bool rebin_grids;
/// \brief Should the grids be expanded if necessary?
bool expand_grids;
/// \brief How often the hills should be projected onto the grids
size_t grids_freq;
/// Keep hills in the restart file (e.g. to accurately rebin later)
bool keep_hills;
/// value of keepHills saved in the most recent restart file
bool restart_keep_hills;
/// \brief Dump the free energy surface (.pmf file) every restartFrequency
bool dump_fes;
/// \brief Dump the free energy surface (.pmf file) every restartFrequency
/// using only the hills from this replica (only applicable to more than one replica)
bool dump_replica_fes;
/// \brief Dump the free energy surface files at different
/// time steps, appending the step number to each file
bool dump_fes_save;
/// \brief Whether to use well-tempered metadynamics
bool well_tempered;
/// \brief Biasing temperature in well-tempered metadynamics
cvm::real bias_temperature;
/// Ensemble-biased metadynamics (EBmeta) flag
bool ebmeta;
/// Target distribution for EBmeta
colvar_grid_scalar* target_dist;
/// Number of equilibration steps for EBmeta
cvm::step_number ebmeta_equil_steps;
/// \brief Try to read the restart information by allocating new
/// grids before replacing the current ones (used e.g. in
/// multiple_replicas)
bool safely_read_restart;
/// Hill energy, cached on a grid
colvar_grid_scalar *hills_energy;
/// Hill forces, cached on a grid
colvar_grid_gradient *hills_energy_gradients;
/// \brief Project the selected hills onto grids
void project_hills(hill_iter h_first, hill_iter h_last,
colvar_grid_scalar *ge, colvar_grid_gradient *gf,
bool print_progress = false);
// Multiple Replicas variables and functions
/// \brief Identifier for this replica
std::string replica_id;
/// \brief File containing the paths to the output files from this replica
std::string replica_file_name;
/// \brief Read the existing replicas on registry
virtual int update_replicas_registry();
/// \brief Read new data from replicas' files
virtual int read_replica_files();
/// Write full state information to be read by other replicas
virtual int write_replica_state_file();
/// Call this after write_replica_state_file()
virtual int reopen_replica_buffer_file();
/// \brief Additional, "mirror" metadynamics biases, to collect info
/// from the other replicas
///
/// These are supposed to be synchronized by reading data from the
/// other replicas, and not be modified by the "local" replica
std::vector<colvarbias_meta *> replicas;
/// \brief Frequency at which data the "mirror" biases are updated
size_t replica_update_freq = 0;
/// List of replicas (and their output list files): contents are
/// copied into replicas_registry for convenience
std::string replicas_registry_file;
/// List of replicas (and their output list files)
std::string replicas_registry;
/// List of files written by this replica
std::string replica_list_file;
/// Hills energy and gradients written specifically for other
/// replica (in addition to its own restart file)
std::string replica_state_file;
/// Whether a mirror bias has read the latest version of its state file
bool replica_state_file_in_sync;
/// If there was a failure reading one of the files (because they
/// are not complete), this counter is incremented
size_t update_status;
/// Explicit hills communicated between replicas
///
/// This file becomes empty after replica_state_file is rewritten
std::string replica_hills_file;
/// Position within replica_hills_file (when reading it)
std::streampos replica_hills_file_pos;
/// Cache of the hills trajectory
std::ostringstream hills_traj_os_buf;
};
/// \brief A hill for the metadynamics bias
class colvarbias_meta::hill {
protected:
/// Time step at which this hill was added
cvm::step_number it;
/// Value of the hill function (ranges between 0 and 1)
cvm::real hill_value;
/// Scale factor, which could be modified at runtime (default: 1)
cvm::real sW;
/// Maximum height in energy of the hill
cvm::real W;
/// Centers of the hill in the collective variable space
std::vector<colvarvalue> centers;
/// Half-widths of the hill in the collective variable space
std::vector<cvm::real> sigmas;
/// Identity of the replica who added this hill
std::string replica;
public:
friend class colvarbias_meta;
/// Constructor of a hill object
/// \param it Step number at which the hill was added
/// \param W Weight of the hill (energy units)
/// \param cv_values Array of collective variable values
/// \param cv_sigmas Array of collective variable values
/// \param replica ID of the replica that creates the hill (optional)
hill(cvm::step_number it, cvm::real W,
std::vector<colvarvalue> const &cv_values,
std::vector<cvm::real> const &cv_sigmas,
std::string const &replica = "");
/// Copy constructor
hill(colvarbias_meta::hill const &h);
/// Destructor
~hill();
/// Assignment operator
hill & operator = (colvarbias_meta::hill const &h);
/// Get the energy
inline cvm::real energy()
{
return W * sW * hill_value;
}
/// Get the energy using another hill weight
inline cvm::real energy(cvm::real const &new_weight)
{
return new_weight * sW * hill_value;
}
/// Get the current hill value
inline cvm::real const &value()
{
return hill_value;
}
/// Set the hill value as specified
inline void value(cvm::real const &new_value)
{
hill_value = new_value;
}
/// Get the weight
inline cvm::real weight()
{
return W * sW;
}
/// Scale the weight with this factor (by default 1.0 is used)
inline void scale(cvm::real const &new_scale_fac)
{
sW = new_scale_fac;
}
/// Get the center of the hill
inline std::vector<colvarvalue> & center()
{
return centers;
}
/// Get the i-th component of the center
inline colvarvalue & center(size_t const &i)
{
return centers[i];
}
/// Comparison operator
inline friend bool operator < (hill const &h1, hill const &h2)
{
if (h1.it < h2.it) return true;
else return false;
}
/// Comparison operator
inline friend bool operator <= (hill const &h1, hill const &h2)
{
if (h1.it <= h2.it) return true;
else return false;
}
/// Comparison operator
inline friend bool operator > (hill const &h1, hill const &h2)
{
if (h1.it > h2.it) return true;
else return false;
}
/// Comparison operator
inline friend bool operator >= (hill const &h1, hill const &h2)
{
if (h1.it >= h2.it) return true;
else return false;
}
/// Comparison operator
inline friend bool operator == (hill const &h1, hill const &h2)
{
if ( (h1.it >= h2.it) && (h1.replica == h2.replica) ) return true;
else return false;
}
/// Represent the hill ina string suitable for a trajectory file
std::string output_traj();
};
#endif
|