testOctreeRearrange.cpp 8.27 KB
Newer Older
1
// See LICENCE file at project root
2 3 4

#include <iostream>

5 6
#include <cstdio>
#include <cstdlib>
7

COULAUD Olivier's avatar
COULAUD Olivier committed
8 9
#include "Utils/FParameters.hpp"
#include "Utils/FTic.hpp"
10

COULAUD Olivier's avatar
COULAUD Olivier committed
11 12
#include "Containers/FOctree.hpp"
#include "Containers/FVector.hpp"
13

COULAUD Olivier's avatar
COULAUD Olivier committed
14
#include "Components/FSimpleLeaf.hpp"
15

COULAUD Olivier's avatar
COULAUD Olivier committed
16
#include "Utils/FPoint.hpp"
17

COULAUD Olivier's avatar
COULAUD Olivier committed
18 19 20 21
#include "Components/FBasicParticleContainer.hpp"
#include "Components/FBasicCell.hpp"
#include "Arranger/FBasicParticleContainerIndexedMover.hpp"
#include "Kernels/P2P/FP2PParticleContainerIndexed.hpp"
22

COULAUD Olivier's avatar
COULAUD Olivier committed
23
#include "Arranger/FOctreeArranger.hpp"
24

COULAUD Olivier's avatar
COULAUD Olivier committed
25
#include "Utils/FParameterNames.hpp"
26

27 28 29

// Simply create particles and try the kernels
int main(int argc, char ** argv){
30 31 32 33 34 35
    FHelpDescribeAndExit(argc, argv,
                         "Put the particles into a tree, then change the position of some particles and update the tree.\n"
                         "This method should be used to avoid the tree reconstruction.",
                         FParameterDefinitions::NbParticles, FParameterDefinitions::OctreeHeight,
                         FParameterDefinitions::OctreeSubHeight);

36 37
    typedef double FReal;

38
    typedef FBasicCell                      CellClass;
39
    typedef FP2PParticleContainerIndexed<FReal>      ContainerClass;
40

41 42
    typedef FSimpleLeaf<FReal, ContainerClass >                     LeafClass;
    typedef FOctree<FReal, CellClass, ContainerClass , LeafClass >  OctreeClass;
43

44 45
    typedef FBasicParticleContainerIndexedMover<FReal,OctreeClass, ContainerClass> MoverClass;
    typedef FOctreeArranger<FReal, OctreeClass, ContainerClass, MoverClass> ArrangerClass;
46

47 48 49 50
    ///////////////////////What we do/////////////////////////////
    std::cout << ">> This executable has to be used to test the FMM algorithm.\n";
    //////////////////////////////////////////////////////////////

51 52
    const int NbLevels          = FParameters::getValue(argc,argv,FParameterDefinitions::OctreeHeight.options, 7);
    const int SizeSubLevels     = FParameters::getValue(argc,argv,FParameterDefinitions::OctreeSubHeight.options, 3);
53
    const FSize NbPart           = FParameters::getValue(argc,argv,FParameterDefinitions::NbParticles.options, FSize(2000000));
54 55 56

    FTic counter;

BRAMAS Berenger's avatar
BRAMAS Berenger committed
57
    srand48 ( 1 ); // volontary set seed to constant
58 59 60 61 62 63 64

    //////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////////

    const FReal BoxWidth = 1.0;
    const FReal BoxCenter = 0.5;

65
    OctreeClass tree(NbLevels, SizeSubLevels, BoxWidth, FPoint<FReal>(BoxCenter,BoxCenter,BoxCenter));
66 67 68 69 70 71 72 73 74 75 76

    //////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////////

    std::cout << "Creating & Inserting " << NbPart << " particles ..." << std::endl;
    std::cout << "\tHeight : " << NbLevels << " \t sub-height : " << SizeSubLevels << std::endl;
    counter.tic();


    {

77
        FPoint<FReal> particleToFill;
78
        for(FSize idxPart = 0 ; idxPart < NbPart ; ++idxPart){
79
            particleToFill.setPosition(
BRAMAS Berenger's avatar
BRAMAS Berenger committed
80 81 82
                        (BoxWidth*FReal(drand48())) + (BoxCenter-(BoxWidth/2)),
                        (BoxWidth*FReal(drand48())) + (BoxCenter-(BoxWidth/2)),
                        (BoxWidth*FReal(drand48())) + (BoxCenter-(BoxWidth/2)));
83
            tree.insert(particleToFill,idxPart);
84 85 86 87 88 89 90 91
        }
    }

    counter.tac();
    std::cout << "Done  " << "(@Creating and Inserting Particles = " << counter.elapsed() << "s)." << std::endl;

    //////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////////
92
    ArrangerClass arrange(&tree);
93

94 95 96 97
    // In order to test multiple displacement of particles
    //    for(int ite=0 ; ite<10 ; ++ite){
        std::cout << "Working on particles ..." << std::endl;
        counter.tic();
98

99 100 101 102 103
        { // Create new position for each particles
            OctreeClass::Iterator octreeIterator(&tree);
            octreeIterator.gotoBottomLeft();
            do{
                ContainerClass* particles = octreeIterator.getCurrentListTargets();
104
                for(FSize idxPart = 0; idxPart < particles->getNbParticles() ; ++idxPart){
105 106 107
                    particles->getPositions()[0][idxPart] = (BoxWidth*FReal(drand48())) + (BoxCenter-(BoxWidth/2));
                    particles->getPositions()[1][idxPart] = (BoxWidth*FReal(drand48())) + (BoxCenter-(BoxWidth/2));
                    particles->getPositions()[2][idxPart] = (BoxWidth*FReal(drand48())) + (BoxCenter-(BoxWidth/2));
108 109 110
                }
            } while(octreeIterator.moveRight());
        }
111

112 113
        counter.tac();
        std::cout << "Done  " << "(@Moving = " << counter.elapsed() << "s)." << std::endl;
114 115


116 117
        //////////////////////////////////////////////////////////////////////////////////
        //////////////////////////////////////////////////////////////////////////////////
118

119 120
        std::cout << "Arrange ..." << std::endl;
        counter.tic();
121

122
        //FOctreeArranger<FReal,OctreeClass, ContainerClass, TestParticle, Converter<TestParticle> > arrange(&tree);
123
        arrange.rearrange();
124 125


126 127
        counter.tac();
        std::cout << "Done  " << "(@Arrange = " << counter.elapsed() << "s)." << std::endl;
128

129 130 131
        //////////////////////////////////////////////////////////////////////////////////
        //////////////////////////////////////////////////////////////////////////////////
        //    }
132 133 134 135
    std::cout << "Test ..." << std::endl;
    counter.tic();

    { // Check that each particle has been put into the right leaf
berenger-bramas's avatar
berenger-bramas committed
136 137
        long counterPart = 0;

138
        OctreeClass::Iterator octreeIterator(&tree);
139 140 141 142
        octreeIterator.gotoBottomLeft();
        do{
            const MortonIndex leafIndex = octreeIterator.getCurrentGlobalIndex();

143
            ContainerClass* particles = octreeIterator.getCurrentListTargets();
144
            for(FSize idxPart = 0; idxPart < particles->getNbParticles() ; ++idxPart){
145 146 147
                const FPoint<FReal> particlePosition( particles->getPositions()[0][idxPart],
                                               particles->getPositions()[1][idxPart],
                                               particles->getPositions()[2][idxPart]);
148 149

                const MortonIndex particleIndex = tree.getMortonFromPosition( particlePosition );
150 151 152 153 154 155
                if( leafIndex != particleIndex){
                    std::cout << "Index problem, should be " << leafIndex <<
                                 " particleIndex "<< particleIndex << std::endl;
                }

            }
156 157 158

            counterPart += octreeIterator.getCurrentListTargets()->getNbParticles();
            if(octreeIterator.getCurrentListTargets()->getNbParticles() == 0){
159 160 161
                std::cout << "Problem, leaf is empty at index " << leafIndex << std::endl;
            }
        } while(octreeIterator.moveRight());
berenger-bramas's avatar
berenger-bramas committed
162 163 164 165

        if( counterPart != NbPart ){
            std::cout <<"Wrong particles number, should be " << NbPart << " but is " << counterPart << std::endl;
        }
166 167 168
    }

    { // Check that each particle has been summed with all other
169 170
        OctreeClass::Iterator octreeIterator(&tree);
        OctreeClass::Iterator avoidGotoLeftIterator(octreeIterator);
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201

        const int heightMinusOne = NbLevels - 1;
        for(int idxLevel = 1 ; idxLevel < heightMinusOne ; ++idxLevel ){
            // for each cells
            do{
                int countChild = 0;
                CellClass** const child = octreeIterator.getCurrentChild();
                for(int idxChild = 0 ; idxChild < 8 ; ++idxChild ){
                    if( child[idxChild] ){
                        countChild += 1;
                    }
                }

                if(countChild == 0){
                    std::cout << "Problem at level " << idxLevel << " cell has no child " << octreeIterator.getCurrentGlobalIndex() << std::endl;
                }

            } while(octreeIterator.moveRight());

            avoidGotoLeftIterator.moveDown();
            octreeIterator = avoidGotoLeftIterator;
        }
    }

    counter.tac();
    std::cout << "Done  " << "(@Test = " << counter.elapsed() << "s)." << std::endl;
    //////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////////

    return 0;
}