49 { cellType::CALCULATED,
"calculated" },
50 { cellType::INTERPOLATED,
"interpolated" },
51 { cellType::HOLE,
"hole" },
52 { cellType::SPECIAL,
"special" },
53 { cellType::POROUS,
"porous" },
59 Foam::cellCellStencil::cellCellStencil(
const fvMesh&
mesh)
62 nonInterpolatedFields_({
"zoneID"})
69 const dictionary&
dict,
75 const word stencilType(
dict.get<word>(
"method"));
77 auto* ctorPtr = meshConstructorTable(stencilType);
86 *meshConstructorTablePtr_
147 zoneID[celli] = label(volZoneID[celli]);
174 return nonInterpolatedFields_;
180 return nonInterpolatedFields_;
188 if (slots[i] >= mesh_.nCells())
199 const globalIndex& gi,
200 const polyMesh&
mesh,
246 cellCellCentres.setSize(cellCells.size());
250 label celli = selectedCells[i];
252 const cell& cFaces =
cells[celli];
254 pointList& stencilPoints = cellCellCentres[celli];
255 stencil.setSize(cFaces.size()+1);
256 stencilPoints.setSize(stencil.size());
260 if (isValidCell[celli])
262 stencil[compacti] = globalCellIDs[celli];
263 stencilPoints[compacti++] = cellCentres[celli];
269 label facei = cFaces[i];
271 label own = faceOwner[facei];
274 bool isValid =
false;
277 nbrCelli = nbrGlobalCellIDs[bFacei];
278 nbrCc = nbrCellCentres[bFacei];
279 isValid = nbrIsValidCell[bFacei];
285 nbrCelli = gi.toGlobal(own);
286 nbrCc = cellCentres[own];
287 isValid = isValidCell[own];
291 label nei = faceNeighbour[facei];
292 nbrCelli = gi.toGlobal(nei);
293 nbrCc = cellCentres[nei];
294 isValid = isValidCell[nei];
300 SubList<label> current(stencil, compacti);
301 if (!current.found(nbrCelli))
303 stencil[compacti] = nbrCelli;
304 stencilPoints[compacti++] = nbrCc;
308 stencil.setSize(compacti);
309 stencilPoints.setSize(compacti);
316 const scalar wantedFraction,
321 const cell& cFaces = mesh_.cells()[celli];
324 const label nbrFacei = cFaces[i];
325 if (fraction[nbrFacei] < wantedFraction)
327 fraction[nbrFacei] = wantedFraction;
328 isFront.set(nbrFacei);
340 const labelList& own = mesh_.faceOwner();
341 const labelList& nei = mesh_.faceNeighbour();
343 for (label facei = 0; facei < mesh_.nInternalFaces(); ++facei)
345 const label ownType = allCellTypes[own[facei]];
346 const label neiType = allCellTypes[nei[facei]];
349 (ownType == HOLE && neiType != HOLE)
350 || (ownType != HOLE && neiType == HOLE)
362 label facei = mesh_.nInternalFaces();
363 facei < mesh_.nFaces();
367 const label ownType = allCellTypes[own[facei]];
368 const label neiType = nbrCellTypes[facei-mesh_.nInternalFaces()];
372 (ownType == HOLE && neiType != HOLE)
373 || (ownType != HOLE && neiType == HOLE)
388 const fvBoundaryMesh& fvm = mesh_.boundary();
392 if (isA<oversetFvPatch>(fvm[patchi]))
394 const labelList& fc = fvm[patchi].faceCells();
397 const label celli = fc[i];
398 if (allCellTypes[celli] == INTERPOLATED)
403 isFront.set(fvm[patchi].start()+i);
413 const globalIndex& globalCells,
414 const label layerRelax,
421 const label holeLayers,
425 if (useLayer > holeLayers)
428 <<
" is larger than : " << holeLayers
435 <<
" can not be zero." 440 bitSet isFront(mesh_.nFaces());
443 DynamicList<labelList> dataSet;
445 DynamicList<scalarField> dAlllWeight;
447 DynamicList<scalar> daverageVolRatio;
450 DynamicList<label> dHoles;
457 for (label currLayer = 1; currLayer < holeLayers+1; ++currLayer)
462 setUpFront(allCellTypes, isFront);
464 labelList allCellTypesWork(allCellTypes);
466 bitSet isFrontWork(isFront);
467 label nCurrLayer = currLayer;
469 while (nCurrLayer > 1 &&
returnReduce(isFrontWork.any(), orOp<bool>()))
471 bitSet newIsFront(mesh_.nFaces());
472 forAll(isFrontWork, facei)
474 if (isFrontWork.test(facei))
476 const label own = mesh_.faceOwner()[facei];
478 if (allCellTypesWork[own] != HOLE)
480 allCellTypesWork[own] = HOLE;
481 newIsFront.set(mesh_.cells()[own]);
484 if (mesh_.isInternalFace(facei))
486 const label nei = mesh_.faceNeighbour()[facei];
487 if (allCellTypesWork[nei] != HOLE)
489 allCellTypesWork[nei] = HOLE;
490 newIsFront.set(mesh_.cells()[nei]);
497 isFrontWork.transfer(newIsFront);
503 if ((
debug&2) && (mesh_.time().outputTime()))
505 tmp<volScalarField> tfld
510 "allCellTypesWork_Holes" +
name(currLayer),
519 setUpFrontOnOversetPatch(allCellTypes, isFront);
525 setUpFrontOnOversetPatch(allCellTypesWork, isFront);
526 setUpFront(allCellTypesWork, isFront);
537 if (isFront.test(facei))
539 fraction[facei] = 1.0;
544 bitSet nHoles(allCellTypes.size());
549 bitSet newIsFront(mesh_.nFaces());
554 if (isFront.test(facei))
556 const label own = mesh_.faceOwner()[facei];
558 if (allCellTypesWork[own] != HOLE)
560 if (allWeightWork[own] < fraction[facei])
564 if (allStencil[own].size())
566 nLayer[own] = currLayer;
568 allWeightWork[own] = fraction[facei];
569 allCellTypesWork[own] = INTERPOLATED;
571 const label donorId = compactStencil[own][0];
573 volRatio[own] = V[own]/compactCellVol[donorId];
578 fraction[facei]-layerRelax,
587 allWeightWork[own] = 0.0;
588 allCellTypesWork[own] = HOLE;
600 if (mesh_.isInternalFace(facei))
602 label nei = mesh_.faceNeighbour()[facei];
603 if (allCellTypesWork[nei] != HOLE)
605 if (allWeightWork[nei] < fraction[facei])
607 if (allStencil[nei].size())
609 nLayer[nei] = currLayer;
611 allWeightWork[nei] = fraction[facei];
612 allCellTypesWork[nei] = INTERPOLATED;
614 const label donorId = compactStencil[nei][0];
616 volRatio[nei] = V[nei]/compactCellVol[donorId];
621 fraction[facei]-layerRelax,
628 allWeightWork[nei] = 0.0;
629 allCellTypesWork[nei] = HOLE;
648 isFront.transfer(newIsFront);
649 fraction.transfer(newFraction);
652 if ((
debug&2) && (mesh_.time().outputTime()))
654 tmp<volScalarField> tfld
659 "allCellTypesWork_Layers" +
name(currLayer),
666 dAlllWeight.append(allWeightWork);
667 dataSet.append(allCellTypesWork);
679 reduce(nCount, sumOp<label>());
681 const scalar aveVol =
mag(
gSum(volRatio));
683 daverageVolRatio.append(aveVol/nCount);
687 label nTotalHoles(nHoles.count());
688 reduce(nTotalHoles, sumOp<label>());
689 dHoles.append(nTotalHoles);
696 & (nTotalHoles > 2.0*dHoles[currLayer - 1])
704 if ((
debug&2) && (mesh_.time().outputTime()))
706 tmp<volScalarField> tfld
708 createField(mesh_,
"walkFront_layers", nLayer)
716 averageVolRatio.
transfer(daverageVolRatio);
717 label minVolId =
findMin(averageVolRatio);
721 Info<<
nl <<
" Number of layers : " << averageVolRatio.size() <<
nl 722 <<
" Average volumetric ratio : " << averageVolRatio <<
nl 723 <<
" Number of holes cells : " << dHoles <<
nl 724 <<
" Using layer : " << useLayer <<
nl <<
endl;
729 minVolId = useLayer - 1;
732 allCellTypes.transfer(dataSet[minVolId]);
733 allWeight.transfer(dAlllWeight[minVolId]);
743 const InfoProxy<cellCellStencil>& ic
746 const cellCellStencil&
e = ic.t_;
749 const labelUList& interpolationCells =
e.interpolationCells();
754 label nInvalidInterpolated = 0;
758 forAll(interpolationCells, i)
760 label celli = interpolationCells[i];
761 const labelList& slots = cellStencil[celli];
765 nInvalidInterpolated++;
768 bool hasLocal =
false;
769 bool hasRemote =
false;
799 reduce(nLocal, sumOp<label>());
800 reduce(nMixed, sumOp<label>());
801 reduce(nRemote, sumOp<label>());
802 reduce(nInvalidInterpolated, sumOp<label>());
804 Info<<
"Overset analysis : nCells : " 810 <<
" (interpolated from local:" << nLocal
811 <<
" mixed local/remote:" << nMixed
812 <<
" remote:" << nRemote
813 <<
" special:" << nInvalidInterpolated <<
")" <<
nl List< labelList > labelListList
A List of labelList.
virtual const wordHashSet & nonInterpolatedFields() const
Return the names of any (stencil or mesh specific) fields that.
Field< label > labelField
Specialisation of Field<T> for label.
void size(const label n)
Older name for setAddressableSize.
const Type & lookupObject(const word &name, const bool recursive=false) const
Lookup and return const reference to the object of the given Type. Fatal if not found or the wrong ty...
void walkFront(const globalIndex &globalCells, const label layerRelax, const labelListList &allStencil, labelList &allCellTypes, scalarField &allWeight, const scalarList &compactCellVol, const labelListList &compactStencil, const labelList &zoneID, const label holeLayers, const label useLayer) const
Surround holes with layer(s) of interpolated cells.
Ostream & indent(Ostream &os)
Indent stream.
errorManipArg< error, int > exit(error &err, const int errNo=1)
const fileName & facesInstance() const
Return the current instance directory for faces.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
word findInstance(const fileName &dir, const word &name=word::null, IOobjectOption::readOption rOpt=IOobjectOption::MUST_READ, const word &stopInstance=word::null) const
Return time instance (location) of dir that contains the file name (eg, used in reading mesh data)...
void transfer(List< T > &list)
Transfer the contents of the argument List into this list and annul the argument list.
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
virtual const labelList & faceNeighbour() const
Return face neighbour.
void seedCell(const label cellI, const scalar wantedFraction, bitSet &isFront, scalarField &fraction) const
Seed faces of cell with wantedFraction (if higher than current)
std::enable_if< std::is_same< bool, TypeT >::value, bool >::type set(const label i, bool val=true)
A bitSet::set() method for a list of bool.
constexpr char nl
The newline '\n' character (0x0a)
static autoPtr< cellCellStencil > New(const fvMesh &, const dictionary &dict, const bool update=true)
New function which constructs and returns pointer to a.
void setUpFront(const labelList &allCellTypes, bitSet &isFront) const
Set up front using allCellTypes.
static word meshSubDir
Return the mesh sub-directory name (usually "polyMesh")
Ostream & endl(Ostream &os)
Add newline and flush stream.
const cellList & cells() const
virtual ~cellCellStencil()
Destructor.
virtual const fileName & dbDir() const
Override the objectRegistry dbDir for a single-region case.
Ignore writing from objectRegistry::writeObject()
List< point > pointList
A List of points.
const Time & time() const
Return the top-level database.
T returnReduce(const T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Perform reduction on a copy, using specified binary operation.
Macros for easy insertion into run-time selection tables.
UList< label > labelUList
A UList of labels.
#define forAll(list, i)
Loop across all elements in list.
bool localStencil(const labelUList &) const
Helper: is stencil fully local.
void setUpFrontOnOversetPatch(const labelList &allCellTypes, bitSet &isFront) const
Set up front on overset patches.
GeometricField< scalar, fvPatchField, volMesh > volScalarField
label findMin(const ListType &input, label start=0)
Linear search for the index of the min element, similar to std::min_element but for lists and returns...
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of 'true' entries.
bool ends_with(char c) const
True if string ends with given character (cf. C++20)
static labelList count(const label size, const labelUList &lst)
Count occurrences (in parallel)
vectorField pointField
pointField is a vectorField.
const dimensionedScalar e
Elementary charge.
Type gSum(const FieldField< Field, Type > &f)
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i)
A class for handling words, derived from Foam::string.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
#define DebugInFunction
Report an information message using Foam::Info.
List< scalar > scalarList
A List of scalars.
virtual const labelList & faceOwner() const
Return face owner.
label nInternalFaces() const noexcept
Number of internal faces.
const vectorField & cellCentres() const
errorManip< error > abort(error &err)
const labelList & cellTypes
An Ostream is an abstract base class for all output systems (streams, files, token lists...
static word baseName(const word &name)
Helper: strip off trailing _0.
virtual bool update()=0
Update stencils. Return false if nothing changed.
List< pointList > pointListList
A List of pointList.
defineRunTimeSelectionTable(reactionRateFlameArea, dictionary)
int debug
Static debugging option.
OBJstream os(runTime.globalPath()/outputName)
defineTypeNameAndDebug(combustionModel, 0)
Ostream & decrIndent(Ostream &os)
Decrement the indent level.
static void globalCellCells(const globalIndex &gi, const polyMesh &mesh, const boolList &isValidDonor, const labelList &selectedCells, labelListList &cellCells, pointListList &cellCellCentres)
Helper: create cell-cell addressing in global numbering.
const labelIOList & zoneID() const
Helper: get reference to registered zoneID. Loads volScalarField.
vector point
Point is a vector.
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
label nCells() const noexcept
Number of mesh cells.
static const Enum< cellType > cellTypeNames_
Mode type names.
void reduce(const List< UPstream::commsStruct > &comms, T &value, const BinaryOp &bop, const int tag, const label comm)
Reduce inplace (cf. MPI Allreduce) using specified communication schedule.
messageStream Info
Information stream (stdout output on master, null elsewhere)
bool foundObject(const word &name, const bool recursive=false) const
Is the named Type found?
static void listCombineGather(const List< commsStruct > &comms, List< T > &values, const CombineOp &cop, const int tag, const label comm)
List< label > labelList
A List of labels.
Ostream & incrIndent(Ostream &os)
Increment the indent level.
#define FatalIOErrorInLookup(ios, lookupTag, lookupName, lookupTable)
Report an error message using Foam::FatalIOError.
List< bool > boolList
A List of bools.
List< cell > cellList
A List of cells.
IOList< label > labelIOList
Label container classes.
IOerror FatalIOError
Error stream (stdout output on all processes), with additional 'FOAM FATAL IO ERROR' header text and ...
static constexpr const zero Zero
Global zero (0)