13 #include "../mesh/nurbs.hpp"
14 #include "../general/binaryio.hpp"
15 #include "../general/text.hpp"
26 #define mkdir(dir, mode) _mkdir(dir)
34 const Mesh *mesh,
int myid)
37 const char path_delim =
'/';
38 std::string::size_type pos = 0;
46 pos = dir_name.find(path_delim, pos+1);
47 std::string subdir = dir_name.substr(0, pos);
50 err = mkdir(subdir.c_str(), 0777);
51 err = (err && (errno != EEXIST)) ? 1 : 0;
53 if (myid == 0 || pmesh == NULL)
55 err = mkdir(subdir.c_str(), 0777);
56 err = (err && (errno != EEXIST)) ? 1 : 0;
60 while ( pos != std::string::npos );
65 MPI_Bcast(&err, 1, MPI_INT, 0, pmesh->
GetComm());
76 std::string::size_type pos = collection_name.find_last_of(
'/');
77 if (pos == std::string::npos)
79 name = collection_name;
85 name = collection_name.substr(pos+1);
148 MPI_Comm_rank(comm, &
myid);
161 default: MFEM_ABORT(
"unknown format: " << fmt);
169 #ifndef MFEM_USE_ZLIB
170 MFEM_VERIFY(!
compression,
"ZLib not enabled in MFEM build.");
192 MFEM_ABORT(
"this method is not implemented");
199 if (
error) {
return; }
227 MFEM_WARNING(
"Error creating directory: " << dir_name);
248 MFEM_WARNING(
"Error writing mesh to file: " << mesh_name);
270 std::string file_name = dir_name +
"/" + field_name;
283 (it->second)->
Save(field_file);
287 MFEM_WARNING(
"Error writing field to file: " << it->first);
296 (it->second)->
Save(q_field_file);
300 MFEM_WARNING(
"Error writing q-field to file: " << it->first);
381 const std::string& collection_name,
386 MPI_Comm_rank(comm, &
myid);
411 MPI_Comm_rank(comm, &
myid);
448 LOD = std::max(LOD,locLOD);
480 if (
myid != 0) {
return; }
485 std::ofstream root_file(root_name.c_str());
490 MFEM_WARNING(
"Error writing VisIt root file: " << root_name);
507 MFEM_WARNING(
"Cannot load parallel VisIt root file in serial.");
510 if (
m_comm == MPI_COMM_NULL)
512 MFEM_WARNING(
"Cannot load parallel VisIt root file without MPI"
521 MPI_Comm_size(
m_comm, &comm_size);
524 MFEM_WARNING(
"Processor number mismatch: VisIt root file: "
525 <<
num_procs <<
", MPI_comm: " << comm_size);
551 std::ifstream root_file(root_name.c_str());
552 std::stringstream buffer;
553 buffer << root_file.rdbuf();
557 MFEM_WARNING(
"Error reading the VisIt root file: " << root_name);
575 MFEM_WARNING(
"Unable to open mesh file: " << mesh_fname);
591 MFEM_WARNING(
"Reading parallel format in serial is not supported");
610 std::string fname = path_left + it->first + path_right;
616 MFEM_WARNING(
"Unable to open field file: " << fname);
622 if ((it->second).association ==
"nodes")
626 else if ((it->second).association ==
"elements")
634 if ((it->second).association ==
"nodes")
640 else if ((it->second).association ==
"elements")
646 MFEM_WARNING(
"Reading parallel format in serial is not supported");
656 std::string path_str =
660 picojson::object top, dsets,
main,
mesh, fields, field, mtags, ftags;
663 std::string file_ext_format =
".%0" + to_string(
pad_digits_rank) +
"d";
664 mtags[
"spatial_dim"] = picojson::value(to_string(
spatial_dim));
665 mtags[
"topo_dim"] = picojson::value(to_string(
topo_dim));
669 mesh[
"tags"] = picojson::value(mtags);
670 mesh[
"format"] = picojson::value(to_string(
format));
676 ftags[
"assoc"] = picojson::value((it->second).association);
677 ftags[
"comps"] = picojson::value(to_string((it->second).num_components));
678 ftags[
"lod"] = picojson::value(to_string((it->second).lod));
679 field[
"path"] = picojson::value(path_str + it->first + file_ext_format);
680 field[
"tags"] = picojson::value(ftags);
681 fields[it->first] = picojson::value(field);
684 main[
"cycle"] = picojson::value(
double(
cycle));
685 main[
"time"] = picojson::value(
time);
686 main[
"time_step"] = picojson::value(
time_step);
687 main[
"domains"] = picojson::value(
double(
num_procs));
688 main[
"mesh"] = picojson::value(mesh);
691 main[
"fields"] = picojson::value(fields);
694 dsets[
"main"] = picojson::value(main);
695 top[
"dsets"] = picojson::value(dsets);
697 return picojson::value(top).serialize(
true);
702 picojson::value top, dsets,
main,
mesh, fields;
703 std::string parse_err = picojson::parse(top, json);
704 if (!parse_err.empty())
707 MFEM_WARNING(
"Unable to parse VisIt root data.");
712 dsets = top.get(
"dsets");
713 main = dsets.get(
"main");
714 cycle = int(main.get(
"cycle").get<
double>());
715 time = main.get(
"time").get<
double>();
716 if (main.contains(
"time_step"))
718 time_step = main.get(
"time_step").get<
double>();
720 num_procs = int(main.get(
"domains").get<
double>());
721 mesh = main.get(
"mesh");
722 fields = main.get(
"fields");
727 std::string path = mesh.get(
"path").get<std::string>();
728 size_t right_sep = path.find(
'_');
729 if (right_sep == std::string::npos)
732 MFEM_WARNING(
"Unable to parse VisIt root data.");
735 name = path.substr(0, right_sep);
737 if (mesh.contains(
"format"))
742 topo_dim =
to_int(mesh.get(
"tags").get(
"topo_dim").get<std::string>());
744 to_int(mesh.get(
"tags").get(
"max_lods").get<std::string>());
748 if (fields.is<picojson::object>())
750 picojson::object fields_obj = fields.get<picojson::object>();
751 for (picojson::object::iterator it = fields_obj.begin();
752 it != fields_obj.end(); ++it)
754 picojson::value tags = it->second.get(
"tags");
757 to_int(tags.get(
"comps").get<std::string>()));
768 high_order_output(false),
780 levels_of_detail = levels_of_detail_;
785 MFEM_WARNING(
"ParaViewDataCollection::Load() is not implemented!");
790 std::string
out =
"";
815 std::string
out =
"data.pvtu";
841 MFEM_WARNING(
"Error creating directory: " << path);
851 if (
myid == 0 && !pvd_stream.is_open())
856 std::ifstream pvd_in;
857 if (restart_mode && (pvd_in.open(pvdname,std::ios::binary),pvd_in.good()))
861 std::fstream::pos_type pos_begin = pvd_in.tellg();
862 std::fstream::pos_type pos_end = pos_begin;
864 std::regex regexp(
"timestep=\"([^[:space:]]+)\".*file=\"Cycle(\\d+)");
868 while (getline(pvd_in,line))
870 if (regex_search(line,match,regexp))
872 MFEM_ASSERT(match.size() == 3,
"Unable to parse DataSet");
873 double tvalue = std::stod(match[1]);
874 if (tvalue >=
GetTime()) {
break; }
875 int cvalue = std::stoi(match[2]);
877 " is too small for restart mode: trying to overwrite"
879 pos_end = pvd_in.tellg();
882 size_t count = pos_end - pos_begin;
883 std::vector<char> buf(count);
885 pvd_in.seekg(pos_begin);
886 pvd_in.read(buf.data(), count);
889 pvd_stream.write(buf.data(), count);
896 pvd_stream <<
"<?xml version=\"1.0\"?>\n";
897 pvd_stream <<
"<VTKFile type=\"Collection\" version=\"0.1\"";
898 pvd_stream <<
" byte_order=\"" <<
VTKByteOrder() <<
"\">\n";
899 pvd_stream <<
"<Collection>" << std::endl;
920 out <<
"<?xml version=\"1.0\"?>\n";
921 out <<
"<VTKFile type=\"PUnstructuredGrid\"";
922 out <<
" version =\"0.1\" byte_order=\"" <<
VTKByteOrder() <<
"\">\n";
923 out <<
"<PUnstructuredGrid GhostLevel=\"0\">\n";
925 out <<
"<PPoints>\n";
927 out <<
" Name=\"Points\" NumberOfComponents=\"3\""
929 out <<
"</PPoints>\n";
932 out <<
"\t<PDataArray type=\"Int32\" ";
933 out <<
" Name=\"connectivity\" NumberOfComponents=\"1\""
935 out <<
"\t<PDataArray type=\"Int32\" ";
936 out <<
" Name=\"offsets\" NumberOfComponents=\"1\""
938 out <<
"\t<PDataArray type=\"UInt8\" ";
939 out <<
" Name=\"types\" NumberOfComponents=\"1\""
941 out <<
"</PCells>\n";
943 out <<
"<PPointData>\n";
946 int vec_dim=it->second->VectorDim();
948 <<
"\" Name=\"" << it->first
949 <<
"\" NumberOfComponents=\"" << vec_dim <<
"\" "
952 out <<
"</PPointData>\n";
955 out <<
"<PCellData>\n";
956 out <<
"\t<PDataArray type=\"Int32\" Name=\"" <<
"attribute"
957 <<
"\" NumberOfComponents=\"1\""
959 out <<
"</PCellData>\n";
965 out <<
"<Piece Source=\"" << nfname <<
"\"/>\n";
967 out <<
"</PUnstructuredGrid>\n";
968 out <<
"</VTKFile>\n";
973 pvd_stream <<
"<DataSet timestep=\"" <<
GetTime();
974 pvd_stream <<
"\" group=\"\" part=\"" << 0 <<
"\" file=\"";
975 pvd_stream << fname <<
"\"/>\n";
976 std::fstream::pos_type pos = pvd_stream.tellp();
977 pvd_stream <<
"</Collection>\n";
978 pvd_stream <<
"</VTKFile>" << std::endl;
979 pvd_stream.seekp(pos);
985 out <<
"<VTKFile type=\"UnstructuredGrid\"";
988 out <<
" compressor=\"vtkZLibDataCompressor\"";
990 out <<
" version=\"0.1\" byte_order=\"" <<
VTKByteOrder() <<
"\">\n";
991 out <<
"<UnstructuredGrid>\n";
995 out <<
"<PointData >\n";
1012 out <<
"</PointData>\n";
1014 out <<
"</Piece>\n";
1015 out <<
"</UnstructuredGrid>\n";
1016 out <<
"</VTKFile>" << std::endl;
1022 MFEM_WARNING(
"SaveQFieldVTU is not currently implemented - field name:"<<it->second);
1031 std::vector<char> buf;
1032 int vec_dim = it->second->VectorDim();
1037 <<
"\" Name=\"" << it->first;
1038 out <<
"\" NumberOfComponents=\"1\" format=\""
1044 it->second->GetValues(i, RefG->
RefPts, val, pmat);
1045 for (
int j = 0; j < val.
Size(); j++)
1057 bin_io::AppendBytes<float>(buf, float(val(j)));
1066 <<
"\" Name=\"" << it->first;
1067 out <<
"\" NumberOfComponents=\"" << vec_dim <<
"\""
1074 it->second->GetVectorValues(i, RefG->
RefPts, vval, pmat);
1076 for (
int jj = 0; jj < vval.
Width(); jj++)
1078 for (
int ii = 0; ii < vval.
Height(); ii++)
1090 bin_io::AppendBytes<float>(buf, float(vval(ii,jj)));
1103 out <<
"</DataArray>" << std::endl;
1108 pv_data_format = fmt;
1118 high_order_output = high_order_output_;
1123 MFEM_ASSERT(compression_level_ >= -1 && compression_level_ <= 9,
1124 "Compression level must be between -1 and 9 (inclusive).");
1141 restart_mode = restart_mode_;
int GetNPoints() const
Returns the number of the points in the integration rule.
virtual void SaveMesh()
Save the mesh, creating the collection directory.
void SaveOneField(const FieldMapIterator &it)
Save one field to disk, assuming the collection directory exists.
virtual void Print(std::ostream &out=mfem::out) const
Class for grid function - Vector with associated FE space.
const IntegrationRule & GetElementIntRule(int idx) const
Get the IntegrationRule associated with mesh element idx.
int format
Output mesh format: see the Format enumeration.
void SetDataFormat(VTKFormat fmt)
double GetTime() const
Get physical time (for time-dependent simulations)
bool appendRankToFileName
Append rank to any output file names.
iterator begin()
Returns a begin iterator to the registered fields.
virtual void RegisterQField(const std::string &q_field_name, QuadratureFunction *qf)
Add a QuadratureFunction to the collection.
void DeleteAll()
Delete data owned by the DataCollection including field information.
const char * GetDataTypeString() const
iterator end()
Returns an end iterator to the registered fields.
int pad_digits_cycle
Number of digits used for the cycle and MPI rank in filenames.
GFieldMap::iterator FieldMapIterator
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
const std::string & GetCollectionName() const
Get the name of the collection.
int GetOrder() const
Returns the order of the finite element. In the case of anisotropic orders, returns the maximum order...
Data type dense matrix using column-major storage.
int Size() const
Returns the size of the vector.
Helper class for VisIt visualization data.
Mesh * GetMesh() const
Returns the mesh.
int GetNE() const
Returns number of elements.
virtual void Save()
Save the collection and a VisIt root file.
std::string GetVisItRootString()
Prepare the VisIt root file in JSON format for the current collection.
void PrintVTU(std::ostream &out, int ref=1, VTKFormat format=VTKFormat::ASCII, bool high_order_output=false, int compression_level=0, bool bdr_elements=false)
bool own_data
Should the collection delete its mesh and fields.
virtual void SetCompression(bool comp)
Set the flag for use of gz compressed files.
void ParseVisItRootString(const std::string &json)
Read in a VisIt root file in JSON format.
Geometry::Type GetElementBaseGeometry(int i) const
std::string GenerateCollectionPath()
virtual void SaveQField(const std::string &q_field_name)
Save one q-field, assuming the collection directory already exists.
MPI_Comm m_comm
Associated MPI communicator.
virtual void Load(int cycle_=0) override
Load the collection - not implemented in the ParaView writer.
double time
Physical time (for time-dependent simulations)
std::map< std::string, VisItFieldInfo >::iterator FieldInfoMapIterator
iterator find(const std::string &fname)
Returns an iterator to the field fname.
void SetCompressionLevel(int compression_level_)
std::string GetMeshShortFileName() const
Mesh * mesh
The (common) mesh for the collected fields.
int GetNE() const
Returns number of elements in the mesh.
int GetNE() const
Returns number of elements in the mesh.
void SaveOneQField(const QFieldMapIterator &it)
Save one q-field to disk, assuming the collection directory exists.
void SaveQFieldVTU(std::ostream &out, int ref, const QFieldMapIterator &it)
virtual void RegisterField(const std::string &field_name, GridFunction *gf)
Add a grid function to the collection.
bool serial
Serial or parallel run? False iff mesh is a ParMesh.
int cycle
Time cycle; for time-dependent simulations cycle >= 0, otherwise = -1.
VisItDataCollection(const std::string &collection_name, Mesh *mesh_=NULL)
Constructor. The collection name is used when saving the data.
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
virtual void Save()
Save the collection to disk.
std::string to_padded_string(int i, int digits)
Convert an integer to a 0-padded string with the given number of digits.
int to_int(const std::string &str)
Convert a string to an int.
int GetCycle() const
Get time cycle (for time-dependent simulations)
void SaveDataVTU(std::ostream &out, int ref)
QuadratureSpace * GetSpace() const
Get the associated QuadratureSpace.
int visit_max_levels_of_detail
void SaveGFieldVTU(std::ostream &out, int ref_, const FieldMapIterator &it)
virtual void SetFormat(int fmt)
Set the desired output mesh and data format.
static int create_directory(const std::string &dir_name, const Mesh *mesh, int myid)
GeometryRefiner GlobGeometryRefiner
void Register(const std::string &fname, T *field, bool own_data)
Register field field with name fname.
DataCollection(const std::string &collection_name, Mesh *mesh_=NULL)
Initialize the collection with its name and Mesh.
void DeleteData()
Delete data owned by the DataCollection keeping field information.
void SetLevelsOfDetail(int levels_of_detail)
Set VisIt parameter: default levels of detail for the MultiresControl.
void SetHighOrderOutput(bool high_order_output_)
static const int pad_digits_default
Default value for pad_digits_*.
RefinedGeometry * Refine(Geometry::Type Geom, int Times, int ETimes=1)
void SetCompression(bool compression_) override
virtual int GetRefinementLevelFromElems(Geometry::Type geom, int Npts)
Get the Refinement level based on number of elements.
FiniteElementSpace * FESpace()
const char * GetDataFormatString() const
virtual void Load(int cycle_=0)
Load the collection based on its VisIt data (described in its root file)
int GetOrder() const
If all orders are identical, return that number. Otherwise, return NURBSFECollection::VariableOrder.
int SpaceDimension() const
std::map< std::string, VisItFieldInfo > field_info_map
void UseRestartMode(bool restart_mode_)
const NURBSExtension * GetNURBSext() const
QFieldMap::iterator QFieldMapIterator
int precision
Precision (number of digits) used for the text output of doubles.
OutStream err(std::cerr)
Global stream used by the library for standard error output. Initially it uses the same std::streambu...
bool IsBinaryFormat() const
Returns true if the output format is BINARY or BINARY32, false if ASCII.
int myid
MPI rank (in parallel)
virtual void SaveField(const std::string &field_name)
Save one field, assuming the collection directory already exists.
std::string GenerateVTUPath()
static const int precision_default
Default value for precision.
void SetMaxLevelsOfDetail(int max_levels_of_detail)
Set VisIt parameter: maximum levels of detail for the MultiresControl.
virtual void RegisterField(const std::string &field_name, GridFunction *gf)
Add a grid function to the collection and update the root file.
NURBSExtension * NURBSext
Optional NURBS mesh extension.
virtual ~DataCollection()
Delete the mesh and fields if owned by the collection.
std::string GetFieldFileName(const std::string &field_name) const
std::string GeneratePVTUPath()
void clear()
Clears the map of registered fields without reclaiming memory.
void SaveRootFile()
Save a VisIt root file for the collection.
std::string GenerateVTUFileName()
const char * VTKByteOrder()
ParaViewDataCollection(const std::string &collection_name, mfem::Mesh *mesh_=NULL)
Constructor. The collection name is used when saving the data.
std::string prefix_path
A path where the directory with results is saved. If not empty, it has '/' at the end...
std::string GeneratePVDFileName()
virtual const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th element in t...
void WriteVTKEncodedCompressed(std::ostream &out, const void *bytes, uint32_t nbytes, int compression_level)
void AppendBytes(std::vector< char > &vec, const T &val)
Append the binary representation of val to the byte buffer vec.
virtual void RegisterQField(const std::string &q_field_name, QuadratureFunction *qf)
Add a quadrature function to the collection and update the root file.
virtual void Load(int cycle_=0)
Load the collection. Not implemented in the base class DataCollection.
void SetLevelsOfDetail(int levels_of_detail_)
std::string GetMeshFileName() const
int visit_levels_of_detail
void LoadVisItRootFile(const std::string &root_name)
virtual void SetMesh(Mesh *new_mesh)
Set/change the mesh associated with the collection.
std::string GeneratePVTUFileName()
virtual void Save() override
std::string name
Name of the collection, used as a directory name when saving.
virtual void SetMesh(Mesh *new_mesh)
Set/change the mesh associated with the collection.
void DeleteAll()
Delete all data owned by VisItDataCollection including field data information.
void DeleteData(bool own_data)
Clear all associations between names and fields.
Class for parallel grid function.
double time_step
Time step i.e. delta_t (for time-dependent simulations)
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
int num_procs
Number of MPI ranks (in parallel)
void ParPrint(std::ostream &out) const
Save the mesh in a parallel mesh format.
Class for parallel meshes.
Class representing a function through its values (scalar or vector) at quadrature points...
void SetPrefixPath(const std::string &prefix)
Set the path where the DataCollection will be saved.