multiphase: Rationalised alphaContactAngle handling
Alpha contact angle boundaries are now specified in the following way
for multiphase solvers (i.e., multiphaseInterFoam,
compressibleMultiphaseInterFoam, and multiphaseEulerFoam):
boundaryField
{
wall
{
type alphaContactAngle;
contactAngleProperties
{
water
{
// Constant contact angle
theta0 90;
}
oil
{
// Dynamic contact angle
theta0 90;
uTheta 1;
thetaA 125;
thetaR 85;
}
}
value uniform 0;
}
}
All solvers now share the same implementation of the alphaContactAngle
boundary condition and the contact angle correction algorithm.
If alpha contact angle boundary conditions are used they must be
specified for all phases or an error will result. The consistency of the
input will also be checked. The angles given for water in the alpha.air
file must be 180 degrees minus the angles given for air in the
alpha.water file.
This commit is contained in:
@ -1,5 +1,4 @@
|
|||||||
phaseModel/phaseModel.C
|
phaseModel/phaseModel.C
|
||||||
alphaContactAngle/alphaContactAngleFvPatchScalarField.C
|
|
||||||
compressibleMultiphaseMixture.C
|
compressibleMultiphaseMixture.C
|
||||||
|
|
||||||
LIB = $(FOAM_LIBBIN)/libcompressibleMultiphaseMixture
|
LIB = $(FOAM_LIBBIN)/libcompressibleMultiphaseMixture
|
||||||
|
|||||||
@ -1,11 +1,13 @@
|
|||||||
EXE_INC = \
|
EXE_INC = \
|
||||||
-I$(LIB_SRC)/physicalProperties/lnInclude \
|
-I$(LIB_SRC)/physicalProperties/lnInclude \
|
||||||
|
-I$(LIB_SRC)/multiphaseModels/multiphaseProperties/lnInclude \
|
||||||
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
|
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
|
||||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||||
-I$(LIB_SRC)/meshTools/lnInclude
|
-I$(LIB_SRC)/meshTools/lnInclude
|
||||||
|
|
||||||
LIB_LIBS = \
|
LIB_LIBS = \
|
||||||
-lfluidThermophysicalModels \
|
-lfluidThermophysicalModels \
|
||||||
|
-lmultiphaseProperties \
|
||||||
-lspecie \
|
-lspecie \
|
||||||
-lfiniteVolume \
|
-lfiniteVolume \
|
||||||
-lmeshTools
|
-lmeshTools
|
||||||
|
|||||||
@ -1,145 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration | Website: https://openfoam.org
|
|
||||||
\\ / A nd | Copyright (C) 2013-2021 OpenFOAM Foundation
|
|
||||||
\\/ 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 3 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, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "alphaContactAngleFvPatchScalarField.H"
|
|
||||||
#include "addToRunTimeSelectionTable.H"
|
|
||||||
#include "fvPatchFieldMapper.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
alphaContactAngleFvPatchScalarField::interfaceThetaProps::interfaceThetaProps
|
|
||||||
(
|
|
||||||
Istream& is
|
|
||||||
)
|
|
||||||
:
|
|
||||||
theta0_(readScalar(is)),
|
|
||||||
uTheta_(readScalar(is)),
|
|
||||||
thetaA_(readScalar(is)),
|
|
||||||
thetaR_(readScalar(is))
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
Istream& operator>>
|
|
||||||
(
|
|
||||||
Istream& is,
|
|
||||||
alphaContactAngleFvPatchScalarField::interfaceThetaProps& tp
|
|
||||||
)
|
|
||||||
{
|
|
||||||
is >> tp.theta0_ >> tp.uTheta_ >> tp.thetaA_ >> tp.thetaR_;
|
|
||||||
return is;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Ostream& operator<<
|
|
||||||
(
|
|
||||||
Ostream& os,
|
|
||||||
const alphaContactAngleFvPatchScalarField::interfaceThetaProps& tp
|
|
||||||
)
|
|
||||||
{
|
|
||||||
os << tp.theta0_ << token::SPACE
|
|
||||||
<< tp.uTheta_ << token::SPACE
|
|
||||||
<< tp.thetaA_ << token::SPACE
|
|
||||||
<< tp.thetaR_;
|
|
||||||
|
|
||||||
return os;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
alphaContactAngleFvPatchScalarField::alphaContactAngleFvPatchScalarField
|
|
||||||
(
|
|
||||||
const fvPatch& p,
|
|
||||||
const DimensionedField<scalar, volMesh>& iF
|
|
||||||
)
|
|
||||||
:
|
|
||||||
zeroGradientFvPatchScalarField(p, iF)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
alphaContactAngleFvPatchScalarField::alphaContactAngleFvPatchScalarField
|
|
||||||
(
|
|
||||||
const fvPatch& p,
|
|
||||||
const DimensionedField<scalar, volMesh>& iF,
|
|
||||||
const dictionary& dict
|
|
||||||
)
|
|
||||||
:
|
|
||||||
zeroGradientFvPatchScalarField(p, iF),
|
|
||||||
thetaProps_(dict.lookup("thetaProperties"))
|
|
||||||
{
|
|
||||||
evaluate();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
alphaContactAngleFvPatchScalarField::alphaContactAngleFvPatchScalarField
|
|
||||||
(
|
|
||||||
const alphaContactAngleFvPatchScalarField& gcpsf,
|
|
||||||
const fvPatch& p,
|
|
||||||
const DimensionedField<scalar, volMesh>& iF,
|
|
||||||
const fvPatchFieldMapper& mapper
|
|
||||||
)
|
|
||||||
:
|
|
||||||
zeroGradientFvPatchScalarField(gcpsf, p, iF, mapper),
|
|
||||||
thetaProps_(gcpsf.thetaProps_)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
alphaContactAngleFvPatchScalarField::alphaContactAngleFvPatchScalarField
|
|
||||||
(
|
|
||||||
const alphaContactAngleFvPatchScalarField& gcpsf,
|
|
||||||
const DimensionedField<scalar, volMesh>& iF
|
|
||||||
)
|
|
||||||
:
|
|
||||||
zeroGradientFvPatchScalarField(gcpsf, iF),
|
|
||||||
thetaProps_(gcpsf.thetaProps_)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
void alphaContactAngleFvPatchScalarField::write(Ostream& os) const
|
|
||||||
{
|
|
||||||
fvPatchScalarField::write(os);
|
|
||||||
writeEntry(os, "thetaProperties", thetaProps_);
|
|
||||||
writeEntry(os, "value", *this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
makePatchTypeField
|
|
||||||
(
|
|
||||||
fvPatchScalarField,
|
|
||||||
alphaContactAngleFvPatchScalarField
|
|
||||||
);
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,206 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration | Website: https://openfoam.org
|
|
||||||
\\ / A nd | Copyright (C) 2013-2021 OpenFOAM Foundation
|
|
||||||
\\/ 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 3 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, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Class
|
|
||||||
Foam::alphaContactAngleFvPatchScalarField
|
|
||||||
|
|
||||||
Description
|
|
||||||
Contact-angle boundary condition for multi-phase interface-capturing
|
|
||||||
simulations. Used in conjunction with multiphaseMixture.
|
|
||||||
|
|
||||||
SourceFiles
|
|
||||||
alphaContactAngleFvPatchScalarField.C
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef alphaContactAngleFvPatchScalarField_H
|
|
||||||
#define alphaContactAngleFvPatchScalarField_H
|
|
||||||
|
|
||||||
#include "zeroGradientFvPatchFields.H"
|
|
||||||
#include "compressibleMultiphaseMixture.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
Class alphaContactAngleFvPatch Declaration
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
class alphaContactAngleFvPatchScalarField
|
|
||||||
:
|
|
||||||
public zeroGradientFvPatchScalarField
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
class interfaceThetaProps
|
|
||||||
{
|
|
||||||
//- Equilibrium contact angle
|
|
||||||
scalar theta0_;
|
|
||||||
|
|
||||||
//- Dynamic contact angle velocity scale
|
|
||||||
scalar uTheta_;
|
|
||||||
|
|
||||||
//- Limiting advancing contact angle
|
|
||||||
scalar thetaA_;
|
|
||||||
|
|
||||||
//- Limiting receding contact angle
|
|
||||||
scalar thetaR_;
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
interfaceThetaProps()
|
|
||||||
{}
|
|
||||||
|
|
||||||
interfaceThetaProps(Istream&);
|
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
|
||||||
|
|
||||||
//- Return the equilibrium contact angle theta0
|
|
||||||
scalar theta0(bool matched=true) const
|
|
||||||
{
|
|
||||||
if (matched) return theta0_;
|
|
||||||
else return 180.0 - theta0_;
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Return the dynamic contact angle velocity scale
|
|
||||||
scalar uTheta() const
|
|
||||||
{
|
|
||||||
return uTheta_;
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Return the limiting advancing contact angle
|
|
||||||
scalar thetaA(bool matched=true) const
|
|
||||||
{
|
|
||||||
if (matched) return thetaA_;
|
|
||||||
else return 180.0 - thetaA_;
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Return the limiting receding contact angle
|
|
||||||
scalar thetaR(bool matched=true) const
|
|
||||||
{
|
|
||||||
if (matched) return thetaR_;
|
|
||||||
else return 180.0 - thetaR_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// IO functions
|
|
||||||
|
|
||||||
friend Istream& operator>>(Istream&, interfaceThetaProps&);
|
|
||||||
friend Ostream& operator<<(Ostream&, const interfaceThetaProps&);
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef HashTable
|
|
||||||
<
|
|
||||||
interfaceThetaProps,
|
|
||||||
compressibleMultiphaseMixture::interfacePair,
|
|
||||||
compressibleMultiphaseMixture::interfacePair::hash
|
|
||||||
> thetaPropsTable;
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
// Private Data
|
|
||||||
|
|
||||||
thetaPropsTable thetaProps_;
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//- Runtime type information
|
|
||||||
TypeName("alphaContactAngle");
|
|
||||||
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
//- Construct from patch and internal field
|
|
||||||
alphaContactAngleFvPatchScalarField
|
|
||||||
(
|
|
||||||
const fvPatch&,
|
|
||||||
const DimensionedField<scalar, volMesh>&
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Construct from patch, internal field and dictionary
|
|
||||||
alphaContactAngleFvPatchScalarField
|
|
||||||
(
|
|
||||||
const fvPatch&,
|
|
||||||
const DimensionedField<scalar, volMesh>&,
|
|
||||||
const dictionary&
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Construct by mapping given alphaContactAngleFvPatchScalarField
|
|
||||||
// onto a new patch
|
|
||||||
alphaContactAngleFvPatchScalarField
|
|
||||||
(
|
|
||||||
const alphaContactAngleFvPatchScalarField&,
|
|
||||||
const fvPatch&,
|
|
||||||
const DimensionedField<scalar, volMesh>&,
|
|
||||||
const fvPatchFieldMapper&
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Construct as copy setting internal field reference
|
|
||||||
alphaContactAngleFvPatchScalarField
|
|
||||||
(
|
|
||||||
const alphaContactAngleFvPatchScalarField&,
|
|
||||||
const DimensionedField<scalar, volMesh>&
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Construct and return a clone setting internal field reference
|
|
||||||
virtual tmp<fvPatchScalarField> clone
|
|
||||||
(
|
|
||||||
const DimensionedField<scalar, volMesh>& iF
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
return tmp<fvPatchScalarField>
|
|
||||||
(
|
|
||||||
new alphaContactAngleFvPatchScalarField(*this, iF)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
|
||||||
|
|
||||||
//- Return the contact angle properties
|
|
||||||
const thetaPropsTable& thetaProps() const
|
|
||||||
{
|
|
||||||
return thetaProps_;
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Write
|
|
||||||
virtual void write(Ostream&) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration | Website: https://openfoam.org
|
\\ / O peration | Website: https://openfoam.org
|
||||||
\\ / A nd | Copyright (C) 2013-2021 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2013-2022 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -25,7 +25,7 @@ License
|
|||||||
|
|
||||||
#include "compressibleMultiphaseMixture.H"
|
#include "compressibleMultiphaseMixture.H"
|
||||||
#include "alphaContactAngleFvPatchScalarField.H"
|
#include "alphaContactAngleFvPatchScalarField.H"
|
||||||
#include "unitConversion.H"
|
#include "correctContactAngle.H"
|
||||||
#include "Time.H"
|
#include "Time.H"
|
||||||
#include "subCycle.H"
|
#include "subCycle.H"
|
||||||
#include "MULES.H"
|
#include "MULES.H"
|
||||||
@ -401,138 +401,6 @@ Foam::tmp<Foam::surfaceScalarField> Foam::compressibleMultiphaseMixture::nHatf
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Correction for the boundary condition on the unit normal nHat on
|
|
||||||
// walls to produce the correct contact angle.
|
|
||||||
|
|
||||||
// The dynamic contact angle is calculated from the component of the
|
|
||||||
// velocity on the direction of the interface, parallel to the wall.
|
|
||||||
|
|
||||||
void Foam::compressibleMultiphaseMixture::correctContactAngle
|
|
||||||
(
|
|
||||||
const phaseModel& alpha1,
|
|
||||||
const phaseModel& alpha2,
|
|
||||||
surfaceVectorField::Boundary& nHatb
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
const volScalarField::Boundary& a1bf = alpha1.boundaryField();
|
|
||||||
const volScalarField::Boundary& a2bf = alpha2.boundaryField();
|
|
||||||
|
|
||||||
const fvBoundaryMesh& boundary = mesh_.boundary();
|
|
||||||
|
|
||||||
forAll(boundary, patchi)
|
|
||||||
{
|
|
||||||
if
|
|
||||||
(
|
|
||||||
isA<alphaContactAngleFvPatchScalarField>(a1bf[patchi])
|
|
||||||
|| isA<alphaContactAngleFvPatchScalarField>(a2bf[patchi])
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if
|
|
||||||
(
|
|
||||||
isA<alphaContactAngleFvPatchScalarField>(a1bf[patchi])
|
|
||||||
&& isA<alphaContactAngleFvPatchScalarField>(a2bf[patchi])
|
|
||||||
)
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "alphaContactAngle boundary condition "
|
|
||||||
"specified on patch " << boundary[patchi].name()
|
|
||||||
<< " for both " << alpha1.name() << " and " << alpha2.name()
|
|
||||||
<< nl << "which may be inconsistent."
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
const alphaContactAngleFvPatchScalarField& acap =
|
|
||||||
isA<alphaContactAngleFvPatchScalarField>(a1bf[patchi])
|
|
||||||
? refCast<const alphaContactAngleFvPatchScalarField>(a1bf[patchi])
|
|
||||||
: refCast<const alphaContactAngleFvPatchScalarField>(a2bf[patchi])
|
|
||||||
;
|
|
||||||
|
|
||||||
vectorField& nHatPatch = nHatb[patchi];
|
|
||||||
|
|
||||||
vectorField AfHatPatch
|
|
||||||
(
|
|
||||||
mesh_.Sf().boundaryField()[patchi]
|
|
||||||
/mesh_.magSf().boundaryField()[patchi]
|
|
||||||
);
|
|
||||||
|
|
||||||
alphaContactAngleFvPatchScalarField::thetaPropsTable::
|
|
||||||
const_iterator tp =
|
|
||||||
acap.thetaProps().find(interfacePair(alpha1, alpha2));
|
|
||||||
|
|
||||||
if (tp == acap.thetaProps().end())
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "Cannot find interface " << interfacePair(alpha1, alpha2)
|
|
||||||
<< "\n in table of theta properties for patch "
|
|
||||||
<< acap.patch().name()
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool matched = (tp.key().first() == alpha1.name());
|
|
||||||
|
|
||||||
const scalar theta0 = degToRad(tp().theta0(matched));
|
|
||||||
|
|
||||||
scalarField theta(boundary[patchi].size(), theta0);
|
|
||||||
|
|
||||||
const scalar uTheta = tp().uTheta();
|
|
||||||
|
|
||||||
// Calculate the dynamic contact angle if required
|
|
||||||
if (uTheta > small)
|
|
||||||
{
|
|
||||||
const scalar thetaA = degToRad(tp().thetaA(matched));
|
|
||||||
const scalar thetaR = degToRad(tp().thetaR(matched));
|
|
||||||
|
|
||||||
// Calculated the component of the velocity parallel to the wall
|
|
||||||
vectorField Uwall
|
|
||||||
(
|
|
||||||
U_.boundaryField()[patchi].patchInternalField()
|
|
||||||
- U_.boundaryField()[patchi]
|
|
||||||
);
|
|
||||||
Uwall -= (AfHatPatch & Uwall)*AfHatPatch;
|
|
||||||
|
|
||||||
// Find the direction of the interface parallel to the wall
|
|
||||||
vectorField nWall
|
|
||||||
(
|
|
||||||
nHatPatch - (AfHatPatch & nHatPatch)*AfHatPatch
|
|
||||||
);
|
|
||||||
|
|
||||||
// Normalise nWall
|
|
||||||
nWall /= (mag(nWall) + small);
|
|
||||||
|
|
||||||
// Calculate Uwall resolved normal to the interface parallel to
|
|
||||||
// the interface
|
|
||||||
const scalarField uwall(nWall & Uwall);
|
|
||||||
|
|
||||||
theta += (thetaA - thetaR)*tanh(uwall/uTheta);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Reset nHatPatch to correspond to the contact angle
|
|
||||||
|
|
||||||
const scalarField a12(nHatPatch & AfHatPatch);
|
|
||||||
|
|
||||||
const scalarField b1(cos(theta));
|
|
||||||
|
|
||||||
scalarField b2(nHatPatch.size());
|
|
||||||
|
|
||||||
forAll(b2, facei)
|
|
||||||
{
|
|
||||||
b2[facei] = cos(acos(a12[facei]) - theta[facei]);
|
|
||||||
}
|
|
||||||
|
|
||||||
const scalarField det(1.0 - a12*a12);
|
|
||||||
|
|
||||||
const scalarField a((b1 - a12*b2)/det);
|
|
||||||
const scalarField b((b2 - a12*b1)/det);
|
|
||||||
|
|
||||||
nHatPatch = a*AfHatPatch + b*nHatPatch;
|
|
||||||
|
|
||||||
nHatPatch /= (mag(nHatPatch) + deltaN_.value());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::tmp<Foam::volScalarField> Foam::compressibleMultiphaseMixture::K
|
Foam::tmp<Foam::volScalarField> Foam::compressibleMultiphaseMixture::K
|
||||||
(
|
(
|
||||||
const phaseModel& alpha1,
|
const phaseModel& alpha1,
|
||||||
@ -541,7 +409,14 @@ Foam::tmp<Foam::volScalarField> Foam::compressibleMultiphaseMixture::K
|
|||||||
{
|
{
|
||||||
tmp<surfaceVectorField> tnHatfv = nHatfv(alpha1, alpha2);
|
tmp<surfaceVectorField> tnHatfv = nHatfv(alpha1, alpha2);
|
||||||
|
|
||||||
correctContactAngle(alpha1, alpha2, tnHatfv.ref().boundaryFieldRef());
|
correctContactAngle
|
||||||
|
(
|
||||||
|
alpha1,
|
||||||
|
alpha2,
|
||||||
|
U_.boundaryField(),
|
||||||
|
deltaN_,
|
||||||
|
tnHatfv.ref().boundaryFieldRef()
|
||||||
|
);
|
||||||
|
|
||||||
// Simple expression for curvature
|
// Simple expression for curvature
|
||||||
return -fvc::div(tnHatfv & mesh_.Sf());
|
return -fvc::div(tnHatfv & mesh_.Sf());
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration | Website: https://openfoam.org
|
\\ / O peration | Website: https://openfoam.org
|
||||||
\\ / A nd | Copyright (C) 2013-2021 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2013-2022 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -171,13 +171,6 @@ private:
|
|||||||
const volScalarField& alpha2
|
const volScalarField& alpha2
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
void correctContactAngle
|
|
||||||
(
|
|
||||||
const phaseModel& alpha1,
|
|
||||||
const phaseModel& alpha2,
|
|
||||||
surfaceVectorField::Boundary& nHatb
|
|
||||||
) const;
|
|
||||||
|
|
||||||
tmp<volScalarField> K
|
tmp<volScalarField> K
|
||||||
(
|
(
|
||||||
const phaseModel& alpha1,
|
const phaseModel& alpha1,
|
||||||
|
|||||||
@ -19,6 +19,7 @@ EXE_LIBS = \
|
|||||||
-leulerianInterfacialCompositionModels \
|
-leulerianInterfacialCompositionModels \
|
||||||
-lmultiphaseMomentumTransportModels \
|
-lmultiphaseMomentumTransportModels \
|
||||||
-lmultiphaseReactions \
|
-lmultiphaseReactions \
|
||||||
|
-lmultiphaseProperties \
|
||||||
-lphaseFluidThermophysicalTransportModels \
|
-lphaseFluidThermophysicalTransportModels \
|
||||||
-lphaseFluidReactionThermophysicalTransportModels \
|
-lphaseFluidReactionThermophysicalTransportModels \
|
||||||
-lfiniteVolume \
|
-lfiniteVolume \
|
||||||
|
|||||||
@ -105,6 +105,4 @@ BlendedInterfacialModel/blendingMethods/hyperbolic/hyperbolic.C
|
|||||||
BlendedInterfacialModel/blendingMethods/continuous/continuous.C
|
BlendedInterfacialModel/blendingMethods/continuous/continuous.C
|
||||||
BlendedInterfacialModel/blendingMethods/segregatedBlendingMethod/segregatedBlendingMethod.C
|
BlendedInterfacialModel/blendingMethods/segregatedBlendingMethod/segregatedBlendingMethod.C
|
||||||
|
|
||||||
alphaContactAngle/alphaContactAngleFvPatchScalarField.C
|
|
||||||
|
|
||||||
LIB = $(FOAM_LIBBIN)/libphaseSystem
|
LIB = $(FOAM_LIBBIN)/libphaseSystem
|
||||||
|
|||||||
@ -3,6 +3,7 @@ EXE_INC = \
|
|||||||
-I../interfacialCompositionModels/lnInclude \
|
-I../interfacialCompositionModels/lnInclude \
|
||||||
-I../multiphaseCompressibleMomentumTransportModels/lnInclude \
|
-I../multiphaseCompressibleMomentumTransportModels/lnInclude \
|
||||||
-I$(LIB_SRC)/physicalProperties/lnInclude \
|
-I$(LIB_SRC)/physicalProperties/lnInclude \
|
||||||
|
-I$(LIB_SRC)/multiphaseModels/multiphaseProperties/lnInclude \
|
||||||
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
|
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
|
||||||
-I$(LIB_SRC)/thermophysicalModels/specie/lnInclude \
|
-I$(LIB_SRC)/thermophysicalModels/specie/lnInclude \
|
||||||
-I$(LIB_SRC)/thermophysicalModels/reactionThermo/lnInclude \
|
-I$(LIB_SRC)/thermophysicalModels/reactionThermo/lnInclude \
|
||||||
|
|||||||
@ -34,7 +34,7 @@ License
|
|||||||
#include "CorrectPhi.H"
|
#include "CorrectPhi.H"
|
||||||
#include "fvcMeshPhi.H"
|
#include "fvcMeshPhi.H"
|
||||||
#include "alphaContactAngleFvPatchScalarField.H"
|
#include "alphaContactAngleFvPatchScalarField.H"
|
||||||
#include "unitConversion.H"
|
#include "correctContactAngle.H"
|
||||||
#include "dragModel.H"
|
#include "dragModel.H"
|
||||||
#include "movingWallVelocityFvPatchVectorField.H"
|
#include "movingWallVelocityFvPatchVectorField.H"
|
||||||
#include "pimpleControl.H"
|
#include "pimpleControl.H"
|
||||||
@ -184,136 +184,6 @@ Foam::tmp<Foam::surfaceScalarField> Foam::phaseSystem::nHatf
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::phaseSystem::correctContactAngle
|
|
||||||
(
|
|
||||||
const phaseModel& phase1,
|
|
||||||
const phaseModel& phase2,
|
|
||||||
surfaceVectorField::Boundary& nHatbf
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
const volScalarField& a1 = phase1;
|
|
||||||
const volScalarField& a2 = phase2;
|
|
||||||
|
|
||||||
const volScalarField::Boundary& a1bf = a1.boundaryField();
|
|
||||||
const volScalarField::Boundary& a2bf = a2.boundaryField();
|
|
||||||
|
|
||||||
const fvBoundaryMesh& boundary = mesh_.boundary();
|
|
||||||
|
|
||||||
forAll(boundary, patchi)
|
|
||||||
{
|
|
||||||
const fvPatchScalarField& a1p = a1bf[patchi];
|
|
||||||
const fvPatchScalarField& a2p = a2bf[patchi];
|
|
||||||
|
|
||||||
const bool a1pIsCa = isA<alphaContactAngleFvPatchScalarField>(a1p);
|
|
||||||
const bool a2pIsCa = isA<alphaContactAngleFvPatchScalarField>(a2p);
|
|
||||||
|
|
||||||
if (a1pIsCa || a2pIsCa)
|
|
||||||
{
|
|
||||||
if (a1pIsCa != a2pIsCa)
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< alphaContactAngleFvPatchScalarField::typeName
|
|
||||||
<< " boundary condition specified on patch "
|
|
||||||
<< boundary[patchi].name() << " for "
|
|
||||||
<< (a1pIsCa ? a1.name() : a2.name()) << " but not for "
|
|
||||||
<< (a2pIsCa ? a1.name() : a2.name())
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
const alphaContactAngleFvPatchScalarField& a1ca =
|
|
||||||
refCast<const alphaContactAngleFvPatchScalarField>(a1p);
|
|
||||||
const alphaContactAngleFvPatchScalarField& a2ca =
|
|
||||||
refCast<const alphaContactAngleFvPatchScalarField>(a2p);
|
|
||||||
|
|
||||||
const bool a1caHasProps = a1ca.thetaProps().found(phase2.name());
|
|
||||||
const bool a2caHasProps = a2ca.thetaProps().found(phase1.name());
|
|
||||||
|
|
||||||
if (!a1caHasProps && !a2caHasProps)
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "Neither "
|
|
||||||
<< alphaContactAngleFvPatchScalarField::typeName
|
|
||||||
<< " boundary condition specified on patch "
|
|
||||||
<< boundary[patchi].name()
|
|
||||||
<< " for " << a1.name() << " and " << a2.name()
|
|
||||||
<< " contains properties for the other phase"
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
if
|
|
||||||
(
|
|
||||||
a1caHasProps && a2caHasProps
|
|
||||||
&& a1ca.thetaProps()[phase2.name()]
|
|
||||||
!= a2ca.thetaProps()[phase1.name()].reversed()
|
|
||||||
)
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "The "
|
|
||||||
<< alphaContactAngleFvPatchScalarField::typeName
|
|
||||||
<< " boundary conditions specified on patch "
|
|
||||||
<< boundary[patchi].name()
|
|
||||||
<< " for " << a1.name() << " and " << a2.name()
|
|
||||||
<< " contain inconsistent properties"
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
const alphaContactAngleFvPatchScalarField::contactAngleProperties
|
|
||||||
tp = a1caHasProps
|
|
||||||
? a1ca.thetaProps()[phase2.name()]
|
|
||||||
: a2ca.thetaProps()[phase1.name()].reversed();
|
|
||||||
|
|
||||||
const vectorField np(mesh_.boundary()[patchi].nf());
|
|
||||||
|
|
||||||
vectorField& nHatp = nHatbf[patchi];
|
|
||||||
|
|
||||||
// Calculate the contact angle
|
|
||||||
scalarField theta(np.size(), degToRad(tp.theta0()));
|
|
||||||
|
|
||||||
// Calculate the dynamic contact angle if required
|
|
||||||
if (tp.dynamic())
|
|
||||||
{
|
|
||||||
const scalar uTheta = tp.uTheta();
|
|
||||||
const scalar thetaA = degToRad(tp.thetaA());
|
|
||||||
const scalar thetaR = degToRad(tp.thetaR());
|
|
||||||
|
|
||||||
// Calculated the component of the velocity parallel to the wall
|
|
||||||
vectorField Uwall
|
|
||||||
(
|
|
||||||
phase1.U()().boundaryField()[patchi].patchInternalField()
|
|
||||||
- phase1.U()().boundaryField()[patchi]
|
|
||||||
);
|
|
||||||
Uwall -= (np & Uwall)*np;
|
|
||||||
|
|
||||||
// Find the direction of the interface parallel to the wall
|
|
||||||
vectorField nWall(nHatp - (np & nHatp)*np);
|
|
||||||
nWall /= (mag(nWall) + small);
|
|
||||||
|
|
||||||
// Calculate Uwall resolved normal to the interface parallel to
|
|
||||||
// the interface
|
|
||||||
const scalarField uwall(nWall & Uwall);
|
|
||||||
|
|
||||||
theta += (thetaA - thetaR)*tanh(uwall/uTheta);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset nHatp to correspond to the contact angle
|
|
||||||
const scalarField a12(nHatp & np);
|
|
||||||
const scalarField b1(cos(theta));
|
|
||||||
scalarField b2(nHatp.size());
|
|
||||||
forAll(b2, facei)
|
|
||||||
{
|
|
||||||
b2[facei] = cos(acos(a12[facei]) - theta[facei]);
|
|
||||||
}
|
|
||||||
const scalarField det(1 - a12*a12);
|
|
||||||
const scalarField a((b1 - a12*b2)/det);
|
|
||||||
const scalarField b((b2 - a12*b1)/det);
|
|
||||||
|
|
||||||
nHatp = a*np + b*nHatp;
|
|
||||||
nHatp /= (mag(nHatp) + deltaN_.value());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::tmp<Foam::volScalarField> Foam::phaseSystem::K
|
Foam::tmp<Foam::volScalarField> Foam::phaseSystem::K
|
||||||
(
|
(
|
||||||
const phaseModel& phase1,
|
const phaseModel& phase1,
|
||||||
@ -322,7 +192,14 @@ Foam::tmp<Foam::volScalarField> Foam::phaseSystem::K
|
|||||||
{
|
{
|
||||||
tmp<surfaceVectorField> tnHatfv = nHatfv(phase1, phase2);
|
tmp<surfaceVectorField> tnHatfv = nHatfv(phase1, phase2);
|
||||||
|
|
||||||
correctContactAngle(phase1, phase2, tnHatfv.ref().boundaryFieldRef());
|
correctContactAngle
|
||||||
|
(
|
||||||
|
phase1,
|
||||||
|
phase2,
|
||||||
|
phase1.U()().boundaryField(),
|
||||||
|
deltaN_,
|
||||||
|
tnHatfv.ref().boundaryFieldRef()
|
||||||
|
);
|
||||||
|
|
||||||
// Simple expression for curvature
|
// Simple expression for curvature
|
||||||
return -fvc::div(tnHatfv & mesh_.Sf());
|
return -fvc::div(tnHatfv & mesh_.Sf());
|
||||||
|
|||||||
@ -211,19 +211,6 @@ protected:
|
|||||||
const volScalarField& alpha2
|
const volScalarField& alpha2
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
//- Correction for the boundary condition on the unit normal nHat on
|
|
||||||
// walls to produce the correct contact angle.
|
|
||||||
//
|
|
||||||
// The dynamic contact angle is calculated from the component of
|
|
||||||
// the velocity on the direction of the interface, parallel to the
|
|
||||||
// wall. Used for interface compression.
|
|
||||||
void correctContactAngle
|
|
||||||
(
|
|
||||||
const phaseModel& alpha1,
|
|
||||||
const phaseModel& alpha2,
|
|
||||||
surfaceVectorField::Boundary& nHatb
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Curvature of interface between two phases
|
//- Curvature of interface between two phases
|
||||||
// Used for interface compression
|
// Used for interface compression
|
||||||
tmp<volScalarField> K
|
tmp<volScalarField> K
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
phase/phase.C
|
phase/phase.C
|
||||||
alphaContactAngle/alphaContactAngleFvPatchScalarField.C
|
|
||||||
multiphaseMixture.C
|
multiphaseMixture.C
|
||||||
|
|
||||||
LIB = $(FOAM_LIBBIN)/libmultiphaseInterFoam
|
LIB = $(FOAM_LIBBIN)/libmultiphaseInterFoam
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
EXE_INC = \
|
EXE_INC = \
|
||||||
-IalphaContactAngle \
|
-IalphaContactAngle \
|
||||||
-I$(LIB_SRC)/physicalProperties/lnInclude \
|
-I$(LIB_SRC)/physicalProperties/lnInclude \
|
||||||
|
-I$(LIB_SRC)/multiphaseModels/multiphaseProperties/lnInclude \
|
||||||
-I$(LIB_SRC)/twoPhaseModels/interfaceProperties/lnInclude \
|
-I$(LIB_SRC)/twoPhaseModels/interfaceProperties/lnInclude \
|
||||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||||
-I$(LIB_SRC)/meshTools/lnInclude
|
-I$(LIB_SRC)/meshTools/lnInclude
|
||||||
@ -8,5 +9,6 @@ EXE_INC = \
|
|||||||
LIB_LIBS = \
|
LIB_LIBS = \
|
||||||
-linterfaceProperties \
|
-linterfaceProperties \
|
||||||
-lphysicalProperties \
|
-lphysicalProperties \
|
||||||
|
-lmultiphaseProperties \
|
||||||
-lfiniteVolume \
|
-lfiniteVolume \
|
||||||
-lmeshTools
|
-lmeshTools
|
||||||
|
|||||||
@ -1,145 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration | Website: https://openfoam.org
|
|
||||||
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation
|
|
||||||
\\/ 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 3 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, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "alphaContactAngleFvPatchScalarField.H"
|
|
||||||
#include "addToRunTimeSelectionTable.H"
|
|
||||||
#include "fvPatchFieldMapper.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
alphaContactAngleFvPatchScalarField::interfaceThetaProps::interfaceThetaProps
|
|
||||||
(
|
|
||||||
Istream& is
|
|
||||||
)
|
|
||||||
:
|
|
||||||
theta0_(readScalar(is)),
|
|
||||||
uTheta_(readScalar(is)),
|
|
||||||
thetaA_(readScalar(is)),
|
|
||||||
thetaR_(readScalar(is))
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
Istream& operator>>
|
|
||||||
(
|
|
||||||
Istream& is,
|
|
||||||
alphaContactAngleFvPatchScalarField::interfaceThetaProps& tp
|
|
||||||
)
|
|
||||||
{
|
|
||||||
is >> tp.theta0_ >> tp.uTheta_ >> tp.thetaA_ >> tp.thetaR_;
|
|
||||||
return is;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Ostream& operator<<
|
|
||||||
(
|
|
||||||
Ostream& os,
|
|
||||||
const alphaContactAngleFvPatchScalarField::interfaceThetaProps& tp
|
|
||||||
)
|
|
||||||
{
|
|
||||||
os << tp.theta0_ << token::SPACE
|
|
||||||
<< tp.uTheta_ << token::SPACE
|
|
||||||
<< tp.thetaA_ << token::SPACE
|
|
||||||
<< tp.thetaR_;
|
|
||||||
|
|
||||||
return os;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
alphaContactAngleFvPatchScalarField::alphaContactAngleFvPatchScalarField
|
|
||||||
(
|
|
||||||
const fvPatch& p,
|
|
||||||
const DimensionedField<scalar, volMesh>& iF
|
|
||||||
)
|
|
||||||
:
|
|
||||||
zeroGradientFvPatchScalarField(p, iF)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
alphaContactAngleFvPatchScalarField::alphaContactAngleFvPatchScalarField
|
|
||||||
(
|
|
||||||
const fvPatch& p,
|
|
||||||
const DimensionedField<scalar, volMesh>& iF,
|
|
||||||
const dictionary& dict
|
|
||||||
)
|
|
||||||
:
|
|
||||||
zeroGradientFvPatchScalarField(p, iF),
|
|
||||||
thetaProps_(dict.lookup("thetaProperties"))
|
|
||||||
{
|
|
||||||
evaluate();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
alphaContactAngleFvPatchScalarField::alphaContactAngleFvPatchScalarField
|
|
||||||
(
|
|
||||||
const alphaContactAngleFvPatchScalarField& gcpsf,
|
|
||||||
const fvPatch& p,
|
|
||||||
const DimensionedField<scalar, volMesh>& iF,
|
|
||||||
const fvPatchFieldMapper& mapper
|
|
||||||
)
|
|
||||||
:
|
|
||||||
zeroGradientFvPatchScalarField(gcpsf, p, iF, mapper),
|
|
||||||
thetaProps_(gcpsf.thetaProps_)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
alphaContactAngleFvPatchScalarField::alphaContactAngleFvPatchScalarField
|
|
||||||
(
|
|
||||||
const alphaContactAngleFvPatchScalarField& gcpsf,
|
|
||||||
const DimensionedField<scalar, volMesh>& iF
|
|
||||||
)
|
|
||||||
:
|
|
||||||
zeroGradientFvPatchScalarField(gcpsf, iF),
|
|
||||||
thetaProps_(gcpsf.thetaProps_)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
void alphaContactAngleFvPatchScalarField::write(Ostream& os) const
|
|
||||||
{
|
|
||||||
fvPatchScalarField::write(os);
|
|
||||||
writeEntry(os, "thetaProperties", thetaProps_);
|
|
||||||
writeEntry(os, "value", *this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
makePatchTypeField
|
|
||||||
(
|
|
||||||
fvPatchScalarField,
|
|
||||||
alphaContactAngleFvPatchScalarField
|
|
||||||
);
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,206 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration | Website: https://openfoam.org
|
|
||||||
\\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation
|
|
||||||
\\/ 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 3 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, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Class
|
|
||||||
Foam::alphaContactAngleFvPatchScalarField
|
|
||||||
|
|
||||||
Description
|
|
||||||
Contact-angle boundary condition for multi-phase interface-capturing
|
|
||||||
simulations. Used in conjunction with multiphaseMixture.
|
|
||||||
|
|
||||||
SourceFiles
|
|
||||||
alphaContactAngleFvPatchScalarField.C
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef alphaContactAngleFvPatchScalarField_H
|
|
||||||
#define alphaContactAngleFvPatchScalarField_H
|
|
||||||
|
|
||||||
#include "zeroGradientFvPatchFields.H"
|
|
||||||
#include "multiphaseMixture.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
Class alphaContactAngleFvPatch Declaration
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
class alphaContactAngleFvPatchScalarField
|
|
||||||
:
|
|
||||||
public zeroGradientFvPatchScalarField
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
class interfaceThetaProps
|
|
||||||
{
|
|
||||||
//- Equilibrium contact angle
|
|
||||||
scalar theta0_;
|
|
||||||
|
|
||||||
//- Dynamic contact angle velocity scale
|
|
||||||
scalar uTheta_;
|
|
||||||
|
|
||||||
//- Limiting advancing contact angle
|
|
||||||
scalar thetaA_;
|
|
||||||
|
|
||||||
//- Limiting receding contact angle
|
|
||||||
scalar thetaR_;
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
interfaceThetaProps()
|
|
||||||
{}
|
|
||||||
|
|
||||||
interfaceThetaProps(Istream&);
|
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
|
||||||
|
|
||||||
//- Return the equilibrium contact angle theta0
|
|
||||||
scalar theta0(bool matched=true) const
|
|
||||||
{
|
|
||||||
if (matched) return theta0_;
|
|
||||||
else return 180.0 - theta0_;
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Return the dynamic contact angle velocity scale
|
|
||||||
scalar uTheta() const
|
|
||||||
{
|
|
||||||
return uTheta_;
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Return the limiting advancing contact angle
|
|
||||||
scalar thetaA(bool matched=true) const
|
|
||||||
{
|
|
||||||
if (matched) return thetaA_;
|
|
||||||
else return 180.0 - thetaA_;
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Return the limiting receding contact angle
|
|
||||||
scalar thetaR(bool matched=true) const
|
|
||||||
{
|
|
||||||
if (matched) return thetaR_;
|
|
||||||
else return 180.0 - thetaR_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// IO functions
|
|
||||||
|
|
||||||
friend Istream& operator>>(Istream&, interfaceThetaProps&);
|
|
||||||
friend Ostream& operator<<(Ostream&, const interfaceThetaProps&);
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef HashTable
|
|
||||||
<
|
|
||||||
interfaceThetaProps,
|
|
||||||
multiphaseMixture::interfacePair,
|
|
||||||
multiphaseMixture::interfacePair::hash
|
|
||||||
> thetaPropsTable;
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
// Private Data
|
|
||||||
|
|
||||||
thetaPropsTable thetaProps_;
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//- Runtime type information
|
|
||||||
TypeName("alphaContactAngle");
|
|
||||||
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
//- Construct from patch and internal field
|
|
||||||
alphaContactAngleFvPatchScalarField
|
|
||||||
(
|
|
||||||
const fvPatch&,
|
|
||||||
const DimensionedField<scalar, volMesh>&
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Construct from patch, internal field and dictionary
|
|
||||||
alphaContactAngleFvPatchScalarField
|
|
||||||
(
|
|
||||||
const fvPatch&,
|
|
||||||
const DimensionedField<scalar, volMesh>&,
|
|
||||||
const dictionary&
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Construct by mapping given alphaContactAngleFvPatchScalarField
|
|
||||||
// onto a new patch
|
|
||||||
alphaContactAngleFvPatchScalarField
|
|
||||||
(
|
|
||||||
const alphaContactAngleFvPatchScalarField&,
|
|
||||||
const fvPatch&,
|
|
||||||
const DimensionedField<scalar, volMesh>&,
|
|
||||||
const fvPatchFieldMapper&
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Construct as copy setting internal field reference
|
|
||||||
alphaContactAngleFvPatchScalarField
|
|
||||||
(
|
|
||||||
const alphaContactAngleFvPatchScalarField&,
|
|
||||||
const DimensionedField<scalar, volMesh>&
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Construct and return a clone setting internal field reference
|
|
||||||
virtual tmp<fvPatchScalarField> clone
|
|
||||||
(
|
|
||||||
const DimensionedField<scalar, volMesh>& iF
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
return tmp<fvPatchScalarField>
|
|
||||||
(
|
|
||||||
new alphaContactAngleFvPatchScalarField(*this, iF)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
|
||||||
|
|
||||||
//- Return the contact angle properties
|
|
||||||
const thetaPropsTable& thetaProps() const
|
|
||||||
{
|
|
||||||
return thetaProps_;
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Write
|
|
||||||
virtual void write(Ostream&) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration | Website: https://openfoam.org
|
\\ / O peration | Website: https://openfoam.org
|
||||||
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -25,7 +25,7 @@ License
|
|||||||
|
|
||||||
#include "multiphaseMixture.H"
|
#include "multiphaseMixture.H"
|
||||||
#include "alphaContactAngleFvPatchScalarField.H"
|
#include "alphaContactAngleFvPatchScalarField.H"
|
||||||
#include "unitConversion.H"
|
#include "correctContactAngle.H"
|
||||||
#include "Time.H"
|
#include "Time.H"
|
||||||
#include "subCycle.H"
|
#include "subCycle.H"
|
||||||
#include "MULES.H"
|
#include "MULES.H"
|
||||||
@ -391,132 +391,6 @@ Foam::tmp<Foam::surfaceScalarField> Foam::multiphaseMixture::nHatf
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::multiphaseMixture::correctContactAngle
|
|
||||||
(
|
|
||||||
const phase& alpha1,
|
|
||||||
const phase& alpha2,
|
|
||||||
surfaceVectorField::Boundary& nHatb
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
const volScalarField::Boundary& a1bf = alpha1.boundaryField();
|
|
||||||
const volScalarField::Boundary& a2bf = alpha2.boundaryField();
|
|
||||||
|
|
||||||
const fvBoundaryMesh& boundary = mesh_.boundary();
|
|
||||||
|
|
||||||
forAll(boundary, patchi)
|
|
||||||
{
|
|
||||||
if
|
|
||||||
(
|
|
||||||
isA<alphaContactAngleFvPatchScalarField>(a1bf[patchi])
|
|
||||||
|| isA<alphaContactAngleFvPatchScalarField>(a2bf[patchi])
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if
|
|
||||||
(
|
|
||||||
isA<alphaContactAngleFvPatchScalarField>(a1bf[patchi])
|
|
||||||
&& isA<alphaContactAngleFvPatchScalarField>(a2bf[patchi])
|
|
||||||
)
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "alphaContactAngle boundary condition "
|
|
||||||
"specified on patch " << boundary[patchi].name()
|
|
||||||
<< " for both " << alpha1.name() << " and " << alpha2.name()
|
|
||||||
<< nl << "which may be inconsistent."
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
const alphaContactAngleFvPatchScalarField& acap =
|
|
||||||
isA<alphaContactAngleFvPatchScalarField>(a1bf[patchi])
|
|
||||||
? refCast<const alphaContactAngleFvPatchScalarField>(a1bf[patchi])
|
|
||||||
: refCast<const alphaContactAngleFvPatchScalarField>(a2bf[patchi])
|
|
||||||
;
|
|
||||||
|
|
||||||
vectorField& nHatPatch = nHatb[patchi];
|
|
||||||
|
|
||||||
const vectorField AfHatPatch
|
|
||||||
(
|
|
||||||
mesh_.Sf().boundaryField()[patchi]
|
|
||||||
/mesh_.magSf().boundaryField()[patchi]
|
|
||||||
);
|
|
||||||
|
|
||||||
alphaContactAngleFvPatchScalarField::thetaPropsTable::
|
|
||||||
const_iterator tp =
|
|
||||||
acap.thetaProps().find(interfacePair(alpha1, alpha2));
|
|
||||||
|
|
||||||
if (tp == acap.thetaProps().end())
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "Cannot find interface " << interfacePair(alpha1, alpha2)
|
|
||||||
<< "\n in table of theta properties for patch "
|
|
||||||
<< acap.patch().name()
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool matched = (tp.key().first() == alpha1.name());
|
|
||||||
|
|
||||||
const scalar theta0 = degToRad(tp().theta0(matched));
|
|
||||||
|
|
||||||
scalarField theta(boundary[patchi].size(), theta0);
|
|
||||||
|
|
||||||
const scalar uTheta = tp().uTheta();
|
|
||||||
|
|
||||||
// Calculate the dynamic contact angle if required
|
|
||||||
if (uTheta > small)
|
|
||||||
{
|
|
||||||
const scalar thetaA = degToRad(tp().thetaA(matched));
|
|
||||||
const scalar thetaR = degToRad(tp().thetaR(matched));
|
|
||||||
|
|
||||||
// Calculated the component of the velocity parallel to the wall
|
|
||||||
vectorField Uwall
|
|
||||||
(
|
|
||||||
U_.boundaryField()[patchi].patchInternalField()
|
|
||||||
- U_.boundaryField()[patchi]
|
|
||||||
);
|
|
||||||
Uwall -= (AfHatPatch & Uwall)*AfHatPatch;
|
|
||||||
|
|
||||||
// Find the direction of the interface parallel to the wall
|
|
||||||
vectorField nWall
|
|
||||||
(
|
|
||||||
nHatPatch - (AfHatPatch & nHatPatch)*AfHatPatch
|
|
||||||
);
|
|
||||||
|
|
||||||
// Normalise nWall
|
|
||||||
nWall /= (mag(nWall) + small);
|
|
||||||
|
|
||||||
// Calculate Uwall resolved normal to the interface parallel to
|
|
||||||
// the interface
|
|
||||||
const scalarField uwall(nWall & Uwall);
|
|
||||||
|
|
||||||
theta += (thetaA - thetaR)*tanh(uwall/uTheta);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Reset nHatPatch to correspond to the contact angle
|
|
||||||
|
|
||||||
const scalarField a12(nHatPatch & AfHatPatch);
|
|
||||||
|
|
||||||
const scalarField b1(cos(theta));
|
|
||||||
|
|
||||||
scalarField b2(nHatPatch.size());
|
|
||||||
|
|
||||||
forAll(b2, facei)
|
|
||||||
{
|
|
||||||
b2[facei] = cos(acos(a12[facei]) - theta[facei]);
|
|
||||||
}
|
|
||||||
|
|
||||||
const scalarField det(1.0 - a12*a12);
|
|
||||||
|
|
||||||
const scalarField a((b1 - a12*b2)/det);
|
|
||||||
const scalarField b((b2 - a12*b1)/det);
|
|
||||||
|
|
||||||
nHatPatch = a*AfHatPatch + b*nHatPatch;
|
|
||||||
|
|
||||||
nHatPatch /= (mag(nHatPatch) + deltaN_.value());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::tmp<Foam::volScalarField> Foam::multiphaseMixture::K
|
Foam::tmp<Foam::volScalarField> Foam::multiphaseMixture::K
|
||||||
(
|
(
|
||||||
const phase& alpha1,
|
const phase& alpha1,
|
||||||
@ -525,7 +399,14 @@ Foam::tmp<Foam::volScalarField> Foam::multiphaseMixture::K
|
|||||||
{
|
{
|
||||||
tmp<surfaceVectorField> tnHatfv = nHatfv(alpha1, alpha2);
|
tmp<surfaceVectorField> tnHatfv = nHatfv(alpha1, alpha2);
|
||||||
|
|
||||||
correctContactAngle(alpha1, alpha2, tnHatfv.ref().boundaryFieldRef());
|
correctContactAngle
|
||||||
|
(
|
||||||
|
alpha1,
|
||||||
|
alpha2,
|
||||||
|
U_.boundaryField(),
|
||||||
|
deltaN_,
|
||||||
|
tnHatfv.ref().boundaryFieldRef()
|
||||||
|
);
|
||||||
|
|
||||||
// Simple expression for curvature
|
// Simple expression for curvature
|
||||||
return -fvc::div(tnHatfv & mesh_.Sf());
|
return -fvc::div(tnHatfv & mesh_.Sf());
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration | Website: https://openfoam.org
|
\\ / O peration | Website: https://openfoam.org
|
||||||
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -173,18 +173,6 @@ private:
|
|||||||
const volScalarField& alpha2
|
const volScalarField& alpha2
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
//- Correction for the boundary condition on the unit normal nHat on
|
|
||||||
// walls to produce the correct contact angle.
|
|
||||||
//
|
|
||||||
// The dynamic contact angle is calculated from the component of the
|
|
||||||
// velocity on the direction of the interface, parallel to the wall.
|
|
||||||
void correctContactAngle
|
|
||||||
(
|
|
||||||
const phase& alpha1,
|
|
||||||
const phase& alpha2,
|
|
||||||
surfaceVectorField::Boundary& nHatb
|
|
||||||
) const;
|
|
||||||
|
|
||||||
tmp<volScalarField> K(const phase& alpha1, const phase& alpha2) const;
|
tmp<volScalarField> K(const phase& alpha1, const phase& alpha2) const;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -59,6 +59,7 @@ wmake $targetType physicalProperties
|
|||||||
|
|
||||||
thermophysicalModels/Allwmake $targetType $*
|
thermophysicalModels/Allwmake $targetType $*
|
||||||
twoPhaseModels/Allwmake $targetType $*
|
twoPhaseModels/Allwmake $targetType $*
|
||||||
|
multiphaseModels/Allwmake $targetType $*
|
||||||
MomentumTransportModels/Allwmake $targetType $*
|
MomentumTransportModels/Allwmake $targetType $*
|
||||||
ThermophysicalTransportModels/Allwmake $targetType $*
|
ThermophysicalTransportModels/Allwmake $targetType $*
|
||||||
wmake $targetType radiationModels
|
wmake $targetType radiationModels
|
||||||
|
|||||||
9
src/multiphaseModels/Allwmake
Executable file
9
src/multiphaseModels/Allwmake
Executable file
@ -0,0 +1,9 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
cd ${0%/*} || exit 1 # Run from this directory
|
||||||
|
|
||||||
|
# Parse arguments for library compilation
|
||||||
|
. $WM_PROJECT_DIR/wmake/scripts/AllwmakeParseArguments
|
||||||
|
|
||||||
|
wmake $targetType multiphaseProperties
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
4
src/multiphaseModels/multiphaseProperties/Make/files
Normal file
4
src/multiphaseModels/multiphaseProperties/Make/files
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
alphaContactAngle/alphaContactAngleFvPatchScalarField.C
|
||||||
|
correctContactAngle/correctContactAngle.C
|
||||||
|
|
||||||
|
LIB = $(FOAM_LIBBIN)/libmultiphaseProperties
|
||||||
5
src/multiphaseModels/multiphaseProperties/Make/options
Normal file
5
src/multiphaseModels/multiphaseProperties/Make/options
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
EXE_INC = \
|
||||||
|
-I$(LIB_SRC)/finiteVolume/lnInclude
|
||||||
|
|
||||||
|
LIB_LIBS = \
|
||||||
|
-lfiniteVolume
|
||||||
@ -26,7 +26,7 @@ Class
|
|||||||
|
|
||||||
Description
|
Description
|
||||||
Contact-angle boundary condition for multi-phase interface-capturing
|
Contact-angle boundary condition for multi-phase interface-capturing
|
||||||
simulations. Used in conjunction with phaseSystem.
|
simulations.
|
||||||
|
|
||||||
SourceFiles
|
SourceFiles
|
||||||
alphaContactAngleFvPatchScalarField.C
|
alphaContactAngleFvPatchScalarField.C
|
||||||
@ -0,0 +1,159 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration | Website: https://openfoam.org
|
||||||
|
\\ / A nd | Copyright (C) 2022 OpenFOAM Foundation
|
||||||
|
\\/ 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "correctContactAngle.H"
|
||||||
|
#include "unitConversion.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::correctContactAngle
|
||||||
|
(
|
||||||
|
const volScalarField& a1,
|
||||||
|
const volScalarField& a2,
|
||||||
|
const volVectorField::Boundary& Ubf,
|
||||||
|
const dimensionedScalar& deltaN,
|
||||||
|
surfaceVectorField::Boundary& nHatbf
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const volScalarField::Boundary& a1bf = a1.boundaryField();
|
||||||
|
const volScalarField::Boundary& a2bf = a2.boundaryField();
|
||||||
|
|
||||||
|
const fvBoundaryMesh& boundary = a1.mesh().boundary();
|
||||||
|
|
||||||
|
forAll(boundary, patchi)
|
||||||
|
{
|
||||||
|
const fvPatchScalarField& a1p = a1bf[patchi];
|
||||||
|
const fvPatchScalarField& a2p = a2bf[patchi];
|
||||||
|
|
||||||
|
const bool a1pIsCa = isA<alphaContactAngleFvPatchScalarField>(a1p);
|
||||||
|
const bool a2pIsCa = isA<alphaContactAngleFvPatchScalarField>(a2p);
|
||||||
|
|
||||||
|
if (a1pIsCa || a2pIsCa)
|
||||||
|
{
|
||||||
|
if (a1pIsCa != a2pIsCa)
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< alphaContactAngleFvPatchScalarField::typeName
|
||||||
|
<< " boundary condition specified on patch "
|
||||||
|
<< boundary[patchi].name() << " for "
|
||||||
|
<< (a1pIsCa ? a1.name() : a2.name()) << " but not for "
|
||||||
|
<< (a2pIsCa ? a1.name() : a2.name())
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
const alphaContactAngleFvPatchScalarField& a1ca =
|
||||||
|
refCast<const alphaContactAngleFvPatchScalarField>(a1p);
|
||||||
|
const alphaContactAngleFvPatchScalarField& a2ca =
|
||||||
|
refCast<const alphaContactAngleFvPatchScalarField>(a2p);
|
||||||
|
|
||||||
|
const bool a1caHasProps = a1ca.thetaProps().found(a2.group());
|
||||||
|
const bool a2caHasProps = a2ca.thetaProps().found(a1.group());
|
||||||
|
|
||||||
|
if (!a1caHasProps && !a2caHasProps)
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Neither "
|
||||||
|
<< alphaContactAngleFvPatchScalarField::typeName
|
||||||
|
<< " boundary condition specified on patch "
|
||||||
|
<< boundary[patchi].name()
|
||||||
|
<< " for " << a1.name() << " and " << a2.name()
|
||||||
|
<< " contains properties for the other phase"
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
a1caHasProps && a2caHasProps
|
||||||
|
&& a1ca.thetaProps()[a2.group()]
|
||||||
|
!= a2ca.thetaProps()[a1.group()].reversed()
|
||||||
|
)
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "The "
|
||||||
|
<< alphaContactAngleFvPatchScalarField::typeName
|
||||||
|
<< " boundary conditions specified on patch "
|
||||||
|
<< boundary[patchi].name()
|
||||||
|
<< " for " << a1.name() << " and " << a2.name()
|
||||||
|
<< " contain inconsistent properties"
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
const alphaContactAngleFvPatchScalarField::contactAngleProperties
|
||||||
|
tp = a1caHasProps
|
||||||
|
? a1ca.thetaProps()[a2.group()]
|
||||||
|
: a2ca.thetaProps()[a1.group()].reversed();
|
||||||
|
|
||||||
|
const vectorField np(a1.mesh().boundary()[patchi].nf());
|
||||||
|
|
||||||
|
vectorField& nHatp = nHatbf[patchi];
|
||||||
|
|
||||||
|
// Calculate the contact angle
|
||||||
|
scalarField theta(np.size(), degToRad(tp.theta0()));
|
||||||
|
|
||||||
|
// Calculate the dynamic contact angle if required
|
||||||
|
if (tp.dynamic())
|
||||||
|
{
|
||||||
|
const scalar uTheta = tp.uTheta();
|
||||||
|
const scalar thetaA = degToRad(tp.thetaA());
|
||||||
|
const scalar thetaR = degToRad(tp.thetaR());
|
||||||
|
|
||||||
|
// Calculated the component of the velocity parallel to the wall
|
||||||
|
vectorField Uwall
|
||||||
|
(
|
||||||
|
Ubf[patchi].patchInternalField() - Ubf[patchi]
|
||||||
|
);
|
||||||
|
Uwall -= (np & Uwall)*np;
|
||||||
|
|
||||||
|
// Find the direction of the interface parallel to the wall
|
||||||
|
vectorField nWall(nHatp - (np & nHatp)*np);
|
||||||
|
nWall /= (mag(nWall) + small);
|
||||||
|
|
||||||
|
// Calculate Uwall resolved normal to the interface parallel to
|
||||||
|
// the interface
|
||||||
|
const scalarField uwall(nWall & Uwall);
|
||||||
|
|
||||||
|
theta += (thetaA - thetaR)*tanh(uwall/uTheta);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset nHatp to correspond to the contact angle
|
||||||
|
const scalarField a12(nHatp & np);
|
||||||
|
const scalarField b1(cos(theta));
|
||||||
|
scalarField b2(nHatp.size());
|
||||||
|
forAll(b2, facei)
|
||||||
|
{
|
||||||
|
b2[facei] = cos(acos(a12[facei]) - theta[facei]);
|
||||||
|
}
|
||||||
|
const scalarField det(1 - a12*a12);
|
||||||
|
const scalarField a((b1 - a12*b2)/det);
|
||||||
|
const scalarField b((b2 - a12*b1)/det);
|
||||||
|
|
||||||
|
nHatp = a*np + b*nHatp;
|
||||||
|
nHatp /= (mag(nHatp) + deltaN.value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,65 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration | Website: https://openfoam.org
|
||||||
|
\\ / A nd | Copyright (C) 2022 OpenFOAM Foundation
|
||||||
|
\\/ 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::correctContactAngle
|
||||||
|
|
||||||
|
Description
|
||||||
|
Correction for the boundary condition on the unit normal nHat on
|
||||||
|
walls to produce the correct contact angle. The dynamic contact angle is
|
||||||
|
calculated from the component of the velocity on the direction of the
|
||||||
|
interface, parallel to the wall.
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
correctContactAngle.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef correctContactAngle_H
|
||||||
|
#define correctContactAngle_H
|
||||||
|
|
||||||
|
#include "alphaContactAngleFvPatchScalarField.H"
|
||||||
|
#include "surfaceFields.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
//- Correct the contact angle for the two volume fraction fields
|
||||||
|
void correctContactAngle
|
||||||
|
(
|
||||||
|
const volScalarField& alpha1,
|
||||||
|
const volScalarField& alpha2,
|
||||||
|
const volVectorField::Boundary& Ubf,
|
||||||
|
const dimensionedScalar& deltaN,
|
||||||
|
surfaceVectorField::Boundary& nHatbf
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -23,43 +23,34 @@ boundaryField
|
|||||||
leftWall
|
leftWall
|
||||||
{
|
{
|
||||||
type alphaContactAngle;
|
type alphaContactAngle;
|
||||||
thetaProperties
|
contactAngleProperties
|
||||||
(
|
{
|
||||||
( water air ) 90 0 0 0
|
oil { theta0 90; }
|
||||||
( oil air ) 90 0 0 0
|
water { theta0 90; }
|
||||||
( mercury air ) 90 0 0 0
|
mercury { theta0 90; }
|
||||||
( water oil ) 90 0 0 0
|
}
|
||||||
( water mercury ) 90 0 0 0
|
|
||||||
( oil mercury ) 90 0 0 0
|
|
||||||
);
|
|
||||||
value uniform 0;
|
value uniform 0;
|
||||||
}
|
}
|
||||||
rightWall
|
rightWall
|
||||||
{
|
{
|
||||||
type alphaContactAngle;
|
type alphaContactAngle;
|
||||||
thetaProperties
|
contactAngleProperties
|
||||||
(
|
{
|
||||||
( water air ) 90 0 0 0
|
oil { theta0 90; }
|
||||||
( oil air ) 90 0 0 0
|
water { theta0 90; }
|
||||||
( mercury air ) 90 0 0 0
|
mercury { theta0 90; }
|
||||||
( water oil ) 90 0 0 0
|
}
|
||||||
( water mercury ) 90 0 0 0
|
|
||||||
( oil mercury ) 90 0 0 0
|
|
||||||
);
|
|
||||||
value uniform 1;
|
value uniform 1;
|
||||||
}
|
}
|
||||||
lowerWall
|
lowerWall
|
||||||
{
|
{
|
||||||
type alphaContactAngle;
|
type alphaContactAngle;
|
||||||
thetaProperties
|
contactAngleProperties
|
||||||
(
|
{
|
||||||
( water air ) 90 0 0 0
|
oil { theta0 90; }
|
||||||
( oil air ) 90 0 0 0
|
water { theta0 90; }
|
||||||
( mercury air ) 90 0 0 0
|
mercury { theta0 90; }
|
||||||
( water oil ) 90 0 0 0
|
}
|
||||||
( water mercury ) 90 0 0 0
|
|
||||||
( oil mercury ) 90 0 0 0
|
|
||||||
);
|
|
||||||
value uniform 0;
|
value uniform 0;
|
||||||
}
|
}
|
||||||
atmosphere
|
atmosphere
|
||||||
|
|||||||
@ -22,15 +22,36 @@ boundaryField
|
|||||||
{
|
{
|
||||||
leftWall
|
leftWall
|
||||||
{
|
{
|
||||||
type zeroGradient;
|
type alphaContactAngle;
|
||||||
|
contactAngleProperties
|
||||||
|
{
|
||||||
|
air { theta0 90; }
|
||||||
|
oil { theta0 90; }
|
||||||
|
water { theta0 90; }
|
||||||
|
}
|
||||||
|
value uniform 0;
|
||||||
}
|
}
|
||||||
rightWall
|
rightWall
|
||||||
{
|
{
|
||||||
type zeroGradient;
|
type alphaContactAngle;
|
||||||
|
contactAngleProperties
|
||||||
|
{
|
||||||
|
air { theta0 90; }
|
||||||
|
oil { theta0 90; }
|
||||||
|
water { theta0 90; }
|
||||||
|
}
|
||||||
|
value uniform 0;
|
||||||
}
|
}
|
||||||
lowerWall
|
lowerWall
|
||||||
{
|
{
|
||||||
type zeroGradient;
|
type alphaContactAngle;
|
||||||
|
contactAngleProperties
|
||||||
|
{
|
||||||
|
air { theta0 90; }
|
||||||
|
oil { theta0 90; }
|
||||||
|
water { theta0 90; }
|
||||||
|
}
|
||||||
|
value uniform 0;
|
||||||
}
|
}
|
||||||
atmosphere
|
atmosphere
|
||||||
{
|
{
|
||||||
|
|||||||
@ -22,15 +22,36 @@ boundaryField
|
|||||||
{
|
{
|
||||||
leftWall
|
leftWall
|
||||||
{
|
{
|
||||||
type zeroGradient;
|
type alphaContactAngle;
|
||||||
|
contactAngleProperties
|
||||||
|
{
|
||||||
|
air { theta0 90; }
|
||||||
|
water { theta0 90; }
|
||||||
|
mercury { theta0 90; }
|
||||||
|
}
|
||||||
|
value uniform 0;
|
||||||
}
|
}
|
||||||
rightWall
|
rightWall
|
||||||
{
|
{
|
||||||
type zeroGradient;
|
type alphaContactAngle;
|
||||||
|
contactAngleProperties
|
||||||
|
{
|
||||||
|
air { theta0 90; }
|
||||||
|
water { theta0 90; }
|
||||||
|
mercury { theta0 90; }
|
||||||
|
}
|
||||||
|
value uniform 0;
|
||||||
}
|
}
|
||||||
lowerWall
|
lowerWall
|
||||||
{
|
{
|
||||||
type zeroGradient;
|
type alphaContactAngle;
|
||||||
|
contactAngleProperties
|
||||||
|
{
|
||||||
|
air { theta0 90; }
|
||||||
|
water { theta0 90; }
|
||||||
|
mercury { theta0 90; }
|
||||||
|
}
|
||||||
|
value uniform 0;
|
||||||
}
|
}
|
||||||
atmosphere
|
atmosphere
|
||||||
{
|
{
|
||||||
|
|||||||
@ -22,15 +22,36 @@ boundaryField
|
|||||||
{
|
{
|
||||||
leftWall
|
leftWall
|
||||||
{
|
{
|
||||||
type zeroGradient;
|
type alphaContactAngle;
|
||||||
|
contactAngleProperties
|
||||||
|
{
|
||||||
|
air { theta0 90; }
|
||||||
|
oil { theta0 90; }
|
||||||
|
mercury { theta0 90; }
|
||||||
|
}
|
||||||
|
value uniform 0;
|
||||||
}
|
}
|
||||||
rightWall
|
rightWall
|
||||||
{
|
{
|
||||||
type zeroGradient;
|
type alphaContactAngle;
|
||||||
|
contactAngleProperties
|
||||||
|
{
|
||||||
|
air { theta0 90; }
|
||||||
|
oil { theta0 90; }
|
||||||
|
mercury { theta0 90; }
|
||||||
|
}
|
||||||
|
value uniform 0;
|
||||||
}
|
}
|
||||||
lowerWall
|
lowerWall
|
||||||
{
|
{
|
||||||
type zeroGradient;
|
type alphaContactAngle;
|
||||||
|
contactAngleProperties
|
||||||
|
{
|
||||||
|
air { theta0 90; }
|
||||||
|
oil { theta0 90; }
|
||||||
|
mercury { theta0 90; }
|
||||||
|
}
|
||||||
|
value uniform 0;
|
||||||
}
|
}
|
||||||
atmosphere
|
atmosphere
|
||||||
{
|
{
|
||||||
|
|||||||
@ -23,43 +23,34 @@ boundaryField
|
|||||||
leftWall
|
leftWall
|
||||||
{
|
{
|
||||||
type alphaContactAngle;
|
type alphaContactAngle;
|
||||||
thetaProperties
|
contactAngleProperties
|
||||||
(
|
{
|
||||||
( water air ) 90 0 0 0
|
oil { theta0 90; }
|
||||||
( oil air ) 90 0 0 0
|
water { theta0 90; }
|
||||||
( mercury air ) 90 0 0 0
|
mercury { theta0 90; }
|
||||||
( water oil ) 90 0 0 0
|
}
|
||||||
( water mercury ) 90 0 0 0
|
|
||||||
( oil mercury ) 90 0 0 0
|
|
||||||
);
|
|
||||||
value uniform 0;
|
value uniform 0;
|
||||||
}
|
}
|
||||||
rightWall
|
rightWall
|
||||||
{
|
{
|
||||||
type alphaContactAngle;
|
type alphaContactAngle;
|
||||||
thetaProperties
|
contactAngleProperties
|
||||||
(
|
{
|
||||||
( water air ) 90 0 0 0
|
oil { theta0 90; }
|
||||||
( oil air ) 90 0 0 0
|
water { theta0 90; }
|
||||||
( mercury air ) 90 0 0 0
|
mercury { theta0 90; }
|
||||||
( water oil ) 90 0 0 0
|
}
|
||||||
( water mercury ) 90 0 0 0
|
|
||||||
( oil mercury ) 90 0 0 0
|
|
||||||
);
|
|
||||||
value uniform 1;
|
value uniform 1;
|
||||||
}
|
}
|
||||||
lowerWall
|
lowerWall
|
||||||
{
|
{
|
||||||
type alphaContactAngle;
|
type alphaContactAngle;
|
||||||
thetaProperties
|
contactAngleProperties
|
||||||
(
|
{
|
||||||
( water air ) 90 0 0 0
|
oil { theta0 90; }
|
||||||
( oil air ) 90 0 0 0
|
water { theta0 90; }
|
||||||
( mercury air ) 90 0 0 0
|
mercury { theta0 90; }
|
||||||
( water oil ) 90 0 0 0
|
}
|
||||||
( water mercury ) 90 0 0 0
|
|
||||||
( oil mercury ) 90 0 0 0
|
|
||||||
);
|
|
||||||
value uniform 0;
|
value uniform 0;
|
||||||
}
|
}
|
||||||
atmosphere
|
atmosphere
|
||||||
|
|||||||
@ -22,15 +22,36 @@ boundaryField
|
|||||||
{
|
{
|
||||||
leftWall
|
leftWall
|
||||||
{
|
{
|
||||||
type zeroGradient;
|
type alphaContactAngle;
|
||||||
|
contactAngleProperties
|
||||||
|
{
|
||||||
|
air { theta0 90; }
|
||||||
|
oil { theta0 90; }
|
||||||
|
water { theta0 90; }
|
||||||
|
}
|
||||||
|
value uniform 0;
|
||||||
}
|
}
|
||||||
rightWall
|
rightWall
|
||||||
{
|
{
|
||||||
type zeroGradient;
|
type alphaContactAngle;
|
||||||
|
contactAngleProperties
|
||||||
|
{
|
||||||
|
air { theta0 90; }
|
||||||
|
oil { theta0 90; }
|
||||||
|
water { theta0 90; }
|
||||||
|
}
|
||||||
|
value uniform 0;
|
||||||
}
|
}
|
||||||
lowerWall
|
lowerWall
|
||||||
{
|
{
|
||||||
type zeroGradient;
|
type alphaContactAngle;
|
||||||
|
contactAngleProperties
|
||||||
|
{
|
||||||
|
air { theta0 90; }
|
||||||
|
oil { theta0 90; }
|
||||||
|
water { theta0 90; }
|
||||||
|
}
|
||||||
|
value uniform 0;
|
||||||
}
|
}
|
||||||
atmosphere
|
atmosphere
|
||||||
{
|
{
|
||||||
|
|||||||
@ -22,15 +22,36 @@ boundaryField
|
|||||||
{
|
{
|
||||||
leftWall
|
leftWall
|
||||||
{
|
{
|
||||||
type zeroGradient;
|
type alphaContactAngle;
|
||||||
|
contactAngleProperties
|
||||||
|
{
|
||||||
|
air { theta0 90; }
|
||||||
|
water { theta0 90; }
|
||||||
|
mercury { theta0 90; }
|
||||||
|
}
|
||||||
|
value uniform 0;
|
||||||
}
|
}
|
||||||
rightWall
|
rightWall
|
||||||
{
|
{
|
||||||
type zeroGradient;
|
type alphaContactAngle;
|
||||||
|
contactAngleProperties
|
||||||
|
{
|
||||||
|
air { theta0 90; }
|
||||||
|
water { theta0 90; }
|
||||||
|
mercury { theta0 90; }
|
||||||
|
}
|
||||||
|
value uniform 0;
|
||||||
}
|
}
|
||||||
lowerWall
|
lowerWall
|
||||||
{
|
{
|
||||||
type zeroGradient;
|
type alphaContactAngle;
|
||||||
|
contactAngleProperties
|
||||||
|
{
|
||||||
|
air { theta0 90; }
|
||||||
|
water { theta0 90; }
|
||||||
|
mercury { theta0 90; }
|
||||||
|
}
|
||||||
|
value uniform 0;
|
||||||
}
|
}
|
||||||
atmosphere
|
atmosphere
|
||||||
{
|
{
|
||||||
|
|||||||
@ -22,15 +22,36 @@ boundaryField
|
|||||||
{
|
{
|
||||||
leftWall
|
leftWall
|
||||||
{
|
{
|
||||||
type zeroGradient;
|
type alphaContactAngle;
|
||||||
|
contactAngleProperties
|
||||||
|
{
|
||||||
|
air { theta0 90; }
|
||||||
|
oil { theta0 90; }
|
||||||
|
mercury { theta0 90; }
|
||||||
|
}
|
||||||
|
value uniform 0;
|
||||||
}
|
}
|
||||||
rightWall
|
rightWall
|
||||||
{
|
{
|
||||||
type zeroGradient;
|
type alphaContactAngle;
|
||||||
|
contactAngleProperties
|
||||||
|
{
|
||||||
|
air { theta0 90; }
|
||||||
|
oil { theta0 90; }
|
||||||
|
mercury { theta0 90; }
|
||||||
|
}
|
||||||
|
value uniform 0;
|
||||||
}
|
}
|
||||||
lowerWall
|
lowerWall
|
||||||
{
|
{
|
||||||
type zeroGradient;
|
type alphaContactAngle;
|
||||||
|
contactAngleProperties
|
||||||
|
{
|
||||||
|
air { theta0 90; }
|
||||||
|
oil { theta0 90; }
|
||||||
|
mercury { theta0 90; }
|
||||||
|
}
|
||||||
|
value uniform 0;
|
||||||
}
|
}
|
||||||
atmosphere
|
atmosphere
|
||||||
{
|
{
|
||||||
|
|||||||
@ -23,43 +23,34 @@ boundaryField
|
|||||||
leftWall
|
leftWall
|
||||||
{
|
{
|
||||||
type alphaContactAngle;
|
type alphaContactAngle;
|
||||||
thetaProperties
|
contactAngleProperties
|
||||||
(
|
{
|
||||||
( water air ) 90 0 0 0
|
oil { theta0 90; }
|
||||||
( oil air ) 90 0 0 0
|
water { theta0 90; }
|
||||||
( mercury air ) 90 0 0 0
|
mercury { theta0 90; }
|
||||||
( water oil ) 90 0 0 0
|
}
|
||||||
( water mercury ) 90 0 0 0
|
|
||||||
( oil mercury ) 90 0 0 0
|
|
||||||
);
|
|
||||||
value uniform 0;
|
value uniform 0;
|
||||||
}
|
}
|
||||||
rightWall
|
rightWall
|
||||||
{
|
{
|
||||||
type alphaContactAngle;
|
type alphaContactAngle;
|
||||||
thetaProperties
|
contactAngleProperties
|
||||||
(
|
{
|
||||||
( water air ) 90 0 0 0
|
oil { theta0 90; }
|
||||||
( oil air ) 90 0 0 0
|
water { theta0 90; }
|
||||||
( mercury air ) 90 0 0 0
|
mercury { theta0 90; }
|
||||||
( water oil ) 90 0 0 0
|
}
|
||||||
( water mercury ) 90 0 0 0
|
|
||||||
( oil mercury ) 90 0 0 0
|
|
||||||
);
|
|
||||||
value uniform 1;
|
value uniform 1;
|
||||||
}
|
}
|
||||||
lowerWall
|
lowerWall
|
||||||
{
|
{
|
||||||
type alphaContactAngle;
|
type alphaContactAngle;
|
||||||
thetaProperties
|
contactAngleProperties
|
||||||
(
|
{
|
||||||
( water air ) 90 0 0 0
|
oil { theta0 90; }
|
||||||
( oil air ) 90 0 0 0
|
water { theta0 90; }
|
||||||
( mercury air ) 90 0 0 0
|
mercury { theta0 90; }
|
||||||
( water oil ) 90 0 0 0
|
}
|
||||||
( water mercury ) 90 0 0 0
|
|
||||||
( oil mercury ) 90 0 0 0
|
|
||||||
);
|
|
||||||
value uniform 0;
|
value uniform 0;
|
||||||
}
|
}
|
||||||
atmosphere
|
atmosphere
|
||||||
|
|||||||
@ -22,15 +22,36 @@ boundaryField
|
|||||||
{
|
{
|
||||||
leftWall
|
leftWall
|
||||||
{
|
{
|
||||||
type zeroGradient;
|
type alphaContactAngle;
|
||||||
|
contactAngleProperties
|
||||||
|
{
|
||||||
|
air { theta0 90; }
|
||||||
|
oil { theta0 90; }
|
||||||
|
water { theta0 90; }
|
||||||
|
}
|
||||||
|
value uniform 0;
|
||||||
}
|
}
|
||||||
rightWall
|
rightWall
|
||||||
{
|
{
|
||||||
type zeroGradient;
|
type alphaContactAngle;
|
||||||
|
contactAngleProperties
|
||||||
|
{
|
||||||
|
air { theta0 90; }
|
||||||
|
oil { theta0 90; }
|
||||||
|
water { theta0 90; }
|
||||||
|
}
|
||||||
|
value uniform 0;
|
||||||
}
|
}
|
||||||
lowerWall
|
lowerWall
|
||||||
{
|
{
|
||||||
type zeroGradient;
|
type alphaContactAngle;
|
||||||
|
contactAngleProperties
|
||||||
|
{
|
||||||
|
air { theta0 90; }
|
||||||
|
oil { theta0 90; }
|
||||||
|
water { theta0 90; }
|
||||||
|
}
|
||||||
|
value uniform 0;
|
||||||
}
|
}
|
||||||
atmosphere
|
atmosphere
|
||||||
{
|
{
|
||||||
|
|||||||
@ -22,15 +22,36 @@ boundaryField
|
|||||||
{
|
{
|
||||||
leftWall
|
leftWall
|
||||||
{
|
{
|
||||||
type zeroGradient;
|
type alphaContactAngle;
|
||||||
|
contactAngleProperties
|
||||||
|
{
|
||||||
|
air { theta0 90; }
|
||||||
|
water { theta0 90; }
|
||||||
|
mercury { theta0 90; }
|
||||||
|
}
|
||||||
|
value uniform 0;
|
||||||
}
|
}
|
||||||
rightWall
|
rightWall
|
||||||
{
|
{
|
||||||
type zeroGradient;
|
type alphaContactAngle;
|
||||||
|
contactAngleProperties
|
||||||
|
{
|
||||||
|
air { theta0 90; }
|
||||||
|
water { theta0 90; }
|
||||||
|
mercury { theta0 90; }
|
||||||
|
}
|
||||||
|
value uniform 0;
|
||||||
}
|
}
|
||||||
lowerWall
|
lowerWall
|
||||||
{
|
{
|
||||||
type zeroGradient;
|
type alphaContactAngle;
|
||||||
|
contactAngleProperties
|
||||||
|
{
|
||||||
|
air { theta0 90; }
|
||||||
|
water { theta0 90; }
|
||||||
|
mercury { theta0 90; }
|
||||||
|
}
|
||||||
|
value uniform 0;
|
||||||
}
|
}
|
||||||
atmosphere
|
atmosphere
|
||||||
{
|
{
|
||||||
|
|||||||
@ -22,15 +22,36 @@ boundaryField
|
|||||||
{
|
{
|
||||||
leftWall
|
leftWall
|
||||||
{
|
{
|
||||||
type zeroGradient;
|
type alphaContactAngle;
|
||||||
|
contactAngleProperties
|
||||||
|
{
|
||||||
|
air { theta0 90; }
|
||||||
|
oil { theta0 90; }
|
||||||
|
mercury { theta0 90; }
|
||||||
|
}
|
||||||
|
value uniform 0;
|
||||||
}
|
}
|
||||||
rightWall
|
rightWall
|
||||||
{
|
{
|
||||||
type zeroGradient;
|
type alphaContactAngle;
|
||||||
|
contactAngleProperties
|
||||||
|
{
|
||||||
|
air { theta0 90; }
|
||||||
|
oil { theta0 90; }
|
||||||
|
mercury { theta0 90; }
|
||||||
|
}
|
||||||
|
value uniform 0;
|
||||||
}
|
}
|
||||||
lowerWall
|
lowerWall
|
||||||
{
|
{
|
||||||
type zeroGradient;
|
type alphaContactAngle;
|
||||||
|
contactAngleProperties
|
||||||
|
{
|
||||||
|
air { theta0 90; }
|
||||||
|
oil { theta0 90; }
|
||||||
|
mercury { theta0 90; }
|
||||||
|
}
|
||||||
|
value uniform 0;
|
||||||
}
|
}
|
||||||
atmosphere
|
atmosphere
|
||||||
{
|
{
|
||||||
|
|||||||
@ -23,43 +23,34 @@ boundaryField
|
|||||||
leftWall
|
leftWall
|
||||||
{
|
{
|
||||||
type alphaContactAngle;
|
type alphaContactAngle;
|
||||||
thetaProperties
|
contactAngleProperties
|
||||||
(
|
{
|
||||||
( water air ) 90 0 0 0
|
oil { theta0 90; }
|
||||||
( oil air ) 90 0 0 0
|
water { theta0 90; }
|
||||||
( mercury air ) 90 0 0 0
|
mercury { theta0 90; }
|
||||||
( water oil ) 90 0 0 0
|
}
|
||||||
( water mercury ) 90 0 0 0
|
|
||||||
( oil mercury ) 90 0 0 0
|
|
||||||
);
|
|
||||||
value uniform 0;
|
value uniform 0;
|
||||||
}
|
}
|
||||||
rightWall
|
rightWall
|
||||||
{
|
{
|
||||||
type alphaContactAngle;
|
type alphaContactAngle;
|
||||||
thetaProperties
|
contactAngleProperties
|
||||||
(
|
{
|
||||||
( water air ) 90 0 0 0
|
oil { theta0 90; }
|
||||||
( oil air ) 90 0 0 0
|
water { theta0 90; }
|
||||||
( mercury air ) 90 0 0 0
|
mercury { theta0 90; }
|
||||||
( water oil ) 90 0 0 0
|
}
|
||||||
( water mercury ) 90 0 0 0
|
|
||||||
( oil mercury ) 90 0 0 0
|
|
||||||
);
|
|
||||||
value uniform 1;
|
value uniform 1;
|
||||||
}
|
}
|
||||||
lowerWall
|
lowerWall
|
||||||
{
|
{
|
||||||
type alphaContactAngle;
|
type alphaContactAngle;
|
||||||
thetaProperties
|
contactAngleProperties
|
||||||
(
|
{
|
||||||
( water air ) 90 0 0 0
|
oil { theta0 90; }
|
||||||
( oil air ) 90 0 0 0
|
water { theta0 90; }
|
||||||
( mercury air ) 90 0 0 0
|
mercury { theta0 90; }
|
||||||
( water oil ) 90 0 0 0
|
}
|
||||||
( water mercury ) 90 0 0 0
|
|
||||||
( oil mercury ) 90 0 0 0
|
|
||||||
);
|
|
||||||
value uniform 0;
|
value uniform 0;
|
||||||
}
|
}
|
||||||
atmosphere
|
atmosphere
|
||||||
|
|||||||
@ -22,15 +22,36 @@ boundaryField
|
|||||||
{
|
{
|
||||||
leftWall
|
leftWall
|
||||||
{
|
{
|
||||||
type zeroGradient;
|
type alphaContactAngle;
|
||||||
|
contactAngleProperties
|
||||||
|
{
|
||||||
|
air { theta0 90; }
|
||||||
|
oil { theta0 90; }
|
||||||
|
water { theta0 90; }
|
||||||
|
}
|
||||||
|
value uniform 0;
|
||||||
}
|
}
|
||||||
rightWall
|
rightWall
|
||||||
{
|
{
|
||||||
type zeroGradient;
|
type alphaContactAngle;
|
||||||
|
contactAngleProperties
|
||||||
|
{
|
||||||
|
air { theta0 90; }
|
||||||
|
oil { theta0 90; }
|
||||||
|
water { theta0 90; }
|
||||||
|
}
|
||||||
|
value uniform 0;
|
||||||
}
|
}
|
||||||
lowerWall
|
lowerWall
|
||||||
{
|
{
|
||||||
type zeroGradient;
|
type alphaContactAngle;
|
||||||
|
contactAngleProperties
|
||||||
|
{
|
||||||
|
air { theta0 90; }
|
||||||
|
oil { theta0 90; }
|
||||||
|
water { theta0 90; }
|
||||||
|
}
|
||||||
|
value uniform 0;
|
||||||
}
|
}
|
||||||
atmosphere
|
atmosphere
|
||||||
{
|
{
|
||||||
|
|||||||
@ -22,15 +22,36 @@ boundaryField
|
|||||||
{
|
{
|
||||||
leftWall
|
leftWall
|
||||||
{
|
{
|
||||||
type zeroGradient;
|
type alphaContactAngle;
|
||||||
|
contactAngleProperties
|
||||||
|
{
|
||||||
|
air { theta0 90; }
|
||||||
|
water { theta0 90; }
|
||||||
|
mercury { theta0 90; }
|
||||||
|
}
|
||||||
|
value uniform 0;
|
||||||
}
|
}
|
||||||
rightWall
|
rightWall
|
||||||
{
|
{
|
||||||
type zeroGradient;
|
type alphaContactAngle;
|
||||||
|
contactAngleProperties
|
||||||
|
{
|
||||||
|
air { theta0 90; }
|
||||||
|
water { theta0 90; }
|
||||||
|
mercury { theta0 90; }
|
||||||
|
}
|
||||||
|
value uniform 0;
|
||||||
}
|
}
|
||||||
lowerWall
|
lowerWall
|
||||||
{
|
{
|
||||||
type zeroGradient;
|
type alphaContactAngle;
|
||||||
|
contactAngleProperties
|
||||||
|
{
|
||||||
|
air { theta0 90; }
|
||||||
|
water { theta0 90; }
|
||||||
|
mercury { theta0 90; }
|
||||||
|
}
|
||||||
|
value uniform 0;
|
||||||
}
|
}
|
||||||
atmosphere
|
atmosphere
|
||||||
{
|
{
|
||||||
|
|||||||
@ -22,15 +22,36 @@ boundaryField
|
|||||||
{
|
{
|
||||||
leftWall
|
leftWall
|
||||||
{
|
{
|
||||||
type zeroGradient;
|
type alphaContactAngle;
|
||||||
|
contactAngleProperties
|
||||||
|
{
|
||||||
|
air { theta0 90; }
|
||||||
|
oil { theta0 90; }
|
||||||
|
mercury { theta0 90; }
|
||||||
|
}
|
||||||
|
value uniform 0;
|
||||||
}
|
}
|
||||||
rightWall
|
rightWall
|
||||||
{
|
{
|
||||||
type zeroGradient;
|
type alphaContactAngle;
|
||||||
|
contactAngleProperties
|
||||||
|
{
|
||||||
|
air { theta0 90; }
|
||||||
|
oil { theta0 90; }
|
||||||
|
mercury { theta0 90; }
|
||||||
|
}
|
||||||
|
value uniform 0;
|
||||||
}
|
}
|
||||||
lowerWall
|
lowerWall
|
||||||
{
|
{
|
||||||
type zeroGradient;
|
type alphaContactAngle;
|
||||||
|
contactAngleProperties
|
||||||
|
{
|
||||||
|
air { theta0 90; }
|
||||||
|
oil { theta0 90; }
|
||||||
|
mercury { theta0 90; }
|
||||||
|
}
|
||||||
|
value uniform 0;
|
||||||
}
|
}
|
||||||
atmosphere
|
atmosphere
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user