source: src/Tesselation/unittests/Tesselation_BoundaryTriangleUnitTest.cpp@ c1d78c

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

FIX: Tesselation_BoundaryTriangleUnitTest did not properly removed temporary TesselPoints.

  • although we did remove them correctly in teardown(), in intermediate removals in functions we did so only via "delete triangle". This kept the TesselPoints especially in the static Observable map which causes memory corruption on program exit.
  • Property mode set to 100644
File size: 15.8 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2010-2012 University of Bonn. All rights reserved.
5 * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
6 */
7
8/*
9 * Tesselation_BoundaryTriangleUnitTest.cpp
10 *
11 * Created on: Jan 13, 2010
12 * Author: heber
13 */
14
15// include config.h
16#ifdef HAVE_CONFIG_H
17#include <config.h>
18#endif
19
20using namespace std;
21
22#include <cppunit/CompilerOutputter.h>
23#include <cppunit/extensions/TestFactoryRegistry.h>
24#include <cppunit/ui/text/TestRunner.h>
25
26#include <cstring>
27#include <iostream>
28
29#include "CodePatterns/Log.hpp"
30#include "Helpers/defs.hpp"
31#include "Atom/TesselPoint.hpp"
32#include "LinearAlgebra/Plane.hpp"
33#include "LinearAlgebra/RealSpaceMatrix.hpp"
34#include "LinearAlgebra/VectorSet.hpp"
35#include "Tesselation/BoundaryPointSet.hpp"
36#include "Tesselation/BoundaryLineSet.hpp"
37#include "Tesselation/BoundaryTriangleSet.hpp"
38#include "Tesselation/CandidateForTesselation.hpp"
39
40#include "Tesselation_BoundaryTriangleUnitTest.hpp"
41
42#ifdef HAVE_TESTRUNNER
43#include "UnitTestMain.hpp"
44#endif /*HAVE_TESTRUNNER*/
45
46const double TesselationBoundaryTriangleTest::SPHERERADIUS=2.;
47
48/********************************************** Test classes **************************************/
49
50// Registers the fixture into the 'registry'
51CPPUNIT_TEST_SUITE_REGISTRATION( TesselationBoundaryTriangleTest );
52
53
54void TesselationBoundaryTriangleTest::createTriangle(const std::vector<Vector> &Vectors)
55{
56 CPPUNIT_ASSERT_EQUAL( (size_t)NDIM, Vectors.size() );
57
58 // create nodes
59 for (size_t count = 0; count < NDIM; ++count) {
60 tesselpoints[count] = new TesselPoint;
61 tesselpoints[count]->setPosition( Vectors[count] );
62 tesselpoints[count]->setName(toString(count));
63 tesselpoints[count]->setNr(count);
64 points[count] = new BoundaryPointSet(tesselpoints[count]);
65 }
66
67 // create line
68 lines[0] = new BoundaryLineSet(points[0], points[1], 0);
69 lines[1] = new BoundaryLineSet(points[1], points[2], 1);
70 lines[2] = new BoundaryLineSet(points[0], points[2], 2);
71
72 // create triangle
73 triangle = new BoundaryTriangleSet(lines, 0);
74 Plane p(Vectors[0], Vectors[1], Vectors[2]);
75 triangle->GetNormalVector(p.getNormal());
76}
77
78/** This cleanly removes a triangle created via createTriangle() from memory.
79 *
80 */
81void TesselationBoundaryTriangleTest::removeTriangle()
82{
83 delete(triangle);
84 for (int i=0;i<NDIM;++i) {
85 // TesselPoint does not delete its vector as it only got a reference
86 delete tesselpoints[i];
87 }
88}
89
90void TesselationBoundaryTriangleTest::setUp()
91{
92 setVerbosity(5);
93
94 // create nodes
95 std::vector<Vector> Vectors;
96 Vectors.push_back( Vector(0., 0., 0.) );
97 Vectors.push_back( Vector(0., 1., 0.) );
98 Vectors.push_back( Vector(1., 0., 0.) );
99
100 // create triangle
101 createTriangle(Vectors);
102}
103
104void TesselationBoundaryTriangleTest::tearDown()
105{
106 removeTriangle();
107 logger::purgeInstance();
108 errorLogger::purgeInstance();
109}
110
111/** UnitTest for Tesselation::IsInsideTriangle()
112 */
113void TesselationBoundaryTriangleTest::IsInsideTriangleTest()
114{
115 // inside points
116 {
117 // check each endnode
118 for (size_t i=0; i< NDIM; ++i) {
119 const Vector testPoint(triangle->endpoints[i]->node->getPosition());
120 LOG(1, "INFO: Testing whether " << testPoint << " is an inner point.");
121 CPPUNIT_ASSERT( triangle->IsInsideTriangle( testPoint ) );
122 }
123 }
124
125 {
126 // check points along each BoundaryLine
127 for (size_t i=0; i< NDIM; ++i) {
128 Vector offset = triangle->endpoints[i%3]->node->getPosition();
129 Vector direction = triangle->endpoints[(i+1)%3]->node->getPosition() - offset;
130 for (double s = 0.1; s < 1.; s+= 0.1) {
131 Vector testPoint = offset + s*direction;
132 LOG(1, "INFO: Testing whether " << testPoint << " is an inner point.");
133 CPPUNIT_ASSERT( triangle->IsInsideTriangle( testPoint ) );
134 }
135 }
136 }
137
138 {
139 // check central point
140 Vector center;
141 triangle->GetCenter(center);
142 LOG(1, "INFO: Testing whether " << center << " is an inner point.");
143 CPPUNIT_ASSERT( triangle->IsInsideTriangle( center ) );
144 }
145
146 // outside points
147 {
148 // check points outside (i.e. those not in xy-plane through origin)
149 double n[3];
150 const double boundary = 4.;
151 const double step = 1.;
152 // go through the cube and check each point
153 for (n[0] = -boundary; n[0] <= boundary; n[0]+=step)
154 for (n[1] = -boundary; n[1] <= boundary; n[1]+=step)
155 for (n[2] = -boundary; n[2] <= boundary; n[2]+=step) {
156 const Vector testPoint(n[0], n[1], n[2]);
157 if (n[2] != 0) {
158 LOG(1, "INFO: Testing whether " << testPoint << " is not an inner point.");
159 CPPUNIT_ASSERT( !triangle->IsInsideTriangle( testPoint ) );
160 }
161 }
162 }
163
164 {
165 // check points within the plane but outside of triangle
166 double n[3];
167 const double boundary = 4.;
168 const double step = 1.;
169 n[2] = 0;
170 for (n[0] = -boundary; n[0] <= boundary; n[0]+=step)
171 for (n[1] = -boundary; n[1] <= boundary; n[1]+=step) {
172 const Vector testPoint(n[0], n[1], n[2]);
173 if ((n[0] >=0) && (n[1] >=0) && (n[0]<=1) && (n[1]<=1)) {
174 if (n[0]+n[1] <= 1) {
175 LOG(1, "INFO: Testing whether " << testPoint << " is an inner point.");
176 CPPUNIT_ASSERT( triangle->IsInsideTriangle( testPoint) );
177 } else {
178 LOG(1, "INFO: Testing whether " << testPoint << " is not an inner point.");
179 CPPUNIT_ASSERT( !triangle->IsInsideTriangle( testPoint) );
180 }
181 } else {
182 LOG(1, "INFO: Testing whether " << testPoint << " is not an inner point.");
183 CPPUNIT_ASSERT( !triangle->IsInsideTriangle( testPoint) );
184 }
185 }
186 }
187}
188
189/** UnitTest for Tesselation::IsInsideTriangle()
190 *
191 * We test for some specific points that occured in larger examples of the code.
192 *
193 */
194void TesselationBoundaryTriangleTest::IsInsideTriangle_specificTest()
195{
196 {
197 removeTriangle();
198 // test is from --create-micelle 200 --radius 30. --position "0,0,0" of sles.data
199 // failure is: Intersection (23.1644,24.1867,65.1272) is not inside triangle [659|Na2451,O3652,Na3762].
200 const Vector testPoint(1.57318,1.57612,10.9874);
201 const Vector testIntersection(23.1644,24.1867,65.1272);
202 std::vector<Vector> vectors;
203 vectors.push_back( Vector(23.0563,30.4673,73.7555) );
204 vectors.push_back( Vector(25.473,25.1512,68.5467) );
205 vectors.push_back( Vector(23.1644,24.1867,65.1272) );
206 createTriangle(vectors);
207 CPPUNIT_ASSERT( triangle->IsInsideTriangle( testIntersection ) );
208 }
209 {
210 removeTriangle();
211 // test is from --create-micelle 200 --radius 30. --position "0,0,0" of sles.data
212 // failure is: Intersection (20.6787,70.655,71.5657) is not inside triangle [622|Na1197,Na2166,O3366].
213 // fix is lower LINALG_MYEPSILON (not std::numeric_limits<doubble>*100 but *1e-4)
214 const Vector testPoint(1.57318,14.185,61.2155);
215 const Vector testIntersection(20.67867516517798,70.65496977054023,71.56572984946152);
216 std::vector<Vector> vectors;
217 vectors.push_back( Vector(22.9592,68.7791,77.5907) );
218 vectors.push_back( Vector(18.4729,72.0386,68.08839999999999) );
219 vectors.push_back( Vector(20.3834,71.0154,70.1443) );
220 createTriangle(vectors);
221 CPPUNIT_ASSERT( triangle->IsInsideTriangle( testIntersection ) );
222 }
223 {
224 removeTriangle();
225 // test is from --create-micelle 200 --radius 30. --position "0,0,0" of sles.data
226 // failure is:Intersection (27.56537519896,13.40256646925,6.672946688134) is not inside triangle [702|Na5016,O6388,Na6498].
227 // note that the Intersection cannot possibly lie be within the triangle!
228 // we test now against correct intersection
229 const Vector testIntersection(14.6872,36.204,39.8043);
230 std::vector<Vector> vectors;
231 vectors.push_back( Vector(10.7513,43.4247,48.4127) );
232 vectors.push_back( Vector(13.7119,37.0827,47.4203) );
233 vectors.push_back( Vector(14.6872,36.204,39.8043) );
234 createTriangle(vectors);
235 CPPUNIT_ASSERT( triangle->IsInsideTriangle( testIntersection ) );
236 }
237}
238
239/** UnitTest for Tesselation::GetClosestPointInsideTriangle()
240 *
241 * We check whether this function always returns a intersection inside the
242 * triangle.
243 *
244 */
245void TesselationBoundaryTriangleTest::GetClosestPointInsideTriangleTest()
246{
247 Vector TestIntersection;
248
249 {
250 // march through a cube mesh on triangle in xy plane
251 double n[3];
252 const double boundary = 4.;
253 const double step = 1.;
254 // go through the cube and check each point
255 for (n[0] = -boundary; n[0] <= boundary; n[0]+=step)
256 for (n[1] = -boundary; n[1] <= boundary; n[1]+=step)
257 for (n[2] = -boundary; n[2] <= boundary; n[2]+=step) {
258 const Vector testPoint(n[0], n[1], n[2]);
259 triangle->GetClosestPointInsideTriangle(testPoint, TestIntersection);
260 CPPUNIT_ASSERT( triangle->IsInsideTriangle( TestIntersection ));
261 }
262 }
263
264 removeTriangle();
265 // create better triangle;
266 VECTORSET(std::vector) Vectors;
267 Vectors.push_back( Vector(0., 0., 0.) );
268 Vectors.push_back( Vector(0., 1., 0.) );
269 Vectors.push_back( Vector(1., 0., 0.) );
270 RealSpaceMatrix M;
271 M.setRotation(M_PI/3., M_PI/4., 2.*M_PI/3.);
272 Vectors.transform(M);
273 createTriangle(Vectors);
274
275 {
276 // march through a cube mesh on rotated triangle
277 double n[3];
278 const double boundary = 4.;
279 const double step = 1.;
280 // go through the cube and check each point
281 for (n[0] = -boundary; n[0] <= boundary; n[0]+=step)
282 for (n[1] = -boundary; n[1] <= boundary; n[1]+=step)
283 for (n[2] = -boundary; n[2] <= boundary; n[2]+=step) {
284 const Vector testPoint(n[0], n[1], n[2]);
285 triangle->GetClosestPointInsideTriangle(testPoint, TestIntersection);
286 CPPUNIT_ASSERT( triangle->IsInsideTriangle( TestIntersection ));
287 }
288 }
289}
290
291/** UnitTest for Tesselation::GetClosestPointInsideTriangle()
292 *
293 * We test for some specific points that occured in larger examples of the code.
294 *
295 */
296void TesselationBoundaryTriangleTest::GetClosestPointInsideTriangle_specificTest()
297{
298 {
299 removeTriangle();
300 // test is from --create-micelle 200 --radius 30. --position "0,0,0" of sles.data
301 // failure is:Intersection (27.56537519896,13.40256646925,6.672946688134) is not inside triangle [702|Na5016,O6388,Na6498].
302 // note that the Intersection cannot possibly lie be within the triangle
303 // however, it is on its plane (off only by 2.7e-12)
304 // testPoint2 is corrected version
305 const Vector testPoint(27.56537519896,13.40256646925,6.672946688134);
306 const Vector testPoint2(14.6872,36.204,39.8043);
307 Vector testIntersection;
308 std::vector<Vector> vectors;
309 vectors.push_back( Vector(10.7513,43.4247,48.4127) );
310 vectors.push_back( Vector(13.7119,37.0827,47.4203) );
311 vectors.push_back( Vector(14.6872,36.204,39.8043) );
312 createTriangle(vectors);
313 triangle->GetClosestPointInsideTriangle(testPoint, testIntersection);
314 CPPUNIT_ASSERT ( testPoint != testIntersection );
315 CPPUNIT_ASSERT ( testPoint2 == testIntersection );
316 }
317}
318
319/** UnitTest for Tesselation::IsInnerPoint()
320 */
321void TesselationBoundaryTriangleTest::GetClosestPointOnPlaneTest()
322{
323 Vector TestIntersection;
324 Vector Point;
325
326 // simple test on y line
327 Point = Vector(-1.,0.5,0.);
328 CPPUNIT_ASSERT_EQUAL( 1., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
329 Point = Vector(0.,0.5,0.);
330 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
331 Point = Vector(-4.,0.5,0.);
332 CPPUNIT_ASSERT_EQUAL( 16., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
333 Point = Vector(0.,0.5,0.);
334 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
335
336 // simple test on x line
337 Point = Vector(0.5,-1.,0.);
338 CPPUNIT_ASSERT_EQUAL( 1., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
339 Point = Vector(0.5,0.,0.);
340 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
341 Point = Vector(0.5,-6.,0.);
342 CPPUNIT_ASSERT_EQUAL( 36., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
343 Point = Vector(0.5,0.,0.);
344 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
345
346 // simple test on slanted line
347 Point = Vector(1.,1.,0.);
348 CPPUNIT_ASSERT_EQUAL( 0.5, triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
349 Point = Vector(0.5,0.5,0.);
350 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
351 Point = Vector(5.,5.,0.);
352 CPPUNIT_ASSERT_EQUAL( 40.5, triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
353 Point = Vector(0.5,0.5,0.);
354 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
355
356 // simple test on first node
357 Point = Vector(-1.,-1.,0.);
358 CPPUNIT_ASSERT_EQUAL( 2., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
359 Point = Vector(0.,0.,0.);
360 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
361
362 // simple test on second node
363 Point = Vector(0.,2.,0.);
364 CPPUNIT_ASSERT_EQUAL( 1., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
365 Point = Vector(0.,1.,0.);
366 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
367
368 // simple test on third node
369 Point = Vector(2.,0.,0.);
370 CPPUNIT_ASSERT_EQUAL( 1., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
371 Point = Vector(1.,0.,0.);
372 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
373};
374
375/** UnitTest for Tesselation::IsInnerPoint()
376 */
377void TesselationBoundaryTriangleTest::GetClosestPointOffPlaneTest()
378{
379 Vector TestIntersection;
380 Vector Point;
381
382 // straight down/up
383 Point = Vector(1./3.,1./3.,+5.);
384 CPPUNIT_ASSERT_EQUAL( 25. , triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
385 Point = Vector(1./3.,1./3.,0.);
386 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
387 Point = Vector(1./3.,1./3.,-5.);
388 CPPUNIT_ASSERT_EQUAL( 25. , triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
389 Point = Vector(1./3.,1./3.,0.);
390 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
391
392 // simple test on y line
393 Point = Vector(-1.,0.5,+2.);
394 CPPUNIT_ASSERT_EQUAL( 5., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
395 Point = Vector(0.,0.5,0.);
396 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
397 Point = Vector(-1.,0.5,-3.);
398 CPPUNIT_ASSERT_EQUAL( 10., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
399 Point = Vector(0.,0.5,0.);
400 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
401
402 // simple test on x line
403 Point = Vector(0.5,-1.,+1.);
404 CPPUNIT_ASSERT_EQUAL( 2., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
405 Point = Vector(0.5,0.,0.);
406 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
407 Point = Vector(0.5,-1.,-2.);
408 CPPUNIT_ASSERT_EQUAL( 5., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
409 Point = Vector(0.5,0.,0.);
410 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
411
412 // simple test on slanted line
413 Point = Vector(1.,1.,+3.);
414 CPPUNIT_ASSERT_EQUAL( 9.5, triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
415 Point = Vector(0.5,0.5,0.);
416 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
417 Point = Vector(1.,1.,-4.);
418 CPPUNIT_ASSERT_EQUAL( 16.5, triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
419 Point = Vector(0.5,0.5,0.);
420 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
421
422 // simple test on first node
423 Point = Vector(-1.,-1.,5.);
424 CPPUNIT_ASSERT_EQUAL( 27., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
425 Point = Vector(0.,0.,0.);
426 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
427
428 // simple test on second node
429 Point = Vector(0.,2.,5.);
430 CPPUNIT_ASSERT_EQUAL( 26., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
431 Point = Vector(0.,1.,0.);
432 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
433
434 // simple test on third node
435 Point = Vector(2.,0.,5.);
436 CPPUNIT_ASSERT_EQUAL( 26., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
437 Point = Vector(1.,0.,0.);
438 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
439};
Note: See TracBrowser for help on using the repository browser.