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_))
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;
588 return tmp<Field<Type>>
601 if (this->oversetPatch_.master())
604 const fvMesh&
mesh = this->internalField().mesh();
606 const word& fldName = this->internalField().name();
615 Info<<
"Skipping overset interpolation for solved-for field " 619 else if (!fvSchemes.
found(
"oversetInterpolation"))
622 <<
"Missing required dictionary entry" 623 <<
" 'oversetInterpolation'" 624 <<
". Skipping overset interpolation for field " 627 else if (fvSchemes.
found(
"oversetInterpolationRequired"))
632 if (fvSchemes.
found(
"oversetInterpolationSuppressed"))
635 <<
"Cannot have both dictionary entry" 636 <<
" 'oversetInterpolationSuppresed' and " 637 <<
" 'oversetInterpolationRequired' for field " 642 "oversetInterpolationRequired" 644 if (intDict.found(fldName))
648 Info<<
"Interpolating field " << fldName <<
endl;
658 const_cast<Field<Type>&
> 660 this->primitiveField()
666 Info<<
"Skipping overset interpolation for field " 674 fvSchemes.
findDict(
"oversetInterpolationSuppressed")
680 bool skipInterpolate = suppress.found(fldName);
686 || dictPtr->found(fldName);
693 Info<<
"Skipping suppressed overset interpolation" 694 <<
" for field " << fldName <<
endl;
701 Info<<
"Interpolating non-suppressed field " << fldName
714 const_cast<Field<Type>&
>(this->primitiveField());
725 if (this->setHoleCellValue_)
728 label nConstrained = 0;
731 const label cType = types[celli];
738 fld[celli] = this->holeCellValue_;
746 <<
" patch:" << this->oversetPatch_.name()
747 <<
" set:" << nConstrained <<
" cells to:" 748 << this->holeCellValue_ <<
endl;
765 if (this->manipulatedMatrix())
770 const oversetFvPatch& ovp = this->oversetPatch_;
774 if (fluxCorrection_ || (
debug & 2))
776 storeFringeCoefficients(matrix);
780 const fvMesh&
mesh = this->internalField().mesh();
781 const word& fldName = this->internalField().name();
793 <<
" patch:" << ovp.name() <<
endl;
800 dynamic_cast<const oversetFvMeshBase&>(
mesh).normalisation(matrix)
807 dynamic_cast<const oversetFvMeshBase&
>(
mesh).addInterpolation
811 this->setHoleCellValue_,
823 scalarField marker(this->primitiveField().size(), 0);
844 && marker[celli] > SMALL
848 <<
" field:" << fldName
849 <<
" patch:" << ovp.name()
850 <<
" found:" << celli
852 <<
" donorSlots:" << stencil[celli]
854 << UIndirectList<point>(allCs, stencil[celli])
855 <<
" amount-of-hole:" << marker[celli]
864 const labelUList& upperAddr = addr.upperAddr();
865 const labelUList& lowerAddr = addr.lowerAddr();
871 const label l = lowerAddr[facei];
873 const label u = upperAddr[facei];
878 (lHole &&
upper[facei] != 0.0)
879 || (uHole &&
lower[facei] != 0.0)
883 <<
"Hole-neighbouring face:" << facei
885 <<
" type:" << types[l]
886 <<
" coeff:" <<
lower[facei]
887 <<
" upper:" << upperAddr[facei]
888 <<
" type:" << types[u]
889 <<
" coeff:" <<
upper[facei]
899 && stencil[l].empty()
904 && stencil[u].empty()
909 (lEmpty &&
upper[facei] != 0.0)
910 || (uEmpty &&
lower[facei] != 0.0)
914 <<
"Still connected face:" << facei <<
" lower:" << l
915 <<
" type:" << types[l]
916 <<
" coeff:" <<
lower[facei]
918 <<
" type:" << types[u]
919 <<
" coeff:" <<
upper[facei]
926 const labelUList& fc = addr.patchAddr(patchi);
931 const label celli = fc[i];
934 if (lHole && bouCoeffs[i] != pTraits<Type>::zero)
937 <<
"Patch:" << patchi
938 <<
" patchFace:" << i
939 <<
" lower:" << celli
940 <<
" type:" << types[celli]
941 <<
" bouCoeff:" << bouCoeffs[i]
949 && stencil[celli].empty()
952 if (lEmpty && bouCoeffs[i] != pTraits<Type>::zero)
955 <<
"Patch:" << patchi
956 <<
" patchFace:" << i
957 <<
" lower:" << celli
958 <<
" type:" << types[celli]
959 <<
" bouCoeff:" << bouCoeffs[i]
968 const FieldField<Field, Type>& internalCoeffs =
975 forAll(internalCoeffs, patchi)
977 const labelUList& fc = addr.patchAddr(patchi);
978 const Field<Type>& intCoeffs = internalCoeffs[patchi];
979 const scalarField cmptCoeffs(intCoeffs.component(cmpt));
982 diag[fc[i]] += cmptCoeffs[i];
991 <<
"Patch:" << ovp.name()
994 <<
" diag:" <<
diag[celli]
1006 template<
class Type>
1012 const label interfacei,
1022 template<
class Type>
1037 if (fluxCorrection_ && this->oversetPatch_.master())
1039 adjustPsi(
psi, lduAddr, result);
1044 template<
class Type>
1049 if (this->setHoleCellValue_)
1055 "interpolateHoleCellValue",
1057 interpolateHoleCellValue_
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.
static const Type & New(const Mesh &mesh, Args &&... args)
Get existing or create a new MeshObject. Registered with typeName.
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.
Type & refCast(U &obj)
A dynamic_cast (for references). Generates a FatalError on failed casts and uses the virtual type() m...
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.
virtual tmp< Field< Type > > patchNeighbourField() const
Return neighbour field. Dummy.
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.
string upper(const std::string &s)
Return string copy transformed with std::toupper on each character.
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.
virtual void initEvaluate(const Pstream::commsTypes commsType)
Initialise the evaluation of the patch field.
const dictionary & subDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a sub-dictionary.
UList< label > labelUList
A UList of labels.
virtual const labelUList & cellTypes() const
Return the cell type list.
bool found(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find an entry (const access) with the given keyword.
const labelUList & neighbour() const
Internal face neighbour.
#define forAll(list, i)
Loop across all elements in list.
virtual void write(Ostream &) const
Write.
void diag(pointPatchField< vector > &, const pointPatchField< tensor > &)
void storeFringeCoefficients(const fvMatrix< Type > &matrix)
Store fringe coefficients and faces.
vectorField pointField
pointField is a vectorField.
void setSize(const label n)
Alias for resize()
virtual const labelListList & cellStencil() const
Per interpolated cell the neighbour cells (in terms of slots as.
const polyBoundaryMesh & boundaryMesh() const noexcept
Return boundary mesh.
A class for handling words, derived from Foam::string.
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
virtual const List< scalarList > & cellInterpolationWeights() const
Weights for cellStencil.
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.
const labelList & cellTypes
A polyBoundaryMesh is a polyPatch list with additional search methods and registered IO...
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)
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))
string lower(const std::string &s)
Return string copy transformed with std::tolower on each character.
#define WarningInFunction
Report a warning using Foam::Warning.
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Selector class for finite volume differencing schemes. fvMesh is derived from fvSchemes so that all f...
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...
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)
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.
A class for managing temporary objects.
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...
const dictionary * findDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a sub-dictionary pointer if present (and a sub-dictionary) otherwise return nullptr...
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)