source: src/Potentials/Specifics/ManyBodyPotential_Tersoff.cpp@ 94453f1

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

Added getCoordinator() to EmpiricalPotential interface.

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