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_
136 auto& zoneID = *zoneIDPtr;
153 zoneID[celli] = label(volZoneID[celli]);
179 return nonInterpolatedFields_;
185 return nonInterpolatedFields_;
193 if (slots[i] >= mesh_.nCells())
204 const globalIndex& gi,
205 const polyMesh&
mesh,
251 cellCellCentres.setSize(cellCells.size());
255 label celli = selectedCells[i];
257 const cell& cFaces =
cells[celli];
259 pointList& stencilPoints = cellCellCentres[celli];
260 stencil.setSize(cFaces.size()+1);
261 stencilPoints.setSize(stencil.size());
265 if (isValidCell[celli])
267 stencil[compacti] = globalCellIDs[celli];
268 stencilPoints[compacti++] = cellCentres[celli];
274 label facei = cFaces[i];
276 label own = faceOwner[facei];
279 bool isValid =
false;
282 nbrCelli = nbrGlobalCellIDs[bFacei];
283 nbrCc = nbrCellCentres[bFacei];
284 isValid = nbrIsValidCell[bFacei];
290 nbrCelli = gi.toGlobal(own);
291 nbrCc = cellCentres[own];
292 isValid = isValidCell[own];
296 label nei = faceNeighbour[facei];
297 nbrCelli = gi.toGlobal(nei);
298 nbrCc = cellCentres[nei];
299 isValid = isValidCell[nei];
305 SubList<label> current(stencil, compacti);
306 if (!current.found(nbrCelli))
308 stencil[compacti] = nbrCelli;
309 stencilPoints[compacti++] = nbrCc;
313 stencil.setSize(compacti);
314 stencilPoints.setSize(compacti);
321 const scalar wantedFraction,
326 const cell& cFaces = mesh_.cells()[celli];
329 const label nbrFacei = cFaces[i];
330 if (fraction[nbrFacei] < wantedFraction)
332 fraction[nbrFacei] = wantedFraction;
333 isFront.set(nbrFacei);
345 const labelList& own = mesh_.faceOwner();
346 const labelList& nei = mesh_.faceNeighbour();
348 for (label facei = 0; facei < mesh_.nInternalFaces(); ++facei)
350 const label ownType = allCellTypes[own[facei]];
351 const label neiType = allCellTypes[nei[facei]];
354 (ownType == HOLE && neiType != HOLE)
355 || (ownType != HOLE && neiType == HOLE)
367 label facei = mesh_.nInternalFaces();
368 facei < mesh_.nFaces();
372 const label ownType = allCellTypes[own[facei]];
373 const label neiType = nbrCellTypes[facei-mesh_.nInternalFaces()];
377 (ownType == HOLE && neiType != HOLE)
378 || (ownType != HOLE && neiType == HOLE)
393 const fvBoundaryMesh& fvm = mesh_.boundary();
397 if (isA<oversetFvPatch>(fvm[patchi]))
399 const labelList& fc = fvm[patchi].faceCells();
402 const label celli = fc[i];
403 if (allCellTypes[celli] == INTERPOLATED)
408 isFront.set(fvm[patchi].start()+i);
418 const globalIndex& globalCells,
419 const scalar layerRelax,
426 const label holeLayers,
430 if (useLayer > holeLayers)
433 <<
" is larger than : " << holeLayers
440 <<
" can not be zero." 445 bitSet isFront(mesh_.nFaces());
448 DynamicList<labelList> dataSet;
450 DynamicList<scalarField> dAlllWeight;
452 DynamicList<scalar> daverageVolRatio;
455 DynamicList<label> dHoles;
462 for (label currLayer = 1; currLayer < holeLayers+1; ++currLayer)
467 setUpFront(allCellTypes, isFront);
469 labelList allCellTypesWork(allCellTypes);
471 bitSet isFrontWork(isFront);
472 label nCurrLayer = currLayer;
474 while (nCurrLayer > 1 &&
returnReduce(isFrontWork.any(), orOp<bool>()))
476 bitSet newIsFront(mesh_.nFaces());
477 forAll(isFrontWork, facei)
479 if (isFrontWork.test(facei))
481 const label own = mesh_.faceOwner()[facei];
483 if (allCellTypesWork[own] != HOLE)
485 allCellTypesWork[own] = HOLE;
486 newIsFront.set(mesh_.cells()[own]);
489 if (mesh_.isInternalFace(facei))
491 const label nei = mesh_.faceNeighbour()[facei];
492 if (allCellTypesWork[nei] != HOLE)
494 allCellTypesWork[nei] = HOLE;
495 newIsFront.set(mesh_.cells()[nei]);
502 isFrontWork.transfer(newIsFront);
508 if ((
debug&2) && (mesh_.time().outputTime()))
510 tmp<volScalarField> tfld
515 "allCellTypesWork_Holes" +
name(currLayer),
524 setUpFrontOnOversetPatch(allCellTypes, isFront);
530 setUpFrontOnOversetPatch(allCellTypesWork, isFront);
531 setUpFront(allCellTypesWork, isFront);
542 if (isFront.test(facei))
544 fraction[facei] = 1.0;
549 bitSet nHoles(allCellTypes.size());
554 bitSet newIsFront(mesh_.nFaces());
559 if (isFront.test(facei))
561 const label own = mesh_.faceOwner()[facei];
563 if (allCellTypesWork[own] != HOLE)
565 if (allWeightWork[own] < fraction[facei])
569 if (allStencil[own].size())
571 nLayer[own] = currLayer;
573 allWeightWork[own] = fraction[facei];
574 allCellTypesWork[own] = INTERPOLATED;
576 const label donorId = compactStencil[own][0];
578 volRatio[own] = V[own]/compactCellVol[donorId];
583 fraction[facei]-layerRelax,
592 allWeightWork[own] = 0.0;
593 allCellTypesWork[own] = HOLE;
605 if (mesh_.isInternalFace(facei))
607 label nei = mesh_.faceNeighbour()[facei];
608 if (allCellTypesWork[nei] != HOLE)
610 if (allWeightWork[nei] < fraction[facei])
612 if (allStencil[nei].size())
614 nLayer[nei] = currLayer;
616 allWeightWork[nei] = fraction[facei];
617 allCellTypesWork[nei] = INTERPOLATED;
619 const label donorId =
620 compactStencil[nei][0];
623 V[nei]/compactCellVol[donorId];
628 fraction[facei]-layerRelax,
635 allWeightWork[nei] = 0.0;
636 allCellTypesWork[nei] = HOLE;
655 isFront.transfer(newIsFront);
656 fraction.transfer(newFraction);
659 if ((
debug&2) && (mesh_.time().outputTime()))
661 tmp<volScalarField> tfld
666 "allCellTypesWork_Layers" +
name(currLayer),
673 dAlllWeight.append(allWeightWork);
674 dataSet.append(allCellTypesWork);
686 reduce(nCount, sumOp<label>());
688 const scalar aveVol =
mag(
gSum(volRatio));
690 daverageVolRatio.append(aveVol/nCount);
694 label nTotalHoles(nHoles.count());
695 reduce(nTotalHoles, sumOp<label>());
696 dHoles.append(nTotalHoles);
703 & (nTotalHoles > 2.0*dHoles[currLayer - 1])
711 if ((
debug&2) && (mesh_.time().outputTime()))
713 tmp<volScalarField> tfld
715 createField(mesh_,
"walkFront_layers", nLayer)
723 averageVolRatio.
transfer(daverageVolRatio);
724 label minVolId =
findMin(averageVolRatio);
728 Info<<
nl <<
" Number of layers : " << averageVolRatio.size() <<
nl 729 <<
" Average volumetric ratio : " << averageVolRatio <<
nl 730 <<
" Number of holes cells : " << dHoles <<
nl 731 <<
" Using layer : " << useLayer <<
nl <<
endl;
736 minVolId = useLayer - 1;
739 allCellTypes.transfer(dataSet[minVolId]);
740 allWeight.transfer(dAlllWeight[minVolId]);
750 const InfoProxy<cellCellStencil>& iproxy
753 const auto&
e = *iproxy;
756 const labelUList& interpolationCells =
e.interpolationCells();
761 label nInvalidInterpolated = 0;
765 forAll(interpolationCells, i)
767 label celli = interpolationCells[i];
768 const labelList& slots = cellStencil[celli];
772 nInvalidInterpolated++;
775 bool hasLocal =
false;
776 bool hasRemote =
false;
806 reduce(nLocal, sumOp<label>());
807 reduce(nMixed, sumOp<label>());
808 reduce(nRemote, sumOp<label>());
809 reduce(nInvalidInterpolated, sumOp<label>());
811 Info<<
"Overset analysis : nCells : " 817 <<
" (interpolated from local:" << nLocal
818 <<
" mixed local/remote:" << nMixed
819 <<
" remote:" << nRemote
820 <<
" special:" << nInvalidInterpolated <<
")" <<
nl 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)
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.
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)
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 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.
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.
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)
static void listCombineGather(const List< commsStruct > &comms, List< T > &values, const CombineOp &cop, const int tag, const label comm)
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)
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)