66 if (!weightingFactorsPtr_)
71 return (*weightingFactorsPtr_);
77 if (!differenceFactorsPtr_)
82 return (*differenceFactorsPtr_);
88 if (orthogonal_ ==
false && !correctionVectorsPtr_)
90 makeCorrectionVectors();
102 <<
"cannot return correctionVectors; mesh is orthogonal" 106 return (*correctionVectorsPtr_);
112 if (skew_ ==
true && !skewCorrectionVectorsPtr_)
114 makeSkewCorrectionVectors();
127 <<
"cannot return skewCorrectionVectors; mesh is now skewed" 131 return (*skewCorrectionVectorsPtr_);
137 lPNptr_.reset(
nullptr);
138 weightingFactorsPtr_.reset(
nullptr);
139 differenceFactorsPtr_.reset(
nullptr);
142 correctionVectorsPtr_.reset(
nullptr);
145 skewCorrectionVectorsPtr_.reset(
nullptr);
151 const Foam::vector& Foam::edgeInterpolation::skewCorr(
const label edgeI)
const 153 #ifdef FA_SKEW_CORRECTION 157 skewCorrectionVectorsPtr_
158 ? (*skewCorrectionVectorsPtr_)[edgeI]
159 : pTraits<vector>::zero
164 return (*skewCorrectionVectorsPtr_)[edgeI];
170 void Foam::edgeInterpolation::makeLPN()
const 173 <<
"Constructing geodesic distance between points P and N" 177 lPNptr_ = std::make_unique<edgeScalarField>
182 mesh().time().constant(),
206 const vector& skewCorrEdge = skewCorr(edgeI);
213 - faceCentres[owner[edgeI]]
219 faceCentres[neighbour[edgeI]]
224 lPNIn[edgeI] = (lPE + lEN);
227 if (
mag(lPNIn[edgeI]) < SMALL)
229 lPNIn[edgeI] = SMALL;
234 forAll(lPN.boundaryField(), patchI)
238 lPN.boundaryFieldRef()[patchI]
241 lPN.boundaryFieldRef()[patchI] = 1.0/lPN.boundaryField()[patchI];
246 <<
"Finished constructing geodesic distance PN" 251 void Foam::edgeInterpolation::makeWeights()
const 254 <<
"Constructing weighting factors for edge interpolation" 258 weightingFactorsPtr_ = std::make_unique<edgeScalarField>
263 mesh().pointsInstance(),
281 scalarField& weightingFactorsIn = weightingFactors.primitiveFieldRef();
288 const vector& skewCorrEdge = skewCorr(edgeI);
295 - faceCentres[owner[edgeI]]
301 faceCentres[neighbour[edgeI]]
307 const scalar lPN = lPE + lEN;
308 if (
mag(lPN) > SMALL)
310 weightingFactorsIn[edgeI] = lEN/lPN;
318 weightingFactors.boundaryFieldRef()[patchI]
323 <<
"Finished constructing weighting factors for face interpolation" 328 void Foam::edgeInterpolation::makeDeltaCoeffs()
const 331 <<
"Constructing differencing factors array for edge gradient" 338 differenceFactorsPtr_ = std::make_unique<edgeScalarField>
343 mesh().pointsInstance(),
376 faceCentres[neighbour[edgeI]]
377 - faceCentres[owner[edgeI]];
383 const vector& skewCorrEdge = skewCorr(edgeI);
390 - faceCentres[owner[edgeI]]
396 faceCentres[neighbour[edgeI]]
401 scalar lPN = lPE + lEN;
408 const scalar
alpha = lPN*(unitDelta & edgeNormal);
411 dc[edgeI] = scalar(1)/
max(
alpha, 0.05*lPN);
416 forAll(DeltaCoeffs.boundaryField(), patchI)
420 DeltaCoeffs.boundaryFieldRef()[patchI]
426 void Foam::edgeInterpolation::makeCorrectionVectors()
const 429 <<
"Constructing non-orthogonal correction vectors" 432 correctionVectorsPtr_ = std::make_unique<edgeVectorField>
437 mesh().pointsInstance(),
461 vectorField& CorrVecsIn = CorrVecs.primitiveFieldRef();
471 faceCentres[neighbour[edgeI]]
472 - faceCentres[owner[edgeI]];
481 const scalar
alpha = unitDelta & edgeNormal;
484 deltaCoeffs[edgeI] = scalar(1)/
alpha;
490 - deltaCoeffs[edgeI]*unitDelta;
496 forAll(CorrVecs.boundaryField(), patchI)
498 mesh().
boundary()[patchI].makeCorrectionVectors(CorrVecsbf[patchI]);
501 scalar NonOrthogCoeff = 0.0;
503 if (owner.size() > 0)
506 sinAlpha.clamp_range(-1, 1);
511 reduce(NonOrthogCoeff, maxOp<scalar>());
514 <<
"non-orthogonality coefficient = " << NonOrthogCoeff <<
" deg." 517 if (NonOrthogCoeff < 0.1)
520 correctionVectorsPtr_.reset(
nullptr);
528 <<
"Finished constructing non-orthogonal correction vectors" 533 void Foam::edgeInterpolation::makeSkewCorrectionVectors()
const 536 <<
"Constructing skew correction vectors" 539 skewCorrectionVectorsPtr_ = std::make_unique<edgeVectorField>
543 "skewCorrectionVectors",
544 mesh().pointsInstance(),
568 const vector& P =
C[owner[edgeI]];
569 const vector&
N =
C[neighbour[edgeI]];
583 const scalar
beta = -((d^(S - P)) & de)/
alpha;
588 SkewCorrVecs[edgeI] = Ce[edgeI] - E;
593 SkewCorrVecs.boundaryFieldRef();
595 forAll(SkewCorrVecs.boundaryField(), patchI)
599 if (patchSkewCorrVecs.coupled())
609 forAll(patchSkewCorrVecs, edgeI)
611 const vector& P =
C[edgeFaces[edgeI]];
626 const scalar
beta = -((d^(S - P)) & de)/
alpha;
630 patchSkewCorrVecs[edgeI] =
631 Ce.boundaryField()[patchI][edgeI] - E;
636 #ifdef FA_SKEW_CORRECTION 638 constexpr scalar maxSkewRatio = 0.1;
639 scalar skewCoeff = 0;
643 const scalar magSkew =
mag(skewCorrVecs[edgeI]);
649 - skewCorrVecs[edgeI]
656 + skewCorrVecs[edgeI]
659 const scalar ratio = magSkew/lPN;
661 if (skewCoeff < ratio)
665 if (skewCoeff > maxSkewRatio)
673 <<
"skew coefficient = " << skewCoeff <<
endl;
675 if (skewCoeff < maxSkewRatio)
677 skewCorrectionVectorsPtr_.reset(
nullptr);
682 skew_ = bool(skewCorrectionVectorsPtr_);
686 <<
"Finished constructing skew correction vectors"
Finite area mesh (used for 2-D non-Euclidian finite area method) defined using a patch of faces on a ...
const edgeVectorField & skewCorrectionVectors() const
Return reference to skew vectors array.
const edgeScalarField & weights() const
Return reference to weighting factors array.
const edgeScalarField & deltaCoeffs() const
Return reference to difference factors array.
const edgeVectorField & correctionVectors() const
Return reference to non-orthogonality correction vectors array.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
List< edge > edgeList
List of edge.
dimensionedTensor skew(const dimensionedTensor &dt)
edgeInterpolation(const edgeInterpolation &)=delete
No copy construct.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
dimensioned< vector > dimensionedVector
Dimensioned vector obtained from generic dimensioned type.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Face to edge interpolation scheme. Included in faMesh.
Vector< Cmpt > & normalise(const scalar tol=ROOTVSMALL)
Inplace normalise the vector by its magnitude.
GeometricBoundaryField< Type, PatchField, GeoMesh > Boundary
Type of boundary fields.
SubList< edge > subList
Declare type of subList.
Ignore writing from objectRegistry::writeObject()
quaternion normalised(const quaternion &q)
Return the normalised (unit) quaternion of the given quaternion.
const dimensionSet dimless
Dimensionless.
bool movePoints() const
Do what is necessary if the mesh has moved.
const edgeScalarField & lPN() const
Return reference to PN geodesic distance.
dimensionedScalar asin(const dimensionedScalar &ds)
UList< label > labelUList
A UList of labels.
const labelUList & neighbour() const
Internal face neighbour.
virtual const pointField & points() const
Return raw points.
#define forAll(list, i)
Loop across all elements in list.
vectorField pointField
pointField is a vectorField.
const dimensionedScalar e
Elementary charge.
Info<< nl<< "Wrote faMesh in vtk format: "<< writer.output().name()<< nl;}{ const Field< vector > edgeCentres(faMeshTools::flattenEdgeField(aMesh.edgeCentres(), true))
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
#define DebugInFunction
Report an information message using Foam::Info.
GeometricField< vector, faePatchField, edgeMesh > edgeVectorField
bool orthogonal() const
Return whether mesh is orthogonal or not.
GeometricField< scalar, faePatchField, edgeMesh > edgeScalarField
errorManip< error > abort(error &err)
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
defineTypeNameAndDebug(combustionModel, 0)
bool skew() const
Return whether mesh is skew or not.
const Vector< label > N(dict.get< Vector< label >>("N"))
const labelUList & owner() const
Internal face owner. Note bypassing virtual mechanism so.
const edgeList & edges() const
Return mesh edges. Uses calcEdges.
const dimensionSet dimLength(0, 1, 0, 0, 0, 0, 0)
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
faePatchField< vector > faePatchVectorField
const fvBoundaryMesh & boundary() const noexcept
Return reference to boundary mesh.
dimensionedScalar beta("beta", dimless/dimTemperature, laminarTransport)
Field< vector > vectorField
Specialisation of Field<T> for vector.
const dimensionedScalar alpha
Fine-structure constant: default SI units: [].
Vector< Cmpt > & removeCollinear(const Vector< Cmpt > &unitVec)
Inplace removal of components that are collinear to the given unit vector.
Calculate the matrix for the second temporal derivative.
GeometricField< vector, faPatchField, areaMesh > areaVectorField
const Boundary & boundaryField() const noexcept
Return const-reference to the boundary field.
Do not request registration (bool: false)
void reduce(T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Reduce inplace (cf. MPI Allreduce) using linear/tree communication schedule.
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
static constexpr const zero Zero
Global zero (0)