55 Foam::isoAdvection::isoAdvection
98 nAlphaBounds_(dict_.getOrDefault<label>(
"nAlphaBounds", 3)),
99 isoFaceTol_(dict_.getOrDefault<scalar>(
"isoFaceTol", 1
e-8)),
100 surfCellTol_(dict_.getOrDefault<scalar>(
"surfCellTol", 1
e-8)),
101 writeIsoFacesToFile_(dict_.getOrDefault(
"writeIsoFaces", false)),
104 surfCells_(label(0.2*mesh_.nCells())),
107 bsFaces_(label(0.2*mesh_.nBoundaryFaces())),
108 bsx0_(bsFaces_.size()),
109 bsn0_(bsFaces_.size()),
110 bsUn0_(bsFaces_.size()),
113 porosityEnabled_(dict_.getOrDefault<
bool>(
"porosityEnabled", false)),
114 porosityPtr_(nullptr),
117 procPatchLabels_(mesh_.
boundary().size()),
118 surfaceCellFacesOnProcPatches_(0)
138 setProcessorPatches();
146 "porosityProperties",
157 if (porosityEnabled_)
170 <<
"Porosity field has values <= 0 or > 1"
177 <<
"Porosity enabled in constant/porosityProperties "
178 <<
"but no porosity field is found in object registry."
187 void Foam::isoAdvection::setProcessorPatches()
189 const polyBoundaryMesh&
patches = mesh_.boundaryMesh();
190 surfaceCellFacesOnProcPatches_.
clear();
191 surfaceCellFacesOnProcPatches_.resize(
patches.size());
194 procPatchLabels_.clear();
199 isA<processorPolyPatch>(
patches[patchi])
203 procPatchLabels_.append(patchi);
209 void Foam::isoAdvection::extendMarkedCells
215 bitSet markedFace(mesh_.nFaces());
217 for (
const label celli : markedCell)
219 markedFace.set(mesh_.cells()[celli]);
225 for (label facei = 0; facei < mesh_.nInternalFaces(); ++facei)
227 if (markedFace.test(facei))
229 markedCell.set(mesh_.faceOwner()[facei]);
230 markedCell.set(mesh_.faceNeighbour()[facei]);
233 for (label facei = mesh_.nInternalFaces(); facei < mesh_.nFaces(); ++facei)
235 if (markedFace.test(facei))
237 markedCell.set(mesh_.faceOwner()[facei]);
243 void Foam::isoAdvection::timeIntegratedFlux()
247 const scalar dt = mesh_.time().deltaTValue();
250 interpolationCellPoint<vector> UInterp(U_);
253 label nSurfaceCells = 0;
261 const scalarField& magSfIn = mesh_.magSf().primitiveField();
265 const cellList& cellFaces = mesh_.cells();
266 const labelList& own = mesh_.faceOwner();
270 DynamicList<List<point>> isoFacePts;
271 const DynamicField<label>& interfaceLabels = surf_->interfaceLabels();
277 const label celli = interfaceLabels[i];
278 const point x0(surf_->centre()[celli]);
280 Un0[i] = UInterp.interpolate(x0, celli) & n0;
284 if (porosityEnabled_)
288 const label celli = interfaceLabels[i];
289 Un0[i] /= porosityPtr_->primitiveField()[celli];
294 forAll(interfaceLabels, i)
296 const label celli = interfaceLabels[i];
297 if (
mag(surf_->normal()[celli]) != 0)
302 surfCells_.append(celli);
303 const point x0(surf_->centre()[celli]);
307 <<
"\n------------ Cell " << celli <<
" with alpha1 = "
308 << alpha1In_[celli] <<
" and 1-alpha1 = "
309 << 1.0 - alpha1In_[celli] <<
" ------------"
315 const cell& celliFaces = cellFaces[celli];
316 for (
const label facei : celliFaces)
318 if (mesh_.isInternalFace(facei))
320 bool isDownwindFace =
false;
322 if (celli == own[facei])
324 if (phiIn[facei] >= 0)
326 isDownwindFace =
true;
331 if (phiIn[facei] < 0)
333 isDownwindFace =
true;
339 dVfIn[facei] = advectFace_.timeIntegratedFaceFlux
354 bsFaces_.append(facei);
357 bsUn0_.append(Un0[i]);
367 const polyBoundaryMesh& boundaryMesh = mesh_.boundaryMesh();
368 const surfaceScalarField::Boundary&
phib = phi_.boundaryField();
369 const surfaceScalarField::Boundary& magSfb = mesh_.magSf().boundaryField();
370 surfaceScalarField::Boundary& dVfb = dVf_.boundaryFieldRef();
371 const label nInternalFaces = mesh_.nInternalFaces();
377 const label facei = bsFaces_[i];
378 const label patchi = boundaryMesh.patchID()[facei - nInternalFaces];
379 const label start = boundaryMesh[patchi].start();
381 if (!
phib[patchi].empty())
383 const label patchFacei = facei - start;
384 const scalar phiP =
phib[patchi][patchFacei];
388 const scalar magSf = magSfb[patchi][patchFacei];
390 dVfb[patchi][patchFacei] = advectFace_.timeIntegratedFaceFlux
403 checkIfOnProcPatch(facei);
409 syncProcPatches(dVf_, phi_);
411 writeIsoFaces(isoFacePts);
413 DebugInfo <<
"Number of isoAdvector surface cells = "
418 void Foam::isoAdvection::setDownwindFaces
421 DynamicLabelList& downwindFaces
427 const labelList& own = mesh_.faceOwner();
429 const cell&
c =
cells[celli];
431 downwindFaces.
clear();
434 for (
const label facei:
c)
437 const scalar
phi = faceValue(phi_, facei);
439 if (own[facei] == celli)
443 downwindFaces.append(facei);
448 downwindFaces.append(facei);
452 downwindFaces.shrink();
456 Foam::scalar Foam::isoAdvection::netFlux
465 const cell&
c = mesh_.cells()[celli];
468 const labelList& own = mesh_.faceOwner();
470 for (
const label facei :
c)
472 const scalar dVff = faceValue(dVf, facei);
474 if (own[facei] == celli)
492 bool returnSyncedFaces
495 DynamicLabelList syncedFaces(0);
496 const polyBoundaryMesh&
patches = mesh_.boundaryMesh();
503 for (
const label patchi : procPatchLabels_)
505 const processorPolyPatch& procPatch =
506 refCast<const processorPolyPatch>(
patches[patchi]);
508 UOPstream toNbr(procPatch.neighbProcNo(), pBufs);
509 const scalarField& pFlux = dVf.boundaryField()[patchi];
511 const List<label>& surfCellFacesOnProcPatch =
512 surfaceCellFacesOnProcPatches_[patchi];
514 const UIndirectList<scalar> dVfPatch
517 surfCellFacesOnProcPatch
520 toNbr << surfCellFacesOnProcPatch << dVfPatch;
523 pBufs.finishedSends();
527 for (
const label patchi : procPatchLabels_)
529 const processorPolyPatch& procPatch =
530 refCast<const processorPolyPatch>(
patches[patchi]);
532 UIPstream fromNeighb(procPatch.neighbProcNo(), pBufs);
534 List<scalar> nbrdVfs;
536 fromNeighb >> faceIDs >> nbrdVfs;
537 if (returnSyncedFaces)
539 List<label> syncedFaceI(faceIDs);
540 for (label& faceI : syncedFaceI)
542 faceI += procPatch.start();
544 syncedFaces.append(syncedFaceI);
549 Pout<<
"Received at time = " << mesh_.time().value()
550 <<
": surfCellFacesOnProcPatch = " << faceIDs <<
nl
551 <<
"Received at time = " << mesh_.time().value()
552 <<
": dVfPatch = " << nbrdVfs <<
endl;
556 scalarField& localFlux = dVf.boundaryFieldRef()[patchi];
560 const label facei = faceIDs[i];
561 localFlux[facei] = - nbrdVfs[i];
562 if (
debug &&
mag(localFlux[facei] + nbrdVfs[i]) > ROOTVSMALL)
564 Pout<<
"localFlux[facei] = " << localFlux[facei]
565 <<
" and nbrdVfs[i] = " << nbrdVfs[i]
566 <<
" for facei = " << facei <<
endl;
574 forAll(procPatchLabels_, patchLabeli)
576 const label patchi = procPatchLabels_[patchLabeli];
577 const scalarField& localFlux = dVf.boundaryField()[patchi];
578 Pout<<
"time = " << mesh_.time().value() <<
": localFlux = "
579 << localFlux <<
endl;
584 forAll(surfaceCellFacesOnProcPatches_, patchi)
586 surfaceCellFacesOnProcPatches_[patchi].clear();
594 void Foam::isoAdvection::checkIfOnProcPatch(
const label facei)
596 if (!mesh_.isInternalFace(facei))
598 const polyBoundaryMesh& pbm = mesh_.boundaryMesh();
599 const label patchi = pbm.patchID()[facei - mesh_.nInternalFaces()];
601 if (isA<processorPolyPatch>(pbm[patchi]) && !pbm[patchi].empty())
603 const label patchFacei = pbm[patchi].whichFace(facei);
604 surfaceCellFacesOnProcPatches_[patchi].append(patchFacei);
610 void Foam::isoAdvection::applyBruteForceBounding()
613 bool alpha1Changed =
false;
615 const scalar snapAlphaTol = dict_.getOrDefault<scalar>(
"snapTol", 0);
616 if (snapAlphaTol > 0)
620 *
pos0(alpha1_ - snapAlphaTol)
621 *
neg0(alpha1_ - (1.0 - snapAlphaTol))
622 +
pos0(alpha1_ - (1.0 - snapAlphaTol));
624 alpha1Changed =
true;
627 if (dict_.getOrDefault(
"clip",
true))
629 alpha1_ =
min(scalar(1),
max(scalar(0), alpha1_));
630 alpha1Changed =
true;
635 alpha1_.correctBoundaryConditions();
642 if (!mesh_.time().writeTime())
return;
644 if (dict_.getOrDefault(
"writeSurfCells",
false))
651 mesh_.time().timeName(),
657 cSet.insert(surfCells_);
666 const DynamicList<List<point>>& faces
669 if (!writeIsoFacesToFile_ || !mesh_.time().writeTime())
return;
672 const fileName outputFile
674 mesh_.time().globalPath()
676 /
word::printf(
"isoFaces_%012d.obj", mesh_.time().timeIndex())
688 mkDir(outputFile.path());
689 OBJstream
os(outputFile);
690 Info<<
nl <<
"isoAdvection: writing iso faces to file: "
694 forAll(allProcFaces, proci)
696 const DynamicList<List<point>>& procFacePts =
699 for (
const List<point>& facePts : procFacePts)
701 if (facePts.size() !=
f.size())
713 mkDir(outputFile.path());
714 OBJstream
os(outputFile);
715 Info<<
nl <<
"isoAdvection: writing iso faces to file: "
719 for (
const List<point>& facePts : faces)
721 if (facePts.size() !=
f.size())