source: src/Potentials/Specifics/unittests/ManyBodyPotential_TersoffUnitTest.cpp@ 990a62

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 990a62 was 990a62, checked in by Frederik Heber <heber@…>, 12 years ago

FIX: Tersoff parameters lambda3, alpha, chi, and omega are now fixed.

  • for this we needed to exclude them from params. This is the cleanest way as suggested in levmar FAQ Q20.
  • Property mode set to 100644
File size: 13.0 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2012 University of Bonn. All rights reserved.
5 *
6 *
7 * This file is part of MoleCuilder.
8 *
9 * MoleCuilder is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * MoleCuilder is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with MoleCuilder. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23/*
24 * ManyBodyPotential_TersoffUnitTest.cpp
25 *
26 * Created on: Oct 04, 2012
27 * Author: heber
28 */
29
30// include config.h
31#ifdef HAVE_CONFIG_H
32#include <config.h>
33#endif
34
35using namespace std;
36
37#include <cppunit/CompilerOutputter.h>
38#include <cppunit/extensions/TestFactoryRegistry.h>
39#include <cppunit/ui/text/TestRunner.h>
40
41#include "ManyBodyPotential_TersoffUnitTest.hpp"
42
43#include <boost/assign.hpp>
44#include <boost/function.hpp>
45
46#include <limits>
47
48#include "CodePatterns/Assert.hpp"
49#include "CodePatterns/Log.hpp"
50
51#include "FunctionApproximation/FunctionArgument.hpp"
52#include "Potentials/Specifics/ManyBodyPotential_Tersoff.hpp"
53#include "Potentials/helpers.hpp"
54
55using namespace boost::assign;
56
57#ifdef HAVE_TESTRUNNER
58#include "UnitTestMain.hpp"
59#endif /*HAVE_TESTRUNNER*/
60
61/********************************************** Test classes **************************************/
62
63// Registers the fixture into the 'registry'
64CPPUNIT_TEST_SUITE_REGISTRATION( ManyBodyPotential_TersoffTest );
65
66ManyBodyPotential_TersoffTest::configurations_t ManyBodyPotential_TersoffTest::configurations;
67ManyBodyPotential_TersoffTest::configuration_t *ManyBodyPotential_TersoffTest::CurrentConfiguration = NULL;
68
69/** This function looks up all distances ik and jk to a given ij and
70 * returns a vector of pairs.
71 */
72std::vector<FunctionModel::arguments_t>
73triplefunction(const argument_t &arguments, const double cutoff)
74{
75 std::vector<FunctionModel::arguments_t> result;
76 // go through current configuration and gather all other distances
77 ManyBodyPotential_TersoffTest::configuration_t::const_iterator firstiter =
78 ManyBodyPotential_TersoffTest::CurrentConfiguration->begin();
79 std::advance(firstiter, arguments.indices.first);
80 ManyBodyPotential_TersoffTest::configuration_t::const_iterator seconditer =
81 ManyBodyPotential_TersoffTest::CurrentConfiguration->begin();
82 std::advance(seconditer, arguments.indices.second);
83 for (ManyBodyPotential_TersoffTest::configuration_t::const_iterator iter =
84 ManyBodyPotential_TersoffTest::CurrentConfiguration->begin();
85 iter != ManyBodyPotential_TersoffTest::CurrentConfiguration->end();
86 ++iter) {
87 // skip k==i and k==j
88 if ((iter == firstiter) || (iter == seconditer))
89 continue;
90 FunctionModel::arguments_t args(2);
91 // ik
92 args[0].distance = firstiter->distance(*iter);
93 args[0].indices = std::make_pair(
94 std::distance( // enforce const_iterator return from begin()
95 const_cast<const ManyBodyPotential_TersoffTest::configuration_t *>(
96 ManyBodyPotential_TersoffTest::CurrentConfiguration
97 )->begin(), firstiter),
98 std::distance( // enforce const_iterator return from begin()
99 const_cast<const ManyBodyPotential_TersoffTest::configuration_t *>(
100 ManyBodyPotential_TersoffTest::CurrentConfiguration
101 )->begin(), iter)
102 );
103 // jk
104 args[1].distance = seconditer->distance(*iter);
105 args[1].indices = std::make_pair(
106 std::distance( // enforce const_iterator return from begin()
107 const_cast<const ManyBodyPotential_TersoffTest::configuration_t *>(
108 ManyBodyPotential_TersoffTest::CurrentConfiguration
109 )->begin(), seconditer),
110 std::distance( // enforce const_iterator return from begin()
111 const_cast<const ManyBodyPotential_TersoffTest::configuration_t *>(
112 ManyBodyPotential_TersoffTest::CurrentConfiguration
113 )->begin(), iter)
114 );
115 result.push_back(args);
116 }
117 return result;
118}
119
120void ManyBodyPotential_TersoffTest::setUp()
121{
122 // failing asserts should be thrown
123 ASSERT_DO(Assert::Throw);
124
125 setVerbosity(10);
126
127 // we use parameters from tremolo/defaults/tersoff/tersoff.potentials
128 // [Tersoff, '89]
129 params.resize(ManyBodyPotential_Tersoff::MAXPARAMS,0.);
130 params[ManyBodyPotential_Tersoff::R] = 1.800000e+00;
131 params[ManyBodyPotential_Tersoff::S] = 2.100000e+00;
132 params[ManyBodyPotential_Tersoff::A] = 1.393600e+03;
133 params[ManyBodyPotential_Tersoff::B] = 3.467000e+02;
134 params[ManyBodyPotential_Tersoff::lambda] = 3.487900e+00;
135 params[ManyBodyPotential_Tersoff::mu] = 2.211900e+00;
136// params[ManyBodyPotential_Tersoff::lambda3] = 0.;
137// params[ManyBodyPotential_Tersoff::alpha] = 0.;
138 params[ManyBodyPotential_Tersoff::beta] = 1.572400e-07;
139// params[ManyBodyPotential_Tersoff::chi] = 1.;
140// params[ManyBodyPotential_Tersoff::omega] = 1.;
141 params[ManyBodyPotential_Tersoff::n] = 7.275100e-01;
142 params[ManyBodyPotential_Tersoff::c] = 3.804900e+04;
143 params[ManyBodyPotential_Tersoff::d] = 4.384000e+00;
144 params[ManyBodyPotential_Tersoff::h] = -5.705800e-01;
145
146 // initial configuration as in tremolo/default/tersoff/tersoff.data with
147 // Si renamed to C.
148 // create test configurations of 5 C atoms, constructed via:
149 // for file in tersoff.vis.00?0.xyz; do
150 // echo -e "\t{\n\t\tconfiguration_t positions;\n\t\tpositions +="
151 // tail -n 5 $file | awk -F " " {'print "\t\t\t\tVector("$2","$3","$4")"(NR!=5 ? "," : ";")'}
152 // echo -e -n "\t}\n"
153 // done
154 {
155 configuration_t positions;
156 positions +=
157 Vector(1.000000e+01,1.100000e+01,1.100000e+01),
158 Vector(1.120000e+01,1.000000e+01,1.000000e+01),
159 Vector(8.800000e+00,1.000000e+01,1.000000e+01),
160 Vector(1.000000e+01,1.200000e+01,1.000000e+01),
161 Vector(1.000000e+01,1.100000e+01,1.240000e+01);
162 configurations.push_back(positions);
163 }
164 {
165 configuration_t positions;
166 positions +=
167 Vector(1.000000e+01,1.099315e+01,1.099482e+01),
168 Vector(1.119779e+01,1.000179e+01,1.000235e+01),
169 Vector(8.802208e+00,1.000179e+01,1.000235e+01),
170 Vector(1.000000e+01,1.200262e+01,9.999421e+00),
171 Vector(1.000000e+01,1.100066e+01,1.240107e+01);
172 configurations.push_back(positions);
173 }
174 {
175 configuration_t positions;
176 positions +=
177 Vector(1.000000e+01,1.097354e+01,1.098018e+01),
178 Vector(1.119164e+01,1.000675e+01,1.000902e+01),
179 Vector(8.808358e+00,1.000675e+01,1.000902e+01),
180 Vector(1.000000e+01,1.201036e+01,9.997816e+00),
181 Vector(1.000000e+01,1.100260e+01,1.240397e+01);
182 configurations.push_back(positions);
183 }
184 {
185 configuration_t positions;
186 positions +=
187 Vector(1.000000e+01,1.094419e+01,1.095884e+01),
188 Vector(1.118308e+01,1.001364e+01,1.001884e+01),
189 Vector(8.816924e+00,1.001364e+01,1.001884e+01),
190 Vector(1.000000e+01,1.202283e+01,9.995566e+00),
191 Vector(1.000000e+01,1.100570e+01,1.240790e+01);
192 configurations.push_back(positions);
193 }
194 {
195 configuration_t positions;
196 positions +=
197 Vector(1.000000e+01,1.090791e+01,1.093293e+01),
198 Vector(1.117318e+01,1.002158e+01,1.003102e+01),
199 Vector(8.826818e+00,1.002158e+01,1.003102e+01),
200 Vector(1.000000e+01,1.203924e+01,9.993210e+00),
201 Vector(1.000000e+01,1.100969e+01,1.241182e+01);
202 configurations.push_back(positions);
203 }
204 {
205 configuration_t positions;
206 positions +=
207 Vector(1.000000e+01,1.086664e+01,1.090321e+01),
208 Vector(1.116216e+01,1.003043e+01,1.004546e+01),
209 Vector(8.837839e+00,1.003043e+01,1.004546e+01),
210 Vector(1.000000e+01,1.205848e+01,9.991167e+00),
211 Vector(1.000000e+01,1.101403e+01,1.241470e+01);
212 configurations.push_back(positions);
213 }
214 {
215 configuration_t positions;
216 positions +=
217 Vector(1.000000e+01,1.082297e+01,1.087033e+01),
218 Vector(1.115036e+01,1.003997e+01,1.006213e+01),
219 Vector(8.849644e+00,1.003997e+01,1.006213e+01),
220 Vector(1.000000e+01,1.207923e+01,9.989652e+00),
221 Vector(1.000000e+01,1.101786e+01,1.241577e+01);
222 configurations.push_back(positions);
223 }
224 {
225 configuration_t positions;
226 positions +=
227 Vector(1.000000e+01,1.077905e+01,1.083482e+01),
228 Vector(1.113831e+01,1.004988e+01,1.008085e+01),
229 Vector(8.861694e+00,1.004988e+01,1.008085e+01),
230 Vector(1.000000e+01,1.210048e+01,9.989022e+00),
231 Vector(1.000000e+01,1.102071e+01,1.241446e+01);
232 configurations.push_back(positions);
233 }
234 {
235 configuration_t positions;
236 positions +=
237 Vector(1.000000e+01,1.073683e+01,1.079745e+01),
238 Vector(1.112678e+01,1.005973e+01,1.010129e+01),
239 Vector(8.873218e+00,1.005973e+01,1.010129e+01),
240 Vector(1.000000e+01,1.212139e+01,9.989594e+00),
241 Vector(1.000000e+01,1.102232e+01,1.241038e+01);
242 configurations.push_back(positions);
243 }
244 {
245 configuration_t positions;
246 positions +=
247 Vector(1.000000e+01,1.069834e+01,1.075920e+01),
248 Vector(1.111685e+01,1.006891e+01,1.012296e+01),
249 Vector(8.883151e+00,1.006891e+01,1.012296e+01),
250 Vector(1.000000e+01,1.214131e+01,9.991602e+00),
251 Vector(1.000000e+01,1.102252e+01,1.240327e+01);
252 configurations.push_back(positions);
253 }
254
255 // cut from tersoff.etot via:
256 // for i in `seq 0 1 9`; do
257 // grep $i.000000e-01 tersoff.etot | awk -F" " {'print "\t\t\t\t"$2","'}
258 // done
259 // (though timestep 0 is missing and is added manually)
260 output +=
261 -1.333927e+01,
262 -1.359628e+01,
263 -1.420701e+01,
264 -1.479974e+01,
265 -1.537942e+01,
266 -1.584603e+01,
267 -1.615832e+01,
268 -1.630598e+01,
269 -1.626654e+01,
270 -1.603360e+01;
271
272 CPPUNIT_ASSERT_EQUAL( output.size(), configurations.size() );
273}
274
275void ManyBodyPotential_TersoffTest::tearDown()
276{
277 configurations.clear();
278 CurrentConfiguration = NULL;
279}
280
281/** UnitTest for operator()
282 */
283void ManyBodyPotential_TersoffTest::operatorTest()
284{
285 boost::function<
286 std::vector<FunctionModel::arguments_t>(const argument_t &, const double)
287 > fct =
288 triplefunction;
289 ManyBodyPotential_Tersoff tersoff(fct);
290 tersoff.setParameters(params);
291 for (size_t index = 0; index < configurations.size(); ++index) {
292 CurrentConfiguration = &(configurations[index]);
293 double temp = 0.;
294 for (size_t i=0; i < CurrentConfiguration->size(); ++i)
295 for (size_t j=0; j < CurrentConfiguration->size(); ++j) {
296 if (i == j)
297 continue;
298 argument_t arg;
299 arg.indices = std::make_pair(i,j);
300 arg.distance = (*CurrentConfiguration)[i].distance((*CurrentConfiguration)[j]);
301 FunctionModel::arguments_t args(1,arg);
302 const ManyBodyPotential_Tersoff::results_t res = tersoff(args);
303 temp += res[0];
304 }
305 // this little precision is because tremolo does seem to handle coordinates
306 // a little differently than we do, the precise difference in the x coordinate
307 // of the first and second position for the second configuration is easy to
308 // see as 1.119779. However, tremolo obtains 1.1197792 for unknown reasons.
309 // Maybe, there is some float floating around in the code ...
310 CPPUNIT_ASSERT(
311 Helpers::isEqual(
312 output[index],
313 .5*temp,
314 1.e-4/std::numeric_limits<double>::epsilon()
315 )
316 );
317 }
318}
319
320/** UnitTest for derivative()
321 */
322void ManyBodyPotential_TersoffTest::derivativeTest()
323{
324// boost::function<
325// std::vector<FunctionModel::arguments_t>(const argument_t &, const double)
326// > fct =
327// triplefunction;
328// ManyBodyPotential_Tersoff tersoff(fct);
329// tersoff.setParameters(params);
330// CPPUNIT_ASSERT(
331// Helpers::isEqual(
332// 0.,
333// tersoff.derivative(
334// FunctionModel::arguments_t(1,argument_t(1.))
335// )[0]
336// )
337// );
338}
339
340
341/** UnitTest for parameter_derivative()
342 */
343void ManyBodyPotential_TersoffTest::parameter_derivativeTest()
344{
345// boost::function<
346// std::vector<FunctionModel::arguments_t>(const argument_t &, const double)
347// > fct =
348// triplefunction;
349// ManyBodyPotential_Tersoff tersoff(fct);
350// tersoff.setParameters(params);
351// CPPUNIT_ASSERT(
352// Helpers::isEqual(
353// 0.,
354// tersoff.parameter_derivative(
355// FunctionModel::arguments_t(1,argument_t(1.)),
356// 0
357// )[0]
358// )
359// );
360// CPPUNIT_ASSERT(
361// Helpers::isEqual(
362// 0.,
363// tersoff.parameter_derivative(
364// FunctionModel::arguments_t(1,argument_t(1.)),
365// 1
366// )[0]
367// )
368// );
369// CPPUNIT_ASSERT(
370// Helpers::isEqual(
371// 1.,
372// tersoff.parameter_derivative(
373// FunctionModel::arguments_t(1,argument_t(1.)),
374// 2
375// )[0]
376// )
377// );
378}
Note: See TracBrowser for help on using the repository browser.