source: src/Potentials/Specifics/FourBodyPotential_Torsion.cpp@ f5dbea

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 f5dbea was 9c793c, checked in by Frederik Heber <heber@…>, 8 years ago

All ..Potentials now return BindingModel instead of HomologyGraph, Extractors::reorderArg..() uses it.

  • Extractors::filterArg..() and ::reorderArg..() expect BindingModel instead of HomologyGraph.
  • TESTFIX: Lennard Jones potential fitting regression test no longer fails because it is purely non-bonded.
  • Property mode set to 100644
File size: 10.7 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2013 Frederik Heber. All rights reserved.
5 * Please see the COPYING file or "Copyright notice" in builder.cpp for details.
6 *
7 *
8 * This file is part of MoleCuilder.
9 *
10 * MoleCuilder is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * MoleCuilder is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with MoleCuilder. If not, see <http://www.gnu.org/licenses/>.
22 */
23
24/*
25 * FourBodyPotential_Torsion.cpp
26 *
27 * Created on: Jul 08, 2013
28 * Author: heber
29 */
30
31
32// include config.h
33#ifdef HAVE_CONFIG_H
34#include <config.h>
35#endif
36
37#include "CodePatterns/MemDebug.hpp"
38
39#include "FourBodyPotential_Torsion.hpp"
40
41#include <boost/assign/list_of.hpp> // for 'map_list_of()'
42#include <boost/bind.hpp>
43#include <boost/lambda/lambda.hpp>
44#include <string>
45
46#include "CodePatterns/Assert.hpp"
47
48#include "FunctionApproximation/Extractors.hpp"
49#include "FunctionApproximation/TrainingData.hpp"
50#include "Potentials/helpers.hpp"
51#include "Potentials/InternalCoordinates/FourBody_TorsionAngle.hpp"
52#include "Potentials/ParticleTypeCheckers.hpp"
53#include "RandomNumbers/RandomNumberGeneratorFactory.hpp"
54#include "RandomNumbers/RandomNumberGenerator.hpp"
55
56class Fragment;
57
58// static definitions1
59const FourBodyPotential_Torsion::ParameterNames_t
60FourBodyPotential_Torsion::ParameterNames =
61 boost::assign::list_of<std::string>
62 ("spring_constant")
63 ("equilibrium_distance")
64 ;
65const std::string FourBodyPotential_Torsion::potential_token("torsion");
66Coordinator::ptr FourBodyPotential_Torsion::coordinator(Memory::ignore(new FourBody_TorsionAngle()));
67
68static BindingModel generateBindingModel(const EmpiricalPotential::ParticleTypes_t &_ParticleTypes)
69{
70 // fill nodes
71 BindingModel::vector_nodes_t nodes;
72 {
73 ASSERT( _ParticleTypes.size() == (size_t)4,
74 "generateBindingModel() - FourBodyPotential_Torsion needs four types.");
75 nodes.push_back( FragmentNode(_ParticleTypes[0], 1) );
76 nodes.push_back( FragmentNode(_ParticleTypes[1], 2) );
77 nodes.push_back( FragmentNode(_ParticleTypes[2], 2) );
78 nodes.push_back( FragmentNode(_ParticleTypes[3], 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 inserter = edges.insert( std::make_pair( FragmentEdge(_ParticleTypes[2], _ParticleTypes[3]), 1) );
92 if (!inserter.second)
93 ++(inserter.first->second);
94 }
95
96 return BindingModel(nodes, edges);
97}
98
99FourBodyPotential_Torsion::FourBodyPotential_Torsion() :
100 EmpiricalPotential(),
101 params(parameters_t(MAXPARAMS, 0.)),
102 bindingmodel(BindingModel())
103{
104 // have some decent defaults for parameter_derivative checking
105 params[spring_constant] = 1.;
106 params[equilibrium_distance] = 0.1;
107}
108
109FourBodyPotential_Torsion::FourBodyPotential_Torsion(
110 const ParticleTypes_t &_ParticleTypes
111 ) :
112 EmpiricalPotential(_ParticleTypes),
113 params(parameters_t(MAXPARAMS, 0.)),
114 bindingmodel(generateBindingModel(_ParticleTypes))
115{
116 // have some decent defaults for parameter_derivative checking
117 params[spring_constant] = 1.;
118 params[equilibrium_distance] = 0.1;
119}
120
121FourBodyPotential_Torsion::FourBodyPotential_Torsion(
122 const ParticleTypes_t &_ParticleTypes,
123 const double _spring_constant,
124 const double _equilibrium_distance) :
125 EmpiricalPotential(_ParticleTypes),
126 params(parameters_t(MAXPARAMS, 0.)),
127 bindingmodel(generateBindingModel(_ParticleTypes))
128{
129 params[spring_constant] = _spring_constant;
130 params[equilibrium_distance] = _equilibrium_distance;
131}
132
133void FourBodyPotential_Torsion::setParameters(const parameters_t &_params)
134{
135 const size_t paramsDim = _params.size();
136 ASSERT( paramsDim <= getParameterDimension(),
137 "FourBodyPotential_Torsion::setParameters() - we need not more than "
138 +toString(getParameterDimension())+" parameters.");
139 for(size_t i=0;i<paramsDim;++i)
140 params[i] = _params[i];
141
142#ifndef NDEBUG
143 parameters_t check_params(getParameters());
144 check_params.resize(paramsDim); // truncate to same size
145 ASSERT( check_params == _params,
146 "FourBodyPotential_Torsion::setParameters() - failed, mismatch in to be set "
147 +toString(_params)+" and set "+toString(check_params)+" params.");
148#endif
149}
150
151FourBodyPotential_Torsion::result_t
152FourBodyPotential_Torsion::function_theta(
153 const double &r_ij,
154 const double &r_ik,
155 const double &r_il,
156 const double &r_jk,
157 const double &r_jl,
158 const double &r_kl
159 ) const
160{
161// Info info(__func__);
162 const double h_1 = .5*sqrt(2.*(Helpers::pow(r_ij,2)+Helpers::pow(r_ik,2))-Helpers::pow(r_jk,2));
163 const double h_2 = .5*sqrt(2.*(Helpers::pow(r_jl,2)+Helpers::pow(r_kl,2))-Helpers::pow(r_jk,2));
164 const double angle = Helpers::pow(h_1,2) + Helpers::pow(h_2,2) - Helpers::pow(r_il,2);
165 const double divisor = 2.* h_1 * h_2;
166
167// LOG(2, "DEBUG: cos(theta)= " << angle/divisor);
168 if (divisor == 0.)
169 return 0.;
170 else
171 return angle/divisor;
172}
173
174FourBodyPotential_Torsion::results_t
175FourBodyPotential_Torsion::operator()(
176 const list_of_arguments_t &listarguments
177 ) const
178{
179 result_t result = 0.;
180 for(list_of_arguments_t::const_iterator iter = listarguments.begin();
181 iter != listarguments.end(); ++iter) {
182 const arguments_t &arguments = *iter;
183 ASSERT( arguments.size() == getSpecificArgumentCount(),
184 "FourBodyPotential_Torsion::operator() - requires exactly three arguments.");
185 ASSERT( ParticleTypeChecker::checkArgumentsAgainstParticleTypes(
186 arguments, getParticleTypes()),
187 "FourBodyPotential_Torsion::operator() - types don't match with ones in arguments.");
188 const argument_t &r_ij = arguments[0]; // 01
189 const argument_t &r_ik = arguments[1]; // 02
190 const argument_t &r_il = arguments[2]; // 03
191 const argument_t &r_jk = arguments[3]; // 12
192 const argument_t &r_jl = arguments[4]; // 13
193 const argument_t &r_kl = arguments[5]; // 23
194 result +=
195 params[spring_constant]
196 * Helpers::pow( function_theta(r_ij.distance, r_ik.distance, r_il.distance, r_jk.distance, r_jl.distance, r_kl.distance)
197 - params[equilibrium_distance], 2 );
198 }
199 return results_t(1, result);
200}
201
202FourBodyPotential_Torsion::derivative_components_t
203FourBodyPotential_Torsion::derivative(
204 const list_of_arguments_t &listarguments
205 ) const
206{
207 result_t result = 0.;
208 for(list_of_arguments_t::const_iterator iter = listarguments.begin();
209 iter != listarguments.end(); ++iter) {
210 const arguments_t &arguments = *iter;
211 ASSERT( arguments.size() == getSpecificArgumentCount(),
212 "FourBodyPotential_Torsion::operator() - requires exactly three arguments.");
213 ASSERT( ParticleTypeChecker::checkArgumentsAgainstParticleTypes(
214 arguments, getParticleTypes()),
215 "FourBodyPotential_Torsion::operator() - types don't match with ones in arguments.");
216 const argument_t &r_ij = arguments[0]; // 01
217 const argument_t &r_ik = arguments[1]; // 02
218 const argument_t &r_il = arguments[2]; // 03
219 const argument_t &r_jk = arguments[3]; // 12
220 const argument_t &r_jl = arguments[4]; // 13
221 const argument_t &r_kl = arguments[5]; // 23
222 result +=
223 2. * params[spring_constant] *
224 ( function_theta(r_ij.distance, r_ik.distance, r_il.distance, r_jk.distance, r_jl.distance, r_kl.distance)
225 - params[equilibrium_distance]);
226 }
227 return derivative_components_t(1, result);
228}
229
230FourBodyPotential_Torsion::results_t
231FourBodyPotential_Torsion::parameter_derivative(
232 const list_of_arguments_t &listarguments,
233 const size_t index
234 ) const
235{
236 result_t result = 0.;
237 for(list_of_arguments_t::const_iterator iter = listarguments.begin();
238 iter != listarguments.end(); ++iter) {
239 const arguments_t &arguments = *iter;
240 ASSERT( arguments.size() == getSpecificArgumentCount(),
241 "FourBodyPotential_Torsion::parameter_derivative() - requires exactly three arguments.");
242 ASSERT( ParticleTypeChecker::checkArgumentsAgainstParticleTypes(
243 arguments, getParticleTypes()),
244 "FourBodyPotential_Torsion::operator() - types don't match with ones in arguments.");
245 const argument_t &r_ij = arguments[0]; // 01
246 const argument_t &r_ik = arguments[1]; // 02
247 const argument_t &r_il = arguments[2]; // 03
248 const argument_t &r_jk = arguments[3]; // 12
249 const argument_t &r_jl = arguments[4]; // 13
250 const argument_t &r_kl = arguments[5]; // 23
251 switch (index) {
252 case spring_constant:
253 {
254 result +=
255 Helpers::pow( function_theta(r_ij.distance, r_ik.distance, r_il.distance, r_jk.distance, r_jl.distance, r_kl.distance) - params[equilibrium_distance], 2 );
256 break;
257 }
258 case equilibrium_distance:
259 {
260 result +=
261 -2. * params[spring_constant]
262 * ( function_theta(r_ij.distance, r_ik.distance, r_il.distance, r_jk.distance, r_jl.distance, r_kl.distance) - params[equilibrium_distance]);
263 break;
264 }
265 default:
266 ASSERT(0, "FourBodyPotential_Torsion::parameter_derivative() - derivative to unknown parameter desired.");
267 break;
268 }
269 }
270 return results_t(1, result);
271}
272
273FunctionModel::filter_t
274FourBodyPotential_Torsion::getSpecificFilter() const
275{
276 FunctionModel::filter_t returnfunction =
277 boost::bind(&Extractors::reorderArgumentsByParticleTypes,
278 boost::bind(&Extractors::filterArgumentsByParticleTypes,
279 _2, _1,
280 boost::cref(getParticleTypes()), boost::cref(getBindingModel())),
281 _1,
282 boost::cref(getParticleTypes()), boost::cref(getBindingModel())
283 );
284 return returnfunction;
285}
286
287void
288FourBodyPotential_Torsion::setParametersToRandomInitialValues(
289 const TrainingData &data)
290{
291 RandomNumberGenerator &random = RandomNumberGeneratorFactory::getInstance().makeRandomNumberGenerator();
292 const double rng_min = random.min();
293 const double rng_max = random.max();
294 params[FourBodyPotential_Torsion::spring_constant] = 2.*(random()/(rng_max-rng_min));
295 params[FourBodyPotential_Torsion::equilibrium_distance] = 2.*(random()/(rng_max-rng_min));
296}
297
Note: See TracBrowser for help on using the repository browser.