|
flow 1.3.0
Kokkos cut-cell IBM incompressible Navier-Stokes solver + pnm pore extraction
|
flow — VoF rung V6 (WO-V6): the DYNAMIC contact angle (Cox-Voinov with an explicit slip length) and advancing/receding HYSTERESIS with pinning. More...
#include <cmath>#include <functional>#include <Kokkos_Core.hpp>#include <Kokkos_MathematicalFunctions.hpp>#include "policy.hpp"#include "vof/advect_wy.hpp"Go to the source code of this file.
Classes | |
| struct | peclet::flow::vof::VofDynamicWetting |
The driver: produces WyAdvector::contactAngle() from the current colour, geometry, wall SDF, fluid-only normals and cell-centre velocity, once per band fill. More... | |
| struct | peclet::flow::vof::VofDynamicWetting::Census |
Census over the INNER region: cells per state, mean imposed / apparent angle (degrees) over the contact cells, and max |Ca_cl|. More... | |
Namespaces | |
| namespace | peclet |
| namespace | peclet::flow |
| namespace | peclet::flow::vof |
Enumerations | |
| enum | peclet::flow::vof::VofDynamicState : int { peclet::flow::vof::kVofDynNone = 0 , peclet::flow::vof::kVofDynStatic = 1 , peclet::flow::vof::kVofDynPinned = 2 , peclet::flow::vof::kVofDynAdvancing = 3 , peclet::flow::vof::kVofDynReceding = 4 , peclet::flow::vof::kVofDynStateCount = 5 } |
Which rule produced a band cell's imposed angle (vof_dynamic_field(4)). More... | |
Functions | |
| double | peclet::flow::vof::coxVoinovAngle (double thetaE, double ca, double logRatio, double thetaMin, double thetaMax) |
| Cox-Voinov / Afkhami-Zaleski-Bussmann grid-scale apparent angle, in RADIANS. | |
| int | peclet::flow::vof::vofHysteresisBase (double thetaApp, double thetaA, double thetaR, double &base) |
| The hysteresis selector: which base angle the Cox-Voinov correction is applied to, and whether the line is pinned. | |
| int | peclet::flow::vof::vofDynamicContactAngle (double thetaApp, double uCl, double muL, double sigma, double logRatio, bool hyst, double thetaA, double thetaR, double thetaE, double thetaMin, double thetaMax, double &thetaOut, double &caOut) |
| The whole rung in one pure function: hysteresis selector, then Cox-Voinov on the selected base. | |
| bool | peclet::flow::vof::vofWallTangent (const double mfIn[3], const double nwIn[3], double tEps, double that[3], double &cosApp, const VofMetric &g) |
| The in-wall (tangential) unit direction of the interface and its apparent cosine. | |
| bool | peclet::flow::vof::vofWallTangent (const double mfIn[3], const double nwIn[3], double tEps, double that[3], double &cosApp) |
| Unit-metric overload (isotropic cells) — the pre-Phase-3 signature, unchanged arithmetic. | |
| double | peclet::flow::vof::vofContactLineSpeed (const double u[3], const double that[3]) |
U_cl = +u . | |
flow — VoF rung V6 (WO-V6): the DYNAMIC contact angle (Cox-Voinov with an explicit slip length) and advancing/receding HYSTERESIS with pinning.
Nothing in the V5b fill changes; only the VALUE of theta per contact cell does. wetting.hpp already reads theta as a per-cell field (WyAdvector::contactAngle()), so this rung is a producer for that field and nothing else — the plane construction, the anchor, the branch census and passes 2-3 of the band fill are WO-S's, untouched.
Afkhami, Zaleski & Bussmann, JCP 228:5370 (2009). A sharp-interface simulation cannot resolve the microscopic contact line, so the angle it imposes at the grid scale Delta is not the equilibrium angle but the Cox-Voinov apparent angle at that scale, with the outer cut-off set to the cell size and the inner one to an EXPLICIT slip length lambda:
theta_Delta^3 = theta_e^3 + 9 Ca_cl ln(Delta / lambda), Ca_cl = mu_l U_cl / sigma
(angles in RADIANS; Ca_cl > 0 advancing, < 0 receding). The point of the explicit lambda is that the numerical slip of a VoF contact line is proportional to Delta, so a computation without it silently makes the imposed angle grid-dependent — VOF_PLAN §6's "grid-dependent
mobility" trap. Never report a dynamic-wetting result without stating lambda.
theta_Delta is clamped into [thetaMin, thetaMax] (default 1 deg / 179 deg): the cubic has no solution above the maximum receding capillary number (where a liquid film is entrained) and the fill's plane construction degenerates at 0/180.
With an advancing angle theta_a and a receding angle theta_r (Dussan; Fang et al.), the contact line is PINNED while its apparent angle lies between them:
theta_app > theta_a -> impose theta_a (+ the Cox-Voinov correction with U_cl)
theta_app < theta_r -> impose theta_r (+ the correction)
otherwise -> impose theta_app (PINNED: the fill then reproduces the
current interface, so nothing moves)
The pinned branch is the load-bearing one and it is exact because the V5b fill is idempotent (WO-S finding 1): writing the band with the plane of the CURRENT apparent angle is the identity on the current configuration, so no Young force appears and the line does not move. A fill that were not idempotent could not express pinning at all.
theta_app comes from the same quantity the fill rotates: cos(theta_app) = m_f . n_w with m_f the fluid-only Youngs normal of the anchor cell (wetting.hpp) and n_w the wall normal. The contact line moves along the IN-WALL direction t_hat = (m_f - (m_f.n_w) n_w)/|...|, which points from the LIQUID towards the DRY wall (because m points into the gas), so the liquid ADVANCES when the fluid velocity points along +t_hat:
U_cl = + u_anchor . t_hat
(the work order writes -t_hat; that is a sign slip — see vofContactLineSpeed for the derivation and the measurement that settles it).
u_anchor is the cell-centre velocity (the mean of the cell's two faces per axis) of the anchor cell, and U_cl is then smoothed with a 3-POINT MEAN along t_hat (the cell and its two in-wall neighbours in the direction of motion) — a MAC velocity next to a wall is noisy cell to cell and an unsmoothed Ca_cl puts that noise straight into the imposed angle through the cube root.
The angle kernels below (coxVoinovAngle, vofHysteresisBase, vofDynamicContactAngle, vofWallTangent, vofContactLineSpeed) are container-free — scalars and small arrays only, the plic.hpp rule — so a host oracle calls them verbatim (that IS gate G1). VofDynamicWetting below is the driver that runs them over the colour block; it owns only its own scratch views and reads the advector through its public accessors, so advect_wy.hpp is not touched by this rung.
Definition in file wetting_dynamic.hpp.