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

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

Extractors require additionally the binding graph of the fragment itself.

  • this is used in ::filterArguments..(), ::reorderArguments(), and CompountPotential::splitUpArgumentsByModelsFilter().
  • Property mode set to 100644
File size: 11.1 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 HomologyGraph generateBindingModel(const EmpiricalPotential::ParticleTypes_t &_ParticleTypes)
69{
70 // fill nodes
71 HomologyGraph::nodes_t nodes;
72 {
73 ASSERT( _ParticleTypes.size() == (size_t)4,
74 "generateBindingModel() - FourBodyPotential_Torsion needs four types.");
75 std::pair<HomologyGraph::nodes_t::iterator, bool > inserter;
76 inserter = nodes.insert( std::make_pair(FragmentNode(_ParticleTypes[0], 1), 1) );
77 if (!inserter.second)
78 ++(inserter.first->second);
79 inserter = nodes.insert( std::make_pair(FragmentNode(_ParticleTypes[1], 2), 1) );
80 if (!inserter.second)
81 ++(inserter.first->second);
82 inserter = nodes.insert( std::make_pair(FragmentNode(_ParticleTypes[2], 2), 1) );
83 if (!inserter.second)
84 ++(inserter.first->second);
85 inserter = nodes.insert( std::make_pair(FragmentNode(_ParticleTypes[3], 1), 1) );
86 if (!inserter.second)
87 ++(inserter.first->second);
88 }
89
90 // there are no edges
91 HomologyGraph::edges_t edges;
92 {
93 std::pair<HomologyGraph::edges_t::iterator, bool > inserter;
94 inserter = edges.insert( std::make_pair( FragmentEdge(_ParticleTypes[0], _ParticleTypes[1]), 1) );
95 if (!inserter.second)
96 ++(inserter.first->second);
97 inserter = edges.insert( std::make_pair( FragmentEdge(_ParticleTypes[1], _ParticleTypes[2]), 1) );
98 if (!inserter.second)
99 ++(inserter.first->second);
100 inserter = edges.insert( std::make_pair( FragmentEdge(_ParticleTypes[2], _ParticleTypes[3]), 1) );
101 if (!inserter.second)
102 ++(inserter.first->second);
103 }
104
105 return HomologyGraph(nodes, edges);
106}
107
108FourBodyPotential_Torsion::FourBodyPotential_Torsion() :
109 EmpiricalPotential(),
110 params(parameters_t(MAXPARAMS, 0.)),
111 bindingmodel(HomologyGraph())
112{
113 // have some decent defaults for parameter_derivative checking
114 params[spring_constant] = 1.;
115 params[equilibrium_distance] = 0.1;
116}
117
118FourBodyPotential_Torsion::FourBodyPotential_Torsion(
119 const ParticleTypes_t &_ParticleTypes
120 ) :
121 EmpiricalPotential(_ParticleTypes),
122 params(parameters_t(MAXPARAMS, 0.)),
123 bindingmodel(generateBindingModel(_ParticleTypes))
124{
125 // have some decent defaults for parameter_derivative checking
126 params[spring_constant] = 1.;
127 params[equilibrium_distance] = 0.1;
128}
129
130FourBodyPotential_Torsion::FourBodyPotential_Torsion(
131 const ParticleTypes_t &_ParticleTypes,
132 const double _spring_constant,
133 const double _equilibrium_distance) :
134 EmpiricalPotential(_ParticleTypes),
135 params(parameters_t(MAXPARAMS, 0.)),
136 bindingmodel(generateBindingModel(_ParticleTypes))
137{
138 params[spring_constant] = _spring_constant;
139 params[equilibrium_distance] = _equilibrium_distance;
140}
141
142void FourBodyPotential_Torsion::setParameters(const parameters_t &_params)
143{
144 const size_t paramsDim = _params.size();
145 ASSERT( paramsDim <= getParameterDimension(),
146 "FourBodyPotential_Torsion::setParameters() - we need not more than "
147 +toString(getParameterDimension())+" parameters.");
148 for(size_t i=0;i<paramsDim;++i)
149 params[i] = _params[i];
150
151#ifndef NDEBUG
152 parameters_t check_params(getParameters());
153 check_params.resize(paramsDim); // truncate to same size
154 ASSERT( check_params == _params,
155 "FourBodyPotential_Torsion::setParameters() - failed, mismatch in to be set "
156 +toString(_params)+" and set "+toString(check_params)+" params.");
157#endif
158}
159
160FourBodyPotential_Torsion::result_t
161FourBodyPotential_Torsion::function_theta(
162 const double &r_ij,
163 const double &r_ik,
164 const double &r_il,
165 const double &r_jk,
166 const double &r_jl,
167 const double &r_kl
168 ) const
169{
170// Info info(__func__);
171 const double h_1 = .5*sqrt(2.*(Helpers::pow(r_ij,2)+Helpers::pow(r_ik,2))-Helpers::pow(r_jk,2));
172 const double h_2 = .5*sqrt(2.*(Helpers::pow(r_jl,2)+Helpers::pow(r_kl,2))-Helpers::pow(r_jk,2));
173 const double angle = Helpers::pow(h_1,2) + Helpers::pow(h_2,2) - Helpers::pow(r_il,2);
174 const double divisor = 2.* h_1 * h_2;
175
176// LOG(2, "DEBUG: cos(theta)= " << angle/divisor);
177 if (divisor == 0.)
178 return 0.;
179 else
180 return angle/divisor;
181}
182
183FourBodyPotential_Torsion::results_t
184FourBodyPotential_Torsion::operator()(
185 const list_of_arguments_t &listarguments
186 ) const
187{
188 result_t result = 0.;
189 for(list_of_arguments_t::const_iterator iter = listarguments.begin();
190 iter != listarguments.end(); ++iter) {
191 const arguments_t &arguments = *iter;
192 ASSERT( arguments.size() == getSpecificArgumentCount(),
193 "FourBodyPotential_Torsion::operator() - requires exactly three arguments.");
194 ASSERT( ParticleTypeChecker::checkArgumentsAgainstParticleTypes(
195 arguments, getParticleTypes()),
196 "FourBodyPotential_Torsion::operator() - types don't match with ones in arguments.");
197 const argument_t &r_ij = arguments[0]; // 01
198 const argument_t &r_ik = arguments[1]; // 02
199 const argument_t &r_il = arguments[2]; // 03
200 const argument_t &r_jk = arguments[3]; // 12
201 const argument_t &r_jl = arguments[4]; // 13
202 const argument_t &r_kl = arguments[5]; // 23
203 result +=
204 params[spring_constant]
205 * Helpers::pow( function_theta(r_ij.distance, r_ik.distance, r_il.distance, r_jk.distance, r_jl.distance, r_kl.distance)
206 - params[equilibrium_distance], 2 );
207 }
208 return results_t(1, result);
209}
210
211FourBodyPotential_Torsion::derivative_components_t
212FourBodyPotential_Torsion::derivative(
213 const list_of_arguments_t &listarguments
214 ) const
215{
216 result_t result = 0.;
217 for(list_of_arguments_t::const_iterator iter = listarguments.begin();
218 iter != listarguments.end(); ++iter) {
219 const arguments_t &arguments = *iter;
220 ASSERT( arguments.size() == getSpecificArgumentCount(),
221 "FourBodyPotential_Torsion::operator() - requires exactly three arguments.");
222 ASSERT( ParticleTypeChecker::checkArgumentsAgainstParticleTypes(
223 arguments, getParticleTypes()),
224 "FourBodyPotential_Torsion::operator() - types don't match with ones in arguments.");
225 const argument_t &r_ij = arguments[0]; // 01
226 const argument_t &r_ik = arguments[1]; // 02
227 const argument_t &r_il = arguments[2]; // 03
228 const argument_t &r_jk = arguments[3]; // 12
229 const argument_t &r_jl = arguments[4]; // 13
230 const argument_t &r_kl = arguments[5]; // 23
231 result +=
232 2. * params[spring_constant] *
233 ( function_theta(r_ij.distance, r_ik.distance, r_il.distance, r_jk.distance, r_jl.distance, r_kl.distance)
234 - params[equilibrium_distance]);
235 }
236 return derivative_components_t(1, result);
237}
238
239FourBodyPotential_Torsion::results_t
240FourBodyPotential_Torsion::parameter_derivative(
241 const list_of_arguments_t &listarguments,
242 const size_t index
243 ) const
244{
245 result_t result = 0.;
246 for(list_of_arguments_t::const_iterator iter = listarguments.begin();
247 iter != listarguments.end(); ++iter) {
248 const arguments_t &arguments = *iter;
249 ASSERT( arguments.size() == getSpecificArgumentCount(),
250 "FourBodyPotential_Torsion::parameter_derivative() - requires exactly three arguments.");
251 ASSERT( ParticleTypeChecker::checkArgumentsAgainstParticleTypes(
252 arguments, getParticleTypes()),
253 "FourBodyPotential_Torsion::operator() - types don't match with ones in arguments.");
254 const argument_t &r_ij = arguments[0]; // 01
255 const argument_t &r_ik = arguments[1]; // 02
256 const argument_t &r_il = arguments[2]; // 03
257 const argument_t &r_jk = arguments[3]; // 12
258 const argument_t &r_jl = arguments[4]; // 13
259 const argument_t &r_kl = arguments[5]; // 23
260 switch (index) {
261 case spring_constant:
262 {
263 result +=
264 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 );
265 break;
266 }
267 case equilibrium_distance:
268 {
269 result +=
270 -2. * params[spring_constant]
271 * ( function_theta(r_ij.distance, r_ik.distance, r_il.distance, r_jk.distance, r_jl.distance, r_kl.distance) - params[equilibrium_distance]);
272 break;
273 }
274 default:
275 ASSERT(0, "FourBodyPotential_Torsion::parameter_derivative() - derivative to unknown parameter desired.");
276 break;
277 }
278 }
279 return results_t(1, result);
280}
281
282FunctionModel::filter_t
283FourBodyPotential_Torsion::getSpecificFilter() const
284{
285 FunctionModel::filter_t returnfunction =
286 boost::bind(&Extractors::reorderArgumentsByParticleTypes,
287 boost::bind(&Extractors::filterArgumentsByParticleTypes,
288 _2, _1,
289 boost::cref(getParticleTypes()), boost::cref(getBindingModel())),
290 _1,
291 boost::cref(getParticleTypes()), boost::cref(getBindingModel())
292 );
293 return returnfunction;
294}
295
296void
297FourBodyPotential_Torsion::setParametersToRandomInitialValues(
298 const TrainingData &data)
299{
300 RandomNumberGenerator &random = RandomNumberGeneratorFactory::getInstance().makeRandomNumberGenerator();
301 const double rng_min = random.min();
302 const double rng_max = random.max();
303 params[FourBodyPotential_Torsion::spring_constant] = 2.*(random()/(rng_max-rng_min));
304 params[FourBodyPotential_Torsion::equilibrium_distance] = 2.*(random()/(rng_max-rng_min));
305}
306
Note: See TracBrowser for help on using the repository browser.