40 Foam::label Foam::turbulentDFSEMInletFvPatchVectorField::seedIterMax_ = 1000;
44 void Foam::turbulentDFSEMInletFvPatchVectorField::writeEddyOBJ()
const
48 OFstream os(db().time().
path()/
"eddyBox.obj");
50 const polyPatch& pp = this->
patch().patch();
51 const labelList& boundaryPoints = pp.boundaryPoints();
52 const pointField& localPoints = pp.localPoints();
54 vector offset = patchNormal_*maxSigmaX_;
57 point p = localPoints[boundaryPoints[i]];
59 os <<
"v " <<
p.x() <<
" " <<
p.y() <<
" " <<
p.z() <<
nl;
64 point p = localPoints[boundaryPoints[i]];
66 os <<
"v " <<
p.x() <<
" " <<
p.y() <<
" " <<
p.z() <<
nl;
89 const Time& time = db().time();
92 time.path()/
"eddies_" +
Foam::name(time.timeIndex()) +
".obj"
95 label pointOffset = 0;
98 const eddy&
e = eddies_[eddyI];
99 pointOffset +=
e.writeSurfaceOBJ(pointOffset, patchNormal_, os);
105 void Foam::turbulentDFSEMInletFvPatchVectorField::writeLumleyCoeffs()
const
112 const fileName valsFile
116 this->db().time().globalPath()
135 const rawIOField<symmTensor> Rexp(io,
false);
137 OFstream os(db().time().
path()/
"lumley_input.out");
154 scalar xi =
cbrt(0.5*iii);
155 scalar eta =
sqrt(-ii/3.0);
163 OFstream os(db().time().
path()/
"lumley_interpolated.out");
180 scalar xi =
cbrt(0.5*iii);
181 scalar eta =
sqrt(-ii/3.0);
190 Foam::turbulentDFSEMInletFvPatchVectorField::patchMapper()
const
195 const fileName samplePointsFile
197 this->db().time().globalPath()
215 const rawIOField<point> samplePoints(io,
false);
219 <<
" Read " << samplePoints.size() <<
" sample points from "
220 << samplePointsFile <<
endl;
227 && mapMethod_ !=
"planarInterpolation"
233 new pointToPointPlanarInterpolation
247 void Foam::turbulentDFSEMInletFvPatchVectorField::initialisePatch()
255 scalar error =
max(
magSqr(patchNormal_ + nf));
260 <<
"Patch " <<
patch().name() <<
" is not planar"
264 patchNormal_ /=
mag(patchNormal_) + ROOTVSMALL;
269 const polyPatch&
patch = this->
patch().patch();
273 DynamicList<label> triToFace(2*
patch.size());
274 DynamicList<scalar> triMagSf(2*
patch.size());
276 DynamicList<face> tris(5);
279 triMagSf.append(0.0);
283 const face&
f =
patch[faceI];
290 triToFace.append(faceI);
298 sumTriMagSf_[i] = 0.0;
306 for (label i = 1; i < triMagSf.size(); i++)
308 triMagSf[i] += triMagSf[i-1];
313 triToFace_.transfer(triToFace);
314 triCumulativeMagSf_.transfer(triMagSf);
317 for (label i = 1; i < sumTriMagSf_.size(); i++)
319 sumTriMagSf_[i] += sumTriMagSf_[i-1];
323 patchArea_ = sumTriMagSf_.last();
326 patchBounds_ = boundBox(
patch.localPoints(),
false);
327 patchBounds_.inflate(0.1);
331 reduce(singleProc_, orOp<bool>());
335 void Foam::turbulentDFSEMInletFvPatchVectorField::initialiseEddyBox()
345 scalar&
s = sigmax_[faceI];
349 s =
min(
s, kappa_*delta_);
354 s =
max(
s, nCellPerEddy_*cellDx[faceI]);
358 maxSigmaX_ =
gMax(sigmax_);
361 v0_ = 2*
gSum(magSf)*maxSigmaX_;
365 Info<<
"Patch: " <<
patch().patch().name() <<
" eddy box:" <<
nl
366 <<
" volume : " << v0_ <<
nl
367 <<
" maxSigmaX : " << maxSigmaX_ <<
nl
381 const polyPatch&
patch = this->
patch().patch();
386 scalar areaFraction = rndGen_.globalPosition<scalar>(0, patchArea_);
392 if (areaFraction >= sumTriMagSf_[i])
403 scalar offset = sumTriMagSf_[procI];
406 if (areaFraction > triCumulativeMagSf_[i] + offset)
414 const face& tf = triFace_[triI];
418 pos.setIndex(triToFace_[triI]);
419 pos.rawPoint() = tri.randomPoint(rndGen_);
426 scalar maxAreaLimit = triCumulativeMagSf_.last();
427 scalar areaFraction = rndGen_.position<scalar>(0, maxAreaLimit);
431 if (areaFraction > triCumulativeMagSf_[i])
439 const face& tf = triFace_[triI];
443 pos.setIndex(triToFace_[triI]);
444 pos.rawPoint() = tri.randomPoint(rndGen_);
451 void Foam::turbulentDFSEMInletFvPatchVectorField::initialiseEddies()
453 DynamicList<eddy> eddies(size());
456 scalar sumVolEddy = 0;
457 scalar sumVolEddyAllProc = 0;
459 while (sumVolEddyAllProc/v0_ < d_)
464 while (
search && iter++ < seedIterMax_)
468 label faceI =
pos.index();
477 rndGen_.position<scalar>(-maxSigmaX_, maxSigmaX_),
484 if (
e.patchFaceI() != -1)
487 sumVolEddy +=
e.volume();
497 sumVolEddyAllProc =
returnReduce(sumVolEddy, sumOp<scalar>());
499 eddies_.transfer(eddies);
501 nEddy_ = eddies_.size();
505 Pout<<
"Patch:" <<
patch().patch().name();
512 Pout<<
" seeded:" << nEddy_ <<
" eddies" <<
endl;
515 reduce(nEddy_, sumOp<label>());
519 Info<<
"Turbulent DFSEM patch: " <<
patch().name()
520 <<
" seeded " << nEddy_ <<
" eddies with total volume "
527 <<
"Patch: " <<
patch().patch().name()
528 <<
" on field " << internalField().name()
529 <<
": No eddies seeded - please check your set-up" <<
endl;
534 void Foam::turbulentDFSEMInletFvPatchVectorField::convectEddies
545 eddy&
e = eddies_[eddyI];
546 e.move(deltaT*(UMean_ & patchNormal_));
548 const scalar position0 =
e.x();
551 if (position0 > maxSigmaX_)
556 while (
search && iter++ < seedIterMax_)
560 label faceI =
pos.index();
566 position0 - floor(position0/maxSigmaX_)*maxSigmaX_,
572 if (
e.patchFaceI() != -1)
582 reduce(nRecycled, sumOp<label>());
584 if (
debug && nRecycled > 0)
586 Info<<
"Patch: " <<
patch().patch().name() <<
" recycled "
587 << nRecycled <<
" eddies" <<
endl;
592 Foam::vector Foam::turbulentDFSEMInletFvPatchVectorField::uDashEddy
594 const List<eddy>& eddies,
595 const point& patchFaceCf
602 const eddy&
e = eddies[
k];
603 uDash +=
e.uDash(patchFaceCf, patchNormal_);
610 void Foam::turbulentDFSEMInletFvPatchVectorField::calcOverlappingProcEddies
612 List<List<eddy>>& overlappingEddies
629 const eddy&
e = eddies_[i];
632 point x =
e.position(patchNormal_);
633 boundBox ebb =
e.bounds();
642 if (ebb.overlaps(patchBBs[procI]))
644 dynSendMap[procI].append(i);
653 sendMap[procI].transfer(dynSendMap[procI]);
676 forAll(constructMap, procI)
682 constructMap[procI].setSize(nRecv);
684 for (label i = 0; i < nRecv; i++)
686 constructMap[procI][i] = segmentI++;
691 mapDistribute map(segmentI, std::move(sendMap), std::move(constructMap));
697 const labelList& sendElems = map.subMap()[domain];
701 List<eddy> subEddies(UIndirectList<eddy>(eddies_, sendElems));
703 UOPstream toDomain(domain, pBufs);
705 toDomain<< subEddies;
710 pBufs.finishedSends();
715 const labelList& recvElems = map.constructMap()[domain];
719 UIPstream str(domain, pBufs);
721 str >> overlappingEddies[domain];
746 mapMethod_(
"nearestCell"),
748 interpolateR_(
false),
749 interpolateL_(
false),
750 interpolateU_(
false),
759 triCumulativeMagSf_(),
767 sigmax_(size(),
Zero),
791 perturb_(ptf.perturb_),
792 mapMethod_(ptf.mapMethod_),
794 interpolateR_(ptf.interpolateR_),
795 interpolateL_(ptf.interpolateL_),
796 interpolateU_(ptf.interpolateU_),
802 patchArea_(ptf.patchArea_),
803 triFace_(ptf.triFace_),
804 triToFace_(ptf.triToFace_),
805 triCumulativeMagSf_(ptf.triCumulativeMagSf_),
806 sumTriMagSf_(ptf.sumTriMagSf_),
808 eddies_(ptf.eddies_),
809 nCellPerEddy_(ptf.nCellPerEddy_),
810 patchNormal_(ptf.patchNormal_),
812 rndGen_(ptf.rndGen_),
813 sigmax_(ptf.sigmax_, mapper),
814 maxSigmaX_(ptf.maxSigmaX_),
817 patchBounds_(ptf.patchBounds_),
818 singleProc_(ptf.singleProc_),
819 writeEddies_(ptf.writeEddies_)
832 delta_(
dict.
get<scalar>(
"delta")),
842 R_(interpolateOrRead<symmTensor>(
"R",
dict, interpolateR_)),
843 L_(interpolateOrRead<scalar>(
"L",
dict, interpolateL_)),
844 U_(interpolateOrRead<vector>(
"U",
dict, interpolateU_)),
850 triCumulativeMagSf_(),
858 sigmax_(size(),
Zero),
886 perturb_(ptf.perturb_),
887 mapMethod_(ptf.mapMethod_),
889 interpolateR_(ptf.interpolateR_),
890 interpolateL_(ptf.interpolateL_),
891 interpolateU_(ptf.interpolateU_),
897 patchArea_(ptf.patchArea_),
898 triFace_(ptf.triFace_),
899 triToFace_(ptf.triToFace_),
900 triCumulativeMagSf_(ptf.triCumulativeMagSf_),
901 sumTriMagSf_(ptf.sumTriMagSf_),
903 eddies_(ptf.eddies_),
904 nCellPerEddy_(ptf.nCellPerEddy_),
905 patchNormal_(ptf.patchNormal_),
907 rndGen_(ptf.rndGen_),
908 sigmax_(ptf.sigmax_),
909 maxSigmaX_(ptf.maxSigmaX_),
912 patchBounds_(ptf.patchBounds_),
913 singleProc_(ptf.singleProc_),
914 writeEddies_(ptf.writeEddies_)
930 perturb_(ptf.perturb_),
931 mapMethod_(ptf.mapMethod_),
933 interpolateR_(ptf.interpolateR_),
934 interpolateL_(ptf.interpolateL_),
935 interpolateU_(ptf.interpolateU_),
941 patchArea_(ptf.patchArea_),
942 triFace_(ptf.triFace_),
943 triToFace_(ptf.triToFace_),
944 triCumulativeMagSf_(ptf.triCumulativeMagSf_),
945 sumTriMagSf_(ptf.sumTriMagSf_),
947 eddies_(ptf.eddies_),
948 nCellPerEddy_(ptf.nCellPerEddy_),
949 patchNormal_(ptf.patchNormal_),
951 rndGen_(ptf.rndGen_),
952 sigmax_(ptf.sigmax_),
953 maxSigmaX_(ptf.maxSigmaX_),
956 patchBounds_(ptf.patchBounds_),
957 singleProc_(ptf.singleProc_),
958 writeEddies_(ptf.writeEddies_)
979 <<
"Reynolds stress " <<
R <<
" at face " << facei
980 <<
" does not obey the constraint: R_xx > 0"
984 scalar a_xx =
sqrt(
R.xx());
986 scalar a_xy =
R.xy()/a_xx;
988 scalar a_yy_2 =
R.yy() -
sqr(a_xy);
993 <<
"Reynolds stress " <<
R <<
" at face " << facei
994 <<
" leads to an invalid Cholesky decomposition due to the "
995 <<
"constraint R_yy - sqr(a_xy) >= 0"
1001 scalar a_xz =
R.xz()/a_xx;
1003 scalar a_yz = (
R.yz() - a_xy*a_xz)*a_yy;
1005 scalar a_zz_2 =
R.zz() -
sqr(a_xz) -
sqr(a_yz);
1010 <<
"Reynolds stress " <<
R <<
" at face " << facei
1011 <<
" leads to an invalid Cholesky decomposition due to the "
1012 <<
"constraint R_zz - sqr(a_xz) - sqr(a_yz) >= 0"
1021 <<
" a_xx:" << a_xx <<
" a_xy:" << a_xy <<
" a_xz:" << a_xy
1022 <<
" a_yy:" << a_yy <<
" a_yz:" << a_yz
1058 refCast<const turbulentDFSEMInletFvPatchVectorField>(ptf);
1060 R_.rmap(dfsemptf.R_, addr);
1061 L_.rmap(dfsemptf.L_, addr);
1062 U_.rmap(dfsemptf.U_, addr);
1067 sigmax_.rmap(dfsemptf.sigmax_, addr);
1078 if (curTimeIndex_ == -1)
1082 initialiseEddyBox();
1088 if (curTimeIndex_ != db().time().
timeIndex())
1092 label
n = eddies_.size();
1097 const scalar deltaT = db().time().deltaTValue();
1100 convectEddies(deltaT);
1111 const scalar FACTOR = 2;
1121 U[faceI] +=
c*uDashEddy(eddies_, Cf[faceI]);
1129 U[faceI] +=
c*uDashEddy(eddies_, Cf[faceI]);
1134 calcOverlappingProcEddies(overlappingEddies);
1136 forAll(overlappingEddies, procI)
1138 const List<eddy>& eddies = overlappingEddies[procI];
1147 U[faceI] +=
c*uDashEddy(eddies, Cf[faceI]);
1155 gSum((UMean_ & patchNormal_)*
patch().magSf())
1162 Info<<
"Patch:" <<
patch().patch().name()
1166 curTimeIndex_ = db().time().timeIndex();
1173 if (
debug && db().time().writeTime())
1175 writeLumleyCoeffs();
1179 fixedValueFvPatchVectorField::updateCoeffs();
1186 writeEntry(
"value", os);
1209 if (!mapMethod_.empty())