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

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

Removed parameter charges from getFragmentSpecificExtractor().

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