OPAL (Object Oriented Parallel Accelerator Library) 2022.1
OPAL
IrregularDomain.cpp
Go to the documentation of this file.
1//
2// Class IrregularDomain
3// Defines a common abstract interface for different types of boundaries.
4//
5// Copyright (c) 2008, Yves Ineichen, ETH Zürich,
6// 2013 - 2015, Tülin Kaman, Paul Scherrer Institut, Villigen PSI, Switzerland
7// 2017 - 2020, Paul Scherrer Institut, Villigen PSI, Switzerland
8// All rights reserved
9//
10// Implemented as part of the master thesis
11// "A Parallel Multigrid Solver for Beam Dynamics"
12// and the paper
13// "A fast parallel Poisson solver on irregular domains applied to beam dynamics simulations"
14// (https://doi.org/10.1016/j.jcp.2010.02.022)
15//
16// This file is part of OPAL.
17//
18// OPAL is free software: you can redistribute it and/or modify
19// it under the terms of the GNU General Public License as published by
20// the Free Software Foundation, either version 3 of the License, or
21// (at your option) any later version.
22//
23// You should have received a copy of the GNU General Public License
24// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
25//
26
28
29#include "Utility/PAssert.h"
31
33 const std::string& interpl)
34 : nr_m(nr)
35 , hr_m(hr)
36{
37 if (interpl == "CONSTANT")
39 else if (interpl == "LINEAR")
41 else if (interpl == "QUADRATIC")
43}
44
45
46void IrregularDomain::getNeighbours(int x, int y, int z, StencilIndex_t& index) const
47{
48 index.west = -1;
49 index.east = -1;
50 index.south = -1;
51 index.north = -1;
52 index.front = -1;
53 index.back = -1;
54
55 if (x > 0 && isInside(x - 1, y, z))
56 index.west = getIdx(x - 1, y, z);
57
58 if (x < nr_m[0] - 1 && isInside(x + 1, y, z))
59 index.east = getIdx(x + 1, y, z);
60
61 if (y > 0 && isInside(x, y - 1, z))
62 index.south = getIdx(x, y - 1, z);
63
64 if (y < nr_m[1] - 1 && isInside(x, y + 1, z))
65 index.north = getIdx(x, y + 1, z);
66
67 if (z > 0 && isInside(x, y, z - 1))
68 index.front = getIdx(x, y, z - 1);
69
70 if (z < nr_m[2] - 1 && isInside(x, y, z + 1))
71 index.back = getIdx(x, y, z + 1);
72}
73
74
76 int x = 0, y = 0, z = 0;
77 getCoord(id, x, y, z);
78 getNeighbours(x, y, z, index);
79}
80
81
82void IrregularDomain::getCoord(int idx, int& x, int& y, int& z) const {
83 int xy = coordAccess(idx);
84 x = xy % nr_m[0];
85 y = (xy - x) / nr_m[0];
86 z = idx / getNumXY();
87}
88
89int IrregularDomain::getIdx(int x, int y, int z) const {
90 if (x < 0 || y < 0 || z < 0 || !isInside(x, y, z))
91 return -1;
92 return indexAccess(x, y, z);
93}
94
95void IrregularDomain::getBoundaryStencil(int x, int y, int z, StencilValue_t& value,
96 double &scaleFactor) const
97{
98 scaleFactor = 1.0;
99
100 // determine which interpolation method we use for points near the boundary
101 switch (interpolationMethod_m) {
102 case CONSTANT:
103 constantInterpolation(x, y, z, value, scaleFactor);
104 break;
105 case LINEAR:
106 linearInterpolation(x, y, z, value, scaleFactor);
107 break;
108 case QUADRATIC:
109 quadraticInterpolation(x, y, z, value, scaleFactor);
110 break;
111 }
112
113 // stencil center value has to be positive!
114 PAssert(value.center > 0);
115}
116
117
119 double &scaleFactor) const
120{
121 int idx = 0, idy = 0, idz = 0;
122 getCoord(id, idx, idy, idz);
123 getBoundaryStencil(idx, idy, idz, value, scaleFactor);
124}
125
126
128 const Vector_t& /*rmin*/, const Vector_t& /*rmax*/,
129 double /*dh*/)
130{
131 origin = min_m;
132 for (int i = 0; i < 3; i++)
133 hr[i] = (max_m[i] - min_m[i]) / nr_m[i];
134};
135
136
137void IrregularDomain::constantInterpolation(int /*idx*/, int /*idy*/, int /*idz*/,
138 StencilValue_t& /*value*/, double &/*scaleFactor*/) const
139{
140 throw OpalException("IrregularDomain::constantInterpolation()",
141 "No constant interpolation method Implemented!");
142}
143
144
145void IrregularDomain::linearInterpolation(int /*idx*/, int /*idy*/, int /*idz*/,
146 StencilValue_t& /*value*/, double &/*scaleFactor*/) const
147{
148 throw OpalException("IrregularDomain::linearInterpolation()",
149 "No linear interpolation method Implemented!");
150}
151
152
153void IrregularDomain::quadraticInterpolation(int /*idx*/, int /*idy*/, int /*idz*/,
154 StencilValue_t& /*value*/, double &/*scaleFactor*/) const
155{
156 throw OpalException("IrregularDomain::quadraticInterpolation()",
157 "No quadratic interpolation method Implemented!");
158}
const int nr
Definition: ClassicRandom.h:24
@ QUADRATIC
@ CONSTANT
@ LINEAR
#define PAssert(c)
Definition: PAssert.h:102
IntVector_t nr_m
number of mesh points in each direction
virtual int coordAccess(int idx) const =0
void getBoundaryStencil(int x, int y, int z, StencilValue_t &value, double &scaleFactor) const
virtual int getNumXY() const
int interpolationMethod_m
interpolation type
int getIdx(int x, int y, int z) const
Conversion from (x,y,z) to index on the 3D grid.
virtual void resizeMesh(Vector_t &origin, Vector_t &hr, const Vector_t &, const Vector_t &, double)
virtual void quadraticInterpolation(int x, int y, int z, StencilValue_t &value, double &scaleFactor) const
void getNeighbours(int x, int y, int z, StencilIndex_t &index) const
virtual bool isInside(int x, int y, int z) const =0
virtual void constantInterpolation(int x, int y, int z, StencilValue_t &value, double &scaleFactor) const
different interpolation methods for boundary points
IrregularDomain(const IntVector_t &nr, const Vector_t &hr, const std::string &interpl)
virtual void linearInterpolation(int x, int y, int z, StencilValue_t &value, double &scaleFactor) const
virtual int indexAccess(int x, int y, int z) const =0
virtual void getCoord(int idx, int &x, int &y, int &z) const
Conversion from a 3D index to (x,y,z)
The base class for all OPAL exceptions.
Definition: OpalException.h:28