git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@12811 f3b2605a-c512-4ea7-a41b-209d697bcdaa

This commit is contained in:
sjplimp 2014-12-02 02:09:53 +00:00
parent 9c0f849594
commit c4af1cdbbd
34 changed files with 5927 additions and 4786 deletions

File diff suppressed because it is too large Load Diff

View File

@ -31,9 +31,8 @@
///
/// Please note that most of its members are \link colvarvalue
/// \endlink objects, i.e. they can handle different data types
/// together, and must all be set to the same type of colvar::x by
/// using the colvarvalue::type() member function before using them
/// together in assignments or other operations; this is usually done
/// together, and must all be set to the same type of colvar::value()
/// before using them together in assignments or other operations; this is usually done
/// automatically in the constructor. If you add a new member of
/// \link colvarvalue \endlink type, you should also add its
/// initialization line in the \link colvar \endlink constructor.
@ -45,16 +44,13 @@ public:
/// Name
std::string name;
/// Type of value
colvarvalue::Type type() const;
/// \brief Current value (previously obtained from calc() or read_traj())
/// \brief Current value (previously set by calc() or by read_traj())
colvarvalue const & value() const;
/// \brief Current actual value (not extended DOF)
colvarvalue const & actual_value() const;
/// \brief Current velocity (previously obtained from calc() or read_traj())
/// \brief Current velocity (previously set by calc() or by read_traj())
colvarvalue const & velocity() const;
/// \brief Current system force (previously obtained from calc() or
@ -83,9 +79,9 @@ public:
/// combination of \link cvc \endlink elements
bool b_linear;
/// \brief True if this \link colvar \endlink is equal to
/// its only constituent cvc
bool b_single_cvc;
/// \brief True if this \link colvar \endlink is a linear
/// combination of cvcs with coefficients 1 or -1
bool b_homogeneous;
/// \brief True if all \link cvc \endlink objects are capable
/// of calculating inverse gradients
@ -170,11 +166,11 @@ protected:
extended:
H = H_{0} + \sum_{i} 1/2*\lambda*(S_i(x(t))-s_i(t))^2 \\
+ \sum_{i} 1/2*m_i*(ds_i(t)/dt)^2 \\
+ \sum_{t'<t} W * exp (-1/2*\sum_{i} (s_i(t')-s_i(t))^2/(\delta{}s_i)^2) \\
+ \sum_{t'<t} W * exp(-1/2*\sum_{i} (s_i(t')-s_i(t))^2/(\delta{}s_i)^2) \\
+ \sum_{w} (\sum_{i}c_{w,i}s_i(t) - D_w)^M/(\Sigma_w)^M
normal:
H = H_{0} + \sum_{t'<t} W * exp (-1/2*\sum_{i} (S_i(x(t'))-S_i(x(t)))^2/(\delta{}S_i)^2) \\
H = H_{0} + \sum_{t'<t} W * exp(-1/2*\sum_{i} (S_i(x(t'))-S_i(x(t)))^2/(\delta{}S_i)^2) \\
+ \sum_{w} (\sum_{i}c_{w,i}S_i(t) - D_w)^M/(\Sigma_w)^M
output:
@ -190,13 +186,20 @@ protected:
/// Value of the colvar
colvarvalue x;
// TODO: implement functionality to treat these
// /// Vector of individual values from CVCs
// colvarvalue x_cvc;
// /// Jacobian matrix of individual values from CVCs
// colvarvalue dx_cvc;
/// Cached reported value (x may be manipulated)
colvarvalue x_reported;
/// Finite-difference velocity
colvarvalue v_fdiff;
inline colvarvalue fdiff_velocity (colvarvalue const &xold,
inline colvarvalue fdiff_velocity(colvarvalue const &xold,
colvarvalue const &xnew)
{
// using the gradient of the square distance to calculate the
@ -204,7 +207,7 @@ protected:
// account)
cvm::real dt = cvm::dt();
return ( ( (dt > 0.0) ? (1.0/dt) : 1.0 ) *
0.5 * dist2_lgrad (xnew, xold) );
0.5 * dist2_lgrad(xnew, xold) );
}
/// Cached reported velocity
@ -284,17 +287,17 @@ public:
bool periodic_boundaries() const;
/// \brief Is the interval defined by the two boundaries periodic?
bool periodic_boundaries (colvarvalue const &lb, colvarvalue const &ub) const;
bool periodic_boundaries(colvarvalue const &lb, colvarvalue const &ub) const;
/// Constructor
colvar (std::string const &conf);
colvar(std::string const &conf);
/// Enable the specified task
int enable (colvar::task const &t);
int enable(colvar::task const &t);
/// Disable the specified task
void disable (colvar::task const &t);
void disable(colvar::task const &t);
/// Get ready for a run and possibly re-initialize internal data
void setup();
@ -308,13 +311,13 @@ public:
void calc();
/// \brief Calculate just the value, and store it in the argument
void calc_value (colvarvalue &xn);
void calc_value(colvarvalue &xn);
/// Set the total biasing force to zero
void reset_bias_force();
/// Add to the total force from biases
void add_bias_force (colvarvalue const &force);
void add_bias_force(colvarvalue const &force);
/// \brief Collect all forces on this colvar, integrate internal
/// equations of motion of internal degrees of freedom; see also
@ -331,48 +334,48 @@ public:
/// \endlink objects) to calculate square distances and gradients
///
/// Handles correctly symmetries and periodic boundary conditions
cvm::real dist2 (colvarvalue const &x1,
cvm::real dist2(colvarvalue const &x1,
colvarvalue const &x2) const;
/// \brief Use the internal metrics (as from \link cvc
/// \endlink objects) to calculate square distances and gradients
///
/// Handles correctly symmetries and periodic boundary conditions
colvarvalue dist2_lgrad (colvarvalue const &x1,
colvarvalue dist2_lgrad(colvarvalue const &x1,
colvarvalue const &x2) const;
/// \brief Use the internal metrics (as from \link cvc
/// \endlink objects) to calculate square distances and gradients
///
/// Handles correctly symmetries and periodic boundary conditions
colvarvalue dist2_rgrad (colvarvalue const &x1,
colvarvalue dist2_rgrad(colvarvalue const &x1,
colvarvalue const &x2) const;
/// \brief Use the internal metrics (as from \link cvc
/// \endlink objects) to wrap a value into a standard interval
///
/// Handles correctly symmetries and periodic boundary conditions
void wrap (colvarvalue &x) const;
void wrap(colvarvalue &x) const;
/// Read the analysis tasks
int parse_analysis (std::string const &conf);
int parse_analysis(std::string const &conf);
/// Perform analysis tasks
void analyse();
/// Read the value from a collective variable trajectory file
std::istream & read_traj (std::istream &is);
std::istream & read_traj(std::istream &is);
/// Output formatted values to the trajectory file
std::ostream & write_traj (std::ostream &os);
std::ostream & write_traj(std::ostream &os);
/// Write a label to the trajectory file (comment line)
std::ostream & write_traj_label (std::ostream &os);
std::ostream & write_traj_label(std::ostream &os);
/// Read the collective variable from a restart file
std::istream & read_restart (std::istream &is);
std::istream & read_restart(std::istream &is);
/// Write the collective variable to a restart file
std::ostream & write_restart (std::ostream &os);
std::ostream & write_restart(std::ostream &os);
/// Write output files (if defined, e.g. in analysis mode)
int write_output_files();
@ -431,23 +434,23 @@ protected:
acf_type_e acf_type;
/// \brief Velocity ACF, scalar product between v(0) and v(t)
int calc_vel_acf (std::list<colvarvalue> &v_history,
int calc_vel_acf(std::list<colvarvalue> &v_history,
colvarvalue const &v);
/// \brief Coordinate ACF, scalar product between x(0) and x(t)
/// (does not work with scalar numbers)
void calc_coor_acf (std::list<colvarvalue> &x_history,
void calc_coor_acf(std::list<colvarvalue> &x_history,
colvarvalue const &x);
/// \brief Coordinate ACF, second order Legendre polynomial between
/// x(0) and x(t) (does not work with scalar numbers)
void calc_p2coor_acf (std::list<colvarvalue> &x_history,
void calc_p2coor_acf(std::list<colvarvalue> &x_history,
colvarvalue const &x);
/// Calculate the auto-correlation function (ACF)
int calc_acf();
/// Save the ACF to a file
void write_acf (std::ostream &os);
void write_acf(std::ostream &os);
/// Length of running average series
size_t runave_length;
@ -479,6 +482,7 @@ public:
class distance_z;
class distance_xy;
class distance_inv;
class distance_pairs;
class angle;
class dihedral;
class coordnum;
@ -500,6 +504,7 @@ public:
// non-scalar components
class distance_vec;
class distance_dir;
class cartesian;
class orientation;
protected:
@ -509,7 +514,7 @@ protected:
/// \brief Initialize the sorted list of atom IDs for atoms involved
/// in all cvcs (called when enabling task_collect_gradients)
void build_atom_list (void);
void build_atom_list(void);
private:
/// Name of scripted function to be used
@ -528,16 +533,11 @@ public:
/// For scalar variables only!
std::vector<cvm::rvector> atomic_gradients;
inline size_t n_components () const {
inline size_t n_components() const {
return cvcs.size();
}
};
inline colvarvalue::Type colvar::type() const
{
return x.type();
}
inline colvarvalue const & colvar::value() const
{
@ -563,13 +563,14 @@ inline colvarvalue const & colvar::system_force() const
}
inline void colvar::add_bias_force (colvarvalue const &force)
inline void colvar::add_bias_force(colvarvalue const &force)
{
fb += force;
}
inline void colvar::reset_bias_force() {
fb.type(value());
fb.reset();
}

View File

@ -13,28 +13,28 @@
// Note: "conf" is the configuration of the cvc who is using this atom group;
// "key" is the name of the atom group (e.g. "atoms", "group1", "group2", ...)
cvm::atom_group::atom_group (std::string const &conf,
cvm::atom_group::atom_group(std::string const &conf,
char const *key)
: b_center (false), b_rotate (false), b_user_defined_fit (false),
b_fit_gradients (false),
ref_pos_group (NULL),
noforce (false)
: b_center(false), b_rotate(false), b_user_defined_fit(false),
b_fit_gradients(false),
ref_pos_group(NULL),
noforce(false)
{
cvm::log ("Defining atom group \""+
std::string (key)+"\".\n");
cvm::log("Defining atom group \""+
std::string(key)+"\".\n");
// real work is done by parse
parse (conf, key);
parse(conf, key);
}
cvm::atom_group::atom_group (std::vector<cvm::atom> const &atoms)
: b_dummy (false), b_center (false), b_rotate (false),
b_fit_gradients (false), ref_pos_group (NULL),
noforce (false)
cvm::atom_group::atom_group(std::vector<cvm::atom> const &atoms)
: b_dummy(false), b_center(false), b_rotate(false),
b_fit_gradients(false), ref_pos_group(NULL),
noforce(false)
{
this->reserve (atoms.size());
this->reserve(atoms.size());
for (size_t i = 0; i < atoms.size(); i++) {
this->push_back (atoms[i]);
this->push_back(atoms[i]);
}
total_mass = 0.0;
for (cvm::atom_iter ai = this->begin();
@ -45,9 +45,9 @@ cvm::atom_group::atom_group (std::vector<cvm::atom> const &atoms)
cvm::atom_group::atom_group()
: b_dummy (false), b_center (false), b_rotate (false),
b_user_defined_fit (false), b_fit_gradients (false),
ref_pos_group (NULL), noforce (false)
: b_dummy(false), b_center(false), b_rotate(false),
b_user_defined_fit(false), b_fit_gradients(false),
ref_pos_group(NULL), noforce(false)
{
total_mass = 0.0;
}
@ -62,12 +62,12 @@ cvm::atom_group::~atom_group()
}
void cvm::atom_group::add_atom (cvm::atom const &a)
void cvm::atom_group::add_atom(cvm::atom const &a)
{
if (b_dummy) {
cvm::error ("Error: cannot add atoms to a dummy group.\n", INPUT_ERROR);
cvm::error("Error: cannot add atoms to a dummy group.\n", INPUT_ERROR);
} else {
this->push_back (a);
this->push_back(a);
total_mass += a.mass;
}
}
@ -80,12 +80,12 @@ void cvm::atom_group::reset_mass(std::string &name, int i, int j)
ai != this->end(); ai++) {
total_mass += ai->mass;
}
cvm::log ("Re-initialized atom group "+name+":"+cvm::to_str (i)+"/"+
cvm::to_str (j)+". "+ cvm::to_str (this->size())+
" atoms: total mass = "+cvm::to_str (this->total_mass)+".\n");
cvm::log("Re-initialized atom group "+name+":"+cvm::to_str(i)+"/"+
cvm::to_str(j)+". "+ cvm::to_str(this->size())+
" atoms: total mass = "+cvm::to_str(this->total_mass)+".\n");
}
int cvm::atom_group::parse (std::string const &conf,
int cvm::atom_group::parse(std::string const &conf,
char const *key)
{
std::string group_conf;
@ -94,13 +94,13 @@ int cvm::atom_group::parse (std::string const &conf,
// not the config string of this group, but of its parent object
// (which has already taken care of the delimiters)
save_delimiters = false;
key_lookup (conf, key, group_conf, dummy_pos);
key_lookup(conf, key, group_conf, dummy_pos);
// restoring the normal value, because we do want keywords checked
// inside "group_conf"
save_delimiters = true;
if (group_conf.size() == 0) {
cvm::error ("Error: atom group \""+std::string (key)+
cvm::error("Error: atom group \""+std::string(key)+
"\" is set, but has no definition.\n",
INPUT_ERROR);
return COLVARS_ERROR;
@ -108,7 +108,7 @@ int cvm::atom_group::parse (std::string const &conf,
cvm::increase_depth();
cvm::log ("Initializing atom group \""+std::string (key)+"\".\n");
cvm::log("Initializing atom group \""+std::string(key)+"\".\n");
// whether or not to include messages in the log
// colvarparse::Parse_Mode mode = parse_silent;
@ -124,23 +124,23 @@ int cvm::atom_group::parse (std::string const &conf,
std::string numbers_conf = "";
size_t pos = 0;
std::vector<int> atom_indexes;
while (key_lookup (group_conf, "atomNumbers", numbers_conf, pos)) {
while (key_lookup(group_conf, "atomNumbers", numbers_conf, pos)) {
if (numbers_conf.size()) {
std::istringstream is (numbers_conf);
std::istringstream is(numbers_conf);
int ia;
while (is >> ia) {
atom_indexes.push_back (ia);
atom_indexes.push_back(ia);
}
}
if (atom_indexes.size()) {
this->reserve (this->size()+atom_indexes.size());
this->reserve(this->size()+atom_indexes.size());
for (size_t i = 0; i < atom_indexes.size(); i++) {
this->push_back (cvm::atom (atom_indexes[i]));
this->push_back(cvm::atom(atom_indexes[i]));
}
if (cvm::get_error()) return COLVARS_ERROR;
} else {
cvm::error ("Error: no numbers provided for \""
cvm::error("Error: no numbers provided for \""
"atomNumbers\".\n", INPUT_ERROR);
return COLVARS_ERROR;
}
@ -149,7 +149,7 @@ int cvm::atom_group::parse (std::string const &conf,
}
std::string index_group_name;
if (get_keyval (group_conf, "indexGroup", index_group_name)) {
if (get_keyval(group_conf, "indexGroup", index_group_name)) {
// use an index group from the index file read globally
std::list<std::string>::iterator names_i = cvm::index_group_names.begin();
std::list<std::vector<int> >::iterator index_groups_i = cvm::index_groups.begin();
@ -158,14 +158,14 @@ int cvm::atom_group::parse (std::string const &conf,
break;
}
if (names_i == cvm::index_group_names.end()) {
cvm::error ("Error: could not find index group "+
cvm::error("Error: could not find index group "+
index_group_name+" among those provided by the index file.\n",
INPUT_ERROR);
return COLVARS_ERROR;
}
this->reserve (index_groups_i->size());
this->reserve(index_groups_i->size());
for (size_t i = 0; i < index_groups_i->size(); i++) {
this->push_back (cvm::atom ((*index_groups_i)[i]));
this->push_back(cvm::atom((*index_groups_i)[i]));
}
if (cvm::get_error()) return COLVARS_ERROR;
}
@ -174,18 +174,18 @@ int cvm::atom_group::parse (std::string const &conf,
{
std::string range_conf = "";
size_t pos = 0;
while (key_lookup (group_conf, "atomNumbersRange",
while (key_lookup(group_conf, "atomNumbersRange",
range_conf, pos)) {
if (range_conf.size()) {
std::istringstream is (range_conf);
std::istringstream is(range_conf);
int initial, final;
char dash;
if ( (is >> initial) && (initial > 0) &&
(is >> dash) && (dash == '-') &&
(is >> final) && (final > 0) ) {
for (int anum = initial; anum <= final; anum++) {
this->push_back (cvm::atom (anum));
this->push_back(cvm::atom(anum));
}
if (cvm::get_error()) return COLVARS_ERROR;
range_conf = "";
@ -193,18 +193,18 @@ int cvm::atom_group::parse (std::string const &conf,
}
}
cvm::error ("Error: no valid definition for \"atomNumbersRange\", \""+
cvm::error("Error: no valid definition for \"atomNumbersRange\", \""+
range_conf+"\".\n", INPUT_ERROR);
}
}
std::vector<std::string> psf_segids;
get_keyval (group_conf, "psfSegID", psf_segids, std::vector<std::string> (), mode);
get_keyval(group_conf, "psfSegID", psf_segids, std::vector<std::string> (), mode);
for (std::vector<std::string>::iterator psii = psf_segids.begin();
psii < psf_segids.end(); ++psii) {
if ( (psii->size() == 0) || (psii->size() > 4) ) {
cvm::error ("Error: invalid segmend identifier provided, \""+
cvm::error("Error: invalid segmend identifier provided, \""+
(*psii)+"\".\n", INPUT_ERROR);
}
}
@ -214,20 +214,20 @@ int cvm::atom_group::parse (std::string const &conf,
size_t pos = 0;
size_t range_count = 0;
std::vector<std::string>::iterator psii = psf_segids.begin();
while (key_lookup (group_conf, "atomNameResidueRange",
while (key_lookup(group_conf, "atomNameResidueRange",
range_conf, pos)) {
range_count++;
if (range_count > psf_segids.size()) {
cvm::error ("Error: more instances of \"atomNameResidueRange\" than "
cvm::error("Error: more instances of \"atomNameResidueRange\" than "
"values of \"psfSegID\".\n", INPUT_ERROR);
}
std::string const &psf_segid = psf_segids.size() ? *psii : std::string ("");
std::string const &psf_segid = psf_segids.size() ? *psii : std::string("");
if (range_conf.size()) {
std::istringstream is (range_conf);
std::istringstream is(range_conf);
std::string atom_name;
int initial, final;
char dash;
@ -236,18 +236,18 @@ int cvm::atom_group::parse (std::string const &conf,
(is >> dash) && (dash == '-') &&
(is >> final) && (final > 0) ) {
for (int resid = initial; resid <= final; resid++) {
this->push_back (cvm::atom (resid, atom_name, psf_segid));
this->push_back(cvm::atom(resid, atom_name, psf_segid));
}
if (cvm::get_error()) return COLVARS_ERROR;
range_conf = "";
} else {
cvm::error ("Error: cannot parse definition for \""
cvm::error("Error: cannot parse definition for \""
"atomNameResidueRange\", \""+
range_conf+"\".\n");
}
} else {
cvm::error ("Error: atomNameResidueRange with empty definition.\n");
cvm::error("Error: atomNameResidueRange with empty definition.\n");
}
if (psf_segid.size())
@ -258,21 +258,21 @@ int cvm::atom_group::parse (std::string const &conf,
{
// read the atoms from a file
std::string atoms_file_name;
if (get_keyval (group_conf, "atomsFile", atoms_file_name, std::string (""), mode)) {
if (get_keyval(group_conf, "atomsFile", atoms_file_name, std::string(""), mode)) {
std::string atoms_col;
if (!get_keyval (group_conf, "atomsCol", atoms_col, std::string (""), mode)) {
cvm::error ("Error: parameter atomsCol is required if atomsFile is set.\n",
if (!get_keyval(group_conf, "atomsCol", atoms_col, std::string(""), mode)) {
cvm::error("Error: parameter atomsCol is required if atomsFile is set.\n",
INPUT_ERROR);
}
double atoms_col_value;
bool const atoms_col_value_defined = get_keyval (group_conf, "atomsColValue", atoms_col_value, 0.0, mode);
bool const atoms_col_value_defined = get_keyval(group_conf, "atomsColValue", atoms_col_value, 0.0, mode);
if (atoms_col_value_defined && (!atoms_col_value)) {
cvm::error ("Error: atomsColValue, if provided, must be non-zero.\n", INPUT_ERROR);
cvm::error("Error: atomsColValue, if provided, must be non-zero.\n", INPUT_ERROR);
}
cvm::load_atoms (atoms_file_name.c_str(), *this, atoms_col, atoms_col_value);
cvm::load_atoms(atoms_file_name.c_str(), *this, atoms_col, atoms_col_value);
}
}
@ -286,31 +286,31 @@ int cvm::atom_group::parse (std::string const &conf,
for ( ; a2 != this->end(); ++a2) {
if (a1->id == a2->id) {
if (cvm::debug())
cvm::log ("Discarding doubly counted atom with number "+
cvm::to_str (a1->id+1)+".\n");
a2 = this->erase (a2);
cvm::log("Discarding doubly counted atom with number "+
cvm::to_str(a1->id+1)+".\n");
a2 = this->erase(a2);
if (a2 == this->end())
break;
}
}
}
if (get_keyval (group_conf, "dummyAtom", dummy_atom_pos, cvm::atom_pos(), mode)) {
if (get_keyval(group_conf, "dummyAtom", dummy_atom_pos, cvm::atom_pos(), mode)) {
b_dummy = true;
this->total_mass = 1.0;
} else
b_dummy = false;
if (b_dummy && (this->size())) {
cvm::error ("Error: cannot set up group \""+
std::string (key)+"\" as a dummy atom "
cvm::error("Error: cannot set up group \""+
std::string(key)+"\" as a dummy atom "
"and provide it with atom definitions.\n", INPUT_ERROR);
}
#if (! defined (COLVARS_STANDALONE))
#if(! defined(COLVARS_STANDALONE))
if ( (!b_dummy) && (!cvm::b_analysis) && (!(this->size())) ) {
cvm::error ("Error: no atoms defined for atom group \""+
std::string (key)+"\".\n");
cvm::error("Error: no atoms defined for atom group \""+
std::string(key)+"\".\n");
}
#endif
@ -325,39 +325,39 @@ int cvm::atom_group::parse (std::string const &conf,
if (!b_dummy) {
bool enable_forces = true;
// disableForces is deprecated
if (get_keyval (group_conf, "enableForces", enable_forces, true, mode)) {
if (get_keyval(group_conf, "enableForces", enable_forces, true, mode)) {
noforce = !enable_forces;
} else {
get_keyval (group_conf, "disableForces", noforce, false, mode);
get_keyval(group_conf, "disableForces", noforce, false, mode);
}
}
// FITTING OPTIONS
bool b_defined_center = get_keyval (group_conf, "centerReference", b_center, false, mode);
bool b_defined_rotate = get_keyval (group_conf, "rotateReference", b_rotate, false, mode);
bool b_defined_center = get_keyval(group_conf, "centerReference", b_center, false, mode);
bool b_defined_rotate = get_keyval(group_conf, "rotateReference", b_rotate, false, mode);
// is the user setting explicit options?
b_user_defined_fit = b_defined_center || b_defined_rotate;
get_keyval (group_conf, "enableFitGradients", b_fit_gradients, true, mode);
get_keyval(group_conf, "enableFitGradients", b_fit_gradients, true, mode);
if (b_center || b_rotate) {
if (b_dummy)
cvm::error ("Error: centerReference or rotateReference "
cvm::error("Error: centerReference or rotateReference "
"cannot be defined for a dummy atom.\n");
if (key_lookup (group_conf, "refPositionsGroup")) {
if (key_lookup(group_conf, "refPositionsGroup")) {
// instead of this group, define another group to compute the fit
if (ref_pos_group) {
cvm::error ("Error: the atom group \""+
std::string (key)+"\" has already a reference group "
cvm::error("Error: the atom group \""+
std::string(key)+"\" has already a reference group "
"for the rototranslational fit, which was communicated by the "
"colvar component. You should not use refPositionsGroup "
"in this case.\n");
}
cvm::log ("Within atom group \""+std::string (key)+"\":\n");
ref_pos_group = new atom_group (group_conf, "refPositionsGroup");
cvm::log("Within atom group \""+std::string(key)+"\":\n");
ref_pos_group = new atom_group(group_conf, "refPositionsGroup");
// regardless of the configuration, fit gradients must be calculated by refPositionsGroup
ref_pos_group->b_fit_gradients = this->b_fit_gradients;
@ -366,32 +366,32 @@ int cvm::atom_group::parse (std::string const &conf,
atom_group *group_for_fit = ref_pos_group ? ref_pos_group : this;
get_keyval (group_conf, "refPositions", ref_pos, ref_pos, mode);
get_keyval(group_conf, "refPositions", ref_pos, ref_pos, mode);
std::string ref_pos_file;
if (get_keyval (group_conf, "refPositionsFile", ref_pos_file, std::string (""), mode)) {
if (get_keyval(group_conf, "refPositionsFile", ref_pos_file, std::string(""), mode)) {
if (ref_pos.size()) {
cvm::error ("Error: cannot specify \"refPositionsFile\" and "
cvm::error("Error: cannot specify \"refPositionsFile\" and "
"\"refPositions\" at the same time.\n");
}
std::string ref_pos_col;
double ref_pos_col_value;
if (get_keyval (group_conf, "refPositionsCol", ref_pos_col, std::string (""), mode)) {
if (get_keyval(group_conf, "refPositionsCol", ref_pos_col, std::string(""), mode)) {
// if provided, use PDB column to select coordinates
bool found = get_keyval (group_conf, "refPositionsColValue", ref_pos_col_value, 0.0, mode);
bool found = get_keyval(group_conf, "refPositionsColValue", ref_pos_col_value, 0.0, mode);
if (found && !ref_pos_col_value)
cvm::error ("Error: refPositionsColValue, "
cvm::error("Error: refPositionsColValue, "
"if provided, must be non-zero.\n");
} else {
// if not, rely on existing atom indices for the group
group_for_fit->create_sorted_ids();
ref_pos.resize (group_for_fit->size());
ref_pos.resize(group_for_fit->size());
}
cvm::load_coords (ref_pos_file.c_str(), ref_pos, group_for_fit->sorted_ids,
cvm::load_coords(ref_pos_file.c_str(), ref_pos, group_for_fit->sorted_ids,
ref_pos_col, ref_pos_col_value);
}
@ -399,11 +399,11 @@ int cvm::atom_group::parse (std::string const &conf,
if (b_rotate) {
if (ref_pos.size() != group_for_fit->size())
cvm::error ("Error: the number of reference positions provided ("+
cvm::to_str (ref_pos.size())+
cvm::error("Error: the number of reference positions provided("+
cvm::to_str(ref_pos.size())+
") does not match the number of atoms within \""+
std::string (key)+
"\" ("+cvm::to_str (group_for_fit->size())+
std::string(key)+
"\" ("+cvm::to_str(group_for_fit->size())+
"): to perform a rotational fit, "+
"these numbers should be equal.\n", INPUT_ERROR);
}
@ -412,42 +412,42 @@ int cvm::atom_group::parse (std::string const &conf,
center_ref_pos();
} else {
#if (! defined (COLVARS_STANDALONE))
cvm::error ("Error: no reference positions provided.\n");
#if(! defined(COLVARS_STANDALONE))
cvm::error("Error: no reference positions provided.\n");
#endif
}
if (b_fit_gradients) {
group_for_fit->fit_gradients.assign (group_for_fit->size(), cvm::atom_pos (0.0, 0.0, 0.0));
rot.request_group1_gradients (group_for_fit->size());
group_for_fit->fit_gradients.assign(group_for_fit->size(), cvm::atom_pos(0.0, 0.0, 0.0));
rot.request_group1_gradients(group_for_fit->size());
}
if (b_rotate && !noforce) {
cvm::log ("Warning: atom group \""+std::string (key)+
cvm::log("Warning: atom group \""+std::string(key)+
"\" will be aligned to a fixed orientation given by the reference positions provided. "
"If the internal structure of the group changes too much (i.e. its RMSD is comparable "
"to its radius of gyration), the optimal rotation and its gradients may become discontinuous. "
"If that happens, use refPositionsGroup (or a different definition for it if already defined) "
"to align the coordinates.\n");
// initialize rot member data
rot.request_group1_gradients (this->size());
rot.request_group1_gradients(this->size());
}
}
if (cvm::debug())
cvm::log ("Done initializing atom group with name \""+
std::string (key)+"\".\n");
cvm::log("Done initializing atom group with name \""+
std::string(key)+"\".\n");
this->check_keywords (group_conf, key);
this->check_keywords(group_conf, key);
if (cvm::get_error()) {
cvm::error("Error setting up atom group \""+std::string (key)+"\".");
cvm::error("Error setting up atom group \""+std::string(key)+"\".");
return COLVARS_ERROR;
}
cvm::log ("Atom group \""+std::string (key)+"\" defined, "+
cvm::to_str (this->size())+" atoms initialized: total mass = "+
cvm::to_str (this->total_mass)+".\n");
cvm::log("Atom group \""+std::string(key)+"\" defined, "+
cvm::to_str(this->size())+" atoms initialized: total mass = "+
cvm::to_str(this->total_mass)+".\n");
cvm::decrease_depth();
@ -455,7 +455,7 @@ int cvm::atom_group::parse (std::string const &conf,
}
int cvm::atom_group::create_sorted_ids (void)
int cvm::atom_group::create_sorted_ids(void)
{
// Only do the work if the vector is not yet populated
if (sorted_ids.size())
@ -464,12 +464,12 @@ int cvm::atom_group::create_sorted_ids (void)
std::list<int> temp_id_list;
cvm::atom_iter ai;
for (ai = this->begin(); ai != this->end(); ai++) {
temp_id_list.push_back (ai->id);
temp_id_list.push_back(ai->id);
}
temp_id_list.sort();
temp_id_list.unique();
if (temp_id_list.size() != this->size()) {
cvm::error ("Error: duplicate atom IDs in atom group? (found " +
cvm::error("Error: duplicate atom IDs in atom group? (found " +
cvm::to_str(temp_id_list.size()) +
" unique atom IDs instead of" +
cvm::to_str(this->size()) + ").\n");
@ -492,7 +492,7 @@ void cvm::atom_group::center_ref_pos()
// the rotational fit
// This is called either by atom_group::parse or by CVCs that set
// reference positions (eg. RMSD, eigenvector)
ref_pos_cog = cvm::atom_pos (0.0, 0.0, 0.0);
ref_pos_cog = cvm::atom_pos(0.0, 0.0, 0.0);
std::vector<cvm::atom_pos>::iterator pi;
for (pi = ref_pos.begin(); pi != ref_pos.end(); ++pi) {
ref_pos_cog += *pi;
@ -532,11 +532,11 @@ void cvm::atom_group::calc_apply_roto_translation()
if (b_rotate) {
// rotate the group (around the center of geometry if b_center is
// true, around the origin otherwise)
rot.calc_optimal_rotation (fit_group->positions(), ref_pos);
rot.calc_optimal_rotation(fit_group->positions(), ref_pos);
for (cvm::atom_iter ai = this->begin();
ai != this->end(); ai++) {
ai->pos = rot.rotate (ai->pos);
ai->pos = rot.rotate(ai->pos);
}
}
@ -549,7 +549,7 @@ void cvm::atom_group::calc_apply_roto_translation()
}
}
void cvm::atom_group::apply_translation (cvm::rvector const &t)
void cvm::atom_group::apply_translation(cvm::rvector const &t)
{
if (b_dummy) return;
@ -559,13 +559,13 @@ void cvm::atom_group::apply_translation (cvm::rvector const &t)
}
}
void cvm::atom_group::apply_rotation (cvm::rotation const &rot)
void cvm::atom_group::apply_rotation(cvm::rotation const &rot)
{
if (b_dummy) return;
for (cvm::atom_iter ai = this->begin();
ai != this->end(); ai++) {
ai->pos = rot.rotate (ai->pos);
ai->pos = rot.rotate(ai->pos);
}
}
@ -579,7 +579,7 @@ void cvm::atom_group::read_velocities()
for (cvm::atom_iter ai = this->begin();
ai != this->end(); ai++) {
ai->read_velocity();
ai->vel = rot.rotate (ai->vel);
ai->vel = rot.rotate(ai->vel);
}
} else {
@ -600,7 +600,7 @@ void cvm::atom_group::read_system_forces()
for (cvm::atom_iter ai = this->begin();
ai != this->end(); ai++) {
ai->read_system_force();
ai->system_force = rot.rotate (ai->system_force);
ai->system_force = rot.rotate(ai->system_force);
}
} else {
@ -617,7 +617,7 @@ cvm::atom_pos cvm::atom_group::center_of_geometry() const
if (b_dummy)
return dummy_atom_pos;
cvm::atom_pos cog (0.0, 0.0, 0.0);
cvm::atom_pos cog(0.0, 0.0, 0.0);
for (cvm::atom_const_iter ai = this->begin();
ai != this->end(); ai++) {
cog += ai->pos;
@ -631,7 +631,7 @@ cvm::atom_pos cvm::atom_group::center_of_mass() const
if (b_dummy)
return dummy_atom_pos;
cvm::atom_pos com (0.0, 0.0, 0.0);
cvm::atom_pos com(0.0, 0.0, 0.0);
for (cvm::atom_const_iter ai = this->begin();
ai != this->end(); ai++) {
com += ai->mass * ai->pos;
@ -641,7 +641,7 @@ cvm::atom_pos cvm::atom_group::center_of_mass() const
}
void cvm::atom_group::set_weighted_gradient (cvm::rvector const &grad)
void cvm::atom_group::set_weighted_gradient(cvm::rvector const &grad)
{
if (b_dummy) return;
@ -659,21 +659,21 @@ void cvm::atom_group::calc_fit_gradients()
if ((!b_center) && (!b_rotate)) return; // no fit
if (cvm::debug())
cvm::log ("Calculating fit gradients.\n");
cvm::log("Calculating fit gradients.\n");
atom_group *group_for_fit = ref_pos_group ? ref_pos_group : this;
group_for_fit->fit_gradients.assign (group_for_fit->size(), cvm::rvector (0.0, 0.0, 0.0));
group_for_fit->fit_gradients.assign(group_for_fit->size(), cvm::rvector(0.0, 0.0, 0.0));
if (b_center) {
// add the center of geometry contribution to the gradients
for (size_t i = 0; i < this->size(); i++) {
// need to bring the gradients in original frame first
cvm::rvector const atom_grad = b_rotate ?
(rot.inverse()).rotate ((*this)[i].grad) :
(rot.inverse()).rotate((*this)[i].grad) :
(*this)[i].grad;
for (size_t j = 0; j < group_for_fit->size(); j++) {
group_for_fit->fit_gradients[j] +=
(-1.0)/(cvm::real (group_for_fit->size())) *
(-1.0)/(cvm::real(group_for_fit->size())) *
atom_grad;
}
}
@ -687,12 +687,12 @@ void cvm::atom_group::calc_fit_gradients()
for (size_t i = 0; i < this->size(); i++) {
cvm::atom_pos const pos_orig = rot_inv.rotate ((b_center ? ((*this)[i].pos - cog) : ((*this)[i].pos)));
cvm::atom_pos const pos_orig = rot_inv.rotate((b_center ? ((*this)[i].pos - cog) : ((*this)[i].pos)));
for (size_t j = 0; j < group_for_fit->size(); j++) {
// calculate \partial(R(q) \vec{x}_i)/\partial q) \cdot \partial\xi/\partial\vec{x}_i
cvm::quaternion const dxdq =
rot.q.position_derivative_inner (pos_orig, (*this)[i].grad);
rot.q.position_derivative_inner(pos_orig, (*this)[i].grad);
// multiply by \cdot {\partial q}/\partial\vec{x}_j and add it to the fit gradients
for (size_t iq = 0; iq < 4; iq++) {
group_for_fit->fit_gradients[j] += dxdq[iq] * rot.dQ0_1[j][iq];
@ -701,18 +701,18 @@ void cvm::atom_group::calc_fit_gradients()
}
}
if (cvm::debug())
cvm::log ("Done calculating fit gradients.\n");
cvm::log("Done calculating fit gradients.\n");
}
std::vector<cvm::atom_pos> cvm::atom_group::positions() const
{
if (b_dummy) {
cvm::error ("Error: positions are not available "
cvm::error("Error: positions are not available "
"from a dummy atom group.\n");
}
std::vector<cvm::atom_pos> x (this->size(), 0.0);
std::vector<cvm::atom_pos> x(this->size(), 0.0);
cvm::atom_const_iter ai = this->begin();
std::vector<cvm::atom_pos>::iterator xi = x.begin();
for ( ; ai != this->end(); ++xi, ++ai) {
@ -721,14 +721,14 @@ std::vector<cvm::atom_pos> cvm::atom_group::positions() const
return x;
}
std::vector<cvm::atom_pos> cvm::atom_group::positions_shifted (cvm::rvector const &shift) const
std::vector<cvm::atom_pos> cvm::atom_group::positions_shifted(cvm::rvector const &shift) const
{
if (b_dummy) {
cvm::error ("Error: positions are not available "
cvm::error("Error: positions are not available "
"from a dummy atom group.\n");
}
std::vector<cvm::atom_pos> x (this->size(), 0.0);
std::vector<cvm::atom_pos> x(this->size(), 0.0);
cvm::atom_const_iter ai = this->begin();
std::vector<cvm::atom_pos>::iterator xi = x.begin();
for ( ; ai != this->end(); ++xi, ++ai) {
@ -740,11 +740,11 @@ std::vector<cvm::atom_pos> cvm::atom_group::positions_shifted (cvm::rvector cons
std::vector<cvm::rvector> cvm::atom_group::velocities() const
{
if (b_dummy) {
cvm::error ("Error: velocities are not available "
cvm::error("Error: velocities are not available "
"from a dummy atom group.\n");
}
std::vector<cvm::rvector> v (this->size(), 0.0);
std::vector<cvm::rvector> v(this->size(), 0.0);
cvm::atom_const_iter ai = this->begin();
std::vector<cvm::atom_pos>::iterator vi = v.begin();
for ( ; ai != this->end(); vi++, ai++) {
@ -756,11 +756,11 @@ std::vector<cvm::rvector> cvm::atom_group::velocities() const
std::vector<cvm::rvector> cvm::atom_group::system_forces() const
{
if (b_dummy) {
cvm::error ("Error: system forces are not available "
cvm::error("Error: system forces are not available "
"from a dummy atom group.\n");
}
std::vector<cvm::rvector> f (this->size(), 0.0);
std::vector<cvm::rvector> f(this->size(), 0.0);
cvm::atom_const_iter ai = this->begin();
std::vector<cvm::atom_pos>::iterator fi = f.begin();
for ( ; ai != this->end(); ++fi, ++ai) {
@ -772,11 +772,11 @@ std::vector<cvm::rvector> cvm::atom_group::system_forces() const
cvm::rvector cvm::atom_group::system_force() const
{
if (b_dummy) {
cvm::error ("Error: system forces are not available "
cvm::error("Error: system forces are not available "
"from a dummy atom group.\n");
}
cvm::rvector f (0.0);
cvm::rvector f(0.0);
for (cvm::atom_const_iter ai = this->begin(); ai != this->end(); ai++) {
f += ai->system_force;
}
@ -784,13 +784,13 @@ cvm::rvector cvm::atom_group::system_force() const
}
void cvm::atom_group::apply_colvar_force (cvm::real const &force)
void cvm::atom_group::apply_colvar_force(cvm::real const &force)
{
if (b_dummy)
return;
if (noforce) {
cvm::error ("Error: sending a force to a group that has "
cvm::error("Error: sending a force to a group that has "
"\"enableForces\" set to off.\n");
return;
}
@ -801,14 +801,14 @@ void cvm::atom_group::apply_colvar_force (cvm::real const &force)
cvm::rotation const rot_inv = rot.inverse();
for (cvm::atom_iter ai = this->begin();
ai != this->end(); ai++) {
ai->apply_force (rot_inv.rotate (force * ai->grad));
ai->apply_force(rot_inv.rotate(force * ai->grad));
}
} else {
for (cvm::atom_iter ai = this->begin();
ai != this->end(); ai++) {
ai->apply_force (force * ai->grad);
ai->apply_force(force * ai->grad);
}
}
@ -821,11 +821,11 @@ void cvm::atom_group::apply_colvar_force (cvm::real const &force)
// rotate forces back to the original frame
cvm::rotation const rot_inv = rot.inverse();
for (size_t j = 0; j < group_for_fit->size(); j++) {
(*group_for_fit)[j].apply_force (rot_inv.rotate (force * group_for_fit->fit_gradients[j]));
(*group_for_fit)[j].apply_force(rot_inv.rotate(force * group_for_fit->fit_gradients[j]));
}
} else {
for (size_t j = 0; j < group_for_fit->size(); j++) {
(*group_for_fit)[j].apply_force (force * group_for_fit->fit_gradients[j]);
(*group_for_fit)[j].apply_force(force * group_for_fit->fit_gradients[j]);
}
}
}
@ -833,13 +833,13 @@ void cvm::atom_group::apply_colvar_force (cvm::real const &force)
}
void cvm::atom_group::apply_force (cvm::rvector const &force)
void cvm::atom_group::apply_force(cvm::rvector const &force)
{
if (b_dummy)
return;
if (noforce) {
cvm::error ("Error: sending a force to a group that has "
cvm::error("Error: sending a force to a group that has "
"\"disableForces\" defined.\n");
return;
}
@ -849,30 +849,30 @@ void cvm::atom_group::apply_force (cvm::rvector const &force)
cvm::rotation const rot_inv = rot.inverse();
for (cvm::atom_iter ai = this->begin();
ai != this->end(); ai++) {
ai->apply_force (rot_inv.rotate ((ai->mass/this->total_mass) * force));
ai->apply_force(rot_inv.rotate((ai->mass/this->total_mass) * force));
}
} else {
for (cvm::atom_iter ai = this->begin();
ai != this->end(); ai++) {
ai->apply_force ((ai->mass/this->total_mass) * force);
ai->apply_force((ai->mass/this->total_mass) * force);
}
}
}
void cvm::atom_group::apply_forces (std::vector<cvm::rvector> const &forces)
void cvm::atom_group::apply_forces(std::vector<cvm::rvector> const &forces)
{
if (b_dummy)
return;
if (noforce)
cvm::error ("Error: sending a force to a group that has "
cvm::error("Error: sending a force to a group that has "
"\"disableForces\" defined.\n");
if (forces.size() != this->size()) {
cvm::error ("Error: trying to apply an array of forces to an atom "
cvm::error("Error: trying to apply an array of forces to an atom "
"group which does not have the same length.\n");
}
@ -882,7 +882,7 @@ void cvm::atom_group::apply_forces (std::vector<cvm::rvector> const &forces)
cvm::atom_iter ai = this->begin();
std::vector<cvm::rvector>::const_iterator fi = forces.begin();
for ( ; ai != this->end(); ++fi, ++ai) {
ai->apply_force (rot_inv.rotate (*fi));
ai->apply_force(rot_inv.rotate(*fi));
}
} else {
@ -890,7 +890,7 @@ void cvm::atom_group::apply_forces (std::vector<cvm::rvector> const &forces)
cvm::atom_iter ai = this->begin();
std::vector<cvm::rvector>::const_iterator fi = forces.begin();
for ( ; ai != this->end(); ++fi, ++ai) {
ai->apply_force (*fi);
ai->apply_force(*fi);
}
}
}

View File

@ -58,32 +58,32 @@ public:
cvm::rvector grad;
/// \brief Default constructor, setting index and id to invalid numbers
atom() : index (-1), id (-1) { reset_data(); }
atom() : index(-1), id(-1) { reset_data(); }
/// \brief Initialize an atom for collective variable calculation
/// and get its internal identifier \param atom_number Atom index in
/// the system topology (starting from 1)
atom (int const &atom_number);
atom(int const &atom_number);
/// \brief Initialize an atom for collective variable calculation
/// and get its internal identifier \param residue Residue number
/// \param atom_name Name of the atom in the residue \param
/// segment_id For PSF topologies, the segment identifier; for other
/// type of topologies, may not be required
atom (cvm::residue_id const &residue,
atom(cvm::residue_id const &residue,
std::string const &atom_name,
std::string const &segment_id = std::string (""));
std::string const &segment_id = std::string(""));
/// Copy constructor
atom (atom const &a);
atom(atom const &a);
/// Destructor
~atom();
/// Set non-constant data (everything except id and mass) to zero
inline void reset_data() {
pos = atom_pos (0.0);
vel = grad = system_force = rvector (0.0);
pos = atom_pos(0.0);
vel = grad = system_force = rvector(0.0);
}
/// Get the current position
@ -102,7 +102,7 @@ public:
/// motion. Multiple calls to this function by either the same
/// \link atom \endlink object or different objects with identical
/// \link id \endlink, will all add to the existing MD force.
void apply_force (cvm::rvector const &new_force);
void apply_force(cvm::rvector const &new_force);
};
@ -137,7 +137,7 @@ public:
std::vector<int> sorted_ids;
/// Allocates and populates the sorted list of atom ids
int create_sorted_ids (void);
int create_sorted_ids(void);
/// \brief When updating atomic coordinates, translate them to align with the
@ -188,24 +188,24 @@ public:
/// string in conf and parsing it; this is actually done by parse(),
/// which is a member function so that a group can be initialized
/// also after construction
atom_group (std::string const &conf,
atom_group(std::string const &conf,
char const *key);
/// \brief Initialize the group by looking up its configuration
/// string in conf and parsing it
int parse (std::string const &conf,
int parse(std::string const &conf,
char const *key);
/// \brief Initialize the group after a temporary vector of atoms
atom_group (std::vector<cvm::atom> const &atoms);
atom_group(std::vector<cvm::atom> const &atoms);
/// \brief Add an atom to this group
void add_atom (cvm::atom const &a);
void add_atom(cvm::atom const &a);
/// \brief Re-initialize the total mass of a group.
/// This is needed in case the hosting MD code has an option to
/// change atom masses after their initialization.
void reset_mass (std::string &name, int i, int j);
void reset_mass(std::string &name, int i, int j);
/// \brief Default constructor
atom_group();
@ -225,10 +225,10 @@ public:
void center_ref_pos();
/// \brief Move all positions
void apply_translation (cvm::rvector const &t);
void apply_translation(cvm::rvector const &t);
/// \brief Rotate all positions
void apply_rotation (cvm::rotation const &q);
void apply_rotation(cvm::rotation const &q);
/// \brief Get the current velocities; this must be called always
@ -254,7 +254,7 @@ public:
std::vector<cvm::atom_pos> positions() const;
/// \brief Return a copy of the current atom positions, shifted by a constant vector
std::vector<cvm::atom_pos> positions_shifted (cvm::rvector const &shift) const;
std::vector<cvm::atom_pos> positions_shifted(cvm::rvector const &shift) const;
/// \brief Return the center of geometry of the positions, assuming
/// that coordinates are already pbc-wrapped
@ -281,7 +281,7 @@ public:
/// \brief Shorthand: save the specified gradient on each atom,
/// weighting with the atom mass (mostly used in combination with
/// \link center_of_mass() \endlink)
void set_weighted_gradient (cvm::rvector const &grad);
void set_weighted_gradient(cvm::rvector const &grad);
/// \brief Calculate the derivatives of the fitting transformation
void calc_fit_gradients();
@ -301,7 +301,7 @@ public:
/// the group is being rotated to a reference frame (e.g. to express
/// the colvar independently from the solute rotation), the
/// gradients are temporarily rotated to the original frame.
void apply_colvar_force (cvm::real const &force);
void apply_colvar_force(cvm::real const &force);
/// \brief Apply a force "to the center of mass", i.e. the force is
/// distributed on each atom according to its mass
@ -312,7 +312,7 @@ public:
/// are not used, either because they were not defined (e.g because
/// the colvar has not a scalar value) or the biases require to
/// micromanage the force.
void apply_force (cvm::rvector const &force);
void apply_force(cvm::rvector const &force);
/// \brief Apply an array of forces directly on the individual
/// atoms; the length of the specified vector must be the same of
@ -324,7 +324,7 @@ public:
/// are not used, either because they were not defined (e.g because
/// the colvar has not a scalar value) or the biases require to
/// micromanage the forces.
void apply_forces (std::vector<cvm::rvector> const &forces);
void apply_forces(std::vector<cvm::rvector> const &forces);
};

View File

@ -5,54 +5,54 @@
#include "colvarbias.h"
colvarbias::colvarbias (std::string const &conf, char const *key)
: colvarparse(), has_data (false)
colvarbias::colvarbias(std::string const &conf, char const *key)
: colvarparse(), has_data(false)
{
cvm::log ("Initializing a new \""+std::string (key)+"\" instance.\n");
cvm::log("Initializing a new \""+std::string(key)+"\" instance.\n");
size_t rank = 1;
std::string const key_str (key);
std::string const key_str(key);
if (to_lower_cppstr (key_str) == std::string ("abf")) {
if (to_lower_cppstr(key_str) == std::string("abf")) {
rank = cvm::n_abf_biases+1;
}
if (to_lower_cppstr (key_str) == std::string ("harmonic") ||
to_lower_cppstr (key_str) == std::string ("linear")) {
if (to_lower_cppstr(key_str) == std::string("harmonic") ||
to_lower_cppstr(key_str) == std::string("linear")) {
rank = cvm::n_rest_biases+1;
}
if (to_lower_cppstr (key_str) == std::string ("histogram")) {
if (to_lower_cppstr(key_str) == std::string("histogram")) {
rank = cvm::n_histo_biases+1;
}
if (to_lower_cppstr (key_str) == std::string ("metadynamics")) {
if (to_lower_cppstr(key_str) == std::string("metadynamics")) {
rank = cvm::n_meta_biases+1;
}
get_keyval (conf, "name", name, key_str+cvm::to_str (rank));
get_keyval(conf, "name", name, key_str+cvm::to_str(rank));
if (cvm::bias_by_name (this->name) != NULL) {
cvm::error ("Error: this bias cannot have the same name, \""+this->name+
if (cvm::bias_by_name(this->name) != NULL) {
cvm::error("Error: this bias cannot have the same name, \""+this->name+
"\", as another bias.\n", INPUT_ERROR);
return;
}
// lookup the associated colvars
std::vector<std::string> colvars_str;
if (get_keyval (conf, "colvars", colvars_str)) {
if (get_keyval(conf, "colvars", colvars_str)) {
for (size_t i = 0; i < colvars_str.size(); i++) {
add_colvar (colvars_str[i]);
add_colvar(colvars_str[i]);
}
}
if (!colvars.size()) {
cvm::error ("Error: no collective variables specified.\n");
cvm::error("Error: no collective variables specified.\n");
return;
}
get_keyval (conf, "outputEnergy", b_output_energy, false);
get_keyval(conf, "outputEnergy", b_output_energy, false);
}
colvarbias::colvarbias()
: colvarparse(), has_data (false)
: colvarparse(), has_data(false)
{}
colvarbias::~colvarbias()
@ -65,7 +65,7 @@ colvarbias::~colvarbias()
bi != (*cvi)->biases.end();
++bi) {
if ( *bi == this) {
(*cvi)->biases.erase (bi);
(*cvi)->biases.erase(bi);
break;
}
}
@ -75,25 +75,27 @@ colvarbias::~colvarbias()
bi != cvm::biases.end();
++bi) {
if ( *bi == this) {
cvm::biases.erase (bi);
cvm::biases.erase(bi);
break;
}
}
}
void colvarbias::add_colvar (std::string const &cv_name)
void colvarbias::add_colvar(std::string const &cv_name)
{
if (colvar *cvp = cvm::colvar_by_name (cv_name)) {
cvp->enable (colvar::task_gradients);
if (colvar *cv = cvm::colvar_by_name(cv_name)) {
cv->enable(colvar::task_gradients);
if (cvm::debug())
cvm::log ("Applying this bias to collective variable \""+
cvp->name+"\".\n");
colvars.push_back (cvp);
colvar_forces.push_back (colvarvalue (cvp->type()));
cvp->biases.push_back (this); // add back-reference to this bias to colvar
cvm::log("Applying this bias to collective variable \""+
cv->name+"\".\n");
colvars.push_back(cv);
colvar_forces.push_back(colvarvalue());
colvar_forces.back().type(cv->value()); // make sure each forces is initialized to zero
colvar_forces.back().reset();
cv->biases.push_back(this); // add back-reference to this bias to colvar
} else {
cvm::error ("Error: cannot find a colvar named \""+
cv_name+"\".\n");
cvm::error("Error: cannot find a colvar named \""+
cv_name+"\".\n");
}
}
@ -102,24 +104,23 @@ void colvarbias::communicate_forces()
{
for (size_t i = 0; i < colvars.size(); i++) {
if (cvm::debug()) {
cvm::log ("Communicating a force to colvar \""+
colvars[i]->name+"\", of type \""+
colvarvalue::type_desc[colvars[i]->type()]+"\".\n");
cvm::log("Communicating a force to colvar \""+
colvars[i]->name+"\".\n");
}
colvars[i]->add_bias_force (colvar_forces[i]);
colvars[i]->add_bias_force(colvar_forces[i]);
}
}
void colvarbias::change_configuration(std::string const &conf)
{
cvm::error ("Error: change_configuration() not implemented.\n");
cvm::error("Error: change_configuration() not implemented.\n");
}
cvm::real colvarbias::energy_difference(std::string const &conf)
{
cvm::error ("Error: energy_difference() not implemented.\n");
cvm::error("Error: energy_difference() not implemented.\n");
return 0.;
}
@ -127,32 +128,36 @@ cvm::real colvarbias::energy_difference(std::string const &conf)
// So far, these are only implemented in colvarsbias_abf
int colvarbias::bin_num()
{
cvm::error ("Error: bin_num() not implemented.\n");
return -1;
cvm::error("Error: bin_num() not implemented.\n");
return COLVARS_NOT_IMPLEMENTED;
}
int colvarbias::current_bin()
{
cvm::error ("Error: current_bin() not implemented.\n");
return -1;
cvm::error("Error: current_bin() not implemented.\n");
return COLVARS_NOT_IMPLEMENTED;
}
int colvarbias::bin_count(int bin_index)
{
cvm::error ("Error: bin_count() not implemented.\n");
return -1;
cvm::error("Error: bin_count() not implemented.\n");
return COLVARS_NOT_IMPLEMENTED;
}
int colvarbias::replica_share()
{
cvm::error("Error: replica_share() not implemented.\n");
return COLVARS_NOT_IMPLEMENTED;
}
std::ostream & colvarbias::write_traj_label (std::ostream &os)
std::ostream & colvarbias::write_traj_label(std::ostream &os)
{
os << " ";
if (b_output_energy)
os << " E_"
<< cvm::wrap_string (this->name, cvm::en_width-2);
<< cvm::wrap_string(this->name, cvm::en_width-2);
return os;
}
std::ostream & colvarbias::write_traj (std::ostream &os)
std::ostream & colvarbias::write_traj(std::ostream &os)
{
os << " ";
if (b_output_energy)

View File

@ -15,7 +15,7 @@ public:
std::string name;
/// Add a new collective variable to this bias
void add_colvar (std::string const &cv_name);
void add_colvar(std::string const &cv_name);
/// Retrieve colvar values and calculate their biasing forces
/// Return bias energy
@ -34,9 +34,9 @@ public:
/// Calculate the bin index for a given bias.
virtual int current_bin();
//// Give the count at a given bin index.
virtual int bin_count(int bin_index);
virtual int bin_count(int bin_index);
//// Share information between replicas, whatever it may be.
virtual void replica_share() {};
virtual int replica_share();
/// Perform analysis tasks
virtual inline void analyse() {}
@ -48,7 +48,7 @@ public:
///
/// The constructor of the colvarbias base class is protected, so
/// that it can only be called from inherited classes
colvarbias (std::string const &conf, char const *key);
colvarbias(std::string const &conf, char const *key);
/// Default constructor
colvarbias();
@ -57,18 +57,18 @@ public:
virtual ~colvarbias();
/// Read the bias configuration from a restart file
virtual std::istream & read_restart (std::istream &is) = 0;
virtual std::istream & read_restart(std::istream &is) = 0;
/// Write the bias configuration to a restart file
virtual std::ostream & write_restart (std::ostream &os) = 0;
virtual std::ostream & write_restart(std::ostream &os) = 0;
/// Write a label to the trajectory file (comment line)
virtual std::ostream & write_traj_label (std::ostream &os);
virtual std::ostream & write_traj_label(std::ostream &os);
/// Output quantities such as the bias energy to the trajectory file
virtual std::ostream & write_traj (std::ostream &os);
virtual std::ostream & write_traj(std::ostream &os);
inline cvm::real get_energy () {
inline cvm::real get_energy() {
return bias_energy;
}
protected:

View File

@ -10,85 +10,85 @@
/// ABF bias constructor; parses the config file
colvarbias_abf::colvarbias_abf (std::string const &conf, char const *key)
: colvarbias (conf, key),
gradients (NULL),
samples (NULL)
colvarbias_abf::colvarbias_abf(std::string const &conf, char const *key)
: colvarbias(conf, key),
gradients(NULL),
samples(NULL)
{
// TODO relax this in case of VMD plugin
if (cvm::temperature() == 0.0)
cvm::log ("WARNING: ABF should not be run without a thermostat or at 0 Kelvin!\n");
cvm::log("WARNING: ABF should not be run without a thermostat or at 0 Kelvin!\n");
// ************* parsing general ABF options ***********************
get_keyval (conf, "applyBias", apply_bias, true);
if (!apply_bias) cvm::log ("WARNING: ABF biases will *not* be applied!\n");
get_keyval(conf, "applyBias", apply_bias, true);
if (!apply_bias) cvm::log("WARNING: ABF biases will *not* be applied!\n");
get_keyval (conf, "updateBias", update_bias, true);
if (!update_bias) cvm::log ("WARNING: ABF biases will *not* be updated!\n");
get_keyval(conf, "updateBias", update_bias, true);
if (!update_bias) cvm::log("WARNING: ABF biases will *not* be updated!\n");
get_keyval (conf, "hideJacobian", hide_Jacobian, false);
get_keyval(conf, "hideJacobian", hide_Jacobian, false);
if (hide_Jacobian) {
cvm::log ("Jacobian (geometric) forces will be handled internally.\n");
cvm::log("Jacobian (geometric) forces will be handled internally.\n");
} else {
cvm::log ("Jacobian (geometric) forces will be included in reported free energy gradients.\n");
cvm::log("Jacobian (geometric) forces will be included in reported free energy gradients.\n");
}
get_keyval (conf, "fullSamples", full_samples, 200);
get_keyval(conf, "fullSamples", full_samples, 200);
if ( full_samples <= 1 ) full_samples = 1;
min_samples = full_samples / 2;
// full_samples - min_samples >= 1 is guaranteed
get_keyval (conf, "inputPrefix", input_prefix, std::vector<std::string> ());
get_keyval (conf, "outputFreq", output_freq, cvm::restart_out_freq);
get_keyval (conf, "historyFreq", history_freq, 0);
get_keyval(conf, "inputPrefix", input_prefix, std::vector<std::string> ());
get_keyval(conf, "outputFreq", output_freq, cvm::restart_out_freq);
get_keyval(conf, "historyFreq", history_freq, 0);
b_history_files = (history_freq > 0);
// shared ABF
get_keyval (conf, "shared", shared_on, false);
get_keyval(conf, "shared", shared_on, false);
if (shared_on) {
if (!cvm::replica_enabled || cvm::replica_num() <= 1)
cvm::error ("Error: shared ABF requires more than one replica.");
cvm::error("Error: shared ABF requires more than one replica.");
else
cvm::log ("shared ABF will be applied among "+ cvm::to_str(cvm::replica_num()) + " replicas.\n");
cvm::log("shared ABF will be applied among "+ cvm::to_str(cvm::replica_num()) + " replicas.\n");
// If shared_freq is not set, we default to output_freq
get_keyval (conf, "sharedFreq", shared_freq, output_freq);
get_keyval(conf, "sharedFreq", shared_freq, output_freq);
}
// ************* checking the associated colvars *******************
if (colvars.size() == 0) {
cvm::error ("Error: no collective variables specified for the ABF bias.\n");
cvm::error("Error: no collective variables specified for the ABF bias.\n");
}
for (size_t i = 0; i < colvars.size(); i++) {
if (colvars[i]->type() != colvarvalue::type_scalar) {
cvm::error ("Error: ABF bias can only use scalar-type variables.\n");
if (colvars[i]->value().type() != colvarvalue::type_scalar) {
cvm::error("Error: ABF bias can only use scalar-type variables.\n");
}
colvars[i]->enable (colvar::task_gradients);
colvars[i]->enable(colvar::task_gradients);
if (update_bias) {
// Request calculation of system force (which also checks for availability)
colvars[i]->enable (colvar::task_system_force);
colvars[i]->enable(colvar::task_system_force);
if (!colvars[i]->tasks[colvar::task_extended_lagrangian]) {
// request computation of Jacobian force
colvars[i]->enable (colvar::task_Jacobian_force);
colvars[i]->enable(colvar::task_Jacobian_force);
// request Jacobian force as part as system force
// except if the user explicitly requires the "silent" Jacobian
// correction AND the colvar has a single component
if (hide_Jacobian) {
if (colvars[i]->n_components() > 1) {
cvm::log ("WARNING: colvar \"" + colvars[i]->name
cvm::log("WARNING: colvar \"" + colvars[i]->name
+ "\" has multiple components; reporting its Jacobian forces\n");
colvars[i]->enable (colvar::task_report_Jacobian_force);
colvars[i]->enable(colvar::task_report_Jacobian_force);
}
} else {
colvars[i]->enable (colvar::task_report_Jacobian_force);
colvars[i]->enable(colvar::task_report_Jacobian_force);
}
}
}
@ -97,13 +97,13 @@ colvarbias_abf::colvarbias_abf (std::string const &conf, char const *key)
// and make it just a warning if some parameter is set?
}
if (get_keyval (conf, "maxForce", max_force)) {
if (get_keyval(conf, "maxForce", max_force)) {
if (max_force.size() != colvars.size()) {
cvm::error ("Error: Number of parameters to maxForce does not match number of colvars.");
cvm::error("Error: Number of parameters to maxForce does not match number of colvars.");
}
for (size_t i=0; i<colvars.size(); i++) {
if (max_force[i] < 0.0) {
cvm::error ("Error: maxForce should be non-negative.");
cvm::error("Error: maxForce should be non-negative.");
}
}
cap_force = true;
@ -111,13 +111,13 @@ colvarbias_abf::colvarbias_abf (std::string const &conf, char const *key)
cap_force = false;
}
bin.assign (colvars.size(), 0);
force_bin.assign (colvars.size(), 0);
bin.assign(colvars.size(), 0);
force_bin.assign(colvars.size(), 0);
force = new cvm::real [colvars.size()];
// Construct empty grids based on the colvars
samples = new colvar_grid_count (colvars);
gradients = new colvar_grid_gradient (colvars);
gradients = new colvar_grid_gradient(colvars);
gradients->samples = samples;
samples->has_parent_data = true;
@ -125,17 +125,17 @@ colvarbias_abf::colvarbias_abf (std::string const &conf, char const *key)
// This used to be only if "shared" was defined,
// but now we allow calling share externally (e.g. from Tcl).
last_samples = new colvar_grid_count (colvars);
last_gradients = new colvar_grid_gradient (colvars);
last_gradients = new colvar_grid_gradient(colvars);
last_gradients->samples = last_samples;
last_samples->has_parent_data = true;
shared_last_step = -1;
// If custom grids are provided, read them
if ( input_prefix.size() > 0 ) {
read_gradients_samples ();
read_gradients_samples();
}
cvm::log ("Finished ABF setup.\n");
cvm::log("Finished ABF setup.\n");
}
/// Destructor
@ -176,7 +176,7 @@ colvarbias_abf::~colvarbias_abf()
cvm::real colvarbias_abf::update()
{
if (cvm::debug()) cvm::log ("Updating ABF bias " + this->name);
if (cvm::debug()) cvm::log("Updating ABF bias " + this->name);
if (cvm::step_relative() == 0) {
@ -201,13 +201,13 @@ cvm::real colvarbias_abf::update()
bin[i] = samples->current_bin_scalar(i);
}
if ( update_bias && samples->index_ok (force_bin) ) {
if ( update_bias && samples->index_ok(force_bin) ) {
// Only if requested and within bounds of the grid...
for (size_t i=0; i<colvars.size(); i++) { // get forces (lagging by 1 timestep) from colvars
for (size_t i=0; i<colvars.size(); i++) { // get forces(lagging by 1 timestep) from colvars
force[i] = colvars[i]->system_force();
}
gradients->acc_force (force_bin, force);
gradients->acc_force(force_bin, force);
}
}
@ -220,28 +220,28 @@ cvm::real colvarbias_abf::update()
}
// Compute and apply the new bias, if applicable
if ( apply_bias && samples->index_ok (bin) ) {
if ( apply_bias && samples->index_ok(bin) ) {
size_t count = samples->value (bin);
size_t count = samples->value(bin);
cvm::real fact = 1.0;
// Factor that ensures smooth introduction of the force
if ( count < full_samples ) {
fact = ( count < min_samples) ? 0.0 :
(cvm::real (count - min_samples)) / (cvm::real (full_samples - min_samples));
(cvm::real(count - min_samples)) / (cvm::real(full_samples - min_samples));
}
const cvm::real * grad = &(gradients->value (bin));
const cvm::real * grad = &(gradients->value(bin));
if ( fact != 0.0 ) {
if ( (colvars.size() == 1) && colvars[0]->periodic_boundaries() ) {
// Enforce a zero-mean bias on periodic, 1D coordinates
// in other words: boundary condition is that the biasing potential is periodic
colvar_forces[0].real_value = fact * (grad[0] / cvm::real (count) - gradients->average ());
colvar_forces[0].real_value = fact * (grad[0] / cvm::real(count) - gradients->average());
} else {
for (size_t i=0; i<colvars.size(); i++) {
// subtracting the mean force (opposite of the FE gradient) means adding the gradient
colvar_forces[i].real_value = fact * grad[i] / cvm::real (count);
colvar_forces[i].real_value = fact * grad[i] / cvm::real(count);
}
}
if (cap_force) {
@ -255,14 +255,14 @@ cvm::real colvarbias_abf::update()
}
if (output_freq && (cvm::step_absolute() % output_freq) == 0) {
if (cvm::debug()) cvm::log ("ABF bias trying to write gradients and samples to disk");
write_gradients_samples (output_prefix);
if (cvm::debug()) cvm::log("ABF bias trying to write gradients and samples to disk");
write_gradients_samples(output_prefix);
}
if (b_history_files && (cvm::step_absolute() % history_freq) == 0) {
cvm::log ("ABFHISTORYFILE "+cvm::to_str(cvm::step_absolute()));
cvm::log("ABFHISTORYFILE "+cvm::to_str(cvm::step_absolute()));
// append to existing file only if cvm::step_absolute() > 0
// otherwise, backup and replace
write_gradients_samples (output_prefix + ".hist", (cvm::step_absolute() > 0));
write_gradients_samples(output_prefix + ".hist", (cvm::step_absolute() > 0));
}
if (shared_on && shared_last_step >= 0 && cvm::step_absolute() % shared_freq == 0) {
@ -276,27 +276,27 @@ cvm::real colvarbias_abf::update()
last_gradients->copy_grid(*gradients);
last_samples->copy_grid(*samples);
shared_last_step = cvm::step_absolute();
cvm::log ("Prepared sample and gradient buffers at step "+cvm::to_str(cvm::step_absolute())+".");
cvm::log("Prepared sample and gradient buffers at step "+cvm::to_str(cvm::step_absolute())+".");
}
return 0.0;
}
void colvarbias_abf::replica_share () {
int colvarbias_abf::replica_share() {
int p;
if( !cvm::replica_enabled() ) {
cvm::error ("Error: shared ABF: No replicas.\n");
return;
if ( !cvm::replica_enabled() ) {
cvm::error("Error: shared ABF: No replicas.\n");
return COLVARS_ERROR;
}
// We must have stored the last_gradients and last_samples.
if (shared_last_step < 0 ) {
cvm::error ("Error: shared ABF: Tried to apply shared ABF before any sampling had occurred.\n");
return;
cvm::error("Error: shared ABF: Tried to apply shared ABF before any sampling had occurred.\n");
return COLVARS_ERROR;
}
// Share gradients for shared ABF.
cvm::log ("shared ABF: Sharing gradient and samples among replicas at step "+cvm::to_str(cvm::step_absolute()) );
cvm::log("shared ABF: Sharing gradient and samples among replicas at step "+cvm::to_str(cvm::step_absolute()) );
// Count of data items.
size_t data_n = gradients->raw_data_num();
@ -330,8 +330,8 @@ void colvarbias_abf::replica_share () {
} else {
// All other replicas send their delta gradient and count.
// Calculate the delta gradient and count.
last_gradients->delta_grid (*gradients);
last_samples->delta_grid (*samples);
last_gradients->delta_grid(*gradients);
last_samples->delta_grid(*samples);
// Cast the raw char data to the gradient and samples.
last_gradients->raw_data_out((cvm::real*)(&msg_data[0]));
@ -355,9 +355,11 @@ void colvarbias_abf::replica_share () {
last_gradients->copy_grid(*gradients);
last_samples->copy_grid(*samples);
shared_last_step = cvm::step_absolute();
return COLVARS_OK;
}
void colvarbias_abf::write_gradients_samples (const std::string &prefix, bool append)
void colvarbias_abf::write_gradients_samples(const std::string &prefix, bool append)
{
std::string samples_out_name = prefix + ".count";
std::string gradients_out_name = prefix + ".grad";
@ -366,28 +368,28 @@ void colvarbias_abf::write_gradients_samples (const std::string &prefix, bool ap
std::ofstream samples_os;
std::ofstream gradients_os;
if (!append) cvm::backup_file (samples_out_name.c_str());
samples_os.open (samples_out_name.c_str(), mode);
if (!samples_os.good()) cvm::error ("Error opening ABF samples file " + samples_out_name + " for writing");
samples->write_multicol (samples_os);
samples_os.close ();
if (!append) cvm::backup_file(samples_out_name.c_str());
samples_os.open(samples_out_name.c_str(), mode);
if (!samples_os.good()) cvm::error("Error opening ABF samples file " + samples_out_name + " for writing");
samples->write_multicol(samples_os);
samples_os.close();
if (!append) cvm::backup_file (gradients_out_name.c_str());
gradients_os.open (gradients_out_name.c_str(), mode);
if (!gradients_os.good()) cvm::error ("Error opening ABF gradient file " + gradients_out_name + " for writing");
gradients->write_multicol (gradients_os);
gradients_os.close ();
if (!append) cvm::backup_file(gradients_out_name.c_str());
gradients_os.open(gradients_out_name.c_str(), mode);
if (!gradients_os.good()) cvm::error("Error opening ABF gradient file " + gradients_out_name + " for writing");
gradients->write_multicol(gradients_os);
gradients_os.close();
if (colvars.size () == 1) {
if (colvars.size() == 1) {
std::string pmf_out_name = prefix + ".pmf";
if (!append) cvm::backup_file (pmf_out_name.c_str());
if (!append) cvm::backup_file(pmf_out_name.c_str());
std::ofstream pmf_os;
// Do numerical integration and output a PMF
pmf_os.open (pmf_out_name.c_str(), mode);
if (!pmf_os.good()) cvm::error ("Error opening pmf file " + pmf_out_name + " for writing");
gradients->write_1D_integral (pmf_os);
pmf_os.open(pmf_out_name.c_str(), mode);
if (!pmf_os.good()) cvm::error("Error opening pmf file " + pmf_out_name + " for writing");
gradients->write_1D_integral(pmf_os);
pmf_os << std::endl;
pmf_os.close ();
pmf_os.close();
}
return;
}
@ -405,7 +407,7 @@ int colvarbias_abf::current_bin() {
/// Give the count at a given bin index.
int colvarbias_abf::bin_count(int bin_index) {
if (bin_index < 0 || bin_index >= bin_num()) {
cvm::error ("Error: Tried to get bin count from invalid bin index "+cvm::to_str(bin_index));
cvm::error("Error: Tried to get bin count from invalid bin index "+cvm::to_str(bin_index));
return -1;
}
std::vector<int> ix(1,(int)bin_index);
@ -413,7 +415,7 @@ int colvarbias_abf::bin_count(int bin_index) {
}
void colvarbias_abf::read_gradients_samples ()
void colvarbias_abf::read_gradients_samples()
{
std::string samples_in_name, gradients_in_name;
@ -424,27 +426,27 @@ void colvarbias_abf::read_gradients_samples ()
std::ifstream is;
cvm::log ("Reading sample count from " + samples_in_name + " and gradients from " + gradients_in_name);
is.open (samples_in_name.c_str());
if (!is.good()) cvm::error ("Error opening ABF samples file " + samples_in_name + " for reading");
samples->read_multicol (is, true);
is.close ();
cvm::log("Reading sample count from " + samples_in_name + " and gradients from " + gradients_in_name);
is.open(samples_in_name.c_str());
if (!is.good()) cvm::error("Error opening ABF samples file " + samples_in_name + " for reading");
samples->read_multicol(is, true);
is.close();
is.clear();
is.open (gradients_in_name.c_str());
if (!is.good()) cvm::error ("Error opening ABF gradient file " + gradients_in_name + " for reading");
gradients->read_multicol (is, true);
is.close ();
is.open(gradients_in_name.c_str());
if (!is.good()) cvm::error("Error opening ABF gradient file " + gradients_in_name + " for reading");
gradients->read_multicol(is, true);
is.close();
}
return;
}
std::ostream & colvarbias_abf::write_restart (std::ostream& os)
std::ostream & colvarbias_abf::write_restart(std::ostream& os)
{
std::ios::fmtflags flags (os.flags ());
os.setf(std::ios::fmtflags (0), std::ios::floatfield); // default floating-point format
std::ios::fmtflags flags(os.flags());
os.setf(std::ios::fmtflags(0), std::ios::floatfield); // default floating-point format
os << "abf {\n"
<< " configuration {\n"
@ -452,89 +454,89 @@ std::ostream & colvarbias_abf::write_restart (std::ostream& os)
os << " }\n";
os << "samples\n";
samples->write_raw (os, 8);
samples->write_raw(os, 8);
os << "\ngradient\n";
gradients->write_raw (os);
gradients->write_raw(os);
os << "}\n\n";
os.flags (flags);
os.flags(flags);
return os;
}
std::istream & colvarbias_abf::read_restart (std::istream& is)
std::istream & colvarbias_abf::read_restart(std::istream& is)
{
if ( input_prefix.size() > 0 ) {
cvm::error ("ERROR: cannot provide both inputPrefix and restart information (colvarsInput)");
cvm::error("ERROR: cannot provide both inputPrefix and restart information(colvarsInput)");
}
size_t const start_pos = is.tellg();
cvm::log ("Restarting ABF bias \""+
cvm::log("Restarting ABF bias \""+
this->name+"\".\n");
std::string key, brace, conf;
if ( !(is >> key) || !(key == "abf") ||
!(is >> brace) || !(brace == "{") ||
!(is >> colvarparse::read_block ("configuration", conf)) ) {
cvm::log ("Error: in reading restart configuration for ABF bias \""+
!(is >> colvarparse::read_block("configuration", conf)) ) {
cvm::log("Error: in reading restart configuration for ABF bias \""+
this->name+"\" at position "+
cvm::to_str (is.tellg())+" in stream.\n");
cvm::to_str(is.tellg())+" in stream.\n");
is.clear();
is.seekg (start_pos, std::ios::beg);
is.setstate (std::ios::failbit);
is.seekg(start_pos, std::ios::beg);
is.setstate(std::ios::failbit);
return is;
}
std::string name = "";
if ( (colvarparse::get_keyval (conf, "name", name, std::string (""), colvarparse::parse_silent)) &&
if ( (colvarparse::get_keyval(conf, "name", name, std::string(""), colvarparse::parse_silent)) &&
(name != this->name) )
cvm::error ("Error: in the restart file, the "
"\"abf\" block has wrong name (" + name + ")\n");
cvm::error("Error: in the restart file, the "
"\"abf\" block has wrong name(" + name + ")\n");
if ( name == "" ) {
cvm::error ("Error: \"abf\" block in the restart file has no name.\n");
cvm::error("Error: \"abf\" block in the restart file has no name.\n");
}
if ( !(is >> key) || !(key == "samples")) {
cvm::log ("Error: in reading restart configuration for ABF bias \""+
cvm::log("Error: in reading restart configuration for ABF bias \""+
this->name+"\" at position "+
cvm::to_str (is.tellg())+" in stream.\n");
cvm::to_str(is.tellg())+" in stream.\n");
is.clear();
is.seekg (start_pos, std::ios::beg);
is.setstate (std::ios::failbit);
is.seekg(start_pos, std::ios::beg);
is.setstate(std::ios::failbit);
return is;
}
if (! samples->read_raw (is)) {
if (! samples->read_raw(is)) {
is.clear();
is.seekg (start_pos, std::ios::beg);
is.setstate (std::ios::failbit);
is.seekg(start_pos, std::ios::beg);
is.setstate(std::ios::failbit);
return is;
}
if ( !(is >> key) || !(key == "gradient")) {
cvm::log ("Error: in reading restart configuration for ABF bias \""+
cvm::log("Error: in reading restart configuration for ABF bias \""+
this->name+"\" at position "+
cvm::to_str (is.tellg())+" in stream.\n");
cvm::to_str(is.tellg())+" in stream.\n");
is.clear();
is.seekg (start_pos, std::ios::beg);
is.setstate (std::ios::failbit);
is.seekg(start_pos, std::ios::beg);
is.setstate(std::ios::failbit);
return is;
}
if (! gradients->read_raw (is)) {
if (! gradients->read_raw(is)) {
is.clear();
is.seekg (start_pos, std::ios::beg);
is.setstate (std::ios::failbit);
is.seekg(start_pos, std::ios::beg);
is.setstate(std::ios::failbit);
return is;
}
is >> brace;
if (brace != "}") {
cvm::error ("Error: corrupt restart information for ABF bias \""+
cvm::error("Error: corrupt restart information for ABF bias \""+
this->name+"\": no matching brace at position "+
cvm::to_str (is.tellg())+" in the restart file.\n");
is.setstate (std::ios::failbit);
cvm::to_str(is.tellg())+" in the restart file.\n");
is.setstate(std::ios::failbit);
}
return is;
}
@ -544,23 +546,20 @@ std::istream & colvarbias_abf::read_restart (std::istream& is)
/// Histogram "bias" constructor
colvarbias_histogram::colvarbias_histogram (std::string const &conf, char const *key)
: colvarbias (conf, key),
grid (NULL)
colvarbias_histogram::colvarbias_histogram(std::string const &conf, char const *key)
: colvarbias(conf, key),
grid(NULL), out_name("")
{
get_keyval (conf, "outputfreq", output_freq, cvm::restart_out_freq);
get_keyval(conf, "outputfreq", output_freq, cvm::restart_out_freq);
if ( output_freq == 0 ) {
cvm::error ("User required histogram with zero output frequency");
cvm::error("User required histogram with zero output frequency");
}
grid = new colvar_grid_count (colvars);
bin.assign (colvars.size(), 0);
bin.assign(colvars.size(), 0);
out_name = cvm::output_prefix + "." + this->name + ".dat";
cvm::log ("Histogram will be written to file " + out_name);
cvm::log ("Finished histogram setup.\n");
cvm::log("Finished histogram setup.\n");
}
/// Destructor
@ -580,86 +579,94 @@ colvarbias_histogram::~colvarbias_histogram()
/// Update the grid
cvm::real colvarbias_histogram::update()
{
if (cvm::debug()) cvm::log ("Updating Grid bias " + this->name);
if (cvm::debug()) cvm::log("Updating Grid bias " + this->name);
// 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 + "\"");
}
for (size_t i=0; i<colvars.size(); i++) {
bin[i] = grid->current_bin_scalar(i);
}
if ( grid->index_ok (bin) ) { // Only within bounds of the grid...
grid->incr_count (bin);
if ( grid->index_ok(bin) ) { // Only within bounds of the grid...
grid->incr_count(bin);
}
if (output_freq && (cvm::step_absolute() % output_freq) == 0) {
if (cvm::debug()) cvm::log ("Histogram bias trying to write grid to disk");
if (cvm::debug()) cvm::log("Histogram bias trying to write grid to disk");
grid_os.open (out_name.c_str());
if (!grid_os.good()) cvm::error ("Error opening histogram file " + out_name + " for writing");
grid->write_multicol (grid_os);
grid_os.close ();
grid_os.open(out_name.c_str());
if (!grid_os.good()) cvm::error("Error opening histogram file " + out_name + " for writing");
grid->write_multicol(grid_os);
grid_os.close();
}
return 0.0; // no bias energy for histogram
}
std::istream & colvarbias_histogram::read_restart (std::istream& is)
std::istream & colvarbias_histogram::read_restart(std::istream& is)
{
size_t const start_pos = is.tellg();
cvm::log ("Restarting collective variable histogram \""+
cvm::log("Restarting collective variable histogram \""+
this->name+"\".\n");
std::string key, brace, conf;
if ( !(is >> key) || !(key == "histogram") ||
!(is >> brace) || !(brace == "{") ||
!(is >> colvarparse::read_block ("configuration", conf)) ) {
cvm::log ("Error: in reading restart configuration for histogram \""+
!(is >> colvarparse::read_block("configuration", conf)) ) {
cvm::log("Error: in reading restart configuration for histogram \""+
this->name+"\" at position "+
cvm::to_str (is.tellg())+" in stream.\n");
cvm::to_str(is.tellg())+" in stream.\n");
is.clear();
is.seekg (start_pos, std::ios::beg);
is.setstate (std::ios::failbit);
is.seekg(start_pos, std::ios::beg);
is.setstate(std::ios::failbit);
return is;
}
int id = -1;
std::string name = "";
if ( (colvarparse::get_keyval (conf, "name", name, std::string (""), colvarparse::parse_silent)) &&
if ( (colvarparse::get_keyval(conf, "name", name, std::string(""), colvarparse::parse_silent)) &&
(name != this->name) )
cvm::error ("Error: in the restart file, the "
cvm::error("Error: in the restart file, the "
"\"histogram\" block has a wrong name: different system?\n");
if ( (id == -1) && (name == "") ) {
cvm::error ("Error: \"histogram\" block in the restart file "
cvm::error("Error: \"histogram\" block in the restart file "
"has no name.\n");
}
if ( !(is >> key) || !(key == "grid")) {
cvm::error ("Error: in reading restart configuration for histogram \""+
cvm::error("Error: in reading restart configuration for histogram \""+
this->name+"\" at position "+
cvm::to_str (is.tellg())+" in stream.\n");
cvm::to_str(is.tellg())+" in stream.\n");
is.clear();
is.seekg (start_pos, std::ios::beg);
is.setstate (std::ios::failbit);
is.seekg(start_pos, std::ios::beg);
is.setstate(std::ios::failbit);
return is;
}
if (! grid->read_raw (is)) {
if (! grid->read_raw(is)) {
is.clear();
is.seekg (start_pos, std::ios::beg);
is.setstate (std::ios::failbit);
is.seekg(start_pos, std::ios::beg);
is.setstate(std::ios::failbit);
return is;
}
is >> brace;
if (brace != "}") {
cvm::error ("Error: corrupt restart information for ABF bias \""+
cvm::error("Error: corrupt restart information for ABF bias \""+
this->name+"\": no matching brace at position "+
cvm::to_str (is.tellg())+" in the restart file.\n");
is.setstate (std::ios::failbit);
cvm::to_str(is.tellg())+" in the restart file.\n");
is.setstate(std::ios::failbit);
}
return is;
}
std::ostream & colvarbias_histogram::write_restart (std::ostream& os)
std::ostream & colvarbias_histogram::write_restart(std::ostream& os)
{
os << "histogram {\n"
<< " configuration {\n"
@ -667,7 +674,7 @@ std::ostream & colvarbias_histogram::write_restart (std::ostream& os)
os << " }\n";
os << "grid\n";
grid->write_raw (os, 8);
grid->write_raw(os, 8);
os << "}\n\n";

View File

@ -21,10 +21,10 @@ class colvarbias_abf : public colvarbias {
public:
colvarbias_abf (std::string const &conf, char const *key);
~colvarbias_abf ();
colvarbias_abf(std::string const &conf, char const *key);
~colvarbias_abf();
cvm::real update ();
cvm::real update();
private:
@ -64,7 +64,7 @@ private:
size_t shared_freq;
int shared_last_step;
// Share between replicas -- may be called independently of update
virtual void replica_share();
virtual int replica_share();
// Store the last set for shared ABF
colvar_grid_gradient *last_gradients;
@ -79,14 +79,14 @@ private:
virtual int bin_count(int bin_index);
/// Write human-readable FE gradients and sample count
void write_gradients_samples (const std::string &prefix, bool append = false);
void write_last_gradients_samples (const std::string &prefix, bool append = false);
void write_gradients_samples(const std::string &prefix, bool append = false);
void write_last_gradients_samples(const std::string &prefix, bool append = false);
/// Read human-readable FE gradients and sample count (if not using restart)
void read_gradients_samples ();
void read_gradients_samples();
std::istream& read_restart (std::istream&);
std::ostream& write_restart (std::ostream&);
std::istream& read_restart(std::istream&);
std::ostream& write_restart(std::ostream&);
};
@ -95,10 +95,10 @@ class colvarbias_histogram : public colvarbias {
public:
colvarbias_histogram (std::string const &conf, char const *key);
~colvarbias_histogram ();
colvarbias_histogram(std::string const &conf, char const *key);
~colvarbias_histogram();
cvm::real update ();
cvm::real update();
private:
@ -108,11 +108,11 @@ private:
std::string out_name;
int output_freq;
void write_grid ();
void write_grid();
std::ofstream grid_os; /// Stream for writing grid to disk
std::istream& read_restart (std::istream&);
std::ostream& write_restart (std::ostream&);
std::istream& read_restart(std::istream&);
std::ostream& write_restart(std::ostream&);
};
#endif

View File

@ -1,8 +1,20 @@
// -*- c++ -*-
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "colvarmodule.h"
#include "colvarbias_alb.h"
#include "colvarbias.h"
#include <stdio.h>
#include <stdlib.h>
#ifdef _MSC_VER
#if _MSC_VER <= 1700
#define copysign(A,B) _copysign(A,B)
double fmax(double A, double B) { return ( A > B ? A : B ); }
double fmin(double A, double B) { return ( A < B ? A : B ); }
#endif
#endif
/* Note about nomenclature. Force constant is called a coupling
* constant here to emphasize its changing in the code. Outwards,
@ -16,7 +28,7 @@ colvarbias_alb::colvarbias_alb(std::string const &conf, char const *key) :
size_t i;
// get the initial restraint centers
colvar_centers.resize (colvars.size());
colvar_centers.resize(colvars.size());
means.resize(colvars.size());
ssd.resize(colvars.size()); //sum of squares of differences from mean
@ -31,7 +43,7 @@ colvarbias_alb::colvarbias_alb(std::string const &conf, char const *key) :
for (i = 0; i < colvars.size(); i++) {
colvar_centers[i].type (colvars[i]->type());
colvar_centers[i].type(colvars[i]->value());
//zero moments
means[i] = ssd[i] = 0;
@ -39,47 +51,47 @@ colvarbias_alb::colvarbias_alb(std::string const &conf, char const *key) :
coupling_accum[i] = current_coupling[i] = 0;
}
if (get_keyval (conf, "centers", colvar_centers, colvar_centers)) {
if (get_keyval(conf, "centers", colvar_centers, colvar_centers)) {
for (i = 0; i < colvars.size(); i++) {
colvar_centers[i].apply_constraints();
}
} else {
colvar_centers.clear();
cvm::fatal_error ("Error: must define the initial centers of adaptive linear bias .\n");
cvm::fatal_error("Error: must define the initial centers of adaptive linear bias .\n");
}
if (colvar_centers.size() != colvars.size())
cvm::fatal_error ("Error: number of centers does not match "
cvm::fatal_error("Error: number of centers does not match "
"that of collective variables.\n");
if(!get_keyval (conf, "UpdateFrequency", update_freq, 0))
if (!get_keyval(conf, "UpdateFrequency", update_freq, 0))
cvm::fatal_error("Error: must set updateFrequency for adaptive linear bias.\n");
//we split the time between updating and equilibrating
update_freq /= 2;
if(update_freq == 0)
if (update_freq == 0)
cvm::fatal_error("Error: must set updateFrequency to greater than 2.\n");
get_keyval (conf, "outputCenters", b_output_centers, false);
get_keyval (conf, "outputGradient", b_output_grad, false);
get_keyval (conf, "outputCoupling", b_output_coupling, true);
get_keyval (conf, "hardForceRange", b_hard_coupling_range, true);
get_keyval(conf, "outputCenters", b_output_centers, false);
get_keyval(conf, "outputGradient", b_output_grad, false);
get_keyval(conf, "outputCoupling", b_output_coupling, true);
get_keyval(conf, "hardForceRange", b_hard_coupling_range, true);
//initial guess
if(!get_keyval (conf, "forceConstant", set_coupling, set_coupling))
for(i =0 ; i < colvars.size(); i++)
if (!get_keyval(conf, "forceConstant", set_coupling, set_coupling))
for (i =0 ; i < colvars.size(); i++)
set_coupling[i] = 0.;
//how we're going to increase to that point
for(i = 0; i < colvars.size(); i++)
for (i = 0; i < colvars.size(); i++)
coupling_rate[i] = (set_coupling[i] - current_coupling[i]) / update_freq;
if(!get_keyval (conf, "forceRange", max_coupling_range, max_coupling_range)) {
if (!get_keyval(conf, "forceRange", max_coupling_range, max_coupling_range)) {
//set to default
for(i = 0; i < colvars.size(); i++) {
if(cvm::temperature() > 0)
for (i = 0; i < colvars.size(); i++) {
if (cvm::temperature() > 0)
max_coupling_range[i] = 3 * cvm::temperature() * cvm::boltzmann();
else
max_coupling_range[i] = 3 * cvm::boltzmann();
@ -88,16 +100,16 @@ colvarbias_alb::colvarbias_alb(std::string const &conf, char const *key) :
if(!get_keyval (conf, "rateMax", max_coupling_rate, max_coupling_rate)) {
if (!get_keyval(conf, "rateMax", max_coupling_rate, max_coupling_rate)) {
//set to default
for(i = 0; i < colvars.size(); i++) {
for (i = 0; i < colvars.size(); i++) {
max_coupling_rate[i] = max_coupling_range[i] / (10 * update_freq);
}
}
if (cvm::debug())
cvm::log (" bias.\n");
cvm::log(" bias.\n");
}
@ -114,7 +126,7 @@ cvm::real colvarbias_alb::update() {
update_calls++;
if (cvm::debug())
cvm::log ("Updating the adaptive linear bias \""+this->name+"\".\n");
cvm::log("Updating the adaptive linear bias \""+this->name+"\".\n");
@ -131,7 +143,7 @@ cvm::real colvarbias_alb::update() {
colvars[i],
colvar_centers[i]);
if(!b_equilibration) {
if (!b_equilibration) {
//Welford, West, and Hanso online variance method
delta = static_cast<cvm::real>(colvars[i]->value()) - means[i];
@ -140,7 +152,7 @@ cvm::real colvarbias_alb::update() {
} else {
//check if we've reached the setpoint
if(coupling_rate[i] == 0 || pow(current_coupling[i] - set_coupling[i],2) < pow(coupling_rate[i],2)) {
if (coupling_rate[i] == 0 || pow(current_coupling[i] - set_coupling[i],2) < pow(coupling_rate[i],2)) {
finished_equil_flag &= 1; //we continue equilibrating as long as we haven't reached all the set points
}
else {
@ -150,7 +162,7 @@ cvm::real colvarbias_alb::update() {
//update max_coupling_range
if(!b_hard_coupling_range && fabs(current_coupling[i]) > max_coupling_range[i]) {
if (!b_hard_coupling_range && fabs(current_coupling[i]) > max_coupling_range[i]) {
std::ostringstream logStream;
logStream << "Coupling constant for "
<< colvars[i]->name
@ -167,25 +179,25 @@ cvm::real colvarbias_alb::update() {
}
}
if(b_equilibration && finished_equil_flag) {
if (b_equilibration && finished_equil_flag) {
b_equilibration = false;
update_calls = 0;
}
//now we update coupling constant, if necessary
if(!b_equilibration && update_calls == update_freq) {
if (!b_equilibration && update_calls == update_freq) {
//use estimated variance to take a step
cvm::real step_size = 0;
cvm::real temp;
//reset means and sum of squares of differences
for(size_t i = 0; i < colvars.size(); i++) {
for (size_t i = 0; i < colvars.size(); i++) {
temp = 2. * (means[i] / (static_cast<cvm::real> (colvar_centers[i])) - 1) * ssd[i] / (update_calls - 1);
if(cvm::temperature() > 0)
if (cvm::temperature() > 0)
step_size = temp / (cvm::temperature() * cvm::boltzmann());
else
step_size = temp / cvm::boltzmann();
@ -194,7 +206,7 @@ cvm::real colvarbias_alb::update() {
ssd[i] = 0;
//stochastic if we do that update or not
if(colvars.size() == 1 || rand() < RAND_MAX / ((int) colvars.size())) {
if (colvars.size() == 1 || rand() < RAND_MAX / ((int) colvars.size())) {
coupling_accum[i] += step_size * step_size;
current_coupling[i] = set_coupling[i];
set_coupling[i] += max_coupling_range[i] / sqrt(coupling_accum[i]) * step_size;
@ -217,121 +229,121 @@ cvm::real colvarbias_alb::update() {
}
std::istream & colvarbias_alb::read_restart (std::istream &is)
std::istream & colvarbias_alb::read_restart(std::istream &is)
{
size_t const start_pos = is.tellg();
cvm::log ("Restarting adaptive linear bias \""+
cvm::log("Restarting adaptive linear bias \""+
this->name+"\".\n");
std::string key, brace, conf;
if ( !(is >> key) || !(key == "ALB") ||
!(is >> brace) || !(brace == "{") ||
!(is >> colvarparse::read_block ("configuration", conf)) ) {
!(is >> colvarparse::read_block("configuration", conf)) ) {
cvm::log ("Error: in reading restart configuration for restraint bias \""+
cvm::log("Error: in reading restart configuration for restraint bias \""+
this->name+"\" at position "+
cvm::to_str (is.tellg())+" in stream.\n");
cvm::to_str(is.tellg())+" in stream.\n");
is.clear();
is.seekg (start_pos, std::ios::beg);
is.setstate (std::ios::failbit);
is.seekg(start_pos, std::ios::beg);
is.setstate(std::ios::failbit);
return is;
}
std::string name = "";
if ( (colvarparse::get_keyval (conf, "name", name, std::string (""), colvarparse::parse_silent)) &&
if ( (colvarparse::get_keyval(conf, "name", name, std::string(""), colvarparse::parse_silent)) &&
(name != this->name) )
cvm::fatal_error ("Error: in the restart file, the "
cvm::fatal_error("Error: in the restart file, the "
"\"ALB\" block has a wrong name\n");
if (name.size() == 0) {
cvm::fatal_error ("Error: \"ALB\" block in the restart file "
cvm::fatal_error("Error: \"ALB\" block in the restart file "
"has no identifiers.\n");
}
if (!get_keyval (conf, "setCoupling", set_coupling))
cvm::fatal_error ("Error: current setCoupling is missing from the restart.\n");
if (!get_keyval(conf, "setCoupling", set_coupling))
cvm::fatal_error("Error: current setCoupling is missing from the restart.\n");
if (!get_keyval (conf, "currentCoupling", current_coupling))
cvm::fatal_error ("Error: current setCoupling is missing from the restart.\n");
if (!get_keyval(conf, "currentCoupling", current_coupling))
cvm::fatal_error("Error: current setCoupling is missing from the restart.\n");
if (!get_keyval (conf, "maxCouplingRange", max_coupling_range))
cvm::fatal_error ("Error: maxCouplingRange is missing from the restart.\n");
if (!get_keyval(conf, "maxCouplingRange", max_coupling_range))
cvm::fatal_error("Error: maxCouplingRange is missing from the restart.\n");
if (!get_keyval (conf, "couplingRate", coupling_rate))
cvm::fatal_error ("Error: current setCoupling is missing from the restart.\n");
if (!get_keyval(conf, "couplingRate", coupling_rate))
cvm::fatal_error("Error: current setCoupling is missing from the restart.\n");
if (!get_keyval (conf, "couplingAccum", coupling_accum))
cvm::fatal_error ("Error: couplingAccum is missing from the restart.\n");
if (!get_keyval(conf, "couplingAccum", coupling_accum))
cvm::fatal_error("Error: couplingAccum is missing from the restart.\n");
if (!get_keyval (conf, "mean", means))
cvm::fatal_error ("Error: current mean is missing from the restart.\n");
if (!get_keyval(conf, "mean", means))
cvm::fatal_error("Error: current mean is missing from the restart.\n");
if (!get_keyval (conf, "ssd", ssd))
cvm::fatal_error ("Error: current ssd is missing from the restart.\n");
if (!get_keyval(conf, "ssd", ssd))
cvm::fatal_error("Error: current ssd is missing from the restart.\n");
if (!get_keyval (conf, "updateCalls", update_calls))
cvm::fatal_error ("Error: current updateCalls is missing from the restart.\n");
if (!get_keyval(conf, "updateCalls", update_calls))
cvm::fatal_error("Error: current updateCalls is missing from the restart.\n");
if (!get_keyval (conf, "b_equilibration", b_equilibration))
cvm::fatal_error ("Error: current updateCalls is missing from the restart.\n");
if (!get_keyval(conf, "b_equilibration", b_equilibration))
cvm::fatal_error("Error: current updateCalls is missing from the restart.\n");
is >> brace;
if (brace != "}") {
cvm::fatal_error ("Error: corrupt restart information for adaptive linear bias \""+
cvm::fatal_error("Error: corrupt restart information for adaptive linear bias \""+
this->name+"\": no matching brace at position "+
cvm::to_str (is.tellg())+" in the restart file.\n");
is.setstate (std::ios::failbit);
cvm::to_str(is.tellg())+" in the restart file.\n");
is.setstate(std::ios::failbit);
}
return is;
}
std::ostream & colvarbias_alb::write_restart (std::ostream &os)
std::ostream & colvarbias_alb::write_restart(std::ostream &os)
{
os << "ALB {\n"
<< " configuration {\n"
<< " name " << this->name << "\n";
os << " setCoupling ";
size_t i;
for(i = 0; i < colvars.size(); i++) {
os << std::setprecision (cvm::en_prec)
<< std::setw (cvm::en_width) << set_coupling[i] << "\n";
for (i = 0; i < colvars.size(); i++) {
os << std::setprecision(cvm::en_prec)
<< std::setw(cvm::en_width) << set_coupling[i] << "\n";
}
os << " currentCoupling ";
for(i = 0; i < colvars.size(); i++) {
os << std::setprecision (cvm::en_prec)
<< std::setw (cvm::en_width) << current_coupling[i] << "\n";
for (i = 0; i < colvars.size(); i++) {
os << std::setprecision(cvm::en_prec)
<< std::setw(cvm::en_width) << current_coupling[i] << "\n";
}
os << " maxCouplingRange ";
for(i = 0; i < colvars.size(); i++) {
os << std::setprecision (cvm::en_prec)
<< std::setw (cvm::en_width) << max_coupling_range[i] << "\n";
for (i = 0; i < colvars.size(); i++) {
os << std::setprecision(cvm::en_prec)
<< std::setw(cvm::en_width) << max_coupling_range[i] << "\n";
}
os << " couplingRate ";
for(i = 0; i < colvars.size(); i++) {
os << std::setprecision (cvm::en_prec)
<< std::setw (cvm::en_width) << coupling_rate[i] << "\n";
for (i = 0; i < colvars.size(); i++) {
os << std::setprecision(cvm::en_prec)
<< std::setw(cvm::en_width) << coupling_rate[i] << "\n";
}
os << " couplingAccum ";
for(i = 0; i < colvars.size(); i++) {
os << std::setprecision (cvm::en_prec)
<< std::setw (cvm::en_width) << coupling_accum[i] << "\n";
for (i = 0; i < colvars.size(); i++) {
os << std::setprecision(cvm::en_prec)
<< std::setw(cvm::en_width) << coupling_accum[i] << "\n";
}
os << " mean ";
for(i = 0; i < colvars.size(); i++) {
os << std::setprecision (cvm::en_prec)
<< std::setw (cvm::en_width) << means[i] << "\n";
for (i = 0; i < colvars.size(); i++) {
os << std::setprecision(cvm::en_prec)
<< std::setw(cvm::en_width) << means[i] << "\n";
}
os << " ssd ";
for(i = 0; i < colvars.size(); i++) {
os << std::setprecision (cvm::en_prec)
<< std::setw (cvm::en_width) << ssd[i] << "\n";
for (i = 0; i < colvars.size(); i++) {
os << std::setprecision(cvm::en_prec)
<< std::setw(cvm::en_width) << ssd[i] << "\n";
}
os << " updateCalls " << update_calls << "\n";
if(b_equilibration)
if (b_equilibration)
os << " b_equilibration yes\n";
else
os << " b_equilibration no\n";
@ -343,51 +355,51 @@ std::ostream & colvarbias_alb::write_restart (std::ostream &os)
}
std::ostream & colvarbias_alb::write_traj_label (std::ostream &os)
std::ostream & colvarbias_alb::write_traj_label(std::ostream &os)
{
os << " ";
if (b_output_energy)
os << " E_"
<< cvm::wrap_string (this->name, cvm::en_width-2);
<< cvm::wrap_string(this->name, cvm::en_width-2);
if (b_output_coupling)
for(size_t i = 0; i < current_coupling.size(); i++) {
for (size_t i = 0; i < current_coupling.size(); i++) {
os << " ForceConst_" << i
<<std::setw(cvm::en_width - 6 - (i / 10 + 1))
<< "";
}
if(b_output_grad)
for(size_t i = 0; i < means.size(); i++) {
if (b_output_grad)
for (size_t i = 0; i < means.size(); i++) {
os << "Grad_"
<< cvm::wrap_string(colvars[i]->name, cvm::cv_width - 4);
}
if (b_output_centers)
for (size_t i = 0; i < colvars.size(); i++) {
size_t const this_cv_width = (colvars[i]->value()).output_width (cvm::cv_width);
size_t const this_cv_width = (colvars[i]->value()).output_width(cvm::cv_width);
os << " x0_"
<< cvm::wrap_string (colvars[i]->name, this_cv_width-3);
<< cvm::wrap_string(colvars[i]->name, this_cv_width-3);
}
return os;
}
std::ostream & colvarbias_alb::write_traj (std::ostream &os)
std::ostream & colvarbias_alb::write_traj(std::ostream &os)
{
os << " ";
if (b_output_energy)
os << " "
<< std::setprecision (cvm::en_prec) << std::setw (cvm::en_width)
<< std::setprecision(cvm::en_prec) << std::setw(cvm::en_width)
<< bias_energy;
if(b_output_coupling)
for(size_t i = 0; i < current_coupling.size(); i++) {
if (b_output_coupling)
for (size_t i = 0; i < current_coupling.size(); i++) {
os << " "
<< std::setprecision (cvm::en_prec) << std::setw (cvm::en_width)
<< std::setprecision(cvm::en_prec) << std::setw(cvm::en_width)
<< current_coupling[i];
}
@ -395,12 +407,12 @@ std::ostream & colvarbias_alb::write_traj (std::ostream &os)
if (b_output_centers)
for (size_t i = 0; i < colvars.size(); i++) {
os << " "
<< std::setprecision (cvm::cv_prec) << std::setw (cvm::cv_width)
<< std::setprecision(cvm::cv_prec) << std::setw(cvm::cv_width)
<< colvar_centers[i];
}
if(b_output_grad)
for(size_t i = 0; i < means.size(); i++) {
if (b_output_grad)
for (size_t i = 0; i < means.size(); i++) {
os << " "
<< std::setprecision(cvm::cv_prec) << std::setw(cvm::cv_width)
<< -2. * (means[i] / (static_cast<cvm::real> (colvar_centers[i])) - 1) * ssd[i] / (fmax(update_calls,2) - 1);

View File

@ -1,3 +1,5 @@
// -*- c++ -*-
#ifndef COLVARBIAS_ALB_H
#define COLVARBIAS_ALB_H
@ -14,16 +16,16 @@ public:
virtual cvm::real update();
/// Read the bias configuration from a restart file
virtual std::istream & read_restart (std::istream &is);
virtual std::istream & read_restart(std::istream &is);
/// Write the bias configuration to a restart file
virtual std::ostream & write_restart (std::ostream &os);
virtual std::ostream & write_restart(std::ostream &os);
/// Write a label to the trajectory file (comment line)
virtual std::ostream & write_traj_label (std::ostream &os);
virtual std::ostream & write_traj_label(std::ostream &os);
/// Output quantities such as the bias energy to the trajectory file
virtual std::ostream & write_traj (std::ostream &os);
virtual std::ostream & write_traj(std::ostream &os);
protected:

File diff suppressed because it is too large Load Diff

View File

@ -28,7 +28,7 @@ public:
Communication comm;
/// Constructor
colvarbias_meta (std::string const &conf, char const *key);
colvarbias_meta(std::string const &conf, char const *key);
/// Default constructor
colvarbias_meta();
@ -38,9 +38,9 @@ public:
virtual cvm::real update();
virtual std::istream & read_restart (std::istream &is);
virtual std::istream & read_restart(std::istream &is);
virtual std::ostream & write_restart (std::ostream &os);
virtual std::ostream & write_restart(std::ostream &os);
virtual void write_pmf();
@ -79,11 +79,11 @@ protected:
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,
void recount_hills_off_grid(hill_iter h_first, hill_iter h_last,
colvar_grid_scalar *ge);
/// Read a hill from a file
std::istream & read_hill (std::istream &is);
std::istream & read_hill(std::istream &is);
/// \brief step present in a state file
///
@ -95,15 +95,15 @@ protected:
/// \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
virtual std::list<hill>::const_iterator create_hill (hill const &h);
virtual std::list<hill>::const_iterator create_hill(hill const &h);
/// \brief Remove a previously saved hill (returns an iterator for
/// the next hill in the list)
virtual std::list<hill>::const_iterator delete_hill (hill_iter &h);
virtual 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,
virtual void calc_hills(hill_iter h_first,
hill_iter h_last,
cvm::real &energy,
std::vector<colvarvalue> const &values = std::vector<colvarvalue> (0));
@ -111,7 +111,7 @@ protected:
/// \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,
virtual void calc_hills_force(size_t const &i,
hill_iter h_first,
hill_iter h_last,
std::vector<colvarvalue> &forces,
@ -167,7 +167,7 @@ protected:
colvar_grid_gradient *hills_energy_gradients;
/// \brief Project the selected hills onto grids
void project_hills (hill_iter h_first, hill_iter h_last,
void project_hills(hill_iter h_first, hill_iter h_last,
colvar_grid_scalar *ge, colvar_grid_gradient *gf,
bool print_progress = false);
@ -268,28 +268,28 @@ public:
/// cv Pointer to the array of collective variables involved \param
/// replica (optional) Identity of the replica which creates the
/// hill
inline hill (cvm::real const &W_in,
inline hill(cvm::real const &W_in,
std::vector<colvar *> &cv,
cvm::real const &hill_width,
std::string const &replica_in = "")
: sW (1.0),
W (W_in),
centers (cv.size()),
widths (cv.size()),
it (cvm::it),
replica (replica_in)
: sW(1.0),
W(W_in),
centers(cv.size()),
widths(cv.size()),
it(cvm::it),
replica(replica_in)
{
for (size_t i = 0; i < cv.size(); i++) {
centers[i].type (cv[i]->type());
centers[i].type(cv[i]->value());
centers[i] = cv[i]->value();
widths[i] = cv[i]->width * hill_width;
}
if (cvm::debug())
cvm::log ("New hill, applied to "+cvm::to_str (cv.size())+
cvm::log("New hill, applied to "+cvm::to_str(cv.size())+
" collective variables, with centers "+
cvm::to_str (centers)+", widths "+
cvm::to_str (widths)+" and weight "+
cvm::to_str (W)+".\n");
cvm::to_str(centers)+", widths "+
cvm::to_str(widths)+" and weight "+
cvm::to_str(W)+".\n");
}
/// \brief General constructor: all data are explicitly passed as
@ -298,27 +298,27 @@ public:
/// weight Weight of the hill \param centers Center of the hill
/// \param widths Width of the hill around centers \param replica
/// (optional) Identity of the replica which creates the hill
inline hill (size_t const &it_in,
inline hill(size_t const &it_in,
cvm::real const &W_in,
std::vector<colvarvalue> const &centers_in,
std::vector<cvm::real> const &widths_in,
std::string const &replica_in = "")
: sW (1.0),
W (W_in),
centers (centers_in),
widths (widths_in),
it (it_in),
replica (replica_in)
: sW(1.0),
W(W_in),
centers(centers_in),
widths(widths_in),
it(it_in),
replica(replica_in)
{}
/// Copy constructor
inline hill (colvarbias_meta::hill const &h)
: sW (1.0),
W (h.W),
centers (h.centers),
widths (h.widths),
it (h.it),
replica (h.replica)
inline hill(colvarbias_meta::hill const &h)
: sW(1.0),
W(h.W),
centers(h.centers),
widths(h.widths),
it(h.it),
replica(h.replica)
{}
/// Destructor
@ -332,7 +332,7 @@ public:
}
/// Get the energy using another hill weight
inline cvm::real energy (cvm::real const &new_weight)
inline cvm::real energy(cvm::real const &new_weight)
{
return new_weight * sW * hill_value;
}
@ -344,7 +344,7 @@ public:
}
/// Set the hill value as specified
inline void value (cvm::real const &new_value)
inline void value(cvm::real const &new_value)
{
hill_value = new_value;
}
@ -356,7 +356,7 @@ public:
}
/// Scale the weight with this factor (by default 1.0 is used)
inline void scale (cvm::real const &new_scale_fac)
inline void scale(cvm::real const &new_scale_fac)
{
sW = new_scale_fac;
}
@ -368,7 +368,7 @@ public:
}
/// Get the i-th component of the center
inline colvarvalue & center (size_t const &i)
inline colvarvalue & center(size_t const &i)
{
return centers[i];
}

View File

@ -5,55 +5,74 @@
#include "colvarbias_restraint.h"
colvarbias_restraint::colvarbias_restraint (std::string const &conf,
char const *key)
: colvarbias (conf, key),
target_nstages (0),
target_nsteps (0)
colvarbias_restraint::colvarbias_restraint(std::string const &conf,
char const *key)
: colvarbias(conf, key),
target_nstages(0),
target_nsteps(0)
{
get_keyval (conf, "forceConstant", force_k, 1.0);
get_keyval(conf, "forceConstant", force_k, 1.0);
// get the initial restraint centers
colvar_centers.resize (colvars.size());
colvar_centers_raw.resize (colvars.size());
for (size_t i = 0; i < colvars.size(); i++) {
colvar_centers[i].type (colvars[i]->type());
colvar_centers_raw[i].type (colvars[i]->type());
}
if (get_keyval (conf, "centers", colvar_centers, colvar_centers)) {
for (size_t i = 0; i < colvars.size(); i++) {
colvar_centers[i].apply_constraints();
colvar_centers_raw[i] = colvar_centers[i];
{
// get the initial restraint centers
colvar_centers.resize(colvars.size());
colvar_centers_raw.resize(colvars.size());
size_t i;
for (i = 0; i < colvars.size(); i++) {
colvar_centers[i].type(colvars[i]->value());
colvar_centers_raw[i].type(colvars[i]->value());
if (cvm::debug()) {
cvm::log("colvarbias_restraint: center size = "+
cvm::to_str(colvar_centers[i].vector1d_value.size())+"\n");
}
}
} else {
colvar_centers.clear();
cvm::error ("Error: must define the initial centers of the restraints.\n");
}
if (get_keyval(conf, "centers", colvar_centers, colvar_centers)) {
for (i = 0; i < colvars.size(); i++) {
if (cvm::debug()) {
cvm::log("colvarbias_restraint: parsing initial centers, i = "+cvm::to_str(i)+".\n");
}
if (colvar_centers.size() != colvars.size())
cvm::error ("Error: number of centers does not match "
"that of collective variables.\n");
if (get_keyval (conf, "targetCenters", target_centers, colvar_centers)) {
b_chg_centers = true;
for (size_t i = 0; i < target_centers.size(); i++) {
target_centers[i].apply_constraints();
colvar_centers[i].apply_constraints();
colvar_centers_raw[i] = colvar_centers[i];
}
} else {
colvar_centers.clear();
cvm::error("Error: must define the initial centers of the restraints.\n");
}
if (colvar_centers.size() != colvars.size()) {
cvm::error("Error: number of centers does not match "
"that of collective variables.\n");
}
} else {
b_chg_centers = false;
target_centers.clear();
}
if (get_keyval (conf, "targetForceConstant", target_force_k, 0.0)) {
{
if (cvm::debug()) {
cvm::log("colvarbias_restraint: parsing target centers.\n");
}
size_t i;
if (get_keyval(conf, "targetCenters", target_centers, colvar_centers)) {
b_chg_centers = true;
for (i = 0; i < target_centers.size(); i++) {
target_centers[i].apply_constraints();
}
} else {
b_chg_centers = false;
target_centers.clear();
}
}
if (get_keyval(conf, "targetForceConstant", target_force_k, 0.0)) {
if (b_chg_centers)
cvm::error ("Error: cannot specify both targetCenters and targetForceConstant.\n");
cvm::error("Error: cannot specify both targetCenters and targetForceConstant.\n");
starting_force_k = force_k;
b_chg_force_k = true;
get_keyval (conf, "targetEquilSteps", target_equil_steps, 0);
get_keyval(conf, "targetEquilSteps", target_equil_steps, 0);
get_keyval (conf, "lambdaSchedule", lambda_schedule, lambda_schedule);
get_keyval(conf, "lambdaSchedule", lambda_schedule, lambda_schedule);
if (lambda_schedule.size()) {
// There is one more lambda-point than stages
target_nstages = lambda_schedule.size() - 1;
@ -63,13 +82,13 @@ colvarbias_restraint::colvarbias_restraint (std::string const &conf,
}
if (b_chg_centers || b_chg_force_k) {
get_keyval (conf, "targetNumSteps", target_nsteps, 0);
get_keyval(conf, "targetNumSteps", target_nsteps, 0);
if (!target_nsteps)
cvm::error ("Error: targetNumSteps must be non-zero.\n");
cvm::error("Error: targetNumSteps must be non-zero.\n");
if (get_keyval (conf, "targetNumStages", target_nstages, target_nstages) &&
if (get_keyval(conf, "targetNumStages", target_nstages, target_nstages) &&
lambda_schedule.size()) {
cvm::error ("Error: targetNumStages and lambdaSchedule are incompatible.\n");
cvm::error("Error: targetNumStages and lambdaSchedule are incompatible.\n");
}
if (target_nstages) {
@ -78,60 +97,63 @@ colvarbias_restraint::colvarbias_restraint (std::string const &conf,
restraint_FE = 0.0;
}
if (get_keyval (conf, "targetForceExponent", force_k_exp, 1.0)) {
if (get_keyval(conf, "targetForceExponent", force_k_exp, 1.0)) {
if (! b_chg_force_k)
cvm::log ("Warning: not changing force constant: targetForceExponent will be ignored\n");
cvm::log("Warning: not changing force constant: targetForceExponent will be ignored\n");
if (force_k_exp < 1.0)
cvm::log ("Warning: for all practical purposes, targetForceExponent should be 1.0 or greater.\n");
cvm::log("Warning: for all practical purposes, targetForceExponent should be 1.0 or greater.\n");
}
}
get_keyval (conf, "outputCenters", b_output_centers, false);
get_keyval(conf, "outputCenters", b_output_centers, false);
if (b_chg_centers) {
get_keyval (conf, "outputAccumulatedWork", b_output_acc_work, false);
get_keyval(conf, "outputAccumulatedWork", b_output_acc_work, false);
} else {
b_output_acc_work = false;
}
acc_work = 0.0;
if (cvm::debug())
cvm::log ("Done initializing a new restraint bias.\n");
cvm::log("Done initializing a new restraint bias.\n");
}
colvarbias_restraint::~colvarbias_restraint ()
colvarbias_restraint::~colvarbias_restraint()
{
if (cvm::n_rest_biases > 0)
cvm::n_rest_biases -= 1;
}
void colvarbias_restraint::change_configuration (std::string const &conf)
void colvarbias_restraint::change_configuration(std::string const &conf)
{
get_keyval (conf, "forceConstant", force_k, force_k);
if (get_keyval (conf, "centers", colvar_centers, colvar_centers)) {
get_keyval(conf, "forceConstant", force_k, force_k);
if (get_keyval(conf, "centers", colvar_centers, colvar_centers)) {
for (size_t i = 0; i < colvars.size(); i++) {
colvar_centers[i].type(colvars[i]->value());
colvar_centers[i].apply_constraints();
colvar_centers_raw[i].type(colvars[i]->value());
colvar_centers_raw[i] = colvar_centers[i];
}
}
}
cvm::real colvarbias_restraint::energy_difference (std::string const &conf)
cvm::real colvarbias_restraint::energy_difference(std::string const &conf)
{
std::vector<colvarvalue> alt_colvar_centers;
cvm::real alt_force_k;
cvm::real alt_bias_energy = 0.0;
get_keyval (conf, "forceConstant", alt_force_k, force_k);
get_keyval(conf, "forceConstant", alt_force_k, force_k);
alt_colvar_centers.resize (colvars.size());
alt_colvar_centers.resize(colvars.size());
size_t i;
for (i = 0; i < colvars.size(); i++) {
alt_colvar_centers[i].type (colvars[i]->type());
alt_colvar_centers[i].type(colvars[i]->value());
}
if (get_keyval (conf, "centers", alt_colvar_centers, colvar_centers)) {
if (get_keyval(conf, "centers", alt_colvar_centers, colvar_centers)) {
for (i = 0; i < colvars.size(); i++) {
colvar_centers[i].type(colvars[i]->value());
colvar_centers[i].apply_constraints();
}
}
@ -151,7 +173,7 @@ cvm::real colvarbias_restraint::update()
bias_energy = 0.0;
if (cvm::debug())
cvm::log ("Updating the restraint bias \""+this->name+"\".\n");
cvm::log("Updating the restraint bias \""+this->name+"\".\n");
// Setup first stage of staged variable force constant calculation
if (b_chg_force_k && target_nstages && cvm::step_absolute() == 0) {
@ -162,10 +184,10 @@ cvm::real colvarbias_restraint::update()
lambda = 0.0;
}
force_k = starting_force_k + (target_force_k - starting_force_k)
* std::pow (lambda, force_k_exp);
cvm::log ("Restraint " + this->name + ", stage " +
* std::pow(lambda, force_k_exp);
cvm::log("Restraint " + this->name + ", stage " +
cvm::to_str(stage) + " : lambda = " + cvm::to_str(lambda));
cvm::log ("Setting force constant to " + cvm::to_str (force_k));
cvm::log("Setting force constant to " + cvm::to_str(force_k));
}
if (b_chg_centers) {
@ -175,16 +197,16 @@ cvm::real colvarbias_restraint::update()
// at each simulation step (or stage, if applicable)
// (take current stage into account: it can be non-zero
// if we are restarting a staged calculation)
centers_incr.resize (colvars.size());
centers_incr.resize(colvars.size());
for (size_t i = 0; i < colvars.size(); i++) {
centers_incr[i].type (colvars[i]->type());
centers_incr[i].type(colvars[i]->value());
centers_incr[i] = (target_centers[i] - colvar_centers_raw[i]) /
cvm::real ( target_nstages ? (target_nstages - stage) :
cvm::real( target_nstages ? (target_nstages - stage) :
(target_nsteps - cvm::step_absolute()));
}
if (cvm::debug()) {
cvm::log ("Center increment for the restraint bias \""+
this->name+"\": "+cvm::to_str (centers_incr)+" at stage "+cvm::to_str (stage)+ ".\n");
cvm::log("Center increment for the restraint bias \""+
this->name+"\": "+cvm::to_str(centers_incr)+" at stage "+cvm::to_str(stage)+ ".\n");
}
}
@ -200,10 +222,10 @@ cvm::real colvarbias_restraint::update()
colvar_centers[i].apply_constraints();
}
stage++;
cvm::log ("Moving restraint \"" + this->name +
cvm::log("Moving restraint \"" + this->name +
"\" stage " + cvm::to_str(stage) +
" : setting centers to " + cvm::to_str (colvar_centers) +
" at step " + cvm::to_str (cvm::step_absolute()));
" : setting centers to " + cvm::to_str(colvar_centers) +
" at step " + cvm::to_str(cvm::step_absolute()));
}
} else if ((cvm::step_relative() > 0) && (cvm::step_absolute() <= target_nsteps)) {
// move the restraint centers in the direction of the targets
@ -217,8 +239,8 @@ cvm::real colvarbias_restraint::update()
}
if (cvm::debug())
cvm::log ("Current centers for the restraint bias \""+
this->name+"\": "+cvm::to_str (colvar_centers)+".\n");
cvm::log("Current centers for the restraint bias \""+
this->name+"\": "+cvm::to_str(colvar_centers)+".\n");
}
if (b_chg_force_k) {
@ -240,7 +262,7 @@ cvm::real colvarbias_restraint::update()
// Square distance normalized by square colvar width
cvm::real dist_sq = 0.0;
for (size_t i = 0; i < colvars.size(); i++) {
dist_sq += colvars[i]->dist2 (colvars[i]->value(), colvar_centers[i])
dist_sq += colvars[i]->dist2(colvars[i]->value(), colvar_centers[i])
/ (colvars[i]->width * colvars[i]->width);
}
@ -252,8 +274,8 @@ cvm::real colvarbias_restraint::update()
if (cvm::step_absolute() % target_nsteps == 0 &&
cvm::step_absolute() > 0) {
cvm::log ("Lambda= " + cvm::to_str (lambda) + " dA/dLambda= "
+ cvm::to_str (restraint_FE / cvm::real(target_nsteps - target_equil_steps)));
cvm::log("Lambda= " + cvm::to_str(lambda) + " dA/dLambda= "
+ cvm::to_str(restraint_FE / cvm::real(target_nsteps - target_equil_steps)));
// ...and move on to the next one
if (stage < target_nstages) {
@ -266,25 +288,26 @@ cvm::real colvarbias_restraint::update()
lambda = cvm::real(stage) / cvm::real(target_nstages);
}
force_k = starting_force_k + (target_force_k - starting_force_k)
* std::pow (lambda, force_k_exp);
cvm::log ("Restraint " + this->name + ", stage " +
* std::pow(lambda, force_k_exp);
cvm::log("Restraint " + this->name + ", stage " +
cvm::to_str(stage) + " : lambda = " + cvm::to_str(lambda));
cvm::log ("Setting force constant to " + cvm::to_str (force_k));
cvm::log("Setting force constant to " + cvm::to_str(force_k));
}
}
} else if (cvm::step_absolute() <= target_nsteps) {
// update force constant (slow growth)
lambda = cvm::real(cvm::step_absolute()) / cvm::real(target_nsteps);
force_k = starting_force_k + (target_force_k - starting_force_k)
* std::pow (lambda, force_k_exp);
* std::pow(lambda, force_k_exp);
}
}
if (cvm::debug())
cvm::log ("Done updating the restraint bias \""+this->name+"\".\n");
cvm::log("Done updating the restraint bias \""+this->name+"\".\n");
// Force and energy calculation
for (size_t i = 0; i < colvars.size(); i++) {
colvar_forces[i].type(colvars[i]->value());
colvar_forces[i] = -1.0 * restraint_force(restraint_convert_k(force_k, colvars[i]->width),
colvars[i],
colvar_centers[i]);
@ -292,8 +315,8 @@ cvm::real colvarbias_restraint::update()
colvars[i],
colvar_centers[i]);
if (cvm::debug()) {
cvm::log ("dist_grad["+cvm::to_str (i)+
"] = "+cvm::to_str (colvars[i]->dist2_lgrad (colvars[i]->value(),
cvm::log("dist_grad["+cvm::to_str(i)+
"] = "+cvm::to_str(colvars[i]->dist2_lgrad(colvars[i]->value(),
colvar_centers[i]))+"\n");
}
}
@ -308,31 +331,31 @@ cvm::real colvarbias_restraint::update()
}
if (cvm::debug())
cvm::log ("Current forces for the restraint bias \""+
this->name+"\": "+cvm::to_str (colvar_forces)+".\n");
cvm::log("Current forces for the restraint bias \""+
this->name+"\": "+cvm::to_str(colvar_forces)+".\n");
return bias_energy;
}
std::istream & colvarbias_restraint::read_restart (std::istream &is)
std::istream & colvarbias_restraint::read_restart(std::istream &is)
{
size_t const start_pos = is.tellg();
cvm::log ("Restarting restraint bias \""+
cvm::log("Restarting restraint bias \""+
this->name+"\".\n");
std::string key, brace, conf;
if ( !(is >> key) || !(key == "restraint" || key == "harmonic") ||
!(is >> brace) || !(brace == "{") ||
!(is >> colvarparse::read_block ("configuration", conf)) ) {
!(is >> colvarparse::read_block("configuration", conf)) ) {
cvm::log ("Error: in reading restart configuration for restraint bias \""+
cvm::log("Error: in reading restart configuration for restraint bias \""+
this->name+"\" at position "+
cvm::to_str (is.tellg())+" in stream.\n");
cvm::to_str(is.tellg())+" in stream.\n");
is.clear();
is.seekg (start_pos, std::ios::beg);
is.setstate (std::ios::failbit);
is.seekg(start_pos, std::ios::beg);
is.setstate(std::ios::failbit);
return is;
}
@ -340,53 +363,53 @@ std::istream & colvarbias_restraint::read_restart (std::istream &is)
std::string name = "";
// if ( ( (colvarparse::get_keyval (conf, "id", id, -1, colvarparse::parse_silent)) &&
// (id != this->id) ) ||
if ( (colvarparse::get_keyval (conf, "name", name, std::string (""), colvarparse::parse_silent)) &&
if ( (colvarparse::get_keyval(conf, "name", name, std::string(""), colvarparse::parse_silent)) &&
(name != this->name) )
cvm::error ("Error: in the restart file, the "
cvm::error("Error: in the restart file, the "
"\"restraint\" block has a wrong name\n");
// if ( (id == -1) && (name == "") ) {
if (name.size() == 0) {
cvm::error ("Error: \"restraint\" block in the restart file "
cvm::error("Error: \"restraint\" block in the restart file "
"has no identifiers.\n");
}
if (b_chg_centers) {
// cvm::log ("Reading the updated restraint centers from the restart.\n");
if (!get_keyval (conf, "centers", colvar_centers))
cvm::error ("Error: restraint centers are missing from the restart.\n");
if (!get_keyval (conf, "centers_raw", colvar_centers_raw))
cvm::error ("Error: \"raw\" restraint centers are missing from the restart.\n");
if (!get_keyval(conf, "centers", colvar_centers))
cvm::error("Error: restraint centers are missing from the restart.\n");
if (!get_keyval(conf, "centers_raw", colvar_centers_raw))
cvm::error("Error: \"raw\" restraint centers are missing from the restart.\n");
}
if (b_chg_force_k) {
// cvm::log ("Reading the updated force constant from the restart.\n");
if (!get_keyval (conf, "forceConstant", force_k))
cvm::error ("Error: force constant is missing from the restart.\n");
if (!get_keyval(conf, "forceConstant", force_k))
cvm::error("Error: force constant is missing from the restart.\n");
}
if (target_nstages) {
// cvm::log ("Reading current stage from the restart.\n");
if (!get_keyval (conf, "stage", stage))
cvm::error ("Error: current stage is missing from the restart.\n");
if (!get_keyval(conf, "stage", stage))
cvm::error("Error: current stage is missing from the restart.\n");
}
if (b_output_acc_work) {
if (!get_keyval (conf, "accumulatedWork", acc_work))
cvm::error ("Error: accumulatedWork is missing from the restart.\n");
if (!get_keyval(conf, "accumulatedWork", acc_work))
cvm::error("Error: accumulatedWork is missing from the restart.\n");
}
is >> brace;
if (brace != "}") {
cvm::error ("Error: corrupt restart information for restraint bias \""+
cvm::error("Error: corrupt restart information for restraint bias \""+
this->name+"\": no matching brace at position "+
cvm::to_str (is.tellg())+" in the restart file.\n");
is.setstate (std::ios::failbit);
cvm::to_str(is.tellg())+" in the restart file.\n");
is.setstate(std::ios::failbit);
}
return is;
}
std::ostream & colvarbias_restraint::write_restart (std::ostream &os)
std::ostream & colvarbias_restraint::write_restart(std::ostream &os)
{
os << "restraint {\n"
<< " configuration {\n"
@ -409,12 +432,12 @@ std::ostream & colvarbias_restraint::write_restart (std::ostream &os)
if (b_chg_force_k) {
os << " forceConstant "
<< std::setprecision (cvm::en_prec)
<< std::setw (cvm::en_width) << force_k << "\n";
<< std::setprecision(cvm::en_prec)
<< std::setw(cvm::en_width) << force_k << "\n";
}
if (target_nstages) {
os << " stage " << std::setw (cvm::it_width)
os << " stage " << std::setw(cvm::it_width)
<< stage << "\n";
}
@ -429,48 +452,48 @@ std::ostream & colvarbias_restraint::write_restart (std::ostream &os)
}
std::ostream & colvarbias_restraint::write_traj_label (std::ostream &os)
std::ostream & colvarbias_restraint::write_traj_label(std::ostream &os)
{
os << " ";
if (b_output_energy)
os << " E_"
<< cvm::wrap_string (this->name, cvm::en_width-2);
<< cvm::wrap_string(this->name, cvm::en_width-2);
if (b_output_centers)
for (size_t i = 0; i < colvars.size(); i++) {
size_t const this_cv_width = (colvars[i]->value()).output_width (cvm::cv_width);
size_t const this_cv_width = (colvars[i]->value()).output_width(cvm::cv_width);
os << " x0_"
<< cvm::wrap_string (colvars[i]->name, this_cv_width-3);
<< cvm::wrap_string(colvars[i]->name, this_cv_width-3);
}
if (b_output_acc_work)
os << " W_"
<< cvm::wrap_string (this->name, cvm::en_width-2);
<< cvm::wrap_string(this->name, cvm::en_width-2);
return os;
}
std::ostream & colvarbias_restraint::write_traj (std::ostream &os)
std::ostream & colvarbias_restraint::write_traj(std::ostream &os)
{
os << " ";
if (b_output_energy)
os << " "
<< std::setprecision (cvm::en_prec) << std::setw (cvm::en_width)
<< std::setprecision(cvm::en_prec) << std::setw(cvm::en_width)
<< bias_energy;
if (b_output_centers)
for (size_t i = 0; i < colvars.size(); i++) {
os << " "
<< std::setprecision (cvm::cv_prec) << std::setw (cvm::cv_width)
<< std::setprecision(cvm::cv_prec) << std::setw(cvm::cv_width)
<< colvar_centers[i];
}
if (b_output_acc_work)
os << " "
<< std::setprecision (cvm::en_prec) << std::setw (cvm::en_width)
<< std::setprecision(cvm::en_prec) << std::setw(cvm::en_width)
<< acc_work;
return os;
@ -480,9 +503,9 @@ colvarbias_restraint_harmonic::colvarbias_restraint_harmonic(std::string const &
colvarbias_restraint(conf, key) {
for (size_t i = 0; i < colvars.size(); i++) {
if (colvars[i]->width != 1.0)
cvm::log ("The force constant for colvar \""+colvars[i]->name+
cvm::log("The force constant for colvar \""+colvars[i]->name+
"\" will be rescaled to "+
cvm::to_str (restraint_convert_k(force_k, colvars[i]->width))+
cvm::to_str(restraint_convert_k(force_k, colvars[i]->width))+
" according to the specified width.\n");
}
}
@ -507,9 +530,9 @@ colvarbias_restraint_linear::colvarbias_restraint_linear(std::string const &conf
colvarbias_restraint(conf, key) {
for (size_t i = 0; i < colvars.size(); i++) {
if (colvars[i]->width != 1.0)
cvm::log ("The force constant for colvar \""+colvars[i]->name+
cvm::log("The force constant for colvar \""+colvars[i]->name+
"\" will be rescaled to "+
cvm::to_str (restraint_convert_k(force_k, colvars[i]->width))+
cvm::to_str(restraint_convert_k(force_k, colvars[i]->width))+
" according to the specified width.\n");
}
}

View File

@ -21,19 +21,19 @@ public:
virtual cvm::real energy_difference(std::string const &conf);
/// Read the bias configuration from a restart file
virtual std::istream & read_restart (std::istream &is);
virtual std::istream & read_restart(std::istream &is);
/// Write the bias configuration to a restart file
virtual std::ostream & write_restart (std::ostream &os);
virtual std::ostream & write_restart(std::ostream &os);
/// Write a label to the trajectory file (comment line)
virtual std::ostream & write_traj_label (std::ostream &os);
virtual std::ostream & write_traj_label(std::ostream &os);
/// Output quantities such as the bias energy to the trajectory file
virtual std::ostream & write_traj (std::ostream &os);
virtual std::ostream & write_traj(std::ostream &os);
/// \brief Constructor
colvarbias_restraint (std::string const &conf, char const *key);
colvarbias_restraint(std::string const &conf, char const *key);
/// Destructor
virtual ~colvarbias_restraint();

View File

@ -8,54 +8,54 @@
colvar::cvc::cvc()
: sup_coeff (1.0), sup_np (1),
b_periodic (false),
b_inverse_gradients (false),
b_Jacobian_derivative (false),
b_debug_gradients (false)
: sup_coeff(1.0), sup_np(1),
b_periodic(false),
b_inverse_gradients(false),
b_Jacobian_derivative(false),
b_debug_gradients(false)
{}
colvar::cvc::cvc (std::string const &conf)
: sup_coeff (1.0), sup_np (1),
b_periodic (false),
b_inverse_gradients (false),
b_Jacobian_derivative (false),
b_debug_gradients (false)
colvar::cvc::cvc(std::string const &conf)
: sup_coeff(1.0), sup_np(1),
b_periodic(false),
b_inverse_gradients(false),
b_Jacobian_derivative(false),
b_debug_gradients(false)
{
if (cvm::debug())
cvm::log ("Initializing cvc base object.\n");
cvm::log("Initializing cvc base object.\n");
get_keyval (conf, "name", this->name, std::string (""), parse_silent);
get_keyval(conf, "name", this->name, std::string(""), parse_silent);
get_keyval (conf, "componentCoeff", sup_coeff, 1.0);
get_keyval (conf, "componentExp", sup_np, 1);
get_keyval(conf, "componentCoeff", sup_coeff, 1.0);
get_keyval(conf, "componentExp", sup_np, 1);
get_keyval (conf, "period", period, 0.0);
get_keyval (conf, "wrapAround", wrap_center, 0.0);
get_keyval(conf, "period", period, 0.0);
get_keyval(conf, "wrapAround", wrap_center, 0.0);
get_keyval (conf, "debugGradients", b_debug_gradients, false, parse_silent);
get_keyval(conf, "debugGradients", b_debug_gradients, false, parse_silent);
if (cvm::debug())
cvm::log ("Done initializing cvc base object.\n");
cvm::log("Done initializing cvc base object.\n");
}
void colvar::cvc::parse_group (std::string const &conf,
void colvar::cvc::parse_group(std::string const &conf,
char const *group_key,
cvm::atom_group &group,
bool optional)
{
if (key_lookup (conf, group_key)) {
if (group.parse (conf, group_key) != COLVARS_OK) {
cvm::error ("Error parsing definition for atom group \""+
std::string (group_key)+"\".\n");
if (key_lookup(conf, group_key)) {
if (group.parse(conf, group_key) != COLVARS_OK) {
cvm::error("Error parsing definition for atom group \""+
std::string(group_key)+"\".\n");
return;
}
} else {
if (! optional) {
cvm::error ("Error: definition for atom group \""+
std::string (group_key)+"\" not found.\n");
cvm::error("Error: definition for atom group \""+
std::string(group_key)+"\" not found.\n");
return;
}
}
@ -68,19 +68,19 @@ colvar::cvc::~cvc()
void colvar::cvc::calc_force_invgrads()
{
cvm::fatal_error ("Error: calculation of inverse gradients is not implemented "
cvm::fatal_error("Error: calculation of inverse gradients is not implemented "
"for colvar components of type \""+function_type+"\".\n");
}
void colvar::cvc::calc_Jacobian_derivative()
{
cvm::fatal_error ("Error: calculation of inverse gradients is not implemented "
cvm::fatal_error("Error: calculation of inverse gradients is not implemented "
"for colvar components of type \""+function_type+"\".\n");
}
void colvar::cvc::debug_gradients (cvm::atom_group &group)
void colvar::cvc::debug_gradients(cvm::atom_group &group)
{
// this function should work for any scalar variable:
// the only difference will be the name of the atom group (here, "group")
@ -90,9 +90,10 @@ void colvar::cvc::debug_gradients (cvm::atom_group &group)
cvm::rotation const rot_0 = group.rot;
cvm::rotation const rot_inv = group.rot.inverse();
cvm::real const x_0 = x.real_value;
cvm::real x_0 = x.real_value;
if ((x.type() == colvarvalue::type_vector) && (x.size() == 1)) x_0 = x[0];
// cvm::log ("gradients = "+cvm::to_str (gradients)+"\n");
// cvm::log("gradients = "+cvm::to_str (gradients)+"\n");
// it only makes sense to debug the fit gradients
// when the fitting group is the same as this group
@ -102,13 +103,13 @@ void colvar::cvc::debug_gradients (cvm::atom_group &group)
if (group.b_rotate) {
// fit_gradients are in the original frame, we should print them in the rotated frame
for (size_t j = 0; j < group.fit_gradients.size(); j++) {
group.fit_gradients[j] = rot_0.rotate (group.fit_gradients[j]);
group.fit_gradients[j] = rot_0.rotate(group.fit_gradients[j]);
}
}
cvm::log ("fit_gradients = "+cvm::to_str (group.fit_gradients)+"\n");
cvm::log("fit_gradients = "+cvm::to_str(group.fit_gradients)+"\n");
if (group.b_rotate) {
for (size_t j = 0; j < group.fit_gradients.size(); j++) {
group.fit_gradients[j] = rot_inv.rotate (group.fit_gradients[j]);
group.fit_gradients[j] = rot_inv.rotate(group.fit_gradients[j]);
}
}
}
@ -117,7 +118,7 @@ void colvar::cvc::debug_gradients (cvm::atom_group &group)
// tests are best conducted in the unrotated (simulation) frame
cvm::rvector const atom_grad = group.b_rotate ?
rot_inv.rotate (group[ia].grad) :
rot_inv.rotate(group[ia].grad) :
group[ia].grad;
for (size_t id = 0; id < 3; id++) {
@ -130,19 +131,20 @@ void colvar::cvc::debug_gradients (cvm::atom_group &group)
group.calc_apply_roto_translation();
}
calc_value();
cvm::real const x_1 = x.real_value;
cvm::log ("Atom "+cvm::to_str (ia)+", component "+cvm::to_str (id)+":\n");
cvm::log ("dx(actual) = "+cvm::to_str (x_1 - x_0,
cvm::real x_1 = x.real_value;
if ((x.type() == colvarvalue::type_vector) && (x.size() == 1)) x_1 = x[0];
cvm::log("Atom "+cvm::to_str(ia)+", component "+cvm::to_str(id)+":\n");
cvm::log("dx(actual) = "+cvm::to_str(x_1 - x_0,
21, 14)+"\n");
//cvm::real const dx_pred = (group.fit_gradients.size() && (group.ref_pos_group == NULL)) ?
cvm::real const dx_pred = (group.fit_gradients.size()) ?
(cvm::debug_gradients_step_size * (atom_grad[id] + group.fit_gradients[ia][id])) :
(cvm::debug_gradients_step_size * atom_grad[id]);
cvm::log ("dx(interp) = "+cvm::to_str (dx_pred,
cvm::log("dx(interp) = "+cvm::to_str(dx_pred,
21, 14)+"\n");
cvm::log ("|dx(actual) - dx(interp)|/|dx(actual)| = "+
cvm::to_str (std::fabs (x_1 - x_0 - dx_pred) /
std::fabs (x_1 - x_0), 12, 5)+"\n");
cvm::log("|dx(actual) - dx(interp)|/|dx(actual)| = "+
cvm::to_str(std::fabs(x_1 - x_0 - dx_pred) /
std::fabs(x_1 - x_0), 12, 5)+"\n");
}
}
@ -164,18 +166,18 @@ void colvar::cvc::debug_gradients (cvm::atom_group &group)
// group.calc_apply_roto_translation();
// calc_value();
// cvm::real const x_1 = x.real_value;
// cvm::log ("refPosGroup atom "+cvm::to_str (ia)+", component "+cvm::to_str (id)+":\n");
// cvm::log ("dx(actual) = "+cvm::to_str (x_1 - x_0,
// cvm::log("refPosGroup atom "+cvm::to_str(ia)+", component "+cvm::to_str (id)+":\n");
// cvm::log("dx(actual) = "+cvm::to_str (x_1 - x_0,
// 21, 14)+"\n");
// //cvm::real const dx_pred = (group.fit_gradients.size() && (group.ref_pos_group == NULL)) ?
// // cvm::real const dx_pred = (group.fit_gradients.size()) ?
// // (cvm::debug_gradients_step_size * (atom_grad[id] + group.fit_gradients[ia][id])) :
// // (cvm::debug_gradients_step_size * atom_grad[id]);
// cvm::real const dx_pred = cvm::debug_gradients_step_size * ref.fit_gradients[ia][id];
// cvm::log ("dx(interp) = "+cvm::to_str (dx_pred,
// cvm::log("dx(interp) = "+cvm::to_str (dx_pred,
// 21, 14)+"\n");
// cvm::log ("|dx(actual) - dx(interp)|/|dx(actual)| = "+
// cvm::to_str (std::fabs (x_1 - x_0 - dx_pred) /
// cvm::to_str(std::fabs (x_1 - x_0 - dx_pred) /
// std::fabs (x_1 - x_0),
// 12, 5)+
// ".\n");

File diff suppressed because it is too large Load Diff

View File

@ -7,48 +7,48 @@
#include <cmath>
colvar::angle::angle (std::string const &conf)
: cvc (conf)
colvar::angle::angle(std::string const &conf)
: cvc(conf)
{
function_type = "angle";
b_inverse_gradients = true;
b_Jacobian_derivative = true;
parse_group (conf, "group1", group1);
parse_group (conf, "group2", group2);
parse_group (conf, "group3", group3);
atom_groups.push_back (&group1);
atom_groups.push_back (&group2);
atom_groups.push_back (&group3);
if (get_keyval (conf, "oneSiteSystemForce", b_1site_force, false)) {
cvm::log ("Computing system force on group 1 only");
parse_group(conf, "group1", group1);
parse_group(conf, "group2", group2);
parse_group(conf, "group3", group3);
atom_groups.push_back(&group1);
atom_groups.push_back(&group2);
atom_groups.push_back(&group3);
if (get_keyval(conf, "oneSiteSystemForce", b_1site_force, false)) {
cvm::log("Computing system force on group 1 only");
}
x.type (colvarvalue::type_scalar);
x.type(colvarvalue::type_scalar);
}
colvar::angle::angle (cvm::atom const &a1,
colvar::angle::angle(cvm::atom const &a1,
cvm::atom const &a2,
cvm::atom const &a3)
: group1 (std::vector<cvm::atom> (1, a1)),
group2 (std::vector<cvm::atom> (1, a2)),
group3 (std::vector<cvm::atom> (1, a3))
: group1(std::vector<cvm::atom> (1, a1)),
group2(std::vector<cvm::atom> (1, a2)),
group3(std::vector<cvm::atom> (1, a3))
{
function_type = "angle";
b_inverse_gradients = true;
b_Jacobian_derivative = true;
b_1site_force = false;
atom_groups.push_back (&group1);
atom_groups.push_back (&group2);
atom_groups.push_back (&group3);
atom_groups.push_back(&group1);
atom_groups.push_back(&group2);
atom_groups.push_back(&group3);
x.type (colvarvalue::type_scalar);
x.type(colvarvalue::type_scalar);
}
colvar::angle::angle()
{
function_type = "angle";
x.type (colvarvalue::type_scalar);
x.type(colvarvalue::type_scalar);
}
@ -62,14 +62,14 @@ void colvar::angle::calc_value()
cvm::atom_pos const g2_pos = group2.center_of_mass();
cvm::atom_pos const g3_pos = group3.center_of_mass();
r21 = cvm::position_distance (g2_pos, g1_pos);
r21 = cvm::position_distance(g2_pos, g1_pos);
r21l = r21.norm();
r23 = cvm::position_distance (g2_pos, g3_pos);
r23 = cvm::position_distance(g2_pos, g3_pos);
r23l = r23.norm();
cvm::real const cos_theta = (r21*r23)/(r21l*r23l);
x.real_value = (180.0/PI) * std::acos (cos_theta);
x.real_value = (180.0/PI) * std::acos(cos_theta);
}
@ -77,7 +77,7 @@ void colvar::angle::calc_gradients()
{
size_t i;
cvm::real const cos_theta = (r21*r23)/(r21l*r23l);
cvm::real const dxdcos = -1.0 / std::sqrt (1.0 - cos_theta*cos_theta);
cvm::real const dxdcos = -1.0 / std::sqrt(1.0 - cos_theta*cos_theta);
dxdr1 = (180.0/PI) * dxdcos *
(1.0/r21l) * ( r23/r23l + (-1.0) * cos_theta * r21/r21l );
@ -132,56 +132,56 @@ void colvar::angle::calc_Jacobian_derivative()
}
void colvar::angle::apply_force (colvarvalue const &force)
void colvar::angle::apply_force(colvarvalue const &force)
{
if (!group1.noforce)
group1.apply_colvar_force (force.real_value);
group1.apply_colvar_force(force.real_value);
if (!group2.noforce)
group2.apply_colvar_force (force.real_value);
group2.apply_colvar_force(force.real_value);
if (!group3.noforce)
group3.apply_colvar_force (force.real_value);
group3.apply_colvar_force(force.real_value);
}
colvar::dihedral::dihedral (std::string const &conf)
: cvc (conf)
colvar::dihedral::dihedral(std::string const &conf)
: cvc(conf)
{
function_type = "dihedral";
period = 360.0;
b_periodic = true;
b_inverse_gradients = true;
b_Jacobian_derivative = true;
if (get_keyval (conf, "oneSiteSystemForce", b_1site_force, false)) {
cvm::log ("Computing system force on group 1 only");
if (get_keyval(conf, "oneSiteSystemForce", b_1site_force, false)) {
cvm::log("Computing system force on group 1 only");
}
parse_group (conf, "group1", group1);
parse_group (conf, "group2", group2);
parse_group (conf, "group3", group3);
parse_group (conf, "group4", group4);
atom_groups.push_back (&group1);
atom_groups.push_back (&group2);
atom_groups.push_back (&group3);
atom_groups.push_back (&group4);
parse_group(conf, "group1", group1);
parse_group(conf, "group2", group2);
parse_group(conf, "group3", group3);
parse_group(conf, "group4", group4);
atom_groups.push_back(&group1);
atom_groups.push_back(&group2);
atom_groups.push_back(&group3);
atom_groups.push_back(&group4);
x.type (colvarvalue::type_scalar);
x.type(colvarvalue::type_scalar);
}
colvar::dihedral::dihedral (cvm::atom const &a1,
colvar::dihedral::dihedral(cvm::atom const &a1,
cvm::atom const &a2,
cvm::atom const &a3,
cvm::atom const &a4)
: group1 (std::vector<cvm::atom> (1, a1)),
group2 (std::vector<cvm::atom> (1, a2)),
group3 (std::vector<cvm::atom> (1, a3)),
group4 (std::vector<cvm::atom> (1, a4))
: group1(std::vector<cvm::atom> (1, a1)),
group2(std::vector<cvm::atom> (1, a2)),
group3(std::vector<cvm::atom> (1, a3)),
group4(std::vector<cvm::atom> (1, a4))
{
if (cvm::debug())
cvm::log ("Initializing dihedral object from atom groups.\n");
cvm::log("Initializing dihedral object from atom groups.\n");
function_type = "dihedral";
period = 360.0;
@ -190,15 +190,15 @@ colvar::dihedral::dihedral (cvm::atom const &a1,
b_Jacobian_derivative = true;
b_1site_force = false;
atom_groups.push_back (&group1);
atom_groups.push_back (&group2);
atom_groups.push_back (&group3);
atom_groups.push_back (&group4);
atom_groups.push_back(&group1);
atom_groups.push_back(&group2);
atom_groups.push_back(&group3);
atom_groups.push_back(&group4);
x.type (colvarvalue::type_scalar);
x.type(colvarvalue::type_scalar);
if (cvm::debug())
cvm::log ("Done initializing dihedral object from atom groups.\n");
cvm::log("Done initializing dihedral object from atom groups.\n");
}
@ -209,7 +209,7 @@ colvar::dihedral::dihedral()
b_periodic = true;
b_inverse_gradients = true;
b_Jacobian_derivative = true;
x.type (colvarvalue::type_scalar);
x.type(colvarvalue::type_scalar);
}
@ -226,28 +226,28 @@ void colvar::dihedral::calc_value()
cvm::atom_pos const g4_pos = group4.center_of_mass();
// Usual sign convention: r12 = r2 - r1
r12 = cvm::position_distance (g1_pos, g2_pos);
r23 = cvm::position_distance (g2_pos, g3_pos);
r34 = cvm::position_distance (g3_pos, g4_pos);
r12 = cvm::position_distance(g1_pos, g2_pos);
r23 = cvm::position_distance(g2_pos, g3_pos);
r34 = cvm::position_distance(g3_pos, g4_pos);
cvm::rvector const n1 = cvm::rvector::outer (r12, r23);
cvm::rvector const n2 = cvm::rvector::outer (r23, r34);
cvm::rvector const n1 = cvm::rvector::outer(r12, r23);
cvm::rvector const n2 = cvm::rvector::outer(r23, r34);
cvm::real const cos_phi = n1 * n2;
cvm::real const sin_phi = n1 * r34 * r23.norm();
x.real_value = (180.0/PI) * std::atan2 (sin_phi, cos_phi);
this->wrap (x);
x.real_value = (180.0/PI) * std::atan2(sin_phi, cos_phi);
this->wrap(x);
}
void colvar::dihedral::calc_gradients()
{
cvm::rvector A = cvm::rvector::outer (r12, r23);
cvm::rvector A = cvm::rvector::outer(r12, r23);
cvm::real rA = A.norm();
cvm::rvector B = cvm::rvector::outer (r23, r34);
cvm::rvector B = cvm::rvector::outer(r23, r34);
cvm::real rB = B.norm();
cvm::rvector C = cvm::rvector::outer (r23, A);
cvm::rvector C = cvm::rvector::outer(r23, A);
cvm::real rC = C.norm();
cvm::real const cos_phi = (A*B)/(rA*rB);
@ -258,7 +258,7 @@ void colvar::dihedral::calc_gradients()
rB = 1.0/rB;
B *= rB;
if (std::fabs (sin_phi) > 0.1) {
if (std::fabs(sin_phi) > 0.1) {
rA = 1.0/rA;
A *= rA;
cvm::rvector const dcosdA = rA*(cos_phi*A-B);
@ -267,10 +267,10 @@ void colvar::dihedral::calc_gradients()
cvm::real const K = (1.0/sin_phi) * (180.0/PI);
f1 = K * cvm::rvector::outer (r23, dcosdA);
f3 = K * cvm::rvector::outer (dcosdB, r23);
f2 = K * (cvm::rvector::outer (dcosdA, r12)
+ cvm::rvector::outer (r34, dcosdB));
f1 = K * cvm::rvector::outer(r23, dcosdA);
f3 = K * cvm::rvector::outer(dcosdB, r23);
f2 = K * (cvm::rvector::outer(dcosdA, r12)
+ cvm::rvector::outer(r34, dcosdB));
}
else {
rC = 1.0/rC;
@ -291,7 +291,7 @@ void colvar::dihedral::calc_gradients()
- r23.z*r23.x*dsindC.x
- r23.z*r23.y*dsindC.y);
f3 = cvm::rvector::outer (dsindB, r23);
f3 = cvm::rvector::outer(dsindB, r23);
f3 *= K;
f2.x = K*(-(r23.y*r12.y + r23.z*r12.z)*dsindC.x
@ -332,14 +332,14 @@ void colvar::dihedral::calc_force_invgrads()
cvm::real const d12 = r12.norm();
cvm::real const d34 = r34.norm();
cvm::rvector const cross1 = (cvm::rvector::outer (u23, u12)).unit();
cvm::rvector const cross4 = (cvm::rvector::outer (u23, u34)).unit();
cvm::rvector const cross1 = (cvm::rvector::outer(u23, u12)).unit();
cvm::rvector const cross4 = (cvm::rvector::outer(u23, u34)).unit();
cvm::real const dot1 = u23 * u12;
cvm::real const dot4 = u23 * u34;
cvm::real const fact1 = d12 * std::sqrt (1.0 - dot1 * dot1);
cvm::real const fact4 = d34 * std::sqrt (1.0 - dot4 * dot4);
cvm::real const fact1 = d12 * std::sqrt(1.0 - dot1 * dot1);
cvm::real const fact4 = d34 * std::sqrt(1.0 - dot4 * dot4);
group1.read_system_forces();
if ( b_1site_force ) {
@ -361,19 +361,19 @@ void colvar::dihedral::calc_Jacobian_derivative()
}
void colvar::dihedral::apply_force (colvarvalue const &force)
void colvar::dihedral::apply_force(colvarvalue const &force)
{
if (!group1.noforce)
group1.apply_colvar_force (force.real_value);
group1.apply_colvar_force(force.real_value);
if (!group2.noforce)
group2.apply_colvar_force (force.real_value);
group2.apply_colvar_force(force.real_value);
if (!group3.noforce)
group3.apply_colvar_force (force.real_value);
group3.apply_colvar_force(force.real_value);
if (!group4.noforce)
group4.apply_colvar_force (force.real_value);
group4.apply_colvar_force(force.real_value);
}

View File

@ -12,21 +12,21 @@
template<bool calculate_gradients>
cvm::real colvar::coordnum::switching_function (cvm::real const &r0,
cvm::real colvar::coordnum::switching_function(cvm::real const &r0,
int const &en,
int const &ed,
cvm::atom &A1,
cvm::atom &A2)
{
cvm::rvector const diff = cvm::position_distance (A1.pos, A2.pos);
cvm::rvector const diff = cvm::position_distance(A1.pos, A2.pos);
cvm::real const l2 = diff.norm2()/(r0*r0);
// Assume en and ed are even integers, and avoid sqrt in the following
int const en2 = en/2;
int const ed2 = ed/2;
cvm::real const xn = std::pow (l2, en2);
cvm::real const xd = std::pow (l2, ed2);
cvm::real const xn = std::pow(l2, en2);
cvm::real const xd = std::pow(l2, ed2);
cvm::real const func = (1.0-xn)/(1.0-xd);
if (calculate_gradients) {
@ -41,27 +41,27 @@ cvm::real colvar::coordnum::switching_function (cvm::real const &r0,
template<bool calculate_gradients>
cvm::real colvar::coordnum::switching_function (cvm::rvector const &r0_vec,
cvm::real colvar::coordnum::switching_function(cvm::rvector const &r0_vec,
int const &en,
int const &ed,
cvm::atom &A1,
cvm::atom &A2)
{
cvm::rvector const diff = cvm::position_distance (A1.pos, A2.pos);
cvm::rvector const scal_diff (diff.x/r0_vec.x, diff.y/r0_vec.y, diff.z/r0_vec.z);
cvm::rvector const diff = cvm::position_distance(A1.pos, A2.pos);
cvm::rvector const scal_diff(diff.x/r0_vec.x, diff.y/r0_vec.y, diff.z/r0_vec.z);
cvm::real const l2 = scal_diff.norm2();
// Assume en and ed are even integers, and avoid sqrt in the following
int const en2 = en/2;
int const ed2 = ed/2;
cvm::real const xn = std::pow (l2, en2);
cvm::real const xd = std::pow (l2, ed2);
cvm::real const xn = std::pow(l2, en2);
cvm::real const xd = std::pow(l2, ed2);
cvm::real const func = (1.0-xn)/(1.0-xd);
if (calculate_gradients) {
cvm::real const dFdl2 = (1.0/(1.0-xd))*(en2*(xn/l2) - func*ed2*(xd/l2))*(-1.0);
cvm::rvector const dl2dx ((2.0/(r0_vec.x*r0_vec.x))*diff.x,
cvm::rvector const dl2dx((2.0/(r0_vec.x*r0_vec.x))*diff.x,
(2.0/(r0_vec.y*r0_vec.y))*diff.y,
(2.0/(r0_vec.z*r0_vec.z))*diff.z);
A1.grad += (-1.0)*dFdl2*dl2dx;
@ -72,29 +72,29 @@ cvm::real colvar::coordnum::switching_function (cvm::rvector const &r0_vec,
colvar::coordnum::coordnum (std::string const &conf)
: distance (conf), b_anisotropic (false), b_group2_center_only (false)
colvar::coordnum::coordnum(std::string const &conf)
: distance(conf), b_anisotropic(false), b_group2_center_only(false)
{
function_type = "coordnum";
x.type (colvarvalue::type_scalar);
x.type(colvarvalue::type_scalar);
// group1 and group2 are already initialized by distance()
if (group1.b_dummy)
cvm::fatal_error ("Error: only group2 is allowed to be a dummy atom\n");
cvm::fatal_error("Error: only group2 is allowed to be a dummy atom\n");
// need to specify this explicitly because the distance() constructor
// has set it to true
b_inverse_gradients = false;
bool const b_scale = get_keyval (conf, "cutoff", r0,
cvm::real (4.0 * cvm::unit_angstrom()));
bool const b_scale = get_keyval(conf, "cutoff", r0,
cvm::real(4.0 * cvm::unit_angstrom()));
if (get_keyval (conf, "cutoff3", r0_vec,
cvm::rvector (4.0, 4.0, 4.0), parse_silent)) {
if (get_keyval(conf, "cutoff3", r0_vec,
cvm::rvector(4.0, 4.0, 4.0), parse_silent)) {
if (b_scale)
cvm::fatal_error ("Error: cannot specify \"scale\" and "
cvm::fatal_error("Error: cannot specify \"scale\" and "
"\"scale3\" at the same time.\n");
b_anisotropic = true;
// remove meaningless negative signs
@ -103,22 +103,22 @@ colvar::coordnum::coordnum (std::string const &conf)
if (r0_vec.z < 0.0) r0_vec.z *= -1.0;
}
get_keyval (conf, "expNumer", en, int (6) );
get_keyval (conf, "expDenom", ed, int (12));
get_keyval(conf, "expNumer", en, int(6) );
get_keyval(conf, "expDenom", ed, int(12));
if ( (en%2) || (ed%2) ) {
cvm::fatal_error ("Error: odd exponents provided, can only use even ones.\n");
cvm::fatal_error("Error: odd exponents provided, can only use even ones.\n");
}
get_keyval (conf, "group2CenterOnly", b_group2_center_only, group2.b_dummy);
get_keyval(conf, "group2CenterOnly", b_group2_center_only, group2.b_dummy);
}
colvar::coordnum::coordnum()
: b_anisotropic (false), b_group2_center_only (false)
: b_anisotropic(false), b_group2_center_only(false)
{
function_type = "coordnum";
x.type (colvarvalue::type_scalar);
x.type(colvarvalue::type_scalar);
}
@ -174,7 +174,7 @@ void colvar::coordnum::calc_gradients()
switching_function<true> (r0, en, ed, *ai1, group2_com_atom);
}
group2.set_weighted_gradient (group2_com_atom.grad);
group2.set_weighted_gradient(group2_com_atom.grad);
} else {
@ -193,86 +193,86 @@ void colvar::coordnum::calc_gradients()
// if (cvm::debug()) {
// for (size_t i = 0; i < group1.size(); i++) {
// cvm::log ("atom["+cvm::to_str (group1[i].id+1)+"] gradient: "+
// cvm::log("atom["+cvm::to_str (group1[i].id+1)+"] gradient: "+
// cvm::to_str (group1[i].grad)+"\n");
// }
// for (size_t i = 0; i < group2.size(); i++) {
// cvm::log ("atom["+cvm::to_str (group2[i].id+1)+"] gradient: "+
// cvm::log("atom["+cvm::to_str (group2[i].id+1)+"] gradient: "+
// cvm::to_str (group2[i].grad)+"\n");
// }
// }
}
void colvar::coordnum::apply_force (colvarvalue const &force)
void colvar::coordnum::apply_force(colvarvalue const &force)
{
if (!group1.noforce)
group1.apply_colvar_force (force.real_value);
group1.apply_colvar_force(force.real_value);
if (!group2.noforce)
group2.apply_colvar_force (force.real_value);
group2.apply_colvar_force(force.real_value);
}
// h_bond member functions
colvar::h_bond::h_bond (std::string const &conf)
: cvc (conf)
colvar::h_bond::h_bond(std::string const &conf)
: cvc(conf)
{
if (cvm::debug())
cvm::log ("Initializing h_bond object.\n");
cvm::log("Initializing h_bond object.\n");
function_type = "h_bond";
x.type (colvarvalue::type_scalar);
x.type(colvarvalue::type_scalar);
int a_num, d_num;
get_keyval (conf, "acceptor", a_num, -1);
get_keyval (conf, "donor", d_num, -1);
get_keyval(conf, "acceptor", a_num, -1);
get_keyval(conf, "donor", d_num, -1);
if ( (a_num == -1) || (d_num == -1) ) {
cvm::fatal_error ("Error: either acceptor or donor undefined.\n");
cvm::fatal_error("Error: either acceptor or donor undefined.\n");
}
acceptor = cvm::atom (a_num);
donor = cvm::atom (d_num);
atom_groups.push_back (new cvm::atom_group);
atom_groups[0]->add_atom (acceptor);
atom_groups[0]->add_atom (donor);
acceptor = cvm::atom(a_num);
donor = cvm::atom(d_num);
atom_groups.push_back(new cvm::atom_group);
atom_groups[0]->add_atom(acceptor);
atom_groups[0]->add_atom(donor);
get_keyval (conf, "cutoff", r0, (3.3 * cvm::unit_angstrom()));
get_keyval (conf, "expNumer", en, 6);
get_keyval (conf, "expDenom", ed, 8);
get_keyval(conf, "cutoff", r0, (3.3 * cvm::unit_angstrom()));
get_keyval(conf, "expNumer", en, 6);
get_keyval(conf, "expDenom", ed, 8);
if ( (en%2) || (ed%2) ) {
cvm::fatal_error ("Error: odd exponents provided, can only use even ones.\n");
cvm::fatal_error("Error: odd exponents provided, can only use even ones.\n");
}
if (cvm::debug())
cvm::log ("Done initializing h_bond object.\n");
cvm::log("Done initializing h_bond object.\n");
}
colvar::h_bond::h_bond (cvm::atom const &acceptor_i,
colvar::h_bond::h_bond(cvm::atom const &acceptor_i,
cvm::atom const &donor_i,
cvm::real r0_i, int en_i, int ed_i)
: acceptor (acceptor_i),
donor (donor_i),
r0 (r0_i), en (en_i), ed (ed_i)
: acceptor(acceptor_i),
donor(donor_i),
r0(r0_i), en(en_i), ed(ed_i)
{
function_type = "h_bond";
x.type (colvarvalue::type_scalar);
x.type(colvarvalue::type_scalar);
atom_groups.push_back (new cvm::atom_group);
atom_groups[0]->add_atom (acceptor);
atom_groups[0]->add_atom (donor);
atom_groups.push_back(new cvm::atom_group);
atom_groups[0]->add_atom(acceptor);
atom_groups[0]->add_atom(donor);
}
colvar::h_bond::h_bond()
: cvc ()
: cvc()
{
function_type = "h_bond";
x.type (colvarvalue::type_scalar);
x.type(colvarvalue::type_scalar);
}
@ -298,20 +298,20 @@ void colvar::h_bond::calc_gradients()
}
void colvar::h_bond::apply_force (colvarvalue const &force)
void colvar::h_bond::apply_force(colvarvalue const &force)
{
acceptor.apply_force (force.real_value * acceptor.grad);
acceptor.apply_force(force.real_value * acceptor.grad);
donor.apply_force (force.real_value * donor.grad);
}
colvar::selfcoordnum::selfcoordnum (std::string const &conf)
: distance (conf, false)
colvar::selfcoordnum::selfcoordnum(std::string const &conf)
: distance(conf, false)
{
function_type = "selfcoordnum";
x.type (colvarvalue::type_scalar);
x.type(colvarvalue::type_scalar);
// group1 is already initialized by distance()
@ -319,12 +319,12 @@ colvar::selfcoordnum::selfcoordnum (std::string const &conf)
// has set it to true
b_inverse_gradients = false;
get_keyval (conf, "cutoff", r0, cvm::real (4.0 * cvm::unit_angstrom()));
get_keyval (conf, "expNumer", en, int (6) );
get_keyval (conf, "expDenom", ed, int (12));
get_keyval(conf, "cutoff", r0, cvm::real(4.0 * cvm::unit_angstrom()));
get_keyval(conf, "expNumer", en, int(6) );
get_keyval(conf, "expDenom", ed, int(12));
if ( (en%2) || (ed%2) ) {
cvm::fatal_error ("Error: odd exponents provided, can only use even ones.\n");
cvm::fatal_error("Error: odd exponents provided, can only use even ones.\n");
}
}
@ -332,7 +332,7 @@ colvar::selfcoordnum::selfcoordnum (std::string const &conf)
colvar::selfcoordnum::selfcoordnum()
{
function_type = "selfcoordnum";
x.type (colvarvalue::type_scalar);
x.type(colvarvalue::type_scalar);
}
@ -353,9 +353,9 @@ void colvar::selfcoordnum::calc_gradients()
colvar::coordnum::switching_function<true> (r0, en, ed, group1[i], group1[j]);
}
void colvar::selfcoordnum::apply_force (colvarvalue const &force)
void colvar::selfcoordnum::apply_force(colvarvalue const &force)
{
if (!group1.noforce)
group1.apply_colvar_force (force.real_value);
group1.apply_colvar_force(force.real_value);
}

File diff suppressed because it is too large Load Diff

View File

@ -13,97 +13,97 @@
// alpha component
//////////////////////////////////////////////////////////////////////
colvar::alpha_angles::alpha_angles (std::string const &conf)
: cvc (conf)
colvar::alpha_angles::alpha_angles(std::string const &conf)
: cvc(conf)
{
if (cvm::debug())
cvm::log ("Initializing alpha_angles object.\n");
cvm::log("Initializing alpha_angles object.\n");
function_type = "alpha_angles";
x.type (colvarvalue::type_scalar);
x.type(colvarvalue::type_scalar);
std::string segment_id;
get_keyval (conf, "psfSegID", segment_id, std::string ("MAIN"));
get_keyval(conf, "psfSegID", segment_id, std::string("MAIN"));
std::vector<int> residues;
{
std::string residues_conf = "";
key_lookup (conf, "residueRange", residues_conf);
key_lookup(conf, "residueRange", residues_conf);
if (residues_conf.size()) {
std::istringstream is (residues_conf);
std::istringstream is(residues_conf);
int initial, final;
char dash;
if ( (is >> initial) && (initial > 0) &&
(is >> dash) && (dash == '-') &&
(is >> final) && (final > 0) ) {
for (int rnum = initial; rnum <= final; rnum++) {
residues.push_back (rnum);
residues.push_back(rnum);
}
}
} else {
cvm::fatal_error ("Error: no residues defined in \"residueRange\".\n");
cvm::fatal_error("Error: no residues defined in \"residueRange\".\n");
}
}
if (residues.size() < 5) {
cvm::fatal_error ("Error: not enough residues defined in \"residueRange\".\n");
cvm::fatal_error("Error: not enough residues defined in \"residueRange\".\n");
}
std::string const &sid = segment_id;
std::vector<int> const &r = residues;
get_keyval (conf, "hBondCoeff", hb_coeff, 0.5);
get_keyval(conf, "hBondCoeff", hb_coeff, 0.5);
if ( (hb_coeff < 0.0) || (hb_coeff > 1.0) ) {
cvm::fatal_error ("Error: hBondCoeff must be defined between 0 and 1.\n");
cvm::fatal_error("Error: hBondCoeff must be defined between 0 and 1.\n");
}
get_keyval (conf, "angleRef", theta_ref, 88.0);
get_keyval (conf, "angleTol", theta_tol, 15.0);
get_keyval(conf, "angleRef", theta_ref, 88.0);
get_keyval(conf, "angleTol", theta_tol, 15.0);
if (hb_coeff < 1.0) {
for (size_t i = 0; i < residues.size()-2; i++) {
theta.push_back (new colvar::angle (cvm::atom (r[i ], "CA", sid),
cvm::atom (r[i+1], "CA", sid),
cvm::atom (r[i+2], "CA", sid)));
theta.push_back(new colvar::angle(cvm::atom(r[i ], "CA", sid),
cvm::atom(r[i+1], "CA", sid),
cvm::atom(r[i+2], "CA", sid)));
}
} else {
cvm::log ("The hBondCoeff specified will disable the Calpha-Calpha-Calpha angle terms.\n");
cvm::log("The hBondCoeff specified will disable the Calpha-Calpha-Calpha angle terms.\n");
}
{
cvm::real r0;
size_t en, ed;
get_keyval (conf, "hBondCutoff", r0, (3.3 * cvm::unit_angstrom()));
get_keyval (conf, "hBondExpNumer", en, 6);
get_keyval (conf, "hBondExpDenom", ed, 8);
get_keyval(conf, "hBondCutoff", r0, (3.3 * cvm::unit_angstrom()));
get_keyval(conf, "hBondExpNumer", en, 6);
get_keyval(conf, "hBondExpDenom", ed, 8);
if (hb_coeff > 0.0) {
for (size_t i = 0; i < residues.size()-4; i++) {
hb.push_back (new colvar::h_bond (cvm::atom (r[i ], "O", sid),
cvm::atom (r[i+4], "N", sid),
hb.push_back(new colvar::h_bond(cvm::atom(r[i ], "O", sid),
cvm::atom(r[i+4], "N", sid),
r0, en, ed));
}
} else {
cvm::log ("The hBondCoeff specified will disable the hydrogen bond terms.\n");
cvm::log("The hBondCoeff specified will disable the hydrogen bond terms.\n");
}
}
if (cvm::debug())
cvm::log ("Done initializing alpha_angles object.\n");
cvm::log("Done initializing alpha_angles object.\n");
}
colvar::alpha_angles::alpha_angles()
: cvc ()
: cvc()
{
function_type = "alpha_angles";
x.type (colvarvalue::type_scalar);
x.type(colvarvalue::type_scalar);
}
colvar::alpha_angles::~alpha_angles()
@ -125,38 +125,38 @@ void colvar::alpha_angles::calc_value()
if (theta.size()) {
cvm::real const theta_norm =
(1.0-hb_coeff) / cvm::real (theta.size());
(1.0-hb_coeff) / cvm::real(theta.size());
for (size_t i = 0; i < theta.size(); i++) {
(theta[i])->calc_value();
cvm::real const t = ((theta[i])->value().real_value-theta_ref)/theta_tol;
cvm::real const f = ( (1.0 - std::pow (t, (int) 2)) /
(1.0 - std::pow (t, (int) 4)) );
cvm::real const f = ( (1.0 - std::pow(t, (int) 2)) /
(1.0 - std::pow(t, (int) 4)) );
x.real_value += theta_norm * f;
if (cvm::debug())
cvm::log ("Calpha-Calpha angle no. "+cvm::to_str (i+1)+" in \""+
cvm::log("Calpha-Calpha angle no. "+cvm::to_str(i+1)+" in \""+
this->name+"\" has a value of "+
(cvm::to_str ((theta[i])->value().real_value))+
" degrees, f = "+cvm::to_str (f)+".\n");
(cvm::to_str((theta[i])->value().real_value))+
" degrees, f = "+cvm::to_str(f)+".\n");
}
}
if (hb.size()) {
cvm::real const hb_norm =
hb_coeff / cvm::real (hb.size());
hb_coeff / cvm::real(hb.size());
for (size_t i = 0; i < hb.size(); i++) {
(hb[i])->calc_value();
x.real_value += hb_norm * (hb[i])->value().real_value;
if (cvm::debug())
cvm::log ("Hydrogen bond no. "+cvm::to_str (i+1)+" in \""+
cvm::log("Hydrogen bond no. "+cvm::to_str(i+1)+" in \""+
this->name+"\" has a value of "+
(cvm::to_str ((hb[i])->value().real_value))+".\n");
(cvm::to_str((hb[i])->value().real_value))+".\n");
}
}
}
@ -173,25 +173,25 @@ void colvar::alpha_angles::calc_gradients()
}
void colvar::alpha_angles::apply_force (colvarvalue const &force)
void colvar::alpha_angles::apply_force(colvarvalue const &force)
{
if (theta.size()) {
cvm::real const theta_norm =
(1.0-hb_coeff) / cvm::real (theta.size());
(1.0-hb_coeff) / cvm::real(theta.size());
for (size_t i = 0; i < theta.size(); i++) {
cvm::real const t = ((theta[i])->value().real_value-theta_ref)/theta_tol;
cvm::real const f = ( (1.0 - std::pow (t, (int) 2)) /
(1.0 - std::pow (t, (int) 4)) );
cvm::real const f = ( (1.0 - std::pow(t, (int) 2)) /
(1.0 - std::pow(t, (int) 4)) );
cvm::real const dfdt =
1.0/(1.0 - std::pow (t, (int) 4)) *
( (-2.0 * t) + (-1.0*f)*(-4.0 * std::pow (t, (int) 3)) );
1.0/(1.0 - std::pow(t, (int) 4)) *
( (-2.0 * t) + (-1.0*f)*(-4.0 * std::pow(t, (int) 3)) );
(theta[i])->apply_force (theta_norm *
(theta[i])->apply_force(theta_norm *
dfdt * (1.0/theta_tol) *
force.real_value );
}
@ -200,10 +200,10 @@ void colvar::alpha_angles::apply_force (colvarvalue const &force)
if (hb.size()) {
cvm::real const hb_norm =
hb_coeff / cvm::real (hb.size());
hb_coeff / cvm::real(hb.size());
for (size_t i = 0; i < hb.size(); i++) {
(hb[i])->apply_force (0.5 * hb_norm * force.real_value);
(hb[i])->apply_force(0.5 * hb_norm * force.real_value);
}
}
}
@ -221,40 +221,40 @@ void colvar::alpha_angles::apply_force (colvarvalue const &force)
// that do not calculate explicit gradients
// SO: we need a flag giving the availability of
// atomic gradients
colvar::dihedPC::dihedPC (std::string const &conf)
: cvc (conf)
colvar::dihedPC::dihedPC(std::string const &conf)
: cvc(conf)
{
if (cvm::debug())
cvm::log ("Initializing dihedral PC object.\n");
cvm::log("Initializing dihedral PC object.\n");
function_type = "dihedPC";
x.type (colvarvalue::type_scalar);
x.type(colvarvalue::type_scalar);
std::string segment_id;
get_keyval (conf, "psfSegID", segment_id, std::string ("MAIN"));
get_keyval(conf, "psfSegID", segment_id, std::string("MAIN"));
std::vector<int> residues;
{
std::string residues_conf = "";
key_lookup (conf, "residueRange", residues_conf);
key_lookup(conf, "residueRange", residues_conf);
if (residues_conf.size()) {
std::istringstream is (residues_conf);
std::istringstream is(residues_conf);
int initial, final;
char dash;
if ( (is >> initial) && (initial > 0) &&
(is >> dash) && (dash == '-') &&
(is >> final) && (final > 0) ) {
for (int rnum = initial; rnum <= final; rnum++) {
residues.push_back (rnum);
residues.push_back(rnum);
}
}
} else {
cvm::fatal_error ("Error: no residues defined in \"residueRange\".\n");
cvm::fatal_error("Error: no residues defined in \"residueRange\".\n");
}
}
if (residues.size() < 2) {
cvm::fatal_error ("Error: dihedralPC requires at least two residues.\n");
cvm::fatal_error("Error: dihedralPC requires at least two residues.\n");
}
std::string const &sid = segment_id;
@ -262,15 +262,15 @@ colvar::dihedPC::dihedPC (std::string const &conf)
std::string vecFileName;
int vecNumber;
if (get_keyval (conf, "vectorFile", vecFileName, vecFileName)) {
get_keyval (conf, "vectorNumber", vecNumber, 0);
if (get_keyval(conf, "vectorFile", vecFileName, vecFileName)) {
get_keyval(conf, "vectorNumber", vecNumber, 0);
if (vecNumber < 1)
cvm::fatal_error ("A positive value of vectorNumber is required.");
cvm::fatal_error("A positive value of vectorNumber is required.");
std::ifstream vecFile;
vecFile.open (vecFileName.c_str());
vecFile.open(vecFileName.c_str());
if (!vecFile.good())
cvm::fatal_error ("Error opening dihedral PCA vector file " + vecFileName + " for reading");
cvm::fatal_error("Error opening dihedral PCA vector file " + vecFileName + " for reading");
// TODO: adapt to different formats by setting this flag
bool eigenvectors_as_columns = true;
@ -282,7 +282,7 @@ colvar::dihedPC::dihedPC (std::string const &conf)
while (vecFile.good()) {
getline(vecFile, line);
if (line.length() < 2) break;
std::istringstream ls (line);
std::istringstream ls(line);
for (int i=0; i<vecNumber; i++) ls >> c;
coeffs.push_back(c);
}
@ -295,11 +295,11 @@ colvar::dihedPC::dihedPC (std::string const &conf)
vecFile.ignore(999999, '\n');
if (!vecFile.good())
cvm::fatal_error ("Error reading dihedral PCA vector file " + vecFileName);
cvm::fatal_error("Error reading dihedral PCA vector file " + vecFileName);
std::string line;
getline(vecFile, line);
std::istringstream ls (line);
std::istringstream ls(line);
cvm::real c;
while (ls.good()) {
ls >> c;
@ -310,11 +310,11 @@ colvar::dihedPC::dihedPC (std::string const &conf)
vecFile.close();
} else {
get_keyval (conf, "vector", coeffs, coeffs);
get_keyval(conf, "vector", coeffs, coeffs);
}
if ( coeffs.size() != 4 * (residues.size() - 1)) {
cvm::fatal_error ("Error: wrong number of coefficients: " +
cvm::fatal_error("Error: wrong number of coefficients: " +
cvm::to_str(coeffs.size()) + ". Expected " +
cvm::to_str(4 * (residues.size() - 1)) +
" (4 coeffs per residue, minus one residue).\n");
@ -322,27 +322,27 @@ colvar::dihedPC::dihedPC (std::string const &conf)
for (size_t i = 0; i < residues.size()-1; i++) {
// Psi
theta.push_back (new colvar::dihedral (cvm::atom (r[i ], "N", sid),
cvm::atom (r[i ], "CA", sid),
cvm::atom (r[i ], "C", sid),
cvm::atom (r[i+1], "N", sid)));
theta.push_back(new colvar::dihedral(cvm::atom(r[i ], "N", sid),
cvm::atom(r[i ], "CA", sid),
cvm::atom(r[i ], "C", sid),
cvm::atom(r[i+1], "N", sid)));
// Phi (next res)
theta.push_back (new colvar::dihedral (cvm::atom (r[i ], "C", sid),
cvm::atom (r[i+1], "N", sid),
cvm::atom (r[i+1], "CA", sid),
cvm::atom (r[i+1], "C", sid)));
theta.push_back(new colvar::dihedral(cvm::atom(r[i ], "C", sid),
cvm::atom(r[i+1], "N", sid),
cvm::atom(r[i+1], "CA", sid),
cvm::atom(r[i+1], "C", sid)));
}
if (cvm::debug())
cvm::log ("Done initializing dihedPC object.\n");
cvm::log("Done initializing dihedPC object.\n");
}
colvar::dihedPC::dihedPC()
: cvc ()
: cvc()
{
function_type = "dihedPC";
x.type (colvarvalue::type_scalar);
x.type(colvarvalue::type_scalar);
}
@ -375,7 +375,7 @@ void colvar::dihedPC::calc_gradients()
}
void colvar::dihedPC::apply_force (colvarvalue const &force)
void colvar::dihedPC::apply_force(colvarvalue const &force)
{
for (size_t i = 0; i < theta.size(); i++) {
cvm::real const t = (PI / 180.) * theta[i]->value().real_value;

View File

@ -10,79 +10,79 @@
colvar::orientation::orientation (std::string const &conf)
: cvc (conf)
colvar::orientation::orientation(std::string const &conf)
: cvc(conf)
{
function_type = "orientation";
parse_group (conf, "atoms", atoms);
atom_groups.push_back (&atoms);
x.type (colvarvalue::type_quaternion);
parse_group(conf, "atoms", atoms);
atom_groups.push_back(&atoms);
x.type(colvarvalue::type_quaternion);
ref_pos.reserve (atoms.size());
ref_pos.reserve(atoms.size());
if (get_keyval (conf, "refPositions", ref_pos, ref_pos)) {
cvm::log ("Using reference positions from input file.\n");
if (get_keyval(conf, "refPositions", ref_pos, ref_pos)) {
cvm::log("Using reference positions from input file.\n");
if (ref_pos.size() != atoms.size()) {
cvm::fatal_error ("Error: reference positions do not "
cvm::fatal_error("Error: reference positions do not "
"match the number of requested atoms.\n");
}
}
{
std::string file_name;
if (get_keyval (conf, "refPositionsFile", file_name)) {
if (get_keyval(conf, "refPositionsFile", file_name)) {
std::string file_col;
double file_col_value;
if (get_keyval (conf, "refPositionsCol", file_col, std::string (""))) {
if (get_keyval(conf, "refPositionsCol", file_col, std::string(""))) {
// use PDB flags if column is provided
bool found = get_keyval (conf, "refPositionsColValue", file_col_value, 0.0);
bool found = get_keyval(conf, "refPositionsColValue", file_col_value, 0.0);
if (found && !file_col_value)
cvm::fatal_error ("Error: refPositionsColValue, "
cvm::fatal_error("Error: refPositionsColValue, "
"if provided, must be non-zero.\n");
} else {
// if not, use atom indices
atoms.create_sorted_ids();
}
ref_pos.resize (atoms.size());
cvm::load_coords (file_name.c_str(), ref_pos, atoms.sorted_ids, file_col, file_col_value);
ref_pos.resize(atoms.size());
cvm::load_coords(file_name.c_str(), ref_pos, atoms.sorted_ids, file_col, file_col_value);
}
}
if (!ref_pos.size()) {
cvm::fatal_error ("Error: must define a set of "
cvm::fatal_error("Error: must define a set of "
"reference coordinates.\n");
}
cvm::log ("Centering the reference coordinates: it is "
cvm::log("Centering the reference coordinates: it is "
"assumed that each atom is the closest "
"periodic image to the center of geometry.\n");
cvm::rvector cog (0.0, 0.0, 0.0);
cvm::rvector cog(0.0, 0.0, 0.0);
size_t i;
for (i = 0; i < ref_pos.size(); i++) {
cog += ref_pos[i];
}
cog /= cvm::real (ref_pos.size());
cog /= cvm::real(ref_pos.size());
for (i = 0; i < ref_pos.size(); i++) {
ref_pos[i] -= cog;
}
get_keyval (conf, "closestToQuaternion", ref_quat, cvm::quaternion (1.0, 0.0, 0.0, 0.0));
get_keyval(conf, "closestToQuaternion", ref_quat, cvm::quaternion(1.0, 0.0, 0.0, 0.0));
// initialize rot member data
if (!atoms.noforce) {
rot.request_group2_gradients (atoms.size());
rot.request_group2_gradients(atoms.size());
}
}
colvar::orientation::orientation()
: cvc ()
: cvc()
{
function_type = "orientation";
x.type (colvarvalue::type_quaternion);
x.type(colvarvalue::type_quaternion);
}
@ -93,9 +93,9 @@ void colvar::orientation::calc_value()
atoms_cog = atoms.center_of_geometry();
rot.calc_optimal_rotation (ref_pos, atoms.positions_shifted (-1.0 * atoms_cog));
rot.calc_optimal_rotation(ref_pos, atoms.positions_shifted(-1.0 * atoms_cog));
if ((rot.q).inner (ref_quat) >= 0.0) {
if ((rot.q).inner(ref_quat) >= 0.0) {
x.quaternion_value = rot.q;
} else {
x.quaternion_value = -1.0 * rot.q;
@ -112,14 +112,14 @@ void colvar::orientation::calc_gradients()
}
void colvar::orientation::apply_force (colvarvalue const &force)
void colvar::orientation::apply_force(colvarvalue const &force)
{
cvm::quaternion const &FQ = force.quaternion_value;
if (!atoms.noforce) {
for (size_t ia = 0; ia < atoms.size(); ia++) {
for (size_t i = 0; i < 4; i++) {
atoms[ia].apply_force (FQ[i] * rot.dQ0_2[ia][i]);
atoms[ia].apply_force(FQ[i] * rot.dQ0_2[ia][i]);
}
}
}
@ -127,11 +127,11 @@ void colvar::orientation::apply_force (colvarvalue const &force)
colvar::orientation_angle::orientation_angle (std::string const &conf)
: orientation (conf)
colvar::orientation_angle::orientation_angle(std::string const &conf)
: orientation(conf)
{
function_type = "orientation_angle";
x.type (colvarvalue::type_scalar);
x.type(colvarvalue::type_scalar);
}
@ -139,7 +139,7 @@ colvar::orientation_angle::orientation_angle()
: orientation()
{
function_type = "orientation_angle";
x.type (colvarvalue::type_scalar);
x.type(colvarvalue::type_scalar);
}
@ -150,12 +150,12 @@ void colvar::orientation_angle::calc_value()
atoms_cog = atoms.center_of_geometry();
rot.calc_optimal_rotation (ref_pos, atoms.positions_shifted (-1.0 * atoms_cog));
rot.calc_optimal_rotation(ref_pos, atoms.positions_shifted(-1.0 * atoms_cog));
if ((rot.q).q0 >= 0.0) {
x.real_value = (180.0/PI) * 2.0 * std::acos ((rot.q).q0);
x.real_value = (180.0/PI) * 2.0 * std::acos((rot.q).q0);
} else {
x.real_value = (180.0/PI) * 2.0 * std::acos (-1.0 * (rot.q).q0);
x.real_value = (180.0/PI) * 2.0 * std::acos(-1.0 * (rot.q).q0);
}
}
@ -164,34 +164,34 @@ void colvar::orientation_angle::calc_gradients()
{
cvm::real const dxdq0 =
( ((rot.q).q0 * (rot.q).q0 < 1.0) ?
((180.0 / PI) * (-2.0) / std::sqrt (1.0 - ((rot.q).q0 * (rot.q).q0))) :
((180.0 / PI) * (-2.0) / std::sqrt(1.0 - ((rot.q).q0 * (rot.q).q0))) :
0.0 );
for (size_t ia = 0; ia < atoms.size(); ia++) {
atoms[ia].grad = (dxdq0 * (rot.dQ0_2[ia])[0]);
}
if (b_debug_gradients) {
cvm::log ("Debugging orientationAngle component gradients:\n");
debug_gradients (atoms);
cvm::log("Debugging orientationAngle component gradients:\n");
debug_gradients(atoms);
}
}
void colvar::orientation_angle::apply_force (colvarvalue const &force)
void colvar::orientation_angle::apply_force(colvarvalue const &force)
{
cvm::real const &fw = force.real_value;
if (!atoms.noforce) {
atoms.apply_colvar_force (fw);
atoms.apply_colvar_force(fw);
}
}
colvar::orientation_proj::orientation_proj (std::string const &conf)
: orientation (conf)
colvar::orientation_proj::orientation_proj(std::string const &conf)
: orientation(conf)
{
function_type = "orientation_proj";
x.type (colvarvalue::type_scalar);
x.type(colvarvalue::type_scalar);
}
@ -199,14 +199,14 @@ colvar::orientation_proj::orientation_proj()
: orientation()
{
function_type = "orientation_proj";
x.type (colvarvalue::type_scalar);
x.type(colvarvalue::type_scalar);
}
void colvar::orientation_proj::calc_value()
{
atoms_cog = atoms.center_of_geometry();
rot.calc_optimal_rotation (ref_pos, atoms.positions_shifted (-1.0 * atoms_cog));
rot.calc_optimal_rotation(ref_pos, atoms.positions_shifted(-1.0 * atoms_cog));
x.real_value = 2.0 * (rot.q).q0 * (rot.q).q0 - 1.0;
}
@ -218,36 +218,36 @@ void colvar::orientation_proj::calc_gradients()
atoms[ia].grad = (dxdq0 * (rot.dQ0_2[ia])[0]);
}
if (b_debug_gradients) {
cvm::log ("Debugging orientationProj component gradients:\n");
debug_gradients (atoms);
cvm::log("Debugging orientationProj component gradients:\n");
debug_gradients(atoms);
}
}
void colvar::orientation_proj::apply_force (colvarvalue const &force)
void colvar::orientation_proj::apply_force(colvarvalue const &force)
{
cvm::real const &fw = force.real_value;
if (!atoms.noforce) {
atoms.apply_colvar_force (fw);
atoms.apply_colvar_force(fw);
}
}
colvar::tilt::tilt (std::string const &conf)
: orientation (conf)
colvar::tilt::tilt(std::string const &conf)
: orientation(conf)
{
function_type = "tilt";
get_keyval (conf, "axis", axis, cvm::rvector (0.0, 0.0, 1.0));
get_keyval(conf, "axis", axis, cvm::rvector(0.0, 0.0, 1.0));
if (axis.norm2() != 1.0) {
axis /= axis.norm();
cvm::log ("Normalizing rotation axis to "+cvm::to_str (axis)+".\n");
cvm::log("Normalizing rotation axis to "+cvm::to_str(axis)+".\n");
}
x.type (colvarvalue::type_scalar);
x.type(colvarvalue::type_scalar);
}
@ -255,7 +255,7 @@ colvar::tilt::tilt()
: orientation()
{
function_type = "tilt";
x.type (colvarvalue::type_scalar);
x.type(colvarvalue::type_scalar);
}
@ -266,56 +266,56 @@ void colvar::tilt::calc_value()
atoms_cog = atoms.center_of_geometry();
rot.calc_optimal_rotation (ref_pos, atoms.positions_shifted (-1.0 * atoms_cog));
rot.calc_optimal_rotation(ref_pos, atoms.positions_shifted(-1.0 * atoms_cog));
x.real_value = rot.cos_theta (axis);
x.real_value = rot.cos_theta(axis);
}
void colvar::tilt::calc_gradients()
{
cvm::quaternion const dxdq = rot.dcos_theta_dq (axis);
cvm::quaternion const dxdq = rot.dcos_theta_dq(axis);
for (size_t ia = 0; ia < atoms.size(); ia++) {
atoms[ia].grad = cvm::rvector (0.0, 0.0, 0.0);
atoms[ia].grad = cvm::rvector(0.0, 0.0, 0.0);
for (size_t iq = 0; iq < 4; iq++) {
atoms[ia].grad += (dxdq[iq] * (rot.dQ0_2[ia])[iq]);
}
}
if (b_debug_gradients) {
cvm::log ("Debugging tilt component gradients:\n");
debug_gradients (atoms);
cvm::log("Debugging tilt component gradients:\n");
debug_gradients(atoms);
}
}
void colvar::tilt::apply_force (colvarvalue const &force)
void colvar::tilt::apply_force(colvarvalue const &force)
{
cvm::real const &fw = force.real_value;
if (!atoms.noforce) {
atoms.apply_colvar_force (fw);
atoms.apply_colvar_force(fw);
}
}
colvar::spin_angle::spin_angle (std::string const &conf)
: orientation (conf)
colvar::spin_angle::spin_angle(std::string const &conf)
: orientation(conf)
{
function_type = "spin_angle";
get_keyval (conf, "axis", axis, cvm::rvector (0.0, 0.0, 1.0));
get_keyval(conf, "axis", axis, cvm::rvector(0.0, 0.0, 1.0));
if (axis.norm2() != 1.0) {
axis /= axis.norm();
cvm::log ("Normalizing rotation axis to "+cvm::to_str (axis)+".\n");
cvm::log("Normalizing rotation axis to "+cvm::to_str(axis)+".\n");
}
period = 360.0;
b_periodic = true;
x.type (colvarvalue::type_scalar);
x.type(colvarvalue::type_scalar);
}
@ -325,7 +325,7 @@ colvar::spin_angle::spin_angle()
function_type = "spin_angle";
period = 360.0;
b_periodic = true;
x.type (colvarvalue::type_scalar);
x.type(colvarvalue::type_scalar);
}
@ -336,19 +336,19 @@ void colvar::spin_angle::calc_value()
atoms_cog = atoms.center_of_geometry();
rot.calc_optimal_rotation (ref_pos, atoms.positions_shifted (-1.0 * atoms_cog));
rot.calc_optimal_rotation(ref_pos, atoms.positions_shifted(-1.0 * atoms_cog));
x.real_value = rot.spin_angle (axis);
this->wrap (x);
x.real_value = rot.spin_angle(axis);
this->wrap(x);
}
void colvar::spin_angle::calc_gradients()
{
cvm::quaternion const dxdq = rot.dspin_angle_dq (axis);
cvm::quaternion const dxdq = rot.dspin_angle_dq(axis);
for (size_t ia = 0; ia < atoms.size(); ia++) {
atoms[ia].grad = cvm::rvector (0.0, 0.0, 0.0);
atoms[ia].grad = cvm::rvector(0.0, 0.0, 0.0);
for (size_t iq = 0; iq < 4; iq++) {
atoms[ia].grad += (dxdq[iq] * (rot.dQ0_2[ia])[iq]);
}
@ -356,11 +356,11 @@ void colvar::spin_angle::calc_gradients()
}
void colvar::spin_angle::apply_force (colvarvalue const &force)
void colvar::spin_angle::apply_force(colvarvalue const &force)
{
cvm::real const &fw = force.real_value;
if (!atoms.noforce) {
atoms.apply_colvar_force (fw);
atoms.apply_colvar_force(fw);
}
}

View File

@ -12,59 +12,59 @@ colvar_grid_count::colvar_grid_count()
: colvar_grid<size_t>()
{}
colvar_grid_count::colvar_grid_count (std::vector<int> const &nx_i,
size_t const &def_count)
: colvar_grid<size_t> (nx_i, def_count)
colvar_grid_count::colvar_grid_count(std::vector<int> const &nx_i,
size_t const &def_count)
: colvar_grid<size_t>(nx_i, def_count)
{}
colvar_grid_count::colvar_grid_count (std::vector<colvar *> &colvars,
size_t const &def_count)
: colvar_grid<size_t> (colvars, def_count)
colvar_grid_count::colvar_grid_count(std::vector<colvar *> &colvars,
size_t const &def_count)
: colvar_grid<size_t>(colvars, def_count)
{}
std::istream & colvar_grid_count::read_restart (std::istream &is)
std::istream & colvar_grid_count::read_restart(std::istream &is)
{
size_t const start_pos = is.tellg();
std::string key, conf;
if ((is >> key) && (key == std::string ("grid_parameters"))) {
is.seekg (start_pos, std::ios::beg);
is >> colvarparse::read_block ("grid_parameters", conf);
parse_params (conf);
if ((is >> key) && (key == std::string("grid_parameters"))) {
is.seekg(start_pos, std::ios::beg);
is >> colvarparse::read_block("grid_parameters", conf);
parse_params(conf);
} else {
cvm::log ("Grid parameters are missing in the restart file, using those from the configuration.\n");
is.seekg (start_pos, std::ios::beg);
cvm::log("Grid parameters are missing in the restart file, using those from the configuration.\n");
is.seekg(start_pos, std::ios::beg);
}
read_raw (is);
read_raw(is);
return is;
}
std::ostream & colvar_grid_count::write_restart (std::ostream &os)
std::ostream & colvar_grid_count::write_restart(std::ostream &os)
{
write_params (os);
write_raw (os);
write_params(os);
write_raw(os);
return os;
}
colvar_grid_scalar::colvar_grid_scalar()
: colvar_grid<cvm::real>(), samples (NULL), grad (NULL)
: colvar_grid<cvm::real>(), samples(NULL), grad(NULL)
{}
colvar_grid_scalar::colvar_grid_scalar (colvar_grid_scalar const &g)
: colvar_grid<cvm::real> (g), samples (NULL), grad (NULL)
colvar_grid_scalar::colvar_grid_scalar(colvar_grid_scalar const &g)
: colvar_grid<cvm::real>(g), samples(NULL), grad(NULL)
{
grad = new cvm::real[nd];
}
colvar_grid_scalar::colvar_grid_scalar (std::vector<int> const &nx_i)
: colvar_grid<cvm::real> (nx_i, 0.0, 1), samples (NULL)
colvar_grid_scalar::colvar_grid_scalar(std::vector<int> const &nx_i)
: colvar_grid<cvm::real>(nx_i, 0.0, 1), samples(NULL)
{
grad = new cvm::real[nd];
}
colvar_grid_scalar::colvar_grid_scalar (std::vector<colvar *> &colvars, bool margin)
: colvar_grid<cvm::real> (colvars, 0.0, 1, margin), samples (NULL)
colvar_grid_scalar::colvar_grid_scalar(std::vector<colvar *> &colvars, bool margin)
: colvar_grid<cvm::real>(colvars, 0.0, 1, margin), samples(NULL)
{
grad = new cvm::real[nd];
}
@ -77,67 +77,67 @@ colvar_grid_scalar::~colvar_grid_scalar()
}
}
std::istream & colvar_grid_scalar::read_restart (std::istream &is)
std::istream & colvar_grid_scalar::read_restart(std::istream &is)
{
size_t const start_pos = is.tellg();
std::string key, conf;
if ((is >> key) && (key == std::string ("grid_parameters"))) {
is.seekg (start_pos, std::ios::beg);
is >> colvarparse::read_block ("grid_parameters", conf);
parse_params (conf);
if ((is >> key) && (key == std::string("grid_parameters"))) {
is.seekg(start_pos, std::ios::beg);
is >> colvarparse::read_block("grid_parameters", conf);
parse_params(conf);
} else {
cvm::log ("Grid parameters are missing in the restart file, using those from the configuration.\n");
is.seekg (start_pos, std::ios::beg);
cvm::log("Grid parameters are missing in the restart file, using those from the configuration.\n");
is.seekg(start_pos, std::ios::beg);
}
read_raw (is);
read_raw(is);
return is;
}
std::ostream & colvar_grid_scalar::write_restart (std::ostream &os)
std::ostream & colvar_grid_scalar::write_restart(std::ostream &os)
{
write_params (os);
write_raw (os);
write_params(os);
write_raw(os);
return os;
}
colvar_grid_gradient::colvar_grid_gradient()
: colvar_grid<cvm::real>(), samples (NULL)
: colvar_grid<cvm::real>(), samples(NULL)
{}
colvar_grid_gradient::colvar_grid_gradient (std::vector<int> const &nx_i)
: colvar_grid<cvm::real> (nx_i, 0.0, nx_i.size()), samples (NULL)
colvar_grid_gradient::colvar_grid_gradient(std::vector<int> const &nx_i)
: colvar_grid<cvm::real>(nx_i, 0.0, nx_i.size()), samples(NULL)
{}
colvar_grid_gradient::colvar_grid_gradient (std::vector<colvar *> &colvars)
: colvar_grid<cvm::real> (colvars, 0.0, colvars.size()), samples (NULL)
colvar_grid_gradient::colvar_grid_gradient(std::vector<colvar *> &colvars)
: colvar_grid<cvm::real>(colvars, 0.0, colvars.size()), samples(NULL)
{}
std::istream & colvar_grid_gradient::read_restart (std::istream &is)
std::istream & colvar_grid_gradient::read_restart(std::istream &is)
{
size_t const start_pos = is.tellg();
std::string key, conf;
if ((is >> key) && (key == std::string ("grid_parameters"))) {
is.seekg (start_pos, std::ios::beg);
is >> colvarparse::read_block ("grid_parameters", conf);
parse_params (conf);
if ((is >> key) && (key == std::string("grid_parameters"))) {
is.seekg(start_pos, std::ios::beg);
is >> colvarparse::read_block("grid_parameters", conf);
parse_params(conf);
} else {
cvm::log ("Grid parameters are missing in the restart file, using those from the configuration.\n");
is.seekg (start_pos, std::ios::beg);
cvm::log("Grid parameters are missing in the restart file, using those from the configuration.\n");
is.seekg(start_pos, std::ios::beg);
}
read_raw (is);
read_raw(is);
return is;
}
std::ostream & colvar_grid_gradient::write_restart (std::ostream &os)
std::ostream & colvar_grid_gradient::write_restart(std::ostream &os)
{
write_params (os);
write_raw (os);
write_params(os);
write_raw(os);
return os;
}
void colvar_grid_gradient::write_1D_integral (std::ostream &os)
void colvar_grid_gradient::write_1D_integral(std::ostream &os)
{
cvm::real bin, min, integral;
std::vector<cvm::real> int_vals;
@ -145,11 +145,11 @@ void colvar_grid_gradient::write_1D_integral (std::ostream &os)
os << "# xi A(xi)\n";
if ( cv.size() != 1 ) {
cvm::fatal_error ("Cannot write integral for multi-dimensional gradient grids.");
cvm::fatal_error("Cannot write integral for multi-dimensional gradient grids.");
}
integral = 0.0;
int_vals.push_back ( 0.0 );
int_vals.push_back( 0.0 );
bin = 0.0;
min = 0.0;
@ -161,31 +161,31 @@ void colvar_grid_gradient::write_1D_integral (std::ostream &os)
corr = 0.0;
}
for (std::vector<int> ix = new_index(); index_ok (ix); incr (ix), bin += 1.0 ) {
for (std::vector<int> ix = new_index(); index_ok(ix); incr(ix), bin += 1.0 ) {
if (samples) {
size_t const samples_here = samples->value (ix);
size_t const samples_here = samples->value(ix);
if (samples_here)
integral += (value (ix) / cvm::real (samples_here) - corr) * cv[0]->width;
integral += (value(ix) / cvm::real(samples_here) - corr) * cv[0]->width;
} else {
integral += (value (ix) - corr) * cv[0]->width;
integral += (value(ix) - corr) * cv[0]->width;
}
if ( integral < min ) min = integral;
int_vals.push_back ( integral );
int_vals.push_back( integral );
}
bin = 0.0;
for ( int i = 0; i < nx[0]; i++, bin += 1.0 ) {
os << std::setw (10) << cv[0]->lower_boundary.real_value + cv[0]->width * bin << " "
<< std::setw (cvm::cv_width)
<< std::setprecision (cvm::cv_prec)
os << std::setw(10) << cv[0]->lower_boundary.real_value + cv[0]->width * bin << " "
<< std::setw(cvm::cv_width)
<< std::setprecision(cvm::cv_prec)
<< int_vals[i] - min << "\n";
}
os << std::setw (10) << cv[0]->lower_boundary.real_value + cv[0]->width * bin << " "
<< std::setw (cvm::cv_width)
<< std::setprecision (cvm::cv_prec)
os << std::setw(10) << cv[0]->lower_boundary.real_value + cv[0]->width * bin << " "
<< std::setw(cvm::cv_width)
<< std::setprecision(cvm::cv_prec)
<< int_vals[nx[0]] - min << "\n";
return;
@ -193,25 +193,3 @@ void colvar_grid_gradient::write_1D_integral (std::ostream &os)
// quaternion_grid::quaternion_grid (std::vector<colvar *> const &cv_i,
// std::vector<std::string> const &grid_str)
// {
// cv = cv_i;
// std::istringstream is (grid_str[0]);
// is >> grid_size;
// min.assign (3, -1.0);
// max.assign (3, 1.0);
// np.assign (3, grid_size);
// dx.assign (3, 2.0/(cvm::real (grid_size)));
// // assumes a uniform grid in the three directions; change
// // get_value() if you want to use different sizes
// cvm::log ("Allocating quaternion grid ("+cvm::to_str (np.size())+" dimensional)...");
// data.create (np, 0.0);
// cvm::log ("done.\n");
// if (cvm::debug()) cvm::log ("Grid size = "+data.size());
// }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@
#define COLVARMODULE_H
#ifndef COLVARS_VERSION
#define COLVARS_VERSION "2014-10-21"
#define COLVARS_VERSION "2014-11-21"
#endif
#ifndef COLVARS_DEBUG
@ -21,6 +21,7 @@
/// objects.
// Internal method return codes
#define COLVARS_NOT_IMPLEMENTED -2
#define COLVARS_ERROR -1
#define COLVARS_OK 0
@ -80,11 +81,8 @@ public:
typedef int residue_id;
class rvector;
template <class T,
size_t const length> class vector1d;
template <class T,
size_t const outer_length,
size_t const inner_length> class matrix2d;
template <class T> class vector1d;
template <class T> class matrix2d;
class quaternion;
class rotation;
@ -160,7 +158,7 @@ public:
/// Array of named (reusable) collective variable components
static std::vector<cvc *> cvcs;
/// Named cvcs register themselves at initialization time
inline void register_cvc (cvc *p) {
inline void register_cvc(cvc *p) {
cvcs.push_back(p);
}
*/
@ -189,7 +187,7 @@ public:
/// \brief Constructor \param config_name Configuration file name
/// \param restart_name (optional) Restart file name
colvarmodule (colvarproxy *proxy);
colvarmodule(colvarproxy *proxy);
/// Destructor
~colvarmodule();
@ -198,26 +196,30 @@ public:
int reset();
/// Open a config file, load its contents, and pass it to config_string()
int config_file (char const *config_file_name);
int config_file(char const *config_file_name);
/// \brief Parse a config string assuming it is a complete configuration
/// (i.e. calling all parse functions)
int config_string (std::string const &conf);
int config_string(std::string const &conf);
/// \brief Parse a "clean" config string (no comments)
int config (std::string &conf);
int config(std::string &conf);
// Parse functions (setup internal data based on a string)
/// Parse the few module's global parameters
int parse_global_params (std::string const &conf);
int parse_global_params(std::string const &conf);
/// Parse and initialize collective variables
int parse_colvars (std::string const &conf);
int parse_colvars(std::string const &conf);
/// Parse and initialize collective variable biases
int parse_biases (std::string const &conf);
int parse_biases(std::string const &conf);
/// Parse and initialize collective variable biases of a specific type
template <class bias_type>
int parse_biases_type(std::string const &conf, char const *keyword, size_t &bias_count);
/// Test error condition and keyword parsing
/// on error, delete new bias
@ -238,23 +240,23 @@ public:
int setup_output();
/// Read the input restart file
std::istream & read_restart (std::istream &is);
std::istream & read_restart(std::istream &is);
/// Write the output restart file
std::ostream & write_restart (std::ostream &os);
std::ostream & write_restart(std::ostream &os);
/// Open a trajectory file if requested (and leave it open)
int open_traj_file (std::string const &file_name);
int open_traj_file(std::string const &file_name);
/// Close it
int close_traj_file();
/// Write in the trajectory file
std::ostream & write_traj (std::ostream &os);
std::ostream & write_traj(std::ostream &os);
/// Write explanatory labels in the trajectory file
std::ostream & write_traj_label (std::ostream &os);
std::ostream & write_traj_label(std::ostream &os);
/// Write all FINAL output files
int write_output_files();
/// Backup a file before writing it
static int backup_file (char const *filename);
static int backup_file(char const *filename);
/// Look up a bias by name; returns NULL if not found
static colvarbias * bias_by_name(std::string const &name);
@ -264,25 +266,23 @@ public:
/// Load new configuration for the given bias -
/// currently works for harmonic (force constant and/or centers)
int change_configuration (std::string const &bias_name, std::string const &conf);
int change_configuration(std::string const &bias_name, std::string const &conf);
/// Read a colvar value
std::string read_colvar(std::string const &name);
/// Calculate change in energy from using alt. config. for the given bias -
/// currently works for harmonic (force constant and/or centers)
real energy_difference (std::string const &bias_name, std::string const &conf);
real energy_difference(std::string const &bias_name, std::string const &conf);
/// Give the bin width in the units of the colvar.
real read_width(std::string const &name);
/// Give the total number of bins for a given bias.
size_t bias_bin_num(std::string const &bias_name);
int bias_bin_num(std::string const &bias_name);
/// Calculate the bin index for a given bias.
size_t bias_current_bin(std::string const &bias_name);
int bias_current_bin(std::string const &bias_name);
//// Give the count at a given bin index.
size_t bias_bin_count(std::string const &bias_name, size_t bin_index);
int bias_bin_count(std::string const &bias_name, size_t bin_index);
//// Share among replicas.
void bias_share(std::string const &bias_name);
int bias_share(std::string const &bias_name);
/// Calculate collective variables and biases
int calc();
@ -291,29 +291,29 @@ public:
int analyze();
/// \brief Read a collective variable trajectory (post-processing
/// only, not called at runtime)
int read_traj (char const *traj_filename,
int read_traj(char const *traj_filename,
size_t traj_read_begin,
size_t traj_read_end);
/// Quick conversion of an object to a string
template<typename T> static std::string to_str (T const &x,
template<typename T> static std::string to_str(T const &x,
size_t const &width = 0,
size_t const &prec = 0);
/// Quick conversion of a vector of objects to a string
template<typename T> static std::string to_str (std::vector<T> const &x,
template<typename T> static std::string to_str(std::vector<T> const &x,
size_t const &width = 0,
size_t const &prec = 0);
/// Reduce the number of characters in a string
static inline std::string wrap_string (std::string const &s,
static inline std::string wrap_string(std::string const &s,
size_t const &nchars)
{
if (!s.size())
return std::string (nchars, ' ');
return std::string(nchars, ' ');
else
return ( (s.size() <= size_t (nchars)) ?
(s+std::string (nchars-s.size(), ' ')) :
(std::string (s, 0, nchars)) );
return ( (s.size() <= size_t(nchars)) ?
(s+std::string(nchars-s.size(), ' ')) :
(std::string(s, 0, nchars)) );
}
/// Number of characters to represent a time step
@ -349,16 +349,16 @@ public:
static void request_system_force();
/// Print a message to the main log
static void log (std::string const &message);
static void log(std::string const &message);
/// Print a message to the main log and exit with error code
static void fatal_error (std::string const &message);
static void fatal_error(std::string const &message);
/// Print a message to the main log and set global error code
static void error (std::string const &message, int code = GENERAL_ERROR);
static void error(std::string const &message, int code = GENERAL_ERROR);
/// Print a message to the main log and exit normally
static void exit (std::string const &message);
static void exit(std::string const &message);
// Replica exchange commands.
static bool replica_enabled();
@ -370,7 +370,7 @@ public:
/// \brief Get the distance between two atomic positions with pbcs handled
/// correctly
static rvector position_distance (atom_pos const &pos1,
static rvector position_distance(atom_pos const &pos1,
atom_pos const &pos2);
@ -380,20 +380,20 @@ public:
/// Note: in the case of periodic boundary conditions, this provides
/// an analytical square distance (while taking the square of
/// position_distance() would produce leads to a cusp)
static real position_dist2 (atom_pos const &pos1,
static real position_dist2(atom_pos const &pos1,
atom_pos const &pos2);
/// \brief Get the closest periodic image to a reference position
/// \param pos The position to look for the closest periodic image
/// \param ref_pos (optional) The reference position
static void select_closest_image (atom_pos &pos,
static void select_closest_image(atom_pos &pos,
atom_pos const &ref_pos);
/// \brief Perform select_closest_image() on a set of atomic positions
///
/// After that, distance vectors can then be calculated directly,
/// without using position_distance()
static void select_closest_images (std::vector<atom_pos> &pos,
static void select_closest_images(std::vector<atom_pos> &pos,
atom_pos const &ref_pos);
@ -404,21 +404,21 @@ public:
static std::list<std::vector<int> > index_groups;
/// \brief Read a Gromacs .ndx file
static int read_index_file (char const *filename);
static int read_index_file(char const *filename);
/// \brief Create atoms from a file \param filename name of the file
/// (usually a PDB) \param atoms array of the atoms to be allocated
/// \param pdb_field (optiona) if "filename" is a PDB file, use this
/// field to determine which are the atoms to be set
static int load_atoms (char const *filename,
static int load_atoms(char const *filename,
std::vector<atom> &atoms,
std::string const &pdb_field,
double const pdb_field_value = 0.0);
/// \brief Load the coordinates for a group of atoms from a file
/// (PDB or XYZ)
static int load_coords (char const *filename,
static int load_coords(char const *filename,
std::vector<atom_pos> &pos,
const std::vector<int> &indices,
std::string const &pdb_field,
@ -426,7 +426,7 @@ public:
/// \brief Load the coordinates for a group of atoms from an
/// XYZ file
static int load_coords_xyz (char const *filename,
static int load_coords_xyz(char const *filename,
std::vector<atom_pos> &pos,
const std::vector<int> &indices);
@ -442,7 +442,7 @@ public:
std::string restart_out_name;
/// Pseudo-random number with Gaussian distribution
static real rand_gaussian (void);
static real rand_gaussian(void);
protected:
/// Configuration file
@ -467,7 +467,7 @@ protected:
static size_t depth;
/// Use scripted colvars forces?
bool use_scripted_forces;
static bool use_scripted_forces;
public:
/// \brief Pointer to the proxy object, used to retrieve atomic data
@ -481,6 +481,8 @@ public:
/// Decrease the depth (number of indentations in the output)
static void decrease_depth();
static inline bool scripted_forces() { return use_scripted_forces; }
};
@ -495,35 +497,35 @@ std::ostream & operator << (std::ostream &os, cvm::rvector const &v);
std::istream & operator >> (std::istream &is, cvm::rvector &v);
template<typename T> std::string cvm::to_str (T const &x,
template<typename T> std::string cvm::to_str(T const &x,
size_t const &width,
size_t const &prec) {
std::ostringstream os;
if (width) os.width (width);
if (width) os.width(width);
if (prec) {
os.setf (std::ios::scientific, std::ios::floatfield);
os.precision (prec);
os.setf(std::ios::scientific, std::ios::floatfield);
os.precision(prec);
}
os << x;
return os.str();
}
template<typename T> std::string cvm::to_str (std::vector<T> const &x,
template<typename T> std::string cvm::to_str(std::vector<T> const &x,
size_t const &width,
size_t const &prec) {
if (!x.size()) return std::string ("");
if (!x.size()) return std::string("");
std::ostringstream os;
if (prec) {
os.setf (std::ios::scientific, std::ios::floatfield);
os.setf(std::ios::scientific, std::ios::floatfield);
}
os << "{ ";
if (width) os.width (width);
if (prec) os.precision (prec);
if (width) os.width(width);
if (prec) os.precision(prec);
os << x[0];
for (size_t i = 1; i < x.size(); i++) {
os << ", ";
if (width) os.width (width);
if (prec) os.precision (prec);
if (width) os.width(width);
if (prec) os.precision(prec);
os << x[i];
}
os << " }";
@ -577,34 +579,34 @@ inline int cvm::replica_comm_send(char* msg_data, int msg_len, int dest_rep) {
inline void cvm::request_system_force()
{
proxy->request_system_force (true);
proxy->request_system_force(true);
}
inline void cvm::select_closest_image (atom_pos &pos,
inline void cvm::select_closest_image(atom_pos &pos,
atom_pos const &ref_pos)
{
proxy->select_closest_image (pos, ref_pos);
proxy->select_closest_image(pos, ref_pos);
}
inline void cvm::select_closest_images (std::vector<atom_pos> &pos,
inline void cvm::select_closest_images(std::vector<atom_pos> &pos,
atom_pos const &ref_pos)
{
proxy->select_closest_images (pos, ref_pos);
proxy->select_closest_images(pos, ref_pos);
}
inline cvm::rvector cvm::position_distance (atom_pos const &pos1,
inline cvm::rvector cvm::position_distance(atom_pos const &pos1,
atom_pos const &pos2)
{
return proxy->position_distance (pos1, pos2);
return proxy->position_distance(pos1, pos2);
}
inline cvm::real cvm::position_dist2 (cvm::atom_pos const &pos1,
inline cvm::real cvm::position_dist2(cvm::atom_pos const &pos1,
cvm::atom_pos const &pos2)
{
return proxy->position_dist2 (pos1, pos2);
return proxy->position_dist2(pos1, pos2);
}
inline cvm::real cvm::rand_gaussian (void)
inline cvm::real cvm::rand_gaussian(void)
{
return proxy->rand_gaussian();
}

View File

@ -19,11 +19,11 @@ size_t colvarparse::dummy_pos = 0;
#define _get_keyval_scalar_string_(TYPE) \
\
bool colvarparse::get_keyval (std::string const &conf, \
char const *key, \
TYPE &value, \
TYPE const &def_value, \
Parse_Mode const parse_mode) \
bool colvarparse::get_keyval(std::string const &conf, \
char const *key, \
TYPE &value, \
TYPE const &def_value, \
Parse_Mode const parse_mode) \
{ \
std::string data; \
bool b_found = false, b_found_any = false; \
@ -31,7 +31,7 @@ size_t colvarparse::dummy_pos = 0;
\
do { \
std::string data_this = ""; \
b_found = key_lookup (conf, key, data_this, save_pos); \
b_found = key_lookup(conf, key, data_this, save_pos); \
if (b_found) { \
if (!b_found_any) \
b_found_any = true; \
@ -41,30 +41,30 @@ size_t colvarparse::dummy_pos = 0;
} while (b_found); \
\
if (found_count > 1) \
cvm::log ("Warning: found more than one instance of \""+ \
std::string (key)+"\".\n"); \
cvm::log("Warning: found more than one instance of \""+ \
std::string(key)+"\".\n"); \
\
if (data.size()) { \
std::istringstream is (data); \
TYPE x (def_value); \
std::istringstream is(data); \
TYPE x(def_value); \
if (is >> x) \
value = x; \
else \
cvm::error ("Error: in parsing \""+ \
std::string (key)+"\".\n", INPUT_ERROR); \
cvm::error("Error: in parsing \""+ \
std::string(key)+"\".\n", INPUT_ERROR); \
if (parse_mode != parse_silent) { \
cvm::log ("# "+std::string (key)+" = "+ \
cvm::to_str (value)+"\n"); \
cvm::log("# "+std::string(key)+" = "+ \
cvm::to_str(value)+"\n"); \
} \
} else { \
\
if (b_found_any) \
cvm::error ("Error: improper or missing value " \
"for \""+std::string (key)+"\".\n", INPUT_ERROR); \
cvm::error("Error: improper or missing value " \
"for \""+std::string(key)+"\".\n", INPUT_ERROR); \
value = def_value; \
if (parse_mode != parse_silent) { \
cvm::log ("# "+std::string (key)+" = \""+ \
cvm::to_str (def_value)+"\" [default]\n"); \
cvm::log("# "+std::string(key)+" = \""+ \
cvm::to_str(def_value)+"\" [default]\n"); \
} \
} \
\
@ -74,11 +74,11 @@ size_t colvarparse::dummy_pos = 0;
#define _get_keyval_scalar_(TYPE) \
\
bool colvarparse::get_keyval (std::string const &conf, \
char const *key, \
TYPE &value, \
TYPE const &def_value, \
Parse_Mode const parse_mode) \
bool colvarparse::get_keyval(std::string const &conf, \
char const *key, \
TYPE &value, \
TYPE const &def_value, \
Parse_Mode const parse_mode) \
{ \
std::string data; \
bool b_found = false, b_found_any = false; \
@ -86,7 +86,7 @@ size_t colvarparse::dummy_pos = 0;
\
do { \
std::string data_this = ""; \
b_found = key_lookup (conf, key, data_this, save_pos); \
b_found = key_lookup(conf, key, data_this, save_pos); \
if (b_found) { \
if (!b_found_any) \
b_found_any = true; \
@ -96,37 +96,37 @@ size_t colvarparse::dummy_pos = 0;
} while (b_found); \
\
if (found_count > 1) \
cvm::log ("Warning: found more than one instance of \""+ \
std::string (key)+"\".\n"); \
cvm::log("Warning: found more than one instance of \""+ \
std::string(key)+"\".\n"); \
\
if (data.size()) { \
std::istringstream is (data); \
std::istringstream is(data); \
size_t data_count = 0; \
TYPE x (def_value); \
TYPE x(def_value); \
while (is >> x) { \
value = x; \
data_count++; \
} \
if (data_count == 0) \
cvm::fatal_error ("Error: in parsing \""+ \
std::string (key)+"\".\n"); \
cvm::fatal_error("Error: in parsing \""+ \
std::string(key)+"\".\n"); \
if (data_count > 1) \
cvm::error ("Error: multiple values " \
"are not allowed for keyword \""+ \
std::string (key)+"\".\n", INPUT_ERROR); \
cvm::error("Error: multiple values " \
"are not allowed for keyword \""+ \
std::string(key)+"\".\n", INPUT_ERROR); \
if (parse_mode != parse_silent) { \
cvm::log ("# "+std::string (key)+" = "+ \
cvm::to_str (value)+"\n"); \
cvm::log("# "+std::string(key)+" = "+ \
cvm::to_str(value)+"\n"); \
} \
} else { \
\
if (b_found_any) \
cvm::error ("Error: improper or missing value " \
"for \""+std::string (key)+"\".\n", INPUT_ERROR); \
cvm::error("Error: improper or missing value " \
"for \""+std::string(key)+"\".\n", INPUT_ERROR); \
value = def_value; \
if (parse_mode != parse_silent) { \
cvm::log ("# "+std::string (key)+" = "+ \
cvm::to_str (def_value)+" [default]\n"); \
cvm::log("# "+std::string(key)+" = "+ \
cvm::to_str(def_value)+" [default]\n"); \
} \
} \
\
@ -138,11 +138,11 @@ size_t colvarparse::dummy_pos = 0;
#define _get_keyval_vector_(TYPE) \
\
bool colvarparse::get_keyval (std::string const &conf, \
char const *key, \
std::vector<TYPE> &values, \
std::vector<TYPE> const &def_values, \
Parse_Mode const parse_mode) \
bool colvarparse::get_keyval(std::string const &conf, \
char const *key, \
std::vector<TYPE> &values, \
std::vector<TYPE> const &def_values, \
Parse_Mode const parse_mode) \
{ \
std::string data; \
bool b_found = false, b_found_any = false; \
@ -150,7 +150,7 @@ size_t colvarparse::dummy_pos = 0;
\
do { \
std::string data_this = ""; \
b_found = key_lookup (conf, key, data_this, save_pos); \
b_found = key_lookup(conf, key, data_this, save_pos); \
if (b_found) { \
if (!b_found_any) \
b_found_any = true; \
@ -160,11 +160,11 @@ size_t colvarparse::dummy_pos = 0;
} while (b_found); \
\
if (found_count > 1) \
cvm::log ("Warning: found more than one instance of \""+ \
std::string (key)+"\".\n"); \
cvm::log("Warning: found more than one instance of \""+ \
std::string(key)+"\".\n"); \
\
if (data.size()) { \
std::istringstream is (data); \
std::istringstream is(data); \
\
if (values.size() == 0) { \
\
@ -172,44 +172,44 @@ size_t colvarparse::dummy_pos = 0;
if (def_values.size()) \
x = def_values; \
else \
x.assign (1, TYPE()); \
x.assign(1, TYPE()); \
\
for (size_t i = 0; \
( is >> x[ ((i<x.size()) ? i : x.size()-1) ] ); \
i++) { \
values.push_back (x[ ((i<x.size()) ? i : x.size()-1) ]); \
values.push_back(x[ ((i<x.size()) ? i : x.size()-1) ]); \
} \
\
} else { \
\
size_t i = 0; \
for ( ; i < values.size(); i++) { \
TYPE x (values[i]); \
TYPE x(values[i]); \
if (is >> x) \
values[i] = x; \
else \
cvm::error ("Error: in parsing \""+ \
std::string (key)+"\".\n", INPUT_ERROR); \
cvm::error("Error: in parsing \""+ \
std::string(key)+"\".\n", INPUT_ERROR); \
} \
} \
\
if (parse_mode != parse_silent) { \
cvm::log ("# "+std::string (key)+" = "+ \
cvm::to_str (values)+"\n"); \
cvm::log("# "+std::string(key)+" = "+ \
cvm::to_str(values)+"\n"); \
} \
\
} else { \
\
if (b_found_any) \
cvm::error ("Error: improper or missing values for \""+ \
std::string (key)+"\".\n", INPUT_ERROR); \
cvm::error("Error: improper or missing values for \""+ \
std::string(key)+"\".\n", INPUT_ERROR); \
\
for (size_t i = 0; i < values.size(); i++) \
values[i] = def_values[ (i > def_values.size()) ? 0 : i ]; \
\
if (parse_mode != parse_silent) { \
cvm::log ("# "+std::string (key)+" = "+ \
cvm::to_str (def_values)+" [default]\n"); \
cvm::log("# "+std::string(key)+" = "+ \
cvm::to_str(def_values)+" [default]\n"); \
} \
} \
\
@ -219,32 +219,32 @@ size_t colvarparse::dummy_pos = 0;
// single-value keyword parsers
_get_keyval_scalar_ (int);
_get_keyval_scalar_ (size_t);
_get_keyval_scalar_string_ (std::string);
_get_keyval_scalar_ (cvm::real);
_get_keyval_scalar_ (cvm::rvector);
_get_keyval_scalar_ (cvm::quaternion);
_get_keyval_scalar_ (colvarvalue);
_get_keyval_scalar_(int);
_get_keyval_scalar_(size_t);
_get_keyval_scalar_string_(std::string);
_get_keyval_scalar_(cvm::real);
_get_keyval_scalar_(cvm::rvector);
_get_keyval_scalar_(cvm::quaternion);
_get_keyval_scalar_(colvarvalue);
// multiple-value keyword parsers
_get_keyval_vector_ (int);
_get_keyval_vector_ (size_t);
_get_keyval_vector_ (std::string);
_get_keyval_vector_ (cvm::real);
_get_keyval_vector_ (cvm::rvector);
_get_keyval_vector_ (cvm::quaternion);
_get_keyval_vector_ (colvarvalue);
_get_keyval_vector_(int);
_get_keyval_vector_(size_t);
_get_keyval_vector_(std::string);
_get_keyval_vector_(cvm::real);
_get_keyval_vector_(cvm::rvector);
_get_keyval_vector_(cvm::quaternion);
_get_keyval_vector_(colvarvalue);
bool colvarparse::get_keyval (std::string const &conf,
char const *key,
bool &value,
bool const &def_value,
Parse_Mode const parse_mode)
bool colvarparse::get_keyval(std::string const &conf,
char const *key,
bool &value,
bool const &def_value,
Parse_Mode const parse_mode)
{
std::string data;
bool b_found = false, b_found_any = false;
@ -252,7 +252,7 @@ bool colvarparse::get_keyval (std::string const &conf,
do {
std::string data_this = "";
b_found = key_lookup (conf, key, data_this, save_pos);
b_found = key_lookup(conf, key, data_this, save_pos);
if (b_found) {
if (!b_found_any)
b_found_any = true;
@ -262,37 +262,37 @@ bool colvarparse::get_keyval (std::string const &conf,
} while (b_found);
if (found_count > 1)
cvm::log ("Warning: found more than one instance of \""+
std::string (key)+"\".\n");
cvm::log("Warning: found more than one instance of \""+
std::string(key)+"\".\n");
if (data.size()) {
if ( (data == std::string ("on")) ||
(data == std::string ("yes")) ||
(data == std::string ("true")) ) {
if ( (data == std::string("on")) ||
(data == std::string("yes")) ||
(data == std::string("true")) ) {
value = true;
} else if ( (data == std::string ("off")) ||
(data == std::string ("no")) ||
(data == std::string ("false")) ) {
} else if ( (data == std::string("off")) ||
(data == std::string("no")) ||
(data == std::string("false")) ) {
value = false;
} else
cvm::fatal_error ("Error: boolean values only are allowed "
"for \""+std::string (key)+"\".\n");
cvm::fatal_error("Error: boolean values only are allowed "
"for \""+std::string(key)+"\".\n");
if (parse_mode != parse_silent) {
cvm::log ("# "+std::string (key)+" = "+
(value ? "on" : "off")+"\n");
cvm::log("# "+std::string(key)+" = "+
(value ? "on" : "off")+"\n");
}
} else {
if (b_found_any) {
if (parse_mode != parse_silent) {
cvm::log ("# "+std::string (key)+" = on\n");
cvm::log("# "+std::string(key)+" = on\n");
}
value = true;
} else {
value = def_value;
if (parse_mode != parse_silent) {
cvm::log ("# "+std::string (key)+" = "+
(def_value ? "on" : "off")+" [default]\n");
cvm::log("# "+std::string(key)+" = "+
(def_value ? "on" : "off")+" [default]\n");
}
}
}
@ -301,21 +301,21 @@ bool colvarparse::get_keyval (std::string const &conf,
}
void colvarparse::add_keyword (char const *key)
void colvarparse::add_keyword(char const *key)
{
for (std::list<std::string>::iterator ki = allowed_keywords.begin();
ki != allowed_keywords.end(); ki++) {
if (to_lower_cppstr (std::string (key)) == *ki)
if (to_lower_cppstr(std::string(key)) == *ki)
return;
}
// not found in the list
// if (cvm::debug())
// cvm::log ("Registering a new keyword, \""+std::string (key)+"\".\n");
allowed_keywords.push_back (to_lower_cppstr (std::string (key)));
// cvm::log("Registering a new keyword, \""+std::string (key)+"\".\n");
allowed_keywords.push_back(to_lower_cppstr(std::string(key)));
}
void colvarparse::strip_values (std::string &conf)
void colvarparse::strip_values(std::string &conf)
{
size_t offset = 0;
data_begin_pos.sort();
@ -338,7 +338,7 @@ void colvarparse::strip_values (std::string &conf)
// << std::string (conf, *data_begin - offset, nchars)
// << "\"\n";
conf.erase (*data_begin - offset, nchars);
conf.erase(*data_begin - offset, nchars);
offset += nchars;
// std::cerr << ("Stripped config = \"\n"+conf+"\"\n");
@ -347,31 +347,31 @@ void colvarparse::strip_values (std::string &conf)
}
int colvarparse::check_keywords (std::string &conf, char const *key)
int colvarparse::check_keywords(std::string &conf, char const *key)
{
if (cvm::debug())
cvm::log ("Configuration string for \""+std::string (key)+
"\": \"\n"+conf+"\".\n");
cvm::log("Configuration string for \""+std::string(key)+
"\": \"\n"+conf+"\".\n");
strip_values (conf);
strip_values(conf);
// after stripping, the config string has either empty lines, or
// lines beginning with a keyword
std::string line;
std::istringstream is (conf);
while (std::getline (is, line)) {
std::istringstream is(conf);
while (std::getline(is, line)) {
if (line.size() == 0)
continue;
if (line.find_first_not_of (white_space) ==
if (line.find_first_not_of(white_space) ==
std::string::npos)
continue;
std::string uk;
std::istringstream line_is (line);
std::istringstream line_is(line);
line_is >> uk;
// if (cvm::debug())
// cvm::log ("Checking the validity of \""+uk+"\" from line:\n" + line);
uk = to_lower_cppstr (uk);
uk = to_lower_cppstr(uk);
bool found_keyword = false;
for (std::list<std::string>::iterator ki = allowed_keywords.begin();
@ -382,8 +382,8 @@ int colvarparse::check_keywords (std::string &conf, char const *key)
}
}
if (!found_keyword) {
cvm::log ("Error: keyword \""+uk+"\" is not supported, "
"or not recognized in this context.\n");
cvm::log("Error: keyword \""+uk+"\" is not supported, "
"or not recognized in this context.\n");
cvm::set_error_bits(INPUT_ERROR);
return COLVARS_ERROR;
}
@ -395,33 +395,33 @@ int colvarparse::check_keywords (std::string &conf, char const *key)
}
std::istream & colvarparse::getline_nocomments (std::istream &is,
std::string &line,
char const delim)
std::istream & colvarparse::getline_nocomments(std::istream &is,
std::string &line,
char const delim)
{
std::getline (is, line, delim);
size_t const comment = line.find ('#');
std::getline(is, line, delim);
size_t const comment = line.find('#');
if (comment != std::string::npos) {
line.erase (comment);
line.erase(comment);
}
return is;
}
bool colvarparse::key_lookup (std::string const &conf,
char const *key_in,
std::string &data,
size_t &save_pos)
bool colvarparse::key_lookup(std::string const &conf,
char const *key_in,
std::string &data,
size_t &save_pos)
{
// add this keyword to the register (in its camelCase version)
add_keyword (key_in);
add_keyword(key_in);
// use the lowercase version from now on
std::string const key (to_lower_cppstr (key_in));
std::string const key(to_lower_cppstr(key_in));
// "conf_lower" is only used to lookup the keyword, but its value
// will be read from "conf", in order not to mess up file names
std::string const conf_lower (to_lower_cppstr (conf));
std::string const conf_lower(to_lower_cppstr(conf));
// by default, there is no value, unless we found one
data = "";
@ -431,7 +431,7 @@ bool colvarparse::key_lookup (std::string const &conf,
colvarparse::dummy_pos = 0;
// start from the first occurrence of key
size_t pos = conf_lower.find (key, save_pos);
size_t pos = conf_lower.find(key, save_pos);
// iterate over all instances until it finds the isolated keyword
while (true) {
@ -444,8 +444,8 @@ bool colvarparse::key_lookup (std::string const &conf,
bool b_isolated_left = true, b_isolated_right = true;
if (pos > 0) {
if ( std::string ("\n"+white_space+
"}").find (conf[pos-1]) ==
if ( std::string("\n"+white_space+
"}").find(conf[pos-1]) ==
std::string::npos ) {
// none of the valid delimiting characters is on the left of key
b_isolated_left = false;
@ -453,8 +453,8 @@ bool colvarparse::key_lookup (std::string const &conf,
}
if (pos < conf.size()-key.size()-1) {
if ( std::string ("\n"+white_space+
"{").find (conf[pos+key.size()]) ==
if ( std::string("\n"+white_space+
"{").find(conf[pos+key.size()]) ==
std::string::npos ) {
// none of the valid delimiting characters is on the right of key
b_isolated_right = false;
@ -462,7 +462,7 @@ bool colvarparse::key_lookup (std::string const &conf,
}
// check that there are matching braces between here and the end of conf
bool const b_not_within_block = brace_check (conf, pos);
bool const b_not_within_block = brace_check(conf, pos);
bool const b_isolated = (b_isolated_left && b_isolated_right &&
b_not_within_block);
@ -472,7 +472,7 @@ bool colvarparse::key_lookup (std::string const &conf,
break;
} else {
// try the next occurrence of key
pos = conf_lower.find (key, pos+key.size());
pos = conf_lower.find(key, pos+key.size());
}
}
@ -491,54 +491,54 @@ bool colvarparse::key_lookup (std::string const &conf,
save_pos = pos + key.size();
// get the remainder of the line
size_t pl = conf.rfind ("\n", pos);
size_t pl = conf.rfind("\n", pos);
size_t line_begin = (pl == std::string::npos) ? 0 : pos;
size_t nl = conf.find ("\n", pos);
size_t line_end = (nl == std::string::npos) ? conf.size() : nl;
std::string line (conf, line_begin, (line_end-line_begin));
std::string line(conf, line_begin, (line_end-line_begin));
size_t data_begin = (to_lower_cppstr (line)).find (key) + key.size();
data_begin = line.find_first_not_of (white_space, data_begin+1);
size_t data_begin = (to_lower_cppstr(line)).find(key) + key.size();
data_begin = line.find_first_not_of(white_space, data_begin+1);
// size_t data_begin_absolute = data_begin + line_begin;
// size_t data_end_absolute = data_begin;
if (data_begin != std::string::npos) {
size_t data_end = line.find_last_not_of (white_space) + 1;
size_t data_end = line.find_last_not_of(white_space) + 1;
data_end = (data_end == std::string::npos) ? line.size() : data_end;
// data_end_absolute = data_end + line_begin;
if (line.find ('{', data_begin) != std::string::npos) {
if (line.find('{', data_begin) != std::string::npos) {
size_t brace_count = 1;
size_t brace = line.find ('{', data_begin); // start from the first opening brace
size_t brace = line.find('{', data_begin); // start from the first opening brace
while (brace_count > 0) {
// find the matching closing brace
brace = line.find_first_of ("{}", brace+1);
brace = line.find_first_of("{}", brace+1);
while (brace == std::string::npos) {
// add a new line
if (line_end >= conf.size()) {
cvm::fatal_error ("Parse error: reached the end while "
"looking for closing brace; until now "
"the following was parsed: \"\n"+
line+"\".\n");
cvm::fatal_error("Parse error: reached the end while "
"looking for closing brace; until now "
"the following was parsed: \"\n"+
line+"\".\n");
return false;
}
size_t const old_end = line.size();
// data_end_absolute += old_end+1;
line_begin = line_end;
nl = conf.find ('\n', line_begin+1);
nl = conf.find('\n', line_begin+1);
if (nl == std::string::npos)
line_end = conf.size();
else
line_end = nl;
line.append (conf, line_begin, (line_end-line_begin));
line.append(conf, line_begin, (line_end-line_begin));
brace = line.find_first_of ("{}", old_end);
brace = line.find_first_of("{}", old_end);
}
if (line[brace] == '{') brace_count++;
@ -546,23 +546,23 @@ bool colvarparse::key_lookup (std::string const &conf,
}
// set data_begin after the opening brace
data_begin = line.find_first_of ('{', data_begin) + 1;
data_begin = line.find_first_not_of (white_space,
data_begin);
data_begin = line.find_first_of('{', data_begin) + 1;
data_begin = line.find_first_not_of(white_space,
data_begin);
// set data_end before the closing brace
data_end = brace;
data_end = line.find_last_not_of (white_space+"}",
data_end) + 1;
data_end = line.find_last_not_of(white_space+"}",
data_end) + 1;
// data_end_absolute = line_end;
if (data_end > line.size())
data_end = line.size();
}
data.append (line, data_begin, (data_end-data_begin));
data.append(line, data_begin, (data_end-data_begin));
if (data.size() && save_delimiters) {
data_begin_pos.push_back (conf.find (data, pos+key.size()));
data_begin_pos.push_back(conf.find(data, pos+key.size()));
data_end_pos.push_back (data_begin_pos.back()+data.size());
// std::cerr << "key = " << key << ", data = \""
// << data << "\", data_begin, data_end = "
@ -587,8 +587,8 @@ std::istream & operator>> (std::istream &is, colvarparse::read_block const &rb)
// the requested keyword has not been found, or it is not possible
// to read data after it
is.clear();
is.seekg (start_pos, std::ios::beg);
is.setstate (std::ios::failbit);
is.seekg(start_pos, std::ios::beg);
is.setstate(std::ios::failbit);
return is;
}
@ -599,17 +599,17 @@ std::istream & operator>> (std::istream &is, colvarparse::read_block const &rb)
size_t brace_count = 1;
std::string line;
while (colvarparse::getline_nocomments (is, line)) {
while (colvarparse::getline_nocomments(is, line)) {
size_t br = 0, br_old = 0;
while ( (br = line.find_first_of ("{}", br)) != std::string::npos) {
while ( (br = line.find_first_of("{}", br)) != std::string::npos) {
if (line[br] == '{') brace_count++;
if (line[br] == '}') brace_count--;
br_old = br;
br++;
}
if (brace_count) (*rb.data).append (line + "\n");
if (brace_count) (*rb.data).append(line + "\n");
else {
(*rb.data).append (line, 0, br_old);
(*rb.data).append(line, 0, br_old);
break;
}
}
@ -617,19 +617,19 @@ std::istream & operator>> (std::istream &is, colvarparse::read_block const &rb)
// end-of-file reached
// restore initial position
is.clear();
is.seekg (start_pos, std::ios::beg);
is.setstate (std::ios::failbit);
is.seekg(start_pos, std::ios::beg);
is.setstate(std::ios::failbit);
}
return is;
}
bool colvarparse::brace_check (std::string const &conf,
size_t const start_pos)
bool colvarparse::brace_check(std::string const &conf,
size_t const start_pos)
{
size_t brace_count = 0;
size_t brace = start_pos;
while ( (brace = conf.find_first_of ("{}", brace)) != std::string::npos) {
while ( (brace = conf.find_first_of("{}", brace)) != std::string::npos) {
if (conf[brace] == '{') brace_count++;
if (conf[brace] == '}') brace_count--;
brace++;

View File

@ -43,20 +43,20 @@ protected:
bool save_delimiters;
/// \brief Add a new valid keyword to the list
void add_keyword (char const *key);
void add_keyword(char const *key);
/// \brief Remove all the values from the config string
void strip_values (std::string &conf);
void strip_values(std::string &conf);
public:
inline colvarparse()
: save_delimiters (true)
: save_delimiters(true)
{}
/// How a keyword is parsed in a string
enum Parse_Mode {
/// \brief (default) Read the first instance of a keyword (if
/// \brief(default) Read the first instance of a keyword (if
/// any), report its value, and print a warning when there is more
/// than one
parse_normal,
@ -92,50 +92,50 @@ public:
/// wrapper class (colvarvalue.h).
#define _get_keyval_scalar_proto_(_type_,_def_value_) \
bool get_keyval (std::string const &conf, \
bool get_keyval(std::string const &conf, \
char const *key, \
_type_ &value, \
_type_ const &def_value = _def_value_, \
Parse_Mode const parse_mode = parse_normal)
_get_keyval_scalar_proto_ (int, (int)0);
_get_keyval_scalar_proto_ (size_t, (size_t)0);
_get_keyval_scalar_proto_ (std::string, std::string (""));
_get_keyval_scalar_proto_ (cvm::real, (cvm::real)0.0);
_get_keyval_scalar_proto_ (cvm::rvector, cvm::rvector());
_get_keyval_scalar_proto_ (cvm::quaternion, cvm::quaternion());
_get_keyval_scalar_proto_ (colvarvalue, colvarvalue (colvarvalue::type_notset));
_get_keyval_scalar_proto_ (bool, false);
_get_keyval_scalar_proto_(int, (int)0);
_get_keyval_scalar_proto_(size_t, (size_t)0);
_get_keyval_scalar_proto_(std::string, std::string(""));
_get_keyval_scalar_proto_(cvm::real, (cvm::real)0.0);
_get_keyval_scalar_proto_(cvm::rvector, cvm::rvector());
_get_keyval_scalar_proto_(cvm::quaternion, cvm::quaternion());
_get_keyval_scalar_proto_(colvarvalue, colvarvalue(colvarvalue::type_notset));
_get_keyval_scalar_proto_(bool, false);
#define _get_keyval_vector_proto_(_type_,_def_value_) \
bool get_keyval (std::string const &conf, \
bool get_keyval(std::string const &conf, \
char const *key, \
std::vector<_type_> &values, \
std::vector<_type_> const &def_values = \
std::vector<_type_> (0, static_cast<_type_>(_def_value_)), \
Parse_Mode const parse_mode = parse_normal)
_get_keyval_vector_proto_ (int, 0);
_get_keyval_vector_proto_ (size_t, 0);
_get_keyval_vector_proto_ (std::string, std::string (""));
_get_keyval_vector_proto_ (cvm::real, 0.0);
_get_keyval_vector_proto_ (cvm::rvector, cvm::rvector());
_get_keyval_vector_proto_ (cvm::quaternion, cvm::quaternion());
_get_keyval_vector_proto_ (colvarvalue, colvarvalue (colvarvalue::type_notset));
_get_keyval_vector_proto_(int, 0);
_get_keyval_vector_proto_(size_t, 0);
_get_keyval_vector_proto_(std::string, std::string(""));
_get_keyval_vector_proto_(cvm::real, 0.0);
_get_keyval_vector_proto_(cvm::rvector, cvm::rvector());
_get_keyval_vector_proto_(cvm::quaternion, cvm::quaternion());
_get_keyval_vector_proto_(colvarvalue, colvarvalue(colvarvalue::type_notset));
/// \brief Check that all the keywords within "conf" are in the list
/// of allowed keywords; this will invoke strip_values() first and
/// then loop over all words
int check_keywords (std::string &conf, char const *key);
int check_keywords(std::string &conf, char const *key);
/// \brief Return a lowercased copy of the string
static inline std::string to_lower_cppstr (std::string const &in)
static inline std::string to_lower_cppstr(std::string const &in)
{
std::string out = "";
for (size_t i = 0; i < in.size(); i++) {
out.append (1, (char) ::tolower (in[i]) );
out.append(1, (char) ::tolower(in[i]) );
}
return out;
}
@ -153,8 +153,8 @@ public:
std::string * const data;
public:
inline read_block (std::string const &key_in, std::string &data_in)
: key (key_in), data (&data_in)
inline read_block(std::string const &key_in, std::string &data_in)
: key(key_in), data(&data_in)
{}
inline ~read_block() {}
friend std::istream & operator >> (std::istream &is, read_block const &rb);
@ -172,7 +172,7 @@ public:
/// \param save_pos (optional) stores the position of the keyword
/// within "conf", useful when doing multiple calls \param
/// save_delimiters (optional)
bool key_lookup (std::string const &conf,
bool key_lookup(std::string const &conf,
char const *key,
std::string &data = dummy_string,
size_t &save_pos = dummy_pos);
@ -184,12 +184,12 @@ public:
/// \brief Works as std::getline() but also removes everything
/// between a comment character and the following newline
static std::istream & getline_nocomments (std::istream &is,
static std::istream & getline_nocomments(std::istream &is,
std::string &s,
char const delim = '\n');
/// Check if the content of the file has matching braces
bool brace_check (std::string const &conf,
bool brace_check(std::string const &conf,
size_t const start_pos = 0);
};

View File

@ -4,18 +4,11 @@
#define COLVARPROXY_H
#ifndef COLVARPROXY_VERSION
#define COLVARPROXY_VERSION "2014-10-21"
#endif
#include "colvarmodule.h"
#include "colvarvalue.h"
// return values for the frame() routine
#define COLVARS_NO_SUCH_FRAME -1
#define COLVARS_NOT_IMPLEMENTED -2
// forward declarations
class colvarscript;
@ -33,7 +26,7 @@ public:
colvarmodule *colvars;
/// Default constructor
inline colvarproxy() : script (NULL) {}
inline colvarproxy() : script(NULL) {}
/// Default destructor
virtual inline ~colvarproxy() {}
@ -58,14 +51,14 @@ public:
virtual cvm::real dt() = 0;
/// \brief Pseudo-random number with Gaussian distribution
virtual cvm::real rand_gaussian (void) = 0;
virtual cvm::real rand_gaussian(void) = 0;
/// \brief Get the current frame number
virtual int frame() { return COLVARS_NOT_IMPLEMENTED; }
/// \brief Set the current frame number
// return 0 on success, -1 on failure
virtual int frame (int) { return COLVARS_NOT_IMPLEMENTED; }
virtual int frame(int) { return COLVARS_NOT_IMPLEMENTED; }
// Replica exchange commands:
@ -124,35 +117,35 @@ public:
// **************** ACCESS ATOMIC DATA ****************
/// Pass restraint energy value for current timestep to MD engine
virtual void add_energy (cvm::real energy) = 0;
virtual void add_energy(cvm::real energy) = 0;
/// Tell the proxy whether system forces are needed (may not always be available)
virtual void request_system_force (bool yesno) = 0;
virtual void request_system_force(bool yesno) = 0;
// **************** PERIODIC BOUNDARY CONDITIONS ****************
/// \brief Get the PBC-aware distance vector between two positions
virtual cvm::rvector position_distance (cvm::atom_pos const &pos1,
virtual cvm::rvector position_distance(cvm::atom_pos const &pos1,
cvm::atom_pos const &pos2) = 0;
/// \brief Get the PBC-aware square distance between two positions;
/// may be implemented independently from position_distance() for optimization purposes
virtual cvm::real position_dist2 (cvm::atom_pos const &pos1,
virtual cvm::real position_dist2(cvm::atom_pos const &pos1,
cvm::atom_pos const &pos2);
/// \brief Get the closest periodic image to a reference position
/// \param pos The position to look for the closest periodic image
/// \param ref_pos The reference position
virtual void select_closest_image (cvm::atom_pos &pos,
virtual void select_closest_image(cvm::atom_pos &pos,
cvm::atom_pos const &ref_pos) = 0;
/// \brief Perform select_closest_image() on a set of atomic positions
///
/// After that, distance vectors can then be calculated directly,
/// without using position_distance()
void select_closest_images (std::vector<cvm::atom_pos> &pos,
void select_closest_images(std::vector<cvm::atom_pos> &pos,
cvm::atom_pos const &ref_pos);
// **************** SCRIPTING INTERFACE ****************
@ -177,29 +170,29 @@ public:
virtual int run_colvar_gradient_callback(std::string const &name,
std::vector<const colvarvalue *> const &cvcs,
std::vector<colvarvalue> &gradient)
std::vector<cvm::matrix2d<cvm::real> > &gradient)
{ return COLVARS_NOT_IMPLEMENTED; }
// **************** INPUT/OUTPUT ****************
/// Print a message to the main log
virtual void log (std::string const &message) = 0;
virtual void log(std::string const &message) = 0;
/// Print a message to the main log and let the rest of the program handle the error
virtual void error (std::string const &message) = 0;
virtual void error(std::string const &message) = 0;
/// Print a message to the main log and exit with error code
virtual void fatal_error (std::string const &message) = 0;
virtual void fatal_error(std::string const &message) = 0;
/// Print a message to the main log and exit normally
virtual void exit (std::string const &message) = 0;
virtual void exit(std::string const &message) = 0;
/// \brief Read atom identifiers from a file \param filename name of
/// the file (usually a PDB) \param atoms array to which atoms read
/// from "filename" will be appended \param pdb_field (optiona) if
/// "filename" is a PDB file, use this field to determine which are
/// the atoms to be set
virtual int load_atoms (char const *filename,
virtual int load_atoms(char const *filename,
std::vector<cvm::atom> &atoms,
std::string const &pdb_field,
double const pdb_field_value = 0.0) = 0;
@ -207,31 +200,31 @@ public:
/// \brief Load the coordinates for a group of atoms from a file
/// (usually a PDB); if "pos" is already allocated, the number of its
/// elements must match the number of atoms in "filename"
virtual int load_coords (char const *filename,
virtual int load_coords(char const *filename,
std::vector<cvm::atom_pos> &pos,
const std::vector<int> &indices,
std::string const &pdb_field,
double const pdb_field_value = 0.0) = 0;
/// \brief Rename the given file, before overwriting it
virtual int backup_file (char const *filename)
virtual int backup_file(char const *filename)
{ return COLVARS_NOT_IMPLEMENTED; }
};
inline void colvarproxy::select_closest_images (std::vector<cvm::atom_pos> &pos,
inline void colvarproxy::select_closest_images(std::vector<cvm::atom_pos> &pos,
cvm::atom_pos const &ref_pos)
{
for (std::vector<cvm::atom_pos>::iterator pi = pos.begin();
pi != pos.end(); ++pi) {
select_closest_image (*pi, ref_pos);
select_closest_image(*pi, ref_pos);
}
}
inline cvm::real colvarproxy::position_dist2 (cvm::atom_pos const &pos1,
inline cvm::real colvarproxy::position_dist2(cvm::atom_pos const &pos1,
cvm::atom_pos const &pos2)
{
return (position_distance (pos1, pos2)).norm2();
return (position_distance(pos1, pos2)).norm2();
}
#endif

View File

@ -1,28 +1,31 @@
// -*- c++ -*-
#include <cstdlib>
#include <stdlib.h>
#include <string.h>
#include "colvarscript.h"
colvarscript::colvarscript (colvarproxy *p)
: proxy (p),
colvars (p->colvars),
proxy_error (0)
colvarscript::colvarscript(colvarproxy *p)
: proxy(p),
colvars(p->colvars),
proxy_error(0)
{
}
/// Run method based on given arguments
int colvarscript::run (int argc, char const *argv[]) {
int colvarscript::run(int argc, char const *argv[]) {
result = "";
if (cvm::debug()) {
cvm::log ("Called script run with " + cvm::to_str(argc) + " args");
for (int i = 0; i < argc; i++) { cvm::log (argv[i]); }
cvm::log("Called script run with " + cvm::to_str(argc) + " args");
for (int i = 0; i < argc; i++) { cvm::log(argv[i]); }
}
if (argc < 2) {
result = "usage: "+std::string (argv[0])+" <subcommand> [args...]\n\
result = "usage: "+std::string(argv[0])+" <subcommand> [args...]\n\
\n\
Managing the colvars module:\n\
configfile <file name> -- read configuration from a file\n\
@ -63,11 +66,11 @@ Accessing biases:\n\
std::string cmd = argv[1];
if (cmd == "colvar") {
return proc_colvar (argc-1, &(argv[1]));
return proc_colvar(argc-1, &(argv[1]));
}
if (cmd == "bias") {
return proc_bias (argc-1, &(argv[1]));
return proc_bias(argc-1, &(argv[1]));
}
if (cmd == "reset") {
@ -116,7 +119,7 @@ Accessing biases:\n\
result = "Missing arguments";
return COLVARSCRIPT_ERROR;
}
if (colvars->config_file (argv[2]) == COLVARS_OK) {
if (colvars->config_file(argv[2]) == COLVARS_OK) {
return COLVARSCRIPT_OK;
} else {
return COLVARSCRIPT_ERROR;
@ -130,7 +133,7 @@ Accessing biases:\n\
return COLVARSCRIPT_ERROR;
}
std::string conf = argv[2];
if (colvars->config_string (conf) == COLVARS_OK) {
if (colvars->config_string(conf) == COLVARS_OK) {
return COLVARSCRIPT_OK;
} else {
return COLVARSCRIPT_ERROR;
@ -156,13 +159,13 @@ Accessing biases:\n\
/// Print the values that would go on colvars.traj
if (cmd == "printframelabels") {
std::ostringstream os;
colvars->write_traj_label (os);
colvars->write_traj_label(os);
result = os.str();
return COLVARSCRIPT_OK;
}
if (cmd == "printframe") {
std::ostringstream os;
colvars->write_traj (os);
colvars->write_traj(os);
result = os.str();
return COLVARSCRIPT_OK;
}
@ -171,7 +174,7 @@ Accessing biases:\n\
if (argc == 2) {
int f = proxy->frame();
if (f >= 0) {
result = cvm::to_str (f);
result = cvm::to_str(f);
return COLVARSCRIPT_OK;
} else {
result = "Frame number is not available";
@ -182,7 +185,7 @@ Accessing biases:\n\
// returns the plain result to let scripts detect available frames
long int f = proxy->frame(strtol(argv[2], NULL, 10));
colvars->it = proxy->frame();
result = cvm::to_str (f);
result = cvm::to_str(f);
return COLVARSCRIPT_OK;
} else {
result = "Wrong arguments to command \"frame\"";
@ -195,9 +198,9 @@ Accessing biases:\n\
}
int colvarscript::proc_colvar (int argc, char const *argv[]) {
int colvarscript::proc_colvar(int argc, char const *argv[]) {
std::string name = argv[1];
colvar *cv = cvm::colvar_by_name (name);
colvar *cv = cvm::colvar_by_name(name);
if (cv == NULL) {
result = "Colvar not found: " + name;
return COLVARSCRIPT_ERROR;
@ -209,14 +212,19 @@ int colvarscript::proc_colvar (int argc, char const *argv[]) {
std::string subcmd = argv[2];
if (subcmd == "value") {
result = cvm::to_str(cv->value(), 0, cvm::cv_prec);
result = (cv->value()).to_simple_string();
return COLVARSCRIPT_OK;
}
if (subcmd == "width") {
result = cvm::to_str(cv->width, 0, cvm::cv_prec);
return COLVARSCRIPT_OK;
}
if (subcmd == "update") {
cv->calc();
cv->update();
result = cvm::to_str(cv->value(), 0, cvm::cv_prec);
result = (cv->value()).to_simple_string();
return COLVARSCRIPT_OK;
}
@ -228,27 +236,27 @@ int colvarscript::proc_colvar (int argc, char const *argv[]) {
// colvar destructor is tasked with the cleanup
delete cv;
// TODO this could be done by the destructors
colvars->write_traj_label (colvars->cv_traj_os);
colvars->write_traj_label(colvars->cv_traj_os);
return COLVARSCRIPT_OK;
}
if (subcmd == "addforce") {
if (argc < 4) {
result = "Missing parameter: force value";
result = "addforce: missing parameter: force value";
return COLVARSCRIPT_ERROR;
}
std::string f_str = argv[3];
std::istringstream is (f_str);
std::istringstream is(f_str);
is.width(cvm::cv_width);
is.precision(cvm::cv_prec);
colvarvalue force (cv->type());
colvarvalue force(cv->value());
force.is_derivative();
if (!(is >> force)) {
result = "Error parsing force value";
if (force.from_simple_string(is.str()) != COLVARS_OK) {
result = "addforce : error parsing force value";
return COLVARSCRIPT_ERROR;
}
cv->add_bias_force(force);
result = cvm::to_str(force, cvm::cv_width, cvm::cv_prec);
result = force.to_simple_string();
return COLVARSCRIPT_OK;
}
@ -257,9 +265,9 @@ int colvarscript::proc_colvar (int argc, char const *argv[]) {
}
int colvarscript::proc_bias (int argc, char const *argv[]) {
int colvarscript::proc_bias(int argc, char const *argv[]) {
std::string name = argv[1];
colvarbias *b = cvm::bias_by_name (name);
colvarbias *b = cvm::bias_by_name(name);
if (b == NULL) {
result = "Bias not found: " + name;
return COLVARSCRIPT_ERROR;
@ -282,16 +290,53 @@ int colvarscript::proc_bias (int argc, char const *argv[]) {
return COLVARSCRIPT_OK;
}
// Subcommands for MW ABF
if (subcmd == "bin") {
int r = b->current_bin();
result = cvm::to_str(r);
return COLVARSCRIPT_OK;
}
if (subcmd == "binnum") {
int r = b->bin_num();
if (r < 0) {
result = "Error: calling bin_num() for bias " + b->name;
return COLVARSCRIPT_ERROR;
}
result = cvm::to_str(r);
return COLVARSCRIPT_OK;
}
if (subcmd == "share") {
int r = b->replica_share();
if (r < 0) {
result = "Error: calling replica_share() for bias " + b->name;
return COLVARSCRIPT_ERROR;
}
result = cvm::to_str(r);
return COLVARSCRIPT_OK;
}
// End commands for MW ABF
if (subcmd == "delete") {
// the bias destructor takes care of the cleanup at cvm level
delete b;
// TODO this could be done by the destructors
colvars->write_traj_label (colvars->cv_traj_os);
colvars->write_traj_label(colvars->cv_traj_os);
return COLVARSCRIPT_OK;
}
if (argc >= 4) {
// std::string param = argv[3];
std::string param = argv[3];
if (subcmd == "count") {
int index;
if (!(std::istringstream(param) >> index)) {
result = "bin_count: error parsing bin index";
return COLVARSCRIPT_ERROR;
}
result = cvm::to_str(b->bin_count(index));
return COLVARSCRIPT_OK;
}
result = "Syntax error";
return COLVARSCRIPT_ERROR;

View File

@ -34,13 +34,13 @@ public:
std::string result;
/// Run script command with given positional arguments
int run (int argc, char const *argv[]);
int run(int argc, char const *argv[]);
/// Run subcommands on colvar
int proc_colvar (int argc, char const *argv[]);
int proc_colvar(int argc, char const *argv[]);
/// Run subcommands on bias
int proc_bias (int argc, char const *argv[]);
int proc_bias(int argc, char const *argv[]);
};

View File

@ -1,22 +1,47 @@
/// -*- c++ -*-
// -*- c++ -*-
#include <stdlib.h>
#include <string.h>
#include "colvarmodule.h"
#include "colvartypes.h"
#include "colvarparse.h"
std::string cvm::rvector::to_simple_string() const
{
std::ostringstream os;
os.setf(std::ios::scientific, std::ios::floatfield);
os.precision(cvm::cv_prec);
os << x << " " << y << " " << z;
return os.str();
}
int cvm::rvector::from_simple_string(std::string const &s)
{
std::stringstream stream(s);
if ( !(stream >> x) ||
!(stream >> y) ||
!(stream >> z) ) {
return COLVARS_ERROR;
}
return COLVARS_OK;
}
std::ostream & operator << (std::ostream &os, colvarmodule::rvector const &v)
{
std::streamsize const w = os.width();
std::streamsize const p = os.precision();
os.width (2);
os.width(2);
os << "( ";
os.width (w); os.precision (p);
os.width(w); os.precision(p);
os << v.x << " , ";
os.width (w); os.precision (p);
os.width(w); os.precision(p);
os << v.y << " , ";
os.width (w); os.precision (p);
os.width(w); os.precision(p);
os << v.z << " )";
return os;
}
@ -31,29 +56,48 @@ std::istream & operator >> (std::istream &is, colvarmodule::rvector &v)
!(is >> v.y) || !(is >> sep) || !(sep == ',') ||
!(is >> v.z) || !(is >> sep) || !(sep == ')') ) {
is.clear();
is.seekg (start_pos, std::ios::beg);
is.setstate (std::ios::failbit);
is.seekg(start_pos, std::ios::beg);
is.setstate(std::ios::failbit);
return is;
}
return is;
}
std::string cvm::quaternion::to_simple_string() const
{
std::ostringstream os;
os.setf(std::ios::scientific, std::ios::floatfield);
os.precision(cvm::cv_prec);
os << q0 << " " << q1 << " " << q2 << " " << q3;
return os.str();
}
int cvm::quaternion::from_simple_string(std::string const &s)
{
std::stringstream stream(s);
if ( !(stream >> q0) ||
!(stream >> q1) ||
!(stream >> q2) ||
!(stream >> q3) ) {
return COLVARS_ERROR;
}
return COLVARS_OK;
}
std::ostream & operator << (std::ostream &os, colvarmodule::quaternion const &q)
{
std::streamsize const w = os.width();
std::streamsize const p = os.precision();
os.width (2);
os.width(2);
os << "( ";
os.width (w); os.precision (p);
os.width(w); os.precision(p);
os << q.q0 << " , ";
os.width (w); os.precision (p);
os.width(w); os.precision(p);
os << q.q1 << " , ";
os.width (w); os.precision (p);
os.width(w); os.precision(p);
os << q.q2 << " , ";
os.width (w); os.precision (p);
os.width(w); os.precision(p);
os << q.q3 << " )";
return os;
}
@ -63,10 +107,10 @@ std::istream & operator >> (std::istream &is, colvarmodule::quaternion &q)
{
size_t const start_pos = is.tellg();
std::string euler ("");
std::string euler("");
if ( (is >> euler) && (colvarparse::to_lower_cppstr (euler) ==
std::string ("euler")) ) {
if ( (is >> euler) && (colvarparse::to_lower_cppstr(euler) ==
std::string("euler")) ) {
// parse the Euler angles
@ -77,18 +121,18 @@ std::istream & operator >> (std::istream &is, colvarmodule::quaternion &q)
!(is >> theta) || !(is >> sep) || !(sep == ',') ||
!(is >> psi) || !(is >> sep) || !(sep == ')') ) {
is.clear();
is.seekg (start_pos, std::ios::beg);
is.setstate (std::ios::failbit);
is.seekg(start_pos, std::ios::beg);
is.setstate(std::ios::failbit);
return is;
}
q = colvarmodule::quaternion (phi, theta, psi);
q = colvarmodule::quaternion(phi, theta, psi);
} else {
// parse the quaternion components
is.seekg (start_pos, std::ios::beg);
is.seekg(start_pos, std::ios::beg);
char sep;
if ( !(is >> sep) || !(sep == '(') ||
!(is >> q.q0) || !(is >> sep) || !(sep == ',') ||
@ -96,8 +140,8 @@ std::istream & operator >> (std::istream &is, colvarmodule::quaternion &q)
!(is >> q.q2) || !(is >> sep) || !(sep == ',') ||
!(is >> q.q3) || !(is >> sep) || !(sep == ')') ) {
is.clear();
is.seekg (start_pos, std::ios::beg);
is.setstate (std::ios::failbit);
is.seekg(start_pos, std::ios::beg);
is.setstate(std::ios::failbit);
return is;
}
}
@ -107,10 +151,10 @@ std::istream & operator >> (std::istream &is, colvarmodule::quaternion &q)
cvm::quaternion
cvm::quaternion::position_derivative_inner (cvm::rvector const &pos,
cvm::quaternion::position_derivative_inner(cvm::rvector const &pos,
cvm::rvector const &vec) const
{
cvm::quaternion result (0.0, 0.0, 0.0, 0.0);
cvm::quaternion result(0.0, 0.0, 0.0, 0.0);
result.q0 = 2.0 * pos.x * q0 * vec.x
@ -174,22 +218,20 @@ cvm::quaternion::position_derivative_inner (cvm::rvector const &pos,
// Calculate the optimal rotation between two groups, and implement it
// as a quaternion. Uses the method documented in: Coutsias EA,
// Seok C, Dill KA. Using quaternions to calculate RMSD. J Comput
// Chem. 25(15):1849-57 (2004) DOI: 10.1002/jcc.20110 PubMed: 15376254
void colvarmodule::rotation::build_matrix (std::vector<cvm::atom_pos> const &pos1,
std::vector<cvm::atom_pos> const &pos2,
matrix2d<cvm::real, 4, 4> &S)
void colvarmodule::rotation::build_matrix(std::vector<cvm::atom_pos> const &pos1,
std::vector<cvm::atom_pos> const &pos2,
cvm::matrix2d<cvm::real> &S)
{
cvm::rmatrix C;
// build the correlation matrix
C.resize(3, 3);
C.reset();
for (size_t i = 0; i < pos1.size(); i++) {
size_t i;
for (i = 0; i < pos1.size(); i++) {
C.xx() += pos1[i].x * pos2[i].x;
C.xy() += pos1[i].x * pos2[i].y;
C.xz() += pos1[i].x * pos2[i].z;
@ -219,120 +261,101 @@ void colvarmodule::rotation::build_matrix (std::vector<cvm::atom_pos> const &pos
S[3][2] = C.yz() + C.zy();
S[2][3] = S[3][2];
S[3][3] = - C.xx() - C.yy() + C.zz();
// if (cvm::debug()) {
// for (size_t i = 0; i < 4; i++) {
// std::string line ("");
// for (size_t j = 0; j < 4; j++) {
// line += std::string (" S["+cvm::to_str (i)+
// "]["+cvm::to_str (j)+"] ="+cvm::to_str (S[i][j]));
// }
// cvm::log (line+"\n");
// }
// }
}
void colvarmodule::rotation::diagonalize_matrix (matrix2d<cvm::real, 4, 4> &S,
cvm::real S_eigval[4],
matrix2d<cvm::real, 4, 4> &S_eigvec)
void colvarmodule::rotation::diagonalize_matrix(cvm::matrix2d<cvm::real> &S,
cvm::vector1d<cvm::real> &S_eigval,
cvm::matrix2d<cvm::real> &S_eigvec)
{
S_eigval.resize(4);
S_eigval.reset();
S_eigvec.resize(4,4);
S_eigvec.reset();
// diagonalize
int jac_nrot = 0;
jacobi (S, S_eigval, S_eigvec, &jac_nrot);
eigsrt (S_eigval, S_eigvec);
jacobi(S.c_array(), S_eigval.c_array(), S_eigvec.c_array(), &jac_nrot);
eigsrt(S_eigval.c_array(), S_eigvec.c_array());
// jacobi saves eigenvectors by columns
transpose (S_eigvec);
transpose(S_eigvec.c_array());
// normalize eigenvectors
for (size_t ie = 0; ie < 4; ie++) {
cvm::real norm2 = 0.0;
size_t i;
for (i = 0; i < 4; i++) norm2 += std::pow (S_eigvec[ie][i], int (2));
cvm::real const norm = std::sqrt (norm2);
for (i = 0; i < 4; i++) S_eigvec[ie][i] /= norm;
for (i = 0; i < 4; i++) {
norm2 += std::pow(S_eigvec[ie][i], int(2));
}
cvm::real const norm = std::sqrt(norm2);
for (i = 0; i < 4; i++) {
S_eigvec[ie][i] /= norm;
}
}
}
// Calculate the rotation, plus its derivatives
void colvarmodule::rotation::calc_optimal_rotation
(std::vector<cvm::atom_pos> const &pos1,
std::vector<cvm::atom_pos> const &pos2)
void colvarmodule::rotation::calc_optimal_rotation(std::vector<cvm::atom_pos> const &pos1,
std::vector<cvm::atom_pos> const &pos2)
{
matrix2d<cvm::real, 4, 4> S;
matrix2d<cvm::real, 4, 4> S_backup;
cvm::real S_eigval[4];
matrix2d<cvm::real, 4, 4> S_eigvec;
S.resize(4,4);
S.reset();
// if (cvm::debug()) {
// cvm::atom_pos cog1 (0.0, 0.0, 0.0);
// for (size_t i = 0; i < pos1.size(); i++) {
// cog1 += pos1[i];
// }
// cog1 /= cvm::real (pos1.size());
// cvm::atom_pos cog2 (0.0, 0.0, 0.0);
// for (size_t i = 0; i < pos2.size(); i++) {
// cog2 += pos2[i];
// }
// cog2 /= cvm::real (pos1.size());
// cvm::log ("calc_optimal_rotation: centers of geometry are: "+
// cvm::to_str (cog1, cvm::cv_width, cvm::cv_prec)+
// " and "+cvm::to_str (cog2, cvm::cv_width, cvm::cv_prec)+".\n");
// }
build_matrix(pos1, pos2, S);
build_matrix (pos1, pos2, S);
S_backup.resize(4,4);
S_backup = S;
if (cvm::debug()) {
if (b_debug_gradients) {
cvm::log ("S = "+cvm::to_str (cvm::to_str (S_backup), cvm::cv_width, cvm::cv_prec)+"\n");
cvm::log("S = "+cvm::to_str(cvm::to_str(S_backup), cvm::cv_width, cvm::cv_prec)+"\n");
}
}
diagonalize_matrix (S, S_eigval, S_eigvec);
diagonalize_matrix(S, S_eigval, S_eigvec);
// eigenvalues and eigenvectors
cvm::real const &L0 = S_eigval[0];
cvm::real const &L1 = S_eigval[1];
cvm::real const &L2 = S_eigval[2];
cvm::real const &L3 = S_eigval[3];
cvm::real const *Q0 = S_eigvec[0];
cvm::real const *Q1 = S_eigvec[1];
cvm::real const *Q2 = S_eigvec[2];
cvm::real const *Q3 = S_eigvec[3];
cvm::real const L0 = S_eigval[0];
cvm::real const L1 = S_eigval[1];
cvm::real const L2 = S_eigval[2];
cvm::real const L3 = S_eigval[3];
cvm::quaternion const Q0(S_eigvec[0]);
cvm::quaternion const Q1(S_eigvec[1]);
cvm::quaternion const Q2(S_eigvec[2]);
cvm::quaternion const Q3(S_eigvec[3]);
lambda = L0;
q = cvm::quaternion (Q0);
q = Q0;
if (q_old.norm2() > 0.0) {
q.match (q_old);
if (q_old.inner (q) < (1.0 - crossing_threshold)) {
cvm::log ("Warning: one molecular orientation has changed by more than "+
cvm::to_str (crossing_threshold)+": discontinuous rotation ?\n");
q.match(q_old);
if (q_old.inner(q) < (1.0 - crossing_threshold)) {
cvm::log("Warning: one molecular orientation has changed by more than "+
cvm::to_str(crossing_threshold)+": discontinuous rotation ?\n");
}
}
q_old = q;
if (cvm::debug()) {
if (b_debug_gradients) {
cvm::log ("L0 = "+cvm::to_str (L0, cvm::cv_width, cvm::cv_prec)+
", Q0 = "+cvm::to_str (cvm::quaternion (Q0), cvm::cv_width, cvm::cv_prec)+
", Q0*Q0 = "+cvm::to_str (cvm::quaternion (Q0).inner (cvm::quaternion (Q0)), cvm::cv_width, cvm::cv_prec)+
"\n");
cvm::log ("L1 = "+cvm::to_str (L1, cvm::cv_width, cvm::cv_prec)+
", Q1 = "+cvm::to_str (cvm::quaternion (Q1), cvm::cv_width, cvm::cv_prec)+
", Q0*Q1 = "+cvm::to_str (cvm::quaternion (Q0).inner (cvm::quaternion (Q1)), cvm::cv_width, cvm::cv_prec)+
"\n");
cvm::log ("L2 = "+cvm::to_str (L2, cvm::cv_width, cvm::cv_prec)+
", Q2 = "+cvm::to_str (cvm::quaternion (Q2), cvm::cv_width, cvm::cv_prec)+
", Q0*Q2 = "+cvm::to_str (cvm::quaternion (Q0).inner (cvm::quaternion (Q2)), cvm::cv_width, cvm::cv_prec)+
"\n");
cvm::log ("L3 = "+cvm::to_str (L3, cvm::cv_width, cvm::cv_prec)+
", Q3 = "+cvm::to_str (cvm::quaternion (Q3), cvm::cv_width, cvm::cv_prec)+
", Q0*Q3 = "+cvm::to_str (cvm::quaternion (Q0).inner (cvm::quaternion (Q3)), cvm::cv_width, cvm::cv_prec)+
"\n");
cvm::log("L0 = "+cvm::to_str(L0, cvm::cv_width, cvm::cv_prec)+
", Q0 = "+cvm::to_str(Q0, cvm::cv_width, cvm::cv_prec)+
", Q0*Q0 = "+cvm::to_str(Q0.inner(Q0), cvm::cv_width, cvm::cv_prec)+
"\n");
cvm::log("L1 = "+cvm::to_str(L1, cvm::cv_width, cvm::cv_prec)+
", Q1 = "+cvm::to_str(Q1, cvm::cv_width, cvm::cv_prec)+
", Q0*Q1 = "+cvm::to_str(Q0.inner(Q1), cvm::cv_width, cvm::cv_prec)+
"\n");
cvm::log("L2 = "+cvm::to_str(L2, cvm::cv_width, cvm::cv_prec)+
", Q2 = "+cvm::to_str(Q2, cvm::cv_width, cvm::cv_prec)+
", Q0*Q2 = "+cvm::to_str(Q0.inner(Q2), cvm::cv_width, cvm::cv_prec)+
"\n");
cvm::log("L3 = "+cvm::to_str(L3, cvm::cv_width, cvm::cv_prec)+
", Q3 = "+cvm::to_str(Q3, cvm::cv_width, cvm::cv_prec)+
", Q0*Q3 = "+cvm::to_str(Q0.inner(Q3), cvm::cv_width, cvm::cv_prec)+
"\n");
}
}
@ -346,7 +369,7 @@ void colvarmodule::rotation::calc_optimal_rotation
cvm::real const &a2y = pos2[ia].y;
cvm::real const &a2z = pos2[ia].z;
matrix2d<cvm::rvector, 4, 4> &ds_1 = dS_1[ia];
cvm::matrix2d<cvm::rvector> &ds_1 = dS_1[ia];
// derivative of the S matrix
ds_1.reset();
@ -367,8 +390,8 @@ void colvarmodule::rotation::calc_optimal_rotation
ds_1[2][3] = ds_1[3][2];
ds_1[3][3].set(-a2x, -a2y, a2z);
cvm::rvector &dl0_1 = dL0_1[ia];
vector1d<cvm::rvector, 4> &dq0_1 = dQ0_1[ia];
cvm::rvector &dl0_1 = dL0_1[ia];
cvm::vector1d<cvm::rvector> &dq0_1 = dQ0_1[ia];
// matrix multiplications; derivatives of L_0 and Q_0 are
// calculated using Hellmann-Feynman theorem (i.e. exploiting the
@ -401,7 +424,7 @@ void colvarmodule::rotation::calc_optimal_rotation
cvm::real const &a1y = pos1[ia].y;
cvm::real const &a1z = pos1[ia].z;
matrix2d<cvm::rvector, 4, 4> &ds_2 = dS_2[ia];
cvm::matrix2d<cvm::rvector> &ds_2 = dS_2[ia];
ds_2.reset();
ds_2[0][0].set( a1x, a1y, a1z);
@ -421,8 +444,8 @@ void colvarmodule::rotation::calc_optimal_rotation
ds_2[2][3] = ds_2[3][2];
ds_2[3][3].set(-a1x, -a1y, a1z);
cvm::rvector &dl0_2 = dL0_2[ia];
vector1d<cvm::rvector, 4> &dq0_2 = dQ0_2[ia];
cvm::rvector &dl0_2 = dL0_2[ia];
cvm::vector1d<cvm::rvector> &dq0_2 = dQ0_2[ia];
dl0_2.reset();
for (size_t i = 0; i < 4; i++) {
@ -447,9 +470,9 @@ void colvarmodule::rotation::calc_optimal_rotation
if (b_debug_gradients) {
matrix2d<cvm::real, 4, 4> S_new;
cvm::real S_new_eigval[4];
matrix2d<cvm::real, 4, 4> S_new_eigvec;
cvm::matrix2d<cvm::real> S_new(4, 4);
cvm::vector1d<cvm::real> S_new_eigval(4);
cvm::matrix2d<cvm::real> S_new_eigvec(4, 4);
// make an infitesimal move along each cartesian coordinate of
// this atom, and solve again the eigenvector problem
@ -464,25 +487,25 @@ void colvarmodule::rotation::calc_optimal_rotation
}
}
// cvm::log ("S_new = "+cvm::to_str (cvm::to_str (S_new), cvm::cv_width, cvm::cv_prec)+"\n");
// cvm::log("S_new = "+cvm::to_str(cvm::to_str (S_new), cvm::cv_width, cvm::cv_prec)+"\n");
diagonalize_matrix (S_new, S_new_eigval, S_new_eigvec);
diagonalize_matrix(S_new, S_new_eigval, S_new_eigvec);
cvm::real const &L0_new = S_new_eigval[0];
cvm::real const *Q0_new = S_new_eigvec[0];
cvm::quaternion const Q0_new(S_new_eigvec[0]);
cvm::real const DL0 = (dl0_2[comp]) * colvarmodule::debug_gradients_step_size;
cvm::quaternion const q0 (Q0);
cvm::quaternion const DQ0 (dq0_2[0][comp] * colvarmodule::debug_gradients_step_size,
dq0_2[1][comp] * colvarmodule::debug_gradients_step_size,
dq0_2[2][comp] * colvarmodule::debug_gradients_step_size,
dq0_2[3][comp] * colvarmodule::debug_gradients_step_size);
cvm::quaternion const q0(Q0);
cvm::quaternion const DQ0(dq0_2[0][comp] * colvarmodule::debug_gradients_step_size,
dq0_2[1][comp] * colvarmodule::debug_gradients_step_size,
dq0_2[2][comp] * colvarmodule::debug_gradients_step_size,
dq0_2[3][comp] * colvarmodule::debug_gradients_step_size);
cvm::log ( "|(l_0+dl_0) - l_0^new|/l_0 = "+
cvm::to_str (std::fabs (L0+DL0 - L0_new)/L0, cvm::cv_width, cvm::cv_prec)+
", |(q_0+dq_0) - q_0^new| = "+
cvm::to_str ((Q0+DQ0 - Q0_new).norm(), cvm::cv_width, cvm::cv_prec)+
"\n");
cvm::log( "|(l_0+dl_0) - l_0^new|/l_0 = "+
cvm::to_str(std::fabs(L0+DL0 - L0_new)/L0, cvm::cv_width, cvm::cv_prec)+
", |(q_0+dq_0) - q_0^new| = "+
cvm::to_str((Q0+DQ0 - Q0_new).norm(), cvm::cv_width, cvm::cv_prec)+
"\n");
}
}
}
@ -494,21 +517,24 @@ void colvarmodule::rotation::calc_optimal_rotation
// Numerical Recipes routine for diagonalization
#define ROTATE(a,i,j,k,l) g=a[i][j]; \
h=a[k][l]; \
a[i][j]=g-s*(h+g*tau); \
h=a[k][l]; \
a[i][j]=g-s*(h+g*tau); \
a[k][l]=h+s*(g-h*tau);
#define n 4
void jacobi(cvm::real **a, cvm::real d[], cvm::real **v, int *nrot)
void jacobi(cvm::real **a, cvm::real *d, cvm::real **v, int *nrot)
{
int j,iq,ip,i;
cvm::real tresh,theta,tau,t,sm,s,h,g,c;
std::vector<cvm::real> b (n, 0.0);
std::vector<cvm::real> z (n, 0.0);
cvm::vector1d<cvm::real> b(n);
cvm::vector1d<cvm::real> z(n);
for (ip=0;ip<n;ip++) {
for (iq=0;iq<n;iq++) v[ip][iq]=0.0;
for (iq=0;iq<n;iq++) {
v[ip][iq]=0.0;
}
v[ip][ip]=1.0;
}
for (ip=0;ip<n;ip++) {
@ -575,10 +601,10 @@ void jacobi(cvm::real **a, cvm::real d[], cvm::real **v, int *nrot)
z[ip]=0.0;
}
}
cvm::error ("Too many iterations in routine jacobi.\n");
cvm::error("Too many iterations in routine jacobi.\n");
}
void eigsrt(cvm::real d[], cvm::real **v)
void eigsrt(cvm::real *d, cvm::real **v)
{
int k,j,i;
cvm::real p;
@ -602,8 +628,9 @@ void eigsrt(cvm::real d[], cvm::real **v)
void transpose(cvm::real **v)
{
cvm::real p;
for (int i=0;i<n;i++) {
for (int j=i+1;j<n;j++) {
int i,j;
for (i=0;i<n;i++) {
for (j=i+1;j<n;j++) {
p=v[i][j];
v[i][j]=v[j][i];
v[j][i]=p;

File diff suppressed because it is too large Load Diff

View File

@ -1,237 +1,385 @@
/// -*- c++ -*-
#include <vector>
#include <sstream>
#include <iostream>
#include "colvarmodule.h"
#include "colvarvalue.h"
std::string const colvarvalue::type_desc[colvarvalue::type_all+1] =
{ "not_set",
"scalar number",
"3-dimensional vector",
"3-dimensional unit vector",
"3-dimensional tangent vector",
"4-dimensional unit quaternion",
"4-dimensional tangent vector",
};
std::string const colvarvalue::type_keyword[colvarvalue::type_all+1] =
{ "not_set",
"scalar",
"vector",
"unit_vector",
"",
"unit_quaternion",
"",
};
size_t const colvarvalue::dof_num[ colvarvalue::type_all+1] =
{ 0, 1, 3, 2, 2, 3, 3 };
void colvarvalue::undef_op() const
void colvarvalue::add_elem(colvarvalue const &x)
{
cvm::error ("Error: Undefined operation on a colvar of type \""+
colvarvalue::type_desc[this->value_type]+"\".\n");
}
void colvarvalue::error_rside
(colvarvalue::Type const &vt) const
{
cvm::error("Trying to assign a colvar value with type \""+
type_desc[this->value_type]+"\" to one with type \""+
type_desc[vt]+"\".\n");
}
void colvarvalue::error_lside(colvarvalue::Type const &vt) const
{
cvm::error("Trying to use a colvar value with type \""+
type_desc[vt]+"\" as one of type \""+
type_desc[this->value_type]+"\".\n");
}
void colvarvalue::inner_opt(colvarvalue const &x,
std::vector<colvarvalue>::iterator &xv,
std::vector<colvarvalue>::iterator const &xv_end,
std::vector<cvm::real>::iterator &inner)
{
// doing type check only once, here
colvarvalue::check_types(x, *xv);
std::vector<colvarvalue>::iterator &xvi = xv;
std::vector<cvm::real>::iterator &ii = inner;
switch (x.value_type) {
case colvarvalue::type_scalar:
while (xvi != xv_end) {
*(ii++) += (xvi++)->real_value * x.real_value;
}
break;
case colvarvalue::type_vector:
case colvarvalue::type_unitvector:
case colvarvalue::type_unitvectorderiv:
while (xvi != xv_end) {
*(ii++) += (xvi++)->rvector_value * x.rvector_value;
}
break;
case colvarvalue::type_quaternion:
case colvarvalue::type_quaternionderiv:
while (xvi != xv_end) {
*(ii++) += ((xvi++)->quaternion_value).cosine (x.quaternion_value);
}
break;
default:
x.undef_op();
};
}
void colvarvalue::inner_opt(colvarvalue const &x,
std::list<colvarvalue>::iterator &xv,
std::list<colvarvalue>::iterator const &xv_end,
std::vector<cvm::real>::iterator &inner)
{
// doing type check only once, here
colvarvalue::check_types(x, *xv);
std::list<colvarvalue>::iterator &xvi = xv;
std::vector<cvm::real>::iterator &ii = inner;
switch (x.value_type) {
case colvarvalue::type_scalar:
while (xvi != xv_end) {
*(ii++) += (xvi++)->real_value * x.real_value;
}
break;
case colvarvalue::type_vector:
case colvarvalue::type_unitvector:
case colvarvalue::type_unitvectorderiv:
while (xvi != xv_end) {
*(ii++) += (xvi++)->rvector_value * x.rvector_value;
}
break;
case colvarvalue::type_quaternion:
case colvarvalue::type_quaternionderiv:
while (xvi != xv_end) {
*(ii++) += ((xvi++)->quaternion_value).cosine (x.quaternion_value);
}
break;
default:
x.undef_op();
};
}
void colvarvalue::p2leg_opt(colvarvalue const &x,
std::vector<colvarvalue>::iterator &xv,
std::vector<colvarvalue>::iterator const &xv_end,
std::vector<cvm::real>::iterator &inner)
{
// doing type check only once, here
colvarvalue::check_types(x, *xv);
std::vector<colvarvalue>::iterator &xvi = xv;
std::vector<cvm::real>::iterator &ii = inner;
switch (x.value_type) {
case colvarvalue::type_scalar:
cvm::error("Error: cannot calculate Legendre polynomials "
"for scalar variables.\n");
if (this->value_type != type_vector) {
cvm::error("Error: trying to set an element for a variable that is not set to be a vector.\n");
return;
}
size_t const n = vector1d_value.size();
size_t const nd = num_dimensions(x.value_type);
elem_types.push_back(x.value_type);
elem_indices.push_back(n);
elem_sizes.push_back(nd);
vector1d_value.resize(n + nd);
set_elem(n, x);
}
colvarvalue const colvarvalue::get_elem(int const i_begin, int const i_end, Type const vt) const
{
if (vector1d_value.size() > 0) {
cvm::vector1d<cvm::real> const v(vector1d_value.slice(i_begin, i_end));
return colvarvalue(v, vt);
} else {
cvm::error("Error: trying to get an element from a variable that is not a vector.\n");
return colvarvalue(type_notset);
}
}
void colvarvalue::set_elem(int const i_begin, int const i_end, colvarvalue const &x)
{
if (vector1d_value.size() > 0) {
vector1d_value.sliceassign(i_begin, i_end, x.as_vector());
} else {
cvm::error("Error: trying to set an element for a variable that is not a vector.\n");
}
}
colvarvalue const colvarvalue::get_elem(int const icv) const
{
if (elem_types.size() > 0) {
return get_elem(elem_indices[icv], elem_indices[icv] + elem_sizes[icv],
elem_types[icv]);
} else {
cvm::error("Error: trying to get a colvarvalue element from a vector colvarvalue that was initialized as a plain array.\n");
return colvarvalue(type_notset);
}
}
void colvarvalue::set_elem(int const icv, colvarvalue const &x)
{
if (elem_types.size() > 0) {
check_types_assign(elem_types[icv], x.value_type);
set_elem(elem_indices[icv], elem_indices[icv] + elem_sizes[icv], x);
} else {
cvm::error("Error: trying to set a colvarvalue element for a colvarvalue that was initialized as a plain array.\n");
}
}
colvarvalue colvarvalue::inverse() const
{
switch (value_type) {
case colvarvalue::type_scalar:
return colvarvalue(1.0/real_value);
break;
case colvarvalue::type_vector:
while (xvi != xv_end) {
cvm::real const cosine =
((xvi)->rvector_value * x.rvector_value) /
((xvi)->rvector_value.norm() * x.rvector_value.norm());
xvi++;
*(ii++) += 1.5*cosine*cosine - 0.5;
}
break;
case colvarvalue::type_unitvector:
case colvarvalue::type_unitvectorderiv:
while (xvi != xv_end) {
cvm::real const cosine = (xvi++)->rvector_value * x.rvector_value;
*(ii++) += 1.5*cosine*cosine - 0.5;
}
case colvarvalue::type_3vector:
case colvarvalue::type_unit3vector:
case colvarvalue::type_unit3vectorderiv:
return colvarvalue(cvm::rvector(1.0/rvector_value.x,
1.0/rvector_value.y,
1.0/rvector_value.z));
break;
case colvarvalue::type_quaternion:
case colvarvalue::type_quaternionderiv:
while (xvi != xv_end) {
cvm::real const cosine = (xvi++)->quaternion_value.cosine (x.quaternion_value);
*(ii++) += 1.5*cosine*cosine - 0.5;
return colvarvalue(cvm::quaternion(1.0/quaternion_value.q0,
1.0/quaternion_value.q1,
1.0/quaternion_value.q2,
1.0/quaternion_value.q3));
break;
case colvarvalue::type_vector:
{
cvm::vector1d<cvm::real> result(vector1d_value);
if (elem_types.size() > 0) {
// if we have information about non-scalar types, use it
size_t i;
for (i = 0; i < elem_types.size(); i++) {
result.sliceassign(elem_indices[i], elem_indices[i]+elem_sizes[i],
cvm::vector1d<cvm::real>((this->get_elem(i)).inverse()));
}
} else {
size_t i;
for (i = 0; i < result.size(); i++) {
if (result[i] != 0.0) {
result = 1.0/result[i];
}
}
}
return colvarvalue(result, type_vector);
}
break;
case colvarvalue::type_notset:
default:
x.undef_op();
undef_op();
break;
}
return colvarvalue();
}
// binary operations between two colvarvalues
colvarvalue operator + (colvarvalue const &x1,
colvarvalue const &x2)
{
colvarvalue::check_types(x1, x2);
switch (x1.value_type) {
case colvarvalue::type_scalar:
return colvarvalue(x1.real_value + x2.real_value);
case colvarvalue::type_3vector:
return colvarvalue(x1.rvector_value + x2.rvector_value);
case colvarvalue::type_unit3vector:
case colvarvalue::type_unit3vectorderiv:
return colvarvalue(x1.rvector_value + x2.rvector_value,
colvarvalue::type_unit3vector);
case colvarvalue::type_quaternion:
case colvarvalue::type_quaternionderiv:
return colvarvalue(x1.quaternion_value + x2.quaternion_value);
case colvarvalue::type_vector:
return colvarvalue(x1.vector1d_value + x2.vector1d_value, colvarvalue::type_vector);
case colvarvalue::type_notset:
default:
x1.undef_op();
return colvarvalue(colvarvalue::type_notset);
};
}
void colvarvalue::p2leg_opt(colvarvalue const &x,
std::list<colvarvalue>::iterator &xv,
std::list<colvarvalue>::iterator const &xv_end,
std::vector<cvm::real>::iterator &inner)
colvarvalue operator - (colvarvalue const &x1,
colvarvalue const &x2)
{
// doing type check only once, here
colvarvalue::check_types(x, *xv);
colvarvalue::check_types(x1, x2);
std::list<colvarvalue>::iterator &xvi = xv;
std::vector<cvm::real>::iterator &ii = inner;
switch (x1.value_type) {
case colvarvalue::type_scalar:
return colvarvalue(x1.real_value - x2.real_value);
case colvarvalue::type_3vector:
return colvarvalue(x1.rvector_value - x2.rvector_value);
case colvarvalue::type_unit3vector:
case colvarvalue::type_unit3vectorderiv:
return colvarvalue(x1.rvector_value - x2.rvector_value,
colvarvalue::type_unit3vector);
case colvarvalue::type_quaternion:
case colvarvalue::type_quaternionderiv:
return colvarvalue(x1.quaternion_value - x2.quaternion_value);
case colvarvalue::type_vector:
return colvarvalue(x1.vector1d_value - x2.vector1d_value, colvarvalue::type_vector);
case colvarvalue::type_notset:
default:
x1.undef_op();
return colvarvalue(colvarvalue::type_notset);
};
}
// binary operations with real numbers
colvarvalue operator * (cvm::real const &a,
colvarvalue const &x)
{
switch (x.value_type) {
case colvarvalue::type_scalar:
cvm::error("Error: cannot calculate Legendre polynomials "
"for scalar variables.\n");
break;
case colvarvalue::type_vector:
while (xvi != xv_end) {
cvm::real const cosine =
((xvi)->rvector_value * x.rvector_value) /
((xvi)->rvector_value.norm() * x.rvector_value.norm());
xvi++;
*(ii++) += 1.5*cosine*cosine - 0.5;
}
break;
case colvarvalue::type_unitvector:
case colvarvalue::type_unitvectorderiv:
while (xvi != xv_end) {
cvm::real const cosine = (xvi++)->rvector_value * x.rvector_value;
*(ii++) += 1.5*cosine*cosine - 0.5;
}
break;
return colvarvalue(a * x.real_value);
case colvarvalue::type_3vector:
return colvarvalue(a * x.rvector_value);
case colvarvalue::type_unit3vector:
case colvarvalue::type_unit3vectorderiv:
return colvarvalue(a * x.rvector_value,
colvarvalue::type_unit3vector);
case colvarvalue::type_quaternion:
case colvarvalue::type_quaternionderiv:
while (xvi != xv_end) {
cvm::real const cosine = (xvi++)->quaternion_value.cosine (x.quaternion_value);
*(ii++) += 1.5*cosine*cosine - 0.5;
}
break;
return colvarvalue(a * x.quaternion_value);
case colvarvalue::type_vector:
return colvarvalue(x.vector1d_value * a, colvarvalue::type_vector);
case colvarvalue::type_notset:
default:
x.undef_op();
return colvarvalue(colvarvalue::type_notset);
}
}
colvarvalue operator * (colvarvalue const &x,
cvm::real const &a)
{
return a * x;
}
colvarvalue operator / (colvarvalue const &x,
cvm::real const &a)
{
switch (x.value_type) {
case colvarvalue::type_scalar:
return colvarvalue(x.real_value / a);
case colvarvalue::type_3vector:
return colvarvalue(x.rvector_value / a);
case colvarvalue::type_unit3vector:
case colvarvalue::type_unit3vectorderiv:
return colvarvalue(x.rvector_value / a,
colvarvalue::type_unit3vector);
case colvarvalue::type_quaternion:
case colvarvalue::type_quaternionderiv:
return colvarvalue(x.quaternion_value / a);
case colvarvalue::type_vector:
return colvarvalue(x.vector1d_value / a, colvarvalue::type_vector);
case colvarvalue::type_notset:
default:
x.undef_op();
return colvarvalue(colvarvalue::type_notset);
}
}
// inner product between two colvarvalues
cvm::real operator * (colvarvalue const &x1,
colvarvalue const &x2)
{
colvarvalue::check_types(x1, x2);
switch (x1.value_type) {
case colvarvalue::type_scalar:
return (x1.real_value * x2.real_value);
case colvarvalue::type_3vector:
case colvarvalue::type_unit3vector:
case colvarvalue::type_unit3vectorderiv:
return (x1.rvector_value * x2.rvector_value);
case colvarvalue::type_quaternion:
case colvarvalue::type_quaternionderiv:
// the "*" product is the quaternion product, here the inner
// member function is used instead
return (x1.quaternion_value.inner(x2.quaternion_value));
case colvarvalue::type_vector:
return (x1.vector1d_value * x2.vector1d_value);
case colvarvalue::type_notset:
default:
x1.undef_op();
return 0.0;
};
}
colvarvalue colvarvalue::dist2_grad(colvarvalue const &x2) const
{
colvarvalue::check_types(*this, x2);
switch (this->value_type) {
case colvarvalue::type_scalar:
return 2.0 * (this->real_value - x2.real_value);
case colvarvalue::type_3vector:
return 2.0 * (this->rvector_value - x2.rvector_value);
case colvarvalue::type_unit3vector:
case colvarvalue::type_unit3vectorderiv:
{
cvm::rvector const &v1 = this->rvector_value;
cvm::rvector const &v2 = x2.rvector_value;
cvm::real const cos_t = v1 * v2;
cvm::real const sin_t = std::sqrt(1.0 - cos_t*cos_t);
return colvarvalue( 2.0 * sin_t *
cvm::rvector((-1.0) * sin_t * v2.x +
cos_t/sin_t * (v1.x - cos_t*v2.x),
(-1.0) * sin_t * v2.y +
cos_t/sin_t * (v1.y - cos_t*v2.y),
(-1.0) * sin_t * v2.z +
cos_t/sin_t * (v1.z - cos_t*v2.z)
),
colvarvalue::type_unit3vector );
}
case colvarvalue::type_quaternion:
case colvarvalue::type_quaternionderiv:
return this->quaternion_value.dist2_grad(x2.quaternion_value);
case colvarvalue::type_vector:
return colvarvalue(2.0 * (this->vector1d_value - x2.vector1d_value), colvarvalue::type_vector);
break;
case colvarvalue::type_notset:
default:
this->undef_op();
return colvarvalue(colvarvalue::type_notset);
};
}
std::string colvarvalue::to_simple_string() const
{
switch (type()) {
case colvarvalue::type_scalar:
return cvm::to_str(real_value, 0, cvm::cv_prec);
break;
case colvarvalue::type_3vector:
case colvarvalue::type_unit3vector:
case colvarvalue::type_unit3vectorderiv:
return rvector_value.to_simple_string();
break;
case colvarvalue::type_quaternion:
case colvarvalue::type_quaternionderiv:
return quaternion_value.to_simple_string();
break;
case colvarvalue::type_vector:
return vector1d_value.to_simple_string();
break;
case colvarvalue::type_notset:
default:
undef_op();
break;
}
return std::string();
}
int colvarvalue::from_simple_string(std::string const &s)
{
switch (type()) {
case colvarvalue::type_scalar:
return ((std::istringstream(s) >> real_value)
? COLVARS_OK : COLVARS_ERROR);
break;
case colvarvalue::type_3vector:
case colvarvalue::type_unit3vector:
case colvarvalue::type_unit3vectorderiv:
return rvector_value.from_simple_string(s);
break;
case colvarvalue::type_quaternion:
case colvarvalue::type_quaternionderiv:
return quaternion_value.from_simple_string(s);
break;
case colvarvalue::type_vector:
return vector1d_value.from_simple_string(s);
break;
case colvarvalue::type_notset:
default:
undef_op();
break;
}
return COLVARS_ERROR;
}
std::ostream & operator << (std::ostream &os, colvarvalue const &x)
{
switch (x.type()) {
case colvarvalue::type_scalar:
os << x.real_value;
break;
case colvarvalue::type_vector:
case colvarvalue::type_unitvector:
case colvarvalue::type_unitvectorderiv:
case colvarvalue::type_3vector:
case colvarvalue::type_unit3vector:
case colvarvalue::type_unit3vectorderiv:
os << x.rvector_value;
break;
case colvarvalue::type_quaternion:
case colvarvalue::type_quaternionderiv:
os << x.quaternion_value;
break;
case colvarvalue::type_vector:
os << x.vector1d_value;
break;
case colvarvalue::type_notset:
os << "not set"; break;
default:
os << "not set";
break;
}
return os;
}
@ -239,7 +387,8 @@ std::ostream & operator << (std::ostream &os, colvarvalue const &x)
std::ostream & operator << (std::ostream &os, std::vector<colvarvalue> const &v)
{
for (size_t i = 0; i < v.size(); i++) {
size_t i;
for (i = 0; i < v.size(); i++) {
os << v[i];
}
return os;
@ -258,11 +407,11 @@ std::istream & operator >> (std::istream &is, colvarvalue &x)
case colvarvalue::type_scalar:
is >> x.real_value;
break;
case colvarvalue::type_vector:
case colvarvalue::type_unitvectorderiv:
case colvarvalue::type_3vector:
case colvarvalue::type_unit3vectorderiv:
is >> x.rvector_value;
break;
case colvarvalue::type_unitvector:
case colvarvalue::type_unit3vector:
is >> x.rvector_value;
x.apply_constraints();
break;
@ -273,6 +422,10 @@ std::istream & operator >> (std::istream &is, colvarvalue &x)
case colvarvalue::type_quaternionderiv:
is >> x.quaternion_value;
break;
case colvarvalue::type_vector:
is >> x.vector1d_value;
break;
case colvarvalue::type_notset:
default:
x.undef_op();
}
@ -285,13 +438,16 @@ size_t colvarvalue::output_width(size_t const &real_width) const
switch (this->value_type) {
case colvarvalue::type_scalar:
return real_width;
case colvarvalue::type_vector:
case colvarvalue::type_unitvector:
case colvarvalue::type_unitvectorderiv:
case colvarvalue::type_3vector:
case colvarvalue::type_unit3vector:
case colvarvalue::type_unit3vectorderiv:
return cvm::rvector::output_width(real_width);
case colvarvalue::type_quaternion:
case colvarvalue::type_quaternionderiv:
return cvm::quaternion::output_width(real_width);
case colvarvalue::type_vector:
// note how this depends on the vector's size
return vector1d_value.output_width(real_width);
case colvarvalue::type_notset:
default:
return 0;
@ -299,3 +455,186 @@ size_t colvarvalue::output_width(size_t const &real_width) const
}
void colvarvalue::inner_opt(colvarvalue const &x,
std::vector<colvarvalue>::iterator &xv,
std::vector<colvarvalue>::iterator const &xv_end,
std::vector<cvm::real>::iterator &result)
{
// doing type check only once, here
colvarvalue::check_types(x, *xv);
std::vector<colvarvalue>::iterator &xvi = xv;
std::vector<cvm::real>::iterator &ii = result;
switch (x.value_type) {
case colvarvalue::type_scalar:
while (xvi != xv_end) {
*(ii++) += (xvi++)->real_value * x.real_value;
}
break;
case colvarvalue::type_3vector:
case colvarvalue::type_unit3vector:
case colvarvalue::type_unit3vectorderiv:
while (xvi != xv_end) {
*(ii++) += (xvi++)->rvector_value * x.rvector_value;
}
break;
case colvarvalue::type_quaternion:
case colvarvalue::type_quaternionderiv:
while (xvi != xv_end) {
*(ii++) += ((xvi++)->quaternion_value).cosine(x.quaternion_value);
}
break;
case colvarvalue::type_vector:
while (xvi != xv_end) {
*(ii++) += (xvi++)->vector1d_value * x.vector1d_value;
}
break;
default:
x.undef_op();
};
}
void colvarvalue::inner_opt(colvarvalue const &x,
std::list<colvarvalue>::iterator &xv,
std::list<colvarvalue>::iterator const &xv_end,
std::vector<cvm::real>::iterator &result)
{
// doing type check only once, here
colvarvalue::check_types(x, *xv);
std::list<colvarvalue>::iterator &xvi = xv;
std::vector<cvm::real>::iterator &ii = result;
switch (x.value_type) {
case colvarvalue::type_scalar:
while (xvi != xv_end) {
*(ii++) += (xvi++)->real_value * x.real_value;
}
break;
case colvarvalue::type_3vector:
case colvarvalue::type_unit3vector:
case colvarvalue::type_unit3vectorderiv:
while (xvi != xv_end) {
*(ii++) += (xvi++)->rvector_value * x.rvector_value;
}
break;
case colvarvalue::type_quaternion:
case colvarvalue::type_quaternionderiv:
while (xvi != xv_end) {
*(ii++) += ((xvi++)->quaternion_value).cosine(x.quaternion_value);
}
break;
case colvarvalue::type_vector:
while (xvi != xv_end) {
*(ii++) += (xvi++)->vector1d_value * x.vector1d_value;
}
break;
default:
x.undef_op();
};
}
void colvarvalue::p2leg_opt(colvarvalue const &x,
std::vector<colvarvalue>::iterator &xv,
std::vector<colvarvalue>::iterator const &xv_end,
std::vector<cvm::real>::iterator &result)
{
// doing type check only once, here
colvarvalue::check_types(x, *xv);
std::vector<colvarvalue>::iterator &xvi = xv;
std::vector<cvm::real>::iterator &ii = result;
switch (x.value_type) {
case colvarvalue::type_scalar:
cvm::error("Error: cannot calculate Legendre polynomials "
"for scalar variables.\n");
return;
break;
case colvarvalue::type_3vector:
while (xvi != xv_end) {
cvm::real const cosine =
((xvi)->rvector_value * x.rvector_value) /
((xvi)->rvector_value.norm() * x.rvector_value.norm());
xvi++;
*(ii++) += 1.5*cosine*cosine - 0.5;
}
break;
case colvarvalue::type_unit3vector:
case colvarvalue::type_unit3vectorderiv:
while (xvi != xv_end) {
cvm::real const cosine = (xvi++)->rvector_value * x.rvector_value;
*(ii++) += 1.5*cosine*cosine - 0.5;
}
break;
case colvarvalue::type_quaternion:
case colvarvalue::type_quaternionderiv:
while (xvi != xv_end) {
cvm::real const cosine = (xvi++)->quaternion_value.cosine(x.quaternion_value);
*(ii++) += 1.5*cosine*cosine - 0.5;
}
break;
case colvarvalue::type_vector:
while (xvi != xv_end) {
cvm::real const cosine =
((xvi)->vector1d_value * x.vector1d_value) /
((xvi)->vector1d_value.norm() * x.rvector_value.norm());
xvi++;
*(ii++) += 1.5*cosine*cosine - 0.5;
}
break;
default:
x.undef_op();
};
}
void colvarvalue::p2leg_opt(colvarvalue const &x,
std::list<colvarvalue>::iterator &xv,
std::list<colvarvalue>::iterator const &xv_end,
std::vector<cvm::real>::iterator &result)
{
// doing type check only once, here
colvarvalue::check_types(x, *xv);
std::list<colvarvalue>::iterator &xvi = xv;
std::vector<cvm::real>::iterator &ii = result;
switch (x.value_type) {
case colvarvalue::type_scalar:
cvm::error("Error: cannot calculate Legendre polynomials "
"for scalar variables.\n");
break;
case colvarvalue::type_3vector:
while (xvi != xv_end) {
cvm::real const cosine =
((xvi)->rvector_value * x.rvector_value) /
((xvi)->rvector_value.norm() * x.rvector_value.norm());
xvi++;
*(ii++) += 1.5*cosine*cosine - 0.5;
}
break;
case colvarvalue::type_unit3vector:
case colvarvalue::type_unit3vectorderiv:
while (xvi != xv_end) {
cvm::real const cosine = (xvi++)->rvector_value * x.rvector_value;
*(ii++) += 1.5*cosine*cosine - 0.5;
}
break;
case colvarvalue::type_quaternion:
case colvarvalue::type_quaternionderiv:
while (xvi != xv_end) {
cvm::real const cosine = (xvi++)->quaternion_value.cosine(x.quaternion_value);
*(ii++) += 1.5*cosine*cosine - 0.5;
}
break;
default:
x.undef_op();
};
}

File diff suppressed because it is too large Load Diff