source: src/Potentials/Specifics/ManyBodyPotential_Tersoff.cpp

Candidate_v1.6.1
Last change on this file was 9eb71b3, checked in by Frederik Heber <frederik.heber@…>, 8 years ago

Commented out MemDebug include and Memory::ignore.

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