00001 #if (__cplusplus >= 201103L)
00002
00003 #include <numeric>
00004 #include <algorithm>
00005 #include <cmath>
00006 #include <cstdlib>
00007 #include <limits>
00008
00009 #include "colvarmodule.h"
00010 #include "colvarvalue.h"
00011 #include "colvarparse.h"
00012 #include "colvar.h"
00013 #include "colvarcomp.h"
00014
00015 colvar::aspathCV::aspathCV(std::string const &conf): CVBasedPath(conf) {
00016 set_function_type("aspathCV");
00017 cvm::log(std::string("Total number of frames: ") + cvm::to_str(total_reference_frames) + std::string("\n"));
00018 std::vector<cvm::real> p_weights(cv.size(), 1.0);
00019 get_keyval(conf, "weights", p_weights, std::vector<cvm::real>(cv.size(), 1.0));
00020 x.type(colvarvalue::type_scalar);
00021 use_explicit_gradients = true;
00022 cvm::real p_lambda;
00023 get_keyval(conf, "lambda", p_lambda, -1.0);
00024 ArithmeticPathCV::ArithmeticPathBase<colvarvalue, cvm::real, ArithmeticPathCV::path_sz::S>::initialize(cv.size(), total_reference_frames, p_lambda, ref_cv[0], p_weights);
00025 cvm::log(std::string("Lambda is ") + cvm::to_str(lambda) + std::string("\n"));
00026 for (size_t i_cv = 0; i_cv < cv.size(); ++i_cv) {
00027 if (!cv[i_cv]->is_enabled(f_cvc_explicit_gradient)) {
00028 use_explicit_gradients = false;
00029 }
00030 cvm::log(std::string("The weight of CV ") + cvm::to_str(i_cv) + std::string(" is ") + cvm::to_str(weights[i_cv]) + std::string("\n"));
00031 }
00032 }
00033
00034 void colvar::aspathCV::updateDistanceToReferenceFrames() {
00035 for (size_t i_cv = 0; i_cv < cv.size(); ++i_cv) {
00036 cv[i_cv]->calc_value();
00037 }
00038 for (size_t i_frame = 0; i_frame < ref_cv.size(); ++i_frame) {
00039 for (size_t i_cv = 0; i_cv < cv.size(); ++i_cv) {
00040 colvarvalue ref_cv_value(ref_cv[i_frame][i_cv]);
00041 colvarvalue current_cv_value(cv[i_cv]->value());
00042 if (current_cv_value.type() == colvarvalue::type_scalar) {
00043 frame_element_distances[i_frame][i_cv] = 0.5 * cv[i_cv]->dist2_lgrad(cv[i_cv]->sup_coeff * (cvm::pow(current_cv_value.real_value, cv[i_cv]->sup_np)), ref_cv_value.real_value);
00044 } else {
00045 frame_element_distances[i_frame][i_cv] = 0.5 * cv[i_cv]->dist2_lgrad(cv[i_cv]->sup_coeff * current_cv_value, ref_cv_value);
00046 }
00047 }
00048 }
00049 }
00050
00051 void colvar::aspathCV::calc_value() {
00052 if (lambda < 0) {
00053
00054
00055 cvm::log("A non-positive value of lambda is detected, which implies that it may not set in the configuration.\n");
00056 cvm::log("This component (aspathCV) will recompute a value for lambda following the suggestion in the origin paper.\n");
00057 std::vector<cvm::real> rmsd_between_refs(total_reference_frames - 1, 0.0);
00058 computeDistanceBetweenReferenceFrames(rmsd_between_refs);
00059 reComputeLambda(rmsd_between_refs);
00060 cvm::log("Ok, the value of lambda is updated to " + cvm::to_str(lambda));
00061 }
00062 computeValue();
00063 x = s;
00064 }
00065
00066 void colvar::aspathCV::calc_gradients() {
00067 computeDerivatives();
00068 for (size_t i_cv = 0; i_cv < cv.size(); ++i_cv) {
00069 cv[i_cv]->calc_gradients();
00070 if (cv[i_cv]->is_enabled(f_cvc_explicit_gradient)) {
00071 cvm::real factor_polynomial = getPolynomialFactorOfCVGradient(i_cv);
00072 for (size_t j_elem = 0; j_elem < cv[i_cv]->value().size(); ++j_elem) {
00073 for (size_t k_ag = 0 ; k_ag < cv[i_cv]->atom_groups.size(); ++k_ag) {
00074 for (size_t l_atom = 0; l_atom < (cv[i_cv]->atom_groups)[k_ag]->size(); ++l_atom) {
00075 (*(cv[i_cv]->atom_groups)[k_ag])[l_atom].grad = dsdx[i_cv][j_elem] * factor_polynomial * (*(cv[i_cv]->atom_groups)[k_ag])[l_atom].grad;
00076 }
00077 }
00078 }
00079 }
00080 }
00081 }
00082
00083 void colvar::aspathCV::apply_force(colvarvalue const &force) {
00084 for (size_t i_cv = 0; i_cv < cv.size(); ++i_cv) {
00085 if (cv[i_cv]->is_enabled(f_cvc_explicit_gradient)) {
00086 for (size_t k_ag = 0 ; k_ag < cv[i_cv]->atom_groups.size(); ++k_ag) {
00087 (cv[i_cv]->atom_groups)[k_ag]->apply_colvar_force(force.real_value);
00088 }
00089 } else {
00090 cvm::real factor_polynomial = getPolynomialFactorOfCVGradient(i_cv);
00091 colvarvalue cv_force = dsdx[i_cv] * force.real_value * factor_polynomial;
00092 cv[i_cv]->apply_force(cv_force);
00093 }
00094 }
00095 }
00096
00097 colvar::aspathCV::~aspathCV() {}
00098
00099 colvar::azpathCV::azpathCV(std::string const &conf): CVBasedPath(conf) {
00100 set_function_type("azpathCV");
00101 cvm::log(std::string("Total number of frames: ") + cvm::to_str(total_reference_frames) + std::string("\n"));
00102 std::vector<cvm::real> p_weights(cv.size(), 1.0);
00103 get_keyval(conf, "weights", p_weights, std::vector<cvm::real>(cv.size(), 1.0));
00104 x.type(colvarvalue::type_scalar);
00105 use_explicit_gradients = true;
00106 cvm::real p_lambda;
00107 get_keyval(conf, "lambda", p_lambda, -1.0);
00108 ArithmeticPathCV::ArithmeticPathBase<colvarvalue, cvm::real, ArithmeticPathCV::path_sz::Z>::initialize(cv.size(), total_reference_frames, p_lambda, ref_cv[0], p_weights);
00109 cvm::log(std::string("Lambda is ") + cvm::to_str(lambda) + std::string("\n"));
00110 for (size_t i_cv = 0; i_cv < cv.size(); ++i_cv) {
00111 if (!cv[i_cv]->is_enabled(f_cvc_explicit_gradient)) {
00112 use_explicit_gradients = false;
00113 }
00114 cvm::log(std::string("The weight of CV ") + cvm::to_str(i_cv) + std::string(" is ") + cvm::to_str(weights[i_cv]) + std::string("\n"));
00115 }
00116 }
00117
00118 void colvar::azpathCV::updateDistanceToReferenceFrames() {
00119 for (size_t i_cv = 0; i_cv < cv.size(); ++i_cv) {
00120 cv[i_cv]->calc_value();
00121 }
00122 for (size_t i_frame = 0; i_frame < ref_cv.size(); ++i_frame) {
00123 for (size_t i_cv = 0; i_cv < cv.size(); ++i_cv) {
00124 colvarvalue ref_cv_value(ref_cv[i_frame][i_cv]);
00125 colvarvalue current_cv_value(cv[i_cv]->value());
00126 if (current_cv_value.type() == colvarvalue::type_scalar) {
00127 frame_element_distances[i_frame][i_cv] = 0.5 * cv[i_cv]->dist2_lgrad(cv[i_cv]->sup_coeff * (cvm::pow(current_cv_value.real_value, cv[i_cv]->sup_np)), ref_cv_value.real_value);
00128 } else {
00129 frame_element_distances[i_frame][i_cv] = 0.5 * cv[i_cv]->dist2_lgrad(cv[i_cv]->sup_coeff * current_cv_value, ref_cv_value);
00130 }
00131 }
00132 }
00133 }
00134
00135 void colvar::azpathCV::calc_value() {
00136 if (lambda < 0) {
00137
00138
00139 cvm::log("A non-positive value of lambda is detected, which implies that it may not set in the configuration.\n");
00140 cvm::log("This component (azpathCV) will recompute a value for lambda following the suggestion in the origin paper.\n");
00141 std::vector<cvm::real> rmsd_between_refs(total_reference_frames - 1, 0.0);
00142 computeDistanceBetweenReferenceFrames(rmsd_between_refs);
00143 reComputeLambda(rmsd_between_refs);
00144 cvm::log("Ok, the value of lambda is updated to " + cvm::to_str(lambda));
00145 }
00146 computeValue();
00147 x = z;
00148 }
00149
00150 void colvar::azpathCV::calc_gradients() {
00151 computeDerivatives();
00152 for (size_t i_cv = 0; i_cv < cv.size(); ++i_cv) {
00153 cv[i_cv]->calc_gradients();
00154 if (cv[i_cv]->is_enabled(f_cvc_explicit_gradient)) {
00155 cvm::real factor_polynomial = getPolynomialFactorOfCVGradient(i_cv);
00156 for (size_t j_elem = 0; j_elem < cv[i_cv]->value().size(); ++j_elem) {
00157 for (size_t k_ag = 0 ; k_ag < cv[i_cv]->atom_groups.size(); ++k_ag) {
00158 for (size_t l_atom = 0; l_atom < (cv[i_cv]->atom_groups)[k_ag]->size(); ++l_atom) {
00159 (*(cv[i_cv]->atom_groups)[k_ag])[l_atom].grad = dzdx[i_cv][j_elem] * factor_polynomial * (*(cv[i_cv]->atom_groups)[k_ag])[l_atom].grad;
00160 }
00161 }
00162 }
00163
00164 }
00165 }
00166 }
00167
00168 void colvar::azpathCV::apply_force(colvarvalue const &force) {
00169 for (size_t i_cv = 0; i_cv < cv.size(); ++i_cv) {
00170 if (cv[i_cv]->is_enabled(f_cvc_explicit_gradient)) {
00171 for (size_t k_ag = 0 ; k_ag < cv[i_cv]->atom_groups.size(); ++k_ag) {
00172 (cv[i_cv]->atom_groups)[k_ag]->apply_colvar_force(force.real_value);
00173 }
00174 } else {
00175 cvm::real factor_polynomial = getPolynomialFactorOfCVGradient(i_cv);
00176 const colvarvalue cv_force = dzdx[i_cv] * force.real_value * factor_polynomial;
00177 cv[i_cv]->apply_force(cv_force);
00178 }
00179 }
00180 }
00181
00182 colvar::azpathCV::~azpathCV() {}
00183
00184 #endif