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_
116 nonInterpolatedFields_.insert(
"cellInterpolationWeight");
117 nonInterpolatedFields_.insert(
"cellTypes");
118 nonInterpolatedFields_.insert(
"maxMagWeight");
122 nonInterpolatedFields_.insert(
"cellDisplacement");
123 nonInterpolatedFields_.insert(
"grad(cellDisplacement)");
124 const word w(
"snGradCorr(cellDisplacement)");
125 const word d(
"((viscosity*faceDiffusivity)*magSf)");
126 nonInterpolatedFields_.insert(
"surfaceIntegrate(("+d+
"*"+w+
"))");
131 nonInterpolatedFields_.insert(
"cellMotionU");
132 nonInterpolatedFields_.insert(
"grad(cellMotionU)");
133 const word w(
"snGradCorr(cellMotionU)");
134 const word d(
"((viscosity*faceDiffusivity)*magSf)");
135 nonInterpolatedFields_.insert(
"surfaceIntegrate(("+d+
"*"+w+
"))");
163 auto& zoneID = *zoneIDPtr;
180 zoneID[celli] = label(volZoneID[celli]);
206 return nonInterpolatedFields_;
212 return nonInterpolatedFields_;
220 if (slots[i] >= mesh_.nCells())
231 const globalIndex& gi,
232 const polyMesh&
mesh,
278 cellCellCentres.setSize(cellCells.size());
282 label celli = selectedCells[i];
284 const cell& cFaces =
cells[celli];
286 pointList& stencilPoints = cellCellCentres[celli];
287 stencil.setSize(cFaces.size()+1);
288 stencilPoints.setSize(stencil.size());
292 if (isValidCell[celli])
294 stencil[compacti] = globalCellIDs[celli];
295 stencilPoints[compacti++] = cellCentres[celli];
301 label facei = cFaces[i];
303 label own = faceOwner[facei];
306 bool isValid =
false;
309 nbrCelli = nbrGlobalCellIDs[bFacei];
310 nbrCc = nbrCellCentres[bFacei];
311 isValid = nbrIsValidCell[bFacei];
317 nbrCelli = gi.toGlobal(own);
318 nbrCc = cellCentres[own];
319 isValid = isValidCell[own];
323 label nei = faceNeighbour[facei];
324 nbrCelli = gi.toGlobal(nei);
325 nbrCc = cellCentres[nei];
326 isValid = isValidCell[nei];
332 SubList<label> current(stencil, compacti);
333 if (!current.found(nbrCelli))
335 stencil[compacti] = nbrCelli;
336 stencilPoints[compacti++] = nbrCc;
340 stencil.setSize(compacti);
341 stencilPoints.setSize(compacti);
348 const scalar wantedFraction,
353 const cell& cFaces = mesh_.cells()[celli];
356 const label nbrFacei = cFaces[i];
357 if (fraction[nbrFacei] < wantedFraction)
359 fraction[nbrFacei] = wantedFraction;
360 isFront.set(nbrFacei);
372 const labelList& own = mesh_.faceOwner();
373 const labelList& nei = mesh_.faceNeighbour();
375 for (label facei = 0; facei < mesh_.nInternalFaces(); ++facei)
377 const label ownType = allCellTypes[own[facei]];
378 const label neiType = allCellTypes[nei[facei]];
381 (ownType == HOLE && neiType != HOLE)
382 || (ownType != HOLE && neiType == HOLE)
394 label facei = mesh_.nInternalFaces();
395 facei < mesh_.nFaces();
399 const label ownType = allCellTypes[own[facei]];
400 const label neiType = nbrCellTypes[facei-mesh_.nInternalFaces()];
404 (ownType == HOLE && neiType != HOLE)
405 || (ownType != HOLE && neiType == HOLE)
420 const fvBoundaryMesh& fvm = mesh_.boundary();
424 if (isA<oversetFvPatch>(fvm[patchi]))
426 const labelList& fc = fvm[patchi].faceCells();
429 const label celli = fc[i];
430 if (allCellTypes[celli] == INTERPOLATED)
435 isFront.set(fvm[patchi].start()+i);
445 const globalIndex& globalCells,
446 const scalar layerRelax,
453 const label holeLayers,
457 if (useLayer > holeLayers)
460 <<
" is larger than : " << holeLayers
467 <<
" can not be zero." 472 bitSet isFront(mesh_.nFaces());
475 DynamicList<labelList> dataSet;
477 DynamicList<scalarField> dAlllWeight;
479 DynamicList<scalar> daverageVolRatio;
482 DynamicList<label> dHoles;
489 for (label currLayer = 1; currLayer < holeLayers+1; ++currLayer)
494 setUpFront(allCellTypes, isFront);
496 labelList allCellTypesWork(allCellTypes);
498 bitSet isFrontWork(isFront);
499 label nCurrLayer = currLayer;
501 while (nCurrLayer > 1 &&
returnReduce(isFrontWork.any(), orOp<bool>()))
503 bitSet newIsFront(mesh_.nFaces());
504 forAll(isFrontWork, facei)
506 if (isFrontWork.test(facei))
508 const label own = mesh_.faceOwner()[facei];
510 if (allCellTypesWork[own] != HOLE)
512 allCellTypesWork[own] = HOLE;
513 newIsFront.set(mesh_.cells()[own]);
516 if (mesh_.isInternalFace(facei))
518 const label nei = mesh_.faceNeighbour()[facei];
519 if (allCellTypesWork[nei] != HOLE)
521 allCellTypesWork[nei] = HOLE;
522 newIsFront.set(mesh_.cells()[nei]);
529 isFrontWork.transfer(newIsFront);
535 if ((
debug & 2) && mesh_.time().writeTime())
537 tmp<volScalarField> tfld
542 "allCellTypesWork_Holes" +
name(currLayer),
551 setUpFrontOnOversetPatch(allCellTypes, isFront);
557 setUpFrontOnOversetPatch(allCellTypesWork, isFront);
558 setUpFront(allCellTypesWork, isFront);
569 if (isFront.test(facei))
571 fraction[facei] = 1.0;
576 bitSet nHoles(allCellTypes.size());
581 bitSet newIsFront(mesh_.nFaces());
586 if (isFront.test(facei))
588 const label own = mesh_.faceOwner()[facei];
590 if (allCellTypesWork[own] != HOLE)
592 if (allWeightWork[own] < fraction[facei])
596 if (allStencil[own].size())
598 nLayer[own] = currLayer;
600 allWeightWork[own] = fraction[facei];
601 allCellTypesWork[own] = INTERPOLATED;
603 const label donorId = compactStencil[own][0];
605 volRatio[own] = V[own]/compactCellVol[donorId];
610 fraction[facei]-layerRelax,
619 allWeightWork[own] = 0.0;
620 allCellTypesWork[own] = HOLE;
632 if (mesh_.isInternalFace(facei))
634 label nei = mesh_.faceNeighbour()[facei];
635 if (allCellTypesWork[nei] != HOLE)
637 if (allWeightWork[nei] < fraction[facei])
639 if (allStencil[nei].size())
641 nLayer[nei] = currLayer;
643 allWeightWork[nei] = fraction[facei];
644 allCellTypesWork[nei] = INTERPOLATED;
646 const label donorId =
647 compactStencil[nei][0];
650 V[nei]/compactCellVol[donorId];
655 fraction[facei]-layerRelax,
662 allWeightWork[nei] = 0.0;
663 allCellTypesWork[nei] = HOLE;
682 isFront.transfer(newIsFront);
683 fraction.transfer(newFraction);
686 if ((
debug & 2) && mesh_.time().writeTime())
688 tmp<volScalarField> tfld
693 "allCellTypesWork_Layers" +
name(currLayer),
700 dAlllWeight.append(allWeightWork);
701 dataSet.append(allCellTypesWork);
713 reduce(nCount, sumOp<label>());
715 const scalar aveVol =
mag(
gSum(volRatio));
717 daverageVolRatio.append(aveVol/nCount);
721 label nTotalHoles(nHoles.count());
722 reduce(nTotalHoles, sumOp<label>());
723 dHoles.append(nTotalHoles);
730 & (nTotalHoles > 2.0*dHoles[currLayer - 1])
738 if ((
debug & 2) && mesh_.time().writeTime())
740 tmp<volScalarField> tfld
750 averageVolRatio.
transfer(daverageVolRatio);
751 label minVolId =
findMin(averageVolRatio);
755 Info<<
nl <<
" Number of layers : " << averageVolRatio.size() <<
nl 756 <<
" Average volumetric ratio : " << averageVolRatio <<
nl 757 <<
" Number of holes cells : " << dHoles <<
nl 758 <<
" Using layer : " << useLayer <<
nl <<
endl;
763 minVolId = useLayer - 1;
766 allCellTypes.transfer(dataSet[minVolId]);
767 allWeight.transfer(dAlllWeight[minVolId]);
777 const InfoProxy<cellCellStencil>& iproxy
780 const auto&
e = *iproxy;
783 const labelUList& interpolationCells =
e.interpolationCells();
788 label nInvalidInterpolated = 0;
792 forAll(interpolationCells, i)
794 label celli = interpolationCells[i];
795 const labelList& slots = cellStencil[celli];
799 nInvalidInterpolated++;
802 bool hasLocal =
false;
803 bool hasRemote =
false;
833 reduce(nLocal, sumOp<label>());
834 reduce(nMixed, sumOp<label>());
835 reduce(nRemote, sumOp<label>());
836 reduce(nInvalidInterpolated, sumOp<label>());
838 os <<
"Overset analysis : nCells : " 844 <<
" (interpolated from local:" << nLocal
845 <<
" mixed local/remote:" << nMixed
846 <<
" remote:" << nRemote
847 <<
" special:" << nInvalidInterpolated <<
")" <<
nl static void listCombineGather(UList< T > &values, const CombineOp &cop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Combines List elements.
List< scalar > scalarList
List of scalar.
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.
Ostream & indent(Ostream &os)
Indent stream.
List< cell > cellList
List of cell.
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)
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.
static tmp< volScalarField > createField(const fvMesh &mesh, const scalar val)
bool store()
Register object with its registry and transfer ownership to the registry.
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()
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.
List< labelList > labelListList
List of labelList.
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)
void suppressMotionFields()
Helper: populate nonInterpolatedFields_ with motion solver.
vectorField pointField
pointField is a vectorField.
const dimensionedScalar e
Elementary charge.
IOList< label > labelIOList
IO for a List of label.
Type gSum(const FieldField< Field, Type > &f)
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
word findInstance(const fileName &directory, const word &name=word::null, IOobjectOption::readOption rOpt=IOobjectOption::MUST_READ, const word &stopInstance=word::null, const bool constant_fallback=true) const
Return time instance (location) of directory containing the file name (eg, used in reading mesh data)...
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i), works like std::iota() but returning a...
A class for handling words, derived from Foam::string.
Type * getObjectPtr(const word &name, const bool recursive=false) const
Return non-const pointer to the object of the given Type, using a const-cast to have it behave like a...
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
#define DebugInFunction
Report an information message using Foam::Info.
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.
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.
messageStream Info
Information stream (stdout output on master, null elsewhere)
List< point > pointList
List of point.
void walkFront(const globalIndex &globalCells, const scalar 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.
List< label > labelList
A List of labels.
List< pointList > pointListList
List of pointList.
Ostream & incrIndent(Ostream &os)
Increment the indent level.
#define FatalIOErrorInLookup(ios, lookupTag, lookupName, lookupTable)
Report an error message using Foam::FatalIOError.
Request registration (bool: true)
List< bool > boolList
A List of bools.
Do not request registration (bool: false)
void reduce(T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Reduce inplace (cf. MPI Allreduce) using linear/tree communication schedule.
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)