Parallel GGI performance improvements
This commit is contained in:
parent
d199b6b6d0
commit
137014f511
102 changed files with 2355 additions and 301 deletions
|
@ -1,5 +1,9 @@
|
||||||
EXE_INC = \
|
EXE_INC = \
|
||||||
|
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||||
-I$(LIB_SRC)/triSurface/lnInclude \
|
-I$(LIB_SRC)/triSurface/lnInclude \
|
||||||
-I$(LIB_SRC)/surfMesh/lnInclude
|
-I$(LIB_SRC)/surfMesh/lnInclude
|
||||||
|
|
||||||
EXE_LIBS = -ltriSurface -lsurfMesh
|
EXE_LIBS = \
|
||||||
|
-lmeshTools \
|
||||||
|
-ltriSurface \
|
||||||
|
-lsurfMesh
|
||||||
|
|
|
@ -471,7 +471,7 @@ DebugSwitches
|
||||||
genericPatch 0;
|
genericPatch 0;
|
||||||
geomCellLooper 0;
|
geomCellLooper 0;
|
||||||
geometricSurfacePatch 0;
|
geometricSurfacePatch 0;
|
||||||
ggi 0;
|
GGIInterpolation 0;
|
||||||
global 0;
|
global 0;
|
||||||
globalMeshData 0;
|
globalMeshData 0;
|
||||||
globalPoints 0;
|
globalPoints 0;
|
||||||
|
|
|
@ -108,8 +108,8 @@ if ( ! $?WM_OSTYPE ) setenv WM_OSTYPE POSIX
|
||||||
# Compiler: set to Gcc, Gcc43 or Icc (for Intel's icc)
|
# Compiler: set to Gcc, Gcc43 or Icc (for Intel's icc)
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
#if ( ! $?WM_COMPILER ) setenv WM_COMPILER Gcc
|
#if ( ! $?WM_COMPILER ) setenv WM_COMPILER Gcc
|
||||||
setenv WM_COMPILER Gcc
|
#setenv WM_COMPILER Gcc
|
||||||
#setenv WM_COMPILER Icc
|
setenv WM_COMPILER Icc
|
||||||
|
|
||||||
setenv WM_COMPILER_ARCH
|
setenv WM_COMPILER_ARCH
|
||||||
setenv WM_COMPILER_LIB_ARCH
|
setenv WM_COMPILER_LIB_ARCH
|
||||||
|
@ -127,8 +127,8 @@ if ( ! $?WM_PRECISION_OPTION ) setenv WM_PRECISION_OPTION DP
|
||||||
|
|
||||||
# WM_COMPILE_OPTION = Opt | Debug | Prof
|
# WM_COMPILE_OPTION = Opt | Debug | Prof
|
||||||
#if ( ! $?WM_COMPILE_OPTION ) setenv WM_COMPILE_OPTION Opt
|
#if ( ! $?WM_COMPILE_OPTION ) setenv WM_COMPILE_OPTION Opt
|
||||||
setenv WM_COMPILE_OPTION Opt
|
#setenv WM_COMPILE_OPTION Opt
|
||||||
#setenv WM_COMPILE_OPTION Debug
|
setenv WM_COMPILE_OPTION Debug
|
||||||
|
|
||||||
# WM_MPLIB = | OPENMPI | MPICH | MPICH-GM | HPMPI | GAMMA | MPI | QSMPI
|
# WM_MPLIB = | OPENMPI | MPICH | MPICH-GM | HPMPI | GAMMA | MPI | QSMPI
|
||||||
if ( ! $?WM_MPLIB ) setenv WM_MPLIB OPENMPI
|
if ( ! $?WM_MPLIB ) setenv WM_MPLIB OPENMPI
|
||||||
|
|
|
@ -15,6 +15,7 @@ set -x
|
||||||
wmakePrintBuild -check || /bin/rm -f OpenFOAM/Make/$WM_OPTIONS/global.? 2>/dev/null
|
wmakePrintBuild -check || /bin/rm -f OpenFOAM/Make/$WM_OPTIONS/global.? 2>/dev/null
|
||||||
|
|
||||||
wmakeLnInclude OpenFOAM
|
wmakeLnInclude OpenFOAM
|
||||||
|
wmakeLnInclude meshTools
|
||||||
wmakeLnInclude OSspecific/$WM_OSTYPE
|
wmakeLnInclude OSspecific/$WM_OSTYPE
|
||||||
Pstream/Allwmake
|
Pstream/Allwmake
|
||||||
|
|
||||||
|
|
|
@ -308,6 +308,7 @@ primitiveShapes = meshes/primitiveShapes
|
||||||
|
|
||||||
$(primitiveShapes)/line/line.C
|
$(primitiveShapes)/line/line.C
|
||||||
$(primitiveShapes)/plane/plane.C
|
$(primitiveShapes)/plane/plane.C
|
||||||
|
$(primitiveShapes)/triangle/triangleFuncs.C
|
||||||
$(primitiveShapes)/triangle/intersection.C
|
$(primitiveShapes)/triangle/intersection.C
|
||||||
|
|
||||||
meshShapes = meshes/meshShapes
|
meshShapes = meshes/meshShapes
|
||||||
|
@ -495,6 +496,7 @@ $(pointBoundaryMesh)/pointBoundaryMesh.C
|
||||||
meshes/boundBox/boundBox.C
|
meshes/boundBox/boundBox.C
|
||||||
|
|
||||||
meshTools = meshes/meshTools
|
meshTools = meshes/meshTools
|
||||||
|
$(meshTools)/meshTools.C
|
||||||
$(meshTools)/matchPoints.C
|
$(meshTools)/matchPoints.C
|
||||||
$(meshTools)/mergePoints.C
|
$(meshTools)/mergePoints.C
|
||||||
|
|
||||||
|
@ -563,12 +565,33 @@ $(interpolations)/RBFInterpolation/RBFFunctions/Gauss/Gauss.C
|
||||||
$(interpolations)/RBFInterpolation/RBFFunctions/TPS/TPS.C
|
$(interpolations)/RBFInterpolation/RBFFunctions/TPS/TPS.C
|
||||||
$(interpolations)/RBFInterpolation/RBFFunctions/IMQB/IMQB.C
|
$(interpolations)/RBFInterpolation/RBFFunctions/IMQB/IMQB.C
|
||||||
|
|
||||||
|
|
||||||
algorithms/MeshWave/MeshWaveName.C
|
algorithms/MeshWave/MeshWaveName.C
|
||||||
algorithms/MeshWave/FaceCellWaveName.C
|
algorithms/MeshWave/FaceCellWaveName.C
|
||||||
algorithms/polygon/clipping/SutherlandHodgman.C
|
algorithms/polygon/clipping/SutherlandHodgman.C
|
||||||
algorithms/polygon/pointInPolygon/HormannAgathos.C
|
algorithms/polygon/pointInPolygon/HormannAgathos.C
|
||||||
algorithms/rotation/RodriguesRotation.C
|
algorithms/rotation/RodriguesRotation.C
|
||||||
|
|
||||||
|
octree = algorithms/octree/octree
|
||||||
|
$(octree)/octreeName.C
|
||||||
|
$(octree)/octreeDataPoint.C
|
||||||
|
$(octree)/octreeDataPointTreeLeaf.C
|
||||||
|
$(octree)/octreeDataEdges.C
|
||||||
|
$(octree)/octreeDataCell.C
|
||||||
|
$(octree)/octreeDataFace.C
|
||||||
|
$(octree)/octreeDataBoundBox.C
|
||||||
|
$(octree)/treeBoundBox.C
|
||||||
|
$(octree)/treeNodeName.C
|
||||||
|
$(octree)/treeLeafName.C
|
||||||
|
$(octree)/pointIndexHitIOList.C
|
||||||
|
|
||||||
|
indexedOctree = algorithms/octree/indexedOctree
|
||||||
|
$(indexedOctree)/indexedOctreeName.C
|
||||||
|
$(indexedOctree)/treeDataCell.C
|
||||||
|
$(indexedOctree)/treeDataEdge.C
|
||||||
|
$(indexedOctree)/treeDataFace.C
|
||||||
|
$(indexedOctree)/treeDataPoint.C
|
||||||
|
|
||||||
graph/curve/curve.C
|
graph/curve/curve.C
|
||||||
graph/graph.C
|
graph/graph.C
|
||||||
|
|
||||||
|
|
|
@ -120,8 +120,8 @@ public:
|
||||||
|
|
||||||
// Search
|
// Search
|
||||||
|
|
||||||
//- Get type (inside,outside,mixed,unknown) of point w.r.t. surface.
|
//- Get type (inside,outside,mixed,unknown) of point w.r.t. surface
|
||||||
// Only makes sense for closed surfaces.
|
// Only makes sense for closed surfaces
|
||||||
label getVolumeType
|
label getVolumeType
|
||||||
(
|
(
|
||||||
const indexedOctree<treeDataCell>&,
|
const indexedOctree<treeDataCell>&,
|
|
@ -77,8 +77,8 @@ bool Foam::treeDataPoint::overlaps
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Calculate nearest point to sample. Updates (if any) nearestDistSqr, minIndex,
|
// Calculate nearest point to sample. Updates (if any) nearestDistSqr,
|
||||||
// nearestPoint.
|
// minIndex, nearestPoint.
|
||||||
void Foam::treeDataPoint::findNearest
|
void Foam::treeDataPoint::findNearest
|
||||||
(
|
(
|
||||||
const labelList& indices,
|
const labelList& indices,
|
|
@ -338,7 +338,7 @@ Foam::label Foam::octree<Type>::findNearest
|
||||||
|
|
||||||
|
|
||||||
template <class Type>
|
template <class Type>
|
||||||
Foam::labelList Foam::octree<Type>::findBox(const boundBox& bb) const
|
Foam::labelList Foam::octree<Type>::findBox(const treeBoundBox& bb) const
|
||||||
{
|
{
|
||||||
// Storage for labels of shapes inside bb. Size estimate.
|
// Storage for labels of shapes inside bb. Size estimate.
|
||||||
labelHashSet elements(100);
|
labelHashSet elements(100);
|
|
@ -339,7 +339,7 @@ public:
|
||||||
|
|
||||||
//- Find (in no particular order) indices of all shapes inside or
|
//- Find (in no particular order) indices of all shapes inside or
|
||||||
// overlapping bounding box (i.e. all shapes not outside box)
|
// overlapping bounding box (i.e. all shapes not outside box)
|
||||||
labelList findBox(const boundBox& bb) const;
|
labelList findBox(const treeBoundBox& bb) const;
|
||||||
|
|
||||||
//- Find intersected shape along line. pointIndexHit contains index
|
//- Find intersected shape along line. pointIndexHit contains index
|
||||||
// of nearest shape intersected and the intersection point. Uses
|
// of nearest shape intersected and the intersection point. Uses
|
210
src/OpenFOAM/algorithms/octree/octree/octreeDataBoundBox.C
Normal file
210
src/OpenFOAM/algorithms/octree/octree/octreeDataBoundBox.C
Normal file
|
@ -0,0 +1,210 @@
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright held by original author
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by the
|
||||||
|
Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "octreeDataBoundBox.H"
|
||||||
|
#include "labelList.H"
|
||||||
|
#include "polyMesh.H"
|
||||||
|
#include "octree.H"
|
||||||
|
#include "polyPatch.H"
|
||||||
|
#include "triangleFuncs.H"
|
||||||
|
#include "linePointRef.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
defineTypeNameAndDebug(Foam::octreeDataBoundBox, 0);
|
||||||
|
|
||||||
|
Foam::scalar Foam::octreeDataBoundBox::tol
|
||||||
|
(
|
||||||
|
debug::tolerances("octreeDataBoundBoxTol", 1e-6)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::octreeDataBoundBox::octreeDataBoundBox
|
||||||
|
(
|
||||||
|
const treeBoundBoxList& bbL
|
||||||
|
)
|
||||||
|
:
|
||||||
|
allBb_(bbL)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::octreeDataBoundBox::octreeDataBoundBox(const octreeDataBoundBox& shapes)
|
||||||
|
:
|
||||||
|
allBb_(shapes.allBb())
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::octreeDataBoundBox::~octreeDataBoundBox()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::label Foam::octreeDataBoundBox::getSampleType
|
||||||
|
(
|
||||||
|
const octree<octreeDataBoundBox>& oc,
|
||||||
|
const point& sample
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return octree<octreeDataBoundBox>::UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::octreeDataBoundBox::overlaps
|
||||||
|
(
|
||||||
|
const label index,
|
||||||
|
const treeBoundBox& sampleBb
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return sampleBb.overlaps(allBb_[index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::octreeDataBoundBox::contains(const label, const point&) const
|
||||||
|
{
|
||||||
|
notImplemented
|
||||||
|
(
|
||||||
|
"octreeDataBoundBox::contains(const label, const point&)"
|
||||||
|
);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::octreeDataBoundBox::intersects
|
||||||
|
(
|
||||||
|
const label index,
|
||||||
|
const point& start,
|
||||||
|
const point& end,
|
||||||
|
point& intersectionPoint
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
notImplemented
|
||||||
|
(
|
||||||
|
"octreeDataBoundBox::intersects(const label, const point&)"
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::octreeDataBoundBox::findTightest
|
||||||
|
(
|
||||||
|
const label index,
|
||||||
|
const point& sample,
|
||||||
|
treeBoundBox& tightest
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
// Get furthest away vertex
|
||||||
|
point myNear, myFar;
|
||||||
|
allBb_[index].calcExtremities(sample, myNear, myFar);
|
||||||
|
|
||||||
|
const point dist = myFar - sample;
|
||||||
|
scalar myFarDist = mag(dist);
|
||||||
|
|
||||||
|
point tightestNear, tightestFar;
|
||||||
|
tightest.calcExtremities(sample, tightestNear, tightestFar);
|
||||||
|
|
||||||
|
scalar tightestFarDist = mag(tightestFar - sample);
|
||||||
|
|
||||||
|
if (tightestFarDist < myFarDist)
|
||||||
|
{
|
||||||
|
// Keep current tightest.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Construct bb around sample and myFar
|
||||||
|
const point dist2(fabs(dist.x()), fabs(dist.y()), fabs(dist.z()));
|
||||||
|
|
||||||
|
tightest.min() = sample - dist2;
|
||||||
|
tightest.max() = sample + dist2;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Determine numerical value of sign of sample compared to shape at index
|
||||||
|
Foam::scalar Foam::octreeDataBoundBox::calcSign
|
||||||
|
(
|
||||||
|
const label index,
|
||||||
|
const point& sample,
|
||||||
|
point& n
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
n = vector::zero;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Calculate nearest point on/in shapei
|
||||||
|
Foam::scalar Foam::octreeDataBoundBox::calcNearest
|
||||||
|
(
|
||||||
|
const label index,
|
||||||
|
const point& sample,
|
||||||
|
point& nearest
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
notImplemented
|
||||||
|
(
|
||||||
|
"octreeDataBoundBox::calcNearest"
|
||||||
|
"(const label index, const point& sample, point& nearest)"
|
||||||
|
);
|
||||||
|
|
||||||
|
return GREAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Calculate nearest point on/in shapei
|
||||||
|
Foam::scalar Foam::octreeDataBoundBox::calcNearest
|
||||||
|
(
|
||||||
|
const label index,
|
||||||
|
const linePointRef& ln,
|
||||||
|
point& linePt,
|
||||||
|
point& shapePt
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
notImplemented
|
||||||
|
(
|
||||||
|
"octreeDataBoundBox::calcNearest"
|
||||||
|
"(const label, const linePointRef&, point&, point&)"
|
||||||
|
);
|
||||||
|
return GREAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::octreeDataBoundBox::write(Ostream& os, const label index) const
|
||||||
|
{
|
||||||
|
os << allBb_[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
213
src/OpenFOAM/algorithms/octree/octree/octreeDataBoundBox.H
Normal file
213
src/OpenFOAM/algorithms/octree/octree/octreeDataBoundBox.H
Normal file
|
@ -0,0 +1,213 @@
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright held by original author
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by the
|
||||||
|
Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::octreeDataBoundBox
|
||||||
|
|
||||||
|
Description
|
||||||
|
Holds data for octree to work on simple bounding boxes
|
||||||
|
|
||||||
|
For example, calculate (in calcNearest) the correct intersection point
|
||||||
|
with a bounding box.
|
||||||
|
|
||||||
|
Using bounding boxes simplify the usage of octree when only
|
||||||
|
primitivePatches entities are available (eg: from inside ggi interpolators)
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
octreeDataBoundBox.C
|
||||||
|
|
||||||
|
Author
|
||||||
|
Martin Beaudoin, Hydro-Quebec, (2010)
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef octreeDataBoundBox_H
|
||||||
|
#define octreeDataBoundBox_H
|
||||||
|
|
||||||
|
#include "treeBoundBoxList.H"
|
||||||
|
#include "faceList.H"
|
||||||
|
#include "point.H"
|
||||||
|
#include "className.H"
|
||||||
|
#include "linePointRef.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
// Forward declaration of classes
|
||||||
|
class primitiveMesh;
|
||||||
|
template<class Type> class octree;
|
||||||
|
class polyPatch;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class octreeDataBoundBox Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class octreeDataBoundBox
|
||||||
|
{
|
||||||
|
// Static data
|
||||||
|
|
||||||
|
//- Tolerance on linear dimensions
|
||||||
|
static scalar tol;
|
||||||
|
|
||||||
|
|
||||||
|
// Private data
|
||||||
|
|
||||||
|
//- Bounding boxes
|
||||||
|
treeBoundBoxList allBb_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Declare name of the class and its debug switch
|
||||||
|
ClassName("octreeDataBoundBox");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from list of precomputed of bound boxes
|
||||||
|
explicit octreeDataBoundBox
|
||||||
|
(
|
||||||
|
const treeBoundBoxList& bbL
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Construct as copy
|
||||||
|
octreeDataBoundBox(const octreeDataBoundBox&);
|
||||||
|
|
||||||
|
|
||||||
|
// Destructor
|
||||||
|
|
||||||
|
~octreeDataBoundBox();
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
// Access
|
||||||
|
|
||||||
|
const treeBoundBoxList& allBb() const
|
||||||
|
{
|
||||||
|
return allBb_;
|
||||||
|
}
|
||||||
|
|
||||||
|
label size() const
|
||||||
|
{
|
||||||
|
return allBb_.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Search
|
||||||
|
|
||||||
|
//- Get type of sample
|
||||||
|
label getSampleType
|
||||||
|
(
|
||||||
|
const octree<octreeDataBoundBox>&,
|
||||||
|
const point&
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Does (bb of) shape at index overlap bb
|
||||||
|
bool overlaps
|
||||||
|
(
|
||||||
|
const label index,
|
||||||
|
const treeBoundBox& sampleBb
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Does shape at index contain sample
|
||||||
|
bool contains
|
||||||
|
(
|
||||||
|
const label index,
|
||||||
|
const point& sample
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Segment (from start to end) intersection with shape
|
||||||
|
// at index. If intersects returns true and sets intersectionPoint
|
||||||
|
bool intersects
|
||||||
|
(
|
||||||
|
const label index,
|
||||||
|
const point& start,
|
||||||
|
const point& end,
|
||||||
|
point& intersectionPoint
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Sets newTightest to bounding box (and returns true) if
|
||||||
|
// nearer to sample than tightest bounding box. Otherwise
|
||||||
|
// returns false.
|
||||||
|
bool findTightest
|
||||||
|
(
|
||||||
|
const label index,
|
||||||
|
const point& sample,
|
||||||
|
treeBoundBox& tightest
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Given index get unit normal and calculate (numerical) sign
|
||||||
|
// of sample.
|
||||||
|
// Used to determine accuracy of calcNearest or inside/outside.
|
||||||
|
scalar calcSign
|
||||||
|
(
|
||||||
|
const label index,
|
||||||
|
const point& sample,
|
||||||
|
vector& n
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Calculates nearest (to sample) point in shape.
|
||||||
|
// Returns point and mag(nearest - sample). Returns GREAT if
|
||||||
|
// sample does not project onto (triangle decomposition) of face.
|
||||||
|
scalar calcNearest
|
||||||
|
(
|
||||||
|
const label index,
|
||||||
|
const point& sample,
|
||||||
|
point& nearest
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Calculates nearest (to line segment) point in shape.
|
||||||
|
// Returns distance and both point.
|
||||||
|
scalar calcNearest
|
||||||
|
(
|
||||||
|
const label index,
|
||||||
|
const linePointRef& ln,
|
||||||
|
point& linePt, // nearest point on line
|
||||||
|
point& shapePt // nearest point on shape
|
||||||
|
) const;
|
||||||
|
|
||||||
|
|
||||||
|
// Write
|
||||||
|
|
||||||
|
//- Write shape at index
|
||||||
|
void write(Ostream& os, const label index) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
|
@ -545,6 +545,7 @@ bool Foam::octreeDataFace::overlaps
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -555,6 +556,7 @@ bool Foam::octreeDataFace::contains(const label, const point&) const
|
||||||
(
|
(
|
||||||
"octreeDataFace::contains(const label, const point&)"
|
"octreeDataFace::contains(const label, const point&)"
|
||||||
);
|
);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -260,13 +260,13 @@ public:
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
//- Overlaps other boundingbox?
|
//- Overlaps other boundingbox?
|
||||||
inline bool overlaps(const treeBoundBox&) const;
|
inline bool overlaps(const boundBox&) const;
|
||||||
|
|
||||||
//- Overlaps boundingSphere (centre + sqr(radius))?
|
//- Overlaps boundingSphere (centre + sqr(radius))?
|
||||||
bool overlaps(const point&, const scalar radiusSqr) const;
|
bool overlaps(const point&, const scalar radiusSqr) const;
|
||||||
|
|
||||||
//- Intersects segment; set point to intersection position and face,
|
//- Intersects segment; set point to intersection position and face
|
||||||
// return true if intersection found.
|
// Will return true if intersection found.
|
||||||
// (pt argument used during calculation even if not intersecting).
|
// (pt argument used during calculation even if not intersecting).
|
||||||
// Calculates intersections from outside supplied vector
|
// Calculates intersections from outside supplied vector
|
||||||
// (overallStart, overallVec). This is so when
|
// (overallStart, overallVec). This is so when
|
||||||
|
@ -333,6 +333,12 @@ public:
|
||||||
// and guarantees in any direction s*mag(span) minimum width
|
// and guarantees in any direction s*mag(span) minimum width
|
||||||
inline treeBoundBox extend(Random&, const scalar s) const;
|
inline treeBoundBox extend(Random&, const scalar s) const;
|
||||||
|
|
||||||
|
//- Return slightly wider bounding box
|
||||||
|
// Extends all dimensions with s*span
|
||||||
|
// MB, 28/May/2011
|
||||||
|
inline treeBoundBox extend(const scalar s) const;
|
||||||
|
|
||||||
|
|
||||||
// Friend Operators
|
// Friend Operators
|
||||||
|
|
||||||
friend bool operator==(const treeBoundBox&, const treeBoundBox&);
|
friend bool operator==(const treeBoundBox&, const treeBoundBox&);
|
|
@ -309,7 +309,7 @@ inline void Foam::treeBoundBox::searchOrder
|
||||||
|
|
||||||
// true if bb's intersect or overlap.
|
// true if bb's intersect or overlap.
|
||||||
// Note: <= to make sure we catch all.
|
// Note: <= to make sure we catch all.
|
||||||
inline bool Foam::treeBoundBox::overlaps(const treeBoundBox& bb) const
|
inline bool Foam::treeBoundBox::overlaps(const boundBox& bb) const
|
||||||
{
|
{
|
||||||
return boundBox::overlaps(bb);
|
return boundBox::overlaps(bb);
|
||||||
}
|
}
|
||||||
|
@ -347,6 +347,28 @@ inline Foam::treeBoundBox Foam::treeBoundBox::extend
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
//- Return slightly wider bounding box, without a random gen param
|
||||||
|
// So we are sure to stay away from very small offsets like rndGen == 0
|
||||||
|
// MB, 28/May/2011
|
||||||
|
inline Foam::treeBoundBox Foam::treeBoundBox::extend(const scalar s) const
|
||||||
|
{
|
||||||
|
treeBoundBox bb(*this);
|
||||||
|
|
||||||
|
vector span(bb.max() - bb.min());
|
||||||
|
|
||||||
|
// Make 3D
|
||||||
|
scalar magSpan = Foam::mag(span);
|
||||||
|
|
||||||
|
for (direction dir = 0; dir < vector::nComponents; dir++)
|
||||||
|
{
|
||||||
|
span[dir] = Foam::max(s*magSpan, span[dir]);
|
||||||
|
}
|
||||||
|
|
||||||
|
bb.min() -= cmptMultiply(s*vector::one, span);
|
||||||
|
bb.max() += cmptMultiply(s*vector::one, span);
|
||||||
|
|
||||||
|
return bb;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
|
@ -334,7 +334,7 @@ template <class Type>
|
||||||
bool Foam::treeLeaf<Type>::findBox
|
bool Foam::treeLeaf<Type>::findBox
|
||||||
(
|
(
|
||||||
const Type& shapes,
|
const Type& shapes,
|
||||||
const boundBox& box,
|
const treeBoundBox& box,
|
||||||
labelHashSet& elements
|
labelHashSet& elements
|
||||||
) const
|
) const
|
||||||
{
|
{
|
|
@ -235,7 +235,7 @@ public:
|
||||||
bool findBox
|
bool findBox
|
||||||
(
|
(
|
||||||
const Type& shapes,
|
const Type& shapes,
|
||||||
const boundBox& bb,
|
const treeBoundBox& bb,
|
||||||
labelHashSet& elements
|
labelHashSet& elements
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
|
@ -276,7 +276,7 @@ public:
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
#include "octreeDataPointTreeLeaf.H"
|
#include "octreeDataPointTreeLeaf.H"
|
||||||
#include "octreeDataTriSurfaceTreeLeaf.H"
|
//#include "octreeDataTriSurfaceTreeLeaf.H" HJ, header moved to triSurfaceMesh.H
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
|
@ -764,7 +764,7 @@ bool Foam::treeNode<Type>::findTightest
|
||||||
// Estimate for best place to start searching
|
// Estimate for best place to start searching
|
||||||
label sampleOctant = this->bb().subOctant(midpoint(), sample, onEdge);
|
label sampleOctant = this->bb().subOctant(midpoint(), sample, onEdge);
|
||||||
|
|
||||||
// Go into all suboctants (one containing sample first) and update tightest.
|
// Go into all suboctants (one containing sample first) and update tightest
|
||||||
// Order of visiting is if e.g. sampleOctant = 5:
|
// Order of visiting is if e.g. sampleOctant = 5:
|
||||||
// 5 1 2 3 4 0 6 7
|
// 5 1 2 3 4 0 6 7
|
||||||
for (label octantI=0; octantI<8; octantI++)
|
for (label octantI=0; octantI<8; octantI++)
|
||||||
|
@ -846,7 +846,7 @@ bool Foam::treeNode<Type>::findNearest
|
||||||
// Estimate for best place to start searching
|
// Estimate for best place to start searching
|
||||||
label sampleOctant = this->bb().subOctant(midpoint(), sample, onEdge);
|
label sampleOctant = this->bb().subOctant(midpoint(), sample, onEdge);
|
||||||
|
|
||||||
// Go into all suboctants (one containing sample first) and update tightest.
|
// Go into all suboctants (one containing sample first) and update tightest
|
||||||
// Order of visiting is if e.g. sampleOctant = 5:
|
// Order of visiting is if e.g. sampleOctant = 5:
|
||||||
// 5 1 2 3 4 0 6 7
|
// 5 1 2 3 4 0 6 7
|
||||||
for (label octantI=0; octantI<8; octantI++)
|
for (label octantI=0; octantI<8; octantI++)
|
||||||
|
@ -1004,7 +1004,7 @@ template <class Type>
|
||||||
bool Foam::treeNode<Type>::findBox
|
bool Foam::treeNode<Type>::findBox
|
||||||
(
|
(
|
||||||
const Type& shapes,
|
const Type& shapes,
|
||||||
const boundBox& box,
|
const treeBoundBox& box,
|
||||||
labelHashSet& elements
|
labelHashSet& elements
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
|
@ -1018,7 +1018,7 @@ bool Foam::treeNode<Type>::findBox
|
||||||
onEdge
|
onEdge
|
||||||
);
|
);
|
||||||
|
|
||||||
// Go into all suboctants (one containing sample first) and update tightest.
|
// Go into all suboctants (one containing sample first) and update tightest
|
||||||
// Order of visiting is if e.g. sampleOctant = 5:
|
// Order of visiting is if e.g. sampleOctant = 5:
|
||||||
// 5 1 2 3 4 0 6 7
|
// 5 1 2 3 4 0 6 7
|
||||||
for (label octantI=0; octantI<8; octantI++)
|
for (label octantI=0; octantI<8; octantI++)
|
|
@ -271,7 +271,7 @@ public:
|
||||||
bool findBox
|
bool findBox
|
||||||
(
|
(
|
||||||
const Type& shapes,
|
const Type& shapes,
|
||||||
const boundBox& bb,
|
const treeBoundBox& bb,
|
||||||
labelHashSet& elements
|
labelHashSet& elements
|
||||||
) const;
|
) const;
|
||||||
|
|
|
@ -279,7 +279,7 @@ public:
|
||||||
//- Am I the master process
|
//- Am I the master process
|
||||||
static bool master()
|
static bool master()
|
||||||
{
|
{
|
||||||
return myProcNo_ == 0;
|
return myProcNo_ == masterNo();
|
||||||
}
|
}
|
||||||
|
|
||||||
//- Process index of the master
|
//- Process index of the master
|
||||||
|
|
|
@ -25,9 +25,10 @@ License
|
||||||
Description
|
Description
|
||||||
Gather data from all processors onto single processor according to some
|
Gather data from all processors onto single processor according to some
|
||||||
communication schedule (usually linear-to-master or tree-to-master).
|
communication schedule (usually linear-to-master or tree-to-master).
|
||||||
The gathered data will be a list with element procID the data from processor
|
The gathered data will be a list with element procID the data from
|
||||||
procID. Before calling every processor should insert its value into
|
processor procID. Before calling every processor should insert
|
||||||
Values[Pstream::myProcNo()].
|
its value into Values[Pstream::myProcNo()].
|
||||||
|
|
||||||
Note: after gather every processor only knows its own data and that of the
|
Note: after gather every processor only knows its own data and that of the
|
||||||
processors below it. Only the 'master' of the communication schedule holds
|
processors below it. Only the 'master' of the communication schedule holds
|
||||||
a fully filled List. Use scatter to distribute the data.
|
a fully filled List. Use scatter to distribute the data.
|
||||||
|
|
|
@ -60,6 +60,38 @@ void GGIInterpolation<MasterPatch, SlavePatch>::interpolate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class MasterPatch, class SlavePatch>
|
||||||
|
template<class Type>
|
||||||
|
void GGIInterpolation<MasterPatch, SlavePatch>::maskedInterpolate
|
||||||
|
(
|
||||||
|
const Field<Type>& ff,
|
||||||
|
Field<Type>& result,
|
||||||
|
const labelList& mask,
|
||||||
|
const labelListList& addr,
|
||||||
|
const scalarListList& weights
|
||||||
|
)
|
||||||
|
{
|
||||||
|
forAll (mask, maskI)
|
||||||
|
{
|
||||||
|
// Pick the masked face
|
||||||
|
const label faceI = mask[maskI];
|
||||||
|
|
||||||
|
const labelList& curAddr = addr[faceI];
|
||||||
|
|
||||||
|
const scalarList& curWeights = weights[faceI];
|
||||||
|
|
||||||
|
// Clear condensed list entry: masked faces only
|
||||||
|
result[maskI] = pTraits<Type>::zero;
|
||||||
|
|
||||||
|
forAll (curAddr, i)
|
||||||
|
{
|
||||||
|
// Put the result into condensed list: masked faces only
|
||||||
|
result[maskI] += ff[curAddr[i]]*curWeights[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class MasterPatch, class SlavePatch>
|
template<class MasterPatch, class SlavePatch>
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void GGIInterpolation<MasterPatch, SlavePatch>::bridge
|
void GGIInterpolation<MasterPatch, SlavePatch>::bridge
|
||||||
|
@ -76,6 +108,44 @@ void GGIInterpolation<MasterPatch, SlavePatch>::bridge
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class MasterPatch, class SlavePatch>
|
||||||
|
template<class Type>
|
||||||
|
void GGIInterpolation<MasterPatch, SlavePatch>::maskedBridge
|
||||||
|
(
|
||||||
|
const Field<Type>& bridgeField,
|
||||||
|
Field<Type>& ff,
|
||||||
|
const labelList& mask,
|
||||||
|
const labelList& addr
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Note: tricky algorithm
|
||||||
|
// In order for a face to be bridged it needs to be both in the
|
||||||
|
// mask and in selection of faces that are bridged (addr).
|
||||||
|
// This implies an n-squared search, but we can use the fact that
|
||||||
|
// both lists are ordered.
|
||||||
|
|
||||||
|
label curAddrI = 0;
|
||||||
|
|
||||||
|
forAll (mask, maskI)
|
||||||
|
{
|
||||||
|
// Pick the masked face
|
||||||
|
const label faceI = mask[maskI];
|
||||||
|
|
||||||
|
for (; curAddrI < addr.size(); curAddrI++)
|
||||||
|
{
|
||||||
|
if (faceI == addr[curAddrI])
|
||||||
|
{
|
||||||
|
// Found masked bridged face
|
||||||
|
// Put the result into condensed list: masked faces only
|
||||||
|
ff[maskI] = bridgeField[faceI];
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class MasterPatch, class SlavePatch>
|
template<class MasterPatch, class SlavePatch>
|
||||||
|
@ -161,6 +231,84 @@ GGIInterpolation<MasterPatch, SlavePatch>::masterToSlave
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class MasterPatch, class SlavePatch>
|
||||||
|
template<class Type>
|
||||||
|
void GGIInterpolation<MasterPatch, SlavePatch>::maskedMasterToSlave
|
||||||
|
(
|
||||||
|
const Field<Type>& ff,
|
||||||
|
Field<Type>& result,
|
||||||
|
const labelList& mask
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
if (ff.size() != masterPatch_.size())
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"void GGIInterpolation::maskedMasterToSlave\n"
|
||||||
|
"(\n"
|
||||||
|
" const Field<Type>& ff,\n"
|
||||||
|
" Field<Type>& result,\n"
|
||||||
|
" const labelList& mask\n"
|
||||||
|
") const"
|
||||||
|
) << "given field does not correspond to patch. Patch size: "
|
||||||
|
<< masterPatch_.size() << " field size: " << ff.size()
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.size() != mask.size())
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"void GGIInterpolation::maskedMasterToSlave\n"
|
||||||
|
"(\n"
|
||||||
|
" const Field<Type>& ff,\n"
|
||||||
|
" Field<Type>& result,\n"
|
||||||
|
" const labelList& mask\n"
|
||||||
|
") const"
|
||||||
|
) << "result field does not correspond to mask. Field size: "
|
||||||
|
<< result.size() << " mask size: " << mask.size()
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->doTransform() && pTraits<Type>::rank > 0)
|
||||||
|
{
|
||||||
|
// Transform master data to slave
|
||||||
|
Field<Type> transformFF;
|
||||||
|
|
||||||
|
if (reverseT_.size() == 1)
|
||||||
|
{
|
||||||
|
// Constant transform
|
||||||
|
transformFF = transform(reverseT_[0], ff);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Full patch transform
|
||||||
|
transformFF = transform(reverseT_, ff);
|
||||||
|
}
|
||||||
|
|
||||||
|
GGIInterpolation<MasterPatch, SlavePatch>::maskedInterpolate
|
||||||
|
(
|
||||||
|
transformFF,
|
||||||
|
result,
|
||||||
|
mask,
|
||||||
|
this->slaveAddr(),
|
||||||
|
this->slaveWeights()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GGIInterpolation<MasterPatch, SlavePatch>::maskedInterpolate
|
||||||
|
(
|
||||||
|
ff,
|
||||||
|
result,
|
||||||
|
mask,
|
||||||
|
this->slaveAddr(),
|
||||||
|
this->slaveWeights()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class MasterPatch, class SlavePatch>
|
template<class MasterPatch, class SlavePatch>
|
||||||
template<class Type>
|
template<class Type>
|
||||||
tmp<Field<Type> >
|
tmp<Field<Type> >
|
||||||
|
@ -244,6 +392,83 @@ GGIInterpolation<MasterPatch, SlavePatch>::slaveToMaster
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class MasterPatch, class SlavePatch>
|
||||||
|
template<class Type>
|
||||||
|
void GGIInterpolation<MasterPatch, SlavePatch>::maskedSlaveToMaster
|
||||||
|
(
|
||||||
|
const Field<Type>& ff,
|
||||||
|
Field<Type>& result,
|
||||||
|
const labelList& mask
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
if (ff.size() != slavePatch_.size())
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"void GGIInterpolation::maskedSlaveToMaster"
|
||||||
|
"(\n"
|
||||||
|
" const Field<Type>& ff,\n"
|
||||||
|
" Field<Type>& result,\n"
|
||||||
|
" const labelList& mask\n"
|
||||||
|
") const"
|
||||||
|
) << "given field does not correspond to patch. Patch size: "
|
||||||
|
<< slavePatch_.size() << " field size: " << ff.size()
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.size() != mask.size())
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"void GGIInterpolation::maskedSlaveToMaster\n"
|
||||||
|
"(\n"
|
||||||
|
" const Field<Type>& ff,\n"
|
||||||
|
" Field<Type>& result,\n"
|
||||||
|
" const labelList& mask\n"
|
||||||
|
") const"
|
||||||
|
) << "result field does not correspond to mask. Field size: "
|
||||||
|
<< result.size() << " mask size: " << mask.size()
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->doTransform() && pTraits<Type>::rank > 0)
|
||||||
|
{
|
||||||
|
// Transform slave data to master
|
||||||
|
Field<Type> transformFF;
|
||||||
|
if (forwardT_.size() == 1)
|
||||||
|
{
|
||||||
|
// Constant transform
|
||||||
|
transformFF = transform(forwardT_[0], ff);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Full patch transform
|
||||||
|
transformFF = transform(forwardT_, ff);
|
||||||
|
}
|
||||||
|
|
||||||
|
GGIInterpolation<MasterPatch, SlavePatch>::maskedInterpolate
|
||||||
|
(
|
||||||
|
transformFF,
|
||||||
|
result,
|
||||||
|
mask,
|
||||||
|
this->masterAddr(),
|
||||||
|
this->masterWeights()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GGIInterpolation<MasterPatch, SlavePatch>::maskedInterpolate
|
||||||
|
(
|
||||||
|
ff,
|
||||||
|
result,
|
||||||
|
mask,
|
||||||
|
this->masterAddr(),
|
||||||
|
this->masterWeights()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class MasterPatch, class SlavePatch>
|
template<class MasterPatch, class SlavePatch>
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void GGIInterpolation<MasterPatch, SlavePatch>::bridgeMaster
|
void GGIInterpolation<MasterPatch, SlavePatch>::bridgeMaster
|
||||||
|
@ -275,6 +500,42 @@ void GGIInterpolation<MasterPatch, SlavePatch>::bridgeMaster
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class MasterPatch, class SlavePatch>
|
||||||
|
template<class Type>
|
||||||
|
void GGIInterpolation<MasterPatch, SlavePatch>::maskedBridgeMaster
|
||||||
|
(
|
||||||
|
const Field<Type>& bridgeField,
|
||||||
|
Field<Type>& ff,
|
||||||
|
const labelList& mask
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
if
|
||||||
|
(
|
||||||
|
bridgeField.size() != masterPatch_.size()
|
||||||
|
|| ff.size() != mask.size()
|
||||||
|
)
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"void GGIInterpolation<MasterPatch, SlavePatch>::"
|
||||||
|
"maskedBridgeMaster\n"
|
||||||
|
"(\n"
|
||||||
|
" const Field<Type>& bridgeField,\n"
|
||||||
|
" Field<Type>& ff,\n"
|
||||||
|
" const labelList& mask\n"
|
||||||
|
") const"
|
||||||
|
) << "given field does not correspond to patch. Patch size: "
|
||||||
|
<< masterPatch_.size()
|
||||||
|
<< " bridge field size: " << bridgeField.size()
|
||||||
|
<< " field size: " << ff.size()
|
||||||
|
<< " mask size: " << mask.size()
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
maskedBridge(bridgeField, ff, mask, uncoveredMasterFaces());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class MasterPatch, class SlavePatch>
|
template<class MasterPatch, class SlavePatch>
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void GGIInterpolation<MasterPatch, SlavePatch>::bridgeSlave
|
void GGIInterpolation<MasterPatch, SlavePatch>::bridgeSlave
|
||||||
|
@ -286,14 +547,16 @@ void GGIInterpolation<MasterPatch, SlavePatch>::bridgeSlave
|
||||||
if
|
if
|
||||||
(
|
(
|
||||||
bridgeField.size() != slavePatch_.size()
|
bridgeField.size() != slavePatch_.size()
|
||||||
|| ff.size() != slavePatch_.size())
|
|| ff.size() != slavePatch_.size()
|
||||||
|
)
|
||||||
{
|
{
|
||||||
FatalErrorIn
|
FatalErrorIn
|
||||||
(
|
(
|
||||||
"void GGIInterpolation<MasterPatch, SlavePatch>::bridgeSlave\n"
|
"void GGIInterpolation<MasterPatch, SlavePatch>::"
|
||||||
|
"bridgeSlave\n"
|
||||||
"(\n"
|
"(\n"
|
||||||
" const Field<Type>& bridgeField,\n"
|
" const Field<Type>& bridgeField,\n"
|
||||||
" Field<Type>& ff\n"
|
" Field<Type>& ff"
|
||||||
") const"
|
") const"
|
||||||
) << "given field does not correspond to patch. Patch size: "
|
) << "given field does not correspond to patch. Patch size: "
|
||||||
<< slavePatch_.size()
|
<< slavePatch_.size()
|
||||||
|
@ -306,6 +569,42 @@ void GGIInterpolation<MasterPatch, SlavePatch>::bridgeSlave
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class MasterPatch, class SlavePatch>
|
||||||
|
template<class Type>
|
||||||
|
void GGIInterpolation<MasterPatch, SlavePatch>::maskedBridgeSlave
|
||||||
|
(
|
||||||
|
const Field<Type>& bridgeField,
|
||||||
|
Field<Type>& ff,
|
||||||
|
const labelList& mask
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
if
|
||||||
|
(
|
||||||
|
bridgeField.size() != slavePatch_.size()
|
||||||
|
|| ff.size() != mask.size()
|
||||||
|
)
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"void GGIInterpolation<MasterPatch, SlavePatch>::"
|
||||||
|
"maskedBridgeSlave\n"
|
||||||
|
"(\n"
|
||||||
|
" const Field<Type>& bridgeField,\n"
|
||||||
|
" Field<Type>& ff\n,"
|
||||||
|
" const labelList& mask\n"
|
||||||
|
") const"
|
||||||
|
) << "given field does not correspond to patch. Patch size: "
|
||||||
|
<< slavePatch_.size()
|
||||||
|
<< " bridge field size: " << bridgeField.size()
|
||||||
|
<< " field size: " << ff.size()
|
||||||
|
<< " mask size: " << mask.size()
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
maskedBridge(bridgeField, ff, mask, uncoveredSlaveFaces());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
} // End namespace Foam
|
} // End namespace Foam
|
||||||
|
|
|
@ -85,6 +85,7 @@ public:
|
||||||
{
|
{
|
||||||
THREE_D_DISTANCE,
|
THREE_D_DISTANCE,
|
||||||
AABB,
|
AABB,
|
||||||
|
BB_OCTREE,
|
||||||
N_SQUARED
|
N_SQUARED
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -192,6 +193,39 @@ class GGIInterpolation
|
||||||
//- Facet normal featureCos criteria
|
//- Facet normal featureCos criteria
|
||||||
static const scalar featureCosTol_;
|
static const scalar featureCosTol_;
|
||||||
|
|
||||||
|
//- Facet bound box extension factor
|
||||||
|
static const scalar faceBoundBoxExtendSpanFraction_;
|
||||||
|
|
||||||
|
//- The next 3 attributes are parameters controlling the creation
|
||||||
|
// of an octree search engine for the GGI facets neighbourhood
|
||||||
|
// determination.
|
||||||
|
//
|
||||||
|
// Tests using GGI patches of up to ~100K facets have shown that
|
||||||
|
// the following values gave the best compromise between the
|
||||||
|
// "octree creation time" vs "octree search time":
|
||||||
|
//
|
||||||
|
// octreeSearchMinNLevel_ : 3
|
||||||
|
// octreeSearchMaxLeafRatio_ : 3
|
||||||
|
// octreeSearchMaxShapeRatio_ : 1
|
||||||
|
//
|
||||||
|
// For GGI patches larger than ~100K facets, your mileage may vary.
|
||||||
|
// So these 3 control parameters are adjustable using the following
|
||||||
|
// global optimization switches:
|
||||||
|
//
|
||||||
|
// GGIOctreeSearchMinNLevel
|
||||||
|
// GGIOctreeSearchMaxLeafRatio
|
||||||
|
// GGIOctreeSearchMaxShapeRatio
|
||||||
|
//
|
||||||
|
|
||||||
|
//- Octree search: minNlevel parameter for octree constructor
|
||||||
|
static const label octreeSearchMinNLevel_;
|
||||||
|
|
||||||
|
//- Octree search: maxLeafRatio parameter for octree constructor
|
||||||
|
static const scalar octreeSearchMaxLeafRatio_;
|
||||||
|
|
||||||
|
//- Octree search: maxShapeRatio parameter for octree constructor
|
||||||
|
static const scalar octreeSearchMaxShapeRatio_;
|
||||||
|
|
||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
|
|
||||||
|
@ -210,6 +244,10 @@ class GGIInterpolation
|
||||||
//- Evaluate faces neighborhood based of faces Axis Aligned BB
|
//- Evaluate faces neighborhood based of faces Axis Aligned BB
|
||||||
void findNeighboursAABB(labelListList& result) const;
|
void findNeighboursAABB(labelListList& result) const;
|
||||||
|
|
||||||
|
//- Evaluate faces neighborhood based of faces BB and an octree
|
||||||
|
// search engine
|
||||||
|
void findNeighboursBBOctree(labelListList& result) const;
|
||||||
|
|
||||||
//- Projects a list of points onto a plane located at
|
//- Projects a list of points onto a plane located at
|
||||||
// planeOrig, oriented along planeNormal
|
// planeOrig, oriented along planeNormal
|
||||||
tmp<pointField> projectPointsOnPlane
|
tmp<pointField> projectPointsOnPlane
|
||||||
|
@ -326,6 +364,18 @@ class GGIInterpolation
|
||||||
const scalarListList& weights
|
const scalarListList& weights
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//- Interpolate given source and target, addressing and weights
|
||||||
|
// for masked faces only
|
||||||
|
template<class Type>
|
||||||
|
static void maskedInterpolate
|
||||||
|
(
|
||||||
|
const Field<Type>& ff,
|
||||||
|
Field<Type>& result,
|
||||||
|
const labelList& mask,
|
||||||
|
const labelListList& addr,
|
||||||
|
const scalarListList& weights
|
||||||
|
);
|
||||||
|
|
||||||
//- Bridge uncovered faces given addressing
|
//- Bridge uncovered faces given addressing
|
||||||
template<class Type>
|
template<class Type>
|
||||||
static void bridge
|
static void bridge
|
||||||
|
@ -335,6 +385,17 @@ class GGIInterpolation
|
||||||
const labelList& addr
|
const labelList& addr
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//- Bridge uncovered faces given addressing
|
||||||
|
// for masked faces only
|
||||||
|
template<class Type>
|
||||||
|
static void maskedBridge
|
||||||
|
(
|
||||||
|
const Field<Type>& bridgeField,
|
||||||
|
Field<Type>& ff,
|
||||||
|
const labelList& mask,
|
||||||
|
const labelList& addr
|
||||||
|
);
|
||||||
|
|
||||||
//- Is a transform required?
|
//- Is a transform required?
|
||||||
inline bool doTransform() const
|
inline bool doTransform() const
|
||||||
{
|
{
|
||||||
|
@ -360,8 +421,8 @@ public:
|
||||||
const tensorField& forwardT,
|
const tensorField& forwardT,
|
||||||
const tensorField& reverseT,
|
const tensorField& reverseT,
|
||||||
const vectorField& forwardSep,
|
const vectorField& forwardSep,
|
||||||
const scalar masterFaceNonOverlapFaceTol = 0.0,
|
const scalar masterFaceNonOverlapFaceTol = 0,
|
||||||
const scalar slaveFaceNonOverlapFaceTol = 0.0,
|
const scalar slaveFaceNonOverlapFaceTol = 0,
|
||||||
const bool rescaleGGIWeightingFactors = true,
|
const bool rescaleGGIWeightingFactors = true,
|
||||||
const quickReject reject = AABB
|
const quickReject reject = AABB
|
||||||
);
|
);
|
||||||
|
@ -399,22 +460,45 @@ public:
|
||||||
|
|
||||||
//- Interpolate from master to slave
|
//- Interpolate from master to slave
|
||||||
template<class Type>
|
template<class Type>
|
||||||
tmp<Field<Type> > masterToSlave(const Field<Type>& pf) const;
|
tmp<Field<Type> > masterToSlave(const Field<Type>& ff) const;
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
tmp<Field<Type> > masterToSlave
|
tmp<Field<Type> > masterToSlave
|
||||||
(
|
(
|
||||||
const tmp<Field<Type> >& tpf
|
const tmp<Field<Type> >& tff
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
|
//- Interpolate from master to slave, only for marked master faces
|
||||||
|
// Addressing picks the faces from patch that are selected
|
||||||
|
// for collection into the result field
|
||||||
|
template<class Type>
|
||||||
|
void maskedMasterToSlave
|
||||||
|
(
|
||||||
|
const Field<Type>& ff,
|
||||||
|
Field<Type>& result,
|
||||||
|
const labelList& mask
|
||||||
|
) const;
|
||||||
|
|
||||||
|
|
||||||
//- Interpolate from slave to master
|
//- Interpolate from slave to master
|
||||||
template<class Type>
|
template<class Type>
|
||||||
tmp<Field<Type> > slaveToMaster(const Field<Type>& pf) const;
|
tmp<Field<Type> > slaveToMaster(const Field<Type>& ff) const;
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
tmp<Field<Type> > slaveToMaster
|
tmp<Field<Type> > slaveToMaster
|
||||||
(
|
(
|
||||||
const tmp<Field<Type> >& tpf
|
const tmp<Field<Type> >& tff
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Interpolate from slave to master, only for marked slave faces
|
||||||
|
// Addressing picks the faces from patch that are selected
|
||||||
|
// for collection into the result field
|
||||||
|
template<class Type>
|
||||||
|
void maskedSlaveToMaster
|
||||||
|
(
|
||||||
|
const Field<Type>& ff,
|
||||||
|
Field<Type>& result,
|
||||||
|
const labelList& mask
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
|
|
||||||
|
@ -426,6 +510,15 @@ public:
|
||||||
Field<Type>& ff
|
Field<Type>& ff
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
|
//- Bridge uncovered master patch field, only for marked master faces
|
||||||
|
template<class Type>
|
||||||
|
void maskedBridgeMaster
|
||||||
|
(
|
||||||
|
const Field<Type>& bridgeField,
|
||||||
|
Field<Type>& ff,
|
||||||
|
const labelList& mask
|
||||||
|
) const;
|
||||||
|
|
||||||
//- Bridge uncovered slave patch field
|
//- Bridge uncovered slave patch field
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void bridgeSlave
|
void bridgeSlave
|
||||||
|
@ -434,6 +527,15 @@ public:
|
||||||
Field<Type>& ff
|
Field<Type>& ff
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
|
//- Bridge uncovered slave patch field, only for marked slave faces
|
||||||
|
template<class Type>
|
||||||
|
void maskedBridgeSlave
|
||||||
|
(
|
||||||
|
const Field<Type>& bridgeField,
|
||||||
|
Field<Type>& ff,
|
||||||
|
const labelList& mask
|
||||||
|
) const;
|
||||||
|
|
||||||
|
|
||||||
// Edit
|
// Edit
|
||||||
|
|
||||||
|
|
|
@ -34,12 +34,45 @@ Author
|
||||||
#include "boundBox.H"
|
#include "boundBox.H"
|
||||||
#include "plane.H"
|
#include "plane.H"
|
||||||
#include "transformField.H"
|
#include "transformField.H"
|
||||||
|
#include "octree.H"
|
||||||
|
#include "octreeDataBoundBox.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class MasterPatch, class SlavePatch>
|
||||||
|
const scalar
|
||||||
|
GGIInterpolation<MasterPatch, SlavePatch>::faceBoundBoxExtendSpanFraction_
|
||||||
|
(
|
||||||
|
debug::tolerances("GGIFaceBoundBoxExtendSpanFraction", 1.0e-2)
|
||||||
|
);
|
||||||
|
|
||||||
|
template<class MasterPatch, class SlavePatch>
|
||||||
|
const label
|
||||||
|
GGIInterpolation<MasterPatch, SlavePatch>::octreeSearchMinNLevel_
|
||||||
|
(
|
||||||
|
debug::optimisationSwitch("GGIOctreeSearchMinNLevel", 3)
|
||||||
|
);
|
||||||
|
|
||||||
|
template<class MasterPatch, class SlavePatch>
|
||||||
|
const scalar
|
||||||
|
GGIInterpolation<MasterPatch, SlavePatch>::octreeSearchMaxLeafRatio_
|
||||||
|
(
|
||||||
|
debug::optimisationSwitch("GGIOctreeSearchMaxLeafRatio", 3)
|
||||||
|
);
|
||||||
|
|
||||||
|
template<class MasterPatch, class SlavePatch>
|
||||||
|
const scalar
|
||||||
|
GGIInterpolation<MasterPatch, SlavePatch>::octreeSearchMaxShapeRatio_
|
||||||
|
(
|
||||||
|
debug::optimisationSwitch("GGIOctreeSearchMaxShapeRatio", 1)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
// From: http://www.gamasutra.com/features/20000330/bobic_02.htm
|
// From: http://www.gamasutra.com/features/20000330/bobic_02.htm
|
||||||
|
@ -382,6 +415,148 @@ void GGIInterpolation<MasterPatch, SlavePatch>::findNeighboursAABB
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This algorithm find the faces in proximity of another face based
|
||||||
|
// on the face BB (Bounding Box) and an octree of bounding boxes.
|
||||||
|
template<class MasterPatch, class SlavePatch>
|
||||||
|
void GGIInterpolation<MasterPatch, SlavePatch>::findNeighboursBBOctree
|
||||||
|
(
|
||||||
|
labelListList& result
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
List<DynamicList<label> > candidateMasterNeighbors(masterPatch_.size());
|
||||||
|
|
||||||
|
// Initialize the list of master patch faces bounding box
|
||||||
|
treeBoundBoxList lmasterFaceBB(masterPatch_.size());
|
||||||
|
|
||||||
|
forAll (masterPatch_, faceMi)
|
||||||
|
{
|
||||||
|
pointField facePoints
|
||||||
|
(
|
||||||
|
masterPatch_[faceMi].points(masterPatch_.points())
|
||||||
|
);
|
||||||
|
|
||||||
|
// Construct face BB with an extension of face span defined by the
|
||||||
|
// global tolerance factor faceBoundBoxExtendSpanFraction_
|
||||||
|
// (1% by default)
|
||||||
|
treeBoundBox bbFaceMaster(facePoints);
|
||||||
|
|
||||||
|
lmasterFaceBB[faceMi] =
|
||||||
|
bbFaceMaster.extend(faceBoundBoxExtendSpanFraction_);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize the list of slave patch faces bounding box
|
||||||
|
treeBoundBoxList lslaveFaceBB(slavePatch_.size());
|
||||||
|
|
||||||
|
forAll (slavePatch_, faceSi)
|
||||||
|
{
|
||||||
|
pointField facePoints
|
||||||
|
(
|
||||||
|
slavePatch_[faceSi].points(slavePatch_.points())
|
||||||
|
);
|
||||||
|
|
||||||
|
// possible transformation and separation for cyclic patches
|
||||||
|
if (doTransform())
|
||||||
|
{
|
||||||
|
if (forwardT_.size() == 1)
|
||||||
|
{
|
||||||
|
transform(facePoints, forwardT_[0], facePoints);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
transform(facePoints, forwardT_[faceSi], facePoints);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (doSeparation())
|
||||||
|
{
|
||||||
|
if (forwardSep_.size() == 1)
|
||||||
|
{
|
||||||
|
facePoints += forwardSep_[0];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
facePoints += forwardSep_[faceSi];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct face BB with an extension of face span defined by the
|
||||||
|
// global tolerance factor faceBoundBoxExtendSpanFraction_
|
||||||
|
// (1% by default)
|
||||||
|
treeBoundBox bbFaceSlave(facePoints);
|
||||||
|
|
||||||
|
lslaveFaceBB[faceSi] =
|
||||||
|
bbFaceSlave.extend(faceBoundBoxExtendSpanFraction_);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the slave octreeData, using the boundBox flavor
|
||||||
|
octreeDataBoundBox slaveDataBB(lslaveFaceBB);
|
||||||
|
|
||||||
|
// Overall slave patch BB
|
||||||
|
treeBoundBox slaveOverallBB(slavePatch_.points());
|
||||||
|
|
||||||
|
// Create the slave patch octree
|
||||||
|
|
||||||
|
octree<octreeDataBoundBox> slavePatchOctree
|
||||||
|
(
|
||||||
|
slaveOverallBB, // overall search domain
|
||||||
|
slaveDataBB,
|
||||||
|
octreeSearchMinNLevel_, // min number of levels
|
||||||
|
octreeSearchMaxLeafRatio_, // max avg. size of leaves
|
||||||
|
octreeSearchMaxShapeRatio_ // max avg. duplicity.
|
||||||
|
);
|
||||||
|
|
||||||
|
const vectorField& masterFaceNormals = masterPatch_.faceNormals();
|
||||||
|
vectorField slaveNormals = slavePatch_.faceNormals();
|
||||||
|
|
||||||
|
// Transform slave normals to master plane if needed
|
||||||
|
if (doTransform())
|
||||||
|
{
|
||||||
|
if (forwardT_.size() == 1)
|
||||||
|
{
|
||||||
|
transform(slaveNormals, forwardT_[0], slaveNormals);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
transform(slaveNormals, forwardT_, slaveNormals);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Visit each master patch face BB and find the potential neighbours
|
||||||
|
// using the slave patch octree
|
||||||
|
|
||||||
|
forAll (lmasterFaceBB, faceMi)
|
||||||
|
{
|
||||||
|
// List of candidate neighbours
|
||||||
|
labelList overlappedFaces =
|
||||||
|
slavePatchOctree.findBox(lmasterFaceBB[faceMi]);
|
||||||
|
|
||||||
|
forAll (overlappedFaces, ovFi)
|
||||||
|
{
|
||||||
|
label faceSi = overlappedFaces[ovFi];
|
||||||
|
|
||||||
|
// Compute and verify featureCos between the two face normals
|
||||||
|
// before adding to the list of candidates
|
||||||
|
scalar featureCos =
|
||||||
|
masterFaceNormals[faceMi] & slaveNormals[faceSi];
|
||||||
|
|
||||||
|
if (mag(featureCos) > featureCosTol_)
|
||||||
|
{
|
||||||
|
candidateMasterNeighbors[faceMi].append(faceSi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Repack the list
|
||||||
|
result.setSize(masterPatch_.size());
|
||||||
|
|
||||||
|
forAll (result, i)
|
||||||
|
{
|
||||||
|
result[i].transfer(candidateMasterNeighbors[i].shrink());
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Projects a list of points onto a plane located at planeOrig,
|
// Projects a list of points onto a plane located at planeOrig,
|
||||||
|
@ -664,8 +839,8 @@ bool GGIInterpolation<MasterPatch, SlavePatch>::detect2dPolygonsOverlap
|
||||||
// accept to discard an intersecting area roughly 10e-6 times the
|
// accept to discard an intersecting area roughly 10e-6 times the
|
||||||
// surface of the smallest polygon, so 1 PPM.
|
// surface of the smallest polygon, so 1 PPM.
|
||||||
//
|
//
|
||||||
// Which means also that our GGI weighting factors will never be smaller
|
// Which means also that our GGI weighting factors will never be
|
||||||
// than roughly 10e-6, because this is the fraction of
|
// smaller than roughly 10e-6, because this is the fraction of
|
||||||
// the intersection surface area we choose to discard.
|
// the intersection surface area we choose to discard.
|
||||||
|
|
||||||
scalar _epsilon = tolFactor*
|
scalar _epsilon = tolFactor*
|
||||||
|
@ -691,12 +866,14 @@ bool GGIInterpolation<MasterPatch, SlavePatch>::detect2dPolygonsOverlap
|
||||||
{
|
{
|
||||||
// We have not found any separating axes by exploring from
|
// We have not found any separating axes by exploring from
|
||||||
// poly1, let's switch by exploring from poly2 instead
|
// poly1, let's switch by exploring from poly2 instead
|
||||||
isOverlapping = detect2dPolygonsOverlap(poly2, poly1, tolFactor, false);
|
isOverlapping =
|
||||||
|
detect2dPolygonsOverlap(poly2, poly1, tolFactor, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return isOverlapping;
|
return isOverlapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
} // End namespace Foam
|
} // End namespace Foam
|
||||||
|
|
|
@ -87,7 +87,11 @@ void GGIInterpolation<MasterPatch, SlavePatch>::calcAddressing() const
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
Info << "Evaluation of GGI weighting factors:" << endl;
|
InfoIn
|
||||||
|
(
|
||||||
|
"void GGIInterpolation<MasterPatch, SlavePatch>::"
|
||||||
|
"calcAddressing() const"
|
||||||
|
) << "Evaluation of GGI weighting factors:" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the dynamic lists to hold the addressing
|
// Create the dynamic lists to hold the addressing
|
||||||
|
@ -112,14 +116,19 @@ void GGIInterpolation<MasterPatch, SlavePatch>::calcAddressing() const
|
||||||
// The candidates master neighbours
|
// The candidates master neighbours
|
||||||
// Choice of algorithm:
|
// Choice of algorithm:
|
||||||
// 1) Axis-aligned bounding box
|
// 1) Axis-aligned bounding box
|
||||||
// 2) 3-D vector distance
|
// 2) Octree search with bounding box
|
||||||
// 3) n-Squared search
|
// 3) 3-D vector distance
|
||||||
|
// 4) n-Squared search
|
||||||
labelListList candidateMasterNeighbors;
|
labelListList candidateMasterNeighbors;
|
||||||
|
|
||||||
if (reject_ == AABB)
|
if (reject_ == AABB)
|
||||||
{
|
{
|
||||||
findNeighboursAABB(candidateMasterNeighbors);
|
findNeighboursAABB(candidateMasterNeighbors);
|
||||||
}
|
}
|
||||||
|
else if (reject_ == BB_OCTREE)
|
||||||
|
{
|
||||||
|
findNeighboursBBOctree(candidateMasterNeighbors);
|
||||||
|
}
|
||||||
else if (reject_ == THREE_D_DISTANCE)
|
else if (reject_ == THREE_D_DISTANCE)
|
||||||
{
|
{
|
||||||
findNeighbours3D(candidateMasterNeighbors);
|
findNeighbours3D(candidateMasterNeighbors);
|
||||||
|
@ -500,7 +509,7 @@ void GGIInterpolation<MasterPatch, SlavePatch>::calcAddressing() const
|
||||||
// other. A good case: the ercoftac conical diffuser, Case0... GGI
|
// other. A good case: the ercoftac conical diffuser, Case0... GGI
|
||||||
// located right between the cylindrical and conical parts, rotate the
|
// located right between the cylindrical and conical parts, rotate the
|
||||||
// cylindrical by 15 degrees. For this case, we will need to devise a
|
// cylindrical by 15 degrees. For this case, we will need to devise a
|
||||||
// decent strategy in order to intelligently take care of this
|
// decent strategy in order to intelligently take care of these
|
||||||
// "missing weights"
|
// "missing weights"
|
||||||
//
|
//
|
||||||
// The purpose of the ::rescaleWeightingFactors() method is mainly for
|
// The purpose of the ::rescaleWeightingFactors() method is mainly for
|
||||||
|
@ -584,6 +593,7 @@ void GGIInterpolation<MasterPatch, SlavePatch>::rescaleWeightingFactors() const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Find non-overlapping faces from both master and slave patches
|
// Find non-overlapping faces from both master and slave patches
|
||||||
// The default non-overlapping criteria is total absence of neighbours.
|
// The default non-overlapping criteria is total absence of neighbours.
|
||||||
// Later on, ths criteria will be based on minimum surface intersection, or
|
// Later on, ths criteria will be based on minimum surface intersection, or
|
||||||
|
|
|
@ -107,12 +107,29 @@ void Foam::ggiGAMGInterfaceField::updateInterfaceMatrix
|
||||||
|
|
||||||
const unallocLabelList& faceCells = ggiInterface_.faceCells();
|
const unallocLabelList& faceCells = ggiInterface_.faceCells();
|
||||||
|
|
||||||
|
// New treatment. HJ, 26/Jun/2011
|
||||||
|
if (zonePnf.size() != faceCells.size())
|
||||||
|
{
|
||||||
|
FatalErrorIn("ggiGAMGInterfaceField::updateInterfaceMatrix")
|
||||||
|
<< "Bananas!!!"
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
forAll(faceCells, elemI)
|
||||||
|
{
|
||||||
|
result[faceCells[elemI]] -= coeffs[elemI]*zonePnf[elemI];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Old treatment
|
||||||
|
#if(0)
|
||||||
const labelList& za = ggiInterface_.zoneAddressing();
|
const labelList& za = ggiInterface_.zoneAddressing();
|
||||||
|
|
||||||
forAll(faceCells, elemI)
|
forAll(faceCells, elemI)
|
||||||
{
|
{
|
||||||
result[faceCells[elemI]] -= coeffs[elemI]*zonePnf[za[elemI]];
|
result[faceCells[elemI]] -= coeffs[elemI]*zonePnf[za[elemI]];
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,49 @@ namespace Foam
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::ggiGAMGInterface::initFastReduce() const
|
||||||
|
{
|
||||||
|
// Init should be executed only once
|
||||||
|
initReduce_ = true;
|
||||||
|
|
||||||
|
// Establish parallel comms pattern
|
||||||
|
if (!localParallel() && Pstream::parRun())
|
||||||
|
{
|
||||||
|
// Only master handles communication
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
receiveAddr_.setSize(Pstream::nProcs());
|
||||||
|
sendAddr_.setSize(Pstream::nProcs());
|
||||||
|
|
||||||
|
receiveAddr_[0] = zoneAddressing();
|
||||||
|
|
||||||
|
for (label procI = 1; procI < Pstream::nProcs(); procI++)
|
||||||
|
{
|
||||||
|
// Note: must use normal comms because the size of the
|
||||||
|
// communicated lists is unknown on the receiving side
|
||||||
|
// HJ, 4/Jun/2011
|
||||||
|
|
||||||
|
// Opt: reconsider mode of communication
|
||||||
|
IPstream ip(Pstream::scheduled, procI);
|
||||||
|
|
||||||
|
receiveAddr_[procI] = labelList(ip);
|
||||||
|
|
||||||
|
sendAddr_[procI] = labelList(ip);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Opt: reconsider mode of communication
|
||||||
|
OPstream op(Pstream::scheduled, Pstream::masterNo());
|
||||||
|
|
||||||
|
op << zoneAddressing() << shadowInterface().zoneAddressing();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::ggiGAMGInterface::ggiGAMGInterface
|
Foam::ggiGAMGInterface::ggiGAMGInterface
|
||||||
|
@ -54,7 +97,10 @@ Foam::ggiGAMGInterface::ggiGAMGInterface
|
||||||
GAMGInterface(lduMesh),
|
GAMGInterface(lduMesh),
|
||||||
fineGgiInterface_(refCast<const ggiLduInterface>(fineInterface)),
|
fineGgiInterface_(refCast<const ggiLduInterface>(fineInterface)),
|
||||||
zoneSize_(0),
|
zoneSize_(0),
|
||||||
zoneAddressing_()
|
zoneAddressing_(),
|
||||||
|
initReduce_(false),
|
||||||
|
receiveAddr_(),
|
||||||
|
sendAddr_()
|
||||||
{
|
{
|
||||||
// Note.
|
// Note.
|
||||||
// All processors will do the same coarsening and then filter
|
// All processors will do the same coarsening and then filter
|
||||||
|
@ -644,6 +690,7 @@ const Foam::labelListList& Foam::ggiGAMGInterface::addressing() const
|
||||||
FatalErrorIn("const labelListList& ggiGAMGInterface::addressing() const")
|
FatalErrorIn("const labelListList& ggiGAMGInterface::addressing() const")
|
||||||
<< "Requested fine addressing at coarse level"
|
<< "Requested fine addressing at coarse level"
|
||||||
<< abort(FatalError);
|
<< abort(FatalError);
|
||||||
|
|
||||||
return labelListList::null();
|
return labelListList::null();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -659,6 +706,7 @@ const Foam::scalarListList& Foam::ggiGAMGInterface::weights() const
|
||||||
FatalErrorIn("const labelListList& ggiGAMGInterface::weights() const")
|
FatalErrorIn("const labelListList& ggiGAMGInterface::weights() const")
|
||||||
<< "Requested fine addressing at coarse level"
|
<< "Requested fine addressing at coarse level"
|
||||||
<< abort(FatalError);
|
<< abort(FatalError);
|
||||||
|
|
||||||
return scalarListList::null();
|
return scalarListList::null();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -681,9 +729,8 @@ void Foam::ggiGAMGInterface::initTransfer
|
||||||
const unallocLabelList& interfaceData
|
const unallocLabelList& interfaceData
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
// Label transfer is straight local
|
// Label transfer is local
|
||||||
labelTransferBuffer_ = interfaceData;
|
labelTransferBuffer_ = interfaceData;
|
||||||
// labelTransferBuffer_ = expand(interfaceData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -706,9 +753,6 @@ void Foam::ggiGAMGInterface::initInternalFieldTransfer
|
||||||
{
|
{
|
||||||
// Label transfer is local without global reduction
|
// Label transfer is local without global reduction
|
||||||
labelTransferBuffer_ = interfaceInternalField(iF);
|
labelTransferBuffer_ = interfaceInternalField(iF);
|
||||||
|
|
||||||
// labelList pif = interfaceInternalField(iF);
|
|
||||||
// labelTransferBuffer_ = expand(pif);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -730,8 +774,14 @@ void Foam::ggiGAMGInterface::initInternalFieldTransfer
|
||||||
{
|
{
|
||||||
scalarField pif = interfaceInternalField(iF);
|
scalarField pif = interfaceInternalField(iF);
|
||||||
|
|
||||||
|
// New treatment. HJ, 26/Jun/2011
|
||||||
|
fieldTransferBuffer_ = fastReduce(pif);
|
||||||
|
|
||||||
|
// Old treatment
|
||||||
|
#if(0)
|
||||||
// Expand the field, executing a reduce operation in init
|
// Expand the field, executing a reduce operation in init
|
||||||
fieldTransferBuffer_ = expand(pif);
|
fieldTransferBuffer_ = expand(pif);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,18 @@ class ggiGAMGInterface
|
||||||
labelList zoneAddressing_;
|
labelList zoneAddressing_;
|
||||||
|
|
||||||
|
|
||||||
|
// Parallel communication optimisation, stored on master processor
|
||||||
|
|
||||||
|
//- Has reduce been initialised?
|
||||||
|
mutable bool initReduce_;
|
||||||
|
|
||||||
|
//- List of zone faces indices received from each processor
|
||||||
|
mutable labelListList receiveAddr_;
|
||||||
|
|
||||||
|
//- List of zone faces indices to send to each processor
|
||||||
|
mutable labelListList sendAddr_;
|
||||||
|
|
||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
|
|
||||||
//- Disallow default bitwise copy construct
|
//- Disallow default bitwise copy construct
|
||||||
|
@ -77,8 +89,19 @@ class ggiGAMGInterface
|
||||||
//- Disallow default bitwise assignment
|
//- Disallow default bitwise assignment
|
||||||
void operator=(const ggiGAMGInterface&);
|
void operator=(const ggiGAMGInterface&);
|
||||||
|
|
||||||
|
|
||||||
|
//- Init fast reduce
|
||||||
|
void initFastReduce() const;
|
||||||
|
|
||||||
|
//- Fast reduce
|
||||||
|
// Note: contains global communications
|
||||||
|
// New, HJ, 24/Jun/2011
|
||||||
|
template<class Type>
|
||||||
|
tmp<Field<Type> > fastReduce(const UList<Type>&) const;
|
||||||
|
|
||||||
//- Expand data to zone size
|
//- Expand data to zone size
|
||||||
// Note: contains global reduce. HJ, 15/May/2009
|
// Note: contains global reduce. HJ, 15/May/2009
|
||||||
|
// Obsolete. HJ, 24/Jun/2011
|
||||||
template<class Type>
|
template<class Type>
|
||||||
tmp<Field<Type> > expand(const UList<Type>&) const;
|
tmp<Field<Type> > expand(const UList<Type>&) const;
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,174 @@ namespace Foam
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
tmp<Field<Type> > ggiGAMGInterface::fastReduce(const UList<Type>& ff) const
|
||||||
|
{
|
||||||
|
// Algorithm
|
||||||
|
// Local processor contains faceCells part of the zone and requires
|
||||||
|
// zoneAddressing part.
|
||||||
|
// For fast communications, each processor will send the faceCells and
|
||||||
|
// zoneAddressing to the master. Master will assemble global zone
|
||||||
|
// and send off messages to all processors containing only
|
||||||
|
// the required data
|
||||||
|
// HJ, 24/Jun/2011
|
||||||
|
|
||||||
|
if (ff.size() != this->size())
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"tmp<Field<Type> > ggiGAMGInterface::fastReduce"
|
||||||
|
"("
|
||||||
|
" const UList<Type>& ff"
|
||||||
|
") const"
|
||||||
|
) << "Wrong field size. ff: " << ff.size()
|
||||||
|
<< " interface: " << this->size()
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (localParallel() || !Pstream::parRun())
|
||||||
|
{
|
||||||
|
// Field remains identical: no parallel communications required
|
||||||
|
tmp<Field<Type> > tresult(new Field<Type>(ff));
|
||||||
|
|
||||||
|
return tresult;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute reduce if not already done
|
||||||
|
if (!initReduce_)
|
||||||
|
{
|
||||||
|
initFastReduce();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
// Master collects information and distributes data.
|
||||||
|
Field<Type> expandField(zoneSize(), pTraits<Type>::zero);
|
||||||
|
|
||||||
|
// Insert master processor
|
||||||
|
const labelList& za = zoneAddressing();
|
||||||
|
|
||||||
|
forAll (za, i)
|
||||||
|
{
|
||||||
|
expandField[za[i]] = ff[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Master receives and inserts data from all processors for which
|
||||||
|
// receiveAddr contains entries
|
||||||
|
for (label procI = 1; procI < Pstream::nProcs(); procI++)
|
||||||
|
{
|
||||||
|
const labelList& curRAddr = receiveAddr_[procI];
|
||||||
|
|
||||||
|
if (!curRAddr.empty())
|
||||||
|
{
|
||||||
|
Field<Type> receiveBuf(curRAddr.size());
|
||||||
|
|
||||||
|
// Opt: reconsider mode of communication
|
||||||
|
IPstream::read
|
||||||
|
(
|
||||||
|
Pstream::blocking,
|
||||||
|
procI,
|
||||||
|
reinterpret_cast<char*>(receiveBuf.begin()),
|
||||||
|
receiveBuf.byteSize()
|
||||||
|
);
|
||||||
|
|
||||||
|
// Insert received information
|
||||||
|
forAll (curRAddr, i)
|
||||||
|
{
|
||||||
|
expandField[curRAddr[i]] = receiveBuf[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expanded field complete, send required data to other processors
|
||||||
|
for (label procI = 1; procI < Pstream::nProcs(); procI++)
|
||||||
|
{
|
||||||
|
const labelList& curSAddr = sendAddr_[procI];
|
||||||
|
|
||||||
|
if (!curSAddr.empty())
|
||||||
|
{
|
||||||
|
Field<Type> sendBuf(curSAddr.size());
|
||||||
|
|
||||||
|
forAll (curSAddr, i)
|
||||||
|
{
|
||||||
|
sendBuf[i] = expandField[curSAddr[i]];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Opt: reconsider mode of communication
|
||||||
|
OPstream::write
|
||||||
|
(
|
||||||
|
Pstream::blocking,
|
||||||
|
procI,
|
||||||
|
reinterpret_cast<const char*>(sendBuf.begin()),
|
||||||
|
sendBuf.byteSize()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: different from ggi patch: field reduction happens within
|
||||||
|
// fastReduce. HJ, 26/Jun/2011
|
||||||
|
const labelList& sza = shadowInterface().zoneAddressing();
|
||||||
|
|
||||||
|
tmp<Field<Type> > tredField
|
||||||
|
(
|
||||||
|
new Field<Type>(sza.size(), pTraits<Type>::zero)
|
||||||
|
);
|
||||||
|
Field<Type>& redField = tredField();
|
||||||
|
|
||||||
|
// Select elements from shadow zone addressing
|
||||||
|
forAll (sza, i)
|
||||||
|
{
|
||||||
|
redField[i] = expandField[sza[i]];
|
||||||
|
}
|
||||||
|
|
||||||
|
return tredField;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Send local data to master and receive remote data
|
||||||
|
// If patch is empty, communication is avoided
|
||||||
|
// HJ, 4/Jun/2011
|
||||||
|
if (size())
|
||||||
|
{
|
||||||
|
// Opt: reconsider mode of communication
|
||||||
|
OPstream::write
|
||||||
|
(
|
||||||
|
Pstream::blocking,
|
||||||
|
Pstream::masterNo(),
|
||||||
|
reinterpret_cast<const char*>(ff.begin()),
|
||||||
|
ff.byteSize()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare to receive remote data
|
||||||
|
const labelList& za = zoneAddressing();
|
||||||
|
|
||||||
|
tmp<Field<Type> > treceiveBuf
|
||||||
|
(
|
||||||
|
new Field<Type>(za.size(), pTraits<Type>::zero)
|
||||||
|
);
|
||||||
|
Field<Type>& receiveBuf = treceiveBuf();
|
||||||
|
|
||||||
|
if (!za.empty())
|
||||||
|
{
|
||||||
|
// Opt: reconsider mode of communication
|
||||||
|
IPstream::read
|
||||||
|
(
|
||||||
|
Pstream::blocking,
|
||||||
|
Pstream::masterNo(),
|
||||||
|
reinterpret_cast<char*>(receiveBuf.begin()),
|
||||||
|
receiveBuf.byteSize()
|
||||||
|
);
|
||||||
|
|
||||||
|
// Note: different from ggi patch: field reduction happens within
|
||||||
|
// fastReduce. HJ, 26/Jun/2011
|
||||||
|
}
|
||||||
|
|
||||||
|
return treceiveBuf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
tmp<Field<Type> > ggiGAMGInterface::expand(const UList<Type>& pd) const
|
tmp<Field<Type> > ggiGAMGInterface::expand(const UList<Type>& pd) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -144,6 +144,19 @@ void Foam::polyBoundaryMesh::clearAddressing()
|
||||||
|
|
||||||
void Foam::polyBoundaryMesh::calcGeometry()
|
void Foam::polyBoundaryMesh::calcGeometry()
|
||||||
{
|
{
|
||||||
|
// Calculation of addressing, with communication
|
||||||
|
// HJ, 12/Jun/2011
|
||||||
|
forAll(*this, patchi)
|
||||||
|
{
|
||||||
|
operator[](patchi).initAddressing();
|
||||||
|
}
|
||||||
|
|
||||||
|
forAll(*this, patchi)
|
||||||
|
{
|
||||||
|
operator[](patchi).calcAddressing();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculation of geometry with communications
|
||||||
forAll(*this, patchi)
|
forAll(*this, patchi)
|
||||||
{
|
{
|
||||||
operator[](patchi).initGeometry();
|
operator[](patchi).initGeometry();
|
||||||
|
|
|
@ -78,7 +78,10 @@ class polyBoundaryMesh
|
||||||
//- Create identity map
|
//- Create identity map
|
||||||
static labelList ident(const label len);
|
static labelList ident(const label len);
|
||||||
|
|
||||||
//- Calculate the geometry for the patches (transformation tensors etc.)
|
//- Calculate the geometry for the patches,
|
||||||
|
// eg transformation tensors etc.
|
||||||
|
// Enhanced for parallel addressing calculations
|
||||||
|
// HJ, 11/Jun/2011
|
||||||
void calcGeometry();
|
void calcGeometry();
|
||||||
|
|
||||||
//- Disallow construct as copy
|
//- Disallow construct as copy
|
||||||
|
|
|
@ -86,6 +86,12 @@ protected:
|
||||||
const scalar absTol = matchTol_
|
const scalar absTol = matchTol_
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
|
//- Initialise the calculation of the patch addressing
|
||||||
|
virtual void initAddressing() = 0;
|
||||||
|
|
||||||
|
//- Calculate the patch addressing
|
||||||
|
virtual void calcAddressing() = 0;
|
||||||
|
|
||||||
//- Initialise the calculation of the patch geometry
|
//- Initialise the calculation of the patch geometry
|
||||||
virtual void initGeometry() = 0;
|
virtual void initGeometry() = 0;
|
||||||
|
|
||||||
|
|
|
@ -950,6 +950,18 @@ Foam::cyclicPolyPatch::~cyclicPolyPatch()
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::cyclicPolyPatch::initAddressing()
|
||||||
|
{
|
||||||
|
polyPatch::initAddressing();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::cyclicPolyPatch::calcAddressing()
|
||||||
|
{
|
||||||
|
polyPatch::calcAddressing();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::cyclicPolyPatch::initGeometry()
|
void Foam::cyclicPolyPatch::initGeometry()
|
||||||
{
|
{
|
||||||
polyPatch::initGeometry();
|
polyPatch::initGeometry();
|
||||||
|
@ -959,6 +971,7 @@ void Foam::cyclicPolyPatch::initGeometry()
|
||||||
void Foam::cyclicPolyPatch::calcGeometry()
|
void Foam::cyclicPolyPatch::calcGeometry()
|
||||||
{
|
{
|
||||||
polyPatch::calcGeometry();
|
polyPatch::calcGeometry();
|
||||||
|
|
||||||
calcTransforms();
|
calcTransforms();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -178,6 +178,12 @@ protected:
|
||||||
|
|
||||||
// Protected Member functions
|
// Protected Member functions
|
||||||
|
|
||||||
|
//- Initialise the calculation of the patch addressing
|
||||||
|
virtual void initAddressing();
|
||||||
|
|
||||||
|
//- Calculate the patch addressing
|
||||||
|
virtual void calcAddressing();
|
||||||
|
|
||||||
//- Initialise the calculation of the patch geometry
|
//- Initialise the calculation of the patch geometry
|
||||||
virtual void initGeometry();
|
virtual void initGeometry();
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,15 @@ namespace Foam
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
bool Foam::ggiPolyPatch::active() const
|
||||||
|
{
|
||||||
|
polyPatchID shadow(shadowName_, boundaryMesh());
|
||||||
|
faceZoneID zone(zoneName_, boundaryMesh().mesh().faceZones());
|
||||||
|
|
||||||
|
return shadow.active() && zone.active();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::ggiPolyPatch::calcZoneAddressing() const
|
void Foam::ggiPolyPatch::calcZoneAddressing() const
|
||||||
{
|
{
|
||||||
// Calculate patch-to-zone addressing
|
// Calculate patch-to-zone addressing
|
||||||
|
@ -61,18 +70,24 @@ void Foam::ggiPolyPatch::calcZoneAddressing() const
|
||||||
<< abort(FatalError);
|
<< abort(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "ggiPolyPatch::calcZoneAddressing() const for patch "
|
||||||
|
<< index() << endl;
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate patch-to-zone addressing
|
// Calculate patch-to-zone addressing
|
||||||
zoneAddressingPtr_ = new labelList(size());
|
zoneAddressingPtr_ = new labelList(size());
|
||||||
labelList& addr = *zoneAddressingPtr_;
|
labelList& zAddr = *zoneAddressingPtr_;
|
||||||
const faceZone& myZone = zone();
|
const faceZone& myZone = zone();
|
||||||
|
|
||||||
for (label i = 0; i < size(); i++)
|
for (label i = 0; i < size(); i++)
|
||||||
{
|
{
|
||||||
addr[i] = myZone.whichFace(start() + i);
|
zAddr[i] = myZone.whichFace(start() + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check zone addressing
|
// Check zone addressing
|
||||||
if (addr.size() > 0 && min(addr) < 0)
|
if (zAddr.size() > 0 && min(zAddr) < 0)
|
||||||
{
|
{
|
||||||
FatalErrorIn("void ggiPolyPatch::calcZoneAddressing() const")
|
FatalErrorIn("void ggiPolyPatch::calcZoneAddressing() const")
|
||||||
<< "Problem with patch-to zone addressing: some patch faces "
|
<< "Problem with patch-to zone addressing: some patch faces "
|
||||||
|
@ -82,6 +97,85 @@ void Foam::ggiPolyPatch::calcZoneAddressing() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::ggiPolyPatch::calcRemoteZoneAddressing() const
|
||||||
|
{
|
||||||
|
// Calculate patch-to-zone addressing
|
||||||
|
if (remoteZoneAddressingPtr_)
|
||||||
|
{
|
||||||
|
FatalErrorIn("void ggiPolyPatch::calcRemoteZoneAddressing() const")
|
||||||
|
<< "Patch to remote zone addressing already calculated"
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "ggiPolyPatch::calcRemoteZoneAddressing() const for patch "
|
||||||
|
<< index() << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Once zone addressing is established, visit the opposite side and find
|
||||||
|
// out which face data is needed for interpolation
|
||||||
|
boolList usedShadows(shadow().zone().size(), false);
|
||||||
|
|
||||||
|
const labelList& zAddr = zoneAddressing();
|
||||||
|
|
||||||
|
if (master())
|
||||||
|
{
|
||||||
|
const labelListList& addr = patchToPatch().masterAddr();
|
||||||
|
|
||||||
|
forAll (zAddr, mfI)
|
||||||
|
{
|
||||||
|
const labelList& nbrs = addr[zAddr[mfI]];
|
||||||
|
|
||||||
|
forAll (nbrs, nbrI)
|
||||||
|
{
|
||||||
|
usedShadows[nbrs[nbrI]] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const labelListList& addr = patchToPatch().slaveAddr();
|
||||||
|
|
||||||
|
forAll (zAddr, mfI)
|
||||||
|
{
|
||||||
|
const labelList& nbrs = addr[zAddr[mfI]];
|
||||||
|
|
||||||
|
forAll (nbrs, nbrI)
|
||||||
|
{
|
||||||
|
usedShadows[nbrs[nbrI]] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count and pick up shadow indices
|
||||||
|
label nShadows = 0;
|
||||||
|
|
||||||
|
forAll (usedShadows, sI)
|
||||||
|
{
|
||||||
|
if (usedShadows[sI])
|
||||||
|
{
|
||||||
|
nShadows++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
remoteZoneAddressingPtr_ = new labelList(nShadows);
|
||||||
|
labelList& rza = *remoteZoneAddressingPtr_;
|
||||||
|
|
||||||
|
// Reset counter for re-use
|
||||||
|
nShadows = 0;
|
||||||
|
|
||||||
|
forAll (usedShadows, sI)
|
||||||
|
{
|
||||||
|
if (usedShadows[sI])
|
||||||
|
{
|
||||||
|
rza[nShadows] = sI;
|
||||||
|
nShadows++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::ggiPolyPatch::calcPatchToPatch() const
|
void Foam::ggiPolyPatch::calcPatchToPatch() const
|
||||||
{
|
{
|
||||||
// Create patch-to-patch interpolation
|
// Create patch-to-patch interpolation
|
||||||
|
@ -98,31 +192,29 @@ void Foam::ggiPolyPatch::calcPatchToPatch() const
|
||||||
patchToPatchPtr_ =
|
patchToPatchPtr_ =
|
||||||
new ggiZoneInterpolation
|
new ggiZoneInterpolation
|
||||||
(
|
(
|
||||||
zone()(),
|
zone()(), // This zone reference
|
||||||
shadow().zone()(),
|
shadow().zone()(), // This shadow zone reference
|
||||||
forwardT(),
|
forwardT(),
|
||||||
reverseT(),
|
reverseT(),
|
||||||
shadow().separation(), // Slave-to-master separation. Bug fix
|
shadow().separation(), // Slave-to-master separation. Bug fix
|
||||||
0, // Non-overlapping face tolerances
|
0, // Non-overlapping face tolerances
|
||||||
0, // HJ, 24/Oct/2008
|
0, // HJ, 24/Oct/2008
|
||||||
true, // Rescale weighting factors. Bug fix, MB.
|
true, // Rescale weighting factors. Bug fix, MB.
|
||||||
ggiInterpolation::AABB
|
// ggiInterpolation::AABB
|
||||||
|
ggiInterpolation::BB_OCTREE // Octree search, MB.
|
||||||
);
|
);
|
||||||
|
|
||||||
// Abort immediatly if uncovered faces are present and the option
|
// Abort immediately if uncovered faces are present and the option
|
||||||
// bridgeOverlap is not set.
|
// bridgeOverlap is not set.
|
||||||
if
|
if
|
||||||
(
|
(
|
||||||
(
|
(
|
||||||
patchToPatch().uncoveredMasterFaces().size() > 0
|
patchToPatch().uncoveredMasterFaces().size() > 0
|
||||||
&&
|
&& !bridgeOverlap()
|
||||||
!bridgeOverlap()
|
|
||||||
)
|
)
|
||||||
||
|
|| (
|
||||||
(
|
|
||||||
patchToPatch().uncoveredSlaveFaces().size() > 0
|
patchToPatch().uncoveredSlaveFaces().size() > 0
|
||||||
&&
|
&& !shadow().bridgeOverlap()
|
||||||
!shadow().bridgeOverlap()
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
@ -144,43 +236,6 @@ void Foam::ggiPolyPatch::calcPatchToPatch() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::ggiPolyPatch::calcLocalParallel() const
|
|
||||||
{
|
|
||||||
// Calculate patch-to-zone addressing
|
|
||||||
if (localParallelPtr_)
|
|
||||||
{
|
|
||||||
FatalErrorIn("void ggiPolyPatch::calcLocalParallel() const")
|
|
||||||
<< "Local parallel switch already calculated"
|
|
||||||
<< abort(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
localParallelPtr_ = new bool(false);
|
|
||||||
bool& emptyOrComplete = *localParallelPtr_;
|
|
||||||
|
|
||||||
// Calculate localisation on master and shadow
|
|
||||||
emptyOrComplete =
|
|
||||||
(zone().size() == size() && shadow().zone().size() == shadow().size())
|
|
||||||
|| (size() == 0 && shadow().size() == 0);
|
|
||||||
|
|
||||||
reduce(emptyOrComplete, andOp<bool>());
|
|
||||||
|
|
||||||
if (debug && Pstream::parRun())
|
|
||||||
{
|
|
||||||
Info<< "GGI patch Master: " << name()
|
|
||||||
<< " Slave: " << shadowName() << " is ";
|
|
||||||
|
|
||||||
if (emptyOrComplete)
|
|
||||||
{
|
|
||||||
Info<< "local parallel" << endl;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Info<< "split between multiple processors" << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::ggiPolyPatch::calcReconFaceCellCentres() const
|
void Foam::ggiPolyPatch::calcReconFaceCellCentres() const
|
||||||
{
|
{
|
||||||
// Create neighbouring face centres using interpolation
|
// Create neighbouring face centres using interpolation
|
||||||
|
@ -209,12 +264,162 @@ void Foam::ggiPolyPatch::calcReconFaceCellCentres() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::ggiPolyPatch::calcLocalParallel() const
|
||||||
|
{
|
||||||
|
// Calculate patch-to-zone addressing
|
||||||
|
if (localParallelPtr_)
|
||||||
|
{
|
||||||
|
FatalErrorIn("void ggiPolyPatch::calcLocalParallel() const")
|
||||||
|
<< "Local parallel switch already calculated"
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
localParallelPtr_ = new bool(false);
|
||||||
|
bool& emptyOrComplete = *localParallelPtr_;
|
||||||
|
|
||||||
|
// If running in serial, all GGIs are local parallel
|
||||||
|
// HJ, 1/Jun/2011
|
||||||
|
if (!Pstream::parRun())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate localisation on master and shadow
|
||||||
|
emptyOrComplete =
|
||||||
|
(zone().size() == size() && shadow().zone().size() == shadow().size())
|
||||||
|
|| (size() == 0 && shadow().size() == 0);
|
||||||
|
|
||||||
|
reduce(emptyOrComplete, andOp<bool>());
|
||||||
|
|
||||||
|
if (debug && Pstream::parRun())
|
||||||
|
{
|
||||||
|
Info<< "GGI patch Master: " << name()
|
||||||
|
<< " Slave: " << shadowName() << " is ";
|
||||||
|
|
||||||
|
if (emptyOrComplete)
|
||||||
|
{
|
||||||
|
Info<< "local parallel" << endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Info<< "split between multiple processors" << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::ggiPolyPatch::calcSendReceive() const
|
||||||
|
{
|
||||||
|
// Note: all processors will execute calcSendReceive but only master will
|
||||||
|
// hold the information. Therefore, pointers on slave processors
|
||||||
|
// will remain meaningless, but for purposes of consistency
|
||||||
|
// (of the calc-call) they will be set to zero-sized array
|
||||||
|
// HJ, 4/Jun/2011
|
||||||
|
|
||||||
|
if (receiveAddrPtr_ || sendAddrPtr_)
|
||||||
|
{
|
||||||
|
FatalErrorIn("void ggiPolyPatch::calcSendReceive() const")
|
||||||
|
<< "Send-receive addressing already calculated"
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "ggiPolyPatch::calcSendReceive() const for patch "
|
||||||
|
<< index() << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Pstream::parRun())
|
||||||
|
{
|
||||||
|
FatalErrorIn("void ggiPolyPatch::calcSendReceive() const")
|
||||||
|
<< "Requested calculation of send-receive addressing for a "
|
||||||
|
<< "serial run. This is not allowed"
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Master will receive and store the maps
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
receiveAddrPtr_ = new labelListList(Pstream::nProcs());
|
||||||
|
labelListList& rAddr = *receiveAddrPtr_;
|
||||||
|
|
||||||
|
sendAddrPtr_ = new labelListList(Pstream::nProcs());
|
||||||
|
labelListList& sAddr = *sendAddrPtr_;
|
||||||
|
|
||||||
|
// Insert master
|
||||||
|
rAddr[0] = zoneAddressing();
|
||||||
|
|
||||||
|
for (label procI = 1; procI < Pstream::nProcs(); procI++)
|
||||||
|
{
|
||||||
|
// Note: must use normal comms because the size of the
|
||||||
|
// communicated lists is unknown on the receiving side
|
||||||
|
// HJ, 4/Jun/2011
|
||||||
|
|
||||||
|
// Opt: reconsider mode of communication
|
||||||
|
IPstream ip(Pstream::scheduled, procI);
|
||||||
|
|
||||||
|
rAddr[procI] = labelList(ip);
|
||||||
|
|
||||||
|
sAddr[procI] = labelList(ip);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Create dummy pointers: only master processor stores maps
|
||||||
|
receiveAddrPtr_ = new labelListList();
|
||||||
|
sendAddrPtr_ = new labelListList();
|
||||||
|
|
||||||
|
// Send information to master
|
||||||
|
const labelList& za = zoneAddressing();
|
||||||
|
const labelList& ra = remoteZoneAddressing();
|
||||||
|
|
||||||
|
// Note: must use normal comms because the size of the
|
||||||
|
// communicated lists is unknown on the receiving side
|
||||||
|
// HJ, 4/Jun/2011
|
||||||
|
|
||||||
|
// Opt: reconsider mode of communication
|
||||||
|
OPstream op(Pstream::scheduled, Pstream::masterNo());
|
||||||
|
|
||||||
|
// Send local and remote addressing to master
|
||||||
|
op << za << ra;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Foam::labelListList& Foam::ggiPolyPatch::receiveAddr() const
|
||||||
|
{
|
||||||
|
if (!receiveAddrPtr_)
|
||||||
|
{
|
||||||
|
calcSendReceive();
|
||||||
|
}
|
||||||
|
|
||||||
|
return *receiveAddrPtr_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Foam::labelListList& Foam::ggiPolyPatch::sendAddr() const
|
||||||
|
{
|
||||||
|
if (!sendAddrPtr_)
|
||||||
|
{
|
||||||
|
calcSendReceive();
|
||||||
|
}
|
||||||
|
|
||||||
|
return *sendAddrPtr_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::ggiPolyPatch::clearGeom()
|
void Foam::ggiPolyPatch::clearGeom()
|
||||||
{
|
{
|
||||||
deleteDemandDrivenData(patchToPatchPtr_);
|
|
||||||
deleteDemandDrivenData(zoneAddressingPtr_);
|
|
||||||
|
|
||||||
deleteDemandDrivenData(reconFaceCellCentresPtr_);
|
deleteDemandDrivenData(reconFaceCellCentresPtr_);
|
||||||
|
|
||||||
|
// Remote addressing and send-receive maps depend on the local
|
||||||
|
// position. Therefore, it needs to be recalculated at mesh motion.
|
||||||
|
// Local zone addressing does not change with mesh motion
|
||||||
|
// HJ, 23/Jun/2011
|
||||||
|
deleteDemandDrivenData(remoteZoneAddressingPtr_);
|
||||||
|
|
||||||
|
deleteDemandDrivenData(receiveAddrPtr_);
|
||||||
|
deleteDemandDrivenData(sendAddrPtr_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -222,6 +427,8 @@ void Foam::ggiPolyPatch::clearOut()
|
||||||
{
|
{
|
||||||
clearGeom();
|
clearGeom();
|
||||||
|
|
||||||
|
deleteDemandDrivenData(zoneAddressingPtr_);
|
||||||
|
deleteDemandDrivenData(patchToPatchPtr_);
|
||||||
deleteDemandDrivenData(localParallelPtr_);
|
deleteDemandDrivenData(localParallelPtr_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,8 +452,11 @@ Foam::ggiPolyPatch::ggiPolyPatch
|
||||||
zoneIndex_(-1),
|
zoneIndex_(-1),
|
||||||
patchToPatchPtr_(NULL),
|
patchToPatchPtr_(NULL),
|
||||||
zoneAddressingPtr_(NULL),
|
zoneAddressingPtr_(NULL),
|
||||||
|
remoteZoneAddressingPtr_(NULL),
|
||||||
|
reconFaceCellCentresPtr_(NULL),
|
||||||
localParallelPtr_(NULL),
|
localParallelPtr_(NULL),
|
||||||
reconFaceCellCentresPtr_(NULL)
|
receiveAddrPtr_(NULL),
|
||||||
|
sendAddrPtr_(NULL)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
@ -270,8 +480,11 @@ Foam::ggiPolyPatch::ggiPolyPatch
|
||||||
zoneIndex_(-1),
|
zoneIndex_(-1),
|
||||||
patchToPatchPtr_(NULL),
|
patchToPatchPtr_(NULL),
|
||||||
zoneAddressingPtr_(NULL),
|
zoneAddressingPtr_(NULL),
|
||||||
|
remoteZoneAddressingPtr_(NULL),
|
||||||
|
reconFaceCellCentresPtr_(NULL),
|
||||||
localParallelPtr_(NULL),
|
localParallelPtr_(NULL),
|
||||||
reconFaceCellCentresPtr_(NULL)
|
receiveAddrPtr_(NULL),
|
||||||
|
sendAddrPtr_(NULL)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
@ -291,8 +504,11 @@ Foam::ggiPolyPatch::ggiPolyPatch
|
||||||
zoneIndex_(-1),
|
zoneIndex_(-1),
|
||||||
patchToPatchPtr_(NULL),
|
patchToPatchPtr_(NULL),
|
||||||
zoneAddressingPtr_(NULL),
|
zoneAddressingPtr_(NULL),
|
||||||
|
remoteZoneAddressingPtr_(NULL),
|
||||||
|
reconFaceCellCentresPtr_(NULL),
|
||||||
localParallelPtr_(NULL),
|
localParallelPtr_(NULL),
|
||||||
reconFaceCellCentresPtr_(NULL)
|
receiveAddrPtr_(NULL),
|
||||||
|
sendAddrPtr_(NULL)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
@ -310,8 +526,11 @@ Foam::ggiPolyPatch::ggiPolyPatch
|
||||||
zoneIndex_(-1),
|
zoneIndex_(-1),
|
||||||
patchToPatchPtr_(NULL),
|
patchToPatchPtr_(NULL),
|
||||||
zoneAddressingPtr_(NULL),
|
zoneAddressingPtr_(NULL),
|
||||||
|
remoteZoneAddressingPtr_(NULL),
|
||||||
|
reconFaceCellCentresPtr_(NULL),
|
||||||
localParallelPtr_(NULL),
|
localParallelPtr_(NULL),
|
||||||
reconFaceCellCentresPtr_(NULL)
|
receiveAddrPtr_(NULL),
|
||||||
|
sendAddrPtr_(NULL)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
@ -333,8 +552,11 @@ Foam::ggiPolyPatch::ggiPolyPatch
|
||||||
zoneIndex_(-1),
|
zoneIndex_(-1),
|
||||||
patchToPatchPtr_(NULL),
|
patchToPatchPtr_(NULL),
|
||||||
zoneAddressingPtr_(NULL),
|
zoneAddressingPtr_(NULL),
|
||||||
|
remoteZoneAddressingPtr_(NULL),
|
||||||
|
reconFaceCellCentresPtr_(NULL),
|
||||||
localParallelPtr_(NULL),
|
localParallelPtr_(NULL),
|
||||||
reconFaceCellCentresPtr_(NULL)
|
receiveAddrPtr_(NULL),
|
||||||
|
sendAddrPtr_(NULL)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
@ -437,6 +659,17 @@ const Foam::labelList& Foam::ggiPolyPatch::zoneAddressing() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Foam::labelList& Foam::ggiPolyPatch::remoteZoneAddressing() const
|
||||||
|
{
|
||||||
|
if (!remoteZoneAddressingPtr_)
|
||||||
|
{
|
||||||
|
calcRemoteZoneAddressing();
|
||||||
|
}
|
||||||
|
|
||||||
|
return *remoteZoneAddressingPtr_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Foam::ggiPolyPatch::localParallel() const
|
bool Foam::ggiPolyPatch::localParallel() const
|
||||||
{
|
{
|
||||||
// Calculate patch-to-zone addressing
|
// Calculate patch-to-zone addressing
|
||||||
|
@ -483,8 +716,45 @@ const Foam::vectorField& Foam::ggiPolyPatch::reconFaceCellCentres() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::ggiPolyPatch::initAddressing()
|
||||||
|
{
|
||||||
|
if (active())
|
||||||
|
{
|
||||||
|
// Force zone addressing first
|
||||||
|
zoneAddressing();
|
||||||
|
remoteZoneAddressing();
|
||||||
|
|
||||||
|
if (Pstream::parRun() && !localParallel())
|
||||||
|
{
|
||||||
|
sendAddr();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
polyPatch::initAddressing();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::ggiPolyPatch::calcAddressing()
|
||||||
|
{
|
||||||
|
polyPatch::calcAddressing();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::ggiPolyPatch::initGeometry()
|
void Foam::ggiPolyPatch::initGeometry()
|
||||||
{
|
{
|
||||||
|
// Communication is allowed either before or after processor
|
||||||
|
// patch comms. HJ, 11/Jul/2011
|
||||||
|
if (active())
|
||||||
|
{
|
||||||
|
calcTransforms();
|
||||||
|
|
||||||
|
// Note: Only master calculates recon; slave uses master interpolation
|
||||||
|
if (master())
|
||||||
|
{
|
||||||
|
reconFaceCellCentres();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
polyPatch::initGeometry();
|
polyPatch::initGeometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -497,18 +767,40 @@ void Foam::ggiPolyPatch::calcGeometry()
|
||||||
// reconFaceCellCentres in order to correctly set the transformation
|
// reconFaceCellCentres in order to correctly set the transformation
|
||||||
// in the interpolation routines.
|
// in the interpolation routines.
|
||||||
// HJ, 3/Jul/2009
|
// HJ, 3/Jul/2009
|
||||||
calcTransforms();
|
|
||||||
|
|
||||||
// Reconstruct the cell face centres
|
|
||||||
if (patchToPatchPtr_ && master())
|
|
||||||
{
|
|
||||||
reconFaceCellCentres();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::ggiPolyPatch::initMovePoints(const pointField& p)
|
void Foam::ggiPolyPatch::initMovePoints(const pointField& p)
|
||||||
{
|
{
|
||||||
|
clearGeom();
|
||||||
|
|
||||||
|
// Calculate transforms on mesh motion?
|
||||||
|
calcTransforms();
|
||||||
|
|
||||||
|
// Update interpolation for new relative position of GGI interfaces
|
||||||
|
if (patchToPatchPtr_)
|
||||||
|
{
|
||||||
|
patchToPatchPtr_->movePoints();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recalculate send and receive maps
|
||||||
|
if (active())
|
||||||
|
{
|
||||||
|
// Force zone addressing first
|
||||||
|
zoneAddressing();
|
||||||
|
remoteZoneAddressing();
|
||||||
|
|
||||||
|
if (Pstream::parRun() && !localParallel())
|
||||||
|
{
|
||||||
|
sendAddr();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (active() && master())
|
||||||
|
{
|
||||||
|
reconFaceCellCentres();
|
||||||
|
}
|
||||||
|
|
||||||
polyPatch::initMovePoints(p);
|
polyPatch::initMovePoints(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -516,7 +808,6 @@ void Foam::ggiPolyPatch::initMovePoints(const pointField& p)
|
||||||
void Foam::ggiPolyPatch::movePoints(const pointField& p)
|
void Foam::ggiPolyPatch::movePoints(const pointField& p)
|
||||||
{
|
{
|
||||||
polyPatch::movePoints(p);
|
polyPatch::movePoints(p);
|
||||||
clearGeom();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -85,25 +85,43 @@ class ggiPolyPatch
|
||||||
//- Patch-to-zone addressing
|
//- Patch-to-zone addressing
|
||||||
mutable labelList* zoneAddressingPtr_;
|
mutable labelList* zoneAddressingPtr_;
|
||||||
|
|
||||||
//- Is the patch localised on a single processor
|
//- Remote zone addressing: data needed for interpolation
|
||||||
// (single processor in a parallel run)?
|
mutable labelList* remoteZoneAddressingPtr_;
|
||||||
// Used for parallel optimisation
|
|
||||||
mutable bool* localParallelPtr_;
|
|
||||||
|
|
||||||
//- Reconstructed patch neighbour cell centres
|
//- Reconstructed patch neighbour cell centres
|
||||||
mutable vectorField* reconFaceCellCentresPtr_;
|
mutable vectorField* reconFaceCellCentresPtr_;
|
||||||
|
|
||||||
|
|
||||||
|
// Parallel communication optimisation, stored on master processor
|
||||||
|
|
||||||
|
//- Is the patch localised on a single processor
|
||||||
|
// (single processor in a parallel run)?
|
||||||
|
// Used for parallel optimisation
|
||||||
|
mutable bool* localParallelPtr_;
|
||||||
|
|
||||||
|
//- List of zone faces indices received from each processor
|
||||||
|
mutable labelListList* receiveAddrPtr_;
|
||||||
|
|
||||||
|
//- List of zone faces indices to send to each processor
|
||||||
|
mutable labelListList* sendAddrPtr_;
|
||||||
|
|
||||||
|
|
||||||
// Private member functions
|
// Private member functions
|
||||||
|
|
||||||
|
//- Is the GGI active& (zone and shadow present)
|
||||||
|
bool active() const;
|
||||||
|
|
||||||
//- Calculate patch-to-zone addressing
|
//- Calculate patch-to-zone addressing
|
||||||
virtual void calcZoneAddressing() const;
|
virtual void calcZoneAddressing() const;
|
||||||
|
|
||||||
|
//- Calculate remote patch-to-zone addressing
|
||||||
|
virtual void calcRemoteZoneAddressing() const;
|
||||||
|
|
||||||
//- Calculate interpolation
|
//- Calculate interpolation
|
||||||
virtual void calcPatchToPatch() const;
|
virtual void calcPatchToPatch() const;
|
||||||
|
|
||||||
//- Calculate local parallel switch
|
|
||||||
void calcLocalParallel() const;
|
// Geometry
|
||||||
|
|
||||||
//- Calculate reconstructed cell centres
|
//- Calculate reconstructed cell centres
|
||||||
void calcReconFaceCellCentres() const;
|
void calcReconFaceCellCentres() const;
|
||||||
|
@ -111,6 +129,25 @@ class ggiPolyPatch
|
||||||
//- Force calculation of transformation tensors
|
//- Force calculation of transformation tensors
|
||||||
virtual void calcTransforms();
|
virtual void calcTransforms();
|
||||||
|
|
||||||
|
|
||||||
|
// Parallel communication optimisation, stored on master processor
|
||||||
|
|
||||||
|
//- Calculate local parallel switch
|
||||||
|
void calcLocalParallel() const;
|
||||||
|
|
||||||
|
//- Calculate send and receive addressing
|
||||||
|
void calcSendReceive() const;
|
||||||
|
|
||||||
|
|
||||||
|
//- Return receive addressing
|
||||||
|
const labelListList& receiveAddr() const;
|
||||||
|
|
||||||
|
//- Return send addressing
|
||||||
|
const labelListList& sendAddr() const;
|
||||||
|
|
||||||
|
|
||||||
|
// Memory management
|
||||||
|
|
||||||
//- Clear geometry
|
//- Clear geometry
|
||||||
void clearGeom();
|
void clearGeom();
|
||||||
|
|
||||||
|
@ -122,6 +159,12 @@ protected:
|
||||||
|
|
||||||
// Protected Member functions
|
// Protected Member functions
|
||||||
|
|
||||||
|
//- Initialise the calculation of the patch addressing
|
||||||
|
virtual void initAddressing();
|
||||||
|
|
||||||
|
//- Calculate the patch addressing
|
||||||
|
virtual void calcAddressing();
|
||||||
|
|
||||||
//- Initialise the calculation of the patch geometry
|
//- Initialise the calculation of the patch geometry
|
||||||
virtual void initGeometry();
|
virtual void initGeometry();
|
||||||
|
|
||||||
|
@ -281,6 +324,9 @@ public:
|
||||||
//- Return patch-to-zone addressing
|
//- Return patch-to-zone addressing
|
||||||
const labelList& zoneAddressing() const;
|
const labelList& zoneAddressing() const;
|
||||||
|
|
||||||
|
//- Return remote patch-to-zone addressing
|
||||||
|
const labelList& remoteZoneAddressing() const;
|
||||||
|
|
||||||
//- Is the patch localised on a single processor
|
//- Is the patch localised on a single processor
|
||||||
bool localParallel() const;
|
bool localParallel() const;
|
||||||
|
|
||||||
|
@ -289,13 +335,21 @@ public:
|
||||||
const ggiZoneInterpolation& patchToPatch() const;
|
const ggiZoneInterpolation& patchToPatch() const;
|
||||||
|
|
||||||
//- Expand face field to full zone size, including reduction
|
//- Expand face field to full zone size, including reduction
|
||||||
|
// New. HJ, 12/Jun/2011
|
||||||
|
template<class Type>
|
||||||
|
tmp<Field<Type> > fastExpand(const Field<Type>& pf) const;
|
||||||
|
|
||||||
|
//- Expand face field to full zone size, including reduction
|
||||||
|
// Obsolete. HJ, 12/Jun/2011
|
||||||
template<class Type>
|
template<class Type>
|
||||||
tmp<Field<Type> > expand(const Field<Type>& pf) const;
|
tmp<Field<Type> > expand(const Field<Type>& pf) const;
|
||||||
|
|
||||||
//- Filter zone field to patch size
|
//- Filter zone field to patch size
|
||||||
|
// Obsolete. HJ, 12/Jun/2011
|
||||||
template<class Type>
|
template<class Type>
|
||||||
tmp<Field<Type> > filter(const Field<Type>& zf) const;
|
tmp<Field<Type> > filter(const Field<Type>& zf) const;
|
||||||
|
|
||||||
|
|
||||||
//- Interpolate face field: given field on a the shadow side,
|
//- Interpolate face field: given field on a the shadow side,
|
||||||
// create an interpolated field on this side
|
// create an interpolated field on this side
|
||||||
template<class Type>
|
template<class Type>
|
||||||
|
|
|
@ -28,26 +28,193 @@ Author
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "ggiPolyPatch.H"
|
#include "ggiPolyPatch.H"
|
||||||
|
#include "OSspecific.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
// New. HJ, 12/Jun/2011
|
||||||
template<class Type>
|
template<class Type>
|
||||||
Foam::tmp<Foam::Field<Type> > Foam::ggiPolyPatch::expand
|
Foam::tmp<Foam::Field<Type> > Foam::ggiPolyPatch::fastExpand
|
||||||
(
|
(
|
||||||
const Field<Type>& pf
|
const Field<Type>& ff
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
// Check and expand the field from patch size to zone size
|
// Check and expand the field from patch size to zone size
|
||||||
if (pf.size() != size())
|
// with communication
|
||||||
|
|
||||||
|
// Algorithm:
|
||||||
|
// 1) Master processor holds maps of all zone addressing (data provided)
|
||||||
|
// and all remote zone addressing (data required)
|
||||||
|
// 2) Each processor will send the locally active data to the master
|
||||||
|
// 3) Master assembles all the data
|
||||||
|
// 4) Master sends to all processors the data they need to receive
|
||||||
|
//
|
||||||
|
// Notes:
|
||||||
|
// A) If the size of zone addressing is zero, data is not sent
|
||||||
|
// B) Communicated data on each processor has the size of live faces
|
||||||
|
// C) Expanded data will be equal to actual data fronm other processors
|
||||||
|
// only for the faces marked in remote; for other faces, it will be
|
||||||
|
// equal to zero
|
||||||
|
// D) On processor zero, complete data is available
|
||||||
|
// HJ, 4/Jun/2011
|
||||||
|
if (ff.size() != size())
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"tmp<Field<Type> > ggiPolyPatch::fastExpand"
|
||||||
|
"("
|
||||||
|
" const Field<Type>& ff"
|
||||||
|
") const"
|
||||||
|
) << "Incorrect patch field size. Field size: "
|
||||||
|
<< ff.size() << " patch size: " << size()
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (localParallel())
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"tmp<Field<Type> > ggiPolyPatch::fastExpand"
|
||||||
|
"("
|
||||||
|
" const Field<Type>& ff"
|
||||||
|
") const"
|
||||||
|
) << "Requested expand on local parallel. This is not allowed"
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expand the field to zone size
|
||||||
|
tmp<Field<Type> > texpandField
|
||||||
|
(
|
||||||
|
new Field<Type>(zone().size(), pTraits<Type>::zero)
|
||||||
|
);
|
||||||
|
|
||||||
|
Field<Type>& expandField = texpandField();
|
||||||
|
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
// Insert master processor
|
||||||
|
const labelList& za = zoneAddressing();
|
||||||
|
|
||||||
|
forAll (za, i)
|
||||||
|
{
|
||||||
|
expandField[za[i]] = ff[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Master receives and inserts data from all processors for which
|
||||||
|
// receiveAddr contains entries
|
||||||
|
for (label procI = 1; procI < Pstream::nProcs(); procI++)
|
||||||
|
{
|
||||||
|
const labelList& curRAddr = receiveAddr()[procI];
|
||||||
|
|
||||||
|
if (!curRAddr.empty())
|
||||||
|
{
|
||||||
|
Field<Type> receiveBuf(curRAddr.size());
|
||||||
|
|
||||||
|
// Opt: reconsider mode of communication
|
||||||
|
IPstream::read
|
||||||
|
(
|
||||||
|
Pstream::blocking,
|
||||||
|
procI,
|
||||||
|
reinterpret_cast<char*>(receiveBuf.begin()),
|
||||||
|
receiveBuf.byteSize()
|
||||||
|
);
|
||||||
|
|
||||||
|
// Insert received information
|
||||||
|
forAll (curRAddr, i)
|
||||||
|
{
|
||||||
|
expandField[curRAddr[i]] = receiveBuf[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expanded field complete, send required data to other processors
|
||||||
|
for (label procI = 1; procI < Pstream::nProcs(); procI++)
|
||||||
|
{
|
||||||
|
const labelList& curSAddr = sendAddr()[procI];
|
||||||
|
|
||||||
|
if (!curSAddr.empty())
|
||||||
|
{
|
||||||
|
Field<Type> sendBuf(curSAddr.size());
|
||||||
|
|
||||||
|
forAll (curSAddr, i)
|
||||||
|
{
|
||||||
|
sendBuf[i] = expandField[curSAddr[i]];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Opt: reconsider mode of communication
|
||||||
|
OPstream::write
|
||||||
|
(
|
||||||
|
Pstream::blocking,
|
||||||
|
procI,
|
||||||
|
reinterpret_cast<const char*>(sendBuf.begin()),
|
||||||
|
sendBuf.byteSize()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Send local data to master and receive remote data
|
||||||
|
// If patch is empty, communication is avoided
|
||||||
|
// HJ, 4/Jun/2011
|
||||||
|
if (size())
|
||||||
|
{
|
||||||
|
// Opt: reconsider mode of communication
|
||||||
|
OPstream::write
|
||||||
|
(
|
||||||
|
Pstream::blocking,
|
||||||
|
Pstream::masterNo(),
|
||||||
|
reinterpret_cast<const char*>(ff.begin()),
|
||||||
|
ff.byteSize()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare to receive remote data
|
||||||
|
const labelList& rza = remoteZoneAddressing();
|
||||||
|
|
||||||
|
if (!rza.empty())
|
||||||
|
{
|
||||||
|
Field<Type> receiveBuf(rza.size());
|
||||||
|
|
||||||
|
// Opt: reconsider mode of communication
|
||||||
|
IPstream::read
|
||||||
|
(
|
||||||
|
Pstream::blocking,
|
||||||
|
Pstream::masterNo(),
|
||||||
|
reinterpret_cast<char*>(receiveBuf.begin()),
|
||||||
|
receiveBuf.byteSize()
|
||||||
|
);
|
||||||
|
|
||||||
|
// Insert the data into expanded field
|
||||||
|
forAll (rza, i)
|
||||||
|
{
|
||||||
|
expandField[rza[i]] = receiveBuf[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return texpandField;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Obsolete. HJ, 12/Jun/2011
|
||||||
|
template<class Type>
|
||||||
|
Foam::tmp<Foam::Field<Type> > Foam::ggiPolyPatch::expand
|
||||||
|
(
|
||||||
|
const Field<Type>& ff
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
// Check and expand the field from patch size to zone size
|
||||||
|
if (ff.size() != size())
|
||||||
{
|
{
|
||||||
FatalErrorIn
|
FatalErrorIn
|
||||||
(
|
(
|
||||||
"tmp<Field<Type> > ggiPolyPatch::expand"
|
"tmp<Field<Type> > ggiPolyPatch::expand"
|
||||||
"("
|
"("
|
||||||
" const Field<Type>& pf"
|
" const Field<Type>& ff"
|
||||||
") const"
|
") const"
|
||||||
) << "Incorrect patch field size. Field size: "
|
) << "Incorrect patch field size. Field size: "
|
||||||
<< pf.size() << " patch size: " << size()
|
<< ff.size() << " patch size: " << size()
|
||||||
<< abort(FatalError);
|
<< abort(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +230,7 @@ Foam::tmp<Foam::Field<Type> > Foam::ggiPolyPatch::expand
|
||||||
|
|
||||||
forAll (addr, i)
|
forAll (addr, i)
|
||||||
{
|
{
|
||||||
expandField[addr[i]] = pf[i];
|
expandField[addr[i]] = ff[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parallel data exchange: update surface field on all processors
|
// Parallel data exchange: update surface field on all processors
|
||||||
|
@ -79,6 +246,7 @@ Foam::tmp<Foam::Field<Type> > Foam::ggiPolyPatch::expand
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Obsolete. HJ, 12/Jun/2011
|
||||||
template<class Type>
|
template<class Type>
|
||||||
Foam::tmp<Foam::Field<Type> > Foam::ggiPolyPatch::filter
|
Foam::tmp<Foam::Field<Type> > Foam::ggiPolyPatch::filter
|
||||||
(
|
(
|
||||||
|
@ -121,25 +289,82 @@ Foam::tmp<Foam::Field<Type> > Foam::ggiPolyPatch::filter
|
||||||
template<class Type>
|
template<class Type>
|
||||||
Foam::tmp<Foam::Field<Type> > Foam::ggiPolyPatch::interpolate
|
Foam::tmp<Foam::Field<Type> > Foam::ggiPolyPatch::interpolate
|
||||||
(
|
(
|
||||||
const Field<Type>& pf
|
const Field<Type>& ff
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
// Check and expand the field from patch size to zone size
|
// Check and expand the field from patch size to zone size
|
||||||
if (pf.size() != shadow().size())
|
if (ff.size() != shadow().size())
|
||||||
{
|
{
|
||||||
FatalErrorIn
|
FatalErrorIn
|
||||||
(
|
(
|
||||||
"tmp<Field<Type> > ggiPolyPatch::interpolate"
|
"tmp<Field<Type> > ggiPolyPatch::interpolate"
|
||||||
"("
|
"("
|
||||||
" const Field<Type>& pf"
|
" const Field<Type>& ff"
|
||||||
") const"
|
") const"
|
||||||
) << "Incorrect slave patch field size. Field size: "
|
) << "Incorrect slave patch field size. Field size: "
|
||||||
<< pf.size() << " patch size: " << shadow().size()
|
<< ff.size() << " patch size: " << shadow().size()
|
||||||
<< abort(FatalError);
|
<< abort(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# if 1
|
||||||
|
|
||||||
|
// New. HJ, 12/Jun/2011
|
||||||
|
if (localParallel())
|
||||||
|
{
|
||||||
|
// No expansion or filtering needed. HJ, 4/Jun/2011
|
||||||
|
|
||||||
|
// Interpolate field
|
||||||
|
if (master())
|
||||||
|
{
|
||||||
|
return patchToPatch().slaveToMaster(ff);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return patchToPatch().masterToSlave(ff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Note: fast expand is always done on the local side
|
||||||
|
// HJ, 24/Jun/2011
|
||||||
|
Field<Type> expandField = fastExpand(ff);
|
||||||
|
|
||||||
|
tmp<Field<Type> > tresult(new Field<Type>(size()));
|
||||||
|
Field<Type>& result = tresult();
|
||||||
|
|
||||||
|
if (master())
|
||||||
|
{
|
||||||
|
patchToPatch().maskedSlaveToMaster
|
||||||
|
(
|
||||||
|
expandField,
|
||||||
|
result,
|
||||||
|
zoneAddressing()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
patchToPatch().maskedMasterToSlave
|
||||||
|
(
|
||||||
|
expandField,
|
||||||
|
result,
|
||||||
|
zoneAddressing()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return tresult;
|
||||||
|
}
|
||||||
|
|
||||||
|
# else
|
||||||
|
|
||||||
|
// Old treatment
|
||||||
|
// Obsolete. HJ, 12/Jun/2011
|
||||||
|
|
||||||
// Expand the field to zone size
|
// Expand the field to zone size
|
||||||
Field<Type> expandField = shadow().expand(pf);
|
// Note: with full fields it is the shadow side that does
|
||||||
|
// the expand. This is different than fastExpand because
|
||||||
|
// the addressing is stored remotely.
|
||||||
|
// HJ, 24/Jun/2011
|
||||||
|
Field<Type> expandField = shadow().expand(ff);
|
||||||
|
|
||||||
Field<Type> zoneField;
|
Field<Type> zoneField;
|
||||||
|
|
||||||
|
@ -154,17 +379,19 @@ Foam::tmp<Foam::Field<Type> > Foam::ggiPolyPatch::interpolate
|
||||||
}
|
}
|
||||||
|
|
||||||
return this->filter(zoneField);
|
return this->filter(zoneField);
|
||||||
|
|
||||||
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
Foam::tmp<Foam::Field<Type> > Foam::ggiPolyPatch::interpolate
|
Foam::tmp<Foam::Field<Type> > Foam::ggiPolyPatch::interpolate
|
||||||
(
|
(
|
||||||
const tmp<Field<Type> >& tpf
|
const tmp<Field<Type> >& tff
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
tmp<Field<Type> > tint = interpolate(tpf());
|
tmp<Field<Type> > tint = interpolate(tff());
|
||||||
tpf.clear();
|
tff.clear();
|
||||||
return tint;
|
return tint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,7 +405,43 @@ void Foam::ggiPolyPatch::bridge
|
||||||
{
|
{
|
||||||
if (bridgeOverlap())
|
if (bridgeOverlap())
|
||||||
{
|
{
|
||||||
// Parallelisation
|
# ifdef FAST_PARALLEL_GGI
|
||||||
|
|
||||||
|
if (localParallel())
|
||||||
|
{
|
||||||
|
if (master())
|
||||||
|
{
|
||||||
|
patchToPatch().bridgeMaster(bridgeField, ff);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
patchToPatch().bridgeSlave(bridgeField, ff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Note: since bridging is only a local operation
|
||||||
|
if (master())
|
||||||
|
{
|
||||||
|
patchToPatch().maskedBridgeMaster
|
||||||
|
(
|
||||||
|
bridgeField,
|
||||||
|
ff,
|
||||||
|
zoneAddressing()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
patchToPatch().maskedBridgeSlave
|
||||||
|
(
|
||||||
|
bridgeField,
|
||||||
|
ff,
|
||||||
|
zoneAddressing()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# else
|
||||||
|
|
||||||
// Expand the field to zone size
|
// Expand the field to zone size
|
||||||
Field<Type> expandBridge = this->expand(bridgeField);
|
Field<Type> expandBridge = this->expand(bridgeField);
|
||||||
|
@ -200,15 +463,8 @@ void Foam::ggiPolyPatch::bridge
|
||||||
{
|
{
|
||||||
ff[i] = expandField[addr[i]];
|
ff[i] = expandField[addr[i]];
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
# endif
|
||||||
{
|
|
||||||
// HJ, temporary
|
|
||||||
InfoIn
|
|
||||||
(
|
|
||||||
"void bridge(const Field<Type>& bridgeField, "
|
|
||||||
"Field<Type>& ff) const"
|
|
||||||
) << "Bridging is switched off " << endl;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -147,6 +147,12 @@ protected:
|
||||||
|
|
||||||
// Protected Member functions
|
// Protected Member functions
|
||||||
|
|
||||||
|
//- Initialise the calculation of the patch addressing
|
||||||
|
virtual void initAddressing();
|
||||||
|
|
||||||
|
//- Calculate the patch addressing
|
||||||
|
virtual void calcAddressing();
|
||||||
|
|
||||||
//- Initialise the calculation of the patch geometry
|
//- Initialise the calculation of the patch geometry
|
||||||
virtual void initGeometry();
|
virtual void initGeometry();
|
||||||
|
|
||||||
|
|
|
@ -175,8 +175,7 @@ void Foam::overlapGgiPolyPatch::calcPatchToPatch() const
|
||||||
if
|
if
|
||||||
(
|
(
|
||||||
patchToPatch().uncoveredMasterFaces().size() > 0
|
patchToPatch().uncoveredMasterFaces().size() > 0
|
||||||
||
|
|| patchToPatch().uncoveredSlaveFaces().size() > 0
|
||||||
patchToPatch().uncoveredSlaveFaces().size() > 0
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
FatalErrorIn("void overlapGgiPolyPatch::calcPatchToPatch() const")
|
FatalErrorIn("void overlapGgiPolyPatch::calcPatchToPatch() const")
|
||||||
|
@ -309,6 +308,18 @@ Foam::overlapGgiPolyPatch::reconFaceCellCentres() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::overlapGgiPolyPatch::initAddressing()
|
||||||
|
{
|
||||||
|
polyPatch::initAddressing();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::overlapGgiPolyPatch::calcAddressing()
|
||||||
|
{
|
||||||
|
polyPatch::calcAddressing();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::overlapGgiPolyPatch::initGeometry()
|
void Foam::overlapGgiPolyPatch::initGeometry()
|
||||||
{
|
{
|
||||||
polyPatch::initGeometry();
|
polyPatch::initGeometry();
|
||||||
|
|
|
@ -135,6 +135,18 @@ Foam::processorPolyPatch::~processorPolyPatch()
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::processorPolyPatch::initAddressing()
|
||||||
|
{
|
||||||
|
polyPatch::initAddressing();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::processorPolyPatch::calcAddressing()
|
||||||
|
{
|
||||||
|
polyPatch::calcAddressing();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::processorPolyPatch::initGeometry()
|
void Foam::processorPolyPatch::initGeometry()
|
||||||
{
|
{
|
||||||
if (Pstream::parRun())
|
if (Pstream::parRun())
|
||||||
|
|
|
@ -92,6 +92,12 @@ protected:
|
||||||
|
|
||||||
// Protected Member functions
|
// Protected Member functions
|
||||||
|
|
||||||
|
//- Initialise the calculation of the patch addressing
|
||||||
|
virtual void initAddressing();
|
||||||
|
|
||||||
|
//- Calculate the patch addressing
|
||||||
|
virtual void calcAddressing();
|
||||||
|
|
||||||
//- Initialise the calculation of the patch geometry
|
//- Initialise the calculation of the patch geometry
|
||||||
void initGeometry();
|
void initGeometry();
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,8 @@ void Foam::regionCouplePolyPatch::calcInterpolation() const
|
||||||
{
|
{
|
||||||
FatalErrorIn("void regionCouplePolyPatch::calcInterpolation() const")
|
FatalErrorIn("void regionCouplePolyPatch::calcInterpolation() const")
|
||||||
<< "Shadow of regionCouple patch " << name()
|
<< "Shadow of regionCouple patch " << name()
|
||||||
<< " named " << shadowPatchName() << " is not a regionCouple." << nl
|
<< " named " << shadowPatchName()
|
||||||
|
<< " is not a regionCouple." << nl
|
||||||
<< "This is not allowed. Please check your mesh definition."
|
<< "This is not allowed. Please check your mesh definition."
|
||||||
<< abort(FatalError);
|
<< abort(FatalError);
|
||||||
}
|
}
|
||||||
|
@ -153,10 +154,17 @@ void Foam::regionCouplePolyPatch::calcReconFaceCellCentres() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::regionCouplePolyPatch::clearGeom() const
|
||||||
|
{
|
||||||
|
deleteDemandDrivenData(reconFaceCellCentresPtr_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::regionCouplePolyPatch::clearOut() const
|
void Foam::regionCouplePolyPatch::clearOut() const
|
||||||
{
|
{
|
||||||
|
clearGeom();
|
||||||
|
|
||||||
deleteDemandDrivenData(patchToPatchPtr_);
|
deleteDemandDrivenData(patchToPatchPtr_);
|
||||||
deleteDemandDrivenData(reconFaceCellCentresPtr_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -173,14 +181,14 @@ Foam::regionCouplePolyPatch::regionCouplePolyPatch
|
||||||
const word& shadowRegionName,
|
const word& shadowRegionName,
|
||||||
const word& shadowPatchName,
|
const word& shadowPatchName,
|
||||||
const bool attached,
|
const bool attached,
|
||||||
const bool attachedWalls
|
const bool isWall
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
coupledPolyPatch(name, size, start, index, bm),
|
coupledPolyPatch(name, size, start, index, bm),
|
||||||
shadowRegionName_(shadowRegionName),
|
shadowRegionName_(shadowRegionName),
|
||||||
shadowPatchName_(shadowPatchName),
|
shadowPatchName_(shadowPatchName),
|
||||||
attached_(attached),
|
attached_(attached),
|
||||||
attachedWalls_(attachedWalls),
|
isWall_(isWall),
|
||||||
shadowIndex_(-1),
|
shadowIndex_(-1),
|
||||||
patchToPatchPtr_(NULL),
|
patchToPatchPtr_(NULL),
|
||||||
reconFaceCellCentresPtr_(NULL)
|
reconFaceCellCentresPtr_(NULL)
|
||||||
|
@ -200,7 +208,7 @@ Foam::regionCouplePolyPatch::regionCouplePolyPatch
|
||||||
shadowRegionName_(dict.lookup("shadowRegion")),
|
shadowRegionName_(dict.lookup("shadowRegion")),
|
||||||
shadowPatchName_(dict.lookup("shadowPatch")),
|
shadowPatchName_(dict.lookup("shadowPatch")),
|
||||||
attached_(dict.lookup("attached")),
|
attached_(dict.lookup("attached")),
|
||||||
attachedWalls_(dict.lookup("attachedWalls")),
|
isWall_(dict.lookup("isWall")),
|
||||||
shadowIndex_(-1),
|
shadowIndex_(-1),
|
||||||
patchToPatchPtr_(NULL),
|
patchToPatchPtr_(NULL),
|
||||||
reconFaceCellCentresPtr_(NULL)
|
reconFaceCellCentresPtr_(NULL)
|
||||||
|
@ -218,7 +226,7 @@ Foam::regionCouplePolyPatch::regionCouplePolyPatch
|
||||||
shadowRegionName_(pp.shadowRegionName_),
|
shadowRegionName_(pp.shadowRegionName_),
|
||||||
shadowPatchName_(pp.shadowPatchName_),
|
shadowPatchName_(pp.shadowPatchName_),
|
||||||
attached_(pp.attached_),
|
attached_(pp.attached_),
|
||||||
attachedWalls_(pp.attachedWalls_),
|
isWall_(pp.isWall_),
|
||||||
shadowIndex_(-1),
|
shadowIndex_(-1),
|
||||||
patchToPatchPtr_(NULL),
|
patchToPatchPtr_(NULL),
|
||||||
reconFaceCellCentresPtr_(NULL)
|
reconFaceCellCentresPtr_(NULL)
|
||||||
|
@ -239,7 +247,7 @@ Foam::regionCouplePolyPatch::regionCouplePolyPatch
|
||||||
shadowRegionName_(pp.shadowRegionName_),
|
shadowRegionName_(pp.shadowRegionName_),
|
||||||
shadowPatchName_(pp.shadowPatchName_),
|
shadowPatchName_(pp.shadowPatchName_),
|
||||||
attached_(pp.attached_),
|
attached_(pp.attached_),
|
||||||
attachedWalls_(pp.attachedWalls_),
|
isWall_(pp.isWall_),
|
||||||
shadowIndex_(-1),
|
shadowIndex_(-1),
|
||||||
patchToPatchPtr_(NULL),
|
patchToPatchPtr_(NULL),
|
||||||
reconFaceCellCentresPtr_(NULL)
|
reconFaceCellCentresPtr_(NULL)
|
||||||
|
@ -278,7 +286,11 @@ void Foam::regionCouplePolyPatch::attach() const
|
||||||
{
|
{
|
||||||
attached_ = true;
|
attached_ = true;
|
||||||
shadow().attach();
|
shadow().attach();
|
||||||
clearOut();
|
|
||||||
|
// Patch-to-patch interpolation does not need to be cleared,
|
||||||
|
// only face/cell centres and interpolation factors
|
||||||
|
// HJ, 6/Jun/2011
|
||||||
|
clearGeom();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,7 +301,11 @@ void Foam::regionCouplePolyPatch::detach() const
|
||||||
{
|
{
|
||||||
attached_ = false;
|
attached_ = false;
|
||||||
shadow().detach();
|
shadow().detach();
|
||||||
clearOut();
|
|
||||||
|
// Patch-to-patch interpolation does not need to be cleared,
|
||||||
|
// only face/cell centres and interpolation factors
|
||||||
|
// HJ, 6/Jun/2011
|
||||||
|
clearGeom();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -336,6 +352,18 @@ Foam::regionCouplePolyPatch::reconFaceCellCentres() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::regionCouplePolyPatch::initAddressing()
|
||||||
|
{
|
||||||
|
polyPatch::initAddressing();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::regionCouplePolyPatch::calcAddressing()
|
||||||
|
{
|
||||||
|
polyPatch::calcAddressing();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::regionCouplePolyPatch::initGeometry()
|
void Foam::regionCouplePolyPatch::initGeometry()
|
||||||
{
|
{
|
||||||
polyPatch::initGeometry();
|
polyPatch::initGeometry();
|
||||||
|
@ -344,6 +372,7 @@ void Foam::regionCouplePolyPatch::initGeometry()
|
||||||
|
|
||||||
void Foam::regionCouplePolyPatch::calcGeometry()
|
void Foam::regionCouplePolyPatch::calcGeometry()
|
||||||
{
|
{
|
||||||
|
polyPatch::calcGeometry();
|
||||||
// Reconstruct the cell face centres
|
// Reconstruct the cell face centres
|
||||||
// reconFaceCellCentres();
|
// reconFaceCellCentres();
|
||||||
}
|
}
|
||||||
|
@ -432,6 +461,8 @@ void Foam::regionCouplePolyPatch::write(Ostream& os) const
|
||||||
<< shadowPatchName_ << token::END_STATEMENT << nl;
|
<< shadowPatchName_ << token::END_STATEMENT << nl;
|
||||||
os.writeKeyword("attached")
|
os.writeKeyword("attached")
|
||||||
<< attached_ << token::END_STATEMENT << nl;
|
<< attached_ << token::END_STATEMENT << nl;
|
||||||
|
os.writeKeyword("isWall")
|
||||||
|
<< isWall_ << token::END_STATEMENT << nl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ class regionCouplePolyPatch
|
||||||
mutable Switch attached_;
|
mutable Switch attached_;
|
||||||
|
|
||||||
//- Are the region attached walls
|
//- Are the region attached walls
|
||||||
mutable Switch attachedWalls_;
|
Switch isWall_;
|
||||||
|
|
||||||
//- Shadow patch index. Delayed evaluation for construction
|
//- Shadow patch index. Delayed evaluation for construction
|
||||||
mutable label shadowIndex_;
|
mutable label shadowIndex_;
|
||||||
|
@ -93,6 +93,12 @@ protected:
|
||||||
|
|
||||||
// Protected Member functions
|
// Protected Member functions
|
||||||
|
|
||||||
|
//- Initialise the calculation of the patch addressing
|
||||||
|
virtual void initAddressing();
|
||||||
|
|
||||||
|
//- Calculate the patch addressing
|
||||||
|
virtual void calcAddressing();
|
||||||
|
|
||||||
//- Initialise the calculation of the patch geometry
|
//- Initialise the calculation of the patch geometry
|
||||||
virtual void initGeometry();
|
virtual void initGeometry();
|
||||||
|
|
||||||
|
@ -121,9 +127,13 @@ protected:
|
||||||
//- Calculate reconstructed cell centres
|
//- Calculate reconstructed cell centres
|
||||||
void calcReconFaceCellCentres() const;
|
void calcReconFaceCellCentres() const;
|
||||||
|
|
||||||
|
//- Clear geometry
|
||||||
|
void clearGeom() const;
|
||||||
|
|
||||||
//- Clear out
|
//- Clear out
|
||||||
void clearOut() const;
|
void clearOut() const;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//- Runtime type information
|
//- Runtime type information
|
||||||
|
@ -237,10 +247,10 @@ public:
|
||||||
return attached_;
|
return attached_;
|
||||||
}
|
}
|
||||||
|
|
||||||
//AJ: read from dictionary if coupled patch is also a wall
|
// Return true if patch is considered a wall
|
||||||
bool isWall() const
|
bool isWall() const
|
||||||
{
|
{
|
||||||
return attachedWalls_;
|
return isWall_;
|
||||||
}
|
}
|
||||||
|
|
||||||
//- Attach regions
|
//- Attach regions
|
||||||
|
|
|
@ -115,6 +115,14 @@ protected:
|
||||||
// The polyPatch geometry initialisation is called by polyBoundaryMesh
|
// The polyPatch geometry initialisation is called by polyBoundaryMesh
|
||||||
friend class polyBoundaryMesh;
|
friend class polyBoundaryMesh;
|
||||||
|
|
||||||
|
//- Initialise the calculation of the patch addressing
|
||||||
|
virtual void initAddressing()
|
||||||
|
{}
|
||||||
|
|
||||||
|
//- Calculate the patch addressing
|
||||||
|
virtual void calcAddressing()
|
||||||
|
{}
|
||||||
|
|
||||||
//- Initialise the calculation of the patch geometry
|
//- Initialise the calculation of the patch geometry
|
||||||
virtual void initGeometry()
|
virtual void initGeometry()
|
||||||
{}
|
{}
|
||||||
|
|
|
@ -119,7 +119,7 @@ public:
|
||||||
const treeBoundBox& cubeBb
|
const treeBoundBox& cubeBb
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Does triangle intersect plane. Return bool and set intersection segment.
|
//- Does triangle intersect plane. Return bool and set intersection segment
|
||||||
static bool intersect
|
static bool intersect
|
||||||
(
|
(
|
||||||
const point& va0,
|
const point& va0,
|
||||||
|
@ -133,7 +133,7 @@ public:
|
||||||
point& pInter1
|
point& pInter1
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Do triangles intersect. Return bool and set intersection segment.
|
//- Do triangles intersect. Return bool and set intersection segment
|
||||||
static bool intersect
|
static bool intersect
|
||||||
(
|
(
|
||||||
const point& va0,
|
const point& va0,
|
|
@ -203,7 +203,7 @@ void Foam::mixerGgiFvMesh::calcMovingMasks() const
|
||||||
forAll (staticPatches, patchI)
|
forAll (staticPatches, patchI)
|
||||||
{
|
{
|
||||||
const label staticSliderID =
|
const label staticSliderID =
|
||||||
boundaryMesh().findPatchID(movingPatches[patchI]);
|
boundaryMesh().findPatchID(staticPatches[patchI]);
|
||||||
|
|
||||||
if (staticSliderID < 0)
|
if (staticSliderID < 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1764,7 +1764,9 @@ void Foam::slidingInterface::coupleInterface(polyTopoChange& ref) const
|
||||||
"polyTopoChange& ref) const"
|
"polyTopoChange& ref) const"
|
||||||
) << "Face " << curFaceID << " reduced to less than "
|
) << "Face " << curFaceID << " reduced to less than "
|
||||||
<< "3 points. Topological/cutting error B." << nl
|
<< "3 points. Topological/cutting error B." << nl
|
||||||
<< "Old face: " << oldFace << " new face: " << newFaceLabels
|
<< "Old face: " << oldFace << " new face: "
|
||||||
|
<< newFaceLabels << nl
|
||||||
|
<< "old points: " << oldFace.points(points)
|
||||||
<< abort(FatalError);
|
<< abort(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ SRFVelocityFvPatchVectorField::SRFVelocityFvPatchVectorField
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
fixedValueFvPatchVectorField(p, iF),
|
fixedValueFvPatchVectorField(p, iF),
|
||||||
relative_(0),
|
relative_(false),
|
||||||
inletValue_(p.size(), vector::zero)
|
inletValue_(p.size(), vector::zero)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@ Description
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
if (mesh.moving())
|
||||||
{
|
{
|
||||||
volScalarField contErr = fvc::div(phi + fvc::meshPhi(U));
|
volScalarField contErr = fvc::div(phi + fvc::meshPhi(U));
|
||||||
|
|
||||||
|
@ -47,5 +48,10 @@ Description
|
||||||
<< ", cumulative = " << cumulativeContErr
|
<< ", cumulative = " << cumulativeContErr
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
# include "continuityErrs.H"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|
|
@ -53,4 +53,5 @@ else
|
||||||
# include "continuityErrs.H"
|
# include "continuityErrs.H"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|
|
@ -30,7 +30,6 @@ License
|
||||||
#include "volFields.H"
|
#include "volFields.H"
|
||||||
#include "surfaceFields.H"
|
#include "surfaceFields.H"
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::totalPressureFvPatchScalarField::totalPressureFvPatchScalarField
|
Foam::totalPressureFvPatchScalarField::totalPressureFvPatchScalarField
|
||||||
|
|
|
@ -16,31 +16,11 @@ primitiveMeshGeometry/primitiveMeshGeometry.C
|
||||||
|
|
||||||
meshSearch/meshSearch.C
|
meshSearch/meshSearch.C
|
||||||
|
|
||||||
meshTools/meshTools.C
|
|
||||||
|
|
||||||
PointEdgeWave/PointEdgeWaveName.C
|
PointEdgeWave/PointEdgeWaveName.C
|
||||||
PointEdgeWave/pointEdgePoint.C
|
PointEdgeWave/pointEdgePoint.C
|
||||||
|
|
||||||
regionSplit/regionSplit.C
|
regionSplit/regionSplit.C
|
||||||
|
|
||||||
octree/octreeName.C
|
|
||||||
octree/octreeDataPoint.C
|
|
||||||
octree/octreeDataPointTreeLeaf.C
|
|
||||||
octree/octreeDataEdges.C
|
|
||||||
octree/octreeDataCell.C
|
|
||||||
octree/octreeDataFace.C
|
|
||||||
octree/treeBoundBox.C
|
|
||||||
octree/treeNodeName.C
|
|
||||||
octree/treeLeafName.C
|
|
||||||
octree/pointIndexHitIOList.C
|
|
||||||
|
|
||||||
indexedOctree/indexedOctreeName.C
|
|
||||||
indexedOctree/treeDataCell.C
|
|
||||||
indexedOctree/treeDataEdge.C
|
|
||||||
indexedOctree/treeDataFace.C
|
|
||||||
indexedOctree/treeDataPoint.C
|
|
||||||
indexedOctree/treeDataTriSurface.C
|
|
||||||
|
|
||||||
searchableSurface = searchableSurface
|
searchableSurface = searchableSurface
|
||||||
$(searchableSurface)/distributedTriSurfaceMesh.C
|
$(searchableSurface)/distributedTriSurfaceMesh.C
|
||||||
$(searchableSurface)/searchableBox.C
|
$(searchableSurface)/searchableBox.C
|
||||||
|
@ -127,7 +107,6 @@ $(intersectedSurface)/edgeSurface.C
|
||||||
triSurface/triSurfaceSearch/triSurfaceSearch.C
|
triSurface/triSurfaceSearch/triSurfaceSearch.C
|
||||||
triSurface/octreeData/octreeDataTriSurface.C
|
triSurface/octreeData/octreeDataTriSurface.C
|
||||||
triSurface/octreeData/octreeDataTriSurfaceTreeLeaf.C
|
triSurface/octreeData/octreeDataTriSurfaceTreeLeaf.C
|
||||||
triSurface/triangleFuncs/triangleFuncs.C
|
|
||||||
triSurface/surfaceFeatures/surfaceFeatures.C
|
triSurface/surfaceFeatures/surfaceFeatures.C
|
||||||
triSurface/triSurfaceTools/triSurfaceTools.C
|
triSurface/triSurfaceTools/triSurfaceTools.C
|
||||||
triSurface/triSurfaceTools/geompack/geompack.C
|
triSurface/triSurfaceTools/geompack/geompack.C
|
||||||
|
|
|
@ -46,6 +46,7 @@ SourceFiles
|
||||||
#include "objectRegistry.H"
|
#include "objectRegistry.H"
|
||||||
#include "indexedOctree.H"
|
#include "indexedOctree.H"
|
||||||
#include "treeDataTriSurface.H"
|
#include "treeDataTriSurface.H"
|
||||||
|
#include "octreeDataTriSurfaceTreeLeaf.H"
|
||||||
#include "treeDataEdge.H"
|
#include "treeDataEdge.H"
|
||||||
#include "EdgeMap.H"
|
#include "EdgeMap.H"
|
||||||
|
|
||||||
|
|
|
@ -129,7 +129,7 @@ Foam::rotatedBoxToCell::rotatedBoxToCell
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
topoSetSource(mesh),
|
topoSetSource(mesh),
|
||||||
origin_(origin_),
|
origin_(origin),
|
||||||
i_(i),
|
i_(i),
|
||||||
j_(j),
|
j_(j),
|
||||||
k_(k)
|
k_(k)
|
||||||
|
|
|
@ -73,6 +73,7 @@ class triSurfaceTools
|
||||||
RED,
|
RED,
|
||||||
GREEN
|
GREEN
|
||||||
};
|
};
|
||||||
|
|
||||||
static void calcRefineStatus
|
static void calcRefineStatus
|
||||||
(
|
(
|
||||||
const triSurface& surf,
|
const triSurface& surf,
|
||||||
|
@ -118,8 +119,8 @@ class triSurfaceTools
|
||||||
label edgeI
|
label edgeI
|
||||||
);
|
);
|
||||||
|
|
||||||
// Return value of faceUsed for faces using vertI (local numbering).
|
// Return value of faceUsed for faces using vertI (local numbering)
|
||||||
// Used internally.
|
// Used internally
|
||||||
static label vertexUsesFace
|
static label vertexUsesFace
|
||||||
(
|
(
|
||||||
const triSurface& surf,
|
const triSurface& surf,
|
||||||
|
|
|
@ -1,2 +1,6 @@
|
||||||
EXE_INC = \
|
EXE_INC = \
|
||||||
|
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||||
-DCELL_DECOMP
|
-DCELL_DECOMP
|
||||||
|
|
||||||
|
EXE_LIBS = \
|
||||||
|
-lmeshTools
|
||||||
|
|
|
@ -1 +1,6 @@
|
||||||
EXE_INC = -DFACE_DECOMP
|
EXE_INC = \
|
||||||
|
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||||
|
-DFACE_DECOMP
|
||||||
|
|
||||||
|
EXE_LIBS = \
|
||||||
|
-lmeshTools
|
||||||
|
|
|
@ -7,6 +7,7 @@ meshTriangulation/meshTriangulation.C
|
||||||
triSurface/triSurface.C
|
triSurface/triSurface.C
|
||||||
triSurface/triSurfaceAddressing.C
|
triSurface/triSurfaceAddressing.C
|
||||||
triSurface/stitchTriangles.C
|
triSurface/stitchTriangles.C
|
||||||
|
triSurface/treeDataTriSurface/treeDataTriSurface.C
|
||||||
|
|
||||||
interfaces = triSurface/interfaces
|
interfaces = triSurface/interfaces
|
||||||
$(interfaces)/STL/writeSTL.C
|
$(interfaces)/STL/writeSTL.C
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
EXE_INC = \
|
EXE_INC = \
|
||||||
|
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||||
-I$(WM_THIRD_PARTY_DIR)/zlib-1.2.3
|
-I$(WM_THIRD_PARTY_DIR)/zlib-1.2.3
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*--------------------------------*- C++ -*----------------------------------*\
|
/*--------------------------------*- C++ -*----------------------------------*\
|
||||||
| ========= | |
|
| ========= | |
|
||||||
| \\ / F ield | OpenFOAM Extend Project: Open Source CFD |
|
| \\ / F ield | OpenFOAM Extend Project: Open source CFD |
|
||||||
| \\ / O peration | Version: 1.6-ext |
|
| \\ / O peration | Version: 1.6-ext |
|
||||||
| \\ / A nd | Web: www.extend-project.de |
|
| \\ / A nd | Web: www.extend-project.de |
|
||||||
| \\/ M anipulation | |
|
| \\/ M anipulation | |
|
||||||
|
@ -10,6 +10,7 @@ FoamFile
|
||||||
version 2.0;
|
version 2.0;
|
||||||
format ascii;
|
format ascii;
|
||||||
class polyBoundaryMesh;
|
class polyBoundaryMesh;
|
||||||
|
location "constant/polyMesh";
|
||||||
object boundary;
|
object boundary;
|
||||||
}
|
}
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
@ -22,21 +23,18 @@ inlet
|
||||||
nFaces 20;
|
nFaces 20;
|
||||||
startFace 1540;
|
startFace 1540;
|
||||||
}
|
}
|
||||||
|
|
||||||
outlet
|
outlet
|
||||||
{
|
{
|
||||||
type patch;
|
type patch;
|
||||||
nFaces 20;
|
nFaces 20;
|
||||||
startFace 1560;
|
startFace 1560;
|
||||||
}
|
}
|
||||||
|
|
||||||
fixedWalls
|
fixedWalls
|
||||||
{
|
{
|
||||||
type wall;
|
type wall;
|
||||||
nFaces 80;
|
nFaces 80;
|
||||||
startFace 1580;
|
startFace 1580;
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultFaces
|
defaultFaces
|
||||||
{
|
{
|
||||||
type empty;
|
type empty;
|
||||||
|
|
|
@ -39,6 +39,7 @@ right
|
||||||
shadowRegion solid;
|
shadowRegion solid;
|
||||||
shadowPatch left;
|
shadowPatch left;
|
||||||
attached on;
|
attached on;
|
||||||
|
isWall yes;
|
||||||
}
|
}
|
||||||
|
|
||||||
bottom
|
bottom
|
||||||
|
|
|
@ -32,6 +32,7 @@ left
|
||||||
shadowRegion region0;
|
shadowRegion region0;
|
||||||
shadowPatch right;
|
shadowPatch right;
|
||||||
attached on;
|
attached on;
|
||||||
|
isWall yes; // Not relevant
|
||||||
}
|
}
|
||||||
|
|
||||||
right
|
right
|
||||||
|
|
Reference in a new issue