source: src/Potentials/Specifics/ManyBodyPotential_Tersoff.cpp@ 16227a

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

Removed FunctionModel::getSpecificExtractor() that is not needed anymore.

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