source: src/Potentials/Specifics/SaturationPotential.cpp@ 1f3b2a

Action_Thermostats Add_AtomRandomPerturbation Add_FitFragmentPartialChargesAction Add_RotateAroundBondAction Add_SelectAtomByNameAction Added_ParseSaveFragmentResults AddingActions_SaveParseParticleParameters Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_ParticleName_to_Atom Adding_StructOpt_integration_tests AtomFragments Automaking_mpqc_open AutomationFragmentation_failures Candidate_v1.5.4 Candidate_v1.6.0 Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator CombiningParticlePotentialParsing 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_BoundInBox_CenterInBox_MoleculeActions Fix_ChargeSampling_PBC Fix_ChronosMutex Fix_FitPartialCharges Fix_FitPotential_needs_atomicnumbers Fix_ForceAnnealing Fix_IndependentFragmentGrids Fix_ParseParticles Fix_ParseParticles_split_forward_backward_Actions Fix_PopActions Fix_QtFragmentList_sorted_selection Fix_Restrictedkeyset_FragmentMolecule Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns Fix_fitting_potentials Fixes ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion FragmentAction_writes_AtomFragments FragmentMolecule_checks_bonddegrees GeometryObjects Gui_Fixes Gui_displays_atomic_force_velocity ImplicitCharges IndependentFragmentGrids IndependentFragmentGrids_IndividualZeroInstances IndependentFragmentGrids_IntegrationTest IndependentFragmentGrids_Sole_NN_Calculation JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix MoreRobust_FragmentAutomation ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PdbParser_setsAtomName PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks Rewrite_FitPartialCharges RotateToPrincipalAxisSystem_UndoRedo SaturateAtoms_findBestMatching SaturateAtoms_singleDegree StoppableMakroAction Subpackage_CodePatterns Subpackage_JobMarket Subpackage_LinearAlgebra Subpackage_levmar Subpackage_mpqc_open Subpackage_vmg Switchable_LogView ThirdParty_MPQC_rebuilt_buildsystem TrajectoryDependenant_MaxOrder TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps TremoloParser_setsAtomName Ubuntu_1604_changes stable
Last change on this file since 1f3b2a was 2ba2ed, checked in by Frederik Heber <heber@…>, 12 years ago

FIX: SaturationPotential's parameter derivatives seem to be working now.

  • the problem seems to be the fitting itself is no good, maybe fitting Morse and Angle to CH4 at the same time just does not work ...
  • Property mode set to 100644
File size: 9.7 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2012 University of Bonn. 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 * SaturationPotential.cpp
26 *
27 * Created on: Oct 11, 2012
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 "SaturationPotential.hpp"
40
41#include "CodePatterns/Assert.hpp"
42#include "CodePatterns/Log.hpp"
43
44#include "Potentials/helpers.hpp"
45
46SaturationPotential::SaturationPotential(
47 const double _saturation_cutoff,
48 boost::function< std::vector<arguments_t>(const argument_t &, const double)> &_triplefunction) :
49 energy_offset(0.),
50 triplefunction(_triplefunction),
51 saturation_cutoff(_saturation_cutoff)
52{}
53
54SaturationPotential::SaturationPotential(
55 const double _morse_spring_constant,
56 const double _morse_equilibrium_distance,
57 const double _morse_dissociation_energy,
58 const double _angle_spring_constant,
59 const double _angle_equilibrium_distance,
60 const double _all_energy_offset,
61 const double _saturation_cutoff,
62 boost::function< std::vector<arguments_t>(const argument_t &, const double)> &_triplefunction) :
63 energy_offset(_all_energy_offset),
64 triplefunction(_triplefunction),
65 saturation_cutoff(_saturation_cutoff)
66{
67 parameters_t morse_params(morse.getParameterDimension());
68 morse_params[PairPotential_Morse::spring_constant] = _morse_spring_constant;
69 morse_params[PairPotential_Morse::equilibrium_distance] = _morse_equilibrium_distance;
70 morse_params[PairPotential_Morse::dissociation_energy] = _morse_dissociation_energy;
71 morse_params[PairPotential_Morse::energy_offset] = 0.;
72 morse.setParameters(morse_params);
73 parameters_t angle_params(angle.getParameterDimension());
74 angle_params[PairPotential_Angle::spring_constant] = _angle_spring_constant;
75 angle_params[PairPotential_Angle::equilibrium_distance] = _angle_equilibrium_distance;
76 angle_params[PairPotential_Angle::energy_offset] = 0.;
77 angle.setParameters(angle_params);
78}
79
80void SaturationPotential::setParameters(const parameters_t &_params)
81{
82 const size_t paramsDim = _params.size();
83 ASSERT( paramsDim <= getParameterDimension(),
84 "SaturationPotential::setParameters() - we need not more than "
85 +toString(getParameterDimension())+" parameters.");
86// LOG(1, "INFO: Setting new SaturationPotential params: " << _params);
87
88
89 // offsets
90 if (paramsDim > all_energy_offset)
91 energy_offset = _params[all_energy_offset];
92
93 // Morse
94 {
95 parameters_t morse_params(morse.getParameters());
96 if (paramsDim > morse_spring_constant)
97 morse_params[PairPotential_Morse::spring_constant] = _params[morse_spring_constant];
98 if (paramsDim > morse_equilibrium_distance)
99 morse_params[PairPotential_Morse::equilibrium_distance] = _params[morse_equilibrium_distance];
100 if (paramsDim > morse_dissociation_energy)
101 morse_params[PairPotential_Morse::dissociation_energy] = _params[morse_dissociation_energy];
102 morse_params[PairPotential_Morse::energy_offset] = 0.;
103 morse.setParameters(morse_params);
104 }
105
106 // Angle
107 {
108 parameters_t angle_params(angle.getParameters());
109 if (paramsDim > angle_spring_constant)
110 angle_params[PairPotential_Angle::spring_constant] = _params[angle_spring_constant];
111 if (paramsDim > angle_equilibrium_distance)
112 angle_params[PairPotential_Angle::equilibrium_distance] = _params[angle_equilibrium_distance];
113 angle_params[PairPotential_Angle::energy_offset] = 0.;
114 angle.setParameters(angle_params);
115 }
116#ifndef NDEBUG
117 parameters_t check_params(getParameters());
118 check_params.resize(paramsDim); // truncate to same size
119 ASSERT( check_params == _params,
120 "SaturationPotential::setParameters() - failed, mismatch in to be set "
121 +toString(_params)+" and set "+toString(check_params)+" params.");
122#endif
123}
124
125SaturationPotential::parameters_t SaturationPotential::getParameters() const
126{
127 parameters_t params(getParameterDimension());
128 const parameters_t morse_params = morse.getParameters();
129 const parameters_t angle_params = angle.getParameters();
130
131 params[all_energy_offset] = energy_offset;
132
133 params[morse_spring_constant] = morse_params[PairPotential_Morse::spring_constant];
134 params[morse_equilibrium_distance] = morse_params[PairPotential_Morse::equilibrium_distance];
135 params[morse_dissociation_energy] = morse_params[PairPotential_Morse::dissociation_energy];
136
137 params[angle_spring_constant] = angle_params[PairPotential_Angle::spring_constant];
138 params[angle_equilibrium_distance] = angle_params[PairPotential_Angle::equilibrium_distance];
139 return params;
140}
141
142SaturationPotential::results_t
143SaturationPotential::operator()(
144 const arguments_t &arguments
145 ) const
146{
147 double result = 0.;
148 for(arguments_t::const_iterator argiter = arguments.begin();
149 argiter != arguments.end();
150 ++argiter) {
151 const argument_t &r_ij = *argiter;
152 if ((r_ij.indices.first == 0)) { // first item must be the non-hydrogen
153 arguments_t args(1, r_ij);
154
155 // Morse contribution
156 result += morse(args)[0];
157 if (result != result)
158 ELOG(1, "result is NAN.");
159
160 // Angle contribution
161 std::vector<arguments_t> triples = triplefunction(r_ij, saturation_cutoff);
162 args.resize(3, r_ij);
163 for (std::vector<arguments_t>::const_iterator iter = triples.begin();
164 iter != triples.end(); ++iter) {
165 ASSERT( iter->size() == 2,
166 "SaturationPotential::function_derivative_c() - the triples result must contain exactly two distances.");
167 const argument_t &r_ik = (*iter)[0];
168 const argument_t &r_jk = (*iter)[1];
169 args[1] = r_ik;
170 args[2] = r_jk;
171 result += .5*angle(args)[0]; // as we have all distances we get both jk and kj
172 if (result != result)
173 ELOG(1, "result is NAN.");
174 }
175 }
176 }
177 return std::vector<result_t>(1, energy_offset + result);
178}
179
180SaturationPotential::derivative_components_t
181SaturationPotential::derivative(
182 const arguments_t &arguments
183 ) const
184{
185 ASSERT( 0,
186 "SaturationPotential::operator() - not implemented.");
187 derivative_components_t result;
188 return result;
189}
190
191SaturationPotential::results_t
192SaturationPotential::parameter_derivative(
193 const arguments_t &arguments,
194 const size_t index
195 ) const
196{
197 double result = 0.;
198 if (index == all_energy_offset) {
199 result = 1.;
200 } else {
201 for(arguments_t::const_iterator argiter = arguments.begin();
202 argiter != arguments.end();
203 ++argiter) {
204 const argument_t &r_ij = *argiter;
205 if ((r_ij.indices.first == 0)) { // first item must be the non-hydrogen
206 arguments_t args(1, r_ij);
207 switch (index) {
208 case morse_spring_constant:
209 {
210 result += morse.parameter_derivative(args, PairPotential_Morse::spring_constant)[0];
211 break;
212 }
213 case morse_equilibrium_distance:
214 {
215 result += morse.parameter_derivative(args, PairPotential_Morse::equilibrium_distance)[0];
216 break;
217 }
218 case morse_dissociation_energy:
219 {
220 result += morse.parameter_derivative(args, PairPotential_Morse::dissociation_energy)[0];
221 break;
222 }
223 default:
224 {
225 args.resize(3, r_ij);
226 std::vector<arguments_t> triples = triplefunction(r_ij, saturation_cutoff);
227 for (std::vector<arguments_t>::const_iterator iter = triples.begin();
228 iter != triples.end(); ++iter) {
229 ASSERT( iter->size() == 2,
230 "SaturationPotential::parameter_derivative() - the triples result must contain exactly two distances.");
231 const argument_t &r_ik = (*iter)[0];
232 ASSERT( r_ik.indices.first == r_ij.indices.first,
233 "SaturationPotential::parameter_derivative() - i not same in ij, ik.");
234 const argument_t &r_jk = (*iter)[1];
235 ASSERT( r_jk.indices.first == r_ij.indices.second,
236 "SaturationPotential::parameter_derivative() - j not same in ij, jk.");
237 ASSERT( r_ik.indices.second == r_jk.indices.second,
238 "SaturationPotential::parameter_derivative() - k not same in ik, jk.");
239 args[1] = r_ik;
240 args[2] = r_jk;
241 switch (index) { // .5 due to we have all distances we get both jk and kj
242 case angle_spring_constant:
243 {
244 result += .5*angle.parameter_derivative(args, PairPotential_Angle::spring_constant)[0];
245 break;
246 }
247 case angle_equilibrium_distance:
248 {
249 result += .5*angle.parameter_derivative(args, PairPotential_Angle::equilibrium_distance)[0];
250 break;
251 }
252 default:
253 break;
254 }
255 }
256 break;
257 }
258 }
259 }
260 }
261 }
262 return SaturationPotential::results_t(1, result);
263}
Note: See TracBrowser for help on using the repository browser.