67 setHoleCellValue_(ptf.setHoleCellValue_),
68 fluxCorrection_(ptf.fluxCorrection_),
69 interpolateHoleCellValue_(ptf.interpolateHoleCellValue_),
70 holeCellValue_(ptf.holeCellValue_),
71 fringeUpperCoeffs_(ptf.fringeUpperCoeffs_),
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_),
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))
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;
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;
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];
408 Info <<
" gSum(phi) on fringes " << phiIn <<
endl;
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]]++;
491 if (facePerCell[celli] > 1)
493 weights[celli] = scalar(1)/facePerCell[celli];
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;
567 scalar psiCorr = -massIn/offDiagCoeffs;
572 const label zonei = zoneID[celli];
575 (bInter && (zonei == zoneId_)) ||(bInter && (zoneId_ == -1))
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 "
611 <<
"Missing required dictionary entry"
612 <<
" 'oversetInterpolation'"
613 <<
". Skipping overset interpolation for field "
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;
649 this->primitiveField()
655 Info<<
"Skipping overset interpolation for field "
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
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;
751 fvMatrix<Type>& matrix
754 if (this->manipulatedMatrix())
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;
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]
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]
913 forAll(matrix.internalCoeffs(), patchi)
915 const labelUList& fc = addr.patchAddr(patchi);
916 const Field<Type>& bouCoeffs = matrix.boundaryCoeffs()[patchi];
920 const label celli = fc[i];
926 <<
"Patch:" << patchi
927 <<
" patchFace:" << i
928 <<
" lower:" << celli
929 <<
" type:" << types[celli]
930 <<
" bouCoeff:" << bouCoeffs[i]
938 && stencil[celli].empty()
944 <<
"Patch:" << patchi
945 <<
" patchFace:" << i
946 <<
" lower:" << celli
947 <<
" type:" << types[celli]
948 <<
" bouCoeff:" << bouCoeffs[i]
958 matrix.internalCoeffs();
960 for (
direction cmpt=0; cmpt<pTraits<Type>::nComponents; ++cmpt)
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]
1000 const lduAddressing& lduAddr,
1001 const label interfacei,
1026 if (fluxCorrection_ && this->oversetPatch_.master())
1038 if (this->setHoleCellValue_)
1040 os.writeEntry(
"setHoleCellValue", setHoleCellValue_);
1041 os.writeEntry(
"holeCellValue", holeCellValue_);
1042 os.writeEntryIfDifferent
1044 "interpolateHoleCellValue",
1046 interpolateHoleCellValue_
Info<< nl;Info<< "Write faMesh in vtk format:"<< nl;{ vtk::uindirectPatchWriter writer(aMesh.patch(), fileName(aMesh.time().globalPath()/vtkBaseFileName));writer.writeGeometry();globalIndex procAddr(aMesh.nFaces());labelList cellIDs;if(UPstream::master()) { cellIDs.resize(procAddr.totalSize());for(const labelRange &range :procAddr.ranges()) { auto slice=cellIDs.slice(range);slice=identity(range);} } writer.beginCellData(4);writer.writeProcIDs();writer.write("cellID", cellIDs);writer.write("area", aMesh.S().field());writer.write("normal", aMesh.faceAreaNormals());writer.beginPointData(1);writer.write("normal", aMesh.pointAreaNormals());Info<< " "<< writer.output().name()<< nl;}{ vtk::lineWriter writer(aMesh.points(), aMesh.edges(), fileName(aMesh.time().globalPath()/(vtkBaseFileName+"-edges")));writer.writeGeometry();writer.beginCellData(4);writer.writeProcIDs();{ Field< scalar > fld(faMeshTools::flattenEdgeField(aMesh.magLe(), true))
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
A field of fields is a PtrList of fields with reference counting.
Generic templated field type that is much like a Foam::List except that it is expected to hold numeri...
void map(const UList< Type > &mapF, const labelUList &mapAddressing)
1 to 1 map from the given field
tmp< Field< cmptType > > component(const direction) const
Return a component field of the field.
bool found(const Key &key) const
Same as contains().
A simple container of IOobject preferences. Can also be used for general handling of read/no-read/rea...
static FOAM_NO_DANGLING_REFERENCE const cellCellStencilObject & New(const fvMesh &mesh, Args &&... args)
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Ostream & writeEntryIfDifferent(const word &key, const T &value1, const T &value2)
Write a keyword/value entry only when the two values differ.
A List with indirect addressing. Like IndirectList but does not store addressing.
bool empty() const noexcept
True if List is empty (ie, size() is zero).
void size(const label n)
Older name for setAddressableSize.
commsTypes
Communications types.
static int & msgType() noexcept
Message tag of standard messages.
Addressing for all faces on surface of mesh. Can either be read from polyMesh or from triSurface....
virtual const wordHashSet & nonInterpolatedFields() const
Return the names of any (stencil or mesh specific) fields that.
virtual const mapDistribute & cellInterpolationMap() const
Return a communication schedule.
virtual const labelUList & cellTypes() const
Return the cell type list.
virtual const List< scalarList > & cellInterpolationWeights() const
Weights for cellStencil.
virtual const labelListList & cellStencil() const
Per interpolated cell the neighbour cells (in terms of slots as.
Calculation of interpolation stencils.
static void interpolate(Field< T > &psi, const fvMesh &mesh, const cellCellStencil &overlap, const List< scalarList > &wghts)
Interpolation of acceptor cells from donor cells.
static const labelIOList & zoneID(const fvMesh &)
Helper: get reference to registered zoneID. Loads volScalarField.
Abstract base class for coupled patches.
virtual void write(Ostream &) const
Write includes "value" entry.
virtual void initEvaluate(const Pstream::commsTypes commsType)
Initialise the evaluation of the patch field.
coupledFvPatchField(const fvPatch &, const DimensionedField< Type, volMesh > &)
Construct from patch and internal field.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
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.
const dictionary * findDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a sub-dictionary pointer if present (and it is a dictionary) otherwise return nullptr...
const dictionary & subDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a sub-dictionary.
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...
bool found(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find an entry (const access) with the given keyword.
A special matrix type and solver, designed for finite volume solutions of scalar equations....
const FieldField< Field, Type > & internalCoeffs() const noexcept
fvBoundary scalar field containing pseudo-matrix coeffs for internal cells
const FieldField< Field, Type > & boundaryCoeffs() const noexcept
fvBoundary scalar field containing pseudo-matrix coeffs for boundary cells
const GeometricField< Type, fvPatchField, volMesh > & psi(const label i=0) const
Return psi.
Mesh data needed to do the Finite Volume discretisation.
virtual const lduAddressing & lduAddr() const
Return ldu addressing.
virtual void interpolate(volScalarField &) const
Interpolate interpolationCells only.
const labelUList & owner() const
Internal face owner. Note bypassing virtual mechanism so.
const labelUList & neighbour() const
Internal face neighbour.
const fvBoundaryMesh & boundary() const noexcept
Return reference to boundary mesh.
bool manipulatedMatrix() const noexcept
True if the matrix has already been manipulated.
A FieldMapper for finite-volume patch fields.
const Field< Type > & primitiveField() const noexcept
Return const-reference to the internal field values.
const DimensionedField< Type, volMesh > & internalField() const noexcept
Return const-reference to the dimensioned internal field.
virtual void manipulateMatrix(fvMatrix< Type > &matrix)
Manipulate matrix.
void extrapolateInternal()
Assign the patch field from the internal field.
A finiteVolume patch using a polyPatch and a fvBoundaryMesh.
virtual const word & name() const
Return name.
label start() const noexcept
The patch start within the polyMesh face list.
virtual const labelUList & faceCells() const
Return faceCells.
Selector class for finite volume differencing schemes. fvMesh is derived from fvSchemes so that all f...
The class contains the addressing required by the lduMatrix: upper, lower and losort.
virtual const labelUList & upperAddr() const =0
Return upper addressing.
virtual const labelUList & lowerAddr() const =0
Return lower addressing.
virtual const labelUList & patchAddr(const label patchNo) const =0
Return patch to internal addressing given patch number.
const scalarField & diag() const
const scalarField & upper() const
const scalarField & lower() const
Class containing processor-to-processor mapping information.
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.
Support for overset functionality.
Boundary condition for use on overset patches. To be run in combination with special dynamicFvMesh ty...
const bool setHoleCellValue_
Flag to set hole cell values.
void storeFringeCoefficients(const fvMatrix< Type > &matrix)
Store fringe coefficients and faces.
const oversetFvPatch & oversetPatch_
Local reference cast into the overset patch.
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.
const bool fluxCorrection_
Flag to correct fluxes.
oversetFvPatchField(const fvPatch &, const DimensionedField< Type, volMesh > &)
Construct from patch and internal field.
virtual void initEvaluate(const Pstream::commsTypes commsType)
Initialise the evaluation of the patch field.
scalarField fringeUpperCoeffs_
Fringe upper coefficients.
virtual void write(Ostream &os) const
Write.
void adjustPsi(solveScalarField &psi, const lduAddressing &lduAddr, solveScalarField &result) const
Adjust psi for mass correction. Requires storeFringeCoefficients.
const Type holeCellValue_
Hole cell value.
void fringeFlux(const fvMatrix< Type > &m, const surfaceScalarField &phi) const
Calculate patch flux (helper function). Requires.
virtual void manipulateMatrix(fvMatrix< Type > &matrix)
Manipulate matrix.
labelField fringeFaces_
Fringe faces.
const bool interpolateHoleCellValue_
Flag to interpolate hole cell values (from nearby non-hole cell).
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 zoneId_
Zone to sum flux for mass conservation.
scalarField fringeLowerCoeffs_
Fringe lower coefficients.
Patch for indicating interpolated boundaries (in overset meshes).
virtual bool master() const
Am I the master interface.
A traits class, which is primarily used for primitives and vector-space.
A polyBoundaryMesh is a polyPatch list with registered IO, a reference to the associated polyMesh,...
const polyBoundaryMesh & boundaryMesh() const noexcept
Return boundary mesh.
A patch is a list of labels that address the faces in the global face list.
label nInternalFaces() const noexcept
Number of internal faces.
const vectorField & cellCentres() const
const dictionary & schemesDict() const
The entire dictionary or the optional "select" sub-dictionary.
A class for handling words, derived from Foam::string.
const volScalarField & psi
const polyBoundaryMesh & patches
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
OBJstream os(runTime.globalPath()/outputName)
const cellCellStencilObject & overlap
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
#define WarningInFunction
Report a warning using Foam::Warning.
Namespace for handling debugging switches.
string upper(const std::string &s)
Return string copy transformed with std::toupper on each character.
string lower(const std::string &s)
Return string copy transformed with std::tolower on each character.
Type & refCast(U &obj)
A dynamic_cast (for references) to Type reference.
HashSet< word, Hash< word > > wordHashSet
A HashSet of words, uses string hasher.
PtrList< fvPatch > fvPatchList
Store lists of fvPatch as a PtrList.
List< labelList > labelListList
List of labelList.
List< label > labelList
A List of labels.
void component(FieldField< Field, typename FieldField< Field, Type >::cmptType > &sf, const FieldField< Field, Type > &f, const direction d)
messageStream Info
Information stream (stdout output on master, null elsewhere).
GeometricField< scalar, fvsPatchField, surfaceMesh > surfaceScalarField
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Ostream & endl(Ostream &os)
Add newline and flush stream.
void add(DimensionedField< scalar, GeoMesh > &result, const dimensioned< scalar > &dt1, const DimensionedField< scalar, GeoMesh > &f2)
const Type * isA(const U &obj)
Attempt dynamic_cast to Type.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
void reduce(T &value, BinaryOp bop, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Reduce inplace (cf. MPI Allreduce).
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Field< solveScalar > solveScalarField
Field< label > labelField
Specialisation of Field<T> for label.
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).
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
vectorField pointField
pointField is a vectorField.
void diag(pointPatchField< vector > &, const pointPatchField< tensor > &)
errorManipArg< error, int > exit(error &err, const int errNo=1)
UList< label > labelUList
A UList of labels.
dict add("bounds", meshBb)
const labelUList & cellTypes
#define forAll(list, i)
Loop across all elements in list.