/*---------------------------------------------------------------------------*\ ========= | \\ / 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" #include "faceTetPolyPatch.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // void freeSurface::makeInterpolators() { if (debug) { Info<< "freeSurface::makeInterpolators(): " << "making patch to patch interpolator" << endl; } // It is an error to attempt to recalculate // if the pointer is already set if ( interpolatorABPtr_ || interpolatorBAPtr_ ) { FatalErrorIn("freeSurface::makeInterpolators()") << "patch to patch interpolators already exists" << abort(FatalError); } 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); } interpolatorBAPtr_ = new patchToPatchInterpolation ( mesh().boundaryMesh()[bPatchID()], mesh().boundaryMesh()[aPatchID()], intersection::VISIBLE // intersection::HALF_RAY ); interpolatorABPtr_ = new patchToPatchInterpolation ( mesh().boundaryMesh()[aPatchID()], mesh().boundaryMesh()[bPatchID()], intersection::VISIBLE // intersection::HALF_RAY ); } void freeSurface::makeControlPoints() { if (debug) { Info<< "freeSurface::makeControlPoints(): " << "making control points" << endl; } // It is an error to attempt to recalculate // if the pointer is already set if (controlPointsPtr_) { FatalErrorIn("freeSurface::makeControlPoints()") << "patch to patch interpolators already exists" << abort(FatalError); } IOobject controlPointsHeader ( "controlPoints", time().timeName(), mesh(), IOobject::MUST_READ ); if (controlPointsHeader.headerOk()) { controlPointsPtr_ = new vectorIOField ( IOobject ( "controlPoints", time().timeName(), mesh(), IOobject::MUST_READ, IOobject::AUTO_WRITE ) ); } else { controlPointsPtr_ = new vectorIOField ( IOobject ( "controlPoints", time().timeName(), mesh(), IOobject::NO_READ, IOobject::AUTO_WRITE ), aMesh().areaCentres().internalField() ); } } 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); } motionPointsMaskPtr_ = new scalarField ( mesh().boundaryMesh()[aPatchID()].nPoints(), 1.0 ); } 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 if ( pointsDisplacementDirPtr_ || facesDisplacementDirPtr_ ) { FatalErrorIn("freeSurface::makeDirections()") << "points and control points displacement directions " << "already exists" << abort(FatalError); } if(aPatchID() == -1) { FatalErrorIn("freeSurface::makeMotionPointsMask()") << "Free surface patch A not defined." << abort(FatalError); } pointsDisplacementDirPtr_ = new vectorField ( mesh().boundaryMesh()[aPatchID()].nPoints(), -(g_/mag(g_)).value() ); facesDisplacementDirPtr_ = new vectorField ( mesh().boundaryMesh()[aPatchID()].size(), -(g_/mag(g_)).value() ); 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", time().timeName(), mesh(), IOobject::NO_READ, IOobject::AUTO_WRITE ), vectorField ( mesh().boundaryMesh()[aPatchID()].nPoints(), vector::zero ) ); } 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", time().timeName(), mesh(), IOobject::MUST_READ, IOobject::AUTO_WRITE ).headerOk() ) { totalDisplacementPtr_ = new vectorIOField ( IOobject ( "totalDisplacement", time().timeName(), mesh(), IOobject::MUST_READ, IOobject::AUTO_WRITE ) ); } } void freeSurface::makeFaMesh() { 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()); } void freeSurface::makeMeshMotionSolver() { if (debug) { Info<< "freeSurface::makeMeshMotionSolver() : " << "making mesh motion solver" << endl; } // It is an error to attempt to recalculate // if the pointer is already set if (mSolverPtr_) { FatalErrorIn("freeSurface::makeMeshMotionSolver()") << "mesh motion solver already exists" << abort(FatalError); } mSolverPtr_ = dynamic_cast ( motionSolver::New(mesh()).ptr() ); } void freeSurface::makePatchPointInterpolators() { if (interpolatorAPtr_ || interpolatorBPtr_) { FatalErrorIn("freeSurface::makePatchPointInterpolators()") << "mesh motion solver already exists" << abort(FatalError); } // Make interpolators if(aPatchID() != -1) { interpolatorAPtr_ = new tetPolyPatchInterpolation ( refCast ( meshMotionSolver().motionU().boundaryField() [aPatchID()].patch() ) ); } if(bPatchID() != -1) { interpolatorBPtr_ = new tetPolyPatchInterpolation ( refCast ( meshMotionSolver().motionU().boundaryField() [bPatchID()].patch() ) ); } } void freeSurface::makeUs() { if (debug) { Info<< "freeSurface::makeUs() : " << "making free-surface velocity field" << endl; } // It is an error to attempt to recalculate // if the pointer is already set if (UsPtr_) { FatalErrorIn("freeSurface::makeUs()") << "free-surface velocity field already exists" << abort(FatalError); } UsPtr_ = new areaVectorField ( IOobject ( "Us", time().timeName(), mesh(), IOobject::NO_READ, IOobject::NO_WRITE ), aMesh(), dimensioned("Us", dimVelocity, vector::zero), zeroGradientFaPatchVectorField::typeName ); } 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", time().timeName(), mesh(), IOobject::NO_READ, IOobject::NO_WRITE ), linearEdgeInterpolate(Us()) & aMesh().Le() ); } void freeSurface::makeSurfactConc() { if (debug) { Info<< "freeSurface::makeSurfactConc() : " << "making free-surface surfactant concentration field" << endl; } // It is an error to attempt to recalculate // if the pointer is already set if (surfactConcPtr_) { FatalErrorIn("freeSurface::makeUs()") << "free-surface surfactant concentratio field already exists" << abort(FatalError); } surfactConcPtr_ = new areaScalarField ( IOobject ( "Cs", time().timeName(), mesh(), IOobject::MUST_READ, IOobject::AUTO_WRITE ), aMesh() ); } void freeSurface::makeSurfaceTension() { 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", time().timeName(), mesh(), IOobject::NO_READ, IOobject::NO_WRITE ), cleanInterfaceSurfTension() + surfactant().surfactR()* surfactant().surfactT()* surfactant().surfactSaturatedConc()* log(1.0 - surfactantConcentration()/ surfactant().surfactSaturatedConc()) ); } void freeSurface::makeSurfactant() { 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); } const dictionary& surfactProp = this->subDict("surfactantProperties"); surfactantPtr_ = new surfactantProperties(surfactProp); } 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", time().timeName(), 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