# Analytic Solution to the Piecewise Linear Interface Construction Problem and Its Application in Curvature Calculation for Volume-of-Fluid Simulation Codes

^{*}

## Abstract

**:**

**2000**, 164, 228–237), which we further improve to include edge cases and micro-optimize to reduce arithmetic operations and branching. We then extend our comparison regarding computing time and accuracy to include two different iterative solutions as well. We find that the best choice depends on the employed hardware platform: on the CPU, Newton–Raphson is fastest with compiler optimization enabled, while analytic solutions perform better than iterative solutions without. On the GPU, the fastest method is our optimized version of the analytic SZ solution. We finally provide details on one of the applications of PLIC—curvature calculation for the Volume-of-Fluid model used for free surface fluid simulations in combination with the lattice Boltzmann method.

## 1. Introduction

## 2. Plane–Cube Intersection

#### 2.1. Applying Symmetry Conditions to Reduce Problem Complexity

#### 2.2. Formulating the Inverse PLIC Problem

#### 2.3. Inverting the Inverse PLIC Formulation Analytically

`NaN`of a square root of a negative number would not be captured in the case condition, leading to an incorrect result. An additional

`fdim`function call in the square root solves this issue. In the implementation, we artificially exclude the edge case ${x}_{4}=0$ in order to, instead of $\mathrm{atan}2(y,x)$, use the faster $\mathrm{atan}(y/x)$, giving the algorithm a $15\%$ speedup. In case branching would be undesirable, bit masking is also an option, but bit masking turned out to be slower even on GPUs.

#### 2.4. The Analytic SZ Solution

- while our solution is based on the ${L}_{2}$-normalized plane normal vector, the SZ solution uses the ${L}_{1}$-normalized normal vector;
- our solution takes two atan operations while the SZ solution takes one acos operation;
- our solution has a smaller number of arithmetic operations and branching than the SZ Kawano implementation, but requires more special functions.

`v1`. In the edge cases of the normal vector $\overrightarrow{n}={(1,0,0)}^{\mathrm{T}}$ and the volume ${V}_{0}\in \{0,1\}$, the algorithm returns

`-NaN`both in our OpenCL and in the original Fortran implementation. By checking cases (5) and (2) first and by avoiding divisions by

`vm1`and

`vm2`before the checks for cases (5) and (2), respectively, we improve the handling of the 1D edge case. We further apply some micro-optimization to significantly reduce the number of arithmetic operations and branching.

- correct edge case behavior;
- more efficient branching by computing easier, more common cases first and less common, more computationally expensive cases last;
- micro-optimization by pre-computing redundant terms and minimizing the number of arithmetic operations and branching.

#### 2.5. Iterative Solutions

#### 2.6. Performance and Accuracy Comparison

#### 2.6.1. CPU Testing

`/Od`,

`/Qpar-`). The execution time results are very different, as shown in Table 2. All variants but the Kawano implementation and nested intervals are within the margin of error regarding computing time. In the edge cases of the normal vector $\overrightarrow{n}={(1,0,0)}^{\mathrm{T}}$ and the volume ${V}_{0}\in \{0,1\}$, the SZ solution by Kawano returns

`-NaN`, which propagates through the entire error averaging procedure. For the IEEE-754 FP32 floating-point format, the machine epsilon is at $\u03f5=5.96\times {10}^{-8}$, meaning that, for all other PLIC variants, the average error ${E}_{\mathrm{avg}}$ is within machine precision.

`/O2`,

`/Oi`,

`/Ot`,

`/Qpar-`and

`/fp:except-`. The results are presented in Table 3. Here, Newton–Raphson considerably outperforms all the other solutions.

`/O2`,

`/Oi`,

`/Ot`,

`/Qpar`,

`/arch:AVX2`and

`/fp:except-`. The results are presented in Table 4. In all variants, execution times do not significantly differ from when AVX is disabled, indicating that auto-vectorization is not being applied at all. As an additional indicator, the CPU clock frequency does not drop by the AVX2 clock offset while the tests are running.

#### 2.6.2. GPU Testing

## 3. Application: Curvature Calculation for VoF-LBM on the GPU

#### 3.1. Volume-of-Fluid Overview

#### 3.2. Obtaining Neighboring Interface Points: PLIC Point Neighborhood

#### 3.3. Validating Curvature Calculation

#### 3.4. Application Example: Simulating a Terminal Velocity Raindrop Impact

## 4. Conclusions

## Author Contributions

## Funding

## Data Availability Statement

## Acknowledgments

## Conflicts of Interest

## Abbreviations

AVX2 | advanced vector extensions 2 (256-bit) |

CPU | central processing unit |

GPU | graphics processing unit |

LBM | lattice Boltzmann method |

PLIC | piecewise linear interface construction |

VoF | Volume-of-Fluid |

## Appendix A. PLIC Inversion with Mathematica

## Appendix B. Code Listings

Listing A1. Fully optimized C implementation of the inverse PLIC solution. To avoid branching between cases (3) and (4), in the implementation, the fdimf(x,y):= max(x-y,0) function is used. Case (2) cannot be included with another fdimf(x,y) because, in case (2), division by n_{1} must be avoided since it could be zero. |

float plic_cube_inverse(const float d0, const float nx, const float ny, const float nz) { // unit cube - plane intersection ↪: plane offset d0, normal vector n -> volume V0 in [0,1] const float n1 = fmin(fmin(fabs(nx), fabs(ny)), fabs(nz)); // eliminate most cases due to symmetry const float n3 = fmax(fmax(fabs(nx), fabs(ny)), fabs(nz)); const float n2 = fabs(nx)-n1+fabs(ny)+fabs(nz)-n3; const float d = 0.5f*(n1+n2+n3)-fabs(d0); // calculate PLIC with reduced symmetry, shift origin from (0.0,0.0,0.0) -> ↪ (0.5,0.5,0.5) float V; // 0.0<=V<=0.5 if(fmin(n1+n2, n3)<=d && d<=n3) { // case (5) V = (d-0.5f*(n1+n2))/n3; // avoid division by n1 and n2 } else if(d<n1) { // case (1) V = cb(d)/(6.0f*n1*n2*n3); // condition d<n1==0 is impossible if d==0.0f } else if(d<=n2) { // case (2) V = (3.0f*d*(d-n1)+sq(n1))/(6.0f*n2*n3); // avoid ;division by n1 } else { // case (3) or (4) V = (cb(d)-cb(d-n1)-cb(d-n2)-cb(fdim(d, n3)))/(6.0f*n1*n2*n3); return copysign(0.5f-V, d0)+0.5f; // apply symmetry for V0>0.5} |

Listing A2. Fully optimized C implementation of our analytic PLIC solution. |

float plic_cube_reduced(const float V, const float n1, const float n2, const float n3) { const float n1pn2=n1+n2, n3xV=n3*V; if (n1pn2<=2.0f*n3xV) return n3xV+0.5f*n1pn2; // case (5) const float V6n2n3=6.0f*n2*n3xV, sqn1=sq(n1); if (V6n2n3>=sq(n1) && 3.0f*n2*(2.0f*n3xV+n1-n2)<=sqn1) return ;0.5f*n1+0.28867513f*sqrt(24.0f*n2*n3xV-sqn1); // case (2) if (V6n2n3<sqn1) return cbrt(V6n2n3*n1); // case (1) const float n1xn2=n1*n2; const float x3 = 81.0f*n1xn2*(n1pn2-2.0f*n3xV); // x3>0 const float y32 = fdim(23328.0f*cb(n1xn2), sq(x3)); // y3>=0 const float u3 = cbrt(sq(x3)+y32); const float d3 = n1pn2-(7.5595264f*n1xn2+0.26456684f*u3)*rsqrt(u3)*sin(0.5235988f-0.33333334f*atan(sqrt(y32)/x3)); // x3↪ >0 if(d3<=n3) return d3; // case (3) const float t4 = 9.0f*sq(n1pn2+n3)-18.0f; const float x4 = fmax(n1xn2*n3*(324.0f-648.0f*V), 1.1754944E-38f); // avoid edge case V==0.5 to make x4>0 const float y42 = 4.0f*cb(t4)-sq(x4); // y4>=0 const float u4 = cbrt(sq(x4)+y42); const float d4 = 0.5f*(n1pn2+n3)-(0.20998684f*t4+0.13228342f*u4)*rsqrt(u4)*sin(0.5235988f-0.33333334f*atan(sqrt(y42)/x4)) ↪ // x4>0 return d4; // case (4)}float plic_cube(const float V0, const float nx, const float ny, const float nz) { // unit cube - plane intersection: volume ↪ V0 in [0,1], normal vector n -> plane offset d0 const float ax=fabs(nx), ay=fabs(ny), az=fabs(nz), V=0.5f-fabs(V0-0.5f); // eliminate symmetry cases const float n1 = fmin(fmin(ax, ay), az); const float n3 = fmax(fmax(ax, ay), az); const float n2 = ax-n1+ay+az-n3; const float d = plic_cube_reduced(V, n1, n2, n3); // calculate PLIC with reduced symmetry return copysign(0.5f*(n1+n2+n3)-d, V0-0.5f); // apply symmetry for V0>0.5} |

Listing A3. The Fortran implementation [5] of the analytic SZ PLIC solution [4] translated to C without further optimization. |

float plic_cube(const float V0, const float nx, const float ny, const float nz) { // unit cube - plane intersection: volume ↪ V0 in [0,1], normal vector n -> plane offset d0 const float l = fabs(nx)+fabs(ny)+fabs(nz); // length in L1 norm const float ax=fabs(nx)/l, ay=fabs(ny)/l, az=fabs(nz)/l, w=0.5f-fabs(V0-0.5f); // eliminate symmetry cases const float vm1 = fmin(fmin(ax, ay), az); const float vm3 = fmax(fmax(ax, ay), az); const float vm2 = fdim(1.0f, vm1+vm3); // ensure vm2>=0 const float vm12 = vm1+vm2; float alpha = 0.0f; const float v1 = sq(vm1)/(6.0f*vm2*vm3+1E-25f); const float w6 = 6.0f*vm1*vm2*vm3*w; if(w<v1) { alpha = cbrt(w6); // case (1) } else if(w<v1+0.5f*(vm2-vm1)/vm3) { alpha = 0.5f*(vm1+sqrt(sq(vm1)+8.0f*vm2*vm3*(w-v1))); // case (2) } else { float v3; if(vm3<vm12) { v3 = (sq(vm3)*(3.0f*vm12-vm3)+sq(vm1)*(vm1-3.0f*vm3)+sq(vm2)*(vm2-3.0f*vm3))/(6.0f*vm1*vm2*vm3); } else { v3 = 0.5f*vm12/vm3; if(v3<=w) alpha = vm3*w+0.5f*vm12; // case (5) } if(alpha==0.0f) { float a0, a1, a2; if(w<v3) { // case (3) a2 = -3.0f*vm12; a1 = 3.0f*(sq(vm1)+sq(vm2)); a0 = w6-cb(vm1)-cb(vm2); } else { // case (4) a2 = -1.5f; a1 = 1.5f*(sq(vm1)+sq(vm2)+sq(vm3)); a0 = 0.5f*(w6-cb(vm1)-cb(vm2)-cb(vm3)); } const float q0 = 0.16666667f*(a1*a2-3.0f*a0)-3.7037037E-2f*cb(a2); // 3.7037037E-2f = 1/27 const float sp = sqrt(0.11111111f*sq(a2)-0.33333334f*a1); alpha = 2.0f*sp*cos(4.1887902f+0.33333334f*acos(q0/cb(sp)))-0.33333334f*a2; // 4.1887902f = 4/3*pi } } return l*copysign(0.5f-alpha, V0-0.5f); // rescale result and apply symmetry for V0 0.5} |

Listing A4. Fully optimized C implementation of the SZ PLIC solution. |

float plic_cube_reduced(const float V, const float n1, const float n2, const float n3) { // optimized solution from SZ and ↪ Kawano const float n12=n1+n2, n3V=n3*V; if(n12<=2.0f*n3V) return n3V+0.5f*n12; // case (5) const float sqn1=sq(n1), n26=6.0f*n2, v1=sqn1/n26; // after case (5) check n2>0 is true if(v1<=n3V && n3V<v1+0.5f*(n2-n1)) return 0.5f*(n1+sqrt(sqn1+8.0f*n2*(n3V-v1))); // case (2) const float V6 = n1*n26*n3V; if(n3V<v1) return cbrt(V6); // case (1) const float v3 = n3<n12 ? (sq(n3)*(3.0f*n12-n3)+sqn1*(n1-3.0f*n3)+sq(n2)*(n2-3.0f*n3))/(n1*n26) : 0.5f*n12; // after case ↪ (2) check n1>0 is true const float sqn12=sqn1+sq(n2), V6cbn12=V6-cb(n1)-cb(n2); const bool case34 = n3V<v3; // true: case (3), false: case (4) const float a = case34 ? V6cbn12 : 0.5f*(V6cbn12-cb(n3)); const float b = case34 ? sqn12 : 0.5f*(sqn12+sq(n3)); const float c = case34 ? n12 : 0.5f; const float t = sqrt(sq(c)-b); return c-2.0f*t*sin(0.33333334f*asin((cb(c)-0.5f*a-1.5f*b*c)/cb(t)));}float plic_cube(const float V0, const float nx, const float ny, const float nz) { // unit cube - plane intersection: volume ↪ V0 in [0,1], normal vector n -> plane offset d0 const float ax=fabs(nx), ay=fabs(ny), az=fabs(nz), V=0.5f-fabs(V0-0.5f), l=ax+ay+az; // eliminate symmetry cases, ↪ normalize n using L1 norm const float n1 = fmin(fmin(ax, ay), az)/l; const float n3 = fmax(fmax(ax, ay), az)/l; const float n2 = fdim(1.0f, n1+n3); // ensure n2>=0 const float d = plic_cube_reduced(V, n1, n2, n3); // calculate PLIC with reduced symmetry return l*copysign(0.5f-d, V0-0.5f); // rescale result and apply symmetry for V0>0.5} |

Listing A5. C implementation of the iterative nested-intervals solution for cases (3) and (4). |

int log2_fast(const float x) { // evil log2 hack: log2(x)=(as_uint(x)>>23)-127 return (as_uint(x)>>23)-127;} float plic_cube_reduced(const float V, const float n1, const float n2, const float n3) { const float n1pn2=n1+n2, n3xV=n3*V; if(n1pn2<=2.0f*n3xV) return n3xV+0.5f*n1pn2; // case (5) const float V6n2n3=6.0f*n2*n3xV, sqn1=sq(n1); if(V6n2n3>=sq(n1) && 3.0f*n2*(2.0f*n3xV+n1-n2)<=sqn1) return 0.5f*n1+0.28867513f*sqrt(24.0f*n2*n3xV-sqn1); // case (2) if(V6n2n3<sqn1) return cbrt(V6n2n3*n1); // case (1) const float V6n1n2n3 = V6n2n3*n1; float dmin, dmax, d; uint k; dmin=n2; dmax=n1+n2; d=0.5f*(dmin+dmax); k = (uint)log2_fast((dmax-dmin)*1.67772162E7f); // deterdmine number of interval halvings to reach machine precision for(uint i=0; i<=k; i++) { if(cb(d)-cb(d-n1)-cb(d-n2)<V6n1n2n3) dmin = d; else dmax = d; d = 0.5f*(dmin+dmax);} if(d<=n3) return d; // case (3) dmin=n3; dmax=0.5f*(n1+n2+n3); d=0.5f*(dmin+dmax); k = (uint)log2_fast((dmax-dmin)*1.67772162E7f); // deterdmine number of interval halvings to reach machine precision for(uint i=0; i<=k; i++) { if(cb(d)-cb(d-n1)-cb(d-n2)-cb(d-n3)<V6n1n2n3) dmin = d; else dmax = d; d = 0.5f*(dmin+dmax);} return d;}float plic_cube(const float V0, const float nx, const float ny, const float nz) { const float n1 = fmin(fmin(fabs(nx), fabs(ny)), fabs(nz)); // eliminate most cases due to symmetry const float n3 = fmax(fmax(fabs(nx), fabs(ny)), fabs(nz)); const float n2 = fabs(nx)-n1+fabs(ny)+fabs(nz)-n3; const float V = 0.5f-fabs(V0-0.5f); const float d = plic_cube_reduced(V, n1, n2, n3); return copysign(0.5f*(n1+n2+n3)-d, V0-0.5f); // apply symmetry for V0>0.5} |

Listing A6. C implementation of the iterative Newton–Raphson solution for cases (1), (3) and (4). Calculating case (1) with Newton–Raphson as well instead of the cbrt() function results in a very small but noticeable improvement in performance when executed on the CPU. |

float plic_cube_reduced(const float V, const float n1, const float n2, const float n3) { const float n1pn2=n1+n2, n3xV=n3*V; if(n1pn2<=2.0f*n3xV) return n3xV+0.5f*n1pn2; // case (5) const float V6n2n3=6.0f*n2*n3xV, sqn1=sq(n1); if(V6n2n3>=sq(n1) && 3.0f*n2*(2.0f*n3xV+n1-n2)<=sqn1) return 0.5f*n1+0.28867513f*sqrt(24.0f*n2*n3xV-sqn1); // case (2) const float V6n1n2n3 = V6n2n3*n1; float dmin, dmax, d; if(V6n2n3<sqn1) { dmin=0.0f; dmax=n1; d=0.5f*(dmin+dmax); for(uint i=0; i<7; i++) { const float f = cb(d)-V6n1n2n3; const float fs = 3.0f*sq(d); d -= f/fs; } return d; // case (1)} dmin=n2; dmax=n1+n2; d=0.5f*(dmin+dmax); for(uint i=0; i<4; i++) { const float f = cb(d)-cb(d-n1)-cb(d-n2)-V6n1n2n3; const float fs = 3.0f*(sq(d)-sq(d-n1)-sq(d-n2)); d -= f/fs;} if(d<=n3) return d; // case (3) dmin=n3; dmax=0.5f*(n1+n2+n3); d=0.5f*(dmin+dmax); for(uint i=0; i<4; i++) { const float f = cb(d)-cb(d-n1)-cb(d-n2)-cb(d-n3)-V6n1n2n3; const float fs = 3.0f*(sq(d)-sq(d-n1)-sq(d-n2)-sq(d-n3)); d -= f/fs;} return d; // case (4)}float plic_cube(const float V0, const float nx, const float ny, const float nz) { const float n1 = fmin(fmin(fabs(nx), fabs(ny)), fabs(nz)); // eliminate most cases due to symmetry const float n3 = fmax(fmax(fabs(nx), fabs(ny)), fabs(nz)); const float n2 = fabs(nx)-n1+fabs(ny)+fabs(nz)-n3; const float V = 0.5f-fabs(V0-0.5f); const float d = plic_cube_reduced(V, n1, n2, n3); return copysign(0.5f*(n1+n2+n3)-d, V0-0.5f); // apply symmetry for V0>0.5} |

## Appendix C. Paraboloid Curvature, Interface Normal and Least-Squares Fit

#### Appendix C.1. Calculating the Interface Normal Vector from a 3^{3} Neighborhood

#### Appendix C.2. Analytic Curvature of a Paraboloid

#### Appendix C.3. Curvature from Least-Squares Paraboloid Fit

## References

- Youngs, D.L. Time-dependent multi-material flow with large fluid distortion. In Numerical Methods in Fluid Dynamics; Academic Press: Cambridge, MA, USA, 1982. [Google Scholar]
- Youngs, D.L. An Interface Tracking Method for a 3D Eulerian Hydrodynamics Code; Technical Report; Atomic Weapons Research Establishment (AWRE): Aldermaston, UK, 1984; Volume 44, p. 35. [Google Scholar]
- Janßen, C.F.; Grilli, S.T.; Krafczyk, M. On enhanced non-linear free surface flow simulations with a hybrid LBM–VOF model. Comput. Math. Appl.
**2013**, 65, 211–229. [Google Scholar] [CrossRef] - Scardovelli, R.; Zaleski, S. Analytical relations connecting linear interfaces and volume fractions in rectangular grids. J. Comput. Phys.
**2000**, 164, 228–237. [Google Scholar] [CrossRef] - Kawano, A. A simple volume-of-fluid reconstruction method for three-dimensional two-phase flows. Comput. Fluids
**2016**, 134, 130–145. [Google Scholar] [CrossRef][Green Version] - Lehmann, M.; Oehlschlägel, L.M.; Häusl, F.P.; Held, A.; Gekle, S. Ejection of marine microplastics by raindrops: A computational and experimental study. Microplastics Nanoplastics
**2021**, 1, 18. [Google Scholar] [CrossRef] - Laermanns, H.; Lehmann, M.; Klee, M.; Löder, M.G.; Gekle, S.; Bogner, C. Tracing the horizontal transport of microplastics on rough surfaces. Microplastics Nanoplastics
**2021**, 1, 11. [Google Scholar] [CrossRef] - Lehmann, M. High Performance Free Surface LBM on GPUs. Master’s Thesis, University of Bayreuth, Bayreuth, Germany, 2019. [Google Scholar]
- Bogner, S.; Rüde, U.; Harting, J. Curvature estimation from a volume-of-fluid indicator function for the simulation of surface tension and wetting with a free-surface lattice Boltzmann method. Phys. Rev. E
**2016**, 93, 043302. [Google Scholar] [CrossRef][Green Version] - Körner, C.; Thies, M.; Hofmann, T.; Thürey, N.; Rüde, U. Lattice Boltzmann model for free surface flow for modeling foaming. J. Stat. Phys.
**2005**, 121, 179–196. [Google Scholar] [CrossRef] - Thürey, N.; Körner, C.; Rüde, U. Interactive Free Surface Fluids with the Lattice Boltzmann Method; Technical Report 05-4; University of Erlangen-Nuremberg: Erlangen, Germany, 2005. [Google Scholar]
- Pohl, T. High Performance Simulation of Free Surface Flows Using the Lattice Boltzmann Method; Verlag Dr. Hut: Erlangen, Germany, 2008. [Google Scholar]
- Schreiber, M.; Neumann, P.; Zimmer, S.; Bungartz, H.J. Free-surface lattice-Boltzmann simulation on many-core architectures. Procedia Comput. Sci.
**2011**, 4, 984–993. [Google Scholar] [CrossRef][Green Version] - Popinet, S. An accurate adaptive solver for surface-tension-driven interfacial flows. J. Comput. Phys.
**2009**, 228, 5838–5866. [Google Scholar] [CrossRef][Green Version] - Jafari, A.; Shirani, E.; Ashgriz, N. An improved three-dimensional model for interface pressure calculations in free-surface flows. Int. J. Comput. Fluid Dyn.
**2007**, 21, 87–97. [Google Scholar] [CrossRef] - Xing, X.Q.; Butler, D.L.; Yang, C. Lattice Boltzmann-based single-phase method for free surface tracking of droplet motions. Int. J. Numer. Methods Fluids
**2007**, 53, 333–351. [Google Scholar] [CrossRef] - Donath, S. Wetting Models for a Parallel High-Performance Free Surface Lattice Boltzmann Method: Benetzungsmodelle Für Eine Parallele Lattice-Boltzmann-Methode Mit Freien Oberflächen; Verlag Dr. Hut: Erlangen, Germany, 2011. [Google Scholar]
- Donath, S.; Mecke, K.; Rabha, S.; Buwa, V.; Rüde, U. Verification of surface tension in the parallel free surface lattice Boltzmann method in waLBerla. Comput. Fluids
**2011**, 45, 177–186. [Google Scholar] [CrossRef] - Anderl, D.; Bogner, S.; Rauh, C.; Rüde, U.; Delgado, A. Free surface lattice Boltzmann with enhanced bubble model. Comput. Math. Appl.
**2014**, 67, 331–339. [Google Scholar] [CrossRef] - Obrecht, C.; Kuznik, F.; Tourancheau, B.; Roux, J.J. A new approach to the lattice Boltzmann method for graphics processing units. Comput. Math. Appl.
**2011**, 61, 3628–3638. [Google Scholar] [CrossRef][Green Version] - Wittmann, M. Hardware-effiziente, hochparallele Implementierungen von Lattice-Boltzmann-Verfahren für komplexe Geometrien. Ph.D. Thesis, Friedrich-Alexander-Universität Erlangen-Nürnberg (FAU), Nürnberg, Germany, 2016. [Google Scholar]
- Delbosc, N.; Summers, J.L.; Khan, A.; Kapur, N.; Noakes, C.J. Optimized implementation of the Lattice Boltzmann Method on a graphics processing unit towards real-time fluid simulation. Comput. Math. Appl.
**2014**, 67, 462–475. [Google Scholar] [CrossRef] - Herschlag, G.; Lee, S.; Vetter, J.S.; Randles, A. GPU data access on complex geometries for d3q19 lattice Boltzmann method. In Proceedings of the 2018 IEEE International Parallel and Distributed Processing Symposium (IPDPS), Vancouver, BC, Canada, 21–25 May 2018; pp. 825–834. [Google Scholar]
- Mawson, M.J.; Revell, A.J. Memory transfer optimization for a lattice Boltzmann solver on Kepler architecture nVidia GPUs. Comput. Phys. Commun.
**2014**, 185, 2566–2574. [Google Scholar] [CrossRef][Green Version] - Wittmann, M.; Zeiser, T.; Hager, G.; Wellein, G. Comparison of different propagation steps for lattice Boltzmann methods. Comput. Math. Appl.
**2013**, 65, 924–935. [Google Scholar] [CrossRef] - Kuznik, F.; Obrecht, C.; Rusaouen, G.; Roux, J.J. LBM based flow simulation using GPU computing processor. Comput. Math. Appl.
**2010**, 59, 2380–2392. [Google Scholar] [CrossRef][Green Version] - Krüger, T.; Kusumaatmaja, H.; Kuzmin, A.; Shardt, O.; Silva, G.; Viggen, E.M. The Lattice Boltzmann Method; Springer International Publishing: Berlin/Heidelberg, Germany, 2017; Volume 10, pp. 4–15. [Google Scholar]
- Chapman, S.; Cowling, T.G.; Burnett, D. The Mathematical Theory of Non-Uniform Gases: An Account of the Kinetic Theory of Viscosity, Thermal Conduction and Diffusion in Gases; Cambridge University Press: Cambridge, MA, USA, 1990. [Google Scholar]
- Purqon, A. Accuracy and Numerical Stabilty Analysis of Lattice Boltzmann Method with Multiple Relaxation Time for Incompressible Flows. J. Phys. Conf. Ser.
**2017**, 877, 012035. [Google Scholar] - Wu, X.; Wu, E. Bubble creation and multi-fluids interaction. In Proceedings of the 2009 11th IEEE International Conference on Computer-Aided Design and Computer Graphics, Huangshan, China, 19–21 August 2009; pp. 87–91. [Google Scholar]
- Yuan, M.; Yang, Y.; Li, T.; Hu, Z. Numerical simulation of film boiling on a sphere with a volume of fluid interface tracking method. Int. J. Heat Mass Transf.
**2008**, 51, 1646–1657. [Google Scholar] [CrossRef] - Ma, C.; Bothe, D. A VOF-based method for the simulation of thermocapillary flow. In APS Division of Fluid Dynamics Meeting Abstracts; Technical University Darmstadt: Darmstadt, Germany, 2010; Volume 63, p. HW-008. [Google Scholar]
- Booshi, S.; Ketabdari, M.J. Modeling of solitary wave interaction with emerged porous breakwater using PLIC-VOF method. Ocean Eng.
**2021**, 241, 110041. [Google Scholar] [CrossRef] - Sato, K.; Koshimura, S. A lattice Boltzmann approach for three-dimensional tsunami simulation based on the PLIC-VOF method. Coast. Eng. Proc.
**2018**, 36, 90. [Google Scholar] [CrossRef][Green Version] - Sheng, M.; Chen, W.; Liu, J.; Shi, S. Ejecting performance simulation of an innovative piezoelectric actuated lubrication generator for space mechanisms. Int. J. Mech. Sci.
**2011**, 53, 867–871. [Google Scholar] [CrossRef] - Meredith, J.S.; Childs, H. Visualization and Analysis-Oriented Reconstruction of Material Interfaces. In Computer Graphics Forum; Wiley Online Library: Hoboken, NJ, USA, 2010; Volume 29, pp. 1241–1250. [Google Scholar]
- NVIDIA. Parallel Thread Execution ISA Version 6.4. 2019. Available online: https://docs.nvidia.com/cuda/parallel-thread-execution/ (accessed on 21 July 2021).
- Ataei, M.; Bussmann, M.; Shaayegan, V.; Costa, F.; Han, S.; Park, C.B. NPLIC: A machine learning approach to piecewise linear interface construction. Comput. Fluids
**2021**, 223, 104950. [Google Scholar] [CrossRef] - Porcù, F.; D’adderio, L.P.; Prodi, F.; Caracciolo, C. Effects of altitude on maximum raindrop size and fall velocity as limited by collisional breakup. J. Atmos. Sci.
**2013**, 70, 1129–1134. [Google Scholar] [CrossRef] - Bourke, P. Polygonising a Scalar Field. 1994. Available online: http://paulbourke.net/geometry/polygonise/ (accessed on 21 July 2021).
- Lorensen, W.E.; Cline, H.E. Marching cubes: A high resolution 3D surface construction algorithm. ACM Siggraph Comput. Graph.
**1987**, 21, 163–169. [Google Scholar] [CrossRef] - Vega, D.; Abache, J.; Coll, D. A Fast and Memory-Saving Marching Cubes 33 Implementation with the Correct Interior Test. J. Comput. Graph. Tech. Vol.
**2019**, 3. Available online: https://jcgt.org/published/0008/03/01/paper.pdf (accessed on 21 July 2021). - Parker, B.; Youngs, D. Two and Three Dimensional Eulerian Simulation of Fluid Flow with Material Interfaces; Atomic Weapons Establishment: Aldermaston, UK, 1992. [Google Scholar]
- Pressley, A.N. Elementary Differential Geometry; Springer Science & Business Media: Berlin/Heidelberg, Germany, 2010. [Google Scholar]
- Abbena, E.; Salamon, S.; Gray, A. Modern Differential Geometry of Curves and Surfaces with Mathematica; Chapman and Hall/CRC: Boca Raton, FL, USA, 2017. [Google Scholar]
- Yu, J.; Yin, X.; Gu, X.; McMillan, L.; Gortler, S. Focal surfaces of discrete geometry. In ACM International Conference Proceeding Series; Eurographics Association/Association for Computing Machinery: Norrköping, Sweden, 2007; Volume 257, pp. 23–32. [Google Scholar]
- Har’el, Z. Curvature of Curves and Surfaces—A Parabolic Approach; Department of Mathematics, Technion–Israel Institute of Technology: Haifa, Israel, 1995. [Google Scholar]
- Jia, Y.B. Gaussian and Mean Curvatures; Com S 477/577 Notes; Iowa State University: Ames, IA, USA, 2018. [Google Scholar]
- Eberly, D. Least Squares Fitting of Data; Magic Software: Chapel Hill, NC, USA, 2000. [Google Scholar]

**Figure 1.**All possible intersection cases of a plane and a unit cube. The truncated volume in reduced symmetry space V (cyan) of cases (1) to (4) is a tetrahedral pyramid with zero (1), one (2), two (3) or all three (4) corners extending outside of the unit cube, being cut-off tetrahedral pyramids themselves. The distance in reduced symmetry space d would be the shortest line from the covered bottom left corner to the intersection plane (not shown).

**Figure 2.**The idea of the Volume-of-Fluid model illustrated in 2D: A sharp interface (black curved line) divides the gas phase (white cells) from the fluid phase (dark blue cells). Lattice points are located at the center of each cell. All cells through which the interface extends are called interface cells (light blue). Every lattice cell has a fill level $\phi \in [0,\phantom{\rule{0.166667em}{0ex}}1]$ assigned to it, which is $\phi =0$ for gas, $\phi =1$ for fluid and $\phi \in ]0,\phantom{\rule{0.166667em}{0ex}}1[$ for interface—based on where exactly the sharp interface cuts through.

**Figure 3.**The curvature calculation procedure with PLIC illustrated in 2D. (

**a**) The fill levels of the interface lattice points indicate the position of the true interface (not known; here illustrated as a black curve), but only a ${3}^{3}$-neighborhood of these fill levels is available in memory. For obtaining the local curvature, the steps are to (

**b**) identify all interface neighbors (Equation (34)), (

**c**) correct the relative interface neighbor positions with the PLIC offset (Section 2), (

**d**) rotate/translate these now PLIC-corrected points into a coordinate system (Equation (41)) with the PLIC-corrected center point being the origin and the z-axis being colinear with the local surface normal (Appendix C.1) and finally (

**e**) perform a paraboloid fit with these points (Appendix C.3).

**Figure 4.**${L}_{1}$ error for our proposed curvature calculation method (red) depending on sphere radius. We also show what happens when we use the PLIC reconstruction for the interface neighborhood not with the center normal vector, but with the normal vectors of the interface neighbors, as discussed in Section 3.2 (orange). For comparison, we provide the curvature approximation method proposed by Donath [17] in both its variants (green and blue).

**Figure 5.**Local ${L}_{1}$ error $\frac{|{\kappa}_{\mathrm{sim}}-{\kappa}_{\mathrm{theo}}|}{{\kappa}_{\mathrm{theo}}}$ for our proposed curvature calculation method illustrated for spheres of radius $R\in \{16,\phantom{\rule{0.166667em}{0ex}}32,\phantom{\rule{0.166667em}{0ex}}64,\phantom{\rule{0.166667em}{0ex}}128\}$.

**Figure 6.**Average curvature for a flat plane of different inclination (rotated around the x-axis). For ${0}^{\circ}$ inclination, the curvature is exactly 0. However, due to the fitting procedure, for an inclination other than ${0}^{\circ}$, it is not, and deviations are especially large in the region ${2}^{\circ}$ to ${15}^{\circ}$.

**Figure 7.**A $5\phantom{\rule{0.166667em}{0ex}}\mathrm{mm}$ diameter raindrop impacting a lake at $9.2\phantom{\rule{0.166667em}{0ex}}\frac{\mathrm{m}}{\mathrm{s}}$ mean sea level pressure terminal velocity [39] and $10{\phantom{\rule{3.33333pt}{0ex}}}^{\circ}\mathrm{C}$ water temperature, simulated with the VoF-LBM GPU simulation code FluidX3D at a lattice resolution of $400\times 400\times 340$ with the D3Q19 discretization and the SRT collision operator. Frames are shown at times $t\in \{0,\phantom{\rule{0.166667em}{0ex}}1,\phantom{\rule{0.166667em}{0ex}}2,\phantom{\rule{0.166667em}{0ex}}3,\phantom{\rule{0.166667em}{0ex}}4,\phantom{\rule{0.166667em}{0ex}}5\}\phantom{\rule{0.166667em}{0ex}}\mathrm{ms}$. Computing time for this simulation is less than one minute on a single Nvidia Titan Xp GPU. Visualization is done with a custom GPU implementation of the marching cubes algorithm [40,41,42].

**Table 1.**Number of operations counted from C code. Arithmetic operations contain all floating-point and integer operations except for those listed separately. For nested intervals, $k\approx 20$ denotes the number of iterations until sufficient convergence.

PLIC Variant | Arithmetic Ops | Branching | $\frac{1}{\sqrt{\mathit{x}}}$ | $\sqrt{\mathit{x}}$ | $\sqrt[3]{\mathit{x}}$ | sin/cos | asin/acos | atan |
---|---|---|---|---|---|---|---|---|

Listing A2 our solution | 95 | 4 | 2 | 3 | 3 | 2 | 2 | |

Listing A3 SZ Kawano | 123 | 6 | 2 | 1 | 1 | 1 | ||

Listing A4 SZ optimized | 97 | 3 | 2 | 1 | 1 | 1 | ||

Listing A5 nested intervals | $750\phantom{\rule{0.166667em}{0ex}}(70+34\phantom{\rule{0.166667em}{0ex}}k)$ | $44\phantom{\rule{0.166667em}{0ex}}(4+2\phantom{\rule{0.166667em}{0ex}}k)$ | 1 | 1 | ||||

Listing A6 Newton-Raphson | 308 | 4 | 1 |

**Table 2.**Comparison of execution time and accuracy of the different PLIC variants with compiler optimizations disabled.

PLIC Variant | Execution Time/ns | ${\mathit{E}}_{\mathbf{avg}}$ |
---|---|---|

Listing A2 our analytic solution | $40.1\pm 7.9$ | $2.04\times {10}^{-8}$ |

Listing A3 SZ solution by Kawano | $51.3\pm 8.3$ | $-\mathrm{NaN}$ |

Listing A4 SZ solution optimized | $35.6\pm 11.4$ | $4.70\times {10}^{-8}$ |

Listing A5 nested intervals | $416.7\pm 19.5$ | $2.62\times {10}^{-8}$ |

Listing A6 Newton-Raphson | $49.3\pm 7.6$ | $1.70\times {10}^{-8}$ |

**Table 3.**Comparison of execution time and accuracy of the different PLIC variants with compiler optimizations enabled but AVX2 auto-vectorization disabled.

PLIC Variant | Execution Time/ns | ${\mathit{E}}_{\mathbf{avg}}$ |
---|---|---|

Listing A2 our analytic solution | $33.0\pm 5.1$ | $2.04\times {10}^{-8}$ |

Listing A3 SZ solution by Kawano | $36.6\pm 5.1$ | $-\mathrm{NaN}$ |

Listing A4 SZ solution optimized | $35.3\pm 7.0$ | $4.70\times {10}^{-8}$ |

Listing A5 nested intervals | $266.0\pm 11.2$ | $2.62\times {10}^{-8}$ |

Listing A6 Newton-Raphson | $10.6\pm 5.8$ | $1.70\times {10}^{-8}$ |

**Table 4.**Comparison of execution time and accuracy of the different PLIC variants with compiler optimizations enabled and with AVX2 auto-vectorization allowed.

PLIC Variant | Execution Time/ns | ${\mathit{E}}_{\mathbf{avg}}$ |
---|---|---|

Listing A2 our analytic solution | $37.0\pm 8.2$ | $2.04\times {10}^{-8}$ |

Listing A3 SZ solution by Kawano | $37.2\pm 3.6$ | $-\mathrm{NaN}$ |

Listing A4 SZ solution optimized | $35.6\pm 5.3$ | $4.70\times {10}^{-8}$ |

Listing A5 nested intervals | $252.2\pm 8.7$ | $2.62\times {10}^{-8}$ |

Listing A6 Newton-Raphson | $9.6\pm 3.1$ | $1.70\times {10}^{-8}$ |

**Table 5.**Comparison of execution time and accuracy of the different PLIC variants in OpenCL on a GPU.

PLIC Variant | Execution Time/ps | ${\mathit{N}}_{\mathit{a}}$ | ${\mathit{N}}_{\mathit{b}}$ | TFLOPs/s | ${\mathit{E}}_{\mathbf{avg}}$ |
---|---|---|---|---|---|

Listing A2 our analytic solution | $19.0\pm 1.7$ | 189 | 13 | $9.9$ | $5.73\times {10}^{-8}$ |

Listing A3 SZ solution by Kawano | $16.0\pm 1.5$ | 149 | 14 | $9.3$ | $-\mathrm{NaN}$ |

Listing A4 SZ solution optimized | $12.8\pm 1.0$ | 132 | 12 | $10.3$ | $6.58\times {10}^{-8}$ |

Listing A5 nested intervals | $106.4\pm 6.2$ | 106 | 13 | $10.0$ | $2.86\times {10}^{-8}$ |

Listing A6 Newton-Raphson | $19.2\pm 1.8$ | 256 | 11 | $13.3$ | $5.47\times {10}^{-8}$ |

Publisher’s Note: MDPI stays neutral with regard to jurisdictional claims in published maps and institutional affiliations. |

© 2022 by the authors. Licensee MDPI, Basel, Switzerland. This article is an open access article distributed under the terms and conditions of the Creative Commons Attribution (CC BY) license (https://creativecommons.org/licenses/by/4.0/).

## Share and Cite

**MDPI and ACS Style**

Lehmann, M.; Gekle, S.
Analytic Solution to the Piecewise Linear Interface Construction Problem and Its Application in Curvature Calculation for Volume-of-Fluid Simulation Codes. *Computation* **2022**, *10*, 21.
https://doi.org/10.3390/computation10020021

**AMA Style**

Lehmann M, Gekle S.
Analytic Solution to the Piecewise Linear Interface Construction Problem and Its Application in Curvature Calculation for Volume-of-Fluid Simulation Codes. *Computation*. 2022; 10(2):21.
https://doi.org/10.3390/computation10020021

**Chicago/Turabian Style**

Lehmann, Moritz, and Stephan Gekle.
2022. "Analytic Solution to the Piecewise Linear Interface Construction Problem and Its Application in Curvature Calculation for Volume-of-Fluid Simulation Codes" *Computation* 10, no. 2: 21.
https://doi.org/10.3390/computation10020021