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

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

Added NaN check to Tersoff's parameter_derivative().

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