Commit d194a302 authored by Andrei Gheata's avatar Andrei Gheata Committed by Andrei Gheata
Browse files

More precision fixes in the ShapeTester, improved use of ApproachSolid

parent 3bd6fe87
......@@ -92,7 +92,7 @@ void ShapeTester<ImplT>::SetDefaults()
fSolidTolerance = vecgeom::kTolerance;
fSolidFarAway = vecgeom::kFarAway;
fStat = false;
fTestBoundaryErrors = true;
fTestBoundaryErrors = false;
fDebug = false;
}
......@@ -708,7 +708,9 @@ int ShapeTester<ImplT>::TestFarAwayPoint()
// Move point far away
point1 = point1 + vec * fSolidFarAway;
// Shoot back to solid, then compute point on surface
distBB = fVolume->GetUnplacedVolume()->ApproachSolid(point1, -1 / vec);
Vec_t invdir = Vec_t(1./NonZero(vec.x()), 1./NonZero(vec.y()), 1./NonZero(vec.z()));
distBB = fVolume->GetUnplacedVolume()->ApproachSolid(point1, -invdir);
distBB -= 10. * tolerance;
pointBB = point1 - distBB * vec;
distIn = fVolume->DistanceToIn(pointBB, -vec);
pointSurf = pointBB - distIn * vec;
......@@ -985,6 +987,11 @@ int ShapeTester<ImplT>::TestOutsidePoint()
int errCode = 0;
int i, n = fMaxPointsInside;
int nError = 0;
// A.G. Approaching to the bonding box risks stepping numerically on the solid boundary,
// so we need to subtract a small value. Also, the initial point may be in a hole, so
// inside the bounding box, in such case disBB being zero. In such case we don't subtract
// toleranceBB
Precision toleranceBB = 10. * fSolidTolerance;
ClearErrors();
for (int j = 0; j < fMaxPointsOutside; j++) {
......@@ -1015,7 +1022,10 @@ int ShapeTester<ImplT>::TestOutsidePoint()
// Connecting point inside
Vec_t vr = fPoints[i + fOffsetInside] - point;
Vec_t v = vr.Unit();
Precision distBB = fVolume->GetUnplacedVolume()->ApproachSolid(point, 1 / v);
Vec_t invdir = Vec_t(1./NonZero(v.x()), 1./NonZero(v.y()), 1./NonZero(v.z()));
Precision distBB = fVolume->GetUnplacedVolume()->ApproachSolid(point, invdir);
// Avoid approaching to the boundary
distBB = (distBB > toleranceBB) ? distBB - toleranceBB : 0.;
Vec_t pointBB = point + distBB * v;
Precision distIn = fVolume->DistanceToIn(pointBB, v);
Precision dist = distIn + distBB;
......@@ -1030,7 +1040,7 @@ int ShapeTester<ImplT>::TestOutsidePoint()
continue;
}
// Make sure the distance is bigger than the safety
if (dist < safeDistance - 1E-10) {
if (dist < safeDistance - fSolidTolerance) {
ReportError(&nError, point, v, safeDistance, "TO: DistanceToIn(p,v) < DistanceToIn(p)");
continue;
}
......@@ -1044,6 +1054,7 @@ int ShapeTester<ImplT>::TestOutsidePoint()
continue;
}
if (insideOrNot == vecgeom::EInside::kInside) {
insideOrNot = fVolume->Inside(p);
ReportError(&nError, point, v, dist, "TO: DistanceToIn(p,v) overshoots");
continue;
}
......@@ -1051,14 +1062,10 @@ int ShapeTester<ImplT>::TestOutsidePoint()
safeDistance = fVolume->SafetyToIn(p);
// The safety from a boundary should not be bigger than the tolerance
if (safeDistance > fSolidTolerance) {
safeDistance = fVolume->SafetyToIn(p);
ReportError(&nError, p, v, safeDistance, "TO2: SafetyToIn(p) should be zero");
continue;
}
safeDistance = fVolume->SafetyToOut(p);
if (safeDistance > fSolidTolerance) {
ReportError(&nError, p, v, safeDistance, "TO2: SafetyToOut(p) should be zero");
continue;
}
dist = fVolume->DistanceToIn(p, v);
safeDistance = fVolume->SafetyToIn(p);
......@@ -1068,6 +1075,7 @@ int ShapeTester<ImplT>::TestOutsidePoint()
// It should, however, *not* be infinity.
//
if (dist >= kInfLength) {
dist = fVolume->DistanceToIn(p, v);
ReportError(&nError, p, v, dist, "TO2: DistanceToIn(p,v) == kInfLength");
continue;
}
......@@ -1095,9 +1103,10 @@ int ShapeTester<ImplT>::TestOutsidePoint()
Vec_t norm1;
valid = fVolume->Normal(p, norm1);
// Check the entering normal when going inwards
if (norm1.Dot(v) > 0) {
ReportError(&nError, p, v, dist, "TO2: Ingoing surfaceNormal is incorrect");
}
// A.G The condition below may fail on corners where the normal is averaged. Disabling.
//if (norm1.Dot(v) > 0) {
// ReportError(&nError, p, v, dist, "TO2: Ingoing surfaceNormal is incorrect");
//}
Vec_t p2 = p + v * dist;
......@@ -1115,10 +1124,13 @@ int ShapeTester<ImplT>::TestOutsidePoint()
Vec_t norm2, norm3;
valid = fVolume->Normal(p2, norm2);
// Normal in exit point
if (norm2.Dot(v) < 0) {
if (fVolume->DistanceToIn(p2, v) != 0)
ReportError(&nError, p2, v, dist, "TO2: Outgoing surfaceNormal is incorrect");
}
// A.G. The normal in the exit point may oppose the direction if exiting through a corner
// where the normal is averaged. Disabling this check
//if (norm2.Dot(v) < 0) {
// if (fVolume->DistanceToIn(p2, v) != 0) {
// ReportError(&nError, p2, v, dist, "TO2: Outgoing surfaceNormal is incorrect");
// }
//}
// Check sign agreement on normals given by Normal and DistanceToOut
if (convex) {
if (norm.Dot(norm2) < 0.0) {
......@@ -1225,6 +1237,7 @@ int ShapeTester<ImplT>::TestAccuracyDistanceToIn(Precision dist)
int iIn = 0, iInNoSurf = 0, iOut = 0, iOutNoSurf = 0;
int iInInf = 0, iInZero = 0;
Precision tolerance = fSolidTolerance;
Precision toleranceBB = 10. * fSolidTolerance;
#ifdef VECGEOM_ROOT
// Histograms
......@@ -1263,8 +1276,10 @@ int ShapeTester<ImplT>::TestAccuracyDistanceToIn(Precision dist)
// Test for consistency for fPoints situated Outside
for (int j = 0; j < 1000; j++) {
vec = GetRandomDirection();
Vec_t invdir = Vec_t(1./NonZero(v.x()), 1./NonZero(v.y()), 1./NonZero(v.z()));
distBB = fVolume->GetUnplacedVolume()->ApproachSolid(point, 1 / vec);
distBB = fVolume->GetUnplacedVolume()->ApproachSolid(point, invdir);
distBB = (distBB > toleranceBB) ? distBB - toleranceBB : 0.;
pointBB = point + distBB * vec;
distIn = fVolume->DistanceToIn(pointBB, vec) + distBB;
distOut = CallDistanceToOut(fVolume, point, vec, normal, convex);
......
......@@ -33,9 +33,7 @@ int runTester(ImplT const *shape, int npoints, bool debug, bool stat)
tester.setDebug(debug);
tester.setStat(stat);
tester.SetMaxPoints(npoints);
#ifdef VECGEOM_FLOAT_PRECISION
tester.SetSolidTolerance(1e-4);
#endif
tester.SetSolidTolerance(vecgeom::kHalfTolerance);
int errcode = tester.Run(shape);
std::cout << "Final Error count for Shape *** " << shape->GetName() << "*** = " << errcode << "\n";
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment