FAbstractUnifKernel.hpp 5.18 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
72
73
74
75
76
77
78
79
80
81
// ===================================================================================
// 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};
  typedef FUnifInterpolator<ORDER> InterpolatorClass;

  /// Needed for P2M, M2M, L2L and L2P operators
  const FSmartPointer<InterpolatorClass,FSmartPointerMemory> Interpolator;
  /// Needed for P2P operator
  const FSmartPointer<MatrixKernelClass,FSmartPointerMemory> MatrixKernel;
  /// 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;

  /**
   * 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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
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
    : Interpolator(new InterpolatorClass()),
      MatrixKernel(new MatrixKernelClass()),
      TreeHeight(inTreeHeight),
      BoxCorner(inBoxCenter - inBoxWidth / FReal(2.)),
      BoxWidth(inBoxWidth),
      BoxWidthLeaf(BoxWidth / FReal(FMath::pow(2, inTreeHeight - 1)))
  {
    /* empty */
  }

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

  const InterpolatorClass *const getPtrToInterpolator() const
  { 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--]