Newer
Older
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
-------------------------------------------------------------------------------
Copyright (C) 2020-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
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 3 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, see <http://www.gnu.org/licenses/>.
Class
Foam::mappedPatchBase
Description
Determines a mapping between patch face centres and mesh cell or face
centres and processors they're on.
If constructed from dictionary:
// Optional world to sample (default is all)
//sampleWorld solidSim;
// Optional explicit coupling (requires functionObject to synchronise
// databases. Default is close coupling (bc to bc)
//sampleDatabase true;
// Region to sample (default is region0)
sampleRegion region0;
// What to sample:
// - nearestCell : sample cell containing point
// - nearestOnlyCell : nearest sample cell (even if not containing
// point)
// - nearestPatchFace : nearest face on selected patch
// - nearestPatchFaceAMI : nearest face on selected patch
- patches need not conform
- uses AMI interpolation
// - nearestFace : nearest boundary face on any patch
// - nearestPatchPoint : nearest patch point (for coupled points
// this might be any of the points so you have
// to guarantee the point data is synchronised
// beforehand)
sampleMode nearestCell;
// If sampleMode is nearestPatchFace : patch to find faces of
samplePatch movingWall;
// If sampleMode is nearestPatchFace : specify patchgroup to find
// samplePatch and sampleRegion (if not provided)
coupleGroup baffleGroup;
// How to supply offset (w.r.t. my patch face centres):
// - uniform : single offset vector
// - nonuniform : per-face offset vector
// - normal : using supplied distance and face normal
offsetMode uniform;
// According to offsetMode (see above) supply one of
// offset, offsets or distance
offset (1 0 0);
Note: if offsetMode is \c normal it uses outwards pointing normals. So
supply a negative distance if sampling inside the domain.
Note
Storage is not optimal. It temporary collects all (patch)face centres
on all processors to keep the addressing calculation simple.
SourceFiles
mappedPatchBase.C
\*---------------------------------------------------------------------------*/
#ifndef mappedPatchBase_H
#define mappedPatchBase_H
#include "pointField.H"
#include "Tuple2.H"
#include "pointIndexHit.H"
#include "AMIPatchToPatchInterpolation.H"
#include "coupleGroupIdentifier.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
class polyPatch;
class polyMesh;
class mapDistribute;
/*---------------------------------------------------------------------------*\
Class mappedPatchBase Declaration
\*---------------------------------------------------------------------------*/
class mappedPatchBase
{
public:
// Type enumerations
//- Mesh items to sample
enum sampleMode
{
NEARESTCELL, //!< nearest cell containing sample
NEARESTPATCHFACE, //!< nearest face on selected patch
NEARESTPATCHFACEAMI, //!< nearest patch face + AMI interpolation
NEARESTPATCHPOINT, //!< nearest point on selected patch
NEARESTFACE, //!< nearest face
NEARESTONLYCELL //!< nearest cell (even if not containing cell)
};
//- How to project face centres
enum offsetMode
{
UNIFORM, //!< single offset vector
NONUNIFORM, //!< per-face offset vector
NORMAL //!< use face normal + distance
static const Enum<sampleMode> sampleModeNames_;
static const Enum<offsetMode> offsetModeNames_;
//- Helper class for finding nearest
// - point+local index
// - sqr(distance)
// - processor
Henry Weller
committed
typedef Tuple2<pointIndexHit, Tuple2<scalar, label>> nearInfo;
class nearestEqOp
{
public:
void operator()(nearInfo& x, const nearInfo& y) const
{
if (y.first().hit())
{
if (!x.first().hit())
{
x = y;
}
else if (y.second().first() < x.second().first())
{
x = y;
}
}
}
};
class maxProcEqOp
{
public:
void operator()(nearInfo& x, const nearInfo& y) const
{
if (y.first().hit())
{
if (!x.first().hit())
{
x = y;
}
else if (y.second().second() > x.second().second())
{
x = y;
}
}
}
};
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
//- nearest + world
// Used to only look at entries from same world
typedef Tuple2<nearInfo, label> nearInfoWorld;
class nearestWorldEqOp
{
public:
void operator()(nearInfoWorld& x, const nearInfoWorld& y) const
{
// Is there a hit and is it sampling the same world
const nearInfo& xi = x.first();
const nearInfo& yi = y.first();
if (yi.first().hit())
{
if (x.second() == y.second())
{
if (!xi.first().hit())
{
x = y;
}
else if (yi.second().first() < xi.second().first())
{
x = y;
}
}
}
}
};
// Protected Data
//- Patch to sample
const polyPatch& patch_;
//- World to sample
mutable word sampleWorld_;
//- Region to sample
mutable word sampleRegion_;
//- What to sample
const sampleMode mode_;
//- Patch (if in sampleMode NEARESTPATCH*)
mutable word samplePatch_;
//- PatchGroup (if in sampleMode NEARESTPATCH*)
const coupleGroupIdentifier coupleGroup_;
//- Empty or location of database
const autoPtr<fileName> sampleDatabasePtr_;
//- How to obtain samples
offsetMode offsetMode_;
//- Offset vector (uniform)
vector offset_;
//- Offset vector (nonuniform)
vectorField offsets_;
//- Offset distance (normal)
scalar distance_;
label communicator_;
mutable bool sameRegion_;
// Derived information
//- Communication schedule:
//
// - Cells/faces to sample per processor
// - Patch faces to receive per processor
// - schedule
mutable autoPtr<mapDistribute> mapPtr_;
// AMI interpolator (only for NEARESTPATCHFACEAMI)
//- Flag to indicate that slave patch should be reversed for AMI
const bool AMIReverse_;
//- Pointer to AMI interpolator
mutable autoPtr<AMIPatchToPatchInterpolation> AMIPtr_;
//- Pointer to projection surface employed by AMI interpolator
mutable autoPtr<searchableSurface> surfPtr_;
//- Dictionary storing projection surface description
dictionary surfDict_;
// Protected Member Functions
//- Add a world-world connection
bool addWorldConnection();
//- Get the communicator for the world-world connection
label getWorldCommunicator() const;
//- Lookup mesh
const polyMesh& lookupMesh(const word& region) const;
//- Lookup patch
const polyPatch& lookupPatch
(
const word& sampleRegion,
const word& samplePatch
) const;
//- Get the points from face-centre-decomposition face centres
//- and project them onto the face-diagonal-decomposition triangles.
tmp<pointField> facePoints(const polyPatch&) const;
//- Collect single list of samples and originating processor+face +
//- wanted world
void collectSamples
(
const label mySampleWorld, // My wanted sampling world
const pointField& facePoints,
pointField& samples, // Per sample: coordinate
labelList& patchFaceWorlds, // Per sample: wanted world
labelList& patchFaceProcs, // Per sample: originating proc
labelList& patchFaces, // Per sample: originating face
pointField& patchFc
) const;
//- Find (local) cells/faces containing samples
void findLocalSamples
(
const sampleMode mode,
const label sampleWorld, // my world as index
const word& sampleRegion,
const word& samplePatch,
const pointField& samplePoints,
List<nearInfoWorld>& nearest
) const;
//- Find (global) cells/faces containing samples
void findSamples
(
const sampleMode mode, // search mode
const label myWorldIndex, // my world (in index form)
const labelList& wantedWorlds,
const labelList& origProcs, // per sample the originating proc
labelList& sampleProcs, // processor containing sample
labelList& sampleIndices, // local index of cell/face
pointField& sampleLocations // actual representative location
) const;
//- Get the sample points given the face points
tmp<pointField> samplePoints(const pointField&) const;
//- Calculate mapping
void calcMapping() const;
//- Calculate AMI interpolator
void calcAMI() const;
// Database Handling
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
//- Read optional database name from dictionary
static autoPtr<fileName> readDatabase(const dictionary& dict);
//- Lookup (sub)objectRegistry by following names of sub registries.
//- Creates non-existing intermediate ones.
static const objectRegistry& subRegistry
(
const objectRegistry& obr,
const wordList& names,
const label index
);
//- Attempt to detect an IOField<Type> and write to dictionary
template<class Type>
static bool writeIOField
(
const regIOobject& obj,
dictionary& dict
);
//- Attempt to read an IOField<Type> and store on objectRegistry
template<class Type>
static bool constructIOField
(
const word& name,
token& tok,
Istream& is,
objectRegistry& obr
);
public:
//- Runtime type information
TypeName("mappedPatchBase");
// Constructors
//- Construct from patch
explicit mappedPatchBase(const polyPatch&);
//- Construct with offsetMode=non-uniform
mappedPatchBase
(
const polyPatch& pp,
const word& sampleRegion,
const sampleMode sampleMode,
const word& samplePatch,
const vectorField& offsets
);
//- Construct from offsetMode=uniform
mappedPatchBase
(
const polyPatch& pp,
const word& sampleRegion,
const sampleMode sampleMode,
const word& samplePatch,
const vector& uniformOffset
);
//- Construct from offsetMode=normal and distance
mappedPatchBase
(
const polyPatch& pp,
const word& sampleRegion,
const sampleMode sampleMode,
const word& samplePatch,
const scalar normalDistance
);
//- Construct from dictionary
mappedPatchBase(const polyPatch&, const dictionary&);
//- Construct from dictionary and (collocated) sample mode
// (only for nearestPatchFace, nearestPatchFaceAMI, nearestPatchPoint)
// Assumes zero offset.
mappedPatchBase(const polyPatch&, const sampleMode, const dictionary&);
//- Construct as copy, resetting patch
mappedPatchBase(const polyPatch&, const mappedPatchBase&);
//- Construct as copy, resetting patch, map original data
mappedPatchBase
(
const polyPatch&,
const mappedPatchBase&,
const labelUList& mapAddressing
);
//- Destructor
virtual ~mappedPatchBase();
// Member Functions
// Edit
void clearOut();
//- Change to normal offset with given distance
void setOffset(const scalar normalDist);
//- Change to uniform offset with value
void setOffset(const vector& uniformOffset);
//- Change to non-uniform offsets
void setOffset(const vectorField& offsets);
inline sampleMode mode() const noexcept;
inline const word& sampleWorld() const noexcept;
//- Region to sample
inline const word& sampleRegion() const;
//- Patch (only if NEARESTPATCHFACE)
inline const word& samplePatch() const;
//- PatchGroup (only if NEARESTPATCHFACE)
inline const word& coupleGroup() const;
//- Return size of mapped mesh/patch/boundary
inline label sampleSize() const;
//- Offset vector (from patch faces to destination mesh objects)
inline const vector& offset() const noexcept;
//- Offset vectors (from patch faces to destination mesh objects)
inline const vectorField& offsets() const noexcept;
//- Get the communicator (worldComm or world-to-world)
inline label getCommunicator() const;
//- Identical to getCommunicator()
//- Is sample world the local world?
inline bool sameWorld() const;
//- Is my world ordered before the sampleWorld?
inline bool masterWorld() const;
inline bool sameRegion() const noexcept;
//- Return reference to the parallel distribution map
inline const mapDistribute& map() const;
//- Return reference to the AMI interpolator
inline const AMIPatchToPatchInterpolation& AMI
(
const bool forceUpdate = false
) const;
//- Is it owner
inline bool owner() const;
//- Return a pointer to the AMI projection surface
const autoPtr<Foam::searchableSurface>& surfPtr() const;
//- Get the region mesh
const polyMesh& sampleMesh() const;
//- Get the patch on the region
const polyPatch& samplePolyPatch() const;
//- Get the sample points
tmp<pointField> samplePoints() const;
//- Get a point on the face given a face decomposition method:
// face-centre-tet : face centre. Returns index of face.
// face-planes : face centre. Returns index of face.
// face-diagonal : intersection of ray from cellcentre to
// facecentre with any of the triangles.
// Returns index (0..size-2) of triangle.
static pointIndexHit facePoint
(
const polyMesh&,
Henry
committed
const polyMesh::cellDecomposition
// For database storage
inline const fileName& sampleDatabasePath() const
{
return *sampleDatabasePtr_;
}
inline bool sampleDatabase() const
{
return bool(sampleDatabasePtr_);
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
}
//- Helper: return path to store data to be sent to processor i
static fileName sendPath(const fileName& root, const label proci);
virtual fileName sendPath(const label proci) const;
//- Helper: return path to store data to be received from
//- processor i
static fileName receivePath
(
const fileName& root,
const label proci
);
virtual fileName receivePath(const label proci) const;
//- Lookup (sub)objectRegistry from '/' separated path (relative to
//- objectRegistry). Creates non-existing intermediate ones.
static const objectRegistry& subRegistry
(
const objectRegistry& obr,
const fileName& path
);
//- Store an IOField on the objectRegistry relative to obr
template<class Type>
static void storeField
(
objectRegistry& obr,
const word& fieldName,
const Field<Type>& values
);
//- Convert objectRegistry contents into dictionary
static void writeDict
(
const objectRegistry& obr,
dictionary& dict
);
//- (recursively) construct and register IOFields from dictionary
static void readDict(const dictionary& d, objectRegistry& obr);
//- Wrapper around map/interpolate data distribution
template<class Type>
void distribute(List<Type>& lst) const;
//- Wrapper around map/interpolate data distribution with operation
template<class Type, class CombineOp>
void distribute(List<Type>& lst, const CombineOp& cop) const;
//- Wrapper around map/interpolate data distribution
template<class Type>
void reverseDistribute(List<Type>& lst) const;
//- Wrapper around map/interpolate data distribution with operation
template<class Type, class CombineOp>
void reverseDistribute(List<Type>& lst, const CombineOp& cop) const;
virtual void write(Ostream& os) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "mappedPatchBaseI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "mappedPatchBaseTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //