MFEM  v4.6.0
Finite element discretization library
vtk.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010-2023, Lawrence Livermore National Security, LLC. Produced
2 // at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3 // LICENSE and NOTICE for details. LLNL-CODE-806117.
4 //
5 // This file is part of the MFEM library. For more information and source code
6 // availability visit https://mfem.org.
7 //
8 // MFEM is free software; you can redistribute it and/or modify it under the
9 // terms of the BSD-3 license. We welcome feedback and contributions, see file
10 // CONTRIBUTING.md for details.
11 
12 #include "vtk.hpp"
13 #include "../general/binaryio.hpp"
14 #ifdef MFEM_USE_ZLIB
15 #include <zlib.h>
16 #endif
17 
18 namespace mfem
19 {
20 
22 {
23  POINT, SEGMENT, TRIANGLE, SQUARE, TETRAHEDRON, CUBE, PRISM, PYRAMID
24 };
25 
27 {
28  POINT, QUADRATIC_SEGMENT, QUADRATIC_TRIANGLE, BIQUADRATIC_SQUARE,
29  QUADRATIC_TETRAHEDRON, TRIQUADRATIC_CUBE, BIQUADRATIC_QUADRATIC_PRISM,
30  QUADRATIC_PYRAMID
31 };
32 
34 {
35  POINT, LAGRANGE_SEGMENT, LAGRANGE_TRIANGLE, LAGRANGE_SQUARE,
36  LAGRANGE_TETRAHEDRON, LAGRANGE_CUBE, LAGRANGE_PRISM, LAGRANGE_PYRAMID
37 };
38 
39 const int VTKGeometry::PrismMap[6] = {0, 2, 1, 3, 5, 4};
40 
42 {
43  NULL, NULL, NULL, NULL, NULL, NULL, VTKGeometry::PrismMap, NULL
44 };
45 
47 {
48  switch (vtk_geom)
49  {
50  case POINT:
51  return Geometry::POINT;
52  case SEGMENT:
53  case QUADRATIC_SEGMENT:
54  case LAGRANGE_SEGMENT:
55  return Geometry::SEGMENT;
56  case TRIANGLE:
57  case QUADRATIC_TRIANGLE:
58  case LAGRANGE_TRIANGLE:
59  return Geometry::TRIANGLE;
60  case SQUARE:
61  case BIQUADRATIC_SQUARE:
62  case LAGRANGE_SQUARE:
63  return Geometry::SQUARE;
64  case TETRAHEDRON:
67  return Geometry::TETRAHEDRON;
68  case CUBE:
69  case TRIQUADRATIC_CUBE:
70  case LAGRANGE_CUBE:
71  return Geometry::CUBE;
72  case PRISM:
74  case LAGRANGE_PRISM:
75  return Geometry::PRISM;
76  case PYRAMID:
77  case QUADRATIC_PYRAMID:
78  case LAGRANGE_PYRAMID:
79  return Geometry::PYRAMID;
80  default:
81  return Geometry::INVALID;
82  }
83 }
84 
85 bool VTKGeometry::IsLagrange(int vtk_geom)
86 {
87  return vtk_geom >= LAGRANGE_SEGMENT && vtk_geom <= LAGRANGE_PYRAMID;
88 }
89 
90 bool VTKGeometry::IsQuadratic(int vtk_geom)
91 {
92  return vtk_geom >= QUADRATIC_SEGMENT
93  && vtk_geom <= BIQUADRATIC_QUADRATIC_PRISM;
94 }
95 
96 int VTKGeometry::GetOrder(int vtk_geom, int npoints)
97 {
98  if (IsQuadratic(vtk_geom))
99  {
100  return 2;
101  }
102  else if (IsLagrange(vtk_geom))
103  {
104  switch (vtk_geom)
105  {
106  case LAGRANGE_SEGMENT:
107  return npoints - 1;
108  case LAGRANGE_TRIANGLE:
109  return static_cast<int>(std::sqrt(8*npoints + 1) - 3)/2;
110  case LAGRANGE_SQUARE:
111  return static_cast<int>(std::round(std::sqrt(npoints))) - 1;
113  switch (npoints)
114  {
115  // Note that for given order, npoints is given by
116  // npoints_order = (order + 1)*(order + 2)*(order + 3)/6,
117  case 4: return 1;
118  case 10: return 2;
119  case 20: return 3;
120  case 35: return 4;
121  case 56: return 5;
122  case 84: return 6;
123  case 120: return 7;
124  case 165: return 8;
125  case 220: return 9;
126  case 286: return 10;
127  default:
128  {
129  constexpr int max_order = 20;
130  int order = 11, npoints_order;
131  for (; order<max_order; ++order)
132  {
133  npoints_order = (order + 1)*(order + 2)*(order + 3)/6;
134  if (npoints_order == npoints) { break; }
135  }
136  MFEM_VERIFY(npoints == npoints_order, "");
137  return order;
138  }
139  }
140  case LAGRANGE_CUBE:
141  return static_cast<int>(std::round(std::cbrt(npoints))) - 1;
142  case LAGRANGE_PRISM:
143  {
144  const double n = npoints;
145  static const double third = 1.0/3.0;
146  static const double ninth = 1.0/9.0;
147  static const double twentyseventh = 1.0/27.0;
148  const double term =
149  std::cbrt(third*sqrt(third)*sqrt((27.0*n - 2.0)*n) + n
150  - twentyseventh);
151  return static_cast<int>(std::round(term + ninth / term - 4*third));
152  }
153  case LAGRANGE_PYRAMID:
154  MFEM_ABORT("Lagrange pyramids not currently supported in VTK.");
155  return 0;
156  }
157  }
158  return 1;
159 }
160 
161 int BarycentricToVTKTriangle(int *b, int ref)
162 {
163  // Cf. https://git.io/JvW8f
164  int max = ref;
165  int min = 0;
166  int bmin = std::min(std::min(b[0], b[1]), b[2]);
167  int idx = 0;
168 
169  // scope into the correct triangle
170  while (bmin > min)
171  {
172  idx += 3*ref;
173  max -= 2;
174  ++min;
175  ref -= 3;
176  }
177  for (int d=0; d<3; ++d)
178  {
179  if (b[(d+2)%3] == max)
180  {
181  // we are on a vertex
182  return idx;
183  }
184  ++idx;
185  }
186  for (int d=0; d<3; ++d)
187  {
188  if (b[(d+1)%3] == min)
189  {
190  // we are on an edge
191  return idx + b[d] - (min + 1);
192  }
193  idx += max - (min + 1);
194  }
195  return idx;
196 }
197 
198 int BarycentricToVTKTetra(int *b, int ref)
199 {
200  // Cf. https://git.io/JvW8c
201  int idx = 0;
202 
203  int max = ref;
204  int min = 0;
205 
206  int bmin = std::min(std::min(std::min(b[0], b[1]), b[2]), b[3]);
207 
208  // scope into the correct tetra
209  while (bmin > min)
210  {
211  idx += 2*(ref*ref + 1);
212  max -= 3;
213  min++;
214  ref -= 4;
215  }
216 
217  // When a linearized tetra vertex is cast into barycentric coordinates, one of
218  // its coordinates is maximal and the other three are minimal. These are the
219  // indices of the maximal barycentric coordinate for each vertex.
220  static const int VertexMaxCoords[4] = {3,0,1,2};
221  // Each linearized tetra edge holds two barycentric tetra coordinates constant
222  // and varies the other two. These are the coordinates that are held constant
223  // for each edge.
224  static const int EdgeMinCoords[6][2] = {{1,2},{2,3},{0,2}, {0,1},{1,3},{0,3}};
225  // The coordinate that increments when traversing an edge (i.e. the coordinate
226  // of the nonzero component of the second vertex of the edge).
227  static const int EdgeCountingCoord[6] = {0,1,3,2,2,2};
228  // When describing a linearized tetra face, there is a mapping between the
229  // four-component barycentric tetra system and the three-component barycentric
230  // triangle system. These are the constant indices within the four-component
231  // system for each face (e.g. face 0 holds barycentric tetra coordinate 1
232  // constant).
233  static const int FaceMinCoord[4] = {1,3,0,2};
234  // When describing a linearized tetra face, there is a mapping between the
235  // four-component barycentric tetra system and the three-component barycentric
236  // triangle system. These are the relevant indices within the four-component
237  // system for each face (e.g. face 0 varies across the barycentric tetra
238  // coordinates 0, 2 and 3).
239  static const int FaceBCoords[4][3] = {{0,2,3}, {2,0,1}, {2,1,3}, {1,0,3}};
240 
241 
242  for (int vertex = 0; vertex < 4; vertex++)
243  {
244  if (b[VertexMaxCoords[vertex]] == max)
245  {
246  // we are on a vertex
247  return idx;
248  }
249  idx++;
250  }
251 
252  for (int edge = 0; edge < 6; edge++)
253  {
254  if (b[EdgeMinCoords[edge][0]] == min && b[EdgeMinCoords[edge][1]] == min)
255  {
256  // we are on an edge
257  return idx + b[EdgeCountingCoord[edge]] - (min + 1);
258  }
259  idx += max - (min + 1);
260  }
261 
262  for (int face = 0; face < 4; face++)
263  {
264  if (b[FaceMinCoord[face]] == min)
265  {
266  // we are on a face
267  int projectedb[3];
268  for (int i = 0; i < 3; i++)
269  {
270  projectedb[i] = b[FaceBCoords[face][i]] - min;
271  }
272  // we must subtract the indices of the face's vertices and edges, which
273  // total to 3*ref
274  return (idx + BarycentricToVTKTriangle(projectedb, ref) - 3*ref);
275  }
276  idx += (ref+1)*(ref+2)/2 - 3*ref;
277  }
278  return idx;
279 }
280 
281 int VTKTriangleDOFOffset(int ref, int i, int j)
282 {
283  return i + ref*(j - 1) - (j*(j + 1))/2;
284 }
285 
286 int CartesianToVTKPrism(int i, int j, int k, int ref)
287 {
288  // Cf. https://git.io/JvW0M
289  int om1 = ref - 1;
290  int ibdr = (i == 0);
291  int jbdr = (j == 0);
292  int ijbdr = (i + j == ref);
293  int kbdr = (k == 0 || k == ref);
294  // How many boundaries do we lie on at once?
295  int nbdr = ibdr + jbdr + ijbdr + kbdr;
296 
297  // Return an invalid index given invalid coordinates
298  if (i < 0 || i > ref || j < 0 || j > ref || i + j > ref || k < 0 || k > ref)
299  {
300  MFEM_ABORT("Invalid index")
301  }
302 
303  if (nbdr == 3) // Vertex DOF
304  {
305  // ijk is a corner node. Return the proper index (somewhere in [0,5]):
306  return (ibdr && jbdr ? 0 : (jbdr && ijbdr ? 1 : 2)) + (k ? 3 : 0);
307  }
308 
309  int offset = 6;
310  if (nbdr == 2) // Edge DOF
311  {
312  if (!kbdr)
313  {
314  // Must be on a vertical edge and 2 of {ibdr, jbdr, ijbdr} are true
315  offset += om1*6;
316  return offset + (k-1)
317  + ((ibdr && jbdr) ? 0 : (jbdr && ijbdr ? 1 : 2))*om1;
318  }
319  else
320  {
321  // Must be on a horizontal edge and kbdr plus 1 of {ibdr, jbdr, ijbdr} is true
322  // Skip past first 3 edges if we are on the top (k = ref) face:
323  offset += (k == ref ? 3*om1 : 0);
324  if (jbdr)
325  {
326  return offset + i - 1;
327  }
328  offset += om1; // Skip the i-axis edge
329  if (ijbdr)
330  {
331  return offset + j - 1;
332  }
333  offset += om1; // Skip the ij-axis edge
334  // if (ibdr)
335  return offset + (ref - j - 1);
336  }
337  }
338 
339  offset += 9*om1; // Skip all the edges
340 
341  // Number of points on a triangular face (but not on edge/corner):
342  int ntfdof = (om1 - 1)*om1/2;
343  int nqfdof = om1*om1;
344  if (nbdr == 1) // Face DOF
345  {
346  if (kbdr)
347  {
348  // We are on a triangular face.
349  if (k > 0)
350  {
351  offset += ntfdof;
352  }
353  return offset + VTKTriangleDOFOffset(ref, i, j);
354  }
355  // Not a k-normal face, so skip them:
356  offset += 2*ntfdof;
357 
358  // Face is quadrilateral (ref - 1) x (ref - 1)
359  // First face is i-normal, then ij-normal, then j-normal
360  if (jbdr) // On i-normal face
361  {
362  return offset + (i - 1) + om1*(k - 1);
363  }
364  offset += nqfdof; // Skip i-normal face
365  if (ijbdr) // on ij-normal face
366  {
367  return offset + (ref - i - 1) + om1*(k - 1);
368  }
369  offset += nqfdof; // Skip ij-normal face
370  return offset + j - 1 + om1*(k - 1);
371  }
372 
373  // Skip all face DOF
374  offset += 2*ntfdof + 3*nqfdof;
375 
376  // nbdr == 0: Body DOF
377  return offset + VTKTriangleDOFOffset(ref, i, j) + ntfdof*(k - 1);
378  // (i - 1) + (ref-1)*((j - 1) + (ref - 1)*(k - 1)));
379 }
380 
381 int CartesianToVTKTensor(int idx_in, int ref, Geometry::Type geom)
382 {
383  int n = ref + 1;
384  switch (geom)
385  {
386  case Geometry::POINT:
387  return idx_in;
388  case Geometry::SEGMENT:
389  if (idx_in == 0 || idx_in == ref)
390  {
391  return idx_in ? 1 : 0;
392  }
393  return idx_in + 1;
394  case Geometry::SQUARE:
395  {
396  // Cf: https://git.io/JvZLT
397  int i = idx_in % n;
398  int j = idx_in / n;
399  // Do we lie on any of the edges
400  bool ibdr = (i == 0 || i == ref);
401  bool jbdr = (j == 0 || j == ref);
402  if (ibdr && jbdr) // Vertex DOF
403  {
404  return (i ? (j ? 2 : 1) : (j ? 3 : 0));
405  }
406  int offset = 4;
407  if (jbdr) // Edge DOF on j==0 or j==ref
408  {
409  return (i - 1) + (j ? ref - 1 + ref - 1 : 0) + offset;
410  }
411  else if (ibdr) // Edge DOF on i==0 or i==ref
412  {
413  return (j - 1) + (i ? ref - 1 : 2 * (ref - 1) + ref - 1) + offset;
414  }
415  else // Interior DOF
416  {
417  offset += 2 * (ref - 1 + ref - 1);
418  return offset + (i - 1) + (ref - 1) * ((j - 1));
419  }
420  }
421  case Geometry::CUBE:
422  {
423  // Cf: https://git.io/JvZLe
424  int i = idx_in % n;
425  int j = (idx_in / n) % n;
426  int k = idx_in / (n*n);
427  bool ibdr = (i == 0 || i == ref);
428  bool jbdr = (j == 0 || j == ref);
429  bool kbdr = (k == 0 || k == ref);
430  // How many boundaries do we lie on at once?
431  int nbdr = (ibdr ? 1 : 0) + (jbdr ? 1 : 0) + (kbdr ? 1 : 0);
432  if (nbdr == 3) // Vertex DOF
433  {
434  // ijk is a corner node. Return the proper index (in [0,7])
435  return (i ? (j ? 2 : 1) : (j ? 3 : 0)) + (k ? 4 : 0);
436  }
437 
438  int offset = 8;
439  if (nbdr == 2) // Edge DOF
440  {
441  if (!ibdr)
442  {
443  // On i axis
444  return (i - 1) +
445  (j ? ref - 1 + ref - 1 : 0) +
446  (k ? 2*(ref - 1 + ref - 1) : 0) +
447  offset;
448  }
449  if (!jbdr)
450  {
451  // On j axis
452  return (j - 1) +
453  (i ? ref - 1 : 2*(ref - 1) + ref - 1) +
454  (k ? 2*(ref - 1 + ref - 1) : 0) +
455  offset;
456  }
457  // !kbdr, On k axis
458  offset += 4*(ref - 1) + 4*(ref - 1);
459  return (k - 1) + (ref - 1)*(i ? (j ? 3 : 1) : (j ? 2 : 0))
460  + offset;
461  }
462 
463  offset += 4*(ref - 1 + ref - 1 + ref - 1);
464  if (nbdr == 1) // Face DOF
465  {
466  if (ibdr) // On i-normal face
467  {
468  return (j - 1) + ((ref - 1)*(k - 1))
469  + (i ? (ref - 1)*(ref - 1) : 0) + offset;
470  }
471  offset += 2*(ref - 1)*(ref - 1);
472  if (jbdr) // On j-normal face
473  {
474  return (i - 1)
475  + ((ref - 1)*(k - 1))
476  + (j ? (ref - 1)*(ref - 1) : 0) + offset;
477  }
478  offset += 2*(ref - 1)*(ref - 1);
479  // kbdr, On k-normal face
480  return (i - 1) + ((ref - 1)*(j - 1))
481  + (k ? (ref - 1)*(ref - 1) : 0) + offset;
482  }
483 
484  // nbdr == 0: Interior DOF
485  offset += 2*((ref - 1)*(ref - 1) +
486  (ref - 1)*(ref - 1) +
487  (ref - 1)*(ref - 1));
488  return offset + (i - 1) + (ref - 1)*((j - 1) + (ref - 1)*(k - 1));
489  }
490  default:
491  MFEM_ABORT("CartesianToVTKOrderingTensor only supports tensor"
492  " geometries.");
493  return -1;
494  }
495 }
496 
498 {
499 
500  RefinedGeometry *RefG = GlobGeometryRefiner.Refine(geom, ref, 1);
501  int nnodes = RefG->RefPts.GetNPoints();
502  con.SetSize(nnodes);
503  if (geom == Geometry::TRIANGLE)
504  {
505  int b[3];
506  int idx = 0;
507  for (b[1]=0; b[1]<=ref; ++b[1])
508  {
509  for (b[0]=0; b[0]<=ref-b[1]; ++b[0])
510  {
511  b[2] = ref - b[0] - b[1];
512  con[BarycentricToVTKTriangle(b, ref)] = idx++;
513  }
514  }
515  }
516  else if (geom == Geometry::TETRAHEDRON)
517  {
518  int idx = 0;
519  int b[4];
520  for (b[2]=0; b[2]<=ref; b[2]++)
521  {
522  for (b[1]=0; b[1]<=ref-b[2]; b[1]++)
523  {
524  for (b[0]=0; b[0]<=ref-b[1]-b[2]; b[0]++)
525  {
526  b[3] = ref-b[0]-b[1]-b[2];
527  con[BarycentricToVTKTetra(b, ref)] = idx++;
528  }
529  }
530  }
531  }
532  else if (geom == Geometry::PRISM)
533  {
534  int idx = 0;
535  for (int k=0; k<=ref; k++)
536  {
537  for (int j=0; j<=ref; j++)
538  {
539  for (int i=0; i<=ref-j; i++)
540  {
541  con[CartesianToVTKPrism(i, j, k, ref)] = idx++;
542  }
543  }
544  }
545  }
546  else if (geom == Geometry::PYRAMID)
547  {
548  MFEM_ABORT("Lagrange pyramid elements not currently supported in VTK.");
549  }
550  else
551  {
552  for (int idx=0; idx<nnodes; ++idx)
553  {
554  con[CartesianToVTKTensor(idx, ref, geom)] = idx;
555  }
556  }
557 }
558 
559 void WriteVTKEncodedCompressed(std::ostream &os, const void *bytes,
560  uint32_t nbytes, int compression_level)
561 {
562  if (compression_level == 0)
563  {
564  // First write size of buffer (as uint32_t), encoded with base 64
565  bin_io::WriteBase64(os, &nbytes, sizeof(nbytes));
566  // Then write all the bytes in the buffer, encoded with base 64
567  bin_io::WriteBase64(os, bytes, nbytes);
568  }
569  else
570  {
571 #ifdef MFEM_USE_ZLIB
572  MFEM_ASSERT(compression_level >= -1 && compression_level <= 9,
573  "Compression level must be between -1 and 9 (inclusive).");
574  uLongf buf_sz = compressBound(nbytes);
575  std::vector<unsigned char> buf(buf_sz);
576  compress2(buf.data(), &buf_sz, static_cast<const Bytef *>(bytes), nbytes,
577  compression_level);
578 
579  // Write the header
580  std::vector<uint32_t> header(4);
581  header[0] = 1; // number of blocks
582  header[1] = nbytes; // uncompressed size
583  header[2] = 0; // size of partial block
584  header[3] = buf_sz; // compressed size
585  bin_io::WriteBase64(os, header.data(), header.size()*sizeof(uint32_t));
586  // Write the compressed data
587  bin_io::WriteBase64(os, buf.data(), buf_sz);
588 #else
589  MFEM_ABORT("MFEM must be compiled with ZLib support to output "
590  "compressed binary data.")
591 #endif
592  }
593 }
594 
596 {
597  int16_t x16 = 1;
598  int8_t *x8 = reinterpret_cast<int8_t *>(&x16);
599  return !*x8;
600 }
601 
602 const char *VTKByteOrder()
603 {
604  if (IsBigEndian())
605  {
606  return "BigEndian";
607  }
608  else
609  {
610  return "LittleEndian";
611  }
612 
613 }
614 
615 // Ensure ASCII output of uint8_t to stream is integer rather than character
616 template <>
617 void WriteBinaryOrASCII<uint8_t>(std::ostream &os, std::vector<char> &buf,
618  const uint8_t &val, const char *suffix,
619  VTKFormat format)
620 {
621  if (format == VTKFormat::ASCII) { os << static_cast<int>(val) << suffix; }
622  else { bin_io::AppendBytes(buf, val); }
623 }
624 
625 template <>
626 void WriteBinaryOrASCII<double>(std::ostream &os, std::vector<char> &buf,
627  const double &val, const char *suffix,
628  VTKFormat format)
629 {
630  if (format == VTKFormat::BINARY32)
631  {
632  bin_io::AppendBytes<float>(buf, float(val));
633  }
634  else if (format == VTKFormat::BINARY)
635  {
636  bin_io::AppendBytes(buf, val);
637  }
638  else
639  {
640  os << ZeroSubnormal(val) << suffix;
641  }
642 }
643 
644 template <>
645 void WriteBinaryOrASCII<float>(std::ostream &os, std::vector<char> &buf,
646  const float &val, const char *suffix,
647  VTKFormat format)
648 {
649  if (format == VTKFormat::BINARY) { bin_io::AppendBytes<double>(buf, val); }
650  else if (format == VTKFormat::BINARY32) { bin_io::AppendBytes(buf, val); }
651  else { os << ZeroSubnormal(val) << suffix; }
652 }
653 
654 void WriteBase64WithSizeAndClear(std::ostream &os, std::vector<char> &buf,
655  int compression_level)
656 {
657  WriteVTKEncodedCompressed(os, buf.data(), buf.size(), compression_level);
658  os << '\n';
659  buf.clear();
660 }
661 
662 } // namespace mfem
static const int BIQUADRATIC_SQUARE
Definition: vtk.hpp:49
int CartesianToVTKPrism(int i, int j, int k, int ref)
Definition: vtk.cpp:286
int GetNPoints() const
Returns the number of the points in the integration rule.
Definition: intrules.hpp:253
static const int HighOrderMap[Geometry::NUM_GEOMETRIES]
Map from MFEM&#39;s Geometry::Type to arbitrary-order Lagrange VTK geometries.
Definition: vtk.hpp:82
static const int QUADRATIC_TETRAHEDRON
Definition: vtk.hpp:50
Data arrays will be written in ASCII format.
bool IsBigEndian()
Definition: vtk.cpp:595
static const int SQUARE
Definition: vtk.hpp:38
static const int QUADRATIC_PYRAMID
Definition: vtk.hpp:54
T ZeroSubnormal(T val)
Definition: vector.hpp:481
static bool IsLagrange(int vtk_geom)
Does the given VTK geometry type describe an arbitrary-order Lagrange element?
Definition: vtk.cpp:85
void WriteBinaryOrASCII< uint8_t >(std::ostream &os, std::vector< char > &buf, const uint8_t &val, const char *suffix, VTKFormat format)
Specialization of WriteBinaryOrASCII for uint8_t to ensure ASCII output is numeric (rather than inter...
Definition: vtk.cpp:617
void WriteBinaryOrASCII< float >(std::ostream &os, std::vector< char > &buf, const float &val, const char *suffix, VTKFormat format)
Specialization of WriteBinaryOrASCII<T> for float.
Definition: vtk.cpp:645
int BarycentricToVTKTetra(int *b, int ref)
Definition: vtk.cpp:198
static const int LAGRANGE_CUBE
Definition: vtk.hpp:63
static const int CUBE
Definition: vtk.hpp:40
GeometryRefiner GlobGeometryRefiner
Definition: geom.cpp:1773
static const int PRISM
Definition: vtk.hpp:41
int VTKTriangleDOFOffset(int ref, int i, int j)
Definition: vtk.cpp:281
static const int QUADRATIC_TRIANGLE
Definition: vtk.hpp:48
int BarycentricToVTKTriangle(int *b, int ref)
Return the VTK node index of the barycentric point b in a triangle with refinement level ref...
Definition: vtk.cpp:161
static const int TRIQUADRATIC_CUBE
Definition: vtk.hpp:51
double b
Definition: lissajous.cpp:42
void WriteBase64(std::ostream &out, const void *bytes, size_t nbytes)
Given a buffer bytes of length nbytes, encode the data in base-64 format, and write the encoded data ...
Definition: binaryio.cpp:25
static const int Map[Geometry::NUM_GEOMETRIES]
Map from MFEM&#39;s Geometry::Type to linear VTK geometries.
Definition: vtk.hpp:78
static const int LAGRANGE_SEGMENT
Definition: vtk.hpp:59
VTKFormat
Data array format for VTK and VTU files.
Definition: vtk.hpp:98
static const int LAGRANGE_SQUARE
Definition: vtk.hpp:61
void WriteBinaryOrASCII< double >(std::ostream &os, std::vector< char > &buf, const double &val, const char *suffix, VTKFormat format)
Specialization of WriteBinaryOrASCII for double.
Definition: vtk.cpp:626
IntegrationRule RefPts
Definition: geom.hpp:314
RefinedGeometry * Refine(Geometry::Type Geom, int Times, int ETimes=1)
Definition: geom.cpp:1099
static const int BIQUADRATIC_QUADRATIC_PRISM
Definition: vtk.hpp:53
static const int QuadraticMap[Geometry::NUM_GEOMETRIES]
Map from MFEM&#39;s Geometry::Type to legacy quadratic VTK geometries/.
Definition: vtk.hpp:80
static const int PYRAMID
Definition: vtk.hpp:42
void WriteVTKEncodedCompressed(std::ostream &os, const void *bytes, uint32_t nbytes, int compression_level)
Outputs encoded binary data in the base 64 format needed by VTK.
Definition: vtk.cpp:559
int CartesianToVTKTensor(int idx_in, int ref, Geometry::Type geom)
Definition: vtk.cpp:381
static Geometry::Type GetMFEMGeometry(int vtk_geom)
Given a VTK geometry type, return the corresponding MFEM Geometry::Type.
Definition: vtk.cpp:46
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
Definition: array.hpp:687
static const int TRIANGLE
Definition: vtk.hpp:37
static const int LAGRANGE_TETRAHEDRON
Definition: vtk.hpp:62
static const int QUADRATIC_SEGMENT
Definition: vtk.hpp:47
static const int TETRAHEDRON
Definition: vtk.hpp:39
const char * VTKByteOrder()
Determine the byte order and return either "BigEndian" or "LittleEndian".
Definition: vtk.cpp:602
static const int POINT
Definition: vtk.hpp:32
void AppendBytes(std::vector< char > &vec, const T &val)
Append the binary representation of val to the byte buffer vec.
Definition: binaryio.hpp:55
static const int LAGRANGE_TRIANGLE
Definition: vtk.hpp:60
static const int PrismMap[6]
Permutation from MFEM&#39;s prism ordering to VTK&#39;s prism ordering.
Definition: vtk.hpp:70
void CreateVTKElementConnectivity(Array< int > &con, Geometry::Type geom, int ref)
Create the VTK element connectivity array for a given element geometry and refinement level...
Definition: vtk.cpp:497
static const int SEGMENT
Definition: vtk.hpp:36
static bool IsQuadratic(int vtk_geom)
Does the given VTK geometry type describe a legacy quadratic element?
Definition: vtk.cpp:90
static const int * VertexPermutation[Geometry::NUM_GEOMETRIES]
Permutation from MFEM&#39;s vertex ordering to VTK&#39;s vertex ordering.
Definition: vtk.hpp:75
static const int LAGRANGE_PYRAMID
Definition: vtk.hpp:65
void WriteBase64WithSizeAndClear(std::ostream &os, std::vector< char > &buf, int compression_level)
Encode in base 64 (and potentially compress) the given data, write it to the output stream (with a he...
Definition: vtk.cpp:654
static int GetOrder(int vtk_geom, int npoints)
For the given VTK geometry type and number of points, return the order of the element.
Definition: vtk.cpp:96
static const int LAGRANGE_PRISM
Definition: vtk.hpp:64