MFEM  v4.6.0
Finite element discretization library
convert-dc.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010-2023, 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 // ---------------------------------------------------------------
13 // Convert DC: Convert between different types of data collections
14 // ---------------------------------------------------------------
15 //
16 // This tool demonstrates how to convert between MFEM's different concrete
17 // DataCollection options.
18 //
19 // Currently supported data collection type options:
20 // visit: VisItDataCollection (default)
21 // sidre or sidre_hdf5: SidreDataCollection
22 // json: ConduitDataCollection w/ protocol json
23 // conduit_json: ConduitDataCollection w/ protocol conduit_json
24 // conduit_bin: ConduitDataCollection w/ protocol conduit_bin
25 // hdf5: ConduitDataCollection w/ protocol hdf5
26 // fms: FMSDataCollection w/ protocol ascii
27 // fms_json: FMSDataCollection w/ protocol json
28 // fms_yaml: FMSDataCollection w/ protocol yaml
29 // fms_hdf5: FMSDataCollection w/ protocol hdf5
30 //
31 // Compile with: make convert-dc
32 //
33 // Serial sample runs:
34 // convert-dc -s ../../examples/Example5 -st visit -o Example5_Conduit -ot json
35 //
36 // Parallel sample runs:
37 // mpirun -np 4 convert-dc -s ../../examples/Example5-Parallel -st visit
38 // -o Example5-Parallel_Conduit -ot json
39 
40 #include "mfem.hpp"
41 
42 using namespace std;
43 using namespace mfem;
44 
45 DataCollection *create_data_collection(const std::string &dc_name,
46  const std::string &dc_type)
47 {
48  DataCollection *dc = NULL;
49 
50  if (dc_type == "visit")
51  {
52 #ifdef MFEM_USE_MPI
53  dc = new VisItDataCollection(MPI_COMM_WORLD, dc_name);
54 #else
55  dc = new VisItDataCollection(dc_name);
56 #endif
57  }
58  else if ( dc_type == "sidre" || dc_type == "sidre_hdf5")
59  {
60 #ifdef MFEM_USE_SIDRE
61  dc = new SidreDataCollection(dc_name);
62 #else
63  MFEM_ABORT("Must build with MFEM_USE_SIDRE=YES for sidre support.");
64 #endif
65  }
66  else if ( dc_type == "json" ||
67  dc_type == "conduit_json" ||
68  dc_type == "conduit_bin" ||
69  dc_type == "hdf5")
70  {
71 #ifdef MFEM_USE_CONDUIT
72 #ifdef MFEM_USE_MPI
73  ConduitDataCollection *conduit_dc = new ConduitDataCollection(MPI_COMM_WORLD,
74  dc_name);
75 #else
76  ConduitDataCollection *conduit_dc = new ConduitDataCollection(dc_name);
77 #endif
78  conduit_dc->SetProtocol(dc_type);
79  dc = conduit_dc;
80 #else
81  MFEM_ABORT("Must build with MFEM_USE_CONDUIT=YES for conduit support.");
82 #endif
83  }
84  else if ( dc_type.substr(0,3) == "fms")
85  {
86 #ifdef MFEM_USE_FMS
87  auto fms_dc = new FMSDataCollection(dc_name);
88  std::string::size_type pos = dc_type.find("_");
89  if (pos != std::string::npos)
90  {
91  std::string fms_protocol(dc_type.substr(pos+1, dc_type.size()-pos-1));
92  fms_dc->SetProtocol(fms_protocol);
93  }
94  dc = fms_dc;
95 #else
96  MFEM_ABORT("Must build with MFEM_USE_FMS=YES for FMS support.");
97 #endif
98  }
99  else
100  {
101  MFEM_ABORT("Unsupported Data Collection type:" << dc_type);
102  }
103 
104  return dc;
105 }
106 
107 int main(int argc, char *argv[])
108 {
109 #ifdef MFEM_USE_MPI
110  Mpi::Init();
111  if (!Mpi::Root()) { mfem::out.Disable(); mfem::err.Disable(); }
112  Hypre::Init();
113 #endif
114 
115  // Parse command-line options.
116  const char *src_coll_name = NULL;
117  const char *src_coll_type = "visit";
118  int src_cycle = 0;
119  int src_pad_digits_cycle = 6;
120  int src_pad_digits_rank = 6;
121  const char *out_coll_name = NULL;
122  const char *out_coll_type = "visit";
123  int out_pad_digits_cycle = -1;
124  int out_pad_digits_rank = -1;
125 
126  OptionsParser args(argc, argv);
127  args.AddOption(&src_coll_name, "-s", "--source-root-prefix",
128  "Set the source data collection root file prefix.", true);
129  args.AddOption(&out_coll_name, "-o", "--output-root-prefix",
130  "Set the source data collection root file prefix.", true);
131  args.AddOption(&src_cycle, "-c", "--cycle",
132  "Set the source cycle index to read.");
133  args.AddOption(&src_pad_digits_cycle, "-pdc", "--pad-digits-cycle",
134  "Number of digits in source cycle.");
135  args.AddOption(&out_pad_digits_cycle, "-opdc", "--out-pad-digits-cycle",
136  "Number of digits in output cycle.");
137  args.AddOption(&src_pad_digits_rank, "-pdr", "--pad-digits-rank",
138  "Number of digits in source MPI rank.");
139  args.AddOption(&out_pad_digits_rank, "-opdr", "--out-pad-digits-rank",
140  "Number of digits in output MPI rank.");
141  args.AddOption(&src_coll_type, "-st", "--source-type",
142  "Set the source data collection type. Options:\n"
143  "\t visit: VisItDataCollection (default)\n"
144  "\t sidre or sidre_hdf5: SidreDataCollection\n"
145  "\t json: ConduitDataCollection w/ protocol json\n"
146  "\t conduit_json: ConduitDataCollection w/ protocol conduit_json\n"
147  "\t conduit_bin: ConduitDataCollection w/ protocol conduit_bin\n"
148  "\t hdf5: ConduitDataCollection w/ protocol hdf5\n"
149  "\t fms: FMSDataCollection w/ protocol ascii\n"
150  "\t fms_json: FMSDataCollection w/ protocol json\n"
151  "\t fms_yaml: FMSDataCollection w/ protocol yaml\n"
152  "\t fms_hdf5: FMSDataCollection w/ protocol hdf5");
153  args.AddOption(&out_coll_type, "-ot", "--output-type",
154  "Set the output data collection type. Options:\n"
155  "\t visit: VisItDataCollection (default)\n"
156  "\t sidre or sidre_hdf5: SidreDataCollection\n"
157  "\t json: ConduitDataCollection w/ protocol json\n"
158  "\t conduit_json: ConduitDataCollection w/ protocol conduit_json\n"
159  "\t conduit_bin: ConduitDataCollection w/ protocol conduit_bin\n"
160  "\t hdf5: ConduitDataCollection w/ protocol hdf5\n"
161  "\t fms: FMSDataCollection w/ protocol ascii\n"
162  "\t fms_json: FMSDataCollection w/ protocol json\n"
163  "\t fms_yaml: FMSDataCollection w/ protocol yaml\n"
164  "\t fms_hdf5: FMSDataCollection w/ protocol hdf5");
165  args.Parse();
166  if (!args.Good())
167  {
168  args.PrintUsage(mfem::out);
169  return 1;
170  }
171  if (out_pad_digits_cycle < 0)
172  {
173  out_pad_digits_cycle = src_pad_digits_cycle;
174  }
175  if (out_pad_digits_rank < 0)
176  {
177  out_pad_digits_rank = src_pad_digits_rank;
178  }
179  args.PrintOptions(mfem::out);
180 
181  DataCollection *src_dc = create_data_collection(std::string(src_coll_name),
182  std::string(src_coll_type));
183 
184  DataCollection *out_dc = create_data_collection(std::string(out_coll_name),
185  std::string(out_coll_type));
186 
187  out_dc->SetPadDigitsCycle(out_pad_digits_cycle);
188  out_dc->SetPadDigitsRank(out_pad_digits_rank);
189  src_dc->SetPadDigitsCycle(src_pad_digits_cycle);
190  src_dc->SetPadDigitsRank(src_pad_digits_rank);
191  src_dc->Load(src_cycle);
192 
193  if (src_dc->Error() != DataCollection::No_Error)
194  {
195  mfem::out << "Error loading data collection: "
196  << src_coll_name
197  << " (type = "
198  << src_coll_type
199  << ")"
200  << endl;
201  return 1;
202  }
203 
204  out_dc->SetOwnData(false);
205 
206  // add mesh from source dc to output dc
207 #ifdef MFEM_USE_MPI
208  out_dc->SetMesh(MPI_COMM_WORLD,src_dc->GetMesh());
209 #else
210  out_dc->SetMesh(src_dc->GetMesh());
211 #endif
212 
213  // propagate the basics
214  out_dc->SetCycle(src_dc->GetCycle());
215  out_dc->SetTime(src_dc->GetTime());
216  out_dc->SetTimeStep(src_dc->GetTimeStep());
217 
218  // loop over all fields in the source dc, and add them to the output dc
219  const DataCollection::FieldMapType &src_fields = src_dc->GetFieldMap();
220 
221  for (DataCollection::FieldMapType::const_iterator it = src_fields.begin();
222  it != src_fields.end();
223  ++it)
224  {
225  out_dc->RegisterField(it->first,it->second);
226  }
227 
228  out_dc->Save();
229 
230  if (out_dc->Error() != DataCollection::No_Error)
231  {
232  mfem::out << "Error saving data collection: "
233  << out_coll_name
234  << " (type = "
235  << out_coll_type
236  << ")"
237  << endl;
238  return 1;
239  }
240 
241  // cleanup
242  delete src_dc;
243  delete out_dc;
244 
245  return 0;
246 }
virtual void SetPadDigitsRank(int digits)
Set the number of digits used for the MPI rank in filenames.
void SetCycle(int c)
Set time cycle (for time-dependent simulations)
int Error() const
Get the current error state.
OutStream err(std::cerr)
Global stream used by the library for standard error output. Initially it uses the same std::streambu...
Definition: globals.hpp:71
void PrintOptions(std::ostream &out) const
Print the options.
Definition: optparser.cpp:331
int main(int argc, char *argv[])
Definition: convert-dc.cpp:107
Data collection that uses the Conduit Mesh Blueprint specification.
void PrintUsage(std::ostream &out) const
Print the usage message.
Definition: optparser.cpp:462
bool Good() const
Return true if the command line options were parsed successfully.
Definition: optparser.hpp:159
STL namespace.
int GetCycle() const
Get time cycle (for time-dependent simulations)
Data collection that uses FMS.
Data collection with Sidre routines following the Conduit mesh blueprint specification.
virtual void RegisterField(const std::string &field_name, GridFunction *gf)
Add a grid function to the collection.
void Parse()
Parse the command-line options. Note that this function expects all the options provided through the ...
Definition: optparser.cpp:151
virtual void Save()
Save the collection to disk.
Data collection with VisIt I/O routines.
double GetTimeStep() const
Get the simulation time step (for time-dependent simulations)
DataCollection * create_data_collection(const std::string &dc_name, const std::string &dc_type)
Definition: convert-dc.cpp:45
void SetTime(double t)
Set physical time (for time-dependent simulations)
const FieldMapType & GetFieldMap() const
Get a const reference to the internal field map.
void SetOwnData(bool o)
Set the ownership of collection data.
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
Definition: globals.hpp:66
void AddOption(bool *var, const char *enable_short_name, const char *enable_long_name, const char *disable_short_name, const char *disable_long_name, const char *description, bool required=false)
Add a boolean option and set &#39;var&#39; to receive the value. Enable/disable tags are used to set the bool...
Definition: optparser.hpp:82
void Disable()
Disable output.
Definition: globals.hpp:54
GFieldMap::MapType FieldMapType
void SetTimeStep(double ts)
Set the simulation time step (for time-dependent simulations)
virtual void SetPadDigitsCycle(int digits)
Set the number of digits used for the cycle.
virtual void Load(int cycle_=0)
Load the collection. Not implemented in the base class DataCollection.
Mesh * GetMesh()
Get a pointer to the mesh in the collection.
virtual void SetMesh(Mesh *new_mesh)
Set/change the mesh associated with the collection.
void SetProtocol(const std::string &protocol)
Set the Conduit relay i/o protocol to use.
double GetTime() const
Get physical time (for time-dependent simulations)