35adios2::Variable<T> SafeDefineVariable(adios2::IO io,
36 const std::string& variable_name,
37 const adios2::Dims& shape = adios2::Dims(),
38 const adios2::Dims& start = adios2::Dims(),
39 const adios2::Dims& count = adios2::Dims())
41 adios2::Variable<T> variable = io.InquireVariable<T>(variable_name);
44 if (variable.Count() != count &&
45 variable.ShapeID() == adios2::ShapeID::LocalArray)
47 variable.SetSelection({start, count});
52 variable = io.DefineVariable<T>(variable_name, shape, start, count);
59adios2::Attribute<T> SafeDefineAttribute(adios2::IO io,
60 const std::string& attribute_name,
62 const std::string& variable_name =
"",
63 const std::string separator =
"/")
65 adios2::Attribute<T> attribute = io.InquireAttribute<T>(attribute_name);
70 return io.DefineAttribute<T>(attribute_name, value, variable_name, separator );
74adios2::Attribute<T> SafeDefineAttribute(adios2::IO io,
75 const std::string& attribute_name,
76 const T* values,
const size_t size,
77 const std::string& variable_name =
"",
78 const std::string separator =
"/")
80 adios2::Attribute<T> attribute = io.InquireAttribute<T>(attribute_name);
85 return io.DefineAttribute<T>(attribute_name, values, size, variable_name,
89bool SetBoolParameter(
const std::string key,
90 const std::map<std::string, std::string>& parameters,
91 const bool default_value)
noexcept
93 auto it = parameters.find(key);
94 if (it != parameters.end())
96 std::string value = it->second;
97 std::transform(value.begin(), value.end(), value.begin(), ::tolower);
98 if (value ==
"on" || value ==
"true")
102 else if ( value ==
"off" || value ==
"false")
107 return default_value;
115 MPI_Comm comm,
const std::string engineType)
117 adios2_openmode(
mode),
118 adios(new adios2::ADIOS(comm)),
119 io(adios->DeclareIO(name))
121 io.SetEngine(engineType);
125 const std::string engineType)
127 adios2_openmode(
mode),
128 adios(new adios2::ADIOS()),
129 io(adios->DeclareIO(name))
131 io.SetEngine(engineType);
139 SafeDefineAttribute<std::string>(io,
"vtk.xml", VTKSchema() );
145 const std::map<std::string, std::string>& parameters)
147 io.SetParameters(parameters);
148 refine = SetBoolParameter(
"RefinedData", parameters,
true);
152 const std::string value)
noexcept
154 io.SetParameter(key, value);
155 if (key ==
"RefinedData")
157 refine = SetBoolParameter(
"RefinedData", io.Parameters(),
true);
165 engine = io.Open(name, adios2::Mode::Write);
173 if (!engine || !active_step)
175 const std::string message =
"MFEM adios2stream error: calling EndStep "
176 "on uninitialized step (need BeginStep)";
180 SafeDefineAttribute<std::string>(io,
"vtk.xml", VTKSchema() );
187 adios2::Variable<double> var_time = SafeDefineVariable<double>(io,
"TIME");
188 engine.Put(var_time, time);
194 adios2::Variable<int> var_cycle = SafeDefineVariable<int>(io,
"CYCLE");
195 engine.Put(var_cycle, cycle);
200 refinement_level = level;
205 return engine.CurrentStep();
214 SafeDefineAttribute<std::string>(io,
"vtk.xml", VTKSchema() );
228 auto lf_DefineMeshMetadata = [
this](
Mesh& mesh)
231 if (!IsConstantElementType(mesh.
elements))
233 throw std::invalid_argument(
"MFEM::adios2stream ERROR: non-constant "
234 " element types not yet implemented\n");
238 SafeDefineAttribute<std::string>(io,
"format",
"MFEM ADIOS2 BP v0.2" );
239 SafeDefineAttribute<std::string>(io,
"format/version",
"0.2" );
240 std::string mesh_type =
"Unknown";
241 std::vector<std::string> viz_tools;
242 viz_tools.reserve(2);
245 mesh_type =
"MFEM NURBS";
246 viz_tools.push_back(
"NONE");
250 mesh_type =
"MFEM mesh v1.1";
251 viz_tools.push_back(
"NONE");
255 mesh_type =
"MFEM mesh v1.0";
256 viz_tools.push_back(
"Paraview: ADIOS2VTXReader");
257 viz_tools.push_back(
"VTK: vtkADIOS2VTXReader.h");
260 SafeDefineAttribute<std::string>(io,
"format/mfem_mesh", mesh_type );
261 SafeDefineAttribute<std::string>(io,
"format/viz_tools", viz_tools.data(),
266 SafeDefineAttribute<uint32_t>(io,
"dimension",
dimension);
267 SafeDefineVariable<uint32_t>(io,
"NumOfElements", {adios2::LocalValueDim});
268 SafeDefineVariable<uint32_t>(io,
"types");
269 size_t nelements = 0;
270 size_t element_nvertices = 0;
271 size_t nvertices = 0;
275 for (
int i = 0; i < mesh.
GetNE(); ++i)
279 refinement_level, 1);
280 if (refined_geometry ==
nullptr)
282 mfem_error(
"ERROR: could not refine geometry in call to Save with adios2stream \n");
288 nelements += refined_geometry->
RefGeoms.
Size() / element_nvertices;
292 refined_mesh_nelements = nelements;
293 refined_mesh_nvertices = nvertices;
297 nelements =
static_cast<size_t>(mesh.
GetNE());
298 element_nvertices =
static_cast<size_t>(mesh.
elements[0]->GetNVertices());
300 SafeDefineVariable<uint64_t>(io,
"connectivity", {}, {}, {nelements, element_nvertices+1});
301 SafeDefineVariable<int32_t>(io,
"attribute", {}, {}, {nelements});
304 SafeDefineVariable<uint32_t>(io,
"NumOfVertices", {adios2::LocalValueDim});
307 SafeDefineVariable<double>( io,
"vertices", {}, {}, {nvertices,
static_cast<size_t>(
dimension)});
312 if (grid_function ==
nullptr)
314 const size_t nVertices =
static_cast<size_t>(mesh.
GetNV());
315 const size_t spaceDim =
static_cast<size_t>(mesh.
SpaceDimension());
317 SafeDefineVariable<double>( io,
"vertices", {}, {}, {nVertices, spaceDim});
321 const size_t size =
static_cast<size_t>(grid_function->
Size());
323 const size_t components =
static_cast<size_t>(fes->
GetVDim());
324 const size_t tuples = size /components;
325 SafeDefineVariable<double>(io,
"vertices", {}, {}, {tuples, components} );
329 ordering_by_node =
true;
335 auto lf_PrintRefinedMeshData = [
this](
Mesh& mesh)
338 engine.Put(
"NumOfElements",
static_cast<uint32_t
>(refined_mesh_nelements));
339 engine.Put(
"NumOfVertices",
static_cast<uint32_t
>(refined_mesh_nvertices));
341 const uint32_t vtkType =
342 GLVISToVTKType(
static_cast<int>(mesh.
elements[0]->GetGeometryType()));
343 engine.Put(
"types", vtkType);
345 adios2::Variable<double> var_vertices = io.InquireVariable<
double>(
"vertices");
346 adios2::Variable<double>::Span span_vertices = engine.Put<
double>(var_vertices);
348 adios2::Variable<uint64_t> var_connectivity =
349 io.InquireVariable<uint64_t>(
"connectivity");
350 adios2::Variable<uint64_t>::Span span_connectivity = engine.Put<uint64_t>
353 adios2::Variable<int32_t> var_element_attribute =
354 io.InquireVariable<int32_t>(
"attribute");
355 adios2::Variable<int32_t>::Span span_element_attribute = engine.Put<int32_t>
356 (var_element_attribute);
358 size_t span_vertices_offset = 0;
359 size_t span_connectivity_offset = 0;
360 size_t span_element_attribute_offset = 0;
365 for (
int e = 0; e < mesh.
GetNE(); ++e)
369 refinement_level, 1);
372 for (
int i = 0; i < pmatrix.
Width(); ++i)
374 for (
int j = 0; j < pmatrix.
Height(); ++j)
376 span_vertices[span_vertices_offset + i*pmatrix.
Height() + j] = pmatrix(j, i);
379 span_vertices_offset +=
static_cast<size_t>(pmatrix.
Width()*pmatrix.
Height());
388 for (
int v = 0; v < element_vertices.
Size();)
390 span_connectivity[span_connectivity_offset] =
static_cast<uint64_t
>(nv);
391 ++span_connectivity_offset;
393 span_element_attribute[span_element_attribute_offset] =
static_cast<int32_t
>
395 ++span_element_attribute_offset;
397 for (
int k =0; k < nv; k++, v++ )
399 span_connectivity[span_connectivity_offset] =
static_cast<uint64_t
>
400 (point_id + element_vertices[v]);
401 ++span_connectivity_offset;
408 for (
int e = 0; e < mesh.
GetNE(); ++e)
412 refinement_level, 1);
416 auto lf_PrintMeshData = [&](
Mesh& mesh)
420 lf_PrintRefinedMeshData(mesh);
425 engine.Put(
"NumOfElements",
static_cast<uint32_t
>(mesh.
GetNE()));
427 const uint32_t vtkType =
428 GLVISToVTKType(
static_cast<int>(mesh.
elements[0]->GetGeometryType()));
429 engine.Put(
"types", vtkType);
431 adios2::Variable<uint64_t> varConnectivity =
432 io.InquireVariable<uint64_t>(
"connectivity");
434 adios2::Variable<uint64_t>::Span spanConnectivity =
435 engine.Put<uint64_t>(varConnectivity);
437 adios2::Variable<int32_t> varElementAttribute =
438 io.InquireVariable<int32_t>(
"attribute");
440 adios2::Variable<int32_t>::Span spanElementAttribute =
441 engine.Put<int32_t>(varElementAttribute);
443 size_t elementPosition = 0;
444 for (
int e = 0; e < mesh.
GetNE(); ++e)
446 spanElementAttribute[e] =
static_cast<int32_t
>(mesh.
GetAttribute(e));
448 const int nVertices = mesh.
elements[e]->GetNVertices();
449 spanConnectivity[elementPosition] = nVertices;
450 for (
int v = 0; v < nVertices; ++v)
452 spanConnectivity[elementPosition + v + 1] =
455 elementPosition += nVertices + 1;
459 engine.Put(
"NumOfVertices",
static_cast<uint32_t
>(mesh.
GetNV()));
463 adios2::Variable<double> varVertices = io.InquireVariable<
double>(
"vertices");
465 adios2::Variable<double>::Span spanVertices = engine.Put(varVertices);
467 for (
int v = 0; v < mesh.
GetNV(); ++v)
470 for (
int coord = 0; coord < space_dim; ++coord)
472 spanVertices[v * space_dim + coord] = mesh.
vertices[v](coord);
479 if (ordering_by_node)
481 adios2::Variable<double> varVertices = io.InquireVariable<
double>(
"vertices");
483 adios2::Variable<double>::Span spanVertices = engine.Put(varVertices);
485 const size_t size =
static_cast<size_t>(grid_function->
Size());
487 const size_t components =
static_cast<size_t>(fes->
GetVDim());
488 const size_t tuples = size /components;
490 const double* data = grid_function->
GetData();
492 for (
size_t i = 0; i < tuples; ++i)
494 for (
size_t j = 0; j < components; ++j)
496 spanVertices[i*components + j] = data[j*tuples + i];
502 grid_function->
Print(*
this,
"vertices");
511 lf_DefineMeshMetadata(ref_mesh);
515 engine = io.Open(name, adios2::Mode::Write);
518 lf_PrintMeshData(ref_mesh);
522 engine.PerformPuts();
525 catch (std::exception& e)
527 const std::string warning =
528 "MFEM: adios2stream exception caught, invalid bp dataset: " + name +
535 const std::string& variable_name,
const data_type type)
537 auto lf_SafeDefine = [&](
const std::string& variable_name,
538 const size_t tuples,
const size_t components,
540 const std::string& fespace_name)
542 adios2::Variable<double> var = io.InquireVariable<
double>(variable_name);
547 io.DefineVariable<
double>(variable_name, {}, {}, {tuples*components});
552 adios2::Dims{components, tuples} :
553 adios2::Dims{tuples, components};
554 io.DefineVariable<
double>(variable_name, {}, {}, count);
556 SafeDefineAttribute<std::string>(io,
"FiniteElementSpace",
557 fespace_name, variable_name);
563 const std::map<std::string, std::string> parameters = io.Parameters();
564 const bool full_data = SetBoolParameter(
"FullData", parameters,
false);
566 if (!full_data && !refine)
576 const size_t components =
static_cast<size_t>(grid_function.
VectorDim());
578 const size_t tuples = refined_mesh_nvertices;
580 lf_SafeDefine(variable_name, tuples, components,
584 point_data_variables.insert(variable_name);
591 adios2::Variable<double> variable = io.InquireVariable<
double>(variable_name);
592 adios2::Variable<double>::Span span = engine.Put<
double>(variable);
599 const int nelements = mesh->
GetNE();
600 for (
int e = 0; e < nelements; ++e)
605 grid_function.
GetValues(e, refined_geometry->
RefPts, scalar, transform);
607 const int size = scalar.
Size();
609 for (
int i = 0; i < size; ++i)
611 const double value = scalar(i);
612 span.at(offset+i) = value;
614 offset +=
static_cast<size_t>(size);
620 for (
int e = 0; e < mesh->
GetNE(); ++e)
626 for (
int i = 0; i < vector.Width(); ++i)
628 for (
int j = 0; j < vector.Height(); ++j)
630 span[offset + i*vector.Height() + j] = vector(j, i);
633 offset +=
static_cast<size_t>(vector.Width()*vector.Height());
640 const size_t size =
static_cast<size_t>(grid_function.
Size());
641 const size_t components =
static_cast<size_t>(fes->
GetVDim());
642 const size_t tuples = size /components;
643 lf_SafeDefine(variable_name +
"/full", tuples, components,
647 grid_function.
Print(*
this, variable_name+
"/full");
651 point_data_variables.insert(variable_name+
"/full");
657int32_t adios2stream::GLVISToVTKType(
658 const int glvisType)
const noexcept
660 uint32_t vtkType = 0;
693bool adios2stream::IsConstantElementType(
const Array<Element*>& elements )
const
696 bool isConstType =
true;
699 for (
int e = 1; e < elements.Size(); ++e)
701 if (type != elements[e]->GetGeometryType())
710std::string adios2stream::VTKSchema() const noexcept
712 std::string vtkSchema = R
"(
714<VTKFile type="UnstructuredGrid" version="0.2" byte_order="LittleEndian">
716 <Piece NumberOfPoints="NumOfVertices" NumberOfCells="NumOfElements">
718 <DataArray Name="vertices" />)";
723 <DataArray Name="attribute" />
726 <DataArray Name="connectivity" />
727 <DataArray Name="types" />
731 if (point_data_variables.empty())
737 for (
const std::string& point_datum : point_data_variables )
739 vtkSchema +=
" <DataArray Name=\"" + point_datum +
"\"/>\n";
745 vtkSchema +=
" <DataArray Name=\"TIME\">\n";
746 vtkSchema +=
" TIME\n";
747 vtkSchema +=
" </DataArray>\n";
762 adios2::Mode adios2Mode = adios2::Mode::Undefined;
766 adios2Mode = adios2::Mode::Write;
769 adios2Mode = adios2::Mode::Read;
772 const std::string message =
"MFEM adios2stream ERROR: only "
773 "openmode::out and openmode::in "
774 " are valid, in call to adios2stream constructor";
int Size() const
Return the logical size of the array.
Data type dense matrix using column-major storage.
virtual const char * Name() const
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Ordering::Type GetOrdering() const
Return the ordering method.
const FiniteElementCollection * FEColl() const
Mesh * GetMesh() const
Returns the mesh.
int GetVDim() const
Returns vector dimension.
RefinedGeometry * Refine(Geometry::Type Geom, int Times, int ETimes=1)
const IntegrationRule * GetVertices(int GeomType) const
Return an IntegrationRule consisting of all vertices of the given Geometry::Type, GeomType.
Class for grid function - Vector with associated FE space.
void GetValues(int i, const IntegrationRule &ir, Vector &vals, int vdim=1) const
FiniteElementSpace * FESpace()
void GetVectorValues(int i, const IntegrationRule &ir, DenseMatrix &vals, DenseMatrix &tr) const
int GetNPoints() const
Returns the number of the points in the integration rule.
NURBSExtension * NURBSext
Optional NURBS mesh extension.
int GetAttribute(int i) const
Return the attribute of element i.
int GetNE() const
Returns number of elements.
int Dimension() const
Dimension of the reference space used within the elements.
void GetElementTransformation(int i, IsoparametricTransformation *ElTr) const
Builds the transformation defining the i-th element in ElTr. ElTr must be allocated in advance and wi...
int SpaceDimension() const
Dimension of the physical space containing the mesh.
void GetNodes(Vector &node_coord) const
int GetNV() const
Returns number of vertices. Vertices are only at the corners of elements, where you would expect them...
NCMesh * ncmesh
Optional nonconforming mesh extension.
Geometry::Type GetElementBaseGeometry(int i) const
Array< Element * > elements
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
void Print(std::ostream &out=mfem::out, int width=8) const
Prints vector to stream out.
int Size() const
Returns the size of the vector.
real_t * GetData() const
Return a pointer to the beginning of the Vector data.
void SetCycle(const int cycle)
void SetParameter(const std::string key, const std::string value) noexcept
void SetTime(const double time)
void SetParameters(const std::map< std::string, std::string > ¶meters=std::map< std::string, std::string >())
void Print(const Mesh &mesh, const adios2stream::mode print_mode=mode::sync)
adios2stream(const std::string &name, const openmode mode, MPI_Comm comm, const std::string engine_type="BPFile")
size_t CurrentStep() const
void Save(const GridFunction &grid_function, const std::string &variable_name, const data_type type)
void SetRefinementLevel(const int level) noexcept
constexpr int dimension
This example only works in 3D. Kernels for 2D are not implemented.
void mfem_error(const char *msg)
GeometryRefiner GlobGeometryRefiner
void mfem_warning(const char *msg)