source: src/Potentials/Specifics/ManyBodyPotential_Tersoff.cpp@ b760bc3

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

Added ParticleTypeChecker functions in own namespace and added checks to every specific potential.

  • these check whether typesin argument_t matches with potential's ParticleTypes.
  • replaced row of Asserts with ParticleTypeChecker call in all specific potentials.
  • Property mode set to 100644
File size: 19.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 * 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/assign/list_of.hpp> // for 'map_list_of()'
42#include <boost/bind.hpp>
43#include <cmath>
44#include <string>
45
46#include "CodePatterns/Assert.hpp"
47//#include "CodePatterns/Info.hpp"
48#include "CodePatterns/Log.hpp"
49
50#include "Potentials/helpers.hpp"
51#include "Potentials/ParticleTypeCheckers.hpp"
52
53// static definitions
54const ManyBodyPotential_Tersoff::ParameterNames_t
55ManyBodyPotential_Tersoff::ParameterNames =
56 boost::assign::list_of<std::string>
57 ("A")
58 ("B")
59 ("lambda")
60 ("mu")
61 ("beta")
62 ("n")
63 ("c")
64 ("d")
65 ("h")
66 ("offset")
67// ("R")
68// ("S")
69// ("lambda3")
70// ("alpha")
71// ("chi")
72// ("omega")
73 ;
74const std::string ManyBodyPotential_Tersoff::potential_token("tersoff");
75
76ManyBodyPotential_Tersoff::ManyBodyPotential_Tersoff(
77 const ParticleTypes_t &_ParticleTypes,
78 boost::function< std::vector<arguments_t>(const argument_t &, const double)> &_triplefunction
79 ) :
80 SerializablePotential(_ParticleTypes),
81 params(parameters_t(MAXPARAMS, 0.)),
82 R(3.2),
83 S(3.5),
84 lambda3(0.),
85 alpha(0.),
86 chi(1.),
87 omega(1.),
88 triplefunction(_triplefunction)
89{}
90
91ManyBodyPotential_Tersoff::ManyBodyPotential_Tersoff(
92 const ParticleTypes_t &_ParticleTypes,
93 const double &_R,
94 const double &_S,
95 const double &_A,
96 const double &_B,
97 const double &_lambda,
98 const double &_mu,
99 const double &_lambda3,
100 const double &_alpha,
101 const double &_beta,
102 const double &_chi,
103 const double &_omega,
104 const double &_n,
105 const double &_c,
106 const double &_d,
107 const double &_h,
108 const double &_offset,
109 boost::function< std::vector<arguments_t>(const argument_t &, const double)> &_triplefunction) :
110 SerializablePotential(_ParticleTypes),
111 params(parameters_t(MAXPARAMS, 0.)),
112 R(_R),
113 S(_S),
114 lambda3(_lambda3),
115 alpha(_alpha),
116 chi(_chi),
117 omega(_mu),
118 triplefunction(_triplefunction)
119{
120// Info info(__func__);
121// R = _R;
122// S = _S;
123 params[A] = _A;
124 params[B] = _B;
125 params[lambda] = _lambda;
126 params[mu] = _mu;
127// lambda3 = _lambda3;
128// alpha = _alpha;
129 params[beta] = _beta;
130// chi = _chi;
131// omega = _omega;
132 params[n] = _n;
133 params[c] = _c;
134 params[d] = _d;
135 params[h] = _h;
136 params[offset] = _offset;
137}
138
139void ManyBodyPotential_Tersoff::setParameters(const parameters_t &_params)
140{
141 const size_t paramsDim = _params.size();
142 ASSERT( paramsDim <= getParameterDimension(),
143 "ManyBodyPotential_Tersoff::setParameters() - we need not more than "
144 +toString(getParameterDimension())+" parameters.");
145 for (size_t i=0; i< paramsDim; ++i)
146 params[i] = _params[i];
147
148#ifndef NDEBUG
149 parameters_t check_params(getParameters());
150 check_params.resize(paramsDim); // truncate to same size
151 ASSERT( check_params == _params,
152 "ManyBodyPotential_Tersoff::setParameters() - failed, mismatch in to be set "
153 +toString(_params)+" and set "+toString(check_params)+" params.");
154#endif
155}
156
157ManyBodyPotential_Tersoff::results_t
158ManyBodyPotential_Tersoff::operator()(
159 const arguments_t &arguments
160 ) const
161{
162// Info info(__func__);
163 double result = 0.;
164 for(arguments_t::const_iterator argiter = arguments.begin();
165 argiter != arguments.end();
166 ++argiter) {
167 const argument_t &r_ij = *argiter;
168 ASSERT( ParticleTypeChecker::checkArgumentsAgainstParticleTypes(
169 arguments_t(1, r_ij), getParticleTypes()),
170 "ManyBodyPotential_Tersoff::operator() - types don't match with ones in arguments.");
171
172 const double cutoff = function_cutoff(r_ij.distance);
173 const double temp = (cutoff == 0.) ?
174 0. :
175 cutoff * (
176 function_prefactor(
177 alpha,
178 function_eta(r_ij))
179 * function_smoother(
180 params[A],
181 params[lambda],
182 r_ij.distance)
183 +
184 function_prefactor(
185 params[beta],
186 function_zeta(r_ij))
187 * function_smoother(
188 -params[B],
189 params[mu],
190 r_ij.distance)
191 );
192 result += temp;
193 }
194// LOG(2, "DEBUG: operator()(" << r_ij.distance << ") = " << result);
195 return std::vector<result_t>(1, params[offset]+result);
196}
197
198ManyBodyPotential_Tersoff::derivative_components_t
199ManyBodyPotential_Tersoff::derivative(
200 const arguments_t &arguments
201 ) const
202{
203// Info info(__func__);
204 return ManyBodyPotential_Tersoff::derivative_components_t();
205}
206
207ManyBodyPotential_Tersoff::results_t
208ManyBodyPotential_Tersoff::parameter_derivative(
209 const arguments_t &arguments,
210 const size_t index
211 ) const
212{
213// Info info(__func__);
214// ASSERT( arguments.size() == 1,
215// "ManyBodyPotential_Tersoff::parameter_derivative() - requires exactly one argument.");
216 if (index == offset)
217 return results_t(1, 1.);
218
219 double result = 0.;
220 for(arguments_t::const_iterator argiter = arguments.begin();
221 argiter != arguments.end();
222 ++argiter) {
223 const argument_t &r_ij = *argiter;
224 ASSERT( ParticleTypeChecker::checkArgumentsAgainstParticleTypes(
225 arguments_t(1, r_ij), getParticleTypes()),
226 "ManyBodyPotential_Tersoff::operator() - types don't match with ones in arguments.");
227
228 switch (index) {
229// case R:
230// {
231// result += 0.;
232// break;
233// }
234// case S:
235// {
236// result += 0.;
237// break;
238// }
239 case A:
240 {
241 const double cutoff = function_cutoff(r_ij.distance);
242 result += (cutoff == 0.) ?
243 0. :
244 cutoff *
245 function_prefactor(
246 alpha,
247 function_eta(r_ij))
248 * function_smoother(
249 1.,
250 params[lambda],
251 r_ij.distance);
252// cutoff * function_prefactor(
253// alpha,
254// function_eta(r_ij))
255// * function_smoother(
256// 1.,
257// params[mu],
258// r_ij.distance);
259 break;
260 }
261 case B:
262 {
263 const double cutoff = function_cutoff(r_ij.distance);
264 result += (cutoff == 0.) ?
265 0. :
266 cutoff * function_prefactor(
267 params[beta],
268 function_zeta(r_ij))
269 * function_smoother(
270 -1.,
271 params[mu],
272 r_ij.distance);
273// cutoff * function_prefactor(
274// beta,
275// function_zeta(r_ij))
276// * function_smoother(
277// -params[B],
278// params[mu],
279// r_ij.distance)/params[B];
280 break;
281 }
282 case lambda:
283 {
284 const double cutoff = function_cutoff(r_ij.distance);
285 result += (cutoff == 0.) ?
286 0. :
287 -r_ij.distance * cutoff *
288 function_prefactor(
289 alpha,
290 function_eta(r_ij))
291 * function_smoother(
292 params[A],
293 params[lambda],
294 r_ij.distance);
295 break;
296 }
297 case mu:
298 {
299 const double cutoff = function_cutoff(r_ij.distance);
300 result += (cutoff == 0.) ?
301 0. :
302 -r_ij.distance * cutoff *(
303 function_prefactor(
304 params[beta],
305 function_zeta(r_ij))
306 * function_smoother(
307 -params[B],
308 params[mu],
309 r_ij.distance)
310 );
311 break;
312 }
313// case lambda3:
314// {
315// result += 0.;
316// break;
317// }
318// case alpha:
319// {
320// const double temp =
321// pow(alpha*function_eta(r_ij), params[n]);
322// const double cutoff = function_cutoff(r_ij.distance);
323// result += (cutoff == 0.) || (alpha == 0. )?
324// 0. :
325// function_smoother(
326// params[A],
327// params[lambda],
328// r_ij.distance)
329// * (-.5) * alpha * (temp/alpha)
330// / (1. + temp)
331// ;
332// break;
333// }
334// case chi:
335// {
336// result += 0.;
337// break;
338// }
339// case omega:
340// {
341// result += 0.;
342// break;
343// }
344 case beta:
345 {
346 const double temp =
347 pow(params[beta]*function_zeta(r_ij), params[n]);
348 const double cutoff = function_cutoff(r_ij.distance);
349 result += (cutoff == 0.) || (params[beta] == 0. )?
350 0. : cutoff *
351 function_smoother(
352 -params[B],
353 params[mu],
354 r_ij.distance)
355 * (-.5)
356 * function_prefactor(
357 params[beta],
358 function_zeta(r_ij))
359 * (temp/params[beta])
360 / (1. + temp)
361 ;
362 break;
363 }
364 case n:
365 {
366 const double zeta = function_zeta(r_ij);
367 const double temp = pow( params[beta]*zeta , params[n]);
368 const double cutoff = function_cutoff(r_ij.distance);
369 const double tempres = ((cutoff == 0.) || (zeta == 0.)) ? // zeta must be caught if zero due to log
370 0. : .5 * cutoff *
371 function_smoother(
372 -params[B],
373 params[mu],
374 r_ij.distance)
375 * function_prefactor(
376 params[beta],
377 function_zeta(r_ij))
378 * ( log(1.+temp)/(params[n]*params[n]) - temp
379 * (log(function_zeta(r_ij)) + log(params[beta]))
380 /(params[n]*(1.+temp)))
381 ;
382// if (tempres != tempres)
383// LOG(2, "DEBUG: tempres is NaN.");
384// LOG(2, "DEBUG: Adding " << tempres << " for p.d. w.r.t n, temp=" << temp << ", cutoff=" << cutoff);
385 result += tempres;
386 break;
387 }
388 case c:
389 {
390 const double zeta = function_zeta(r_ij);
391 if (zeta == 0.)
392 break;
393 const double temp =
394 pow(zeta, params[n]-1.) * pow(params[beta],params[n]);
395 const double cutoff = function_cutoff(r_ij.distance);
396 const double tempres = (cutoff == 0.) ?
397 0. : cutoff *
398 function_smoother(
399 -params[B],
400 params[mu],
401 r_ij.distance)
402 * function_prefactor(
403 params[beta],
404 zeta)
405 * (-1.) * temp / (1.+temp*zeta);
406 double factor = function_derivative_c(r_ij);
407 result += tempres*factor;
408 if (result != result)
409 ELOG(1, "result is NaN, zeta=" << zeta << ", temp=" << temp << ", cutoff=" << cutoff << ", tempres=" << tempres << ", factor=" << factor);
410 break;
411 }
412 case d:
413 {
414 const double zeta = function_zeta(r_ij);
415 const double temp =
416 pow(zeta, params[n]-1.) * pow(params[beta],params[n]);
417 const double cutoff = function_cutoff(r_ij.distance);
418 const double tempres = (cutoff == 0.) ?
419 0. : cutoff *
420 function_smoother(
421 -params[B],
422 params[mu],
423 r_ij.distance)
424 * function_prefactor(
425 params[beta],
426 zeta)
427 * (-1.) * temp / (1.+temp*zeta);
428 double factor = function_derivative_d(r_ij);
429 result += tempres*factor;
430 if (result != result)
431 ELOG(1, "result is NaN, zeta=" << zeta << ", temp=" << temp << ", cutoff=" << cutoff << ", tempres=" << tempres << ", factor=" << factor);
432 break;
433 }
434 case h:
435 {
436 const double zeta = function_zeta(r_ij);
437 const double temp =
438 pow(zeta, params[n]-1.) * pow(params[beta],params[n]);
439 const double cutoff = function_cutoff(r_ij.distance);
440 const double tempres = (cutoff == 0.) ?
441 0. : cutoff *
442 function_smoother(
443 -params[B],
444 params[mu],
445 r_ij.distance)
446 * function_prefactor(
447 params[beta],
448 zeta)
449 * (-1.) * temp / (1.+temp*zeta);
450 double factor = function_derivative_h(r_ij);
451 result += tempres*factor;
452 if (result != result)
453 ELOG(1, "result is NaN, zeta=" << zeta << ", temp=" << temp << ", cutoff=" << cutoff << ", tempres=" << tempres << ", factor=" << factor);
454 break;
455 }
456 case offset:
457 result += 1.;
458 break;
459 default:
460 break;
461 }
462 if (result != result)
463 ELOG(1, "result is NaN.");
464 }
465 return results_t(1,-result);
466}
467
468ManyBodyPotential_Tersoff::result_t
469ManyBodyPotential_Tersoff::function_derivative_c(
470 const argument_t &r_ij
471 ) const
472{
473 double result = 0.;
474 std::vector<arguments_t> triples = triplefunction(r_ij, S);
475 for (std::vector<arguments_t>::const_iterator iter = triples.begin();
476 iter != triples.end(); ++iter) {
477 ASSERT( iter->size() == 2,
478 "ManyBodyPotential_Tersoff::function_derivative_c() - the triples result must contain exactly two distances.");
479 const argument_t &r_ik = (*iter)[0];
480 const argument_t &r_jk = (*iter)[1];
481 const double tempangle = params[h] - function_theta(r_ij.distance, r_ik.distance, r_jk.distance);
482 const double cutoff = function_cutoff(r_ik.distance);
483 result += (cutoff == 0.) ?
484 0. : cutoff * omega * exp( Helpers::pow(lambda3 * (r_ij.distance - r_ik.distance) ,3)) * (
485 params[c]/Helpers::pow(params[d],2)
486 - params[c] / ( Helpers::pow(params[d],2) + Helpers::pow(tempangle,2) )
487 );
488 }
489 return result;
490}
491
492ManyBodyPotential_Tersoff::result_t
493ManyBodyPotential_Tersoff::function_derivative_d(
494 const argument_t &r_ij
495 ) const
496{
497 double result = 0.;
498 std::vector<arguments_t> triples = triplefunction(r_ij, S);
499 for (std::vector<arguments_t>::const_iterator iter = triples.begin();
500 iter != triples.end(); ++iter) {
501 ASSERT( iter->size() == 2,
502 "ManyBodyPotential_Tersoff::function_derivative_d() - the triples result must contain exactly two distances.");
503 const argument_t &r_ik = (*iter)[0];
504 const argument_t &r_jk = (*iter)[1];
505 const double tempangle = params[h] - function_theta(r_ij.distance, r_ik.distance, r_jk.distance);
506 const double cutoff = function_cutoff(r_ik.distance);
507 result += (cutoff == 0.) ?
508 0. : cutoff * omega * exp( Helpers::pow(lambda3 * (r_ij.distance - r_ik.distance) ,3)) * (
509 - Helpers::pow(params[c],2)/Helpers::pow(params[d],3)
510 + Helpers::pow(params[c],2) * params[d]
511 / Helpers::pow(Helpers::pow(params[d],2) + Helpers::pow(tempangle,2),2)
512 );
513 }
514 return result;
515}
516
517ManyBodyPotential_Tersoff::result_t
518ManyBodyPotential_Tersoff::function_derivative_h(
519 const argument_t &r_ij
520 ) const
521{
522 double result = 0.;
523 std::vector<arguments_t> triples = triplefunction(r_ij, S);
524 for (std::vector<arguments_t>::const_iterator iter = triples.begin();
525 iter != triples.end(); ++iter) {
526 ASSERT( iter->size() == 2,
527 "ManyBodyPotential_Tersoff::function_derivative_h() - the triples result must contain exactly two distances.");
528 const argument_t &r_ik = (*iter)[0];
529 const argument_t &r_jk = (*iter)[1];
530 const double tempangle = params[h] - function_theta(r_ij.distance, r_ik.distance, r_jk.distance);
531 const double cutoff = function_cutoff(r_ik.distance);
532 result += (cutoff == 0.) ?
533 0. : cutoff * omega * exp( Helpers::pow(lambda3 * (r_ij.distance - r_ik.distance) ,3)) * (
534 ( Helpers::pow(params[c],2)*tempangle )
535 / Helpers::pow(Helpers::pow(params[d],2) + Helpers::pow(tempangle,2),2)
536 );
537 }
538 return result;
539}
540
541ManyBodyPotential_Tersoff::result_t
542ManyBodyPotential_Tersoff::function_cutoff(
543 const double &distance
544 ) const
545{
546// Info info(__func__);
547 double result = 0.;
548 if (distance < R)
549 result = 1.;
550 else if (distance > S)
551 result = 0.;
552 else {
553 result = (0.5 + 0.5 * cos( M_PI * (distance - R)/(S-R)));
554 }
555// LOG(2, "DEBUG: function_cutoff(" << distance << ") = " << result);
556 return result;
557}
558
559ManyBodyPotential_Tersoff::result_t
560ManyBodyPotential_Tersoff::function_prefactor(
561 const double &alpha,
562 const double &eta
563 ) const
564{
565// Info info(__func__);
566 const double result = chi * pow(
567 (1. + pow(alpha * eta, params[n])),
568 -1./(2.*params[n]));
569// LOG(2, "DEBUG: function_prefactor(" << alpha << "," << eta << ") = " << result);
570 return result;
571}
572
573ManyBodyPotential_Tersoff::result_t
574ManyBodyPotential_Tersoff::function_smoother(
575 const double &prefactor,
576 const double &lambda,
577 const double &distance
578 ) const
579{
580// Info info(__func__);
581 const double result = prefactor * exp(-lambda * distance);
582// LOG(2, "DEBUG: function_smoother(" << prefactor << "," << lambda << "," << distance << ") = " << result);
583 return result;
584}
585
586ManyBodyPotential_Tersoff::result_t
587ManyBodyPotential_Tersoff::function_eta(
588 const argument_t &r_ij
589 ) const
590{
591// Info info(__func__);
592 result_t result = 0.;
593
594 // get all triples within the cutoff
595 std::vector<arguments_t> triples = triplefunction(r_ij, S);
596 for (std::vector<arguments_t>::const_iterator iter = triples.begin();
597 iter != triples.end(); ++iter) {
598 ASSERT( iter->size() == 2,
599 "ManyBodyPotential_Tersoff::function_zeta() - the triples result must contain of exactly two distances.");
600 const argument_t &r_ik = (*iter)[0];
601 result += function_cutoff(r_ik.distance)
602 * exp( Helpers::pow(lambda3 * (r_ij.distance - r_ik.distance) ,3));
603 }
604
605// LOG(2, "DEBUG: function_eta(" << r_ij.distance << ") = " << result);
606 return result;
607}
608
609ManyBodyPotential_Tersoff::result_t
610ManyBodyPotential_Tersoff::function_zeta(
611 const argument_t &r_ij
612 ) const
613{
614// Info info(__func__);
615 result_t result = 0.;
616
617 // get all triples within the cutoff
618 std::vector<arguments_t> triples = triplefunction(r_ij, S);
619 for (std::vector<arguments_t>::const_iterator iter = triples.begin();
620 iter != triples.end(); ++iter) {
621 ASSERT( iter->size() == 2,
622 "ManyBodyPotential_Tersoff::function_zeta() - the triples result must contain exactly two distances.");
623 const argument_t &r_ik = (*iter)[0];
624 const argument_t &r_jk = (*iter)[1];
625 result +=
626 function_cutoff(r_ik.distance)
627 * omega
628 * function_angle(r_ij.distance, r_ik.distance, r_jk.distance)
629 * exp( Helpers::pow(lambda3 * (r_ij.distance - r_ik.distance) ,3));
630 }
631
632// LOG(2, "DEBUG: function_zeta(" << r_ij.distance << ") = " << result);
633 return result;
634}
635
636ManyBodyPotential_Tersoff::result_t
637ManyBodyPotential_Tersoff::function_theta(
638 const double &r_ij,
639 const double &r_ik,
640 const double &r_jk
641 ) const
642{
643 const double angle = Helpers::pow(r_ij,2) + Helpers::pow(r_ik,2) - Helpers::pow(r_jk,2);
644 const double divisor = 2.* r_ij * r_ik;
645 if (divisor != 0.) {
646 LOG(2, "DEBUG: cos(theta)= " << angle/divisor);
647 return angle/divisor;
648 } else
649 return 0.;
650}
651
652ManyBodyPotential_Tersoff::result_t
653ManyBodyPotential_Tersoff::function_angle(
654 const double &r_ij,
655 const double &r_ik,
656 const double &r_jk
657 ) const
658{
659// Info info(__func__);
660 const double result =
661 1.
662 + (Helpers::pow(params[c]/params[d], 2))
663 - Helpers::pow(params[c], 2)/(Helpers::pow(params[d], 2) +
664 Helpers::pow(params[h] - function_theta(r_ij, r_ik, r_jk),2));
665
666// LOG(2, "DEBUG: function_angle(" << r_ij << "," << r_ik << "," << r_jk << ") = " << result);
667 return result;
668}
669
Note: See TracBrowser for help on using the repository browser.