source: src/Potentials/Specifics/FourBodyPotential_Torsion.cpp@ 91a3f7

Fix_FitPotential_needs_atomicnumbers
Last change on this file since 91a3f7 was 35760a, checked in by Frederik Heber <heber@…>, 9 years ago

tempcommit: Merge with b794f5e8

  • Property mode set to 100644
File size: 9.5 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()));
67static PotentialSubgraph generateSubgraph()
68{
69 return PotentialSubgraph();
70}
71const PotentialSubgraph FourBodyPotential_Torsion::subgraph(generateSubgraph());
72
73FourBodyPotential_Torsion::FourBodyPotential_Torsion() :
74 EmpiricalPotential(),
75 params(parameters_t(MAXPARAMS, 0.))
76{
77 // have some decent defaults for parameter_derivative checking
78 params[spring_constant] = 1.;
79 params[equilibrium_distance] = 0.1;
80}
81
82FourBodyPotential_Torsion::FourBodyPotential_Torsion(
83 const ParticleTypes_t &_ParticleTypes
84 ) :
85 EmpiricalPotential(_ParticleTypes),
86 params(parameters_t(MAXPARAMS, 0.))
87{
88 // have some decent defaults for parameter_derivative checking
89 params[spring_constant] = 1.;
90 params[equilibrium_distance] = 0.1;
91}
92
93FourBodyPotential_Torsion::FourBodyPotential_Torsion(
94 const ParticleTypes_t &_ParticleTypes,
95 const double _spring_constant,
96 const double _equilibrium_distance) :
97 EmpiricalPotential(_ParticleTypes),
98 params(parameters_t(MAXPARAMS, 0.))
99{
100 params[spring_constant] = _spring_constant;
101 params[equilibrium_distance] = _equilibrium_distance;
102}
103
104void FourBodyPotential_Torsion::setParameters(const parameters_t &_params)
105{
106 const size_t paramsDim = _params.size();
107 ASSERT( paramsDim <= getParameterDimension(),
108 "FourBodyPotential_Torsion::setParameters() - we need not more than "
109 +toString(getParameterDimension())+" parameters.");
110 for(size_t i=0;i<paramsDim;++i)
111 params[i] = _params[i];
112
113#ifndef NDEBUG
114 parameters_t check_params(getParameters());
115 check_params.resize(paramsDim); // truncate to same size
116 ASSERT( check_params == _params,
117 "FourBodyPotential_Torsion::setParameters() - failed, mismatch in to be set "
118 +toString(_params)+" and set "+toString(check_params)+" params.");
119#endif
120}
121
122FourBodyPotential_Torsion::result_t
123FourBodyPotential_Torsion::function_theta(
124 const double &r_ij,
125 const double &r_ik,
126 const double &r_il,
127 const double &r_jk,
128 const double &r_jl,
129 const double &r_kl
130 ) const
131{
132// Info info(__func__);
133 const double h_1 = .5*sqrt(2.*(Helpers::pow(r_ij,2)+Helpers::pow(r_ik,2))-Helpers::pow(r_jk,2));
134 const double h_2 = .5*sqrt(2.*(Helpers::pow(r_jl,2)+Helpers::pow(r_kl,2))-Helpers::pow(r_jk,2));
135 const double angle = Helpers::pow(h_1,2) + Helpers::pow(h_2,2) - Helpers::pow(r_il,2);
136 const double divisor = 2.* h_1 * h_2;
137
138// LOG(2, "DEBUG: cos(theta)= " << angle/divisor);
139 if (divisor == 0.)
140 return 0.;
141 else
142 return angle/divisor;
143}
144
145FourBodyPotential_Torsion::results_t
146FourBodyPotential_Torsion::operator()(
147 const list_of_arguments_t &listarguments
148 ) const
149{
150 result_t result = 0.;
151 for(list_of_arguments_t::const_iterator iter = listarguments.begin();
152 iter != listarguments.end(); ++iter) {
153 const arguments_t &arguments = *iter;
154 ASSERT( arguments.size() == getSpecificArgumentCount(),
155 "FourBodyPotential_Torsion::operator() - requires exactly three arguments.");
156 ASSERT( ParticleTypeChecker::checkArgumentsAgainstParticleTypes(
157 arguments, getParticleTypes()),
158 "FourBodyPotential_Torsion::operator() - types don't match with ones in arguments.");
159 const argument_t &r_ij = arguments[0]; // 01
160 const argument_t &r_ik = arguments[1]; // 02
161 const argument_t &r_il = arguments[2]; // 03
162 const argument_t &r_jk = arguments[3]; // 12
163 const argument_t &r_jl = arguments[4]; // 13
164 const argument_t &r_kl = arguments[5]; // 23
165 result +=
166 params[spring_constant]
167 * Helpers::pow( function_theta(r_ij.distance, r_ik.distance, r_il.distance, r_jk.distance, r_jl.distance, r_kl.distance)
168 - params[equilibrium_distance], 2 );
169 }
170 return results_t(1, result);
171}
172
173FourBodyPotential_Torsion::derivative_components_t
174FourBodyPotential_Torsion::derivative(
175 const list_of_arguments_t &listarguments
176 ) const
177{
178 result_t result = 0.;
179 for(list_of_arguments_t::const_iterator iter = listarguments.begin();
180 iter != listarguments.end(); ++iter) {
181 const arguments_t &arguments = *iter;
182 ASSERT( arguments.size() == getSpecificArgumentCount(),
183 "FourBodyPotential_Torsion::operator() - requires exactly three arguments.");
184 ASSERT( ParticleTypeChecker::checkArgumentsAgainstParticleTypes(
185 arguments, getParticleTypes()),
186 "FourBodyPotential_Torsion::operator() - types don't match with ones in arguments.");
187 const argument_t &r_ij = arguments[0]; // 01
188 const argument_t &r_ik = arguments[1]; // 02
189 const argument_t &r_il = arguments[2]; // 03
190 const argument_t &r_jk = arguments[3]; // 12
191 const argument_t &r_jl = arguments[4]; // 13
192 const argument_t &r_kl = arguments[5]; // 23
193 result +=
194 2. * params[spring_constant] *
195 ( function_theta(r_ij.distance, r_ik.distance, r_il.distance, r_jk.distance, r_jl.distance, r_kl.distance)
196 - params[equilibrium_distance]);
197 }
198 return derivative_components_t(1, result);
199}
200
201FourBodyPotential_Torsion::results_t
202FourBodyPotential_Torsion::parameter_derivative(
203 const list_of_arguments_t &listarguments,
204 const size_t index
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::parameter_derivative() - 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 switch (index) {
223 case spring_constant:
224 {
225 result +=
226 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 );
227 break;
228 }
229 case equilibrium_distance:
230 {
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) - params[equilibrium_distance]);
234 break;
235 }
236 default:
237 ASSERT(0, "FourBodyPotential_Torsion::parameter_derivative() - derivative to unknown parameter desired.");
238 break;
239 }
240 }
241 return results_t(1, result);
242}
243
244FunctionModel::filter_t
245FourBodyPotential_Torsion::getSpecificFilter() const
246{
247 FunctionModel::filter_t returnfunction =
248 boost::bind(&Extractors::reorderArgumentsByParticleTypes,
249 boost::bind(&Extractors::filterArgumentsByParticleTypes,
250 _1,
251 getParticleTypes(), getSubgraph()),
252 getParticleTypes(), getSubgraph()
253 );
254 return returnfunction;
255}
256
257void
258FourBodyPotential_Torsion::setParametersToRandomInitialValues(
259 const TrainingData &data)
260{
261 RandomNumberGenerator &random = RandomNumberGeneratorFactory::getInstance().makeRandomNumberGenerator();
262 const double rng_min = random.min();
263 const double rng_max = random.max();
264 params[FourBodyPotential_Torsion::spring_constant] = 2.*(random()/(rng_max-rng_min));
265 params[FourBodyPotential_Torsion::equilibrium_distance] = 2.*(random()/(rng_max-rng_min));
266}
Note: See TracBrowser for help on using the repository browser.