Basilisk CFD
Adaptive Cartesian mesh PDE framework
Loading...
Searching...
No Matches
parabola.h
Go to the documentation of this file.
1/** @file parabola.h
2 */
3#include "utils.h"
4
5#define PARABOLA_FIT_CENTER_WEIGHT .1
6
7// Define this to use a x^iy^j polynomial with i = 0...NP-1, j = 0...NP-1
8// #define NP 3
9
10typedef struct {
12#if dimension == 2 /* y = a[0]*x^2 + a[1]*x + a[2] */
14 double M[3][3], rhs[3], a[3];
15#else /* 3D z = a[0]*x^2 + a[1]*y^2 + a[2]*x*y + a[3]*x + a[4]*y + a[5] */
16 double t[3][3];
17# ifdef NP
18 double M[NP*NP][NP*NP], rhs[NP*NP], a[NP*NP];
19# else
20 double M[6][6], rhs[6], a[6];
21# endif
22#endif /* 3D */
24
26{
27 for (int _d = 0; _d < dimension; _d++)
28 p->o.x = o.x;
29#if dimension == 2
30 for (int _d = 0; _d < dimension; _d++)
31 p->m.x = m.x;
32 normalize (&p->m);
33 int n = 3;
34#else /* 3D */
35 double max;
36 coord nx = {0., 0., 0.}, ny, nz;
37 int d = 0;
38
39 for (int _d = 0; _d < dimension; _d++)
40 nz.x = m.x;
41 normalize (&nz);
42 max = sq(nz.x);
43 /* build a vector orthogonal to nz */
44 if (sq(nz.y) > max) { max = sq(nz.y); d = 1; }
45 if (sq(nz.z) > max) d = 2;
46 switch (d) {
47 case 0: nx.x = - nz.z/nz.x; nx.z = 1.0; break;
48 case 1: nx.y = - nz.z/nz.y; nx.z = 1.0; break;
49 case 2: nx.z = - nz.x/nz.z; nx.x = 1.0; break;
50 }
51 normalize (&nx);
52
53 /* build a second vector orthogonal to nx and nz */
54 for (int _d = 0; _d < dimension; _d++)
55 ny.x = nz.y*nx.z - nz.z*nx.y;
56
57 /* transformation matrix from (i,j,k) to (nx, ny, nz) */
58 p->t[0][0] = nx.x; p->t[0][1] = nx.y; p->t[0][2] = nx.z;
59 p->t[1][0] = ny.x; p->t[1][1] = ny.y; p->t[1][2] = ny.z;
60 p->t[2][0] = nz.x; p->t[2][1] = nz.y; p->t[2][2] = nz.z;
61# ifdef NP
62 int n = NP*NP;
63# else
64 int n = 6;
65# endif
66#endif /* 3D */
67 for (int i = 0; i < n; i++) {
68 for (int j = 0; j < n; j++)
69 p->M[i][j] = 0.;
70 p->rhs[i] = 0.;
71 }
72}
73
74static void parabola_fit_add (ParabolaFit * p, coord m, double w)
75{
76#if dimension == 2
77 double x1 = m.x - p->o.x, y1 = m.y - p->o.y;
78 double x = p->m.y*x1 - p->m.x*y1;
79 double y = p->m.x*x1 + p->m.y*y1;
80 double x2 = w*x*x, x3 = x2*x, x4 = x3*x;
81 p->M[0][0] += x4;
82 p->M[1][0] += x3; p->M[1][1] += x2;
83 p->M[2][1] += w*x; p->M[2][2] += w;
84 p->rhs[0] += x2*y; p->rhs[1] += w*x*y; p->rhs[2] += w*y;
85#else /* 3D */
86 double x1 = m.x - p->o.x, y1 = m.y - p->o.y, z1 = m.z - p->o.z;
87 double x = p->t[0][0]*x1 + p->t[0][1]*y1 + p->t[0][2]*z1;
88 double y = p->t[1][0]*x1 + p->t[1][1]*y1 + p->t[1][2]*z1;
89 double z = p->t[2][0]*x1 + p->t[2][1]*y1 + p->t[2][2]*z1;
90# ifdef NP
91 for (int i = 0; i < NP; i++)
92 for (int j = 0; j < NP; j++) {
93 for (int k = 0; k < NP; k++)
94 for (int l = 0; l < NP; l++)
95 p->M[i*NP + j][k*NP + l] += w*pow(x, i + k)*pow(y, j + l);
96 p->rhs[i*NP + j] += w*z*pow(x, i)*pow(y, j);
97 }
98# else // !NP
99 double x2 = x*x, x3 = x2*x, x4 = x3*x;
100 double y2 = y*y, y3 = y2*y, y4 = y3*y;
101 p->M[0][0] += w*x4; p->M[1][1] += w*y4; p->M[2][2] += w*x2*y2;
102 p->M[3][3] += w*x2; p->M[4][4] += w*y2; p->M[5][5] += w;
103 p->M[0][2] += w*x3*y; p->M[0][3] += w*x3; p->M[0][4] += w*x2*y;
104 p->M[1][2] += w*x*y3; p->M[1][3] += w*x*y2; p->M[1][4] += w*y3;
105 p->M[2][5] += w*x*y;
106 p->M[3][5] += w*x;
107 p->M[4][5] += w*y;
108 p->rhs[0] += w*x2*z; p->rhs[1] += w*y2*z; p->rhs[2] += w*x*y*z;
109 p->rhs[3] += w*x*z; p->rhs[4] += w*y*z; p->rhs[5] += w*z;
110# endif // !NP
111#endif /* 3D */
112}
113
115{
116#if dimension == 2
117 p->M[0][1] = p->M[1][0];
118 p->M[0][2] = p->M[2][0] = p->M[1][1];
119 p->M[1][2] = p->M[2][1];
120 double pivmin = smatrix_inverse (3, p->M, 1e-10);
121 if (pivmin) {
122 p->a[0] = p->M[0][0]*p->rhs[0] + p->M[0][1]*p->rhs[1] + p->M[0][2]*p->rhs[2];
123 p->a[1] = p->M[1][0]*p->rhs[0] + p->M[1][1]*p->rhs[1] + p->M[1][2]*p->rhs[2];
124 }
125 else /* this may be a degenerate/isolated interface fragment */
126 p->a[0] = p->a[1] = 0.;
127#else /* 3D */
128# ifdef NP
129 double pivmin = smatrix_inverse (NP*NP, p->M, 1e-10);
130 if (pivmin)
131 for (int i = 0; i < NP*NP; i++) {
132 p->a[i] = 0.;
133 for (int j = 0; j < NP*NP; j++)
134 p->a[i] += p->M[i][j]*p->rhs[j];
135 }
136 else /* this may be a degenerate/isolated interface fragment */
137 for (int i = 0; i < NP*NP; i++)
138 p->a[i] = 0.;
139# else // !NP
140 p->M[0][1] = p->M[2][2]; p->M[0][5] = p->M[3][3];
141 p->M[1][5] = p->M[4][4];
142 p->M[2][3] = p->M[0][4]; p->M[2][4] = p->M[1][3];
143 p->M[3][4] = p->M[2][5];
144 for (int i = 1; i < 6; i++)
145 for (int j = 0; j < i; j++)
146 p->M[i][j] = p->M[j][i];
147 double pivmin = smatrix_inverse (6, p->M, 1e-10);
148 if (pivmin)
149 for (int i = 0; i < 6; i++) {
150 p->a[i] = 0.;
151 for (int j = 0; j < 6; j++)
152 p->a[i] += p->M[i][j]*p->rhs[j];
153 }
154 else /* this may be a degenerate/isolated interface fragment */
155 for (int i = 0; i < 6; i++)
156 p->a[i] = 0.;
157# endif // !NP
158#endif /* 3D */
159 return pivmin;
160}
161
163 double kappamax, double * kmax)
164{
165 double kappa;
166#if dimension == 2
167 double dnm = 1.[0] + sq(p->a[1]);
168 kappa = - 2.*p->a[0]/pow(dnm, 3/2.);
169 if (kmax)
170 *kmax = fabs (kappa);
171#else /* 3D */
172# ifdef NP
173 double hxx = 2.*p->a[2*NP], hyy = 2.*p->a[2], hxy = p->a[NP + 1];
174 double hx = p->a[NP], hy = p->a[1];
175# else
176 double hxx = 2.*p->a[0], hyy = 2.*p->a[1], hxy = p->a[2];
177 double hx = p->a[3], hy = p->a[4];
178# endif
179 double dnm = 1. + sq(hx) + sq(hy);
180 kappa = - (hxx*(1. + sq(hy)) + hyy*(1. + sq(hx)) - 2.*hxy*hx*hy)
181 /sqrt (dnm*dnm*dnm);
182 if (kmax) {
183 double kg = (hxx*hyy - hxy*hxy)/(dnm*dnm);
184 double a = kappa*kappa/4. - kg;
185 *kmax = fabs (kappa/2.);
186 if (a >= 0.)
187 *kmax += sqrt (a);
188 }
189#endif /* 3D */
190 if (fabs (kappa) > kappamax) {
191 if (kmax)
192 *kmax = kappamax;
193 return kappa > 0. ? kappamax : - kappamax;
194 }
195 return kappa;
196}
197
198#if AXI
199static void parabola_fit_axi_curvature (const ParabolaFit * p,
200 double r, double h,
201 double * kappa, double * kmax)
202{
203 double nr = (p->m.x*p->a[1] + p->m.y)/sqrt (1. + sq(p->a[1]));
204 /* limit the minimum radius to half the grid size */
205 double kaxi = nr/max(r, h/2.);
206 *kappa += kaxi;
207 if (kmax)
208 *kmax = max (*kmax, fabs (kaxi));
209}
210#endif /* 2D */
const vector a
Definition all-mach.h:59
scalar h[]
Definition atmosphere.h:6
#define dimension
Definition bitree.h:3
define k
define l
define m((k)==0 &&(l)==0 &&(m)==0) macro2 foreach_point(double _x=0.
int y
Definition common.h:76
int x
Definition common.h:76
int z
Definition common.h:76
void normalize(coord *n)
Definition common.h:98
static number sq(number x)
Definition common.h:11
double smatrix_inverse(const int n, double m[n][n], double pivmin)
Definition common.h:434
vector w[]
#define p
Definition tree.h:320
double hx
Definition curvature.h:80
return hxx pow(1.+sq(hx), 3/2.)
double hxx
Definition curvature.h:81
coord o
Definition curvature.h:672
else return n
Definition curvature.h:101
*cs[i, 0, 0] a *[i -1, 0, 0] j
Definition embed.h:88
double d[2]
Definition embed.h:383
scalar int i
Definition embed.h:74
y1
Definition embed.h:394
double t
Definition events.h:24
size_t max
Definition mtrace.h:8
size_t nr
Definition mtrace.h:10
static double parabola_fit_curvature(ParabolaFit *p, double kappamax, double *kmax)
Definition parabola.h:162
static void parabola_fit_add(ParabolaFit *p, coord m, double w)
Definition parabola.h:74
static void parabola_fit_init(ParabolaFit *p, coord o, coord m)
Definition parabola.h:25
static double parabola_fit_solve(ParabolaFit *p)
Definition parabola.h:114
coord m
Definition parabola.h:13
coord o
Definition parabola.h:11
Definition common.h:78
double x
Definition common.h:79
scalar x
Definition common.h:47
#define kappa(f)
Definition thermal.h:85