FAbstractChebKernel.hpp 6.38 KB
Newer Older
BRAMAS Berenger's avatar
BRAMAS Berenger committed
1
// ===================================================================================
2
// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Berenger Bramas, Matthias Messner
3 4 5 6 7 8 9 10 11 12 13 14
// 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".
BRAMAS Berenger's avatar
BRAMAS Berenger committed
15
// ===================================================================================
16 17 18
#ifndef FABSTRACTCHEBKERNEL_HPP
#define FABSTRACTCHEBKERNEL_HPP

19
#include "../../Utils/FGlobal.hpp"
20

21
#include "../../Utils/FSmartPointer.hpp"
22

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

25
#include "../Interpolation/FInterpP2PKernels.hpp"
26 27
#include "./FChebInterpolator.hpp"

28
#include "../../Containers/FTreeCoordinate.hpp"
29 30 31 32 33 34 35 36 37 38 39 40 41 42

/**
 * @author Matthias Messner(matthias.messner@inria.fr)
 * @class FAbstractChebKernel
 * @brief
 * This kernels implement the Chebyshev 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 Chebyshev interpolation order
 */
43
template < class FReal, class CellClass,	class ContainerClass,	class MatrixKernelClass, int ORDER, int NVALS = 1>
44
class FAbstractChebKernel : public FAbstractKernels< CellClass, ContainerClass>
45 46 47
{
protected:
  enum {nnodes = TensorTraits<ORDER>::nnodes};
48
  typedef FChebInterpolator<FReal, ORDER,MatrixKernelClass,NVALS> InterpolatorClass;
49 50 51 52 53 54

  /// 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
55
  const FPoint<FReal> BoxCorner;
56 57 58 59
  /// Width of oct-tree box   
  const FReal BoxWidth;    
  /// Width of a leaf cell box 
  const FReal BoxWidthLeaf;
60 61
  /// Extension of the box width ( same for all level! )
  const FReal BoxWidthExtension;
62 63 64 65 66 67

  /**
   * Compute center of leaf cell from its tree coordinate.
   * @param[in] Coordinate tree coordinate
   * @return center of leaf cell
   */
68
  const FPoint<FReal> getLeafCellCenter(const FTreeCoordinate& Coordinate) const
69
  {
70
    return FPoint<FReal>(BoxCorner.getX() + (FReal(Coordinate.getX()) + FReal(.5)) * BoxWidthLeaf,
71 72 73
		  BoxCorner.getY() + (FReal(Coordinate.getY()) + FReal(.5)) * BoxWidthLeaf,
		  BoxCorner.getZ() + (FReal(Coordinate.getZ()) + FReal(.5)) * BoxWidthLeaf);
  }
74

75 76 77 78 79 80
  /** 
   * @brief Return the position of the center of a cell from its tree
   *  coordinate 
   * @param FTreeCoordinate
   * @param inLevel the current level of Cell
   */
81
  FPoint<FReal> getCellCenter(const FTreeCoordinate coordinate, int inLevel)
82 83 84 85 86 87 88 89 90 91 92
  {

    //Set the boxes width needed
    FReal widthAtCurrentLevel = BoxWidthLeaf*FReal(1 << (TreeHeight-(inLevel+1)));   
    FReal widthAtCurrentLevelDiv2 = widthAtCurrentLevel/FReal(2.);

    //Set the center real coordinates from box corner and widths.
    FReal X = BoxCorner.getX() + FReal(coordinate.getX())*widthAtCurrentLevel + widthAtCurrentLevelDiv2;
    FReal Y = BoxCorner.getY() + FReal(coordinate.getY())*widthAtCurrentLevel + widthAtCurrentLevelDiv2;
    FReal Z = BoxCorner.getZ() + FReal(coordinate.getZ())*widthAtCurrentLevel + widthAtCurrentLevelDiv2;
    
93
    return FPoint<FReal>(X,Y,Z);
94 95
  }

96
public:
97 98 99 100 101 102
  /**
   * 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).
   */
  FAbstractChebKernel(const int inTreeHeight,
103
                      const FReal inBoxWidth,
104
                      const FPoint<FReal>& inBoxCenter,
105
                      const FReal inBoxWidthExtension = 0.0)
106 107 108
    : Interpolator(new InterpolatorClass(inTreeHeight,
                                         inBoxWidth,
                                         inBoxWidthExtension)),
109 110 111
      TreeHeight(inTreeHeight),
      BoxCorner(inBoxCenter - inBoxWidth / FReal(2.)),
      BoxWidth(inBoxWidth),
112
      BoxWidthLeaf(BoxWidth / FReal(FMath::pow(2, inTreeHeight - 1))),
113
      BoxWidthExtension(inBoxWidthExtension)
114 115 116
  {
    /* empty */
  }
117

118 119 120
  virtual ~FAbstractChebKernel(){
    // should not be used
  }
BRAMAS Berenger's avatar
BRAMAS Berenger committed
121

122
  const InterpolatorClass * getPtrToInterpolator() const
123
  { return Interpolator.getPtr(); }
124

125

126 127
  virtual void P2M(CellClass* const LeafCell,
		   const ContainerClass* const SourceParticles) = 0;
128 129


130 131 132
  virtual void M2M(CellClass* const FRestrict ParentCell,
		   const CellClass*const FRestrict *const FRestrict ChildCells,
		   const int TreeLevel) = 0;
133 134


135
  virtual void M2L(CellClass* const FRestrict TargetCell,
136 137
           const CellClass* SourceCells[],
            const int SourcePositions[],
138 139
		   const int NumSourceCells,
		   const int TreeLevel) = 0;
140 141


142 143 144
  virtual void L2L(const CellClass* const FRestrict ParentCell,
		   CellClass* FRestrict *const FRestrict ChildCells,
		   const int TreeLevel) = 0;
145 146


147 148
  virtual void L2P(const CellClass* const LeafCell,
		   ContainerClass* const TargetParticles) = 0;
149 150 151
	
	

152 153 154
  virtual void P2P(const FTreeCoordinate& /* LeafCellCoordinate */, // needed for periodic boundary conditions
		   ContainerClass* const FRestrict TargetParticles,
		   const ContainerClass* const FRestrict /*SourceParticles*/,
155 156
           ContainerClass* const NeighborSourceParticles[],
            const int SourcePositions[],
157
		   const int /* size */) = 0;
158

159 160 161 162 163
  virtual void P2POuter(const FTreeCoordinate& inLeafPosition,
           ContainerClass* const FRestrict targets,
           ContainerClass* const directNeighborsParticles[], const int neighborPositions[],
           const int size) = 0;

164

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

169 170 171
};


172

173

174

175 176 177
#endif //FCHEBKERNELS_HPP

// [--END--]