source: src/Potentials/Specifics/PairPotential_Morse.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: 8.8 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 * PairPotential_Morse.cpp
27 *
28 * Created on: Oct 03, 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 "PairPotential_Morse.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 <cmath>
46#include <string>
47
48#include "CodePatterns/Assert.hpp"
49
50#include "FunctionApproximation/Extractors.hpp"
51#include "FunctionApproximation/TrainingData.hpp"
52#include "Potentials/helpers.hpp"
53#include "Potentials/InternalCoordinates/TwoBody_Length.hpp"
54#include "Potentials/ParticleTypeCheckers.hpp"
55#include "RandomNumbers/RandomNumberGeneratorFactory.hpp"
56#include "RandomNumbers/RandomNumberGenerator.hpp"
57
58class Fragment;
59
60// static definitions
61const PairPotential_Morse::ParameterNames_t
62PairPotential_Morse::ParameterNames =
63 boost::assign::list_of<std::string>
64 ("spring_constant")
65 ("equilibrium_distance")
66 ("dissociation_energy")
67 ;
68const std::string PairPotential_Morse::potential_token("morse");
69Coordinator::ptr PairPotential_Morse::coordinator(Memory::ignore(new TwoBody_Length()));
70static PotentialSubgraph generateSubgraph()
71{
72 return PotentialSubgraph();
73}
74const PotentialSubgraph PairPotential_Morse::subgraph(generateSubgraph());
75
76PairPotential_Morse::PairPotential_Morse() :
77 EmpiricalPotential(),
78 params(parameters_t(MAXPARAMS, 0.))
79{
80 // have some decent defaults for parameter_derivative checking
81 params[spring_constant] = 1.;
82 params[equilibrium_distance] = 1.;
83 params[dissociation_energy] = 0.1;
84}
85
86PairPotential_Morse::PairPotential_Morse(
87 const ParticleTypes_t &_ParticleTypes
88 ) :
89 EmpiricalPotential(_ParticleTypes),
90 params(parameters_t(MAXPARAMS, 0.))
91{
92 // have some decent defaults for parameter_derivative checking
93 params[spring_constant] = 1.;
94 params[equilibrium_distance] = 1.;
95 params[dissociation_energy] = 0.1;
96}
97
98PairPotential_Morse::PairPotential_Morse(
99 const ParticleTypes_t &_ParticleTypes,
100 const double _spring_constant,
101 const double _equilibrium_distance,
102 const double _dissociation_energy) :
103 EmpiricalPotential(_ParticleTypes),
104 params(parameters_t(MAXPARAMS, 0.))
105{
106 params[spring_constant] = _spring_constant;
107 params[equilibrium_distance] = _equilibrium_distance;
108 params[dissociation_energy] = _dissociation_energy;
109}
110
111void PairPotential_Morse::setParameters(const parameters_t &_params)
112{
113 const size_t paramsDim = _params.size();
114 ASSERT( paramsDim <= getParameterDimension(),
115 "PairPotential_Morse::setParameters() - we need not more than "
116 +toString(getParameterDimension())+" parameters.");
117 for(size_t i=0;i<paramsDim;++i)
118 params[i] = _params[i];
119
120#ifndef NDEBUG
121 parameters_t check_params(getParameters());
122 check_params.resize(paramsDim); // truncate to same size
123 ASSERT( check_params == _params,
124 "PairPotential_Morse::setParameters() - failed, mismatch in to be set "
125 +toString(_params)+" and set "+toString(check_params)+" params.");
126#endif
127}
128
129PairPotential_Morse::results_t
130PairPotential_Morse::operator()(
131 const list_of_arguments_t &listarguments
132 ) const
133{
134 result_t result = 0.;
135 for(list_of_arguments_t::const_iterator iter = listarguments.begin();
136 iter != listarguments.end(); ++iter) {
137 const arguments_t &arguments = *iter;
138 ASSERT( arguments.size() == 1,
139 "PairPotential_Morse::operator() - requires exactly one argument.");
140 ASSERT( ParticleTypeChecker::checkArgumentsAgainstParticleTypes(
141 arguments, getParticleTypes()),
142 "PairPotential_Morse::operator() - types don't match with ones in arguments.");
143 const argument_t &r_ij = arguments[0];
144 // Maple: f(r,D,k,R,c) := D * (1 - exp(-k*(r-R)))^(2)+c
145 result +=
146 params[dissociation_energy] * Helpers::pow( 1.
147 - exp( - params[spring_constant] * ( r_ij.distance - params[equilibrium_distance])),2);
148 }
149 return std::vector<result_t>(1, result);
150}
151
152PairPotential_Morse::derivative_components_t
153PairPotential_Morse::derivative(
154 const list_of_arguments_t &listarguments
155 ) const
156{
157 result_t result = 0.;
158 for(list_of_arguments_t::const_iterator iter = listarguments.begin();
159 iter != listarguments.end(); ++iter) {
160 const arguments_t &arguments = *iter;
161 ASSERT( arguments.size() == 1,
162 "PairPotential_Morse::operator() - requires exactly one argument.");
163 ASSERT( ParticleTypeChecker::checkArgumentsAgainstParticleTypes(
164 arguments, getParticleTypes()),
165 "PairPotential_Morse::operator() - types don't match with ones in arguments.");
166 const argument_t &r_ij = arguments[0];
167 // Maple result: 2*D*(1-exp(-k*(r-R)))*k*exp(-k*(r-R))
168 result +=
169 2. * params[dissociation_energy]
170 * ( 1. - exp( - params[spring_constant] * ( r_ij.distance - params[equilibrium_distance])))
171 * (- params[spring_constant]) * exp( - params[spring_constant] * ( r_ij.distance - params[equilibrium_distance]));
172 }
173 return derivative_components_t(1, result);
174}
175
176PairPotential_Morse::results_t
177PairPotential_Morse::parameter_derivative(
178 const list_of_arguments_t &listarguments,
179 const size_t index
180 ) const
181{
182 result_t result = 0.;
183 for(list_of_arguments_t::const_iterator iter = listarguments.begin();
184 iter != listarguments.end(); ++iter) {
185 const arguments_t &arguments = *iter;
186 ASSERT( arguments.size() == 1,
187 "PairPotential_Morse::parameter_derivative() - requires exactly one argument.");
188 ASSERT( ParticleTypeChecker::checkArgumentsAgainstParticleTypes(
189 arguments, getParticleTypes()),
190 "PairPotential_Morse::operator() - types don't match with ones in arguments.");
191 const argument_t &r_ij = arguments[0];
192 switch (index) {
193 case spring_constant:
194 {
195 // Maple result: -2*D*(1-exp(-k*(r-R)))*(-r+R)*exp(-k*(r-R))
196 result +=
197 - 2. * params[dissociation_energy]
198 * ( 1. - exp( - params[spring_constant] * ( r_ij.distance - params[equilibrium_distance])))
199 * (- r_ij.distance + params[equilibrium_distance])
200 * exp( - params[spring_constant] * ( r_ij.distance - params[equilibrium_distance]))
201 ;
202 break;
203 }
204 case equilibrium_distance:
205 {
206 // Maple result: -2*D*(1-exp(-k*(r-R)))*k*exp(-k*(r-R))
207 result +=
208 - 2. * params[dissociation_energy]
209 * ( 1. - exp( - params[spring_constant] * ( r_ij.distance - params[equilibrium_distance])))
210 * params[spring_constant] * exp( - params[spring_constant] * ( r_ij.distance - params[equilibrium_distance]))
211 ;
212 break;
213 }
214 case dissociation_energy:
215 {
216 // Maple result: (1-exp(-k*(r-R)))^2
217 result +=
218 Helpers::pow(1.
219 - exp( - params[spring_constant] * ( r_ij.distance - params[equilibrium_distance])),2);
220 break;
221 }
222 default:
223 ASSERT(0, "PairPotential_Morse::parameter_derivative() - derivative to unknown parameter desired.");
224 break;
225 }
226 }
227 return results_t(1, result);
228}
229
230FunctionModel::filter_t PairPotential_Morse::getSpecificFilter() const
231{
232 FunctionModel::filter_t returnfunction =
233 boost::bind(&Extractors::filterArgumentsByParticleTypes,
234 _1,
235 getParticleTypes(), getSubgraph());
236 return returnfunction;
237}
238
239void
240PairPotential_Morse::setParametersToRandomInitialValues(
241 const TrainingData &data)
242{
243 RandomNumberGenerator &random = RandomNumberGeneratorFactory::getInstance().makeRandomNumberGenerator();
244 const double rng_min = random.min();
245 const double rng_max = random.max();
246 params[PairPotential_Morse::dissociation_energy] = 1e+0*(random()/(rng_max-rng_min));// 0.5;
247 params[PairPotential_Morse::spring_constant] = 1e+0*(random()/(rng_max-rng_min));// 1.;
248 params[PairPotential_Morse::equilibrium_distance] = 3e+0*(random()/(rng_max-rng_min));//2.9;
249}
250
Note: See TracBrowser for help on using the repository browser.