36 template<
class CellWeight>
41 const CellWeight& cellWeight
53 const label facei =
c[cFacei];
56 for (
label fTrii = 0; fTrii <
f.nTriangles(); ++ fTrii)
58 const tetIndices tetPoints(celli, facei, fTrii + 1);
59 const scalar v = tetPoints.
tet(pMesh).
mag();
61 result[celli] += v*cellWeight[celli];
71 template<
class CellWeight>
76 const CellWeight& cellWeight
88 const label facei =
c[cFacei];
91 for (
label fTrii = 0; fTrii <
f.nTriangles(); ++ fTrii)
93 const tetIndices tetPoints(celli, facei, fTrii + 1);
94 const scalar v = tetPoints.
tet(pMesh).
mag();
97 forAll(triPoints, triPointi)
99 const label pointi = triPoints[triPointi];
101 result[pointi] += v*cellWeight[celli];
107 syncTools::syncPointList
140 pointVolumeWeightedSum
143 (weightSum/cellVolumeWeightedSum(pMesh,
oneField()))()
151 forAll(d.cellAvgCell_, cellAvgi)
153 d.cellCellAvg_[d.cellAvgCell_[cellAvgi]] = -1;
155 forAll(d.pointAvgPoint_, pointAvgi)
157 d.pointPointAvg_[d.pointAvgPoint_[pointAvgi]] = -1;
159 d.cellAvgCell_.clear();
160 d.pointAvgPoint_.clear();
161 d.cellAvgCount_.clear();
162 d.pointAvgCount_.clear();
163 if (d.cellAvgWeightSumPtr_.valid()) d.cellAvgWeightSumPtr_->clear();
164 if (d.pointAvgWeightSumPtr_.valid()) d.pointAvgWeightSumPtr_->clear();
165 d.cellAvgSum_.clear();
166 d.pointAvgSum_.clear();
173 const LagrangianSubSubField<scalar>& weightOrNull,
174 const LagrangianSubSubField<Type>& psiOrWeightPsi,
178 const LagrangianSubMesh& subMesh = psiOrWeightPsi.mesh();
179 const LagrangianMesh&
mesh = subMesh.
mesh();
181 if (
notNull(weightOrNull) != d.cellAvgWeightSumPtr_.valid())
184 <<
"Inconsistent weight specification for average of field "
189 forAll(psiOrWeightPsi, subi)
191 const label i = subMesh.start() + subi;
196 const label cellAvgi = d.cellCellAvg_[celli];
199 if (cellAvgi == -1 || d.cellAvgCount_[cellAvgi] == 0)
202 <<
"Negative cell count for average of field "
207 d.cellAvgCount_[cellAvgi] --;
210 d.cellAvgWeightSumPtr_()[cellAvgi] -=
212 d.cellAvgSum_[cellAvgi] -=
213 coordinates.
a()*weightOrNull[subi]*psiOrWeightPsi[subi];
217 d.cellAvgSum_[cellAvgi] -=
coordinates.
a()*psiOrWeightPsi[subi];
226 const LagrangianSubSubField<scalar>& weightOrNull,
227 const LagrangianSubSubField<Type>& psiOrWeightPsi,
231 const LagrangianSubMesh& subMesh = psiOrWeightPsi.mesh();
232 const LagrangianMesh&
mesh = subMesh.
mesh();
234 if (
notNull(weightOrNull) != d.cellAvgWeightSumPtr_.valid())
237 <<
"Inconsistent weight specification for average of field "
242 forAll(psiOrWeightPsi, subi)
244 const label i = subMesh.start() + subi;
249 label cellAvgi = d.cellCellAvg_[celli];
254 cellAvgi = d.cellAvgCell_.size();
255 d.cellCellAvg_[celli] = cellAvgi;
256 d.cellAvgCell_.append(celli);
257 d.cellAvgCount_.append(
label(0));
260 d.cellAvgWeightSumPtr_().append(scalar(0));
262 d.cellAvgSum_.append(pTraits<Type>::zero);
266 d.cellAvgCount_[cellAvgi] ++;
269 d.cellAvgWeightSumPtr_()[cellAvgi] +=
271 d.cellAvgSum_[cellAvgi] +=
272 coordinates.
a()*weightOrNull[subi]*psiOrWeightPsi[subi];
276 d.cellAvgSum_[cellAvgi] +=
286 const LagrangianSubSubField<scalar>& weightOrNull,
287 const LagrangianSubSubField<Type>& psiOrWeightPsi,
291 const LagrangianSubMesh& subMesh = psiOrWeightPsi.mesh();
292 const LagrangianMesh&
mesh = subMesh.
mesh();
294 if (
notNull(weightOrNull) != d.cellAvgWeightSumPtr_.valid())
297 <<
"Inconsistent weight specification for average of field "
302 forAll(psiOrWeightPsi, subi)
304 const label i = subMesh.start() + subi;
309 const label faceTrii =
mesh.faceTrii()[i];
312 tetIndices(celli, facei, faceTrii).faceTriIs(
mesh.
mesh());
314 forAll(triPoints, triPointi)
316 const label pointi = triPoints[triPointi];
318 label pointAvgi = d.pointPointAvg_[pointi];
323 pointAvgi = d.pointAvgPoint_.size();
324 d.pointPointAvg_[pointi] = pointAvgi;
325 d.pointAvgPoint_.append(pointi);
326 d.pointAvgCount_.append(
label(0));
329 d.pointAvgWeightSumPtr_().append(scalar(0));
331 d.pointAvgSum_.append(pTraits<Type>::zero);
335 d.pointAvgCount_[pointAvgi] ++;
338 d.pointAvgWeightSumPtr_()[pointAvgi] +=
340 d.pointAvgSum_[pointAvgi] +=
343 *psiOrWeightPsi[subi];
347 d.pointAvgSum_[pointAvgi] +=
359 d.pointAvgCount_.resize(d.pointAvgPoint_.size(),
label(0));
362 d.pointAvgWeightSumPtr_().resize(d.pointAvgPoint_.size(), scalar(0));
364 d.pointAvgSum_.resize(d.pointAvgPoint_.size(), pTraits<Type>::zero);
367 syncTools::syncPointList
377 syncTools::syncPointList
381 d.pointAvgWeightSumPtr_(),
386 syncTools::syncPointList
405 forAll(dd.pointAvgPoint_, dPointAvgi)
407 const label pointi = dd.pointAvgPoint_[dPointAvgi];
408 const label pointAvgi = d.pointPointAvg_[pointi];
414 || d.pointAvgCount_[pointAvgi] < dd.pointAvgCount_[dPointAvgi]
418 <<
"Negative point count for average "
423 d.pointAvgCount_[pointAvgi] -= dd.pointAvgCount_[dPointAvgi];
424 if (d.pointAvgWeightSumPtr_.valid())
426 d.pointAvgWeightSumPtr_()[pointAvgi] -=
427 dd.pointAvgWeightSumPtr_()[dPointAvgi];
429 d.pointAvgSum_[pointAvgi] -= dd.pointAvgSum_[dPointAvgi];
441 forAll(dd.pointAvgPoint_, dPointAvgi)
443 const label pointi = dd.pointAvgPoint_[dPointAvgi];
445 label pointAvgi = d.pointPointAvg_[pointi];
450 pointAvgi = d.pointAvgPoint_.size();
451 d.pointPointAvg_[pointi] = pointAvgi;
452 d.pointAvgPoint_.append(pointi);
453 d.pointAvgCount_.append(
label(0));
454 if (d.pointAvgWeightSumPtr_.valid())
456 d.pointAvgWeightSumPtr_().append(scalar(0));
458 d.pointAvgSum_.append(pTraits<Type>::zero);
462 d.pointAvgCount_[pointAvgi] += dd.pointAvgCount_[dPointAvgi];
463 if (d.pointAvgWeightSumPtr_.valid())
465 d.pointAvgWeightSumPtr_()[pointAvgi] +=
466 dd.pointAvgWeightSumPtr_()[dPointAvgi];
468 d.pointAvgSum_[pointAvgi] += dd.pointAvgSum_[dPointAvgi];
476 LagrangianSubField<Type>& result
479 const LagrangianSubMesh& subMesh = result.mesh();
480 const LagrangianMesh&
mesh = subMesh.
mesh();
484 const label i = subMesh.start() + subi;
489 const label faceTrii =
mesh.faceTrii()[i];
492 tetIndices(celli, facei, faceTrii).faceTriIs(
mesh.
mesh());
494 const label cellAvgi = data_.cellCellAvg_[celli];
495 const label dCellAvgi = dData_.cellCellAvg_[celli];
496 const bool haveData =
497 cellAvgi != -1 && data_.cellAvgCount_[cellAvgi] != 0;
498 const bool haveDData =
499 dCellAvgi != -1 && dData_.cellAvgCount_[dCellAvgi] != 0;
501 if (!haveData && !haveDData)
504 <<
"Interpolated value requested for a cell in which no "
505 <<
"elements have been averaged"
509 static const Type& z = pTraits<Type>::zero;
514 (haveData ? data_.cellAvgSum_[cellAvgi] : z)
515 + (haveDData ? dData_.cellAvgSum_[dCellAvgi] : z)
521 !cellWeightSumPtr_.valid()
522 ? (haveData ? data_.cellAvgWeightSumPtr_()[cellAvgi] : 0)
523 + (haveDData ? dData_.cellAvgWeightSumPtr_()[dCellAvgi] : 0)
524 : cellWeightSumPtr_()[celli]
527 forAll(triPoints, triPointi)
529 const label pointi = triPoints[triPointi];
531 const label pointAvgi = data_.pointPointAvg_[pointi];
532 const label dPointAvgi = dData_.pointPointAvg_[pointi];
533 const bool haveData =
534 pointAvgi != -1 && data_.pointAvgCount_[pointAvgi] != 0;
535 const bool haveDData =
536 dPointAvgi != -1 && dData_.pointAvgCount_[dPointAvgi] != 0;
541 (haveData ? data_.pointAvgSum_[pointAvgi] : z)
542 + (haveDData ? dData_.pointAvgSum_[dPointAvgi] : z)
548 !pointWeightSumPtr_.valid()
549 ? (haveData ? data_.pointAvgWeightSumPtr_()[pointAvgi] : 0)
550 + (haveDData ? dData_.pointAvgWeightSumPtr_()[dPointAvgi] : 0)
551 : pointWeightSumPtr_()[pointi]
567 const bool hasWeightSum
570 cellCellAvg_(nCells,
label(-1)),
576 cellAvgWeightSumPtr_(hasWeightSum ? new DynamicList<scalar>() : nullptr),
577 pointAvgWeightSumPtr_(hasWeightSum ? new DynamicList<scalar>() : nullptr),
596 ? cellWeightSum(
mesh.
mesh(), weightSum).ptr()
602 ? pointWeightSum(
mesh.
mesh(), weightSum).ptr()
606 dDataIsValid_(false),
630 <<
"Cannot remove from an average with a cached difference"
634 removeFromCells(weightOrNull, psiOrWeightPsi, data_);
636 addToPoints(weightOrNull, psiOrWeightPsi, dData_);
638 removeFromPoints(dData_, data_);
655 <<
"Cannot add to an average with a cached difference"
659 dDataIsValid_ = cache;
661 addToCells(weightOrNull, psiOrWeightPsi, cache ? dData_ : data_);
663 addToPoints(weightOrNull, psiOrWeightPsi, dData_);
667 addToPoints(dData_, data_);
685 <<
"Cannot correct an average without a cached difference"
691 dDataIsValid_ = cache;
693 addToCells(weightOrNull, psiOrWeightPsi, cache ? dData_ : data_);
695 addToPoints(weightOrNull, psiOrWeightPsi, dData_);
699 addToPoints(dData_, data_);
#define forAll(list, i)
Loop across all elements in list.
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
Basic Lagrangian averaging process in which values are averaged in the cells and then interpolated as...
virtual void remove(const LagrangianSubSubField< scalar > &weight, const LagrangianSubSubField< Type > &psi)
Remove weighted values from the average.
virtual ~cellPoint()
Destructor.
virtual void add(const LagrangianSubSubField< scalar > &weight, const LagrangianSubSubField< Type > &psi, const bool cache)
Add weighted values to the average.
cellPoint(const word &name, const LagrangianMesh &mesh, const dimensionSet &dimensions, const Field< scalar > &weightSum)
Construct with a name, for a mesh and with given dimensions.
virtual void correct(const LagrangianSubSubField< scalar > &weight, const LagrangianSubSubField< Type > &psi, const bool cache)
Correct weighted values in the average.
Class containing Lagrangian geometry and topology.
A cell is defined as a list of faces with extra functionality.
Dimension set for the base types.
A face is a list of labels corresponding to mesh vertices.
const polyMesh & mesh() const
Return reference to polyMesh.
A class representing the concept of a field of 1 used to avoid unnecessary manipulations for objects ...
Mesh consisting of general polyhedral cells.
virtual const faceList & faces() const
Return raw faces.
const cellList & cells() const
Storage and named access for the indices of a tet which is part of the decomposition of a cell.
triFace faceTriIs(const polyMesh &mesh) const
Return the indices corresponding to the tri on the face for.
tetPointRef tet(const polyMesh &mesh, const pointField &meshPoints, const pointField &cellCentres) const
Return the geometry corresponding to this tet and the given.
scalar mag() const
Return volume.
A class for managing temporary objects.
T & ref() const
Return non-const reference or generate a fatal error.
A triangular face using a FixedList of labels corresponding to mesh vertices.
A class for handling words, derived from string.
Foam::fvMesh mesh(Foam::IOobject(regionName, runTime.name(), runTime, Foam::IOobject::MUST_READ), false)
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
autoPtr< CompressibleMomentumTransportModel > New(const volScalarField &rho, const volVectorField &U, const surfaceScalarField &phi, const viscosity &viscosity)
const dimensionedScalar c
Speed of light in a vacuum.
barycentric coordinates(const polyMesh &mesh, const point &position, const label celli, const label facei, const label faceTrii, const scalar stepFraction)
Return the coordinates given the position and tet topology.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Barycentric< scalar > barycentric
A scalar version of the templated Barycentric.
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
const HashTable< dimensionSet > & dimensions()
Get the table of dimension sets.
bool notNull(const T &t)
Return true if t is not a reference to the nullObject of type T.
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
bool isNull(const T &t)
Return true if t is a reference to the nullObject of type T.