FAlgorithmBuilder.hpp 3.54 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
#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"

#ifdef ScalFMM_USE_MPI
#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.
 */
class FAlgorithmBuilder {
public:
    /** To give the informtion to the kernel */
    struct SimulationProperties{
        const int height;
        const FPoint centerOfBox;
        const FReal dimOfBox;
    };

    /** Get the simulation information from the properties (periodic or not etc.) */
    static SimulationProperties BuildKernelSimulationProperties(const int realHeight, const FPoint realCenterOfBox, const FReal realDimOfBox,
                                                   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;
            const FPoint originalBoxCenter = realCenterOfBox;

            const FReal offset = extendedBoxWidth/2;
            const FPoint extendedBoxCenter( originalBoxCenter.getX() - originalBoxWidthDiv2 + offset,
                           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
72
                                       const int periodicUpperlevel = 0){
73 74 75 76 77
    #ifdef ScalFMM_USE_MPI
        if(isPeriodic == false){
            return new FFmmAlgorithmThreadProc<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass>(FMpi::FComm(mpiComm), tree, kernel);
        }
        else{
BRAMAS Berenger's avatar
BRAMAS Berenger committed
78
            auto algo = new FFmmAlgorithmThreadProcPeriodic<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass>(FMpi::FComm(mpiComm), tree, periodicUpperlevel);
79 80 81 82 83 84 85 86
            algo->setKernel(kernel);
            return algo;
        }
    #else
        if(isPeriodic == false){
            return new FFmmAlgorithmThread<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass>(tree, kernel);
        }
        else{
BRAMAS Berenger's avatar
BRAMAS Berenger committed
87
            auto algo = new FFmmAlgorithmPeriodic<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass>(tree, periodicUpperlevel);
88 89 90 91 92 93 94 95 96 97
            algo->setKernel(kernel);
            return algo;
        }
    #endif
    }
};



#endif // FALGORITHMBUILDER_HPP