gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
BergotBasis.cpp
Go to the documentation of this file.
1 // Gmsh - Copyright (C) 1997-2022 C. Geuzaine, J.-F. Remacle
2 //
3 // See the LICENSE.txt file in the Gmsh root directory for license information.
4 // Please report all issues on https://gitlab.onelab.info/gmsh/gmsh/issues.
5 
6 #include <cmath>
7 #include "BergotBasis.h"
8 #include "MElement.h"
9 #include "orthogonalBasis.h"
10 
11 BergotBasis::BergotBasis(int p, bool incpl) : order(p), incomplete(incpl)
12 {
13  if(incomplete && order > 2) {
14  Msg::Error("Incomplete pyramids of order %i not yet implemented", order);
15  }
16 }
17 
19 
20 bool BergotBasis::validIJ(int i, int j) const
21 {
22  if(!incomplete) return (i <= order) && (j <= order);
23  if(i + j <= order) return true;
24  if(i + j == order + 1) return i == 1 || j == 1;
25  return false;
26 }
27 
28 // Values of Bergot basis functions for coordinates (u,v,w) in the unit pyramid:
29 // f = L_i(uhat)*L_j(vhat)*(1-w)^max(i,j)*P_k^{2*max(i,j)+2,0}(what)
30 // with i,j = 0...order and k = 0...order-max(i,j)
31 // and (uhat,vhat,what) = (u/(1-w),v/(1-w),2*w-1) reduced coordinates in the
32 // unit cube [-1,1]^3
33 void BergotBasis::f(double u, double v, double w, double *val) const
34 {
35  // Compute Legendre polynomials at uhat
36  double uhat = (w == 1.) ? 0. : u / (1. - w);
37  std::vector<double> uFcts(order + 1);
38  LegendrePolynomials::f(order, uhat, &(uFcts[0]));
39 
40  // Compute Legendre polynomials at vhat
41  double vhat = (w == 1.) ? 0. : v / (1. - w);
42  std::vector<double> vFcts(order + 1);
43  LegendrePolynomials::f(order, vhat, &(vFcts[0]));
44 
45  // Compute Jacobi polynomials at what
46  double what = 2. * w - 1.;
47  std::vector<std::vector<double> > wFcts(order + 1), wGrads(order + 1);
48  for(int mIJ = 0; mIJ <= order; mIJ++) {
49  int kMax = order - mIJ;
50  std::vector<double> &wf = wFcts[mIJ];
51  wf.resize(kMax + 1);
52  JacobiPolynomials::f(kMax, 2. * mIJ + 2., 0., what, &(wf[0]));
53  }
54 
55  // Recombine to find shape function values
56  int index = 0;
57  for(int i = 0; i <= order; i++) {
58  for(int j = 0; j <= order; j++) {
59  if(validIJ(i, j)) {
60  int mIJ = std::max(i, j);
61  double fact = pow(1. - w, mIJ);
62  std::vector<double> &wf = wFcts[mIJ];
63  for(int k = 0; k <= order - mIJ; k++, index++)
64  val[index] = uFcts[i] * vFcts[j] * wf[k] * fact;
65  }
66  }
67  }
68 }
69 
70 // Derivatives of Bergot basis functions for coordinates (u,v,w) in the unit
71 // pyramid: dfdu =
72 // L'_i(uhat)*L_j(vhat)*(1-w)^(max(i,j)-1)*P_k^{2*max(i,j)+2,0}(what) dfdv =
73 // L_i(uhat)*L'_j(vhat)*(1-w)^(max(i,j)-1)*P_k^{2*max(i,j)+2,0}(what) dfdw =
74 // (1-w)^(max(i,j)-2)*P_k^{2*max(i,j)+2,0}(what)*(u*L'_i(uhat)*L_j(vhat)+v*L_i(uhat)*L'_j(vhat))
75 // +
76 // u*v*(1-w)^(max(i,j)-1)*(2*(1-w)*P'_k^{2*max(i,j)+2,0}(what)-max(i,j)*P_k^{2*max(i,j)+2,0}(what))
77 // with i,j = 0...order and k = 0...order-max(i,j)
78 // and (uhat,vhat,what) = (u/(1-w),v/(1-w),2*w-1) reduced coordinates in the
79 // unit cube [-1,1]^3
80 void BergotBasis::df(double u, double v, double w, double grads[][3]) const
81 {
82  // Compute Legendre polynomials and derivatives at uhat
83  double uhat = (w == 1.) ? 0. : u / (1. - w);
84  std::vector<double> uFcts(order + 1), uGrads(order + 1);
85  LegendrePolynomials::f(order, uhat, &(uFcts[0]));
86  LegendrePolynomials::df(order, uhat, &(uGrads[0]));
87 
88  // Compute Legendre polynomials and derivatives at vhat
89  double vhat = (w == 1.) ? 0. : v / (1. - w);
90  std::vector<double> vFcts(order + 1), vGrads(order + 1);
91  LegendrePolynomials::f(order, vhat, &(vFcts[0]));
92  LegendrePolynomials::df(order, vhat, &(vGrads[0]));
93 
94  // Compute Jacobi polynomials and derivatives at what
95  double what = 2. * w - 1.;
96  std::vector<std::vector<double> > wFcts(order + 1), wGrads(order + 1);
97  for(int mIJ = 0; mIJ <= order; mIJ++) {
98  int kMax = order - mIJ;
99  std::vector<double> &wf = wFcts[mIJ], &wg = wGrads[mIJ];
100  wf.resize(kMax + 1);
101  wg.resize(kMax + 1);
102  JacobiPolynomials::f(kMax, 2. * mIJ + 2., 0., what, &(wf[0]));
103  JacobiPolynomials::df(kMax, 2. * mIJ + 2., 0., what, &(wg[0]));
104  }
105 
106  // Recombine to find the shape function gradients
107  int index = 0;
108  for(int i = 0; i <= order; i++) {
109  for(int j = 0; j <= order; j++) {
110  if(validIJ(i, j)) {
111  int mIJ = std::max(i, j);
112  std::vector<double> &wf = wFcts[mIJ], &wg = wGrads[mIJ];
113  if(mIJ == 0) { // Indeterminate form for mIJ = 0
114  for(int k = 0; k <= order - mIJ; k++, index++) {
115  grads[index][0] = 0.;
116  grads[index][1] = 0.;
117  grads[index][2] = 2. * wg[k];
118  }
119  }
120  else if(mIJ == 1) { // Indeterminate form for mIJ = 1
121  if(i == 0) {
122  for(int k = 0; k <= order - mIJ; k++, index++) {
123  grads[index][0] = 0.;
124  grads[index][1] = wf[k];
125  grads[index][2] = 2. * v * wg[k];
126  }
127  }
128  else if(j == 0) {
129  for(int k = 0; k <= order - mIJ; k++, index++) {
130  grads[index][0] = wf[k];
131  grads[index][1] = 0.;
132  grads[index][2] = 2. * u * wg[k];
133  }
134  }
135  else {
136  for(int k = 0; k <= order - mIJ; k++, index++) {
137  grads[index][0] = vhat * wf[k];
138  grads[index][1] = uhat * wf[k];
139  grads[index][2] = uhat * vhat * wf[k] + 2. * uhat * v * wg[k];
140  }
141  }
142  }
143  else { // General formula
144  double oMW = 1. - w;
145  double powM2 = pow(oMW, mIJ - 2);
146  double powM1 = powM2 * oMW;
147  for(int k = 0; k <= order - mIJ; k++, index++) {
148  grads[index][0] = uGrads[i] * vFcts[j] * wf[k] * powM1;
149  grads[index][1] = uFcts[i] * vGrads[j] * wf[k] * powM1;
150  grads[index][2] =
151  wf[k] * powM2 *
152  (u * uGrads[i] * vFcts[j] + v * uFcts[i] * vGrads[j]) +
153  uFcts[i] * vFcts[j] * powM1 * (2. * oMW * wg[k] - mIJ * wf[k]);
154  }
155  }
156  }
157  }
158  }
159 }
BergotBasis::df
void df(double u, double v, double w, double grads[][3]) const
Definition: BergotBasis.cpp:80
orthogonalBasis.h
BergotBasis::validIJ
bool validIJ(int i, int j) const
Definition: BergotBasis.cpp:20
Msg::Error
static void Error(const char *fmt,...)
Definition: GmshMessage.cpp:482
BergotBasis.h
LegendrePolynomials::f
void f(int n, double u, double *val)
Definition: orthogonalBasis.cpp:77
JacobiPolynomials::f
void f(int n, double alpha, double beta, double u, double *val)
Definition: orthogonalBasis.cpp:134
BergotBasis::incomplete
bool incomplete
serendipity interpolation
Definition: BergotBasis.h:32
BergotBasis::order
int order
Definition: BergotBasis.h:30
LegendrePolynomials::df
void df(int n, double u, double *val)
Definition: orthogonalBasis.cpp:103
BergotBasis::f
void f(double u, double v, double w, double *val) const
Definition: BergotBasis.cpp:33
MElement.h
BergotBasis::~BergotBasis
virtual ~BergotBasis()
Definition: BergotBasis.cpp:18
BergotBasis::BergotBasis
BergotBasis(int p, bool incpl=false)
Definition: BergotBasis.cpp:11
JacobiPolynomials::df
void df(int n, double alpha, double beta, double u, double *val)
Definition: orthogonalBasis.cpp:157