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

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

FIX: Added new copyright lines to files in src/Potentials, too.

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