27#define mkdir(dir, mode) _mkdir(dir)
35 const Mesh *mesh,
int myid)
38 const char path_delim =
'/';
39 std::string::size_type pos = 0;
47 pos = dir_name.find(path_delim, pos+1);
48 std::string subdir = dir_name.substr(0, pos);
51 err_flag = mkdir(subdir.c_str(), 0777);
52 err_flag = (err_flag && (errno != EEXIST)) ? 1 : 0;
54 if (
myid == 0 || pmesh == NULL)
56 err_flag = mkdir(subdir.c_str(), 0777);
57 err_flag = (err_flag && (errno != EEXIST)) ? 1 : 0;
61 while ( pos != std::string::npos );
66 MPI_Bcast(&err_flag, 1, MPI_INT, 0, pmesh->
GetComm());
77 std::string::size_type pos = collection_name.find_last_of(
'/');
78 if (pos == std::string::npos)
80 name = collection_name;
86 name = collection_name.substr(pos+1);
149 MPI_Comm_rank(comm, &
myid);
162 default: MFEM_ABORT(
"unknown format: " << fmt);
171 MFEM_VERIFY(!
compression,
"ZLib not enabled in MFEM build.");
193 MFEM_ABORT(
"this method is not implemented");
200 if (
error) {
return; }
226 MFEM_WARNING(
"Error creating directory: " << dir_name);
247 MFEM_WARNING(
"Error writing mesh to file: " << mesh_name);
269 std::string file_name = dir_name +
"/" + field_name;
282 (it->second)->
Save(field_file);
286 MFEM_WARNING(
"Error writing field to file: " << it->first);
295 (it->second)->
Save(q_field_file);
299 MFEM_WARNING(
"Error writing q-field to file: " << it->first);
380 const std::string& collection_name,
385 MPI_Comm_rank(comm, &
myid);
410 MPI_Comm_rank(comm, &
myid);
425 for (
int e=0; e<gf->
FESpace()->GetNE(); e++)
441 for (
int e=0; e<qf->
GetSpace()->GetNE(); e++)
447 LOD = std::max(LOD,locLOD);
479 if (
myid != 0) {
return; }
484 std::ofstream root_file(root_name);
489 MFEM_WARNING(
"Error writing VisIt root file: " << root_name);
506 MFEM_WARNING(
"Cannot load parallel VisIt root file in serial.");
509 if (
m_comm == MPI_COMM_NULL)
511 MFEM_WARNING(
"Cannot load parallel VisIt root file without MPI"
520 MPI_Comm_size(
m_comm, &comm_size);
523 MFEM_WARNING(
"Processor number mismatch: VisIt root file: "
524 <<
num_procs <<
", MPI_comm: " << comm_size);
550 std::ifstream root_file(root_name);
551 std::stringstream buffer;
552 buffer << root_file.rdbuf();
556 MFEM_WARNING(
"Error reading the VisIt root file: " << root_name);
574 MFEM_WARNING(
"Unable to open mesh file: " << mesh_fname);
590 MFEM_WARNING(
"Reading parallel format in serial is not supported");
609 std::string fname = path_left + it->first + path_right;
615 MFEM_WARNING(
"Unable to open field file: " << fname);
621 if ((it->second).association ==
"nodes")
625 else if ((it->second).association ==
"elements")
633 if ((it->second).association ==
"nodes")
639 else if ((it->second).association ==
"elements")
645 MFEM_WARNING(
"Reading parallel format in serial is not supported");
655 std::string path_str =
659 picojson::object top, dsets,
main,
mesh, fields, field, mtags, ftags;
662 std::string file_ext_format =
".%0" + to_string(
pad_digits_rank) +
"d";
663 mtags[
"spatial_dim"] = picojson::value(to_string(
spatial_dim));
664 mtags[
"topo_dim"] = picojson::value(to_string(
topo_dim));
668 mesh[
"tags"] = picojson::value(mtags);
669 mesh[
"format"] = picojson::value(to_string(
format));
675 ftags[
"assoc"] = picojson::value((it->second).association);
676 ftags[
"comps"] = picojson::value(to_string((it->second).num_components));
677 ftags[
"lod"] = picojson::value(to_string((it->second).lod));
678 field[
"path"] = picojson::value(path_str + it->first + file_ext_format);
679 field[
"tags"] = picojson::value(ftags);
680 fields[it->first] = picojson::value(field);
683 main[
"cycle"] = picojson::value(
double(
cycle));
684 main[
"time"] = picojson::value(
time);
687 main[
"mesh"] = picojson::value(
mesh);
690 main[
"fields"] = picojson::value(fields);
693 dsets[
"main"] = picojson::value(
main);
694 top[
"dsets"] = picojson::value(dsets);
696 return picojson::value(top).serialize(
true);
701 picojson::value top, dsets,
main,
mesh, fields;
702 std::string parse_err = picojson::parse(top, json);
703 if (!parse_err.empty())
706 MFEM_WARNING(
"Unable to parse VisIt root data.");
711 dsets = top.get(
"dsets");
712 main = dsets.get(
"main");
713 cycle = int(
main.get(
"cycle").get<
double>());
714 time =
main.get(
"time").get<
double>();
715 if (
main.contains(
"time_step"))
721 fields =
main.get(
"fields");
726 std::string path =
mesh.get(
"path").get<std::string>();
727 size_t right_sep = path.rfind(
'_');
728 if (right_sep == std::string::npos)
731 MFEM_WARNING(
"Unable to parse VisIt root data.");
734 name = path.substr(0, right_sep);
736 if (
mesh.contains(
"format"))
743 to_int(
mesh.get(
"tags").get(
"max_lods").get<std::string>());
747 if (fields.is<picojson::object>())
749 picojson::object fields_obj = fields.get<picojson::object>();
750 for (picojson::object::iterator it = fields_obj.begin();
751 it != fields_obj.end(); ++it)
753 picojson::value tags = it->second.get(
"tags");
756 to_int(tags.get(
"comps").get<std::string>()));
767 high_order_output(false),
772 compression_level = -1;
782 levels_of_detail = levels_of_detail_;
787 MFEM_WARNING(
"ParaViewDataCollection::Load() is not implemented!");
811 const std::string &prefix)
813 return prefix +
".pvtu";
817 const std::string &prefix,
int rank)
834 MFEM_WARNING(
"Error creating directory: " << path);
844 if (
myid == 0 && !pvd_stream.is_open())
848 bool write_header =
true;
849 std::ifstream pvd_in;
850 if (restart_mode && (pvd_in.open(pvdname,std::ios::binary),pvd_in.good()))
854 std::fstream::pos_type pos_begin = pvd_in.tellg();
855 std::fstream::pos_type pos_end = pos_begin;
857 std::regex regexp(
"timestep=\"([^[:space:]]+)\".*file=\"Cycle(\\d+)");
861 while (getline(pvd_in,line))
863 if (regex_search(line,match,regexp))
865 MFEM_ASSERT(match.size() == 3,
"Unable to parse DataSet");
866 double tvalue = std::stod(match[1]);
867 if (tvalue >=
GetTime()) {
break; }
868 int cvalue = std::stoi(match[2]);
870 " is too small for restart mode: trying to overwrite"
872 pos_end = pvd_in.tellg();
878 size_t count = pos_end - pos_begin;
881 write_header =
false;
882 std::vector<char> buf(count);
886 pvd_in.seekg(pos_begin);
887 pvd_in.read(buf.data(), count);
892 pvd_stream.open(pvdname,std::ios::out|std::ios::trunc|std::ios::binary);
893 pvd_stream.write(buf.data(), count);
896 pvd_stream.open(pvdname,std::ios::in|std::ios::out|std::ios::ate);
902 pvd_stream.open(pvdname,std::ios::out|std::ios::trunc);
903 pvd_stream <<
"<?xml version=\"1.0\"?>\n";
904 pvd_stream <<
"<VTKFile type=\"Collection\" version=\"0.1\"";
905 pvd_stream <<
" byte_order=\"" <<
VTKByteOrder() <<
"\">\n";
906 pvd_stream <<
"<Collection>" << std::endl;
923 const std::string &field_name = qfield.first;
939 pvtu_out <<
"<PPointData>\n";
942 int vec_dim = field_it.second->VectorDim();
944 <<
"\" Name=\"" << field_it.first
945 <<
"\" NumberOfComponents=\"" << vec_dim <<
"\" "
948 pvtu_out <<
"</PPointData>\n";
950 pvtu_out <<
"<PCellData>\n";
951 pvtu_out <<
"\t<PDataArray type=\"Int32\" Name=\"" <<
"attribute"
952 <<
"\" NumberOfComponents=\"1\""
954 pvtu_out <<
"</PCellData>\n";
960 pvd_stream <<
"<DataSet timestep=\"" <<
GetTime()
961 <<
"\" group=\"\" part=\"" << 0 <<
"\" file=\""
963 <<
"\" name=\"mesh\"/>\n";
969 const std::string &q_field_name = q_field.first;
973 std::ofstream pvtu_out(col_path +
"/" + q_fname);
975 int vec_dim = q_field.second->GetVDim();
976 pvtu_out <<
"<PPointData>\n";
978 <<
"\" Name=\"" << q_field_name
979 <<
"\" NumberOfComponents=\"" << vec_dim <<
"\" "
981 pvtu_out <<
"</PPointData>\n";
984 pvd_stream <<
"<DataSet timestep=\"" <<
GetTime()
985 <<
"\" group=\"\" part=\"" << 0 <<
"\" file=\""
986 << q_fname <<
"\" name=\"" << q_field_name <<
"\"/>\n";
991 std::fstream::pos_type pos = pvd_stream.tellp();
992 pvd_stream <<
"</Collection>\n";
993 pvd_stream <<
"</VTKFile>" << std::endl;
994 pvd_stream.seekp(pos);
1000 os <<
"<?xml version=\"1.0\"?>\n";
1001 os <<
"<VTKFile type=\"PUnstructuredGrid\"";
1002 os <<
" version =\"0.1\" byte_order=\"" <<
VTKByteOrder() <<
"\">\n";
1003 os <<
"<PUnstructuredGrid GhostLevel=\"0\">\n";
1005 os <<
"<PPoints>\n";
1007 os <<
" Name=\"Points\" NumberOfComponents=\"3\""
1009 os <<
"</PPoints>\n";
1012 os <<
"\t<PDataArray type=\"Int32\" ";
1013 os <<
" Name=\"connectivity\" NumberOfComponents=\"1\""
1015 os <<
"\t<PDataArray type=\"Int32\" ";
1016 os <<
" Name=\"offsets\" NumberOfComponents=\"1\""
1018 os <<
"\t<PDataArray type=\"UInt8\" ";
1019 os <<
" Name=\"types\" NumberOfComponents=\"1\""
1021 os <<
"</PCells>\n";
1025 const std::string &vtu_prefix)
1030 os <<
"<Piece Source=\"" << vtu_filename <<
"\"/>\n";
1032 os <<
"</PUnstructuredGrid>\n";
1033 os <<
"</VTKFile>\n";
1038 os <<
"<VTKFile type=\"UnstructuredGrid\"";
1041 os <<
" compressor=\"vtkZLibDataCompressor\"";
1043 os <<
" version=\"0.1\" byte_order=\"" <<
VTKByteOrder() <<
"\">\n";
1044 os <<
"<UnstructuredGrid>\n";
1048 os <<
"<PointData >\n";
1055 os <<
"</PointData>\n";
1058 os <<
"</UnstructuredGrid>\n";
1059 os <<
"</VTKFile>" << std::endl;
1068 std::vector<char> buf;
1069 int vec_dim = it->second->VectorDim();
1071 <<
"\" Name=\"" << it->first
1072 <<
"\" NumberOfComponents=\"" << vec_dim <<
"\""
1081 it->second->GetValues(i, RefG->
RefPts, val, pmat);
1082 for (
int j = 0; j < val.
Size(); j++)
1095 it->second->GetVectorValues(i, RefG->
RefPts, vval, pmat);
1096 for (
int jj = 0; jj < vval.
Width(); jj++)
1098 for (
int ii = 0; ii < vval.
Height(); ii++)
1112 os <<
"</DataArray>" << std::endl;
1117 pv_data_format = fmt;
1127 high_order_output = high_order_output_;
1132 MFEM_ASSERT(compression_level_ >= -1 && compression_level_ <= 9,
1133 "Compression level must be between -1 and 9 (inclusive).");
1134 compression_level = compression_level_;
1145 restart_mode = restart_mode_;
int cycle
Time cycle; for time-dependent simulations cycle >= 0, otherwise = -1.
real_t time
Physical time (for time-dependent simulations)
QFieldMap::iterator QFieldMapIterator
virtual void SetMesh(Mesh *new_mesh)
Set/change the mesh associated with the collection.
void SaveOneQField(const QFieldMapIterator &it)
Save one q-field to disk, assuming the collection directory exists.
virtual void RegisterQField(const std::string &q_field_name, QuadratureFunction *qf)
Add a QuadratureFunction to the collection.
const std::string & GetCollectionName() const
Get the name of the collection.
bool own_data
Should the collection delete its mesh and fields.
DataCollection(const std::string &collection_name, Mesh *mesh_=NULL)
Initialize the collection with its name and Mesh.
static int create_directory(const std::string &dir_name, const Mesh *mesh, int myid)
int GetCycle() const
Get time cycle (for time-dependent simulations)
GFieldMap::iterator FieldMapIterator
void SaveOneField(const FieldMapIterator &it)
Save one field to disk, assuming the collection directory exists.
void DeleteAll()
Delete data owned by the DataCollection including field information.
virtual void RegisterField(const std::string &field_name, GridFunction *gf)
Add a grid function to the collection.
static const int precision_default
Default value for precision.
int pad_digits_cycle
Number of digits used for the cycle and MPI rank in filenames.
bool serial
Serial or parallel run? False iff mesh is a ParMesh.
virtual void SetCompression(bool comp)
Set the flag for use of gz compressed files.
std::string prefix_path
A path where the directory with results is saved. If not empty, it has '/' at the end.
std::string GetFieldFileName(const std::string &field_name) const
int myid
MPI rank (in parallel)
static const int pad_digits_default
Default value for pad_digits_*.
real_t time_step
Time step i.e. delta_t (for time-dependent simulations)
int num_procs
Number of MPI ranks (in parallel)
std::string GetMeshShortFileName() const
virtual void Load(int cycle_=0)
Load the collection. Not implemented in the base class DataCollection.
virtual void SetFormat(int fmt)
Set the desired output mesh and data format.
void SetPrefixPath(const std::string &prefix)
Set the path where the DataCollection will be saved.
virtual ~DataCollection()
Delete the mesh and fields if owned by the collection.
std::string GetMeshFileName() const
void DeleteData()
Delete data owned by the DataCollection keeping field information.
bool appendRankToFileName
Append rank to any output file names.
std::string name
Name of the collection, used as a directory name when saving.
virtual void Save()
Save the collection to disk.
virtual void SaveField(const std::string &field_name)
Save one field, assuming the collection directory already exists.
MPI_Comm m_comm
Associated MPI communicator.
Mesh * mesh
The (common) mesh for the collected fields.
virtual void SaveMesh()
Save the mesh, creating the collection directory.
int precision
Precision (number of digits) used for the text output of doubles.
int format
Output mesh format: see the Format enumeration.
virtual void SaveQField(const std::string &q_field_name)
Save one q-field, assuming the collection directory already exists.
real_t GetTime() const
Get physical time (for time-dependent simulations)
Data type dense matrix using column-major storage.
const NURBSExtension * GetNURBSext() const
virtual const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th element in t...
int GetOrder() const
Returns the order of the finite element. In the case of anisotropic orders, returns the maximum order...
RefinedGeometry * Refine(Geometry::Type Geom, int Times, int ETimes=1)
static int GetRefinementLevelFromElems(Geometry::Type geom, int Npts)
Get the Refinement level based on number of elements.
Class for grid function - Vector with associated FE space.
FiniteElementSpace * FESpace()
int GetNPoints() const
Returns the number of the points in the integration rule.
NURBSExtension * NURBSext
Optional NURBS mesh extension.
virtual void Print(std::ostream &os=mfem::out, const std::string &comments="") const
int GetNE() const
Returns number of elements.
int Dimension() const
Dimension of the reference space used within the elements.
int SpaceDimension() const
Dimension of the physical space containing the mesh.
void PrintVTU(std::ostream &os, int ref=1, VTKFormat format=VTKFormat::ASCII, bool high_order_output=false, int compression_level=0, bool bdr_elements=false)
Geometry::Type GetElementBaseGeometry(int i) const
int GetOrder() const
If all orders are identical, return that number. Otherwise, return NURBSFECollection::VariableOrder.
void Register(const std::string &fname, T *field, bool own_data)
Register field field with name fname.
iterator end()
Returns an end iterator to the registered fields.
iterator begin()
Returns a begin iterator to the registered fields.
void DeleteData(bool own_data)
Clear all associations between names and fields.
void clear()
Clears the map of registered fields without reclaiming memory.
iterator find(const std::string &fname)
Returns an iterator to the field fname.
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().
Class for parallel grid function.
Class for parallel meshes.
void ParPrint(std::ostream &out, const std::string &comments="") const
std::string GenerateCollectionPath()
void WritePVTUHeader(std::ostream &out)
void SetHighOrderOutput(bool high_order_output_)
void UseRestartMode(bool restart_mode_)
void SetCompression(bool compression_) override
virtual void Load(int cycle_=0) override
Load the collection - not implemented in the ParaView writer.
bool IsBinaryFormat() const
Returns true if the output format is BINARY or BINARY32, false if ASCII.
std::string GeneratePVDFileName()
ParaViewDataCollection(const std::string &collection_name, mfem::Mesh *mesh_=NULL)
Constructor. The collection name is used when saving the data.
std::string GenerateVTUPath()
void SaveGFieldVTU(std::ostream &out, int ref_, const FieldMapIterator &it)
const char * GetDataFormatString() const
void WritePVTUFooter(std::ostream &out, const std::string &vtu_prefix)
void SaveDataVTU(std::ostream &out, int ref)
std::string GeneratePVTUPath()
void SetCompressionLevel(int compression_level_)
Set the zlib compression level.
void SetLevelsOfDetail(int levels_of_detail_)
int GetCompressionLevel() const
If compression is enabled, return the compression level, otherwise return 0.
std::string GenerateVTUFileName(const std::string &prefix, int rank)
virtual void Save() override
const char * GetDataTypeString() const
std::string GeneratePVTUFileName(const std::string &prefix)
void SetDataFormat(VTKFormat fmt)
Represents values or vectors of values at quadrature points on a mesh.
QuadratureSpaceBase * GetSpace()
Get the associated QuadratureSpaceBase object.
const IntegrationRule & GetIntRule(int idx) const
Get the IntegrationRule associated with entity (element or face) idx.
Mesh * GetMesh() const
Returns the mesh.
int Size() const
Returns the size of the vector.
void SaveRootFile()
Save a VisIt root file for the collection.
std::string GetVisItRootString()
Prepare the VisIt root file in JSON format for the current collection.
int visit_levels_of_detail
virtual void RegisterQField(const std::string &q_field_name, QuadratureFunction *qf) override
Add a quadrature function to the collection and update the root file.
void LoadVisItRootFile(const std::string &root_name)
VisItDataCollection(const std::string &collection_name, Mesh *mesh_=NULL)
Constructor. The collection name is used when saving the data.
virtual void Load(int cycle_=0) override
Load the collection based on its VisIt data (described in its root file)
void SetLevelsOfDetail(int levels_of_detail)
Set VisIt parameter: default levels of detail for the MultiresControl.
virtual void Save() override
Save the collection and a VisIt root file.
void SetMaxLevelsOfDetail(int max_levels_of_detail)
Set VisIt parameter: maximum levels of detail for the MultiresControl.
std::map< std::string, VisItFieldInfo >::iterator FieldInfoMapIterator
virtual void SetMesh(Mesh *new_mesh) override
Set/change the mesh associated with the collection.
virtual void RegisterField(const std::string &field_name, GridFunction *gf) override
Add a grid function to the collection and update the root file.
std::map< std::string, VisItFieldInfo > field_info_map
void DeleteAll()
Delete all data owned by VisItDataCollection including field data information.
void ParseVisItRootString(const std::string &json)
Read in a VisIt root file in JSON format.
int visit_max_levels_of_detail
Helper class for VisIt visualization data.
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.
GeometryRefiner GlobGeometryRefiner
std::string to_padded_string(int i, int digits)
Convert an integer to a 0-padded string with the given number of digits.
VTKFormat
Data array format for VTK and VTU files.
@ ASCII
Data arrays will be written in ASCII format.
int to_int(const std::string &str)
Convert a string to an int.
void WriteBinaryOrASCII(std::ostream &os, std::vector< char > &buf, const T &val, const char *suffix, VTKFormat format)
Write either ASCII data to the stream or binary data to the buffer depending on the given format.
const char * VTKByteOrder()
Determine the byte order and return either "BigEndian" or "LittleEndian".