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

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 Candidate_v1.7.0 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 ffc368 was ffc368, checked in by Frederik Heber <heber@…>, 13 years ago

ManyBodyPotential_Tersoff is now correctly implemented.

  • changed implementation to match with [Tersoff, '89] with incorporates configurations consisting of different elements and which is also the one implemented in tremolo (for whose ptential parameters we aim for).
  • we have unit test of operator() that checks against a set of values obtained from a brief run with tremolo of a configuration consisting of 5 carbon atoms: the results are the same by each function.
  • Property mode set to 100644
File size: 10.9 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2012 University of Bonn. All rights reserved.
5 * Please see the COPYING file or "Copyright notice" in builder.cpp for details.
6 *
7 *
8 * This file is part of MoleCuilder.
9 *
10 * MoleCuilder is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * MoleCuilder is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with MoleCuilder. If not, see <http://www.gnu.org/licenses/>.
22 */
23
24/*
25 * ManyBodyPotential_Tersoff.cpp
26 *
27 * Created on: Sep 26, 2012
28 * Author: heber
29 */
30
31
32// include config.h
33#ifdef HAVE_CONFIG_H
34#include <config.h>
35#endif
36
37#include "CodePatterns/MemDebug.hpp"
38
39#include "ManyBodyPotential_Tersoff.hpp"
40
41#include <boost/bind.hpp>
42#include <cmath>
43
44#include "CodePatterns/Assert.hpp"
45//#include "CodePatterns/Info.hpp"
46
47#include "Potentials/helpers.hpp"
48
49ManyBodyPotential_Tersoff::ManyBodyPotential_Tersoff(
50 boost::function< std::vector<arguments_t>(const argument_t &, const double)> &_triplefunction
51 ) :
52 params(parameters_t(MAXPARAMS, 0.)),
53 triplefunction(_triplefunction)
54{}
55
56ManyBodyPotential_Tersoff::ManyBodyPotential_Tersoff(
57 const double &_R,
58 const double &_S,
59 const double &_A,
60 const double &_B,
61 const double &_lambda,
62 const double &_mu,
63 const double &_lambda3,
64 const double &_alpha,
65 const double &_beta,
66 const double &_chi,
67 const double &_omega,
68 const double &_n,
69 const double &_c,
70 const double &_d,
71 const double &_h,
72 boost::function< std::vector<arguments_t>(const argument_t &, const double)> &_triplefunction) :
73 params(parameters_t(MAXPARAMS, 0.)),
74 triplefunction(_triplefunction)
75{
76// Info info(__func__);
77 params[R] = _R;
78 params[S] = _S;
79 params[A] = _A;
80 params[B] = _B;
81 params[lambda] = _lambda;
82 params[mu] = _mu;
83 params[lambda3] = _lambda3;
84 params[alpha] = _alpha;
85 params[beta] = _beta;
86 params[chi] = _chi;
87 params[omega] = _omega;
88 params[n] = _n;
89 params[c] = _c;
90 params[d] = _d;
91 params[h] = _h;
92}
93
94ManyBodyPotential_Tersoff::results_t
95ManyBodyPotential_Tersoff::operator()(
96 const arguments_t &arguments
97 ) const
98{
99// Info info(__func__);
100 const argument_t &r_ij = arguments[0];
101 const double cutoff = function_cutoff(r_ij.distance);
102 const double result = (cutoff == 0.) ?
103 0. :
104 cutoff * (
105 function_prefactor(
106 params[alpha],
107 function_eta(r_ij))
108 * function_smoother(
109 params[A],
110 params[lambda],
111 r_ij.distance)
112 +
113 function_prefactor(
114 params[beta],
115 function_zeta(r_ij))
116 * function_smoother(
117 -params[B],
118 params[mu],
119 r_ij.distance)
120 );
121// LOG(2, "DEBUG: operator()(" << r_ij.distance << ") = " << result);
122 return std::vector<result_t>(1, result);
123}
124
125ManyBodyPotential_Tersoff::derivative_components_t
126ManyBodyPotential_Tersoff::derivative(
127 const arguments_t &arguments
128 ) const
129{
130// Info info(__func__);
131 return ManyBodyPotential_Tersoff::derivative_components_t();
132}
133
134ManyBodyPotential_Tersoff::results_t
135ManyBodyPotential_Tersoff::parameter_derivative(
136 const arguments_t &arguments,
137 const size_t index
138 ) const
139{
140// Info info(__func__);
141// ASSERT( arguments.size() == 1,
142// "PairPotential_Harmonic::parameter_derivative() - requires exactly one argument.");
143 const argument_t &r_ij = arguments[0];
144 switch (index) {
145 case R:
146 {
147 const double result = 0.;
148 return results_t(1, result);
149 break;
150 }
151 case S:
152 {
153 const double result = 0.;
154 return results_t(1, result);
155 break;
156 }
157 case A:
158 {
159 const double result = 0.;
160 return results_t(1, result);
161 break;
162 }
163 case B:
164 {
165 const double result = 0.;
166 return results_t(1, result);
167 break;
168 }
169 case lambda:
170 {
171 const double cutoff = function_cutoff(r_ij.distance);
172 const double result = (cutoff == 0.) ?
173 0. :
174 -r_ij.distance * cutoff * params[lambda] * (
175 function_prefactor(
176 params[alpha],
177 function_eta(r_ij))
178 * function_smoother(
179 params[A],
180 params[lambda],
181 r_ij.distance)
182 );
183 return results_t(1, result);
184 break;
185 }
186 case mu:
187 {
188 const double cutoff = function_cutoff(r_ij.distance);
189 const double result = (cutoff == 0.) ?
190 0. :
191 -r_ij.distance * cutoff * params[mu] *(
192 function_prefactor(
193 params[beta],
194 function_zeta(r_ij))
195 * function_smoother(
196 -params[B],
197 params[mu],
198 r_ij.distance)
199 );
200 return results_t(1, result);
201 break;
202 }
203 case lambda3:
204 {
205 const double result = 0.;
206 return results_t(1, result);
207 break;
208 }
209 case alpha:
210 {
211 const double temp =
212 pow(params[alpha]*function_eta(r_ij), params[n]);
213 const double cutoff = function_cutoff(r_ij.distance);
214 const double result = (cutoff == 0.) || (params[alpha] == 0. )?
215 0. :
216 function_smoother(
217 -params[A],
218 params[lambda],
219 r_ij.distance)
220 * (-.5) * params[alpha] * (temp/params[alpha])
221 / (1. + temp)
222 ;
223 return results_t(1, result);
224 break;
225 }
226 case beta:
227 {
228 const double temp =
229 pow(params[beta]*function_zeta(r_ij), params[n]);
230 const double cutoff = function_cutoff(r_ij.distance);
231 const double result = (cutoff == 0.) || (params[beta] == 0. )?
232 0. : cutoff *
233 function_smoother(
234 -params[B],
235 params[mu],
236 r_ij.distance)
237 * (-.5) * params[beta] * (temp/params[beta])
238 / (1. + temp)
239 ;
240 return results_t(1, result);
241 break;
242 }
243 case n:
244 {
245 const double temp =
246 pow(params[beta]*function_zeta(r_ij), params[n]);
247 const double cutoff = function_cutoff(r_ij.distance);
248 const double result = (cutoff == 0.) ?
249 0. : cutoff *
250 function_smoother(
251 -params[B],
252 params[mu],
253 r_ij.distance)
254 * params[B]
255 * ( log(1.+temp)/(params[n]*params[n]) - temp
256 * (log(function_zeta(r_ij)) + log(params[beta]))
257 /(params[n]*(1.+temp)))
258 ;
259 return results_t(1, result);
260 break;
261 }
262 case c:
263 {
264 const double result = 0.;
265 return results_t(1, result);
266 break;
267 }
268 case d:
269 {
270 const double result = 0.;
271 return results_t(1, result);
272 break;
273 }
274 case h:
275 {
276 const double result = 0.;
277 return results_t(1, result);
278 break;
279 }
280 default:
281 break;
282 }
283 return results_t(1, 0.);
284}
285
286ManyBodyPotential_Tersoff::result_t
287ManyBodyPotential_Tersoff::function_cutoff(
288 const double &distance
289 ) const
290{
291// Info info(__func__);
292 double result = 0.;
293 if (distance < params[R])
294 result = 1.;
295 else if (distance > params[S])
296 result = 0.;
297 else {
298 result = (0.5 + 0.5 * cos( M_PI * (distance - params[R])/(params[S]-params[R])));
299 }
300// LOG(2, "DEBUG: function_cutoff(" << distance << ") = " << result);
301 return result;
302}
303
304ManyBodyPotential_Tersoff::result_t
305ManyBodyPotential_Tersoff::function_prefactor(
306 const double &alpha,
307 const double &eta
308 ) const
309{
310// Info info(__func__);
311 const double result = params[chi] * pow(
312 (1. + pow(alpha * eta, params[n])),
313 -1./(2.*params[n]));
314// LOG(2, "DEBUG: function_prefactor(" << alpha << "," << eta << ") = " << result);
315 return result;
316}
317
318ManyBodyPotential_Tersoff::result_t
319ManyBodyPotential_Tersoff::function_smoother(
320 const double &prefactor,
321 const double &lambda,
322 const double &distance
323 ) const
324{
325// Info info(__func__);
326 const double result = prefactor * exp(-lambda * distance);
327// LOG(2, "DEBUG: function_smoother(" << prefactor << "," << lambda << "," << distance << ") = " << result);
328 return result;
329}
330
331ManyBodyPotential_Tersoff::result_t
332ManyBodyPotential_Tersoff::function_eta(
333 const argument_t &r_ij
334 ) const
335{
336// Info info(__func__);
337 result_t result = 0.;
338
339 // get all triples within the cutoff
340 std::vector<arguments_t> triples = triplefunction(r_ij, params[S]);
341 for (std::vector<arguments_t>::const_iterator iter = triples.begin();
342 iter != triples.end(); ++iter) {
343 ASSERT( iter->size() == 2,
344 "ManyBodyPotential_Tersoff::function_zeta() - the triples result must contain of exactly two distances.");
345 const argument_t &r_ik = (*iter)[0];
346 result += function_cutoff(r_ik.distance)
347 * exp( Helpers::pow(params[lambda3] * (r_ij.distance - r_ik.distance) ,3));
348 }
349
350// LOG(2, "DEBUG: function_eta(" << r_ij.distance << ") = " << result);
351 return result;
352}
353
354ManyBodyPotential_Tersoff::result_t
355ManyBodyPotential_Tersoff::function_zeta(
356 const argument_t &r_ij
357 ) const
358{
359// Info info(__func__);
360 result_t result = 0.;
361
362 // get all triples within the cutoff
363 std::vector<arguments_t> triples = triplefunction(r_ij, params[S]);
364 for (std::vector<arguments_t>::const_iterator iter = triples.begin();
365 iter != triples.end(); ++iter) {
366 ASSERT( iter->size() == 2,
367 "ManyBodyPotential_Tersoff::function_zeta() - the triples result must contain exactly two distances.");
368 const argument_t &r_ik = (*iter)[0];
369 const argument_t &r_jk = (*iter)[1];
370 result +=
371 function_cutoff(r_ik.distance)
372 * params[omega]
373 * function_angle(r_ij.distance, r_ik.distance, r_jk.distance)
374 * exp( Helpers::pow(params[lambda3] * (r_ij.distance - r_ik.distance) ,3));
375 }
376
377// LOG(2, "DEBUG: function_zeta(" << r_ij.distance << ") = " << result);
378 return result;
379}
380
381ManyBodyPotential_Tersoff::result_t
382ManyBodyPotential_Tersoff::function_angle(
383 const double &r_ij,
384 const double &r_ik,
385 const double &r_jk
386 ) const
387{
388// Info info(__func__);
389 const double angle = Helpers::pow(r_ij,2) + Helpers::pow(r_ik,2) - Helpers::pow(r_jk,2);
390 const double divisor = 2.* r_ij * r_ik;
391// LOG(2, "DEBUG: cos(theta)= " << angle/divisor);
392 if (divisor != 0.) {
393 const double result =
394 1.
395 + (Helpers::pow(params[c]/params[d], 2))
396 - Helpers::pow(params[c], 2)/(Helpers::pow(params[d], 2) +
397 Helpers::pow(params[h] - angle/divisor,2));
398
399// LOG(2, "DEBUG: function_angle(" << r_ij << "," << r_ik << "," << r_jk << ") = " << result);
400 return result;
401 } else
402 return 0.;
403}
404
Note: See TracBrowser for help on using the repository browser.