Shiokaze Framework
A research-oriented fluid solver for computer graphics
WENO.h
Go to the documentation of this file.
1 /*
2 ** WENO.h
3 **
4 ** This is part of Shiokaze, a research-oriented fluid solver for computer graphics.
5 ** Created by Ryoichi Ando <rand@nii.ac.jp> on Feb 7, 2017.
6 **
7 ** Permission is hereby granted, free of charge, to any person obtaining a copy of
8 ** this software and associated documentation files (the "Software"), to deal in
9 ** the Software without restriction, including without limitation the rights to use,
10 ** copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
11 ** Software, and to permit persons to whom the Software is furnished to do so,
12 ** subject to the following conditions:
13 **
14 ** The above copyright notice and this permission notice shall be included in all copies
15 ** or substantial portions of the Software.
16 **
17 ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
18 ** INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
19 ** PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 ** HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
21 ** CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
22 ** OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24 //
25 #ifndef SHKZ_WENO_H
26 #define SHKZ_WENO_H
27 //
28 #include <limits>
29 //
30 // "Level Set Equations on Surfaces via the Closest Point Method"
31 // Colin B. Macdonald · Steven J. Ruuth
32 // https://link.springer.com/article/10.1007/s10915-008-9196-6
33 // Journal of Scientific Computing, June 2008, Volume 35, Issue 2–3, pp 219–240
34 //
36 //
38 class WENO {
41 public:
52  static double interp6( double x, const double v[6], const double eps=std::numeric_limits<double>::epsilon() ) {
53  //
54  const double &f_m2 = v[0]; const double &f_m1 = v[1]; const double &f_p0 = v[2];
55  const double &f_p1 = v[3]; const double &f_p2 = v[4]; const double &f_p3 = v[5];
56  //
57  const double x_m2 = -2.0; const double x_m1 = -1.0; const double x_p0 = 0.0;
58  const double x_p1 = 1.0; const double x_p2 = 2.0; const double x_p3 = 3.0;
59  //
60  double C[3];
61  C[0] = (x_p2-x) * (x_p3-x) / 20.0;
62  C[1] = (x_p3-x) * (x-x_m2) / 10.0;
63  C[2] = (x-x_m2) * (x-x_m1) / 20.0;
64  //
65  double S[3];
66  S[0] = ((0814.*sqr(f_p1))+(4326.*sqr(f_p0))+(2976.*sqr(f_m1))+(0244.*sqr(f_m2))-(3579.*f_p0*f_p1)-(6927.*f_p0*f_m1)+(1854.*f_p0*f_m2)+(2634.*f_p1*f_m1)-(0683.*f_p1*f_m2)-(1659.*f_m1*f_m2)) / 180.0;
67  S[1] = ((1986.*sqr(f_p1))+(1986.*sqr(f_p0))+(0244.*sqr(f_m1))+(0244.*sqr(f_p2))+(1074.*f_p0*f_p2)-(3777.*f_p0*f_p1)-(1269.*f_p0*f_m1)+(1074.*f_p1*f_m1)-(1269.*f_p2*f_p1)-(0293.*f_p2*f_m1)) / 180.0;
68  S[2] = ((0814.*sqr(f_p0))+(4326.*sqr(f_p1))+(2976.*sqr(f_p2))+(0244.*sqr(f_p3))-(0683.*f_p0*f_p3)+(2634.*f_p0*f_p2)-(3579.*f_p0*f_p1)-(6927.*f_p1*f_p2)+(1854.*f_p1*f_p3)-(1659.*f_p2*f_p3)) / 180.0;
69  //
70  double P[3];
71  P[0] = f_m2 + (f_m1-f_m2) * (x-x_m2) + (f_p0-2.*f_m1+f_m2) * (x-x_m2) * (x-x_m1) / 2.0 + (f_p1-3.*f_p0+3.*f_m1-f_m2) * (x-x_m2) * (x-x_m1) * (x-x_p0) / 6.0;
72  P[1] = f_m1 + (f_p0-f_m1) * (x-x_m1) + (f_p1-2.*f_p0+f_m1) * (x-x_m1) * (x-x_p0) / 2.0 + (f_p2-3.*f_p1+3.*f_p0-f_m1) * (x-x_m1) * (x-x_p0) * (x-x_p1) / 6.0;
73  P[2] = f_p0 + (f_p1-f_p0) * (x-x_p0) + (f_p2-2.*f_p1+f_p0) * (x-x_p0) * (x-x_p1) / 2.0 + (f_p3-3.*f_p2+3.*f_p1-f_p0) * (x-x_p0) * (x-x_p1) * (x-x_p2) / 6.0;
74  //
75  double a[3], sum(0.0);
76  for( int i=0; i<3; ++i ) {
77  a[i] = C[i] / (eps+sqr(S[i]));
78  sum += a[i];
79  }
80  double w[3];
81  for( int i=0; i<3; ++i ) {
82  w[i] = a[i] / sum;
83  }
84  //
85  return w[0]*P[0]+w[1]*P[1]+w[2]*P[2];
86  };
97  static double interp4( double x, const double v[4], const double eps=std::numeric_limits<double>::epsilon() ) {
98  //
99  const double &f_m1 = v[0]; const double &f_p0 = v[1];
100  const double &f_p1 = v[2]; const double &f_p2 = v[3];
101  //
102  const double x_m1 = -1.0; const double x_p0 = 0.0;
103  const double x_p1 = 1.0; const double x_p2 = 2.0;
104 #pragma unused(x_p1)
105  //
106  double C[2];
107  C[0] = (x_p2-x) / 3.0;
108  C[1] = (x-x_m1) / 3.0;
109  //
110  double S[2];
111  S[0] = ((26.*f_p1*f_m1)-(52.*f_p0*f_m1)-(76.*f_p1*f_p0)+(25.*sqr(f_p1))+(64.*sqr(f_p0))+(13.*sqr(f_m1))) / 12.0;
112  S[1] = ((26.*f_p2*f_p0)-(52.*f_p2*f_p1)-(76.*f_p1*f_p0)+(25.*sqr(f_p0))+(64.*sqr(f_p1))+(13.*sqr(f_p2))) / 12.0;
113  //
114  double P[2];
115  P[0] = f_p0 + (f_p1-f_m1) * (x-x_p0) / 2.0 + (f_p1-2.*f_p0+f_m1) * sqr(x-x_p0) / 2.0;
116  P[1] = f_p0 + (-f_p2+4.*f_p1-3.*f_p0) * (x-x_p0) / 2.0 + (f_p2-2.*f_p1+f_p0) * sqr(x-x_p0) / 2.0;
117  //
118  double a[2], sum(0.0);
119  for( int i=0; i<2; ++i ) {
120  a[i] = C[i] / (eps+sqr(S[i]));
121  sum += a[i];
122  }
123  double w[2];
124  for( int i=0; i<2; ++i ) {
125  w[i] = a[i] / sum;
126  }
127  //
128  return w[0]*P[0]+w[1]*P[1];
129  }
130 private:
131  static double sqr (const double &x) { return x*x; }
132 };
133 //
135 //
136 #endif
SHKZ_BEGIN_NAMESPACE
#define SHKZ_BEGIN_NAMESPACE
Name space beggining definition for shiokaze.
Definition: common.h:39
WENO::interp4
static double interp4(double x, const double v[4], const double eps=std::numeric_limits< double >::epsilon())
Interpolate using 4th order accurate WENO scheme.
Definition: WENO.h:97
WENO
Class that implements WENO interpolation.
Definition: WENO.h:40
SHKZ_END_NAMESPACE
#define SHKZ_END_NAMESPACE
Name space end definition for shiokaze.
Definition: common.h:44
WENO::interp6
static double interp6(double x, const double v[6], const double eps=std::numeric_limits< double >::epsilon())
Interpolate using 6th order accurate WENO scheme.
Definition: WENO.h:52