source: src/Potentials/Specifics/ThreeBodyPotential_Angle.cpp@ 9eb71b3

Action_Thermostats Add_AtomRandomPerturbation Add_RotateAroundBondAction Add_SelectAtomByNameAction Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_StructOpt_integration_tests AutomationFragmentation_failures Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator Disabling_MemDebug Docu_Python_wait EmpiricalPotential_contain_HomologyGraph_documentation Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph Fix_ChronosMutex Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion GeometryObjects Gui_displays_atomic_force_velocity IndependentFragmentGrids_IntegrationTest JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks RotateToPrincipalAxisSystem_UndoRedo StoppableMakroAction TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps Ubuntu_1604_changes
Last change on this file since 9eb71b3 was 9eb71b3, checked in by Frederik Heber <frederik.heber@…>, 8 years ago

Commented out MemDebug include and Memory::ignore.

  • MemDebug clashes with various allocation operators that use a specific placement in memory. It is so far not possible to wrap new/delete fully. Hence, we stop this effort which so far has forced us to put ever more includes (with clashes) into MemDebug and thereby bloat compilation time.
  • MemDebug does not add that much usefulness which is not also provided by valgrind.
  • Property mode set to 100644
File size: 9.5 KB
RevLine 
[a63187]1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2012 University of Bonn. All rights reserved.
[acc9b1]5 * Copyright (C) 2013 Frederik Heber. All rights reserved.
[a63187]6 * Please see the COPYING file or "Copyright notice" in builder.cpp for details.
7 *
8 *
9 * This file is part of MoleCuilder.
10 *
11 * MoleCuilder is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation, either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * MoleCuilder is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with MoleCuilder. If not, see <http://www.gnu.org/licenses/>.
23 */
24
25/*
[484e2a]26 * ThreeBodyPotential_Angle.cpp
[a63187]27 *
28 * Created on: Oct 11, 2012
29 * Author: heber
30 */
31
32
33// include config.h
34#ifdef HAVE_CONFIG_H
35#include <config.h>
36#endif
37
[9eb71b3]38//#include "CodePatterns/MemDebug.hpp"
[a63187]39
[484e2a]40#include "ThreeBodyPotential_Angle.hpp"
[a63187]41
[ed2551]42#include <boost/assign/list_of.hpp> // for 'map_list_of()'
[7b019a]43#include <boost/bind.hpp>
[da2d5c]44#include <boost/lambda/lambda.hpp>
[ed2551]45#include <string>
46
[a63187]47#include "CodePatterns/Assert.hpp"
48
[7b019a]49#include "FunctionApproximation/Extractors.hpp"
[d52819]50#include "FunctionApproximation/TrainingData.hpp"
[a63187]51#include "Potentials/helpers.hpp"
[94453f1]52#include "Potentials/InternalCoordinates/ThreeBody_Angle.hpp"
[b760bc3]53#include "Potentials/ParticleTypeCheckers.hpp"
[0932c2]54#include "RandomNumbers/RandomNumberGeneratorFactory.hpp"
55#include "RandomNumbers/RandomNumberGenerator.hpp"
[a63187]56
[7b019a]57class Fragment;
58
[ed2551]59// static definitions
[484e2a]60const ThreeBodyPotential_Angle::ParameterNames_t
61ThreeBodyPotential_Angle::ParameterNames =
[ed2551]62 boost::assign::list_of<std::string>
63 ("spring_constant")
64 ("equilibrium_distance")
65 ;
[484e2a]66const std::string ThreeBodyPotential_Angle::potential_token("harmonic_angle");
[9eb71b3]67Coordinator::ptr ThreeBodyPotential_Angle::coordinator( /* Memory::ignore( */ new ThreeBody_Angle() /* ) */ );
[ed2551]68
[9c793c]69static BindingModel generateBindingModel(const EmpiricalPotential::ParticleTypes_t &_ParticleTypes)
[d5ca1a]70{
71 // fill nodes
[9c793c]72 BindingModel::vector_nodes_t nodes;
[d5ca1a]73 {
74 ASSERT( _ParticleTypes.size() == (size_t)3,
75 "generateBindingModel() - ThreeBodyPotential_Angle needs three types.");
[9c793c]76 nodes.push_back( FragmentNode(_ParticleTypes[0], 1) );
77 nodes.push_back( FragmentNode(_ParticleTypes[1], 2) );
78 nodes.push_back( FragmentNode(_ParticleTypes[2], 1) );
[d5ca1a]79 }
80
81 // there are no edges
82 HomologyGraph::edges_t edges;
83 {
84 std::pair<HomologyGraph::edges_t::iterator, bool > inserter;
85 inserter = edges.insert( std::make_pair( FragmentEdge(_ParticleTypes[0], _ParticleTypes[1]), 1) );
86 if (!inserter.second)
87 ++(inserter.first->second);
88 inserter = edges.insert( std::make_pair( FragmentEdge(_ParticleTypes[1], _ParticleTypes[2]), 1) );
89 if (!inserter.second)
90 ++(inserter.first->second);
91 }
92
[9c793c]93 return BindingModel(nodes, edges);
[d5ca1a]94}
95
[484e2a]96ThreeBodyPotential_Angle::ThreeBodyPotential_Angle() :
[a82d33]97 EmpiricalPotential(),
[d5ca1a]98 params(parameters_t(MAXPARAMS, 0.)),
[9c793c]99 bindingmodel(BindingModel())
[a82d33]100{
101 // have some decent defaults for parameter_derivative checking
102 params[spring_constant] = 1.;
103 params[equilibrium_distance] = 0.1;
104}
105
[484e2a]106ThreeBodyPotential_Angle::ThreeBodyPotential_Angle(
[ed2551]107 const ParticleTypes_t &_ParticleTypes
108 ) :
[fdd23a]109 EmpiricalPotential(_ParticleTypes),
[d5ca1a]110 params(parameters_t(MAXPARAMS, 0.)),
111 bindingmodel(generateBindingModel(_ParticleTypes))
[dbf8c8]112{
113 // have some decent defaults for parameter_derivative checking
114 params[spring_constant] = 1.;
115 params[equilibrium_distance] = 0.1;
116}
[a63187]117
[484e2a]118ThreeBodyPotential_Angle::ThreeBodyPotential_Angle(
[ed2551]119 const ParticleTypes_t &_ParticleTypes,
[a63187]120 const double _spring_constant,
[1e242a]121 const double _equilibrium_distance) :
[fdd23a]122 EmpiricalPotential(_ParticleTypes),
[d5ca1a]123 params(parameters_t(MAXPARAMS, 0.)),
124 bindingmodel(generateBindingModel(_ParticleTypes))
[a63187]125{
126 params[spring_constant] = _spring_constant;
127 params[equilibrium_distance] = _equilibrium_distance;
128}
129
[484e2a]130void ThreeBodyPotential_Angle::setParameters(const parameters_t &_params)
[086070]131{
132 const size_t paramsDim = _params.size();
133 ASSERT( paramsDim <= getParameterDimension(),
[484e2a]134 "ThreeBodyPotential_Angle::setParameters() - we need not more than "
[086070]135 +toString(getParameterDimension())+" parameters.");
136 for(size_t i=0;i<paramsDim;++i)
137 params[i] = _params[i];
138
139#ifndef NDEBUG
140 parameters_t check_params(getParameters());
141 check_params.resize(paramsDim); // truncate to same size
142 ASSERT( check_params == _params,
[484e2a]143 "ThreeBodyPotential_Angle::setParameters() - failed, mismatch in to be set "
[086070]144 +toString(_params)+" and set "+toString(check_params)+" params.");
145#endif
146}
147
[484e2a]148ThreeBodyPotential_Angle::result_t
149ThreeBodyPotential_Angle::function_theta(
[a63187]150 const double &r_ij,
[bbc422]151 const double &r_jk,
152 const double &r_ik
[a63187]153 ) const
154{
155// Info info(__func__);
[bbc422]156 const double angle = Helpers::pow(r_ij,2) + Helpers::pow(r_jk,2) - Helpers::pow(r_ik,2);
157 const double divisor = 2.* r_ij * r_jk;
[a63187]158
159// LOG(2, "DEBUG: cos(theta)= " << angle/divisor);
160 if (divisor == 0.)
161 return 0.;
162 else
163 return angle/divisor;
164}
165
[484e2a]166ThreeBodyPotential_Angle::results_t
167ThreeBodyPotential_Angle::operator()(
[e1fe7e]168 const list_of_arguments_t &listarguments
[a63187]169 ) const
170{
[e1fe7e]171 result_t result = 0.;
172 for(list_of_arguments_t::const_iterator iter = listarguments.begin();
173 iter != listarguments.end(); ++iter) {
174 const arguments_t &arguments = *iter;
175 ASSERT( arguments.size() == 3,
176 "ThreeBodyPotential_Angle::operator() - requires exactly three arguments.");
177 ASSERT( ParticleTypeChecker::checkArgumentsAgainstParticleTypes(
178 arguments, getParticleTypes()),
179 "ThreeBodyPotential_Angle::operator() - types don't match with ones in arguments.");
180 const argument_t &r_ij = arguments[0]; // 01
181 const argument_t &r_jk = arguments[2]; // 12
182 const argument_t &r_ik = arguments[1]; // 02
183 result +=
184 params[spring_constant]
185 * Helpers::pow( function_theta(r_ij.distance, r_jk.distance, r_ik.distance)
186 - params[equilibrium_distance], 2 );
187 }
188 return results_t(1, result);
[a63187]189}
190
[484e2a]191ThreeBodyPotential_Angle::derivative_components_t
192ThreeBodyPotential_Angle::derivative(
[e1fe7e]193 const list_of_arguments_t &listarguments
[a63187]194 ) const
195{
[e1fe7e]196 result_t result = 0.;
197 for(list_of_arguments_t::const_iterator iter = listarguments.begin();
198 iter != listarguments.end(); ++iter) {
199 const arguments_t &arguments = *iter;
200 ASSERT( arguments.size() == 3,
201 "ThreeBodyPotential_Angle::operator() - requires exactly three arguments.");
202 ASSERT( ParticleTypeChecker::checkArgumentsAgainstParticleTypes(
203 arguments, getParticleTypes()),
204 "ThreeBodyPotential_Angle::operator() - types don't match with ones in arguments.");
205 const argument_t &r_ij = arguments[0]; //01
206 const argument_t &r_jk = arguments[2]; //12
207 const argument_t &r_ik = arguments[1]; //02
208 result +=
209 2. * params[spring_constant] *
210 ( function_theta(r_ij.distance, r_jk.distance, r_ik.distance)
211 - params[equilibrium_distance]);
212 }
213 return derivative_components_t(1, result);
[a63187]214}
215
[484e2a]216ThreeBodyPotential_Angle::results_t
217ThreeBodyPotential_Angle::parameter_derivative(
[e1fe7e]218 const list_of_arguments_t &listarguments,
[a63187]219 const size_t index
220 ) const
221{
[e1fe7e]222 result_t result = 0.;
223 for(list_of_arguments_t::const_iterator iter = listarguments.begin();
224 iter != listarguments.end(); ++iter) {
225 const arguments_t &arguments = *iter;
226 ASSERT( arguments.size() == 3,
227 "ThreeBodyPotential_Angle::parameter_derivative() - requires exactly three arguments.");
228 ASSERT( ParticleTypeChecker::checkArgumentsAgainstParticleTypes(
229 arguments, getParticleTypes()),
230 "ThreeBodyPotential_Angle::operator() - types don't match with ones in arguments.");
231 const argument_t &r_ij = arguments[0]; //01
232 const argument_t &r_jk = arguments[2]; //12
233 const argument_t &r_ik = arguments[1]; //02
234 switch (index) {
235 case spring_constant:
236 {
237 result +=
238 Helpers::pow( function_theta(r_ij.distance, r_jk.distance, r_ik.distance) - params[equilibrium_distance], 2 );
239 break;
240 }
241 case equilibrium_distance:
242 {
243 result +=
244 -2. * params[spring_constant]
245 * ( function_theta(r_ij.distance, r_jk.distance, r_ik.distance) - params[equilibrium_distance]);
246 break;
247 }
248 default:
249 ASSERT(0, "ThreeBodyPotential_Angle::parameter_derivative() - derivative to unknown parameter desired.");
250 break;
[a63187]251 }
252 }
[e1fe7e]253 return results_t(1, result);
[a63187]254}
[7b019a]255
[484e2a]256FunctionModel::filter_t ThreeBodyPotential_Angle::getSpecificFilter() const
[0f5d38]257{
258 FunctionModel::filter_t returnfunction =
[1155ba]259 boost::bind(&Extractors::filterArgumentsByBindingModel,
260 _2, _1,
[67044a]261 boost::cref(getParticleTypes()), boost::cref(getBindingModel())
[0f5d38]262 );
263 return returnfunction;
264}
265
[d52819]266void
[484e2a]267ThreeBodyPotential_Angle::setParametersToRandomInitialValues(
[d52819]268 const TrainingData &data)
269{
[0932c2]270 RandomNumberGenerator &random = RandomNumberGeneratorFactory::getInstance().makeRandomNumberGenerator();
271 const double rng_min = random.min();
272 const double rng_max = random.max();
273 params[ThreeBodyPotential_Angle::spring_constant] = 1e+0*(random()/(rng_max-rng_min));// 0.2;
274 params[ThreeBodyPotential_Angle::equilibrium_distance] = -0.3;//2e+0*(random()/(rng_max-rng_min)) - 1.;// 1.;
[d52819]275}
276
Note: See TracBrowser for help on using the repository browser.