gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
CGNSConventions.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 // Contributor(s):
7 // Thomas Toulorge
8 
9 #include <iostream>
10 #include <vector>
11 #include <set>
12 #include <algorithm>
13 #include "SVector3.h"
14 #include "GmshDefines.h"
15 #include "fullMatrix.h"
16 #include "ElementType.h"
17 #include "BasisFactory.h"
18 #include "nodalBasis.h"
19 #include "CGNSCommon.h"
20 #include "CGNSConventions.h"
21 
22 #if defined(HAVE_LIBCGNS)
23 
24 namespace {
25 
26  // ------------- Conversion of node ordering between CGNS and Gmsh
27  // -------------
28 
29  void addEdgePointsCGNS(const SVector3 p0, const SVector3 p1, int order,
30  std::vector<SVector3> &points)
31  {
32  if(order < 2) return;
33 
34  double ds = 1. / order;
35  for(int i = 1; i < order; i++) {
36  double f = ds * i;
37  points.push_back(p0 * (1. - f) + p1 * f);
38  }
39  }
40 
41  std::vector<SVector3> generatePointsTriCGNS(int order, bool complete);
42 
43  void addTriPointsCGNS(const SVector3 p0, const SVector3 p1, const SVector3 p2,
44  int order, std::vector<SVector3> &points)
45  {
46  if(order < 3) return;
47 
48  std::vector<SVector3> triPoints = generatePointsTriCGNS(order - 3, true);
49 
50  double scale = double(order - 3) / double(order);
51  SVector3 offset(1. / order, 1. / order, 0);
52 
53  for(size_t i = 0; i < triPoints.size(); i++) {
54  SVector3 ip = triPoints[i];
55  double u = ip[0] * scale + 1. / order;
56  double v = ip[1] * scale + 1. / order;
57  SVector3 pt = (1. - u - v) * p0 + u * p1 + v * p2;
58  points.push_back(pt);
59  }
60  }
61 
62  void addQuaPointsCGNS(int order, std::vector<SVector3> &points)
63  {
64  if(order > 2) {
65  double scale = double(order - 2) / double(order);
66 
67  SVector3 corner[4] = {SVector3(-1, -1, 0), SVector3(1, -1, 0),
68  SVector3(1, 1, 0), SVector3(-1, 1, 0)};
69 
70  for(int i = 0; i < 4; i++) {
71  SVector3 c1 = corner[i];
72  SVector3 c2 = corner[(i + 1) % 4];
73  double ds = 1. / (order - 2);
74  for(int i = 0; i < order - 2; i++)
75  points.push_back((c1 * (1. - i * ds) + c2 * (i * ds)) * scale);
76  }
77  }
78 
79  if(order == 2 || order == 4) points.push_back(SVector3(0, 0, 0));
80  }
81 
82  void addQuaPointsCGNS(const SVector3 p0, const SVector3 p1, const SVector3 p2,
83  const SVector3 p3, int order,
84  std::vector<SVector3> &points)
85  {
86  std::vector<SVector3> quaPoints;
87 
88  addQuaPointsCGNS(order, quaPoints);
89 
90  for(size_t i = 0; i < quaPoints.size(); i++) {
91  SVector3 ip = quaPoints[i];
92  double u = ip[0];
93  double v = ip[1];
94  SVector3 pt = ((1. - u) * (1. - v) * p0 + (1. + u) * (1. - v) * p1 +
95  (1. + u) * (1. + v) * p2 + (1. - u) * (1. + v) * p3) *
96  0.25;
97  points.push_back(pt);
98  }
99  }
100 
101  // void print(std::vector<SVector3> &points, const char *title, int iStart,
102  // int iEnd = -1)
103  // {
104  // iEnd = iEnd == -1 ? points.size() : iEnd;
105 
106  // std::cout << title << std::endl;
107  // for(int i = iStart; i < iEnd; i++) {
108  // std::cout << i << " :";
109  // for(int d = 0; d < 3; d++) std::cout << " " << points[i][d];
110  // std::cout << std::endl;
111  // }
112  // }
113 
114  std::vector<SVector3> generatePointsEdgeCGNS(int order)
115  {
116  std::vector<SVector3> pp;
117 
118  if(order == 0) {
119  pp.push_back(SVector3(0., 0., 0.));
120  return pp;
121  }
122 
123  // primary vertices
124  pp.push_back(SVector3(-1, 0, 0));
125  pp.push_back(SVector3(1, 0, 0));
126 
127  // internal points
128  addEdgePointsCGNS(pp[0], pp[1], order, pp);
129 
130  return pp;
131  }
132 
133  std::vector<SVector3> generatePointsTriCGNS(int order, bool complete)
134  {
135  std::vector<SVector3> pp;
136 
137  if(order == 0) {
138  pp.push_back(SVector3(1. / 3., 1. / 3., 0.));
139  return pp;
140  }
141 
142  // primary vertices
143  pp.push_back(SVector3(0, 0, 0));
144  pp.push_back(SVector3(1, 0, 0));
145  pp.push_back(SVector3(0, 1, 0));
146 
147  // internal points of edges
148  for(int i = 0; i < 3; i++) {
149  addEdgePointsCGNS(pp[i], pp[(i + 1) % 3], order, pp);
150  }
151 
152  // internal points
153  if(complete && order > 2) {
154  addTriPointsCGNS(pp[0], pp[1], pp[2], order, pp);
155  }
156 
157  return pp;
158  }
159 
160  std::vector<SVector3> generatePointsQuaCGNS(int order, bool complete)
161  {
162  std::vector<SVector3> pp;
163 
164  if(order == 0) {
165  pp.push_back(SVector3(0., 0., 0.));
166  return pp;
167  }
168 
169  // primary vertices
170  pp.push_back(SVector3(-1, -1, 0));
171  pp.push_back(SVector3(1, -1, 0));
172  pp.push_back(SVector3(1, 1, 0));
173  pp.push_back(SVector3(-1, 1, 0));
174 
175  // internal points of edges
176  for(int i = 0; i < 4; i++) {
177  addEdgePointsCGNS(pp[i], pp[(i + 1) % 4], order, pp);
178  }
179 
180  // internal points
181  if(complete && order > 1) {
182  addQuaPointsCGNS(pp[0], pp[1], pp[2], pp[3], order, pp);
183  }
184 
185  return pp;
186  }
187 
188  std::vector<SVector3> generatePointsTetCGNS(int order, bool complete)
189  {
190  std::vector<SVector3> pp;
191 
192  if(order == 0) {
193  pp.push_back(SVector3(1. / 4., 1. / 4., 1. / 4.));
194  return pp;
195  }
196 
197  // primary vertices
198  pp.push_back(SVector3(0, 0, 0));
199  pp.push_back(SVector3(1, 0, 0));
200  pp.push_back(SVector3(0, 1, 0));
201  pp.push_back(SVector3(0, 0, 1));
202 
203  // internal points in edges of base triangle
204  for(int i = 0; i < 3; i++)
205  addEdgePointsCGNS(pp[i], pp[(i + 1) % 3], order, pp);
206 
207  // internal points in upstanding edges
208  for(int i = 0; i < 3; i++) addEdgePointsCGNS(pp[i], pp[3], order, pp);
209 
210  if(complete && order > 2) {
211  // internal points of base triangle
212  addTriPointsCGNS(pp[0], pp[1], pp[2], order, pp);
213 
214  // internal points of upstanding triangles
215  for(int i = 0; i < 3; i++) {
216  addTriPointsCGNS(pp[i], pp[(i + 1) % 3], pp[3], order, pp);
217  }
218 
219  // internal points as a tet of order p-3
220  if(order > 3) {
221  std::vector<SVector3> tetPp = generatePointsTetCGNS(order - 4, true);
222 
223  double scale = (order - 4) / order;
224  SVector3 offset(1. / order, 1. / order, 1. / order);
225  for(size_t i = 0; i < tetPp.size(); i++) {
226  SVector3 volumePoint = tetPp[i];
227  volumePoint *= scale;
228  volumePoint += offset;
229  pp.push_back(volumePoint);
230  }
231  }
232  }
233 
234  return pp;
235  }
236 
237  std::vector<SVector3> generatePointsHexCGNS(int order, bool complete)
238  {
239  std::vector<SVector3> pp;
240 
241  if(order == 0) {
242  pp.push_back(SVector3(0., 0., 0.));
243  return pp;
244  }
245 
246  // principal vertices
247  pp.push_back(SVector3(-1, -1, -1));
248  pp.push_back(SVector3(1, -1, -1));
249  pp.push_back(SVector3(1, 1, -1));
250  pp.push_back(SVector3(-1, 1, -1));
251  pp.push_back(SVector3(-1, -1, 1));
252  pp.push_back(SVector3(1, -1, 1));
253  pp.push_back(SVector3(1, 1, 1));
254  pp.push_back(SVector3(-1, 1, 1));
255 
256  // internal points of base quadrangle edges
257  for(int i = 0; i < 4; i++)
258  addEdgePointsCGNS(pp[i], pp[(i + 1) % 4], order, pp);
259 
260  std::vector<SVector3> up[4];
261  // internal points of mounting edges
262  for(int i = 0; i < 4; i++) {
263  addEdgePointsCGNS(pp[i], pp[i + 4], order, up[i]);
264  pp.insert(pp.end(), up[i].begin(), up[i].end());
265  }
266 
267  // internal points of top quadrangle edges
268  for(int i = 0; i < 4; i++)
269  addEdgePointsCGNS(pp[i + 4], pp[(i + 1) % 4 + 4], order, pp);
270 
271  if(complete && order > 1) {
272  // internal points of base quadrangle
273  addQuaPointsCGNS(pp[0], pp[1], pp[2], pp[3], order, pp);
274 
275  // internal points of upstanding faces
276  for(int i = 0; i < 4; i++) {
277  addQuaPointsCGNS(pp[i], pp[(i + 1) % 4], pp[(i + 1) % 4 + 4], pp[i + 4],
278  order, pp);
279  }
280 
281  // internal points of top quadrangle
282  addQuaPointsCGNS(pp[4], pp[5], pp[6], pp[7], order, pp);
283 
284  // internal volume points as a succession of internal planes
285  for(int i = 0; i <= order - 2; i++) {
286  addQuaPointsCGNS(up[0][i], up[1][i], up[2][i], up[3][i], order, pp);
287  }
288  }
289 
290  return pp;
291  }
292 
293  std::vector<SVector3> generatePointsPriCGNS(int order, bool complete)
294  {
295  std::vector<SVector3> pp;
296 
297  if(order == 0) {
298  pp.push_back(SVector3(1. / 3., 1. / 3., 0.));
299  return pp;
300  }
301 
302  // principal vertices
303  pp.push_back(SVector3(0, 0, -1));
304  pp.push_back(SVector3(1, 0, -1));
305  pp.push_back(SVector3(0, 1, -1));
306  pp.push_back(SVector3(0, 0, 1));
307  pp.push_back(SVector3(1, 0, 1));
308  pp.push_back(SVector3(0, 1, 1));
309 
310  // internal points in edges of base triangle
311  for(int i = 0; i < 3; i++)
312  addEdgePointsCGNS(pp[i], pp[(i + 1) % 3], order, pp);
313 
314  // internal points in upstanding edges
315  std::vector<SVector3> edge[3]; // keep for definition of volume pp
316  for(int i = 0; i < 3; i++) {
317  addEdgePointsCGNS(pp[i], pp[i + 3], order, edge[i]);
318  pp.insert(pp.end(), edge[i].begin(), edge[i].end());
319  }
320 
321  // internal points in edges of top triangle
322  for(int i = 0; i < 3; i++)
323  addEdgePointsCGNS(pp[i + 3], pp[(i + 1) % 3 + 3], order, pp);
324 
325  if(complete) {
326  // internal vertices for base triangle
327  addTriPointsCGNS(pp[0], pp[1], pp[2], order, pp);
328 
329  // internal vertices for upstanding quadrilaterals
330  for(int i = 0; i < 3; i++) {
331  addQuaPointsCGNS(pp[i], pp[(i + 1) % 3], pp[(i + 1) % 3 + 3], pp[i + 3],
332  order, pp);
333  }
334 
335  // internal points for top triangle
336  addTriPointsCGNS(pp[3], pp[4], pp[5], order, pp);
337 
338  // internal points in the volume as a succession of "triangles"
339  for(int o = 0; o < order - 1; o++) {
340  addTriPointsCGNS(edge[0][o], edge[1][o], edge[2][o], order, pp);
341  }
342  }
343 
344  return pp;
345  }
346 
347  // WARNING: incomplete pyramid order 2 is wrong
348  std::vector<SVector3> generatePointsPyrCGNS(int order, bool complete)
349  {
350  std::vector<SVector3> pp;
351 
352  if(order == 0) {
353  pp.push_back(SVector3(0., 0., 0.));
354  return pp;
355  }
356 
357  // principal vertices
358  pp.push_back(SVector3(-1, -1, 0));
359  pp.push_back(SVector3(1, -1, 0));
360  pp.push_back(SVector3(1, 1, 0));
361  pp.push_back(SVector3(-1, 1, 0));
362  pp.push_back(SVector3(0, 0, 1));
363 
364  // internal points in edges of base quadrilateral
365  for(int i = 0; i < 4; i++)
366  addEdgePointsCGNS(pp[i], pp[(i + 1) % 4], order, pp);
367 
368  // internal points in upstanding edges
369  for(int i = 0; i < 4; i++) addEdgePointsCGNS(pp[i], pp[4], order, pp);
370 
371  // internal points in base quadrilateral
372  addQuaPointsCGNS(pp[0], pp[1], pp[2], pp[3], order, pp);
373 
374  // internal points in upstanding triangles
375  for(int i = 0; i < 4; i++)
376  addTriPointsCGNS(pp[i], pp[(i + 1) % 4], pp[4], order, pp);
377 
378  // internal points as an internal pyramid of order p-3
379  if(order > 2) {
380  std::vector<SVector3> pyr = generatePointsPyrCGNS(order - 3, true);
381  SVector3 offset(0, 0, 1. / order);
382  double scale = double(order - 3) / double(order);
383  for(size_t i = 0; i < pyr.size(); ++i)
384  pp.push_back((pyr[i] * scale) + offset);
385  }
386 
387  return pp;
388  }
389 
390  fullMatrix<double> generatePointsCGNS(int parentType, int order,
391  bool complete)
392  {
393  std::vector<SVector3> pts;
394 
395  switch(parentType) {
396  case TYPE_LIN: pts = generatePointsEdgeCGNS(order); break;
397  case TYPE_TRI: pts = generatePointsTriCGNS(order, complete); break;
398  case TYPE_QUA: pts = generatePointsQuaCGNS(order, complete); break;
399  case TYPE_TET: pts = generatePointsTetCGNS(order, complete); break;
400  case TYPE_HEX: pts = generatePointsHexCGNS(order, complete); break;
401  case TYPE_PRI: pts = generatePointsPriCGNS(order, complete); break;
402  case TYPE_PYR: pts = generatePointsPyrCGNS(order, complete); break;
403  default:
404  Msg::Error("CGNS element %s of order %i not yet implemented",
405  ElementType::nameOfParentType(parentType).c_str(),
406  order);
407  }
408 
409  size_t dim = 0;
410  switch(parentType) {
411  case TYPE_PNT: dim = 3; break;
412  case TYPE_LIN: dim = 1; break;
413  case TYPE_TRI:
414  case TYPE_QUA: dim = 2; break;
415  case TYPE_TET:
416  case TYPE_HEX:
417  case TYPE_PRI:
418  case TYPE_PYR: dim = 3; break;
419  }
420 
421  fullMatrix<double> ptsCGNS(pts.size(), dim);
422  for(size_t i = 0; i < pts.size(); i++) {
423  for(size_t d = 0; d < dim; d++) ptsCGNS(i, d) = pts[i][d];
424  }
425 
426  return ptsCGNS;
427  }
428 
429  std::vector<int> cgns2MshNodeIndexInit(int mshTag)
430  {
431  const nodalBasis *nb = BasisFactory::getNodalBasis(mshTag);
432  const int nNode = nb->points.size1();
433 
434  std::vector<int> nodes(nNode);
435 
436  switch(mshTag) {
437  case MSH_PNT:
438  case MSH_LIN_2:
439  case MSH_TRI_3:
440  case MSH_QUA_4:
441  case MSH_TET_4:
442  case MSH_HEX_8:
443  case MSH_PRI_6:
444  case MSH_PYR_5: // linear elements: same ordering between Gmsh and CGNS
445  for(int i = 0; i < nNode; i++) nodes[i] = i;
446  break;
447  default: // high-order elements: get reordering by comparing points
448  int parent = ElementType::getParentType(mshTag);
449  int order = ElementType::getOrder(mshTag);
450  bool complete = (ElementType::getSerendipity(mshTag) <= 1);
451  fullMatrix<double> ptsCGNS = generatePointsCGNS(parent, order, complete);
452  const bool reorderOK = computeReordering(ptsCGNS, nb->points, nodes);
453  if(!reorderOK) {
454  Msg::Error("Could not compute reordering between Gmsh and CGNS element "
455  "nodes for MSH type %i", mshTag);
456  }
457  break;
458  }
459 
460  return nodes;
461  }
462 
463  // ------------- Conversion of element types between CGNS and Gmsh
464  // -------------
465 
466  std::vector<CGNS_ENUMT(ElementType_t)> msh2CgnsEltTypeInit()
467  {
468  std::vector<CGNS_ENUMT(ElementType_t)> cgnsType(
469  MSH_MAX_NUM + 1, CGNS_ENUMV(ElementTypeNull));
470 
471  // All orders
472  cgnsType[MSH_PNT] = CGNS_ENUMV(NODE);
473 
474  // Linear elements
475  cgnsType[MSH_LIN_2] = CGNS_ENUMV(BAR_2);
476  cgnsType[MSH_TRI_3] = CGNS_ENUMV(TRI_3);
477  cgnsType[MSH_QUA_4] = CGNS_ENUMV(QUAD_4);
478  cgnsType[MSH_TET_4] = CGNS_ENUMV(TETRA_4);
479  cgnsType[MSH_PYR_5] = CGNS_ENUMV(PYRA_5);
480  cgnsType[MSH_PRI_6] = CGNS_ENUMV(PENTA_6);
481  cgnsType[MSH_HEX_8] = CGNS_ENUMV(HEXA_8);
482 
483  // Quadratic elements
484  cgnsType[MSH_LIN_3] = CGNS_ENUMV(BAR_3);
485  cgnsType[MSH_TRI_6] = CGNS_ENUMV(TRI_6);
486  cgnsType[MSH_QUA_8] = CGNS_ENUMV(QUAD_8);
487  cgnsType[MSH_QUA_9] = CGNS_ENUMV(QUAD_9);
488  cgnsType[MSH_TET_10] = CGNS_ENUMV(TETRA_10);
489  cgnsType[MSH_PYR_13] = CGNS_ENUMV(PYRA_13);
490  cgnsType[MSH_PYR_14] = CGNS_ENUMV(PYRA_14);
491  cgnsType[MSH_PRI_15] = CGNS_ENUMV(PENTA_15);
492  cgnsType[MSH_PRI_18] = CGNS_ENUMV(PENTA_18);
493  cgnsType[MSH_HEX_20] = CGNS_ENUMV(HEXA_20);
494  cgnsType[MSH_HEX_27] = CGNS_ENUMV(HEXA_27);
495 
496  // Cubic elements
497  cgnsType[MSH_LIN_4] = CGNS_ENUMV(BAR_4);
498  cgnsType[MSH_TRI_9] = CGNS_ENUMV(TRI_9);
499  cgnsType[MSH_TRI_10] = CGNS_ENUMV(TRI_10);
500  cgnsType[MSH_QUA_12] = CGNS_ENUMV(QUAD_12);
501  cgnsType[MSH_QUA_16] = CGNS_ENUMV(QUAD_16);
502  cgnsType[MSH_TET_16] = CGNS_ENUMV(TETRA_16);
503  cgnsType[MSH_TET_20] = CGNS_ENUMV(TETRA_20);
504  cgnsType[MSH_PYR_21] = CGNS_ENUMV(PYRA_21);
505  cgnsType[MSH_PYR_29] = CGNS_ENUMV(PYRA_29);
506  cgnsType[MSH_PYR_30] = CGNS_ENUMV(PYRA_30);
507  cgnsType[MSH_PRI_24] = CGNS_ENUMV(PENTA_24);
508  // cgnsType[MSH_PRI_38] = CGNS_ENUMV(PENTA_38);
509  cgnsType[MSH_PRI_40] = CGNS_ENUMV(PENTA_40);
510  cgnsType[MSH_HEX_32] = CGNS_ENUMV(HEXA_32);
511  cgnsType[MSH_HEX_56] = CGNS_ENUMV(HEXA_56);
512  cgnsType[MSH_HEX_64] = CGNS_ENUMV(HEXA_64);
513 
514  // Quartic elements
515  cgnsType[MSH_LIN_5] = CGNS_ENUMV(BAR_5);
516  cgnsType[MSH_TRI_12] = CGNS_ENUMV(TRI_12);
517  cgnsType[MSH_TRI_15] = CGNS_ENUMV(TRI_15);
518  cgnsType[MSH_QUA_16] = CGNS_ENUMV(QUAD_16);
519  cgnsType[MSH_QUA_25] = CGNS_ENUMV(QUAD_25);
520  cgnsType[MSH_TET_22] = CGNS_ENUMV(TETRA_22);
521  cgnsType[MSH_TET_34] = CGNS_ENUMV(TETRA_34);
522  cgnsType[MSH_TET_35] = CGNS_ENUMV(TETRA_35);
523  cgnsType[MSH_PYR_29] = CGNS_ENUMV(PYRA_29);
524  // cgnsType[MSH_PYR_50] = CGNS_ENUMV(PYRA_50);
525  cgnsType[MSH_PYR_55] = CGNS_ENUMV(PYRA_55);
526  cgnsType[MSH_PRI_33] = CGNS_ENUMV(PENTA_33);
527  // cgnsType[MSH_PRI_66] = CGNS_ENUMV(PENTA_66);
528  cgnsType[MSH_PRI_75] = CGNS_ENUMV(PENTA_75);
529  cgnsType[MSH_HEX_44] = CGNS_ENUMV(HEXA_44);
530  // cgnsType[MSH_HEX_98] = CGNS_ENUMV(HEXA_98);
531  cgnsType[MSH_HEX_125] = CGNS_ENUMV(HEXA_125);
532 
533  return cgnsType;
534  }
535 
536  std::vector<int> cgns2MshEltTypeInit()
537  {
538  std::vector<int> mshType(NofValidElementTypes, 0);
539 
540  // All orders
541  mshType[CGNS_ENUMV(NODE)] = MSH_PNT;
542 
543  // Linear elements
544  mshType[CGNS_ENUMV(BAR_2)] = MSH_LIN_2;
545  mshType[CGNS_ENUMV(TRI_3)] = MSH_TRI_3;
546  mshType[CGNS_ENUMV(QUAD_4)] = MSH_QUA_4;
547  mshType[CGNS_ENUMV(TETRA_4)] = MSH_TET_4;
548  mshType[CGNS_ENUMV(PYRA_5)] = MSH_PYR_5;
549  mshType[CGNS_ENUMV(PENTA_6)] = MSH_PRI_6;
550  mshType[CGNS_ENUMV(HEXA_8)] = MSH_HEX_8;
551 
552  // Quadratic elements
553  mshType[CGNS_ENUMV(BAR_3)] = MSH_LIN_3;
554  mshType[CGNS_ENUMV(TRI_6)] = MSH_TRI_6;
555  mshType[CGNS_ENUMV(QUAD_8)] = MSH_QUA_8;
556  mshType[CGNS_ENUMV(QUAD_9)] = MSH_QUA_9;
557  mshType[CGNS_ENUMV(TETRA_10)] = MSH_TET_10;
558  mshType[CGNS_ENUMV(PYRA_13)] = MSH_PYR_13;
559  mshType[CGNS_ENUMV(PYRA_14)] = MSH_PYR_14;
560  mshType[CGNS_ENUMV(PENTA_15)] = MSH_PRI_15;
561  mshType[CGNS_ENUMV(PENTA_18)] = MSH_PRI_18;
562  mshType[CGNS_ENUMV(HEXA_20)] = MSH_HEX_20;
563  mshType[CGNS_ENUMV(HEXA_27)] = MSH_HEX_27;
564 
565  // Cubic elements
566  mshType[CGNS_ENUMV(BAR_4)] = MSH_LIN_4;
567  mshType[CGNS_ENUMV(TRI_9)] = MSH_TRI_9;
568  mshType[CGNS_ENUMV(TRI_10)] = MSH_TRI_10;
569  mshType[CGNS_ENUMV(QUAD_12)] = MSH_QUA_12;
570  mshType[CGNS_ENUMV(QUAD_16)] = MSH_QUA_16;
571  mshType[CGNS_ENUMV(TETRA_16)] = MSH_TET_16;
572  mshType[CGNS_ENUMV(TETRA_20)] = MSH_TET_20;
573  mshType[CGNS_ENUMV(PYRA_21)] = MSH_PYR_21;
574  mshType[CGNS_ENUMV(PYRA_29)] = MSH_PYR_29;
575  mshType[CGNS_ENUMV(PYRA_30)] = MSH_PYR_30;
576  mshType[CGNS_ENUMV(PENTA_24)] = MSH_PRI_24;
577  // mshType[CGNS_ENUMV(PENTA_38)] = MSH_PRI_38;
578  mshType[CGNS_ENUMV(PENTA_40)] = MSH_PRI_40;
579  mshType[CGNS_ENUMV(HEXA_32)] = MSH_HEX_32;
580  mshType[CGNS_ENUMV(HEXA_56)] = MSH_HEX_56;
581  mshType[CGNS_ENUMV(HEXA_64)] = MSH_HEX_64;
582 
583  // Quartic elements
584  mshType[CGNS_ENUMV(BAR_5)] = MSH_LIN_5;
585  mshType[CGNS_ENUMV(TRI_12)] = MSH_TRI_12;
586  mshType[CGNS_ENUMV(TRI_15)] = MSH_TRI_15;
587  mshType[CGNS_ENUMV(QUAD_16)] = MSH_QUA_16;
588  mshType[CGNS_ENUMV(QUAD_25)] = MSH_QUA_25;
589  mshType[CGNS_ENUMV(TETRA_22)] = MSH_TET_22;
590  mshType[CGNS_ENUMV(TETRA_34)] = MSH_TET_34;
591  mshType[CGNS_ENUMV(TETRA_35)] = MSH_TET_35;
592  mshType[CGNS_ENUMV(PYRA_29)] = MSH_PYR_29;
593  // mshType[CGNS_ENUMV(PYRA_50)] = MSH_PYR_50;
594  mshType[CGNS_ENUMV(PYRA_55)] = MSH_PYR_55;
595  mshType[CGNS_ENUMV(PENTA_33)] = MSH_PRI_33;
596  // mshType[CGNS_ENUMV(PENTA_66)] = MSH_PRI_66;
597  mshType[CGNS_ENUMV(PENTA_75)] = MSH_PRI_75;
598  mshType[CGNS_ENUMV(HEXA_44)] = MSH_HEX_44;
599  // mshType[CGNS_ENUMV(HEXA_98)] = MSH_HEX_98;
600  mshType[CGNS_ENUMV(HEXA_125)] = MSH_HEX_125;
601 
602  return mshType;
603  }
604 
605 } // namespace
606 
607 // msh to CGNS element type
608 CGNS_ENUMT(ElementType_t) msh2CgnsEltType(int mshTag)
609 {
610  static std::vector<CGNS_ENUMT(ElementType_t)> cgnsType =
611  msh2CgnsEltTypeInit();
612 
613  if(mshTag >= static_cast<int>(cgnsType.size()))
614  return CGNS_ENUMV(ElementTypeNull);
615  return cgnsType[mshTag];
616 }
617 
618 // CGNS to msh element type
619 int cgns2MshEltType(CGNS_ENUMT(ElementType_t) cgnsType)
620 {
621  static std::vector<int> mshType = cgns2MshEltTypeInit();
622 
623  if(cgnsType >= static_cast<int>(mshType.size())) return 0;
624  return mshType[cgnsType];
625 }
626 
627 // CGNS to msh node ordering
628 std::vector<int> &cgns2MshNodeIndex(int mshTag)
629 {
630  static std::vector<std::vector<int> > mshInd(MSH_MAX_NUM + 1);
631  static std::vector<int> dumInd;
632 
633  if(mshTag > MSH_MAX_NUM) return dumInd;
634 
635  if(mshInd[mshTag].size() == 0) {
636  mshInd[mshTag] = cgns2MshNodeIndexInit(mshTag);
637  }
638 
639  return mshInd[mshTag];
640 }
641 
642 // // msh to CGNS node ordering
643 // std::vector<int> &msh2CgnsNodeIndex(int mshTag)
644 // {
645 // static std::vector<std::vector<int> > cgnsInd(MSH_MAX_NUM+1);
646 // static std::vector<int> dumInd;
647 
648 // if(mshTag > MSH_MAX_NUM) return dumInd;
649 
650 // if(cgnsInd[mshTag].size() == 0) {
651 // std::vector<int> &mshInd = cgns2MshNodeIndex(mshTag);
652 // std::vector<int> &ind = cgnsInd[mshTag];
653 // for(int iV = 0; iV < mshInd.size(); iV++) ind[mshInd[iV]] = iV;
654 // }
655 
656 // return cgnsInd[mshTag];
657 // }
658 
659 void msh2CgnsReferenceElement(int mshType, const fullMatrix<double> &mshPts,
660  std::vector<double> &u, std::vector<double> &v,
661  std::vector<double> &w)
662 {
663  int parentType = ElementType::getParentType(mshType);
664 
665  switch(parentType) {
666  case TYPE_PNT: u[0] = mshPts(0, 0); break;
667  case TYPE_LIN: // Gmsh and CGNS both in [-1, 1]
668  for(int i = 0; i < mshPts.size1(); i++) { u[i] = mshPts(i, 0); }
669  break;
670  case TYPE_QUA: // Gmsh and CGNS both in [-1, 1]
671  for(int i = 0; i < mshPts.size1(); i++) {
672  u[i] = mshPts(i, 0);
673  v[i] = mshPts(i, 1);
674  }
675  break;
676  case TYPE_HEX: // Gmsh and CGNS both in [-1, 1]
677  for(int i = 0; i < mshPts.size1(); i++) {
678  u[i] = mshPts(i, 0);
679  v[i] = mshPts(i, 1);
680  w[i] = mshPts(i, 2);
681  }
682  break;
683  case TYPE_TRI: // Gmsh in [0, 1], CGNS in [-1, 1]
684  for(int i = 0; i < mshPts.size1(); i++) {
685  u[i] = 2. * mshPts(i, 0) - 1.;
686  v[i] = 2. * mshPts(i, 1) - 1.;
687  }
688  break;
689  case TYPE_TET: // Gmsh in [0, 1], CGNS in [-1, 1]
690  for(int i = 0; i < mshPts.size1(); i++) {
691  u[i] = 2. * mshPts(i, 0) - 1.;
692  v[i] = 2. * mshPts(i, 1) - 1.;
693  w[i] = 2. * mshPts(i, 2) - 1.;
694  }
695  break;
696  case TYPE_PRI: // uv: Gmsh in [0, 1] and CGNS in [-1, 1], w: both in [-1, 1]
697  for(int i = 0; i < mshPts.size1(); i++) {
698  u[i] = 2. * mshPts(i, 0) - 1.;
699  v[i] = 2. * mshPts(i, 1) - 1.;
700  w[i] = mshPts(i, 2);
701  }
702  break;
703  case TYPE_PYR: // uv: both in [-1, 1], w: Gmsh in [0, 1] and CGNS in [-1, 1]
704  for(int i = 0; i < mshPts.size1(); i++) {
705  u[i] = mshPts(i, 0);
706  v[i] = mshPts(i, 1);
707  w[i] = 2. * mshPts(i, 2) - 1.;
708  }
709  break;
710  default:
711  Msg::Error("CGNS element %s not yet implemented",
712  ElementType::nameOfParentType(parentType).c_str());
713  }
714 }
715 
716 bool computeReordering(fullMatrix<double> src, fullMatrix<double> dest,
717  std::vector<int> &ind)
718 {
719  static const double TOLSQ = 1e-10 * 1e-10;
720 
721  const size_t nNode = src.size1(), dim = src.size2();
722  ind.resize(nNode, -1);
723 
724  // Loop over src and dest nodes and check distance
725  std::set<int> found;
726  for(size_t iSrc = 0; iSrc < nNode; iSrc++) {
727  for(size_t iDest = 0; iDest < nNode; iDest++) {
728  const double xx = src(iSrc, 0) - dest(iDest, 0);
729  const double yy = (dim > 1) ? src(iSrc, 1) - dest(iDest, 1) : 0.;
730  const double zz = (dim > 2) ? src(iSrc, 2) - dest(iDest, 2) : 0.;
731  const double dd = xx * xx + yy * yy + zz * zz;
732  if(dd < TOLSQ) {
733  ind[iSrc] = iDest;
734  found.insert(iDest);
735  break;
736  }
737  }
738  }
739 
740  // Check bijectivity
741  return (found.size() == nNode);
742 }
743 
744 std::string cgnsString(const std::string &s, std::string::size_type maxLength)
745 {
746  std::string s2(s);
747  if(s2.size() > maxLength) s2.resize(maxLength);
748  return s2;
749 }
750 
751 #endif // HAVE_LIBCGNS
MSH_TRI_10
#define MSH_TRI_10
Definition: GmshDefines.h:100
MSH_LIN_2
#define MSH_LIN_2
Definition: GmshDefines.h:80
MSH_HEX_8
#define MSH_HEX_8
Definition: GmshDefines.h:84
MSH_TRI_6
#define MSH_TRI_6
Definition: GmshDefines.h:88
nodalBasis::points
fullMatrix< double > points
Definition: nodalBasis.h:16
ElementType::nameOfParentType
std::string nameOfParentType(int type, bool plural=false)
Definition: ElementType.cpp:882
MSH_PNT
#define MSH_PNT
Definition: GmshDefines.h:94
TYPE_LIN
#define TYPE_LIN
Definition: GmshDefines.h:65
MSH_PRI_15
#define MSH_PRI_15
Definition: GmshDefines.h:97
MSH_PYR_14
#define MSH_PYR_14
Definition: GmshDefines.h:93
MSH_HEX_64
#define MSH_HEX_64
Definition: GmshDefines.h:172
MSH_TET_35
#define MSH_TET_35
Definition: GmshDefines.h:109
MSH_QUA_4
#define MSH_QUA_4
Definition: GmshDefines.h:82
nodalBasis.h
MSH_QUA_16
#define MSH_QUA_16
Definition: GmshDefines.h:115
Msg::Error
static void Error(const char *fmt,...)
Definition: GmshMessage.cpp:482
MSH_LIN_4
#define MSH_LIN_4
Definition: GmshDefines.h:105
LegendrePolynomials::f
void f(int n, double u, double *val)
Definition: orthogonalBasis.cpp:77
MSH_PRI_75
#define MSH_PRI_75
Definition: GmshDefines.h:170
TYPE_PNT
#define TYPE_PNT
Definition: GmshDefines.h:64
ElementType::getSerendipity
int getSerendipity(int type)
Definition: ElementType.cpp:598
SVector3
Definition: SVector3.h:16
TYPE_TRI
#define TYPE_TRI
Definition: GmshDefines.h:66
MSH_TRI_12
#define MSH_TRI_12
Definition: GmshDefines.h:101
SVector3.h
MSH_HEX_32
#define MSH_HEX_32
Definition: GmshDefines.h:180
MSH_HEX_44
#define MSH_HEX_44
Definition: GmshDefines.h:181
MSH_PYR_29
#define MSH_PYR_29
Definition: GmshDefines.h:211
MSH_PYR_5
#define MSH_PYR_5
Definition: GmshDefines.h:86
MSH_HEX_125
#define MSH_HEX_125
Definition: GmshDefines.h:173
MSH_PRI_40
#define MSH_PRI_40
Definition: GmshDefines.h:169
TYPE_PRI
#define TYPE_PRI
Definition: GmshDefines.h:70
MSH_TET_16
#define MSH_TET_16
Definition: GmshDefines.h:223
MSH_TET_22
#define MSH_TET_22
Definition: GmshDefines.h:111
MSH_TRI_3
#define MSH_TRI_3
Definition: GmshDefines.h:81
fullMatrix< double >
BasisFactory::getNodalBasis
static const nodalBasis * getNodalBasis(int tag)
Definition: BasisFactory.cpp:23
MSH_LIN_3
#define MSH_LIN_3
Definition: GmshDefines.h:87
MSH_QUA_8
#define MSH_QUA_8
Definition: GmshDefines.h:95
MSH_HEX_20
#define MSH_HEX_20
Definition: GmshDefines.h:96
GmshDefines.h
MSH_PYR_55
#define MSH_PYR_55
Definition: GmshDefines.h:203
MSH_TET_34
#define MSH_TET_34
Definition: GmshDefines.h:157
MSH_PYR_30
#define MSH_PYR_30
Definition: GmshDefines.h:202
MSH_TET_10
#define MSH_TET_10
Definition: GmshDefines.h:90
MSH_LIN_5
#define MSH_LIN_5
Definition: GmshDefines.h:106
MSH_QUA_25
#define MSH_QUA_25
Definition: GmshDefines.h:116
CGNSConventions.h
MSH_PRI_24
#define MSH_PRI_24
Definition: GmshDefines.h:194
CGNSCommon.h
fullMatrix::size2
int size2() const
Definition: fullMatrix.h:275
MSH_QUA_12
#define MSH_QUA_12
Definition: GmshDefines.h:118
TYPE_PYR
#define TYPE_PYR
Definition: GmshDefines.h:69
MSH_QUA_9
#define MSH_QUA_9
Definition: GmshDefines.h:89
MSH_HEX_56
#define MSH_HEX_56
Definition: GmshDefines.h:182
TYPE_QUA
#define TYPE_QUA
Definition: GmshDefines.h:67
MSH_PRI_18
#define MSH_PRI_18
Definition: GmshDefines.h:92
nodalBasis
Definition: nodalBasis.h:12
MSH_TET_4
#define MSH_TET_4
Definition: GmshDefines.h:83
fullMatrix::size1
int size1() const
Definition: fullMatrix.h:274
MSH_HEX_27
#define MSH_HEX_27
Definition: GmshDefines.h:91
ElementType::getOrder
int getOrder(int type)
Definition: ElementType.cpp:158
MSH_MAX_NUM
#define MSH_MAX_NUM
Definition: GmshDefines.h:227
TYPE_HEX
#define TYPE_HEX
Definition: GmshDefines.h:71
TYPE_TET
#define TYPE_TET
Definition: GmshDefines.h:68
MSH_TET_20
#define MSH_TET_20
Definition: GmshDefines.h:108
MSH_TRI_15
#define MSH_TRI_15
Definition: GmshDefines.h:102
MSH_PYR_13
#define MSH_PYR_13
Definition: GmshDefines.h:98
MSH_PRI_6
#define MSH_PRI_6
Definition: GmshDefines.h:85
MSH_PYR_21
#define MSH_PYR_21
Definition: GmshDefines.h:210
ElementType.h
MSH_TRI_9
#define MSH_TRI_9
Definition: GmshDefines.h:99
c1
const double c1
Definition: GaussQuadratureHex.cpp:16
ElementType::getParentType
int getParentType(int type)
Definition: ElementType.cpp:10
fullMatrix.h
MSH_PRI_33
#define MSH_PRI_33
Definition: GmshDefines.h:195
BasisFactory.h
scale
static void scale(std::vector< double > &x, double s)
Definition: ConjugateGradients.cpp:21