diff --git a/src/Solvers/ArbitraryDomain.cpp b/src/Solvers/ArbitraryDomain.cpp index 25cf1394f7bd962474ecfcd701b3a20da1308834..c3bbdd97b56586315d70a84f4c7341647ccbd9f8 100644 --- a/src/Solvers/ArbitraryDomain.cpp +++ b/src/Solvers/ArbitraryDomain.cpp @@ -115,74 +115,87 @@ void ArbitraryDomain::compute(Vector_t hr, NDIndex<3> localId){ // because fastIsInside() creates a number of segments that depends on the // distance between P and P0. Using the previous P as the new P0 // assures the smallest possible distance in most cases. -DW - P0 = P; + //P0 = P; std::tuple<int, int, int> pos(idx, idy, idz); dir = Vector_t(0, 0, 1); if (bgeom_m->intersectRayBoundary(P, dir, I)) { - intersectHiZ_m.insert(std::pair< std::tuple<int, int, int>, double >(pos, I[2])); + intersectHiZ_m.insert( + std::pair<std::tuple<int, int, int>, double>(pos, I[2])); } else { #ifdef DEBUG_INTERSECT_RAY_BOUNDARY - *gmsg << "zdir=+1 " << dir << " x,y,z= " << idx << "," << idy - << "," << idz << " P=" << P <<" I=" << I << endl; + INFOMSG( + level2 << "zdir=+1 " << dir << " x,y,z= " << idx << "," << idy << "," + << idz << " P=" << P << " I=" << I << endl); #endif } if (bgeom_m->intersectRayBoundary(P, -dir, I)) { - intersectLoZ_m.insert(std::pair< std::tuple<int, int, int>, double >(pos, I[2])); + intersectLoZ_m.insert( + std::pair<std::tuple<int, int, int>, double>(pos, I[2])); } else { #ifdef DEBUG_INTERSECT_RAY_BOUNDARY - *gmsg << "zdir=-1 " << -dir << " x,y,z= " << idx << "," << idy - << "," << idz << " P=" << P <<" I=" << I << endl; + INFOMSG( + level2 << "zdir=-1 " << -dir << " x,y,z= " << idx << "," << idy << "," + << idz << " P=" << P << " I=" << I << endl); #endif } dir = Vector_t(0, 1, 0); if (bgeom_m->intersectRayBoundary(P, dir, I)) { - intersectHiY_m.insert(std::pair< std::tuple<int, int, int>, double >(pos, I[1])); + intersectHiY_m.insert( + std::pair<std::tuple<int, int, int>, double>(pos, I[1])); } else { #ifdef DEBUG_INTERSECT_RAY_BOUNDARY - *gmsg << "ydir=+1 " << dir << " x,y,z= " << idx << "," << idy - << "," << idz << " P=" << P <<" I=" << I << endl; + INFOMSG( + level2 << "ydir=+1 " << dir << " x,y,z= " << idx << "," << idy << "," + << idz << " P=" << P << " I=" << I << endl); #endif } if (bgeom_m->intersectRayBoundary(P, -dir, I)) { - intersectLoY_m.insert(std::pair< std::tuple<int, int, int>, double >(pos, I[1])); + intersectLoY_m.insert( + std::pair<std::tuple<int, int, int>, double>(pos, I[1])); } else { #ifdef DEBUG_INTERSECT_RAY_BOUNDARY - *gmsg << "ydir=-1" << -dir << " x,y,z= " << idx << "," << idy - << "," << idz << " P=" << P <<" I=" << I << endl; + INFOMSG( + level2 << "ydir=-1" << -dir << " x,y,z= " << idx << "," << idy << "," + << idz << " P=" << P << " I=" << I << endl); #endif } dir = Vector_t(1, 0, 0); if (bgeom_m->intersectRayBoundary(P, dir, I)) { - intersectHiX_m.insert(std::pair< std::tuple<int, int, int>, double >(pos, I[0])); + intersectHiX_m.insert( + std::pair<std::tuple<int, int, int>, double>(pos, I[0])); } else { #ifdef DEBUG_INTERSECT_RAY_BOUNDARY - *gmsg << "xdir=+1 " << dir << " x,y,z= " << idx << "," << idy - << "," << idz << " P=" << P <<" I=" << I << endl; + INFOMSG( + level2 << "xdir=+1 " << dir << " x,y,z= " << idx << "," << idy << "," + << idz << " P=" << P << " I=" << I << endl); #endif } - if (bgeom_m->intersectRayBoundary(P, -dir, I)){ - intersectLoX_m.insert(std::pair< std::tuple<int, int, int>, double >(pos, I[0])); + if (bgeom_m->intersectRayBoundary(P, -dir, I)) { + intersectLoX_m.insert( + std::pair<std::tuple<int, int, int>, double>(pos, I[0])); } else { #ifdef DEBUG_INTERSECT_RAY_BOUNDARY - *gmsg << "xdir=-1 " << -dir << " x,y,z= " << idx << "," << idy - << "," << idz << " P=" << P <<" I=" << I << endl; + INFOMSG( + level2 << "xdir=-1 " << -dir << " x,y,z= " << idx << "," << idy << "," + << idz << " P=" << P << " I=" << I << endl); #endif } } else { isInsideMap_m[toCoordIdx(idx, idy, idz)] = false; #ifdef DEBUG_INTERSECT_RAY_BOUNDARY - *gmsg << "OUTSIDE" << " x,y,z= " << idx << "," << idy - << "," << idz << " P=" << P <<" I=" << I << endl; + INFOMSG( + level2 << "OUTSIDE" << " x,y,z= " << idx << "," << idy << "," << idz + << " P=" << P << " I=" << I << endl); #endif } } @@ -277,88 +290,93 @@ void ArbitraryDomain::linearInterpolation(int idx, int idy, int idz, { scaleFactor = 1; - double cx = (idx - (nr_m[0]-1)/2.0)*hr_m[0]; - double cy = (idy - (nr_m[1]-1)/2.0)*hr_m[1]; - double cz = (idz - (nr_m[2]-1)/2.0)*hr_m[2]; + double cx = getXRangeMin() + hr_m[0] * (idx + 0.5); + double cy = getYRangeMin() + hr_m[1] * (idy + 0.5); + double cz = getZRangeMin() + hr_m[2] * (idz + 0.5); + + std::tuple<int, int, int> coordxyz(idx, idy, idz); + + double dr = 0.0; + + double dw = hr_m[0]; + double de = hr_m[0]; + double dn = hr_m[1]; + double ds = hr_m[1]; + double df = hr_m[2]; + double db = hr_m[2]; - double dx_w=hr_m[0]; - double dx_e=hr_m[0]; - double dy_n=hr_m[1]; - double dy_s=hr_m[1]; - double dz_f=hr_m[2]; - double dz_b=hr_m[2]; value.center = 0.0; - std::tuple<int, int, int> coordxyz(idx, idy, idz); + // we are a left boundary point + if (idx == 0 || !isInside(idx - 1, idy, idz)) { + dr = std::abs(intersectLoX_m.find(coordxyz)->second - cx); + value.center += 1.0 / (dr * dw); + value.west = 0.0; + // ...we are not + } else { + value.center += 1.0 / (dw * dw); + value.west = -1.0 / (dw * dw); + } + + // we are a right boundary point + if (idx == (nr_m[0] - 1) || !isInside(idx + 1, idy, idz)) { + dr = std::abs(intersectHiX_m.find(coordxyz)->second - cx); + value.center += 1.0 / (dr * de); + value.east = 0.0; + // ...we are not + } else { + value.center += 1.0 / (de * de); + value.east = -1.0 / (de * de); + } + + // we are a lower boundary point + if (idy == 0 || !isInside(idx, idy - 1, idz)) { + dr = std::abs(intersectLoY_m.find(coordxyz)->second - cy); + value.center += 1.0 / (dr * ds); + value.south = 0.0; + // ...we are not + } else { + value.center += 1.0 / (ds * ds); + value.south = -1.0 / (ds * ds); + } + + // we are a upper boundary point + if (idy == (nr_m[1] - 1) || !isInside(idx, idy + 1, idz)) { + dr = std::abs(intersectHiY_m.find(coordxyz)->second - cy); + value.center += 1.0 / (dr * dn); + value.north = 0.0; + // ...we are not + } else { + value.center += 1.0 / (dn * dn); + value.north = -1.0 / (dn * dn); + } + + // We are a back boundary point + if (idz == 0 || !isInside(idx, idy, idz - 1)) { + dr = std::abs(intersectLoZ_m.find(coordxyz)->second - cz); + value.center += 1.0 / (dr * db); + value.back = 0.0; + // ...we are not + } else { + value.center += 1.0 / (db * db); + value.back = -1.0 / (db * db); + } + + // We are a front boundary point + if (idz == (nr_m[2] - 1) || !isInside(idx, idy, idz + 1)) { + dr = std::abs(intersectHiZ_m.find(coordxyz)->second - cz); + value.center += 1.0 / (dr * df); + value.front = 0.0; + // ...we are not + } else { + value.center += 1.0 / (df * df); + value.front = -1.0 / (df * df); + } - if (idx == nr_m[0]-1) - dx_e = std::abs(intersectHiX_m.find(coordxyz)->second - cx); - if (idx == 0) - dx_w = std::abs(intersectLoX_m.find(coordxyz)->second - cx); - if (idy == nr_m[1]-1) - dy_n = std::abs(intersectHiY_m.find(coordxyz)->second - cy); - if (idy == 0) - dy_s = std::abs(intersectLoY_m.find(coordxyz)->second - cy); - if (idz == nr_m[2]-1) - dz_b = std::abs(intersectHiZ_m.find(coordxyz)->second - cz); - if (idz == 0) - dz_f = std::abs(intersectLoZ_m.find(coordxyz)->second - cz); - - if(dx_w != 0) - value.west = -(dz_f + dz_b) * (dy_n + dy_s) / dx_w; - else - value.west = 0; - if(dx_e != 0) - value.east = -(dz_f + dz_b) * (dy_n + dy_s) / dx_e; - else - value.east = 0; - if(dy_n != 0) - value.north = -(dz_f + dz_b) * (dx_w + dx_e) / dy_n; - else - value.north = 0; - if(dy_s != 0) - value.south = -(dz_f + dz_b) * (dx_w + dx_e) / dy_s; - else - value.south = 0; - if(dz_f != 0) - value.front = -(dx_w + dx_e) * (dy_n + dy_s) / dz_f; - else - value.front = 0; - if(dz_b != 0) - value.back = -(dx_w + dx_e) * (dy_n + dy_s) / dz_b; - else - value.back = 0; - - //RHS scaleFactor for current 3D index - //0.5* comes from discretiztaion - //scaleFactor = 0.5*(dw+de)*(dn+ds)*(df+db); - scaleFactor = 0.5; - if(dx_w + dx_e != 0) - scaleFactor *= (dx_w + dx_e); - if(dy_n + dy_s != 0) - scaleFactor *= (dy_n + dy_s); - if(dz_f + dz_b != 0) - scaleFactor *= (dz_f + dz_b); - - //catch the case where a point lies on the boundary - double m1 = dx_w * dx_e; - double m2 = dy_n * dy_s; - if(dx_e == 0) - m1 = dx_w; - if(dx_w == 0) - m1 = dx_e; - if(dy_n == 0) - m2 = dy_s; - if(dy_s == 0) - m2 = dy_n; - - value.center = 2 / hr_m[2]; - if(dx_w != 0 || dx_e != 0) - value.center *= (dx_w + dx_e); - if(dy_n != 0 || dy_s != 0) - value.center *= (dy_n + dy_s); - if(dx_w != 0 || dx_e != 0) - value.center += (dz_f + dz_b) * (dy_n + dy_s) * (dx_w + dx_e) / m1; - if(dy_n != 0 || dy_s != 0) - value.center += (dz_f + dz_b) * (dx_w + dx_e) * (dy_n + dy_s) / m2; + if (value.center <= 0.0) { + INFOMSG( + level3 << "Got value.center <= 0.0 at idx/idy/idz = " << idx << "/" << idy << "/" + << idz << endl); + INFOMSG(level3 << "This will lead to an exception and quit OPAL." << endl); + } } diff --git a/src/Solvers/MGPoissonSolver.cpp b/src/Solvers/MGPoissonSolver.cpp index 0bd5ac6eabe41f4fe4ab3aec90afa6e17d858a89..5e90eab44f5623afe39ee06c7fcef903bcb3fe92 100644 --- a/src/Solvers/MGPoissonSolver.cpp +++ b/src/Solvers/MGPoissonSolver.cpp @@ -355,6 +355,7 @@ void MGPoissonSolver::computePotential(Field_t &rho, Vector_t hr) { for (int idx = localId[0].first(); idx <= localId[0].last(); idx++) { NDIndex<3> l(Index(idx, idx), Index(idy, idy), Index(idz, idz)); if (bp_m->isInside(idx, idy, idz)) + id++ RHS->replaceGlobalValue(bp_m->getIdx(idx, idy, idz), 4.0 * M_PI * rho.localElement(l) / scaleFactor); }