source: src/Potentials/Specifics/ManyBodyPotential_Tersoff.cpp@ 550f2a

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

FunctionModel now uses list_of_arguments to split sequence of subsets of distances.

  • this fixes ambiguities with the set of distances: Imagine the distances within a water molecule as OH (A) and HH (B). We then may have a sequence of argument_t as AABAAB. And with the current implementation of CompoundPotential::splitUpArgumentsByModels() we would always choose the latter (and more complex) model. Hence, we make two calls to TriplePotential_Angle, instead of calls twice to PairPotential_Harmonic for A, one to PairPotential_Harmonic for B, and once to TriplePotential_Angle for AAB.
  • now, we new list looks like A,A,B,AAB where each tuple of distances can be uniquely associated with a specific potential.
  • changed signatures of EmpiricalPotential::operator(), ::derivative(), ::parameter_derivative(). This involved changing all of the current specific potentials and CompoundPotential.
  • TrainingData must discern between the InputVector_t (just all distances) and the FilteredInputVector_t (tuples of subsets of distances).
  • FunctionApproximation now has list_of_arguments_t as parameter to evaluate() and evaluate_derivative().
  • DOCU: docu change in TrainingData.
  • Property mode set to 100644
File size: 23.0 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()(
[e1fe7e]186 const list_of_arguments_t &listarguments
[610c11]187 ) const
188{
[ffc368]189// Info info(__func__);
[e1fe7e]190 result_t result = 0.;
191 for(list_of_arguments_t::const_iterator iter = listarguments.begin();
192 iter != listarguments.end(); ++iter) {
193 const arguments_t &arguments = *iter;
194 for(arguments_t::const_iterator argiter = arguments.begin();
195 argiter != arguments.end();
196 ++argiter) {
197 const argument_t &r_ij = *argiter;
198 ASSERT( ParticleTypeChecker::checkArgumentsAgainstParticleTypes(
199 arguments_t(1, r_ij), getParticleTypes()),
200 "ManyBodyPotential_Tersoff::operator() - types don't match with ones in arguments.");
201
202 const double cutoff = function_cutoff(r_ij.distance);
203 const double temp = (cutoff == 0.) ?
204 0. :
205 cutoff * (
206 function_prefactor(
207 alpha,
208 function_eta(r_ij))
209 * function_smoother(
210 params[A],
211 params[lambda],
212 r_ij.distance)
213 +
214 function_prefactor(
215 params[beta],
216 function_zeta(r_ij))
217 * function_smoother(
218 -params[B],
219 params[mu],
220 r_ij.distance)
221 );
222 result += temp;
223 }
[2e9486]224 }
[ffc368]225// LOG(2, "DEBUG: operator()(" << r_ij.distance << ") = " << result);
[e1fe7e]226 return results_t(1, result);
[610c11]227}
228
[ffc368]229ManyBodyPotential_Tersoff::derivative_components_t
230ManyBodyPotential_Tersoff::derivative(
[e1fe7e]231 const list_of_arguments_t &listarguments
[ffc368]232 ) const
233{
234// Info info(__func__);
[e1fe7e]235 return derivative_components_t();
[ffc368]236}
237
238ManyBodyPotential_Tersoff::results_t
239ManyBodyPotential_Tersoff::parameter_derivative(
[e1fe7e]240 const list_of_arguments_t &listarguments,
[ffc368]241 const size_t index
242 ) const
243{
244// Info info(__func__);
245// ASSERT( arguments.size() == 1,
[2e9486]246// "ManyBodyPotential_Tersoff::parameter_derivative() - requires exactly one argument.");
[56c5de4]247
[e1fe7e]248 result_t result = 0.;
249 for(list_of_arguments_t::const_iterator iter = listarguments.begin();
250 iter != listarguments.end(); ++iter) {
251 const arguments_t &arguments = *iter;
252 for(arguments_t::const_iterator argiter = arguments.begin();
253 argiter != arguments.end();
254 ++argiter) {
255 const argument_t &r_ij = *argiter;
256 ASSERT( ParticleTypeChecker::checkArgumentsAgainstParticleTypes(
257 arguments_t(1, r_ij), getParticleTypes()),
258 "ManyBodyPotential_Tersoff::operator() - types don't match with ones in arguments.");
[55fe788]259
[e1fe7e]260 switch (index) {
261// case R:
262// {
263// result += 0.;
264// break;
265// }
266// case S:
267// {
268// result += 0.;
269// break;
270// }
271 case A:
272 {
273 const double cutoff = function_cutoff(r_ij.distance);
274 result += (cutoff == 0.) ?
275 0. :
276 cutoff *
277 function_prefactor(
278 alpha,
279 function_eta(r_ij))
280 * function_smoother(
281 1.,
282 params[lambda],
283 r_ij.distance);
284// cutoff * function_prefactor(
285// alpha,
286// function_eta(r_ij))
287// * function_smoother(
288// 1.,
289// params[mu],
290// r_ij.distance);
291 break;
292 }
293 case B:
294 {
295 const double cutoff = function_cutoff(r_ij.distance);
296 result += (cutoff == 0.) ?
297 0. :
298 cutoff * function_prefactor(
299 params[beta],
300 function_zeta(r_ij))
301 * function_smoother(
302 -1.,
303 params[mu],
304 r_ij.distance);
305// cutoff * function_prefactor(
306// beta,
307// function_zeta(r_ij))
308// * function_smoother(
309// -params[B],
310// params[mu],
311// r_ij.distance)/params[B];
312 break;
313 }
314 case lambda:
315 {
316 const double cutoff = function_cutoff(r_ij.distance);
317 result += (cutoff == 0.) ?
318 0. :
319 -r_ij.distance * cutoff *
320 function_prefactor(
321 alpha,
322 function_eta(r_ij))
323 * function_smoother(
324 params[A],
325 params[lambda],
326 r_ij.distance);
327 break;
328 }
329 case mu:
330 {
331 const double cutoff = function_cutoff(r_ij.distance);
332 result += (cutoff == 0.) ?
333 0. :
334 -r_ij.distance * cutoff *(
335 function_prefactor(
336 params[beta],
337 function_zeta(r_ij))
338 * function_smoother(
339 -params[B],
340 params[mu],
341 r_ij.distance)
342 );
343 break;
344 }
345// case lambda3:
346// {
347// result += 0.;
348// break;
349// }
350// case alpha:
351// {
352// const double temp =
353// pow(alpha*function_eta(r_ij), params[n]);
354// const double cutoff = function_cutoff(r_ij.distance);
355// result += (cutoff == 0.) || (alpha == 0. )?
356// 0. :
357// function_smoother(
358// params[A],
359// params[lambda],
360// r_ij.distance)
361// * (-.5) * alpha * (temp/alpha)
362// / (1. + temp)
363// ;
364// break;
365// }
366// case chi:
367// {
368// result += 0.;
369// break;
370// }
371// case omega:
372// {
373// result += 0.;
374// break;
375// }
376 case beta:
377 {
378 const double temp =
379 pow(params[beta]*function_zeta(r_ij), params[n]);
380 const double cutoff = function_cutoff(r_ij.distance);
381 result += (cutoff == 0.) || (params[beta] == 0. )?
382 0. : cutoff *
383 function_smoother(
384 -params[B],
385 params[mu],
386 r_ij.distance)
387 * (-.5)
388 * function_prefactor(
389 params[beta],
390 function_zeta(r_ij))
391 * (temp/params[beta])
392 / (1. + temp)
393 ;
394 break;
395 }
396 case n:
397 {
398 const double zeta = function_zeta(r_ij);
399 const double temp = pow( params[beta]*zeta , params[n]);
400 const double cutoff = function_cutoff(r_ij.distance);
401 const double tempres = ((cutoff == 0.) || (zeta == 0.)) ? // zeta must be caught if zero due to log
402 0. : .5 * cutoff *
403 function_smoother(
404 -params[B],
405 params[mu],
406 r_ij.distance)
407 * function_prefactor(
408 params[beta],
409 function_zeta(r_ij))
410 * ( log(1.+temp)/(params[n]*params[n]) - temp
411 * (log(function_zeta(r_ij)) + log(params[beta]))
412 /(params[n]*(1.+temp)))
413 ;
414// if (tempres != tempres)
415// LOG(2, "DEBUG: tempres is NaN.");
416// LOG(2, "DEBUG: Adding " << tempres << " for p.d. w.r.t n, temp=" << temp << ", cutoff=" << cutoff);
417 result += tempres;
418 break;
419 }
420 case c:
421 {
422 const double zeta = function_zeta(r_ij);
423 if (zeta == 0.)
424 break;
425 const double temp =
426 pow(zeta, params[n]-1.) * pow(params[beta],params[n]);
427 const double cutoff = function_cutoff(r_ij.distance);
428 const double tempres = (cutoff == 0.) ?
429 0. : cutoff *
430 function_smoother(
431 -params[B],
432 params[mu],
433 r_ij.distance)
434 * function_prefactor(
435 params[beta],
436 zeta)
437 * (-1.) * temp / (1.+temp*zeta);
438 double factor = function_derivative_c(r_ij);
439 result += tempres*factor;
440 if (result != result)
441 ELOG(1, "result is NaN, zeta=" << zeta << ", temp=" << temp << ", cutoff=" << cutoff << ", tempres=" << tempres << ", factor=" << factor);
442 break;
443 }
444 case d:
445 {
446 const double zeta = function_zeta(r_ij);
447 const double temp =
448 pow(zeta, params[n]-1.) * pow(params[beta],params[n]);
449 const double cutoff = function_cutoff(r_ij.distance);
450 const double tempres = (cutoff == 0.) ?
451 0. : cutoff *
452 function_smoother(
453 -params[B],
454 params[mu],
455 r_ij.distance)
456 * function_prefactor(
457 params[beta],
458 zeta)
459 * (-1.) * temp / (1.+temp*zeta);
460 double factor = function_derivative_d(r_ij);
461 result += tempres*factor;
462 if (result != result)
463 ELOG(1, "result is NaN, zeta=" << zeta << ", temp=" << temp << ", cutoff=" << cutoff << ", tempres=" << tempres << ", factor=" << factor);
464 break;
465 }
466 case h:
467 {
468 const double zeta = function_zeta(r_ij);
469 const double temp =
470 pow(zeta, params[n]-1.) * pow(params[beta],params[n]);
471 const double cutoff = function_cutoff(r_ij.distance);
472 const double tempres = (cutoff == 0.) ?
473 0. : cutoff *
474 function_smoother(
475 -params[B],
476 params[mu],
477 r_ij.distance)
478 * function_prefactor(
479 params[beta],
480 zeta)
481 * (-1.) * temp / (1.+temp*zeta);
482 double factor = function_derivative_h(r_ij);
483 result += tempres*factor;
484 if (result != result)
485 ELOG(1, "result is NaN, zeta=" << zeta << ", temp=" << temp << ", cutoff=" << cutoff << ", tempres=" << tempres << ", factor=" << factor);
486 break;
487 }
488 default:
489 ASSERT(0, "ManyBodyPotential_Tersoff::parameter_derivative() - derivative to unknown parameter desired.");
[ca8d82]490 break;
[ffc368]491 }
[e1fe7e]492 if (result != result)
493 ELOG(1, "result is NaN.");
[ffc368]494 }
[2e9486]495 }
496 return results_t(1,-result);
[ffc368]497}
498
[ca8d82]499ManyBodyPotential_Tersoff::result_t
500ManyBodyPotential_Tersoff::function_derivative_c(
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_c() - 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 params[c]/Helpers::pow(params[d],2)
517 - params[c] / ( Helpers::pow(params[d],2) + Helpers::pow(tempangle,2) )
518 );
519 }
520 return result;
521}
522
523ManyBodyPotential_Tersoff::result_t
524ManyBodyPotential_Tersoff::function_derivative_d(
525 const argument_t &r_ij
526 ) const
527{
528 double result = 0.;
529 std::vector<arguments_t> triples = triplefunction(r_ij, S);
530 for (std::vector<arguments_t>::const_iterator iter = triples.begin();
531 iter != triples.end(); ++iter) {
532 ASSERT( iter->size() == 2,
533 "ManyBodyPotential_Tersoff::function_derivative_d() - the triples result must contain exactly two distances.");
534 const argument_t &r_ik = (*iter)[0];
535 const argument_t &r_jk = (*iter)[1];
536 const double tempangle = params[h] - function_theta(r_ij.distance, r_ik.distance, r_jk.distance);
537 const double cutoff = function_cutoff(r_ik.distance);
538 result += (cutoff == 0.) ?
539 0. : cutoff * omega * exp( Helpers::pow(lambda3 * (r_ij.distance - r_ik.distance) ,3)) * (
540 - Helpers::pow(params[c],2)/Helpers::pow(params[d],3)
541 + Helpers::pow(params[c],2) * params[d]
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_derivative_h(
550 const argument_t &r_ij
551 ) const
552{
553 double result = 0.;
554 std::vector<arguments_t> triples = triplefunction(r_ij, S);
555 for (std::vector<arguments_t>::const_iterator iter = triples.begin();
556 iter != triples.end(); ++iter) {
557 ASSERT( iter->size() == 2,
558 "ManyBodyPotential_Tersoff::function_derivative_h() - the triples result must contain exactly two distances.");
559 const argument_t &r_ik = (*iter)[0];
560 const argument_t &r_jk = (*iter)[1];
561 const double tempangle = params[h] - function_theta(r_ij.distance, r_ik.distance, r_jk.distance);
562 const double cutoff = function_cutoff(r_ik.distance);
563 result += (cutoff == 0.) ?
564 0. : cutoff * omega * exp( Helpers::pow(lambda3 * (r_ij.distance - r_ik.distance) ,3)) * (
565 ( Helpers::pow(params[c],2)*tempangle )
566 / Helpers::pow(Helpers::pow(params[d],2) + Helpers::pow(tempangle,2),2)
567 );
568 }
569 return result;
570}
571
[4f82f8]572ManyBodyPotential_Tersoff::result_t
[610c11]573ManyBodyPotential_Tersoff::function_cutoff(
574 const double &distance
575 ) const
576{
[ffc368]577// Info info(__func__);
578 double result = 0.;
[752dc7]579 if (distance < R)
[ffc368]580 result = 1.;
[752dc7]581 else if (distance > S)
[ffc368]582 result = 0.;
[610c11]583 else {
[752dc7]584 result = (0.5 + 0.5 * cos( M_PI * (distance - R)/(S-R)));
[610c11]585 }
[ffc368]586// LOG(2, "DEBUG: function_cutoff(" << distance << ") = " << result);
587 return result;
[610c11]588}
589
[4f82f8]590ManyBodyPotential_Tersoff::result_t
[610c11]591ManyBodyPotential_Tersoff::function_prefactor(
592 const double &alpha,
[ffc368]593 const double &eta
[610c11]594 ) const
595{
[ffc368]596// Info info(__func__);
[990a62]597 const double result = chi * pow(
[ffc368]598 (1. + pow(alpha * eta, params[n])),
599 -1./(2.*params[n]));
600// LOG(2, "DEBUG: function_prefactor(" << alpha << "," << eta << ") = " << result);
601 return result;
602}
603
604ManyBodyPotential_Tersoff::result_t
605ManyBodyPotential_Tersoff::function_smoother(
606 const double &prefactor,
607 const double &lambda,
608 const double &distance
609 ) const
610{
611// Info info(__func__);
612 const double result = prefactor * exp(-lambda * distance);
613// LOG(2, "DEBUG: function_smoother(" << prefactor << "," << lambda << "," << distance << ") = " << result);
614 return result;
[610c11]615}
616
[4f82f8]617ManyBodyPotential_Tersoff::result_t
[610c11]618ManyBodyPotential_Tersoff::function_eta(
619 const argument_t &r_ij
620 ) const
621{
[ffc368]622// Info info(__func__);
[610c11]623 result_t result = 0.;
624
625 // get all triples within the cutoff
[752dc7]626 std::vector<arguments_t> triples = triplefunction(r_ij, S);
[610c11]627 for (std::vector<arguments_t>::const_iterator iter = triples.begin();
628 iter != triples.end(); ++iter) {
629 ASSERT( iter->size() == 2,
630 "ManyBodyPotential_Tersoff::function_zeta() - the triples result must contain of exactly two distances.");
631 const argument_t &r_ik = (*iter)[0];
632 result += function_cutoff(r_ik.distance)
[990a62]633 * exp( Helpers::pow(lambda3 * (r_ij.distance - r_ik.distance) ,3));
[610c11]634 }
635
[ffc368]636// LOG(2, "DEBUG: function_eta(" << r_ij.distance << ") = " << result);
[610c11]637 return result;
638}
639
[4f82f8]640ManyBodyPotential_Tersoff::result_t
[610c11]641ManyBodyPotential_Tersoff::function_zeta(
642 const argument_t &r_ij
643 ) const
644{
[ffc368]645// Info info(__func__);
[610c11]646 result_t result = 0.;
647
648 // get all triples within the cutoff
[752dc7]649 std::vector<arguments_t> triples = triplefunction(r_ij, S);
[610c11]650 for (std::vector<arguments_t>::const_iterator iter = triples.begin();
651 iter != triples.end(); ++iter) {
652 ASSERT( iter->size() == 2,
653 "ManyBodyPotential_Tersoff::function_zeta() - the triples result must contain exactly two distances.");
654 const argument_t &r_ik = (*iter)[0];
655 const argument_t &r_jk = (*iter)[1];
656 result +=
657 function_cutoff(r_ik.distance)
[990a62]658 * omega
[610c11]659 * function_angle(r_ij.distance, r_ik.distance, r_jk.distance)
[990a62]660 * exp( Helpers::pow(lambda3 * (r_ij.distance - r_ik.distance) ,3));
[610c11]661 }
662
[ffc368]663// LOG(2, "DEBUG: function_zeta(" << r_ij.distance << ") = " << result);
[610c11]664 return result;
665}
666
[4f82f8]667ManyBodyPotential_Tersoff::result_t
[f904d5]668ManyBodyPotential_Tersoff::function_theta(
[610c11]669 const double &r_ij,
670 const double &r_ik,
671 const double &r_jk
672 ) const
673{
674 const double angle = Helpers::pow(r_ij,2) + Helpers::pow(r_ik,2) - Helpers::pow(r_jk,2);
[ffc368]675 const double divisor = 2.* r_ij * r_ik;
676 if (divisor != 0.) {
[f904d5]677 LOG(2, "DEBUG: cos(theta)= " << angle/divisor);
678 return angle/divisor;
[ffc368]679 } else
680 return 0.;
[610c11]681}
[ffc368]682
[f904d5]683ManyBodyPotential_Tersoff::result_t
684ManyBodyPotential_Tersoff::function_angle(
685 const double &r_ij,
686 const double &r_ik,
687 const double &r_jk
688 ) const
689{
690// Info info(__func__);
691 const double result =
692 1.
693 + (Helpers::pow(params[c]/params[d], 2))
694 - Helpers::pow(params[c], 2)/(Helpers::pow(params[d], 2) +
[ca8d82]695 Helpers::pow(params[h] - function_theta(r_ij, r_ik, r_jk),2));
[f904d5]696
[ca8d82]697// LOG(2, "DEBUG: function_angle(" << r_ij << "," << r_ik << "," << r_jk << ") = " << result);
[f904d5]698 return result;
699}
700
[0f5d38]701FunctionModel::filter_t ManyBodyPotential_Tersoff::getSpecificFilter() const
702{
703 FunctionModel::filter_t returnfunction =
[51e0e3]704 boost::bind(&Extractors::filterArgumentsByParticleTypes,
705 _1,
706 getParticleTypes());
[0f5d38]707 return returnfunction;
708}
709
[d52819]710void
711ManyBodyPotential_Tersoff::setParametersToRandomInitialValues(
712 const TrainingData &data)
713{
[0932c2]714 RandomNumberGenerator &random = RandomNumberGeneratorFactory::getInstance().makeRandomNumberGenerator();
715 const double rng_min = random.min();
716 const double rng_max = random.max();
[d52819]717// params[ManyBodyPotential_Tersoff::R] = 1./AtomicLengthToAngstroem;
718// params[ManyBodyPotential_Tersoff::S] = 2./AtomicLengthToAngstroem;
[0932c2]719 params[ManyBodyPotential_Tersoff::A] = 1e+4*(random()/(rng_max-rng_min));//1.393600e+03;
720 params[ManyBodyPotential_Tersoff::B] = 1e+4*(random()/(rng_max-rng_min));//3.467000e+02;
721 params[ManyBodyPotential_Tersoff::lambda] = 1e+1*(random()/(rng_max-rng_min));//3.487900e+00;
722 params[ManyBodyPotential_Tersoff::mu] = 1e+1*(random()/(rng_max-rng_min));//2.211900e+00;
[d52819]723 // params[ManyBodyPotential_Tersoff::lambda3] = 0.;
724 // params[ManyBodyPotential_Tersoff::alpha] = 0.;
[0932c2]725 params[ManyBodyPotential_Tersoff::beta] = 1e-1*(random()/(rng_max-rng_min));//1.572400e-07;
[d52819]726 // params[ManyBodyPotential_Tersoff::chi] = 1.;
727 // params[ManyBodyPotential_Tersoff::omega] = 1.;
[0932c2]728 params[ManyBodyPotential_Tersoff::n] = 1e+1*(random()/(rng_max-rng_min));//7.275100e-01;
729 params[ManyBodyPotential_Tersoff::c] = 1e+1*(random()/(rng_max-rng_min));//3.804900e+04;
730 params[ManyBodyPotential_Tersoff::d] = 1e+1*(random()/(rng_max-rng_min));//4.384000e+00;
731 params[ManyBodyPotential_Tersoff::h] = 1e+1*(random()/(rng_max-rng_min));//-5.705800e-01;
[d52819]732}
733
Note: See TracBrowser for help on using the repository browser.