ArbitraryDomain.h 5.91 KB
Newer Older
1 2 3 4 5
//
// Class ArbitraryDomain
//   Interface to iterative solver and boundary geometry
//   for space charge calculation
//
6
// Copyright (c) 2008,        Yves Ineichen, ETH Zürich,
frey_m's avatar
frey_m committed
7 8
//               2013 - 2015, Tülin Kaman, Paul Scherrer Institut, Villigen PSI, Switzerland
//                      2016, Daniel Winklehner, Massachusetts Institute of Technology
9
//               2017 - 2020, Paul Scherrer Institut, Villigen PSI, Switzerland
frey_m's avatar
frey_m committed
10
// All rights reserved
11
//
12 13 14 15 16
// 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
17 18 19 20 21 22 23 24 25 26
//
// 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/>.
27
//
28 29
#ifndef ARBITRARY_DOMAIN_H
#define ARBITRARY_DOMAIN_H
30

gsell's avatar
gsell committed
31 32 33
#include <mpi.h>
#include <hdf5.h>
#include "H5hut.h"
34

gsell's avatar
gsell committed
35
#include <map>
36
#include <string>
snuverink_j's avatar
snuverink_j committed
37 38
#include <tuple>
#include <vector>
39
#include "IrregularDomain.h"
snuverink_j's avatar
snuverink_j committed
40 41

class BoundaryGeometry;
gsell's avatar
gsell committed
42 43 44 45

class ArbitraryDomain : public IrregularDomain {

public:
46 47
    using IrregularDomain::StencilIndex_t;
    using IrregularDomain::StencilValue_t;
gsell's avatar
gsell committed
48

frey_m's avatar
frey_m committed
49 50 51 52 53 54
    ArbitraryDomain(BoundaryGeometry *bgeom, Vector_t nr, Vector_t hr,
                    std::string interpl);

    ArbitraryDomain(BoundaryGeometry *bgeom, Vector_t nr, Vector_t hr,
                    Vector_t globalMeanR, Quaternion_t globalToLocalQuaternion,
                    std::string interpl);
55 56

    ~ArbitraryDomain();
gsell's avatar
gsell committed
57 58

    /// returns discretization at (x,y,z)
59
    void getBoundaryStencil(int idx, int idy, int idz, StencilValue_t& value,
frey_m's avatar
frey_m committed
60 61
                            double &scaleFactor);

gsell's avatar
gsell committed
62
    /// queries if a given (x,y,z) coordinate lies inside the domain
63
    bool isInside(int idx, int idy, int idz);
64
    /// returns number of nodes in xy plane
65
    int getNumXY(int idz);
66 67
    // calculates intersection with rotated and shifted geometry
    void compute(Vector_t hr, NDIndex<3> localId);
gsell's avatar
gsell committed
68

69
    int getStartId() {return startId;}
gsell's avatar
gsell committed
70

71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
    double getXRangeMin(){ return minCoords_m(0); }
    double getYRangeMin(){ return minCoords_m(1); }
    double getZRangeMin(){ return minCoords_m(2); }

    double getXRangeMax(){ return maxCoords_m(0); }
    double getYRangeMax(){ return maxCoords_m(1); }
    double getZRangeMax(){ return maxCoords_m(2); }

    void setXRangeMin(double xmin){ minCoords_m(0) = xmin; }
    void setYRangeMin(double ymin){ minCoords_m(1) = ymin; }
    void setZRangeMin(double zmin){ minCoords_m(2) = zmin; }

    void setXRangeMax(double xmax){ maxCoords_m(0) = xmax; }
    void setYRangeMax(double ymax){ maxCoords_m(1) = ymax; }
    void setZRangeMax(double zmax){ maxCoords_m(2) = zmax; }
86

gsell's avatar
gsell committed
87
private:
88 89
    BoundaryGeometry *bgeom_m;

frey_m's avatar
frey_m committed
90 91 92
    /** PointList maps from an (x,z) resp. (y,z) pair to double values
     * (=intersections with boundary)
     */
93
    typedef std::multimap< std::tuple<int, int, int>, double > PointList;
gsell's avatar
gsell committed
94 95

    /// all intersection points with gridlines in X direction
96 97 98 99 100
    PointList IntersectHiX, IntersectLoX;

    /// all intersection points with gridlines in Y direction
    PointList IntersectHiY, IntersectLoY;

gsell's avatar
gsell committed
101
    /// all intersection points with gridlines in Z direction
102
    PointList IntersectHiZ, IntersectLoZ;
103 104

    // meanR to shift from global to local frame
105
    Vector_t globalMeanR_m;
106
    //    Quaternion_t globalToLocalQuaternion_m;  because defined in parent class
107
    Quaternion_t localToGlobalQuaternion_m;
gsell's avatar
gsell committed
108

109
    int startId;
gsell's avatar
gsell committed
110

111
    // Here we store the number of nodes in a xy layer for a given z coordinate
gsell's avatar
gsell committed
112
    std::map<int, int> numXY;
113 114
    std::map<int, int> numYZ;
    std::map<int, int> numXZ;
gsell's avatar
gsell committed
115

116
    // Number of nodes in the xy plane (for this case: independent of the z coordinate)
117
    int nxy_m[1000];
118
    // mapping (x,y,z) -> idxyz
gsell's avatar
gsell committed
119
    std::map<int, int> IdxMap;
120
    // Mapping idxyz -> (x,y,z)
gsell's avatar
gsell committed
121
    std::map<int, int> CoordMap;
122 123 124 125

    // Mapping all cells that are inside the geometry
    std::map<int, bool> IsInsideMap;

126
    // Interpolation type
127
    int interpolationMethod;
128

129 130
    Vector_t Geo_nr_m;
    Vector_t Geo_hr_m;
131
    Vector_t geomCentroid_m;
132 133
    Vector_t minCoords_m;
    Vector_t maxCoords_m;
134
    Vector_t globalInsideP0_m;
gsell's avatar
gsell committed
135

136 137 138 139 140
    // Conversion from (x,y,z) to index in xyz plane
    inline int toCoordIdx(int idx, int idy, int idz);
    // Conversion from (x,y,z) to index on the 3D grid
    int getIdx(int idx, int idy, int idz);
    // Conversion from a 3D index to (x,y,z)
141
    inline void getCoord(int idxyz, int &x, int &y, int &z);
gsell's avatar
gsell committed
142 143

    inline void crossProduct(double A[], double B[], double C[]);
frey_m's avatar
frey_m committed
144 145 146 147

    inline double dotProduct(double v1[], double v2[]) {
        return (v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]);
    }
gsell's avatar
gsell committed
148

149
    // Different interpolation methods for boundary points
150 151
    void constantInterpolation(int idx, int idy, int idz, StencilValue_t& value,
                               double &scaleFactor);
frey_m's avatar
frey_m committed
152

153 154
    void linearInterpolation(int idx, int idy, int idz, StencilValue_t& value,
                             double &scaleFactor);
frey_m's avatar
frey_m committed
155

156 157
    void quadraticInterpolation(int idx, int idy, int idz, StencilValue_t& value,
                                double &scaleFactor);
158 159

    // Rotate positive axes with quaternion -DW
160
    inline void rotateWithQuaternion(Vector_t &v, Quaternion_t const quaternion);
161

162 163 164
    inline void rotateXAxisWithQuaternion(Vector_t &v, Quaternion_t const quaternion);
    inline void rotateYAxisWithQuaternion(Vector_t &v, Quaternion_t const quaternion);
    inline void rotateZAxisWithQuaternion(Vector_t &v, Quaternion_t const quaternion);
gsell's avatar
gsell committed
165 166
};

167 168 169 170 171 172 173 174 175
#endif

// vi: set et ts=4 sw=4 sts=4:
// Local Variables:
// mode:c
// c-basic-offset: 4
// indent-tabs-mode: nil
// require-final-newline: nil
// End: