13 #include "../general/binaryio.hpp"
23 POINT, SEGMENT, TRIANGLE, SQUARE, TETRAHEDRON, CUBE, PRISM
28 POINT, QUADRATIC_SEGMENT, QUADRATIC_TRIANGLE, BIQUADRATIC_SQUARE,
29 QUADRATIC_TETRAHEDRON, TRIQUADRATIC_CUBE, BIQUADRATIC_QUADRATIC_PRISM
34 POINT, LAGRANGE_SEGMENT, LAGRANGE_TRIANGLE, LAGRANGE_SQUARE,
35 LAGRANGE_TETRAHEDRON, LAGRANGE_CUBE, LAGRANGE_PRISM
106 return std::round(
std::sqrt(npoints)) - 1;
124 constexpr
int max_order = 20;
125 int order = 11, npoints_order;
126 for (; order<max_order; ++order)
128 npoints_order = (order + 1)*(order + 2)*(order + 3)/6;
129 if (npoints_order == npoints) {
break; }
131 MFEM_VERIFY(npoints == npoints_order,
"");
136 return std::round(std::cbrt(npoints)) - 1;
139 const double n = npoints;
140 static const double third = 1.0/3.0;
141 static const double ninth = 1.0/9.0;
142 static const double twentyseventh = 1.0/27.0;
144 std::cbrt(third*
sqrt(third)*
sqrt((27.0*n - 2.0)*n) + n
146 return std::round(term + ninth / term - 4*third);
158 int bmin = std::min(std::min(b[0], b[1]), b[2]);
169 for (
int d=0; d<3; ++d)
171 if (b[(d+2)%3] == max)
178 for (
int d=0; d<3; ++d)
180 if (b[(d+1)%3] == min)
183 return idx + b[d] - (min + 1);
185 idx += max - (min + 1);
198 int bmin = std::min(std::min(std::min(b[0], b[1]), b[2]), b[3]);
203 idx += 2*(ref*ref + 1);
212 static const int VertexMaxCoords[4] = {3,0,1,2};
216 static const int EdgeMinCoords[6][2] = {{1,2},{2,3},{0,2}, {0,1},{1,3},{0,3}};
219 static const int EdgeCountingCoord[6] = {0,1,3,2,2,2};
225 static const int FaceMinCoord[4] = {1,3,0,2};
231 static const int FaceBCoords[4][3] = {{0,2,3}, {2,0,1}, {2,1,3}, {1,0,3}};
234 for (
int vertex = 0; vertex < 4; vertex++)
236 if (b[VertexMaxCoords[vertex]] == max)
244 for (
int edge = 0; edge < 6; edge++)
246 if (b[EdgeMinCoords[edge][0]] == min && b[EdgeMinCoords[edge][1]] == min)
249 return idx + b[EdgeCountingCoord[edge]] - (min + 1);
251 idx += max - (min + 1);
254 for (
int face = 0; face < 4; face++)
256 if (b[FaceMinCoord[face]] == min)
260 for (
int i = 0; i < 3; i++)
262 projectedb[i] = b[FaceBCoords[face][i]] - min;
268 idx += (ref+1)*(ref+2)/2 - 3*ref;
275 return i + ref*(j - 1) - (j*(j + 1))/2;
284 int ijbdr = (i + j == ref);
285 int kbdr = (k == 0 || k == ref);
287 int nbdr = ibdr + jbdr + ijbdr + kbdr;
290 if (i < 0 || i > ref || j < 0 || j > ref || i + j > ref || k < 0 || k > ref)
292 MFEM_ABORT(
"Invalid index")
298 return (ibdr && jbdr ? 0 : (jbdr && ijbdr ? 1 : 2)) + (k ? 3 : 0);
308 return offset + (k-1)
309 + ((ibdr && jbdr) ? 0 : (jbdr && ijbdr ? 1 : 2))*om1;
315 offset += (k == ref ? 3*om1 : 0);
318 return offset + i - 1;
323 return offset + j - 1;
327 return offset + (ref - j - 1);
334 int ntfdof = (om1 - 1)*om1/2;
335 int nqfdof = om1*om1;
354 return offset + (i - 1) + om1*(k - 1);
359 return offset + (ref - i - 1) + om1*(k - 1);
362 return offset + j - 1 + om1*(k - 1);
366 offset += 2*ntfdof + 3*nqfdof;
381 if (idx_in == 0 || idx_in == ref)
383 return idx_in ? 1 : 0;
392 bool ibdr = (i == 0 || i == ref);
393 bool jbdr = (j == 0 || j == ref);
396 return (i ? (j ? 2 : 1) : (j ? 3 : 0));
401 return (i - 1) + (j ? ref - 1 + ref - 1 : 0) + offset;
405 return (j - 1) + (i ? ref - 1 : 2 * (ref - 1) + ref - 1) + offset;
409 offset += 2 * (ref - 1 + ref - 1);
410 return offset + (i - 1) + (ref - 1) * ((j - 1));
417 int j = (idx_in / n) % n;
418 int k = idx_in / (n*n);
419 bool ibdr = (i == 0 || i == ref);
420 bool jbdr = (j == 0 || j == ref);
421 bool kbdr = (k == 0 || k == ref);
423 int nbdr = (ibdr ? 1 : 0) + (jbdr ? 1 : 0) + (kbdr ? 1 : 0);
427 return (i ? (j ? 2 : 1) : (j ? 3 : 0)) + (k ? 4 : 0);
437 (j ? ref - 1 + ref - 1 : 0) +
438 (k ? 2*(ref - 1 + ref - 1) : 0) +
445 (i ? ref - 1 : 2*(ref - 1) + ref - 1) +
446 (k ? 2*(ref - 1 + ref - 1) : 0) +
450 offset += 4*(ref - 1) + 4*(ref - 1);
451 return (k - 1) + (ref - 1)*(i ? (j ? 3 : 1) : (j ? 2 : 0))
455 offset += 4*(ref - 1 + ref - 1 + ref - 1);
460 return (j - 1) + ((ref - 1)*(k - 1))
461 + (i ? (ref - 1)*(ref - 1) : 0) + offset;
463 offset += 2*(ref - 1)*(ref - 1);
467 + ((ref - 1)*(k - 1))
468 + (j ? (ref - 1)*(ref - 1) : 0) + offset;
470 offset += 2*(ref - 1)*(ref - 1);
472 return (i - 1) + ((ref - 1)*(j - 1))
473 + (k ? (ref - 1)*(ref - 1) : 0) + offset;
477 offset += 2*((ref - 1)*(ref - 1) +
478 (ref - 1)*(ref - 1) +
479 (ref - 1)*(ref - 1));
480 return offset + (i - 1) + (ref - 1)*((j - 1) + (ref - 1)*(k - 1));
483 MFEM_ABORT(
"CartesianToVTKOrderingTensor only supports tensor"
499 for (b[1]=0; b[1]<=ref; ++b[1])
501 for (b[0]=0; b[0]<=ref-b[1]; ++b[0])
503 b[2] = ref - b[0] - b[1];
512 for (b[2]=0; b[2]<=ref; b[2]++)
514 for (b[1]=0; b[1]<=ref-b[2]; b[1]++)
516 for (b[0]=0; b[0]<=ref-b[1]-b[2]; b[0]++)
518 b[3] = ref-b[0]-b[1]-b[2];
527 for (
int k=0; k<=ref; k++)
529 for (
int j=0; j<=ref; j++)
531 for (
int i=0; i<=ref-j; i++)
540 for (
int idx=0; idx<nnodes; ++idx)
548 uint32_t nbytes,
int compression_level)
550 if (compression_level == 0)
560 MFEM_ASSERT(compression_level >= -1 && compression_level <= 9,
561 "Compression level must be between -1 and 9 (inclusive).");
562 uLongf buf_sz = compressBound(nbytes);
563 std::vector<unsigned char> buf(buf_sz);
564 compress2(buf.data(), &buf_sz,
static_cast<const Bytef *
>(bytes), nbytes,
568 std::vector<uint32_t> header(4);
577 MFEM_ABORT(
"MFEM must be compiled with ZLib support to output "
578 "compressed binary data.")
586 int8_t *x8 =
reinterpret_cast<int8_t *
>(&x16);
598 return "LittleEndian";
606 const uint8_t &val,
const char *suffix,
615 const double &val,
const char *suffix,
620 bin_io::AppendBytes<float>(buf, float(val));
634 const float &val,
const char *suffix,
643 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 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
FDualNumber< tbase > sqrt(const FDualNumber< tbase > &f)
sqrt([dual number])
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.
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