View Issue Details

IDProjectCategoryView StatusLast Update
0001112OpenFOAM[All Projects] Bugpublic2015-03-29 21:53
Reporteruser146Assigned Tohenry 
Status resolvedResolutionfixed 
Product Version 
Fixed in Version 
Summary0001112: refineMesh utility in 2D refines the third direction while running in parallel

I found a small bug using refineMesh in parallel:

I defined a simple 2D square with blockMesh (says, 10*20*1 cells), with front and back defined as empty (two separate patches). If I use refineMesh, I get a new mesh of 20*40*1 cells.

However, if I decompose the domain (says 4 processors) and run refineMesh in parallel, I obtain 20*40*2 cells. The third direction is also refined.

TagsNo tags attached.



2015-03-29 17:39


refineMesh.C (12,476 bytes)


2015-03-29 17:39


bug1112.patch (604 bytes)
diff --git a/applications/utilities/mesh/manipulation/refineMesh/refineMesh.C b/applications/utilities/mesh/manipulation/refineMesh/refineMesh.C
index cbb528e..35fc778 100644
--- a/applications/utilities/mesh/manipulation/refineMesh/refineMesh.C
+++ b/applications/utilities/mesh/manipulation/refineMesh/refineMesh.C
@@ -271,7 +271,7 @@ label twoDNess(const polyMesh& mesh)
         const polyPatch& patch = patches[patchI];
-        if (!isA<wedgePolyPatch>(patch))
+        if (!isA<wedgePolyPatch>(patch) && !patch.empty())
             const vectorField& n = patch.faceAreas();
bug1112.patch (604 bytes)


2015-03-29 17:44

updater   ~0004537

Attached are the following files:

 - "refineMesh.C" for replacing the one at "OpenFOAM-2.3.x/applications/utilities/mesh/manipulation/refineMesh"

 - "bug1112.patch" which shows the change needed.

Essentially the problem is that the function "twoDNess" would check even the patches that are empty, which results in "mag(min(cosAngle) - max(cosAngle)) > 1e-6" being an impossible check (is no-one greater than 1e-6 ?), hence it probably gives something like "2*GREAT>1e-6".

The proposed bug fix is to first check if the patch is empty or not, before checking if it's perpendicular.


2015-03-29 19:42

manager   ~0004538

Should the test be for patches with 0 faces or of type "empty"? The patches only have 0 faces due to the decomposition; I think a reduction over the processors is needed. Rather than use all the complex geometric testing I think that the polyMesh functions

            //- Return the vector of geometric directions in mesh.
            // Defined according to the presence of empty and wedge patches.
            // 1 indicates unconstrained direction and -1 a constrained
            // direction.
            const Vector<label>& geometricD() const;

            //- Return the number of valid geometric dimensions in the mesh
            label nGeometricD() const;

could be used. These rely on 2D-ness being defined by the presence of empty and wedge patches rather than being a single layer of cell. Alternatively the
twoDNess function in refineMesh would need to be parallelized because at the moment it is possible for different processors to return different results from the 2D test.


2015-03-29 20:13

updater   ~0004543

!! Ooops, I should have checked what "empty()" really meant...
Yes, instead of "!patch.empty()" it should be "patch.size() > 0".

And yes, "nGeometricD()" should give a more accurate and non-redundant code definition about the mesh.


2015-03-29 20:28

manager   ~0004545

You were correct about the meaning of empty() (size = 0) but it is not clear that this test is valid as there is no reduction over the processors to ensure that they all agree.

I am happy to change the code to use geometricD() but it does mean that for 2D cases with front and back defined other than empty (sometimes this in needed) it will be refined in all 3 directions. One option would be to change the patch type to empty and back for the refinement process.


2015-03-29 20:41


refineMeshDict (1,946 bytes)
/*--------------------------------*- C++ -*----------------------------------*\
| =========                 |                                                 |
| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
|  \\    /   O peration     | Version:  2.3.0                                 |
|   \\  /    A nd           | Web:                      |
|    \\/     M anipulation  |                                                 |
    version     2.0;
    format      ascii;
    class       dictionary;
    object      refineMeshDict;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

// Cells to refine; name of cell set
set c0;

// Type of coordinate system:
// - global : coordinate system same for every cell. Usually aligned with
//   x,y,z axis. Specify in globalCoeffs section below.
// - patchLocal : coordinate system different for every cell. Specify in
//   patchLocalCoeffs section below.
coordinateSystem global;
//coordinateSystem patchLocal;

// .. and its coefficients. x,y in this case. (normal direction is calculated
// as tan1^tan2)
    tan1 (1 0 0);
    tan2 (0 1 0);

    patch outside;  // Normal direction is facenormal of zero'th face of patch
    tan1 (1 0 0);

// List of directions to refine

// Whether to use hex topology. This will
// - if patchLocal: all cells on selected patch should be hex
// - split all hexes in 2x2x2 through the middle of edges.
useHexTopology  false;

// Cut purely geometric (will cut hexes through vertices) or take topology
// into account. Incompatible with useHexTopology
geometricCut    false;

// Write meshes from intermediate steps
writeMesh       false;

// ************************************************************************* //
refineMeshDict (1,946 bytes)


2015-03-29 20:48

updater   ~0004546

From what I saw, "refineMesh" was already devised with some corner cases already in mind, therefore you don't need to contemplate all corner cases in a single automatic way.

That is why the "refineMeshDict" is optional and I did manage to use it to enforce to only refine as if it were 2D when executed in parallel (sorry, forgot to say it sooner). The attached dictionary file proves this and can be tested with the tutorial "multiphase/interFoam/ras/damBreak". The downside of using this dictionary file is that we also have to create a "cellSet" that has the whole list of cell IDs.

As for the function "twoDNess", it seemed reliable for the basic 1 cell thickness meshes, without the need to have to sync all processors. But this feels like it's redundant code, if "geometricD()" and "nGeometricD()" already give a similar functionality.


2015-03-29 21:39

manager   ~0004547

I am not convinced the twoDNess function will always work; with the change you made the result may be different on processors with patch-faces and those without. Anyway I have it running with "geometricD()" and "nGeometricD()" and will push the change when I have completed the tests.


2015-03-29 21:52

manager   ~0004548

Resolved by commit d7d91261a91b06828cd7977fcc47150446bdb807

Issue History

Date Modified Username Field Change
2013-12-20 00:58 user146 New Issue
2015-03-29 17:39 wyldckat File Added: refineMesh.C
2015-03-29 17:39 wyldckat File Added: bug1112.patch
2015-03-29 17:44 wyldckat Note Added: 0004537
2015-03-29 19:42 henry Note Added: 0004538
2015-03-29 20:13 wyldckat Note Added: 0004543
2015-03-29 20:28 henry Note Added: 0004545
2015-03-29 20:41 wyldckat File Added: refineMeshDict
2015-03-29 20:48 wyldckat Note Added: 0004546
2015-03-29 21:39 henry Note Added: 0004547
2015-03-29 21:52 henry Note Added: 0004548
2015-03-29 21:52 henry Status new => resolved
2015-03-29 21:52 henry Resolution open => fixed
2015-03-29 21:52 henry Assigned To => henry