MFEM  v4.5.1
Finite element discretization library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
adios2stream.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010-2022, 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 // Created on: Jan 22, 2019
13 // Author: William F Godoy godoywf@ornl.gov
14 // adios2: Adaptable Input/Output System https://github.com/ornladios/ADIOS2
15 
16 #include "adios2stream.hpp"
17 
18 #ifdef MFEM_USE_ADIOS2
19 
20 #include "../fem/geom.hpp"
21 #include "../general/array.hpp"
22 #include "../mesh/element.hpp"
23 #include "../mesh/mesh.hpp"
24 #include "../fem/gridfunc.hpp"
25 
26 #include <algorithm>
27 
28 namespace mfem
29 {
30 
31 namespace
32 {
33 // these functions might be included in adios2 upstream next release
34 template <class T>
35 adios2::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())
40 {
41  adios2::Variable<T> variable = io.InquireVariable<T>(variable_name);
42  if (variable)
43  {
44  if (variable.Count() != count &&
45  variable.ShapeID() == adios2::ShapeID::LocalArray)
46  {
47  variable.SetSelection({start, count});
48  }
49  }
50  else
51  {
52  variable = io.DefineVariable<T>(variable_name, shape, start, count);
53  }
54 
55  return variable;
56 }
57 
58 template <class T>
59 adios2::Attribute<T> SafeDefineAttribute(adios2::IO io,
60  const std::string& attribute_name,
61  const T& value,
62  const std::string& variable_name = "",
63  const std::string separator = "/")
64 {
65  adios2::Attribute<T> attribute = io.InquireAttribute<T>(attribute_name);
66  if (attribute)
67  {
68  return attribute;
69  }
70  return io.DefineAttribute<T>(attribute_name, value, variable_name, separator );
71 }
72 
73 template <class T>
74 adios2::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 = "/")
79 {
80  adios2::Attribute<T> attribute = io.InquireAttribute<T>(attribute_name);
81  if (attribute)
82  {
83  return attribute;
84  }
85  return io.DefineAttribute<T>(attribute_name, values, size, variable_name,
86  separator );
87 }
88 
89 bool SetBoolParameter(const std::string key,
90  const std::map<std::string, std::string>& parameters,
91  const bool default_value) noexcept
92 {
93  auto it = parameters.find(key);
94  if (it != parameters.end())
95  {
96  std::string value = it->second;
97  std::transform(value.begin(), value.end(), value.begin(), ::tolower);
98  if (value == "on" || value == "true")
99  {
100  return true;
101  }
102  else if ( value == "off" || value == "false")
103  {
104  return false;
105  }
106  }
107  return default_value;
108 }
109 
110 } //end empty namespace
111 
112 // PUBLIC
113 #ifdef MFEM_USE_MPI
114 adios2stream::adios2stream(const std::string& name, const openmode mode,
115  MPI_Comm comm, const std::string engineType)
116  : name(name),
117  adios2_openmode(mode),
118  adios(new adios2::ADIOS(comm)),
119  io(adios->DeclareIO(name))
120 {
121  io.SetEngine(engineType);
122 }
123 #else
124 adios2stream::adios2stream(const std::string& name, const openmode mode,
125  const std::string engineType)
126  : name(name),
127  adios2_openmode(mode),
128  adios(new adios2::ADIOS()),
129  io(adios->DeclareIO(name))
130 {
131  io.SetEngine(engineType);
132 }
133 #endif
134 
136 {
137  if (engine)
138  {
139  SafeDefineAttribute<std::string>(io, "vtk.xml", VTKSchema() );
140  engine.Close();
141  }
142 }
143 
145  const std::map<std::string, std::string>& parameters)
146 {
147  io.SetParameters(parameters);
148  refine = SetBoolParameter("RefinedData", parameters, true);
149 }
150 
151 void adios2stream::SetParameter(const std::string key,
152  const std::string value) noexcept
153 {
154  io.SetParameter(key, value);
155  if (key == "RefinedData")
156  {
157  refine = SetBoolParameter("RefinedData", io.Parameters(), true);
158  }
159 }
160 
162 {
163  if (!engine)
164  {
165  engine = io.Open(name, adios2::Mode::Write);
166  }
167  engine.BeginStep();
168  active_step = true;
169 }
170 
172 {
173  if (!engine || !active_step)
174  {
175  const std::string message = "MFEM adios2stream error: calling EndStep "
176  "on uninitialized step (need BeginStep)";
177  mfem_error(message.c_str());
178  }
179 
180  SafeDefineAttribute<std::string>(io, "vtk.xml", VTKSchema() );
181  engine.EndStep();
182  active_step = false;
183 }
184 
185 void adios2stream::SetTime(const double time)
186 {
187  adios2::Variable<double> var_time = SafeDefineVariable<double>(io, "TIME");
188  engine.Put(var_time, time);
189  transient = true;
190 }
191 
192 void adios2stream::SetCycle(const int cycle)
193 {
194  adios2::Variable<int> var_cycle = SafeDefineVariable<int>(io,"CYCLE");
195  engine.Put(var_cycle, cycle);
196 }
197 
198 void adios2stream::SetRefinementLevel(const int level) noexcept
199 {
200  refinement_level = level;
201 }
202 
204 {
205  return engine.CurrentStep();
206 }
207 
209 {
210  if (engine)
211  {
212  if (!active_step)
213  {
214  SafeDefineAttribute<std::string>(io, "vtk.xml", VTKSchema() );
215  }
216  engine.Close();
217  }
218  if (adios)
219  {
220  adios.reset();
221  }
222 }
223 
224 
225 // PROTECTED (accessible by friend class Mesh)
226 void adios2stream::Print(const Mesh& mesh, const mode print_mode)
227 {
228  auto lf_DefineMeshMetadata = [this](Mesh& mesh)
229  {
230  // check types are constant
231  if (!IsConstantElementType(mesh.elements))
232  {
233  throw std::invalid_argument("MFEM::adios2stream ERROR: non-constant "
234  " element types not yet implemented\n");
235  }
236 
237  // format info
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); //for now
243  if (mesh.NURBSext)
244  {
245  mesh_type = "MFEM NURBS";
246  viz_tools.push_back("NONE");
247  }
248  else if (mesh.ncmesh)
249  {
250  mesh_type = "MFEM mesh v1.1";
251  viz_tools.push_back("NONE");
252  }
253  else
254  {
255  mesh_type = "MFEM mesh v1.0";
256  viz_tools.push_back("Paraview: ADIOS2VTXReader");
257  viz_tools.push_back("VTK: vtkADIOS2VTXReader.h");
258  }
259 
260  SafeDefineAttribute<std::string>(io, "format/mfem_mesh", mesh_type );
261  SafeDefineAttribute<std::string>(io, "format/viz_tools", viz_tools.data(),
262  viz_tools.size() );
263 
264  // elements
265  const uint32_t dimension = static_cast<int32_t>(mesh.Dimension());
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;
272 
273  if (refine)
274  {
275  for (int i = 0; i < mesh.GetNE(); ++i)
276  {
277  const Geometry::Type type = mesh.GetElementBaseGeometry(i);
278  RefinedGeometry* refined_geometry = GlobGeometryRefiner.Refine(type,
279  refinement_level, 1);
280  if (refined_geometry == nullptr)
281  {
282  mfem_error("ERROR: could not refine geometry in call to Save with adios2stream \n");
283  }
284 
285 
286  element_nvertices = static_cast<size_t>(Geometries.GetVertices(
287  type)->GetNPoints());
288  nelements += refined_geometry->RefGeoms.Size() / element_nvertices;
289  nvertices += refined_geometry->RefPts.GetNPoints();
290  }
291 
292  refined_mesh_nelements = nelements;
293  refined_mesh_nvertices = nvertices;
294  }
295  else
296  {
297  nelements = static_cast<size_t>(mesh.GetNE());
298  element_nvertices = static_cast<size_t>(mesh.elements[0]->GetNVertices());
299  }
300  SafeDefineVariable<uint64_t>(io, "connectivity", {}, {}, {nelements, element_nvertices+1});
301  SafeDefineVariable<int32_t>(io, "attribute", {}, {}, {nelements});
302 
303  // vertices
304  SafeDefineVariable<uint32_t>(io,"NumOfVertices", {adios2::LocalValueDim});
305  if (refine)
306  {
307  SafeDefineVariable<double>( io, "vertices", {}, {}, {nvertices, static_cast<size_t>(dimension)});
308  }
309  else
310  {
311  const GridFunction* grid_function = mesh.GetNodes();
312  if (grid_function == nullptr)
313  {
314  const size_t nVertices = static_cast<size_t>(mesh.GetNV());
315  const size_t spaceDim = static_cast<size_t>(mesh.SpaceDimension());
316  // similar to Ordering::byVDIM
317  SafeDefineVariable<double>( io, "vertices", {}, {}, {nVertices, spaceDim});
318  }
319  else
320  {
321  const size_t size = static_cast<size_t>(grid_function->Size());
322  const FiniteElementSpace* fes = grid_function->FESpace();
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} );
326 
327  if (fes->GetOrdering() == Ordering::byNODES)
328  {
329  ordering_by_node = true;
330  }
331  }
332  }
333  };
334 
335  auto lf_PrintRefinedMeshData = [this](Mesh& mesh)
336  {
337  // elements and vertices
338  engine.Put("NumOfElements", static_cast<uint32_t>(refined_mesh_nelements));
339  engine.Put("NumOfVertices", static_cast<uint32_t>(refined_mesh_nvertices));
340 
341  const uint32_t vtkType =
342  GLVISToVTKType(static_cast<int>(mesh.elements[0]->GetGeometryType()));
343  engine.Put("types", vtkType);
344 
345  adios2::Variable<double> var_vertices = io.InquireVariable<double>("vertices");
346  adios2::Variable<double>::Span span_vertices = engine.Put<double>(var_vertices);
347 
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>
351  (var_connectivity);
352 
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);
357 
358  size_t span_vertices_offset = 0;
359  size_t span_connectivity_offset = 0;
360  size_t span_element_attribute_offset = 0;
361  // use for setting absolute node id for each element
362  size_t point_id = 0;
363  DenseMatrix pmatrix;
364 
365  for (int e = 0; e < mesh.GetNE(); ++e)
366  {
367  const Geometry::Type type = mesh.GetElementBaseGeometry(e);
368  RefinedGeometry* refined_geometry = GlobGeometryRefiner.Refine(type,
369  refinement_level, 1);
370  // vertices
371  mesh.GetElementTransformation(e)->Transform(refined_geometry->RefPts, pmatrix);
372  for (int i = 0; i < pmatrix.Width(); ++i)
373  {
374  for (int j = 0; j < pmatrix.Height(); ++j)
375  {
376  span_vertices[span_vertices_offset + i*pmatrix.Height() + j] = pmatrix(j, i);
377  }
378  }
379  span_vertices_offset += static_cast<size_t>(pmatrix.Width()*pmatrix.Height());
380 
381  // element attribute
382  const int element_attribute = mesh.GetAttribute(e);
383 
384  // connectivity
385  const int nv = Geometries.GetVertices(type)->GetNPoints();
386  const Array<int> &element_vertices = refined_geometry->RefGeoms;
387 
388  for (int v = 0; v < element_vertices.Size();)
389  {
390  span_connectivity[span_connectivity_offset] = static_cast<uint64_t>(nv);
391  ++span_connectivity_offset;
392 
393  span_element_attribute[span_element_attribute_offset] = static_cast<int32_t>
394  (element_attribute);
395  ++span_element_attribute_offset;
396 
397  for (int k =0; k < nv; k++, v++ )
398  {
399  span_connectivity[span_connectivity_offset] = static_cast<uint64_t>
400  (point_id + element_vertices[v]);
401  ++span_connectivity_offset;
402  }
403  }
404 
405  point_id += static_cast<size_t>(refined_geometry->RefPts.GetNPoints());
406  }
407 
408  for (int e = 0; e < mesh.GetNE(); ++e)
409  {
410  const Geometry::Type type = mesh.GetElementBaseGeometry(e);
411  RefinedGeometry* refined_geometry = GlobGeometryRefiner.Refine(type,
412  refinement_level, 1);
413  }
414  };
415 
416  auto lf_PrintMeshData = [&](Mesh& mesh)
417  {
418  if (refine)
419  {
420  lf_PrintRefinedMeshData(mesh);
421  return;
422  }
423 
424  // elements
425  engine.Put("NumOfElements", static_cast<uint32_t>(mesh.GetNE()));
426 
427  const uint32_t vtkType =
428  GLVISToVTKType(static_cast<int>(mesh.elements[0]->GetGeometryType()));
429  engine.Put("types", vtkType);
430 
431  adios2::Variable<uint64_t> varConnectivity =
432  io.InquireVariable<uint64_t>("connectivity");
433  // zero-copy access to adios2 buffer to put non-contiguous to contiguous memory
434  adios2::Variable<uint64_t>::Span spanConnectivity =
435  engine.Put<uint64_t>(varConnectivity);
436 
437  adios2::Variable<int32_t> varElementAttribute =
438  io.InquireVariable<int32_t>("attribute");
439  // zero-copy access to adios2 buffer to put non-contiguous to contiguous memory
440  adios2::Variable<int32_t>::Span spanElementAttribute =
441  engine.Put<int32_t>(varElementAttribute);
442 
443  size_t elementPosition = 0;
444  for (int e = 0; e < mesh.GetNE(); ++e)
445  {
446  spanElementAttribute[e] = static_cast<int32_t>(mesh.GetAttribute(e));
447 
448  const int nVertices = mesh.elements[e]->GetNVertices();
449  spanConnectivity[elementPosition] = nVertices;
450  for (int v = 0; v < nVertices; ++v)
451  {
452  spanConnectivity[elementPosition + v + 1] =
453  mesh.elements[e]->GetVertices()[v];
454  }
455  elementPosition += nVertices + 1;
456  }
457 
458  // vertices
459  engine.Put("NumOfVertices", static_cast<uint32_t>(mesh.GetNV()));
460 
461  if (mesh.GetNodes() == nullptr)
462  {
463  adios2::Variable<double> varVertices = io.InquireVariable<double>("vertices");
464  // zero-copy access to adios2 buffer to put non-contiguous to contiguous memory
465  adios2::Variable<double>::Span spanVertices = engine.Put(varVertices);
466 
467  for (int v = 0; v < mesh.GetNV(); ++v)
468  {
469  const int space_dim = mesh.SpaceDimension();
470  for (int coord = 0; coord < space_dim; ++coord)
471  {
472  spanVertices[v * space_dim + coord] = mesh.vertices[v](coord);
473  }
474  }
475  }
476  else
477  {
478  const GridFunction* grid_function = mesh.GetNodes();
479  if (ordering_by_node)
480  {
481  adios2::Variable<double> varVertices = io.InquireVariable<double>("vertices");
482  // zero-copy access to adios2 buffer to put non-contiguous to contiguous memory
483  adios2::Variable<double>::Span spanVertices = engine.Put(varVertices);
484 
485  const size_t size = static_cast<size_t>(grid_function->Size());
486  const FiniteElementSpace* fes = grid_function->FESpace();
487  const size_t components = static_cast<size_t>(fes->GetVDim());
488  const size_t tuples = size /components;
489 
490  const double* data = grid_function->GetData();
491 
492  for (size_t i = 0; i < tuples; ++i)
493  {
494  for (size_t j = 0; j < components; ++j)
495  {
496  spanVertices[i*components + j] = data[j*tuples + i];
497  }
498  }
499  }
500  else
501  {
502  grid_function->Print(*this, "vertices");
503  }
504  }
505  };
506 
507  // BODY OF FUNCTION STARTS HERE
508  try
509  {
510  Mesh ref_mesh(mesh);
511  lf_DefineMeshMetadata(ref_mesh);
512 
513  if (!engine) // if Engine is closed
514  {
515  engine = io.Open(name, adios2::Mode::Write);
516  }
517 
518  lf_PrintMeshData(ref_mesh);
519 
520  if (print_mode == mode::sync)
521  {
522  engine.PerformPuts();
523  }
524  }
525  catch (std::exception& e)
526  {
527  const std::string warning =
528  "MFEM: adios2stream exception caught, invalid bp dataset: " + name +
529  "," + e.what();
530  mfem_warning( warning.c_str());
531  }
532 }
533 
534 void adios2stream::Save(const GridFunction& grid_function,
535  const std::string& variable_name, const data_type type)
536 {
537  auto lf_SafeDefine = [&](const std::string& variable_name,
538  const size_t tuples, const size_t components,
539  const Ordering::Type ordering,
540  const std::string& fespace_name)
541  {
542  adios2::Variable<double> var = io.InquireVariable<double>(variable_name);
543  if (!var)
544  {
545  if (components == 1 && type == adios2stream::data_type::point_data)
546  {
547  io.DefineVariable<double>(variable_name, {}, {}, {tuples*components});
548  }
549  else
550  {
551  const adios2::Dims count = (ordering == Ordering::byNODES) ?
552  adios2::Dims{components, tuples} :
553  adios2::Dims{tuples, components};
554  io.DefineVariable<double>(variable_name, {}, {}, count);
555  }
556  SafeDefineAttribute<std::string>(io, "FiniteElementSpace",
557  fespace_name, variable_name);
558 
559  }
560  };
561 
562  // BODY OF FUNCTION STARTS HERE
563  const std::map<std::string, std::string> parameters = io.Parameters();
564  const bool full_data = SetBoolParameter("FullData", parameters, false);
565 
566  if (!full_data && !refine)
567  {
568  return;
569  }
570 
571  const FiniteElementSpace* fes = grid_function.FESpace();
572 
573  if (refine)
574  {
575  const Mesh *mesh = fes->GetMesh();
576  const size_t components = static_cast<size_t>(grid_function.VectorDim());
577  // const size_t tuples = static_cast<size_t>(mesh->GetNV());
578  const size_t tuples = refined_mesh_nvertices;
579 
580  lf_SafeDefine(variable_name, tuples, components,
581  Ordering::byVDIM, std::string(fes->FEColl()->Name()));
583  {
584  point_data_variables.insert(variable_name);
585  }
586 
587  RefinedGeometry* refined_geometry;
588  DenseMatrix transform;
589 
590  // zero-copy access to adios2 buffer to put non-contiguous to contiguous memory
591  adios2::Variable<double> variable = io.InquireVariable<double>(variable_name);
592  adios2::Variable<double>::Span span = engine.Put<double>(variable);
593 
594  size_t offset = 0;
595  if (components == 1)
596  {
597  Vector scalar;
598 
599  const int nelements = mesh->GetNE();
600  for (int e = 0; e < nelements; ++e)
601  {
602  refined_geometry = GlobGeometryRefiner.Refine(
603  mesh->GetElementBaseGeometry(e), refinement_level, 1);
604 
605  grid_function.GetValues(e, refined_geometry->RefPts, scalar, transform);
606 
607  const int size = scalar.Size();
608 
609  for (int i = 0; i < size; ++i)
610  {
611  const double value = scalar(i);
612  span.at(offset+i) = value;
613  }
614  offset += static_cast<size_t>(size);
615  }
616  }
617  else
618  {
619  DenseMatrix vector;
620  for (int e = 0; e < mesh->GetNE(); ++e)
621  {
622  refined_geometry = GlobGeometryRefiner.Refine(
623  mesh->GetElementBaseGeometry(e), refinement_level, 1);
624  grid_function.GetVectorValues(e, refined_geometry->RefPts, vector, transform);
625 
626  for (int i = 0; i < vector.Width(); ++i)
627  {
628  for (int j = 0; j < vector.Height(); ++j)
629  {
630  span[offset + i*vector.Height() + j] = vector(j, i);
631  }
632  }
633  offset += static_cast<size_t>(vector.Width()*vector.Height());
634  }
635  }
636  }
637 
638  if (full_data)
639  {
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,
644  fes->GetOrdering(),
645  std::string(fes->FEColl()->Name()) );
646  // calls Vector::Print
647  grid_function.Print(*this, variable_name+"/full");
648 
649  if (!refine && type == adios2stream::data_type::point_data)
650  {
651  point_data_variables.insert(variable_name+"/full");
652  }
653  }
654 }
655 
656 // PRIVATE
657 int32_t adios2stream::GLVISToVTKType(
658  const int glvisType) const noexcept
659 {
660  uint32_t vtkType = 0;
661  switch (glvisType)
662  {
663  case Geometry::Type::POINT:
664  vtkType = 1;
665  break;
666  case Geometry::Type::SEGMENT:
667  vtkType = 3;
668  break;
669  case Geometry::Type::TRIANGLE:
670  vtkType = 5;
671  break;
672  case Geometry::Type::SQUARE:
673  // vtkType = 8;
674  vtkType = 9;
675  break;
676  case Geometry::Type::TETRAHEDRON:
677  vtkType = 10;
678  break;
679  case Geometry::Type::CUBE:
680  // vtkType = 11;
681  vtkType = 12;
682  break;
683  case Geometry::Type::PRISM:
684  vtkType = 13;
685  break;
686  default:
687  vtkType = 0;
688  break;
689  }
690  return vtkType;
691 }
692 
693 bool adios2stream::IsConstantElementType(const Array<Element*>& elements ) const
694 noexcept
695 {
696  bool isConstType = true;
697  const Geometry::Type type = elements[0]->GetGeometryType();
698 
699  for (int e = 1; e < elements.Size(); ++e)
700  {
701  if (type != elements[e]->GetGeometryType())
702  {
703  isConstType = false;
704  break;
705  }
706  }
707  return isConstType;
708 }
709 
710 std::string adios2stream::VTKSchema() const noexcept
711 {
712  std::string vtkSchema = R"( <?xml version="1.0"?> <VTKFile type="UnstructuredGrid" version="0.2" byte_order="LittleEndian"> <UnstructuredGrid> <Piece NumberOfPoints="NumOfVertices" NumberOfCells="NumOfElements"> <Points> <DataArray Name="vertices" />)";
713 
714  vtkSchema += R"( </Points> <CellData> <DataArray Name="attribute" /> </CellData> <Cells> <DataArray Name="connectivity" /> <DataArray Name="types" /> </Cells> <PointData>)";
715 
716  if (point_data_variables.empty())
717  {
718  vtkSchema += "\n";
719  }
720  else
721  {
722  for (const std::string& point_datum : point_data_variables )
723  {
724  vtkSchema += " <DataArray Name=\"" + point_datum +"\"/>\n";
725  }
726  }
727 
728  if (transient)
729  {
730  vtkSchema += " <DataArray Name=\"TIME\">\n";
731  vtkSchema += " TIME\n";
732  vtkSchema += " </DataArray>\n";
733  }
734 
735  vtkSchema += R"( </PointData> </Piece> </UnstructuredGrid> </VTKFile>)";
736 
737  return vtkSchema;
738 }
739 
740 adios2::Mode adios2stream::ToADIOS2Mode(const adios2stream::openmode mode) const
741 noexcept
742 {
743  adios2::Mode adios2Mode = adios2::Mode::Undefined;
744  switch (mode)
745  {
747  adios2Mode = adios2::Mode::Write;
748  break;
750  adios2Mode = adios2::Mode::Read;
751  break;
752  default:
753  const std::string message = "MFEM adios2stream ERROR: only "
754  "openmode::out and openmode::in "
755  " are valid, in call to adios2stream constructor";
756  mfem_error(message.c_str());
757  }
758  return adios2Mode;
759 }
760 
761 } // end namespace mfem
762 
763 #endif // MFEM_USE_ADIOS2
764 
int GetNPoints() const
Returns the number of the points in the integration rule.
Definition: intrules.hpp:247
Ordering::Type GetOrdering() const
Return the ordering method.
Definition: fespace.hpp:599
int Size() const
Return the logical size of the array.
Definition: array.hpp:138
void Save(const GridFunction &grid_function, const std::string &variable_name, const data_type type)
void GetVectorValues(int i, const IntegrationRule &ir, DenseMatrix &vals, DenseMatrix &tr) const
Definition: gridfunc.cpp:706
Class for grid function - Vector with associated FE space.
Definition: gridfunc.hpp:30
void SetTime(const double time)
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
Definition: operator.hpp:73
int VectorDim() const
Definition: gridfunc.cpp:324
T * Write(Memory< T > &mem, int size, bool on_dev=true)
Get a pointer for write access to mem with the mfem::Device&#39;s DeviceMemoryClass, if on_dev = true...
Definition: device.hpp:336
Data type dense matrix using column-major storage.
Definition: densemat.hpp:23
int Size() const
Returns the size of the vector.
Definition: vector.hpp:200
int GetNE() const
Returns number of elements.
Definition: mesh.hpp:923
double * GetData() const
Return a pointer to the beginning of the Vector data.
Definition: vector.hpp:209
Geometry::Type GetElementBaseGeometry(int i) const
Definition: mesh.hpp:1069
void Print(const Mesh &mesh, const adios2stream::mode print_mode=mode::sync)
const IntegrationRule * GetVertices(int GeomType)
Return an IntegrationRule consisting of all vertices of the given Geometry::Type, GeomType...
Definition: geom.cpp:265
void SetParameter(const std::string key, const std::string value) noexcept
Geometry Geometries
Definition: fe.cpp:49
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
Definition: operator.hpp:67
Mesh * GetMesh() const
Returns the mesh.
Definition: fespace.hpp:441
void mfem_error(const char *msg)
Function called when an error is encountered. Used by the macros MFEM_ABORT, MFEM_ASSERT, MFEM_VERIFY.
Definition: error.cpp:154
Type
Ordering methods:
Definition: fespace.hpp:33
GeometryRefiner GlobGeometryRefiner
Definition: geom.cpp:1773
void SetRefinementLevel(const int level) noexcept
IntegrationRule RefPts
Definition: geom.hpp:282
RefinedGeometry * Refine(Geometry::Type Geom, int Times, int ETimes=1)
Definition: geom.cpp:1099
void GetValues(int i, const IntegrationRule &ir, Vector &vals, int vdim=1) const
Definition: gridfunc.cpp:513
void SetCycle(const int cycle)
int GetVDim() const
Returns vector dimension.
Definition: fespace.hpp:581
FiniteElementSpace * FESpace()
Definition: gridfunc.hpp:668
const T * Read(const Memory< T > &mem, int size, bool on_dev=true)
Get a pointer for read access to mem with the mfem::Device&#39;s DeviceMemoryClass, if on_dev = true...
Definition: device.hpp:319
int Dimension() const
Definition: mesh.hpp:1006
int SpaceDimension() const
Definition: mesh.hpp:1007
void Print(std::ostream &out=mfem::out, int width=8) const
Prints vector to stream out.
Definition: vector.cpp:724
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Definition: fespace.hpp:96
size_t CurrentStep() const
void SetParameters(const std::map< std::string, std::string > &parameters=std::map< std::string, std::string >())
Array< Vertex > vertices
Definition: mesh.hpp:90
Array< Element * > elements
Definition: mesh.hpp:85
NURBSExtension * NURBSext
Optional NURBS mesh extension.
Definition: mesh.hpp:272
int GetNV() const
Returns number of vertices. Vertices are only at the corners of elements, where you would expect them...
Definition: mesh.hpp:920
virtual const char * Name() const
Definition: fe_coll.hpp:65
void mfem_warning(const char *msg)
Function called by the macro MFEM_WARNING.
Definition: error.cpp:187
void GetElementTransformation(int i, IsoparametricTransformation *ElTr)
Definition: mesh.cpp:348
constexpr int dimension
This example only works in 3D. Kernels for 2D are not implemented.
Definition: hooke.cpp:45
NCMesh * ncmesh
Optional nonconforming mesh extension.
Definition: mesh.hpp:273
Vector data type.
Definition: vector.hpp:60
const FiniteElementCollection * FEColl() const
Definition: fespace.hpp:601
adios2stream(const std::string &name, const openmode mode, MPI_Comm comm, const std::string engine_type="BPFile")
void GetNodes(Vector &node_coord) const
Definition: mesh.cpp:7908
int GetAttribute(int i) const
Return the attribute of element i.
Definition: mesh.hpp:1480
Array< int > RefGeoms
Definition: geom.hpp:283