13 #include "../mesh/nurbs.hpp"
14 #include "../general/binaryio.hpp"
15 #include "../general/text.hpp"
25 #define mkdir(dir, mode) _mkdir(dir)
33 const Mesh *mesh,
int myid)
36 const char path_delim =
'/';
37 std::string::size_type pos = 0;
45 pos = dir_name.find(path_delim, pos+1);
46 std::string subdir = dir_name.substr(0, pos);
49 err = mkdir(subdir.c_str(), 0777);
50 err = (err && (errno != EEXIST)) ? 1 : 0;
52 if (myid == 0 || pmesh == NULL)
54 err = mkdir(subdir.c_str(), 0777);
55 err = (err && (errno != EEXIST)) ? 1 : 0;
59 while ( pos != std::string::npos );
64 MPI_Bcast(&err, 1, MPI_INT, 0, pmesh->
GetComm());
75 std::string::size_type pos = collection_name.find_last_of(
'/');
76 if (pos == std::string::npos)
78 name = collection_name;
84 name = collection_name.substr(pos+1);
147 MPI_Comm_rank(comm, &
myid);
160 default: MFEM_ABORT(
"unknown format: " << fmt);
168 #ifndef MFEM_USE_ZLIB
169 MFEM_VERIFY(!
compression,
"ZLib not enabled in MFEM build.");
191 MFEM_ABORT(
"this method is not implemented");
198 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);
461 if (
myid != 0) {
return; }
466 std::ofstream root_file(root_name.c_str());
471 MFEM_WARNING(
"Error writing VisIt root file: " << root_name);
488 MFEM_WARNING(
"Cannot load parallel VisIt root file in serial.");
491 if (
m_comm == MPI_COMM_NULL)
493 MFEM_WARNING(
"Cannot load parallel VisIt root file without MPI"
502 MPI_Comm_size(
m_comm, &comm_size);
505 MFEM_WARNING(
"Processor number mismatch: VisIt root file: "
506 <<
num_procs <<
", MPI_comm: " << comm_size);
532 std::ifstream root_file(root_name.c_str());
533 std::stringstream buffer;
534 buffer << root_file.rdbuf();
538 MFEM_WARNING(
"Error reading the VisIt root file: " << root_name);
554 MFEM_WARNING(
"Unable to open mesh file: " << mesh_fname);
570 MFEM_WARNING(
"Reading parallel format in serial is not supported");
589 std::string fname = path_left + it->first + path_right;
595 MFEM_WARNING(
"Unable to open field file: " << fname);
611 MFEM_WARNING(
"Reading parallel format in serial is not supported");
621 std::string path_str =
625 picojson::object top, dsets,
main,
mesh, fields, field, mtags, ftags;
634 mesh[
"tags"] = picojson::value(mtags);
641 ftags[
"assoc"] = picojson::value((it->second).association);
642 ftags[
"comps"] = picojson::value(
to_string((it->second).num_components));
644 field[
"path"] = picojson::value(path_str + it->first + file_ext_format);
645 field[
"tags"] = picojson::value(ftags);
646 fields[it->first] = picojson::value(field);
649 main[
"cycle"] = picojson::value(
double(
cycle));
650 main[
"time"] = picojson::value(
time);
651 main[
"time_step"] = picojson::value(
time_step);
652 main[
"domains"] = picojson::value(
double(
num_procs));
653 main[
"mesh"] = picojson::value(mesh);
656 main[
"fields"] = picojson::value(fields);
659 dsets[
"main"] = picojson::value(main);
660 top[
"dsets"] = picojson::value(dsets);
662 return picojson::value(top).serialize(
true);
667 picojson::value top, dsets,
main,
mesh, fields;
668 std::string parse_err = picojson::parse(top, json);
669 if (!parse_err.empty())
672 MFEM_WARNING(
"Unable to parse VisIt root data.");
677 dsets = top.get(
"dsets");
678 main = dsets.get(
"main");
679 cycle = int(main.get(
"cycle").get<
double>());
680 time = main.get(
"time").get<
double>();
681 if (main.contains(
"time_step"))
683 time_step = main.get(
"time_step").get<
double>();
685 num_procs = int(main.get(
"domains").get<
double>());
686 mesh = main.get(
"mesh");
687 fields = main.get(
"fields");
692 std::string path = mesh.get(
"path").get<std::string>();
693 size_t right_sep = path.find(
'_');
694 if (right_sep == std::string::npos)
697 MFEM_WARNING(
"Unable to parse VisIt root data.");
700 name = path.substr(0, right_sep);
702 if (mesh.contains(
"format"))
707 topo_dim =
to_int(mesh.get(
"tags").get(
"topo_dim").get<std::string>());
709 to_int(mesh.get(
"tags").get(
"max_lods").get<std::string>());
713 if (fields.is<picojson::object>())
715 picojson::object fields_obj = fields.get<picojson::object>();
716 for (picojson::object::iterator it = fields_obj.begin();
717 it != fields_obj.end(); ++it)
719 picojson::value tags = it->second.get(
"tags");
722 to_int(tags.get(
"comps").get<std::string>()));
733 high_order_output(false)
750 levels_of_detail = levels_of_detail_;
755 MFEM_WARNING(
"ParaViewDataCollection::Load() is not implemented!");
760 std::string
out =
"";
785 std::string
out =
"data.pvtu";
811 MFEM_WARNING(
"Error creating directory: " << path);
818 if (!pvd_stream.is_open())
824 pvd_stream <<
"<?xml version=\"1.0\"?>\n";
825 pvd_stream <<
"<VTKFile type=\"Collection\" version=\"0.1\"";
826 pvd_stream <<
" byte_order=\"" <<
VTKByteOrder() <<
"\">\n";
827 pvd_stream <<
"<Collection>" << std::endl;
847 out <<
"<?xml version=\"1.0\"?>\n";
848 out <<
"<VTKFile type=\"PUnstructuredGrid\"";
849 out <<
" version =\"0.1\" byte_order=\"" <<
VTKByteOrder() <<
"\">\n";
850 out <<
"<PUnstructuredGrid GhostLevel=\"0\">\n";
852 out <<
"<PPoints>\n";
854 out <<
" Name=\"Points\" NumberOfComponents=\"3\""
856 out <<
"</PPoints>\n";
859 out <<
"\t<PDataArray type=\"Int32\" ";
860 out <<
" Name=\"connectivity\" NumberOfComponents=\"1\""
862 out <<
"\t<PDataArray type=\"Int32\" ";
863 out <<
" Name=\"offsets\" NumberOfComponents=\"1\""
865 out <<
"\t<PDataArray type=\"UInt8\" ";
866 out <<
" Name=\"types\" NumberOfComponents=\"1\""
868 out <<
"</PCells>\n";
870 out <<
"<PPointData>\n";
873 int vec_dim=it->second->VectorDim();
875 <<
"\" Name=\"" << it->first
876 <<
"\" NumberOfComponents=\"" << vec_dim <<
"\" "
879 out <<
"</PPointData>\n";
882 out <<
"<PCellData>\n";
883 out <<
"\t<PDataArray type=\"Int32\" Name=\"" <<
"material"
884 <<
"\" NumberOfComponents=\"1\""
886 out <<
"</PCellData>\n";
892 out <<
"<Piece Source=\"" << nfname <<
"\"/>\n";
894 out <<
"</PUnstructuredGrid>\n";
895 out <<
"</VTKFile>\n";
900 pvd_stream <<
"<DataSet timestep=\"" <<
GetTime();
901 pvd_stream <<
"\" group=\"\" part=\"" << 0 <<
"\" file=\"";
902 pvd_stream << fname <<
"\"/>\n";
903 std::fstream::pos_type pos = pvd_stream.tellp();
904 pvd_stream <<
"</Collection>\n";
905 pvd_stream <<
"</VTKFile>" << std::endl;
906 pvd_stream.seekp(pos);
912 out <<
"<VTKFile type=\"UnstructuredGrid\"";
915 out <<
" compressor=\"vtkZLibDataCompressor\"";
917 out <<
" version=\"0.1\" byte_order=\"" <<
VTKByteOrder() <<
"\">\n";
918 out <<
"<UnstructuredGrid>\n";
922 out <<
"<PointData >\n";
939 out <<
"</PointData>\n";
942 out <<
"</UnstructuredGrid>\n";
943 out <<
"</VTKFile>" << std::endl;
949 MFEM_WARNING(
"SaveQFieldVTU is not currently implemented - field name:"<<it->second);
958 std::vector<char> buf;
959 int vec_dim = it->second->VectorDim();
964 <<
"\" Name=\"" << it->first;
965 out <<
"\" NumberOfComponents=\"1\" format=\""
971 it->second->GetValues(i, RefG->
RefPts, val, pmat);
972 for (
int j = 0; j < val.
Size(); j++)
976 out << val(j) <<
'\n';
984 bin_io::AppendBytes<float>(buf, float(val(j)));
993 <<
"\" Name=\"" << it->first;
994 out <<
"\" NumberOfComponents=\"" << vec_dim <<
"\""
1001 it->second->GetVectorValues(i, RefG->
RefPts, vval, pmat);
1003 for (
int jj = 0; jj < vval.
Width(); jj++)
1005 for (
int ii = 0; ii < vval.
Height(); ii++)
1009 out << vval(ii,jj) <<
' ';
1017 bin_io::AppendBytes<float>(buf, float(vval(ii,jj)));
1030 out <<
"</DataArray>" << std::endl;
1035 pv_data_format = fmt;
1045 high_order_output = high_order_output_;
1050 MFEM_ASSERT(compression_level_ >= -1 && compression_level_ <= 9,
1051 "Compression level must be between -1 and 9 (inclusive).");
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.
int format
Output mesh format: see the Format enumeration.
void SetDataFormat(VTKFormat fmt)
double GetTime() const
Get physical time (for time-dependent simulations)
void PrintVTU(std::ostream &out, int ref=1, VTKFormat format=VTKFormat::ASCII, bool high_order_output=false, int compression_level=0)
bool appendRankToFileName
Append rank to any output file names.
iterator begin()
Returns a begin iterator to the registered fields.
void DeleteAll()
Delete data owned by the DataCollection including field information.
std::string to_string(int i)
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.
virtual void RegisterField(const std::string &field_name, mfem::GridFunction *gf) override
Add a grid function to 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.
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.
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.
int main(int argc, char *argv[])
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.
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)
int to_int(const std::string &str)
void SaveDataVTU(std::ostream &out, int ref)
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
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
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()
const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement associated with i'th element.
void WriteVTKEncodedCompressed(std::ostream &out, const void *bytes, uint32_t nbytes, int compression_level)
void AppendBytes(std::vector< char > &vec, const T &val)
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.
void SetPrefixPath(const std::string &prefix)
Set the path where the DataCollection will be saved.