34#include "surfaceInterpolate.H"
65Foam::fv::directionalPressureGradientExplicitSource::pressureDropModelNames_
67 { pressureDropModel::pVolumetricFlowRateTable,
"volumetricFlowRateTable" },
68 { pressureDropModel::pConstant,
"constant" },
69 { pressureDropModel::pDarcyForchheimer,
"DarcyForchheimer" },
75void Foam::fv::directionalPressureGradientExplicitSource::initialise()
77 const faceZone& fZone =
mesh_.faceZones()[zoneID_];
80 label numFaces = fZone.size();
82 faceId_.resize_nocopy(numFaces);
83 facePatchId_.resize_nocopy(numFaces);
91 const label meshFacei = fZone[i];
95 label facePatchId = -1;
98 if (!
mesh_.isInternalFace(meshFacei))
100 facePatchId =
mesh_.boundaryMesh().whichPatch(meshFacei);
101 const polyPatch&
pp =
mesh_.boundaryMesh()[facePatchId];
110 if (cpp && !cpp->owner())
120 faceId_[numFaces] =
faceId;
121 facePatchId_[numFaces] = facePatchId;
129 faceId_.resize(numFaces);
130 facePatchId_.resize(numFaces);
134void Foam::fv::directionalPressureGradientExplicitSource::writeProps
140 if (mesh_.time().writeTime())
146 name_ +
"Properties",
147 mesh_.time().timeName(),
166 const word& sourceName,
167 const word& modelType,
172 fv::cellSetOption(sourceName, modelType,
dict,
mesh),
173 model_(pressureDropModelNames_.get(
"model", coeffs_)),
174 gradP0_(cells_.size(),
Zero),
175 dGradP_(cells_.size(),
Zero),
176 gradPporous_(cells_.size(),
Zero),
177 flowDir_(coeffs_.get<
vector>(
"flowDir")),
184 faceZoneName_(coeffs_.get<
word>(
"faceZone")),
185 zoneID_(mesh_.faceZones().findZoneID(faceZoneName_)),
188 relaxationFactor_(coeffs_.getOrDefault<scalar>(
"relaxationFactor", 0.3)),
189 cellFaceMap_(cells_.size(), -1)
198 <<
"Source can only be applied to a single field. Current "
199 <<
"settings are:" << fieldNames_ << exit(FatalError);
205 <<
type() <<
" " << this->
name() <<
": "
206 <<
" Unknown face zone name: " << faceZoneName_
213 flowRate_ = interpolationTable<scalar>(
coeffs_);
217 coeffs_.readEntry(
"pressureDrop", pressureDrop_);
223 coeffs_.readEntry(
"length", length_);
228 <<
"Did not find mode " << model_ <<
nl
229 <<
"Please set 'model' to one of "
230 << pressureDropModelNames_
239 mesh_.time().timePath()/
"uniform"/(
name_ +
"Properties")
242 if (propsFile.good())
244 Info<<
" Reading pressure gradient from file" <<
endl;
246 propsDict.readEntry(
"gradient", gradP0_);
249 Info<<
" Initial pressure gradient = " << gradP0_ <<
nl <<
endl;
270 case pDarcyForchheimer:
274 const auto& turbModel =
282 gradPporous_ = -flowDir_*(D_*
nu + I_*0.5*magUn)*magUn*length_;
286 const auto& turbModel =
297 - flowDir_*(D_*
mu + I_*0.5*
rho*magUn)*magUn*length_;
303 gradPporous_ = -flowDir_*pressureDrop_;
307 case pVolumetricFlowRateTable:
309 scalar volFlowRate = 0;
314 label faceI = faceId_[i];
315 if (facePatchId_[i] != -1)
317 label patchI = facePatchId_[i];
318 totalphi +=
phi.boundaryField()[patchI][faceI];
322 totalphi +=
phi[faceI];
325 reduce(totalphi, sumOp<scalar>());
329 volFlowRate =
mag(totalphi);
333 const auto& turbModel =
341 volFlowRate =
mag(totalphi)/rhoAve;
344 gradPporous_ = -flowDir_*flowRate_(volFlowRate);
349 const faceZone& fZone = mesh_.faceZones()[zoneID_];
351 labelList meshToLocal(mesh_.nCells(), -1);
354 meshToLocal[cells_[i]] = i;
357 labelList faceToCellIndex(fZone.size(), -1);
358 const labelList& mc = fZone.masterCells();
359 const labelList& sc = fZone.slaveCells();
363 label masterCellI = mc[i];
365 if (meshToLocal[masterCellI] != -1 && masterCellI != -1)
367 faceToCellIndex[i] = meshToLocal[masterCellI];
369 else if (meshToLocal[masterCellI] == -1)
372 <<
"Did not find cell " << masterCellI
373 <<
"in cellZone :" << zoneName()
382 const polyBoundaryMesh&
pbm = mesh_.boundaryMesh();
384 FieldField<Field, vector> upwindValues(
pbm.size());
386 forAll(
U.boundaryField(), patchI)
392 upwindValues.set(patchI, pf.patchNeighbourField());
402 label faceI = fZone[i];
403 label
cellId = faceToCellIndex[i];
407 label sourceCellId = sc[i];
408 if (mesh_.isInternalFace(faceI))
410 scalar w = mesh_.magSf()[faceI];
411 UfCells[
cellId] +=
U[sourceCellId]*w;
412 UfCellWeights[
cellId] += w;
414 else if (fZone.flipMap()[i])
416 const label patchI =
pbm.patchID(faceI);
417 label localFaceI =
pbm[patchI].whichFace(faceI);
419 scalar w = mesh_.magSf().boundaryField()[patchI][localFaceI];
421 if (upwindValues.set(patchI))
423 UfCells[
cellId] += upwindValues[patchI][localFaceI]*w;
424 UfCellWeights[
cellId] += w;
430 UfCells /= UfCellWeights;
434 label cellI = cells_[i];
436 const vector Ufnorm(UfCells[i]/(
mag(UfCells[i]) + SMALL));
443 (
D & UfCells[i]) -
U[cellI]
449 Info<<
"Difference mag(U) = "
450 <<
mag(UfCells[i]) -
mag(
U[cellI])
452 Info<<
"Pressure drop in flowDir direction : "
453 << gradPporous_[i] <<
endl;
454 Info<<
"UfCell:= " << UfCells[i] <<
"U : " <<
U[cellI] <<
endl;
457 writeProps(gradP0_ + dGradP_);
463 fvMatrix<vector>& eqn,
469 name_ + fieldNames_[fieldI] +
"Sup",
474 auto&
Su = tSu.ref();
489 this->
addSup(eqn, fieldI);
512 invAPtr_() = 1.0/eqn.
A();
537 coeffs.getOrDefault<scalar>(
"relaxationFactor", 0.3);
539 coeffs.readEntry(
"flowDir", flowDir_);
540 flowDir_.normalise();
542 if (model_ == pConstant)
544 coeffs.readEntry(
"pressureDrop", pressureDrop_);
546 else if (model_ == pDarcyForchheimer)
548 coeffs.readEntry(
"D", D_);
549 coeffs.readEntry(
"I", I_);
550 coeffs.readEntry(
"length", length_);
Macros for easy insertion into run-time selection tables.
#define addToRunTimeSelectionTable(baseType, thisType, argNames)
Add to construction table with typeName as the key.
IOdictionary propsDict(dictIO)
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
const polyBoundaryMesh & pbm
static tmp< DimensionedField< Type, GeoMesh > > New(const word &name, IOobjectOption::registerOption regOpt, const Mesh &mesh, const dimensionSet &dims, const Field< Type > &iField)
Return tmp field (NO_READ, NO_WRITE) from name, mesh, dimensions, copy of internal field....
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
A field of fields is a PtrList of fields with reference counting.
Input from file stream as an ISstream, normally using std::ifstream for the actual input.
@ NO_REGISTER
Do not request registration (bool: false).
@ NO_READ
Nothing to be read.
@ NO_WRITE
Ignore writing from objectRegistry::writeObject().
static word scopedName(const std::string &scope, const word &name)
Create scope:name or scope_name string.
bool good() const noexcept
True if next operation might succeed.
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
const T * set(const label i) const
Return const pointer to element (can be nullptr), or nullptr for out-of-range access (ie,...
A List with indirect addressing. Like IndirectList but does not store addressing.
void size(const label n)
Older name for setAddressableSize.
Vector< Cmpt > & normalise(const scalar tol=ROOTVSMALL)
Inplace normalise the vector by its magnitude.
wordList names() const
A list of the zone names.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
bool readEntry(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX, IOobjectOption::readOption readOpt=IOobjectOption::MUST_READ) const
Find entry and assign to T val. FatalIOError if it is found and the number of tokens is incorrect,...
A subset of mesh faces organised as a primitive patch.
const labelList & slaveCells() const
Deprecated(2023-09) same as backCells.
const boolList & flipMap() const noexcept
Return face flip map.
const labelList & masterCells() const
Deprecated(2023-09) same as frontCells.
A special matrix type and solver, designed for finite volume solutions of scalar equations....
tmp< volScalarField > A() const
Return the central coefficient.
const dimensionSet & dimensions() const noexcept
Mesh data needed to do the Finite Volume discretisation.
virtual bool coupled() const
True if the patch field is coupled.
virtual tmp< Field< Type > > patchNeighbourField() const
Return patchField on the opposite patch of a coupled patch.
labelList cells_
Set of cells to apply source to.
cellSetOption(const word &name, const word &modelType, const dictionary &dict, const fvMesh &mesh)
Construct from components.
const wordRe & zoneName() const
Return const access to the first set/zone name.
Applies an explicit pressure gradient source in such a way to deflect the flow towards an specific di...
directionalPressureGradientExplicitSource(const word &sourceName, const word &modelType, const dictionary &dict, const fvMesh &mesh)
Construct from explicit source name and mesh.
virtual void writeData(Ostream &os) const
Write the source properties.
virtual bool read(const dictionary &dict)
Read source dictionary.
virtual void addSup(fvMatrix< vector > &eqn, const label fieldI)
Add explicit contribution to momentum equation.
pressureDropModel
Modes of pressure drop.
@ pVolumetricFlowRateTable
virtual void constrain(fvMatrix< vector > &eqn, const label fieldI)
Set 1/A coefficient.
virtual void correct(volVectorField &U)
Correct the pressure gradient.
Base abstract class for handling finite volume options (i.e. fvOption).
const word & name() const noexcept
Return const access to the source name.
const dictionary & coeffs() const noexcept
Return dictionary.
const fvMesh & mesh_
Reference to the mesh database.
wordList fieldNames_
Field names to apply source to - populated by derived models.
dictionary coeffs_
Dictionary containing source coefficients.
void resetApplied()
Resize/reset applied flag list for all fieldNames_ entries.
const fvMesh & mesh() const noexcept
Return const access to the mesh database.
const word name_
Source name.
An interpolation/look-up table of scalar vs <Type> values. The reference scalar values must be monoto...
A polyBoundaryMesh is a polyPatch list with registered IO, a reference to the associated polyMesh,...
const faceZoneMesh & faceZones() const noexcept
Return face zone mesh.
static const word propertiesName
Default name of the turbulence properties dictionary.
A class for handling words, derived from Foam::string.
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
volVectorField gradP(fvc::grad(p))
#define NotImplemented
Issue a FatalErrorIn for a function not currently implemented.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
OBJstream os(runTime.globalPath()/outputName)
A special matrix type and solver, designed for finite volume solutions of scalar equations.
tmp< volScalarField > rAU
ThermalDiffusivity< CompressibleTurbulenceModel< fluidThermo > > turbulenceModel
Namespace for handling debugging switches.
Namespace for finite-volume.
IncompressibleTurbulenceModel< transportModel > turbulenceModel
GeometricField< vector, fvPatchField, volMesh > volVectorField
Type gWeightedAverage(const UList< scalar > &weights, const UList< Type > &fld, const label comm)
The global weighted average of a field, using the mag() of the weights.
List< label > labelList
A List of labels.
const dimensionSet dimTime(0, 0, 1, 0, 0, 0, 0)
GeometricField< scalar, fvPatchField, volMesh > volScalarField
tensor rotationTensor(const vector &n1, const vector &n2)
Rotational transformation tensor from vector n1 to n2.
messageStream Info
Information stream (stdout output on master, null elsewhere).
GeometricField< scalar, fvsPatchField, surfaceMesh > surfaceScalarField
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
const word GlobalIOList< Tuple2< scalar, vector > >::typeName("scalarVectorTable")
Ostream & endl(Ostream &os)
Add newline and flush stream.
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).
Field< vector > vectorField
Specialisation of Field<T> for vector.
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...
const dimensionSet dimVolume(pow3(dimLength))
errorManipArg< error, int > exit(error &err, const int errNo=1)
void Su(fvMatrix< typename Expr::value_type > &m, const Expr &expression)
fvPatchField< vector > fvPatchVectorField
dimensioned< vector > dimensionedVector
Dimensioned vector obtained from generic dimensioned type.
constexpr char nl
The newline '\n' character (0x0a).
const dimensionedScalar & D
#define forAll(list, i)
Loop across all elements in list.