gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
pyramidalBasis.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 <algorithm>
8 #include "pyramidalBasis.h"
9 #include "pointsGenerators.h"
10 
11 pyramidalBasis::pyramidalBasis(int tag) : nodalBasis(tag), bergot(nullptr)
12 {
13  if(serendip && order > 2) {
14  Msg::Warning("Serendipity pyramid for order %i not yet implemented", order);
15  return;
16  }
17 
19 
20  int num_points = points.size1();
21 
22  bergotCoefficients.resize(num_points, num_points);
23  double *fval = new double[num_points];
24 
25  // Invert the Vandermonde matrix
26  fullMatrix<double> VDM(num_points, num_points);
27  for(int j = 0; j < num_points; j++) {
28  bergot->f(points(j, 0), points(j, 1), points(j, 2), fval);
29  for(int i = 0; i < num_points; i++) VDM(i, j) = fval[i];
30  }
32 
33  coefficients.resize(num_points, num_points);
34  monomials.resize(num_points, 3);
35 
36  int idx = 0;
37  for(int i = 0; i <= order; i++) {
38  for(int j = 0; j <= order; j++) {
39  if(bergot->validIJ(i, j)) {
40  for(int k = 0; k <= order - std::max(i, j); k++, idx++) {
41  monomials(idx, 0) = i;
42  monomials(idx, 1) = j;
43  monomials(idx, 2) = k;
44 
45  for(int l = 0; l < num_points; l++) {
46  double oneMinW = std::max(1e-14, 1 - points(l, 2));
47  VDM(idx, l) = std::pow(points(l, 0), i);
48  VDM(idx, l) *= std::pow(points(l, 1), j);
49  VDM(idx, l) *= std::pow(points(l, 2), k);
50  VDM(idx, l) *= std::pow(oneMinW, std::max(i, j) - i - j);
51  }
52  }
53  }
54  }
55  }
56  VDM.invert(coefficients);
57 
58  delete[] fval;
59 }
60 
62 {
63  if(bergot) delete bergot;
64 }
65 
67 
68 void pyramidalBasis::f(double u, double v, double w, double *val) const
69 {
70  if(!bergot) return;
71 
72  const int N = points.size1();
73 
74  double *fval = new double[N];
75  bergot->f(u, v, w, fval);
76 
77  for(int i = 0; i < N; i++) {
78  val[i] = 0.;
79  for(int j = 0; j < N; j++) val[i] += bergotCoefficients(i, j) * fval[j];
80  }
81 
82  delete[] fval;
83 }
84 
86  fullMatrix<double> &sf) const
87 {
88  if(!bergot) return;
89 
90  const int N = points.size1(), NPts = coord.size1();
91 
92  sf.resize(NPts, N);
93  double *fval = new double[N];
94 
95  for(int iPt = 0; iPt < NPts; iPt++) {
96  bergot->f(coord(iPt, 0), coord(iPt, 1), coord(iPt, 2), fval);
97  for(int i = 0; i < N; i++) {
98  sf(iPt, i) = 0.;
99  for(int j = 0; j < N; j++)
100  sf(iPt, i) += bergotCoefficients(i, j) * fval[j];
101  }
102  }
103 
104  delete[] fval;
105 }
106 
107 void pyramidalBasis::f(double u, double v, double w, int i, double *val) const
108 {
109  if(!bergot) return;
110 
111  if(i < 0 || i >= bergotCoefficients.size1()) {
112  Msg::Error("Node out of range for pyramidal basis");
113  return;
114  }
115 
116  const int N = points.size1();
117 
118  double *fval = new double[N];
119  bergot->f(u, v, w, fval);
120 
121  *val = 0.;
122  for(int j = 0; j < N; j++) *val += bergotCoefficients(i, j) * fval[j];
123 
124  delete[] fval;
125 }
126 
127 void pyramidalBasis::df(double u, double v, double w, double grads[][3]) const
128 {
129  if(!bergot) return;
130 
131  const int N = points.size1();
132 
133  double(*dfval)[3] = new double[N][3];
134  bergot->df(u, v, w, dfval);
135 
136  for(int i = 0; i < N; i++) {
137  grads[i][0] = 0.;
138  grads[i][1] = 0.;
139  grads[i][2] = 0.;
140  for(int j = 0; j < N; j++) {
141  grads[i][0] += bergotCoefficients(i, j) * dfval[j][0];
142  grads[i][1] += bergotCoefficients(i, j) * dfval[j][1];
143  grads[i][2] += bergotCoefficients(i, j) * dfval[j][2];
144  }
145  }
146 
147  delete[] dfval;
148 }
149 
151  fullMatrix<double> &dfm) const
152 {
153  if(!bergot) return;
154 
155  const int N = points.size1(), NPts = coord.size1();
156 
157  double(*dfv)[3] = new double[N][3];
158  dfm.resize(3 * NPts, N, false);
159 
160  for(int iPt = 0; iPt < NPts; iPt++) {
161  df(coord(iPt, 0), coord(iPt, 1), coord(iPt, 2), dfv);
162  for(int i = 0; i < N; i++) {
163  dfm(3 * iPt + 0, i) = dfv[i][0];
164  dfm(3 * iPt + 1, i) = dfv[i][1];
165  dfm(3 * iPt + 2, i) = dfv[i][2];
166  }
167  }
168 
169  delete[] dfv;
170 }
171 
172 void pyramidalBasis::df(double u, double v, double w, int i,
173  double grad[3]) const
174 {
175  if(!bergot) return;
176 
177  if(i < 0 || i >= bergotCoefficients.size1()) {
178  Msg::Error("Node out of range for pyramidal basis gradient");
179  return;
180  }
181 
182  const int N = points.size1();
183 
184  double(*dfval)[3] = new double[N][3];
185  bergot->df(u, v, w, dfval);
186 
187  grad[0] = 0.;
188  grad[1] = 0.;
189  grad[2] = 0.;
190  for(int j = 0; j < N; j++) {
191  grad[0] += bergotCoefficients(i, j) * dfval[j][0];
192  grad[1] += bergotCoefficients(i, j) * dfval[j][1];
193  grad[2] += bergotCoefficients(i, j) * dfval[j][2];
194  }
195 
196  delete[] dfval;
197 }
pyramidalBasis::monomials
fullMatrix< double > monomials
Definition: pyramidalBasis.h:21
pyramidalBasis::coefficients
fullMatrix< double > coefficients
Definition: pyramidalBasis.h:20
BergotBasis::df
void df(double u, double v, double w, double grads[][3]) const
Definition: BergotBasis.cpp:80
pyramidalBasis.h
nodalBasis::points
fullMatrix< double > points
Definition: nodalBasis.h:16
pyramidalBasis::bergot
BergotBasis * bergot
Definition: pyramidalBasis.h:16
BergotBasis::validIJ
bool validIJ(int i, int j) const
Definition: BergotBasis.cpp:20
Msg::Warning
static void Warning(const char *fmt,...)
Definition: GmshMessage.cpp:543
Msg::Error
static void Error(const char *fmt,...)
Definition: GmshMessage.cpp:482
nodalBasis::serendip
bool serendip
Definition: nodalBasis.h:15
fullMatrix< double >
nodalBasis::order
int order
Definition: nodalBasis.h:14
pyramidalBasis::getNumShapeFunctions
virtual int getNumShapeFunctions() const
Definition: pyramidalBasis.cpp:66
pyramidalBasis::~pyramidalBasis
~pyramidalBasis()
Definition: pyramidalBasis.cpp:61
pyramidalBasis::pyramidalBasis
pyramidalBasis(int tag)
Definition: pyramidalBasis.cpp:11
pyramidalBasis::df
virtual void df(double u, double v, double w, double grads[][3]) const
Definition: pyramidalBasis.cpp:127
pyramidalBasis::bergotCoefficients
fullMatrix< double > bergotCoefficients
Definition: pyramidalBasis.h:17
BergotBasis
Definition: BergotBasis.h:17
nodalBasis
Definition: nodalBasis.h:12
fullMatrix::size1
int size1() const
Definition: fullMatrix.h:274
BergotBasis::f
void f(double u, double v, double w, double *val) const
Definition: BergotBasis.cpp:33
pointsGenerators.h
fullMatrix::resize
bool resize(int r, int c, bool resetValue=true)
Definition: fullMatrix.h:307
pyramidalBasis::f
virtual void f(double u, double v, double w, double *val) const
Definition: pyramidalBasis.cpp:68
fullMatrix::invert
bool invert(fullMatrix< scalar > &result) const
Definition: fullMatrix.h:641