1 // Gmsh - Copyright (C) 1997-2021 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 // Contributor(s):
7 // Amaury Johnen
8 //
9
10 #include "incompleteBasis.h"
11 #include "BasisFactory.h"
12 #include "ElementType.h"
13
_computeCoefficientsTriangle()14 void incompleteBasis::_computeCoefficientsTriangle()
15 {
16 if(order < 3) {
17 coefficients.resize(0, 0);
18 return;
19 }
20
21 int szInc = getNumShapeFunctions();
22 int szComp = completeBasis->getNumShapeFunctions();
23 coefficients.resize(szComp - szInc, szInc, true);
24
25 std::map<std::pair<int, int>, int> coord2idx;
26 for(int i = 0; i < szInc; ++i) {
27 int u = static_cast<int>(points(i, 0) * order + .5);
28 int v = static_cast<int>(points(i, 1) * order + .5);
29 coord2idx[std::make_pair(u, v)] = i;
30 }
31
32 int &n = order;
33 fullMatrix<double> pts = completeBasis->getReferenceNodes();
34 for(int i = 0; i < szComp - szInc; ++i) {
35 double xi = pts(szInc + i, 0);
36 double eta = pts(szInc + i, 1);
37 int u = static_cast<int>(xi * order + .5);
38 int v = static_cast<int>(eta * order + .5);
39
40 coefficients(i, coord2idx[std::make_pair(u + v, 0)]) = xi;
41 coefficients(i, coord2idx[std::make_pair(n, 0)]) = -xi;
42 coefficients(i, coord2idx[std::make_pair(n - v, v)]) = xi;
43 coefficients(i, coord2idx[std::make_pair(u, n - u)]) = eta;
44 coefficients(i, coord2idx[std::make_pair(0, n)]) = -eta;
45 coefficients(i, coord2idx[std::make_pair(0, u + v)]) = eta;
46 coefficients(i, coord2idx[std::make_pair(0, v)]) = 1 - xi - eta;
47 coefficients(i, coord2idx[std::make_pair(0, 0)]) = -(1 - xi - eta);
48 coefficients(i, coord2idx[std::make_pair(u, 0)]) = 1 - xi - eta;
49 }
50
51 coefficients.print("coefficients");
52 }
53
incompleteBasis(int tag)54 incompleteBasis::incompleteBasis(int tag)
55 // If the element is complete, compute the incomplete basis anyway
56 : nodalBasis(ElementType::getType(ElementType::getParentType(tag),
57 ElementType::getOrder(tag), true)),
58 completeBasis(nullptr), polyBasis(nullptr)
59 {
60 int tagComplete = ElementType::getType(parentType, order, false);
61 switch(parentType) {
62 case TYPE_LIN:
63 case TYPE_PNT:
64 case TYPE_QUA:
65 case TYPE_HEX: polyBasis = new polynomialBasis(type); break;
66 case TYPE_TET:
67 case TYPE_PRI:
68 case TYPE_PYR:
69 completeBasis = BasisFactory::getNodalBasis(tagComplete);
70 break;
71 case TYPE_TRI:
72 completeBasis = BasisFactory::getNodalBasis(tagComplete);
73 _computeCoefficientsTriangle();
74 break;
75 }
76 }
77
~incompleteBasis()78 incompleteBasis::~incompleteBasis() { delete polyBasis; }
79
f(double u,double v,double w,double * sf) const80 void incompleteBasis::f(double u, double v, double w, double *sf) const
81 {
82 if(polyBasis)
83 polyBasis->f(u, v, w, sf);
84 else {
85 double csf[1331];
86 completeBasis->f(u, v, w, csf);
87 int szInc = getNumShapeFunctions();
88 for(int i = 0; i < szInc; ++i) {
89 sf[i] = csf[i];
90 for(int j = 0; j < coefficients.size1(); ++j) {
91 sf[i] += csf[szInc + j] * coefficients(j, i);
92 }
93 }
94 }
95 }
96
f(const fullMatrix<double> & coord,fullMatrix<double> & sf) const97 void incompleteBasis::f(const fullMatrix<double> &coord,
98 fullMatrix<double> &sf) const
99 {
100 if(polyBasis)
101 polyBasis->f(coord, sf);
102 else {
103 completeBasis->f(coord, sf);
104 int szInc = getNumShapeFunctions();
105 for(int k = 0; k < sf.size1(); ++k) {
106 for(int i = 0; i < szInc; ++i) {
107 for(int j = 0; j < coefficients.size1(); ++j) {
108 sf(k, i) += sf(k, szInc + j) * coefficients(j, i);
109 }
110 }
111 }
112 sf.resize(sf.size1(), szInc, false);
113 }
114 }
115
df(const fullMatrix<double> & coord,fullMatrix<double> & dfm) const116 void incompleteBasis::df(const fullMatrix<double> &coord,
117 fullMatrix<double> &dfm) const
118 {
119 if(polyBasis)
120 polyBasis->df(coord, dfm);
121 else {
122 completeBasis->df(coord, dfm);
123 int szInc = getNumShapeFunctions();
124 for(int k = 0; k < dfm.size1(); ++k) {
125 for(int i = 0; i < szInc; ++i) {
126 for(int j = 0; j < coefficients.size1(); ++j) {
127 dfm(k, i) += dfm(k, szInc + j) * coefficients(j, i);
128 }
129 }
130 }
131 dfm.resize(dfm.size1(), szInc, false);
132 }
133 }
134
df(double u,double v,double w,double grads[][3]) const135 void incompleteBasis::df(double u, double v, double w, double grads[][3]) const
136 {
137 if(polyBasis)
138 polyBasis->df(u, v, w, grads);
139 else {
140 double cgrads[1331][3];
141 completeBasis->df(u, v, w, cgrads);
142 int szInc = getNumShapeFunctions();
143 for(int i = 0; i < szInc; ++i) {
144 grads[i][0] = cgrads[i][0];
145 grads[i][1] = cgrads[i][1];
146 grads[i][2] = cgrads[i][2];
147 for(int j = 0; j < coefficients.size1(); ++j) {
148 grads[i][0] = cgrads[szInc + j][0] * coefficients(j, i);
149 grads[i][1] = cgrads[szInc + j][1] * coefficients(j, i);
150 grads[i][2] = cgrads[szInc + j][2] * coefficients(j, i);
151 }
152 }
153 }
154 }
155
ddf(double u,double v,double w,double hess[][3][3]) const156 void incompleteBasis::ddf(double u, double v, double w,
157 double hess[][3][3]) const
158 {
159 if(polyBasis)
160 polyBasis->ddf(u, v, w, hess);
161 else {
162 double chess[1331][3][3];
163 completeBasis->ddf(u, v, w, chess);
164 int szInc = getNumShapeFunctions();
165 for(int i = 0; i < szInc; ++i) {
166 for(int k = 0; k < 3; ++k) {
167 for(int l = 0; l < 3; ++l) { hess[i][k][l] = chess[i][k][l]; }
168 }
169 for(int j = 0; j < coefficients.size1(); ++j) {
170 for(int k = 0; k < 3; ++k) {
171 for(int l = 0; l < 3; ++l) {
172 hess[i][k][l] = chess[szInc + j][k][l] * coefficients(j, i);
173 }
174 }
175 }
176 }
177 }
178 }
179
dddf(double u,double v,double w,double third[][3][3][3]) const180 void incompleteBasis::dddf(double u, double v, double w,
181 double third[][3][3][3]) const
182 {
183 if(polyBasis)
184 polyBasis->dddf(u, v, w, third);
185 else {
186 double cthird[1331][3][3][3];
187 completeBasis->dddf(u, v, w, cthird);
188 int szInc = getNumShapeFunctions();
189 for(int i = 0; i < szInc; ++i) {
190 for(int k = 0; k < 3; ++k) {
191 for(int l = 0; l < 3; ++l) {
192 for(int m = 0; m < 3; ++m) { third[i][k][l][m] = cthird[i][k][l][m]; }
193 }
194 }
195 for(int j = 0; j < coefficients.size1(); ++j) {
196 for(int k = 0; k < 3; ++k) {
197 for(int l = 0; l < 3; ++l) {
198 for(int m = 0; m < 3; ++m) {
199 third[i][k][l][m] =
200 cthird[szInc + j][k][l][m] * coefficients(j, i);
201 }
202 }
203 }
204 }
205 }
206 }
207 }
208