source: src/Potentials/Specifics/ManyBodyPotential_Tersoff.cpp@ 990a62

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

FIX: Tersoff parameters lambda3, alpha, chi, and omega are now fixed.

  • for this we needed to exclude them from params. This is the cleanest way as suggested in levmar FAQ Q20.
  • Property mode set to 100644
File size: 11.2 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 * ManyBodyPotential_Tersoff.cpp
26 *
27 * Created on: Sep 26, 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 "ManyBodyPotential_Tersoff.hpp"
40
41#include <boost/bind.hpp>
42#include <cmath>
43
44#include "CodePatterns/Assert.hpp"
45//#include "CodePatterns/Info.hpp"
46
47#include "Potentials/helpers.hpp"
48
49ManyBodyPotential_Tersoff::ManyBodyPotential_Tersoff(
50 boost::function< std::vector<arguments_t>(const argument_t &, const double)> &_triplefunction
51 ) :
52 params(parameters_t(MAXPARAMS, 0.)),
53 lambda3(0.),
54 alpha(0.),
55 chi(1.),
56 omega(1.),
57 triplefunction(_triplefunction)
58{}
59
60ManyBodyPotential_Tersoff::ManyBodyPotential_Tersoff(
61 const double &_R,
62 const double &_S,
63 const double &_A,
64 const double &_B,
65 const double &_lambda,
66 const double &_mu,
67 const double &_lambda3,
68 const double &_alpha,
69 const double &_beta,
70 const double &_chi,
71 const double &_omega,
72 const double &_n,
73 const double &_c,
74 const double &_d,
75 const double &_h,
76 boost::function< std::vector<arguments_t>(const argument_t &, const double)> &_triplefunction) :
77 params(parameters_t(MAXPARAMS, 0.)),
78 lambda3(_lambda3),
79 alpha(_alpha),
80 chi(_chi),
81 omega(_mu),
82 triplefunction(_triplefunction)
83{
84// Info info(__func__);
85 params[R] = _R;
86 params[S] = _S;
87 params[A] = _A;
88 params[B] = _B;
89 params[lambda] = _lambda;
90 params[mu] = _mu;
91// lambda3 = _lambda3;
92// alpha = _alpha;
93 params[beta] = _beta;
94// chi = _chi;
95// omega = _omega;
96 params[n] = _n;
97 params[c] = _c;
98 params[d] = _d;
99 params[h] = _h;
100}
101
102ManyBodyPotential_Tersoff::results_t
103ManyBodyPotential_Tersoff::operator()(
104 const arguments_t &arguments
105 ) const
106{
107// Info info(__func__);
108 const argument_t &r_ij = arguments[0];
109 const double cutoff = function_cutoff(r_ij.distance);
110 const double result = (cutoff == 0.) ?
111 0. :
112 cutoff * (
113 function_prefactor(
114 alpha,
115 function_eta(r_ij))
116 * function_smoother(
117 params[A],
118 params[lambda],
119 r_ij.distance)
120 +
121 function_prefactor(
122 params[beta],
123 function_zeta(r_ij))
124 * function_smoother(
125 -params[B],
126 params[mu],
127 r_ij.distance)
128 );
129// LOG(2, "DEBUG: operator()(" << r_ij.distance << ") = " << result);
130 return std::vector<result_t>(1, result);
131}
132
133ManyBodyPotential_Tersoff::derivative_components_t
134ManyBodyPotential_Tersoff::derivative(
135 const arguments_t &arguments
136 ) const
137{
138// Info info(__func__);
139 return ManyBodyPotential_Tersoff::derivative_components_t();
140}
141
142ManyBodyPotential_Tersoff::results_t
143ManyBodyPotential_Tersoff::parameter_derivative(
144 const arguments_t &arguments,
145 const size_t index
146 ) const
147{
148// Info info(__func__);
149// ASSERT( arguments.size() == 1,
150// "PairPotential_Harmonic::parameter_derivative() - requires exactly one argument.");
151 const argument_t &r_ij = arguments[0];
152 switch (index) {
153 case R:
154 {
155 const double result = 0.;
156 return results_t(1, result);
157 break;
158 }
159 case S:
160 {
161 const double result = 0.;
162 return results_t(1, result);
163 break;
164 }
165 case A:
166 {
167 const double result = 0.;
168 return results_t(1, result);
169 break;
170 }
171 case B:
172 {
173 const double result = 0.;
174 return results_t(1, result);
175 break;
176 }
177 case lambda:
178 {
179 const double cutoff = function_cutoff(r_ij.distance);
180 const double result = (cutoff == 0.) ?
181 0. :
182 -r_ij.distance * cutoff * params[lambda] * (
183 function_prefactor(
184 alpha,
185 function_eta(r_ij))
186 * function_smoother(
187 params[A],
188 params[lambda],
189 r_ij.distance)
190 );
191 return results_t(1, result);
192 break;
193 }
194 case mu:
195 {
196 const double cutoff = function_cutoff(r_ij.distance);
197 const double result = (cutoff == 0.) ?
198 0. :
199 -r_ij.distance * cutoff * params[mu] *(
200 function_prefactor(
201 params[beta],
202 function_zeta(r_ij))
203 * function_smoother(
204 -params[B],
205 params[mu],
206 r_ij.distance)
207 );
208 return results_t(1, result);
209 break;
210 }
211// case lambda3:
212// {
213// const double result = 0.;
214// return results_t(1, result);
215// break;
216// }
217// case alpha:
218// {
219// const double temp =
220// pow(alpha*function_eta(r_ij), params[n]);
221// const double cutoff = function_cutoff(r_ij.distance);
222// const double result = (cutoff == 0.) || (alpha == 0. )?
223// 0. :
224// function_smoother(
225// -params[A],
226// params[lambda],
227// r_ij.distance)
228// * (-.5) * alpha * (temp/alpha)
229// / (1. + temp)
230// ;
231// return results_t(1, result);
232// break;
233// }
234// case chi:
235// {
236// const double result = 0.;
237// return results_t(1, result);
238// break;
239// }
240// case omega:
241// {
242// const double result = 0.;
243// return results_t(1, result);
244// break;
245// }
246 case beta:
247 {
248 const double temp =
249 pow(params[beta]*function_zeta(r_ij), params[n]);
250 const double cutoff = function_cutoff(r_ij.distance);
251 const double result = (cutoff == 0.) || (params[beta] == 0. )?
252 0. : cutoff *
253 function_smoother(
254 -params[B],
255 params[mu],
256 r_ij.distance)
257 * (-.5) * params[beta] * (temp/params[beta])
258 / (1. + temp)
259 ;
260 return results_t(1, result);
261 break;
262 }
263 case n:
264 {
265 const double temp =
266 pow(params[beta]*function_zeta(r_ij), params[n]);
267 const double cutoff = function_cutoff(r_ij.distance);
268 const double result = (cutoff == 0.) ?
269 0. : cutoff *
270 function_smoother(
271 -params[B],
272 params[mu],
273 r_ij.distance)
274 * params[B]
275 * ( log(1.+temp)/(params[n]*params[n]) - temp
276 * (log(function_zeta(r_ij)) + log(params[beta]))
277 /(params[n]*(1.+temp)))
278 ;
279 return results_t(1, result);
280 break;
281 }
282 case c:
283 {
284 const double result = 0.;
285 return results_t(1, result);
286 break;
287 }
288 case d:
289 {
290 const double result = 0.;
291 return results_t(1, result);
292 break;
293 }
294 case h:
295 {
296 const double result = 0.;
297 return results_t(1, result);
298 break;
299 }
300 default:
301 break;
302 }
303 return results_t(1, 0.);
304}
305
306ManyBodyPotential_Tersoff::result_t
307ManyBodyPotential_Tersoff::function_cutoff(
308 const double &distance
309 ) const
310{
311// Info info(__func__);
312 double result = 0.;
313 if (distance < params[R])
314 result = 1.;
315 else if (distance > params[S])
316 result = 0.;
317 else {
318 result = (0.5 + 0.5 * cos( M_PI * (distance - params[R])/(params[S]-params[R])));
319 }
320// LOG(2, "DEBUG: function_cutoff(" << distance << ") = " << result);
321 return result;
322}
323
324ManyBodyPotential_Tersoff::result_t
325ManyBodyPotential_Tersoff::function_prefactor(
326 const double &alpha,
327 const double &eta
328 ) const
329{
330// Info info(__func__);
331 const double result = chi * pow(
332 (1. + pow(alpha * eta, params[n])),
333 -1./(2.*params[n]));
334// LOG(2, "DEBUG: function_prefactor(" << alpha << "," << eta << ") = " << result);
335 return result;
336}
337
338ManyBodyPotential_Tersoff::result_t
339ManyBodyPotential_Tersoff::function_smoother(
340 const double &prefactor,
341 const double &lambda,
342 const double &distance
343 ) const
344{
345// Info info(__func__);
346 const double result = prefactor * exp(-lambda * distance);
347// LOG(2, "DEBUG: function_smoother(" << prefactor << "," << lambda << "," << distance << ") = " << result);
348 return result;
349}
350
351ManyBodyPotential_Tersoff::result_t
352ManyBodyPotential_Tersoff::function_eta(
353 const argument_t &r_ij
354 ) const
355{
356// Info info(__func__);
357 result_t result = 0.;
358
359 // get all triples within the cutoff
360 std::vector<arguments_t> triples = triplefunction(r_ij, params[S]);
361 for (std::vector<arguments_t>::const_iterator iter = triples.begin();
362 iter != triples.end(); ++iter) {
363 ASSERT( iter->size() == 2,
364 "ManyBodyPotential_Tersoff::function_zeta() - the triples result must contain of exactly two distances.");
365 const argument_t &r_ik = (*iter)[0];
366 result += function_cutoff(r_ik.distance)
367 * exp( Helpers::pow(lambda3 * (r_ij.distance - r_ik.distance) ,3));
368 }
369
370// LOG(2, "DEBUG: function_eta(" << r_ij.distance << ") = " << result);
371 return result;
372}
373
374ManyBodyPotential_Tersoff::result_t
375ManyBodyPotential_Tersoff::function_zeta(
376 const argument_t &r_ij
377 ) const
378{
379// Info info(__func__);
380 result_t result = 0.;
381
382 // get all triples within the cutoff
383 std::vector<arguments_t> triples = triplefunction(r_ij, params[S]);
384 for (std::vector<arguments_t>::const_iterator iter = triples.begin();
385 iter != triples.end(); ++iter) {
386 ASSERT( iter->size() == 2,
387 "ManyBodyPotential_Tersoff::function_zeta() - the triples result must contain exactly two distances.");
388 const argument_t &r_ik = (*iter)[0];
389 const argument_t &r_jk = (*iter)[1];
390 result +=
391 function_cutoff(r_ik.distance)
392 * omega
393 * function_angle(r_ij.distance, r_ik.distance, r_jk.distance)
394 * exp( Helpers::pow(lambda3 * (r_ij.distance - r_ik.distance) ,3));
395 }
396
397// LOG(2, "DEBUG: function_zeta(" << r_ij.distance << ") = " << result);
398 return result;
399}
400
401ManyBodyPotential_Tersoff::result_t
402ManyBodyPotential_Tersoff::function_angle(
403 const double &r_ij,
404 const double &r_ik,
405 const double &r_jk
406 ) const
407{
408// Info info(__func__);
409 const double angle = Helpers::pow(r_ij,2) + Helpers::pow(r_ik,2) - Helpers::pow(r_jk,2);
410 const double divisor = 2.* r_ij * r_ik;
411// LOG(2, "DEBUG: cos(theta)= " << angle/divisor);
412 if (divisor != 0.) {
413 const double result =
414 1.
415 + (Helpers::pow(params[c]/params[d], 2))
416 - Helpers::pow(params[c], 2)/(Helpers::pow(params[d], 2) +
417 Helpers::pow(params[h] - angle/divisor,2));
418
419// LOG(2, "DEBUG: function_angle(" << r_ij << "," << r_ik << "," << r_jk << ") = " << result);
420 return result;
421 } else
422 return 0.;
423}
424
Note: See TracBrowser for help on using the repository browser.