FAbstractUnifKernel.hpp 5.39 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
// ===================================================================================
// 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".
// ===================================================================================
#ifndef FABSTRACTUNIFKERNEL_HPP
#define FABSTRACTUNIFKERNEL_HPP

#include "../../Utils/FGlobal.hpp"
#include "../../Utils/FTrace.hpp"
#include "../../Utils/FSmartPointer.hpp"

#include "../../Components/FAbstractKernels.hpp"

#include "../Interpolation/FInterpP2PKernels.hpp"
#include "./FUnifInterpolator.hpp"

#include "../../Containers/FTreeCoordinate.hpp"

/**
 * @author Pierre Blanchard (pierre.blanchard@inria.fr)
 * @class FAbstractUnifKernel
 * @brief
 * This kernels implement the Lagrange interpolation based FMM operators. It
 * implements all interfaces (P2P, P2M, M2M, M2L, L2L, L2P) which are required by
 * the FFmmAlgorithm and FFmmAlgorithmThread.
 *
 * @tparam CellClass Type of cell
 * @tparam ContainerClass Type of container to store particles
 * @tparam MatrixKernelClass Type of matrix kernel function
 * @tparam ORDER Lagrange interpolation order
 */
template < class CellClass,	class ContainerClass,	class MatrixKernelClass, int ORDER, int NVALS = 1>
class FAbstractUnifKernel : public FAbstractKernels< CellClass, ContainerClass>
{
protected:
  enum {nnodes = TensorTraits<ORDER>::nnodes};
48
  typedef FUnifInterpolator<ORDER,MatrixKernelClass> InterpolatorClass;
49 50 51 52 53 54 55 56 57 58 59

  /// Needed for P2M, M2M, L2L and L2P operators
  const FSmartPointer<InterpolatorClass,FSmartPointerMemory> Interpolator;
  /// Height of the entire oct-tree
  const unsigned int TreeHeight;
  /// Corner of oct-tree box
  const FPoint BoxCorner;
  /// Width of oct-tree box
  const FReal BoxWidth;
  /// Width of a leaf cell box
  const FReal BoxWidthLeaf;
60 61 62
  /// Extension of the box width ( same for all level! )
  const FReal BoxWidthExtension;

63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
  /**
   * Compute center of leaf cell from its tree coordinate.
   * @param[in] Coordinate tree coordinate
   * @return center of leaf cell
   */
  const FPoint getLeafCellCenter(const FTreeCoordinate& Coordinate) const
  {
    return FPoint(BoxCorner.getX() + (FReal(Coordinate.getX()) + FReal(.5)) * BoxWidthLeaf,
                  BoxCorner.getY() + (FReal(Coordinate.getY()) + FReal(.5)) * BoxWidthLeaf,
                  BoxCorner.getZ() + (FReal(Coordinate.getZ()) + FReal(.5)) * BoxWidthLeaf);
  }

public:
  /**
   * The constructor initializes all constant attributes and it reads the
   * precomputed and compressed M2L operators from a binary file (an
   * runtime_error is thrown if the required file is not valid).
   */
  FAbstractUnifKernel(const int inTreeHeight,
82 83
                      const FReal inBoxWidth,
                      const FPoint& inBoxCenter,
84
                      const FReal inBoxWidthExtension = 0.0)
85 86 87
    : Interpolator(new InterpolatorClass(inTreeHeight,
                                         inBoxWidth,
                                         inBoxWidthExtension)),
88 89 90
      TreeHeight(inTreeHeight),
      BoxCorner(inBoxCenter - inBoxWidth / FReal(2.)),
      BoxWidth(inBoxWidth),
91
      BoxWidthLeaf(BoxWidth / FReal(FMath::pow(2, inTreeHeight - 1))),
92
      BoxWidthExtension(inBoxWidthExtension)
93 94 95 96 97 98 99 100
  {
    /* empty */
  }

  virtual ~FAbstractUnifKernel(){
    // should not be used
  }

101
  const InterpolatorClass * getPtrToInterpolator() const
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
  { return Interpolator.getPtr(); }


  virtual void P2M(CellClass* const LeafCell,
                   const ContainerClass* const SourceParticles) = 0;


  virtual void M2M(CellClass* const FRestrict ParentCell,
                   const CellClass*const FRestrict *const FRestrict ChildCells,
                   const int TreeLevel) = 0;


  virtual void M2L(CellClass* const FRestrict TargetCell,
                   const CellClass* SourceCells[343],
                   const int NumSourceCells,
                   const int TreeLevel) = 0;


  virtual void L2L(const CellClass* const FRestrict ParentCell,
                   CellClass* FRestrict *const FRestrict ChildCells,
                   const int TreeLevel) = 0;


  virtual void L2P(const CellClass* const LeafCell,
                   ContainerClass* const TargetParticles) = 0;



  virtual void P2P(const FTreeCoordinate& /* LeafCellCoordinate */, // needed for periodic boundary conditions
                   ContainerClass* const FRestrict TargetParticles,
                   const ContainerClass* const FRestrict /*SourceParticles*/,
                   ContainerClass* const NeighborSourceParticles[27],
                   const int /* size */) = 0;


  virtual void P2PRemote(const FTreeCoordinate& /*inPosition*/,
                         ContainerClass* const FRestrict inTargets, const ContainerClass* const FRestrict /*inSources*/,
                         ContainerClass* const inNeighbors[27], const int /*inSize*/) = 0;

};





#endif //FABSTRACTUNIFKERNEL_HPP

// [--END--]