19 inline double calcDet3x3(
double M11,
double M12,
double M13,
double M21,
20 double M22,
double M23,
double M31,
double M32,
23 return M11 * (M22 * M33 - M23 * M32) - M12 * (M21 * M33 - M23 * M31) +
24 M13 * (M21 * M32 - M22 * M31);
29 inline double calcInvCondNum2D(
double dxdX,
double dxdY,
double dydX,
30 double dydY,
double dzdX,
double dzdY,
31 double nx,
double ny,
double nz)
33 const double dxdXSq = dxdX * dxdX, dydXSq = dydX * dydX,
35 const double dxdYSq = dxdY * dxdY, dydYSq = dydY * dydY,
37 const double Dx = dxdXSq - dxdYSq, Dy = dydXSq - dydYSq;
38 const double Cx = dxdX * dxdY, Cy = dydX * dydY;
39 const double S1 = dzdYSq * dzdYSq;
40 const double S2 = (dzdXSq - Dy - Dx) * dzdYSq;
41 const double S3 = (Cy + Cx) * dzdX * dzdY;
42 const double S4 = dzdXSq * dzdXSq;
43 const double S5 = (Dy + Dx) * dzdXSq;
44 const double S6 = Cx * Cy;
45 const double S7 = dydXSq * dydXSq;
46 const double S8 = Dy * dydXSq;
47 const double S9 = dxdXSq * dxdXSq;
48 const double S10 = Dx * dxdXSq;
49 const double S11 = Dy * Dy;
50 const double S12 = Dx * Dy;
51 const double S13 = Dx * Dx;
52 const double S = 2. * (S2 + S5 + S12) + 4. * (S7 - S8 + S9 - S10) +
53 8. * (S3 + S6) + S1 + S4 + S11 + S13;
54 const double N = dxdXSq + dxdYSq + dydXSq + dydYSq + dzdXSq + dzdYSq;
55 const double sqrtS = (
S > 0.0) ? sqrt(
S) : 0.0;
56 const double sigma1Sq = 0.5 * (N + sqrtS), sigma2Sq = 0.5 * (N - sqrtS);
57 const double iCN = 2. * sqrt(sigma1Sq * sigma2Sq) / (sigma1Sq + sigma2Sq);
59 const double lnx = dydX * dzdY - dzdX * dydY,
62 lnz = dxdX * dydY - dydX * dxdY;
63 const double dp = lnx * nx + lny * ny +
65 return (dp >= 0.) ? iCN : -iCN;
75 inline double calcInvCondNum3D(
double J11,
double J12,
double J13,
double J21,
76 double J22,
double J23,
double J31,
double J32,
79 const double D = calcDet3x3(J11, J12, J13, J21, J22, J23, J31, J32, J33);
80 if(
D == 0.)
return 0.;
81 const double I11 = J22 * J33 - J23 * J32, I12 = J13 * J32 - J12 * J33,
82 I13 = J12 * J23 - J13 * J22, I21 = J23 * J31 - J21 * J33,
83 I22 = J11 * J33 - J13 * J31, I23 = J13 * J21 - J11 * J23,
84 I31 = J21 * J32 - J22 * J31, I32 = J12 * J31 - J11 * J32,
85 I33 = J11 * J22 - J12 * J21;
86 const double nSqJ = J11 * J11 + J12 * J12 + J13 * J13 + J21 * J21 +
87 J22 * J22 + J23 * J23 + J31 * J31 + J32 * J32 +
89 const double nSqDInvJ = I11 * I11 + I12 * I12 + I13 * I13 + I21 * I21 +
90 I22 * I22 + I23 * I23 + I31 * I31 + I32 * I32 +
93 return 3. *
D / sqrt(nSqJ * nSqDInvJ);
95 return 3. * std::fabs(
D) / sqrt(nSqJ * nSqDInvJ);
101 inline void calcGradInvCondNum2D(
double dxdX,
double dxdY,
double dydX,
102 double dydY,
double dzdX,
double dzdY,
103 double nx,
double ny,
double nz,
int i,
109 const double EpsDegen = 1.e-6;
113 const double lnx = dydX * dzdY - dzdX * dydY,
116 lnz = dxdX * dydY - dydX * dxdY;
117 const double dp = lnx * nx + lny * ny +
122 const double dxdXSq = dxdX * dxdX, dydXSq = dydX * dydX,
123 dzdXSq = dzdX * dzdX;
124 const double dxdYSq = dxdY * dxdY, dydYSq = dydY * dydY,
125 dzdYSq = dzdY * dzdY;
126 const double Dx = dxdXSq - dxdYSq, Dy = dydXSq - dydYSq;
127 const double Cx = dxdX * dxdY, Cy = dydX * dydY;
128 const double S1 = dzdYSq * dzdYSq;
129 const double S2 = (dzdXSq - Dy - Dx) * dzdYSq;
130 const double S3 = (Cy + Cx) * dzdX * dzdY;
131 const double S4 = dzdXSq * dzdXSq;
132 const double S5 = (Dy + Dx) * dzdXSq;
133 const double S6 = Cx * Cy;
134 const double S7 = dydXSq * dydXSq;
135 const double S8 = Dy * dydXSq;
136 const double S9 = dxdXSq * dxdXSq;
137 const double S10 = Dx * dxdXSq;
138 const double S11 = Dy * Dy;
139 const double S12 = Dx * Dy;
140 const double S13 = Dx * Dx;
141 const double S = 2. * (S2 + S5 + S12) + 4. * (S7 - S8 + S9 - S10) +
142 8. * (S3 + S6) + S1 + S4 + S11 + S13;
144 for(
int j = 0; j < 3 * numMapNodes; j++) IDI(i, j) = 0.;
145 IDI(i, 3 * numMapNodes) = posJac ? 1. : -1.;
148 const double N = dxdXSq + dxdYSq + dydXSq + dydYSq + dzdXSq + dzdYSq;
149 const double sqrtS = sqrt(
S), invSqrtS = 1. / sqrtS;
150 const double sigma1Sq = 0.5 * (N + sqrtS), sigma2Sq = 0.5 * (N - sqrtS);
152 (sigma2Sq < EpsDegen * sigma1Sq);
153 const double sum = sigma1Sq + sigma2Sq, invSum = 1. / sum;
154 const double prod = sigma1Sq * sigma2Sq;
155 const double sqrtProd = sqrt(prod);
156 const double halfICN = sqrtProd * invSum;
157 IDI(i, 3 * numMapNodes) = posJac ? 2. * halfICN : -2. * halfICN;
160 const double nnXx = dzdX * ny - dydX * nz, nnXy = dxdX * nz - dzdX * nx,
161 nnXz = dydX * nx - dxdX * ny;
162 const double nnYx = dzdY * ny - dydY * nz, nnYy = dxdY * nz - dzdY * nx,
163 nnYz = dydY * nx - dxdY * ny;
164 const double fact = 2. / N;
165 for(
int j = 0; j < numMapNodes; j++) {
166 const double &dPhidX = dSMat_dX(i, j);
167 const double &dPhidY = dSMat_dY(i, j);
168 IDI(i, j) = fact * (dPhidY * nnXx - dPhidX * nnYx);
169 IDI(i, j + numMapNodes) = fact * (dPhidY * nnXy - dPhidX * nnYy);
170 IDI(i, j + 2 * numMapNodes) = fact * (dPhidY * nnXz - dPhidX * nnYz);
175 const double invSqrtProd = 1. / sqrtProd;
177 for(
int j = 0; j < numMapNodes; j++) {
178 const double &dPhidX = dSMat_dX(i, j);
179 const double &dPhidY = dSMat_dY(i, j);
181 const double ddxdXSqdxj = 2. * dPhidX * dxdX,
182 ddxdYSqdxj = 2. * dPhidY * dxdY;
183 const double dDxdxj = ddxdXSqdxj - ddxdYSqdxj;
184 const double dCxdxj = dPhidX * dxdY + dxdX * dPhidY;
185 const double dS2dxj = -dDxdxj * dzdYSq;
186 const double dS3dxj = dCxdxj * dzdX * dzdY;
187 const double dS5dxj = dDxdxj * dzdXSq;
188 const double dS6dxj = dCxdxj * Cy;
189 const double dS9dxj = 2. * ddxdXSqdxj * dxdXSq;
190 const double dS10dxj = dDxdxj * dxdXSq + Dx * ddxdXSqdxj;
191 const double dS12dxj = dDxdxj * Dy;
192 const double dS13dxj = 2. * dDxdxj * Dx;
193 const double dSdxj = 2. * (dS2dxj + dS5dxj + dS12dxj) +
194 4. * (dS9dxj - dS10dxj) + 8. * (dS3dxj + dS6dxj) +
196 const double dNdxj = ddxdXSqdxj + ddxdYSqdxj;
197 const double dsqrtSdxj = 0.5 * dSdxj * invSqrtS;
198 const double dsigma1Sqdxj = 0.5 * (dNdxj + dsqrtSdxj),
199 dsigma2Sqdxj = 0.5 * (dNdxj - dsqrtSdxj);
200 const double dSumdxj = dsigma1Sqdxj + dsigma2Sqdxj;
201 const double dProddxj = dsigma1Sqdxj * sigma2Sq + sigma1Sq * dsigma2Sqdxj;
202 const double diCNdxj =
203 (dProddxj * sum - 2. * prod * dSumdxj) * invSum * invSum * invSqrtProd;
204 IDI(i, j) = posJac ? diCNdxj : -diCNdxj;
206 const double ddydXSqdyj = 2. * dPhidX * dydX,
207 ddydYSqdyj = 2. * dPhidY * dydY;
208 const double dDydyj = ddydXSqdyj - ddydYSqdyj;
209 const double dCydyj = dPhidX * dydY + dydX * dPhidY;
210 const double dS2dyj = -dDydyj * dzdYSq;
211 const double dS3dyj = dCydyj * dzdX * dzdY;
212 const double dS5dyj = dDydyj * dzdXSq;
213 const double dS6dyj = Cx * dCydyj;
214 const double dS7dyj = 2. * ddydXSqdyj * dydXSq;
215 const double dS8dyj = dDydyj * dydXSq + Dy * ddydXSqdyj;
216 const double dS11dyj = 2. * dDydyj * Dy;
217 const double dS12dyj = Dx * dDydyj;
218 const double dSdyj = 2. * (dS2dyj + dS5dyj + dS12dyj) +
219 4. * (dS7dyj - dS8dyj) + 8. * (dS3dyj + dS6dyj) +
221 const double dNdyj = ddydXSqdyj + ddydYSqdyj;
222 const double dsqrtSdyj = 0.5 * dSdyj * invSqrtS;
223 const double dsigma1Sqdyj = 0.5 * (dNdyj + dsqrtSdyj),
224 dsigma2Sqdyj = 0.5 * (dNdyj - dsqrtSdyj);
225 const double dSumdyj = dsigma1Sqdyj + dsigma2Sqdyj;
226 const double dProddyj = dsigma1Sqdyj * sigma2Sq + sigma1Sq * dsigma2Sqdyj;
227 const double diCNdyj =
228 (dProddyj * sum - 2. * prod * dSumdyj) * invSum * invSum * invSqrtProd;
229 IDI(i, j + numMapNodes) = posJac ? diCNdyj : -diCNdyj;
231 const double ddzdXSqdzj = 2. * dPhidX * dzdX,
232 ddzdYSqdzj = 2. * dPhidY * dzdY;
233 const double dS1dzj = 2. * ddzdYSqdzj * dzdYSq;
234 const double dS2dzj = (dzdXSq - Dy - Dx) * ddzdYSqdzj;
235 const double dS3dzj = (Cy + Cx) * (ddzdXSqdzj * dzdY + dzdX * ddzdYSqdzj);
236 const double dS4dzj = 2. * ddzdXSqdzj * dzdXSq;
237 const double dS5dzj = (Dy + Dx) * ddzdXSqdzj;
239 2. * (dS2dzj + dS5dzj) + 8. * dS3dzj + dS1dzj + dS4dzj;
240 const double dNdzj = ddzdXSqdzj + ddzdYSqdzj;
241 const double dsqrtSdzj = 0.5 * dSdzj * invSqrtS;
242 const double dsigma1Sqdzj = 0.5 * (dNdzj + dsqrtSdzj),
243 dsigma2Sqdzj = 0.5 * (dNdzj - dsqrtSdzj);
244 const double dSumdzj = dsigma1Sqdzj + dsigma2Sqdzj;
245 const double dProddzj = dsigma1Sqdzj * sigma2Sq + sigma1Sq * dsigma2Sqdzj;
246 const double diCNdzj =
247 (dProddzj * sum - 2. * prod * dSumdzj) * invSum * invSum * invSqrtProd;
248 IDI(i, j + 2 * numMapNodes) = posJac ? diCNdzj : -diCNdzj;
255 inline void calcGradInvCondNum3D(
256 double dxdX,
double dxdY,
double dxdZ,
double dydX,
double dydY,
257 double dydZ,
double dzdX,
double dzdY,
double dzdZ,
int i,
int numMapNodes,
261 const double normJSq = dxdX * dxdX + dxdY * dxdY + dxdZ * dxdZ +
262 dydX * dydX + dydY * dydY + dydZ * dydZ +
263 dzdX * dzdX + dzdY * dzdY + dzdZ * dzdZ;
264 const double I11 = dydY * dzdZ - dydZ * dzdY,
265 I12 = dxdZ * dzdY - dxdY * dzdZ,
266 I13 = dxdY * dydZ - dxdZ * dydY,
267 I21 = dydZ * dzdX - dydX * dzdZ,
268 I22 = dxdX * dzdZ - dxdZ * dzdX,
269 I23 = dxdZ * dydX - dxdX * dydZ,
270 I31 = dydX * dzdY - dydY * dzdX,
271 I32 = dxdY * dzdX - dxdX * dzdY,
272 I33 = dxdX * dydY - dxdY * dydX;
273 const double normISq = I11 * I11 + I12 * I12 + I13 * I13 + I21 * I21 +
274 I22 * I22 + I23 * I23 + I31 * I31 + I32 * I32 +
276 const double invProd = 1. / (normJSq * normISq),
277 invSqrtProd = sqrt(invProd);
279 calcDet3x3(dxdX, dxdY, dxdZ, dydX, dydY, dydZ, dzdX, dzdY, dzdZ);
280 const bool reverse = (!sign && (
D < 0.));
281 const double sICN = 3. *
D * invSqrtProd;
282 IDI(i, 3 * numMapNodes) = reverse ? -sICN : sICN;
284 for(
int j = 0; j < numMapNodes; j++) {
285 const double &dPhidX = dSMat_dX(i, j);
286 const double &dPhidY = dSMat_dY(i, j);
287 const double &dPhidZ = dSMat_dZ(i, j);
289 const double dNormJSqdxj =
290 2. * (dPhidX * dxdX + dPhidY * dxdY + dPhidZ * dxdZ);
291 const double dNormISqdxj = 2. * ((dPhidZ * dzdY - dPhidY * dzdZ) * I12 +
292 (dPhidY * dydZ - dPhidZ * dydY) * I13 +
293 (dPhidX * dzdZ - dPhidZ * dzdX) * I22 +
294 (dPhidZ * dydX - dPhidX * dydZ) * I23 +
295 (dPhidY * dzdX - dPhidX * dzdY) * I32 +
296 (dPhidX * dydY - dPhidY * dydX) * I33);
297 const double dProddxj = dNormJSqdxj * normISq + dNormISqdxj * normJSq;
298 const double dDdxj = dPhidX * dydY * dzdZ + dzdX * dPhidY * dydZ +
299 dydX * dzdY * dPhidZ - dzdX * dydY * dPhidZ -
300 dPhidX * dzdY * dydZ - dydX * dPhidY * dzdZ;
301 const double dsICNdxj =
302 3. * (dDdxj * invSqrtProd - 0.5 *
D * dProddxj * invProd * invSqrtProd);
303 IDI(i, j) = reverse ? -dsICNdxj : dsICNdxj;
305 const double dNormJSqdyj =
306 2. * (dPhidX * dydX + dPhidY * dydY + dPhidZ * dydZ);
307 const double dNormISqdyj = 2. * ((dPhidY * dzdZ - dPhidZ * dzdY) * I11 +
308 (dxdY * dPhidZ - dxdZ * dPhidY) * I13 +
309 (dPhidZ * dzdX - dPhidX * dzdZ) * I21 +
310 (dxdZ * dPhidX - dxdX * dPhidZ) * I23 +
311 (dPhidX * dzdY - dPhidY * dzdX) * I31 +
312 (dxdX * dPhidY - dxdY * dPhidX) * I33);
313 const double dProddyj = dNormJSqdyj * normISq + dNormISqdyj * normJSq;
314 const double dDdyj = dxdX * dPhidY * dzdZ + dzdX * dxdY * dPhidZ +
315 dPhidX * dzdY * dxdZ - dzdX * dPhidY * dxdZ -
316 dxdX * dzdY * dPhidZ - dPhidX * dxdY * dzdZ;
317 const double dsICNdyj =
318 3. * (dDdyj * invSqrtProd - 0.5 *
D * dProddyj * invProd * invSqrtProd);
319 IDI(i, j + numMapNodes) = reverse ? -dsICNdyj : dsICNdyj;
321 const double dNormJSqdzj =
322 2. * (dPhidX * dzdX + dPhidY * dzdY + dPhidZ * dzdZ);
323 const double dNormISqdzj = 2. * ((dydY * dPhidZ - dydZ * dPhidY) * I11 +
324 (dxdZ * dPhidY - dxdY * dPhidZ) * I12 +
325 (dydZ * dPhidX - dydX * dPhidZ) * I21 +
326 (dxdX * dPhidZ - dxdZ * dPhidX) * I22 +
327 (dydX * dPhidY - dydY * dPhidX) * I31 +
328 (dxdY * dPhidX - dxdX * dPhidY) * I32);
329 const double dProddzj = dNormJSqdzj * normISq + dNormISqdzj * normJSq;
330 const double dDdzj = dxdX * dydY * dPhidZ + dPhidX * dxdY * dydZ +
331 dydX * dPhidY * dxdZ - dPhidX * dydY * dxdZ -
332 dxdX * dPhidY * dydZ - dydX * dxdY * dPhidZ;
333 const double dsICNdzj =
334 3. * (dDdzj * invSqrtProd - 0.5 *
D * dProddzj * invProd * invSqrtProd);
335 IDI(i, j + 2 * numMapNodes) = reverse ? -dsICNdzj : dsICNdzj;
343 _condNumOrder(cnOrder >= 0 ? cnOrder : condNumOrder(tag))
372 double xBar = 0., yBar = 0., zBar = 0.;
373 double barycenter[3] = {0., 0., 0.};
375 for(
int j = 0; j < primMapBasis->
points.
size2(); ++j) {
376 barycenter[j] += primMapBasis->
points(i, j);
384 primMapBasis->
df(xBar, yBar, zBar, barDPsi);
411 case TYPE_TRI:
return (order == 1) ? 0 : order;
413 case TYPE_TET:
return (order == 1) ? 0 : order;
419 Msg::Error(
"Unknown element type %d, return order 0", parentType);
436 for(
int i = 0; i < nCondNumNodes; i++) condNum(i) = 1.;
441 Msg::Warning(
"Inverse condition number not implemented in 1D");
448 dSMat_dX.
mult(nodesXYZ, dxyzdX);
449 dSMat_dY.
mult(nodesXYZ, dxyzdY);
450 for(
int i = 0; i < nCondNumNodes; i++) {
451 const double &dxdX = dxyzdX(i, 0), &dydX = dxyzdX(i, 1),
452 &dzdX = dxyzdX(i, 2);
453 const double &dxdY = dxyzdY(i, 0), &dydY = dxyzdY(i, 1),
454 &dzdY = dxyzdY(i, 2);
455 const double &nx = normals(0, 0), &ny = normals(0, 1),
458 calcInvCondNum2D<sign>(dxdX, dxdY, dydX, dydY, dzdX, dzdY, nx, ny, nz);
465 for(
int i = 0; i < nCondNumNodes; i++) condNum(i) = 1.;
469 dxyzdZ(nCondNumNodes, 3);
470 dSMat_dX.
mult(nodesXYZ, dxyzdX);
471 dSMat_dY.
mult(nodesXYZ, dxyzdY);
472 dSMat_dZ.
mult(nodesXYZ, dxyzdZ);
473 for(
int i = 0; i < nCondNumNodes; i++) {
474 const double &dxdX = dxyzdX(i, 0), &dydX = dxyzdX(i, 1),
475 &dzdX = dxyzdX(i, 2);
476 const double &dxdY = dxyzdY(i, 0), &dydY = dxyzdY(i, 1),
477 &dzdY = dxyzdY(i, 2);
478 const double &dxdZ = dxyzdZ(i, 0), &dydZ = dxyzdZ(i, 1),
479 &dzdZ = dxyzdZ(i, 2);
480 condNum(i) = calcInvCondNum3D<sign>(dxdX, dxdY, dxdZ, dydX, dydY, dydZ,
496 getInvCondNumGeneral<false>(nCondNumNodes, dSMat_dX, dSMat_dY, dSMat_dZ,
497 nodesXYZ, dumNormals, invCond);
506 getInvCondNumGeneral<true>(nCondNumNodes, dSMat_dX, dSMat_dY, dSMat_dZ,
507 nodesXYZ, normals, invCond);
525 for(
int i = 0; i < nCondNumNodes; i++) {
537 Msg::Warning(
"Inverse condition number not implemented in 1D");
544 dSMat_dX.
mult(nodesXYZ, dxyzdX);
545 dSMat_dY.
mult(nodesXYZ, dxyzdY);
546 for(
int i = 0; i < nCondNumNodes; i++) {
547 const double &dxdX = dxyzdX(i, 0), &dydX = dxyzdX(i, 1),
548 &dzdX = dxyzdX(i, 2);
549 const double &dxdY = dxyzdY(i, 0), &dydY = dxyzdY(i, 1),
550 &dzdY = dxyzdY(i, 2);
551 const double &nx = normals(0, 0), &ny = normals(0, 1),
553 calcGradInvCondNum2D<sign>(dxdX, dxdY, dydX, dydY, dzdX, dzdY, nx, ny, nz,
561 for(
int i = 0; i < nCondNumNodes; i++) {
572 dxyzdZ(nCondNumNodes, 3);
573 dSMat_dX.
mult(nodesXYZ, dxyzdX);
574 dSMat_dY.
mult(nodesXYZ, dxyzdY);
575 dSMat_dZ.
mult(nodesXYZ, dxyzdZ);
576 for(
int i = 0; i < nCondNumNodes; i++) {
577 const double &dxdX = dxyzdX(i, 0), &dydX = dxyzdX(i, 1),
578 &dzdX = dxyzdX(i, 2);
579 const double &dxdY = dxyzdY(i, 0), &dydY = dxyzdY(i, 1),
580 &dzdY = dxyzdY(i, 2);
581 const double &dxdZ = dxyzdZ(i, 0), &dydZ = dxyzdZ(i, 1),
582 &dzdZ = dxyzdZ(i, 2);
583 calcGradInvCondNum3D<sign>(dxdX, dxdY, dxdZ, dydX, dydY, dydZ, dzdX, dzdY,
598 getInvCondNumAndGradientsGeneral<false>(nCondNumNodes, dSMat_dX, dSMat_dY,
599 dSMat_dZ, nodesXYZ, dumNormals, IDI);
608 getInvCondNumAndGradientsGeneral<true>(nCondNumNodes, dSMat_dX, dSMat_dY,
609 dSMat_dZ, nodesXYZ, normals, IDI);