-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhenry.h
231 lines (199 loc) · 5.59 KB
/
henry.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
/**
# Advection/diffusion of a soluble tracer
We consider the transport and diffusion of a tracer $c$ with different
solubilities in the two-phases described by
[two-phase.h](/src/two-phase.h).
The diffusion coefficients in the two phases are $D_1$ and $D_2$ and
the jump in concentration at the interface is given by
$$
c_1 = \alpha c_2
$$
The advection/diffusion equation for $c$ can then be written
$$
\partial_t c + \nabla\cdot(\mathbf{u} c) =
\nabla\cdot\left(D\nabla c - D \frac{c(\alpha - 1)}
{\alpha f + (1 - f)}\nabla f\right)
$$
with $f$ the volume fraction and
$$
D = \frac{D_1 D_2}{D_2 f + D_1 (1 - f)}
$$
the harmonic mean of the diffusion coefficients (see [Haroun et al.,
2010](#haroun2010)).
The diffusion coefficients and solubility are attributes of each
tracer.
The *stracers* list of soluble tracers must be defined by the calling
code. */
attribute {
double D1, D2, alpha; //D1 for f = 1, D2 for f = 0
scalar phi1, phi2; // private
}
extern scalar * stracers;
/**
## Defaults
On trees we need to ensure conservation of the tracer when
refining/coarsening. */
#if TREE
event defaults (i = 0)
{
for (scalar s in stracers) {
#if EMBED
s.refine = s.prolongation = refine_embed_linear;
#else
s.refine = refine_linear;
#endif
s.restriction = restriction_volume_average;
s.dirty = true;
}
}
#endif // TREE
/**
## Advection
To avoid numerical diffusion through the interface we use the [VOF
tracer transport scheme](/src/vof.h) for the temporary fields
$\phi_1$ and $\phi_2$, see section 3.2 of [Farsoiya et al.,
2021](#farsoiya2021). */
static scalar * phi_tracers = NULL;
event vof (i++)
{
phi_tracers = f.tracers;
for (scalar c in stracers) {
scalar phi1 = new scalar, phi2 = new scalar;
c.phi1 = phi1, c.phi2 = phi2;
scalar_clone (phi1, c);
scalar_clone (phi2, c);
phi2.inverse = true;
f.tracers = list_append (f.tracers, phi1);
f.tracers = list_append (f.tracers, phi2);
/**
$\phi_1$ and $\phi_2$ are computed from $c$ as
$$
\phi_1 = c \frac{\alpha f}{\alpha f + (1 - f)}
$$
$$
\phi_2 = c \frac{1 - f}{\alpha f + (1 - f)}
$$
*/
foreach() {
double a = c[]/(f[]*c.alpha + (1. - f[]));
phi1[] = a*f[]*c.alpha;
phi2[] = a*(1. - f[]);
}
}
}
/**
## Diffusion
We first define the relaxation and residual functions needed to solve
the implicit discrete system
$$
\frac{c^{n + 1} - c^n}{\Delta t} =
\nabla\cdot (D \nabla c^{n + 1} + \beta c^{n + 1})
$$
see section 3.2 of [Farsoiya et al., 2021](#farsoiya2021).
Note that these functions are close to that in [poisson.h]() and
[diffusion.h]() but with the additional term $\nabla\cdot (\beta c^{n
+ 1})$. */
struct HDiffusion {
face vector D;
face vector beta;
};
static void h_relax (scalar * al, scalar * bl, int l, void * data)
{
scalar a = al[0], b = bl[0];
struct HDiffusion * p = (struct HDiffusion *) data;
face vector D = p->D, beta = p->beta;
scalar c = a;
foreach_level_or_leaf (l) {
double n = - sq(Delta)*b[], d = cm[]/dt*sq(Delta);
foreach_dimension() {
n += D.x[1]*a[1] + D.x[]*a[-1] +
Delta*(beta.x[1]*a[1] - beta.x[]*a[-1])/2.;
d += D.x[1] + D.x[] - Delta*(beta.x[1] - beta.x[])/2.;
}
c[] = n/d;
}
}
static double h_residual (scalar * al, scalar * bl, scalar * resl, void * data)
{
scalar a = al[0], b = bl[0], res = resl[0];
struct HDiffusion * p = (struct HDiffusion *) data;
face vector D = p->D, beta = p->beta;
double maxres = 0.;
#if TREE
/* conservative coarse/fine discretisation (2nd order) */
face vector g[];
foreach_face()
g.x[] = D.x[]*face_gradient_x (a, 0) + beta.x[]*face_value (a, 0);
foreach (reduction(max:maxres)) {
res[] = b[] + cm[]/dt*a[];
foreach_dimension()
res[] -= (g.x[1] - g.x[])/Delta;
if (fabs (res[]) > maxres)
maxres = fabs (res[]);
}
#else // !TREE
/* "naive" discretisation (only 1st order on trees) */
foreach (reduction(max:maxres)) {
res[] = b[] + cm[]/dt*a[];
foreach_dimension()
res[] -= (D.x[1]*face_gradient_x (a, 1) -
D.x[0]*face_gradient_x (a, 0) +
beta.x[1]*face_value (a, 1) -
beta.x[0]*face_value (a, 0))/Delta;
if (fabs (res[]) > maxres)
maxres = fabs (res[]);
}
#endif // !TREE
return maxres;
}
event tracer_diffusion (i++)
{
free (f.tracers);
f.tracers = phi_tracers;
for (scalar c in stracers) {
/**
The advected concentration is computed from $\phi_1$ and $\phi_2$ as
$$
c = \phi_1 + \phi_2
$$
and these fields are then discarded. */
scalar phi1 = c.phi1, phi2 = c.phi2, r[];
foreach() {
c[] = phi1[] + phi2[];
r[] = - cm[]*c[]/dt;
}
delete ({phi1, phi2});
/**
The diffusion equation for $c$ is then solved using the multigrid
solver and the residual and relaxation functions defined above. */
face vector D[], beta[];
foreach_face() {
double ff = (f[] + f[-1])/2.;
D.x[] = fm.x[]*c.D1*c.D2/(c.D1*(1. - ff) + ff*c.D2);
beta.x[] = - D.x[]*(c.alpha - 1.)/
(ff*c.alpha + (1. - ff))*(f[] - f[-1])/Delta;
}
restriction ({D, beta, cm});
struct HDiffusion q;
q.D = D;
q.beta = beta;
mg_solve ({c}, {r}, h_residual, h_relax, &q);
}
}
/**
## References
~~~bib
@article{haroun2010,
title = {Volume of fluid method for interfacial reactive mass transfer:
application to stable liquid film},
author = {Haroun, Y and Legendre, D and Raynal, L},
journal = {Chemical Engineering Science},
volume = {65},
number = {10},
pages = {2896--2909},
year = {2010},
doi = {10.1016/j.ces.2010.01.012}
}
@hal{farsoiya2021, hal-03227997}
~~~
*/