VTK  9.7.20261001
TriCnGradient.h
Go to the documentation of this file.
1// Gradients of the arbitrary-order Lagrange interpolants on the triangle.
2//
3// See TriCnBasis.h for the definition of the interpolants. Differentiating
4// the product of Silvester polynomials by the chain rule, and using
5// ∂λ0/∂r = -1, ∂λ1/∂r = 1, ∂λ2/∂r = 0 (and likewise for s), gives
6//
7// ∂L/∂r = P_{i2}(λ2) (P'_{i1}(λ1) P_{i0}(λ0) - P'_{i0}(λ0) P_{i1}(λ1))
8// ∂L/∂s = P_{i1}(λ1) (P'_{i2}(λ2) P_{i0}(λ0) - P'_{i0}(λ0) P_{i2}(λ2))
9RealT nn = RealT(order[0]);
10
11WORKSPACE(RealT, bary, 3);
12bary[0] = 1. - rr - ss;
13bary[1] = rr;
14bary[2] = ss;
15
16// Tabulate P_m and its derivative for every barycentric coordinate and every
17// degree up to n. Differentiating the recurrence used in TriCnBasis.h gives
18// P'_m(x) = (P'_{m-1}(x) (n x - (m - 1)) + P_{m-1}(x) n) / m.
19WORKSPACE(RealT, pval, 3 * (order[0] + 1));
20WORKSPACE(RealT, pder, 3 * (order[0] + 1));
21for (int kk = 0; kk < 3; ++kk)
22{
23 int base = kk * (order[0] + 1);
24 pval[base] = 1.;
25 pder[base] = 0.;
26 for (int mm = 1; mm <= order[0]; ++mm)
27 {
28 RealT rmm = RealT(mm);
29 RealT factor = nn * bary[kk] - (rmm - 1.);
30 pder[base + mm] = (pder[base + mm - 1] * factor + pval[base + mm - 1] * nn) / rmm;
31 pval[base + mm] = pval[base + mm - 1] * factor / rmm;
32 }
33}
34
35int idx = 0;
36for (int i2 = 0; i2 <= order[0]; ++i2)
37{
38 for (int i1 = 0; i1 <= order[0] - i2; ++i1)
39 {
40 int i0 = order[0] - i1 - i2;
41 RealT p0 = pval[i0];
42 RealT p1 = pval[(order[0] + 1) + i1];
43 RealT p2 = pval[2 * (order[0] + 1) + i2];
44 RealT d0 = pder[i0];
45 RealT d1 = pder[(order[0] + 1) + i1];
46 RealT d2 = pder[2 * (order[0] + 1) + i2];
47 basisGradient[idx++] = p2 * (d1 * p0 - d0 * p1); // ∂/∂r
48 basisGradient[idx++] = p1 * (d2 * p0 - d0 * p2); // ∂/∂s
49 basisGradient[idx++] = 0.;
50 }
51}
int idx
Definition HexCnBasis.h:79
bary[0]
Definition TetCnBasis.h:15
WORKSPACE(RealT, bary, 3)
basisGradient[0]
RealT nn
Definition TetCnBasis.h:7