13 #include "../general/binaryio.hpp"
23 POINT, SEGMENT, TRIANGLE, SQUARE, TETRAHEDRON, CUBE, PRISM, PYRAMID
28 POINT, QUADRATIC_SEGMENT, QUADRATIC_TRIANGLE, BIQUADRATIC_SQUARE,
29 QUADRATIC_TETRAHEDRON, TRIQUADRATIC_CUBE, BIQUADRATIC_QUADRATIC_PRISM,
35 POINT, LAGRANGE_SEGMENT, LAGRANGE_TRIANGLE, LAGRANGE_SQUARE,
36 LAGRANGE_TETRAHEDRON, LAGRANGE_CUBE, LAGRANGE_PRISM, LAGRANGE_PYRAMID
109 return static_cast<int>(std::sqrt(8*npoints + 1) - 3)/2;
111 return static_cast<int>(std::round(std::sqrt(npoints))) - 1;
129 constexpr
int max_order = 20;
130 int order = 11, npoints_order;
131 for (; order<max_order; ++order)
133 npoints_order = (order + 1)*(order + 2)*(order + 3)/6;
134 if (npoints_order == npoints) {
break; }
136 MFEM_VERIFY(npoints == npoints_order,
"");
141 return static_cast<int>(std::round(std::cbrt(npoints))) - 1;
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;
149 std::cbrt(third*sqrt(third)*sqrt((27.0*n - 2.0)*n) + n
151 return static_cast<int>(std::round(term + ninth / term - 4*third));
154 MFEM_ABORT(
"Lagrange pyramids not currently supported in VTK.");
166 int bmin = std::min(std::min(b[0], b[1]), b[2]);
177 for (
int d=0; d<3; ++d)
179 if (b[(d+2)%3] == max)
186 for (
int d=0; d<3; ++d)
188 if (b[(d+1)%3] == min)
191 return idx + b[d] - (min + 1);
193 idx += max - (min + 1);
206 int bmin = std::min(std::min(std::min(b[0], b[1]), b[2]), b[3]);
211 idx += 2*(ref*ref + 1);
220 static const int VertexMaxCoords[4] = {3,0,1,2};
224 static const int EdgeMinCoords[6][2] = {{1,2},{2,3},{0,2}, {0,1},{1,3},{0,3}};
227 static const int EdgeCountingCoord[6] = {0,1,3,2,2,2};
233 static const int FaceMinCoord[4] = {1,3,0,2};
239 static const int FaceBCoords[4][3] = {{0,2,3}, {2,0,1}, {2,1,3}, {1,0,3}};
242 for (
int vertex = 0; vertex < 4; vertex++)
244 if (b[VertexMaxCoords[vertex]] == max)
252 for (
int edge = 0; edge < 6; edge++)
254 if (b[EdgeMinCoords[edge][0]] == min && b[EdgeMinCoords[edge][1]] == min)
257 return idx + b[EdgeCountingCoord[edge]] - (min + 1);
259 idx += max - (min + 1);
262 for (
int face = 0; face < 4; face++)
264 if (b[FaceMinCoord[face]] == min)
268 for (
int i = 0; i < 3; i++)
270 projectedb[i] = b[FaceBCoords[face][i]] - min;
276 idx += (ref+1)*(ref+2)/2 - 3*ref;
283 return i + ref*(j - 1) - (j*(j + 1))/2;
292 int ijbdr = (i + j == ref);
293 int kbdr = (k == 0 || k == ref);
295 int nbdr = ibdr + jbdr + ijbdr + kbdr;
298 if (i < 0 || i > ref || j < 0 || j > ref || i + j > ref || k < 0 || k > ref)
300 MFEM_ABORT(
"Invalid index")
306 return (ibdr && jbdr ? 0 : (jbdr && ijbdr ? 1 : 2)) + (k ? 3 : 0);
316 return offset + (k-1)
317 + ((ibdr && jbdr) ? 0 : (jbdr && ijbdr ? 1 : 2))*om1;
323 offset += (k == ref ? 3*om1 : 0);
326 return offset + i - 1;
331 return offset + j - 1;
335 return offset + (ref - j - 1);
342 int ntfdof = (om1 - 1)*om1/2;
343 int nqfdof = om1*om1;
362 return offset + (i - 1) + om1*(k - 1);
367 return offset + (ref - i - 1) + om1*(k - 1);
370 return offset + j - 1 + om1*(k - 1);
374 offset += 2*ntfdof + 3*nqfdof;
389 if (idx_in == 0 || idx_in == ref)
391 return idx_in ? 1 : 0;
400 bool ibdr = (i == 0 || i == ref);
401 bool jbdr = (j == 0 || j == ref);
404 return (i ? (j ? 2 : 1) : (j ? 3 : 0));
409 return (i - 1) + (j ? ref - 1 + ref - 1 : 0) + offset;
413 return (j - 1) + (i ? ref - 1 : 2 * (ref - 1) + ref - 1) + offset;
417 offset += 2 * (ref - 1 + ref - 1);
418 return offset + (i - 1) + (ref - 1) * ((j - 1));
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);
431 int nbdr = (ibdr ? 1 : 0) + (jbdr ? 1 : 0) + (kbdr ? 1 : 0);
435 return (i ? (j ? 2 : 1) : (j ? 3 : 0)) + (k ? 4 : 0);
445 (j ? ref - 1 + ref - 1 : 0) +
446 (k ? 2*(ref - 1 + ref - 1) : 0) +
453 (i ? ref - 1 : 2*(ref - 1) + ref - 1) +
454 (k ? 2*(ref - 1 + ref - 1) : 0) +
458 offset += 4*(ref - 1) + 4*(ref - 1);
459 return (k - 1) + (ref - 1)*(i ? (j ? 3 : 1) : (j ? 2 : 0))
463 offset += 4*(ref - 1 + ref - 1 + ref - 1);
468 return (j - 1) + ((ref - 1)*(k - 1))
469 + (i ? (ref - 1)*(ref - 1) : 0) + offset;
471 offset += 2*(ref - 1)*(ref - 1);
475 + ((ref - 1)*(k - 1))
476 + (j ? (ref - 1)*(ref - 1) : 0) + offset;
478 offset += 2*(ref - 1)*(ref - 1);
480 return (i - 1) + ((ref - 1)*(j - 1))
481 + (k ? (ref - 1)*(ref - 1) : 0) + offset;
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));
491 MFEM_ABORT(
"CartesianToVTKOrderingTensor only supports tensor"
507 for (b[1]=0; b[1]<=ref; ++b[1])
509 for (b[0]=0; b[0]<=ref-b[1]; ++b[0])
511 b[2] = ref - b[0] - b[1];
520 for (b[2]=0; b[2]<=ref; b[2]++)
522 for (b[1]=0; b[1]<=ref-b[2]; b[1]++)
524 for (b[0]=0; b[0]<=ref-b[1]-b[2]; b[0]++)
526 b[3] = ref-b[0]-b[1]-b[2];
535 for (
int k=0; k<=ref; k++)
537 for (
int j=0; j<=ref; j++)
539 for (
int i=0; i<=ref-j; i++)
548 MFEM_ABORT(
"Lagrange pyramid elements not currently supported in VTK.");
552 for (
int idx=0; idx<nnodes; ++idx)
560 uint32_t nbytes,
int compression_level)
562 if (compression_level == 0)
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,
580 std::vector<uint32_t> header(4);
589 MFEM_ABORT(
"MFEM must be compiled with ZLib support to output "
590 "compressed binary data.")
598 int8_t *x8 =
reinterpret_cast<int8_t *
>(&x16);
610 return "LittleEndian";
618 const uint8_t &val,
const char *suffix,
627 const double &val,
const char *suffix,
632 bin_io::AppendBytes<float>(buf, float(val));
646 const float &val,
const char *suffix,
655 int compression_level)
static const int BIQUADRATIC_SQUARE
int GetNPoints() const
Returns the number of the points in the integration rule.
int CartesianToVTKPrism(int i, int j, int k, int ref)
static const int HighOrderMap[Geometry::NUM_GEOMETRIES]
Map from MFEM's Geometry::Type to arbitrary-order Lagrange VTK geometries.
static const int QUADRATIC_TETRAHEDRON
Data arrays will be written in ASCII format.
static const int QUADRATIC_PYRAMID
static bool IsLagrange(int vtk_geom)
Does the given VTK geometry type describe an arbitrary-order Lagrange element?
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...
void WriteBinaryOrASCII< float >(std::ostream &os, std::vector< char > &buf, const float &val, const char *suffix, VTKFormat format)
Specialization of WriteBinaryOrASCII<T> for float.
int BarycentricToVTKTetra(int *b, int ref)
static const int LAGRANGE_CUBE
int VTKTriangleDOFOffset(int ref, int i, int j)
static const int QUADRATIC_TRIANGLE
int BarycentricToVTKTriangle(int *b, int ref)
Return the VTK node index of the barycentric point b in a triangle with refinement level ref...
static const int TRIQUADRATIC_CUBE
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 ...
static const int Map[Geometry::NUM_GEOMETRIES]
Map from MFEM's Geometry::Type to linear VTK geometries.
static const int LAGRANGE_SEGMENT
VTKFormat
Data array format for VTK and VTU files.
GeometryRefiner GlobGeometryRefiner
static const int LAGRANGE_SQUARE
void WriteBinaryOrASCII< double >(std::ostream &os, std::vector< char > &buf, const double &val, const char *suffix, VTKFormat format)
Specialization of WriteBinaryOrASCII for double.
RefinedGeometry * Refine(Geometry::Type Geom, int Times, int ETimes=1)
static const int BIQUADRATIC_QUADRATIC_PRISM
static const int QuadraticMap[Geometry::NUM_GEOMETRIES]
Map from MFEM's Geometry::Type to legacy quadratic VTK geometries/.
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.
int CartesianToVTKTensor(int idx_in, int ref, Geometry::Type geom)
static Geometry::Type GetMFEMGeometry(int vtk_geom)
Given a VTK geometry type, return the corresponding MFEM Geometry::Type.
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
static const int TRIANGLE
static const int LAGRANGE_TETRAHEDRON
static const int QUADRATIC_SEGMENT
static const int TETRAHEDRON
const char * VTKByteOrder()
Determine the byte order and return either "BigEndian" or "LittleEndian".
void AppendBytes(std::vector< char > &vec, const T &val)
Append the binary representation of val to the byte buffer vec.
static const int LAGRANGE_TRIANGLE
static const int PrismMap[6]
Permutation from MFEM's prism ordering to VTK's prism ordering.
void CreateVTKElementConnectivity(Array< int > &con, Geometry::Type geom, int ref)
Create the VTK element connectivity array for a given element geometry and refinement level...
static bool IsQuadratic(int vtk_geom)
Does the given VTK geometry type describe a legacy quadratic element?
static const int * VertexPermutation[Geometry::NUM_GEOMETRIES]
Permutation from MFEM's vertex ordering to VTK's vertex ordering.
static const int LAGRANGE_PYRAMID
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...
static int GetOrder(int vtk_geom, int npoints)
For the given VTK geometry type and number of points, return the order of the element.
static const int LAGRANGE_PRISM