source: src/Tesselation/unittests/Tesselation_InsideOutsideUnitTest.cpp@ b9d387

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

FIX: As we use GSL internally, we are as of now required to use GPL v2 license.

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