utestOctree.cpp 4.44 KB
Newer Older
1
// ===================================================================================
2 3 4 5
// Copyright ScalFmm 2016 INRIA, Olivier Coulaud, Bérenger Bramas,
// Matthias Messner olivier.coulaud@inria.fr, berenger.bramas@inria.fr
// This software is a computer program whose purpose is to compute the
// FMM.
6
//
7
// This software is governed by the CeCILL-C and LGPL licenses and
8
// abiding by the rules of distribution of free software.
9 10 11
// An extension to the license is given to allow static linking of scalfmm
// inside a proprietary application (no matter its license).
// See the main license file for more details.
12
//
13 14 15
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 17 18
// GNU General Public and CeCILL-C Licenses for more details.
// "http://www.cecill.info".
// "http://www.gnu.org/licenses".
19
// ===================================================================================
20 21
#include "FUTester.hpp"

BRAMAS Berenger's avatar
BRAMAS Berenger committed
22 23 24 25
#include "Containers/FOctree.hpp"
#include "Containers/FBlockAllocator.hpp"
#include "Containers/FVector.hpp"
#include "Components/FSimpleLeaf.hpp"
26

BRAMAS Berenger's avatar
BRAMAS Berenger committed
27 28
#include "Utils/FAssert.hpp"
#include "Utils/FPoint.hpp"
29

BRAMAS Berenger's avatar
BRAMAS Berenger committed
30 31
#include "Components/FBasicParticleContainer.hpp"
#include "Components/FBasicCell.hpp"
32

BRAMAS Berenger's avatar
BRAMAS Berenger committed
33
#include "Utils/FTic.hpp"
34 35 36 37 38 39 40 41 42 43

/**
  In this test we create a lot of different octree by using various height and subheigt
  then we insert particle in all leaf and we test that all leaves
  and all cells has been created.
  */


/** this class test the octree container */
class TestOctree : public FUTester<TestOctree> {
44
    typedef double FReal;
45
    typedef FBasicCell                   CellClass;
46
    typedef FBasicParticleContainer<FReal,0,FReal>      ContainerClass;
47

48 49
    typedef FSimpleLeaf<FReal, ContainerClass >                     LeafClass;
    typedef FOctree<FReal, CellClass, ContainerClass , LeafClass , FBasicBlockAllocator<CellClass> >  OctreeClass;
50 51 52 53 54 55 56 57 58 59

    // test size
    void TestAll(){
        const FReal BoxWidth = 1.0;
        const FReal BoxCenter = 0.5;

        // We try for many levels
        for(int idxHeight = 2 ; idxHeight < 8 ; ++idxHeight){

            // Compute the number of leaves for a tree of this height
berenger-bramas's avatar
berenger-bramas committed
60
            const int NbSmallBoxesPerSide = (1 << (idxHeight-1));
61 62 63 64 65 66 67 68
            const FReal SmallBoxWidth = BoxWidth / FReal(NbSmallBoxesPerSide);
            const FReal SmallBoxWidthDiv2 = SmallBoxWidth / 2;

            const int NbPart = NbSmallBoxesPerSide * NbSmallBoxesPerSide * NbSmallBoxesPerSide;

            // For each level we try many sub-levels
            for(int idxSub = 1 ; idxSub < idxHeight ; ++idxSub){

69
                OctreeClass tree(idxHeight, idxSub, BoxWidth, FPoint<FReal>(BoxCenter,BoxCenter,BoxCenter));
70 71 72 73 74

                // fill the tree
                for(int idxX = 0 ; idxX < NbSmallBoxesPerSide ; ++idxX){
                    for(int idxY = 0 ; idxY < NbSmallBoxesPerSide ; ++idxY){
                        for(int idxZ = 0 ; idxZ < NbSmallBoxesPerSide ; ++idxZ){
75
                            const FPoint<FReal> pos(FReal(idxX)*SmallBoxWidth + SmallBoxWidthDiv2,
76 77
                                                       FReal(idxY)*SmallBoxWidth + SmallBoxWidthDiv2,
                                                       FReal(idxZ)*SmallBoxWidth + SmallBoxWidthDiv2);
78
                            tree.insert(pos);
79 80 81 82 83 84 85 86 87 88 89 90
                        }
                    }
                }

                // test all cells
                OctreeClass::Iterator octreeIterator(&tree);
                octreeIterator.gotoBottomLeft();
                int nbCell = NbPart;
                for(int idxLevel = idxHeight - 1 ; idxLevel >= 1 ; --idxLevel ){
                    MortonIndex currentIndex = 0;
                    do{
                        // Morton index must increase one by one
91
                        uassert( currentIndex == octreeIterator.getCurrentGlobalIndex());
92 93 94
                        ++currentIndex;
                    } while(octreeIterator.moveRight());
                    // Then number of cells must be divided by 8 at each level
95
                    uassert(currentIndex == nbCell);
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
                    nbCell /= 8;

                    octreeIterator.moveUp();
                    octreeIterator.gotoLeft();
                }
            }
        }
    }

    // set test
    void SetTests(){
        AddTest(&TestOctree::TestAll,"Test Octree");
    }
};

// You must do this
TestClass(TestOctree)