-
Notifications
You must be signed in to change notification settings - Fork 0
/
two-phaseVE.h
139 lines (113 loc) · 3.71 KB
/
two-phaseVE.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
/**
* Modification by Vatsal Sanjay
* Version 2.0, Oct 17, 2024
# Changelog
- Oct 17, 2024: added support for VE simulations.
# Brief history
- v1.0 is the vanilla Basilisk code for two-phase flows: http://basilisk.fr/src/two-phase.h + http://basilisk.fr/src/two-phase-generic.h
- v2.0 is the modification for viscoelastic fluids using the log-conformation method.
# Two-phase interfacial flows
This is a modified version of [two-phase.h](http://basilisk.fr/src/two-phase.h). It contains the implementation of
Viscoplastic Fluid (Bingham Fluid).<br/>
This file helps setup simulations for flows of two fluids separated by
an interface (i.e. immiscible fluids). It is typically used in
combination with a [Navier--Stokes solver](navier-stokes/centered.h).
The interface between the fluids is tracked with a Volume-Of-Fluid
method. The volume fraction in fluid 1 is $f=1$ and $f=0$ in fluid
2. The densities and dynamic viscosities for fluid 1 and 2 are *rho1*,
*mu1*, *rho2*, *mu2*, respectively. */
#include "vof.h"
scalar f[], * interfaces = {f};
(const) scalar Gp = unity; // elastic modulus
(const) scalar lambda = unity; // relaxation time
double rho1 = 1., mu1 = 0., rho2 = 1., mu2 = 0.;
double G1 = 0., G2 = 0.; // elastic moduli
double lambda1 = 0., lambda2 = 0.; // relaxation times
double TOLelastic = 1e-2; // tolerance for elastic modulus #TOFIX: this must always be a very small number.
/**
Auxilliary fields are necessary to define the (variable) specific
volume $\alpha=1/\rho$ as well as the cell-centered density. */
face vector alphav[];
scalar rhov[];
scalar Gpd[];
scalar lambdapd[];
event defaults (i = 0) {
alpha = alphav;
rho = rhov;
Gp = Gpd;
lambda = lambdapd;
/**
If the viscosity is non-zero, we need to allocate the face-centered
viscosity field. */
mu = new face vector;
}
/**
The density and viscosity are defined using arithmetic averages by
default. The user can overload these definitions to use other types of
averages (i.e. harmonic). */
#ifndef rho
# define rho(f) (clamp(f,0.,1.)*(rho1 - rho2) + rho2)
#endif
#ifndef mu
// for Arithmetic mean, use this
# define mu(f) (clamp(f,0.,1.)*(mu1 - mu2) + mu2)
#endif
/**
We have the option of using some "smearing" of the density/viscosity
jump. */
#ifdef FILTERED
scalar sf[];
#else
# define sf f
#endif
event tracer_advection (i++) {
/**
When using smearing of the density jump, we initialise *sf* with the
vertex-average of *f*. */
#ifndef sf
#if dimension <= 2
foreach()
sf[] = (4.*f[] +
2.*(f[0,1] + f[0,-1] + f[1,0] + f[-1,0]) +
f[-1,-1] + f[1,-1] + f[1,1] + f[-1,1])/16.;
#else // dimension == 3
foreach()
sf[] = (8.*f[] +
4.*(f[-1] + f[1] + f[0,1] + f[0,-1] + f[0,0,1] + f[0,0,-1]) +
2.*(f[-1,1] + f[-1,0,1] + f[-1,0,-1] + f[-1,-1] +
f[0,1,1] + f[0,1,-1] + f[0,-1,1] + f[0,-1,-1] +
f[1,1] + f[1,0,1] + f[1,-1] + f[1,0,-1]) +
f[1,-1,1] + f[-1,1,1] + f[-1,1,-1] + f[1,1,1] +
f[1,1,-1] + f[-1,-1,-1] + f[1,-1,-1] + f[-1,-1,1])/64.;
#endif
#endif
#if TREE
sf.prolongation = refine_bilinear;
sf.dirty = true; // boundary conditions need to be updated
#endif
}
event properties (i++) {
foreach_face() {
double ff = (sf[] + sf[-1])/2.;
alphav.x[] = fm.x[]/rho(ff);
face vector muv = mu;
muv.x[] = fm.x[]*mu(ff);
}
foreach(){
rhov[] = cm[]*rho(sf[]);
Gpd[] = 0.;
lambdapd[] = 0.;
if (clamp(sf[], 0., 1.) > TOLelastic){
Gpd[] += G1*clamp(sf[], 0., 1.);
lambdapd[] += lambda1*clamp(sf[], 0., 1.);
}
if (clamp((1-sf[]), 0., 1.) > TOLelastic){
Gpd[] += G2*clamp((1-sf[]), 0., 1.);
lambdapd[] += lambda2*clamp((1-sf[]), 0., 1.);
}
}
#if TREE
sf.prolongation = fraction_refine;
sf.dirty = true; // boundary conditions need to be updated
#endif
}