1 #ifdef HAVE_SAAMG_SOLVER
18 EllipticDomain::EllipticDomain(
double semimajor,
double semiminor,
Vector_t nr,
Vector_t hr, std::string interpl) {
19 SemiMajor = semimajor;
20 SemiMinor = semiminor;
24 if(interpl ==
"CONSTANT")
25 interpolationMethod = CONSTANT;
26 else if(interpl ==
"LINEAR")
27 interpolationMethod = LINEAR;
28 else if(interpl ==
"QUADRATIC")
29 interpolationMethod = QUADRATIC;
33 SemiMajor = bgeom->
getA();
34 SemiMinor = bgeom->
getB();
39 if(interpl ==
"CONSTANT")
40 interpolationMethod = CONSTANT;
41 else if(interpl ==
"LINEAR")
42 interpolationMethod = LINEAR;
43 else if(interpl ==
"QUADRATIC")
44 interpolationMethod = QUADRATIC;
48 SemiMajor = bgeom->
getA();
49 SemiMinor = bgeom->
getB();
52 hr_m[0] = (getXRangeMax()-getXRangeMin())/nr[0];
53 hr_m[1] = (getYRangeMax()-getYRangeMin())/nr[1];
54 hr_m[2] = (getZRangeMax()-getZRangeMin())/nr[2];
57 if(interpl ==
"CONSTANT")
58 interpolationMethod = CONSTANT;
59 else if(interpl ==
"LINEAR")
60 interpolationMethod = LINEAR;
61 else if(interpl ==
"QUADRATIC")
62 interpolationMethod = QUADRATIC;
65 EllipticDomain::~EllipticDomain() {
73 void EllipticDomain::compute(
Vector_t hr){
75 if(hr[0] == getHr()[0] && hr[1] == getHr()[1] && hr[2] == getHr()[2]) {
76 hasGeometryChanged_m =
false;
80 hasGeometryChanged_m =
true;
88 IntersectYDir.clear();
89 IntersectXDir.clear();
95 for(x = 0; x < nr[0]; x++) {
96 for(y = 0; y < nr[1]; y++) {
97 if(isInside(x, y, 1)) {
98 IdxMap[toCoordIdx(x, y)] = idx;
99 CoordMap[idx++] = toCoordIdx(x, y);
106 switch(interpolationMethod) {
112 double smajsq = SemiMajor * SemiMajor;
113 double sminsq = SemiMinor * SemiMinor;
117 double mx = (nr[0] - 1) * hr[0] / 2.0;
118 double my = (nr[1] - 1) * hr[1] / 2.0;
121 for(x = 0; x < nr[0]; x++) {
122 pos = x * hr[0] - mx;
123 if (pos <= -SemiMajor || pos >= SemiMajor)
125 IntersectYDir.insert(std::pair<int, double>(x, 0));
126 IntersectYDir.insert(std::pair<int, double>(x, 0));
128 yd =
std::abs(
sqrt(sminsq - sminsq * pos * pos / smajsq));
129 IntersectYDir.insert(std::pair<int, double>(x, yd));
130 IntersectYDir.insert(std::pair<int, double>(x, -yd));
135 for(y = 0; y < nr[1]; y++) {
136 pos = y * hr[1] - my;
137 if (pos <= -SemiMinor || pos >= SemiMinor)
139 IntersectXDir.insert(std::pair<int, double>(y, 0));
140 IntersectXDir.insert(std::pair<int, double>(y, 0));
142 xd =
std::abs(
sqrt(smajsq - smajsq * pos * pos / sminsq));
143 IntersectXDir.insert(std::pair<int, double>(y, xd));
144 IntersectXDir.insert(std::pair<int, double>(y, -xd));
152 if(hr[0] == getHr()[0] && hr[1] == getHr()[1] && hr[2] == getHr()[2]) {
153 hasGeometryChanged_m =
false;
157 hasGeometryChanged_m =
true;
165 IntersectYDir.clear();
166 IntersectXDir.clear();
172 for(x = localId[0].first(); x<= localId[0].last(); x++) {
173 for(y = localId[1].first(); y <= localId[1].last(); y++) {
174 if(isInside(x, y, 1)) {
175 IdxMap[toCoordIdx(x, y)] = idx;
176 CoordMap[idx++] = toCoordIdx(x, y);
182 switch(interpolationMethod) {
188 double smajsq = SemiMajor * SemiMajor;
189 double sminsq = SemiMinor * SemiMinor;
193 double mx = (nr[0] - 1) * hr[0] / 2.0;
194 double my = (nr[1] - 1) * hr[1] / 2.0;
197 for(x = localId[0].first(); x <= localId[0].last(); x++) {
198 pos = x * hr[0] - mx;
199 if (pos <= -SemiMajor || pos >= SemiMajor)
201 IntersectYDir.insert(std::pair<int, double>(x, 0));
202 IntersectYDir.insert(std::pair<int, double>(x, 0));
204 yd =
std::abs(
sqrt(sminsq - sminsq * pos * pos / smajsq));
205 IntersectYDir.insert(std::pair<int, double>(x, yd));
206 IntersectYDir.insert(std::pair<int, double>(x, -yd));
211 for(y = localId[0].first(); y < localId[1].last(); y++) {
212 pos = y * hr[1] - my;
213 if (pos <= -SemiMinor || pos >= SemiMinor)
215 IntersectXDir.insert(std::pair<int, double>(y, 0));
216 IntersectXDir.insert(std::pair<int, double>(y, 0));
218 xd =
std::abs(
sqrt(smajsq - smajsq * pos * pos / sminsq));
219 IntersectXDir.insert(std::pair<int, double>(y, xd));
220 IntersectXDir.insert(std::pair<int, double>(y, -xd));
226 void EllipticDomain::getBoundaryStencil(
int x,
int y,
int z,
double &
W,
double &E,
double &S,
double &N,
double &F,
double &B,
double &C,
double &scaleFactor) {
230 switch(interpolationMethod) {
232 constantInterpolation(x, y, z, W, E, S, N, F, B, C, scaleFactor);
235 linearInterpolation(x, y, z, W, E, S, N, F, B, C, scaleFactor);
238 quadraticInterpolation(x, y, z, W, E, S, N, F, B, C, scaleFactor);
246 void EllipticDomain::getBoundaryStencil(
int idx,
double &W,
double &E,
double &S,
double &N,
double &F,
double &B,
double &C,
double &scaleFactor) {
249 int x = 0, y = 0, z = 0;
250 getCoord(idx, x, y, z);
251 getBoundaryStencil(x, y, z, W, E, S, N, F, B, C, scaleFactor);
255 void EllipticDomain::getNeighbours(
int idx,
int &W,
int &E,
int &S,
int &N,
int &F,
int &B) {
257 int x = 0, y = 0, z = 0;
258 getCoord(idx, x, y, z);
259 getNeighbours(x, y, z, W, E, S, N, F, B);
263 void EllipticDomain::getNeighbours(
int x,
int y,
int z,
int &W,
int &E,
int &S,
int &N,
int &F,
int &B) {
266 W = getIdx(x - 1, y, z);
270 E = getIdx(x + 1, y, z);
275 N = getIdx(x, y + 1, z);
279 S = getIdx(x, y - 1, z);
284 F = getIdx(x, y, z - 1);
288 B = getIdx(x, y, z + 1);
294 void EllipticDomain::constantInterpolation(
int x,
int y,
int z,
double &WV,
double &
EV,
double &SV,
double &NV,
double &FV,
double &BV,
double &CV,
double &scaleFactor) {
298 WV = -1/(hr[0]*hr[0]);
299 EV = -1/(hr[0]*hr[0]);
300 NV = -1/(hr[1]*hr[1]);
301 SV = -1/(hr[1]*hr[1]);
302 FV = -1/(hr[2]*hr[2]);
303 BV = -1/(hr[2]*hr[2]);
304 CV = 2/(hr[0]*hr[0]) + 2/(hr[1]*hr[1]) + 2/(hr[2]*hr[2]);
307 if(!isInside(x + 1, y, z))
311 if(!isInside(x - 1, y, z))
315 if(!isInside(x, y + 1, z))
319 if(!isInside(x, y - 1, z))
322 if(z == 1 || z == nr[2] - 2) {
339 double d = hr[2] * (nr[2] - 1) / 2;
340 CV += 2 / (d * hr[2]);
354 void EllipticDomain::linearInterpolation(
int x,
int y,
int z,
double &W,
double &E,
double &S,
double &N,
double &F,
double &B,
double &C,
double &scaleFactor) {
358 double cx = x * hr[0] - (nr[0] - 1) * hr[0] / 2.0;
359 double cy = y * hr[1] - (nr[1] - 1) * hr[1] / 2.0;
368 it = IntersectYDir.find(x);
381 if(!isInside(x + 1, y, z)) {
382 C += 1 / ((dx - cx) * de);
390 if(!isInside(x - 1, y, z)) {
399 if(!isInside(x, y + 1, z)) {
400 C += 1 / ((dy - cy) * dn);
408 if(!isInside(x, y - 1, z)) {
416 F = -1 / (hr[2] * hr[2]);
417 B = -1 / (hr[2] * hr[2]);
418 C += 2 / (hr[2] * hr[2]);
446 void EllipticDomain::quadraticInterpolation(
int x,
int y,
int z,
double &W,
double &E,
double &S,
double &N,
double &F,
double &B,
double &C,
double &scaleFactor) {
448 double cx = (x - (nr[0] - 1) / 2.0) * hr[0];
449 double cy = (y - (nr[1] - 1) / 2.0) * hr[1];
460 it = IntersectYDir.find(x);
505 if(!isInside(x + 1, y, z)) {
512 if(!isInside(x - 1, y, z)) {
519 if(!isInside(x, y + 1, z)) {
526 if(!isInside(x, y - 1, z)) {
532 W *= -1.0 / (dw * (dw + de));
533 E *= -1.0 / (de * (dw + de));
534 N *= -1.0 / (dn * (dn + ds));
535 S *= -1.0 / (ds * (dn + ds));
536 F = -1 / (hr[2] * (hr[2] + hr[2]));
537 B = -1 / (hr[2] * (hr[2] + hr[2]));
541 C += 1 / de * 1 / dw;
542 C += 1 / dn * 1 / ds;
543 C += 1 / hr[2] * 1 / hr[2];
639 if(z == 0 || z == nr[2] - 1) {
650 double d = hr[2] * (nr[2] - 1) / 2;
651 C += 2 / (d * hr[2]);
664 #endif //#ifdef HAVE_SAAMG_SOLVER
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
Tps< T > sqrt(const Tps< T > &x)
Square root.
std::string::iterator iterator