Basilisk CFD
Adaptive Cartesian mesh PDE framework
Loading...
Searching...
No Matches
contact.h
Go to the documentation of this file.
1/** @file contact.h
2 */
3/**
4# Contact angles
5
6This file is used to impose contact angles on boundaries for
7interfaces described using a [VOF](vof.h) tracer and [height
8functions](heights.h).
9
10We first overload the default function used to compute the normal,
11defined in [fractions.h](). */
12
13#include "fractions.h"
14#include "curvature.h"
15
16/**
17We will compute the normal using height-functions instead. If this is
18not possible (typically at low resolutions) we revert back to
19the Mixed-Youngs-Centered approximation. */
20
22{
23 coord n;
24 if (!c.height.x.i || (n = height_normal (point, c, c.height)).x == nodata)
25 n = mycs (point, c);
26 return n;
27}
28
30 return height_myc_normal (point, c);
31}
32
33/**
34The height functions are stored in the vector field associated with
35each VOF tracer. They need to be updated every time the VOF field
36changes. For the [centered Navier-Stokes
37solver](navier-stokes/centered.h), this means after initialisation and
38after VOF advection.
39
40Note that strictly speaking this should be done for each
41[sweep](vof.h#sweep_x) of the direction-split VOF advection, which we
42do not do here i.e. we use the normal at the beginning of the timestep
43and assume it is constant during each sweep. This seems to work
44fine. */
45
46extern scalar * interfaces;
47
48/** @brief Event: init (i = 0) */
49void event_init (void) {
50 for (int _c = 0; _c < 1; _c++) /* scalar in interfaces */
51 if (c.height.x.i)
52 heights (c, c.height);
53}
54
55/** @brief Event: vof (i++) */
56void event_vof (void) {
57 for (int _c = 0; _c < 1; _c++) /* scalar in interfaces */
58 if (c.height.x.i)
59 heights (c, c.height);
60}
61
62/**
63The macro below can be used to impose a contact angle on a boundary by
64setting the corresponding tangential component of the height
65function.
66
67Note that the equivalent function for the normal component of the
68height function is not defined yet. This limits the range of
69accessible contact angles, since values of the normal component of the
70height function will be required to compute curvature at shallow
71angles. */
72
73#if dimension == 2
74
75#define contact_angle(theta) \
76 (val(_s) == nodata ? nodata : val(_s) + \
77 (orientation(val(_s)) ? -1. : 1.)/tan(theta))
78
79/**
80## Three-dimensional implementation
81
82While the 2D implementation is trivial, in 3D one must take into
83account the projection onto the boundary of the normal to the
84interface (see [Afkhami \& Bussmann, 2009](#afkhami2009) for
85details). This leads to the code below, where the only complication
86comes from taking into account the relative orientations of the
87boundary and height-function components.
88
89From a user point-of-view, using the *contact_angle()* macro is as
90simple as in 2D. */
91
92#else // dimension == 3
93
94#define contact_angle(theta) contact_angle_ (point, neighbor, _s, theta)
95
96for (int _d = 0; _d < dimension; _d++)
97static double contact_z (Point point, scalar h, double theta)
98{
99 if (h.i == h.v.z.i) {
101 "contact_angle() cannot be used for '%s' which is the normal\n"
102 " component of the height vector\n",
103 h.name);
104 exit (1);
105 }
106
107 if (h[] == nodata)
108 return nodata;
110 if (h.i == h.v.x.i)
112 coord n = normal2_x (point, h.v);
113 if (n.x != nodata && n.y != nodata)
114 return h[] + 1./(tan(theta)*n.x/sqrt(sq(n.x) + sq(n.y)));
115 }
116 return h[]; // 90 degree contact angle if the normal is not defined
117}
118
120{
121 if (neighbor.i != point.i)
122 return contact_x (point, h, theta);
123 if (neighbor.j != point.j)
124 return contact_y (point, h, theta);
125 if (neighbor.k != point.k)
126 return contact_z (point, h, theta);
127 assert (false); // not reached
128 return 0.;
129}
130
131#endif // dimension == 3
132
133/**
134## References
135
136~~~bib
137@article{afkhami2009,
138 title={Height functions for applying contact angles to 3D VOF simulations},
139 author={Afkhami, S and Bussmann, M},
140 journal={International Journal for Numerical Methods in Fluids},
141 volume={61},
142 number={8},
143 pages={827--847},
144 year={2009},
145 publisher={Wiley Online Library},
146 url={https://web.njit.edu/~shahriar/Publication/IJNMF2.pdf}
147}
148~~~
149*/
scalar h[]
Definition atmosphere.h:6
#define dimension
Definition bitree.h:3
define neighbor(o, p, q)((Point)
Definition cartesian.h:146
int x
Definition common.h:76
#define nodata
Definition common.h:7
static number sq(number x)
Definition common.h:11
#define assert(a)
Definition config.h:107
Point point
Definition conserving.h:86
scalar * interfaces
The height functions are stored in the vector field associated with each VOF tracer.
Definition two-phase.h:56
void event_vof(void)
Event: vof (i++)
Definition contact.h:56
void event_init(void)
Event: init (i = 0)
Definition contact.h:49
coord height_myc_normal(Point point, scalar c)
We will compute the normal using height-functions instead.
Definition contact.h:21
static coord interface_normal(Point point, scalar c)
Definition contact.h:29
coord height_normal(Point point, scalar c, vector h)
The function below works in a similar manner to return the normal estimated using height-functions (o...
Definition curvature.h:261
else return n
Definition curvature.h:101
trace void heights(scalar c, vector h)
The heights() function implementation is similar to the multigrid case, but the construction of the s...
Definition heights.h:366
coord mycs(Point point, scalar c)
Definition myc.h:18
Definition linear.h:21
int i
Definition linear.h:23
Definition common.h:78
int i
Definition common.h:44
double theta
This is the generalised minmod limiter.
Definition utils.h:223
scalar c
Definition vof.h:57