MFEM v4.7.0
Finite element discretization library
Loading...
Searching...
No Matches
vtk.cpp
Go to the documentation of this file.
1// Copyright (c) 2010-2024, 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"
14#ifdef MFEM_USE_ZLIB
15#include <zlib.h>
16#endif
17
18namespace 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
39const 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:
55 return Geometry::SEGMENT;
56 case TRIANGLE:
59 return Geometry::TRIANGLE;
60 case SQUARE:
62 case LAGRANGE_SQUARE:
63 return Geometry::SQUARE;
64 case TETRAHEDRON:
68 case CUBE:
70 case LAGRANGE_CUBE:
71 return Geometry::CUBE;
72 case PRISM:
74 case LAGRANGE_PRISM:
75 return Geometry::PRISM;
76 case PYRAMID:
79 return Geometry::PYRAMID;
80 default:
81 return Geometry::INVALID;
82 }
83}
84
85bool VTKGeometry::IsLagrange(int vtk_geom)
86{
87 return vtk_geom >= LAGRANGE_SEGMENT && vtk_geom <= LAGRANGE_PYRAMID;
88}
89
90bool VTKGeometry::IsQuadratic(int vtk_geom)
91{
92 return vtk_geom >= QUADRATIC_SEGMENT
93 && vtk_geom <= BIQUADRATIC_QUADRATIC_PRISM;
94}
95
96int 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;
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
161int 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
198int 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
281int VTKTriangleDOFOffset(int ref, int i, int j)
282{
283 return i + ref*(j - 1) - (j*(j + 1))/2;
284}
285
286int 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
381int 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;
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
559void 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
602const 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
616template <>
617void 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
625template <>
626void 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
644template <>
645void 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
654void 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
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
Definition array.hpp:697
RefinedGeometry * Refine(Geometry::Type Geom, int Times, int ETimes=1)
Definition geom.cpp:1136
int GetNPoints() const
Returns the number of the points in the integration rule.
Definition intrules.hpp:256
IntegrationRule RefPts
Definition geom.hpp:317
real_t 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
void AppendBytes(std::vector< char > &vec, const T &val)
Append the binary representation of val to the byte buffer vec.
Definition binaryio.hpp:55
int CartesianToVTKTensor(int idx_in, int ref, Geometry::Type geom)
Definition vtk.cpp:381
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
bool IsBigEndian()
Definition vtk.cpp:595
GeometryRefiner GlobGeometryRefiner
Definition geom.cpp:1891
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
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
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
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
VTKFormat
Data array format for VTK and VTU files.
Definition vtk.hpp:99
@ ASCII
Data arrays will be written in ASCII format.
int VTKTriangleDOFOffset(int ref, int i, int j)
Definition vtk.cpp:281
T ZeroSubnormal(T val)
Definition vector.hpp:502
int CartesianToVTKPrism(int i, int j, int k, int ref)
Definition vtk.cpp:286
const char * VTKByteOrder()
Determine the byte order and return either "BigEndian" or "LittleEndian".
Definition vtk.cpp:602
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
int BarycentricToVTKTetra(int *b, int ref)
Definition vtk.cpp:198
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 bool IsQuadratic(int vtk_geom)
Does the given VTK geometry type describe a legacy quadratic element?
Definition vtk.cpp:90
static const int HighOrderMap[Geometry::NUM_GEOMETRIES]
Map from MFEM's Geometry::Type to arbitrary-order Lagrange VTK geometries.
Definition vtk.hpp:82
static const int BIQUADRATIC_QUADRATIC_PRISM
Definition vtk.hpp:53
static const int LAGRANGE_PRISM
Definition vtk.hpp:64
static const int QuadraticMap[Geometry::NUM_GEOMETRIES]
Map from MFEM's Geometry::Type to legacy quadratic VTK geometries/.
Definition vtk.hpp:80
static const int * VertexPermutation[Geometry::NUM_GEOMETRIES]
Permutation from MFEM's vertex ordering to VTK's vertex ordering.
Definition vtk.hpp:75
static const int LAGRANGE_TETRAHEDRON
Definition vtk.hpp:62
static const int LAGRANGE_TRIANGLE
Definition vtk.hpp:60
static const int QUADRATIC_TRIANGLE
Definition vtk.hpp:48
static const int PrismMap[6]
Permutation from MFEM's prism ordering to VTK's prism ordering.
Definition vtk.hpp:70
static const int SQUARE
Definition vtk.hpp:38
static const int CUBE
Definition vtk.hpp:40
static const int TRIANGLE
Definition vtk.hpp:37
static const int TETRAHEDRON
Definition vtk.hpp:39
static const int LAGRANGE_SQUARE
Definition vtk.hpp:61
static bool IsLagrange(int vtk_geom)
Does the given VTK geometry type describe an arbitrary-order Lagrange element?
Definition vtk.cpp:85
static const int POINT
Definition vtk.hpp:32
static const int PRISM
Definition vtk.hpp:41
static const int QUADRATIC_SEGMENT
Definition vtk.hpp:47
static const int SEGMENT
Definition vtk.hpp:36
static const int BIQUADRATIC_SQUARE
Definition vtk.hpp:49
static const int LAGRANGE_CUBE
Definition vtk.hpp:63
static Geometry::Type GetMFEMGeometry(int vtk_geom)
Given a VTK geometry type, return the corresponding MFEM Geometry::Type.
Definition vtk.cpp:46
static const int LAGRANGE_SEGMENT
Definition vtk.hpp:59
static const int QUADRATIC_TETRAHEDRON
Definition vtk.hpp:50
static const int QUADRATIC_PYRAMID
Definition vtk.hpp:54
static const int LAGRANGE_PYRAMID
Definition vtk.hpp:65
static const int TRIQUADRATIC_CUBE
Definition vtk.hpp:51
static const int Map[Geometry::NUM_GEOMETRIES]
Map from MFEM's Geometry::Type to linear VTK geometries.
Definition vtk.hpp:78
static const int PYRAMID
Definition vtk.hpp:42
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