From 875003f11f6d6c06c201fd465b6d38ad776e4e4f Mon Sep 17 00:00:00 2001 From: Fabrizio Marinelli Date: Mon, 22 Aug 2022 14:28:23 -0400 Subject: [PATCH 01/62] Starting to implement interval (forces removal beyond boundaries) and hills reflection --- src/colvarbias_meta.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index 1131c88ec..885357caa 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -156,6 +156,8 @@ int colvarbias_meta::init(std::string const &conf) error_code |= init_replicas_params(conf); error_code |= init_well_tempered_params(conf); + error_code |= init_reflection_params(conf); + error_code |= init_interval_params(conf); error_code |= init_ebmeta_params(conf); if (cvm::debug()) From 3bf669d5e630bb8a48a6a83286941bd4910ab91f Mon Sep 17 00:00:00 2001 From: Fabrizio Marinelli Date: Mon, 22 Aug 2022 18:31:09 -0400 Subject: [PATCH 02/62] Introduced init_reflection --- src/colvarbias_meta.cpp | 207 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 207 insertions(+) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index 885357caa..831da5850 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -313,6 +313,213 @@ int colvarbias_meta::init_ebmeta_params(std::string const &conf) return error_code; } +int colvarbias_meta::init_reflection_params(std::string const &conf) +{ + bool use_reflection; + nrefvarsl=0; + nrefvarsu=0; + reflection_type = rt_none; + get_keyval(conf, "useHillsReflection", use_reflection, false); + if (use_reflection) { + + reflection_type = rt_monod; + std::string reflection_type_str; + get_keyval(conf, "reflectionType", reflection_type_str, to_lower_cppstr(std::string("monoDimensional"))); + reflection_type_str = to_lower_cppstr(reflection_type_str); + if (reflection_type_str == to_lower_cppstr(std::string("monoDimensional"))) { + reflection_type = rt_monod; + } else if (reflection_type_str == to_lower_cppstr(std::string("multiDimensional"))) { + reflection_type = rt_multid; + } + + get_keyval(conf, "reflectionLowLimitNCVs", nrefvarsl, num_variables()); + get_keyval(conf, "reflectionUpLimitNCVs", nrefvarsu, num_variables()); + if (reflection_llimit_cv.size()==0) { + reflection_llimit_cv.resize(nrefvarsl); + for (size_t i = 0; i < nrefvarsl; i++) { + reflection_llimit_cv[i]=i; + } + } + if (reflection_ulimit_cv.size()==0) { + reflection_ulimit_cv.resize(nrefvarsu); + for (size_t i = 0; i < nrefvarsu; i++) { + reflection_ulimit_cv[i]=i; + } + } + if (nrefvarsl>0 || nrefvarsu>0) { + get_keyval(conf, "reflectionRange", reflection_int, 6.0); + cvm::log("Reflection range is "+cvm::to_str(reflection_int)+".\n"); + } + if(nrefvarsl>0) { + if (get_keyval(conf, "reflectionLowLimitUseCVs", reflection_llimit_cv, reflection_llimit_cv)) { + if (reflection_llimit.size()==0) { + reflection_llimit.resize(nrefvarsl); + } + } else { + cvm::log("Using all variables for lower limits of reflection \n"); + } + if (get_keyval(conf, "reflectionLowLimit", reflection_llimit, reflection_llimit)) { + for (size_t i = 0; i < nrefvarsl; i++) { + if (use_grids) { + size_t ii=reflection_llimit_cv[i]; + cvm:: real sigma=0.5*variables(ii)->width*hill_width; + cvm:: real bound=variables(ii)->lower_boundary; + cvm:: real ref_r=reflection_llimit[i]-reflection_int*sigma; + if (ref_r < bound) { + cvm::error("Error: When using grids, lower boundary for CV"+cvm::to_str(ii)+" must be smaller than"+cvm::to_str(ref_r)+".\n", INPUT_ERROR); + } + } + cvm::log("Reflection condition is applied on a lower limit for CV "+cvm::to_str(reflection_llimit_cv[i])+".\n"); + cvm::log("Reflection condition lower limit for this CV is "+cvm::to_str(reflection_llimit[i])+".\n"); + } + } else { + cvm::error("Error: Lower limits for reflection not provided.\n", INPUT_ERROR); + return INPUT_ERROR; + } + } + + if(nrefvarsu>0) { + if (get_keyval(conf, "reflectionUpLimitUseCVs", reflection_ulimit_cv, reflection_ulimit_cv)) { + if (reflection_ulimit.size()==0) { + reflection_ulimit.resize(nrefvarsu); + } + } else { + cvm::log("Using all variables for upper limits of reflection \n"); + } + + if (get_keyval(conf, "reflectionUpLimit", reflection_ulimit, reflection_ulimit)) { + for (size_t i = 0; i < nrefvarsu; i++) { + if (use_grids) { + size_t ii=reflection_ulimit_cv[i]; + cvm:: real sigma=0.5*variables(ii)->width*hill_width; + cvm:: real bound=variables(ii)->upper_boundary; + cvm:: real ref_r=reflection_ulimit[i]+reflection_int*sigma; + if (ref_r > bound) { + cvm::error("Error: When using grids, upper boundary for CV"+cvm::to_str(ii)+" must be larger than"+cvm::to_str(ref_r)+".\n", INPUT_ERROR); + } + } + cvm::log("Reflection condition is applied on an upper limit for CV "+cvm::to_str(reflection_ulimit_cv[i])+".\n"); + cvm::log("Reflection condition upper limit for this CV is "+cvm::to_str(reflection_ulimit[i])+".\n"); + } + } else { + cvm::error("Error: Upper limits for reflection not provided.\n", INPUT_ERROR); + return INPUT_ERROR; + } + } + } + // use reflection only with scalar variables + + for (size_t i = 0; i < nrefvarsl; i++) { + if (reflection_llimit_cv[i]>=num_variables() || reflection_llimit_cv[i]<0) { + cvm::error("Error: CV number is negative or >= num_variables \n", INPUT_ERROR); + return INPUT_ERROR; + } + int j=reflection_llimit_cv[i]; + if (variables(j)->value().type()!=colvarvalue::type_scalar) { + cvm::error("Error: Hills reflection can be used only with scalar variables.\n", INPUT_ERROR); + return INPUT_ERROR; + } + } + + for (size_t i = 0; i < nrefvarsu; i++) { + if (reflection_ulimit_cv[i]>=num_variables() || reflection_ulimit_cv[i]<0) { + cvm::error("Error: CV number is negative or >= num_variables \n", INPUT_ERROR); + return INPUT_ERROR; + } + int j=reflection_ulimit_cv[i]; + if (variables(j)->value().type()!=colvarvalue::type_scalar) { + cvm::error("Error: Hills reflection can be used only with scalar variables.\n", INPUT_ERROR); + return INPUT_ERROR; + } + } + // mono vs multimensional reflection + + switch (reflection_type) { + case rt_none: + break; + case rt_monod: + cvm::log("Using monodimensional reflection \n"); + break; + case rt_multid: + // generate reflection states + cvm::log("Using multidimensional reflection \n"); + int sum=1; + int nstates; + int nvars=num_variables(); + if (reflection_usel.size()==0) { + reflection_usel.resize(nvars,std::vector(2)); + } + + if (reflection_l.size()==0) { + reflection_l.resize(nvars,std::vector(2)); + } + + for (size_t j = 1; j < nvars; j++) { + reflection_usel[j][0]=false; + reflection_l[j][0]=0.0; + reflection_usel[j][1]=false; + reflection_l[j][1]=0.0; + } + + for (size_t i = 0; i < nrefvarsl; i++) { + int j=reflection_llimit_cv[i]; + reflection_usel[j][0]=true; + reflection_l[j][0]=reflection_llimit[i]; + } + + for (size_t i = 0; i < nrefvarsu; i++) { + int j=reflection_ulimit_cv[i]; + reflection_usel[j][1]=true; + reflection_l[j][1]=reflection_ulimit[i]; + } + +// Generate all possible reflection states (e.g. through faces, edges and vertex). +// Consider for example a cube, the states are: +// [0,0,1] +// [0,1,0] [0,1,1] +// [1,0,0] [1,0,1] [1,1,0] [1,1,1] +// where 1 means reflect on that coordinate and 0 do not reflect. +// These states can be generated as: +// ref_state[0][0]=1 +// ref_state[1][0]=10 ref_state[1][1]=11 +// ref_state[2][0]=100 ref_state[2][1]=101 ref_state[2][2]=110 ref_state[2][3]=111 +// going down along the rows the size ref_state[j].size() is the number of previous states +// (j-1) plus one. +// A specific state instead can be generated starting from a power of 10 and then summing +// the states of the previous rows: +// ref_state[1][1]=ref_state[1][0]+ref_state[0][0] +// ref_state[2][1]=ref_state[2][0]+ref_state[0][0] +// ref_state[2][2]=ref_state[2][0]+ref_state[1][0] +// ref_state[2][3]=ref_state[2][0]+ref_state[1][1] + + if (ref_state.size()==0) { + ref_state.resize(nvars,std::vector(1)); + } + ref_state[0][0]=1; + for (size_t j = 1; j < nvars; j++) { + sum*=10; + nstates=0; + for (size_t jj = 0; jj < j; jj++) { + nstates+=ref_state[j].size(); + } + nstates++; + ref_state[j].resize(nstates); + ref_state[j][0]=sum; + int count=0; + for (size_t jj = 0; jj < j; jj++) { + for (size_t ii = 0; ii < ref_state[jj].size(); ii++) { + count++; + ref_state[j][count]=ref_state[j][0]+ref_state[jj][ii]; + } + } + } + + break; + } + + return COLVARS_OK; +} + colvarbias_meta::~colvarbias_meta() { From 42bffcf6eceae0dc75da959cfa1488995a5ceb6a Mon Sep 17 00:00:00 2001 From: Fabrizio Marinelli Date: Tue, 23 Aug 2022 09:49:40 -0400 Subject: [PATCH 03/62] Introduced init_interval --- src/colvarbias_meta.cpp | 133 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index 831da5850..2d06c884b 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -520,6 +520,139 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) return COLVARS_OK; } +int colvarbias_meta::init_interval_params(std::string const &conf) +{ + bool use_interval; + use_interval=false; + nintvarsl=0; + nintvarsu=0; + std::vector interval_llimit_cv; + std::vector interval_ulimit_cv; + if (get_keyval(conf, "useHillsInterval", use_interval, use_interval)) { + if (use_interval) { + get_keyval(conf, "intervalLowLimitNCVs", nintvarsl, num_variables()); + get_keyval(conf, "intervalUpLimitNCVs", nintvarsu, num_variables()); + interval_llimit_cv.resize(nintvarsl); + for (size_t i = 0; i < nintvarsl; i++) { + interval_llimit_cv[i]=i; + } + interval_ulimit_cv.resize(nintvarsu); + for (size_t i = 0; i < nintvarsu; i++) { + interval_ulimit_cv[i]=i; + } + if(nintvarsl>0) { + if (get_keyval(conf, "intervalLowLimitUseCVs", interval_llimit_cv, interval_llimit_cv)) { + if (interval_llimit.size()==0) { + interval_llimit.resize(nintvarsl); + } + } else { + cvm::log("Using all variables for lower limits of interval \n"); + } + if (get_keyval(conf, "intervalLowLimit", interval_llimit, interval_llimit)) { + for (size_t i = 0; i < nintvarsl; i++) { + cvm::log("Hills forces will be removed beyond a lower limit for CV "+cvm::to_str(interval_llimit_cv[i])+".\n"); + cvm::log("Interval condition lower limit for this CV is "+cvm::to_str(interval_llimit[i])+".\n"); + } + } else { + cvm::error("Error: Lower limits for interval not provided.\n", INPUT_ERROR); + return INPUT_ERROR; + } + } + + if(nintvarsu>0) { + if (get_keyval(conf, "intervalUpLimitUseCVs", interval_ulimit_cv, interval_ulimit_cv)) { + if (interval_ulimit.size()==0) { + interval_ulimit.resize(nintvarsu); + } + } else { + cvm::log("Using all variables for upper limits of interval \n"); + } + + if (get_keyval(conf, "intervalUpLimit", interval_ulimit, interval_ulimit)) { + for (size_t i = 0; i < nintvarsu; i++) { + cvm::log("Hills forces will be removed beyond an upper limit for CV "+cvm::to_str(interval_ulimit_cv[i])+".\n"); + cvm::log("Interval condition upper limit for this CV is "+cvm::to_str(interval_ulimit[i])+".\n"); + } + } else { + cvm::error("Error: Upper limits for interval not provided.\n", INPUT_ERROR); + return INPUT_ERROR; + } + } + } + } else { + if (nrefvarsl>0 || nrefvarsu>0) { + cvm::log("Reflection active: Using by default reflection variables and limits for interval \n"); + nintvarsl=nrefvarsl; + nintvarsu=nrefvarsu; + interval_llimit_cv.resize(nintvarsl); + if (interval_llimit.size()==0) { + interval_llimit.resize(nintvarsl); + } + for (size_t i = 0; i < nintvarsl; i++) { + interval_llimit_cv[i]=reflection_llimit_cv[i]; + interval_llimit[i]=reflection_llimit[i]; + } + interval_ulimit_cv.resize(nintvarsu); + if (interval_ulimit.size()==0) { + interval_ulimit.resize(nintvarsu); + } + for (size_t i = 0; i < nintvarsu; i++) { + interval_ulimit_cv[i]=reflection_ulimit_cv[i]; + interval_ulimit[i]=reflection_ulimit[i]; + } + } + } + + if (which_int_llimit_cv.size()==0) { + which_int_llimit_cv.resize(num_variables()); + } + for (size_t i = 0; i < num_variables(); i++) { + which_int_llimit_cv[i]=-1; + } + for (size_t i = 0; i < nintvarsl; i++) { + int j=interval_llimit_cv[i]; + which_int_llimit_cv[j]=i; + } + + if (which_int_ulimit_cv.size()==0) { + which_int_ulimit_cv.resize(num_variables()); + } + for (size_t i = 0; i < num_variables(); i++) { + which_int_ulimit_cv[i]=-1; + } + for (size_t i = 0; i < nintvarsu; i++) { + int j=interval_ulimit_cv[i]; + which_int_ulimit_cv[j]=i; + } + // use interval only with scalar variables + + for (size_t i = 0; i < nintvarsl; i++) { + if (interval_llimit_cv[i]>=num_variables() || interval_llimit_cv[i]<0) { + cvm::error("Error: CV number is negative or >= num_variables \n", INPUT_ERROR); + return INPUT_ERROR; + } + int j=interval_llimit_cv[i]; + if (variables(j)->value().type()!=colvarvalue::type_scalar) { + cvm::error("Error: Hills interval can be used only with scalar variables.\n", INPUT_ERROR); + return INPUT_ERROR; + } + } + + for (size_t i = 0; i < nintvarsu; i++) { + if (interval_ulimit_cv[i]>=num_variables() || interval_ulimit_cv[i]<0) { + cvm::error("Error: CV number is negative or >= num_variables \n", INPUT_ERROR); + return INPUT_ERROR; + } + int j=interval_ulimit_cv[i]; + if (variables(j)->value().type()!=colvarvalue::type_scalar) { + cvm::error("Error: Hills interval can be used only with scalar variables.\n", INPUT_ERROR); + return INPUT_ERROR; + } + } + + return COLVARS_OK; +} + colvarbias_meta::~colvarbias_meta() { From ecb243ca975e365a55d51190eb845bdad551a27a Mon Sep 17 00:00:00 2001 From: Fabrizio Marinelli Date: Mon, 29 Aug 2022 17:09:30 -0400 Subject: [PATCH 04/62] Added reflection & interval routines --- src/colvarbias_meta.cpp | 189 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index 2d06c884b..b13234b4a 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -707,6 +707,195 @@ colvarbias_meta::add_hill(colvarbias_meta::hill const &h) return hills.end(); } +bool colvarbias_meta::check_reflection_limits(bool &ah) +{ + for (size_t i = 0; i < nrefvarsl; i++) { + int ii=reflection_llimit_cv[i]; + cvm:: real cv_value=variables(ii)->value(); + if (cv_valuevalue(); + if (cv_value>reflection_ulimit[i]) { + ah=false; + } + } + return ah; +} + +int colvarbias_meta::reflect_hill_multid(cvm::real const &h_scale) +{ + size_t i = 0; + std::vector curr_cv_values(num_variables()); + for (i = 0; i < num_variables(); i++) { + curr_cv_values[i].type(variables(i)->value()); + } + std::vector h_w(num_variables()); + for (i = 0; i < num_variables(); i++) { + curr_cv_values[i] = variables(i)->value(); + h_w[i]=variables(i)->width*hill_width; + } + + // sum over all possible reflection states previously generated, + // see init + + for (size_t j = 0; j < num_variables(); j++) { + int startsum=1; + for (size_t i = 0; i < j; i++) { + startsum*=10; + } + for (size_t jj = 0; jj < ref_state[j].size(); jj++) { + int getsum=startsum; + int check_val=ref_state[j][jj]; + int numberref=0; + int startsumk=1; + for (size_t i = 0; i <= j; i++) { + int upordown=std::floor(check_val/getsum); + check_val=check_val-getsum; + getsum=getsum/10; + if (upordown==1) { + numberref++; + if(numberref>1) startsumk*=10; + } + } + + // sum over all possible lower and upper boudary combinations + // exploiting kstate=ref_state[k][kk]: + // for just one reflection these are 0(lower boundary) and 1(upper boundary) + // for two reflections these are 0 1 10 11 (0,0 0,1 1,0 1,1) + // where 0 is reflect on the two lower boudaries of the two coordinates etc. + + int nkstates=2; + int kstate=0; + for (size_t k = 0; k 0) nkstates=ref_state[k].size(); + for (size_t kk = 0; kk < nkstates; kk++) { + if (k==0 && kk==1) { + kstate=1; + } else if (k>0) { + kstate=ref_state[k][kk]; + } + + int getsum=startsum; + int countstate=0; + int check_val=ref_state[j][jj]; + bool hill_add=true; + int getsumk=startsumk; + int checkk=kstate; + for (size_t i = 0; i <= j; i++) { + int upordown=std::floor(check_val/getsum); + int state=num_variables()-1-j+countstate; + countstate++; + check_val=check_val-getsum; + getsum=getsum/10; + if (upordown==1) { + cvm:: real tmps=0.5*h_w[state]; + colvarvalue tmp=curr_cv_values[state]; // store original current cv value + colvarvalue unitary=curr_cv_values[state]; + unitary.set_to_one(); + int valk=std::floor(checkk/getsumk); + if(checkk-getsumk>=0) checkk=checkk-getsumk; + getsumk=getsumk/10; + cvm:: real reflection_limit=reflection_l[state][valk]; + cvm:: real tmpd=reflection_limit-cvm::real(curr_cv_values[state]); + tmpd=std::sqrt(tmpd*tmpd); + if (tmpdname+"\""+ + ((comm != single_replica) ? ", replica \""+replica_id+"\"" : "")+ + " while writing hills for the other replicas.\n", FILE_ERROR); + } + break; + } + + for (size_t i = 0; i < num_variables(); i++) { + curr_cv_values[i] = variables(i)->value(); // go back to previous values + } + } else { + for (size_t i = 0; i < num_variables(); i++) { + curr_cv_values[i] = variables(i)->value(); // go back to previous values + } + } + } + } + } + } + return COLVARS_OK; +} + +int colvarbias_meta::reflect_hill_monod(int const &aa, + cvm::real const &h_scale, + cvm::real const &ref_lim) + +{ + size_t i = 0; + std::vector curr_cv_values(num_variables()); + for (i = 0; i < num_variables(); i++) { + curr_cv_values[i].type(variables(i)->value()); + } + std::vector h_w(num_variables()); + for (i = 0; i < num_variables(); i++) { + curr_cv_values[i] = variables(i)->value(); + h_w[i]=variables(i)->width*hill_width; + } + cvm:: real tmps=0.5*h_w[aa]; + colvarvalue tmp=curr_cv_values[aa]; // store original current cv value + colvarvalue unitary=curr_cv_values[aa]; + unitary.set_to_one(); + cvm:: real tmpd=ref_lim-cvm::real(curr_cv_values[aa]); + tmpd=std::sqrt(tmpd*tmpd); + if (tmpdname+"\""+ + ((comm != single_replica) ? ", replica \""+replica_id+"\"" : "")+ + " while writing hills for the other replicas.\n", FILE_ERROR); + } + break; + } + curr_cv_values[aa]=tmp; // go back to previous value + } + return COLVARS_OK; +} + std::list::const_iterator colvarbias_meta::delete_hill(hill_iter &h) From d421fe98fd8d2a53eeaea390e904c3a2c7a3bbae Mon Sep 17 00:00:00 2001 From: Fabrizio Marinelli Date: Mon, 29 Aug 2022 17:18:33 -0400 Subject: [PATCH 05/62] Added calls to reflected hills when required --- src/colvarbias_meta.cpp | 71 +++++++++++++++++++++++++++++++---------- 1 file changed, 54 insertions(+), 17 deletions(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index b13234b4a..81974fa39 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -1102,29 +1102,66 @@ int colvarbias_meta::update_bias() hills_scale *= cvm::exp(-1.0*hills_energy_sum_here/(bias_temperature*proxy->boltzmann())); } - switch (comm) { + // Whether add a hill + bool add_a_hill=true; - case single_replica: + // Do not add hills beyond reflection borders + // as just reflected hills must be present + // beyond those boundaries - add_hill(hill(cvm::step_absolute(), hill_weight*hills_scale, - colvar_values, colvar_sigmas)); + // Check reflection borders: if beyond borders do not add hill - break; + add_a_hill=check_reflection_limits(add_a_hill); - case multiple_replicas: - add_hill(hill(cvm::step_absolute(), hill_weight*hills_scale, - colvar_values, colvar_sigmas, replica_id)); - std::ostream &replica_hills_os = - cvm::proxy->output_stream(replica_hills_file, "replica hills file"); - if (replica_hills_os) { - write_hill(replica_hills_os, hills.back()); - } else { - return cvm::error("Error: in metadynamics bias \""+this->name+"\""+ - ((comm != single_replica) ? ", replica \""+replica_id+"\"" : "")+ - " while writing hills for the other replicas.\n", COLVARS_FILE_ERROR); + if (add_a_hill) { + + switch (comm) { + + case single_replica: + + add_hill(hill(cvm::step_absolute(), hill_weight*hills_scale, + colvar_values, colvar_sigmas)); + + break; + + case multiple_replicas: + add_hill(hill(cvm::step_absolute(), hill_weight*hills_scale, + colvar_values, colvar_sigmas, replica_id)); + std::ostream &replica_hills_os = + cvm::proxy->output_stream(replica_hills_file, "replica hills file"); + if (replica_hills_os) { + replica_hills_os << hills.back(); + } else { + return cvm::error("Error: in metadynamics bias \""+this->name+"\""+ + ((comm != single_replica) ? ", replica \""+replica_id+"\"" : "")+ + " while writing hills for the other replicas.\n", COLVARS_FILE_ERROR); + } + break; } - break; + + // add reflected hills if required + + switch (reflection_type) { + case rt_none: + break; + case rt_monod: + for (size_t i = 0; i < nrefvarsl; i++) { + size_t ii=reflection_llimit_cv[i]; + reflect_hill_monod(ii, hills_scale, reflection_llimit[i]); + } + + for (size_t i = 0; i < nrefvarsu; i++) { + size_t ii=reflection_ulimit_cv[i]; + reflect_hill_monod(ii, hills_scale, reflection_ulimit[i]); + } + break; + case rt_multid: + reflect_hill_multid(hills_scale); + break; + } + } + } return COLVARS_OK; From caf45db0882e47b2f8cebc3c09e994a03705fa58 Mon Sep 17 00:00:00 2001 From: Fabrizio Marinelli Date: Tue, 30 Aug 2022 12:06:39 -0400 Subject: [PATCH 06/62] Introduced reflection and iontervals vars in colvarbias_meta.h --- src/colvarbias_meta.h | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/colvarbias_meta.h b/src/colvarbias_meta.h index 57aa21ed6..8d615c5ff 100644 --- a/src/colvarbias_meta.h +++ b/src/colvarbias_meta.h @@ -48,6 +48,8 @@ class colvarbias_meta virtual int init_replicas_params(std::string const &conf); virtual int init_well_tempered_params(std::string const &conf); virtual int init_ebmeta_params(std::string const &conf); + virtual int init_reflection_params(std::string const &conf); + virtual int init_interval_params(std::string const &conf); virtual int clear_state_data(); @@ -210,6 +212,45 @@ class colvarbias_meta /// \brief Biasing temperature in well-tempered metadynamics cvm::real bias_temperature; + // hills reflection + + /// \brief For which variables reflection limits are on + + std::vector reflection_llimit_cv; + std::vector reflection_ulimit_cv; + cvm::real reflection_int; + int nrefvarsl; + int nrefvarsu; + + /// \brief Limits for reflection + std::vector reflection_llimit; + std::vector reflection_ulimit; + + /// \brief Whether reflection are of mono or multidimensional type + enum reflection_type_e { + rt_monod, + rt_multid, + rt_none + }; + int reflection_type; + + /// \brief Multidimensional reflection : store cvs to use and pointers to the limits + std::vector > reflection_usel; + std::vector> reflection_l; + + /// \brief Multidimensional reflection or inversion states + std::vector > ref_state; + + /// \brief For which variables hills forces beyond the boundaries(interval) must be removed + + std::vector which_int_llimit_cv; + std::vector which_int_ulimit_cv; + int nintvarsl; + int nintvarsu; + /// \brief Limits for interval + std::vector interval_llimit; + std::vector interval_ulimit; + /// Ensemble-biased metadynamics (EBmeta) flag bool ebmeta; From e23e7c5cc775f5f26d77701ec3ae38857ac545c5 Mon Sep 17 00:00:00 2001 From: Fabrizio Marinelli Date: Tue, 30 Aug 2022 12:15:47 -0400 Subject: [PATCH 07/62] Removed forces beyond CVs intervals when defined in colvarbias_meta.cpp --- src/colvarbias_meta.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index 81974fa39..e77198d5a 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -1374,9 +1374,22 @@ void colvarbias_meta::calc_hills_force(size_t const &i, if (h->value() == 0.0) continue; colvarvalue const ¢er = h->centers[i]; cvm::real const sigma = h->sigmas[i]; - forces[i].real_value += - ( h->weight() * h->value() * (0.5 / (sigma*sigma)) * - (variables(i)->dist2_lgrad(x, center)).real_value ); + + // if outside interval boundaries do not add force + bool add_force=true; + int ii=which_int_llimit_cv[i]; + if (ii>-1 && x[i]-1 && x[i]>interval_ulimit[ii] ) { + add_force=false; + } + if (add_force) { + forces[i].real_value += + ( h->weight() * h->value() * (0.5 / (sigma*sigma)) * + (variables(i)->dist2_lgrad(x, center)).real_value ); + } } break; From c5b3f386b44bd6e32b024bbd6a0a5bf999a5a200 Mon Sep 17 00:00:00 2001 From: Fabrizio Marinelli Date: Tue, 30 Aug 2022 15:07:06 -0400 Subject: [PATCH 08/62] Update argument of hill() to match recent version of colvars --- src/colvarbias_meta.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index e77198d5a..3c2d4bdae 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -815,19 +815,19 @@ int colvarbias_meta::reflect_hill_multid(cvm::real const &h_scale) case single_replica: - add_hill(hill(cvm::step_absolute(), hill_weight*h_scale, curr_cv_values, h_w, h_replica)); + add_hill(hill(cvm::step_absolute(), hill_weight*h_scale, curr_cv_values, 0.5*h_w)); break; case multiple_replicas: h_replica=replica_id; - add_hill(hill(cvm::step_absolute(), hill_weight*h_scale, curr_cv_values, h_w, replica_id)); + add_hill(hill(cvm::step_absolute(), hill_weight*h_scale, curr_cv_values, 0.5*h_w, replica_id)); if (replica_hills_os) { *replica_hills_os << hills.back(); } else { return cvm::error("Error: in metadynamics bias \""+this->name+"\""+ ((comm != single_replica) ? ", replica \""+replica_id+"\"" : "")+ - " while writing hills for the other replicas.\n", FILE_ERROR); + " while writing hills for the other replicas.\n", COLVARS_FILE_ERROR); } break; } @@ -875,19 +875,19 @@ int colvarbias_meta::reflect_hill_monod(int const &aa, case single_replica: - add_hill(hill(cvm::step_absolute(), hill_weight*h_scale, curr_cv_values, h_w, h_replica)); + add_hill(hill(cvm::step_absolute(), hill_weight*h_scale, curr_cv_values, 0.5*h_w)); break; case multiple_replicas: h_replica=replica_id; - add_hill(hill(cvm::step_absolute(), hill_weight*h_scale, curr_cv_values, h_w, h_replica)); + add_hill(hill(cvm::step_absolute(), hill_weight*h_scale, curr_cv_values, 0.5*h_w, h_replica)); if (replica_hills_os) { *replica_hills_os << hills.back(); } else { return cvm::error("Error: in metadynamics bias \""+this->name+"\""+ ((comm != single_replica) ? ", replica \""+replica_id+"\"" : "")+ - " while writing hills for the other replicas.\n", FILE_ERROR); + " while writing hills for the other replicas.\n", COLVARS_FILE_ERROR); } break; } From 59ac4a47ecd21924e21360f5ee36b6998b1cfdee Mon Sep 17 00:00:00 2001 From: Fabrizio Marinelli Date: Tue, 30 Aug 2022 16:58:56 -0400 Subject: [PATCH 09/62] Corrected INPUT_ERROR with COLVARS_INPUT_ERROR in colvarbias_meta.cpp --- src/colvarbias_meta.cpp | 52 ++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index 3c2d4bdae..3d0545fea 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -366,15 +366,15 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) cvm:: real bound=variables(ii)->lower_boundary; cvm:: real ref_r=reflection_llimit[i]-reflection_int*sigma; if (ref_r < bound) { - cvm::error("Error: When using grids, lower boundary for CV"+cvm::to_str(ii)+" must be smaller than"+cvm::to_str(ref_r)+".\n", INPUT_ERROR); + cvm::error("Error: When using grids, lower boundary for CV"+cvm::to_str(ii)+" must be smaller than"+cvm::to_str(ref_r)+".\n", COLVARS_INPUT_ERROR); } } cvm::log("Reflection condition is applied on a lower limit for CV "+cvm::to_str(reflection_llimit_cv[i])+".\n"); cvm::log("Reflection condition lower limit for this CV is "+cvm::to_str(reflection_llimit[i])+".\n"); } } else { - cvm::error("Error: Lower limits for reflection not provided.\n", INPUT_ERROR); - return INPUT_ERROR; + cvm::error("Error: Lower limits for reflection not provided.\n", COLVARS_INPUT_ERROR); + return COLVARS_INPUT_ERROR; } } @@ -395,15 +395,15 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) cvm:: real bound=variables(ii)->upper_boundary; cvm:: real ref_r=reflection_ulimit[i]+reflection_int*sigma; if (ref_r > bound) { - cvm::error("Error: When using grids, upper boundary for CV"+cvm::to_str(ii)+" must be larger than"+cvm::to_str(ref_r)+".\n", INPUT_ERROR); + cvm::error("Error: When using grids, upper boundary for CV"+cvm::to_str(ii)+" must be larger than"+cvm::to_str(ref_r)+".\n", COLVARS_INPUT_ERROR); } } cvm::log("Reflection condition is applied on an upper limit for CV "+cvm::to_str(reflection_ulimit_cv[i])+".\n"); cvm::log("Reflection condition upper limit for this CV is "+cvm::to_str(reflection_ulimit[i])+".\n"); } } else { - cvm::error("Error: Upper limits for reflection not provided.\n", INPUT_ERROR); - return INPUT_ERROR; + cvm::error("Error: Upper limits for reflection not provided.\n", COLVARS_INPUT_ERROR); + return COLVARS_INPUT_ERROR; } } } @@ -411,25 +411,25 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) for (size_t i = 0; i < nrefvarsl; i++) { if (reflection_llimit_cv[i]>=num_variables() || reflection_llimit_cv[i]<0) { - cvm::error("Error: CV number is negative or >= num_variables \n", INPUT_ERROR); - return INPUT_ERROR; + cvm::error("Error: CV number is negative or >= num_variables \n", COLVARS_INPUT_ERROR); + return COLVARS_INPUT_ERROR; } int j=reflection_llimit_cv[i]; if (variables(j)->value().type()!=colvarvalue::type_scalar) { - cvm::error("Error: Hills reflection can be used only with scalar variables.\n", INPUT_ERROR); - return INPUT_ERROR; + cvm::error("Error: Hills reflection can be used only with scalar variables.\n", COLVARS_INPUT_ERROR); + return COLVARS_INPUT_ERROR; } } for (size_t i = 0; i < nrefvarsu; i++) { if (reflection_ulimit_cv[i]>=num_variables() || reflection_ulimit_cv[i]<0) { - cvm::error("Error: CV number is negative or >= num_variables \n", INPUT_ERROR); - return INPUT_ERROR; + cvm::error("Error: CV number is negative or >= num_variables \n", COLVARS_INPUT_ERROR); + return COLVARS_INPUT_ERROR; } int j=reflection_ulimit_cv[i]; if (variables(j)->value().type()!=colvarvalue::type_scalar) { - cvm::error("Error: Hills reflection can be used only with scalar variables.\n", INPUT_ERROR); - return INPUT_ERROR; + cvm::error("Error: Hills reflection can be used only with scalar variables.\n", COLVARS_INPUT_ERROR); + return COLVARS_INPUT_ERROR; } } // mono vs multimensional reflection @@ -554,8 +554,8 @@ int colvarbias_meta::init_interval_params(std::string const &conf) cvm::log("Interval condition lower limit for this CV is "+cvm::to_str(interval_llimit[i])+".\n"); } } else { - cvm::error("Error: Lower limits for interval not provided.\n", INPUT_ERROR); - return INPUT_ERROR; + cvm::error("Error: Lower limits for interval not provided.\n", COLVARS_INPUT_ERROR); + return COLVARS_INPUT_ERROR; } } @@ -574,8 +574,8 @@ int colvarbias_meta::init_interval_params(std::string const &conf) cvm::log("Interval condition upper limit for this CV is "+cvm::to_str(interval_ulimit[i])+".\n"); } } else { - cvm::error("Error: Upper limits for interval not provided.\n", INPUT_ERROR); - return INPUT_ERROR; + cvm::error("Error: Upper limits for interval not provided.\n", COLVARS_INPUT_ERROR); + return COLVARS_INPUT_ERROR; } } } @@ -628,25 +628,25 @@ int colvarbias_meta::init_interval_params(std::string const &conf) for (size_t i = 0; i < nintvarsl; i++) { if (interval_llimit_cv[i]>=num_variables() || interval_llimit_cv[i]<0) { - cvm::error("Error: CV number is negative or >= num_variables \n", INPUT_ERROR); - return INPUT_ERROR; + cvm::error("Error: CV number is negative or >= num_variables \n", COLVARS_INPUT_ERROR); + return COLVARS_INPUT_ERROR; } int j=interval_llimit_cv[i]; if (variables(j)->value().type()!=colvarvalue::type_scalar) { - cvm::error("Error: Hills interval can be used only with scalar variables.\n", INPUT_ERROR); - return INPUT_ERROR; + cvm::error("Error: Hills interval can be used only with scalar variables.\n", COLVARS_INPUT_ERROR); + return COLVARS_INPUT_ERROR; } } for (size_t i = 0; i < nintvarsu; i++) { if (interval_ulimit_cv[i]>=num_variables() || interval_ulimit_cv[i]<0) { - cvm::error("Error: CV number is negative or >= num_variables \n", INPUT_ERROR); - return INPUT_ERROR; + cvm::error("Error: CV number is negative or >= num_variables \n", COLVARS_INPUT_ERROR); + return COLVARS_INPUT_ERROR; } int j=interval_ulimit_cv[i]; if (variables(j)->value().type()!=colvarvalue::type_scalar) { - cvm::error("Error: Hills interval can be used only with scalar variables.\n", INPUT_ERROR); - return INPUT_ERROR; + cvm::error("Error: Hills interval can be used only with scalar variables.\n", COLVARS_INPUT_ERROR); + return COLVARS_INPUT_ERROR; } } From f8447bb0901344b81d3e817f558d88cbf7178f2f Mon Sep 17 00:00:00 2001 From: Fabrizio Marinelli Date: Tue, 30 Aug 2022 17:03:56 -0400 Subject: [PATCH 10/62] Added declaration of reflection routines in colvarbias_meta.h --- src/colvarbias_meta.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/colvarbias_meta.h b/src/colvarbias_meta.h index 8d615c5ff..ae787b395 100644 --- a/src/colvarbias_meta.h +++ b/src/colvarbias_meta.h @@ -156,6 +156,19 @@ class colvarbias_meta /// the next hill in the list) std::list::const_iterator delete_hill(hill_iter &h); + + /// \brief Check is current colvar value is within inversion or + /// reflection limits to assess whether to add a hill + bool check_reflection_limits(bool &ah); + + /// \brief Multidimensional routine to reflect hills + int reflect_hill_multid(cvm::real const &h_scale); + + /// \brief Monodimensional routine to reflect hills + int reflect_hill_monod(int const &aa, + cvm::real const &h_scale, + cvm::real const &ref_lim); + /// \brief Calculate the values of the hills, incrementing /// bias_energy virtual void calc_hills(hill_iter h_first, From 38d85dcd0c255aaddc2abc6f64191f173658c23d Mon Sep 17 00:00:00 2001 From: Fabrizio Marinelli Date: Wed, 31 Aug 2022 10:16:55 -0400 Subject: [PATCH 11/62] Modified sigmas and call to set_ones --- src/colvarbias_meta.cpp | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index 3d0545fea..094cd276e 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -736,7 +736,7 @@ int colvarbias_meta::reflect_hill_multid(cvm::real const &h_scale) std::vector h_w(num_variables()); for (i = 0; i < num_variables(); i++) { curr_cv_values[i] = variables(i)->value(); - h_w[i]=variables(i)->width*hill_width; + h_w[i]=variables(i)->width*hill_width*0.5; } // sum over all possible reflection states previously generated, @@ -792,10 +792,10 @@ int colvarbias_meta::reflect_hill_multid(cvm::real const &h_scale) check_val=check_val-getsum; getsum=getsum/10; if (upordown==1) { - cvm:: real tmps=0.5*h_w[state]; + cvm:: real tmps=h_w[state]; colvarvalue tmp=curr_cv_values[state]; // store original current cv value colvarvalue unitary=curr_cv_values[state]; - unitary.set_to_one(); + unitary.set_ones(); int valk=std::floor(checkk/getsumk); if(checkk-getsumk>=0) checkk=checkk-getsumk; getsumk=getsumk/10; @@ -815,13 +815,15 @@ int colvarbias_meta::reflect_hill_multid(cvm::real const &h_scale) case single_replica: - add_hill(hill(cvm::step_absolute(), hill_weight*h_scale, curr_cv_values, 0.5*h_w)); + add_hill(hill(cvm::step_absolute(), hill_weight*h_scale, curr_cv_values, h_w)); break; case multiple_replicas: h_replica=replica_id; - add_hill(hill(cvm::step_absolute(), hill_weight*h_scale, curr_cv_values, 0.5*h_w, replica_id)); + add_hill(hill(cvm::step_absolute(), hill_weight*h_scale, curr_cv_values, h_w, replica_id)); + std::ostream *replica_hills_os = + cvm::proxy->get_output_stream(replica_hills_file); if (replica_hills_os) { *replica_hills_os << hills.back(); } else { @@ -860,12 +862,12 @@ int colvarbias_meta::reflect_hill_monod(int const &aa, std::vector h_w(num_variables()); for (i = 0; i < num_variables(); i++) { curr_cv_values[i] = variables(i)->value(); - h_w[i]=variables(i)->width*hill_width; + h_w[i]=variables(i)->width*hill_width*0.5; } - cvm:: real tmps=0.5*h_w[aa]; + cvm:: real tmps=h_w[aa]; colvarvalue tmp=curr_cv_values[aa]; // store original current cv value colvarvalue unitary=curr_cv_values[aa]; - unitary.set_to_one(); + unitary.set_ones(); cvm:: real tmpd=ref_lim-cvm::real(curr_cv_values[aa]); tmpd=std::sqrt(tmpd*tmpd); if (tmpdget_output_stream(replica_hills_file); if (replica_hills_os) { *replica_hills_os << hills.back(); } else { From e16034edcc8c0380e86edf42ac92d9e8cd8ee335 Mon Sep 17 00:00:00 2001 From: Fabrizio Marinelli Date: Wed, 31 Aug 2022 10:26:12 -0400 Subject: [PATCH 12/62] h_w substituted with colvar_sigmas --- src/colvarbias_meta.cpp | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index 094cd276e..7c870e772 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -733,10 +733,8 @@ int colvarbias_meta::reflect_hill_multid(cvm::real const &h_scale) for (i = 0; i < num_variables(); i++) { curr_cv_values[i].type(variables(i)->value()); } - std::vector h_w(num_variables()); for (i = 0; i < num_variables(); i++) { curr_cv_values[i] = variables(i)->value(); - h_w[i]=variables(i)->width*hill_width*0.5; } // sum over all possible reflection states previously generated, @@ -792,7 +790,7 @@ int colvarbias_meta::reflect_hill_multid(cvm::real const &h_scale) check_val=check_val-getsum; getsum=getsum/10; if (upordown==1) { - cvm:: real tmps=h_w[state]; + cvm:: real tmps=colvar_sigmas[state]; colvarvalue tmp=curr_cv_values[state]; // store original current cv value colvarvalue unitary=curr_cv_values[state]; unitary.set_ones(); @@ -815,13 +813,13 @@ int colvarbias_meta::reflect_hill_multid(cvm::real const &h_scale) case single_replica: - add_hill(hill(cvm::step_absolute(), hill_weight*h_scale, curr_cv_values, h_w)); + add_hill(hill(cvm::step_absolute(), hill_weight*h_scale, curr_cv_values, colvar_sigmas)); break; case multiple_replicas: h_replica=replica_id; - add_hill(hill(cvm::step_absolute(), hill_weight*h_scale, curr_cv_values, h_w, replica_id)); + add_hill(hill(cvm::step_absolute(), hill_weight*h_scale, curr_cv_values, colvar_sigmas, replica_id)); std::ostream *replica_hills_os = cvm::proxy->get_output_stream(replica_hills_file); if (replica_hills_os) { @@ -859,12 +857,10 @@ int colvarbias_meta::reflect_hill_monod(int const &aa, for (i = 0; i < num_variables(); i++) { curr_cv_values[i].type(variables(i)->value()); } - std::vector h_w(num_variables()); for (i = 0; i < num_variables(); i++) { curr_cv_values[i] = variables(i)->value(); - h_w[i]=variables(i)->width*hill_width*0.5; } - cvm:: real tmps=h_w[aa]; + cvm:: real tmps=colvar_sigmas[aa]; colvarvalue tmp=curr_cv_values[aa]; // store original current cv value colvarvalue unitary=curr_cv_values[aa]; unitary.set_ones(); @@ -877,13 +873,13 @@ int colvarbias_meta::reflect_hill_monod(int const &aa, case single_replica: - add_hill(hill(cvm::step_absolute(), hill_weight*h_scale, curr_cv_values, h_w)); + add_hill(hill(cvm::step_absolute(), hill_weight*h_scale, curr_cv_values, colvar_sigmas)); break; case multiple_replicas: h_replica=replica_id; - add_hill(hill(cvm::step_absolute(), hill_weight*h_scale, curr_cv_values, h_w, h_replica)); + add_hill(hill(cvm::step_absolute(), hill_weight*h_scale, curr_cv_values, colvar_sigmas, h_replica)); std::ostream *replica_hills_os = cvm::proxy->get_output_stream(replica_hills_file); if (replica_hills_os) { From c4c8b0fc65c3917d7e850dea96a528c1740a32fc Mon Sep 17 00:00:00 2001 From: Fabrizio Marinelli Date: Wed, 31 Aug 2022 10:47:32 -0400 Subject: [PATCH 13/62] Changed some variables from int to size_t, this was giving error in the checks --- src/colvarbias_meta.cpp | 2 +- src/colvarbias_meta.h | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index 7c870e772..1e887023f 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -445,7 +445,7 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) cvm::log("Using multidimensional reflection \n"); int sum=1; int nstates; - int nvars=num_variables(); + size_t nvars=num_variables(); if (reflection_usel.size()==0) { reflection_usel.resize(nvars,std::vector(2)); } diff --git a/src/colvarbias_meta.h b/src/colvarbias_meta.h index ae787b395..9223c3762 100644 --- a/src/colvarbias_meta.h +++ b/src/colvarbias_meta.h @@ -232,8 +232,8 @@ class colvarbias_meta std::vector reflection_llimit_cv; std::vector reflection_ulimit_cv; cvm::real reflection_int; - int nrefvarsl; - int nrefvarsu; + size_t nrefvarsl; + size_t nrefvarsu; /// \brief Limits for reflection std::vector reflection_llimit; @@ -258,8 +258,8 @@ class colvarbias_meta std::vector which_int_llimit_cv; std::vector which_int_ulimit_cv; - int nintvarsl; - int nintvarsu; + size_t nintvarsl; + size_t nintvarsu; /// \brief Limits for interval std::vector interval_llimit; std::vector interval_ulimit; From 9b83dea5c1ab3cad50c9bc54373f9a724c103773 Mon Sep 17 00:00:00 2001 From: Fabrizio Marinelli Date: Wed, 31 Aug 2022 11:11:20 -0400 Subject: [PATCH 14/62] Changed some size_t to int --- src/colvarbias_meta.cpp | 70 ++++++++++++++++++++--------------------- src/colvarbias_meta.h | 8 ++--- 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index 1e887023f..b6df390aa 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -336,13 +336,13 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) get_keyval(conf, "reflectionUpLimitNCVs", nrefvarsu, num_variables()); if (reflection_llimit_cv.size()==0) { reflection_llimit_cv.resize(nrefvarsl); - for (size_t i = 0; i < nrefvarsl; i++) { + for (int i = 0; i < nrefvarsl; i++) { reflection_llimit_cv[i]=i; } } if (reflection_ulimit_cv.size()==0) { reflection_ulimit_cv.resize(nrefvarsu); - for (size_t i = 0; i < nrefvarsu; i++) { + for (int i = 0; i < nrefvarsu; i++) { reflection_ulimit_cv[i]=i; } } @@ -359,9 +359,9 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) cvm::log("Using all variables for lower limits of reflection \n"); } if (get_keyval(conf, "reflectionLowLimit", reflection_llimit, reflection_llimit)) { - for (size_t i = 0; i < nrefvarsl; i++) { + for (int i = 0; i < nrefvarsl; i++) { if (use_grids) { - size_t ii=reflection_llimit_cv[i]; + int ii=reflection_llimit_cv[i]; cvm:: real sigma=0.5*variables(ii)->width*hill_width; cvm:: real bound=variables(ii)->lower_boundary; cvm:: real ref_r=reflection_llimit[i]-reflection_int*sigma; @@ -388,9 +388,9 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) } if (get_keyval(conf, "reflectionUpLimit", reflection_ulimit, reflection_ulimit)) { - for (size_t i = 0; i < nrefvarsu; i++) { + for (int i = 0; i < nrefvarsu; i++) { if (use_grids) { - size_t ii=reflection_ulimit_cv[i]; + int ii=reflection_ulimit_cv[i]; cvm:: real sigma=0.5*variables(ii)->width*hill_width; cvm:: real bound=variables(ii)->upper_boundary; cvm:: real ref_r=reflection_ulimit[i]+reflection_int*sigma; @@ -409,7 +409,7 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) } // use reflection only with scalar variables - for (size_t i = 0; i < nrefvarsl; i++) { + for (int i = 0; i < nrefvarsl; i++) { if (reflection_llimit_cv[i]>=num_variables() || reflection_llimit_cv[i]<0) { cvm::error("Error: CV number is negative or >= num_variables \n", COLVARS_INPUT_ERROR); return COLVARS_INPUT_ERROR; @@ -421,7 +421,7 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) } } - for (size_t i = 0; i < nrefvarsu; i++) { + for (int i = 0; i < nrefvarsu; i++) { if (reflection_ulimit_cv[i]>=num_variables() || reflection_ulimit_cv[i]<0) { cvm::error("Error: CV number is negative or >= num_variables \n", COLVARS_INPUT_ERROR); return COLVARS_INPUT_ERROR; @@ -445,7 +445,7 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) cvm::log("Using multidimensional reflection \n"); int sum=1; int nstates; - size_t nvars=num_variables(); + int nvars=num_variables(); if (reflection_usel.size()==0) { reflection_usel.resize(nvars,std::vector(2)); } @@ -454,20 +454,20 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) reflection_l.resize(nvars,std::vector(2)); } - for (size_t j = 1; j < nvars; j++) { + for (int j = 1; j < nvars; j++) { reflection_usel[j][0]=false; reflection_l[j][0]=0.0; reflection_usel[j][1]=false; reflection_l[j][1]=0.0; } - for (size_t i = 0; i < nrefvarsl; i++) { + for (int i = 0; i < nrefvarsl; i++) { int j=reflection_llimit_cv[i]; reflection_usel[j][0]=true; reflection_l[j][0]=reflection_llimit[i]; } - for (size_t i = 0; i < nrefvarsu; i++) { + for (int i = 0; i < nrefvarsu; i++) { int j=reflection_ulimit_cv[i]; reflection_usel[j][1]=true; reflection_l[j][1]=reflection_ulimit[i]; @@ -496,18 +496,18 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) ref_state.resize(nvars,std::vector(1)); } ref_state[0][0]=1; - for (size_t j = 1; j < nvars; j++) { + for (int j = 1; j < nvars; j++) { sum*=10; nstates=0; - for (size_t jj = 0; jj < j; jj++) { + for (int jj = 0; jj < j; jj++) { nstates+=ref_state[j].size(); } nstates++; ref_state[j].resize(nstates); ref_state[j][0]=sum; int count=0; - for (size_t jj = 0; jj < j; jj++) { - for (size_t ii = 0; ii < ref_state[jj].size(); ii++) { + for (int jj = 0; jj < j; jj++) { + for (int ii = 0; ii < ref_state[jj].size(); ii++) { count++; ref_state[j][count]=ref_state[j][0]+ref_state[jj][ii]; } @@ -533,11 +533,11 @@ int colvarbias_meta::init_interval_params(std::string const &conf) get_keyval(conf, "intervalLowLimitNCVs", nintvarsl, num_variables()); get_keyval(conf, "intervalUpLimitNCVs", nintvarsu, num_variables()); interval_llimit_cv.resize(nintvarsl); - for (size_t i = 0; i < nintvarsl; i++) { + for (int i = 0; i < nintvarsl; i++) { interval_llimit_cv[i]=i; } interval_ulimit_cv.resize(nintvarsu); - for (size_t i = 0; i < nintvarsu; i++) { + for (int i = 0; i < nintvarsu; i++) { interval_ulimit_cv[i]=i; } if(nintvarsl>0) { @@ -549,7 +549,7 @@ int colvarbias_meta::init_interval_params(std::string const &conf) cvm::log("Using all variables for lower limits of interval \n"); } if (get_keyval(conf, "intervalLowLimit", interval_llimit, interval_llimit)) { - for (size_t i = 0; i < nintvarsl; i++) { + for (int i = 0; i < nintvarsl; i++) { cvm::log("Hills forces will be removed beyond a lower limit for CV "+cvm::to_str(interval_llimit_cv[i])+".\n"); cvm::log("Interval condition lower limit for this CV is "+cvm::to_str(interval_llimit[i])+".\n"); } @@ -569,7 +569,7 @@ int colvarbias_meta::init_interval_params(std::string const &conf) } if (get_keyval(conf, "intervalUpLimit", interval_ulimit, interval_ulimit)) { - for (size_t i = 0; i < nintvarsu; i++) { + for (int i = 0; i < nintvarsu; i++) { cvm::log("Hills forces will be removed beyond an upper limit for CV "+cvm::to_str(interval_ulimit_cv[i])+".\n"); cvm::log("Interval condition upper limit for this CV is "+cvm::to_str(interval_ulimit[i])+".\n"); } @@ -588,7 +588,7 @@ int colvarbias_meta::init_interval_params(std::string const &conf) if (interval_llimit.size()==0) { interval_llimit.resize(nintvarsl); } - for (size_t i = 0; i < nintvarsl; i++) { + for (int i = 0; i < nintvarsl; i++) { interval_llimit_cv[i]=reflection_llimit_cv[i]; interval_llimit[i]=reflection_llimit[i]; } @@ -596,7 +596,7 @@ int colvarbias_meta::init_interval_params(std::string const &conf) if (interval_ulimit.size()==0) { interval_ulimit.resize(nintvarsu); } - for (size_t i = 0; i < nintvarsu; i++) { + for (int i = 0; i < nintvarsu; i++) { interval_ulimit_cv[i]=reflection_ulimit_cv[i]; interval_ulimit[i]=reflection_ulimit[i]; } @@ -609,7 +609,7 @@ int colvarbias_meta::init_interval_params(std::string const &conf) for (size_t i = 0; i < num_variables(); i++) { which_int_llimit_cv[i]=-1; } - for (size_t i = 0; i < nintvarsl; i++) { + for (int i = 0; i < nintvarsl; i++) { int j=interval_llimit_cv[i]; which_int_llimit_cv[j]=i; } @@ -620,13 +620,13 @@ int colvarbias_meta::init_interval_params(std::string const &conf) for (size_t i = 0; i < num_variables(); i++) { which_int_ulimit_cv[i]=-1; } - for (size_t i = 0; i < nintvarsu; i++) { + for (int i = 0; i < nintvarsu; i++) { int j=interval_ulimit_cv[i]; which_int_ulimit_cv[j]=i; } // use interval only with scalar variables - for (size_t i = 0; i < nintvarsl; i++) { + for (int i = 0; i < nintvarsl; i++) { if (interval_llimit_cv[i]>=num_variables() || interval_llimit_cv[i]<0) { cvm::error("Error: CV number is negative or >= num_variables \n", COLVARS_INPUT_ERROR); return COLVARS_INPUT_ERROR; @@ -638,7 +638,7 @@ int colvarbias_meta::init_interval_params(std::string const &conf) } } - for (size_t i = 0; i < nintvarsu; i++) { + for (int i = 0; i < nintvarsu; i++) { if (interval_ulimit_cv[i]>=num_variables() || interval_ulimit_cv[i]<0) { cvm::error("Error: CV number is negative or >= num_variables \n", COLVARS_INPUT_ERROR); return COLVARS_INPUT_ERROR; @@ -709,14 +709,14 @@ colvarbias_meta::add_hill(colvarbias_meta::hill const &h) bool colvarbias_meta::check_reflection_limits(bool &ah) { - for (size_t i = 0; i < nrefvarsl; i++) { + for (int i = 0; i < nrefvarsl; i++) { int ii=reflection_llimit_cv[i]; cvm:: real cv_value=variables(ii)->value(); if (cv_valuevalue(); if (cv_value>reflection_ulimit[i]) { @@ -745,7 +745,7 @@ int colvarbias_meta::reflect_hill_multid(cvm::real const &h_scale) for (size_t i = 0; i < j; i++) { startsum*=10; } - for (size_t jj = 0; jj < ref_state[j].size(); jj++) { + for (int jj = 0; jj < ref_state[j].size(); jj++) { int getsum=startsum; int check_val=ref_state[j][jj]; int numberref=0; @@ -768,9 +768,9 @@ int colvarbias_meta::reflect_hill_multid(cvm::real const &h_scale) int nkstates=2; int kstate=0; - for (size_t k = 0; k 0) nkstates=ref_state[k].size(); - for (size_t kk = 0; kk < nkstates; kk++) { + for (int kk = 0; kk < nkstates; kk++) { if (k==0 && kk==1) { kstate=1; } else if (k>0) { @@ -1145,13 +1145,13 @@ int colvarbias_meta::update_bias() case rt_none: break; case rt_monod: - for (size_t i = 0; i < nrefvarsl; i++) { - size_t ii=reflection_llimit_cv[i]; + for (int i = 0; i < nrefvarsl; i++) { + int ii=reflection_llimit_cv[i]; reflect_hill_monod(ii, hills_scale, reflection_llimit[i]); } - for (size_t i = 0; i < nrefvarsu; i++) { - size_t ii=reflection_ulimit_cv[i]; + for (int i = 0; i < nrefvarsu; i++) { + int ii=reflection_ulimit_cv[i]; reflect_hill_monod(ii, hills_scale, reflection_ulimit[i]); } break; diff --git a/src/colvarbias_meta.h b/src/colvarbias_meta.h index 9223c3762..ae787b395 100644 --- a/src/colvarbias_meta.h +++ b/src/colvarbias_meta.h @@ -232,8 +232,8 @@ class colvarbias_meta std::vector reflection_llimit_cv; std::vector reflection_ulimit_cv; cvm::real reflection_int; - size_t nrefvarsl; - size_t nrefvarsu; + int nrefvarsl; + int nrefvarsu; /// \brief Limits for reflection std::vector reflection_llimit; @@ -258,8 +258,8 @@ class colvarbias_meta std::vector which_int_llimit_cv; std::vector which_int_ulimit_cv; - size_t nintvarsl; - size_t nintvarsu; + int nintvarsl; + int nintvarsu; /// \brief Limits for interval std::vector interval_llimit; std::vector interval_ulimit; From 8bd270c290cc9fede9e8a047b7f5efdf14c69917 Mon Sep 17 00:00:00 2001 From: Fabrizio Marinelli Date: Wed, 31 Aug 2022 11:27:14 -0400 Subject: [PATCH 15/62] Introduced nvars and int of num_variables as the latter is size_t --- src/colvarbias_meta.cpp | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index b6df390aa..0aa393425 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -319,6 +319,7 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) nrefvarsl=0; nrefvarsu=0; reflection_type = rt_none; + int nvars=num_variables(); get_keyval(conf, "useHillsReflection", use_reflection, false); if (use_reflection) { @@ -332,8 +333,8 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) reflection_type = rt_multid; } - get_keyval(conf, "reflectionLowLimitNCVs", nrefvarsl, num_variables()); - get_keyval(conf, "reflectionUpLimitNCVs", nrefvarsu, num_variables()); + get_keyval(conf, "reflectionLowLimitNCVs", nrefvarsl, nvars); + get_keyval(conf, "reflectionUpLimitNCVs", nrefvarsu, nvars); if (reflection_llimit_cv.size()==0) { reflection_llimit_cv.resize(nrefvarsl); for (int i = 0; i < nrefvarsl; i++) { @@ -410,7 +411,7 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) // use reflection only with scalar variables for (int i = 0; i < nrefvarsl; i++) { - if (reflection_llimit_cv[i]>=num_variables() || reflection_llimit_cv[i]<0) { + if (reflection_llimit_cv[i]>=nvars || reflection_llimit_cv[i]<0) { cvm::error("Error: CV number is negative or >= num_variables \n", COLVARS_INPUT_ERROR); return COLVARS_INPUT_ERROR; } @@ -422,7 +423,7 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) } for (int i = 0; i < nrefvarsu; i++) { - if (reflection_ulimit_cv[i]>=num_variables() || reflection_ulimit_cv[i]<0) { + if (reflection_ulimit_cv[i]>=nvars || reflection_ulimit_cv[i]<0) { cvm::error("Error: CV number is negative or >= num_variables \n", COLVARS_INPUT_ERROR); return COLVARS_INPUT_ERROR; } @@ -445,7 +446,6 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) cvm::log("Using multidimensional reflection \n"); int sum=1; int nstates; - int nvars=num_variables(); if (reflection_usel.size()==0) { reflection_usel.resize(nvars,std::vector(2)); } @@ -507,7 +507,7 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) ref_state[j][0]=sum; int count=0; for (int jj = 0; jj < j; jj++) { - for (int ii = 0; ii < ref_state[jj].size(); ii++) { + for (size_t ii = 0; ii < ref_state[jj].size(); ii++) { count++; ref_state[j][count]=ref_state[j][0]+ref_state[jj][ii]; } @@ -528,10 +528,11 @@ int colvarbias_meta::init_interval_params(std::string const &conf) nintvarsu=0; std::vector interval_llimit_cv; std::vector interval_ulimit_cv; + int nvars=num_variables(); if (get_keyval(conf, "useHillsInterval", use_interval, use_interval)) { if (use_interval) { - get_keyval(conf, "intervalLowLimitNCVs", nintvarsl, num_variables()); - get_keyval(conf, "intervalUpLimitNCVs", nintvarsu, num_variables()); + get_keyval(conf, "intervalLowLimitNCVs", nintvarsl, nvars); + get_keyval(conf, "intervalUpLimitNCVs", nintvarsu, nvars); interval_llimit_cv.resize(nintvarsl); for (int i = 0; i < nintvarsl; i++) { interval_llimit_cv[i]=i; @@ -604,9 +605,9 @@ int colvarbias_meta::init_interval_params(std::string const &conf) } if (which_int_llimit_cv.size()==0) { - which_int_llimit_cv.resize(num_variables()); + which_int_llimit_cv.resize(nvars); } - for (size_t i = 0; i < num_variables(); i++) { + for (int i = 0; i < nvars; i++) { which_int_llimit_cv[i]=-1; } for (int i = 0; i < nintvarsl; i++) { @@ -615,9 +616,9 @@ int colvarbias_meta::init_interval_params(std::string const &conf) } if (which_int_ulimit_cv.size()==0) { - which_int_ulimit_cv.resize(num_variables()); + which_int_ulimit_cv.resize(nvars); } - for (size_t i = 0; i < num_variables(); i++) { + for (int i = 0; i < nvars; i++) { which_int_ulimit_cv[i]=-1; } for (int i = 0; i < nintvarsu; i++) { @@ -627,7 +628,7 @@ int colvarbias_meta::init_interval_params(std::string const &conf) // use interval only with scalar variables for (int i = 0; i < nintvarsl; i++) { - if (interval_llimit_cv[i]>=num_variables() || interval_llimit_cv[i]<0) { + if (interval_llimit_cv[i]>=nvars || interval_llimit_cv[i]<0) { cvm::error("Error: CV number is negative or >= num_variables \n", COLVARS_INPUT_ERROR); return COLVARS_INPUT_ERROR; } @@ -639,7 +640,7 @@ int colvarbias_meta::init_interval_params(std::string const &conf) } for (int i = 0; i < nintvarsu; i++) { - if (interval_ulimit_cv[i]>=num_variables() || interval_ulimit_cv[i]<0) { + if (interval_ulimit_cv[i]>=nvars || interval_ulimit_cv[i]<0) { cvm::error("Error: CV number is negative or >= num_variables \n", COLVARS_INPUT_ERROR); return COLVARS_INPUT_ERROR; } @@ -745,7 +746,7 @@ int colvarbias_meta::reflect_hill_multid(cvm::real const &h_scale) for (size_t i = 0; i < j; i++) { startsum*=10; } - for (int jj = 0; jj < ref_state[j].size(); jj++) { + for (size_t jj = 0; jj < ref_state[j].size(); jj++) { int getsum=startsum; int check_val=ref_state[j][jj]; int numberref=0; From 84d96acb2fa8b667d3708d64ea98fccffac8d03a Mon Sep 17 00:00:00 2001 From: Fabrizio Marinelli Date: Wed, 31 Aug 2022 11:42:31 -0400 Subject: [PATCH 16/62] Trying to remove warnings causing problems in checks --- src/colvarbias_meta.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index 0aa393425..98af2fb17 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -743,7 +743,7 @@ int colvarbias_meta::reflect_hill_multid(cvm::real const &h_scale) for (size_t j = 0; j < num_variables(); j++) { int startsum=1; - for (size_t i = 0; i < j; i++) { + for (i = 0; i < j; i++) { startsum*=10; } for (size_t jj = 0; jj < ref_state[j].size(); jj++) { @@ -751,7 +751,7 @@ int colvarbias_meta::reflect_hill_multid(cvm::real const &h_scale) int check_val=ref_state[j][jj]; int numberref=0; int startsumk=1; - for (size_t i = 0; i <= j; i++) { + for (i = 0; i <= j; i++) { int upordown=std::floor(check_val/getsum); check_val=check_val-getsum; getsum=getsum/10; @@ -778,13 +778,13 @@ int colvarbias_meta::reflect_hill_multid(cvm::real const &h_scale) kstate=ref_state[k][kk]; } - int getsum=startsum; + getsum=startsum; int countstate=0; - int check_val=ref_state[j][jj]; + check_val=ref_state[j][jj]; bool hill_add=true; int getsumk=startsumk; int checkk=kstate; - for (size_t i = 0; i <= j; i++) { + for (i = 0; i <= j; i++) { int upordown=std::floor(check_val/getsum); int state=num_variables()-1-j+countstate; countstate++; @@ -833,11 +833,11 @@ int colvarbias_meta::reflect_hill_multid(cvm::real const &h_scale) break; } - for (size_t i = 0; i < num_variables(); i++) { + for (i = 0; i < num_variables(); i++) { curr_cv_values[i] = variables(i)->value(); // go back to previous values } } else { - for (size_t i = 0; i < num_variables(); i++) { + for (i = 0; i < num_variables(); i++) { curr_cv_values[i] = variables(i)->value(); // go back to previous values } } From 3c2c41cfae12edb129613cb22373c3b94068515d Mon Sep 17 00:00:00 2001 From: Fabrizio Marinelli Date: Wed, 31 Aug 2022 12:29:17 -0400 Subject: [PATCH 17/62] Trying to resolve "error: '>>' should be '> >' within a nested template argument list" in colvarbias_meta.h --- src/colvarbias_meta.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/colvarbias_meta.h b/src/colvarbias_meta.h index ae787b395..46058130a 100644 --- a/src/colvarbias_meta.h +++ b/src/colvarbias_meta.h @@ -249,7 +249,7 @@ class colvarbias_meta /// \brief Multidimensional reflection : store cvs to use and pointers to the limits std::vector > reflection_usel; - std::vector> reflection_l; + std::vector > reflection_l; /// \brief Multidimensional reflection or inversion states std::vector > ref_state; From 56146ff0a4577e7f8091d42767bf3aff291175cd Mon Sep 17 00:00:00 2001 From: Fabrizio Marinelli Date: Mon, 19 Sep 2022 11:25:52 -0400 Subject: [PATCH 18/62] Removed monodimensional reflection --- src/colvarbias_meta.cpp | 179 +++++++++++----------------------------- src/colvarbias_meta.h | 15 +--- 2 files changed, 47 insertions(+), 147 deletions(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index 98af2fb17..9550ca1bf 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -323,16 +323,6 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) get_keyval(conf, "useHillsReflection", use_reflection, false); if (use_reflection) { - reflection_type = rt_monod; - std::string reflection_type_str; - get_keyval(conf, "reflectionType", reflection_type_str, to_lower_cppstr(std::string("monoDimensional"))); - reflection_type_str = to_lower_cppstr(reflection_type_str); - if (reflection_type_str == to_lower_cppstr(std::string("monoDimensional"))) { - reflection_type = rt_monod; - } else if (reflection_type_str == to_lower_cppstr(std::string("multiDimensional"))) { - reflection_type = rt_multid; - } - get_keyval(conf, "reflectionLowLimitNCVs", nrefvarsl, nvars); get_keyval(conf, "reflectionUpLimitNCVs", nrefvarsu, nvars); if (reflection_llimit_cv.size()==0) { @@ -433,45 +423,37 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) return COLVARS_INPUT_ERROR; } } - // mono vs multimensional reflection + // multimensional reflection - switch (reflection_type) { - case rt_none: - break; - case rt_monod: - cvm::log("Using monodimensional reflection \n"); - break; - case rt_multid: - // generate reflection states - cvm::log("Using multidimensional reflection \n"); - int sum=1; - int nstates; - if (reflection_usel.size()==0) { - reflection_usel.resize(nvars,std::vector(2)); - } + // generate reflection states + int sum=1; + int nstates; + if (reflection_usel.size()==0) { + reflection_usel.resize(nvars,std::vector(2)); + } - if (reflection_l.size()==0) { - reflection_l.resize(nvars,std::vector(2)); - } + if (reflection_l.size()==0) { + reflection_l.resize(nvars,std::vector(2)); + } - for (int j = 1; j < nvars; j++) { - reflection_usel[j][0]=false; - reflection_l[j][0]=0.0; - reflection_usel[j][1]=false; - reflection_l[j][1]=0.0; - } + for (int j = 1; j < nvars; j++) { + reflection_usel[j][0]=false; + reflection_l[j][0]=0.0; + reflection_usel[j][1]=false; + reflection_l[j][1]=0.0; + } - for (int i = 0; i < nrefvarsl; i++) { - int j=reflection_llimit_cv[i]; - reflection_usel[j][0]=true; - reflection_l[j][0]=reflection_llimit[i]; - } + for (int i = 0; i < nrefvarsl; i++) { + int j=reflection_llimit_cv[i]; + reflection_usel[j][0]=true; + reflection_l[j][0]=reflection_llimit[i]; + } - for (int i = 0; i < nrefvarsu; i++) { - int j=reflection_ulimit_cv[i]; - reflection_usel[j][1]=true; - reflection_l[j][1]=reflection_ulimit[i]; - } + for (int i = 0; i < nrefvarsu; i++) { + int j=reflection_ulimit_cv[i]; + reflection_usel[j][1]=true; + reflection_l[j][1]=reflection_ulimit[i]; + } // Generate all possible reflection states (e.g. through faces, edges and vertex). // Consider for example a cube, the states are: @@ -492,31 +474,29 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) // ref_state[2][2]=ref_state[2][0]+ref_state[1][0] // ref_state[2][3]=ref_state[2][0]+ref_state[1][1] - if (ref_state.size()==0) { - ref_state.resize(nvars,std::vector(1)); + if (ref_state.size()==0) { + ref_state.resize(nvars,std::vector(1)); + } + ref_state[0][0]=1; + for (int j = 1; j < nvars; j++) { + sum*=10; + nstates=0; + for (int jj = 0; jj < j; jj++) { + nstates+=ref_state[j].size(); } - ref_state[0][0]=1; - for (int j = 1; j < nvars; j++) { - sum*=10; - nstates=0; - for (int jj = 0; jj < j; jj++) { - nstates+=ref_state[j].size(); - } - nstates++; - ref_state[j].resize(nstates); - ref_state[j][0]=sum; - int count=0; - for (int jj = 0; jj < j; jj++) { - for (size_t ii = 0; ii < ref_state[jj].size(); ii++) { - count++; - ref_state[j][count]=ref_state[j][0]+ref_state[jj][ii]; - } - } + nstates++; + ref_state[j].resize(nstates); + ref_state[j][0]=sum; + int count=0; + for (int jj = 0; jj < j; jj++) { + for (size_t ii = 0; ii < ref_state[jj].size(); ii++) { + count++; + ref_state[j][count]=ref_state[j][0]+ref_state[jj][ii]; + } } - - break; } + return COLVARS_OK; } @@ -848,56 +828,6 @@ int colvarbias_meta::reflect_hill_multid(cvm::real const &h_scale) return COLVARS_OK; } -int colvarbias_meta::reflect_hill_monod(int const &aa, - cvm::real const &h_scale, - cvm::real const &ref_lim) - -{ - size_t i = 0; - std::vector curr_cv_values(num_variables()); - for (i = 0; i < num_variables(); i++) { - curr_cv_values[i].type(variables(i)->value()); - } - for (i = 0; i < num_variables(); i++) { - curr_cv_values[i] = variables(i)->value(); - } - cvm:: real tmps=colvar_sigmas[aa]; - colvarvalue tmp=curr_cv_values[aa]; // store original current cv value - colvarvalue unitary=curr_cv_values[aa]; - unitary.set_ones(); - cvm:: real tmpd=ref_lim-cvm::real(curr_cv_values[aa]); - tmpd=std::sqrt(tmpd*tmpd); - if (tmpdget_output_stream(replica_hills_file); - if (replica_hills_os) { - *replica_hills_os << hills.back(); - } else { - return cvm::error("Error: in metadynamics bias \""+this->name+"\""+ - ((comm != single_replica) ? ", replica \""+replica_id+"\"" : "")+ - " while writing hills for the other replicas.\n", COLVARS_FILE_ERROR); - } - break; - } - curr_cv_values[aa]=tmp; // go back to previous value - } - return COLVARS_OK; -} - - std::list::const_iterator colvarbias_meta::delete_hill(hill_iter &h) { @@ -1142,24 +1072,7 @@ int colvarbias_meta::update_bias() // add reflected hills if required - switch (reflection_type) { - case rt_none: - break; - case rt_monod: - for (int i = 0; i < nrefvarsl; i++) { - int ii=reflection_llimit_cv[i]; - reflect_hill_monod(ii, hills_scale, reflection_llimit[i]); - } - - for (int i = 0; i < nrefvarsu; i++) { - int ii=reflection_ulimit_cv[i]; - reflect_hill_monod(ii, hills_scale, reflection_ulimit[i]); - } - break; - case rt_multid: - reflect_hill_multid(hills_scale); - break; - } + reflect_hill_multid(hills_scale); } diff --git a/src/colvarbias_meta.h b/src/colvarbias_meta.h index 46058130a..c3d7cc4b5 100644 --- a/src/colvarbias_meta.h +++ b/src/colvarbias_meta.h @@ -164,11 +164,6 @@ class colvarbias_meta /// \brief Multidimensional routine to reflect hills int reflect_hill_multid(cvm::real const &h_scale); - /// \brief Monodimensional routine to reflect hills - int reflect_hill_monod(int const &aa, - cvm::real const &h_scale, - cvm::real const &ref_lim); - /// \brief Calculate the values of the hills, incrementing /// bias_energy virtual void calc_hills(hill_iter h_first, @@ -239,19 +234,11 @@ class colvarbias_meta std::vector reflection_llimit; std::vector reflection_ulimit; - /// \brief Whether reflection are of mono or multidimensional type - enum reflection_type_e { - rt_monod, - rt_multid, - rt_none - }; - int reflection_type; - /// \brief Multidimensional reflection : store cvs to use and pointers to the limits std::vector > reflection_usel; std::vector > reflection_l; - /// \brief Multidimensional reflection or inversion states + /// \brief Multidimensional reflection states std::vector > ref_state; /// \brief For which variables hills forces beyond the boundaries(interval) must be removed From f68d95c585d2d5ba5c264f5c909fae21a1646c2e Mon Sep 17 00:00:00 2001 From: Fabrizio Marinelli Date: Tue, 27 Sep 2022 11:11:35 -0400 Subject: [PATCH 19/62] In calc_hills_force, boundary check is now outside the hills loop for efficiency --- src/colvarbias_meta.cpp | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index 9550ca1bf..b9270aadf 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -348,6 +348,10 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) } } else { cvm::log("Using all variables for lower limits of reflection \n"); + } + // if grids are defined define reflection boundaries as grid boundaries + if (use_grids) { + } if (get_keyval(conf, "reflectionLowLimit", reflection_llimit, reflection_llimit)) { for (int i = 0; i < nrefvarsl; i++) { @@ -1284,22 +1288,21 @@ void colvarbias_meta::calc_hills_force(size_t const &i, switch (x.type()) { case colvarvalue::type_scalar: - for (h = h_first; h != h_last; h++) { - if (h->value() == 0.0) continue; - colvarvalue const ¢er = h->centers[i]; - cvm::real const sigma = h->sigmas[i]; - - // if outside interval boundaries do not add force - bool add_force=true; - int ii=which_int_llimit_cv[i]; - if (ii>-1 && x[i]-1 && x[i]>interval_ulimit[ii] ) { - add_force=false; - } - if (add_force) { + // if outside interval boundaries do not add force + bool add_force=true; + int ii=which_int_llimit_cv[i]; + if (ii>-1 && x[i]-1 && x[i]>interval_ulimit[ii] ) { + add_force=false; + } + if (add_force) { + for (h = h_first; h != h_last; h++) { + if (h->value() == 0.0) continue; + colvarvalue const ¢er = h->centers[i]; + cvm::real const sigma = h->sigmas[i]; forces[i].real_value += ( h->weight() * h->value() * (0.5 / (sigma*sigma)) * (variables(i)->dist2_lgrad(x, center)).real_value ); From 566c7878112f952d86b6080ebd36720d1f7f0bca Mon Sep 17 00:00:00 2001 From: Fabrizio Marinelli Date: Tue, 27 Sep 2022 15:34:48 -0400 Subject: [PATCH 20/62] Modified init_reflection introducing lower and upper boundaries of the grid the default limits of reflection plus a few simplifications --- src/colvarbias_meta.cpp | 144 ++++++++++++++++++++++++---------------- 1 file changed, 88 insertions(+), 56 deletions(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index b9270aadf..2a780db0b 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -323,84 +323,116 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) get_keyval(conf, "useHillsReflection", use_reflection, false); if (use_reflection) { - get_keyval(conf, "reflectionLowLimitNCVs", nrefvarsl, nvars); - get_keyval(conf, "reflectionUpLimitNCVs", nrefvarsu, nvars); - if (reflection_llimit_cv.size()==0) { - reflection_llimit_cv.resize(nrefvarsl); - for (int i = 0; i < nrefvarsl; i++) { - reflection_llimit_cv[i]=i; + get_keyval(conf, "reflectionRange", reflection_int, 6.0); + cvm::log("Reflection range is "+cvm::to_str(reflection_int)+".\n"); + + if (get_keyval(conf, "reflectionLowLimitUseCVs", reflection_llimit_cv, reflection_llimit_cv)) { + nrefvarsl=reflection_llimit_cv.size(); + cvm::log("Using lower limits reflection on "+cvm::to_str(nrefvarsl)+" variables.\n"); + } else { + nrefvarsl=nvars; + if (reflection_llimit_cv.size()==0) { + reflection_llimit_cv.resize(nrefvarsl); + for (int i = 0; i < nrefvarsl; i++) { + reflection_llimit_cv[i]=i; + } } + cvm::log("Using all variables for lower limits of reflection \n"); } - if (reflection_ulimit_cv.size()==0) { + + if (reflection_llimit.size()==0) { + reflection_llimit.resize(nrefvarsl); + } + + if (get_keyval(conf, "reflectionUpLimitUseCVs", reflection_ulimit_cv, reflection_ulimit_cv)) { + nrefvarsu=reflection_ulimit_cv.size(); + cvm::log("Using upper limits reflection on "+cvm::to_str(nrefvarsu)+" variables.\n"); + } else { + nrefvarsu=nvars; reflection_ulimit_cv.resize(nrefvarsu); for (int i = 0; i < nrefvarsu; i++) { reflection_ulimit_cv[i]=i; } + cvm::log("Using all variables for upper limits of reflection \n"); } - if (nrefvarsl>0 || nrefvarsu>0) { - get_keyval(conf, "reflectionRange", reflection_int, 6.0); - cvm::log("Reflection range is "+cvm::to_str(reflection_int)+".\n"); + + if (reflection_ulimit.size()==0) { + reflection_ulimit.resize(nrefvarsu); } - if(nrefvarsl>0) { - if (get_keyval(conf, "reflectionLowLimitUseCVs", reflection_llimit_cv, reflection_llimit_cv)) { - if (reflection_llimit.size()==0) { - reflection_llimit.resize(nrefvarsl); - } - } else { - cvm::log("Using all variables for lower limits of reflection \n"); + + // if grids and hard boundaries are defined set by default reflection boundaries as grid boundaries + if (use_grids) { + std::vector ref_lower_boundaries(hills_energy->lower_boundaries); + std::vector ref_upper_boundaries(hills_energy->upper_boundaries); + for (int i = 0; i < nrefvarsl; i++) { + int ii=reflection_llimit_cv[i]; + if (variables(ii)->is_enabled(f_cv_hard_lower_boundary)) { + reflection_llimit[i]=ref_lower_boundaries[ii].real_value; + } } - // if grids are defined define reflection boundaries as grid boundaries - if (use_grids) { - + for (int i = 0; i < nrefvarsu; i++) { + int ii=reflection_ulimit_cv[i]; + if (variables(ii)->is_enabled(f_cv_hard_upper_boundary)) { + reflection_ulimit[i]=ref_upper_boundaries[ii].real_value; + } } - if (get_keyval(conf, "reflectionLowLimit", reflection_llimit, reflection_llimit)) { - for (int i = 0; i < nrefvarsl; i++) { - if (use_grids) { - int ii=reflection_llimit_cv[i]; - cvm:: real sigma=0.5*variables(ii)->width*hill_width; - cvm:: real bound=variables(ii)->lower_boundary; - cvm:: real ref_r=reflection_llimit[i]-reflection_int*sigma; - if (ref_r < bound) { - cvm::error("Error: When using grids, lower boundary for CV"+cvm::to_str(ii)+" must be smaller than"+cvm::to_str(ref_r)+".\n", COLVARS_INPUT_ERROR); - } + } + + if (get_keyval(conf, "reflectionLowLimit", reflection_llimit, reflection_llimit)) { + for (int i = 0; i < nrefvarsl; i++) { + if (use_grids) { + int ii=reflection_llimit_cv[i]; + cvm:: real bound=ref_lower_boundaries[ii].real_value; + if (reflection_llimit[i] < bound) { + cvm::error("Error: When using grids, grid lower boundary for CV"+cvm::to_str(ii)+" must be equal or smaller than"+cvm::to_str(reflection_llimit[i])+".\n", COLVARS_INPUT_ERROR); } - cvm::log("Reflection condition is applied on a lower limit for CV "+cvm::to_str(reflection_llimit_cv[i])+".\n"); - cvm::log("Reflection condition lower limit for this CV is "+cvm::to_str(reflection_llimit[i])+".\n"); - } + } + } + } else { + if (use_grids) { + for (int i = 0; i < nrefvarsl; i++) { + int ii=reflection_llimit_cv[i]; + if (!variables(ii)->is_enabled(f_cv_hard_lower_boundary)) { + cvm::error("Error: Lower limits for reflection not provided.\n", COLVARS_INPUT_ERROR); + } + } } else { cvm::error("Error: Lower limits for reflection not provided.\n", COLVARS_INPUT_ERROR); - return COLVARS_INPUT_ERROR; } } - if(nrefvarsu>0) { - if (get_keyval(conf, "reflectionUpLimitUseCVs", reflection_ulimit_cv, reflection_ulimit_cv)) { - if (reflection_ulimit.size()==0) { - reflection_ulimit.resize(nrefvarsu); - } - } else { - cvm::log("Using all variables for upper limits of reflection \n"); - } + for (int i = 0; i < nrefvarsl; i++) { + cvm::log("Reflection condition is applied on a lower limit for CV "+cvm::to_str(reflection_llimit_cv[i])+".\n"); + cvm::log("Reflection condition lower limit for this CV is "+cvm::to_str(reflection_llimit[i])+".\n"); + } - if (get_keyval(conf, "reflectionUpLimit", reflection_ulimit, reflection_ulimit)) { - for (int i = 0; i < nrefvarsu; i++) { - if (use_grids) { - int ii=reflection_ulimit_cv[i]; - cvm:: real sigma=0.5*variables(ii)->width*hill_width; - cvm:: real bound=variables(ii)->upper_boundary; - cvm:: real ref_r=reflection_ulimit[i]+reflection_int*sigma; - if (ref_r > bound) { - cvm::error("Error: When using grids, upper boundary for CV"+cvm::to_str(ii)+" must be larger than"+cvm::to_str(ref_r)+".\n", COLVARS_INPUT_ERROR); - } + if (get_keyval(conf, "reflectionUpLimit", reflection_ulimit, reflection_ulimit)) { + for (int i = 0; i < nrefvarsu; i++) { + if (use_grids) { + int ii=reflection_ulimit_cv[i]; + cvm:: real bound=ref_upper_boundaries[ii].real_value; + if (reflection_ulimit[i] > bound) { + cvm::error("Error: When using grids, upper boundary for CV"+cvm::to_str(ii)+" must be larger than"+cvm::to_str(reflection_ulimit[i])+".\n", COLVARS_INPUT_ERROR); } - cvm::log("Reflection condition is applied on an upper limit for CV "+cvm::to_str(reflection_ulimit_cv[i])+".\n"); - cvm::log("Reflection condition upper limit for this CV is "+cvm::to_str(reflection_ulimit[i])+".\n"); - } + } + } + } else { + if (use_grids) { + for (int i = 0; i < nrefvarsu; i++) { + int ii=reflection_ulimit_cv[i]; + if (!variables(ii)->is_enabled(f_cv_hard_upper_boundary)) { + cvm::error("Error: Upper limits for reflection not provided.\n", COLVARS_INPUT_ERROR); + } + } } else { cvm::error("Error: Upper limits for reflection not provided.\n", COLVARS_INPUT_ERROR); - return COLVARS_INPUT_ERROR; } } + + for (int i = 0; i < nrefvarsu; i++) { + cvm::log("Reflection condition is applied on an upper limit for CV "+cvm::to_str(reflection_ulimit_cv[i])+".\n"); + cvm::log("Reflection condition upper limit for this CV is "+cvm::to_str(reflection_ulimit[i])+".\n"); + } } // use reflection only with scalar variables From 456d602c7837be38c7b3f3a930a01a87bcd4d925 Mon Sep 17 00:00:00 2001 From: Fabrizio Marinelli Date: Tue, 27 Sep 2022 15:38:48 -0400 Subject: [PATCH 21/62] reflection_type removed --- src/colvarbias_meta.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index 2a780db0b..9c6abe8e8 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -318,7 +318,6 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) bool use_reflection; nrefvarsl=0; nrefvarsu=0; - reflection_type = rt_none; int nvars=num_variables(); get_keyval(conf, "useHillsReflection", use_reflection, false); if (use_reflection) { From 1b62ff3da82716ba93dd4365383a20b4c9b2774f Mon Sep 17 00:00:00 2001 From: Fabrizio Marinelli Date: Tue, 27 Sep 2022 16:30:52 -0400 Subject: [PATCH 22/62] reflection states generated only if reflection is active --- src/colvarbias_meta.cpp | 235 ++++++++++++++++++++-------------------- 1 file changed, 119 insertions(+), 116 deletions(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index 9c6abe8e8..4785e01c8 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -359,44 +359,71 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) reflection_ulimit.resize(nrefvarsu); } - // if grids and hard boundaries are defined set by default reflection boundaries as grid boundaries + // use reflection only with scalar variables + + for (int i = 0; i < nrefvarsl; i++) { + if (reflection_llimit_cv[i]>=nvars || reflection_llimit_cv[i]<0) { + cvm::error("Error: CV number is negative or >= num_variables \n", COLVARS_INPUT_ERROR); + return COLVARS_INPUT_ERROR; + } + int j=reflection_llimit_cv[i]; + if (variables(j)->value().type()!=colvarvalue::type_scalar) { + cvm::error("Error: Hills reflection can be used only with scalar variables.\n", COLVARS_INPUT_ERROR); + return COLVARS_INPUT_ERROR; + } + } + + for (int i = 0; i < nrefvarsu; i++) { + if (reflection_ulimit_cv[i]>=nvars || reflection_ulimit_cv[i]<0) { + cvm::error("Error: CV number is negative or >= num_variables \n", COLVARS_INPUT_ERROR); + return COLVARS_INPUT_ERROR; + } + int j=reflection_ulimit_cv[i]; + if (variables(j)->value().type()!=colvarvalue::type_scalar) { + cvm::error("Error: Hills reflection can be used only with scalar variables.\n", COLVARS_INPUT_ERROR); + return COLVARS_INPUT_ERROR; + } + } + + // if grids and hard boundaries are defined, set by default reflection boundaries as grid boundaries if (use_grids) { - std::vector ref_lower_boundaries(hills_energy->lower_boundaries); - std::vector ref_upper_boundaries(hills_energy->upper_boundaries); for (int i = 0; i < nrefvarsl; i++) { int ii=reflection_llimit_cv[i]; if (variables(ii)->is_enabled(f_cv_hard_lower_boundary)) { - reflection_llimit[i]=ref_lower_boundaries[ii].real_value; + reflection_llimit[i]=hills_energy->lower_boundaries[ii].real_value; } } for (int i = 0; i < nrefvarsu; i++) { int ii=reflection_ulimit_cv[i]; if (variables(ii)->is_enabled(f_cv_hard_upper_boundary)) { - reflection_ulimit[i]=ref_upper_boundaries[ii].real_value; + reflection_ulimit[i]=hills_energy->upper_boundaries[ii].real_value; } } } - if (get_keyval(conf, "reflectionLowLimit", reflection_llimit, reflection_llimit)) { - for (int i = 0; i < nrefvarsl; i++) { - if (use_grids) { - int ii=reflection_llimit_cv[i]; - cvm:: real bound=ref_lower_boundaries[ii].real_value; - if (reflection_llimit[i] < bound) { - cvm::error("Error: When using grids, grid lower boundary for CV"+cvm::to_str(ii)+" must be equal or smaller than"+cvm::to_str(reflection_llimit[i])+".\n", COLVARS_INPUT_ERROR); - } - } - } - } else { - if (use_grids) { + + if (nrefvarsl>0) { + if (get_keyval(conf, "reflectionLowLimit", reflection_llimit, reflection_llimit)) { for (int i = 0; i < nrefvarsl; i++) { - int ii=reflection_llimit_cv[i]; - if (!variables(ii)->is_enabled(f_cv_hard_lower_boundary)) { - cvm::error("Error: Lower limits for reflection not provided.\n", COLVARS_INPUT_ERROR); - } - } + if (use_grids) { + int ii=reflection_llimit_cv[i]; + cvm:: real bound=ref_lower_boundaries[ii].real_value; + if (reflection_llimit[i] < bound) { + cvm::error("Error: When using grids, grid lower boundary for CV"+cvm::to_str(ii)+" must be equal or smaller than"+cvm::to_str(reflection_llimit[i])+".\n", COLVARS_INPUT_ERROR); + } + } + } } else { - cvm::error("Error: Lower limits for reflection not provided.\n", COLVARS_INPUT_ERROR); + if (use_grids) { + for (int i = 0; i < nrefvarsl; i++) { + int ii=reflection_llimit_cv[i]; + if (!variables(ii)->is_enabled(f_cv_hard_lower_boundary)) { + cvm::error("Error: Lower limits for reflection not provided.\n", COLVARS_INPUT_ERROR); + } + } + } else { + cvm::error("Error: Lower limits for reflection not provided.\n", COLVARS_INPUT_ERROR); + } } } @@ -405,26 +432,28 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) cvm::log("Reflection condition lower limit for this CV is "+cvm::to_str(reflection_llimit[i])+".\n"); } - if (get_keyval(conf, "reflectionUpLimit", reflection_ulimit, reflection_ulimit)) { - for (int i = 0; i < nrefvarsu; i++) { - if (use_grids) { - int ii=reflection_ulimit_cv[i]; - cvm:: real bound=ref_upper_boundaries[ii].real_value; - if (reflection_ulimit[i] > bound) { - cvm::error("Error: When using grids, upper boundary for CV"+cvm::to_str(ii)+" must be larger than"+cvm::to_str(reflection_ulimit[i])+".\n", COLVARS_INPUT_ERROR); - } - } - } - } else { - if (use_grids) { + if (nrefvarsu>0) { + if (get_keyval(conf, "reflectionUpLimit", reflection_ulimit, reflection_ulimit)) { for (int i = 0; i < nrefvarsu; i++) { - int ii=reflection_ulimit_cv[i]; - if (!variables(ii)->is_enabled(f_cv_hard_upper_boundary)) { - cvm::error("Error: Upper limits for reflection not provided.\n", COLVARS_INPUT_ERROR); - } + if (use_grids) { + int ii=reflection_ulimit_cv[i]; + cvm:: real bound=ref_upper_boundaries[ii].real_value; + if (reflection_ulimit[i] > bound) { + cvm::error("Error: When using grids, upper boundary for CV"+cvm::to_str(ii)+" must be larger than"+cvm::to_str(reflection_ulimit[i])+".\n", COLVARS_INPUT_ERROR); + } + } } } else { - cvm::error("Error: Upper limits for reflection not provided.\n", COLVARS_INPUT_ERROR); + if (use_grids) { + for (int i = 0; i < nrefvarsu; i++) { + int ii=reflection_ulimit_cv[i]; + if (!variables(ii)->is_enabled(f_cv_hard_upper_boundary)) { + cvm::error("Error: Upper limits for reflection not provided.\n", COLVARS_INPUT_ERROR); + } + } + } else { + cvm::error("Error: Upper limits for reflection not provided.\n", COLVARS_INPUT_ERROR); + } } } @@ -432,63 +461,38 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) cvm::log("Reflection condition is applied on an upper limit for CV "+cvm::to_str(reflection_ulimit_cv[i])+".\n"); cvm::log("Reflection condition upper limit for this CV is "+cvm::to_str(reflection_ulimit[i])+".\n"); } - } - // use reflection only with scalar variables - for (int i = 0; i < nrefvarsl; i++) { - if (reflection_llimit_cv[i]>=nvars || reflection_llimit_cv[i]<0) { - cvm::error("Error: CV number is negative or >= num_variables \n", COLVARS_INPUT_ERROR); - return COLVARS_INPUT_ERROR; - } - int j=reflection_llimit_cv[i]; - if (variables(j)->value().type()!=colvarvalue::type_scalar) { - cvm::error("Error: Hills reflection can be used only with scalar variables.\n", COLVARS_INPUT_ERROR); - return COLVARS_INPUT_ERROR; - } - } - - for (int i = 0; i < nrefvarsu; i++) { - if (reflection_ulimit_cv[i]>=nvars || reflection_ulimit_cv[i]<0) { - cvm::error("Error: CV number is negative or >= num_variables \n", COLVARS_INPUT_ERROR); - return COLVARS_INPUT_ERROR; - } - int j=reflection_ulimit_cv[i]; - if (variables(j)->value().type()!=colvarvalue::type_scalar) { - cvm::error("Error: Hills reflection can be used only with scalar variables.\n", COLVARS_INPUT_ERROR); - return COLVARS_INPUT_ERROR; - } - } - // multimensional reflection - - // generate reflection states - int sum=1; - int nstates; - if (reflection_usel.size()==0) { - reflection_usel.resize(nvars,std::vector(2)); - } - - if (reflection_l.size()==0) { - reflection_l.resize(nvars,std::vector(2)); - } - - for (int j = 1; j < nvars; j++) { - reflection_usel[j][0]=false; - reflection_l[j][0]=0.0; - reflection_usel[j][1]=false; - reflection_l[j][1]=0.0; - } - - for (int i = 0; i < nrefvarsl; i++) { - int j=reflection_llimit_cv[i]; - reflection_usel[j][0]=true; - reflection_l[j][0]=reflection_llimit[i]; - } + // multimensional reflection - for (int i = 0; i < nrefvarsu; i++) { - int j=reflection_ulimit_cv[i]; - reflection_usel[j][1]=true; - reflection_l[j][1]=reflection_ulimit[i]; - } + // generate reflection states + int sum=1; + int nstates; + if (reflection_usel.size()==0) { + reflection_usel.resize(nvars,std::vector(2)); + } + + if (reflection_l.size()==0) { + reflection_l.resize(nvars,std::vector(2)); + } + + for (int j = 1; j < nvars; j++) { + reflection_usel[j][0]=false; + reflection_l[j][0]=0.0; + reflection_usel[j][1]=false; + reflection_l[j][1]=0.0; + } + + for (int i = 0; i < nrefvarsl; i++) { + int j=reflection_llimit_cv[i]; + reflection_usel[j][0]=true; + reflection_l[j][0]=reflection_llimit[i]; + } + + for (int i = 0; i < nrefvarsu; i++) { + int j=reflection_ulimit_cv[i]; + reflection_usel[j][1]=true; + reflection_l[j][1]=reflection_ulimit[i]; + } // Generate all possible reflection states (e.g. through faces, edges and vertex). // Consider for example a cube, the states are: @@ -509,29 +513,28 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) // ref_state[2][2]=ref_state[2][0]+ref_state[1][0] // ref_state[2][3]=ref_state[2][0]+ref_state[1][1] - if (ref_state.size()==0) { - ref_state.resize(nvars,std::vector(1)); - } - ref_state[0][0]=1; - for (int j = 1; j < nvars; j++) { - sum*=10; - nstates=0; - for (int jj = 0; jj < j; jj++) { - nstates+=ref_state[j].size(); - } - nstates++; - ref_state[j].resize(nstates); - ref_state[j][0]=sum; - int count=0; - for (int jj = 0; jj < j; jj++) { - for (size_t ii = 0; ii < ref_state[jj].size(); ii++) { - count++; - ref_state[j][count]=ref_state[j][0]+ref_state[jj][ii]; - } + if (ref_state.size()==0) { + ref_state.resize(nvars,std::vector(1)); + } + ref_state[0][0]=1; + for (int j = 1; j < nvars; j++) { + sum*=10; + nstates=0; + for (int jj = 0; jj < j; jj++) { + nstates+=ref_state[j].size(); + } + nstates++; + ref_state[j].resize(nstates); + ref_state[j][0]=sum; + int count=0; + for (int jj = 0; jj < j; jj++) { + for (size_t ii = 0; ii < ref_state[jj].size(); ii++) { + count++; + ref_state[j][count]=ref_state[j][0]+ref_state[jj][ii]; + } + } } } - - return COLVARS_OK; } From 692821b8ef36fd80b58dc527c90c89d6f6d6beb5 Mon Sep 17 00:00:00 2001 From: Fabrizio Marinelli Date: Wed, 28 Sep 2022 09:06:24 -0400 Subject: [PATCH 23/62] removed i index onn interval in calc_hills_force --- src/colvarbias_meta.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index 4785e01c8..799d22ac4 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -1325,11 +1325,11 @@ void colvarbias_meta::calc_hills_force(size_t const &i, // if outside interval boundaries do not add force bool add_force=true; int ii=which_int_llimit_cv[i]; - if (ii>-1 && x[i]-1 && x-1 && x[i]>interval_ulimit[ii] ) { + if (ii>-1 && x>interval_ulimit[ii] ) { add_force=false; } if (add_force) { From f3af47b102aca45fe3ebdcb209a4a2188d13ae9c Mon Sep 17 00:00:00 2001 From: Fabrizio Marinelli Date: Wed, 28 Sep 2022 09:18:15 -0400 Subject: [PATCH 24/62] modifed cal_hills to account for interval --- src/colvarbias_meta.cpp | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index 799d22ac4..6daf6da4c 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -1282,6 +1282,38 @@ void colvarbias_meta::calc_hills(colvarbias_meta::hill_iter h_first, { size_t i = 0; + std::vector curr_values(num_variables()); + for (i = 0; i < num_variables(); i++) { + curr_values[i].type(variables(i)->value()); + } + + if (colvar_values.size()) { + for (i = 0; i < num_variables(); i++) { + curr_values[i] = colvar_values[i]; + } + } else { + for (i = 0; i < num_variables(); i++) { + curr_values[i] = variables(i)->value(); + } + } + + // modifications for interval: if curr_value is out of the border assign value at the border + + for (i = 0; i < num_variables(); i++) { + int ii=which_int_llimit_cv[i]; + if (ii>-1) { + if (curr_values[i]-1) { + if (curr_values[i]>interval_ulimit[ii]){ + curr_values[i]=interval_ulimit[ii]; + } + } + } + for (hill_iter h = h_first; h != h_last; h++) { // compute the gaussian exponent From 4b5b2f214088eaa59dc8bfd819a65fdbfaa78fac Mon Sep 17 00:00:00 2001 From: Fabrizio Marinelli Date: Wed, 28 Sep 2022 10:59:41 -0400 Subject: [PATCH 25/62] Finished adding curr_values to calc_hills to account for interval --- src/colvarbias_meta.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index 6daf6da4c..9364eaeb1 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -1319,7 +1319,7 @@ void colvarbias_meta::calc_hills(colvarbias_meta::hill_iter h_first, // compute the gaussian exponent cvm::real cv_sqdev = 0.0; for (i = 0; i < num_variables(); i++) { - colvarvalue const &x = values ? (*values)[i] : colvar_values[i]; + colvarvalue const &x = curr_values[i]; colvarvalue const ¢er = h->centers[i]; cvm::real const sigma = h->sigmas[i]; cv_sqdev += (variables(i)->dist2(x, center)) / (sigma*sigma); From e1624cda83528edb3c5683a06a6c6452642359b1 Mon Sep 17 00:00:00 2001 From: Fabrizio Marinelli Date: Wed, 28 Sep 2022 11:33:53 -0400 Subject: [PATCH 26/62] some changes of declaratins leading to compilation error --- src/colvarbias_meta.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index 9364eaeb1..0dfdcf968 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -407,7 +407,7 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) for (int i = 0; i < nrefvarsl; i++) { if (use_grids) { int ii=reflection_llimit_cv[i]; - cvm:: real bound=ref_lower_boundaries[ii].real_value; + cvm:: real bound=hills_energy->lower_boundaries[ii].real_value; if (reflection_llimit[i] < bound) { cvm::error("Error: When using grids, grid lower boundary for CV"+cvm::to_str(ii)+" must be equal or smaller than"+cvm::to_str(reflection_llimit[i])+".\n", COLVARS_INPUT_ERROR); } @@ -437,7 +437,7 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) for (int i = 0; i < nrefvarsu; i++) { if (use_grids) { int ii=reflection_ulimit_cv[i]; - cvm:: real bound=ref_upper_boundaries[ii].real_value; + cvm:: real bound=hills_energy->upper_boundaries[ii].real_value; if (reflection_ulimit[i] > bound) { cvm::error("Error: When using grids, upper boundary for CV"+cvm::to_str(ii)+" must be larger than"+cvm::to_str(reflection_ulimit[i])+".\n", COLVARS_INPUT_ERROR); } @@ -1355,8 +1355,10 @@ void colvarbias_meta::calc_hills_force(size_t const &i, case colvarvalue::type_scalar: // if outside interval boundaries do not add force - bool add_force=true; - int ii=which_int_llimit_cv[i]; + bool add_force; + add_force=true; + int ii; + ii=which_int_llimit_cv[i]; if (ii>-1 && x Date: Thu, 29 Sep 2022 12:32:31 -0400 Subject: [PATCH 27/62] Modified calc_energy and project_hills to account for hills reflection+interval --- src/colvarbias_meta.cpp | 96 ++++++++++++++++++++++++----------------- src/colvarbias_meta.h | 2 + 2 files changed, 58 insertions(+), 40 deletions(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index 0dfdcf968..c7de1e286 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -540,7 +540,6 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) int colvarbias_meta::init_interval_params(std::string const &conf) { - bool use_interval; use_interval=false; nintvarsl=0; nintvarsu=0; @@ -600,6 +599,7 @@ int colvarbias_meta::init_interval_params(std::string const &conf) } } else { if (nrefvarsl>0 || nrefvarsu>0) { + use_interval=true; cvm::log("Reflection active: Using by default reflection variables and limits for interval \n"); nintvarsl=nrefvarsl; nintvarsu=nrefvarsu; @@ -1148,12 +1148,43 @@ int colvarbias_meta::calc_energy(std::vector const *values) { size_t ir = 0; + // interval + if (use_interval) { + size_t i; + size_t ii; + std::vector curr_values(num_variables()); + for (i = 0; i < num_variables(); i++) { + curr_values[i].type(variables(i)->value()); + } + + if ((*values).size()) { + for (i = 0; i < num_variables(); i++) { + curr_values[i] = (*values)[i]; + } + } else { + for (i = 0; i < num_variables(); i++) { + curr_values[i] = variables(i)->value(); + } + } + for (i = 0; i < num_variables(); i++) { + ii=which_int_llimit_cv[i]; + if (ii>-1 && curr_values[i]-1 && curr_values[i]>interval_ulimit[ii] ) { + curr_values[i]=interval_ulimit[ii]; + } + } + } else { + std::vector const &curr_values=values ? (*values) : colvar_values; + } + for (ir = 0; ir < replicas.size(); ir++) { replicas[ir]->bias_energy = 0.0; } - bool index_ok = false; - std::vector curr_bin; + std::vector const curr_bin = hills_energy->get_colvars_index(curr_values); if (use_grids) { @@ -1184,7 +1215,7 @@ int colvarbias_meta::calc_energy(std::vector const *values) calc_hills(replicas[ir]->hills_off_grid.begin(), replicas[ir]->hills_off_grid.end(), bias_energy, - values); + curr_values); } } @@ -1195,7 +1226,7 @@ int colvarbias_meta::calc_energy(std::vector const *values) calc_hills(replicas[ir]->new_hills_begin, replicas[ir]->hills.end(), bias_energy, - values); + curr_values); if (cvm::debug()) { cvm::log("Hills energy = "+cvm::to_str(bias_energy)+".\n"); } @@ -1282,44 +1313,12 @@ void colvarbias_meta::calc_hills(colvarbias_meta::hill_iter h_first, { size_t i = 0; - std::vector curr_values(num_variables()); - for (i = 0; i < num_variables(); i++) { - curr_values[i].type(variables(i)->value()); - } - - if (colvar_values.size()) { - for (i = 0; i < num_variables(); i++) { - curr_values[i] = colvar_values[i]; - } - } else { - for (i = 0; i < num_variables(); i++) { - curr_values[i] = variables(i)->value(); - } - } - - // modifications for interval: if curr_value is out of the border assign value at the border - - for (i = 0; i < num_variables(); i++) { - int ii=which_int_llimit_cv[i]; - if (ii>-1) { - if (curr_values[i]-1) { - if (curr_values[i]>interval_ulimit[ii]){ - curr_values[i]=interval_ulimit[ii]; - } - } - } - for (hill_iter h = h_first; h != h_last; h++) { // compute the gaussian exponent cvm::real cv_sqdev = 0.0; for (i = 0; i < num_variables(); i++) { - colvarvalue const &x = curr_values[i]; + colvarvalue const &x = values ? (*values)[i] : colvar_values[i]; colvarvalue const ¢er = h->centers[i]; cvm::real const sigma = h->sigmas[i]; cv_sqdev += (variables(i)->dist2(x, center)) / (sigma*sigma); @@ -1440,6 +1439,9 @@ void colvarbias_meta::project_hills(colvarbias_meta::hill_iter h_first, // TODO: improve it by looping over a small subgrid instead of the whole grid std::vector new_colvar_values(num_variables()); + // vector defined to account for reflection+interval + std::vector new_hcolvar_values(num_variables()); + std::vector colvar_forces_scalar(num_variables()); std::vector he_ix = he->new_index(); @@ -1453,17 +1455,31 @@ void colvarbias_meta::project_hills(colvarbias_meta::hill_iter h_first, if (hg != NULL) { // loop over the points of the grid + size_t i; + size_t ii; for ( ; (he->index_ok(he_ix)) && (hg->index_ok(hg_ix)); count++) { - size_t i; for (i = 0; i < num_variables(); i++) { new_colvar_values[i] = he->bin_to_value_scalar(he_ix[i], i); + new_hcolvar_values[i] = he->bin_to_value_scalar(he_ix[i], i); + ii=which_int_llimit_cv[i]; + if (ii>-1 ){ + if ( new_hcolvar_values[i]-1){ + if( new_hcolvar_values[i]>interval_ulimit[ii] ) { + new_hcolvar_values[i]=interval_ulimit[ii]; + } + } } // loop over the hills and increment the energy grid locally hills_energy_here = 0.0; - calc_hills(h_first, h_last, hills_energy_here, &new_colvar_values); + calc_hills(h_first, h_last, hills_energy_here, &new_hcolvar_values); he->acc_value(he_ix, hills_energy_here); for (i = 0; i < num_variables(); i++) { diff --git a/src/colvarbias_meta.h b/src/colvarbias_meta.h index c3d7cc4b5..7308e5a0b 100644 --- a/src/colvarbias_meta.h +++ b/src/colvarbias_meta.h @@ -241,6 +241,8 @@ class colvarbias_meta /// \brief Multidimensional reflection states std::vector > ref_state; + /// \brief whether using interval + bool use_interval; /// \brief For which variables hills forces beyond the boundaries(interval) must be removed std::vector which_int_llimit_cv; From 89df2e0fc753b10ae38325db827b0e1058fef5f9 Mon Sep 17 00:00:00 2001 From: Fabrizio Marinelli Date: Thu, 29 Sep 2022 13:16:14 -0400 Subject: [PATCH 28/62] condition for reflection+interval added externally to calc_hills_force --- src/colvarbias_meta.cpp | 98 +++++++++++++++++++++++------------------ 1 file changed, 56 insertions(+), 42 deletions(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index c7de1e286..4388f8828 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -1238,15 +1238,34 @@ int colvarbias_meta::calc_energy(std::vector const *values) int colvarbias_meta::calc_forces(std::vector const *values) { + std::vector const &curr_values=values ? (*values) : colvar_values; size_t ir = 0, ic = 0; + std::vector add_force(num_variables()); for (ir = 0; ir < replicas.size(); ir++) { for (ic = 0; ic < num_variables(); ic++) { replicas[ir]->colvar_forces[ic].reset(); } } + + + for (ic = 0; ic < num_variables(); ic++) { + add_force[ic]=true; + int ii; + ii=which_int_llimit_cv[ic]; + if (ii>-1) { + if( curr_values[ic]-1) { + if( curr_values[ic]>interval_ulimit[ii] ) { + add_force[ic]=false; + } + } + } - bool index_ok = false; - std::vector curr_bin; + std::vector const curr_bin = hills_energy->get_colvars_index(curr_values); if (use_grids) { @@ -1263,18 +1282,22 @@ int colvarbias_meta::calc_forces(std::vector const *values) cvm::real const *f = &(replicas[ir]->hills_energy_gradients->value(curr_bin)); for (ic = 0; ic < num_variables(); ic++) { // the gradients are stored, not the forces - colvar_forces[ic].real_value += -1.0 * f[ic]; + if (add_force[ic]) { + colvar_forces[ic].real_value += -1.0 * f[ic]; + } } } } else { // off the grid: compute analytically only the hills at the grid's edges for (ir = 0; ir < replicas.size(); ir++) { for (ic = 0; ic < num_variables(); ic++) { - calc_hills_force(ic, - replicas[ir]->hills_off_grid.begin(), - replicas[ir]->hills_off_grid.end(), - colvar_forces, - values); + if (add_force[ic]) { + calc_hills_force(ic, + replicas[ir]->hills_off_grid.begin(), + replicas[ir]->hills_off_grid.end(), + colvar_forces, + curr_values); + } } } } @@ -1290,11 +1313,13 @@ int colvarbias_meta::calc_forces(std::vector const *values) for (ir = 0; ir < replicas.size(); ir++) { for (ic = 0; ic < num_variables(); ic++) { - calc_hills_force(ic, - replicas[ir]->new_hills_begin, - replicas[ir]->hills.end(), - colvar_forces, - values); + if (add_force[ic]) { + calc_hills_force(ic, + replicas[ir]->new_hills_begin, + replicas[ir]->hills.end(), + colvar_forces, + curr_values); + } if (cvm::debug()) { cvm::log("Hills forces = "+cvm::to_str(colvar_forces)+".\n"); } @@ -1353,27 +1378,13 @@ void colvarbias_meta::calc_hills_force(size_t const &i, switch (x.type()) { case colvarvalue::type_scalar: - // if outside interval boundaries do not add force - bool add_force; - add_force=true; - int ii; - ii=which_int_llimit_cv[i]; - if (ii>-1 && x-1 && x>interval_ulimit[ii] ) { - add_force=false; - } - if (add_force) { - for (h = h_first; h != h_last; h++) { - if (h->value() == 0.0) continue; - colvarvalue const ¢er = h->centers[i]; - cvm::real const sigma = h->sigmas[i]; - forces[i].real_value += - ( h->weight() * h->value() * (0.5 / (sigma*sigma)) * - (variables(i)->dist2_lgrad(x, center)).real_value ); - } + for (h = h_first; h != h_last; h++) { + if (h->value() == 0.0) continue; + colvarvalue const ¢er = h->centers[i]; + cvm::real const sigma = h->sigmas[i]; + forces[i].real_value += + ( h->weight() * h->value() * (0.5 / (sigma*sigma)) * + (variables(i)->dist2_lgrad(x, center)).real_value ); } break; @@ -1439,8 +1450,6 @@ void colvarbias_meta::project_hills(colvarbias_meta::hill_iter h_first, // TODO: improve it by looping over a small subgrid instead of the whole grid std::vector new_colvar_values(num_variables()); - // vector defined to account for reflection+interval - std::vector new_hcolvar_values(num_variables()); std::vector colvar_forces_scalar(num_variables()); @@ -1457,22 +1466,25 @@ void colvarbias_meta::project_hills(colvarbias_meta::hill_iter h_first, // loop over the points of the grid size_t i; size_t ii; + std::vector add_force(num_variables()); for ( ; (he->index_ok(he_ix)) && (hg->index_ok(hg_ix)); count++) { for (i = 0; i < num_variables(); i++) { + add_force[i]=true; new_colvar_values[i] = he->bin_to_value_scalar(he_ix[i], i); - new_hcolvar_values[i] = he->bin_to_value_scalar(he_ix[i], i); ii=which_int_llimit_cv[i]; if (ii>-1 ){ - if ( new_hcolvar_values[i]-1){ - if( new_hcolvar_values[i]>interval_ulimit[ii] ) { - new_hcolvar_values[i]=interval_ulimit[ii]; + if( new_colvar_values[i]>interval_ulimit[ii] ) { + new_colvar_values[i]=interval_ulimit[ii]; + add_force[i]=false; } } } @@ -1484,7 +1496,9 @@ void colvarbias_meta::project_hills(colvarbias_meta::hill_iter h_first, for (i = 0; i < num_variables(); i++) { hills_forces_here[i].reset(); - calc_hills_force(i, h_first, h_last, hills_forces_here, &new_colvar_values); + if (add_force[i]){ + calc_hills_force(i, h_first, h_last, hills_forces_here, &new_colvar_values); + } colvar_forces_scalar[i] = hills_forces_here[i].real_value; } hg->acc_force(hg_ix, &(colvar_forces_scalar.front())); From 3ba6d0983861dd8aa97a5cc8c4eb3fa352418162 Mon Sep 17 00:00:00 2001 From: Fabrizio Marinelli Date: Thu, 29 Sep 2022 13:27:44 -0400 Subject: [PATCH 29/62] Remove requiremend of hard boundaries as a default for grid + reflection --- src/colvarbias_meta.cpp | 29 +++++------------------------ 1 file changed, 5 insertions(+), 24 deletions(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index 4388f8828..5e177a6c5 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -385,23 +385,18 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) } } - // if grids and hard boundaries are defined, set by default reflection boundaries as grid boundaries + // if grids are defined, set by default reflection boundaries as grid boundaries if (use_grids) { for (int i = 0; i < nrefvarsl; i++) { int ii=reflection_llimit_cv[i]; - if (variables(ii)->is_enabled(f_cv_hard_lower_boundary)) { - reflection_llimit[i]=hills_energy->lower_boundaries[ii].real_value; - } + reflection_llimit[i]=hills_energy->lower_boundaries[ii].real_value; } for (int i = 0; i < nrefvarsu; i++) { int ii=reflection_ulimit_cv[i]; - if (variables(ii)->is_enabled(f_cv_hard_upper_boundary)) { - reflection_ulimit[i]=hills_energy->upper_boundaries[ii].real_value; - } + reflection_ulimit[i]=hills_energy->upper_boundaries[ii].real_value; } } - if (nrefvarsl>0) { if (get_keyval(conf, "reflectionLowLimit", reflection_llimit, reflection_llimit)) { for (int i = 0; i < nrefvarsl; i++) { @@ -414,14 +409,7 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) } } } else { - if (use_grids) { - for (int i = 0; i < nrefvarsl; i++) { - int ii=reflection_llimit_cv[i]; - if (!variables(ii)->is_enabled(f_cv_hard_lower_boundary)) { - cvm::error("Error: Lower limits for reflection not provided.\n", COLVARS_INPUT_ERROR); - } - } - } else { + if (!use_grids) { cvm::error("Error: Lower limits for reflection not provided.\n", COLVARS_INPUT_ERROR); } } @@ -444,14 +432,7 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) } } } else { - if (use_grids) { - for (int i = 0; i < nrefvarsu; i++) { - int ii=reflection_ulimit_cv[i]; - if (!variables(ii)->is_enabled(f_cv_hard_upper_boundary)) { - cvm::error("Error: Upper limits for reflection not provided.\n", COLVARS_INPUT_ERROR); - } - } - } else { + if (!use_grids) { cvm::error("Error: Upper limits for reflection not provided.\n", COLVARS_INPUT_ERROR); } } From 6145aa1a23520b5943e5b02b94407a01e3fb6844 Mon Sep 17 00:00:00 2001 From: Fabrizio Marinelli Date: Thu, 29 Sep 2022 13:53:19 -0400 Subject: [PATCH 30/62] a few changes to resolve compilation errors --- src/colvarbias_meta.cpp | 42 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index 5e177a6c5..38e5d75e5 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -1129,24 +1129,23 @@ int colvarbias_meta::calc_energy(std::vector const *values) { size_t ir = 0; - // interval - if (use_interval) { - size_t i; - size_t ii; - std::vector curr_values(num_variables()); + size_t i; + size_t ii; + std::vector curr_values(num_variables()); + for (i = 0; i < num_variables(); i++) { + curr_values[i].type(variables(i)->value()); + } + + if ((*values).size()) { for (i = 0; i < num_variables(); i++) { - curr_values[i].type(variables(i)->value()); + curr_values[i] = (*values)[i]; } - - if ((*values).size()) { - for (i = 0; i < num_variables(); i++) { - curr_values[i] = (*values)[i]; - } - } else { - for (i = 0; i < num_variables(); i++) { - curr_values[i] = variables(i)->value(); - } + } else { + for (i = 0; i < num_variables(); i++) { + curr_values[i] = variables(i)->value(); } + } + if (use_interval) { for (i = 0; i < num_variables(); i++) { ii=which_int_llimit_cv[i]; if (ii>-1 && curr_values[i] const *values) curr_values[i]=interval_ulimit[ii]; } } - } else { - std::vector const &curr_values=values ? (*values) : colvar_values; } + for (ir = 0; ir < replicas.size(); ir++) { replicas[ir]->bias_energy = 0.0; @@ -1196,7 +1194,7 @@ int colvarbias_meta::calc_energy(std::vector const *values) calc_hills(replicas[ir]->hills_off_grid.begin(), replicas[ir]->hills_off_grid.end(), bias_energy, - curr_values); + &curr_values); } } @@ -1207,7 +1205,7 @@ int colvarbias_meta::calc_energy(std::vector const *values) calc_hills(replicas[ir]->new_hills_begin, replicas[ir]->hills.end(), bias_energy, - curr_values); + &curr_values); if (cvm::debug()) { cvm::log("Hills energy = "+cvm::to_str(bias_energy)+".\n"); } @@ -1277,7 +1275,7 @@ int colvarbias_meta::calc_forces(std::vector const *values) replicas[ir]->hills_off_grid.begin(), replicas[ir]->hills_off_grid.end(), colvar_forces, - curr_values); + &curr_values); } } } @@ -1299,7 +1297,7 @@ int colvarbias_meta::calc_forces(std::vector const *values) replicas[ir]->new_hills_begin, replicas[ir]->hills.end(), colvar_forces, - curr_values); + &curr_values); } if (cvm::debug()) { cvm::log("Hills forces = "+cvm::to_str(colvar_forces)+".\n"); @@ -1472,7 +1470,7 @@ void colvarbias_meta::project_hills(colvarbias_meta::hill_iter h_first, // loop over the hills and increment the energy grid locally hills_energy_here = 0.0; - calc_hills(h_first, h_last, hills_energy_here, &new_hcolvar_values); + calc_hills(h_first, h_last, hills_energy_here, &new_colvar_values); he->acc_value(he_ix, hills_energy_here); for (i = 0; i < num_variables(); i++) { From a6c1a3898d95681d9ef95299da5b88a564b0492e Mon Sep 17 00:00:00 2001 From: Fabrizio Marinelli Date: Thu, 29 Sep 2022 14:00:11 -0400 Subject: [PATCH 31/62] changed variables->values with colvar_values in calc_energy --- src/colvarbias_meta.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index 38e5d75e5..df4fc85e6 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -1142,7 +1142,7 @@ int colvarbias_meta::calc_energy(std::vector const *values) } } else { for (i = 0; i < num_variables(); i++) { - curr_values[i] = variables(i)->value(); + curr_values[i] = colvar_values[i]; } } if (use_interval) { From 35ee8cb35d66e8e95327bb94b394a03596bee20e Mon Sep 17 00:00:00 2001 From: Fabrizio Marinelli Date: Thu, 29 Sep 2022 17:15:20 -0400 Subject: [PATCH 32/62] Added errors/warning and defaults to account for periodic variables + hills refletions, to be continued for interval --- src/colvarbias_meta.cpp | 159 ++++++++++++++++++++++++++-------------- 1 file changed, 105 insertions(+), 54 deletions(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index df4fc85e6..be37d4c9b 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -318,7 +318,21 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) bool use_reflection; nrefvarsl=0; nrefvarsu=0; - int nvars=num_variables(); + size_t nvars; + nvars=num_variables(); + size_t nonpvars; + size_t i; + size_t ii; + size_t j; + size_t jj, + ii=0; + for (i = 0; i < nvars; i++) { + if (!variables(i)->is_enabled(f_cv_periodic)) { + ii++; + } + } + nonpvars=ii; + get_keyval(conf, "useHillsReflection", use_reflection, false); if (use_reflection) { @@ -327,16 +341,19 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) if (get_keyval(conf, "reflectionLowLimitUseCVs", reflection_llimit_cv, reflection_llimit_cv)) { nrefvarsl=reflection_llimit_cv.size(); + if(nrefvarsl>nvars) cvm::error("Error: number CVs with active lower reflection limit is > num_variables \n", COLVARS_INPUT_ERROR); cvm::log("Using lower limits reflection on "+cvm::to_str(nrefvarsl)+" variables.\n"); } else { - nrefvarsl=nvars; - if (reflection_llimit_cv.size()==0) { - reflection_llimit_cv.resize(nrefvarsl); - for (int i = 0; i < nrefvarsl; i++) { - reflection_llimit_cv[i]=i; - } + nrefvarsl=nonpvars; + reflection_llimit_cv.resize(nrefvarsl); + ii=0; + for (i = 0; i < nvars; i++) { + if (!variables(i)->is_enabled(f_cv_periodic)) { + reflection_llimit_cv[ii]=i; + ii++; + } } - cvm::log("Using all variables for lower limits of reflection \n"); + cvm::log("Using all non-periodic variables for lower limits of reflection \n"); } if (reflection_llimit.size()==0) { @@ -345,14 +362,19 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) if (get_keyval(conf, "reflectionUpLimitUseCVs", reflection_ulimit_cv, reflection_ulimit_cv)) { nrefvarsu=reflection_ulimit_cv.size(); + if(nrefvarsu>nvars) cvm::error("Error: number CVs with active upper reflection limit is > num_variables \n", COLVARS_INPUT_ERROR); cvm::log("Using upper limits reflection on "+cvm::to_str(nrefvarsu)+" variables.\n"); } else { - nrefvarsu=nvars; + nrefvarsu=nonpvars; reflection_ulimit_cv.resize(nrefvarsu); - for (int i = 0; i < nrefvarsu; i++) { - reflection_ulimit_cv[i]=i; + ii=0; + for (i = 0; i < nvars; i++) { + if (!variables(i)->is_enabled(f_cv_periodic)) { + reflection_ulimit_cv[ii]=i; + ii++; + } } - cvm::log("Using all variables for upper limits of reflection \n"); + cvm::log("Using all non-periodic variables for upper limits of reflection \n"); } if (reflection_ulimit.size()==0) { @@ -361,47 +383,49 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) // use reflection only with scalar variables - for (int i = 0; i < nrefvarsl; i++) { + for (i = 0; i < nrefvarsl; i++) { if (reflection_llimit_cv[i]>=nvars || reflection_llimit_cv[i]<0) { cvm::error("Error: CV number is negative or >= num_variables \n", COLVARS_INPUT_ERROR); - return COLVARS_INPUT_ERROR; } - int j=reflection_llimit_cv[i]; + j=reflection_llimit_cv[i]; if (variables(j)->value().type()!=colvarvalue::type_scalar) { cvm::error("Error: Hills reflection can be used only with scalar variables.\n", COLVARS_INPUT_ERROR); - return COLVARS_INPUT_ERROR; } + if (variables(j)->is_enabled(f_cv_periodic)) { + cvm::log("Warning: you are using hills reflection with a periodic variable, make sure you are using it far from periodic boundaries \n"); + } } - for (int i = 0; i < nrefvarsu; i++) { + for (i = 0; i < nrefvarsu; i++) { if (reflection_ulimit_cv[i]>=nvars || reflection_ulimit_cv[i]<0) { cvm::error("Error: CV number is negative or >= num_variables \n", COLVARS_INPUT_ERROR); - return COLVARS_INPUT_ERROR; } - int j=reflection_ulimit_cv[i]; + j=reflection_ulimit_cv[i]; if (variables(j)->value().type()!=colvarvalue::type_scalar) { cvm::error("Error: Hills reflection can be used only with scalar variables.\n", COLVARS_INPUT_ERROR); - return COLVARS_INPUT_ERROR; + } + if (variables(j)->is_enabled(f_cv_periodic)) { + cvm::log("Warning: you are using hills reflection with a periodic variable, make sure you are using it far from periodic boundaries \n"); } } // if grids are defined, set by default reflection boundaries as grid boundaries if (use_grids) { - for (int i = 0; i < nrefvarsl; i++) { - int ii=reflection_llimit_cv[i]; + for (i = 0; i < nrefvarsl; i++) { + ii=reflection_llimit_cv[i]; reflection_llimit[i]=hills_energy->lower_boundaries[ii].real_value; } - for (int i = 0; i < nrefvarsu; i++) { - int ii=reflection_ulimit_cv[i]; + for (i = 0; i < nrefvarsu; i++) { + ii=reflection_ulimit_cv[i]; reflection_ulimit[i]=hills_energy->upper_boundaries[ii].real_value; } } if (nrefvarsl>0) { - if (get_keyval(conf, "reflectionLowLimit", reflection_llimit, reflection_llimit)) { - for (int i = 0; i < nrefvarsl; i++) { + if (get_keyval(conf, "reflectionLowLimit", reflection_llimit, reflection_llimit)) { + for (i = 0; i < nrefvarsl; i++) { if (use_grids) { - int ii=reflection_llimit_cv[i]; + ii=reflection_llimit_cv[i]; cvm:: real bound=hills_energy->lower_boundaries[ii].real_value; if (reflection_llimit[i] < bound) { cvm::error("Error: When using grids, grid lower boundary for CV"+cvm::to_str(ii)+" must be equal or smaller than"+cvm::to_str(reflection_llimit[i])+".\n", COLVARS_INPUT_ERROR); @@ -415,16 +439,16 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) } } - for (int i = 0; i < nrefvarsl; i++) { + for (i = 0; i < nrefvarsl; i++) { cvm::log("Reflection condition is applied on a lower limit for CV "+cvm::to_str(reflection_llimit_cv[i])+".\n"); cvm::log("Reflection condition lower limit for this CV is "+cvm::to_str(reflection_llimit[i])+".\n"); } if (nrefvarsu>0) { if (get_keyval(conf, "reflectionUpLimit", reflection_ulimit, reflection_ulimit)) { - for (int i = 0; i < nrefvarsu; i++) { + for (i = 0; i < nrefvarsu; i++) { if (use_grids) { - int ii=reflection_ulimit_cv[i]; + ii=reflection_ulimit_cv[i]; cvm:: real bound=hills_energy->upper_boundaries[ii].real_value; if (reflection_ulimit[i] > bound) { cvm::error("Error: When using grids, upper boundary for CV"+cvm::to_str(ii)+" must be larger than"+cvm::to_str(reflection_ulimit[i])+".\n", COLVARS_INPUT_ERROR); @@ -438,7 +462,7 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) } } - for (int i = 0; i < nrefvarsu; i++) { + for (i = 0; i < nrefvarsu; i++) { cvm::log("Reflection condition is applied on an upper limit for CV "+cvm::to_str(reflection_ulimit_cv[i])+".\n"); cvm::log("Reflection condition upper limit for this CV is "+cvm::to_str(reflection_ulimit[i])+".\n"); } @@ -446,8 +470,11 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) // multimensional reflection // generate reflection states - int sum=1; - int nstates; + int sum; + sum=1; + size_t nstates; + size_t count; + if (reflection_usel.size()==0) { reflection_usel.resize(nvars,std::vector(2)); } @@ -456,21 +483,21 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) reflection_l.resize(nvars,std::vector(2)); } - for (int j = 1; j < nvars; j++) { + for (j = 1; j < nvars; j++) { reflection_usel[j][0]=false; reflection_l[j][0]=0.0; reflection_usel[j][1]=false; reflection_l[j][1]=0.0; } - for (int i = 0; i < nrefvarsl; i++) { - int j=reflection_llimit_cv[i]; + for (i = 0; i < nrefvarsl; i++) { + j=reflection_llimit_cv[i]; reflection_usel[j][0]=true; reflection_l[j][0]=reflection_llimit[i]; } - for (int i = 0; i < nrefvarsu; i++) { - int j=reflection_ulimit_cv[i]; + for (i = 0; i < nrefvarsu; i++) { + j=reflection_ulimit_cv[i]; reflection_usel[j][1]=true; reflection_l[j][1]=reflection_ulimit[i]; } @@ -498,18 +525,18 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) ref_state.resize(nvars,std::vector(1)); } ref_state[0][0]=1; - for (int j = 1; j < nvars; j++) { + for (j = 1; j < nvars; j++) { sum*=10; nstates=0; - for (int jj = 0; jj < j; jj++) { + for (jj = 0; jj < j; jj++) { nstates+=ref_state[j].size(); } nstates++; ref_state[j].resize(nstates); ref_state[j][0]=sum; - int count=0; - for (int jj = 0; jj < j; jj++) { - for (size_t ii = 0; ii < ref_state[jj].size(); ii++) { + count=0; + for (jj = 0; jj < j; jj++) { + for ( ii = 0; ii < ref_state[jj].size(); ii++) { count++; ref_state[j][count]=ref_state[j][0]+ref_state[jj][ii]; } @@ -524,20 +551,44 @@ int colvarbias_meta::init_interval_params(std::string const &conf) use_interval=false; nintvarsl=0; nintvarsu=0; - std::vector interval_llimit_cv; - std::vector interval_ulimit_cv; - int nvars=num_variables(); + std::vector interval_llimit_cv; + std::vector interval_ulimit_cv; + size_t nvars; + size_t nonpvars; + nvars=num_variables(); + size_t i; + size_t ii; + ii=0; + for (i = 0; i < nvars; i++) { + if (!variables(i)->is_enabled(f_cv_periodic)) { + ii++; + } + } + nonpvars=ii; + if (get_keyval(conf, "useHillsInterval", use_interval, use_interval)) { if (use_interval) { - get_keyval(conf, "intervalLowLimitNCVs", nintvarsl, nvars); - get_keyval(conf, "intervalUpLimitNCVs", nintvarsu, nvars); - interval_llimit_cv.resize(nintvarsl); - for (int i = 0; i < nintvarsl; i++) { - interval_llimit_cv[i]=i; + if (get_keyval(conf, "intervalLowLimitUseCVs", interval_llimit_cv, interval_llimit_cv)) { + nintvarsl=interval_llimit_cv.size(); + cvm::log("Using lower limits interval on "+cvm::to_str(nintvarsl)+" variables.\n"); + } else { + nintvarsl=nvars; + interval_llimit_cv.resize(nintvarsl); + for (int i = 0; i < nintvarsl; i++) { + interval_llimit_cv[i]=i; + } + cvm::log("Using all variables for lower limits of interval \n"); } - interval_ulimit_cv.resize(nintvarsu); - for (int i = 0; i < nintvarsu; i++) { - interval_ulimit_cv[i]=i; + if (get_keyval(conf, "intervalUpLimitUseCVs", interval_ulimit_cv, interval_ulimit_cv)) { + nintvarsu=interval_ulimit_cv.size(); + cvm::log("Using upper limits interval on "+cvm::to_str(nintvarsu)+" variables.\n"); + } else { + nintvarsu=nvars; + interval_ulimit_cv.resize(nintvarsu); + for (int i = 0; i < nintvarsu; i++) { + interval_ulimit_cv[i]=i; + } + cvm::log("Using all variables for upper limits of interval \n"); } if(nintvarsl>0) { if (get_keyval(conf, "intervalLowLimitUseCVs", interval_llimit_cv, interval_llimit_cv)) { From 15c474143b3749bdf3874086584a3c0034d179f8 Mon Sep 17 00:00:00 2001 From: Fabrizio Marinelli Date: Fri, 30 Sep 2022 15:53:31 -0400 Subject: [PATCH 33/62] Resolved compilation errors due to curr_values on calc energy introduced use_reflection as a general variable to be use to call associated function to add refleted hills --- src/colvarbias_meta.cpp | 243 +++++++++++++++++++--------------------- src/colvarbias_meta.h | 17 +-- 2 files changed, 127 insertions(+), 133 deletions(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index be37d4c9b..a641c900f 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -315,18 +315,15 @@ int colvarbias_meta::init_ebmeta_params(std::string const &conf) int colvarbias_meta::init_reflection_params(std::string const &conf) { - bool use_reflection; nrefvarsl=0; nrefvarsu=0; - size_t nvars; - nvars=num_variables(); size_t nonpvars; size_t i; - size_t ii; + size_t ii=0; size_t j; - size_t jj, - ii=0; - for (i = 0; i < nvars; i++) { + size_t jj; + + for ( i = 0; i < num_variables(); i++ ) { if (!variables(i)->is_enabled(f_cv_periodic)) { ii++; } @@ -341,13 +338,13 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) if (get_keyval(conf, "reflectionLowLimitUseCVs", reflection_llimit_cv, reflection_llimit_cv)) { nrefvarsl=reflection_llimit_cv.size(); - if(nrefvarsl>nvars) cvm::error("Error: number CVs with active lower reflection limit is > num_variables \n", COLVARS_INPUT_ERROR); + if(nrefvarsl>num_variables()) cvm::error("Error: number CVs with active lower reflection limit is > num_variables \n", COLVARS_INPUT_ERROR); cvm::log("Using lower limits reflection on "+cvm::to_str(nrefvarsl)+" variables.\n"); } else { nrefvarsl=nonpvars; reflection_llimit_cv.resize(nrefvarsl); ii=0; - for (i = 0; i < nvars; i++) { + for (i = 0; i < num_variables(); i++) { if (!variables(i)->is_enabled(f_cv_periodic)) { reflection_llimit_cv[ii]=i; ii++; @@ -362,13 +359,13 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) if (get_keyval(conf, "reflectionUpLimitUseCVs", reflection_ulimit_cv, reflection_ulimit_cv)) { nrefvarsu=reflection_ulimit_cv.size(); - if(nrefvarsu>nvars) cvm::error("Error: number CVs with active upper reflection limit is > num_variables \n", COLVARS_INPUT_ERROR); + if(nrefvarsu>num_variables()) cvm::error("Error: number CVs with active upper reflection limit is > num_variables \n", COLVARS_INPUT_ERROR); cvm::log("Using upper limits reflection on "+cvm::to_str(nrefvarsu)+" variables.\n"); } else { nrefvarsu=nonpvars; reflection_ulimit_cv.resize(nrefvarsu); ii=0; - for (i = 0; i < nvars; i++) { + for (i = 0; i < num_variables(); i++) { if (!variables(i)->is_enabled(f_cv_periodic)) { reflection_ulimit_cv[ii]=i; ii++; @@ -384,7 +381,7 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) // use reflection only with scalar variables for (i = 0; i < nrefvarsl; i++) { - if (reflection_llimit_cv[i]>=nvars || reflection_llimit_cv[i]<0) { + if (reflection_llimit_cv[i]>=num_variables() || reflection_llimit_cv[i]<0) { cvm::error("Error: CV number is negative or >= num_variables \n", COLVARS_INPUT_ERROR); } j=reflection_llimit_cv[i]; @@ -397,7 +394,7 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) } for (i = 0; i < nrefvarsu; i++) { - if (reflection_ulimit_cv[i]>=nvars || reflection_ulimit_cv[i]<0) { + if (reflection_ulimit_cv[i]>=num_variables() || reflection_ulimit_cv[i]<0) { cvm::error("Error: CV number is negative or >= num_variables \n", COLVARS_INPUT_ERROR); } j=reflection_ulimit_cv[i]; @@ -428,7 +425,7 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) ii=reflection_llimit_cv[i]; cvm:: real bound=hills_energy->lower_boundaries[ii].real_value; if (reflection_llimit[i] < bound) { - cvm::error("Error: When using grids, grid lower boundary for CV"+cvm::to_str(ii)+" must be equal or smaller than"+cvm::to_str(reflection_llimit[i])+".\n", COLVARS_INPUT_ERROR); + cvm::log("Warning: you are using hills reflection with lower limit smaller than grid lower boundary for CV"+cvm::to_str(ii)+" \n"); } } } @@ -451,7 +448,7 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) ii=reflection_ulimit_cv[i]; cvm:: real bound=hills_energy->upper_boundaries[ii].real_value; if (reflection_ulimit[i] > bound) { - cvm::error("Error: When using grids, upper boundary for CV"+cvm::to_str(ii)+" must be larger than"+cvm::to_str(reflection_ulimit[i])+".\n", COLVARS_INPUT_ERROR); + cvm::log("Warning: you are using hills reflection with upper limit larger than grid upper boundary for CV"+cvm::to_str(ii)+" \n"); } } } @@ -470,20 +467,20 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) // multimensional reflection // generate reflection states - int sum; + size_t sum; sum=1; size_t nstates; size_t count; if (reflection_usel.size()==0) { - reflection_usel.resize(nvars,std::vector(2)); + reflection_usel.resize(num_variables(),std::vector(2)); } if (reflection_l.size()==0) { - reflection_l.resize(nvars,std::vector(2)); + reflection_l.resize(num_variables(),std::vector(2)); } - for (j = 1; j < nvars; j++) { + for (j = 1; j < num_variables(); j++) { reflection_usel[j][0]=false; reflection_l[j][0]=0.0; reflection_usel[j][1]=false; @@ -522,10 +519,10 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) // ref_state[2][3]=ref_state[2][0]+ref_state[1][1] if (ref_state.size()==0) { - ref_state.resize(nvars,std::vector(1)); + ref_state.resize(num_variables(),std::vector(1)); } ref_state[0][0]=1; - for (j = 1; j < nvars; j++) { + for (j = 1; j < num_variables(); j++) { sum*=10; nstates=0; for (jj = 0; jj < j; jj++) { @@ -553,79 +550,55 @@ int colvarbias_meta::init_interval_params(std::string const &conf) nintvarsu=0; std::vector interval_llimit_cv; std::vector interval_ulimit_cv; - size_t nvars; - size_t nonpvars; - nvars=num_variables(); size_t i; size_t ii; - ii=0; - for (i = 0; i < nvars; i++) { - if (!variables(i)->is_enabled(f_cv_periodic)) { - ii++; - } - } - nonpvars=ii; + size_t j; if (get_keyval(conf, "useHillsInterval", use_interval, use_interval)) { if (use_interval) { if (get_keyval(conf, "intervalLowLimitUseCVs", interval_llimit_cv, interval_llimit_cv)) { nintvarsl=interval_llimit_cv.size(); cvm::log("Using lower limits interval on "+cvm::to_str(nintvarsl)+" variables.\n"); - } else { - nintvarsl=nvars; - interval_llimit_cv.resize(nintvarsl); - for (int i = 0; i < nintvarsl; i++) { - interval_llimit_cv[i]=i; + for (i = 0; i < nintvarsl; i++) { + j=interval_llimit_cv[i]; + if (variables(j)->is_enabled(f_cv_periodic)) { + cvm::log("Warning: you are using interval with a periodic variable, make sure you are using it far from periodic boundaries \n"); + } } - cvm::log("Using all variables for lower limits of interval \n"); + } else { + cvm::error("Error: Upper limit variables for interval not provided.\n", COLVARS_INPUT_ERROR); } if (get_keyval(conf, "intervalUpLimitUseCVs", interval_ulimit_cv, interval_ulimit_cv)) { nintvarsu=interval_ulimit_cv.size(); cvm::log("Using upper limits interval on "+cvm::to_str(nintvarsu)+" variables.\n"); - } else { - nintvarsu=nvars; - interval_ulimit_cv.resize(nintvarsu); - for (int i = 0; i < nintvarsu; i++) { - interval_ulimit_cv[i]=i; + for (i = 0; i < nintvarsu; i++) { + j=interval_ulimit_cv[i]; + if (variables(j)->is_enabled(f_cv_periodic)) { + cvm::log("Warning: you are using interval with a periodic variable, make sure you are using it far from periodic boundaries \n"); + } } - cvm::log("Using all variables for upper limits of interval \n"); + } else { + cvm::error("Error: Upper limits variables for interval not provided.\n", COLVARS_INPUT_ERROR); } if(nintvarsl>0) { - if (get_keyval(conf, "intervalLowLimitUseCVs", interval_llimit_cv, interval_llimit_cv)) { - if (interval_llimit.size()==0) { - interval_llimit.resize(nintvarsl); - } - } else { - cvm::log("Using all variables for lower limits of interval \n"); - } if (get_keyval(conf, "intervalLowLimit", interval_llimit, interval_llimit)) { - for (int i = 0; i < nintvarsl; i++) { + for ( i = 0; i < nintvarsl; i++) { cvm::log("Hills forces will be removed beyond a lower limit for CV "+cvm::to_str(interval_llimit_cv[i])+".\n"); cvm::log("Interval condition lower limit for this CV is "+cvm::to_str(interval_llimit[i])+".\n"); } } else { cvm::error("Error: Lower limits for interval not provided.\n", COLVARS_INPUT_ERROR); - return COLVARS_INPUT_ERROR; } } if(nintvarsu>0) { - if (get_keyval(conf, "intervalUpLimitUseCVs", interval_ulimit_cv, interval_ulimit_cv)) { - if (interval_ulimit.size()==0) { - interval_ulimit.resize(nintvarsu); - } - } else { - cvm::log("Using all variables for upper limits of interval \n"); - } - if (get_keyval(conf, "intervalUpLimit", interval_ulimit, interval_ulimit)) { - for (int i = 0; i < nintvarsu; i++) { + for ( i = 0; i < nintvarsu; i++) { cvm::log("Hills forces will be removed beyond an upper limit for CV "+cvm::to_str(interval_ulimit_cv[i])+".\n"); cvm::log("Interval condition upper limit for this CV is "+cvm::to_str(interval_ulimit[i])+".\n"); } } else { cvm::error("Error: Upper limits for interval not provided.\n", COLVARS_INPUT_ERROR); - return COLVARS_INPUT_ERROR; } } } @@ -647,7 +620,7 @@ int colvarbias_meta::init_interval_params(std::string const &conf) if (interval_ulimit.size()==0) { interval_ulimit.resize(nintvarsu); } - for (int i = 0; i < nintvarsu; i++) { + for ( i = 0; i < nintvarsu; i++) { interval_ulimit_cv[i]=reflection_ulimit_cv[i]; interval_ulimit[i]=reflection_ulimit[i]; } @@ -655,46 +628,46 @@ int colvarbias_meta::init_interval_params(std::string const &conf) } if (which_int_llimit_cv.size()==0) { - which_int_llimit_cv.resize(nvars); + which_int_llimit_cv.resize(num_variables()); } - for (int i = 0; i < nvars; i++) { + for ( i = 0; i < num_variables(); i++) { which_int_llimit_cv[i]=-1; } - for (int i = 0; i < nintvarsl; i++) { - int j=interval_llimit_cv[i]; + for ( i = 0; i < nintvarsl; i++) { + j=interval_llimit_cv[i]; which_int_llimit_cv[j]=i; } if (which_int_ulimit_cv.size()==0) { - which_int_ulimit_cv.resize(nvars); + which_int_ulimit_cv.resize(num_variables()); } - for (int i = 0; i < nvars; i++) { + for ( i = 0; i < num_variables(); i++) { which_int_ulimit_cv[i]=-1; } - for (int i = 0; i < nintvarsu; i++) { - int j=interval_ulimit_cv[i]; + for ( i = 0; i < nintvarsu; i++) { + j=interval_ulimit_cv[i]; which_int_ulimit_cv[j]=i; } // use interval only with scalar variables - for (int i = 0; i < nintvarsl; i++) { - if (interval_llimit_cv[i]>=nvars || interval_llimit_cv[i]<0) { + for ( i = 0; i < nintvarsl; i++) { + if (interval_llimit_cv[i]>=num_variables() || interval_llimit_cv[i]<0) { cvm::error("Error: CV number is negative or >= num_variables \n", COLVARS_INPUT_ERROR); return COLVARS_INPUT_ERROR; } - int j=interval_llimit_cv[i]; + j=interval_llimit_cv[i]; if (variables(j)->value().type()!=colvarvalue::type_scalar) { cvm::error("Error: Hills interval can be used only with scalar variables.\n", COLVARS_INPUT_ERROR); return COLVARS_INPUT_ERROR; } } - for (int i = 0; i < nintvarsu; i++) { - if (interval_ulimit_cv[i]>=nvars || interval_ulimit_cv[i]<0) { + for ( i = 0; i < nintvarsu; i++) { + if (interval_ulimit_cv[i]>=num_variables() || interval_ulimit_cv[i]<0) { cvm::error("Error: CV number is negative or >= num_variables \n", COLVARS_INPUT_ERROR); return COLVARS_INPUT_ERROR; } - int j=interval_ulimit_cv[i]; + j=interval_ulimit_cv[i]; if (variables(j)->value().type()!=colvarvalue::type_scalar) { cvm::error("Error: Hills interval can be used only with scalar variables.\n", COLVARS_INPUT_ERROR); return COLVARS_INPUT_ERROR; @@ -760,17 +733,17 @@ colvarbias_meta::add_hill(colvarbias_meta::hill const &h) bool colvarbias_meta::check_reflection_limits(bool &ah) { - for (int i = 0; i < nrefvarsl; i++) { - int ii=reflection_llimit_cv[i]; - cvm:: real cv_value=variables(ii)->value(); - if (cv_valuevalue(); - if (cv_value>reflection_ulimit[i]) { + for ( i = 0; i < nrefvarsu; i++) { + ii=reflection_ulimit_cv[i]; + if (colvar_values[ii]>reflection_ulimit[i]) { ah=false; } } @@ -780,29 +753,53 @@ bool colvarbias_meta::check_reflection_limits(bool &ah) int colvarbias_meta::reflect_hill_multid(cvm::real const &h_scale) { size_t i = 0; + size_t j; + size_t jj; + size_t startsum; + int getsum; + int check_val; + size_t numberref; + size_t startsumk; + int upordown; + size_t nkstates; + size_t kstate; + size_t k; + size_t kk; + size_t countstate; + bool hill_add; + int getsumk; + int checkk; + size_t state; + int valk; + cvm:: real tmps; + colvarvalue tmp; + colvarvalue unitary; + cvm:: real reflection_limit; + cvm:: real tmpd; + std::vector curr_cv_values(num_variables()); for (i = 0; i < num_variables(); i++) { curr_cv_values[i].type(variables(i)->value()); } for (i = 0; i < num_variables(); i++) { - curr_cv_values[i] = variables(i)->value(); + curr_cv_values[i] = colvar_values[i]; } // sum over all possible reflection states previously generated, // see init - for (size_t j = 0; j < num_variables(); j++) { - int startsum=1; + for ( j = 0; j < num_variables(); j++) { + startsum=1; for (i = 0; i < j; i++) { startsum*=10; } - for (size_t jj = 0; jj < ref_state[j].size(); jj++) { - int getsum=startsum; - int check_val=ref_state[j][jj]; - int numberref=0; - int startsumk=1; + for (jj = 0; jj < ref_state[j].size(); jj++) { + getsum=startsum; + check_val=ref_state[j][jj]; + numberref=0; + startsumk=1; for (i = 0; i <= j; i++) { - int upordown=std::floor(check_val/getsum); + upordown=std::floor(check_val/getsum); check_val=check_val-getsum; getsum=getsum/10; if (upordown==1) { @@ -817,11 +814,11 @@ int colvarbias_meta::reflect_hill_multid(cvm::real const &h_scale) // for two reflections these are 0 1 10 11 (0,0 0,1 1,0 1,1) // where 0 is reflect on the two lower boudaries of the two coordinates etc. - int nkstates=2; - int kstate=0; - for (int k = 0; k 0) nkstates=ref_state[k].size(); - for (int kk = 0; kk < nkstates; kk++) { + for ( kk = 0; kk < nkstates; kk++) { if (k==0 && kk==1) { kstate=1; } else if (k>0) { @@ -829,27 +826,27 @@ int colvarbias_meta::reflect_hill_multid(cvm::real const &h_scale) } getsum=startsum; - int countstate=0; + countstate=0; check_val=ref_state[j][jj]; - bool hill_add=true; - int getsumk=startsumk; - int checkk=kstate; + hill_add=true; + getsumk=startsumk; + checkk=kstate; for (i = 0; i <= j; i++) { - int upordown=std::floor(check_val/getsum); - int state=num_variables()-1-j+countstate; + upordown=std::floor(check_val/getsum); + state=num_variables()-1-j+countstate; countstate++; check_val=check_val-getsum; getsum=getsum/10; if (upordown==1) { - cvm:: real tmps=colvar_sigmas[state]; - colvarvalue tmp=curr_cv_values[state]; // store original current cv value - colvarvalue unitary=curr_cv_values[state]; + tmps=colvar_sigmas[state]; + tmp=curr_cv_values[state]; // store original current cv value + unitary=curr_cv_values[state]; unitary.set_ones(); - int valk=std::floor(checkk/getsumk); + valk=std::floor(checkk/getsumk); if(checkk-getsumk>=0) checkk=checkk-getsumk; getsumk=getsumk/10; - cvm:: real reflection_limit=reflection_l[state][valk]; - cvm:: real tmpd=reflection_limit-cvm::real(curr_cv_values[state]); + reflection_limit=reflection_l[state][valk]; + tmpd=reflection_limit-cvm::real(curr_cv_values[state]); tmpd=std::sqrt(tmpd*tmpd); if (tmpdvalue(); // go back to previous values + curr_cv_values[i] = colvar_values[i]; // go back to previous values } } else { for (i = 0; i < num_variables(); i++) { - curr_cv_values[i] = variables(i)->value(); // go back to previous values + curr_cv_values[i] = colvar_values[i]; // go back to previous values } } } @@ -1141,8 +1138,9 @@ int colvarbias_meta::update_bias() } // add reflected hills if required - - reflect_hill_multid(hills_scale); + if (use_reflection) { + reflect_hill_multid(hills_scale); + } } @@ -1181,21 +1179,14 @@ int colvarbias_meta::calc_energy(std::vector const *values) size_t ir = 0; size_t i; - size_t ii; + int ii; std::vector curr_values(num_variables()); for (i = 0; i < num_variables(); i++) { curr_values[i].type(variables(i)->value()); } + + curr_values = values ? *values : colvar_values; - if ((*values).size()) { - for (i = 0; i < num_variables(); i++) { - curr_values[i] = (*values)[i]; - } - } else { - for (i = 0; i < num_variables(); i++) { - curr_values[i] = colvar_values[i]; - } - } if (use_interval) { for (i = 0; i < num_variables(); i++) { ii=which_int_llimit_cv[i]; @@ -1270,6 +1261,7 @@ int colvarbias_meta::calc_forces(std::vector const *values) { std::vector const &curr_values=values ? (*values) : colvar_values; size_t ir = 0, ic = 0; + int ii; std::vector add_force(num_variables()); for (ir = 0; ir < replicas.size(); ir++) { for (ic = 0; ic < num_variables(); ic++) { @@ -1280,7 +1272,6 @@ int colvarbias_meta::calc_forces(std::vector const *values) for (ic = 0; ic < num_variables(); ic++) { add_force[ic]=true; - int ii; ii=which_int_llimit_cv[ic]; if (ii>-1) { if( curr_values[ic] add_force(num_variables()); for ( ; (he->index_ok(he_ix)) && (hg->index_ok(hg_ix)); diff --git a/src/colvarbias_meta.h b/src/colvarbias_meta.h index 7308e5a0b..4f97cd5f1 100644 --- a/src/colvarbias_meta.h +++ b/src/colvarbias_meta.h @@ -222,13 +222,16 @@ class colvarbias_meta // hills reflection + /// \brief Whether using hills reflection + bool use_reflection; + /// \brief For which variables reflection limits are on - std::vector reflection_llimit_cv; - std::vector reflection_ulimit_cv; + std::vector reflection_llimit_cv; + std::vector reflection_ulimit_cv; cvm::real reflection_int; - int nrefvarsl; - int nrefvarsu; + size_t nrefvarsl; + size_t nrefvarsu; /// \brief Limits for reflection std::vector reflection_llimit; @@ -239,7 +242,7 @@ class colvarbias_meta std::vector > reflection_l; /// \brief Multidimensional reflection states - std::vector > ref_state; + std::vector > ref_state; /// \brief whether using interval bool use_interval; @@ -247,8 +250,8 @@ class colvarbias_meta std::vector which_int_llimit_cv; std::vector which_int_ulimit_cv; - int nintvarsl; - int nintvarsu; + size_t nintvarsl; + size_t nintvarsu; /// \brief Limits for interval std::vector interval_llimit; std::vector interval_ulimit; From d73e519467eecc59dd017b7fc62e0937ca655f5f Mon Sep 17 00:00:00 2001 From: Fabrizio Marinelli Date: Sat, 1 Oct 2022 11:55:25 -0400 Subject: [PATCH 34/62] Updated calc_energy in case reflection boundaries are grid boundaries, accounting for binning at the border which was leading to following bin which is out of the grid --- src/colvarbias_meta.cpp | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index a641c900f..a84197ea9 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -1191,16 +1191,15 @@ int colvarbias_meta::calc_energy(std::vector const *values) for (i = 0; i < num_variables(); i++) { ii=which_int_llimit_cv[i]; if (ii>-1 && curr_values[i]width); } ii=which_int_ulimit_cv[i]; if (ii>-1 && curr_values[i]>interval_ulimit[ii] ) { - curr_values[i]=interval_ulimit[ii]; + curr_values[i]=interval_ulimit[ii]-0.5*(variables(i)->width); } } } - for (ir = 0; ir < replicas.size(); ir++) { replicas[ir]->bias_energy = 0.0; } @@ -1232,17 +1231,33 @@ int colvarbias_meta::calc_energy(std::vector const *values) } } else { // off the grid: compute analytically only the hills at the grid's edges - for (ir = 0; ir < replicas.size(); ir++) { - calc_hills(replicas[ir]->hills_off_grid.begin(), - replicas[ir]->hills_off_grid.end(), - bias_energy, - &curr_values); + if (!use_interval) { + for (ir = 0; ir < replicas.size(); ir++) { + calc_hills(replicas[ir]->hills_off_grid.begin(), + replicas[ir]->hills_off_grid.end(), + bias_energy, + &curr_values); + } } } // now include the hills that have not been binned yet (starting // from new_hills_begin) + if (use_interval) { + curr_values = values ? *values : colvar_values; + for (i = 0; i < num_variables(); i++) { + ii=which_int_llimit_cv[i]; + if (ii>-1 && curr_values[i]-1 && curr_values[i]>interval_ulimit[ii] ) { + curr_values[i]=interval_ulimit[ii]; + } + } + } + for (ir = 0; ir < replicas.size(); ir++) { calc_hills(replicas[ir]->new_hills_begin, replicas[ir]->hills.end(), From b11065e14ab270b9389e451d021a713dbd4c15fd Mon Sep 17 00:00:00 2001 From: Fabrizio Marinelli Date: Sat, 1 Oct 2022 16:15:48 -0400 Subject: [PATCH 35/62] cal_energy modified to put interval upper boundaries inside the grid by subtracting half width --- src/colvarbias_meta.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index a84197ea9..0c72f08d6 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -1191,11 +1191,15 @@ int colvarbias_meta::calc_energy(std::vector const *values) for (i = 0; i < num_variables(); i++) { ii=which_int_llimit_cv[i]; if (ii>-1 && curr_values[i]width); + curr_values[i]=interval_llimit[ii]; } ii=which_int_ulimit_cv[i]; if (ii>-1 && curr_values[i]>interval_ulimit[ii] ) { - curr_values[i]=interval_ulimit[ii]-0.5*(variables(i)->width); + if (interval_ulimit[ii]==hills_energy->upper_boundaries[ii].real_value){ + curr_values[i]=interval_ulimit[ii]-0.5*(variables(i)->width); // upper border is out of grid; in this way is in + } else { + curr_values[i]=interval_ulimit[ii]; + } } } } From 11262bdf645f9221b4fb545d136bd1d97e76fae3 Mon Sep 17 00:00:00 2001 From: Fabrizio Marinelli Date: Sat, 1 Oct 2022 18:38:13 -0400 Subject: [PATCH 36/62] Corretted bug on allocation of ref_state array for reflection --- src/colvarbias_meta.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index 0c72f08d6..84e68fe8a 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -526,7 +526,7 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) sum*=10; nstates=0; for (jj = 0; jj < j; jj++) { - nstates+=ref_state[j].size(); + nstates+=ref_state[jj].size(); } nstates++; ref_state[j].resize(nstates); From dc2fb6b81afba7fee14a61aef4fea3e6b6f8c458 Mon Sep 17 00:00:00 2001 From: Fabrizio Marinelli Date: Tue, 4 Oct 2022 00:11:35 -0400 Subject: [PATCH 37/62] Corrected bug in multidimensional reflection visible in 3D checkval-getsum>=0 required to make things work --- src/colvarbias_meta.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index 84e68fe8a..4b4385451 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -800,7 +800,7 @@ int colvarbias_meta::reflect_hill_multid(cvm::real const &h_scale) startsumk=1; for (i = 0; i <= j; i++) { upordown=std::floor(check_val/getsum); - check_val=check_val-getsum; + if(check_val-getsum>=0) check_val=check_val-getsum; getsum=getsum/10; if (upordown==1) { numberref++; @@ -835,7 +835,7 @@ int colvarbias_meta::reflect_hill_multid(cvm::real const &h_scale) upordown=std::floor(check_val/getsum); state=num_variables()-1-j+countstate; countstate++; - check_val=check_val-getsum; + if(check_val-getsum>=0) check_val=check_val-getsum; getsum=getsum/10; if (upordown==1) { tmps=colvar_sigmas[state]; From 0b8e3d4c385c1ee0d10e1650e48fca02242031ab Mon Sep 17 00:00:00 2001 From: Giacomo Fiorin Date: Fri, 7 Oct 2022 09:01:50 -0400 Subject: [PATCH 38/62] Fix leftover compiler issues; also remove trailing whitespace via Git hooks --- src/colvarbias_meta.cpp | 93 ++++++++++++++++++++--------------------- 1 file changed, 46 insertions(+), 47 deletions(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index 4b4385451..aea936bc4 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -364,14 +364,14 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) } else { nrefvarsu=nonpvars; reflection_ulimit_cv.resize(nrefvarsu); - ii=0; + ii=0; for (i = 0; i < num_variables(); i++) { if (!variables(i)->is_enabled(f_cv_periodic)) { reflection_ulimit_cv[ii]=i; - ii++; + ii++; } } - cvm::log("Using all non-periodic variables for upper limits of reflection \n"); + cvm::log("Using all non-periodic variables for upper limits of reflection \n"); } if (reflection_ulimit.size()==0) { @@ -379,7 +379,7 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) } // use reflection only with scalar variables - + for (i = 0; i < nrefvarsl; i++) { if (reflection_llimit_cv[i]>=num_variables() || reflection_llimit_cv[i]<0) { cvm::error("Error: CV number is negative or >= num_variables \n", COLVARS_INPUT_ERROR); @@ -390,9 +390,9 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) } if (variables(j)->is_enabled(f_cv_periodic)) { cvm::log("Warning: you are using hills reflection with a periodic variable, make sure you are using it far from periodic boundaries \n"); - } + } } - + for (i = 0; i < nrefvarsu; i++) { if (reflection_ulimit_cv[i]>=num_variables() || reflection_ulimit_cv[i]<0) { cvm::error("Error: CV number is negative or >= num_variables \n", COLVARS_INPUT_ERROR); @@ -402,7 +402,7 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) cvm::error("Error: Hills reflection can be used only with scalar variables.\n", COLVARS_INPUT_ERROR); } if (variables(j)->is_enabled(f_cv_periodic)) { - cvm::log("Warning: you are using hills reflection with a periodic variable, make sure you are using it far from periodic boundaries \n"); + cvm::log("Warning: you are using hills reflection with a periodic variable, make sure you are using it far from periodic boundaries \n"); } } @@ -414,18 +414,18 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) } for (i = 0; i < nrefvarsu; i++) { ii=reflection_ulimit_cv[i]; - reflection_ulimit[i]=hills_energy->upper_boundaries[ii].real_value; + reflection_ulimit[i]=hills_energy->upper_boundaries[ii].real_value; } } if (nrefvarsl>0) { - if (get_keyval(conf, "reflectionLowLimit", reflection_llimit, reflection_llimit)) { + if (get_keyval(conf, "reflectionLowLimit", reflection_llimit, reflection_llimit)) { for (i = 0; i < nrefvarsl; i++) { if (use_grids) { ii=reflection_llimit_cv[i]; cvm:: real bound=hills_energy->lower_boundaries[ii].real_value; if (reflection_llimit[i] < bound) { - cvm::log("Warning: you are using hills reflection with lower limit smaller than grid lower boundary for CV"+cvm::to_str(ii)+" \n"); + cvm::log("Warning: you are using hills reflection with lower limit smaller than grid lower boundary for CV"+cvm::to_str(ii)+" \n"); } } } @@ -438,20 +438,20 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) for (i = 0; i < nrefvarsl; i++) { cvm::log("Reflection condition is applied on a lower limit for CV "+cvm::to_str(reflection_llimit_cv[i])+".\n"); - cvm::log("Reflection condition lower limit for this CV is "+cvm::to_str(reflection_llimit[i])+".\n"); + cvm::log("Reflection condition lower limit for this CV is "+cvm::to_str(reflection_llimit[i])+".\n"); } if (nrefvarsu>0) { if (get_keyval(conf, "reflectionUpLimit", reflection_ulimit, reflection_ulimit)) { for (i = 0; i < nrefvarsu; i++) { - if (use_grids) { + if (use_grids) { ii=reflection_ulimit_cv[i]; cvm:: real bound=hills_energy->upper_boundaries[ii].real_value; if (reflection_ulimit[i] > bound) { - cvm::log("Warning: you are using hills reflection with upper limit larger than grid upper boundary for CV"+cvm::to_str(ii)+" \n"); + cvm::log("Warning: you are using hills reflection with upper limit larger than grid upper boundary for CV"+cvm::to_str(ii)+" \n"); } } - } + } } else { if (!use_grids) { cvm::error("Error: Upper limits for reflection not provided.\n", COLVARS_INPUT_ERROR); @@ -462,7 +462,7 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) for (i = 0; i < nrefvarsu; i++) { cvm::log("Reflection condition is applied on an upper limit for CV "+cvm::to_str(reflection_ulimit_cv[i])+".\n"); cvm::log("Reflection condition upper limit for this CV is "+cvm::to_str(reflection_ulimit[i])+".\n"); - } + } // multimensional reflection @@ -471,28 +471,28 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) sum=1; size_t nstates; size_t count; - + if (reflection_usel.size()==0) { reflection_usel.resize(num_variables(),std::vector(2)); } - + if (reflection_l.size()==0) { reflection_l.resize(num_variables(),std::vector(2)); } - + for (j = 1; j < num_variables(); j++) { reflection_usel[j][0]=false; reflection_l[j][0]=0.0; reflection_usel[j][1]=false; reflection_l[j][1]=0.0; } - + for (i = 0; i < nrefvarsl; i++) { j=reflection_llimit_cv[i]; reflection_usel[j][0]=true; reflection_l[j][0]=reflection_llimit[i]; } - + for (i = 0; i < nrefvarsu; i++) { j=reflection_ulimit_cv[i]; reflection_usel[j][1]=true; @@ -502,21 +502,21 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) // Generate all possible reflection states (e.g. through faces, edges and vertex). // Consider for example a cube, the states are: // [0,0,1] -// [0,1,0] [0,1,1] +// [0,1,0] [0,1,1] // [1,0,0] [1,0,1] [1,1,0] [1,1,1] // where 1 means reflect on that coordinate and 0 do not reflect. -// These states can be generated as: +// These states can be generated as: // ref_state[0][0]=1 // ref_state[1][0]=10 ref_state[1][1]=11 // ref_state[2][0]=100 ref_state[2][1]=101 ref_state[2][2]=110 ref_state[2][3]=111 // going down along the rows the size ref_state[j].size() is the number of previous states // (j-1) plus one. -// A specific state instead can be generated starting from a power of 10 and then summing +// A specific state instead can be generated starting from a power of 10 and then summing // the states of the previous rows: -// ref_state[1][1]=ref_state[1][0]+ref_state[0][0] +// ref_state[1][1]=ref_state[1][0]+ref_state[0][0] // ref_state[2][1]=ref_state[2][0]+ref_state[0][0] -// ref_state[2][2]=ref_state[2][0]+ref_state[1][0] -// ref_state[2][3]=ref_state[2][0]+ref_state[1][1] +// ref_state[2][2]=ref_state[2][0]+ref_state[1][0] +// ref_state[2][3]=ref_state[2][0]+ref_state[1][1] if (ref_state.size()==0) { ref_state.resize(num_variables(),std::vector(1)); @@ -551,7 +551,6 @@ int colvarbias_meta::init_interval_params(std::string const &conf) std::vector interval_llimit_cv; std::vector interval_ulimit_cv; size_t i; - size_t ii; size_t j; if (get_keyval(conf, "useHillsInterval", use_interval, use_interval)) { @@ -570,7 +569,7 @@ int colvarbias_meta::init_interval_params(std::string const &conf) } if (get_keyval(conf, "intervalUpLimitUseCVs", interval_ulimit_cv, interval_ulimit_cv)) { nintvarsu=interval_ulimit_cv.size(); - cvm::log("Using upper limits interval on "+cvm::to_str(nintvarsu)+" variables.\n"); + cvm::log("Using upper limits interval on "+cvm::to_str(nintvarsu)+" variables.\n"); for (i = 0; i < nintvarsu; i++) { j=interval_ulimit_cv[i]; if (variables(j)->is_enabled(f_cv_periodic)) { @@ -612,7 +611,7 @@ int colvarbias_meta::init_interval_params(std::string const &conf) if (interval_llimit.size()==0) { interval_llimit.resize(nintvarsl); } - for (int i = 0; i < nintvarsl; i++) { + for (i = 0; i < nintvarsl; i++) { interval_llimit_cv[i]=reflection_llimit_cv[i]; interval_llimit[i]=reflection_llimit[i]; } @@ -772,7 +771,7 @@ int colvarbias_meta::reflect_hill_multid(cvm::real const &h_scale) size_t state; int valk; cvm:: real tmps; - colvarvalue tmp; + colvarvalue tmp; colvarvalue unitary; cvm:: real reflection_limit; cvm:: real tmpd; @@ -1114,14 +1113,14 @@ int colvarbias_meta::update_bias() if (add_a_hill) { switch (comm) { - + case single_replica: - + add_hill(hill(cvm::step_absolute(), hill_weight*hills_scale, colvar_values, colvar_sigmas)); - + break; - + case multiple_replicas: add_hill(hill(cvm::step_absolute(), hill_weight*hills_scale, colvar_values, colvar_sigmas, replica_id)); @@ -1141,7 +1140,7 @@ int colvarbias_meta::update_bias() if (use_reflection) { reflect_hill_multid(hills_scale); } - + } } @@ -1186,10 +1185,10 @@ int colvarbias_meta::calc_energy(std::vector const *values) } curr_values = values ? *values : colvar_values; - + if (use_interval) { - for (i = 0; i < num_variables(); i++) { - ii=which_int_llimit_cv[i]; + for (i = 0; i < num_variables(); i++) { + ii=which_int_llimit_cv[i]; if (ii>-1 && curr_values[i] const *values) } } } - + for (ir = 0; ir < replicas.size(); ir++) { replicas[ir]->bias_energy = 0.0; } @@ -1287,9 +1286,9 @@ int colvarbias_meta::calc_forces(std::vector const *values) replicas[ir]->colvar_forces[ic].reset(); } } - - - for (ic = 0; ic < num_variables(); ic++) { + + + for (ic = 0; ic < num_variables(); ic++) { add_force[ic]=true; ii=which_int_llimit_cv[ic]; if (ii>-1) { @@ -1337,7 +1336,7 @@ int colvarbias_meta::calc_forces(std::vector const *values) replicas[ir]->hills_off_grid.end(), colvar_forces, &curr_values); - } + } } } } @@ -1490,7 +1489,7 @@ void colvarbias_meta::project_hills(colvarbias_meta::hill_iter h_first, // TODO: improve it by looping over a small subgrid instead of the whole grid std::vector new_colvar_values(num_variables()); - + std::vector colvar_forces_scalar(num_variables()); std::vector he_ix = he->new_index(); @@ -1511,17 +1510,17 @@ void colvarbias_meta::project_hills(colvarbias_meta::hill_iter h_first, (he->index_ok(he_ix)) && (hg->index_ok(hg_ix)); count++) { for (i = 0; i < num_variables(); i++) { - add_force[i]=true; + add_force[i]=true; new_colvar_values[i] = he->bin_to_value_scalar(he_ix[i], i); ii=which_int_llimit_cv[i]; - if (ii>-1 ){ + if (ii>-1 ){ if ( new_colvar_values[i]-1){ + if (ii>-1){ if( new_colvar_values[i]>interval_ulimit[ii] ) { new_colvar_values[i]=interval_ulimit[ii]; add_force[i]=false; From 9e42105e2501e4f161d03978420d8c9faf7dc77c Mon Sep 17 00:00:00 2001 From: Fabrizio Marinelli Date: Fri, 7 Oct 2022 09:01:56 -0400 Subject: [PATCH 39/62] Resolving compilers issues, chenged limits of CVs to integers so control for negative values should work --- src/colvarbias_meta.cpp | 4 ++-- src/colvarbias_meta.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index aea936bc4..ed334d7df 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -548,8 +548,8 @@ int colvarbias_meta::init_interval_params(std::string const &conf) use_interval=false; nintvarsl=0; nintvarsu=0; - std::vector interval_llimit_cv; - std::vector interval_ulimit_cv; + std::vector interval_llimit_cv; + std::vector interval_ulimit_cv; size_t i; size_t j; diff --git a/src/colvarbias_meta.h b/src/colvarbias_meta.h index 4f97cd5f1..a14073671 100644 --- a/src/colvarbias_meta.h +++ b/src/colvarbias_meta.h @@ -227,8 +227,8 @@ class colvarbias_meta /// \brief For which variables reflection limits are on - std::vector reflection_llimit_cv; - std::vector reflection_ulimit_cv; + std::vector reflection_llimit_cv; + std::vector reflection_ulimit_cv; cvm::real reflection_int; size_t nrefvarsl; size_t nrefvarsu; From d7990d1cc1e93e915bb8f048cf505654f0d4d8ed Mon Sep 17 00:00:00 2001 From: Fabrizio Marinelli Date: Fri, 7 Oct 2022 09:02:02 -0400 Subject: [PATCH 40/62] num_variables casted to int when required --- src/colvarbias_meta.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index ed334d7df..ba0c0a0cb 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -381,7 +381,7 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) // use reflection only with scalar variables for (i = 0; i < nrefvarsl; i++) { - if (reflection_llimit_cv[i]>=num_variables() || reflection_llimit_cv[i]<0) { + if (reflection_llimit_cv[i]>=static_cast(num_variables()) || reflection_llimit_cv[i]<0) { cvm::error("Error: CV number is negative or >= num_variables \n", COLVARS_INPUT_ERROR); } j=reflection_llimit_cv[i]; @@ -394,7 +394,7 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) } for (i = 0; i < nrefvarsu; i++) { - if (reflection_ulimit_cv[i]>=num_variables() || reflection_ulimit_cv[i]<0) { + if (reflection_ulimit_cv[i]>=static_cast(num_variables()) || reflection_ulimit_cv[i]<0) { cvm::error("Error: CV number is negative or >= num_variables \n", COLVARS_INPUT_ERROR); } j=reflection_ulimit_cv[i]; @@ -650,7 +650,7 @@ int colvarbias_meta::init_interval_params(std::string const &conf) // use interval only with scalar variables for ( i = 0; i < nintvarsl; i++) { - if (interval_llimit_cv[i]>=num_variables() || interval_llimit_cv[i]<0) { + if (interval_llimit_cv[i]>=static_cast(num_variables()) || interval_llimit_cv[i]<0) { cvm::error("Error: CV number is negative or >= num_variables \n", COLVARS_INPUT_ERROR); return COLVARS_INPUT_ERROR; } @@ -662,7 +662,7 @@ int colvarbias_meta::init_interval_params(std::string const &conf) } for ( i = 0; i < nintvarsu; i++) { - if (interval_ulimit_cv[i]>=num_variables() || interval_ulimit_cv[i]<0) { + if (interval_ulimit_cv[i]>=static_cast(num_variables()) || interval_ulimit_cv[i]<0) { cvm::error("Error: CV number is negative or >= num_variables \n", COLVARS_INPUT_ERROR); return COLVARS_INPUT_ERROR; } From 686a9f9012c5c81842c65c566dbec53d6ab1e93c Mon Sep 17 00:00:00 2001 From: Fabrizio Marinelli Date: Fri, 7 Oct 2022 09:02:07 -0400 Subject: [PATCH 41/62] corrected bug on calc_energy at the boundary --- src/colvarbias_meta.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index ba0c0a0cb..abed1b05a 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -1194,7 +1194,7 @@ int colvarbias_meta::calc_energy(std::vector const *values) } ii=which_int_ulimit_cv[i]; if (ii>-1 && curr_values[i]>interval_ulimit[ii] ) { - if (interval_ulimit[ii]==hills_energy->upper_boundaries[ii].real_value){ + if (interval_ulimit[ii]==hills_energy->upper_boundaries[i].real_value){ curr_values[i]=interval_ulimit[ii]-0.5*(variables(i)->width); // upper border is out of grid; in this way is in } else { curr_values[i]=interval_ulimit[ii]; From ecb69816d6bbcb004c89a6055130ef852f9f3465 Mon Sep 17 00:00:00 2001 From: fabsugar Date: Sun, 9 Oct 2022 00:40:20 -0400 Subject: [PATCH 42/62] Corrected calc_force to take into account that also the force components must be put back at the border when coordinates go out of the reflection border --- src/colvarbias_meta.cpp | 52 +++++++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 12 deletions(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index abed1b05a..f7184cdf2 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -1277,9 +1277,13 @@ int colvarbias_meta::calc_energy(std::vector const *values) int colvarbias_meta::calc_forces(std::vector const *values) { - std::vector const &curr_values=values ? (*values) : colvar_values; size_t ir = 0, ic = 0; int ii; + std::vector curr_values(num_variables()); + for (ic = 0; ic < num_variables(); ic++) { + curr_values[ic].type(variables(ic)->value()); + } + curr_values = values ? *values : colvar_values; std::vector add_force(num_variables()); for (ir = 0; ir < replicas.size(); ir++) { for (ic = 0; ic < num_variables(); ic++) { @@ -1287,19 +1291,24 @@ int colvarbias_meta::calc_forces(std::vector const *values) } } - for (ic = 0; ic < num_variables(); ic++) { add_force[ic]=true; ii=which_int_llimit_cv[ic]; if (ii>-1) { - if( curr_values[ic]-1) { - if( curr_values[ic]>interval_ulimit[ii] ) { + if ( curr_values[ic]>interval_ulimit[ii] ) { add_force[ic]=false; + if (interval_ulimit[ii]==hills_energy->upper_boundaries[ic].real_value){ + curr_values[ic]=interval_ulimit[ii]-0.5*(variables(ic)->width); // upper border is out of grid; in this way is in + } else { + curr_values[ic]=interval_ulimit[ii]; + } } } } @@ -1328,14 +1337,14 @@ int colvarbias_meta::calc_forces(std::vector const *values) } } else { // off the grid: compute analytically only the hills at the grid's edges - for (ir = 0; ir < replicas.size(); ir++) { - for (ic = 0; ic < num_variables(); ic++) { - if (add_force[ic]) { - calc_hills_force(ic, - replicas[ir]->hills_off_grid.begin(), - replicas[ir]->hills_off_grid.end(), - colvar_forces, - &curr_values); + if (!use_interval) { + for (ir = 0; ir < replicas.size(); ir++) { + for (ic = 0; ic < num_variables(); ic++) { + calc_hills_force(ic, + replicas[ir]->hills_off_grid.begin(), + replicas[ir]->hills_off_grid.end(), + colvar_forces, + &curr_values); } } } @@ -1344,6 +1353,25 @@ int colvarbias_meta::calc_forces(std::vector const *values) // now include the hills that have not been binned yet (starting // from new_hills_begin) + if (use_interval) { + curr_values = values ? *values : colvar_values; + for (ic = 0; ic < num_variables(); ic++) { + ii=which_int_llimit_cv[ic]; + if (ii>-1) { + if ( curr_values[ic]-1) { + if ( curr_values[ic]>interval_ulimit[ii] ) { + curr_values[ic]=interval_ulimit[ii]; + } + } + } + } + + if (cvm::debug()) { cvm::log("Metadynamics bias \""+this->name+"\""+ ((comm != single_replica) ? ", replica \""+replica_id+"\"" : "")+ From c301593341e59674b7a9993ee585ee25f423ae07 Mon Sep 17 00:00:00 2001 From: fabsugar Date: Fri, 21 Oct 2022 14:12:38 -0400 Subject: [PATCH 43/62] Corrected calc_energy and calc_forces function to check that upper limit of reflection is in the boundary before correction was handling most of cases but now should be fine in every case --- src/colvarbias_meta.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index f7184cdf2..628826ed5 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -1179,6 +1179,7 @@ int colvarbias_meta::calc_energy(std::vector const *values) size_t i; int ii; + cvm::real up_bound_bin_value; std::vector curr_values(num_variables()); for (i = 0; i < num_variables(); i++) { curr_values[i].type(variables(i)->value()); @@ -1194,7 +1195,10 @@ int colvarbias_meta::calc_energy(std::vector const *values) } ii=which_int_ulimit_cv[i]; if (ii>-1 && curr_values[i]>interval_ulimit[ii] ) { - if (interval_ulimit[ii]==hills_energy->upper_boundaries[i].real_value){ + // check if upper border is out of the grid otherwise put it back on the grid + up_bound_bin_value=hills_energy->lower_boundaries[i].real_value+variables(i)->width*(0.5+cvm::floor((interval_ulimit[ii]-hills_energy->lower_boundaries[i].real_value)/variables(i)->width)); + //if (interval_ulimit[ii]==hills_energy->upper_boundaries[i].real_value){ + if (up_bound_bin_value>hills_energy->upper_boundaries[i].real_value) { curr_values[i]=interval_ulimit[ii]-0.5*(variables(i)->width); // upper border is out of grid; in this way is in } else { curr_values[i]=interval_ulimit[ii]; @@ -1279,6 +1283,7 @@ int colvarbias_meta::calc_forces(std::vector const *values) { size_t ir = 0, ic = 0; int ii; + cvm::real up_bound_bin_value; std::vector curr_values(num_variables()); for (ic = 0; ic < num_variables(); ic++) { curr_values[ic].type(variables(ic)->value()); @@ -1304,7 +1309,9 @@ int colvarbias_meta::calc_forces(std::vector const *values) if (ii>-1) { if ( curr_values[ic]>interval_ulimit[ii] ) { add_force[ic]=false; - if (interval_ulimit[ii]==hills_energy->upper_boundaries[ic].real_value){ + up_bound_bin_value=hills_energy->lower_boundaries[ic].real_value+variables(ic)->width*(0.5+cvm::floor((interval_ulimit[ii]-hills_energy->lower_boundaries[ic].real_value)/variables(ic)->width)); + //if (interval_ulimit[ii]==hills_energy->upper_boundaries[ic].real_value){ + if (up_bound_bin_value>hills_energy->upper_boundaries[ic].real_value) { curr_values[ic]=interval_ulimit[ii]-0.5*(variables(ic)->width); // upper border is out of grid; in this way is in } else { curr_values[ic]=interval_ulimit[ii]; From 645693e1e4ccbba4d51f98f1f84cbd161806b06c Mon Sep 17 00:00:00 2001 From: fabsugar Date: Fri, 4 Nov 2022 11:43:05 -0400 Subject: [PATCH 44/62] Removed some spaces --- src/colvarbias_meta.cpp | 4 ++-- src/colvarbias_meta.h | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index 628826ed5..a00707d5d 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -1196,7 +1196,7 @@ int colvarbias_meta::calc_energy(std::vector const *values) ii=which_int_ulimit_cv[i]; if (ii>-1 && curr_values[i]>interval_ulimit[ii] ) { // check if upper border is out of the grid otherwise put it back on the grid - up_bound_bin_value=hills_energy->lower_boundaries[i].real_value+variables(i)->width*(0.5+cvm::floor((interval_ulimit[ii]-hills_energy->lower_boundaries[i].real_value)/variables(i)->width)); + up_bound_bin_value=hills_energy->lower_boundaries[i].real_value+variables(i)->width*(0.5+cvm::floor((interval_ulimit[ii]-hills_energy->lower_boundaries[i].real_value)/variables(i)->width)); //if (interval_ulimit[ii]==hills_energy->upper_boundaries[i].real_value){ if (up_bound_bin_value>hills_energy->upper_boundaries[i].real_value) { curr_values[i]=interval_ulimit[ii]-0.5*(variables(i)->width); // upper border is out of grid; in this way is in @@ -1309,7 +1309,7 @@ int colvarbias_meta::calc_forces(std::vector const *values) if (ii>-1) { if ( curr_values[ic]>interval_ulimit[ii] ) { add_force[ic]=false; - up_bound_bin_value=hills_energy->lower_boundaries[ic].real_value+variables(ic)->width*(0.5+cvm::floor((interval_ulimit[ii]-hills_energy->lower_boundaries[ic].real_value)/variables(ic)->width)); + up_bound_bin_value=hills_energy->lower_boundaries[ic].real_value+variables(ic)->width*(0.5+cvm::floor((interval_ulimit[ii]-hills_energy->lower_boundaries[ic].real_value)/variables(ic)->width)); //if (interval_ulimit[ii]==hills_energy->upper_boundaries[ic].real_value){ if (up_bound_bin_value>hills_energy->upper_boundaries[ic].real_value) { curr_values[ic]=interval_ulimit[ii]-0.5*(variables(ic)->width); // upper border is out of grid; in this way is in diff --git a/src/colvarbias_meta.h b/src/colvarbias_meta.h index a14073671..5dbeffd88 100644 --- a/src/colvarbias_meta.h +++ b/src/colvarbias_meta.h @@ -157,7 +157,7 @@ class colvarbias_meta std::list::const_iterator delete_hill(hill_iter &h); - /// \brief Check is current colvar value is within inversion or + /// \brief Check is current colvar value is within inversion or /// reflection limits to assess whether to add a hill bool check_reflection_limits(bool &ah); @@ -220,12 +220,12 @@ class colvarbias_meta /// \brief Biasing temperature in well-tempered metadynamics cvm::real bias_temperature; - // hills reflection + // hills reflection /// \brief Whether using hills reflection bool use_reflection; - /// \brief For which variables reflection limits are on + /// \brief For which variables reflection limits are on std::vector reflection_llimit_cv; std::vector reflection_ulimit_cv; @@ -233,7 +233,7 @@ class colvarbias_meta size_t nrefvarsl; size_t nrefvarsu; - /// \brief Limits for reflection + /// \brief Limits for reflection std::vector reflection_llimit; std::vector reflection_ulimit; @@ -245,14 +245,14 @@ class colvarbias_meta std::vector > ref_state; /// \brief whether using interval - bool use_interval; + bool use_interval; /// \brief For which variables hills forces beyond the boundaries(interval) must be removed std::vector which_int_llimit_cv; std::vector which_int_ulimit_cv; size_t nintvarsl; size_t nintvarsu; - /// \brief Limits for interval + /// \brief Limits for interval std::vector interval_llimit; std::vector interval_ulimit; From ce3eada2f34236dcdda4487d715aecbff6ed18b1 Mon Sep 17 00:00:00 2001 From: fabsugar Date: Fri, 4 Nov 2022 13:06:43 -0400 Subject: [PATCH 45/62] Added >= to check values out of upper boundary just to be extra precise --- src/colvarbias_meta.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index a00707d5d..a43fde84b 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -1194,7 +1194,7 @@ int colvarbias_meta::calc_energy(std::vector const *values) curr_values[i]=interval_llimit[ii]; } ii=which_int_ulimit_cv[i]; - if (ii>-1 && curr_values[i]>interval_ulimit[ii] ) { + if (ii>-1 && curr_values[i]>=interval_ulimit[ii] ) { // check if upper border is out of the grid otherwise put it back on the grid up_bound_bin_value=hills_energy->lower_boundaries[i].real_value+variables(i)->width*(0.5+cvm::floor((interval_ulimit[ii]-hills_energy->lower_boundaries[i].real_value)/variables(i)->width)); //if (interval_ulimit[ii]==hills_energy->upper_boundaries[i].real_value){ @@ -1307,7 +1307,7 @@ int colvarbias_meta::calc_forces(std::vector const *values) } ii=which_int_ulimit_cv[ic]; if (ii>-1) { - if ( curr_values[ic]>interval_ulimit[ii] ) { + if ( curr_values[ic]>=interval_ulimit[ii] ) { add_force[ic]=false; up_bound_bin_value=hills_energy->lower_boundaries[ic].real_value+variables(ic)->width*(0.5+cvm::floor((interval_ulimit[ii]-hills_energy->lower_boundaries[ic].real_value)/variables(ic)->width)); //if (interval_ulimit[ii]==hills_energy->upper_boundaries[ic].real_value){ From 3bdfd46ffb9980875b72e3fbdc90968f02f9ad6c Mon Sep 17 00:00:00 2001 From: fabsugar Date: Fri, 4 Nov 2022 17:12:54 -0400 Subject: [PATCH 46/62] Introdiced error if reflection limits are explicity specified out of grid boundaries --- src/colvarbias_meta.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index a43fde84b..63de6038d 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -424,8 +424,8 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) if (use_grids) { ii=reflection_llimit_cv[i]; cvm:: real bound=hills_energy->lower_boundaries[ii].real_value; - if (reflection_llimit[i] < bound) { - cvm::log("Warning: you are using hills reflection with lower limit smaller than grid lower boundary for CV"+cvm::to_str(ii)+" \n"); + if (reflection_llimit[i] != bound && reflection_llimit[i] < bound+variables(ii)->width) { + cvm::error("Error: please set lower reflection limit for CV "+cvm::to_str(ii)+" either at grid lower boundary ("+cvm::to_str(bound)+") or well above it (above "+cvm::to_str(bound+variables(ii)->width)+").\n", COLVARS_INPUT_ERROR); } } } @@ -447,8 +447,8 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) if (use_grids) { ii=reflection_ulimit_cv[i]; cvm:: real bound=hills_energy->upper_boundaries[ii].real_value; - if (reflection_ulimit[i] > bound) { - cvm::log("Warning: you are using hills reflection with upper limit larger than grid upper boundary for CV"+cvm::to_str(ii)+" \n"); + if (reflection_ulimit[i] != bound && reflection_ulimit[i] > bound-variables(ii)->width) { + cvm::error("Error: please set upper reflection limit for CV "+cvm::to_str(ii)+" either at grid upper boundary ("+cvm::to_str(bound)+") or well below it (below "+cvm::to_str(bound-variables(ii)->width)+").\n", COLVARS_INPUT_ERROR); } } } From 8705debbd0314a469f6d85fdf259a1ef54f7897d Mon Sep 17 00:00:00 2001 From: fabsugar Date: Mon, 7 Nov 2022 15:36:10 -0500 Subject: [PATCH 47/62] Modified implementation of interval in calc_energy and calc_forces by using get_colvar_index_bound to treat vaules out of the boundary (which are projected inside the closest boundary). Additionally curr_values are now defined as a general variable to avoid define a new variable every time functions are called --- src/colvarbias_meta.cpp | 94 +++++++++-------------------------------- src/colvarbias_meta.h | 3 ++ src/colvargrid.h | 11 +++++ 3 files changed, 34 insertions(+), 74 deletions(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index 63de6038d..d19df9eb1 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -552,6 +552,11 @@ int colvarbias_meta::init_interval_params(std::string const &conf) std::vector interval_ulimit_cv; size_t i; size_t j; + // allocate accessory variable of colvar values to be used in energy and forces calculation + curr_values.resize(num_variables()); + for (i = 0; i < num_variables(); i++) { + curr_values[i].type(variables(i)->value()); + } if (get_keyval(conf, "useHillsInterval", use_interval, use_interval)) { if (use_interval) { @@ -1179,11 +1184,7 @@ int colvarbias_meta::calc_energy(std::vector const *values) size_t i; int ii; - cvm::real up_bound_bin_value; - std::vector curr_values(num_variables()); - for (i = 0; i < num_variables(); i++) { - curr_values[i].type(variables(i)->value()); - } + std::vector curr_bin; curr_values = values ? *values : colvar_values; @@ -1194,36 +1195,20 @@ int colvarbias_meta::calc_energy(std::vector const *values) curr_values[i]=interval_llimit[ii]; } ii=which_int_ulimit_cv[i]; - if (ii>-1 && curr_values[i]>=interval_ulimit[ii] ) { - // check if upper border is out of the grid otherwise put it back on the grid - up_bound_bin_value=hills_energy->lower_boundaries[i].real_value+variables(i)->width*(0.5+cvm::floor((interval_ulimit[ii]-hills_energy->lower_boundaries[i].real_value)/variables(i)->width)); - //if (interval_ulimit[ii]==hills_energy->upper_boundaries[i].real_value){ - if (up_bound_bin_value>hills_energy->upper_boundaries[i].real_value) { - curr_values[i]=interval_ulimit[ii]-0.5*(variables(i)->width); // upper border is out of grid; in this way is in - } else { - curr_values[i]=interval_ulimit[ii]; - } + if (ii>-1 && curr_values[i]>interval_ulimit[ii] ) { + curr_values[i]=interval_ulimit[ii]; } } + curr_bin = hills_energy->get_colvars_index_bound(curr_values); + } else { + curr_bin = hills_energy->get_colvars_index(curr_values); } for (ir = 0; ir < replicas.size(); ir++) { replicas[ir]->bias_energy = 0.0; } - std::vector const curr_bin = hills_energy->get_colvars_index(curr_values); - - if (use_grids) { - - curr_bin = values ? - hills_energy->get_colvars_index(*values) : - hills_energy->get_colvars_index(); - - index_ok = hills_energy->index_ok(curr_bin); - - } - - if ( index_ok ) { + if (hills_energy->index_ok(curr_bin)) { // index is within the grid: get the energy from there for (ir = 0; ir < replicas.size(); ir++) { @@ -1251,20 +1236,6 @@ int colvarbias_meta::calc_energy(std::vector const *values) // now include the hills that have not been binned yet (starting // from new_hills_begin) - if (use_interval) { - curr_values = values ? *values : colvar_values; - for (i = 0; i < num_variables(); i++) { - ii=which_int_llimit_cv[i]; - if (ii>-1 && curr_values[i]-1 && curr_values[i]>interval_ulimit[ii] ) { - curr_values[i]=interval_ulimit[ii]; - } - } - } - for (ir = 0; ir < replicas.size(); ir++) { calc_hills(replicas[ir]->new_hills_begin, replicas[ir]->hills.end(), @@ -1283,11 +1254,7 @@ int colvarbias_meta::calc_forces(std::vector const *values) { size_t ir = 0, ic = 0; int ii; - cvm::real up_bound_bin_value; - std::vector curr_values(num_variables()); - for (ic = 0; ic < num_variables(); ic++) { - curr_values[ic].type(variables(ic)->value()); - } + std::vector curr_bin; curr_values = values ? *values : colvar_values; std::vector add_force(num_variables()); for (ir = 0; ir < replicas.size(); ir++) { @@ -1307,20 +1274,18 @@ int colvarbias_meta::calc_forces(std::vector const *values) } ii=which_int_ulimit_cv[ic]; if (ii>-1) { - if ( curr_values[ic]>=interval_ulimit[ii] ) { + if ( curr_values[ic]>interval_ulimit[ii] ) { add_force[ic]=false; - up_bound_bin_value=hills_energy->lower_boundaries[ic].real_value+variables(ic)->width*(0.5+cvm::floor((interval_ulimit[ii]-hills_energy->lower_boundaries[ic].real_value)/variables(ic)->width)); - //if (interval_ulimit[ii]==hills_energy->upper_boundaries[ic].real_value){ - if (up_bound_bin_value>hills_energy->upper_boundaries[ic].real_value) { - curr_values[ic]=interval_ulimit[ii]-0.5*(variables(ic)->width); // upper border is out of grid; in this way is in - } else { - curr_values[ic]=interval_ulimit[ii]; - } + curr_values[ic]=interval_ulimit[ii]; } } } - std::vector const curr_bin = hills_energy->get_colvars_index(curr_values); + if (use_interval) { + curr_bin = hills_energy->get_colvars_index_bound(curr_values); + } else { + curr_bin = hills_energy->get_colvars_index(curr_values); + } if (use_grids) { @@ -1360,25 +1325,6 @@ int colvarbias_meta::calc_forces(std::vector const *values) // now include the hills that have not been binned yet (starting // from new_hills_begin) - if (use_interval) { - curr_values = values ? *values : colvar_values; - for (ic = 0; ic < num_variables(); ic++) { - ii=which_int_llimit_cv[ic]; - if (ii>-1) { - if ( curr_values[ic]-1) { - if ( curr_values[ic]>interval_ulimit[ii] ) { - curr_values[ic]=interval_ulimit[ii]; - } - } - } - } - - if (cvm::debug()) { cvm::log("Metadynamics bias \""+this->name+"\""+ ((comm != single_replica) ? ", replica \""+replica_id+"\"" : "")+ diff --git a/src/colvarbias_meta.h b/src/colvarbias_meta.h index 5dbeffd88..738deccc5 100644 --- a/src/colvarbias_meta.h +++ b/src/colvarbias_meta.h @@ -256,6 +256,9 @@ class colvarbias_meta std::vector interval_llimit; std::vector interval_ulimit; + /// \brief Current value of colvars to be modifed for calculation of energy and forces with interval + std::vector curr_values; + /// Ensemble-biased metadynamics (EBmeta) flag bool ebmeta; diff --git a/src/colvargrid.h b/src/colvargrid.h index 697b46a56..7738bac9a 100644 --- a/src/colvargrid.h +++ b/src/colvargrid.h @@ -714,6 +714,17 @@ template class colvar_grid : public colvar_grid_params, public colvarp /// \brief Get the bin indices corresponding to the provided values of /// the colvars and assign first or last bin if out of boundaries + inline std::vector const get_colvars_index_bound(std::vector const &values) const + { + std::vector index = new_index(); + for (size_t i = 0; i < nd; i++) { + index[i] = value_to_bin_scalar_bound(values[i], i); + } + return index; + } + + /// \brief Get the bin indices corresponding to the current values of + /// the colvars and assign first or last bin if out of boundaries inline std::vector const get_colvars_index_bound() const { std::vector index = new_index(); From 1fac297b35b95b5b69ab3d8d3c647731f37f0991 Mon Sep 17 00:00:00 2001 From: fabsugar Date: Tue, 18 Apr 2023 11:46:19 -0400 Subject: [PATCH 48/62] removed obsolete/unused h_replica in reflect_multid routine --- src/colvarbias_meta.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index d19df9eb1..d30dcdb63 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -860,7 +860,6 @@ int colvarbias_meta::reflect_hill_multid(cvm::real const &h_scale) } } if (hill_add) { - std::string h_replica = ""; switch (comm) { case single_replica: @@ -870,7 +869,6 @@ int colvarbias_meta::reflect_hill_multid(cvm::real const &h_scale) break; case multiple_replicas: - h_replica=replica_id; add_hill(hill(cvm::step_absolute(), hill_weight*h_scale, curr_cv_values, colvar_sigmas, replica_id)); std::ostream *replica_hills_os = cvm::proxy->get_output_stream(replica_hills_file); From 998418a3a775b49500fad659fb9643d1ca10344c Mon Sep 17 00:00:00 2001 From: fabsugar Date: Wed, 19 Apr 2023 14:35:13 -0400 Subject: [PATCH 49/62] Added interval vectors as argument of project hills function. This fixes the seg fault when using multiple replicas --- src/colvarbias_meta.cpp | 30 ++++++++++++++++++++---------- src/colvarbias_meta.h | 7 +++++-- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index d30dcdb63..869eb5da6 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -1156,7 +1156,9 @@ int colvarbias_meta::update_grid_data() { if ((cvm::step_absolute() % grids_freq) == 0) { // map the most recent gaussians to the grids - project_hills(new_hills_begin, hills.end(), hills_energy.get(), hills_energy_gradients.get()); + project_hills(new_hills_begin, hills.end(), hills_energy.get(), hills_energy_gradients.get(), + which_int_llimit_cv, which_int_ulimit_cv, + interval_llimit, interval_ulimit); new_hills_begin = hills.end(); // TODO: we may want to condense all into one replicas array, @@ -1166,7 +1168,9 @@ int colvarbias_meta::update_grid_data() replicas[ir]->project_hills(replicas[ir]->new_hills_begin, replicas[ir]->hills.end(), replicas[ir]->hills_energy.get(), - replicas[ir]->hills_energy_gradients.get()); + replicas[ir]->hills_energy_gradients.get(), + which_int_llimit_cv, which_int_ulimit_cv, + interval_llimit, interval_ulimit); replicas[ir]->new_hills_begin = replicas[ir]->hills.end(); } } @@ -1458,6 +1462,10 @@ void colvarbias_meta::project_hills(colvarbias_meta::hill_iter h_first, colvarbias_meta::hill_iter h_last, colvar_grid_scalar *he, colvar_grid_gradient *hg, + std::vector const &w_int_llimit_cv, + std::vector const &w_int_ulimit_cv, + std::vector const &int_llimit, + std::vector const &int_ulimit, bool print_progress) { if (cvm::debug()) @@ -1491,17 +1499,17 @@ void colvarbias_meta::project_hills(colvarbias_meta::hill_iter h_first, for (i = 0; i < num_variables(); i++) { add_force[i]=true; new_colvar_values[i] = he->bin_to_value_scalar(he_ix[i], i); - ii=which_int_llimit_cv[i]; + ii=w_int_llimit_cv[i]; if (ii>-1 ){ - if ( new_colvar_values[i]-1){ - if( new_colvar_values[i]>interval_ulimit[ii] ) { - new_colvar_values[i]=interval_ulimit[ii]; + if( new_colvar_values[i]>int_ulimit[ii] ) { + new_colvar_values[i]=int_ulimit[ii]; add_force[i]=false; } } @@ -2074,8 +2082,10 @@ void colvarbias_meta::rebin_grids_after_restart() // if there are hills, recompute the new grids from them cvm::log("Rebinning the energy and forces grids from "+ cvm::to_str(hills.size())+" hills (this may take a bit)...\n"); - project_hills(hills.begin(), hills.end(), new_hills_energy.get(), - new_hills_energy_gradients.get(), true); + project_hills(hills.begin(), hills.end(), + new_hills_energy.get(), new_hills_energy_gradients.get(), + which_int_llimit_cv, which_int_ulimit_cv, + interval_llimit, interval_ulimit, true); cvm::log("rebinning done.\n"); } else { diff --git a/src/colvarbias_meta.h b/src/colvarbias_meta.h index 738deccc5..5ee53f76f 100644 --- a/src/colvarbias_meta.h +++ b/src/colvarbias_meta.h @@ -281,8 +281,11 @@ class colvarbias_meta std::shared_ptr hills_energy_gradients; /// Project the selected hills onto grids - void project_hills(hill_iter h_first, hill_iter h_last, colvar_grid_scalar *ge, - colvar_grid_gradient *gf, bool print_progress = false); + void project_hills(hill_iter h_first, hill_iter h_last, + colvar_grid_scalar *ge, colvar_grid_gradient *gf, + std::vector const &w_int_llimit_cv, std::vector const &w_int_ulimit_cv, + std::vector const &int_llimit, std::vector const &int_ulimit, + bool print_progress = false); // Multiple Replicas variables and functions From 91329c6227dfd125308a1bd57815a9dd447a2ed5 Mon Sep 17 00:00:00 2001 From: Giacomo Fiorin Date: Wed, 19 Apr 2023 16:28:17 -0400 Subject: [PATCH 50/62] Integrate change to stream access --- src/colvarbias_meta.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index 869eb5da6..6775e52fd 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -552,7 +552,7 @@ int colvarbias_meta::init_interval_params(std::string const &conf) std::vector interval_ulimit_cv; size_t i; size_t j; - // allocate accessory variable of colvar values to be used in energy and forces calculation + // allocate accessory variable of colvar values to be used in energy and forces calculation curr_values.resize(num_variables()); for (i = 0; i < num_variables(); i++) { curr_values[i].type(variables(i)->value()); @@ -870,10 +870,10 @@ int colvarbias_meta::reflect_hill_multid(cvm::real const &h_scale) case multiple_replicas: add_hill(hill(cvm::step_absolute(), hill_weight*h_scale, curr_cv_values, colvar_sigmas, replica_id)); - std::ostream *replica_hills_os = - cvm::proxy->get_output_stream(replica_hills_file); + std::ostream &replica_hills_os = + cvm::proxy->output_stream(replica_hills_file); if (replica_hills_os) { - *replica_hills_os << hills.back(); + replica_hills_os << hills.back(); } else { return cvm::error("Error: in metadynamics bias \""+this->name+"\""+ ((comm != single_replica) ? ", replica \""+replica_id+"\"" : "")+ @@ -1287,7 +1287,7 @@ int colvarbias_meta::calc_forces(std::vector const *values) curr_bin = hills_energy->get_colvars_index_bound(curr_values); } else { curr_bin = hills_energy->get_colvars_index(curr_values); - } + } if (use_grids) { @@ -1462,9 +1462,9 @@ void colvarbias_meta::project_hills(colvarbias_meta::hill_iter h_first, colvarbias_meta::hill_iter h_last, colvar_grid_scalar *he, colvar_grid_gradient *hg, - std::vector const &w_int_llimit_cv, + std::vector const &w_int_llimit_cv, std::vector const &w_int_ulimit_cv, - std::vector const &int_llimit, + std::vector const &int_llimit, std::vector const &int_ulimit, bool print_progress) { @@ -2084,7 +2084,7 @@ void colvarbias_meta::rebin_grids_after_restart() cvm::to_str(hills.size())+" hills (this may take a bit)...\n"); project_hills(hills.begin(), hills.end(), new_hills_energy.get(), new_hills_energy_gradients.get(), - which_int_llimit_cv, which_int_ulimit_cv, + which_int_llimit_cv, which_int_ulimit_cv, interval_llimit, interval_ulimit, true); cvm::log("rebinning done.\n"); From 10af1fe1f18844abefe18fc45708be250cc7edae Mon Sep 17 00:00:00 2001 From: Giacomo Fiorin Date: Fri, 13 Oct 2023 13:39:26 -0400 Subject: [PATCH 51/62] Fix remaining merge conflicts --- src/colvarbias_meta.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index 6775e52fd..9e90abdf3 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -871,9 +871,9 @@ int colvarbias_meta::reflect_hill_multid(cvm::real const &h_scale) case multiple_replicas: add_hill(hill(cvm::step_absolute(), hill_weight*h_scale, curr_cv_values, colvar_sigmas, replica_id)); std::ostream &replica_hills_os = - cvm::proxy->output_stream(replica_hills_file); + cvm::proxy->output_stream(replica_hills_file, "replica hills file"); if (replica_hills_os) { - replica_hills_os << hills.back(); + write_hill(replica_hills_os, hills.back()); } else { return cvm::error("Error: in metadynamics bias \""+this->name+"\""+ ((comm != single_replica) ? ", replica \""+replica_id+"\"" : "")+ @@ -1130,7 +1130,7 @@ int colvarbias_meta::update_bias() std::ostream &replica_hills_os = cvm::proxy->output_stream(replica_hills_file, "replica hills file"); if (replica_hills_os) { - replica_hills_os << hills.back(); + write_hill(replica_hills_os, hills.back()); } else { return cvm::error("Error: in metadynamics bias \""+this->name+"\""+ ((comm != single_replica) ? ", replica \""+replica_id+"\"" : "")+ @@ -2443,7 +2443,10 @@ template OST &colvarbias_meta::write_state_data_template_(OST &os // this is a very good time to project hills, if you haven't done // it already! - project_hills(new_hills_begin, hills.end(), hills_energy.get(), hills_energy_gradients.get()); + project_hills(new_hills_begin, hills.end(), + hills_energy.get(), hills_energy_gradients.get(), + which_int_llimit_cv, which_int_ulimit_cv, + interval_llimit, interval_ulimit); new_hills_begin = hills.end(); // write down the grids to the restart file From 1c46af3ebd788f68c7b77ee6f30e54adb3da2341 Mon Sep 17 00:00:00 2001 From: fabsugar Date: Tue, 6 Feb 2024 12:45:37 -0500 Subject: [PATCH 52/62] Added test for reflection in metadynamics (not tested yet) --- .../AutoDiff/test.colvars.out | 157 +++++++++++++++++ .../AutoDiff/test.colvars.state.stripped | 47 +++++ .../AutoDiff/test.colvars.traj | 22 +++ .../AutoDiff/test.pmf | 23 +++ .../AutoDiff/test.restart.colvars.out | 162 ++++++++++++++++++ .../test.restart.colvars.state.stripped | 47 +++++ .../AutoDiff/test.restart.colvars.traj | 22 +++ .../AutoDiff/test.restart.pmf | 23 +++ .../namd-version.txt | 3 + .../test.in | 43 +++++ 10 files changed, 549 insertions(+) create mode 100644 namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.colvars.out create mode 100644 namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.colvars.state.stripped create mode 100644 namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.colvars.traj create mode 100644 namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.pmf create mode 100644 namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.restart.colvars.out create mode 100644 namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.restart.colvars.state.stripped create mode 100644 namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.restart.colvars.traj create mode 100644 namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.restart.pmf create mode 100644 namd/tests/library/000_distance-grid_metadynamics-reflection/namd-version.txt create mode 100644 namd/tests/library/000_distance-grid_metadynamics-reflection/test.in diff --git a/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.colvars.out b/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.colvars.out new file mode 100644 index 000000000..0343b9172 --- /dev/null +++ b/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.colvars.out @@ -0,0 +1,157 @@ +colvars: ---------------------------------------------------------------------- +colvars: Please cite Fiorin et al, Mol Phys 2013: +colvars: https://dx.doi.org/10.1080/00268976.2013.813594 +colvars: in any publication based on this calculation. +colvars: SMP parallelism is enabled; if needed, use "smp off" to override this. +colvars: This version was built with the C++11 standard or higher. +colvars: ---------------------------------------------------------------------- +colvars: Reading new configuration from file "test.in": +colvars: # units = "" [default] +colvars: # indexFile = "index.ndx" +colvars: The following index groups are currently defined: +colvars: Protein (104 atoms) +colvars: Protein_noH (51 atoms) +colvars: Protein_Backbone (40 atoms) +colvars: Protein_C-alpha (10 atoms) +colvars: RMSD_atoms (10 atoms) +colvars: Protein_C-alpha_1_2 (2 atoms) +colvars: Protein_C-alpha_9_10 (2 atoms) +colvars: Protein_C-alpha_1 (1 atoms) +colvars: group1 (4 atoms) +colvars: Protein_C-alpha_2 (1 atoms) +colvars: group2 (4 atoms) +colvars: Protein_C-alpha_3 (1 atoms) +colvars: group3 (4 atoms) +colvars: Protein_C-alpha_4 (1 atoms) +colvars: group4 (4 atoms) +colvars: Protein_C-alpha_5 (1 atoms) +colvars: group5 (4 atoms) +colvars: Protein_C-alpha_6 (1 atoms) +colvars: group6 (4 atoms) +colvars: Protein_C-alpha_7 (1 atoms) +colvars: group7 (4 atoms) +colvars: Protein_C-alpha_8 (1 atoms) +colvars: group8 (4 atoms) +colvars: Protein_C-alpha_9 (1 atoms) +colvars: group9 (4 atoms) +colvars: Protein_C-alpha_10 (1 atoms) +colvars: group10 (4 atoms) +colvars: heavy_atoms (51 atoms) +colvars: # smp = on [default] +colvars: # colvarsTrajFrequency = 1 +colvars: # colvarsRestartFrequency = 10 +colvars: # scriptedColvarForces = off [default] +colvars: # scriptingAfterBiases = off [default] +colvars: ---------------------------------------------------------------------- +colvars: Initializing a new collective variable. +colvars: # name = "one" +colvars: Initializing a new "distance" component. +colvars: # name = "" [default] +colvars: # componentCoeff = 1 [default] +colvars: # componentExp = 1 [default] +colvars: # period = 0 [default] +colvars: # wrapAround = 0 [default] +colvars: # forceNoPBC = off [default] +colvars: # scalable = on [default] +colvars: Initializing atom group "group1". +colvars: # name = "" [default] +colvars: # centerReference = off [default] +colvars: # rotateReference = off [default] +colvars: # atomsOfGroup = "" [default] +colvars: # indexGroup = "group1" +colvars: # psfSegID = [default] +colvars: # atomsFile = "" [default] +colvars: # dummyAtom = ( 0 , 0 , 0 ) [default] +colvars: # enableForces = on [default] +colvars: # enableFitGradients = on [default] +colvars: Enabling scalable calculation for group "group1". +colvars: # printAtomIDs = off [default] +colvars: Atom group "group1" defined with 4 atoms requested: total mass = 54.028, total charge = -0.72. +colvars: Initializing atom group "group2". +colvars: # name = "" [default] +colvars: # centerReference = off [default] +colvars: # rotateReference = off [default] +colvars: # atomsOfGroup = "" [default] +colvars: # indexGroup = "group2" +colvars: # psfSegID = [default] +colvars: # atomsFile = "" [default] +colvars: # dummyAtom = ( 0 , 0 , 0 ) [default] +colvars: # enableForces = on [default] +colvars: # enableFitGradients = on [default] +colvars: Enabling scalable calculation for group "group2". +colvars: # printAtomIDs = off [default] +colvars: Atom group "group2" defined with 4 atoms requested: total mass = 54.028, total charge = -0.4. +colvars: # oneSiteSystemForce = off [default] +colvars: # oneSiteTotalForce = off [default] +colvars: All components initialized. +colvars: # timeStepFactor = 1 [default] +colvars: # width = 0.5 +colvars: # lowerBoundary = 0 [default] +colvars: # upperBoundary = 10 +colvars: # hardLowerBoundary = on [default] +colvars: # hardUpperBoundary = off [default] +colvars: # expandBoundaries = off [default] +colvars: # extendedLagrangian = off [default] +colvars: # outputValue = on [default] +colvars: # outputVelocity = off [default] +colvars: # outputTotalForce = off [default] +colvars: # outputAppliedForce = on +colvars: # subtractAppliedForce = off [default] +colvars: # runAve = off [default] +colvars: # corrFunc = off [default] +colvars: ---------------------------------------------------------------------- +colvars: Collective variables initialized, 1 in total. +colvars: ---------------------------------------------------------------------- +colvars: Initializing a new "metadynamics" instance. +colvars: # name = "metadynamics1" [default] +colvars: # colvars = { one } +colvars: # stepZeroData = off [default] +colvars: # outputEnergy = off [default] +colvars: # outputFreq = 10 [default] +colvars: # timeStepFactor = 1 [default] +colvars: # writeTISamples = off [default] +colvars: # writeTIPMF = off [default] +colvars: # hillWeight = 0.001 +colvars: # newHillFrequency = 10 +colvars: # gaussianSigmas = [default] +colvars: # hillWidth = 1.25331 +colvars: Half-widths of the Gaussian hills (sigma's): +colvars: one: 0.313329 +colvars: # multipleReplicas = off [default] +colvars: # useGrids = on [default] +colvars: # gridsUpdateFrequency = 10 [default] +colvars: # rebinGrids = off [default] +colvars: # writeFreeEnergyFile = on [default] +colvars: # keepHills = off [default] +colvars: # keepFreeEnergyFiles = off [default] +colvars: # writeHillsTrajectory = off [default] +colvars: # wellTempered = off [default] +colvars: # biasTemperature = -1 [default] +colvars: # ebMeta = off [default] +colvars: ---------------------------------------------------------------------- +colvars: Collective variables biases initialized, 1 in total. +colvars: ---------------------------------------------------------------------- +colvars: Collective variables module (re)initialized. +colvars: ---------------------------------------------------------------------- +colvars: Updating NAMD interface: +colvars: updating atomic data (0 atoms). +colvars: updating group data (2 scalable groups, 8 atoms in total). +colvars: Re-initialized atom group for variable "one":0/0. 4 atoms: total mass = 54.028, total charge = -0.72. +colvars: Re-initialized atom group for variable "one":0/1. 4 atoms: total mass = 54.028, total charge = -0.4. +colvars: The restart output state file will be "test.tmp.colvars.state". +colvars: The final output state file will be "test.colvars.state". +colvars: Opening trajectory file "test.colvars.traj". +colvars: Redefining the Tcl "cv" command to the new script interface. +colvars: Updating NAMD interface: +colvars: updating atomic data (0 atoms). +colvars: updating group data (2 scalable groups, 8 atoms in total). +colvars: Re-initialized atom group for variable "one":0/0. 4 atoms: total mass = 54.028, total charge = -0.72. +colvars: Re-initialized atom group for variable "one":0/1. 4 atoms: total mass = 54.028, total charge = -0.4. +colvars: The restart output state file will be "test.tmp.colvars.state". +colvars: The final output state file will be "test.colvars.state". +colvars: Synchronizing (emptying the buffer of) trajectory file "test.colvars.traj". +colvars: Synchronizing (emptying the buffer of) trajectory file "test.colvars.traj". +colvars: Saving collective variables state to "test.tmp.colvars.state". +colvars: Synchronizing (emptying the buffer of) trajectory file "test.colvars.traj". +colvars: Saving collective variables state to "test.tmp.colvars.state". +colvars: Saving collective variables state to "test.colvars.state". diff --git a/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.colvars.state.stripped b/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.colvars.state.stripped new file mode 100644 index 000000000..6de09bffd --- /dev/null +++ b/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.colvars.state.stripped @@ -0,0 +1,47 @@ +configuration { + step 20 + dt 1.000000e+00 +} + +colvar { + name one + x 3.21688278597333e+00 +} + +metadynamics { + configuration { + step 20 + name metadynamics1 + } + hills_energy +grid_parameters { + n_colvars 1 + lower_boundaries 0.00000000000000e+00 + upper_boundaries 1.00000000000000e+01 + widths 5.00000000000000e-01 + sizes 20 +} + 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 + 3.46920492770083e-08 1.70721010112539e-05 6.58298335288197e-04 + 1.98901157291202e-03 4.70902104436801e-04 8.73580076380761e-06 + 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 + 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 + 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 + 0.00000000000000e+00 0.00000000000000e+00 + hills_energy_gradients +grid_parameters { + n_colvars 1 + lower_boundaries 0.00000000000000e+00 + upper_boundaries 1.00000000000000e+01 + widths 5.00000000000000e-01 + sizes 20 +} + 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 + 5.18433073974142e-07 1.68175610579987e-04 3.13214890940428e-03 + -6.66334787942696e-04 -2.55603942784152e-03 -9.19086519769792e-05 + 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 + 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 + 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 + 0.00000000000000e+00 0.00000000000000e+00 +} + diff --git a/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.colvars.traj b/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.colvars.traj new file mode 100644 index 000000000..3ac32bb03 --- /dev/null +++ b/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.colvars.traj @@ -0,0 +1,22 @@ +# step one fa_one + 0 3.20554673468334e+00 0.00000000000000e+00 + 1 3.20437148316546e+00 0.00000000000000e+00 + 2 3.20384028589204e+00 0.00000000000000e+00 + 3 3.20396721187433e+00 0.00000000000000e+00 + 4 3.20472817287036e+00 0.00000000000000e+00 + 5 3.20606308066645e+00 0.00000000000000e+00 + 6 3.20787989003051e+00 0.00000000000000e+00 + 7 3.21005997943917e+00 0.00000000000000e+00 + 8 3.21246460655188e+00 0.00000000000000e+00 + 9 3.21494247388772e+00 0.00000000000000e+00 + 10 3.21733851236362e+00 3.30884583259955e-04 + 11 3.21950367891521e+00 3.30884583259955e-04 + 12 3.22130501376020e+00 3.30884583259955e-04 + 13 3.22263482513293e+00 3.30884583259955e-04 + 14 3.22341774651982e+00 3.30884583259955e-04 + 15 3.22361481079113e+00 3.30884583259955e-04 + 16 3.22322427751010e+00 3.30884583259955e-04 + 17 3.22227956023865e+00 3.30884583259955e-04 + 18 3.22084496840419e+00 3.30884583259955e-04 + 19 3.21901000786075e+00 3.30884583259955e-04 + 20 3.21688278597333e+00 6.66334787942696e-04 diff --git a/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.pmf b/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.pmf new file mode 100644 index 000000000..3a05a7c71 --- /dev/null +++ b/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.pmf @@ -0,0 +1,23 @@ +# 1 +# 0.00000000000000e+00 5.00000000000000e-01 20 0 + + 2.50000000000000e-01 1.98901157291202e-03 + 7.50000000000000e-01 1.98901157291202e-03 + 1.25000000000000e+00 1.98901157291202e-03 + 1.75000000000000e+00 1.98897688086274e-03 + 2.25000000000000e+00 1.97193947190077e-03 + 2.75000000000000e+00 1.33071323762382e-03 + 3.25000000000000e+00 -0.00000000000000e+00 + 3.75000000000000e+00 1.51810946847522e-03 + 4.25000000000000e+00 1.98027577214821e-03 + 4.75000000000000e+00 1.98901157291202e-03 + 5.25000000000000e+00 1.98901157291202e-03 + 5.75000000000000e+00 1.98901157291202e-03 + 6.25000000000000e+00 1.98901157291202e-03 + 6.75000000000000e+00 1.98901157291202e-03 + 7.25000000000000e+00 1.98901157291202e-03 + 7.75000000000000e+00 1.98901157291202e-03 + 8.25000000000000e+00 1.98901157291202e-03 + 8.75000000000000e+00 1.98901157291202e-03 + 9.25000000000000e+00 1.98901157291202e-03 + 9.75000000000000e+00 1.98901157291202e-03 diff --git a/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.restart.colvars.out b/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.restart.colvars.out new file mode 100644 index 000000000..1c3db0232 --- /dev/null +++ b/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.restart.colvars.out @@ -0,0 +1,162 @@ +colvars: ---------------------------------------------------------------------- +colvars: Please cite Fiorin et al, Mol Phys 2013: +colvars: https://dx.doi.org/10.1080/00268976.2013.813594 +colvars: in any publication based on this calculation. +colvars: SMP parallelism is enabled; if needed, use "smp off" to override this. +colvars: This version was built with the C++11 standard or higher. +colvars: ---------------------------------------------------------------------- +colvars: Reading new configuration from file "test.in": +colvars: # units = "" [default] +colvars: # indexFile = "index.ndx" +colvars: The following index groups are currently defined: +colvars: Protein (104 atoms) +colvars: Protein_noH (51 atoms) +colvars: Protein_Backbone (40 atoms) +colvars: Protein_C-alpha (10 atoms) +colvars: RMSD_atoms (10 atoms) +colvars: Protein_C-alpha_1_2 (2 atoms) +colvars: Protein_C-alpha_9_10 (2 atoms) +colvars: Protein_C-alpha_1 (1 atoms) +colvars: group1 (4 atoms) +colvars: Protein_C-alpha_2 (1 atoms) +colvars: group2 (4 atoms) +colvars: Protein_C-alpha_3 (1 atoms) +colvars: group3 (4 atoms) +colvars: Protein_C-alpha_4 (1 atoms) +colvars: group4 (4 atoms) +colvars: Protein_C-alpha_5 (1 atoms) +colvars: group5 (4 atoms) +colvars: Protein_C-alpha_6 (1 atoms) +colvars: group6 (4 atoms) +colvars: Protein_C-alpha_7 (1 atoms) +colvars: group7 (4 atoms) +colvars: Protein_C-alpha_8 (1 atoms) +colvars: group8 (4 atoms) +colvars: Protein_C-alpha_9 (1 atoms) +colvars: group9 (4 atoms) +colvars: Protein_C-alpha_10 (1 atoms) +colvars: group10 (4 atoms) +colvars: heavy_atoms (51 atoms) +colvars: # smp = on [default] +colvars: # colvarsTrajFrequency = 1 +colvars: # colvarsRestartFrequency = 10 +colvars: # scriptedColvarForces = off [default] +colvars: # scriptingAfterBiases = off [default] +colvars: ---------------------------------------------------------------------- +colvars: Initializing a new collective variable. +colvars: # name = "one" +colvars: Initializing a new "distance" component. +colvars: # name = "" [default] +colvars: # componentCoeff = 1 [default] +colvars: # componentExp = 1 [default] +colvars: # period = 0 [default] +colvars: # wrapAround = 0 [default] +colvars: # forceNoPBC = off [default] +colvars: # scalable = on [default] +colvars: Initializing atom group "group1". +colvars: # name = "" [default] +colvars: # centerReference = off [default] +colvars: # rotateReference = off [default] +colvars: # atomsOfGroup = "" [default] +colvars: # indexGroup = "group1" +colvars: # psfSegID = [default] +colvars: # atomsFile = "" [default] +colvars: # dummyAtom = ( 0 , 0 , 0 ) [default] +colvars: # enableForces = on [default] +colvars: # enableFitGradients = on [default] +colvars: Enabling scalable calculation for group "group1". +colvars: # printAtomIDs = off [default] +colvars: Atom group "group1" defined with 4 atoms requested: total mass = 54.028, total charge = -0.72. +colvars: Initializing atom group "group2". +colvars: # name = "" [default] +colvars: # centerReference = off [default] +colvars: # rotateReference = off [default] +colvars: # atomsOfGroup = "" [default] +colvars: # indexGroup = "group2" +colvars: # psfSegID = [default] +colvars: # atomsFile = "" [default] +colvars: # dummyAtom = ( 0 , 0 , 0 ) [default] +colvars: # enableForces = on [default] +colvars: # enableFitGradients = on [default] +colvars: Enabling scalable calculation for group "group2". +colvars: # printAtomIDs = off [default] +colvars: Atom group "group2" defined with 4 atoms requested: total mass = 54.028, total charge = -0.4. +colvars: # oneSiteSystemForce = off [default] +colvars: # oneSiteTotalForce = off [default] +colvars: All components initialized. +colvars: # timeStepFactor = 1 [default] +colvars: # width = 0.5 +colvars: # lowerBoundary = 0 [default] +colvars: # upperBoundary = 10 +colvars: # hardLowerBoundary = on [default] +colvars: # hardUpperBoundary = off [default] +colvars: # expandBoundaries = off [default] +colvars: # extendedLagrangian = off [default] +colvars: # outputValue = on [default] +colvars: # outputVelocity = off [default] +colvars: # outputTotalForce = off [default] +colvars: # outputAppliedForce = on +colvars: # subtractAppliedForce = off [default] +colvars: # runAve = off [default] +colvars: # corrFunc = off [default] +colvars: ---------------------------------------------------------------------- +colvars: Collective variables initialized, 1 in total. +colvars: ---------------------------------------------------------------------- +colvars: Initializing a new "metadynamics" instance. +colvars: # name = "metadynamics1" [default] +colvars: # colvars = { one } +colvars: # stepZeroData = off [default] +colvars: # outputEnergy = off [default] +colvars: # outputFreq = 10 [default] +colvars: # timeStepFactor = 1 [default] +colvars: # writeTISamples = off [default] +colvars: # writeTIPMF = off [default] +colvars: # hillWeight = 0.001 +colvars: # newHillFrequency = 10 +colvars: # gaussianSigmas = [default] +colvars: # hillWidth = 1.25331 +colvars: Half-widths of the Gaussian hills (sigma's): +colvars: one: 0.313329 +colvars: # multipleReplicas = off [default] +colvars: # useGrids = on [default] +colvars: # gridsUpdateFrequency = 10 [default] +colvars: # rebinGrids = off [default] +colvars: # writeFreeEnergyFile = on [default] +colvars: # keepHills = off [default] +colvars: # keepFreeEnergyFiles = off [default] +colvars: # writeHillsTrajectory = off [default] +colvars: # wellTempered = off [default] +colvars: # biasTemperature = -1 [default] +colvars: # ebMeta = off [default] +colvars: ---------------------------------------------------------------------- +colvars: Collective variables biases initialized, 1 in total. +colvars: ---------------------------------------------------------------------- +colvars: Collective variables module (re)initialized. +colvars: ---------------------------------------------------------------------- +colvars: Updating NAMD interface: +colvars: updating atomic data (0 atoms). +colvars: updating group data (2 scalable groups, 8 atoms in total). +colvars: Re-initialized atom group for variable "one":0/0. 4 atoms: total mass = 54.028, total charge = -0.72. +colvars: Re-initialized atom group for variable "one":0/1. 4 atoms: total mass = 54.028, total charge = -0.4. +colvars: ---------------------------------------------------------------------- +colvars: Restarting from file "test.colvars.state". +colvars: Restarting collective variable "one" from value: 3.21688 +colvars: Restarting metadynamics bias "metadynamics1" from step number 20. +colvars: ---------------------------------------------------------------------- +colvars: The restart output state file will be "test.restart.tmp.colvars.state". +colvars: The final output state file will be "test.restart.colvars.state". +colvars: Opening trajectory file "test.restart.colvars.traj". +colvars: Redefining the Tcl "cv" command to the new script interface. +colvars: Updating NAMD interface: +colvars: updating atomic data (0 atoms). +colvars: updating group data (2 scalable groups, 8 atoms in total). +colvars: Re-initialized atom group for variable "one":0/0. 4 atoms: total mass = 54.028, total charge = -0.72. +colvars: Re-initialized atom group for variable "one":0/1. 4 atoms: total mass = 54.028, total charge = -0.4. +colvars: The restart output state file will be "test.restart.tmp.colvars.state". +colvars: The final output state file will be "test.restart.colvars.state". +colvars: Synchronizing (emptying the buffer of) trajectory file "test.restart.colvars.traj". +colvars: Synchronizing (emptying the buffer of) trajectory file "test.restart.colvars.traj". +colvars: Saving collective variables state to "test.restart.tmp.colvars.state". +colvars: Synchronizing (emptying the buffer of) trajectory file "test.restart.colvars.traj". +colvars: Saving collective variables state to "test.restart.tmp.colvars.state". +colvars: Saving collective variables state to "test.restart.colvars.state". diff --git a/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.restart.colvars.state.stripped b/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.restart.colvars.state.stripped new file mode 100644 index 000000000..235b1896e --- /dev/null +++ b/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.restart.colvars.state.stripped @@ -0,0 +1,47 @@ +configuration { + step 40 + dt 1.000000e+00 +} + +colvar { + name one + x 3.21405136134992e+00 +} + +metadynamics { + configuration { + step 40 + name metadynamics1 + } + hills_energy +grid_parameters { + n_colvars 1 + lower_boundaries 0.00000000000000e+00 + upper_boundaries 1.00000000000000e+01 + widths 5.00000000000000e-01 + sizes 20 +} + 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 + 7.43923403227782e-08 3.57122155647627e-05 1.34466139685731e-03 + 3.97104317655277e-03 9.19770327415716e-04 1.67080044623168e-05 + 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 + 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 + 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 + 0.00000000000000e+00 0.00000000000000e+00 + hills_energy_gradients +grid_parameters { + n_colvars 1 + lower_boundaries 0.00000000000000e+00 + upper_boundaries 1.00000000000000e+01 + widths 5.00000000000000e-01 + sizes 20 +} + 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 + 1.10794466055357e-06 3.50062167930554e-04 6.33510417866273e-03 + -1.50805868972440e-03 -5.03195891853835e-03 -1.76471077879577e-04 + 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 + 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 + 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 + 0.00000000000000e+00 0.00000000000000e+00 +} + diff --git a/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.restart.colvars.traj b/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.restart.colvars.traj new file mode 100644 index 000000000..6b959f565 --- /dev/null +++ b/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.restart.colvars.traj @@ -0,0 +1,22 @@ +# step one fa_one + 20 3.21688278597333e+00 6.66334787942696e-04 + 21 3.21458283262116e+00 6.66334787942696e-04 + 22 3.21223351074552e+00 6.66334787942696e-04 + 23 3.20995434276490e+00 6.66334787942696e-04 + 24 3.20785376300757e+00 6.66334787942696e-04 + 25 3.20602301895356e+00 6.66334787942696e-04 + 26 3.20453185497061e+00 6.66334787942696e-04 + 27 3.20342630674324e+00 6.66334787942696e-04 + 28 3.20272853390700e+00 6.66334787942696e-04 + 29 3.20243824119566e+00 6.66334787942696e-04 + 30 3.20253526877602e+00 1.14429095260314e-03 + 31 3.20298298275490e+00 1.14429095260314e-03 + 32 3.20373228243844e+00 1.14429095260314e-03 + 33 3.20472609508842e+00 1.14429095260314e-03 + 34 3.20590411372385e+00 1.14429095260314e-03 + 35 3.20720736612802e+00 1.14429095260314e-03 + 36 3.20858216980690e+00 1.14429095260314e-03 + 37 3.20998315211066e+00 1.14429095260314e-03 + 38 3.21137529195283e+00 1.14429095260314e-03 + 39 3.21273513276742e+00 1.14429095260314e-03 + 40 3.21405136134992e+00 1.50805868972440e-03 diff --git a/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.restart.pmf b/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.restart.pmf new file mode 100644 index 000000000..051812fec --- /dev/null +++ b/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.restart.pmf @@ -0,0 +1,23 @@ +# 1 +# 0.00000000000000e+00 5.00000000000000e-01 20 0 + + 2.50000000000000e-01 3.97104317655277e-03 + 7.50000000000000e-01 3.97104317655277e-03 + 1.25000000000000e+00 3.97104317655277e-03 + 1.75000000000000e+00 3.97096878421245e-03 + 2.25000000000000e+00 3.93533096098801e-03 + 2.75000000000000e+00 2.62638177969546e-03 + 3.25000000000000e+00 -0.00000000000000e+00 + 3.75000000000000e+00 3.05127284913705e-03 + 4.25000000000000e+00 3.95433517209045e-03 + 4.75000000000000e+00 3.97104317655277e-03 + 5.25000000000000e+00 3.97104317655277e-03 + 5.75000000000000e+00 3.97104317655277e-03 + 6.25000000000000e+00 3.97104317655277e-03 + 6.75000000000000e+00 3.97104317655277e-03 + 7.25000000000000e+00 3.97104317655277e-03 + 7.75000000000000e+00 3.97104317655277e-03 + 8.25000000000000e+00 3.97104317655277e-03 + 8.75000000000000e+00 3.97104317655277e-03 + 9.25000000000000e+00 3.97104317655277e-03 + 9.75000000000000e+00 3.97104317655277e-03 diff --git a/namd/tests/library/000_distance-grid_metadynamics-reflection/namd-version.txt b/namd/tests/library/000_distance-grid_metadynamics-reflection/namd-version.txt new file mode 100644 index 000000000..e2b19c981 --- /dev/null +++ b/namd/tests/library/000_distance-grid_metadynamics-reflection/namd-version.txt @@ -0,0 +1,3 @@ +Info: NAMD 2.14b1 for Linux-x86_64-multicore +colvars: Initializing the collective variables module, version "2020-04-09". +colvars: Using NAMD interface, version "2020-04-07". diff --git a/namd/tests/library/000_distance-grid_metadynamics-reflection/test.in b/namd/tests/library/000_distance-grid_metadynamics-reflection/test.in new file mode 100644 index 000000000..7b7d14392 --- /dev/null +++ b/namd/tests/library/000_distance-grid_metadynamics-reflection/test.in @@ -0,0 +1,43 @@ +colvarsTrajFrequency 1 +colvarsRestartFrequency 10 +indexFile index.ndx + +colvar { + + name one + + outputAppliedForce on + + # use a non-trivial width to test bias behavior + width 0.5 + # The lower boundary is already defined at 0 for a distance function + # lowerBoundary 0.0 + upperBoundary 10.0 + + hardUpperBoundary on + hardLowerBoundary on + + distance { + group1 { + indexGroup group1 + } + group2 { + indexGroup group2 + } + } +} + +metadynamics { + colvars one + hillWeight 0.001 + hillWidth 1.2533141373155001 # Old default + newHillFrequency 10 + useHillsReflection on +} + +harmonicWalls { + name wall_dist_N_O + colvars dist_N_O + forceConstant 0.6 + upperWalls 10.0 +} From dc3848433fab7733b730436d11e7a67e71ebe2d5 Mon Sep 17 00:00:00 2001 From: fabsugar Date: Tue, 6 Feb 2024 12:59:22 -0500 Subject: [PATCH 53/62] Corrected typos on reflection test --- .../000_distance-grid_metadynamics-reflection/test.in | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/namd/tests/library/000_distance-grid_metadynamics-reflection/test.in b/namd/tests/library/000_distance-grid_metadynamics-reflection/test.in index 7b7d14392..43c2075d3 100644 --- a/namd/tests/library/000_distance-grid_metadynamics-reflection/test.in +++ b/namd/tests/library/000_distance-grid_metadynamics-reflection/test.in @@ -14,6 +14,8 @@ colvar { # lowerBoundary 0.0 upperBoundary 10.0 + # not required to define hard limits but recommended to avoid unnecessary grid expansion + # likely to be activated by default with refletion in the future hardUpperBoundary on hardLowerBoundary on @@ -36,8 +38,8 @@ metadynamics { } harmonicWalls { - name wall_dist_N_O - colvars dist_N_O - forceConstant 0.6 + name wall_one + colvars one + forceConstant 1.0 upperWalls 10.0 } From adbff1d5d5b5fd8455b0a5b4531ac6acddb34ec8 Mon Sep 17 00:00:00 2001 From: fabsugar Date: Wed, 5 Feb 2025 15:08:36 -0600 Subject: [PATCH 54/62] Simplified code by removing interval routines and changing names of variables for clarity --- src/colvarbias_meta.cpp | 289 ++++++++++++---------------------------- src/colvarbias_meta.h | 10 +- 2 files changed, 87 insertions(+), 212 deletions(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index 9e90abdf3..cfbb8bad6 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -157,7 +157,6 @@ int colvarbias_meta::init(std::string const &conf) error_code |= init_replicas_params(conf); error_code |= init_well_tempered_params(conf); error_code |= init_reflection_params(conf); - error_code |= init_interval_params(conf); error_code |= init_ebmeta_params(conf); if (cvm::debug()) @@ -319,18 +318,18 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) nrefvarsu=0; size_t nonpvars; size_t i; - size_t ii=0; + size_t icount=0; size_t j; - size_t jj; + size_t jcount; for ( i = 0; i < num_variables(); i++ ) { if (!variables(i)->is_enabled(f_cv_periodic)) { - ii++; + icount++; } } - nonpvars=ii; + nonpvars=icount; - get_keyval(conf, "useHillsReflection", use_reflection, false); + get_keyval(conf, "useHillsReflection", use_reflection, true); if (use_reflection) { get_keyval(conf, "reflectionRange", reflection_int, 6.0); @@ -343,11 +342,11 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) } else { nrefvarsl=nonpvars; reflection_llimit_cv.resize(nrefvarsl); - ii=0; + icount=0; for (i = 0; i < num_variables(); i++) { if (!variables(i)->is_enabled(f_cv_periodic)) { - reflection_llimit_cv[ii]=i; - ii++; + reflection_llimit_cv[icount]=i; + icount++; } } cvm::log("Using all non-periodic variables for lower limits of reflection \n"); @@ -364,11 +363,11 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) } else { nrefvarsu=nonpvars; reflection_ulimit_cv.resize(nrefvarsu); - ii=0; + icount=0; for (i = 0; i < num_variables(); i++) { if (!variables(i)->is_enabled(f_cv_periodic)) { - reflection_ulimit_cv[ii]=i; - ii++; + reflection_ulimit_cv[icount]=i; + icount++; } } cvm::log("Using all non-periodic variables for upper limits of reflection \n"); @@ -409,12 +408,12 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) // if grids are defined, set by default reflection boundaries as grid boundaries if (use_grids) { for (i = 0; i < nrefvarsl; i++) { - ii=reflection_llimit_cv[i]; - reflection_llimit[i]=hills_energy->lower_boundaries[ii].real_value; + icount=reflection_llimit_cv[i]; + reflection_llimit[i]=hills_energy->lower_boundaries[icount].real_value; } for (i = 0; i < nrefvarsu; i++) { - ii=reflection_ulimit_cv[i]; - reflection_ulimit[i]=hills_energy->upper_boundaries[ii].real_value; + icount=reflection_ulimit_cv[i]; + reflection_ulimit[i]=hills_energy->upper_boundaries[icount].real_value; } } @@ -422,10 +421,10 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) if (get_keyval(conf, "reflectionLowLimit", reflection_llimit, reflection_llimit)) { for (i = 0; i < nrefvarsl; i++) { if (use_grids) { - ii=reflection_llimit_cv[i]; - cvm:: real bound=hills_energy->lower_boundaries[ii].real_value; - if (reflection_llimit[i] != bound && reflection_llimit[i] < bound+variables(ii)->width) { - cvm::error("Error: please set lower reflection limit for CV "+cvm::to_str(ii)+" either at grid lower boundary ("+cvm::to_str(bound)+") or well above it (above "+cvm::to_str(bound+variables(ii)->width)+").\n", COLVARS_INPUT_ERROR); + icount=reflection_llimit_cv[i]; + cvm:: real bound=hills_energy->lower_boundaries[icount].real_value; + if (reflection_llimit[i] != bound && reflection_llimit[i] < bound+variables(icount)->width) { + cvm::error("Error: please set lower reflection limit for CV "+cvm::to_str(icount)+" either at grid lower boundary ("+cvm::to_str(bound)+") or well above it (above "+cvm::to_str(bound+variables(icount)->width)+").\n", COLVARS_INPUT_ERROR); } } } @@ -445,10 +444,10 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) if (get_keyval(conf, "reflectionUpLimit", reflection_ulimit, reflection_ulimit)) { for (i = 0; i < nrefvarsu; i++) { if (use_grids) { - ii=reflection_ulimit_cv[i]; - cvm:: real bound=hills_energy->upper_boundaries[ii].real_value; - if (reflection_ulimit[i] != bound && reflection_ulimit[i] > bound-variables(ii)->width) { - cvm::error("Error: please set upper reflection limit for CV "+cvm::to_str(ii)+" either at grid upper boundary ("+cvm::to_str(bound)+") or well below it (below "+cvm::to_str(bound-variables(ii)->width)+").\n", COLVARS_INPUT_ERROR); + icount=reflection_ulimit_cv[i]; + cvm:: real bound=hills_energy->upper_boundaries[icount].real_value; + if (reflection_ulimit[i] != bound && reflection_ulimit[i] > bound-variables(icount)->width) { + cvm::error("Error: please set upper reflection limit for CV "+cvm::to_str(icount)+" either at grid upper boundary ("+cvm::to_str(bound)+") or well below it (below "+cvm::to_str(bound-variables(icount)->width)+").\n", COLVARS_INPUT_ERROR); } } } @@ -525,111 +524,21 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) for (j = 1; j < num_variables(); j++) { sum*=10; nstates=0; - for (jj = 0; jj < j; jj++) { - nstates+=ref_state[jj].size(); + for (jcount = 0; jcount < j; jcount++) { + nstates+=ref_state[jcount].size(); } nstates++; ref_state[j].resize(nstates); ref_state[j][0]=sum; count=0; - for (jj = 0; jj < j; jj++) { - for ( ii = 0; ii < ref_state[jj].size(); ii++) { + for (jcount = 0; jcount < j; jcount++) { + for ( icount = 0; icount < ref_state[jcount].size(); icount++) { count++; - ref_state[j][count]=ref_state[j][0]+ref_state[jj][ii]; + ref_state[j][count]=ref_state[j][0]+ref_state[jcount][icount]; } } } } - return COLVARS_OK; -} - -int colvarbias_meta::init_interval_params(std::string const &conf) -{ - use_interval=false; - nintvarsl=0; - nintvarsu=0; - std::vector interval_llimit_cv; - std::vector interval_ulimit_cv; - size_t i; - size_t j; - // allocate accessory variable of colvar values to be used in energy and forces calculation - curr_values.resize(num_variables()); - for (i = 0; i < num_variables(); i++) { - curr_values[i].type(variables(i)->value()); - } - - if (get_keyval(conf, "useHillsInterval", use_interval, use_interval)) { - if (use_interval) { - if (get_keyval(conf, "intervalLowLimitUseCVs", interval_llimit_cv, interval_llimit_cv)) { - nintvarsl=interval_llimit_cv.size(); - cvm::log("Using lower limits interval on "+cvm::to_str(nintvarsl)+" variables.\n"); - for (i = 0; i < nintvarsl; i++) { - j=interval_llimit_cv[i]; - if (variables(j)->is_enabled(f_cv_periodic)) { - cvm::log("Warning: you are using interval with a periodic variable, make sure you are using it far from periodic boundaries \n"); - } - } - } else { - cvm::error("Error: Upper limit variables for interval not provided.\n", COLVARS_INPUT_ERROR); - } - if (get_keyval(conf, "intervalUpLimitUseCVs", interval_ulimit_cv, interval_ulimit_cv)) { - nintvarsu=interval_ulimit_cv.size(); - cvm::log("Using upper limits interval on "+cvm::to_str(nintvarsu)+" variables.\n"); - for (i = 0; i < nintvarsu; i++) { - j=interval_ulimit_cv[i]; - if (variables(j)->is_enabled(f_cv_periodic)) { - cvm::log("Warning: you are using interval with a periodic variable, make sure you are using it far from periodic boundaries \n"); - } - } - } else { - cvm::error("Error: Upper limits variables for interval not provided.\n", COLVARS_INPUT_ERROR); - } - if(nintvarsl>0) { - if (get_keyval(conf, "intervalLowLimit", interval_llimit, interval_llimit)) { - for ( i = 0; i < nintvarsl; i++) { - cvm::log("Hills forces will be removed beyond a lower limit for CV "+cvm::to_str(interval_llimit_cv[i])+".\n"); - cvm::log("Interval condition lower limit for this CV is "+cvm::to_str(interval_llimit[i])+".\n"); - } - } else { - cvm::error("Error: Lower limits for interval not provided.\n", COLVARS_INPUT_ERROR); - } - } - - if(nintvarsu>0) { - if (get_keyval(conf, "intervalUpLimit", interval_ulimit, interval_ulimit)) { - for ( i = 0; i < nintvarsu; i++) { - cvm::log("Hills forces will be removed beyond an upper limit for CV "+cvm::to_str(interval_ulimit_cv[i])+".\n"); - cvm::log("Interval condition upper limit for this CV is "+cvm::to_str(interval_ulimit[i])+".\n"); - } - } else { - cvm::error("Error: Upper limits for interval not provided.\n", COLVARS_INPUT_ERROR); - } - } - } - } else { - if (nrefvarsl>0 || nrefvarsu>0) { - use_interval=true; - cvm::log("Reflection active: Using by default reflection variables and limits for interval \n"); - nintvarsl=nrefvarsl; - nintvarsu=nrefvarsu; - interval_llimit_cv.resize(nintvarsl); - if (interval_llimit.size()==0) { - interval_llimit.resize(nintvarsl); - } - for (i = 0; i < nintvarsl; i++) { - interval_llimit_cv[i]=reflection_llimit_cv[i]; - interval_llimit[i]=reflection_llimit[i]; - } - interval_ulimit_cv.resize(nintvarsu); - if (interval_ulimit.size()==0) { - interval_ulimit.resize(nintvarsu); - } - for ( i = 0; i < nintvarsu; i++) { - interval_ulimit_cv[i]=reflection_ulimit_cv[i]; - interval_ulimit[i]=reflection_ulimit[i]; - } - } - } if (which_int_llimit_cv.size()==0) { which_int_llimit_cv.resize(num_variables()); @@ -637,8 +546,8 @@ int colvarbias_meta::init_interval_params(std::string const &conf) for ( i = 0; i < num_variables(); i++) { which_int_llimit_cv[i]=-1; } - for ( i = 0; i < nintvarsl; i++) { - j=interval_llimit_cv[i]; + for ( i = 0; i < nrefvarsl; i++) { + j=reflection_llimit_cv[i]; which_int_llimit_cv[j]=i; } @@ -648,40 +557,14 @@ int colvarbias_meta::init_interval_params(std::string const &conf) for ( i = 0; i < num_variables(); i++) { which_int_ulimit_cv[i]=-1; } - for ( i = 0; i < nintvarsu; i++) { - j=interval_ulimit_cv[i]; + for ( i = 0; i < nrefvarsu; i++) { + j=reflection_ulimit_cv[i]; which_int_ulimit_cv[j]=i; } - // use interval only with scalar variables - - for ( i = 0; i < nintvarsl; i++) { - if (interval_llimit_cv[i]>=static_cast(num_variables()) || interval_llimit_cv[i]<0) { - cvm::error("Error: CV number is negative or >= num_variables \n", COLVARS_INPUT_ERROR); - return COLVARS_INPUT_ERROR; - } - j=interval_llimit_cv[i]; - if (variables(j)->value().type()!=colvarvalue::type_scalar) { - cvm::error("Error: Hills interval can be used only with scalar variables.\n", COLVARS_INPUT_ERROR); - return COLVARS_INPUT_ERROR; - } - } - - for ( i = 0; i < nintvarsu; i++) { - if (interval_ulimit_cv[i]>=static_cast(num_variables()) || interval_ulimit_cv[i]<0) { - cvm::error("Error: CV number is negative or >= num_variables \n", COLVARS_INPUT_ERROR); - return COLVARS_INPUT_ERROR; - } - j=interval_ulimit_cv[i]; - if (variables(j)->value().type()!=colvarvalue::type_scalar) { - cvm::error("Error: Hills interval can be used only with scalar variables.\n", COLVARS_INPUT_ERROR); - return COLVARS_INPUT_ERROR; - } - } - + return COLVARS_OK; } - colvarbias_meta::~colvarbias_meta() { colvarbias_meta::clear_state_data(); @@ -738,16 +621,16 @@ colvarbias_meta::add_hill(colvarbias_meta::hill const &h) bool colvarbias_meta::check_reflection_limits(bool &ah) { size_t i; - size_t ii; + size_t icount; for ( i = 0; i < nrefvarsl; i++) { - ii=reflection_llimit_cv[i]; - if (colvar_values[ii]reflection_ulimit[i]) { + icount=reflection_ulimit_cv[i]; + if (colvar_values[icount]>reflection_ulimit[i]) { ah=false; } } @@ -758,7 +641,7 @@ int colvarbias_meta::reflect_hill_multid(cvm::real const &h_scale) { size_t i = 0; size_t j; - size_t jj; + size_t jcount; size_t startsum; int getsum; int check_val; @@ -768,11 +651,11 @@ int colvarbias_meta::reflect_hill_multid(cvm::real const &h_scale) size_t nkstates; size_t kstate; size_t k; - size_t kk; + size_t kcount; size_t countstate; bool hill_add; int getsumk; - int checkk; + int checkstate; size_t state; int valk; cvm:: real tmps; @@ -797,9 +680,9 @@ int colvarbias_meta::reflect_hill_multid(cvm::real const &h_scale) for (i = 0; i < j; i++) { startsum*=10; } - for (jj = 0; jj < ref_state[j].size(); jj++) { + for (jcount = 0; jcount < ref_state[j].size(); jcount++) { getsum=startsum; - check_val=ref_state[j][jj]; + check_val=ref_state[j][jcount]; numberref=0; startsumk=1; for (i = 0; i <= j; i++) { @@ -813,7 +696,7 @@ int colvarbias_meta::reflect_hill_multid(cvm::real const &h_scale) } // sum over all possible lower and upper boudary combinations - // exploiting kstate=ref_state[k][kk]: + // exploiting kstate=ref_state[k][kcount]: // for just one reflection these are 0(lower boundary) and 1(upper boundary) // for two reflections these are 0 1 10 11 (0,0 0,1 1,0 1,1) // where 0 is reflect on the two lower boudaries of the two coordinates etc. @@ -822,19 +705,19 @@ int colvarbias_meta::reflect_hill_multid(cvm::real const &h_scale) kstate=0; for ( k = 0; k 0) nkstates=ref_state[k].size(); - for ( kk = 0; kk < nkstates; kk++) { - if (k==0 && kk==1) { + for ( kcount = 0; kcount < nkstates; kcount++) { + if (k==0 && kcount==1) { kstate=1; } else if (k>0) { - kstate=ref_state[k][kk]; + kstate=ref_state[k][kcount]; } getsum=startsum; countstate=0; - check_val=ref_state[j][jj]; + check_val=ref_state[j][jcount]; hill_add=true; getsumk=startsumk; - checkk=kstate; + checkstate=kstate; for (i = 0; i <= j; i++) { upordown=std::floor(check_val/getsum); state=num_variables()-1-j+countstate; @@ -846,8 +729,8 @@ int colvarbias_meta::reflect_hill_multid(cvm::real const &h_scale) tmp=curr_cv_values[state]; // store original current cv value unitary=curr_cv_values[state]; unitary.set_ones(); - valk=std::floor(checkk/getsumk); - if(checkk-getsumk>=0) checkk=checkk-getsumk; + valk=std::floor(checkstate/getsumk); + if(checkstate-getsumk>=0) checkstate=checkstate-getsumk; getsumk=getsumk/10; reflection_limit=reflection_l[state][valk]; tmpd=reflection_limit-cvm::real(curr_cv_values[state]); @@ -1158,7 +1041,7 @@ int colvarbias_meta::update_grid_data() // map the most recent gaussians to the grids project_hills(new_hills_begin, hills.end(), hills_energy.get(), hills_energy_gradients.get(), which_int_llimit_cv, which_int_ulimit_cv, - interval_llimit, interval_ulimit); + reflection_llimit, reflection_ulimit); new_hills_begin = hills.end(); // TODO: we may want to condense all into one replicas array, @@ -1170,7 +1053,7 @@ int colvarbias_meta::update_grid_data() replicas[ir]->hills_energy.get(), replicas[ir]->hills_energy_gradients.get(), which_int_llimit_cv, which_int_ulimit_cv, - interval_llimit, interval_ulimit); + reflection_llimit, reflection_ulimit); replicas[ir]->new_hills_begin = replicas[ir]->hills.end(); } } @@ -1185,20 +1068,20 @@ int colvarbias_meta::calc_energy(std::vector const *values) size_t ir = 0; size_t i; - int ii; + int icount; std::vector curr_bin; curr_values = values ? *values : colvar_values; - if (use_interval) { + if (use_reflection) { for (i = 0; i < num_variables(); i++) { - ii=which_int_llimit_cv[i]; - if (ii>-1 && curr_values[i]-1 && curr_values[i]-1 && curr_values[i]>interval_ulimit[ii] ) { - curr_values[i]=interval_ulimit[ii]; + icount=which_int_ulimit_cv[i]; + if (icount>-1 && curr_values[i]>reflection_ulimit[icount] ) { + curr_values[i]=reflection_ulimit[icount]; } } curr_bin = hills_energy->get_colvars_index_bound(curr_values); @@ -1225,7 +1108,7 @@ int colvarbias_meta::calc_energy(std::vector const *values) } } else { // off the grid: compute analytically only the hills at the grid's edges - if (!use_interval) { + if (!use_reflection) { for (ir = 0; ir < replicas.size(); ir++) { calc_hills(replicas[ir]->hills_off_grid.begin(), replicas[ir]->hills_off_grid.end(), @@ -1255,7 +1138,7 @@ int colvarbias_meta::calc_energy(std::vector const *values) int colvarbias_meta::calc_forces(std::vector const *values) { size_t ir = 0, ic = 0; - int ii; + int icount; std::vector curr_bin; curr_values = values ? *values : colvar_values; std::vector add_force(num_variables()); @@ -1267,23 +1150,23 @@ int colvarbias_meta::calc_forces(std::vector const *values) for (ic = 0; ic < num_variables(); ic++) { add_force[ic]=true; - ii=which_int_llimit_cv[ic]; - if (ii>-1) { - if ( curr_values[ic]-1) { + if ( curr_values[ic]-1) { - if ( curr_values[ic]>interval_ulimit[ii] ) { + icount=which_int_ulimit_cv[ic]; + if (icount>-1) { + if ( curr_values[ic]>reflection_ulimit[icount] ) { add_force[ic]=false; - curr_values[ic]=interval_ulimit[ii]; + curr_values[ic]=reflection_ulimit[icount]; } } } - if (use_interval) { + if (use_reflection) { curr_bin = hills_energy->get_colvars_index_bound(curr_values); } else { curr_bin = hills_energy->get_colvars_index(curr_values); @@ -1311,7 +1194,7 @@ int colvarbias_meta::calc_forces(std::vector const *values) } } else { // off the grid: compute analytically only the hills at the grid's edges - if (!use_interval) { + if (!use_reflection) { for (ir = 0; ir < replicas.size(); ir++) { for (ic = 0; ic < num_variables(); ic++) { calc_hills_force(ic, @@ -1464,8 +1347,8 @@ void colvarbias_meta::project_hills(colvarbias_meta::hill_iter h_first, colvar_grid_gradient *hg, std::vector const &w_int_llimit_cv, std::vector const &w_int_ulimit_cv, - std::vector const &int_llimit, - std::vector const &int_ulimit, + std::vector const &ref_llimit, + std::vector const &ref_ulimit, bool print_progress) { if (cvm::debug()) @@ -1491,7 +1374,7 @@ void colvarbias_meta::project_hills(colvarbias_meta::hill_iter h_first, // loop over the points of the grid size_t i; - int ii; + int icount; std::vector add_force(num_variables()); for ( ; (he->index_ok(he_ix)) && (hg->index_ok(hg_ix)); @@ -1499,17 +1382,17 @@ void colvarbias_meta::project_hills(colvarbias_meta::hill_iter h_first, for (i = 0; i < num_variables(); i++) { add_force[i]=true; new_colvar_values[i] = he->bin_to_value_scalar(he_ix[i], i); - ii=w_int_llimit_cv[i]; - if (ii>-1 ){ - if ( new_colvar_values[i]-1 ){ + if ( new_colvar_values[i]-1){ - if( new_colvar_values[i]>int_ulimit[ii] ) { - new_colvar_values[i]=int_ulimit[ii]; + icount=w_int_ulimit_cv[i]; + if (icount>-1){ + if( new_colvar_values[i]>ref_ulimit[icount] ) { + new_colvar_values[i]=ref_ulimit[icount]; add_force[i]=false; } } @@ -2085,7 +1968,7 @@ void colvarbias_meta::rebin_grids_after_restart() project_hills(hills.begin(), hills.end(), new_hills_energy.get(), new_hills_energy_gradients.get(), which_int_llimit_cv, which_int_ulimit_cv, - interval_llimit, interval_ulimit, true); + reflection_llimit, reflection_ulimit, true); cvm::log("rebinning done.\n"); } else { @@ -2446,7 +2329,7 @@ template OST &colvarbias_meta::write_state_data_template_(OST &os project_hills(new_hills_begin, hills.end(), hills_energy.get(), hills_energy_gradients.get(), which_int_llimit_cv, which_int_ulimit_cv, - interval_llimit, interval_ulimit); + reflection_llimit, reflection_ulimit); new_hills_begin = hills.end(); // write down the grids to the restart file diff --git a/src/colvarbias_meta.h b/src/colvarbias_meta.h index 5ee53f76f..8e745c187 100644 --- a/src/colvarbias_meta.h +++ b/src/colvarbias_meta.h @@ -49,7 +49,6 @@ class colvarbias_meta virtual int init_well_tempered_params(std::string const &conf); virtual int init_ebmeta_params(std::string const &conf); virtual int init_reflection_params(std::string const &conf); - virtual int init_interval_params(std::string const &conf); virtual int clear_state_data(); @@ -244,17 +243,10 @@ class colvarbias_meta /// \brief Multidimensional reflection states std::vector > ref_state; - /// \brief whether using interval - bool use_interval; /// \brief For which variables hills forces beyond the boundaries(interval) must be removed std::vector which_int_llimit_cv; std::vector which_int_ulimit_cv; - size_t nintvarsl; - size_t nintvarsu; - /// \brief Limits for interval - std::vector interval_llimit; - std::vector interval_ulimit; /// \brief Current value of colvars to be modifed for calculation of energy and forces with interval std::vector curr_values; @@ -284,7 +276,7 @@ class colvarbias_meta void project_hills(hill_iter h_first, hill_iter h_last, colvar_grid_scalar *ge, colvar_grid_gradient *gf, std::vector const &w_int_llimit_cv, std::vector const &w_int_ulimit_cv, - std::vector const &int_llimit, std::vector const &int_ulimit, + std::vector const &ref_llimit, std::vector const &ref_ulimit, bool print_progress = false); From da81f7c81a97a677580e378c204953e61084b9c4 Mon Sep 17 00:00:00 2001 From: fabsugar Date: Sat, 8 Feb 2025 11:06:54 -0600 Subject: [PATCH 55/62] Reflection put as default when use_grid active. Introduced control for non scalar variables as reflection is focused on scalae CVs and has not been tested for a mix of scalar and vetor variables (but might work). --- src/colvarbias_meta.cpp | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index cfbb8bad6..04eb6ed6f 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -322,6 +322,10 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) size_t j; size_t jcount; + if (use_grids) { + use_reflection=true; + } + for ( i = 0; i < num_variables(); i++ ) { if (!variables(i)->is_enabled(f_cv_periodic)) { icount++; @@ -329,7 +333,15 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) } nonpvars=icount; - get_keyval(conf, "useHillsReflection", use_reflection, true); + get_keyval(conf, "useHillsReflection", use_reflection, use_reflection); + + for ( i = 0; i < num_variables(); i++ ) { + if (variables(i)->value().type()!=colvarvalue::type_scalar) { + use_reflection=false; + cvm::log("Note: CV number "+cvm::to_str(i)+" is not of scalar type. Hills reflection has been disabled as it can be used only with scalar variables.\n"); + } + } + if (use_reflection) { get_keyval(conf, "reflectionRange", reflection_int, 6.0); @@ -384,9 +396,6 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) cvm::error("Error: CV number is negative or >= num_variables \n", COLVARS_INPUT_ERROR); } j=reflection_llimit_cv[i]; - if (variables(j)->value().type()!=colvarvalue::type_scalar) { - cvm::error("Error: Hills reflection can be used only with scalar variables.\n", COLVARS_INPUT_ERROR); - } if (variables(j)->is_enabled(f_cv_periodic)) { cvm::log("Warning: you are using hills reflection with a periodic variable, make sure you are using it far from periodic boundaries \n"); } @@ -397,9 +406,6 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) cvm::error("Error: CV number is negative or >= num_variables \n", COLVARS_INPUT_ERROR); } j=reflection_ulimit_cv[i]; - if (variables(j)->value().type()!=colvarvalue::type_scalar) { - cvm::error("Error: Hills reflection can be used only with scalar variables.\n", COLVARS_INPUT_ERROR); - } if (variables(j)->is_enabled(f_cv_periodic)) { cvm::log("Warning: you are using hills reflection with a periodic variable, make sure you are using it far from periodic boundaries \n"); } From b6fbb4d0501613a95b0bc80b88260d0066d89a3e Mon Sep 17 00:00:00 2001 From: fabsugar Date: Sat, 8 Feb 2025 13:08:32 -0600 Subject: [PATCH 56/62] useHillsReflection if off by default for now, this should change and should be set on automatically when using grids --- src/colvarbias_meta.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index 04eb6ed6f..36d8e3814 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -322,9 +322,13 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) size_t j; size_t jcount; - if (use_grids) { - use_reflection=true; - } + // in future remove the line below and uncomment the three following ones as reflection should be default with grids + + use_reflection=false; + + //if (use_grids) { + // use_reflection=true; + //} for ( i = 0; i < num_variables(); i++ ) { if (!variables(i)->is_enabled(f_cv_periodic)) { From 55cfb1c6ffc51f0623c4af3905c7a0a01db327bd Mon Sep 17 00:00:00 2001 From: fabsugar Date: Sat, 8 Feb 2025 13:15:55 -0600 Subject: [PATCH 57/62] Added and run test for reflection for namd --- .../AutoDiff/test.colvars.out | 152 +++++++++++------ .../AutoDiff/test.colvars.state.stripped | 43 ++--- .../AutoDiff/test.colvars.traj | 44 ++--- .../AutoDiff/test.pmf | 36 ++-- .../AutoDiff/test.restart.colvars.out | 161 ++++++++++++------ .../test.restart.colvars.state.stripped | 43 ++--- .../AutoDiff/test.restart.colvars.traj | 44 ++--- .../AutoDiff/test.restart.pmf | 36 ++-- .../namd-version.txt | 6 +- .../test.in | 7 +- 10 files changed, 337 insertions(+), 235 deletions(-) diff --git a/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.colvars.out b/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.colvars.out index 0343b9172..3b313108e 100644 --- a/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.colvars.out +++ b/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.colvars.out @@ -1,9 +1,12 @@ colvars: ---------------------------------------------------------------------- colvars: Please cite Fiorin et al, Mol Phys 2013: -colvars: https://dx.doi.org/10.1080/00268976.2013.813594 -colvars: in any publication based on this calculation. -colvars: SMP parallelism is enabled; if needed, use "smp off" to override this. +colvars: https://doi.org/10.1080/00268976.2013.813594 +colvars: as well as all other papers listed below for individual features used. +colvars: SMP parallelism is enabled (num threads = 4). colvars: This version was built with the C++11 standard or higher. +colvars: Redefining the Tcl "cv" command to the new script interface. +colvars: The restart output state file will be "test.tmp.colvars.state". +colvars: The final output state file will be "test.colvars.state". colvars: ---------------------------------------------------------------------- colvars: Reading new configuration from file "test.in": colvars: # units = "" [default] @@ -42,54 +45,55 @@ colvars: # colvarsTrajFrequency = 1 colvars: # colvarsRestartFrequency = 10 colvars: # scriptedColvarForces = off [default] colvars: # scriptingAfterBiases = off [default] +colvars: # sourceTclFile = "" [default] colvars: ---------------------------------------------------------------------- colvars: Initializing a new collective variable. colvars: # name = "one" colvars: Initializing a new "distance" component. +colvars: # name = "" [default] +colvars: # componentCoeff = 1 [default] +colvars: # componentExp = 1 [default] +colvars: # period = 0 [default] +colvars: # wrapAround = 0 [default] +colvars: # forceNoPBC = off [default] +colvars: # scalable = on [default] +colvars: Initializing atom group "group1". colvars: # name = "" [default] -colvars: # componentCoeff = 1 [default] -colvars: # componentExp = 1 [default] -colvars: # period = 0 [default] -colvars: # wrapAround = 0 [default] -colvars: # forceNoPBC = off [default] -colvars: # scalable = on [default] -colvars: Initializing atom group "group1". -colvars: # name = "" [default] -colvars: # centerReference = off [default] -colvars: # rotateReference = off [default] -colvars: # atomsOfGroup = "" [default] -colvars: # indexGroup = "group1" -colvars: # psfSegID = [default] -colvars: # atomsFile = "" [default] -colvars: # dummyAtom = ( 0 , 0 , 0 ) [default] -colvars: # enableForces = on [default] -colvars: # enableFitGradients = on [default] -colvars: Enabling scalable calculation for group "group1". -colvars: # printAtomIDs = off [default] -colvars: Atom group "group1" defined with 4 atoms requested: total mass = 54.028, total charge = -0.72. -colvars: Initializing atom group "group2". -colvars: # name = "" [default] -colvars: # centerReference = off [default] -colvars: # rotateReference = off [default] -colvars: # atomsOfGroup = "" [default] -colvars: # indexGroup = "group2" -colvars: # psfSegID = [default] -colvars: # atomsFile = "" [default] -colvars: # dummyAtom = ( 0 , 0 , 0 ) [default] -colvars: # enableForces = on [default] -colvars: # enableFitGradients = on [default] -colvars: Enabling scalable calculation for group "group2". -colvars: # printAtomIDs = off [default] -colvars: Atom group "group2" defined with 4 atoms requested: total mass = 54.028, total charge = -0.4. -colvars: # oneSiteSystemForce = off [default] -colvars: # oneSiteTotalForce = off [default] +colvars: # centerToOrigin = off [default] +colvars: # centerToReference = off [default] +colvars: # rotateToReference = off [default] +colvars: # atomsOfGroup = "" [default] +colvars: # indexGroup = "group1" +colvars: # psfSegID = [default] +colvars: # atomsFile = "" [default] +colvars: # dummyAtom = ( 0 , 0 , 0 ) [default] +colvars: # enableFitGradients = on [default] +colvars: Enabling scalable calculation for group "group1". +colvars: # printAtomIDs = off [default] +colvars: Atom group "group1" defined with 4 atoms requested: total mass = 54.028, total charge = -0.72. +colvars: Initializing atom group "group2". +colvars: # name = "" [default] +colvars: # centerToOrigin = off [default] +colvars: # centerToReference = off [default] +colvars: # rotateToReference = off [default] +colvars: # atomsOfGroup = "" [default] +colvars: # indexGroup = "group2" +colvars: # psfSegID = [default] +colvars: # atomsFile = "" [default] +colvars: # dummyAtom = ( 0 , 0 , 0 ) [default] +colvars: # enableFitGradients = on [default] +colvars: Enabling scalable calculation for group "group2". +colvars: # printAtomIDs = off [default] +colvars: Atom group "group2" defined with 4 atoms requested: total mass = 54.028, total charge = -0.4. +colvars: # oneSiteSystemForce = off [default] +colvars: # oneSiteTotalForce = off [default] colvars: All components initialized. colvars: # timeStepFactor = 1 [default] colvars: # width = 0.5 -colvars: # lowerBoundary = 0 [default] -colvars: # upperBoundary = 10 -colvars: # hardLowerBoundary = on [default] -colvars: # hardUpperBoundary = off [default] +colvars: # lowerBoundary = 3.2 +colvars: # upperBoundary = 10.2 +colvars: # hardLowerBoundary = on +colvars: # hardUpperBoundary = on colvars: # expandBoundaries = off [default] colvars: # extendedLagrangian = off [default] colvars: # outputValue = on [default] @@ -102,6 +106,25 @@ colvars: # corrFunc = off [default] colvars: ---------------------------------------------------------------------- colvars: Collective variables initialized, 1 in total. colvars: ---------------------------------------------------------------------- +colvars: Initializing a new "harmonicwalls" instance. +colvars: # name = "wall_one" +colvars: # colvars = { one } +colvars: # stepZeroData = off [default] +colvars: # outputEnergy = off [default] +colvars: # outputFreq = 10 [default] +colvars: # timeStepFactor = 1 [default] +colvars: # writeTISamples = off [default] +colvars: # writeTIPMF = off [default] +colvars: # forceConstant = 1 +colvars: # decoupling = off [default] +colvars: # targetForceConstant = -1 [default] +colvars: # lowerWalls = { 3.2 } +colvars: # upperWalls = { 10.2 } +colvars: # lowerWallConstant = 1 [default] +colvars: # upperWallConstant = 1 [default] +colvars: The lower wall force constant for colvar "one" will be rescaled to 4 according to the specified width (0.5). +colvars: The upper wall force constant for colvar "one" will be rescaled to 4 according to the specified width (0.5). +colvars: ---------------------------------------------------------------------- colvars: Initializing a new "metadynamics" instance. colvars: # name = "metadynamics1" [default] colvars: # colvars = { one } @@ -127,28 +150,55 @@ colvars: # keepFreeEnergyFiles = off [default] colvars: # writeHillsTrajectory = off [default] colvars: # wellTempered = off [default] colvars: # biasTemperature = -1 [default] +colvars: # useHillsReflection = on +colvars: # reflectionRange = 6 [default] +colvars: Reflection range is 6. +colvars: # reflectionLowLimitUseCVs = [default] +colvars: Using all non-periodic variables for lower limits of reflection +colvars: # reflectionUpLimitUseCVs = [default] +colvars: Using all non-periodic variables for upper limits of reflection +colvars: # reflectionLowLimit = { 3.2 } [default] +colvars: Reflection condition is applied on a lower limit for CV 0. +colvars: Reflection condition lower limit for this CV is 3.2. +colvars: # reflectionUpLimit = { 10.2 } [default] +colvars: Reflection condition is applied on an upper limit for CV 0. +colvars: Reflection condition upper limit for this CV is 10.2. colvars: # ebMeta = off [default] colvars: ---------------------------------------------------------------------- -colvars: Collective variables biases initialized, 1 in total. +colvars: Collective variables biases initialized, 2 in total. colvars: ---------------------------------------------------------------------- colvars: Collective variables module (re)initialized. colvars: ---------------------------------------------------------------------- colvars: Updating NAMD interface: colvars: updating atomic data (0 atoms). colvars: updating group data (2 scalable groups, 8 atoms in total). -colvars: Re-initialized atom group for variable "one":0/0. 4 atoms: total mass = 54.028, total charge = -0.72. -colvars: Re-initialized atom group for variable "one":0/1. 4 atoms: total mass = 54.028, total charge = -0.4. -colvars: The restart output state file will be "test.tmp.colvars.state". -colvars: The final output state file will be "test.colvars.state". -colvars: Opening trajectory file "test.colvars.traj". -colvars: Redefining the Tcl "cv" command to the new script interface. +colvars: updating grid object data (0 grid objects in total). +colvars: +colvars: SUMMARY OF COLVARS FEATURES USED SO FAR AND THEIR CITATIONS: +colvars: +colvars: - Colvars module: +colvars: - Colvars-NAMD interface: +colvars: - Metadynamics colvar bias implementation: +colvars: - Optimal rotation via flexible fitting: +colvars: - distance colvar component: +colvars: - harmonicWalls colvar bias implementation: +colvars: Fiorin2013 https://doi.org/10.1080/00268976.2013.813594 +colvars: +colvars: - NAMD engine: +colvars: - Scalable center-of-mass computation (NAMD): +colvars: Phillips2020 https://doi.org/10.1063/5.0014475 +colvars: +colvars: updating target temperature (T = 0 K). colvars: Updating NAMD interface: colvars: updating atomic data (0 atoms). colvars: updating group data (2 scalable groups, 8 atoms in total). +colvars: updating grid object data (0 grid objects in total). +colvars: updating target temperature (T = 0 K). +colvars: Current simulation parameters: initial step = 0, integration timestep = 1 +colvars: Updating atomic parameters (masses, charges, etc). colvars: Re-initialized atom group for variable "one":0/0. 4 atoms: total mass = 54.028, total charge = -0.72. colvars: Re-initialized atom group for variable "one":0/1. 4 atoms: total mass = 54.028, total charge = -0.4. colvars: The restart output state file will be "test.tmp.colvars.state". -colvars: The final output state file will be "test.colvars.state". colvars: Synchronizing (emptying the buffer of) trajectory file "test.colvars.traj". colvars: Synchronizing (emptying the buffer of) trajectory file "test.colvars.traj". colvars: Saving collective variables state to "test.tmp.colvars.state". diff --git a/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.colvars.state.stripped b/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.colvars.state.stripped index 6de09bffd..ca7eeb6cc 100644 --- a/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.colvars.state.stripped +++ b/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.colvars.state.stripped @@ -5,40 +5,45 @@ configuration { colvar { name one - x 3.21688278597333e+00 + x 3.2168853380692 +} + +restraint { + configuration { +step 20 +name wall_one + } } metadynamics { configuration { - step 20 - name metadynamics1 +step 20 +name metadynamics1 } - hills_energy + +hills_energy grid_parameters { n_colvars 1 - lower_boundaries 0.00000000000000e+00 - upper_boundaries 1.00000000000000e+01 - widths 5.00000000000000e-01 - sizes 20 + lower_boundaries 3.2 + upper_boundaries 10.2 + widths 0.5 + sizes 14 } - 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 - 3.46920492770083e-08 1.70721010112539e-05 6.58298335288197e-04 - 1.98901157291202e-03 4.70902104436801e-04 8.73580076380761e-06 + 2.90793197471122e-03 2.29589040998682e-04 1.43098718458920e-06 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 - hills_energy_gradients + +hills_energy_gradients grid_parameters { n_colvars 1 - lower_boundaries 0.00000000000000e+00 - upper_boundaries 1.00000000000000e+01 - widths 5.00000000000000e-01 - sizes 20 + lower_boundaries 3.2 + upper_boundaries 10.2 + widths 0.5 + sizes 14 } - 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 - 5.18433073974142e-07 1.68175610579987e-04 3.13214890940428e-03 - -6.66334787942696e-04 -2.55603942784152e-03 -9.19086519769792e-05 + -7.38291182480299e-03 -1.74872845262777e-03 -1.81663860935017e-05 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 diff --git a/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.colvars.traj b/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.colvars.traj index 3ac32bb03..84d326415 100644 --- a/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.colvars.traj +++ b/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.colvars.traj @@ -1,22 +1,22 @@ -# step one fa_one - 0 3.20554673468334e+00 0.00000000000000e+00 - 1 3.20437148316546e+00 0.00000000000000e+00 - 2 3.20384028589204e+00 0.00000000000000e+00 - 3 3.20396721187433e+00 0.00000000000000e+00 - 4 3.20472817287036e+00 0.00000000000000e+00 - 5 3.20606308066645e+00 0.00000000000000e+00 - 6 3.20787989003051e+00 0.00000000000000e+00 - 7 3.21005997943917e+00 0.00000000000000e+00 - 8 3.21246460655188e+00 0.00000000000000e+00 - 9 3.21494247388772e+00 0.00000000000000e+00 - 10 3.21733851236362e+00 3.30884583259955e-04 - 11 3.21950367891521e+00 3.30884583259955e-04 - 12 3.22130501376020e+00 3.30884583259955e-04 - 13 3.22263482513293e+00 3.30884583259955e-04 - 14 3.22341774651982e+00 3.30884583259955e-04 - 15 3.22361481079113e+00 3.30884583259955e-04 - 16 3.22322427751010e+00 3.30884583259955e-04 - 17 3.22227956023865e+00 3.30884583259955e-04 - 18 3.22084496840419e+00 3.30884583259955e-04 - 19 3.21901000786075e+00 3.30884583259955e-04 - 20 3.21688278597333e+00 6.66334787942696e-04 +# step one fa_one + 0 3.20554673468334e+00 0.00000000000000e+00 + 1 3.20437148316484e+00 0.00000000000000e+00 + 2 3.20384028588952e+00 0.00000000000000e+00 + 3 3.20396721186862e+00 0.00000000000000e+00 + 4 3.20472817286016e+00 0.00000000000000e+00 + 5 3.20606308065050e+00 0.00000000000000e+00 + 6 3.20787989000757e+00 0.00000000000000e+00 + 7 3.21005997940810e+00 0.00000000000000e+00 + 8 3.21246460651160e+00 0.00000000000000e+00 + 9 3.21494247383722e+00 0.00000000000000e+00 + 10 3.21733851230199e+00 3.69111079117202e-03 + 11 3.21950373044117e+00 3.69111079117202e-03 + 12 3.22130516783262e+00 3.69111079117202e-03 + 13 3.22263513141286e+00 3.69111079117202e-03 + 14 3.22341825276891e+00 3.69111079117202e-03 + 15 3.22361556235479e+00 3.69111079117202e-03 + 16 3.22322531690825e+00 3.69111079117202e-03 + 17 3.22228092687886e+00 3.69111079117202e-03 + 18 3.22084669842434e+00 3.69111079117202e-03 + 19 3.21901213410055e+00 3.69111079117202e-03 + 20 3.21688533806922e+00 7.38291182480299e-03 diff --git a/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.pmf b/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.pmf index 3a05a7c71..7aa384a05 100644 --- a/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.pmf +++ b/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.pmf @@ -1,23 +1,17 @@ # 1 -# 0.00000000000000e+00 5.00000000000000e-01 20 0 +# 3.20000000000000e+00 5.00000000000000e-01 14 0 - 2.50000000000000e-01 1.98901157291202e-03 - 7.50000000000000e-01 1.98901157291202e-03 - 1.25000000000000e+00 1.98901157291202e-03 - 1.75000000000000e+00 1.98897688086274e-03 - 2.25000000000000e+00 1.97193947190077e-03 - 2.75000000000000e+00 1.33071323762382e-03 - 3.25000000000000e+00 -0.00000000000000e+00 - 3.75000000000000e+00 1.51810946847522e-03 - 4.25000000000000e+00 1.98027577214821e-03 - 4.75000000000000e+00 1.98901157291202e-03 - 5.25000000000000e+00 1.98901157291202e-03 - 5.75000000000000e+00 1.98901157291202e-03 - 6.25000000000000e+00 1.98901157291202e-03 - 6.75000000000000e+00 1.98901157291202e-03 - 7.25000000000000e+00 1.98901157291202e-03 - 7.75000000000000e+00 1.98901157291202e-03 - 8.25000000000000e+00 1.98901157291202e-03 - 8.75000000000000e+00 1.98901157291202e-03 - 9.25000000000000e+00 1.98901157291202e-03 - 9.75000000000000e+00 1.98901157291202e-03 + 3.45000000000000e+00 -0.00000000000000e+00 + 3.95000000000000e+00 2.67834293371254e-03 + 4.45000000000000e+00 2.90650098752663e-03 + 4.95000000000000e+00 2.90793197471122e-03 + 5.45000000000000e+00 2.90793197471122e-03 + 5.95000000000000e+00 2.90793197471122e-03 + 6.45000000000000e+00 2.90793197471122e-03 + 6.95000000000000e+00 2.90793197471122e-03 + 7.45000000000000e+00 2.90793197471122e-03 + 7.95000000000000e+00 2.90793197471122e-03 + 8.45000000000000e+00 2.90793197471122e-03 + 8.95000000000000e+00 2.90793197471122e-03 + 9.45000000000000e+00 2.90793197471122e-03 + 9.95000000000000e+00 2.90793197471122e-03 diff --git a/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.restart.colvars.out b/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.restart.colvars.out index 1c3db0232..056ab6f7e 100644 --- a/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.restart.colvars.out +++ b/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.restart.colvars.out @@ -1,9 +1,12 @@ colvars: ---------------------------------------------------------------------- colvars: Please cite Fiorin et al, Mol Phys 2013: -colvars: https://dx.doi.org/10.1080/00268976.2013.813594 -colvars: in any publication based on this calculation. -colvars: SMP parallelism is enabled; if needed, use "smp off" to override this. +colvars: https://doi.org/10.1080/00268976.2013.813594 +colvars: as well as all other papers listed below for individual features used. +colvars: SMP parallelism is enabled (num threads = 4). colvars: This version was built with the C++11 standard or higher. +colvars: Redefining the Tcl "cv" command to the new script interface. +colvars: The restart output state file will be "test.restart.tmp.colvars.state". +colvars: The final output state file will be "test.restart.colvars.state". colvars: ---------------------------------------------------------------------- colvars: Reading new configuration from file "test.in": colvars: # units = "" [default] @@ -42,54 +45,55 @@ colvars: # colvarsTrajFrequency = 1 colvars: # colvarsRestartFrequency = 10 colvars: # scriptedColvarForces = off [default] colvars: # scriptingAfterBiases = off [default] +colvars: # sourceTclFile = "" [default] colvars: ---------------------------------------------------------------------- colvars: Initializing a new collective variable. colvars: # name = "one" colvars: Initializing a new "distance" component. +colvars: # name = "" [default] +colvars: # componentCoeff = 1 [default] +colvars: # componentExp = 1 [default] +colvars: # period = 0 [default] +colvars: # wrapAround = 0 [default] +colvars: # forceNoPBC = off [default] +colvars: # scalable = on [default] +colvars: Initializing atom group "group1". colvars: # name = "" [default] -colvars: # componentCoeff = 1 [default] -colvars: # componentExp = 1 [default] -colvars: # period = 0 [default] -colvars: # wrapAround = 0 [default] -colvars: # forceNoPBC = off [default] -colvars: # scalable = on [default] -colvars: Initializing atom group "group1". -colvars: # name = "" [default] -colvars: # centerReference = off [default] -colvars: # rotateReference = off [default] -colvars: # atomsOfGroup = "" [default] -colvars: # indexGroup = "group1" -colvars: # psfSegID = [default] -colvars: # atomsFile = "" [default] -colvars: # dummyAtom = ( 0 , 0 , 0 ) [default] -colvars: # enableForces = on [default] -colvars: # enableFitGradients = on [default] -colvars: Enabling scalable calculation for group "group1". -colvars: # printAtomIDs = off [default] -colvars: Atom group "group1" defined with 4 atoms requested: total mass = 54.028, total charge = -0.72. -colvars: Initializing atom group "group2". -colvars: # name = "" [default] -colvars: # centerReference = off [default] -colvars: # rotateReference = off [default] -colvars: # atomsOfGroup = "" [default] -colvars: # indexGroup = "group2" -colvars: # psfSegID = [default] -colvars: # atomsFile = "" [default] -colvars: # dummyAtom = ( 0 , 0 , 0 ) [default] -colvars: # enableForces = on [default] -colvars: # enableFitGradients = on [default] -colvars: Enabling scalable calculation for group "group2". -colvars: # printAtomIDs = off [default] -colvars: Atom group "group2" defined with 4 atoms requested: total mass = 54.028, total charge = -0.4. -colvars: # oneSiteSystemForce = off [default] -colvars: # oneSiteTotalForce = off [default] +colvars: # centerToOrigin = off [default] +colvars: # centerToReference = off [default] +colvars: # rotateToReference = off [default] +colvars: # atomsOfGroup = "" [default] +colvars: # indexGroup = "group1" +colvars: # psfSegID = [default] +colvars: # atomsFile = "" [default] +colvars: # dummyAtom = ( 0 , 0 , 0 ) [default] +colvars: # enableFitGradients = on [default] +colvars: Enabling scalable calculation for group "group1". +colvars: # printAtomIDs = off [default] +colvars: Atom group "group1" defined with 4 atoms requested: total mass = 54.028, total charge = -0.72. +colvars: Initializing atom group "group2". +colvars: # name = "" [default] +colvars: # centerToOrigin = off [default] +colvars: # centerToReference = off [default] +colvars: # rotateToReference = off [default] +colvars: # atomsOfGroup = "" [default] +colvars: # indexGroup = "group2" +colvars: # psfSegID = [default] +colvars: # atomsFile = "" [default] +colvars: # dummyAtom = ( 0 , 0 , 0 ) [default] +colvars: # enableFitGradients = on [default] +colvars: Enabling scalable calculation for group "group2". +colvars: # printAtomIDs = off [default] +colvars: Atom group "group2" defined with 4 atoms requested: total mass = 54.028, total charge = -0.4. +colvars: # oneSiteSystemForce = off [default] +colvars: # oneSiteTotalForce = off [default] colvars: All components initialized. colvars: # timeStepFactor = 1 [default] colvars: # width = 0.5 -colvars: # lowerBoundary = 0 [default] -colvars: # upperBoundary = 10 -colvars: # hardLowerBoundary = on [default] -colvars: # hardUpperBoundary = off [default] +colvars: # lowerBoundary = 3.2 +colvars: # upperBoundary = 10.2 +colvars: # hardLowerBoundary = on +colvars: # hardUpperBoundary = on colvars: # expandBoundaries = off [default] colvars: # extendedLagrangian = off [default] colvars: # outputValue = on [default] @@ -102,6 +106,25 @@ colvars: # corrFunc = off [default] colvars: ---------------------------------------------------------------------- colvars: Collective variables initialized, 1 in total. colvars: ---------------------------------------------------------------------- +colvars: Initializing a new "harmonicwalls" instance. +colvars: # name = "wall_one" +colvars: # colvars = { one } +colvars: # stepZeroData = off [default] +colvars: # outputEnergy = off [default] +colvars: # outputFreq = 10 [default] +colvars: # timeStepFactor = 1 [default] +colvars: # writeTISamples = off [default] +colvars: # writeTIPMF = off [default] +colvars: # forceConstant = 1 +colvars: # decoupling = off [default] +colvars: # targetForceConstant = -1 [default] +colvars: # lowerWalls = { 3.2 } +colvars: # upperWalls = { 10.2 } +colvars: # lowerWallConstant = 1 [default] +colvars: # upperWallConstant = 1 [default] +colvars: The lower wall force constant for colvar "one" will be rescaled to 4 according to the specified width (0.5). +colvars: The upper wall force constant for colvar "one" will be rescaled to 4 according to the specified width (0.5). +colvars: ---------------------------------------------------------------------- colvars: Initializing a new "metadynamics" instance. colvars: # name = "metadynamics1" [default] colvars: # colvars = { one } @@ -127,33 +150,63 @@ colvars: # keepFreeEnergyFiles = off [default] colvars: # writeHillsTrajectory = off [default] colvars: # wellTempered = off [default] colvars: # biasTemperature = -1 [default] +colvars: # useHillsReflection = on +colvars: # reflectionRange = 6 [default] +colvars: Reflection range is 6. +colvars: # reflectionLowLimitUseCVs = [default] +colvars: Using all non-periodic variables for lower limits of reflection +colvars: # reflectionUpLimitUseCVs = [default] +colvars: Using all non-periodic variables for upper limits of reflection +colvars: # reflectionLowLimit = { 3.2 } [default] +colvars: Reflection condition is applied on a lower limit for CV 0. +colvars: Reflection condition lower limit for this CV is 3.2. +colvars: # reflectionUpLimit = { 10.2 } [default] +colvars: Reflection condition is applied on an upper limit for CV 0. +colvars: Reflection condition upper limit for this CV is 10.2. colvars: # ebMeta = off [default] colvars: ---------------------------------------------------------------------- -colvars: Collective variables biases initialized, 1 in total. +colvars: Collective variables biases initialized, 2 in total. colvars: ---------------------------------------------------------------------- colvars: Collective variables module (re)initialized. colvars: ---------------------------------------------------------------------- colvars: Updating NAMD interface: colvars: updating atomic data (0 atoms). colvars: updating group data (2 scalable groups, 8 atoms in total). -colvars: Re-initialized atom group for variable "one":0/0. 4 atoms: total mass = 54.028, total charge = -0.72. -colvars: Re-initialized atom group for variable "one":0/1. 4 atoms: total mass = 54.028, total charge = -0.4. +colvars: updating grid object data (0 grid objects in total). +colvars: +colvars: SUMMARY OF COLVARS FEATURES USED SO FAR AND THEIR CITATIONS: +colvars: +colvars: - Colvars module: +colvars: - Colvars-NAMD interface: +colvars: - Metadynamics colvar bias implementation: +colvars: - Optimal rotation via flexible fitting: +colvars: - distance colvar component: +colvars: - harmonicWalls colvar bias implementation: +colvars: Fiorin2013 https://doi.org/10.1080/00268976.2013.813594 +colvars: +colvars: - NAMD engine: +colvars: - Scalable center-of-mass computation (NAMD): +colvars: Phillips2020 https://doi.org/10.1063/5.0014475 +colvars: +colvars: updating target temperature (T = 0 K). colvars: ---------------------------------------------------------------------- -colvars: Restarting from file "test.colvars.state". -colvars: Restarting collective variable "one" from value: 3.21688 -colvars: Restarting metadynamics bias "metadynamics1" from step number 20. +colvars: Loading state from text file "test.colvars.state". +colvars: Restarting collective variable "one" from value: 3.21689 +colvars: Restarted harmonicwalls bias "wall_one" with step number 20. +colvars: successfully read the biasing potential and its gradients from grids. +colvars: successfully read 0 explicit hills from state. +colvars: Restarted metadynamics bias "metadynamics1" with step number 20. colvars: ---------------------------------------------------------------------- -colvars: The restart output state file will be "test.restart.tmp.colvars.state". -colvars: The final output state file will be "test.restart.colvars.state". -colvars: Opening trajectory file "test.restart.colvars.traj". -colvars: Redefining the Tcl "cv" command to the new script interface. colvars: Updating NAMD interface: colvars: updating atomic data (0 atoms). colvars: updating group data (2 scalable groups, 8 atoms in total). +colvars: updating grid object data (0 grid objects in total). +colvars: updating target temperature (T = 0 K). +colvars: Current simulation parameters: initial step = 20, integration timestep = 1 +colvars: Updating atomic parameters (masses, charges, etc). colvars: Re-initialized atom group for variable "one":0/0. 4 atoms: total mass = 54.028, total charge = -0.72. colvars: Re-initialized atom group for variable "one":0/1. 4 atoms: total mass = 54.028, total charge = -0.4. colvars: The restart output state file will be "test.restart.tmp.colvars.state". -colvars: The final output state file will be "test.restart.colvars.state". colvars: Synchronizing (emptying the buffer of) trajectory file "test.restart.colvars.traj". colvars: Synchronizing (emptying the buffer of) trajectory file "test.restart.colvars.traj". colvars: Saving collective variables state to "test.restart.tmp.colvars.state". diff --git a/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.restart.colvars.state.stripped b/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.restart.colvars.state.stripped index 235b1896e..54fade905 100644 --- a/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.restart.colvars.state.stripped +++ b/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.restart.colvars.state.stripped @@ -5,40 +5,45 @@ configuration { colvar { name one - x 3.21405136134992e+00 + x 3.21407617475 +} + +restraint { + configuration { +step 40 +name wall_one + } } metadynamics { configuration { - step 40 - name metadynamics1 +step 40 +name metadynamics1 } - hills_energy + +hills_energy grid_parameters { n_colvars 1 - lower_boundaries 0.00000000000000e+00 - upper_boundaries 1.00000000000000e+01 - widths 5.00000000000000e-01 - sizes 20 + lower_boundaries 3.2 + upper_boundaries 10.2 + widths 0.5 + sizes 14 } - 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 - 7.43923403227782e-08 3.57122155647627e-05 1.34466139685731e-03 - 3.97104317655277e-03 9.19770327415716e-04 1.67080044623168e-05 + 5.81689037532263e-03 4.58131531298534e-04 2.84164743658542e-06 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 - hills_energy_gradients + +hills_energy_gradients grid_parameters { n_colvars 1 - lower_boundaries 0.00000000000000e+00 - upper_boundaries 1.00000000000000e+01 - widths 5.00000000000000e-01 - sizes 20 + lower_boundaries 3.2 + upper_boundaries 10.2 + widths 0.5 + sizes 14 } - 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 - 1.10794466055357e-06 3.50062167930554e-04 6.33510417866273e-03 - -1.50805868972440e-03 -5.03195891853835e-03 -1.76471077879577e-04 + -1.47827984492445e-02 -3.49284785612392e-03 -3.61088189994010e-05 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 0.00000000000000e+00 diff --git a/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.restart.colvars.traj b/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.restart.colvars.traj index 6b959f565..c0034b7fa 100644 --- a/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.restart.colvars.traj +++ b/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.restart.colvars.traj @@ -1,22 +1,22 @@ -# step one fa_one - 20 3.21688278597333e+00 6.66334787942696e-04 - 21 3.21458283262116e+00 6.66334787942696e-04 - 22 3.21223351074552e+00 6.66334787942696e-04 - 23 3.20995434276490e+00 6.66334787942696e-04 - 24 3.20785376300757e+00 6.66334787942696e-04 - 25 3.20602301895356e+00 6.66334787942696e-04 - 26 3.20453185497061e+00 6.66334787942696e-04 - 27 3.20342630674324e+00 6.66334787942696e-04 - 28 3.20272853390700e+00 6.66334787942696e-04 - 29 3.20243824119566e+00 6.66334787942696e-04 - 30 3.20253526877602e+00 1.14429095260314e-03 - 31 3.20298298275490e+00 1.14429095260314e-03 - 32 3.20373228243844e+00 1.14429095260314e-03 - 33 3.20472609508842e+00 1.14429095260314e-03 - 34 3.20590411372385e+00 1.14429095260314e-03 - 35 3.20720736612802e+00 1.14429095260314e-03 - 36 3.20858216980690e+00 1.14429095260314e-03 - 37 3.20998315211066e+00 1.14429095260314e-03 - 38 3.21137529195283e+00 1.14429095260314e-03 - 39 3.21273513276742e+00 1.14429095260314e-03 - 40 3.21405136134992e+00 1.50805868972440e-03 +# step one fa_one + 20 3.21688533806922e+00 7.38291182480299e-03 + 21 3.21458588882441e+00 7.38291182480299e-03 + 22 3.21223714587457e+00 7.38291182480299e-03 + 23 3.20995862787481e+00 7.38291182480299e-03 + 24 3.20785876515602e+00 7.38291182480299e-03 + 25 3.20602880105322e+00 7.38291182480299e-03 + 26 3.20453847572721e+00 7.38291182480299e-03 + 27 3.20343382065677e+00 7.38291182480299e-03 + 28 3.20273699133106e+00 7.38291182480299e-03 + 29 3.20244768843368e+00 7.38291182480299e-03 + 30 3.20254574820329e+00 1.10871252733508e-02 + 31 3.20299458251580e+00 1.10871252733508e-02 + 32 3.20374508637636e+00 1.10871252733508e-02 + 33 3.20474018224177e+00 1.10871252733508e-02 + 34 3.20591955787466e+00 1.10871252733508e-02 + 35 3.20722423546519e+00 1.10871252733508e-02 + 36 3.20860052667966e+00 1.10871252733508e-02 + 37 3.21000305295022e+00 1.10871252733508e-02 + 38 3.21139678731726e+00 1.10871252733508e-02 + 39 3.21275826748767e+00 1.10871252733508e-02 + 40 3.21407617475000e+00 1.47827984492445e-02 diff --git a/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.restart.pmf b/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.restart.pmf index 051812fec..a360859b5 100644 --- a/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.restart.pmf +++ b/namd/tests/library/000_distance-grid_metadynamics-reflection/AutoDiff/test.restart.pmf @@ -1,23 +1,17 @@ # 1 -# 0.00000000000000e+00 5.00000000000000e-01 20 0 +# 3.20000000000000e+00 5.00000000000000e-01 14 0 - 2.50000000000000e-01 3.97104317655277e-03 - 7.50000000000000e-01 3.97104317655277e-03 - 1.25000000000000e+00 3.97104317655277e-03 - 1.75000000000000e+00 3.97096878421245e-03 - 2.25000000000000e+00 3.93533096098801e-03 - 2.75000000000000e+00 2.62638177969546e-03 - 3.25000000000000e+00 -0.00000000000000e+00 - 3.75000000000000e+00 3.05127284913705e-03 - 4.25000000000000e+00 3.95433517209045e-03 - 4.75000000000000e+00 3.97104317655277e-03 - 5.25000000000000e+00 3.97104317655277e-03 - 5.75000000000000e+00 3.97104317655277e-03 - 6.25000000000000e+00 3.97104317655277e-03 - 6.75000000000000e+00 3.97104317655277e-03 - 7.25000000000000e+00 3.97104317655277e-03 - 7.75000000000000e+00 3.97104317655277e-03 - 8.25000000000000e+00 3.97104317655277e-03 - 8.75000000000000e+00 3.97104317655277e-03 - 9.25000000000000e+00 3.97104317655277e-03 - 9.75000000000000e+00 3.97104317655277e-03 + 3.45000000000000e+00 -0.00000000000000e+00 + 3.95000000000000e+00 5.35875884402410e-03 + 4.45000000000000e+00 5.81404872788604e-03 + 4.95000000000000e+00 5.81689037532263e-03 + 5.45000000000000e+00 5.81689037532263e-03 + 5.95000000000000e+00 5.81689037532263e-03 + 6.45000000000000e+00 5.81689037532263e-03 + 6.95000000000000e+00 5.81689037532263e-03 + 7.45000000000000e+00 5.81689037532263e-03 + 7.95000000000000e+00 5.81689037532263e-03 + 8.45000000000000e+00 5.81689037532263e-03 + 8.95000000000000e+00 5.81689037532263e-03 + 9.45000000000000e+00 5.81689037532263e-03 + 9.95000000000000e+00 5.81689037532263e-03 diff --git a/namd/tests/library/000_distance-grid_metadynamics-reflection/namd-version.txt b/namd/tests/library/000_distance-grid_metadynamics-reflection/namd-version.txt index e2b19c981..fd296a0f7 100644 --- a/namd/tests/library/000_distance-grid_metadynamics-reflection/namd-version.txt +++ b/namd/tests/library/000_distance-grid_metadynamics-reflection/namd-version.txt @@ -1,3 +1,3 @@ -Info: NAMD 2.14b1 for Linux-x86_64-multicore -colvars: Initializing the collective variables module, version "2020-04-09". -colvars: Using NAMD interface, version "2020-04-07". +Info: NAMD 3.0.1 for Linux-x86_64-multicore +colvars: Initializing the collective variables module, version 2023-12-05. +colvars: Using NAMD interface, version "2023-12-05". diff --git a/namd/tests/library/000_distance-grid_metadynamics-reflection/test.in b/namd/tests/library/000_distance-grid_metadynamics-reflection/test.in index 43c2075d3..97b3e5b99 100644 --- a/namd/tests/library/000_distance-grid_metadynamics-reflection/test.in +++ b/namd/tests/library/000_distance-grid_metadynamics-reflection/test.in @@ -11,8 +11,8 @@ colvar { # use a non-trivial width to test bias behavior width 0.5 # The lower boundary is already defined at 0 for a distance function - # lowerBoundary 0.0 - upperBoundary 10.0 + lowerBoundary 3.2 + upperBoundary 10.2 # not required to define hard limits but recommended to avoid unnecessary grid expansion # likely to be activated by default with refletion in the future @@ -41,5 +41,6 @@ harmonicWalls { name wall_one colvars one forceConstant 1.0 - upperWalls 10.0 + lowerWalls 3.2 + upperWalls 10.2 } From d0bb57a2aaed437839d3298ca56fcc86ed527046 Mon Sep 17 00:00:00 2001 From: Giacomo Fiorin Date: Mon, 5 May 2025 14:54:54 -0400 Subject: [PATCH 58/62] Fix merge conflict --- src/colvarbias_meta.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index 36d8e3814..0e1f28774 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -322,13 +322,13 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) size_t j; size_t jcount; - // in future remove the line below and uncomment the three following ones as reflection should be default with grids - + // in future remove the line below and uncomment the three following ones as reflection should be default with grids + use_reflection=false; //if (use_grids) { - // use_reflection=true; - //} + // use_reflection=true; + //} for ( i = 0; i < num_variables(); i++ ) { if (!variables(i)->is_enabled(f_cv_periodic)) { @@ -341,7 +341,7 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) for ( i = 0; i < num_variables(); i++ ) { if (variables(i)->value().type()!=colvarvalue::type_scalar) { - use_reflection=false; + use_reflection=false; cvm::log("Note: CV number "+cvm::to_str(i)+" is not of scalar type. Hills reflection has been disabled as it can be used only with scalar variables.\n"); } } @@ -571,7 +571,7 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) j=reflection_ulimit_cv[i]; which_int_ulimit_cv[j]=i; } - + return COLVARS_OK; } @@ -1182,6 +1182,8 @@ int colvarbias_meta::calc_forces(std::vector const *values) curr_bin = hills_energy->get_colvars_index(curr_values); } + bool index_ok = false; + if (use_grids) { curr_bin = values ? @@ -1975,7 +1977,7 @@ void colvarbias_meta::rebin_grids_after_restart() // if there are hills, recompute the new grids from them cvm::log("Rebinning the energy and forces grids from "+ cvm::to_str(hills.size())+" hills (this may take a bit)...\n"); - project_hills(hills.begin(), hills.end(), + project_hills(hills.begin(), hills.end(), new_hills_energy.get(), new_hills_energy_gradients.get(), which_int_llimit_cv, which_int_ulimit_cv, reflection_llimit, reflection_ulimit, true); From c217f462bbfe1cebf43ee16579a2e77c11183b8f Mon Sep 17 00:00:00 2001 From: fabsugar Date: Wed, 28 May 2025 10:36:00 -0500 Subject: [PATCH 59/62] Removed use_grid condition in calc_force routine as curr_bin is already defined and w3ill be overwritten --- src/colvarbias_meta.cpp | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index 0e1f28774..192ba240d 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -1182,19 +1182,7 @@ int colvarbias_meta::calc_forces(std::vector const *values) curr_bin = hills_energy->get_colvars_index(curr_values); } - bool index_ok = false; - - if (use_grids) { - - curr_bin = values ? - hills_energy->get_colvars_index(*values) : - hills_energy->get_colvars_index(); - - index_ok = hills_energy->index_ok(curr_bin); - - } - - if ( index_ok ) { + if (hills_energy->index_ok(curr_bin)) { for (ir = 0; ir < replicas.size(); ir++) { cvm::real const *f = &(replicas[ir]->hills_energy_gradients->value(curr_bin)); for (ic = 0; ic < num_variables(); ic++) { From 47116bd30ac25403de30d403df862ef4d70d7a3b Mon Sep 17 00:00:00 2001 From: fabsugar Date: Wed, 28 May 2025 15:26:07 -0500 Subject: [PATCH 60/62] Integrated merge_meta_reflaction changes to colvarbias_meta --- src/colvarbias_meta.cpp | 54 ++++++++++++++++++++++++++++++++++------- 1 file changed, 45 insertions(+), 9 deletions(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index 192ba240d..20a1a0afe 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -342,7 +342,7 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) for ( i = 0; i < num_variables(); i++ ) { if (variables(i)->value().type()!=colvarvalue::type_scalar) { use_reflection=false; - cvm::log("Note: CV number "+cvm::to_str(i)+" is not of scalar type. Hills reflection has been disabled as it can be used only with scalar variables.\n"); + cvm::log("Note: CV "+cvm::to_str(variables(i)->name)+" is not of scalar type. Hills reflection has been disabled as it can be used only with scalar variables.\n"); } } @@ -351,9 +351,28 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) get_keyval(conf, "reflectionRange", reflection_int, 6.0); cvm::log("Reflection range is "+cvm::to_str(reflection_int)+".\n"); - if (get_keyval(conf, "reflectionLowLimitUseCVs", reflection_llimit_cv, reflection_llimit_cv)) { - nrefvarsl=reflection_llimit_cv.size(); - if(nrefvarsl>num_variables()) cvm::error("Error: number CVs with active lower reflection limit is > num_variables \n", COLVARS_INPUT_ERROR); + std::vector colvar_names_l; + std::vector check_dup(num_variables()); + if (get_keyval(conf, "reflectionLowLimitUseCVs", colvar_names_l)) { + nrefvarsl=colvar_names_l.size(); + reflection_llimit_cv.resize(nrefvarsl); + + for (i = 0; i < num_variables(); i++) check_dup[i]=0; + for (j = 0; j < nrefvarsl; j++) { + icount=0; + for (i = 0; i < num_variables(); i++) { + if (colvar_names_l[j].compare(variables(i)->name)==0) { + reflection_llimit_cv[j]=i; + icount++; + check_dup[i]++; + } + } + if (icount!=1) cvm::error("Error: CV name "+colvar_names_l[j]+" mismatch or duplication for lower reflection limit \n", COLVARS_INPUT_ERROR); + } + for (i = 0; i < num_variables(); i++) { + if (check_dup[i]>1) cvm::error("Error: CV name duplication for lower reflection limit \n", COLVARS_INPUT_ERROR); + } + if(nrefvarsl>num_variables()) cvm::error("Error: number of CVs with active lower reflection limit is > num_variables \n", COLVARS_INPUT_ERROR); cvm::log("Using lower limits reflection on "+cvm::to_str(nrefvarsl)+" variables.\n"); } else { nrefvarsl=nonpvars; @@ -372,9 +391,26 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) reflection_llimit.resize(nrefvarsl); } - if (get_keyval(conf, "reflectionUpLimitUseCVs", reflection_ulimit_cv, reflection_ulimit_cv)) { - nrefvarsu=reflection_ulimit_cv.size(); - if(nrefvarsu>num_variables()) cvm::error("Error: number CVs with active upper reflection limit is > num_variables \n", COLVARS_INPUT_ERROR); + std::vector colvar_names_u; + if (get_keyval(conf, "reflectionUpLimitUseCVs", colvar_names_u)) { + nrefvarsu=colvar_names_u.size(); + reflection_ulimit_cv.resize(nrefvarsu); + for (i = 0; i < num_variables(); i++) check_dup[i]=0; + for (j = 0; j < nrefvarsu; j++) { + icount=0; + for (i = 0; i < num_variables(); i++) { + if (colvar_names_u[j].compare(variables(i)->name)==0) { + reflection_ulimit_cv[j]=i; + icount++; + check_dup[i]++; + } + } + if (icount!=1) cvm::error("Error: CV name "+cvm::to_str(colvar_names_u[j])+" mismatch or duplication for upper reflection limit \n", COLVARS_INPUT_ERROR); + } + for (i = 0; i < num_variables(); i++) { + if (check_dup[i]>1) cvm::error("Error: CV name duplication for upper reflection limit \n", COLVARS_INPUT_ERROR); + } + if(nrefvarsu>num_variables()) cvm::error("Error: number of CVs with active upper reflection limit is > num_variables \n", COLVARS_INPUT_ERROR); cvm::log("Using upper limits reflection on "+cvm::to_str(nrefvarsu)+" variables.\n"); } else { nrefvarsu=nonpvars; @@ -446,7 +482,7 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) } for (i = 0; i < nrefvarsl; i++) { - cvm::log("Reflection condition is applied on a lower limit for CV "+cvm::to_str(reflection_llimit_cv[i])+".\n"); + cvm::log("Reflection condition is applied on a lower limit for CV "+cvm::to_str(variables(reflection_llimit_cv[i])->name)+".\n"); cvm::log("Reflection condition lower limit for this CV is "+cvm::to_str(reflection_llimit[i])+".\n"); } @@ -469,7 +505,7 @@ int colvarbias_meta::init_reflection_params(std::string const &conf) } for (i = 0; i < nrefvarsu; i++) { - cvm::log("Reflection condition is applied on an upper limit for CV "+cvm::to_str(reflection_ulimit_cv[i])+".\n"); + cvm::log("Reflection condition is applied on an upper limit for CV "+cvm::to_str(variables(reflection_ulimit_cv[i])->name)+".\n"); cvm::log("Reflection condition upper limit for this CV is "+cvm::to_str(reflection_ulimit[i])+".\n"); } From 734e292288a135ea4c6fea939b559ae46f8d2c42 Mon Sep 17 00:00:00 2001 From: fabsugar Date: Wed, 28 May 2025 16:51:53 -0500 Subject: [PATCH 61/62] merged documentation of hills reflection from merge_meta_reflection --- doc/colvars-code-refs.bib | 1 + doc/colvars-refman-main.tex | 177 ++++++++++++++++++++++++------------ doc/colvars-refman.bib | 10 ++ 3 files changed, 128 insertions(+), 60 deletions(-) diff --git a/doc/colvars-code-refs.bib b/doc/colvars-code-refs.bib index 8e2570f0e..6b96b1fc2 100644 --- a/doc/colvars-code-refs.bib +++ b/doc/colvars-code-refs.bib @@ -156,6 +156,7 @@ @article{Fiorin2020 % Scripted functions (Tcl) % ABMD bias % Updated multiple-walker ABF implementation +% Metadynamics Hills reflection at the boundaries @article{Fiorin2024, author = {Fiorin, Giacomo and Marinelli, Fabrizio and Forrest, Lucy R. and Chen, Haochuan and Chipot, Christophe and Kohlmeyer, Axel and Santuz, Hubert and H{\'e}nin, J{\'e}rôme}, title = {Expanded Functionality and Portability for the Colvars Library}, diff --git a/doc/colvars-refman-main.tex b/doc/colvars-refman-main.tex index 256da757a..1e200a9fe 100644 --- a/doc/colvars-refman-main.tex +++ b/doc/colvars-refman-main.tex @@ -6249,66 +6249,6 @@ where $t_{e}$ is the time after which the bias potential grows (approximately) evenly during the simulation and $t_{tot}$ is the total simulation time. The free energy calculated according to eq.~\ref{eq:colvars_meta_fes_av} can thus be obtained averaging on time multiple time-dependent free energy estimates, that can be printed out through the keyword \texttt{keepFreeEnergyFiles}. An alternative is to obtain the free energy profiles by summing the hills added during the simulation; the hills trajectory can be printed out by enabling the option \texttt{writeHillsTrajectory}. -\cvsubsubsec{Treatment of the PMF boundaries}{sec:colvarbias_meta_boundaries} - -In typical scenarios the Gaussian hills of a metadynamics potential are interpolated and summed together onto a grid, which is much more efficient than computing each hill independently at every step (the keyword \refkey{useGrids}{metadynamics|useGrids} is \texttt{on} by default). -This numerical approximation typically yields negligible errors in the resulting PMF \cite{Fiorin2013}. -However, due to the finite thickness of the Gaussian function, the metadynamics potential would suddenly vanish each time a variable exceeds its grid boundaries. - -To avoid such discontinuity the Colvars metadynamics code will keep an explicit copy of each hill that straddles a grid's boundary, and will use it to compute metadynamics forces outside the grid. -This measure is taken to protect the accuracy and stability of a metadynamics simulation, except in cases of ``natural'' boundaries (for example, the $[0:180]$ interval of an \texttt{angle} colvar) or when the flags \refkey{hardLowerBoundary}{colvar|hardLowerBoundary} and \refkey{hardUpperBoundary}{colvar|hardUpperBoundary} are explicitly set by the user. -Unfortunately, processing explicit hills alongside the potential and force grids could easily become inefficient, slowing down the simulation and increasing the state file's size. - -In general, it is a good idea to \emph{define a repulsive potential to avoid hills from coming too close to the grid's boundaries}, for example as a \texttt{harmonicWalls} restraint (see \ref{sec:colvarbias_harmonic_walls}).\\ - -\noindent\textbf{Example:} Using harmonic walls to protect the grid's boundaries. -\begin{cvexampleinput} -\-colvar~\{\\ -\-\-~~name~r\\ -\-\-~~distance~\{~...~\}\\ -\-\-~~upperBoundary~15.0\\ -\-\-~~width~0.2\\ -\-\}\\ -\\ -\-metadynamics~\{\\ -\-\-~~name~meta\_r\\ -\-\-~~colvars~r\\ -\-\-~~hillWeight~0.001\\ -\-\-~~hillWidth~2.0\\ -\-\}\\ -\\ -\-harmonicWalls~\{\\ -\-\-~~name~wall\_r\\ -\-\-~~colvars~r\\ -\-\-~~upperWalls~13.0\\ -\-\-~~upperWallConstant~2.0\\ -\-\} -\end{cvexampleinput} - -In the colvar \texttt{r}, the \texttt{distance} function used has a \texttt{lowerBoundary} automatically set to 0 by default, thus the keyword \texttt{lowerBoundary} itself is not mandatory and \texttt{hardLowerBoundary} is set to \texttt{yes} internally. -However, \texttt{upperBoundary} does not have such a ``natural'' choice of value. -The metadynamics potential \texttt{meta\_r} will individually process any hill whose center is too close to the \texttt{upperBoundary}, more precisely within fewer grid points than 6 times the Gaussian $\sigma$ parameter plus one. -It goes without saying that if the colvar \texttt{r} represents a distance between two freely-moving molecules, it will cross this ``threshold'' rather frequently. - -In this example, where the value of \texttt{hillWidth} ($2\sigma$) amounts to 2 grid points, the threshold is 6+1 = 7 grid points away from \texttt{upperBoundary}. -In explicit units, the \texttt{width} of $r$ is $w_r =$ 0.2~\AA, and the threshold is 15.0 - 7$\times$0.2 = 13.6~\AA. - -The \texttt{wall\_r} restraint included in the example prevents this: the position of its \texttt{upperWall} is 13~\AA{}, i.e.{} 3 grid points below the buffer's threshold (13.6~\AA). -For the chosen value of \texttt{upperWallConstant}, the energy of the \texttt{wall\_r} bias at \texttt{r} = $r_{\mathrm{upper}}$ = 13.6~\AA{} is: -\begin{equation*} - E^* = \frac{1}{2} \- k \left(\frac{r - r_{\mathrm{upper}}}{w_r}\right)^2 = \frac{1}{2} \- 2.0 \left(-3\right)^2 = 9~\mathrm{kcal/mol} -\end{equation*} -which results in a relative probability $\exp(-E^*/\kappa_{\mathrm{B}}T) \simeq$ $3\times{}10^{-7}$ that \texttt{r} crosses the threshold. -The probability that \texttt{r} exceeds \texttt{upperBoundary}, which is further away, has also become vanishingly small. -At that point, you may want to set \texttt{hardUpperBoundary} to \texttt{yes} for \texttt{r}, and let \texttt{meta\_r} know that no special treatment near the grid's boundaries will be needed. - -\emph{What is the impact of the wall restraint onto the PMF?} Not a very complicated one: the PMF reconstructed by metadynamics will simply show a sharp increase in free-energy where the wall potential kicks in (\texttt{r}~$>$ 13~\AA{}). -You may then choose between using the PMF only up until that point and discard the rest, or subtracting the energy of the \texttt{harmonicWalls} restraint from the PMF itself. -Keep in mind, however, that the statistical convergence of metadynamics may be less accurate where the wall potential is strong. - -In summary, although it would be simpler to set the wall's position \texttt{upperWall} and the grid's boundary \texttt{upperBoundary} to the same number, the finite width of the Gaussian hills calls for setting the former strictly within the latter. - - \cvsubsubsec{Required metadynamics keywords}{sec:colvarbias_meta_basics} To enable a metadynamics-based calculation, a \texttt{metadynamics \{...\}} block must be included in the Colvars configuration file. @@ -6379,6 +6319,123 @@ \end{itemize} +\cvsubsubsec{Treatment of the PMF boundaries}{sec:colvarbias_meta_boundaries} + +Similar to other PMF calculation methods, it is common for sampling to be restricted to a predefined region of the CV space. This restriction can arise either from the ``natural'' boundaries of the CVs (e.g., the $[0:180]$ interval of an \texttt{angle} collective variable) or from user-imposed limits to focus on a specific region of interest, such as defining a repulsive potential between boundaries using \texttt{harmonicWalls}. In both cases, the finite size of the Gaussian hills causes significant systematic errors near the boundaries \cite{Crespo2010,Fiorin2024}, resulting in artificial spikes and oscillations in the bias potential. Over time, this leads to large forces (also by driving the system towards high-energy regions of \texttt{harmonicWalls} restraints), ultimately generating simulation instabilities. +To prevent such errors, colvars implements a specific methodology\cite{Fiorin2024} whereby the hills are reflected beyond the boundaries and the biasing forces are set to zero in the direction orthogonal to the boundaries once crossed. This results in a continuous biasing potential that remains constant in the direction orthogonal to the boundaries once crossed \cite{Fiorin2024}. This feature can be enabled by setting the keyword \refkey{useHillsReflection}{metadynamics|useHillsReflection} to \texttt{on} and is applied by default on all non-periodic active CVs, except for non-scalar variables, which, if present, will lead to deactivation of the boundary correction. +Normally, the Gaussian hills in a metadynamics potential are interpolated and summed on a grid, which yields negligible errors in the PMF \cite{Fiorin2013} and is more efficient than computing each hill independently at every step (the \texttt{useGrids} keyword is \texttt{on} by default). When both \texttt{useGrids} and \refkey{useHillsReflection}{metadynamics|useHillsReflection} are active, the reflective boudary correction is automatically applied at the grid edge`s, preventing discontinuities outside the boundaries. +It is recommended to activate \refkey{useHillsReflection}{metadynamics|useHillsReflection} both in presence of ``natural'' boundaries or user-defined \texttt{harmonicWalls}. The latter walls should be placed at the same boundaries where the reflective boudary correction is applied (e.g. at the CVs or grid boundaries). +When \refkey{useHillsReflection}{metadynamics|useHillsReflection} is inactive, Colvars keeps an explicit copy of each hill crossing a grid boundary to compute metadynamics forces outside the grid. This approach slows the simulation and increases the state file size over time, but is necessary to avoid critical issues, like boundary trapping. This feature is disabled when 'natural' boundaries or explicit \texttt{hardLowerBoundary} and \texttt{hardUpperBoundary} flags are set. If \refkey{useHillsReflection}{metadynamics|useHillsReflection} is off, it’s recommended to use \texttt{harmonicWalls} restraints (see \ref{sec:colvarbias_harmonic_walls}) placed at least 8 Gaussian sigmas within the boundaries to minimize inefficiencies. While these measures prevent boundary trapping, they do not address systematic errors, which are fully resolved only by enabling \refkey{useHillsReflection}{metadynamics|useHillsReflection}. + +\noindent\textbf{Example:} Using hills reflection to avoid systematic erros at the grid's boundaries and harmonic walls to limit the sampling within those. +\begin{cvexampleinput} +\-colvar~\{\\ +\-\-~~name~r\\ +\-\-~~distance~\{~...~\}\\ +\-\-~~upperBoundary~13.0\\ +\-\-~~width~0.2\\ +\-\}\\ +\\ +\-metadynamics~\{\\ +\-\-~~name~meta\_r\\ +\-\-~~colvars~r\\ +\-\-~~hillWeight~0.001\\ +\-\-~~hillWidth~2.0\\ +\-\-~~useHillsReflection~on\\ +\-\}\\ +\\ +\-harmonicWalls~\{\\ +\-\-~~name~wall\_r\\ +\-\-~~colvars~r\\ +\-\-~~upperWalls~13.0\\ +\-\-~~upperWallConstant~2.0\\ +\-\} +\end{cvexampleinput} + +In the colvar \texttt{r}, the \texttt{distance} function used has a \texttt{lowerBoundary} automatically set to 0 by default, thus the keyword \texttt{lowerBoundary} itself is not mandatory and \refkey{hardLowerBoundary}{colvar|hardLowerBoundary} is set to \texttt{yes} internally. +However, \texttt{upperBoundary} does not have such a ``natural'' choice of value. +The activation of the reflective boudary correction via \refkey{useHillsReflection}{metadynamics|useHillsReflection} set to \texttt{on}, will lead to hills that are reflected at distances of 0 and 13. + +\emph{What is the impact of the reflective boudary correction onto the PMF?} Not a very complicated one: the PMF reconstructed by metadynamics will simply show a slight flattening very close to the boundaries (\texttt{r}~$=$ 0~\AA{} and \texttt{r}~$=$ 13~\AA{}), with the biasing forces becoming negligible. Those forces are completely removed after crossing the boundaries (\texttt{r}~$>$ 13~\AA{}) and the metadynamics bias potential remains constant. Thus, the only biasing forces applied beyond the upper boundary are those from the \texttt{harmonicWalls} restraints. + +Although the reflective boudary correction typically leads to a reasonable estimate of the PMF, a more rigorous evaluation can be obtained by rewighting or mean force estimates, such as the Force Correction Analisys Method\cite{Marinelli2021}. + +In summary, enabling the \refkey{useHillsReflection}{metadynamics|useHillsReflection} keyword corrects boundary artifacts, ensuring a more stable metadynamics simulation and improved PMF accuracy. + +While \refkey{useHillsReflection}{metadynamics|useHillsReflection} is in most cases the only required keyword to activate the reflective boundary correction, a complete list of associated keywords is provided below. + +\begin{itemize} + +\item % + \labelkey{metadynamics|useHillsReflection} + \keydef + {useHillsReflection}{% + \texttt{metadynamics}}{% + use reflective boundary correction}{% + boolean}{% + \texttt{off}}{% + This keyword instructs Colvars to use reflective boundary correction. + When active, this is applied by default on all non-periodic variables. + When \texttt{useGrids} is \texttt{on}, the boundary correction is applied + by default at the grid boundaries. Optionally, the CVs and boundaries on + which this correction is applied can be specified via the keywords + \texttt{reflectionLowLimitUseCVs}, \texttt{reflectionUpLimitUseCVs}, + \texttt{reflectionLowLimit} and \texttt{reflectionUpLimit}. Currently, + this option is implemented for all types of variables except the non-scalar + types (\texttt{distanceDir} or \texttt{orientation}), and it becomes inactive + if those are active. To enhance efficiency, the boundary correction is applied + only to Gaussians that lie within a specified cutoff distance from the boundaries + (defaulting to 6 times the Gaussian's sigma, though this can be adjusted using + the keyword \texttt{reflectionRange})} + +\item % + \labelkey{metadynamics|reflectionLowLimitUseCVs} + \keydef + {reflectionLowLimitUseCVs}{% + \texttt{metadynamics}}{% + Collective variables involved}{% + space-separated list of colvar names}{% + All non-periodic variables}{% + This option selects by name all the variables to which a reflective boundary + correction is applied at their lower boundaries.} + + +\item % + \labelkey{metadynamics|reflectionUpLimitUseCVs} + \keydef + {reflectionUpLimitUseCVs}{% + \texttt{metadynamics}}{% + Collective variables involved}{% + space-separated list of colvar names}{% + All non-periodic variables}{% + This option selects by name all the variables to which a reflective boundary + correction is applied at their upper boundaries.} + +\item % + \labelkey{metadynamics|reflectionLowLimit} + \keydef + {reflectionLowLimit}{% + \texttt{metadynamics}}{% + Lower boundaries for the reflective boundary correction (one for each colvar)}{% + space-separated list of decimals}{% + Grid lower boundaries if \refkey{useGrids}{metadynamics|useGrids} is \texttt{on}}{% + This option sets the values of the lower boundaries for the CVs specified in + \refkey{reflectionLowLimitUseCVs}{metadynamics|reflectionLowLimitUseCVs}.} + +\item % + \labelkey{metadynamics|reflectionUpLimit} + \keydef + {reflectionUpLimit}{% + \texttt{metadynamics}}{% + Upper boundaries for the reflective boundary correction (one for each colvar)}{% + space-separated list of decimals}{% + Grid upper boundaries if \refkey{useGrids}{metadynamics|useGrids} is \texttt{on}}{% + This option sets the values of the upper boundaries for the CVs specified in + \refkey{reflectionUpLimitUseCVs}{metadynamics|reflectionUpLimitUseCVs}.} + +\end{itemize} + + \cvsubsubsec{Output files}{sec:colvarbias_meta_output} When interpolating grids are enabled (default behavior), the PMF is written by default every \texttt{colvarsRestartFrequency} steps to the file \outputName\texttt{.pmf} in multicolumn text format (\ref{sec:colvar_multicolumn_grid}). diff --git a/doc/colvars-refman.bib b/doc/colvars-refman.bib index 8ae6dbc64..2bbb3532d 100644 --- a/doc/colvars-refman.bib +++ b/doc/colvars-refman.bib @@ -84,6 +84,16 @@ @ARTICLE{Crespo2010 url = {https://link.aps.org/doi/10.1103/PhysRevE.81.055701}, } +@article{Marinelli2021, + author = {Marinelli, Fabrizio and Faraldo-Gómez, José D.}, + title = {Force-Correction Analysis Method for Derivation of Multidimensional Free-Energy Landscapes from Adaptively Biased Replica Simulations}, + journal = {J. Chem. Theory Comput.}, + volume = {17}, + pages = {6775-6788}, + year = {2021}, + url = {https://doi.org/10.1021/acs.jctc.1c00586}, +} + @ARTICLE{Darve2008, author = {Eric Darve and David Rodr{\'i}guez-G{\'o}mez and Andrew Pohorille}, title = {Adaptive biasing force method for scalar and vector free energy calculations}, From 08cd75c7899ed5cd002c2c4d34b9aeceef467066 Mon Sep 17 00:00:00 2001 From: fabsugar Date: Mon, 16 Jun 2025 23:55:39 -0500 Subject: [PATCH 62/62] Used get_colvar_index_bound in ebmeta when calculating the value of the target function to avoid bins off the grid --- src/colvarbias_meta.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/colvarbias_meta.cpp b/src/colvarbias_meta.cpp index 20a1a0afe..a0c92b2ce 100644 --- a/src/colvarbias_meta.cpp +++ b/src/colvarbias_meta.cpp @@ -1011,7 +1011,7 @@ int colvarbias_meta::update_bias() cvm::real hills_scale=1.0; if (ebmeta) { - hills_scale *= 1.0/target_dist->value(target_dist->get_colvars_index()); + hills_scale *= 1.0/target_dist->value(target_dist->get_colvars_index_bound()); if(cvm::step_absolute() <= ebmeta_equil_steps) { cvm::real const hills_lambda = (cvm::real(ebmeta_equil_steps - cvm::step_absolute())) /