45 setHoleCellValue_(false),
46 fluxCorrection_(false),
47 interpolateHoleCellValue_(false),
67 setHoleCellValue_(ptf.setHoleCellValue_),
68 fluxCorrection_(ptf.fluxCorrection_),
69 interpolateHoleCellValue_(ptf.interpolateHoleCellValue_),
70 holeCellValue_(ptf.holeCellValue_),
71 fringeUpperCoeffs_(ptf.fringeUpperCoeffs_),
72 fringeLowerCoeffs_(ptf.fringeLowerCoeffs_),
73 fringeFaces_(ptf.fringeFaces_),
88 setHoleCellValue_(
dict.getOrDefault(
"setHoleCellValue", false)),
91 dict.getOrDefaultCompat
94 {{
"massCorrection", 2206}},
98 interpolateHoleCellValue_
105 ?
dict.
get<Type>(
"holeCellValue")
108 fringeUpperCoeffs_(),
109 fringeLowerCoeffs_(),
114 if (!this->readValueEntry(
dict))
124 const oversetFvPatchField<Type>& ptf
127 coupledFvPatchField<Type>(ptf),
128 oversetPatch_(ptf.oversetPatch_),
129 setHoleCellValue_(ptf.setHoleCellValue_),
130 fluxCorrection_(ptf.fluxCorrection_),
131 interpolateHoleCellValue_(ptf.interpolateHoleCellValue_),
132 holeCellValue_(ptf.holeCellValue_),
133 fringeUpperCoeffs_(ptf.fringeUpperCoeffs_),
134 fringeLowerCoeffs_(ptf.fringeLowerCoeffs_),
135 fringeFaces_(ptf.fringeFaces_),
148 oversetPatch_(ptf.oversetPatch_),
149 setHoleCellValue_(ptf.setHoleCellValue_),
150 fluxCorrection_(ptf.fluxCorrection_),
151 interpolateHoleCellValue_(ptf.interpolateHoleCellValue_),
152 holeCellValue_(ptf.holeCellValue_),
153 fringeUpperCoeffs_(ptf.fringeUpperCoeffs_),
154 fringeLowerCoeffs_(ptf.fringeLowerCoeffs_),
155 fringeFaces_(ptf.fringeFaces_),
168 const fvMesh&
mesh = this->internalField().mesh();
178 label fringesFaces = 0;
182 const label zonei = zoneID[own[facei]];
184 const label ownType =
cellTypes[own[facei]];
185 const label neiType =
cellTypes[nei[facei]];
195 const bool ownNei = (ownCalc || neiCalc);
199 (ownNei && (zonei == zoneId_)) || (ownNei && (zoneId_ == -1))
213 const fvPatch& curPatch =
patches[patchi];
217 const label start = curPatch.start();
221 const label facei = start + i;
222 const label celli = fc[i];
226 const label zonei = zoneID[celli];
233 if (ownCalc && (zonei == zoneId_))
240 fringeUpperCoeffs_.setSize(fringesFaces,
Zero);
241 fringeLowerCoeffs_.setSize(fringesFaces,
Zero);
242 fringeFaces_.setSize(fringesFaces, -1);
250 const label zonei = zoneID[own[facei]];
252 const label ownType =
cellTypes[own[facei]];
253 const label neiType =
cellTypes[nei[facei]];
263 const bool ownNei = (ownCalc || neiCalc);
267 (ownNei && (zonei == zoneId_)) || (ownNei && (zoneId_ == -1))
270 fringeUpperCoeffs_[fringesFaces] =
upper[facei];
271 fringeLowerCoeffs_[fringesFaces] =
lower[facei];
272 fringeFaces_[fringesFaces] = facei;
277 forAll(boundaryMesh, patchi)
279 const polyPatch&
p = boundaryMesh[patchi];
281 if (isA<coupledPolyPatch>(
p))
284 const label start =
p.start();
288 const label facei = start + i;
289 const label celli = fc[i];
293 const label zonei = zoneID[celli];
303 if ((ownCalc||neiCalc) && (zonei == zoneId_))
305 fringeLowerCoeffs_[fringesFaces] =
312 fringeUpperCoeffs_[fringesFaces] =
319 fringeFaces_[fringesFaces] = facei;
332 const fvMatrix<Type>& matrix,
339 const Field<Type>&
psi = matrix.psi();
344 if (this->oversetPatch_.master())
346 const fvMesh&
mesh = this->internalField().mesh();
355 label fringesFaces = 0;
358 const label zonei = zoneID[own[facei]];
360 const label ownType =
cellTypes[own[facei]];
361 const label neiType =
cellTypes[nei[facei]];
371 const bool ownNei = (ownCalc || neiCalc);
375 (ownNei && (zonei == zoneId_)) || (ownNei && (zoneId_ == -1))
378 const label fringei = fringeFaces_[fringesFaces];
384 const scalar& ufc =
upper[fringei];
385 const scalar& lfc =
lower[fringei];
388 ufc*
psi[nei[fringei]] - lfc*
psi[own[fringei]];
392 phiIn -=
phi[fringei];
397 phiIn +=
phi[fringei];
405 reduce(massIn, sumOp<scalar>());
406 reduce(phiIn, sumOp<scalar>());
409 Info <<
" gSum(p.flux) on fringes " << massIn <<
endl;
421 const fvMesh&
mesh = this->internalField().mesh();
433 scalar offDiagCoeffs = 0;
440 label fringesFaces = 0;
444 const label zonei = zoneID[own[facei]];
446 const label ownType =
cellTypes[own[facei]];
447 const label neiType =
cellTypes[nei[facei]];
457 const bool ownNei = (ownCalc || neiCalc);
461 (ownNei && (zonei == zoneId_)) || (ownNei && (zoneId_ == -1))
465 const scalar& ufc = fringeUpperCoeffs_[fringesFaces];
466 const scalar& lfc = fringeLowerCoeffs_[fringesFaces];
468 const scalar curFlux =
469 ufc*
psi[nei[facei]] - lfc*
psi[own[facei]];
474 offDiagCoeffs += lfc;
475 facePerCell[own[facei]]++;
480 offDiagCoeffs += ufc;
481 facePerCell[nei[facei]]++;
488 scalarField weights(facePerCell.size(), scalar(1));
491 if (facePerCell[celli] > 1)
493 weights[celli] = scalar(1)/facePerCell[celli];
503 forAll(boundaryMesh, patchi)
507 if (isA<coupledPolyPatch>(
p))
509 const auto& coupledPatch = refCast<const coupledPolyPatch>(
p);
512 const label start =
p.start();
516 const label facei = start + i;
517 const label celli = fc[i];
521 const label zonei = zoneID[celli];
531 if ((ownCalc||neiCalc) && (zonei == zoneId_))
533 const scalar psiOwn =
psi[celli];
534 const scalar& lfc = fringeLowerCoeffs_[fringesFaces];
535 const scalar curFlux = lfc*psiOwn;
541 if (coupledPatch.owner())
543 offDiagCoeffs -= lfc;
552 if (coupledPatch.owner())
554 offDiagCoeffs -= lfc;
564 reduce(massIn, sumOp<scalar>());
565 reduce(offDiagCoeffs, sumOp<scalar>());
567 scalar psiCorr = -massIn/offDiagCoeffs;
572 const label zonei = zoneID[celli];
575 (bInter && (zonei == zoneId_)) ||(bInter && (zoneId_ == -1))
578 psi[celli] += psiCorr;
590 if (this->oversetPatch_.master())
593 const fvMesh&
mesh = this->internalField().mesh();
595 const word& fldName = this->internalField().
name();
604 Info<<
"Skipping overset interpolation for solved-for field " 608 else if (!fvSchemes.found(
"oversetInterpolation"))
611 <<
"Missing required dictionary entry" 612 <<
" 'oversetInterpolation'" 613 <<
". Skipping overset interpolation for field " 616 else if (fvSchemes.found(
"oversetInterpolationRequired"))
621 if (fvSchemes.found(
"oversetInterpolationSuppressed"))
624 <<
"Cannot have both dictionary entry" 625 <<
" 'oversetInterpolationSuppresed' and " 626 <<
" 'oversetInterpolationRequired' for field " 631 "oversetInterpolationRequired" 633 if (intDict.found(fldName))
637 Info<<
"Interpolating field " << fldName <<
endl;
647 const_cast<Field<Type>&
> 649 this->primitiveField()
655 Info<<
"Skipping overset interpolation for field " 663 fvSchemes.findDict(
"oversetInterpolationSuppressed")
669 bool skipInterpolate = suppress.found(fldName);
675 || dictPtr->found(fldName);
682 Info<<
"Skipping suppressed overset interpolation" 683 <<
" for field " << fldName <<
endl;
690 Info<<
"Interpolating non-suppressed field " << fldName
703 const_cast<Field<Type>&
>(this->primitiveField());
714 if (this->setHoleCellValue_)
717 label nConstrained = 0;
720 const label cType = types[celli];
727 fld[celli] = this->holeCellValue_;
735 <<
" patch:" << this->oversetPatch_.name()
736 <<
" set:" << nConstrained <<
" cells to:" 737 << this->holeCellValue_ <<
endl;
754 if (this->manipulatedMatrix())
759 const oversetFvPatch& ovp = this->oversetPatch_;
763 if (fluxCorrection_ || (
debug & 2))
765 storeFringeCoefficients(matrix);
769 const fvMesh&
mesh = this->internalField().mesh();
770 const word& fldName = this->internalField().
name();
782 <<
" patch:" << ovp.name() <<
endl;
789 dynamic_cast<const oversetFvMeshBase&>(
mesh).normalisation(matrix)
796 dynamic_cast<const oversetFvMeshBase&
>(
mesh).addInterpolation
800 this->setHoleCellValue_,
812 scalarField marker(this->primitiveField().size(), 0);
833 && marker[celli] > SMALL
837 <<
" field:" << fldName
838 <<
" patch:" << ovp.name()
839 <<
" found:" << celli
841 <<
" donorSlots:" << stencil[celli]
843 << UIndirectList<point>(allCs, stencil[celli])
844 <<
" amount-of-hole:" << marker[celli]
853 const labelUList& upperAddr = addr.upperAddr();
854 const labelUList& lowerAddr = addr.lowerAddr();
860 const label l = lowerAddr[facei];
862 const label u = upperAddr[facei];
867 (lHole &&
upper[facei] != 0.0)
868 || (uHole &&
lower[facei] != 0.0)
872 <<
"Hole-neighbouring face:" << facei
874 <<
" type:" << types[l]
875 <<
" coeff:" <<
lower[facei]
876 <<
" upper:" << upperAddr[facei]
877 <<
" type:" << types[u]
878 <<
" coeff:" <<
upper[facei]
888 && stencil[l].empty()
893 && stencil[u].empty()
898 (lEmpty &&
upper[facei] != 0.0)
899 || (uEmpty &&
lower[facei] != 0.0)
903 <<
"Still connected face:" << facei <<
" lower:" << l
904 <<
" type:" << types[l]
905 <<
" coeff:" <<
lower[facei]
907 <<
" type:" << types[u]
908 <<
" coeff:" <<
upper[facei]
915 const labelUList& fc = addr.patchAddr(patchi);
920 const label celli = fc[i];
923 if (lHole && bouCoeffs[i] != pTraits<Type>::zero)
926 <<
"Patch:" << patchi
927 <<
" patchFace:" << i
928 <<
" lower:" << celli
929 <<
" type:" << types[celli]
930 <<
" bouCoeff:" << bouCoeffs[i]
938 && stencil[celli].empty()
941 if (lEmpty && bouCoeffs[i] != pTraits<Type>::zero)
944 <<
"Patch:" << patchi
945 <<
" patchFace:" << i
946 <<
" lower:" << celli
947 <<
" type:" << types[celli]
948 <<
" bouCoeff:" << bouCoeffs[i]
957 const FieldField<Field, Type>& internalCoeffs =
964 forAll(internalCoeffs, patchi)
966 const labelUList& fc = addr.patchAddr(patchi);
967 const Field<Type>& intCoeffs = internalCoeffs[patchi];
968 const scalarField cmptCoeffs(intCoeffs.component(cmpt));
971 diag[fc[i]] += cmptCoeffs[i];
980 <<
"Patch:" << ovp.name()
983 <<
" diag:" <<
diag[celli]
1001 const label interfacei,
1011 template<
class Type>
1026 if (fluxCorrection_ && this->oversetPatch_.master())
1028 adjustPsi(
psi, lduAddr, result);
1033 template<
class Type>
1038 if (this->setHoleCellValue_)
1044 "interpolateHoleCellValue",
1046 interpolateHoleCellValue_
const scalarField & diag() const
void size(const label n)
Older name for setAddressableSize.
errorManipArg< error, int > exit(error &err, const int errNo=1)
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
commsTypes
Communications types.
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
void fringeFlux(const fvMatrix< Type > &m, const surfaceScalarField &phi) const
Calculate patch flux (helper function). Requires.
void distribute(List< T > &fld, const bool dummyTransform=true, const int tag=UPstream::msgType()) const
Distribute List data using default commsType, default flip/negate operator.
virtual void updateInterfaceMatrix(solveScalarField &result, const bool add, const lduAddressing &lduAddr, const label patchId, const solveScalarField &psiInternal, const scalarField &coeffs, const direction, const Pstream::commsTypes commsType) const
Update result field based on interface functionality.
static FOAM_NO_DANGLING_REFERENCE const Type & New(const Mesh &mesh, Args &&... args)
Get existing or create MeshObject registered with typeName.
Type & refCast(U &obj)
A dynamic_cast (for references) to Type reference.
virtual void initEvaluate(const Pstream::commsTypes commsType)
Initialise the evaluation of the patch field.
Addressing for all faces on surface of mesh. Can either be read from polyMesh or from triSurface...
Ostream & endl(Ostream &os)
Add newline and flush stream.
A finiteVolume patch using a polyPatch and a fvBoundaryMesh.
A traits class, which is primarily used for primitives and vector-space.
Patch for indicating interpolated boundaries (in overset meshes).
void extrapolateInternal()
Assign the patch field from the internal field.
Ostream & writeEntry(const keyType &key, const T &value)
Write a keyword/value entry.
static int & msgType() noexcept
Message tag of standard messages.
::Foam::direction nComponents(const expressions::valueTypeCode) noexcept
The number of components associated with given valueTypeCode.
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a T. FatalIOError if not found, or if the number of tokens is incorrect.
virtual void interpolate(volScalarField &) const
Interpolate interpolationCells only.
static void interpolate(Field< T > &psi, const fvMesh &mesh, const cellCellStencil &overlap, const List< scalarList > &wghts)
Interpolation of acceptor cells from donor cells.
List< labelList > labelListList
List of labelList.
const fileName & name() const noexcept
The dictionary name.
virtual void initEvaluate(const Pstream::commsTypes commsType)
Initialise the evaluation of the patch field.
UList< label > labelUList
A UList of labels.
virtual const labelUList & cellTypes() const
Return the cell type list.
void reduce(T &value, [[maybe_unused]] BinaryOp bop, [[maybe_unused]] const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Reduce inplace (cf. MPI Allreduce)
const labelUList & neighbour() const
Internal face neighbour.
#define forAll(list, i)
Loop across all elements in list.
virtual void write(Ostream &) const
Write includes "value" entry.
void diag(pointPatchField< vector > &, const pointPatchField< tensor > &)
void storeFringeCoefficients(const fvMatrix< Type > &matrix)
Store fringe coefficients and faces.
vectorField pointField
pointField is a vectorField.
virtual const labelListList & cellStencil() const
Per interpolated cell the neighbour cells (in terms of slots as.
const polyBoundaryMesh & boundaryMesh() const noexcept
Return boundary mesh.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
virtual const lduAddressing & lduAddr() const
Return ldu addressing.
A FieldMapper for finite-volume patch fields.
const cellCellStencilObject & overlap
const labelUList & cellTypes
virtual const List< scalarList > & cellInterpolationWeights() const
Weights for cellStencil.
const scalarField & lower() const
A special matrix type and solver, designed for finite volume solutions of scalar equations. Face addressing is used to make all matrix assembly and solution loops vectorise.
virtual void manipulateMatrix(fvMatrix< Type > &matrix)
Manipulate matrix.
const dictionary & schemesDict() const
The entire dictionary or the optional "select" sub-dictionary.
virtual void initInterfaceMatrixUpdate(Field< Type > &, const bool add, const lduAddressing &, const label interfacei, const Field< Type > &, const scalarField &, const Pstream::commsTypes commsType) const
Initialise neighbour matrix update.
label nInternalFaces() const noexcept
Number of internal faces.
HashSet< word, Hash< word > > wordHashSet
A HashSet of words, uses string hasher.
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
const vectorField & cellCentres() const
Ostream & writeEntryIfDifferent(const word &key, const T &value1, const T &value2)
Write a keyword/value entry only when the two values differ.
Abstract base class for coupled patches.
A polyBoundaryMesh is a polyPatch list with registered IO, a reference to the associated polyMesh...
oversetFvPatchField(const fvPatch &, const DimensionedField< Type, volMesh > &)
Construct from patch and internal field.
void adjustPsi(solveScalarField &psi, const lduAddressing &lduAddr, solveScalarField &result) const
Adjust psi for mass correction. Requires storeFringeCoefficients.
void add(FieldField< Field1, typename typeOfSum< Type1, Type2 >::type > &f, const FieldField< Field1, Type1 > &f1, const FieldField< Field2, Type2 > &f2)
int debug
Static debugging option.
OBJstream os(runTime.globalPath()/outputName)
string upper(const std::string &s)
Return string copy transformed with std::toupper on each character.
const labelUList & owner() const
Internal face owner. Note bypassing virtual mechanism so.
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< ' ';}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< ' ';}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< ' ';}gmvFile<< nl;for(const word &name :lagrangianScalarNames){ IOField< scalar > fld(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
const scalarField & upper() const
#define WarningInFunction
Report a warning using Foam::Warning.
const word & name() const
Return reference to name.
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Mesh data needed to do the Finite Volume discretisation.
virtual const mapDistribute & cellInterpolationMap() const
Return a communication schedule.
A simple container of IOobject preferences. Can also be used for general handling of read/no-read/rea...
const polyBoundaryMesh & patches
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
string lower(const std::string &s)
Return string copy transformed with std::tolower on each character.
messageStream Info
Information stream (stdout output on master, null elsewhere)
const fvBoundaryMesh & boundary() const noexcept
Return reference to boundary mesh.
const FieldField< Field, Type > & internalCoeffs() const noexcept
fvBoundary scalar field containing pseudo-matrix coeffs for internal cells
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
const volScalarField & psi
The class contains the addressing required by the lduMatrix: upper, lower and losort.
const FieldField< Field, Type > & boundaryCoeffs() const noexcept
fvBoundary scalar field containing pseudo-matrix coeffs for boundary cells
virtual void manipulateMatrix(fvMatrix< Type > &matrix)
Manipulate matrix.
virtual void write(Ostream &os) const
Write.
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a T, or return the given default value. FatalIOError if it is found and the number of...
List< label > labelList
A List of labels.
GeometricField< scalar, fvsPatchField, surfaceMesh > surfaceScalarField
static const labelIOList & zoneID(const fvMesh &)
Helper: get reference to registered zoneID. Loads volScalarField.
void component(FieldField< Field, typename FieldField< Field, Type >::cmptType > &sf, const FieldField< Field, Type > &f, const direction d)
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
PtrList< fvPatch > fvPatchList
Store lists of fvPatch as a PtrList.
Boundary condition for use on overset patches. To be run in combination with special dynamicFvMesh ty...
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)