pele
Python energy landscape explorer
|
00001 #ifndef _PELE_COMBINE_POTENTIALS_H_ 00002 #define _PELE_COMBINE_POTENTIALS_H_ 00003 #include <list> 00004 #include <memory> 00005 #include "base_potential.h" 00006 00007 namespace pele { 00008 00015 class CombinedPotential : public BasePotential{ 00016 protected: 00017 std::list<std::shared_ptr<BasePotential> > _potentials; 00018 00019 public: 00020 CombinedPotential() {} 00021 00025 virtual ~CombinedPotential() {} 00026 00030 virtual void add_potential(std::shared_ptr<BasePotential> potential) 00031 { 00032 _potentials.push_back(potential); 00033 } 00034 00035 virtual double get_energy(Array<double> x) 00036 { 00037 double energy = 0.; 00038 for (auto & pot_ptr : _potentials){ 00039 energy += pot_ptr->get_energy(x); 00040 } 00041 return energy; 00042 } 00043 00044 virtual double get_energy_gradient(Array<double> x, Array<double> grad) 00045 { 00046 if (x.size() != grad.size()) { 00047 throw std::invalid_argument("the gradient has the wrong size"); 00048 } 00049 00050 double energy = 0.; 00051 grad.assign(0.); 00052 00053 for (auto & pot_ptr : _potentials){ 00054 energy += pot_ptr->add_energy_gradient(x, grad); 00055 } 00056 return energy; 00057 } 00058 00059 virtual double get_energy_gradient_hessian(Array<double> x, Array<double> grad, 00060 Array<double> hess) 00061 { 00062 if (x.size() != grad.size()) { 00063 throw std::invalid_argument("the gradient has the wrong size"); 00064 } 00065 if (hess.size() != x.size() * x.size()) { 00066 throw std::invalid_argument("the Hessian has the wrong size"); 00067 } 00068 00069 double energy = 0.; 00070 grad.assign(0.); 00071 hess.assign(0.); 00072 00073 for (auto & pot_ptr : _potentials){ 00074 energy += pot_ptr->add_energy_gradient_hessian(x, grad, hess); 00075 } 00076 return energy; 00077 } 00078 00079 }; 00080 } 00081 00082 #endif