source: src/Potentials/Specifics/ManyBodyPotential_Tersoff.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 086070, checked in by Frederik Heber <heber@…>, 12 years ago

Moved all setParameters() from header files into module.

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