source: src/Tesselation/unittests/Tesselation_InsideOutsideUnitTest.cpp@ 6dc3fe

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 6dc3fe was 53bc04, checked in by Frederik Heber <heber@…>, 13 years ago

BUG: Added spherical and non-convex test cases to Tesselation_InsideOutsideUnitTest.

  • we now test not only on cube, but also on sphere and a non-convex shape.
  • creation is generalized to allow for different shapes, also we use extension of VectorSet to allow for transformations.
  • TESTFIX: Added Tesselation_InOutsideUnitTestto XFAILs. Merge with enhancement of the test.
  • 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) 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_InsideOutsideUnitTest.cpp
10 *
11 * Created on: Dec 28, 2009
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 "Atom/TesselPoint.hpp"
30#include "CodePatterns/Log.hpp"
31#include "Helpers/defs.hpp"
32#include "LinearAlgebra/RealSpaceMatrix.hpp"
33#include "LinkedCell/PointCloudAdaptor.hpp"
34#include "Tesselation/BoundaryLineSet.hpp"
35#include "Tesselation/BoundaryTriangleSet.hpp"
36#include "Tesselation/CandidateForTesselation.hpp"
37#include "Tesselation/tesselation.hpp"
38
39#include "Tesselation_InsideOutsideUnitTest.hpp"
40
41#ifdef HAVE_TESTRUNNER
42#include "UnitTestMain.hpp"
43#endif /*HAVE_TESTRUNNER*/
44
45/********************************************** Test classes **************************************/
46
47// Registers the fixture into the 'registry'
48CPPUNIT_TEST_SUITE_REGISTRATION( TesselationInOutsideTest );
49
50/** Creates TesselPoints out of given Vector's.
51 *
52 * @param Vectors given vector with Vector's as positions for TesselPoint's
53 */
54void TesselationInOutsideTest::prepareCorners(const std::vector<Vector> &Vectors)
55{
56 class TesselPoint *Walker;
57 size_t index = 0;
58 for (std::vector<Vector>::const_iterator iter = Vectors.begin();
59 iter != Vectors.end(); ++iter) {
60 Walker = new TesselPoint;
61 Walker->setPosition( *iter );
62 Walker->setNr(index++);
63 Walker->setName(toString(index)); // yes, name is one higher than index
64 Corners.push_back(Walker);
65 }
66}
67
68/** Prepares Vector's in such a way that the mesh forms a cube.
69 *
70 * @param vectors vector of Vector's to work on
71 * @param factor factor to expand mesh
72 * @param offset offset to translate mesh
73 * @param return vector for concatenation
74 */
75std::vector<Vector> TesselationInOutsideTest::translateAndexpand(
76 VECTORSET(std::vector) Vectors, const double factor, const Vector &offset) const
77{
78 RealSpaceMatrix M;
79 M.setIdentity();
80 M *= factor;
81 Vectors.transform(M);
82 Vectors.translate(offset);
83 return Vectors;
84}
85
86/** Prepares Vector's in such a way that the mesh forms a cube.
87 *
88 */
89std::vector<Vector> TesselationInOutsideTest::setupCube() const
90{
91 std::vector<Vector> returnVectors;
92 returnVectors.push_back( Vector(0., 0., 0.) );
93 returnVectors.push_back( Vector(0., 1., 0.) );
94 returnVectors.push_back( Vector(1., 0., 0.) );
95 returnVectors.push_back( Vector(1., 1., 0.) );
96 returnVectors.push_back( Vector(0., 0., 1.) );
97 returnVectors.push_back( Vector(0., 1., 1.) );
98 returnVectors.push_back( Vector(1., 0., 1.) );
99 returnVectors.push_back( Vector(1., 1., 1.) );
100 return returnVectors;
101}
102
103/** Prepares Vector's in such a way that the mesh forms a sphere.
104 *
105 */
106std::vector<Vector> TesselationInOutsideTest::setupSphere() const
107{
108 std::vector<Vector> returnVectors;
109 // start with a cube
110 returnVectors.push_back( Vector(0., 0., 0.) );
111 returnVectors.push_back( Vector(0., 1., 0.) );
112 returnVectors.push_back( Vector(1., 0., 0.) );
113 returnVectors.push_back( Vector(1., 1., 0.) );
114 returnVectors.push_back( Vector(0., 0., 1.) );
115 returnVectors.push_back( Vector(0., 1., 1.) );
116 returnVectors.push_back( Vector(1., 0., 1.) );
117 returnVectors.push_back( Vector(1., 1., 1.) );
118 // then add a point slightly above each face
119 returnVectors.push_back( Vector(0.5, 0.5, -0.4142136) );
120 returnVectors.push_back( Vector(0.5, 0.5, 1.4142136) );
121 returnVectors.push_back( Vector(0.5, -0.4142136, 0.5) );
122 returnVectors.push_back( Vector(0.5, 1.4142136, 0.5) );
123 returnVectors.push_back( Vector(-0.4142136, 0.5, 0.5) );
124 returnVectors.push_back( Vector(1.4142136, 0.5, 0.5) );
125 return returnVectors;
126}
127
128/** Prepares Vector's in such a way that the mesh forms a nonconvex form.
129 *
130 */
131std::vector<Vector> TesselationInOutsideTest::setupNonConvex() const
132{
133 std::vector<Vector> returnVectors;
134 // make an along the x-axis elongated cuboid
135 returnVectors.push_back( Vector(0., 0., 0.) );
136 returnVectors.push_back( Vector(0., 1., 0.) );
137 returnVectors.push_back( Vector(2., 0., 0.) );
138 returnVectors.push_back( Vector(2., 1., 0.) );
139 returnVectors.push_back( Vector(0., 0., 1.) );
140 returnVectors.push_back( Vector(0., 1., 1.) );
141 returnVectors.push_back( Vector(2., 0., 1.) );
142 returnVectors.push_back( Vector(2., 1., 1.) );
143 // add two lowered points in the middle of the elongation
144 returnVectors.push_back( Vector(1., 0.5, 0.) );
145 returnVectors.push_back( Vector(1., 0.5, 1.) );
146 returnVectors.push_back( Vector(1., 0., 0.) );
147 returnVectors.push_back( Vector(1., 0., 1.) );
148 return returnVectors;
149}
150
151/** Creates the tesselation out of current setup in \a Corners.
152 *
153 */
154void TesselationInOutsideTest::prepareTesselation(const double SPHERERADIUS)
155{
156 // create LinkedCell
157 PointCloudAdaptor< TesselPointSTLList > cloud(&Corners, "TesselPointSTLList");
158 LinkedList = new LinkedCell_deprecated(cloud, 2.*SPHERERADIUS);
159
160 // create tesselation
161 TesselStruct = new Tesselation;
162 (*TesselStruct)(cloud, SPHERERADIUS);
163}
164
165/** Removes any currently present tesselation.
166 *
167 */
168void TesselationInOutsideTest::removeTesselation()
169{
170 delete LinkedList;
171 delete TesselStruct;
172 for (TesselPointSTLList::iterator Runner = Corners.begin(); Runner != Corners.end(); Runner++)
173 delete *Runner;
174
175 LinkedList = NULL;
176 TesselStruct = NULL;
177}
178
179void TesselationInOutsideTest::setUp()
180{
181 setVerbosity(6);
182}
183
184void TesselationInOutsideTest::tearDown()
185{
186 removeTesselation();
187 Corners.clear();
188 logger::purgeInstance();
189 errorLogger::purgeInstance();
190}
191
192/** UnitTest for Tesselation::IsInnerPoint() with a cube mesh
193 */
194void TesselationInOutsideTest::IsInnerPointCubeTest()
195{
196 {
197 const double SPHERERADIUS = 2.;
198 prepareCorners( translateAndexpand( setupCube(), 1., Vector(0.,0.,0.)) );
199 prepareTesselation(SPHERERADIUS);
200 CPPUNIT_ASSERT( TesselStruct != NULL );
201 PointCloudAdaptor< TesselPointSTLList > cloud(&Corners, "TesselPointSTLList");
202 TesselStruct->Output("cube", cloud);
203 double n[3];
204 const double boundary = 2.;
205 const double step = 1.;
206 // go through the cube and check each point
207 for (n[0] = -boundary; n[0] <= boundary; n[0]+=step)
208 for (n[1] = -boundary; n[1] <= boundary; n[1]+=step)
209 for (n[2] = -boundary; n[2] <= boundary; n[2]+=step) {
210 const Vector testPoint(n[0], n[1], n[2]);
211 if ( ((n[0] >= 0.) && (n[1] >= 0.) && (n[2] >= 0.)) && ((n[0] <= 1.) && (n[1] <= 1.) && (n[2] <= 1.)))
212 CPPUNIT_ASSERT_EQUAL( true , TesselStruct->IsInnerPoint(testPoint, LinkedList) );
213 else
214 CPPUNIT_ASSERT_EQUAL( false , TesselStruct->IsInnerPoint(testPoint, LinkedList) );
215 }
216 }
217}
218
219/** UnitTest for Tesselation::IsInnerPoint() with a sphere mesh
220 */
221void TesselationInOutsideTest::IsInnerPointSphereTest()
222{
223 {
224 // with radius 2, we see the opposite point which causes FindStartingTriangle() to fail
225 const double SPHERERADIUS = 1.;
226 const Vector offset(0.5,0.5,0.5);
227 const double factor = 1.;
228 prepareCorners( translateAndexpand( setupSphere(), factor, offset) );
229 prepareTesselation(SPHERERADIUS);
230 CPPUNIT_ASSERT( TesselStruct != NULL );
231 double n[3];
232 const double boundary = 2.;
233 const double step = 1.;
234 const std::vector<bool> test(1, true);
235 const Vector SphereCenter( Vector(0.5,0.5,0.5) + offset );
236 const double SphereRadius = (Vector(0.,0.,0.)+offset - SphereCenter).Norm();
237 // go through the cube and check each point
238 for (n[0] = -boundary; n[0] <= boundary; n[0]+=step)
239 for (n[1] = -boundary; n[1] <= boundary; n[1]+=step)
240 for (n[2] = -boundary; n[2] <= boundary; n[2]+=step) {
241 const Vector testPoint(n[0], n[1], n[2]);
242 // radius is actually 2. but we simply avoid the corners in this test
243 if ( testPoint.DistanceSquared(SphereCenter) <= factor*SphereRadius ) {
244 LOG(1, "INFO: Testing whether " << testPoint << " is an inner point.");
245 CPPUNIT_ASSERT_EQUAL( true , TesselStruct->IsInnerPoint(testPoint, LinkedList) );
246 } else {
247 LOG(1, "INFO: Testing whether " << testPoint << " is not an inner point.");
248 CPPUNIT_ASSERT_EQUAL( false , TesselStruct->IsInnerPoint(testPoint, LinkedList) );
249 }
250 }
251 }
252}
253
254/** UnitTest for Tesselation::IsInnerPoint() with a non-convex mesh
255 */
256void TesselationInOutsideTest::IsInnerPointNonConvexTest()
257{
258 {
259 const double SPHERERADIUS = 1.;
260 prepareCorners( translateAndexpand( setupNonConvex(), 1., Vector(0.,0.,0.)) );
261 prepareTesselation(SPHERERADIUS);
262 CPPUNIT_ASSERT( TesselStruct != NULL );
263 double n[3];
264 const double boundary = 4.;
265 const double step = 1.;
266 // go through the cube and check each point
267 for (n[0] = -boundary; n[0] <= boundary; n[0]+=step)
268 for (n[1] = -boundary; n[1] <= boundary; n[1]+=step)
269 for (n[2] = -boundary; n[2] <= boundary; n[2]+=step) {
270 const Vector testPoint(n[0], n[1], n[2]);
271 if ( ((n[0] >= 0.) && (n[1] >= 0.) && (n[2] >= 0.)) && ((n[0] <= 2.) && (n[1] <= .5) && (n[2] <= 1.))) {
272 // (y) lower half of elongated block
273 LOG(1, "INFO: Testing whether " << testPoint << " is an inner point.");
274 CPPUNIT_ASSERT_EQUAL( true , TesselStruct->IsInnerPoint(testPoint, LinkedList) );
275 } else if ( ((n[0] >= 0.) && (n[1] >= 0.5) && (n[2] >= 0.)) && ((n[0] <= 2.) && (n[1] <= 1.) && (n[2] <= 1.))) {
276 // (y) upper half of elongated block
277 if ( ((n[0] >= 0.) && (n[1] >= 0.5) && (n[2] >= 0.)) && ((n[0] <= 1.) && (n[1] <= 1.) && (n[2] <= 1.))) {
278 // (x) left side
279 if (n[0]+n[1] <= 1.) {
280 LOG(1, "INFO: Testing whether " << testPoint << " is an inner point.");
281 CPPUNIT_ASSERT_EQUAL( true , TesselStruct->IsInnerPoint(testPoint, LinkedList) );
282 } else {
283 LOG(1, "INFO: Testing whether " << testPoint << " is not an inner point.");
284 CPPUNIT_ASSERT_EQUAL( false , TesselStruct->IsInnerPoint(testPoint, LinkedList) );
285 }
286 } else {
287 // (x) right side)
288 if ((1.-n[0])+n[1] <= 1.) {
289 LOG(1, "INFO: Testing whether " << testPoint << " is an inner point.");
290 CPPUNIT_ASSERT_EQUAL( true , TesselStruct->IsInnerPoint(testPoint, LinkedList) );
291 } else {
292 LOG(1, "INFO: Testing whether " << testPoint << " is not an inner point.");
293 CPPUNIT_ASSERT_EQUAL( false , TesselStruct->IsInnerPoint(testPoint, LinkedList) );
294 }
295 }
296 } else {
297 LOG(1, "INFO: Testing whether " << testPoint << " is not an inner point.");
298 CPPUNIT_ASSERT_EQUAL( false , TesselStruct->IsInnerPoint(testPoint, LinkedList) );
299 }
300 }
301 }
302}
Note: See TracBrowser for help on using the repository browser.