IrregularDomain.h 6.3 KB
Newer Older
1
//
frey_m's avatar
frey_m committed
2 3
// Class IrregularDomain
//   Defines a common abstract interface for different types of boundaries.
4
//
5
// Copyright (c) 2008,        Yves Ineichen, ETH Zürich,
frey_m's avatar
frey_m committed
6
//               2013 - 2015, Tülin Kaman, Paul Scherrer Institut, Villigen PSI, Switzerland
7
//               2017 - 2020, Paul Scherrer Institut, Villigen PSI, Switzerland
frey_m's avatar
frey_m committed
8
// All rights reserved
9
//
10 11 12 13 14
// Implemented as part of the master thesis
// "A Parallel Multigrid Solver for Beam Dynamics"
// and the paper
// "A fast parallel Poisson solver on irregular domains applied to beam dynamics simulations"
// (https://doi.org/10.1016/j.jcp.2010.02.022)
frey_m's avatar
frey_m committed
15 16 17 18 19 20 21 22 23 24
//
// This file is part of OPAL.
//
// OPAL is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// You should have received a copy of the GNU General Public License
// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
25
//
gsell's avatar
gsell committed
26 27 28
#ifndef IRREGULAR_DOMAIN_H
#define IRREGULAR_DOMAIN_H

29
#include <map>
gsell's avatar
gsell committed
30
#include <string>
31 32
#include "Algorithms/Vektor.h"
#include "Algorithms/Quaternion.h"
gsell's avatar
gsell committed
33
#include "Index/NDIndex.h"
34

gsell's avatar
gsell committed
35 36 37 38 39 40 41
/// enumeration corresponding to different interpolation methods at the boundary
enum {
    CONSTANT,
    LINEAR,
    QUADRATIC
};

42

gsell's avatar
gsell committed
43 44 45 46
class IrregularDomain {

public:

47 48 49 50 51 52 53 54 55 56 57 58 59
    template<typename T>
    struct Stencil {
        T center;   // x,   y,   z
        T west;     // x-1, y,   z
        T east;     // x+1, y,   z
        T north;    // x,   y+1, z
        T south;    // x,   y-1, z
        T front;    // x,   y,   z-1
        T back;     // x,   y,   z+1
    };

    typedef Stencil<int>    StencilIndex_t;
    typedef Stencil<double> StencilValue_t;
60
    typedef Vektor<int, 3>  IntVector_t;
61

62
    IrregularDomain(const IntVector_t& nr,
63 64
                    const Vector_t& hr,
                    const std::string& interpl);
frey_m's avatar
frey_m committed
65 66


frey_m's avatar
frey_m committed
67 68
    /** method to compute the intersection points with the boundary geometry
     * (stored in some appropriate data structure)
gsell's avatar
gsell committed
69 70
     * \param hr updated mesh spacings
     */
71
    virtual void compute(Vector_t hr, NDIndex<3> localId) = 0;
gsell's avatar
gsell committed
72 73 74 75 76

    /// method to calculate the stencil at a boundary points
    /// \param x index of the current element in the matrix
    /// \param y index of the current element in the matrix
    /// \param z index of the current element in the matrix
77 78
    /// \param values of stencil element
    /// \param scaleFactor of stencil values
79
    void getBoundaryStencil(int x, int y, int z,
frey_m's avatar
frey_m committed
80 81
                            StencilValue_t& value,
                            double &scaleFactor) const;
gsell's avatar
gsell committed
82 83

    /// method to calculate the stencil at a boundary points
84
    /// \param id index of the current element in the matrix
85 86 87
    // \param values of stencil element
    /// \param scaleFactor of stencil values
    void getBoundaryStencil(int id, StencilValue_t& value,
88
                            double &scaleFactor) const;
gsell's avatar
gsell committed
89 90 91 92 93

    /// method to calculate the neighbours in the matrix of the current index (x,y,z)
    /// \param x index of the current element in the matrix
    /// \param y index of the current element in the matrix
    /// \param z index of the current element in the matrix
94
    /// \param index stencil indices of an element
95
    void getNeighbours(int x, int y, int z, StencilIndex_t& index) const;
96

97
    void getNeighbours(int idx, StencilIndex_t& index) const;
98

frey_m's avatar
frey_m committed
99
    /// Conversion from a 3D index to (x,y,z)
100
    virtual void getCoord(int idx, int &x, int &y, int &z) const;
101

frey_m's avatar
frey_m committed
102
    /// Conversion from (x,y,z) to index on the 3D grid
103 104 105
    int getIdx(int x, int y, int z) const;

    virtual int getNumXY() const { return nr_m[0] * nr_m[1]; }
gsell's avatar
gsell committed
106 107 108 109 110 111

    /// method that checks if a given point lies inside the boundary
    /// \param x index of the current element in the matrix
    /// \param y index of the current element in the matrix
    /// \param z index of the current element in the matrix
    /// \return boolean indicating if the point lies inside the boundary
112 113 114 115
    virtual bool isInside(int x, int y, int z)  const = 0;

    IntVector_t getNr() const { return nr_m; }
    Vector_t    getHr() const { return hr_m; }
gsell's avatar
gsell committed
116

117 118
    void setNr(IntVector_t nr) { nr_m = nr; }
    void setHr(Vector_t hr)    { hr_m = hr; }
gsell's avatar
gsell committed
119

120 121 122 123
    void setMinMaxZ(double minz, double maxz) {
        zMin_m = minz;
        zMax_m = maxz;
    }
gsell's avatar
gsell committed
124

125 126
    double getMinZ() const { return zMin_m; }
    double getMaxZ() const { return zMax_m; }
127

128 129 130 131 132 133
    double getXRangeMin() const { return min_m(0); }
    double getXRangeMax() const { return max_m(0); }
    double getYRangeMin() const { return min_m(1); }
    double getYRangeMax() const { return max_m(1); }
    double getZRangeMin() const { return min_m(2); }
    double getZRangeMax() const { return max_m(2); }
gsell's avatar
gsell committed
134

135 136 137 138
    void setRangeMin(const Vector_t& min) { min_m = min; }
    void setRangeMax(const Vector_t& max) { max_m = max; }

    bool hasGeometryChanged() const { return hasGeometryChanged_m; }
139

140
    virtual ~IrregularDomain() {};
gsell's avatar
gsell committed
141

142
    virtual void resizeMesh(Vector_t& origin, Vector_t& hr,
frey_m's avatar
frey_m committed
143
                            const Vector_t& /*rmin*/, const Vector_t& /*rmax*/,
144
                            double /*dh*/);
145

gsell's avatar
gsell committed
146 147
protected:

148 149 150
    virtual int indexAccess(int x, int y, int z) const = 0;

    virtual int coordAccess(int idx) const = 0;
frey_m's avatar
frey_m committed
151

152 153
    /// different interpolation methods for boundary points
    virtual void constantInterpolation(int x, int y, int z, StencilValue_t& value,
154
                               double &scaleFactor) const;
155 156

    virtual void linearInterpolation(int x, int y, int z, StencilValue_t& value,
157
                             double &scaleFactor) const;
158 159

    virtual void quadraticInterpolation(int x, int y, int z, StencilValue_t& value,
160
                                double &scaleFactor) const;
161 162


gsell's avatar
gsell committed
163 164
    // a irregular domain is always defined on a grid
    /// number of mesh points in each direction
165
    IntVector_t nr_m;
gsell's avatar
gsell committed
166
    /// mesh-spacings in each direction
frey_m's avatar
frey_m committed
167
    Vector_t hr_m;
gsell's avatar
gsell committed
168 169 170 171

    /// min/max of bunch in floor coordinates
    double zMin_m;
    double zMax_m;
172

173 174 175
    Vector_t min_m;
    Vector_t max_m;

176 177 178
    /// flag indicating if geometry has changed for the current time-step
    bool hasGeometryChanged_m;

179 180 181
    /// interpolation type
    int interpolationMethod_m;

182 183 184 185 186 187
    /// mapping (x,y,z) -> idx
    std::map<int, int> idxMap_m;

    /// mapping idx -> (x,y,z)
    std::map<int, int> coordMap_m;

gsell's avatar
gsell committed
188 189
};

190
#endif