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

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

FIX: Default cstor of specific potentials did not allocate parameter vector.

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