FUnifCell.hpp 9.36 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
// Keep in private GIT

18 19 20 21 22
#ifndef FUNIFCELL_HPP
#define FUNIFCELL_HPP


#include "./FUnifTensor.hpp"
23
#include "../../Components/FBasicCell.hpp"
24 25
#include "../../Extensions/FExtendCellType.hpp"

26
#include "../../Utils/FComplex.hpp"
27 28 29

/**
 * @author Pierre Blanchard (pierre.blanchard@inria.fr)
30
 *
31 32 33
 * Please read the license
 *
 * This class defines a cell used in the Lagrange based FMM.
34 35
 *
 * PB: This class also contains the storage and accessors for the transformed
36
 * expansion (in Fourier space, i.e. complex valued).
37 38 39
 *
 * @param NVALS is the number of right hand side.
 */
40
template < class FReal, int ORDER, int NRHS = 1, int NLHS = 1, int NVALS = 1>
41
class FUnifCell : public FBasicCell, public FAbstractSendable
42
{
43 44
    static const int VectorSize = TensorTraits<ORDER>::nnodes;
    static const int TransformedVectorSize = (2*ORDER-1)*(2*ORDER-1)*(2*ORDER-1);
45 46

public:
47 48 49 50 51 52 53 54 55 56 57 58 59
    struct multipole_t {
        FReal multipole_exp[NRHS * NVALS * VectorSize]; //< Multipole expansion
        // Multipole expansion in Fourier space
        FComplex<FReal> transformed_multipole_exp[NRHS * NVALS * TransformedVectorSize];

        const FReal* getMultipole(const int inRhs) const
        { return this->multipole_exp + inRhs*VectorSize; }
        FReal* getMultipole(const int inRhs)
        { return this->multipole_exp + inRhs*VectorSize; }
        const FComplex<FReal>* getTransformedMultipole(const int inRhs) const
        { return this->transformed_multipole_exp + inRhs*TransformedVectorSize; }
        FComplex<FReal>* getTransformedMultipole(const int inRhs)
        { return this->transformed_multipole_exp + inRhs*TransformedVectorSize; }
60

61 62 63
        constexpr int getVectorSize() const {
            return VectorSize;
        }
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78

        // to extend FAbstractSendable
        template <class BufferWriterClass>
        void serialize(BufferWriterClass& buffer) const{
            buffer.write(this->multipole_exp, VectorSize*NVALS*NRHS);
            buffer.write(this->transformed_multipole_exp, TransformedVectorSize*NVALS*NRHS);
        }

        template <class BufferReaderClass>
        void deserialize(BufferReaderClass& buffer){
            buffer.fillArray(this->multipole_exp, VectorSize*NVALS*NRHS);
            buffer.fillArray(this->transformed_multipole_exp, TransformedVectorSize*NVALS*NRHS);
        }


79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
    };

    struct local_expansion_t {
        FReal local_exp[NLHS * NVALS * VectorSize]; //< Local expansion
        // Local expansion in Fourier space
        FComplex<FReal> transformed_local_exp[NLHS * NVALS * TransformedVectorSize];

        const FReal* getLocal(const int inRhs) const
        { return this->local_exp + inRhs*VectorSize; }
        FReal* getLocal(const int inRhs)
        { return this->local_exp + inRhs*VectorSize; }

        const FComplex<FReal>* getTransformedLocal(const int inRhs) const
        { return this->transformed_local_exp + inRhs*TransformedVectorSize; }
        FComplex<FReal>* getTransformedLocal(const int inRhs)
        { return this->transformed_local_exp + inRhs*TransformedVectorSize; }

96 97 98 99
        constexpr int getVectorSize() const {
            return VectorSize;
        }

100 101 102 103 104 105 106 107 108 109 110 111
        // to extend FAbstractSendable
        template <class BufferWriterClass>
        void serialize(BufferWriterClass& buffer) const{
            buffer.write(this->local_exp, VectorSize*NVALS*NLHS);
            buffer.write(this->transformed_local_exp, TransformedVectorSize*NVALS*NLHS);
        }

        template <class BufferReaderClass>
        void deserialize(BufferReaderClass& buffer){
            buffer.fillArray(this->local_exp, VectorSize*NVALS*NLHS);
            buffer.fillArray(this->transformed_local_exp, TransformedVectorSize*NVALS*NLHS);
        }
112 113
    };

114 115
    multipole_t m_data {};
    local_expansion_t l_data {};
116 117 118

    multipole_t* up = &m_data;
    local_expansion_t* down = &l_data;
119

120
    FUnifCell(){
121 122 123
        memset(up->multipole_exp, 0, sizeof(FReal) * NRHS * NVALS * VectorSize);
        memset(down->local_exp, 0, sizeof(FReal) * NLHS * NVALS * VectorSize);
        memset(up->transformed_multipole_exp, 0,
124
               sizeof(FComplex<FReal>) * NRHS * NVALS * TransformedVectorSize);
125
        memset(down->transformed_local_exp, 0,
126 127 128 129 130
               sizeof(FComplex<FReal>) * NLHS * NVALS * TransformedVectorSize);
    }

    ~FUnifCell() {}

131 132
    bool hasMultipoleData() const noexcept {
        return up != nullptr;
133
    }
134 135
    bool hasLocalExpansionData() const noexcept {
        return up != nullptr;
136 137 138
    }


139 140
    multipole_t& getMultipoleData() noexcept {
        return *up;
141
    }
142 143
    const multipole_t& getMultipoleData() const noexcept {
        return *up;
144 145
    }

146 147
    local_expansion_t& getLocalExpansionData() noexcept {
        return *down;
148
    }
149 150
    const local_expansion_t& getLocalExpansionData() const noexcept {
        return *down;
151 152 153 154 155 156 157 158
    }


    ///////////////////////////////////////////////////////
    // to extend FAbstractSendable
    ///////////////////////////////////////////////////////
    template <class BufferWriterClass>
    void serializeUp(BufferWriterClass& buffer) const{
159
        up->serialize(buffer);
160 161 162 163
    }

    template <class BufferReaderClass>
    void deserializeUp(BufferReaderClass& buffer){
164
        up->deserialize(buffer);
165 166 167 168
    }

    template <class BufferWriterClass>
    void serializeDown(BufferWriterClass& buffer) const{
169
        down->serialize(buffer);
170 171 172 173
    }

    template <class BufferReaderClass>
    void deserializeDown(BufferReaderClass& buffer){
174
        down->deserialize(buffer);
175 176 177 178 179 180 181 182
    }

    ///////////////////////////////////////////////////////
    // to extend Serializable
    ///////////////////////////////////////////////////////
    template <class BufferWriterClass>
    void save(BufferWriterClass& buffer) const{
        FBasicCell::save(buffer);
183 184 185 186
        buffer.write(up->multipole_exp, VectorSize*NVALS*NRHS);
        buffer.write(up->transformed_multipole_exp, TransformedVectorSize*NVALS*NRHS);
        buffer.write(down->local_exp, VectorSize*NVALS*NLHS);
        buffer.write(down->transformed_local_exp, TransformedVectorSize*NVALS*NLHS);
187 188 189 190 191
    }

    template <class BufferReaderClass>
    void restore(BufferReaderClass& buffer){
        FBasicCell::restore(buffer);
192 193 194 195
        buffer.fillArray(up->multipole_exp, VectorSize*NVALS*NRHS);
        buffer.fillArray(up->transformed_multipole_exp, TransformedVectorSize*NVALS*NRHS);
        buffer.fillArray(down->local_exp, VectorSize*NVALS*NLHS);
        buffer.fillArray(down->transformed_local_exp, TransformedVectorSize*NVALS*NLHS);
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
    }

    FSize getSavedSize() const {
        return (NRHS+NLHS)*NVALS*VectorSize * (FSize) sizeof(FReal) + (NRHS+NLHS)*NVALS*TransformedVectorSize * (FSize) sizeof(FComplex<FReal>)
                + FBasicCell::getSavedSize();
    }

    FSize getSavedSizeUp() const {
        return (NRHS)*NVALS*VectorSize * (FSize) sizeof(FReal) + (NRHS)*NVALS*TransformedVectorSize * (FSize) sizeof(FComplex<FReal>);
    }

    FSize getSavedSizeDown() const {
        return (NLHS)*NVALS*VectorSize * (FSize) sizeof(FReal) + (NLHS)*NVALS*TransformedVectorSize * (FSize) sizeof(FComplex<FReal>);
    }

    template <class StreamClass>
212
    friend StreamClass& operator<<(StreamClass& output, const FUnifCell<FReal,ORDER, NRHS, NLHS, NVALS>&  cell){
213 214 215 216 217 218 219 220 221 222 223 224 225
        output <<"  Multipole exp NRHS " << NRHS <<" NVALS "  <<NVALS << " VectorSize "  << cell.getVectorSize() << std::endl;
        for (int rhs= 0 ; rhs < NRHS ; ++rhs) {
            const FReal* pole = cell.getMultipole(rhs);
            for (int val= 0 ; val < NVALS ; ++val) {
                output<< "      val : " << val << " exp: " ;
                for (int i= 0 ; i < cell.getVectorSize()  ; ++i) {
                    output<< pole[i] << " ";
                }
                output << std::endl;
            }
        }
        return output;
    }
226

227 228
};

229 230
template <class FReal, int ORDER, int NRHS = 1, int NLHS = 1, int NVALS = 1>
class FTypedUnifCell : public FUnifCell<FReal,ORDER,NRHS,NLHS,NVALS>, public FExtendCellType {
231
public:
232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248
    template <class BufferWriterClass>
    void save(BufferWriterClass& buffer) const{
        FUnifCell<FReal,ORDER,NRHS,NLHS,NVALS>::save(buffer);
        FExtendCellType::save(buffer);
    }
    template <class BufferReaderClass>
    void restore(BufferReaderClass& buffer){
        FUnifCell<FReal,ORDER,NRHS,NLHS,NVALS>::restore(buffer);
        FExtendCellType::restore(buffer);
    }
    void resetToInitialState(){
        FUnifCell<FReal,ORDER,NRHS,NLHS,NVALS>::resetToInitialState();
        FExtendCellType::resetToInitialState();
    }
    FSize getSavedSize() const {
        return FExtendCellType::getSavedSize() + FUnifCell<FReal, ORDER,NRHS,NLHS,NVALS>::getSavedSize();
    }
249 250 251
};

#endif //FUNIFCELL_HPP