Numerical flux¶
In the previous step, I have obtained the surface function
and its diffused representation
for each cell center \(\left( \pic, \pjc \right)\).
In this section, I compute the numerical flux
to integrate the avection equation and to update \(\phi\).
Explicitly, on a two-dimensional Cartesian domain, this integral is consisted of four terms:
divided by the cell size
Now I focus the first term, and the other terms can be evaluated in the same manner.
First of all, since \(\ux\) is constant on the local cell face, I can take it out of the integral:
To stabilise the cell-face integral, I need to use the upward scheme: namely information of the upwind cell should be used, i.e.
Recall that \(\hat{H}\) is defined on the local coordinate system attached to each cell center. Thus, for the left cell \(\left( \pimm, \pjc \right)\), the integrand should be evaluated at \(x = \frac{1}{2}\), while \(x = -\frac{1}{2}\) for the right cell \(\left( \pic, \pjc \right)\).
Same applied to the all fluxes.
29const double vel = UX(i, j);
30const int ii = vel < 0. ? i : i - 1;
31const double x = vel < 0. ? -0.5 : +0.5;
52const double vel = UX(i, j, k);
53const int ii = vel < 0. ? i : i - 1;
54const double x = vel < 0. ? -0.5 : +0.5;
29const double vel = UY(i, j);
30const int jj = vel < 0. ? j : j - 1;
31const double y = vel < 0. ? -0.5 : +0.5;
52const double vel = UY(i, j, k);
53const int jj = vel < 0. ? j : j - 1;
54const double y = vel < 0. ? -0.5 : +0.5;
28const double vel = UZ(i, j, k);
29const int kk = vel < 0. ? k : k - 1;
30const double z = vel < 0. ? -0.5 : +0.5;
Also notice that
and thus
whose integral is again approximated by the \(N\)-th-order Gaussian quadrature:
which is implemented here:
33const double lvof = VOF(ii, j);
34if(lvof < vofmin || 1. - vofmin < lvof){
35 FLXX(i, j) = vel * lvof;
36 continue;
37}
38double flux = 0.;
39for(int jj = 0; jj < NGAUSS; jj++){
40 const double w = gauss_ws[jj];
41 const double y = gauss_ps[jj];
42 flux += w * indicator(NORMAL(ii, j), (const double [NDIMS]){x, y});
43}
44FLXX(i, j) = vel * flux;
56const double lvof = VOF(ii, j, k);
57if(lvof < vofmin || 1. - vofmin < lvof){
58 FLXX(i, j, k) = vel * lvof;
59 continue;
60}
61double flux = 0.;
62for(int kk = 0; kk < NGAUSS; kk++){
63 for(int jj = 0; jj < NGAUSS; jj++){
64 const double w = gauss_ws[jj] * gauss_ws[kk];
65 const double y = gauss_ps[jj];
66 const double z = gauss_ps[kk];
67 flux += w * indicator(NORMAL(ii, j, k), (const double [NDIMS]){x, y, z});
68 }
69}
70FLXX(i, j, k) = vel * flux;
33const double lvof = VOF(i, jj);
34if(lvof < vofmin || 1. - vofmin < lvof){
35 FLXY(i, j) = vel * lvof;
36 continue;
37}
38double flux = 0.;
39for(int ii = 0; ii < NGAUSS; ii++){
40 const double w = gauss_ws[ii];
41 const double x = gauss_ps[ii];
42 flux += w * indicator(NORMAL(i, jj), (const double [NDIMS]){x, y});
43}
44FLXY(i, j) = vel * flux;
56const double lvof = VOF(i, jj, k);
57if(lvof < vofmin || 1. - vofmin < lvof){
58 FLXY(i, j, k) = vel * lvof;
59 continue;
60}
61double flux = 0.;
62for(int kk = 0; kk < NGAUSS; kk++){
63 for(int ii = 0; ii < NGAUSS; ii++){
64 const double w = gauss_ws[ii] * gauss_ws[kk];
65 const double x = gauss_ps[ii];
66 const double z = gauss_ps[kk];
67 flux += w * indicator(NORMAL(i, jj, k), (const double [NDIMS]){x, y, z});
68 }
69}
70FLXY(i, j, k) = vel * flux;
32const double lvof = VOF(i, j, kk);
33if(lvof < vofmin || 1. - vofmin < lvof){
34 FLXZ(i, j, k) = vel * lvof;
35 continue;
36}
37double flux = 0.;
38for(int jj = 0; jj < NGAUSS; jj++){
39 for(int ii = 0; ii < NGAUSS; ii++){
40 const double w = gauss_ws[ii] * gauss_ws[jj];
41 const double x = gauss_ps[ii];
42 const double y = gauss_ps[jj];
43 flux += w * indicator(NORMAL(i, j, kk), (const double [NDIMS]){x, y, z});
44 }
45}
46FLXZ(i, j, k) = vel * flux;
Note
For very small (\(\approx 0\)) or very large (\(\approx 1\)) volume fractions, i.e. single-phase regions,
gives a good approximation and thus is directly used.
All the fluxes evaluated at the cell faces are stored in FLXX
and FLXY
, which are used to update \(\phi\):
74#if NDIMS == 2
75 for(int j = 1; j <= jsize; j++){
76 for(int i = 1; i <= isize; i++){
77 const double dx = DXF(i );
78 SRC(i, j) += 1. / dx * (
79 + FLXX(i , j )
80 - FLXX(i+1, j )
81 );
82 }
83 }
84#else
85 for(int k = 1; k <= ksize; k++){
86 for(int j = 1; j <= jsize; j++){
87 for(int i = 1; i <= isize; i++){
88 const double dx = DXF(i );
89 SRC(i, j, k) += 1. / dx * (
90 + FLXX(i , j , k )
91 - FLXX(i+1, j , k )
92 );
93 }
94 }
95 }
96#endif
98#if NDIMS == 2
99 for(int j = 1; j <= jsize; j++){
100 for(int i = 1; i <= isize; i++){
101 SRC(i, j) += 1. / dy * (
102 + FLXY(i , j )
103 - FLXY(i , j+1)
104 );
105 }
106 }
107#else
108 for(int k = 1; k <= ksize; k++){
109 for(int j = 1; j <= jsize; j++){
110 for(int i = 1; i <= isize; i++){
111 SRC(i, j, k) += 1. / dy * (
112 + FLXY(i , j , k )
113 - FLXY(i , j+1, k )
114 );
115 }
116 }
117 }
118#endif
121for(int k = 1; k <= ksize; k++){
122 for(int j = 1; j <= jsize; j++){
123 for(int i = 1; i <= isize; i++){
124 SRC(i, j, k) += 1. / dz * (
125 + FLXZ(i , j , k )
126 - FLXZ(i , j , k+1)
127 );
128 }
129 }
130}
A conventional three-step Runge-Kutta scheme is adopted to integrate the equation in time.
149 const double coef = rkcoefs[rkstep][rk_a];
150 const double * restrict src = interface->src[rk_a].data;
151#if NDIMS == 2
152 for(int j = 1; j <= jsize; j++){
153 for(int i = 1; i <= isize; i++){
154 VOF(i, j) += dt * coef * SRC(i, j);
155 }
156 }
157#else
158 for(int k = 1; k <= ksize; k++){
159 for(int j = 1; j <= jsize; j++){
160 for(int i = 1; i <= isize; i++){
161 VOF(i, j, k) += dt * coef * SRC(i, j, k);
162 }
163 }
164 }
165#endif
168 if(0 != rkstep){
169 const double coef = rkcoefs[rkstep][rk_b];
170 const double * restrict src = interface->src[rk_b].data;
171#if NDIMS == 2
172 for(int j = 1; j <= jsize; j++){
173 for(int i = 1; i <= isize; i++){
174 VOF(i, j) += dt * coef * SRC(i, j);
175 }
176 }
177#else
178 for(int k = 1; k <= ksize; k++){
179 for(int j = 1; j <= jsize; j++){
180 for(int i = 1; i <= isize; i++){
181 VOF(i, j, k) += dt * coef * SRC(i, j, k);
182 }
183 }
184 }
185#endif
186 }