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

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 d29b31 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
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2012 University of Bonn. All rights reserved.
5 * Copyright (C) 2013 Frederik Heber. All rights reserved.
6 * Please see the COPYING file or "Copyright notice" in builder.cpp for details.
7 *
8 *
9 * This file is part of MoleCuilder.
10 *
11 * MoleCuilder is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation, either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * MoleCuilder is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with MoleCuilder. If not, see <http://www.gnu.org/licenses/>.
23 */
24
25/*
26 * ManyBodyPotential_Tersoff.cpp
27 *
28 * Created on: Sep 26, 2012
29 * Author: heber
30 */
31
32
33// include config.h
34#ifdef HAVE_CONFIG_H
35#include <config.h>
36#endif
37
38#include "CodePatterns/MemDebug.hpp"
39
40#include "ManyBodyPotential_Tersoff.hpp"
41
42#include <boost/assign/list_of.hpp> // for 'map_list_of()'
43#include <boost/bind.hpp>
44#include <cmath>
45#include <string>
46
47#include "CodePatterns/Assert.hpp"
48//#include "CodePatterns/Info.hpp"
49#include "CodePatterns/Log.hpp"
50
51#include "FunctionApproximation/Extractors.hpp"
52#include "FunctionApproximation/TrainingData.hpp"
53#include "Potentials/helpers.hpp"
54#include "Potentials/InternalCoordinates/OneBody_Constant.hpp"
55#include "Potentials/ParticleTypeCheckers.hpp"
56
57class Fragment;
58
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");
80Coordinator::ptr ManyBodyPotential_Tersoff::coordinator(new OneBody_Constant());
81
82ManyBodyPotential_Tersoff::ManyBodyPotential_Tersoff() :
83 EmpiricalPotential(),
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
94ManyBodyPotential_Tersoff::ManyBodyPotential_Tersoff(
95 const ParticleTypes_t &_ParticleTypes
96 ) :
97 EmpiricalPotential(_ParticleTypes),
98 params(parameters_t(MAXPARAMS, 0.)),
99 R(3.2),
100 S(3.5),
101 lambda3(0.),
102 alpha(0.),
103 chi(1.),
104 omega(1.),
105 triplefunction(&Helpers::NoOp_Triplefunction)
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}
118
119ManyBodyPotential_Tersoff::ManyBodyPotential_Tersoff(
120 const ParticleTypes_t &_ParticleTypes,
121 const double &_R,
122 const double &_S,
123 const double &_A,
124 const double &_B,
125 const double &_lambda,
126 const double &_mu,
127 const double &_lambda3,
128 const double &_alpha,
129 const double &_beta,
130 const double &_chi,
131 const double &_omega,
132 const double &_n,
133 const double &_c,
134 const double &_d,
135 const double &_h) :
136 EmpiricalPotential(_ParticleTypes),
137 params(parameters_t(MAXPARAMS, 0.)),
138 R(_R),
139 S(_S),
140 lambda3(_lambda3),
141 alpha(_alpha),
142 chi(_chi),
143 omega(_mu),
144 triplefunction(&Helpers::NoOp_Triplefunction)
145{
146// Info info(__func__);
147// R = _R;
148// S = _S;
149 params[A] = _A;
150 params[B] = _B;
151 params[lambda] = _lambda;
152 params[mu] = _mu;
153// lambda3 = _lambda3;
154// alpha = _alpha;
155 params[beta] = _beta;
156// chi = _chi;
157// omega = _omega;
158 params[n] = _n;
159 params[c] = _c;
160 params[d] = _d;
161 params[h] = _h;
162}
163
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
182ManyBodyPotential_Tersoff::results_t
183ManyBodyPotential_Tersoff::operator()(
184 const arguments_t &arguments
185 ) const
186{
187// Info info(__func__);
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;
193 ASSERT( ParticleTypeChecker::checkArgumentsAgainstParticleTypes(
194 arguments_t(1, r_ij), getParticleTypes()),
195 "ManyBodyPotential_Tersoff::operator() - types don't match with ones in arguments.");
196
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 }
219// LOG(2, "DEBUG: operator()(" << r_ij.distance << ") = " << result);
220 return std::vector<result_t>(1, result);
221}
222
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,
240// "ManyBodyPotential_Tersoff::parameter_derivative() - requires exactly one argument.");
241
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;
247 ASSERT( ParticleTypeChecker::checkArgumentsAgainstParticleTypes(
248 arguments_t(1, r_ij), getParticleTypes()),
249 "ManyBodyPotential_Tersoff::operator() - types don't match with ones in arguments.");
250
251 switch (index) {
252// case R:
253// {
254// result += 0.;
255// break;
256// }
257// case S:
258// {
259// result += 0.;
260// break;
261// }
262 case A:
263 {
264 const double cutoff = function_cutoff(r_ij.distance);
265 result += (cutoff == 0.) ?
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);
282 break;
283 }
284 case B:
285 {
286 const double cutoff = function_cutoff(r_ij.distance);
287 result += (cutoff == 0.) ?
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];
303 break;
304 }
305 case lambda:
306 {
307 const double cutoff = function_cutoff(r_ij.distance);
308 result += (cutoff == 0.) ?
309 0. :
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);
318 break;
319 }
320 case mu:
321 {
322 const double cutoff = function_cutoff(r_ij.distance);
323 result += (cutoff == 0.) ?
324 0. :
325 -r_ij.distance * cutoff *(
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 }
336// case lambda3:
337// {
338// result += 0.;
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);
346// result += (cutoff == 0.) || (alpha == 0. )?
347// 0. :
348// function_smoother(
349// params[A],
350// params[lambda],
351// r_ij.distance)
352// * (-.5) * alpha * (temp/alpha)
353// / (1. + temp)
354// ;
355// break;
356// }
357// case chi:
358// {
359// result += 0.;
360// break;
361// }
362// case omega:
363// {
364// result += 0.;
365// break;
366// }
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);
372 result += (cutoff == 0.) || (params[beta] == 0. )?
373 0. : cutoff *
374 function_smoother(
375 -params[B],
376 params[mu],
377 r_ij.distance)
378 * (-.5)
379 * function_prefactor(
380 params[beta],
381 function_zeta(r_ij))
382 * (temp/params[beta])
383 / (1. + temp)
384 ;
385 break;
386 }
387 case n:
388 {
389 const double zeta = function_zeta(r_ij);
390 const double temp = pow( params[beta]*zeta , params[n]);
391 const double cutoff = function_cutoff(r_ij.distance);
392 const double tempres = ((cutoff == 0.) || (zeta == 0.)) ? // zeta must be caught if zero due to log
393 0. : .5 * cutoff *
394 function_smoother(
395 -params[B],
396 params[mu],
397 r_ij.distance)
398 * function_prefactor(
399 params[beta],
400 function_zeta(r_ij))
401 * ( log(1.+temp)/(params[n]*params[n]) - temp
402 * (log(function_zeta(r_ij)) + log(params[beta]))
403 /(params[n]*(1.+temp)))
404 ;
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;
409 break;
410 }
411 case c:
412 {
413 const double zeta = function_zeta(r_ij);
414 if (zeta == 0.)
415 break;
416 const double temp =
417 pow(zeta, params[n]-1.) * pow(params[beta],params[n]);
418 const double cutoff = function_cutoff(r_ij.distance);
419 const double tempres = (cutoff == 0.) ?
420 0. : cutoff *
421 function_smoother(
422 -params[B],
423 params[mu],
424 r_ij.distance)
425 * function_prefactor(
426 params[beta],
427 zeta)
428 * (-1.) * temp / (1.+temp*zeta);
429 double factor = function_derivative_c(r_ij);
430 result += tempres*factor;
431 if (result != result)
432 ELOG(1, "result is NaN, zeta=" << zeta << ", temp=" << temp << ", cutoff=" << cutoff << ", tempres=" << tempres << ", factor=" << factor);
433 break;
434 }
435 case d:
436 {
437 const double zeta = function_zeta(r_ij);
438 const double temp =
439 pow(zeta, params[n]-1.) * pow(params[beta],params[n]);
440 const double cutoff = function_cutoff(r_ij.distance);
441 const double tempres = (cutoff == 0.) ?
442 0. : cutoff *
443 function_smoother(
444 -params[B],
445 params[mu],
446 r_ij.distance)
447 * function_prefactor(
448 params[beta],
449 zeta)
450 * (-1.) * temp / (1.+temp*zeta);
451 double factor = function_derivative_d(r_ij);
452 result += tempres*factor;
453 if (result != result)
454 ELOG(1, "result is NaN, zeta=" << zeta << ", temp=" << temp << ", cutoff=" << cutoff << ", tempres=" << tempres << ", factor=" << factor);
455 break;
456 }
457 case h:
458 {
459 const double zeta = function_zeta(r_ij);
460 const double temp =
461 pow(zeta, params[n]-1.) * pow(params[beta],params[n]);
462 const double cutoff = function_cutoff(r_ij.distance);
463 const double tempres = (cutoff == 0.) ?
464 0. : cutoff *
465 function_smoother(
466 -params[B],
467 params[mu],
468 r_ij.distance)
469 * function_prefactor(
470 params[beta],
471 zeta)
472 * (-1.) * temp / (1.+temp*zeta);
473 double factor = function_derivative_h(r_ij);
474 result += tempres*factor;
475 if (result != result)
476 ELOG(1, "result is NaN, zeta=" << zeta << ", temp=" << temp << ", cutoff=" << cutoff << ", tempres=" << tempres << ", factor=" << factor);
477 break;
478 }
479 default:
480 ASSERT(0, "ManyBodyPotential_Tersoff::parameter_derivative() - derivative to unknown parameter desired.");
481 break;
482 }
483 if (result != result)
484 ELOG(1, "result is NaN.");
485 }
486 return results_t(1,-result);
487}
488
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
562ManyBodyPotential_Tersoff::result_t
563ManyBodyPotential_Tersoff::function_cutoff(
564 const double &distance
565 ) const
566{
567// Info info(__func__);
568 double result = 0.;
569 if (distance < R)
570 result = 1.;
571 else if (distance > S)
572 result = 0.;
573 else {
574 result = (0.5 + 0.5 * cos( M_PI * (distance - R)/(S-R)));
575 }
576// LOG(2, "DEBUG: function_cutoff(" << distance << ") = " << result);
577 return result;
578}
579
580ManyBodyPotential_Tersoff::result_t
581ManyBodyPotential_Tersoff::function_prefactor(
582 const double &alpha,
583 const double &eta
584 ) const
585{
586// Info info(__func__);
587 const double result = chi * pow(
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;
605}
606
607ManyBodyPotential_Tersoff::result_t
608ManyBodyPotential_Tersoff::function_eta(
609 const argument_t &r_ij
610 ) const
611{
612// Info info(__func__);
613 result_t result = 0.;
614
615 // get all triples within the cutoff
616 std::vector<arguments_t> triples = triplefunction(r_ij, S);
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)
623 * exp( Helpers::pow(lambda3 * (r_ij.distance - r_ik.distance) ,3));
624 }
625
626// LOG(2, "DEBUG: function_eta(" << r_ij.distance << ") = " << result);
627 return result;
628}
629
630ManyBodyPotential_Tersoff::result_t
631ManyBodyPotential_Tersoff::function_zeta(
632 const argument_t &r_ij
633 ) const
634{
635// Info info(__func__);
636 result_t result = 0.;
637
638 // get all triples within the cutoff
639 std::vector<arguments_t> triples = triplefunction(r_ij, S);
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)
648 * omega
649 * function_angle(r_ij.distance, r_ik.distance, r_jk.distance)
650 * exp( Helpers::pow(lambda3 * (r_ij.distance - r_ik.distance) ,3));
651 }
652
653// LOG(2, "DEBUG: function_zeta(" << r_ij.distance << ") = " << result);
654 return result;
655}
656
657ManyBodyPotential_Tersoff::result_t
658ManyBodyPotential_Tersoff::function_theta(
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);
665 const double divisor = 2.* r_ij * r_ik;
666 if (divisor != 0.) {
667 LOG(2, "DEBUG: cos(theta)= " << angle/divisor);
668 return angle/divisor;
669 } else
670 return 0.;
671}
672
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) +
685 Helpers::pow(params[h] - function_theta(r_ij, r_ik, r_jk),2));
686
687// LOG(2, "DEBUG: function_angle(" << r_ij << "," << r_ik << "," << r_jk << ") = " << result);
688 return result;
689}
690
691FunctionModel::extractor_t
692ManyBodyPotential_Tersoff::getSpecificExtractor() const
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
702FunctionModel::filter_t ManyBodyPotential_Tersoff::getSpecificFilter() const
703{
704 FunctionModel::filter_t returnfunction =
705 boost::bind(&Extractors::filterArgumentsByParticleTypes,
706 _1,
707 getParticleTypes());
708 return returnfunction;
709}
710
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.