Compare commits

...

1 Commits

Author SHA1 Message Date
d12c1508b9 ENH: dynamicContactAngle: enable zonal input using persistent field storage
Temporary field creation is replaced with persistent field storage,
so that contact-angle can be input per zone using setFields utility.
2025-10-16 20:25:33 +01:00
2 changed files with 53 additions and 45 deletions

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2020-2023 OpenCFD Ltd. Copyright (C) 2020-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -26,9 +26,9 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "dynamicContactAngleForce.H" #include "dynamicContactAngleForce.H"
#include "addToRunTimeSelectionTable.H"
#include "Function1.H" #include "Function1.H"
#include "distributionModel.H" #include "distributionModel.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -59,6 +59,7 @@ dynamicContactAngleForce::dynamicContactAngleForce
) )
: :
contactAngleForce(typeName, film, dict), contactAngleForce(typeName, film, dict),
thetaPtr_(nullptr),
U_vs_thetaPtr_ U_vs_thetaPtr_
( (
Function1<scalar>::NewIfPresent Function1<scalar>::NewIfPresent
@ -80,46 +81,56 @@ dynamicContactAngleForce::dynamicContactAngleForce
) )
), ),
rndGen_(label(0)), rndGen_(label(0)),
distribution_ distributionPtr_(nullptr)
(
distributionModel::New
(
coeffDict_.subDict("distribution"),
rndGen_
)
)
{ {
if (U_vs_thetaPtr_ && T_vs_thetaPtr_) if (U_vs_thetaPtr_ && T_vs_thetaPtr_)
{ {
FatalIOErrorInFunction(dict) FatalIOErrorInFunction(dict)
<< "Entries Utheta and Ttheta could not be used together" << "Only one of Utheta or Ttheta should be provided; "
<< "both inputs cannot be used together."
<< abort(FatalIOError); << abort(FatalIOError);
} }
thetaPtr_.emplace
(
IOobject
(
IOobject::scopedName(typeName, "theta"),
film.regionMesh().time().timeName(),
film.regionMesh().thisDb(),
IOobject::READ_IF_PRESENT,
IOobject::AUTO_WRITE
),
film.regionMesh(),
dimensionedScalar(dimless, Zero)
);
if (coeffDict_.findEntry("distribution"))
{
distributionPtr_ = distributionModel::New
(
coeffDict_.subDict("distribution"),
rndGen_
);
}
} }
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::dynamicContactAngleForce::~dynamicContactAngleForce()
{} // distributionModel was forward declared
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
tmp<areaScalarField> dynamicContactAngleForce::theta() const tmp<areaScalarField> dynamicContactAngleForce::theta() const
{ {
auto ttheta = tmp<areaScalarField>::New areaScalarField& theta = thetaPtr_.ref();
(
IOobject
(
IOobject::scopedName(typeName, "theta"),
film().regionMesh().time().timeName(),
film().regionMesh().thisDb(),
IOobject::NO_READ,
IOobject::NO_WRITE,
IOobject::NO_REGISTER
),
film().regionMesh(),
dimensionedScalar(dimless, Zero)
);
areaScalarField& theta = ttheta.ref();
scalarField& thetai = theta.ref(); scalarField& thetai = theta.ref();
if (U_vs_thetaPtr_) if (U_vs_thetaPtr_)
{ {
// Initialize with the function of film speed // Initialize with the function of film speed
@ -136,13 +147,16 @@ tmp<areaScalarField> dynamicContactAngleForce::theta() const
thetai = T_vs_thetaPtr_->value(T()); thetai = T_vs_thetaPtr_->value(T());
} }
// Add the stochastic perturbation if (distributionPtr_)
forAll(thetai, facei)
{ {
thetai[facei] += distribution_->sample(); // Add the stochastic perturbation
forAll(thetai, facei)
{
thetai[facei] += distributionPtr_->sample();
}
} }
return ttheta; return thetaPtr_();
} }

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2020-2022 OpenCFD Ltd. Copyright (C) 2020-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -112,6 +112,9 @@ class dynamicContactAngleForce
{ {
// Private Data // Private Data
//- Contact-angle field in degrees
mutable autoPtr<areaScalarField> thetaPtr_;
//- Contact angle as a function of film speed //- Contact angle as a function of film speed
autoPtr<Function1<scalar>> U_vs_thetaPtr_; autoPtr<Function1<scalar>> U_vs_thetaPtr_;
@ -121,17 +124,8 @@ class dynamicContactAngleForce
//- Random number generator //- Random number generator
Random rndGen_; Random rndGen_;
//- Parcel size PDF model //- Stochastic perturbation model for contact angle
const autoPtr<distributionModel> distribution_; autoPtr<distributionModel> distributionPtr_;
// Private Member Functions
//- No copy construct
dynamicContactAngleForce(const dynamicContactAngleForce&) = delete;
//- No copy assignment
void operator=(const dynamicContactAngleForce&) = delete;
protected: protected:
@ -148,7 +142,7 @@ public:
// Constructors // Constructors
//- Construct from surface film model //- Construct from surface film model and dictionary
dynamicContactAngleForce dynamicContactAngleForce
( (
liquidFilmBase& film, liquidFilmBase& film,
@ -157,7 +151,7 @@ public:
//- Destructor //- Destructor
virtual ~dynamicContactAngleForce() = default; virtual ~dynamicContactAngleForce();
}; };