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

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

Removed energy_offset from ManyBodyPotential_Tersoff.

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