| version 1.30 | version 1.31 |
|---|
| |
| | |
| // -*- c++ -*- | // -*- c++ -*- |
| | // This file is part of the Collective Variables module (Colvars). |
| | // The original version of Colvars and its updates are located at: |
| | // https://github.com/colvars/colvars |
| | // Please update all Colvars source files before making any changes. |
| | // If you wish to distribute your changes, please submit them to the |
| | // Colvars repository at GitHub. |
| | |
| | |
| #include "colvarmodule.h" | #include "colvarmodule.h" |
| #include "colvarvalue.h" | #include "colvarvalue.h" |
| |
| } | } |
| | |
| | |
| colvar::colvar(std::string const &conf) | colvar::colvar() |
| : colvarparse(conf) | { |
| | // Initialize static array once and for all |
| | init_cv_requires(); |
| | } |
| | |
| | |
| | int colvar::init(std::string const &conf) |
| { | { |
| cvm::log("Initializing a new collective variable.\n"); | cvm::log("Initializing a new collective variable.\n"); |
| | colvarparse::init(conf); |
| | |
| int error_code = COLVARS_OK; | int error_code = COLVARS_OK; |
| | |
| | colvarmodule *cv = cvm::main(); |
| | |
| get_keyval(conf, "name", this->name, | get_keyval(conf, "name", this->name, |
| (std::string("colvar")+cvm::to_str(cvm::colvars.size()+1))); | (std::string("colvar")+cvm::to_str(cv->variables()->size()+1))); |
| | |
| if (cvm::colvar_by_name(this->name) != NULL) { | if ((cvm::colvar_by_name(this->name) != NULL) && |
| | (cvm::colvar_by_name(this->name) != this)) { |
| cvm::error("Error: this colvar cannot have the same name, \""+this->name+ | cvm::error("Error: this colvar cannot have the same name, \""+this->name+ |
| "\", as another colvar.\n", | "\", as another colvar.\n", |
| INPUT_ERROR); | INPUT_ERROR); |
| return; | return INPUT_ERROR; |
| } | } |
| | |
| // Initialize dependency members | // Initialize dependency members |
| |
| | |
| this->description = "colvar " + this->name; | this->description = "colvar " + this->name; |
| | |
| // Initialize static array once and for all | |
| init_cv_requires(); | |
| | |
| kinetic_energy = 0.0; | kinetic_energy = 0.0; |
| potential_energy = 0.0; | potential_energy = 0.0; |
| | |
| error_code |= init_components(conf); | error_code |= init_components(conf); |
| if (error_code != COLVARS_OK) return; | if (error_code != COLVARS_OK) { |
| | return cvm::get_error(); |
| | } |
| | |
| size_t i; | size_t i; |
| | |
| |
| } | } |
| } | } |
| if (x.type() == colvarvalue::type_notset) { | if (x.type() == colvarvalue::type_notset) { |
| cvm::error("Could not parse scripted colvar type."); | cvm::error("Could not parse scripted colvar type.", INPUT_ERROR); |
| return; | return INPUT_ERROR; |
| } | } |
| | |
| cvm::log(std::string("Expecting colvar value of type ") | cvm::log(std::string("Expecting colvar value of type ") |
| |
| if (x.type() == colvarvalue::type_vector) { | if (x.type() == colvarvalue::type_vector) { |
| int size; | int size; |
| if (!get_keyval(conf, "scriptedFunctionVectorSize", size)) { | if (!get_keyval(conf, "scriptedFunctionVectorSize", size)) { |
| cvm::error("Error: no size specified for vector scripted function."); | cvm::error("Error: no size specified for vector scripted function.", |
| return; | INPUT_ERROR); |
| | return INPUT_ERROR; |
| } | } |
| x.vector1d_value.resize(size); | x.vector1d_value.resize(size); |
| } | } |
| |
| } | } |
| feature_states[f_cv_homogeneous]->enabled = homogeneous; | feature_states[f_cv_homogeneous]->enabled = homogeneous; |
| } | } |
| // Colvar is deemed periodic iff: | |
| | // Colvar is deemed periodic if: |
| // - it is homogeneous | // - it is homogeneous |
| // - all cvcs are periodic | // - all cvcs are periodic |
| // - all cvcs have the same period | // - all cvcs have the same period |
| | if (cvcs[0]->b_periodic) { // TODO make this a CVC feature |
| b_periodic = cvcs[0]->b_periodic && is_enabled(f_cv_homogeneous); | bool b_periodic = true; |
| period = cvcs[0]->period; | period = cvcs[0]->period; |
| for (i = 1; i < cvcs.size(); i++) { | for (i = 1; i < cvcs.size(); i++) { |
| if (!cvcs[i]->b_periodic || cvcs[i]->period != period) { | if (!cvcs[i]->b_periodic || cvcs[i]->period != period) { |
| b_periodic = false; | b_periodic = false; |
| period = 0.0; | period = 0.0; |
| | cvm::log("Warning: although one component is periodic, this colvar will " |
| | "not be treated as periodic, either because the exponent is not " |
| | "1, or because components of different periodicity are defined. " |
| | "Make sure that you know what you are doing!"); |
| } | } |
| } | } |
| feature_states[f_cv_periodic]->enabled = b_periodic; | feature_states[f_cv_periodic]->enabled = b_periodic; |
| | } |
| | |
| // check that cvcs are compatible | // check that cvcs are compatible |
| | |
| for (i = 0; i < cvcs.size(); i++) { | for (i = 0; i < cvcs.size(); i++) { |
| if ((cvcs[i])->b_periodic && !b_periodic) { | |
| cvm::log("Warning: although this component is periodic, the colvar will " | |
| "not be treated as periodic, either because the exponent is not " | |
| "1, or because multiple components are present. Make sure that " | |
| "you know what you are doing!"); | |
| } | |
| | |
| // components may have different types only for scripted functions | // components may have different types only for scripted functions |
| if (!is_enabled(f_cv_scripted) && (colvarvalue::check_types(cvcs[i]->value(), | if (!is_enabled(f_cv_scripted) && (colvarvalue::check_types(cvcs[i]->value(), |
| |
| "by using components of different types. " | "by using components of different types. " |
| "You must use the same type in order to " | "You must use the same type in order to " |
| " sum them together.\n", INPUT_ERROR); | " sum them together.\n", INPUT_ERROR); |
| return; | return INPUT_ERROR; |
| } | } |
| } | } |
| | |
| |
| // at this point, the colvar's type is defined | // at this point, the colvar's type is defined |
| f.type(value()); | f.type(value()); |
| f_accumulated.type(value()); | f_accumulated.type(value()); |
| fb.type(value()); | |
| | x_old.type(value()); |
| | v_fdiff.type(value()); |
| | v_reported.type(value()); |
| | fj.type(value()); |
| | ft.type(value()); |
| | ft_reported.type(value()); |
| | f_old.type(value()); |
| | f_old.reset(); |
| | |
| | x_restart.type(value()); |
| | after_restart = false; |
| | |
| | reset_bias_force(); |
| | |
| | // TODO use here information from the CVCs' own natural boundaries |
| | error_code |= init_grid_parameters(conf); |
| | |
| | get_keyval(conf, "timeStepFactor", time_step_factor, 1); |
| | |
| | error_code |= init_extended_Lagrangian(conf); |
| | error_code |= init_output_flags(conf); |
| | |
| | // Start in active state by default |
| | enable(f_cv_active); |
| | // Make sure dependency side-effects are correct |
| | refresh_deps(); |
| | |
| | if (cvm::b_analysis) |
| | parse_analysis(conf); |
| | |
| | if (cvm::debug()) |
| | cvm::log("Done initializing collective variable \""+this->name+"\".\n"); |
| | |
| | return error_code; |
| | } |
| | |
| | |
| | int colvar::init_grid_parameters(std::string const &conf) |
| | { |
| | colvarmodule *cv = cvm::main(); |
| | |
| get_keyval(conf, "width", width, 1.0); | get_keyval(conf, "width", width, 1.0); |
| if (width <= 0.0) { | if (width <= 0.0) { |
| cvm::error("Error: \"width\" must be positive.\n", INPUT_ERROR); | cvm::error("Error: \"width\" must be positive.\n", INPUT_ERROR); |
| return; | return INPUT_ERROR; |
| } | } |
| | |
| // NOTE: not porting wall stuff to new deps, as this will change to a separate bias | |
| // the grid functions will wait a little as well | |
| | |
| lower_boundary.type(value()); | lower_boundary.type(value()); |
| lower_wall.type(value()); | |
| | |
| upper_boundary.type(value()); | upper_boundary.type(value()); |
| upper_wall.type(value()); | upper_wall.type(value()); |
| |
| provide(f_cv_lower_boundary); | provide(f_cv_lower_boundary); |
| enable(f_cv_lower_boundary); | enable(f_cv_lower_boundary); |
| } | } |
| | std::string lw_conf, uw_conf; |
| | |
| get_keyval(conf, "lowerWallConstant", lower_wall_k, 0.0); | if (get_keyval(conf, "lowerWallConstant", lower_wall_k, 0.0, parse_silent)) { |
| if (lower_wall_k > 0.0) { | cvm::log("Warning: lowerWallConstant and lowerWall are deprecated, " |
| | "please define a harmonicWalls bias instead.\n"); |
| | lower_wall.type(value()); |
| get_keyval(conf, "lowerWall", lower_wall, lower_boundary); | get_keyval(conf, "lowerWall", lower_wall, lower_boundary); |
| enable(f_cv_lower_wall); | lw_conf = std::string("\n\ |
| | harmonicWalls {\n\ |
| | name "+this->name+"lw\n\ |
| | colvars "+this->name+"\n\ |
| | forceConstant "+cvm::to_str(lower_wall_k*width*width)+"\n\ |
| | lowerWalls "+cvm::to_str(lower_wall)+"\n\ |
| | }\n"); |
| | cv->append_new_config(lw_conf); |
| } | } |
| | |
| if (get_keyval(conf, "upperBoundary", upper_boundary, upper_boundary)) { | if (get_keyval(conf, "upperBoundary", upper_boundary, upper_boundary)) { |
| |
| enable(f_cv_upper_boundary); | enable(f_cv_upper_boundary); |
| } | } |
| | |
| get_keyval(conf, "upperWallConstant", upper_wall_k, 0.0); | if (get_keyval(conf, "upperWallConstant", upper_wall_k, 0.0, parse_silent)) { |
| if (upper_wall_k > 0.0) { | cvm::log("Warning: upperWallConstant and upperWall are deprecated, " |
| | "please define a harmonicWalls bias instead.\n"); |
| | upper_wall.type(value()); |
| get_keyval(conf, "upperWall", upper_wall, upper_boundary); | get_keyval(conf, "upperWall", upper_wall, upper_boundary); |
| enable(f_cv_upper_wall); | uw_conf = std::string("\n\ |
| | harmonicWalls {\n\ |
| | name "+this->name+"uw\n\ |
| | colvars "+this->name+"\n\ |
| | forceConstant "+cvm::to_str(upper_wall_k*width*width)+"\n\ |
| | upperWalls "+cvm::to_str(upper_wall)+"\n\ |
| | }\n"); |
| | cv->append_new_config(uw_conf); |
| | } |
| | |
| | if (lw_conf.size() && uw_conf.size()) { |
| | if (lower_wall >= upper_wall) { |
| | cvm::error("Error: the upper wall, "+ |
| | cvm::to_str(upper_wall)+ |
| | ", is not higher than the lower wall, "+ |
| | cvm::to_str(lower_wall)+".\n", |
| | INPUT_ERROR); |
| | return INPUT_ERROR; |
| | } |
| } | } |
| } | } |
| | |
| |
| ", is not higher than the lower boundary, "+ | ", is not higher than the lower boundary, "+ |
| cvm::to_str(lower_boundary)+".\n", | cvm::to_str(lower_boundary)+".\n", |
| INPUT_ERROR); | INPUT_ERROR); |
| } | return INPUT_ERROR; |
| } | |
| | |
| if (is_enabled(f_cv_lower_wall) && is_enabled(f_cv_upper_wall)) { | |
| if (lower_wall >= upper_wall) { | |
| cvm::error("Error: the upper wall, "+ | |
| cvm::to_str(upper_wall)+ | |
| ", is not higher than the lower wall, "+ | |
| cvm::to_str(lower_wall)+".\n", | |
| INPUT_ERROR); | |
| } | } |
| } | } |
| | |
| |
| cvm::error("Error: trying to expand boundaries that already " | cvm::error("Error: trying to expand boundaries that already " |
| "cover a whole period of a periodic colvar.\n", | "cover a whole period of a periodic colvar.\n", |
| INPUT_ERROR); | INPUT_ERROR); |
| | return INPUT_ERROR; |
| } | } |
| if (expand_boundaries && hard_lower_boundary && hard_upper_boundary) { | if (expand_boundaries && hard_lower_boundary && hard_upper_boundary) { |
| cvm::error("Error: inconsistent configuration " | cvm::error("Error: inconsistent configuration " |
| "(trying to expand boundaries with both " | "(trying to expand boundaries with both " |
| "hardLowerBoundary and hardUpperBoundary enabled).\n", | "hardLowerBoundary and hardUpperBoundary enabled).\n", |
| INPUT_ERROR); | INPUT_ERROR); |
| | return INPUT_ERROR; |
| | } |
| | |
| | return COLVARS_OK; |
| } | } |
| | |
| get_keyval(conf, "timeStepFactor", time_step_factor, 1); | |
| | |
| | int colvar::init_extended_Lagrangian(std::string const &conf) |
| { | { |
| bool b_extended_Lagrangian; | bool b_extended_Lagrangian; |
| get_keyval(conf, "extendedLagrangian", b_extended_Lagrangian, false); | get_keyval(conf, "extendedLagrangian", b_extended_Lagrangian, false); |
| |
| enable(f_cv_extended_Lagrangian); | enable(f_cv_extended_Lagrangian); |
| provide(f_cv_Langevin); | provide(f_cv_Langevin); |
| | |
| | // The extended mass will apply forces |
| | enable(f_cv_gradient); |
| | |
| xr.type(value()); | xr.type(value()); |
| vr.type(value()); | vr.type(value()); |
| fr.type(value()); | fr.type(value()); |
| |
| cvm::error("Error: a positive temperature must be provided, either " | cvm::error("Error: a positive temperature must be provided, either " |
| "by enabling a thermostat, or through \"extendedTemp\".\n", | "by enabling a thermostat, or through \"extendedTemp\".\n", |
| INPUT_ERROR); | INPUT_ERROR); |
| | return INPUT_ERROR; |
| } | } |
| | |
| get_keyval(conf, "extendedFluctuation", tolerance); | get_keyval(conf, "extendedFluctuation", tolerance); |
| if (tolerance <= 0.0) { | if (tolerance <= 0.0) { |
| cvm::error("Error: \"extendedFluctuation\" must be positive.\n", INPUT_ERROR); | cvm::error("Error: \"extendedFluctuation\" must be positive.\n", INPUT_ERROR); |
| | return INPUT_ERROR; |
| } | } |
| ext_force_k = cvm::boltzmann() * temp / (tolerance * tolerance); | ext_force_k = cvm::boltzmann() * temp / (tolerance * tolerance); |
| cvm::log("Computed extended system force constant: " + cvm::to_str(ext_force_k) + " kcal/mol/U^2"); | cvm::log("Computed extended system force constant: " + cvm::to_str(ext_force_k) + " kcal/mol/U^2"); |
| |
| get_keyval(conf, "extendedLangevinDamping", ext_gamma, 1.0); | get_keyval(conf, "extendedLangevinDamping", ext_gamma, 1.0); |
| if (ext_gamma < 0.0) { | if (ext_gamma < 0.0) { |
| cvm::error("Error: \"extendedLangevinDamping\" may not be negative.\n", INPUT_ERROR); | cvm::error("Error: \"extendedLangevinDamping\" may not be negative.\n", INPUT_ERROR); |
| | return INPUT_ERROR; |
| } | } |
| if (ext_gamma != 0.0) { | if (ext_gamma != 0.0) { |
| enable(f_cv_Langevin); | enable(f_cv_Langevin); |
| |
| ext_sigma = std::sqrt(2.0 * cvm::boltzmann() * temp * ext_gamma * ext_mass / cvm::dt()); | ext_sigma = std::sqrt(2.0 * cvm::boltzmann() * temp * ext_gamma * ext_mass / cvm::dt()); |
| } | } |
| } | } |
| | |
| | return COLVARS_OK; |
| } | } |
| | |
| | |
| | int colvar::init_output_flags(std::string const &conf) |
| | { |
| { | { |
| bool b_output_value; | bool b_output_value; |
| get_keyval(conf, "outputValue", b_output_value, true); | get_keyval(conf, "outputValue", b_output_value, true); |
| |
| if (get_keyval(conf, "outputSystemForce", temp, false, colvarparse::parse_silent)) { | if (get_keyval(conf, "outputSystemForce", temp, false, colvarparse::parse_silent)) { |
| cvm::error("Option outputSystemForce is deprecated: only outputTotalForce is supported instead.\n" | cvm::error("Option outputSystemForce is deprecated: only outputTotalForce is supported instead.\n" |
| "The two are NOT identical: see http://colvars.github.io/totalforce.html.\n", INPUT_ERROR); | "The two are NOT identical: see http://colvars.github.io/totalforce.html.\n", INPUT_ERROR); |
| return; | return INPUT_ERROR; |
| } | } |
| } | } |
| | |
| |
| get_keyval_feature(this, conf, "outputAppliedForce", f_cv_output_applied_force, false); | get_keyval_feature(this, conf, "outputAppliedForce", f_cv_output_applied_force, false); |
| get_keyval_feature(this, conf, "subtractAppliedForce", f_cv_subtract_applied_force, false); | get_keyval_feature(this, conf, "subtractAppliedForce", f_cv_subtract_applied_force, false); |
| | |
| // Start in active state by default | return COLVARS_OK; |
| enable(f_cv_active); | |
| // Make sure dependency side-effects are correct | |
| refresh_deps(); | |
| | |
| x_old.type(value()); | |
| v_fdiff.type(value()); | |
| v_reported.type(value()); | |
| fj.type(value()); | |
| ft.type(value()); | |
| ft_reported.type(value()); | |
| f_old.type(value()); | |
| f_old.reset(); | |
| | |
| if (cvm::b_analysis) | |
| parse_analysis(conf); | |
| | |
| if (cvm::debug()) | |
| cvm::log("Done initializing collective variable \""+this->name+"\".\n"); | |
| } | } |
| | |
| | |
| |
| | |
| std::string runave_outfile; | std::string runave_outfile; |
| get_keyval(conf, "runAveOutputFile", runave_outfile, | get_keyval(conf, "runAveOutputFile", runave_outfile, |
| std::string(cvm::output_prefix+"."+ | std::string(cvm::output_prefix()+"."+ |
| this->name+".runave.traj")); | this->name+".runave.traj")); |
| | |
| size_t const this_cv_width = x.output_width(cvm::cv_width); | size_t const this_cv_width = x.output_width(cvm::cv_width); |
| |
| | |
| get_keyval(conf, "corrFuncNormalize", acf_normalize, true); | get_keyval(conf, "corrFuncNormalize", acf_normalize, true); |
| get_keyval(conf, "corrFuncOutputFile", acf_outfile, | get_keyval(conf, "corrFuncOutputFile", acf_outfile, |
| std::string(cvm::output_prefix+"."+this->name+ | std::string(cvm::output_prefix()+"."+this->name+ |
| ".corrfunc.dat")); | ".corrfunc.dat")); |
| } | } |
| return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK); | return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK); |
| |
| } | } |
| | |
| // remove reference to this colvar from the CVM | // remove reference to this colvar from the CVM |
| for (std::vector<colvar *>::iterator cvi = cvm::colvars.begin(); | colvarmodule *cv = cvm::main(); |
| cvi != cvm::colvars.end(); | for (std::vector<colvar *>::iterator cvi = cv->variables()->begin(); |
| | cvi != cv->variables()->end(); |
| ++cvi) { | ++cvi) { |
| if ( *cvi == this) { | if ( *cvi == this) { |
| cvm::colvars.erase(cvi); | cv->variables()->erase(cvi); |
| break; | break; |
| } | } |
| } | } |
| |
| cvm::log("Colvar \""+this->name+"\" has value "+ | cvm::log("Colvar \""+this->name+"\" has value "+ |
| cvm::to_str(x, cvm::cv_width, cvm::cv_prec)+".\n"); | cvm::to_str(x, cvm::cv_width, cvm::cv_prec)+".\n"); |
| | |
| | if (after_restart) { |
| | after_restart = false; |
| | if (cvm::proxy->simulation_running()) { |
| | cvm::real const jump2 = dist2(x, x_restart) / (width*width); |
| | if (jump2 > 0.25) { |
| | cvm::error("Error: the calculated value of colvar \""+name+ |
| | "\":\n"+cvm::to_str(x)+"\n differs greatly from the value " |
| | "last read from the state file:\n"+cvm::to_str(x_restart)+ |
| | "\nPossible causes are changes in configuration, " |
| | "wrong state file, or how PBC wrapping is handled.\n", |
| | INPUT_ERROR); |
| | return INPUT_ERROR; |
| | } |
| | } |
| | } |
| | |
| return COLVARS_OK; | return COLVARS_OK; |
| } | } |
| | |
| |
| if (cvm::debug()) | if (cvm::debug()) |
| cvm::log("Calculating total force of colvar \""+this->name+"\".\n"); | cvm::log("Calculating total force of colvar \""+this->name+"\".\n"); |
| | |
| // if (!tasks[task_extended_lagrangian] && (cvm::step_relative() > 0)) { | |
| // Disabled check to allow for explicit total force calculation | |
| // even with extended Lagrangian | |
| cvm::increase_depth(); | cvm::increase_depth(); |
| | |
| for (i = first_cvc, cvc_count = 0; | for (i = first_cvc, cvc_count = 0; |
| |
| // get from the cvcs the total forces from the PREVIOUS step | // get from the cvcs the total forces from the PREVIOUS step |
| for (size_t i = 0; i < cvcs.size(); i++) { | for (size_t i = 0; i < cvcs.size(); i++) { |
| if (!cvcs[i]->is_enabled()) continue; | if (!cvcs[i]->is_enabled()) continue; |
| | if (cvm::debug()) |
| | cvm::log("Colvar component no. "+cvm::to_str(i+1)+ |
| | " within colvar \""+this->name+"\" has total force "+ |
| | cvm::to_str((cvcs[i])->total_force(), |
| | cvm::cv_width, cvm::cv_prec)+".\n"); |
| // linear combination is assumed | // linear combination is assumed |
| ft += (cvcs[i])->total_force() * (cvcs[i])->sup_coeff / active_cvc_square_norm; | ft += (cvcs[i])->total_force() * (cvcs[i])->sup_coeff / active_cvc_square_norm; |
| } | } |
| |
| fj.reset(); | fj.reset(); |
| for (size_t i = 0; i < cvcs.size(); i++) { | for (size_t i = 0; i < cvcs.size(); i++) { |
| if (!cvcs[i]->is_enabled()) continue; | if (!cvcs[i]->is_enabled()) continue; |
| | if (cvm::debug()) |
| | cvm::log("Colvar component no. "+cvm::to_str(i+1)+ |
| | " within colvar \""+this->name+"\" has Jacobian derivative"+ |
| | cvm::to_str((cvcs[i])->Jacobian_derivative(), |
| | cvm::cv_width, cvm::cv_prec)+".\n"); |
| // linear combination is assumed | // linear combination is assumed |
| fj += (cvcs[i])->Jacobian_derivative() * (cvcs[i])->sup_coeff / active_cvc_square_norm; | fj += (cvcs[i])->Jacobian_derivative() * (cvcs[i])->sup_coeff / active_cvc_square_norm; |
| } | } |
| |
| f -= fj; | f -= fj; |
| } | } |
| | |
| // Wall force | |
| colvarvalue fw(x); | |
| fw.reset(); | |
| | |
| if (is_enabled(f_cv_lower_wall) || is_enabled(f_cv_upper_wall)) { | |
| | |
| if (cvm::debug()) | |
| cvm::log("Calculating wall forces for colvar \""+this->name+"\".\n"); | |
| | |
| // For a periodic colvar, both walls may be applicable at the same time | |
| // in which case we pick the closer one | |
| if ( (!is_enabled(f_cv_upper_wall)) || | |
| (this->dist2(x, lower_wall) < this->dist2(x, upper_wall)) ) { | |
| | |
| cvm::real const grad = this->dist2_lgrad(x, lower_wall); | |
| if (grad < 0.0) { | |
| fw = -0.5 * lower_wall_k * grad; | |
| if (cvm::debug()) | |
| cvm::log("Applying a lower wall force("+ | |
| cvm::to_str(fw)+") to \""+this->name+"\".\n"); | |
| } | |
| | |
| } else { | |
| | |
| cvm::real const grad = this->dist2_lgrad(x, upper_wall); | |
| if (grad > 0.0) { | |
| fw = -0.5 * upper_wall_k * grad; | |
| if (cvm::debug()) | |
| cvm::log("Applying an upper wall force("+ | |
| cvm::to_str(fw)+") to \""+this->name+"\".\n"); | |
| } | |
| } | |
| } | |
| | |
| // At this point f is the force f from external biases that will be applied to the | // At this point f is the force f from external biases that will be applied to the |
| // extended variable if there is one | // extended variable if there is one |
| | |
| if (is_enabled(f_cv_extended_Lagrangian)) { | if (is_enabled(f_cv_extended_Lagrangian)) { |
| | |
| | if (cvm::debug()) { |
| | cvm::log("Updating extended-Lagrangian degrees of freedom.\n"); |
| | } |
| | |
| cvm::real dt = cvm::dt(); | cvm::real dt = cvm::dt(); |
| colvarvalue f_ext(fr.type()); | colvarvalue f_ext(fr.type()); |
| f_ext.reset(); | f_ext.reset(); |
| |
| // f_ext: total force on extended variable (including harmonic spring) | // f_ext: total force on extended variable (including harmonic spring) |
| // f: - initially, external biasing force | // f: - initially, external biasing force |
| // - after this code block, colvar force to be applied to atomic coordinates | // - after this code block, colvar force to be applied to atomic coordinates |
| // ie. spring force + wall force | // ie. spring force (fb_actual will be added just below) |
| fr = f; | fr = f; |
| f_ext = f + (-0.5 * ext_force_k) * this->dist2_lgrad(xr, x); | f_ext = f + (-0.5 * ext_force_k) * this->dist2_lgrad(xr, x); |
| f = (-0.5 * ext_force_k) * this->dist2_rgrad(xr, x); | f = (-0.5 * ext_force_k) * this->dist2_rgrad(xr, x); |
| |
| if (this->is_enabled(f_cv_periodic)) this->wrap(xr); | if (this->is_enabled(f_cv_periodic)) this->wrap(xr); |
| } | } |
| | |
| f += fw; | // Now adding the force on the actual colvar (for those biases who |
| | // bypass the extended Lagrangian mass) |
| | f += fb_actual; |
| | |
| // Store force to be applied, possibly summed over several timesteps | // Store force to be applied, possibly summed over several timesteps |
| f_accumulated += f; | f_accumulated += f; |
| |
| void colvar::communicate_forces() | void colvar::communicate_forces() |
| { | { |
| size_t i; | size_t i; |
| if (cvm::debug()) | if (cvm::debug()) { |
| cvm::log("Communicating forces from colvar \""+this->name+"\".\n"); | cvm::log("Communicating forces from colvar \""+this->name+"\".\n"); |
| | cvm::log("Force to be applied: " + cvm::to_str(f_accumulated) + "\n"); |
| | } |
| | |
| if (is_enabled(f_cv_scripted)) { | if (is_enabled(f_cv_scripted)) { |
| std::vector<cvm::matrix2d<cvm::real> > func_grads; | std::vector<cvm::matrix2d<cvm::real> > func_grads; |
| |
| } | } |
| } | } |
| | |
| if ( !(get_keyval(conf, "x", x, | if ( !(get_keyval(conf, "x", x, x, colvarparse::parse_silent)) ) { |
| colvarvalue(x.type()), colvarparse::parse_silent)) ) { | |
| cvm::log("Error: restart file does not contain " | cvm::log("Error: restart file does not contain " |
| "the value of the colvar \""+ | "the value of the colvar \""+ |
| name+"\" .\n"); | name+"\" .\n"); |
| } else { | } else { |
| cvm::log("Restarting collective variable \""+name+"\" from value: "+ | cvm::log("Restarting collective variable \""+name+"\" from value: "+ |
| cvm::to_str(x)+"\n"); | cvm::to_str(x)+"\n"); |
| | x_restart = x; |
| | after_restart = true; |
| } | } |
| | |
| if (is_enabled(f_cv_extended_Lagrangian)) { | if (is_enabled(f_cv_extended_Lagrangian)) { |