source: src/Potentials/Specifics/unittests/ManyBodyPotential_TersoffUnitTest.cpp@ 35d171

Action_Thermostats Add_AtomRandomPerturbation Add_FitFragmentPartialChargesAction Add_RotateAroundBondAction Add_SelectAtomByNameAction Added_ParseSaveFragmentResults Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_StructOpt_integration_tests 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_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 FragmentMolecule_checks_bonddegrees GeometryObjects Gui_Fixes Gui_displays_atomic_force_velocity IndependentFragmentGrids IndependentFragmentGrids_IndividualZeroInstances IndependentFragmentGrids_IntegrationTest IndependentFragmentGrids_Sole_NN_Calculation JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks 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 35d171 was e1fe7e, checked in by Frederik Heber <heber@…>, 11 years ago

FunctionModel now uses list_of_arguments to split sequence of subsets of distances.

  • this fixes ambiguities with the set of distances: Imagine the distances within a water molecule as OH (A) and HH (B). We then may have a sequence of argument_t as AABAAB. And with the current implementation of CompoundPotential::splitUpArgumentsByModels() we would always choose the latter (and more complex) model. Hence, we make two calls to TriplePotential_Angle, instead of calls twice to PairPotential_Harmonic for A, one to PairPotential_Harmonic for B, and once to TriplePotential_Angle for AAB.
  • now, we new list looks like A,A,B,AAB where each tuple of distances can be uniquely associated with a specific potential.
  • changed signatures of EmpiricalPotential::operator(), ::derivative(), ::parameter_derivative(). This involved changing all of the current specific potentials and CompoundPotential.
  • TrainingData must discern between the InputVector_t (just all distances) and the FilteredInputVector_t (tuples of subsets of distances).
  • FunctionApproximation now has list_of_arguments_t as parameter to evaluate() and evaluate_derivative().
  • DOCU: docu change in TrainingData.
  • Property mode set to 100644
File size: 13.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 *
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;
67
68/** This function looks up all distances ik and jk to a given ij and
69 * returns a vector of pairs.
70 */
71std::vector<FunctionModel::arguments_t>
72triplefunction(const argument_t &arguments, const double cutoff)
73{
74 const ManyBodyPotential_TersoffTest::configuration_t &CurrentConfiguration =
75 ManyBodyPotential_TersoffTest::configurations[arguments.globalid];
76 std::vector<FunctionModel::arguments_t> result;
77 // go through current configuration and gather all other distances
78 ManyBodyPotential_TersoffTest::configuration_t::const_iterator firstiter =
79 CurrentConfiguration.begin();
80 std::advance(firstiter, arguments.indices.first);
81 ManyBodyPotential_TersoffTest::configuration_t::const_iterator seconditer =
82 CurrentConfiguration.begin();
83 std::advance(seconditer, arguments.indices.second);
84 for (ManyBodyPotential_TersoffTest::configuration_t::const_iterator iter =
85 CurrentConfiguration.begin();
86 iter != CurrentConfiguration.end();
87 ++iter) {
88 // skip k==i and k==j
89 if ((iter == firstiter) || (iter == seconditer))
90 continue;
91 FunctionModel::arguments_t args(2);
92 // ik
93 args[0].distance = firstiter->distance(*iter);
94 args[0].indices = std::make_pair(
95 std::distance(CurrentConfiguration.begin(), firstiter),
96 std::distance(CurrentConfiguration.begin(), iter)
97 );
98 args[0].globalid = arguments.globalid;
99 // jk
100 args[1].distance = seconditer->distance(*iter);
101 args[1].indices = std::make_pair(
102 std::distance(CurrentConfiguration.begin(), seconditer),
103 std::distance(CurrentConfiguration.begin(), iter)
104 );
105 args[1].globalid = arguments.globalid;
106 result.push_back(args);
107 }
108 return result;
109}
110
111void ManyBodyPotential_TersoffTest::setUp()
112{
113 // failing asserts should be thrown
114 ASSERT_DO(Assert::Throw);
115
116 setVerbosity(10);
117
118 // we use parameters from tremolo/defaults/tersoff/tersoff.potentials
119 // [Tersoff, '89]
120 params.resize(ManyBodyPotential_Tersoff::MAXPARAMS,0.);
121// params[ManyBodyPotential_Tersoff::R] = 1.800000e+00;
122// params[ManyBodyPotential_Tersoff::S] = 2.100000e+00;
123 params[ManyBodyPotential_Tersoff::A] = 1.393600e+03;
124 params[ManyBodyPotential_Tersoff::B] = 3.467000e+02;
125 params[ManyBodyPotential_Tersoff::lambda] = 3.487900e+00;
126 params[ManyBodyPotential_Tersoff::mu] = 2.211900e+00;
127// params[ManyBodyPotential_Tersoff::lambda3] = 0.;
128// params[ManyBodyPotential_Tersoff::alpha] = 0.;
129 params[ManyBodyPotential_Tersoff::beta] = 1.572400e-07;
130// params[ManyBodyPotential_Tersoff::chi] = 1.;
131// params[ManyBodyPotential_Tersoff::omega] = 1.;
132 params[ManyBodyPotential_Tersoff::n] = 7.275100e-01;
133 params[ManyBodyPotential_Tersoff::c] = 3.804900e+04;
134 params[ManyBodyPotential_Tersoff::d] = 4.384000e+00;
135 params[ManyBodyPotential_Tersoff::h] = -5.705800e-01;
136
137 // initial configuration as in tremolo/default/tersoff/tersoff.data with
138 // Si renamed to C.
139 // create test configurations of 5 C atoms, constructed via:
140 // for file in tersoff.vis.00?0.xyz; do
141 // echo -e "\t{\n\t\tconfiguration_t positions;\n\t\tpositions +="
142 // tail -n 5 $file | awk -F " " {'print "\t\t\t\tVector("$2","$3","$4")"(NR!=5 ? "," : ";")'}
143 // echo -e -n "\t}\n"
144 // done
145 {
146 configuration_t positions;
147 positions +=
148 Vector(1.000000e+01,1.100000e+01,1.100000e+01),
149 Vector(1.120000e+01,1.000000e+01,1.000000e+01),
150 Vector(8.800000e+00,1.000000e+01,1.000000e+01),
151 Vector(1.000000e+01,1.200000e+01,1.000000e+01),
152 Vector(1.000000e+01,1.100000e+01,1.240000e+01);
153 configurations.push_back(positions);
154 }
155 {
156 configuration_t positions;
157 positions +=
158 Vector(1.000000e+01,1.099315e+01,1.099482e+01),
159 Vector(1.119779e+01,1.000179e+01,1.000235e+01),
160 Vector(8.802208e+00,1.000179e+01,1.000235e+01),
161 Vector(1.000000e+01,1.200262e+01,9.999421e+00),
162 Vector(1.000000e+01,1.100066e+01,1.240107e+01);
163 configurations.push_back(positions);
164 }
165 {
166 configuration_t positions;
167 positions +=
168 Vector(1.000000e+01,1.097354e+01,1.098018e+01),
169 Vector(1.119164e+01,1.000675e+01,1.000902e+01),
170 Vector(8.808358e+00,1.000675e+01,1.000902e+01),
171 Vector(1.000000e+01,1.201036e+01,9.997816e+00),
172 Vector(1.000000e+01,1.100260e+01,1.240397e+01);
173 configurations.push_back(positions);
174 }
175 {
176 configuration_t positions;
177 positions +=
178 Vector(1.000000e+01,1.094419e+01,1.095884e+01),
179 Vector(1.118308e+01,1.001364e+01,1.001884e+01),
180 Vector(8.816924e+00,1.001364e+01,1.001884e+01),
181 Vector(1.000000e+01,1.202283e+01,9.995566e+00),
182 Vector(1.000000e+01,1.100570e+01,1.240790e+01);
183 configurations.push_back(positions);
184 }
185 {
186 configuration_t positions;
187 positions +=
188 Vector(1.000000e+01,1.090791e+01,1.093293e+01),
189 Vector(1.117318e+01,1.002158e+01,1.003102e+01),
190 Vector(8.826818e+00,1.002158e+01,1.003102e+01),
191 Vector(1.000000e+01,1.203924e+01,9.993210e+00),
192 Vector(1.000000e+01,1.100969e+01,1.241182e+01);
193 configurations.push_back(positions);
194 }
195 {
196 configuration_t positions;
197 positions +=
198 Vector(1.000000e+01,1.086664e+01,1.090321e+01),
199 Vector(1.116216e+01,1.003043e+01,1.004546e+01),
200 Vector(8.837839e+00,1.003043e+01,1.004546e+01),
201 Vector(1.000000e+01,1.205848e+01,9.991167e+00),
202 Vector(1.000000e+01,1.101403e+01,1.241470e+01);
203 configurations.push_back(positions);
204 }
205 {
206 configuration_t positions;
207 positions +=
208 Vector(1.000000e+01,1.082297e+01,1.087033e+01),
209 Vector(1.115036e+01,1.003997e+01,1.006213e+01),
210 Vector(8.849644e+00,1.003997e+01,1.006213e+01),
211 Vector(1.000000e+01,1.207923e+01,9.989652e+00),
212 Vector(1.000000e+01,1.101786e+01,1.241577e+01);
213 configurations.push_back(positions);
214 }
215 {
216 configuration_t positions;
217 positions +=
218 Vector(1.000000e+01,1.077905e+01,1.083482e+01),
219 Vector(1.113831e+01,1.004988e+01,1.008085e+01),
220 Vector(8.861694e+00,1.004988e+01,1.008085e+01),
221 Vector(1.000000e+01,1.210048e+01,9.989022e+00),
222 Vector(1.000000e+01,1.102071e+01,1.241446e+01);
223 configurations.push_back(positions);
224 }
225 {
226 configuration_t positions;
227 positions +=
228 Vector(1.000000e+01,1.073683e+01,1.079745e+01),
229 Vector(1.112678e+01,1.005973e+01,1.010129e+01),
230 Vector(8.873218e+00,1.005973e+01,1.010129e+01),
231 Vector(1.000000e+01,1.212139e+01,9.989594e+00),
232 Vector(1.000000e+01,1.102232e+01,1.241038e+01);
233 configurations.push_back(positions);
234 }
235 {
236 configuration_t positions;
237 positions +=
238 Vector(1.000000e+01,1.069834e+01,1.075920e+01),
239 Vector(1.111685e+01,1.006891e+01,1.012296e+01),
240 Vector(8.883151e+00,1.006891e+01,1.012296e+01),
241 Vector(1.000000e+01,1.214131e+01,9.991602e+00),
242 Vector(1.000000e+01,1.102252e+01,1.240327e+01);
243 configurations.push_back(positions);
244 }
245
246 // cut from tersoff.etot via:
247 // for i in `seq 0 1 9`; do
248 // grep $i.000000e-01 tersoff.etot | awk -F" " {'print "\t\t\t\t"$2","'}
249 // done
250 // (though timestep 0 is missing and is added manually)
251 output +=
252 -1.333927e+01,
253 -1.359628e+01,
254 -1.420701e+01,
255 -1.479974e+01,
256 -1.537942e+01,
257 -1.584603e+01,
258 -1.615832e+01,
259 -1.630598e+01,
260 -1.626654e+01,
261 -1.603360e+01;
262
263 CPPUNIT_ASSERT_EQUAL( output.size(), configurations.size() );
264}
265
266void ManyBodyPotential_TersoffTest::tearDown()
267{
268 configurations.clear();
269}
270
271/** UnitTest for operator()
272 */
273void ManyBodyPotential_TersoffTest::operatorTest()
274{
275 boost::function<
276 std::vector<FunctionModel::arguments_t>(const argument_t &, const double)
277 > fct =
278 triplefunction;
279 ManyBodyPotential_Tersoff::ParticleTypes_t types =
280 boost::assign::list_of<ManyBodyPotential_Tersoff::ParticleType_t>
281 (0)(1)
282 ;
283 ManyBodyPotential_Tersoff tersoff(types);
284 tersoff.setTriplefunction(fct);
285 tersoff.setParameters(params);
286 const_cast<double &>(tersoff.R) = 1.8;
287 const_cast<double &>(tersoff.S) = 2.1;
288 for (size_t index = 0; index < configurations.size(); ++index) {
289 const configuration_t &CurrentConfiguration = configurations[index];
290 double temp = 0.;
291 for (size_t i=0; i < CurrentConfiguration.size(); ++i)
292 for (size_t j=0; j < CurrentConfiguration.size(); ++j) {
293 if (i == j)
294 continue;
295 argument_t arg;
296 arg.indices = std::make_pair(i,j);
297 arg.types = std::make_pair(0,1);
298 arg.distance = CurrentConfiguration[i].distance(CurrentConfiguration[j]);
299 arg.globalid = index; // this is needed for the triplefunction to the configuration
300 FunctionModel::arguments_t args(1,arg);
301 const ManyBodyPotential_Tersoff::results_t res =
302 tersoff( FunctionModel::list_of_arguments_t(1, 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 ... see strtod() bugs
310// LOG(2, "Comparing " << output[index] << " and " << .5*temp);
311 CPPUNIT_ASSERT(
312 Helpers::isEqual(
313 output[index],
314 .5*temp,
315 1.e-4/std::numeric_limits<double>::epsilon()
316 )
317 );
318 }
319}
320
321/** UnitTest for derivative()
322 */
323void ManyBodyPotential_TersoffTest::derivativeTest()
324{
325// boost::function<
326// std::vector<FunctionModel::arguments_t>(const argument_t &, const double)
327// > fct =
328// triplefunction;
329// ManyBodyPotential_Tersoff::ParticleTypes_t types =
330// boost::assign::list_of<ManyBodyPotential_Tersoff::ParticleType_t>
331// (0)(1)
332// ;
333// ManyBodyPotential_Tersoff tersoff(types, fct);
334// tersoff.setParameters(params);
335// CPPUNIT_ASSERT(
336// Helpers::isEqual(
337// 0.,
338// tersoff.derivative(
339// FunctionModel::list_of_arguments_t(1, FunctionModel::arguments_t(1,argument_t(1.)))
340// )[0]
341// )
342// );
343}
344
345
346/** UnitTest for parameter_derivative()
347 */
348void ManyBodyPotential_TersoffTest::parameter_derivativeTest()
349{
350// boost::function<
351// std::vector<FunctionModel::arguments_t>(const argument_t &, const double)
352// > fct =
353// triplefunction;
354// ManyBodyPotential_Tersoff::ParticleTypes_t types =
355// boost::assign::list_of<ManyBodyPotential_Tersoff::ParticleType_t>
356// (0)(1)
357// ;
358// ManyBodyPotential_Tersoff tersoff(types, fct);
359// tersoff.setParameters(params);
360// CPPUNIT_ASSERT(
361// Helpers::isEqual(
362// 0.,
363// tersoff.parameter_derivative(
364// FunctionModel::list_of_arguments_t(1, FunctionModel::arguments_t(1,argument_t(1.))),
365// 0
366// )[0]
367// )
368// );
369// CPPUNIT_ASSERT(
370// Helpers::isEqual(
371// 0.,
372// tersoff.parameter_derivative(
373// FunctionModel::list_of_arguments_t(1, FunctionModel::arguments_t(1,argument_t(1.))),
374// 1
375// )[0]
376// )
377// );
378// CPPUNIT_ASSERT(
379// Helpers::isEqual(
380// 1.,
381// tersoff.parameter_derivative(
382// FunctionModel::list_of_arguments_t(1, FunctionModel::arguments_t(1,argument_t(1.))),
383// 2
384// )[0]
385// )
386// );
387}
Note: See TracBrowser for help on using the repository browser.