From 0e7954c22bb83388c4e4e0e0fd1d5569ff90ae41 Mon Sep 17 00:00:00 2001
From: mattijs <mattijs>
Date: Tue, 29 Aug 2017 14:41:22 +0100
Subject: [PATCH] BUG: sampledTriSurfaceMesh: sampling outside of mesh. Fixes
 #575.

There are a few issues:
- error would only throw exceptions if not parallel
- if we change this we also need to make sure the functionObjectList
  construction is synchronised
- bounding box overlap was not returning the correct status so the code
  to avoid the issue of 'badly formed bounding box' was not triggered.
---
 src/OpenFOAM/db/error/error.C                 | 66 +++++++++----------
 .../functionObjectList/functionObjectList.C   |  4 +-
 src/OpenFOAM/meshes/boundBox/boundBoxI.H      | 11 +++-
 .../sampledTriSurfaceMesh.C                   | 28 ++++++--
 4 files changed, 64 insertions(+), 45 deletions(-)

diff --git a/src/OpenFOAM/db/error/error.C b/src/OpenFOAM/db/error/error.C
index cc0907d2221..b0c4b3d8771 100644
--- a/src/OpenFOAM/db/error/error.C
+++ b/src/OpenFOAM/db/error/error.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2014 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2015-2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -182,7 +182,17 @@ void Foam::error::exit(const int errNo)
         abort();
     }
 
-    if (Pstream::parRun())
+    if (throwExceptions_)
+    {
+        // Make a copy of the error to throw
+        error errorException(*this);
+
+        // Reset the message buffer for the next error message
+        messageStreamPtr_->reset();
+
+        throw errorException;
+    }
+    else if (Pstream::parRun())
     {
         Perr<< endl << *this << endl
             << "\nFOAM parallel run exiting\n" << endl;
@@ -190,22 +200,9 @@ void Foam::error::exit(const int errNo)
     }
     else
     {
-        if (throwExceptions_)
-        {
-            // Make a copy of the error to throw
-            error errorException(*this);
-
-            // Reset the message buffer for the next error message
-            messageStreamPtr_->reset();
-
-            throw errorException;
-        }
-        else
-        {
-            Perr<< endl << *this << endl
-                << "\nFOAM exiting\n" << endl;
-            ::exit(1);
-        }
+        Perr<< endl << *this << endl
+            << "\nFOAM exiting\n" << endl;
+        ::exit(1);
     }
 }
 
@@ -226,7 +223,17 @@ void Foam::error::abort()
         ::abort();
     }
 
-    if (Pstream::parRun())
+    if (throwExceptions_)
+    {
+        // Make a copy of the error to throw
+        error errorException(*this);
+
+        // Reset the message buffer for the next error message
+        messageStreamPtr_->reset();
+
+        throw errorException;
+    }
+    else if (Pstream::parRun())
     {
         Perr<< endl << *this << endl
             << "\nFOAM parallel run aborting\n" << endl;
@@ -235,23 +242,10 @@ void Foam::error::abort()
     }
     else
     {
-        if (throwExceptions_)
-        {
-            // Make a copy of the error to throw
-            error errorException(*this);
-
-            // Reset the message buffer for the next error message
-            messageStreamPtr_->reset();
-
-            throw errorException;
-        }
-        else
-        {
-            Perr<< endl << *this << endl
-                << "\nFOAM aborting\n" << endl;
-            printStack(Perr);
-            ::abort();
-        }
+        Perr<< endl << *this << endl
+            << "\nFOAM aborting\n" << endl;
+        printStack(Perr);
+        ::abort();
     }
 }
 
diff --git a/src/OpenFOAM/db/functionObjects/functionObjectList/functionObjectList.C b/src/OpenFOAM/db/functionObjects/functionObjectList/functionObjectList.C
index fea664c7419..762bfb3bf93 100644
--- a/src/OpenFOAM/db/functionObjects/functionObjectList/functionObjectList.C
+++ b/src/OpenFOAM/db/functionObjects/functionObjectList/functionObjectList.C
@@ -791,7 +791,9 @@ bool Foam::functionObjectList::read()
                 FatalError.throwExceptions(throwingError);
                 FatalIOError.throwExceptions(throwingIOerr);
 
-                if (foPtr.valid())
+                // If one processor only has thrown an exception (so exited the
+                // constructor) invalidate the whole functionObject
+                if (returnReduce(foPtr.valid(), andOp<bool>()))
                 {
                     objPtr = foPtr.ptr();
                 }
diff --git a/src/OpenFOAM/meshes/boundBox/boundBoxI.H b/src/OpenFOAM/meshes/boundBox/boundBoxI.H
index 03be3b7305e..004cc3655ea 100644
--- a/src/OpenFOAM/meshes/boundBox/boundBoxI.H
+++ b/src/OpenFOAM/meshes/boundBox/boundBoxI.H
@@ -59,7 +59,16 @@ inline Foam::boundBox::boundBox(Istream& is)
 
 inline bool Foam::boundBox::empty() const
 {
-    return (min_ > max_);
+    // Note: cannot use min_ > max_ here since that tests for -all- components
+    // of min_ being larger than max_.
+    for (direction dir = 0; dir < vector::nComponents; ++dir)
+    {
+        if (min_[dir] > max_[dir])
+        {
+            return true;
+        }
+    }
+    return false;
 }
 
 
diff --git a/src/sampling/sampledSurface/sampledTriSurfaceMesh/sampledTriSurfaceMesh.C b/src/sampling/sampledSurface/sampledTriSurfaceMesh/sampledTriSurfaceMesh.C
index 50fe214cbe8..3359515ade4 100644
--- a/src/sampling/sampledSurface/sampledTriSurfaceMesh/sampledTriSurfaceMesh.C
+++ b/src/sampling/sampledSurface/sampledTriSurfaceMesh/sampledTriSurfaceMesh.C
@@ -683,7 +683,8 @@ Foam::sampledTriSurfaceMesh::sampledTriSurfaceMesh
             IOobject::MUST_READ,
             IOobject::NO_WRITE,
             false
-        )
+        ),
+        dict
     ),
     sampleSource_(samplingSourceNames_.lookup("source", dict)),
     needsUpdate_(true),
@@ -779,15 +780,28 @@ bool Foam::sampledTriSurfaceMesh::update()
         surface_.triSurface::meshPoints()
     );
 
-    bb.intersect(mesh().bounds());
+    // Check for overlap with (global!) mesh bb
+    const bool intersect = bb.intersect(mesh().bounds());
 
-    // Extend a bit
-    const vector span(bb.span());
+    if (!intersect)
+    {
+        // Surface and mesh do not overlap at all. Guarantee a valid
+        // bounding box so we don't get any 'invalid bounding box' errors.
+        bb = treeBoundBox(mesh().bounds());
+        const vector span(bb.span());
 
-    bb.min() -= 0.5*span;
-    bb.max() += 0.5*span;
+        bb.min() += (0.5-1e-6)*span;
+        bb.max() -= (0.5-1e-6)*span;
+    }
+    else
+    {
+        // Extend a bit
+        const vector span(bb.span());
+        bb.min() -= 0.5*span;
+        bb.max() += 0.5*span;
 
-    bb.inflate(1e-6);
+        bb.inflate(1e-6);
+    }
 
     // Mesh search engine, no triangulation of faces.
     meshSearch meshSearcher(mesh(), bb, polyMesh::FACE_PLANES);
-- 
GitLab