/* * Project: MoleCuilder * Description: creates and alters molecular systems * Copyright (C) 2011 University of Bonn. All rights reserved. * Please see the LICENSE file or "Copyright notice" in builder.cpp for details. */ /* * LinkedCell_ModelUnitTest.cpp * * Created on: Nov 17, 2011 * Author: heber */ // include config.h #ifdef HAVE_CONFIG_H #include #endif using namespace std; #include #include #include #include #include "Box.hpp" #include "CodePatterns/Assert.hpp" #include "CodePatterns/Log.hpp" #include "LinearAlgebra/RealSpaceMatrix.hpp" #include "LinkedCell/LinkedCell.hpp" #include "LinkedCell/LinkedCell_Model.hpp" #include "LinkedCell/LinkedCell_Model_changeModel.hpp" #include "LinkedCell/LinkedCell_Model_LinkedCellArrayCache.hpp" #include "LinkedCell/LinkedCell_Model_Update.hpp" #include "LinkedCell/PointCloudAdaptor.hpp" #include "LinkedCell/unittests/defs.hpp" #include "LinkedCell_ModelUnitTest.hpp" #ifdef HAVE_TESTRUNNER #include "UnitTestMain.hpp" #endif /*HAVE_TESTRUNNER*/ /********************************************** Test classes **************************************/ // Registers the fixture into the 'registry' CPPUNIT_TEST_SUITE_REGISTRATION( LinkedCell_ModelTest ); void LinkedCell_ModelTest::setUp() { // failing asserts should be thrown ASSERT_DO(Assert::Throw); setVerbosity(3); // create diag(20.) matrix RealSpaceMatrix BoxM; BoxM.setIdentity(); BoxM *= DOMAINLENGTH; // create Box with this matrix domain = new Box(BoxM); // create LinkedCell structure with this Box LC = new LinkedCell::LinkedCell_Model(EDGELENGTH, *domain); // create a list of nodes and add to LCImpl std::vector< Vector > VectorList; for (size_t i=0;i<((size_t)floor(NUMBERCELLS));++i) VectorList.push_back(Vector((double)i*EDGELENGTH,(double)i*EDGELENGTH,(double)i*EDGELENGTH)); for (size_t i=0;isetName(std::string("Walker")+toString(i)); Walker->setPosition(VectorList[i]); NodeList.insert(Walker); } } void LinkedCell_ModelTest::tearDown() { delete LC; delete domain; // remove all nodes again for (PointSet::iterator iter = NodeList.begin(); !NodeList.empty(); iter = NodeList.begin()) { delete *iter; NodeList.erase(iter); } } /** UnitTest for correct construction */ void LinkedCell_ModelTest::AllocationTest() { // check that first cell is allocated LinkedCell::tripleIndex index; index[0] = index[1] = index[2] = 0; CPPUNIT_ASSERT(LC->N->getN()(index) != NULL); // check that very last cell is allocated index[0] = index[1] = index[2] = (size_t)floor(NUMBERCELLS)-1; CPPUNIT_ASSERT(LC->N->getN()(index) != NULL); } /** UnitTest for getSize() */ void LinkedCell_ModelTest::getSizeTest() { // check getSize() for(size_t i=0; igetSize(i)); #ifndef NDEBUG std::cout << "The following assertion is intended and is not a failure of the code." << std::endl; CPPUNIT_ASSERT_THROW( LC->getSize(4), Assert::AssertionFailure); #endif } /** UnitTest for Reset() */ void LinkedCell_ModelTest::ResetTest() { LC->Reset(); for(size_t i=0; igetSize(i)); } /** UnitTest for insertPointCloud() */ void LinkedCell_ModelTest::insertPointCloudTest() { // create the linked cell structure PointCloudAdaptor< PointSet > cloud(&NodeList, std::string("NodeList")); LC->insertPointCloud(cloud); // assure that we are updated before accessing internals CPPUNIT_ASSERT_EQUAL( true, *(LC->N->UpToDate) ); // test structure CPPUNIT_ASSERT_EQUAL(((size_t)floor(NUMBERCELLS)), LC->CellLookup.size()); LinkedCell::tripleIndex index; for (size_t i=0;i<((size_t)floor(NUMBERCELLS));++i) { index[0] = index[1] = index[2] = i; // assert that in the destined cell we have one Walker CPPUNIT_ASSERT_EQUAL((size_t)1, LC->N->getN()(index)->size()); } index[0] = 9; index[1] = index[2] = 0; // assert that in the destined cell we have one Walker CPPUNIT_ASSERT_EQUAL((size_t)0, LC->N->getN()(index)->size()); } /** UnitTest for setPartition() */ void LinkedCell_ModelTest::setPartitionTest() { RealSpaceMatrix Pmatrix = LC->Partition; RealSpaceMatrix Dmatrix = LC->Dimensions; LC->Reset(); LC->setPartition(2.*EDGELENGTH); Pmatrix *= 0.5; Dmatrix *= 0.5; CPPUNIT_ASSERT_EQUAL(Pmatrix, LC->Partition); CPPUNIT_ASSERT_EQUAL(Dmatrix, LC->Dimensions); } /** UnitTest for getStep() */ void LinkedCell_ModelTest::getStepTest() { // zero distance LinkedCell::tripleIndex index = LC->getStep(0.); for (size_t i = 0; igetStep(length); for (size_t i = 0; igetStep(length); for (size_t i = 0; igetIndexToVector(test); for (size_t i = 0; igetIndexToVector(test); for (size_t i = 0; igetIndexToVector(test); for (size_t i = 0; isetName(std::string("Walker9")); Walker->setPosition(Vector(9.8,7.6,5.4)); PointCloudAdaptor< PointSet > cloud(&NodeList, std::string("NodeList")); LC->insertPointCloud(cloud); // check addNode { LC->addNode(Walker); // assure that we are updated before accessing internals CPPUNIT_ASSERT_EQUAL( true, *(LC->N->UpToDate) ); CPPUNIT_ASSERT_EQUAL( NodeList.size()+1, LC->CellLookup.size()); LinkedCell::tripleIndex index1 = LC->getIndexToVector(Walker->getPosition()); const LinkedCell::tripleIndex &index2 = LC->CellLookup[Walker]->getIndices(); CPPUNIT_ASSERT(index1 == index2); } // check moveNode { LinkedCell::tripleIndex index1 = LC->getIndexToVector(Walker->getPosition()); const LinkedCell::tripleIndex &index2 = LC->CellLookup[Walker]->getIndices(); Walker->setPosition(Vector(0.,0.,0.)); LinkedCell::tripleIndex newindex1 = LC->getIndexToVector(Walker->getPosition()); CPPUNIT_ASSERT( index1 != newindex1); // we have to call moveNode ourselves, as we have just added TesselPoints, not via World LC->moveNode(Walker); // assure that we are updated before accessing internals CPPUNIT_ASSERT_EQUAL( true, *(LC->N->UpToDate) ); const LinkedCell::tripleIndex &newindex2 = LC->CellLookup[Walker]->getIndices(); CPPUNIT_ASSERT( index2 != newindex2); } // check deleteNode { LC->deleteNode(Walker); // assure that we are updated before accessing internals CPPUNIT_ASSERT_EQUAL( true, *(LC->N->UpToDate) ); CPPUNIT_ASSERT_EQUAL( NodeList.size(), LC->CellLookup.size()); } delete Walker; } /** UnitTest whether lazy updates are working. */ void LinkedCell_ModelTest::lazyUpdatesTest() { // create point TesselPoint * Walker = new TesselPoint(); Walker->setName(std::string("Walker9")); Walker->setPosition(Vector(9.8,7.6,5.4)); TesselPoint * Walker2 = new TesselPoint(); Walker2->setName(std::string("Walker10")); Walker2->setPosition(Vector(9.8,7.6,5.4)); PointCloudAdaptor< PointSet > cloud(&NodeList, std::string("NodeList")); LC->insertPointCloud(cloud); // initial read operation { CPPUNIT_ASSERT( !NodeList.empty() ); LinkedCell::tripleIndex index = LC->getIndexToVector((*NodeList.begin())->getPosition()); const size_t size = LC->N->getN()(index)->size(); // this will cause the update CPPUNIT_ASSERT( size >= (size_t)1 ); } // do some write ops LC->addNode(Walker); LC->addNode(Walker2); CPPUNIT_ASSERT( LC->Changes->queue.find(Walker) != LC->Changes->queue.end() ); LinkedCell::LinkedCell_Model::Update *update = LC->Changes->queue[Walker]; Walker->setPosition(Vector(0.,0.,0.)); LC->moveNode(Walker); // check that they all reside in cache and nothing is changed so far CPPUNIT_ASSERT( LC->Changes->queue.size() > (size_t)0 ); // check that add priority is prefered over move CPPUNIT_ASSERT( LC->Changes->queue[Walker] == update ); // perform read op { LinkedCell::tripleIndex index = LC->getIndexToVector(Walker->getPosition()); CPPUNIT_ASSERT( LC->N->getN()(index)->size() >= (size_t)1 ); } // check that cache is emptied CPPUNIT_ASSERT( LC->Changes->queue.size() == (size_t)0 ); delete Walker; delete Walker2; }