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
RevLine 
[bcf653]1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
[0aa122]4 * Copyright (C) 2010-2012 University of Bonn. All rights reserved.
[bcf653]5 * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
6 */
7
[c15ca2]8/*
[f844ef]9 * Tesselation_InsideOutsideUnitTest.cpp
[c15ca2]10 *
11 * Created on: Dec 28, 2009
12 * Author: heber
13 */
14
[bf3817]15// include config.h
16#ifdef HAVE_CONFIG_H
17#include <config.h>
18#endif
19
[c15ca2]20using namespace std;
21
22#include <cppunit/CompilerOutputter.h>
23#include <cppunit/extensions/TestFactoryRegistry.h>
24#include <cppunit/ui/text/TestRunner.h>
25
[49e1ae]26#include <cstring>
[d74077]27#include <iostream>
[49e1ae]28
[6f0841]29#include "Atom/TesselPoint.hpp"
[255829]30#include "CodePatterns/Log.hpp"
[34c43a]31#include "Helpers/defs.hpp"
[53bc04]32#include "LinearAlgebra/RealSpaceMatrix.hpp"
[53c7fc]33#include "LinkedCell/PointCloudAdaptor.hpp"
34#include "Tesselation/BoundaryLineSet.hpp"
35#include "Tesselation/BoundaryTriangleSet.hpp"
36#include "Tesselation/CandidateForTesselation.hpp"
[6f0841]37#include "Tesselation/tesselation.hpp"
[c15ca2]38
[f844ef]39#include "Tesselation_InsideOutsideUnitTest.hpp"
40
[9b6b2f]41#ifdef HAVE_TESTRUNNER
42#include "UnitTestMain.hpp"
43#endif /*HAVE_TESTRUNNER*/
44
[c15ca2]45/********************************************** Test classes **************************************/
46
47// Registers the fixture into the 'registry'
48CPPUNIT_TEST_SUITE_REGISTRATION( TesselationInOutsideTest );
49
[53bc04]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)
[c15ca2]55{
56 class TesselPoint *Walker;
[53bc04]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}
[c15ca2]150
[53bc04]151/** Creates the tesselation out of current setup in \a Corners.
152 *
153 */
154void TesselationInOutsideTest::prepareTesselation(const double SPHERERADIUS)
155{
[cc21cd]156 // create LinkedCell
[caa06ef]157 PointCloudAdaptor< TesselPointSTLList > cloud(&Corners, "TesselPointSTLList");
[6bd7e0]158 LinkedList = new LinkedCell_deprecated(cloud, 2.*SPHERERADIUS);
[c15ca2]159
160 // create tesselation
161 TesselStruct = new Tesselation;
[cc21cd]162 (*TesselStruct)(cloud, SPHERERADIUS);
[53bc04]163}
[c15ca2]164
[53bc04]165/** Removes any currently present tesselation.
166 *
167 */
168void TesselationInOutsideTest::removeTesselation()
[c15ca2]169{
[53bc04]170 delete LinkedList;
[cc21cd]171 delete TesselStruct;
[34c43a]172 for (TesselPointSTLList::iterator Runner = Corners.begin(); Runner != Corners.end(); Runner++)
[cc21cd]173 delete *Runner;
[53bc04]174
175 LinkedList = NULL;
176 TesselStruct = NULL;
177}
178
179void TesselationInOutsideTest::setUp()
180{
181 setVerbosity(6);
182}
183
184void TesselationInOutsideTest::tearDown()
185{
186 removeTesselation();
[c15ca2]187 Corners.clear();
188 logger::purgeInstance();
189 errorLogger::purgeInstance();
[53bc04]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}
[c15ca2]253
[53bc04]254/** UnitTest for Tesselation::IsInnerPoint() with a non-convex mesh
[c15ca2]255 */
[53bc04]256void TesselationInOutsideTest::IsInnerPointNonConvexTest()
[c15ca2]257{
[53bc04]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.