00001 // -*- c++ -*- 00002 00003 // This file is part of the Collective Variables module (Colvars). 00004 // The original version of Colvars and its updates are located at: 00005 // https://github.com/Colvars/colvars 00006 // Please update all Colvars source files before making any changes. 00007 // If you wish to distribute your changes, please submit them to the 00008 // Colvars repository at GitHub. 00009 00010 00011 #include <algorithm> 00012 00013 #include "colvarmodule.h" 00014 #include "colvarvalue.h" 00015 #include "colvarparse.h" 00016 #include "colvar.h" 00017 #include "colvarcomp.h" 00018 00019 00020 colvar::alch_lambda::alch_lambda(std::string const &conf) 00021 : cvc(conf) 00022 { 00023 set_function_type("alchLambda"); 00024 00025 disable(f_cvc_explicit_gradient); 00026 disable(f_cvc_gradient); 00027 00028 x.type(colvarvalue::type_scalar); 00029 // Query initial value from back-end 00030 cvm::proxy->get_alch_lambda(&x.real_value); 00031 } 00032 00033 00034 void colvar::alch_lambda::calc_value() 00035 { 00036 // Special workflow: 00037 // at the beginning of the timestep we get a force instead of calculating the value 00038 00039 cvm::proxy->get_dE_dlambda(&ft.real_value); 00040 ft.real_value *= -1.0; // Energy derivative to force 00041 00042 // Include any force due to bias on Flambda 00043 ft.real_value += cvm::proxy->indirect_lambda_biasing_force; 00044 cvm::proxy->indirect_lambda_biasing_force = 0.0; 00045 } 00046 00047 00048 void colvar::alch_lambda::calc_gradients() 00049 { 00050 } 00051 00052 00053 void colvar::alch_lambda::apply_force(colvarvalue const & /* force */) 00054 { 00055 // new value will be cached and sent at end of timestep 00056 cvm::proxy->set_alch_lambda(x.real_value); 00057 } 00058 00059 simple_scalar_dist_functions(alch_lambda) 00060 00061 00062 00063 colvar::alch_Flambda::alch_Flambda(std::string const &conf) 00064 : cvc(conf) 00065 { 00066 set_function_type("alch_Flambda"); 00067 00068 disable(f_cvc_explicit_gradient); 00069 disable(f_cvc_gradient); 00070 00071 x.type(colvarvalue::type_scalar); 00072 } 00073 00074 00075 void colvar::alch_Flambda::calc_value() 00076 { 00077 // Special workflow: 00078 // at the beginning of the timestep we get a force instead of calculating the value 00079 00080 // Query initial value from back-end 00081 cvm::proxy->get_dE_dlambda(&x.real_value); 00082 x.real_value *= -1.0; // Energy derivative to force 00083 } 00084 00085 00086 void colvar::alch_Flambda::calc_gradients() 00087 { 00088 } 00089 00090 00091 void colvar::alch_Flambda::apply_force(colvarvalue const &force) 00092 { 00093 // Convert force on Flambda to force on dE/dlambda 00094 cvm::real f = -1.0 * force.real_value; 00095 // Send scalar force to back-end, which will distribute it onto atoms 00096 cvm::proxy->apply_force_dE_dlambda(&f); 00097 00098 // Propagate force on Flambda to lambda internally 00099 cvm::real d2E_dlambda2; 00100 cvm::proxy->get_d2E_dlambda2(&d2E_dlambda2); 00101 00102 // This accumulates a force, it needs to be zeroed when taken into account by lambda 00103 cvm::proxy->indirect_lambda_biasing_force += d2E_dlambda2 * f; 00104 } 00105 00106 simple_scalar_dist_functions(alch_Flambda)