source: src/Potentials/Specifics/ManyBodyPotential_Tersoff.cpp@ 752dc7

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

FIX: Made R and S also fixed parameters, this is in accordance with [Malshe].

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