testFmmAlgorithmPeriodic.cpp 6.81 KB
Newer Older
1
// ===================================================================================
2 3 4 5 6 7 8 9 10 11 12 13 14
// Copyright ScalFmm 2011 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.
//
// This software is governed by the CeCILL-C and LGPL licenses and
// abiding by the rules of distribution of free software.  
// 
// 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
// GNU General Public and CeCILL-C Licenses for more details.
// "http://www.cecill.info". 
// "http://www.gnu.org/licenses".
15
// ===================================================================================
16 17 18 19


#include <iostream>

20 21
#include <cstdio>
#include <cstdlib>
22

23 24
#include "../../Src/Utils/FParameters.hpp"
#include "../../Src/Utils/FTic.hpp"
25

26 27
#include "../../Src/Files/FRandomLoader.hpp"

28 29
#include "../../Src/Containers/FOctree.hpp"
#include "../../Src/Containers/FVector.hpp"
30

31
#include "../../Src/Components/FSimpleLeaf.hpp"
32

33 34
#include "../../Src/Components/FTestParticleContainer.hpp"

BRAMAS Berenger's avatar
BRAMAS Berenger committed
35
#include "../../Src/Utils/FPoint.hpp"
36

37 38
#include "../../Src/Components/FTestCell.hpp"
#include "../../Src/Components/FTestKernels.hpp"
39

40
#include "../../Src/Core/FFmmAlgorithmPeriodic.hpp"
41 42 43 44 45 46 47 48 49 50

/** This program show an example of use of
  * the fmm basic algo
  * it also check that each particles is impacted each other particles
  */


// Simply create particles and try the kernels
int main(int argc, char ** argv){
    typedef FTestCell                   CellClass;
51
    typedef FTestParticleContainer      ContainerClass;
52

53 54 55
    typedef FSimpleLeaf< ContainerClass >                     LeafClass;
    typedef FOctree< CellClass, ContainerClass , LeafClass >  OctreeClass;
    typedef FTestKernels< CellClass, ContainerClass >         KernelClass;
56

57
    typedef FFmmAlgorithmPeriodic<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass >     FmmClass;
58 59 60 61
    ///////////////////////What we do/////////////////////////////
    std::cout << ">> This executable has to be used to test the FMM algorithm.\n";
    //////////////////////////////////////////////////////////////

62 63
    const int NbLevels          = FParameters::getValue(argc,argv,"-h", 7);
    const int SizeSubLevels     = FParameters::getValue(argc,argv,"-sh", 3);
64 65 66 67 68 69 70 71 72 73
    const long NbParticles      = FParameters::getValue(argc,argv,"-nb", 1000);
    const int PeriodicDeep      = FParameters::getValue(argc,argv,"-per", 2);
    // choose in +x dir or -/+x dir or all dirs
    int PeriodicDirs          = (FParameters::existParameter(argc,argv,"-x")?DirMinusX:0) |
                                (FParameters::existParameter(argc,argv,"+x")?DirPlusX:0) |
                                (FParameters::existParameter(argc,argv,"-y")?DirMinusY:0) |
                                (FParameters::existParameter(argc,argv,"+y")?DirPlusY:0) |
                                (FParameters::existParameter(argc,argv,"-z")?DirMinusZ:0) |
                                (FParameters::existParameter(argc,argv,"+z")?DirPlusZ:0);
    if( PeriodicDirs == 0 ) PeriodicDirs =  AllDirs;
74 75 76 77 78 79

    FTic counter;

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

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

84
    FRandomLoader loader(NbParticles);
85
    OctreeClass tree(NbLevels, SizeSubLevels, loader.getBoxWidth(), loader.getCenterOfBox());
86 87 88 89 90 91 92 93

    {
        FPoint particlePosition;
        for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){
            loader.fillParticle(&particlePosition);
            tree.insert(particlePosition);
        }
    }
94 95 96 97 98 99 100 101 102 103 104

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

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

    std::cout << "Working on particles ..." << std::endl;
    counter.tic();

    KernelClass kernels;
105 106
    FmmClass algo( &tree, PeriodicDeep, PeriodicDirs);
    algo.setKernel(&kernels);
107 108 109 110 111 112 113 114
    algo.execute();

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

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

115
    { // Check that each particle has been summed with all other
116
        long long int counterNbPart = 0;
117

118 119 120 121
        tree.forEachCellLeaf([&](CellClass* cell, LeafClass* leaf){
            if(cell->getDataUp() != leaf->getSrc()->getNbParticles() ){
                    std::cout << "Problem P2M Data up = " << cell->getDataUp() <<
                                 " Size = " << leaf->getSrc()->getNbParticles() << "\n";
122 123
            }
            // we also count the number of particles.
124 125
            counterNbPart += leaf->getSrc()->getNbParticles();
        });
126

127 128
        if( counterNbPart != NbParticles){
            std::cout << "Problem global nb part, counter = " << counterNbPart << " created = " << NbParticles << std::endl;
129 130
        }
    }
131 132 133 134 135 136 137
    {
        const FTreeCoordinate repetitions = algo.repetitions();
        const int totalRepeatedBox = repetitions.getX() * repetitions.getY() * repetitions.getZ();
        std::cout << "The box is repeated " << repetitions.getX() <<" "<< repetitions.getY()<<" "<<
                     repetitions.getZ() << " there are " << totalRepeatedBox << " boxes in total\n";
        const long long NbParticlesEntireSystem = NbParticles * totalRepeatedBox;
        std::cout << "The total number of particles is "  << NbParticlesEntireSystem << "\n";
138
        FTreeCoordinate min, max;
139
        algo.repetitionsIntervals(&min, &max);
140
        std::cout << "Min is " << min << " Max is " << max << std::endl;
141

142 143 144
        tree.forEachLeaf([&](LeafClass* leaf){
            for(int idxPart = 0 ; idxPart < leaf->getSrc()->getNbParticles() ; ++idxPart ){
                if( NbParticlesEntireSystem - 1 != leaf->getSrc()->getDataDown()[idxPart]){
145
                    std::cout << "P2P probleme, should be " << NbParticlesEntireSystem - 1 <<
146
                                 " iter.data().getDataDown() "<< leaf->getSrc()->getDataDown()[idxPart] << std::endl;
147 148
                }
            }
149
        });
150 151
    }

152 153 154 155 156 157 158
    //////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////////

    return 0;
}


159