2010-05-12 13:27:55 +00:00
|
|
|
/*---------------------------------------------------------------------------*\
|
|
|
|
========= |
|
|
|
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
|
|
\\ / O peration |
|
|
|
|
\\ / A nd | Copyright held by original author
|
|
|
|
\\/ M anipulation |
|
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
License
|
|
|
|
This file is part of OpenFOAM.
|
|
|
|
|
|
|
|
OpenFOAM is free software; you can redistribute it and/or modify it
|
|
|
|
under the terms of the GNU General Public License as published by the
|
|
|
|
Free Software Foundation; either version 2 of the License, or (at your
|
|
|
|
option) any later version.
|
|
|
|
|
|
|
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
|
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
|
|
for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with OpenFOAM; if not, write to the Free Software Foundation,
|
|
|
|
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
|
|
|
|
\*---------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
#include "freeSurface.H"
|
|
|
|
#include "primitivePatchInterpolation.H"
|
2010-11-25 13:16:12 +00:00
|
|
|
#include "wedgeFaPatch.H"
|
|
|
|
#include "wallFvPatch.H"
|
|
|
|
#include "wedgeFaPatchFields.H"
|
|
|
|
#include "slipFaPatchFields.H"
|
2010-05-12 13:27:55 +00:00
|
|
|
|
|
|
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
|
|
|
|
|
|
namespace Foam
|
|
|
|
{
|
|
|
|
|
|
|
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
|
|
|
|
|
|
|
void freeSurface::makeInterpolators()
|
|
|
|
{
|
|
|
|
if (debug)
|
|
|
|
{
|
2010-11-25 13:16:12 +00:00
|
|
|
Info<< "freeSurface::makeInterpolators() : "
|
|
|
|
<< "making pathc to patch interpolator"
|
2010-05-12 13:27:55 +00:00
|
|
|
<< endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// It is an error to attempt to recalculate
|
|
|
|
// if the pointer is already set
|
2013-07-18 01:02:34 +00:00
|
|
|
if
|
2010-05-12 13:27:55 +00:00
|
|
|
(
|
2013-07-18 01:02:34 +00:00
|
|
|
interpolatorBAPtr_ ||
|
2010-11-25 13:16:12 +00:00
|
|
|
interpolatorABPtr_
|
2010-05-12 13:27:55 +00:00
|
|
|
)
|
|
|
|
{
|
|
|
|
FatalErrorIn("freeSurface::makeInterpolators()")
|
|
|
|
<< "patch to patch interpolators already exists"
|
2010-11-25 13:16:12 +00:00
|
|
|
<< abort(FatalError);
|
2010-05-12 13:27:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(aPatchID() == -1)
|
|
|
|
{
|
|
|
|
FatalErrorIn("freeSurface::makeInterpolators()")
|
|
|
|
<< "Free surface patch A not defined."
|
|
|
|
<< abort(FatalError);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(bPatchID() == -1)
|
|
|
|
{
|
|
|
|
FatalErrorIn("freeSurface::makeInterpolators()")
|
|
|
|
<< "Free surface patch B not defined."
|
|
|
|
<< abort(FatalError);
|
|
|
|
}
|
|
|
|
|
2010-11-25 13:16:12 +00:00
|
|
|
// patchToPatchInterpolation::setDirectHitTol(1e-2);
|
|
|
|
|
|
|
|
interpolatorBAPtr_ = new IOpatchToPatchInterpolation
|
2010-05-12 13:27:55 +00:00
|
|
|
(
|
2010-11-25 13:16:12 +00:00
|
|
|
IOobject
|
|
|
|
(
|
|
|
|
"baInterpolator",
|
|
|
|
DB().timeName(),
|
|
|
|
mesh(),
|
|
|
|
IOobject::READ_IF_PRESENT,
|
|
|
|
IOobject::AUTO_WRITE
|
|
|
|
),
|
2010-05-12 13:27:55 +00:00
|
|
|
mesh().boundaryMesh()[bPatchID()],
|
|
|
|
mesh().boundaryMesh()[aPatchID()],
|
|
|
|
intersection::VISIBLE
|
|
|
|
// intersection::HALF_RAY
|
|
|
|
);
|
|
|
|
|
2013-07-18 01:02:34 +00:00
|
|
|
|
|
|
|
const scalarField& faceDistBA =
|
2010-11-25 13:16:12 +00:00
|
|
|
interpolatorBAPtr_->faceDistanceToIntersection();
|
|
|
|
|
|
|
|
forAll(faceDistBA, faceI)
|
|
|
|
{
|
|
|
|
if(mag(faceDistBA[faceI] - GREAT) < SMALL)
|
|
|
|
{
|
|
|
|
FatalErrorIn("freeSurface::makeInterpolators()")
|
|
|
|
<< "Error in B-to-A face patchToPatchInterpolation."
|
2013-07-18 01:02:34 +00:00
|
|
|
<< abort(FatalError);
|
2010-11-25 13:16:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-07-18 01:02:34 +00:00
|
|
|
const scalarField& pointDistBA =
|
2010-11-25 13:16:12 +00:00
|
|
|
interpolatorBAPtr_->pointDistanceToIntersection();
|
|
|
|
|
|
|
|
forAll(pointDistBA, pointI)
|
|
|
|
{
|
|
|
|
if(mag(pointDistBA[pointI] - GREAT) < SMALL)
|
|
|
|
{
|
|
|
|
FatalErrorIn("freeSurface::makeInterpolators()")
|
|
|
|
<< "Error in B-to-A point patchToPatchInterpolation."
|
2013-07-18 01:02:34 +00:00
|
|
|
<< abort(FatalError);
|
2010-11-25 13:16:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-05-12 13:27:55 +00:00
|
|
|
|
2010-11-25 13:16:12 +00:00
|
|
|
interpolatorABPtr_ = new IOpatchToPatchInterpolation
|
2010-05-12 13:27:55 +00:00
|
|
|
(
|
2010-11-25 13:16:12 +00:00
|
|
|
IOobject
|
|
|
|
(
|
|
|
|
"abInterpolator",
|
|
|
|
DB().timeName(),
|
|
|
|
mesh(),
|
|
|
|
IOobject::READ_IF_PRESENT,
|
|
|
|
IOobject::AUTO_WRITE
|
|
|
|
),
|
2010-05-12 13:27:55 +00:00
|
|
|
mesh().boundaryMesh()[aPatchID()],
|
|
|
|
mesh().boundaryMesh()[bPatchID()],
|
|
|
|
intersection::VISIBLE
|
|
|
|
// intersection::HALF_RAY
|
|
|
|
);
|
2010-11-25 13:16:12 +00:00
|
|
|
|
|
|
|
|
2013-07-18 01:02:34 +00:00
|
|
|
const scalarField& faceDistAB =
|
2010-11-25 13:16:12 +00:00
|
|
|
interpolatorABPtr_->faceDistanceToIntersection();
|
|
|
|
|
|
|
|
forAll(faceDistAB, faceI)
|
|
|
|
{
|
|
|
|
if(mag(faceDistAB[faceI] - GREAT) < SMALL)
|
|
|
|
{
|
|
|
|
FatalErrorIn("freeSurface::makeInterpolators()")
|
|
|
|
<< "Error in A-to-B face patchToPatchInterpolation."
|
2013-07-18 01:02:34 +00:00
|
|
|
<< abort(FatalError);
|
2010-11-25 13:16:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-07-18 01:02:34 +00:00
|
|
|
const scalarField& pointDistAB =
|
2010-11-25 13:16:12 +00:00
|
|
|
interpolatorABPtr_->pointDistanceToIntersection();
|
|
|
|
|
|
|
|
forAll(pointDistAB, pointI)
|
|
|
|
{
|
|
|
|
if(mag(pointDistAB[pointI] - GREAT)<SMALL)
|
|
|
|
{
|
|
|
|
FatalErrorIn("freeSurface::makeInterpolators()")
|
|
|
|
<< "Error in A-to-B point patchToPatchInterpolation."
|
2013-07-18 01:02:34 +00:00
|
|
|
<< abort(FatalError);
|
2010-11-25 13:16:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Info << "\nCheck A-to-B and B-to-A interpolators" << endl;
|
|
|
|
|
|
|
|
scalar maxDist = max
|
|
|
|
(
|
|
|
|
mag
|
|
|
|
(
|
|
|
|
interpolatorABPtr_->faceInterpolate
|
|
|
|
(
|
|
|
|
vectorField(mesh().boundaryMesh()[aPatchID()]
|
|
|
|
.faceCentres())
|
|
|
|
)
|
|
|
|
- mesh().boundaryMesh()[bPatchID()].faceCentres()
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
scalar maxDistPt = max
|
|
|
|
(
|
|
|
|
mag
|
|
|
|
(
|
|
|
|
interpolatorABPtr_->pointInterpolate
|
|
|
|
(
|
|
|
|
vectorField(mesh().boundaryMesh()[aPatchID()]
|
|
|
|
.localPoints())
|
|
|
|
)
|
|
|
|
- mesh().boundaryMesh()[bPatchID()].localPoints()
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
Info << "A-to-B interpolation error, face: " << maxDist
|
|
|
|
<< ", point: " << maxDistPt << endl;
|
|
|
|
|
|
|
|
|
|
|
|
maxDist = max
|
|
|
|
(
|
|
|
|
mag
|
|
|
|
(
|
|
|
|
interpolatorBAPtr_->faceInterpolate
|
|
|
|
(
|
|
|
|
vectorField
|
|
|
|
(
|
|
|
|
mesh().boundaryMesh()[bPatchID()].faceCentres()
|
|
|
|
)
|
|
|
|
)
|
|
|
|
- mesh().boundaryMesh()[aPatchID()].faceCentres()
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
maxDistPt = max
|
|
|
|
(
|
|
|
|
mag
|
|
|
|
(
|
|
|
|
interpolatorBAPtr_->pointInterpolate
|
|
|
|
(
|
|
|
|
vectorField
|
|
|
|
(
|
|
|
|
mesh().boundaryMesh()[bPatchID()].localPoints()
|
|
|
|
)
|
|
|
|
)
|
|
|
|
- mesh().boundaryMesh()[aPatchID()].localPoints()
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
Info << "B-to-A interpolation error, face: " << maxDist
|
|
|
|
<< ", point: " << maxDistPt << endl;
|
2010-05-12 13:27:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void freeSurface::makeControlPoints()
|
|
|
|
{
|
|
|
|
if (debug)
|
|
|
|
{
|
2010-11-25 13:16:12 +00:00
|
|
|
Info<< "freeSurface::makeControlPoints() : "
|
2010-05-12 13:27:55 +00:00
|
|
|
<< "making control points"
|
|
|
|
<< endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// It is an error to attempt to recalculate
|
|
|
|
// if the pointer is already set
|
|
|
|
if (controlPointsPtr_)
|
|
|
|
{
|
2010-11-25 13:16:12 +00:00
|
|
|
FatalErrorIn("freeSurface::makeInterpolators()")
|
2010-05-12 13:27:55 +00:00
|
|
|
<< "patch to patch interpolators already exists"
|
|
|
|
<< abort(FatalError);
|
|
|
|
}
|
|
|
|
|
|
|
|
IOobject controlPointsHeader
|
|
|
|
(
|
|
|
|
"controlPoints",
|
2010-11-25 13:16:12 +00:00
|
|
|
DB().timeName(),
|
2010-05-12 13:27:55 +00:00
|
|
|
mesh(),
|
|
|
|
IOobject::MUST_READ
|
|
|
|
);
|
|
|
|
|
|
|
|
if (controlPointsHeader.headerOk())
|
|
|
|
{
|
|
|
|
controlPointsPtr_ =
|
|
|
|
new vectorIOField
|
|
|
|
(
|
|
|
|
IOobject
|
|
|
|
(
|
|
|
|
"controlPoints",
|
2010-11-25 13:16:12 +00:00
|
|
|
DB().timeName(),
|
2010-05-12 13:27:55 +00:00
|
|
|
mesh(),
|
|
|
|
IOobject::MUST_READ,
|
|
|
|
IOobject::AUTO_WRITE
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
controlPointsPtr_ =
|
|
|
|
new vectorIOField
|
|
|
|
(
|
|
|
|
IOobject
|
|
|
|
(
|
|
|
|
"controlPoints",
|
2010-11-25 13:16:12 +00:00
|
|
|
DB().timeName(),
|
2010-05-12 13:27:55 +00:00
|
|
|
mesh(),
|
|
|
|
IOobject::NO_READ,
|
|
|
|
IOobject::AUTO_WRITE
|
|
|
|
),
|
|
|
|
aMesh().areaCentres().internalField()
|
|
|
|
);
|
2010-11-25 13:16:12 +00:00
|
|
|
|
|
|
|
initializeControlPointsPosition();
|
2010-05-12 13:27:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void freeSurface::makeMotionPointsMask()
|
|
|
|
{
|
|
|
|
if (debug)
|
|
|
|
{
|
|
|
|
Info<< "freeSurface::makeMotionPointsMask() : "
|
|
|
|
<< "making motion points mask"
|
|
|
|
<< endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// It is an error to attempt to recalculate
|
|
|
|
// if the pointer is already set
|
|
|
|
if (motionPointsMaskPtr_)
|
|
|
|
{
|
|
|
|
FatalErrorIn("freeSurface::motionPointsMask()")
|
|
|
|
<< "motion points mask already exists"
|
|
|
|
<< abort(FatalError);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(aPatchID() == -1)
|
|
|
|
{
|
|
|
|
FatalErrorIn("freeSurface::makeMotionPointsMask()")
|
|
|
|
<< "Free surface patch A not defined."
|
|
|
|
<< abort(FatalError);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-11-25 13:16:12 +00:00
|
|
|
motionPointsMaskPtr_ = new labelList
|
2010-05-12 13:27:55 +00:00
|
|
|
(
|
|
|
|
mesh().boundaryMesh()[aPatchID()].nPoints(),
|
2010-11-25 13:16:12 +00:00
|
|
|
1
|
2010-05-12 13:27:55 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void freeSurface::makeDirections()
|
|
|
|
{
|
|
|
|
if (debug)
|
|
|
|
{
|
|
|
|
Info<< "freeSurface::makeDirections() : "
|
|
|
|
<< "making displacement directions for points and "
|
|
|
|
<< "control points"
|
|
|
|
<< endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// It is an error to attempt to recalculate
|
|
|
|
// if the pointer is already set
|
2013-07-18 01:02:34 +00:00
|
|
|
if
|
2010-05-12 13:27:55 +00:00
|
|
|
(
|
2013-07-18 01:02:34 +00:00
|
|
|
pointsDisplacementDirPtr_ ||
|
2010-05-12 13:27:55 +00:00
|
|
|
facesDisplacementDirPtr_
|
|
|
|
)
|
|
|
|
{
|
|
|
|
FatalErrorIn("freeSurface::makeDirections()")
|
|
|
|
<< "points and control points displacement directions "
|
|
|
|
<< "already exists"
|
|
|
|
<< abort(FatalError);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(aPatchID() == -1)
|
|
|
|
{
|
2010-11-25 13:16:12 +00:00
|
|
|
FatalErrorIn("freeSurface::makeDirections()")
|
2010-05-12 13:27:55 +00:00
|
|
|
<< "Free surface patch A not defined."
|
|
|
|
<< abort(FatalError);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-07-18 01:02:34 +00:00
|
|
|
pointsDisplacementDirPtr_ =
|
2010-05-12 13:27:55 +00:00
|
|
|
new vectorField
|
|
|
|
(
|
|
|
|
mesh().boundaryMesh()[aPatchID()].nPoints(),
|
2010-11-25 13:16:12 +00:00
|
|
|
vector::zero
|
2010-05-12 13:27:55 +00:00
|
|
|
);
|
|
|
|
|
2013-07-18 01:02:34 +00:00
|
|
|
facesDisplacementDirPtr_ =
|
2010-05-12 13:27:55 +00:00
|
|
|
new vectorField
|
|
|
|
(
|
|
|
|
mesh().boundaryMesh()[aPatchID()].size(),
|
2010-11-25 13:16:12 +00:00
|
|
|
vector::zero
|
2010-05-12 13:27:55 +00:00
|
|
|
);
|
|
|
|
|
2010-11-25 13:16:12 +00:00
|
|
|
if(!normalMotionDir())
|
|
|
|
{
|
|
|
|
if(mag(motionDir_) < SMALL)
|
|
|
|
{
|
|
|
|
FatalErrorIn("freeSurface::makeDirections()")
|
|
|
|
<< "Zero motion direction"
|
|
|
|
<< abort(FatalError);
|
|
|
|
}
|
|
|
|
|
|
|
|
facesDisplacementDir() = motionDir_;
|
|
|
|
pointsDisplacementDir() = motionDir_;
|
|
|
|
}
|
2010-05-12 13:27:55 +00:00
|
|
|
|
|
|
|
updateDisplacementDirections();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void freeSurface::makeTotalDisplacement()
|
|
|
|
{
|
|
|
|
if (debug)
|
|
|
|
{
|
|
|
|
Info<< "freeSurface::makeTotalDisplacement() : "
|
|
|
|
<< "making zero total points displacement"
|
|
|
|
<< endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// It is an error to attempt to recalculate
|
|
|
|
// if the pointer is already set
|
|
|
|
if (totalDisplacementPtr_)
|
|
|
|
{
|
|
|
|
FatalErrorIn("freeSurface::makeTotalDisplacement()")
|
|
|
|
<< "total points displacement already exists"
|
|
|
|
<< abort(FatalError);
|
|
|
|
}
|
|
|
|
|
|
|
|
totalDisplacementPtr_ =
|
|
|
|
new vectorIOField
|
|
|
|
(
|
|
|
|
IOobject
|
|
|
|
(
|
|
|
|
"totalDisplacement",
|
2010-11-25 13:16:12 +00:00
|
|
|
DB().timeName(),
|
2010-05-12 13:27:55 +00:00
|
|
|
mesh(),
|
|
|
|
IOobject::NO_READ,
|
|
|
|
IOobject::AUTO_WRITE
|
|
|
|
),
|
|
|
|
vectorField
|
|
|
|
(
|
2013-07-18 01:02:34 +00:00
|
|
|
mesh().boundaryMesh()[aPatchID()].nPoints(),
|
2010-05-12 13:27:55 +00:00
|
|
|
vector::zero
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
2013-07-18 01:02:34 +00:00
|
|
|
|
2010-05-12 13:27:55 +00:00
|
|
|
|
|
|
|
void freeSurface::readTotalDisplacement()
|
|
|
|
{
|
|
|
|
if (debug)
|
|
|
|
{
|
|
|
|
Info<< "freeSurface::readTotalDisplacement() : "
|
|
|
|
<< "reading total points displacement if present"
|
|
|
|
<< endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// It is an error to attempt to recalculate
|
|
|
|
// if the pointer is already set
|
|
|
|
if (totalDisplacementPtr_)
|
|
|
|
{
|
|
|
|
FatalErrorIn("freeSurface::makeTotalDisplacement()")
|
|
|
|
<< "total points displacement already exists"
|
|
|
|
<< abort(FatalError);
|
|
|
|
}
|
|
|
|
|
|
|
|
if
|
|
|
|
(
|
|
|
|
IOobject
|
|
|
|
(
|
|
|
|
"totalDisplacement",
|
2010-11-25 13:16:12 +00:00
|
|
|
DB().timeName(),
|
2010-05-12 13:27:55 +00:00
|
|
|
mesh(),
|
|
|
|
IOobject::MUST_READ,
|
|
|
|
IOobject::AUTO_WRITE
|
|
|
|
).headerOk()
|
|
|
|
)
|
|
|
|
{
|
|
|
|
totalDisplacementPtr_ =
|
|
|
|
new vectorIOField
|
|
|
|
(
|
|
|
|
IOobject
|
|
|
|
(
|
|
|
|
"totalDisplacement",
|
2010-11-25 13:16:12 +00:00
|
|
|
DB().timeName(),
|
2010-05-12 13:27:55 +00:00
|
|
|
mesh(),
|
|
|
|
IOobject::MUST_READ,
|
|
|
|
IOobject::AUTO_WRITE
|
2013-07-18 01:02:34 +00:00
|
|
|
)
|
2010-05-12 13:27:55 +00:00
|
|
|
);
|
2013-07-18 01:02:34 +00:00
|
|
|
}
|
2010-05-12 13:27:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-11-25 13:16:12 +00:00
|
|
|
void freeSurface::makeFaMesh() const
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
|
|
|
if (debug)
|
|
|
|
{
|
|
|
|
Info<< "freeSurface::makeFaMesh() : "
|
|
|
|
<< "making finite area mesh"
|
|
|
|
<< endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
// It is an error to attempt to recalculate
|
|
|
|
// if the pointer is already set
|
|
|
|
if (aMeshPtr_)
|
|
|
|
{
|
|
|
|
FatalErrorIn("freeSurface::makeFaMesh()")
|
|
|
|
<< "finite area mesh already exists"
|
|
|
|
<< abort(FatalError);
|
|
|
|
}
|
|
|
|
|
|
|
|
aMeshPtr_ = new faMesh(mesh());
|
|
|
|
}
|
|
|
|
|
2010-11-25 13:16:12 +00:00
|
|
|
void freeSurface::makeUs() const
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
|
|
|
if (debug)
|
|
|
|
{
|
2010-11-25 13:16:12 +00:00
|
|
|
Info<< "freeSurface::makeUs() : "
|
|
|
|
<< "making free-surface velocity field"
|
2010-05-12 13:27:55 +00:00
|
|
|
<< endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// It is an error to attempt to recalculate
|
|
|
|
// if the pointer is already set
|
2010-11-25 13:16:12 +00:00
|
|
|
if (UsPtr_)
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
2010-11-25 13:16:12 +00:00
|
|
|
FatalErrorIn("freeSurface::makeUs()")
|
|
|
|
<< "free-surface velocity field already exists"
|
2010-05-12 13:27:55 +00:00
|
|
|
<< abort(FatalError);
|
|
|
|
}
|
|
|
|
|
2010-11-25 13:16:12 +00:00
|
|
|
|
|
|
|
wordList patchFieldTypes
|
2010-05-12 13:27:55 +00:00
|
|
|
(
|
2010-11-25 13:16:12 +00:00
|
|
|
aMesh().boundary().size(),
|
|
|
|
zeroGradientFaPatchVectorField::typeName
|
2010-05-12 13:27:55 +00:00
|
|
|
);
|
|
|
|
|
2010-11-25 13:16:12 +00:00
|
|
|
forAll(aMesh().boundary(), patchI)
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
2010-11-25 13:16:12 +00:00
|
|
|
if
|
|
|
|
(
|
|
|
|
aMesh().boundary()[patchI].type()
|
|
|
|
== wedgeFaPatch::typeName
|
|
|
|
)
|
|
|
|
{
|
2013-07-18 01:02:34 +00:00
|
|
|
patchFieldTypes[patchI] =
|
2010-11-25 13:16:12 +00:00
|
|
|
wedgeFaPatchVectorField::typeName;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-07-18 01:02:34 +00:00
|
|
|
label ngbPolyPatchID =
|
2010-11-25 13:16:12 +00:00
|
|
|
aMesh().boundary()[patchI].ngbPolyPatchIndex();
|
2010-05-12 13:27:55 +00:00
|
|
|
|
2010-11-25 13:16:12 +00:00
|
|
|
if (ngbPolyPatchID != -1)
|
|
|
|
{
|
|
|
|
if
|
2010-05-12 13:27:55 +00:00
|
|
|
(
|
2010-11-25 13:16:12 +00:00
|
|
|
mesh().boundary()[ngbPolyPatchID].type()
|
|
|
|
== wallFvPatch::typeName
|
2010-05-12 13:27:55 +00:00
|
|
|
)
|
2010-11-25 13:16:12 +00:00
|
|
|
{
|
|
|
|
patchFieldTypes[patchI] =
|
|
|
|
slipFaPatchVectorField::typeName;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-05-12 13:27:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
UsPtr_ = new areaVectorField
|
|
|
|
(
|
|
|
|
IOobject
|
|
|
|
(
|
|
|
|
"Us",
|
2010-11-25 13:16:12 +00:00
|
|
|
DB().timeName(),
|
2010-05-12 13:27:55 +00:00
|
|
|
mesh(),
|
|
|
|
IOobject::NO_READ,
|
|
|
|
IOobject::NO_WRITE
|
|
|
|
),
|
|
|
|
aMesh(),
|
|
|
|
dimensioned<vector>("Us", dimVelocity, vector::zero),
|
2010-11-25 13:16:12 +00:00
|
|
|
patchFieldTypes
|
2010-05-12 13:27:55 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void freeSurface::makePhis()
|
|
|
|
{
|
|
|
|
if (debug)
|
|
|
|
{
|
|
|
|
Info<< "freeSurface::makePhis() : "
|
|
|
|
<< "making free-surface fluid flux"
|
|
|
|
<< endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// It is an error to attempt to recalculate
|
|
|
|
// if the pointer is already set
|
|
|
|
if (phisPtr_)
|
|
|
|
{
|
|
|
|
FatalErrorIn("freeSurface::makePhis()")
|
|
|
|
<< "free-surface fluid flux already exists"
|
|
|
|
<< abort(FatalError);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
phisPtr_ = new edgeScalarField
|
|
|
|
(
|
|
|
|
IOobject
|
|
|
|
(
|
|
|
|
"phis",
|
2010-11-25 13:16:12 +00:00
|
|
|
DB().timeName(),
|
2010-05-12 13:27:55 +00:00
|
|
|
mesh(),
|
|
|
|
IOobject::NO_READ,
|
|
|
|
IOobject::NO_WRITE
|
|
|
|
),
|
|
|
|
linearEdgeInterpolate(Us()) & aMesh().Le()
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-11-25 13:16:12 +00:00
|
|
|
void freeSurface::makeSurfactConc() const
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
|
|
|
if (debug)
|
|
|
|
{
|
|
|
|
Info<< "freeSurface::makeSurfactConc() : "
|
|
|
|
<< "making free-surface surfactant concentration field"
|
|
|
|
<< endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-07-18 01:02:34 +00:00
|
|
|
// It is an error to attempt to recalculate
|
2010-05-12 13:27:55 +00:00
|
|
|
// if the pointer is already set
|
|
|
|
if (surfactConcPtr_)
|
|
|
|
{
|
2010-11-25 13:16:12 +00:00
|
|
|
FatalErrorIn("freeSurface::makeSurfaceConc()")
|
2010-05-12 13:27:55 +00:00
|
|
|
<< "free-surface surfactant concentratio field already exists"
|
|
|
|
<< abort(FatalError);
|
|
|
|
}
|
|
|
|
|
|
|
|
surfactConcPtr_ = new areaScalarField
|
|
|
|
(
|
|
|
|
IOobject
|
|
|
|
(
|
|
|
|
"Cs",
|
2010-11-25 13:16:12 +00:00
|
|
|
DB().timeName(),
|
2010-05-12 13:27:55 +00:00
|
|
|
mesh(),
|
|
|
|
IOobject::MUST_READ,
|
|
|
|
IOobject::AUTO_WRITE
|
|
|
|
),
|
|
|
|
aMesh()
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-11-25 13:16:12 +00:00
|
|
|
void freeSurface::makeSurfaceTension() const
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
|
|
|
if (debug)
|
|
|
|
{
|
|
|
|
Info<< "freeSurface::makeSurfaceTension() : "
|
|
|
|
<< "making surface tension field"
|
|
|
|
<< endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// It is an error to attempt to recalculate
|
|
|
|
// if the pointer is already set
|
|
|
|
if (surfaceTensionPtr_)
|
|
|
|
{
|
|
|
|
FatalErrorIn("freeSurface::makeSurfaceTension()")
|
|
|
|
<< "surface tension field already exists"
|
|
|
|
<< abort(FatalError);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
surfaceTensionPtr_ = new areaScalarField
|
|
|
|
(
|
|
|
|
IOobject
|
|
|
|
(
|
|
|
|
"surfaceTension",
|
2010-11-25 13:16:12 +00:00
|
|
|
DB().timeName(),
|
2010-05-12 13:27:55 +00:00
|
|
|
mesh(),
|
|
|
|
IOobject::NO_READ,
|
|
|
|
IOobject::NO_WRITE
|
|
|
|
),
|
|
|
|
cleanInterfaceSurfTension()
|
|
|
|
+ surfactant().surfactR()*
|
|
|
|
surfactant().surfactT()*
|
|
|
|
surfactant().surfactSaturatedConc()*
|
|
|
|
log(1.0 - surfactantConcentration()/
|
|
|
|
surfactant().surfactSaturatedConc())
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-11-25 13:16:12 +00:00
|
|
|
void freeSurface::makeSurfactant() const
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
|
|
|
if (debug)
|
|
|
|
{
|
|
|
|
Info<< "freeSurface::makeSurfactant() : "
|
|
|
|
<< "making surfactant properties"
|
|
|
|
<< endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// It is an error to attempt to recalculate
|
|
|
|
// if the pointer is already set
|
|
|
|
if (surfactantPtr_)
|
|
|
|
{
|
|
|
|
FatalErrorIn("freeSurface::makeSurfactant()")
|
|
|
|
<< "surfactant properties already exists"
|
|
|
|
<< abort(FatalError);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-07-18 01:02:34 +00:00
|
|
|
const dictionary& surfactProp =
|
2010-05-12 13:27:55 +00:00
|
|
|
this->subDict("surfactantProperties");
|
|
|
|
|
|
|
|
surfactantPtr_ = new surfactantProperties(surfactProp);
|
|
|
|
}
|
|
|
|
|
2010-11-25 13:16:12 +00:00
|
|
|
|
2010-05-12 13:27:55 +00:00
|
|
|
void freeSurface::makeFluidIndicator()
|
|
|
|
{
|
|
|
|
if (debug)
|
|
|
|
{
|
|
|
|
Info<< "freeSurface::makeFluidIndicator() : "
|
|
|
|
<< "making fluid indicator"
|
|
|
|
<< endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// It is an error to attempt to recalculate
|
|
|
|
// if the pointer is already set
|
|
|
|
if (fluidIndicatorPtr_)
|
|
|
|
{
|
|
|
|
FatalErrorIn("freeSurface::makeFluidIndicator()")
|
|
|
|
<< "fluid indicator already exists"
|
|
|
|
<< abort(FatalError);
|
|
|
|
}
|
|
|
|
|
|
|
|
fluidIndicatorPtr_ = new volScalarField
|
|
|
|
(
|
|
|
|
IOobject
|
|
|
|
(
|
|
|
|
"fluidIndicator",
|
2010-11-25 13:16:12 +00:00
|
|
|
DB().timeName(),
|
2010-05-12 13:27:55 +00:00
|
|
|
mesh(),
|
|
|
|
IOobject::NO_READ,
|
|
|
|
IOobject::NO_WRITE
|
|
|
|
),
|
|
|
|
mesh(),
|
|
|
|
dimensionedScalar("1", dimless, 1.0),
|
|
|
|
zeroGradientFvPatchScalarField::typeName
|
|
|
|
);
|
|
|
|
|
|
|
|
volScalarField& fluidIndicator = *fluidIndicatorPtr_;
|
|
|
|
|
|
|
|
if (twoFluids())
|
|
|
|
{
|
|
|
|
// find start cell
|
|
|
|
label pointOnShadowPatch =
|
|
|
|
mesh().boundaryMesh()[bPatchID()][0][0];
|
|
|
|
|
|
|
|
label startCell = mesh().pointCells()[pointOnShadowPatch][0];
|
|
|
|
|
|
|
|
|
|
|
|
// get cell-cells addressing
|
|
|
|
const labelListList& cellCells = mesh().cellCells();
|
|
|
|
|
|
|
|
SLList<label> slList(startCell);
|
|
|
|
|
|
|
|
while (slList.size())
|
|
|
|
{
|
|
|
|
label curCell = slList.removeHead();
|
|
|
|
|
|
|
|
if (fluidIndicator[curCell] == 1)
|
|
|
|
{
|
|
|
|
fluidIndicator[curCell] = 0.0;
|
|
|
|
|
2010-11-25 13:16:12 +00:00
|
|
|
for (int i = 0; i < cellCells[curCell].size(); i++)
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
|
|
|
slList.append(cellCells[curCell][i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fluidIndicator.correctBoundaryConditions();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
|
|
|
|
2010-11-25 13:16:12 +00:00
|
|
|
const IOpatchToPatchInterpolation& freeSurface::interpolatorAB()
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
|
|
|
if (!interpolatorABPtr_)
|
|
|
|
{
|
|
|
|
makeInterpolators();
|
|
|
|
}
|
2013-07-18 01:02:34 +00:00
|
|
|
|
2010-05-12 13:27:55 +00:00
|
|
|
return *interpolatorABPtr_;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-11-25 13:16:12 +00:00
|
|
|
const IOpatchToPatchInterpolation& freeSurface::interpolatorBA()
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
|
|
|
if (!interpolatorBAPtr_)
|
|
|
|
{
|
|
|
|
makeInterpolators();
|
|
|
|
}
|
2013-07-18 01:02:34 +00:00
|
|
|
|
2010-05-12 13:27:55 +00:00
|
|
|
return *interpolatorBAPtr_;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
vectorField& freeSurface::controlPoints()
|
|
|
|
{
|
|
|
|
if (!controlPointsPtr_)
|
|
|
|
{
|
|
|
|
makeControlPoints();
|
|
|
|
}
|
|
|
|
|
|
|
|
return *controlPointsPtr_;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-11-25 13:16:12 +00:00
|
|
|
labelList& freeSurface::motionPointsMask()
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
|
|
|
if (!motionPointsMaskPtr_)
|
|
|
|
{
|
|
|
|
makeMotionPointsMask();
|
|
|
|
}
|
|
|
|
|
|
|
|
return *motionPointsMaskPtr_;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
vectorField& freeSurface::pointsDisplacementDir()
|
|
|
|
{
|
|
|
|
if (!pointsDisplacementDirPtr_)
|
|
|
|
{
|
|
|
|
makeDirections();
|
|
|
|
}
|
|
|
|
|
|
|
|
return *pointsDisplacementDirPtr_;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
vectorField& freeSurface::facesDisplacementDir()
|
|
|
|
{
|
|
|
|
if (!facesDisplacementDirPtr_)
|
|
|
|
{
|
|
|
|
makeDirections();
|
|
|
|
}
|
|
|
|
|
|
|
|
return *facesDisplacementDirPtr_;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
vectorField& freeSurface::totalDisplacement()
|
|
|
|
{
|
|
|
|
if (!totalDisplacementPtr_)
|
|
|
|
{
|
|
|
|
makeTotalDisplacement();
|
|
|
|
}
|
|
|
|
|
|
|
|
return *totalDisplacementPtr_;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
faMesh& freeSurface::aMesh()
|
|
|
|
{
|
|
|
|
if (!aMeshPtr_)
|
|
|
|
{
|
|
|
|
makeFaMesh();
|
|
|
|
}
|
2013-07-18 01:02:34 +00:00
|
|
|
|
2010-05-12 13:27:55 +00:00
|
|
|
return *aMeshPtr_;
|
|
|
|
}
|
|
|
|
|
2010-11-25 13:16:12 +00:00
|
|
|
const faMesh& freeSurface::aMesh() const
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
2010-11-25 13:16:12 +00:00
|
|
|
if (!aMeshPtr_)
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
2010-11-25 13:16:12 +00:00
|
|
|
makeFaMesh();
|
2010-05-12 13:27:55 +00:00
|
|
|
}
|
2013-07-18 01:02:34 +00:00
|
|
|
|
2010-11-25 13:16:12 +00:00
|
|
|
return *aMeshPtr_;
|
2010-05-12 13:27:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
areaVectorField& freeSurface::Us()
|
|
|
|
{
|
|
|
|
if (!UsPtr_)
|
|
|
|
{
|
|
|
|
makeUs();
|
|
|
|
}
|
2013-07-18 01:02:34 +00:00
|
|
|
|
2010-05-12 13:27:55 +00:00
|
|
|
return *UsPtr_;
|
|
|
|
}
|
|
|
|
|
2010-11-25 13:16:12 +00:00
|
|
|
const areaVectorField& freeSurface::Us() const
|
|
|
|
{
|
|
|
|
if (!UsPtr_)
|
|
|
|
{
|
|
|
|
makeUs();
|
|
|
|
}
|
2013-07-18 01:02:34 +00:00
|
|
|
|
2010-11-25 13:16:12 +00:00
|
|
|
return *UsPtr_;
|
|
|
|
}
|
2010-05-12 13:27:55 +00:00
|
|
|
|
|
|
|
edgeScalarField& freeSurface::Phis()
|
|
|
|
{
|
|
|
|
if (!phisPtr_)
|
|
|
|
{
|
|
|
|
makePhis();
|
|
|
|
}
|
2013-07-18 01:02:34 +00:00
|
|
|
|
2010-05-12 13:27:55 +00:00
|
|
|
return *phisPtr_;
|
|
|
|
}
|
|
|
|
|
|
|
|
areaScalarField& freeSurface::surfactantConcentration()
|
|
|
|
{
|
|
|
|
if (!surfactConcPtr_)
|
|
|
|
{
|
|
|
|
makeSurfactConc();
|
|
|
|
}
|
2013-07-18 01:02:34 +00:00
|
|
|
|
2010-05-12 13:27:55 +00:00
|
|
|
return *surfactConcPtr_;
|
|
|
|
}
|
|
|
|
|
2010-11-25 13:16:12 +00:00
|
|
|
const areaScalarField& freeSurface::surfactantConcentration() const
|
|
|
|
{
|
|
|
|
if (!surfactConcPtr_)
|
|
|
|
{
|
|
|
|
makeSurfactConc();
|
|
|
|
}
|
2013-07-18 01:02:34 +00:00
|
|
|
|
2010-11-25 13:16:12 +00:00
|
|
|
return *surfactConcPtr_;
|
|
|
|
}
|
2010-05-12 13:27:55 +00:00
|
|
|
|
|
|
|
areaScalarField& freeSurface::surfaceTension()
|
|
|
|
{
|
|
|
|
if (!surfaceTensionPtr_)
|
|
|
|
{
|
|
|
|
makeSurfaceTension();
|
|
|
|
}
|
2013-07-18 01:02:34 +00:00
|
|
|
|
2010-05-12 13:27:55 +00:00
|
|
|
return *surfaceTensionPtr_;
|
|
|
|
}
|
|
|
|
|
2010-11-25 13:16:12 +00:00
|
|
|
const areaScalarField& freeSurface::surfaceTension() const
|
|
|
|
{
|
|
|
|
if (!surfaceTensionPtr_)
|
|
|
|
{
|
|
|
|
makeSurfaceTension();
|
|
|
|
}
|
2013-07-18 01:02:34 +00:00
|
|
|
|
2010-11-25 13:16:12 +00:00
|
|
|
return *surfaceTensionPtr_;
|
|
|
|
}
|
2010-05-12 13:27:55 +00:00
|
|
|
|
2010-11-25 13:16:12 +00:00
|
|
|
const surfactantProperties& freeSurface::surfactant() const
|
2010-05-12 13:27:55 +00:00
|
|
|
{
|
|
|
|
if (!surfactantPtr_)
|
|
|
|
{
|
|
|
|
makeSurfactant();
|
|
|
|
}
|
2013-07-18 01:02:34 +00:00
|
|
|
|
2010-05-12 13:27:55 +00:00
|
|
|
return *surfactantPtr_;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const volScalarField& freeSurface::fluidIndicator()
|
2013-07-18 01:02:34 +00:00
|
|
|
{
|
2010-05-12 13:27:55 +00:00
|
|
|
if (!fluidIndicatorPtr_)
|
|
|
|
{
|
|
|
|
makeFluidIndicator();
|
|
|
|
}
|
|
|
|
|
|
|
|
return *fluidIndicatorPtr_;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-11-25 13:16:12 +00:00
|
|
|
tmp<areaVectorField> freeSurface::surfaceTensionGrad()
|
|
|
|
{
|
|
|
|
tmp<areaVectorField> tgrad
|
|
|
|
(
|
|
|
|
new areaVectorField
|
|
|
|
(
|
|
|
|
IOobject
|
|
|
|
(
|
|
|
|
"surfaceTensionGrad",
|
|
|
|
DB().timeName(),
|
|
|
|
mesh(),
|
|
|
|
IOobject::NO_READ,
|
|
|
|
IOobject::NO_WRITE
|
|
|
|
),
|
|
|
|
(-fac::grad(surfactantConcentration())*
|
|
|
|
surfactant().surfactR()*surfactant().surfactT()/
|
|
|
|
(1.0 - surfactantConcentration()/
|
|
|
|
surfactant().surfactSaturatedConc()))()
|
|
|
|
)
|
|
|
|
);
|
2013-07-18 01:02:34 +00:00
|
|
|
|
2010-11-25 13:16:12 +00:00
|
|
|
return tgrad;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-05-12 13:27:55 +00:00
|
|
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
|
|
|
|
|
|
} // End namespace Foam
|
|
|
|
|
|
|
|
// ************************************************************************* //
|