36 Foam::turbulentDigitalFilterInletFvPatchVectorField::patchMapper()
const
42 const fileName samplePointsFile
44 this->db().time().globalPath()
62 const rawIOField<point> samplePoints(io,
false);
68 && mapMethod_ !=
"planarInterpolation"
74 new pointToPointPlanarInterpolation
89 Foam::turbulentDigitalFilterInletFvPatchVectorField::indexPairs()
96 scalar minMag =
mag(nf[minCmpt]);
97 for (
direction cmpt = 1; cmpt < pTraits<vector>::nComponents; ++cmpt)
99 const scalar
s =
mag(nf[cmpt]);
115 coordSystem::cartesian cs
135 const boundBox bb(localPos);
138 const Vector2D<label>
n(n_.first(), n_.second());
139 invDelta_[0] =
n[0]/bb.span()[0];
140 invDelta_[1] =
n[1]/bb.span()[1];
141 const point localMinPt(bb.min());
144 List<Pair<label>> indexPairs(this->size(), Pair<label>(
Zero,
Zero));
148 const scalar& centre0 = localPos[facei][0];
149 const scalar& centre1 = localPos[facei][1];
152 const label j = label((centre0 - localMinPt[0])*invDelta_[0]);
153 const label
k = label((centre1 - localMinPt[1])*invDelta_[1]);
155 indexPairs[facei] = Pair<label>(facei,
k*
n[0] + j);
162 void Foam::turbulentDigitalFilterInletFvPatchVectorField::checkR()
const
168 if (R_[facei].xx() <= 0)
171 <<
"Reynolds stress tensor component Rxx cannot be negative"
172 <<
" or zero, where Rxx = " << R_[facei].xx()
173 <<
" at the face centre = " << faceCentres[facei]
177 if (R_[facei].yy() < 0 || R_[facei].zz() < 0)
180 <<
"Reynolds stress tensor components Ryy or Rzz cannot be"
181 <<
" negative where Ryy = " << R_[facei].yy()
182 <<
", and Rzz = " << R_[facei].zz()
183 <<
" at the face centre = " << faceCentres[facei]
187 const scalar x0 = R_[facei].xx()*R_[facei].yy() -
sqr(R_[facei].xy());
192 <<
"Reynolds stress tensor component group, Rxx*Ryy - Rxy^2"
193 <<
" cannot be negative or zero"
194 <<
" at the face centre = " << faceCentres[facei]
198 const scalar x1 = R_[facei].zz() -
sqr(R_[facei].xz())/R_[facei].xx();
199 const scalar x2 =
sqr(R_[facei].yz() - R_[facei].xy()*R_[facei].xz()
200 /(R_[facei].xx()*x0));
201 const scalar x3 = x1 - x2;
206 <<
"Reynolds stress tensor component group, "
207 <<
"Rzz - Rxz^2/Rxx - (Ryz - Rxy*Rxz/(Rxx*(Rxx*Ryy - Rxy^2)))^2"
208 <<
" cannot be negative at the face centre = "
209 << faceCentres[facei]
214 Info<<
" # Reynolds stress tensor on patch is consistent #" <<
endl;
232 lws.xy() =
R.xy()/lws.xx();
233 lws.xz() =
R.xz()/lws.xx();
235 lws.yz() = (
R.yz() - lws.xy()*lws.xz())/lws.yy();
243 Foam::scalar Foam::turbulentDigitalFilterInletFvPatchVectorField::
247 return gSum((UMean_ & patchNormal)*
patch().magSf());
251 Foam::tensor Foam::turbulentDigitalFilterInletFvPatchVectorField::
266 const scalar invDeltaT = 1.0/db().time().deltaTValue();
269 Ls.row(0, Ls.x()*invDeltaT);
270 Ls.row(1, Ls.y()*invDelta_[0]);
271 Ls.row(2, Ls.z()*invDelta_[1]);
281 label rangeModifier = 0;
287 rangeModifier = pTraits<vector>::nComponents;
290 List<label> szBox(pTraits<tensor>::nComponents, initValue);
291 Vector<label> szPlane
301 : labelRange(rangeModifier, pTraits<tensor>::nComponents - rangeModifier)
305 const label slicei = label(i/pTraits<vector>::nComponents);
308 const label
n = ceil(L_[i]);
309 const label twiceN = 4*
n;
312 szBox[i] = szPlane[slicei] + twiceN;
320 initFactors2D()
const
322 List<label> boxFactors2D(pTraits<vector>::nComponents);
324 for (
direction dir = 0; dir < pTraits<vector>::nComponents; ++dir)
327 szBox_[pTraits<vector>::nComponents + dir]
328 *szBox_[pTraits<symmTensor>::nComponents + dir];
336 initFactors3D()
const
338 List<label> boxFactors3D(pTraits<vector>::nComponents);
340 for (
direction dir = 0; dir < pTraits<vector>::nComponents; ++dir)
342 boxFactors3D[dir] = boxFactors2D_[dir]*szBox_[dir];
350 initPlaneFactors()
const
352 List<label> planeFactors(pTraits<vector>::nComponents);
354 for (
direction dir = 0; dir < pTraits<vector>::nComponents; ++dir)
356 planeFactors[dir] = boxFactors2D_[dir]*(szBox_[dir] - 1);
364 Foam::turbulentDigitalFilterInletFvPatchVectorField::fillBox()
366 List<List<scalar>> box(pTraits<vector>::nComponents, List<scalar>());
369 for (
direction dir = 0; dir < pTraits<vector>::nComponents; ++dir)
372 box[dir] = randomSet<List<scalar>, scalar>(boxFactors3D_[dir]);
380 Foam::turbulentDigitalFilterInletFvPatchVectorField::calcFilterCoeffs()
const
382 List<List<scalar>> filterCoeffs
384 pTraits<tensor>::nComponents,
392 initValue = pTraits<vector>::nComponents;
395 for (
direction dir = initValue; dir < pTraits<tensor>::nComponents; ++dir)
399 const label
n = ceil(L_[dir]);
403 const label twiceN = 4*
n;
407 filterCoeffs[dir] = List<scalar>(twiceN + 1,
Zero);
410 const scalar initElem = -2*scalar(
n);
415 filterCoeffs[dir].
begin(),
416 filterCoeffs[dir].
end(),
421 List<scalar> fTemp(filterCoeffs[dir]);
423 const scalar nSqr =
n*
n;
431 exp(C1_*
sqr(filterCoeffs[dir])/nSqr)/fSum;
438 filterCoeffs[dir] =
exp(C1_*
mag(filterCoeffs[dir])/
n)/fSum;
446 void Foam::turbulentDigitalFilterInletFvPatchVectorField::shiftRefill()
450 List<scalar>& r = box_[dir];
456 for (label i = 0; i < boxFactors2D_[dir]; ++i)
458 r[i] = rndGen_.GaussNormal<scalar>();
464 void Foam::turbulentDigitalFilterInletFvPatchVectorField::mapFilteredBox
469 for (
const auto&
x : indexPairs_)
471 const label xf =
x.first();
472 const label xs =
x.second();
473 U[xf][0] = filteredBox_[0][xs];
474 U[xf][1] = filteredBox_[1][xs];
475 U[xf][2] = filteredBox_[2][xs];
480 void Foam::turbulentDigitalFilterInletFvPatchVectorField::onePointCorrs
491 Us.z() =
Us.x()*lws.xz() +
Us.y()*lws.yz() +
Us.z()*lws.zz();
492 Us.y() =
Us.x()*lws.xy() +
Us.y()*lws.yy();
493 Us.x() =
Us.x()*lws.xx();
498 void Foam::turbulentDigitalFilterInletFvPatchVectorField::twoPointCorrs()
500 for (
direction dir = 0; dir < pTraits<vector>::nComponents; ++dir)
502 List<scalar>& in = box_[dir];
503 List<scalar>& out = filteredBox_[dir];
504 const List<scalar>& filter1 = filterCoeffs_[dir];
505 const List<scalar>& filter2 = filterCoeffs_[3 + dir];
506 const List<scalar>& filter3 = filterCoeffs_[6 + dir];
508 const label sz1 = szBox_[dir];
509 const label sz2 = szBox_[3 + dir];
510 const label sz3 = szBox_[6 + dir];
511 const label szfilter1 = filterCoeffs_[dir].size();
512 const label szfilter2 = filterCoeffs_[3 + dir].size();
513 const label szfilter3 = filterCoeffs_[6 + dir].size();
514 const label sz23 = boxFactors2D_[dir];
515 const label sz123 = boxFactors3D_[dir];
516 const label validSlice2 = sz2 - (szfilter2 - label(1));
517 const label validSlice3 = sz3 - (szfilter3 - label(1));
521 label filterCentre = label(szfilter2/label(2));
522 label endIndex = sz2 - filterCentre;
527 for (label i = 0; i < sz1; ++i)
529 for (label j = 0; j < sz3; ++j)
533 for (label
k = filterCentre;
k < endIndex; ++
k)
538 for (label
p = szfilter2 - 1;
p >= 0; --
p, ++q)
540 tmp[i1] += in[i0 + q]*filter2[
p];
546 i0 += (filterCentre + filterCentre);
553 filterCentre = label(szfilter3/label(2));
554 endIndex = sz3 - filterCentre;
558 for (label i = 0; i < sz1; ++i)
562 for (label j = 0; j < sz2; ++j)
567 for (label
k = 0;
k < endIndex - filterCentre; ++
k)
572 for (label
p = szfilter3 - 1;
p >= 0; --
p, ++q)
574 tmp[i1] += tmp2[i2 + q*sz2]*filter3[
p];
580 i1 += (sz2 + filterCentre);
581 i2 += (sz2 + filterCentre);
586 filterCentre = label(szfilter1/label(2));
587 endIndex = sz1 - filterCentre;
588 i1 = (szfilter2 - label(1))/label(2);
589 i2 = (szfilter2 - label(1))/label(2);
592 for (label i = 0; i < validSlice3; ++i)
594 for (label j = 0; j < validSlice2; ++j)
599 for (label
k = szfilter1 - 1;
k >= 0; --
k)
601 sum += tmp[i1]*filter1[
k];
615 calcCoeffs1FSM()
const
617 List<scalar> coeffs1FSM(pTraits<vector>::nComponents);
621 coeffs1FSM[i] =
exp(C1FSM_/L_[i]);
629 calcCoeffs2FSM()
const
631 List<scalar> coeffs2FSM(pTraits<vector>::nComponents);
657 correctFlowRate_(true),
660 mapMethod_(
"nearestCell"),
682 iNextToLastPlane_(
Zero),
702 Gaussian_(ptf.Gaussian_),
703 fixSeed_(ptf.fixSeed_),
704 continuous_(ptf.continuous_),
705 correctFlowRate_(ptf.correctFlowRate_),
706 interpR_(ptf.interpR_),
707 interpUMean_(ptf.interpUMean_),
708 mapMethod_(ptf.mapMethod_),
712 perturb_(ptf.perturb_),
713 flowRate_(ptf.flowRate_),
714 rndGen_(ptf.rndGen_),
716 invDelta_(ptf.invDelta_),
717 indexPairs_(ptf.indexPairs_),
725 coeffs1FSM_(ptf.coeffs1FSM_),
726 coeffs2FSM_(ptf.coeffs2FSM_),
728 boxFactors2D_(ptf.boxFactors2D_),
729 boxFactors3D_(ptf.boxFactors3D_),
730 iNextToLastPlane_(ptf.iNextToLastPlane_),
732 filterCoeffs_(ptf.filterCoeffs_),
733 filteredBox_(ptf.filteredBox_),
748 fsm_(
dict.getOrDefault(
"fsm", false)),
749 Gaussian_(fsm_ ? false :
dict.getOrDefault(
"Gaussian", true)),
750 fixSeed_(
dict.getOrDefault(
"fixSeed", true)),
751 continuous_(
dict.getOrDefault(
"continuous", false)),
752 correctFlowRate_(
dict.getOrDefault(
"correctFlowRate", true)),
755 mapMethod_(
dict.getOrDefault<
word>(
"mapMethod",
"nearestCell")),
767 rndGen_(fixSeed_ ? 1234 : time(0)),
773 [&](const
Tuple2<label, label>&
x)
775 return min(
x.first(),
x.second()) > 0 ? true :
false;
780 indexPairs_(indexPairs()),
781 R_(interpolateOrRead<symmTensor>(
"R",
dict, interpR_)),
783 UMean_(interpolateOrRead<vector>(
"UMean",
dict, interpUMean_)),
789 [&](
const tensor&
x){return cmptMin(x) > ROOTSMALL ? true : false;}
792 L_(meterToCell(Lbak_)),
813 coeffs1FSM_(fsm_ ? calcCoeffs1FSM() : List<scalar>()),
814 coeffs2FSM_(fsm_ ? calcCoeffs2FSM() : List<scalar>()),
816 boxFactors2D_(initFactors2D()),
817 boxFactors3D_(initFactors3D()),
818 iNextToLastPlane_(initPlaneFactors()),
830 filterCoeffs_(calcFilterCoeffs()),
833 pTraits<vector>::nComponents,
834 List<scalar>(n_.first()*n_.second(),
Zero)
839 ? randomSet<vectorField, vector>(
patch().size())
843 if (correctFlowRate_)
845 flowRate_ = calcFlowRate();
849 if (db().time().isAdjustTimeStep())
852 <<
" # Varying time-step computations are not fully supported #"
856 Info<<
" # turbulentDigitalFilterInlet initialisation completed #" <<
endl;
869 Gaussian_(ptf.Gaussian_),
870 fixSeed_(ptf.fixSeed_),
871 continuous_(ptf.continuous_),
872 correctFlowRate_(ptf.correctFlowRate_),
873 interpR_(ptf.interpR_),
874 interpUMean_(ptf.interpUMean_),
875 mapMethod_(ptf.mapMethod_),
876 curTimeIndex_(ptf.curTimeIndex_),
879 perturb_(ptf.perturb_),
880 flowRate_(ptf.flowRate_),
881 rndGen_(ptf.rndGen_),
883 invDelta_(ptf.invDelta_),
884 indexPairs_(ptf.indexPairs_),
892 coeffs1FSM_(ptf.coeffs1FSM_),
893 coeffs2FSM_(ptf.coeffs2FSM_),
895 boxFactors2D_(ptf.boxFactors2D_),
896 boxFactors3D_(ptf.boxFactors3D_),
897 iNextToLastPlane_(ptf.iNextToLastPlane_),
899 filterCoeffs_(ptf.filterCoeffs_),
900 filteredBox_(ptf.filteredBox_),
915 Gaussian_(ptf.Gaussian_),
916 fixSeed_(ptf.fixSeed_),
917 continuous_(ptf.continuous_),
918 correctFlowRate_(ptf.correctFlowRate_),
919 interpR_(ptf.interpR_),
920 interpUMean_(ptf.interpUMean_),
921 mapMethod_(ptf.mapMethod_),
925 perturb_(ptf.perturb_),
926 flowRate_(ptf.flowRate_),
927 rndGen_(ptf.rndGen_),
929 invDelta_(ptf.invDelta_),
930 indexPairs_(ptf.indexPairs_),
938 coeffs1FSM_(ptf.coeffs1FSM_),
939 coeffs2FSM_(ptf.coeffs2FSM_),
941 boxFactors2D_(ptf.boxFactors2D_),
942 boxFactors3D_(ptf.boxFactors3D_),
943 iNextToLastPlane_(ptf.iNextToLastPlane_),
945 filterCoeffs_(ptf.filterCoeffs_),
946 filteredBox_(ptf.filteredBox_),
960 if (curTimeIndex_ != db().time().
timeIndex())
977 for (
direction dir = 0; dir < pTraits<vector>::nComponents; ++dir)
980 U0_.component(dir)*coeffs1FSM_[dir]
981 +
U.component(dir)*coeffs2FSM_[dir];
991 if (correctFlowRate_)
997 curTimeIndex_ = db().time().timeIndex();
1000 fixedValueFvPatchVectorField::updateCoeffs();
1029 if (!mapMethod_.empty())
1058 const fvPatchFieldMapper& m
1082 turbulentDigitalFilterInletFvPatchVectorField