FAlgorithmBuilder.hpp 4.42 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// ===================================================================================
// 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".
// ===================================================================================
16 17 18 19 20 21 22 23 24 25 26 27
#ifndef FALGORITHMBUILDER_HPP
#define FALGORITHMBUILDER_HPP

#include "FCoreCommon.hpp"

#include "../Utils/FGlobal.hpp"
#include "../Utils/FGlobalPeriodic.hpp"

#include "FFmmAlgorithm.hpp"
#include "FFmmAlgorithmThread.hpp"
#include "FFmmAlgorithmPeriodic.hpp"

28
#ifdef SCALFMM_USE_MPI
29 30 31 32 33 34 35 36 37 38 39 40 41 42
#include "../Utils/FMpi.hpp"
#include "FFmmAlgorithmThreadProc.hpp"
#include "FFmmAlgorithmThreadProcPeriodic.hpp"
#else
typedef int MPI_Comm;
#endif




/**
 * @brief The FAlgorithmBuilder class
 * This class manage the creation of an algorithm.
 */
43
template <class FReal>
44 45 46 47 48
class FAlgorithmBuilder {
public:
    /** To give the informtion to the kernel */
    struct SimulationProperties{
        const int height;
49
        const FPoint<FReal> centerOfBox;
50 51 52 53
        const FReal dimOfBox;
    };

    /** Get the simulation information from the properties (periodic or not etc.) */
54
    static SimulationProperties BuildKernelSimulationProperties(const int realHeight, const FPoint<FReal> realCenterOfBox, const FReal realDimOfBox,
55 56 57 58 59 60 61 62 63 64 65 66 67
                                                   const bool isPeriodic = false, const int inUpperLevel = 0){
        if( isPeriodic == false ){
            // Simply return the original data
            SimulationProperties properties = {realHeight, realCenterOfBox, realDimOfBox};
            return properties;
        }
        else{
            // Get the new data
            const int offsetRealTree(inUpperLevel + 3);
            const FReal extendedBoxWidth = realDimOfBox * FReal(1<<offsetRealTree);

            const FReal originalBoxWidth = realDimOfBox;
            const FReal originalBoxWidthDiv2 = originalBoxWidth/2.0;
68
            const FPoint<FReal> originalBoxCenter = realCenterOfBox;
69 70

            const FReal offset = extendedBoxWidth/2;
71
            const FPoint<FReal> extendedBoxCenter( originalBoxCenter.getX() - originalBoxWidthDiv2 + offset,
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
                           originalBoxCenter.getY() - originalBoxWidthDiv2 + offset,
                           originalBoxCenter.getZ() - originalBoxWidthDiv2 + offset);

            const int extendedTreeHeight = realHeight + offsetRealTree;

            SimulationProperties properties = {extendedTreeHeight, extendedBoxCenter, extendedBoxWidth};
            return properties;
        }
    }

    /**
     * Build an algorithm using mpi/periodic or not.
     */
    template<class OctreeClass, class CellClass, class ContainerClass, class KernelClass, class LeafClass>
    static FAbstractAlgorithm* BuildAlgorithm(OctreeClass*const tree, KernelClass*const kernel,
                                       const MPI_Comm mpiComm = (MPI_Comm)0, const bool isPeriodic = false,
BRAMAS Berenger's avatar
BRAMAS Berenger committed
88
                                       const int periodicUpperlevel = 0){
89
    #ifdef SCALFMM_USE_MPI
90 91 92 93
        if(isPeriodic == false){
            return new FFmmAlgorithmThreadProc<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass>(FMpi::FComm(mpiComm), tree, kernel);
        }
        else{
94
            auto algo = new FFmmAlgorithmThreadProcPeriodic<FReal, OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass>(FMpi::FComm(mpiComm), tree, periodicUpperlevel);
95 96 97 98 99 100 101 102
            algo->setKernel(kernel);
            return algo;
        }
    #else
        if(isPeriodic == false){
            return new FFmmAlgorithmThread<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass>(tree, kernel);
        }
        else{
103
            auto algo = new FFmmAlgorithmPeriodic<FReal,OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass>(tree, periodicUpperlevel);
104 105 106 107 108 109 110 111 112 113
            algo->setKernel(kernel);
            return algo;
        }
    #endif
    }
};



#endif // FALGORITHMBUILDER_HPP