source: src/Dynamics/unittests/BondVectorsUnitTest.cpp@ f433ec

AutomationFragmentation_failures Candidate_v1.6.1 ChemicalSpaceEvaluator Exclude_Hydrogens_annealWithBondGraph ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_contraction-expansion Gui_displays_atomic_force_velocity PythonUI_with_named_parameters StoppableMakroAction TremoloParser_IncreasedPrecision
Last change on this file since f433ec was f433ec, checked in by Frederik Heber <frederik.heber@…>, 7 years ago

We now obtain weights via levmar minimization.

  • this should yield the best possible weights within the interval of [1/n,1.].
  • note that we cannot always get an exact solution because of this constraint.
  • Property mode set to 100644
File size: 9.8 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2017 Frederik Heber. 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 * BondVectorsUnitTest.cpp
25 *
26 * Created on: Jun 29, 2017
27 * Author: heber
28 */
29
30// include config.h
31#ifdef HAVE_CONFIG_H
32#include <config.h>
33#endif
34
35#include <cppunit/CompilerOutputter.h>
36#include <cppunit/extensions/TestFactoryRegistry.h>
37#include <cppunit/ui/text/TestRunner.h>
38
39#include "CodePatterns/Assert.hpp"
40#include "CodePatterns/Log.hpp"
41
42#include <boost/assign.hpp>
43
44#include "BondVectorsUnitTest.hpp"
45
46#include "Atom/atom.hpp"
47#include "Bond/bond.hpp"
48#include "Dynamics/BondVectors.hpp"
49#include "Element/periodentafel.hpp"
50#include "World.hpp"
51#include "WorldTime.hpp"
52
53#ifdef HAVE_TESTRUNNER
54#include "UnitTestMain.hpp"
55#endif /*HAVE_TESTRUNNER*/
56
57using namespace boost::assign;
58
59/********************************************** Test classes **************************************/
60
61// Registers the fixture into the 'registry'
62CPPUNIT_TEST_SUITE_REGISTRATION( BondVectorsTest );
63
64
65void BondVectorsTest::setUp()
66{
67 // failing asserts should be thrown
68 ASSERT_DO(Assert::Throw);
69
70 setVerbosity(4);
71
72 // create an atom
73 carbon = World::getInstance().getPeriode()->FindElement(6);
74 CPPUNIT_ASSERT(carbon != NULL);
75
76 _atom = World::getInstance().createAtom();
77 _atom->setType(carbon);
78 _atom->setPosition( zeroVec );
79 atoms.push_back(_atom);
80 _atom = World::getInstance().createAtom();
81 _atom->setType(carbon);
82 _atom->setPosition( Vector(1.6,0.,0.) );
83 atoms.push_back(_atom);
84 _atom = World::getInstance().createAtom();
85 _atom->setType(carbon);
86 _atom->setPosition( Vector(3.2,0.,0.) );
87 atoms.push_back(_atom);
88 _atom = World::getInstance().createAtom();
89 _atom->setType(carbon);
90 _atom->setPosition( Vector(1.6,1.6,0.) );
91 atoms.push_back(_atom);
92 _atom = World::getInstance().createAtom();
93 _atom->setType(carbon);
94 _atom->setPosition( Vector(2.8,2.8,0.) );
95 atoms.push_back(_atom);
96 _atom = World::getInstance().createAtom();
97 _atom->setType(carbon);
98 _atom->setPosition( Vector(1.6,-1.6,0.) );
99 atoms.push_back(_atom);
100 _atom = World::getInstance().createAtom();
101 _atom->setType(carbon);
102 _atom->setPosition( Vector(2.8,-1.2,0.) );
103 atoms.push_back(_atom);
104
105 bv = new BondVectors;
106}
107
108static void clearbondvector(
109 std::vector<bond::ptr> &_bondvector)
110{
111 // remove bonds
112 for (std::vector<bond::ptr>::iterator iter = _bondvector.begin();
113 !_bondvector.empty(); iter = _bondvector.begin()) {
114 (*iter)->leftatom->removeBond((*iter)->rightatom);
115 _bondvector.erase(iter);
116 }
117}
118
119
120void BondVectorsTest::tearDown()
121{
122 delete bv;
123
124 atoms.clear();
125 atomvector.clear();
126 clearbondvector(bondvector);
127 carbon = NULL;
128
129 World::purgeInstance();
130 WorldTime::purgeInstance();
131}
132
133/** Test whether current_mapped is kept up-to-date
134 *
135 */
136void BondVectorsTest::current_mappedTest()
137{
138 {
139 // gather atoms
140 atomvector += atoms[center], atoms[left];
141 // create bonds
142 bondvector += atoms[center]->addBond(atoms[left]);
143 // prepare bondvectors
144 bv->setFromAtomRange< std::vector<atom *> >(atomvector.begin(), atomvector.end(), WorldTime::getTime());
145 // get bond vectors
146 const std::vector<Vector> Bondvectors =
147 bv->getAtomsBondVectorsAtStep(*atoms[center], WorldTime::getTime());
148 // check number of bond vectors
149 CPPUNIT_ASSERT_EQUAL( Bondvectors.size(), (size_t)1 );
150 // check norm of bond vector
151 CPPUNIT_ASSERT( fabs(Bondvectors[0].Norm() - 1.) < MYEPSILON );
152
153 // clear set of atoms and use a different one
154 clearbondvector(bondvector);
155 atomvector.clear();
156 }
157
158 {
159 // gather atoms
160 atomvector += atoms[center], atoms[left], atoms[right], atoms[top];
161 // create bonds
162 bondvector +=
163 atoms[center]->addBond(atoms[left]),
164 atoms[center]->addBond(atoms[right]),
165 atoms[center]->addBond(atoms[top]);
166 // prepare bondvectors
167 bv->setFromAtomRange< std::vector<atom *> >(atomvector.begin(), atomvector.end(), WorldTime::getTime());
168 // get bond vectors
169 const std::vector<Vector> Bondvectors =
170 bv->getAtomsBondVectorsAtStep(*atoms[center], WorldTime::getTime());
171 // check number of bond vectors
172 CPPUNIT_ASSERT_EQUAL( Bondvectors.size(), (size_t)3 );
173 // check norm of bond vector
174 for (size_t i=0;i<3;++i)
175 CPPUNIT_ASSERT( fabs(Bondvectors[i].Norm() - 1.) < MYEPSILON );
176 }
177}
178
179/** Test whether calculating weights works on single bond
180 *
181 */
182void BondVectorsTest::weights_singlebondTest()
183{
184 // gather atoms
185 atomvector += atoms[center], atoms[left];
186 // create bonds
187 bondvector += atoms[center]->addBond(atoms[left]);
188 // prepare bondvectors
189 bv->setFromAtomRange< std::vector<atom *> >(atomvector.begin(), atomvector.end(), WorldTime::getTime());
190 // calculate weights
191 BondVectors::weights_t weights = bv->getWeightsForAtomAtStep(*atoms[center], WorldTime::getTime());
192 LOG(2, "DEBUG: Single bond weights are " << weights);
193 // check number of weights
194 CPPUNIT_ASSERT_EQUAL( weights.size(), (size_t)1 );
195 // check sum of weights
196 const double weight_sum = std::accumulate(weights.begin(), weights.end(), 0.);
197 CPPUNIT_ASSERT( fabs(weight_sum - 1.) < MYEPSILON );
198 // check weight
199 CPPUNIT_ASSERT( fabs(weight_sum - 1.) < 1e-10 );
200}
201
202/** Test whether calculating weights works on linear chain config
203 *
204 */
205void BondVectorsTest::weights_linearchainTest()
206{
207 // gather atoms
208 atomvector += atoms[center], atoms[left], atoms[right];
209 // create bonds
210 bondvector += atoms[center]->addBond(atoms[left]), atoms[center]->addBond(atoms[right]);
211 // prepare bondvectors
212 bv->setFromAtomRange< std::vector<atom *> >(atomvector.begin(), atomvector.end(), WorldTime::getTime());
213 // calculate weights
214 BondVectors::weights_t weights = bv->getWeightsForAtomAtStep(*atoms[center], WorldTime::getTime());
215 LOG(2, "DEBUG: Linear chain weights are " << weights);
216 // check number of weights
217 CPPUNIT_ASSERT_EQUAL( weights.size(), (size_t)2 );
218 // check sum of weights
219 const double weight_sum = std::accumulate(weights.begin(), weights.end(), 0.);
220 CPPUNIT_ASSERT( fabs(weight_sum - 1.) < 1e-10 );
221}
222
223/** Test whether calculating weights works on right angle config
224 *
225 */
226void BondVectorsTest::weights_rightangleTest()
227{
228 // gather atoms
229 atomvector += atoms[center], atoms[left], atoms[top];
230 // create bonds
231 bondvector +=
232 atoms[center]->addBond(atoms[left]),
233 atoms[center]->addBond(atoms[top]);
234 // prepare bondvectors
235 bv->setFromAtomRange< std::vector<atom *> >(atomvector.begin(), atomvector.end(), WorldTime::getTime());
236 // calculate weights
237 BondVectors::weights_t weights = bv->getWeightsForAtomAtStep(*atoms[center], WorldTime::getTime());
238 LOG(2, "DEBUG: Right angle weights are " << weights);
239 // check number of weights
240 CPPUNIT_ASSERT_EQUAL( weights.size(), (size_t)2 );
241 // check sum of weights: two independent vectors == 1+1
242 const double weight_sum = std::accumulate(weights.begin(), weights.end(), 0.);
243 CPPUNIT_ASSERT( fabs(weight_sum - 2.) < 1e-10 );
244}
245
246/** Test whether calculating weights works on triangle config
247 *
248 */
249void BondVectorsTest::weights_triangleTest()
250{
251 // gather atoms
252 atomvector += atoms[center], atoms[left], atoms[right], atoms[top];
253 // create bonds
254 bondvector +=
255 atoms[center]->addBond(atoms[left]),
256 atoms[center]->addBond(atoms[right]),
257 atoms[center]->addBond(atoms[top]);
258 // prepare bondvectors
259 bv->setFromAtomRange< std::vector<atom *> >(atomvector.begin(), atomvector.end(), WorldTime::getTime());
260 // calculate weights
261 BondVectors::weights_t weights = bv->getWeightsForAtomAtStep(*atoms[center], WorldTime::getTime());
262 LOG(2, "DEBUG: Triangle weights are " << weights);
263 // check number of weights
264 CPPUNIT_ASSERT_EQUAL( weights.size(), (size_t)3 );
265 // check sum of weights: one linear independent, two dependent vectors = 1 + 2*0.5
266 const double weight_sum = std::accumulate(weights.begin(), weights.end(), 0.);
267 CPPUNIT_ASSERT( fabs(weight_sum - 2.) < 1e-10 );
268}
269
270/** Test whether calculating weights works on complex config
271 *
272 */
273void BondVectorsTest::weights_complexTest()
274{
275 // gather atoms
276 atomvector += atoms[center], atoms[left], atoms[right], atoms[top], atoms[topright], atoms [bottomright];
277 // create bonds
278 bondvector +=
279 atoms[center]->addBond(atoms[left]),
280 atoms[center]->addBond(atoms[right]),
281 atoms[center]->addBond(atoms[top]),
282 atoms[center]->addBond(atoms[topright]),
283 atoms[center]->addBond(atoms[bottomright]);
284 // prepare bondvectors
285 bv->setFromAtomRange< std::vector<atom *> >(atomvector.begin(), atomvector.end(), WorldTime::getTime());
286 // calculate weights
287 BondVectors::weights_t weights = bv->getWeightsForAtomAtStep(*atoms[center], WorldTime::getTime());
288 LOG(2, "DEBUG: Complex weights are " << weights);
289 // check number of weights
290 CPPUNIT_ASSERT_EQUAL( weights.size(), (size_t)5 );
291 // check sum of weights
292 const double weight_sum = std::accumulate(weights.begin(), weights.end(), 0.);
293 CPPUNIT_ASSERT( fabs(weights[0] - .372244) < 1e-6 );
294 CPPUNIT_ASSERT( fabs(weights[1] - .529694) < 1e-6 );
295 CPPUNIT_ASSERT( fabs(weights[2] - .2) < 1e-6 );
296 CPPUNIT_ASSERT( fabs(weights[3] - .248464) < 1e-6 );
297 CPPUNIT_ASSERT( fabs(weights[4] - .248464) < 1e-6 );
298}
Note: See TracBrowser for help on using the repository browser.