1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | foam-extend: Open Source CFD
4 \\ / O peration | Version: 3.2
5 \\ / A nd | Web: http://www.foam-extend.org
6 \\/ M anipulation | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
9 This file is part of foam-extend.
11 foam-extend is free software: you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation, either version 3 of the License, or (at your
14 option) any later version.
16 foam-extend is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "freeSurface.H"
27 #include "primitivePatchInterpolation.H"
28 #include "wedgeFaPatch.H"
29 #include "wallFvPatch.H"
30 #include "wedgeFaPatchFields.H"
31 #include "slipFaPatchFields.H"
33 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
38 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
40 void freeSurface::makeInterpolators()
44 Info<< "freeSurface::makeInterpolators() : "
45 << "making pathc to patch interpolator"
50 // It is an error to attempt to recalculate
51 // if the pointer is already set
58 FatalErrorIn("freeSurface::makeInterpolators()")
59 << "patch to patch interpolators already exists"
66 FatalErrorIn("freeSurface::makeInterpolators()")
67 << "Free surface patch A not defined."
74 FatalErrorIn("freeSurface::makeInterpolators()")
75 << "Free surface patch B not defined."
79 // patchToPatchInterpolation::setDirectHitTol(1e-2);
81 interpolatorBAPtr_ = new IOpatchToPatchInterpolation
88 IOobject::READ_IF_PRESENT,
91 mesh().boundaryMesh()[bPatchID()],
92 mesh().boundaryMesh()[aPatchID()],
94 // intersection::HALF_RAY
98 const scalarField& faceDistBA =
99 interpolatorBAPtr_->faceDistanceToIntersection();
101 forAll(faceDistBA, faceI)
103 if(mag(faceDistBA[faceI] - GREAT) < SMALL)
105 FatalErrorIn("freeSurface::makeInterpolators()")
106 << "Error in B-to-A face patchToPatchInterpolation."
107 << abort(FatalError);
111 const scalarField& pointDistBA =
112 interpolatorBAPtr_->pointDistanceToIntersection();
114 forAll(pointDistBA, pointI)
116 if(mag(pointDistBA[pointI] - GREAT) < SMALL)
118 FatalErrorIn("freeSurface::makeInterpolators()")
119 << "Error in B-to-A point patchToPatchInterpolation."
120 << abort(FatalError);
125 interpolatorABPtr_ = new IOpatchToPatchInterpolation
132 IOobject::READ_IF_PRESENT,
135 mesh().boundaryMesh()[aPatchID()],
136 mesh().boundaryMesh()[bPatchID()],
137 intersection::VISIBLE
138 // intersection::HALF_RAY
142 const scalarField& faceDistAB =
143 interpolatorABPtr_->faceDistanceToIntersection();
145 forAll(faceDistAB, faceI)
147 if(mag(faceDistAB[faceI] - GREAT) < SMALL)
149 FatalErrorIn("freeSurface::makeInterpolators()")
150 << "Error in A-to-B face patchToPatchInterpolation."
151 << abort(FatalError);
155 const scalarField& pointDistAB =
156 interpolatorABPtr_->pointDistanceToIntersection();
158 forAll(pointDistAB, pointI)
160 if(mag(pointDistAB[pointI] - GREAT)<SMALL)
162 FatalErrorIn("freeSurface::makeInterpolators()")
163 << "Error in A-to-B point patchToPatchInterpolation."
164 << abort(FatalError);
169 Info << "\nCheck A-to-B and B-to-A interpolators" << endl;
175 interpolatorABPtr_->faceInterpolate
177 vectorField(mesh().boundaryMesh()[aPatchID()]
180 - mesh().boundaryMesh()[bPatchID()].faceCentres()
184 scalar maxDistPt = max
188 interpolatorABPtr_->pointInterpolate
190 vectorField(mesh().boundaryMesh()[aPatchID()]
193 - mesh().boundaryMesh()[bPatchID()].localPoints()
197 Info << "A-to-B interpolation error, face: " << maxDist
198 << ", point: " << maxDistPt << endl;
205 interpolatorBAPtr_->faceInterpolate
209 mesh().boundaryMesh()[bPatchID()].faceCentres()
212 - mesh().boundaryMesh()[aPatchID()].faceCentres()
220 interpolatorBAPtr_->pointInterpolate
224 mesh().boundaryMesh()[bPatchID()].localPoints()
227 - mesh().boundaryMesh()[aPatchID()].localPoints()
231 Info << "B-to-A interpolation error, face: " << maxDist
232 << ", point: " << maxDistPt << endl;
236 void freeSurface::makeControlPoints()
240 Info<< "freeSurface::makeControlPoints() : "
241 << "making control points"
246 // It is an error to attempt to recalculate
247 // if the pointer is already set
248 if (controlPointsPtr_)
250 FatalErrorIn("freeSurface::makeInterpolators()")
251 << "patch to patch interpolators already exists"
252 << abort(FatalError);
255 IOobject controlPointsHeader
263 if (controlPointsHeader.headerOk())
291 aMesh().areaCentres().internalField()
294 initializeControlPointsPosition();
299 void freeSurface::makeMotionPointsMask()
303 Info<< "freeSurface::makeMotionPointsMask() : "
304 << "making motion points mask"
309 // It is an error to attempt to recalculate
310 // if the pointer is already set
311 if (motionPointsMaskPtr_)
313 FatalErrorIn("freeSurface::motionPointsMask()")
314 << "motion points mask already exists"
315 << abort(FatalError);
321 FatalErrorIn("freeSurface::makeMotionPointsMask()")
322 << "Free surface patch A not defined."
323 << abort(FatalError);
327 motionPointsMaskPtr_ = new labelList
329 mesh().boundaryMesh()[aPatchID()].nPoints(),
335 void freeSurface::makeDirections()
339 Info<< "freeSurface::makeDirections() : "
340 << "making displacement directions for points and "
346 // It is an error to attempt to recalculate
347 // if the pointer is already set
350 pointsDisplacementDirPtr_ ||
351 facesDisplacementDirPtr_
354 FatalErrorIn("freeSurface::makeDirections()")
355 << "points and control points displacement directions "
357 << abort(FatalError);
363 FatalErrorIn("freeSurface::makeDirections()")
364 << "Free surface patch A not defined."
365 << abort(FatalError);
369 pointsDisplacementDirPtr_ =
372 mesh().boundaryMesh()[aPatchID()].nPoints(),
376 facesDisplacementDirPtr_ =
379 mesh().boundaryMesh()[aPatchID()].size(),
383 if(!normalMotionDir())
385 if(mag(motionDir_) < SMALL)
387 FatalErrorIn("freeSurface::makeDirections()")
388 << "Zero motion direction"
389 << abort(FatalError);
392 facesDisplacementDir() = motionDir_;
393 pointsDisplacementDir() = motionDir_;
396 updateDisplacementDirections();
400 void freeSurface::makeTotalDisplacement()
404 Info<< "freeSurface::makeTotalDisplacement() : "
405 << "making zero total points displacement"
410 // It is an error to attempt to recalculate
411 // if the pointer is already set
412 if (totalDisplacementPtr_)
414 FatalErrorIn("freeSurface::makeTotalDisplacement()")
415 << "total points displacement already exists"
416 << abort(FatalError);
419 totalDisplacementPtr_ =
432 mesh().boundaryMesh()[aPatchID()].nPoints(),
439 void freeSurface::readTotalDisplacement()
443 Info<< "freeSurface::readTotalDisplacement() : "
444 << "reading total points displacement if present"
449 // It is an error to attempt to recalculate
450 // if the pointer is already set
451 if (totalDisplacementPtr_)
453 FatalErrorIn("freeSurface::makeTotalDisplacement()")
454 << "total points displacement already exists"
455 << abort(FatalError);
470 totalDisplacementPtr_ =
486 void freeSurface::makeFaMesh() const
490 Info<< "freeSurface::makeFaMesh() : "
491 << "making finite area mesh"
495 // It is an error to attempt to recalculate
496 // if the pointer is already set
499 FatalErrorIn("freeSurface::makeFaMesh()")
500 << "finite area mesh already exists"
501 << abort(FatalError);
504 aMeshPtr_ = new faMesh(mesh());
507 void freeSurface::makeUs() const
511 Info<< "freeSurface::makeUs() : "
512 << "making free-surface velocity field"
517 // It is an error to attempt to recalculate
518 // if the pointer is already set
521 FatalErrorIn("freeSurface::makeUs()")
522 << "free-surface velocity field already exists"
523 << abort(FatalError);
527 wordList patchFieldTypes
529 aMesh().boundary().size(),
530 zeroGradientFaPatchVectorField::typeName
533 forAll(aMesh().boundary(), patchI)
537 aMesh().boundary()[patchI].type()
538 == wedgeFaPatch::typeName
541 patchFieldTypes[patchI] =
542 wedgeFaPatchVectorField::typeName;
546 label ngbPolyPatchID =
547 aMesh().boundary()[patchI].ngbPolyPatchIndex();
549 if (ngbPolyPatchID != -1)
553 mesh().boundary()[ngbPolyPatchID].type()
554 == wallFvPatch::typeName
557 patchFieldTypes[patchI] =
558 slipFaPatchVectorField::typeName;
565 UsPtr_ = new areaVectorField
576 dimensioned<vector>("Us", dimVelocity, vector::zero),
582 void freeSurface::makePhis()
586 Info<< "freeSurface::makePhis() : "
587 << "making free-surface fluid flux"
592 // It is an error to attempt to recalculate
593 // if the pointer is already set
596 FatalErrorIn("freeSurface::makePhis()")
597 << "free-surface fluid flux already exists"
598 << abort(FatalError);
602 phisPtr_ = new edgeScalarField
612 linearEdgeInterpolate(Us()) & aMesh().Le()
617 void freeSurface::makeSurfactConc() const
621 Info<< "freeSurface::makeSurfactConc() : "
622 << "making free-surface surfactant concentration field"
627 // It is an error to attempt to recalculate
628 // if the pointer is already set
631 FatalErrorIn("freeSurface::makeSurfaceConc()")
632 << "free-surface surfactant concentratio field already exists"
633 << abort(FatalError);
636 surfactConcPtr_ = new areaScalarField
651 void freeSurface::makeSurfaceTension() const
655 Info<< "freeSurface::makeSurfaceTension() : "
656 << "making surface tension field"
661 // It is an error to attempt to recalculate
662 // if the pointer is already set
663 if (surfaceTensionPtr_)
665 FatalErrorIn("freeSurface::makeSurfaceTension()")
666 << "surface tension field already exists"
667 << abort(FatalError);
671 surfaceTensionPtr_ = new areaScalarField
681 cleanInterfaceSurfTension()
682 + surfactant().surfactR()*
683 surfactant().surfactT()*
684 surfactant().surfactSaturatedConc()*
685 log(1.0 - surfactantConcentration()/
686 surfactant().surfactSaturatedConc())
691 void freeSurface::makeSurfactant() const
695 Info<< "freeSurface::makeSurfactant() : "
696 << "making surfactant properties"
701 // It is an error to attempt to recalculate
702 // if the pointer is already set
705 FatalErrorIn("freeSurface::makeSurfactant()")
706 << "surfactant properties already exists"
707 << abort(FatalError);
711 const dictionary& surfactProp =
712 this->subDict("surfactantProperties");
714 surfactantPtr_ = new surfactantProperties(surfactProp);
718 void freeSurface::makeFluidIndicator()
722 Info<< "freeSurface::makeFluidIndicator() : "
723 << "making fluid indicator"
728 // It is an error to attempt to recalculate
729 // if the pointer is already set
730 if (fluidIndicatorPtr_)
732 FatalErrorIn("freeSurface::makeFluidIndicator()")
733 << "fluid indicator already exists"
734 << abort(FatalError);
737 fluidIndicatorPtr_ = new volScalarField
748 dimensionedScalar("1", dimless, 1.0),
749 zeroGradientFvPatchScalarField::typeName
752 volScalarField& fluidIndicator = *fluidIndicatorPtr_;
757 label pointOnShadowPatch =
758 mesh().boundaryMesh()[bPatchID()][0][0];
760 label startCell = mesh().pointCells()[pointOnShadowPatch][0];
763 // get cell-cells addressing
764 const labelListList& cellCells = mesh().cellCells();
766 SLList<label> slList(startCell);
768 while (slList.size())
770 label curCell = slList.removeHead();
772 if (fluidIndicator[curCell] == 1)
774 fluidIndicator[curCell] = 0.0;
776 for (int i = 0; i < cellCells[curCell].size(); i++)
778 slList.append(cellCells[curCell][i]);
784 fluidIndicator.correctBoundaryConditions();
788 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
790 const IOpatchToPatchInterpolation& freeSurface::interpolatorAB()
792 if (!interpolatorABPtr_)
797 return *interpolatorABPtr_;
801 const IOpatchToPatchInterpolation& freeSurface::interpolatorBA()
803 if (!interpolatorBAPtr_)
808 return *interpolatorBAPtr_;
812 vectorField& freeSurface::controlPoints()
814 if (!controlPointsPtr_)
819 return *controlPointsPtr_;
823 labelList& freeSurface::motionPointsMask()
825 if (!motionPointsMaskPtr_)
827 makeMotionPointsMask();
830 return *motionPointsMaskPtr_;
834 vectorField& freeSurface::pointsDisplacementDir()
836 if (!pointsDisplacementDirPtr_)
841 return *pointsDisplacementDirPtr_;
845 vectorField& freeSurface::facesDisplacementDir()
847 if (!facesDisplacementDirPtr_)
852 return *facesDisplacementDirPtr_;
856 vectorField& freeSurface::totalDisplacement()
858 if (!totalDisplacementPtr_)
860 makeTotalDisplacement();
863 return *totalDisplacementPtr_;
867 faMesh& freeSurface::aMesh()
877 const faMesh& freeSurface::aMesh() const
887 areaVectorField& freeSurface::Us()
897 const areaVectorField& freeSurface::Us() const
907 edgeScalarField& freeSurface::Phis()
917 areaScalarField& freeSurface::surfactantConcentration()
919 if (!surfactConcPtr_)
924 return *surfactConcPtr_;
927 const areaScalarField& freeSurface::surfactantConcentration() const
929 if (!surfactConcPtr_)
934 return *surfactConcPtr_;
937 areaScalarField& freeSurface::surfaceTension()
939 if (!surfaceTensionPtr_)
941 makeSurfaceTension();
944 return *surfaceTensionPtr_;
947 const areaScalarField& freeSurface::surfaceTension() const
949 if (!surfaceTensionPtr_)
951 makeSurfaceTension();
954 return *surfaceTensionPtr_;
957 const surfactantProperties& freeSurface::surfactant() const
964 return *surfactantPtr_;
968 const volScalarField& freeSurface::fluidIndicator()
970 if (!fluidIndicatorPtr_)
972 makeFluidIndicator();
975 return *fluidIndicatorPtr_;
979 tmp<areaVectorField> freeSurface::surfaceTensionGrad()
981 tmp<areaVectorField> tgrad
987 "surfaceTensionGrad",
993 (-fac::grad(surfactantConcentration())*
994 surfactant().surfactR()*surfactant().surfactT()/
995 (1.0 - surfactantConcentration()/
996 surfactant().surfactSaturatedConc()))()
1004 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1006 } // End namespace Foam
1008 // ************************************************************************* //