source: src/Potentials/Specifics/ThreeBodyPotential_Angle.cpp@ 1155ba

Action_Thermostats Add_AtomRandomPerturbation Add_RotateAroundBondAction Add_SelectAtomByNameAction Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_StructOpt_integration_tests Automaking_mpqc_open AutomationFragmentation_failures Candidate_v1.6.0 Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator Combining_Subpackages Debian_Package_split Debian_package_split_molecuildergui_only Disabling_MemDebug Docu_Python_wait EmpiricalPotential_contain_HomologyGraph EmpiricalPotential_contain_HomologyGraph_documentation Enable_parallel_make_install Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph FitPartialCharges_GlobalError 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 JobMarket_unresolvable_hostname_fix ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks RotateToPrincipalAxisSystem_UndoRedo StoppableMakroAction Subpackage_CodePatterns Subpackage_JobMarket Subpackage_LinearAlgebra Subpackage_levmar Subpackage_mpqc_open Subpackage_vmg ThirdParty_MPQC_rebuilt_buildsystem TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps Ubuntu_1604_changes stable
Last change on this file since 1155ba was 1155ba, checked in by Frederik Heber <heber@…>, 8 years ago

Converted filterArguments... into faster filter, renamed other to ..ByBindingModel.

  • there are now two filters: One filters by list of particles types and is meant for simple pair potentials. The other one filters (and reorders) by the binding model. This takes more computation time but is required for more complex potentials.
  • TESTFIX: This allows morse and harmonic pair potentials tests to pass again, removed XFAIL from the corresponding regression tests.
  • Property mode set to 100644
File size: 9.4 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2012 University of Bonn. All rights reserved.
5 * Copyright (C) 2013 Frederik Heber. All rights reserved.
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/*
26 * ThreeBodyPotential_Angle.cpp
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
38#include "CodePatterns/MemDebug.hpp"
39
40#include "ThreeBodyPotential_Angle.hpp"
41
42#include <boost/assign/list_of.hpp> // for 'map_list_of()'
43#include <boost/bind.hpp>
44#include <boost/lambda/lambda.hpp>
45#include <string>
46
47#include "CodePatterns/Assert.hpp"
48
49#include "FunctionApproximation/Extractors.hpp"
50#include "FunctionApproximation/TrainingData.hpp"
51#include "Potentials/helpers.hpp"
52#include "Potentials/InternalCoordinates/ThreeBody_Angle.hpp"
53#include "Potentials/ParticleTypeCheckers.hpp"
54#include "RandomNumbers/RandomNumberGeneratorFactory.hpp"
55#include "RandomNumbers/RandomNumberGenerator.hpp"
56
57class Fragment;
58
59// static definitions
60const ThreeBodyPotential_Angle::ParameterNames_t
61ThreeBodyPotential_Angle::ParameterNames =
62 boost::assign::list_of<std::string>
63 ("spring_constant")
64 ("equilibrium_distance")
65 ;
66const std::string ThreeBodyPotential_Angle::potential_token("harmonic_angle");
67Coordinator::ptr ThreeBodyPotential_Angle::coordinator(Memory::ignore(new ThreeBody_Angle()));
68
69static BindingModel generateBindingModel(const EmpiricalPotential::ParticleTypes_t &_ParticleTypes)
70{
71 // fill nodes
72 BindingModel::vector_nodes_t nodes;
73 {
74 ASSERT( _ParticleTypes.size() == (size_t)3,
75 "generateBindingModel() - ThreeBodyPotential_Angle needs three types.");
76 nodes.push_back( FragmentNode(_ParticleTypes[0], 1) );
77 nodes.push_back( FragmentNode(_ParticleTypes[1], 2) );
78 nodes.push_back( FragmentNode(_ParticleTypes[2], 1) );
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
93 return BindingModel(nodes, edges);
94}
95
96ThreeBodyPotential_Angle::ThreeBodyPotential_Angle() :
97 EmpiricalPotential(),
98 params(parameters_t(MAXPARAMS, 0.)),
99 bindingmodel(BindingModel())
100{
101 // have some decent defaults for parameter_derivative checking
102 params[spring_constant] = 1.;
103 params[equilibrium_distance] = 0.1;
104}
105
106ThreeBodyPotential_Angle::ThreeBodyPotential_Angle(
107 const ParticleTypes_t &_ParticleTypes
108 ) :
109 EmpiricalPotential(_ParticleTypes),
110 params(parameters_t(MAXPARAMS, 0.)),
111 bindingmodel(generateBindingModel(_ParticleTypes))
112{
113 // have some decent defaults for parameter_derivative checking
114 params[spring_constant] = 1.;
115 params[equilibrium_distance] = 0.1;
116}
117
118ThreeBodyPotential_Angle::ThreeBodyPotential_Angle(
119 const ParticleTypes_t &_ParticleTypes,
120 const double _spring_constant,
121 const double _equilibrium_distance) :
122 EmpiricalPotential(_ParticleTypes),
123 params(parameters_t(MAXPARAMS, 0.)),
124 bindingmodel(generateBindingModel(_ParticleTypes))
125{
126 params[spring_constant] = _spring_constant;
127 params[equilibrium_distance] = _equilibrium_distance;
128}
129
130void ThreeBodyPotential_Angle::setParameters(const parameters_t &_params)
131{
132 const size_t paramsDim = _params.size();
133 ASSERT( paramsDim <= getParameterDimension(),
134 "ThreeBodyPotential_Angle::setParameters() - we need not more than "
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,
143 "ThreeBodyPotential_Angle::setParameters() - failed, mismatch in to be set "
144 +toString(_params)+" and set "+toString(check_params)+" params.");
145#endif
146}
147
148ThreeBodyPotential_Angle::result_t
149ThreeBodyPotential_Angle::function_theta(
150 const double &r_ij,
151 const double &r_jk,
152 const double &r_ik
153 ) const
154{
155// Info info(__func__);
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;
158
159// LOG(2, "DEBUG: cos(theta)= " << angle/divisor);
160 if (divisor == 0.)
161 return 0.;
162 else
163 return angle/divisor;
164}
165
166ThreeBodyPotential_Angle::results_t
167ThreeBodyPotential_Angle::operator()(
168 const list_of_arguments_t &listarguments
169 ) const
170{
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);
189}
190
191ThreeBodyPotential_Angle::derivative_components_t
192ThreeBodyPotential_Angle::derivative(
193 const list_of_arguments_t &listarguments
194 ) const
195{
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);
214}
215
216ThreeBodyPotential_Angle::results_t
217ThreeBodyPotential_Angle::parameter_derivative(
218 const list_of_arguments_t &listarguments,
219 const size_t index
220 ) const
221{
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;
251 }
252 }
253 return results_t(1, result);
254}
255
256FunctionModel::filter_t ThreeBodyPotential_Angle::getSpecificFilter() const
257{
258 FunctionModel::filter_t returnfunction =
259 boost::bind(&Extractors::filterArgumentsByBindingModel,
260 _2, _1,
261 boost::cref(getParticleTypes()), boost::cref(getBindingModel())
262 );
263 return returnfunction;
264}
265
266void
267ThreeBodyPotential_Angle::setParametersToRandomInitialValues(
268 const TrainingData &data)
269{
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.;
275}
276
Note: See TracBrowser for help on using the repository browser.