libROM  v1.0
Data-driven physical simulation library
BasisReader.cpp
1 
11 // Description: A class that reads basis vectors from a file.
12 
13 #include "BasisReader.h"
14 #include "utils/HDFDatabase.h"
15 #include "utils/HDFDatabaseMPIO.h"
16 #include "Matrix.h"
17 #include "Vector.h"
18 #include "mpi.h"
19 #include "utils/mpi_utils.h"
20 
21 namespace CAROM {
22 
23 BasisReader::BasisReader(
24  const std::string& base_file_name,
25  Database::formats db_format,
26  const int dim) :
27  d_dim(dim),
28  full_file_name(""),
29  base_file_name_(base_file_name),
30  d_format(db_format)
31 {
32  CAROM_ASSERT(!base_file_name.empty());
33 
34  int mpi_init;
35  MPI_Initialized(&mpi_init);
36  int rank;
37  if (mpi_init) {
38  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
39  }
40  else {
41  rank = 0;
42  }
43 
44  full_file_name = base_file_name;
45 
46  // Enforce hdf data format.
47  if (d_format == Database::formats::HDF5)
48  {
49  d_database = new HDFDatabase();
50  }
51  else if (d_format == Database::formats::HDF5_MPIO)
52  {
53  /*
54  For MPIO case, local dimension needs to be specified.
55  We allow 0 local dimension. (global dimension still needs to be positive)
56  */
57  std::vector<int> tmp;
58  d_global_dim = get_global_offsets(d_dim, tmp, MPI_COMM_WORLD);
59  CAROM_VERIFY(d_dim >= 0);
60  CAROM_VERIFY(d_global_dim > 0);
61  d_database = new HDFDatabaseMPIO();
62  }
63  else
64  CAROM_ERROR("BasisWriter only supports HDF5/HDF5_MPIO data format!\n");
65 
66  d_database->open(full_file_name, "r", MPI_COMM_WORLD);
67 }
68 
70 {
71  d_database->close();
72  delete d_database;
73 }
74 
75 Matrix*
77 {
78  int num_rows = getDim("basis");
79  int num_cols = getNumSamples("basis");
80 
81  Matrix* spatial_basis_vectors = new Matrix(num_rows, num_cols, true);
82 
83  d_database->getDoubleArray("spatial_basis",
84  &spatial_basis_vectors->item(0, 0),
85  num_rows*num_cols,
86  true);
87  return spatial_basis_vectors;
88 }
89 
90 Matrix*
92  int n)
93 {
94  return getSpatialBasis(1, n);
95 }
96 
97 Matrix*
99  int start_col,
100  int end_col)
101 {
102  int num_rows = getDim("basis");
103  int num_cols = getNumSamples("basis");
104 
105  char tmp[100];
106  CAROM_VERIFY(0 < start_col <= num_cols);
107  CAROM_VERIFY(start_col <= end_col && end_col <= num_cols);
108  int num_cols_to_read = end_col - start_col + 1;
109 
110  Matrix* spatial_basis_vectors = new Matrix(num_rows, num_cols_to_read, true);
111  sprintf(tmp, "spatial_basis");
112  d_database->getDoubleArray(tmp,
113  &spatial_basis_vectors->item(0, 0),
114  num_rows*num_cols_to_read,
115  start_col - 1,
116  num_cols_to_read,
117  num_cols,
118  true);
119  return spatial_basis_vectors;
120 }
121 
122 Matrix*
124  double ef)
125 {
126  Vector* sv = getSingularValues();
127  double total_energy = 0.0;
128  double energy = 0.0;
129  for (int i = 0; i < sv->dim(); i++)
130  {
131  total_energy += sv->item(i);
132  }
133 
134  int num_used_singular_values = 0;
135  for (int i = 0; i < sv->dim(); i++)
136  {
137  energy += sv->item(i);
138  num_used_singular_values++;
139  if (energy / total_energy >= ef)
140  {
141  break;
142  }
143  }
144 
145  delete sv;
146  return getSpatialBasis(num_used_singular_values);
147 }
148 
149 Matrix*
151 {
152  int num_rows = getDim("temporal_basis");
153  int num_cols = getNumSamples("temporal_basis");
154 
155  char tmp[100];
156  Matrix* temporal_basis_vectors = new Matrix(num_rows, num_cols, false);
157  sprintf(tmp, "temporal_basis");
158  d_database->getDoubleArray(tmp,
159  &temporal_basis_vectors->item(0, 0),
160  num_rows*num_cols);
161  return temporal_basis_vectors;
162 }
163 
164 Matrix*
166  int n)
167 {
168  return getTemporalBasis(1, n);
169 }
170 
171 Matrix*
173  int start_col,
174  int end_col)
175 {
176  int num_rows = getDim("temporal_basis");
177  int num_cols = getNumSamples("temporal_basis");
178 
179  char tmp[100];
180  CAROM_VERIFY(0 < start_col <= num_cols);
181  CAROM_VERIFY(start_col <= end_col && end_col <= num_cols);
182  int num_cols_to_read = end_col - start_col + 1;
183 
184  Matrix* temporal_basis_vectors = new Matrix(num_rows, num_cols_to_read, false);
185  sprintf(tmp, "temporal_basis");
186  d_database->getDoubleArray(tmp,
187  &temporal_basis_vectors->item(0, 0),
188  num_rows*num_cols_to_read,
189  start_col - 1,
190  num_cols_to_read,
191  num_cols);
192  return temporal_basis_vectors;
193 }
194 
195 Matrix*
197  double ef)
198 {
199  Vector* sv = getSingularValues();
200  double total_energy = 0.0;
201  double energy = 0.0;
202  for (int i = 0; i < sv->dim(); i++)
203  {
204  total_energy += sv->item(i);
205  }
206 
207  int num_used_singular_values = 0;
208  for (int i = 0; i < sv->dim(); i++)
209  {
210  energy += sv->item(i);
211  num_used_singular_values++;
212  if (energy / total_energy >= ef)
213  {
214  break;
215  }
216  }
217 
218  delete sv;
219  return getTemporalBasis(num_used_singular_values);
220 }
221 
222 Vector*
224 {
225  char tmp[100];
226  int size;
227  sprintf(tmp, "singular_value_size");
228  d_database->getInteger(tmp, size);
229 
230  Vector* singular_values = new Vector(size, false);
231  sprintf(tmp, "singular_value");
232  d_database->getDoubleArray(tmp,
233  &singular_values->item(0),
234  size);
235  return singular_values;
236 }
237 
238 Vector*
240  double ef)
241 {
242  Vector* sv = getSingularValues();
243  double total_energy = 0.0;
244  double energy = 0.0;
245  for (int i = 0; i < sv->dim(); i++)
246  {
247  total_energy += sv->item(i);
248  }
249 
250  int num_used_singular_values = 0;
251  for (int i = 0; i < sv->dim(); i++)
252  {
253  energy += sv->item(i);
254  num_used_singular_values++;
255  if (energy / total_energy >= ef)
256  {
257  break;
258  }
259  }
260 
261  Vector* truncated_singular_values = new Vector(num_used_singular_values,
262  false);
263  for (int i = 0; i < num_used_singular_values; i++)
264  {
265  truncated_singular_values->item(i) = sv->item(i);
266  }
267 
268  delete sv;
269  return truncated_singular_values;
270 }
271 
272 int
274  const std::string kind)
275 {
276  CAROM_ASSERT((kind == "basis") ||
277  (kind == "snapshot") ||
278  (kind == "temporal_basis"));
279 
280  char tmp[100];
281  int num_rows;
282 
283  if (kind == "basis") sprintf(tmp, "spatial_basis_num_rows");
284  else if (kind == "snapshot") sprintf(tmp, "snapshot_matrix_num_rows");
285  else if (kind == "temporal_basis") sprintf(tmp,
286  "temporal_basis_num_rows");
287 
288  d_database->getInteger(tmp, num_rows);
289  /* only basis and snapshot are stored as distributed matrices */
290  if ((kind != "temporal_basis") && (d_format == Database::formats::HDF5_MPIO))
291  {
292  /*
293  for MPIO database, return specified local dimension.
294  only checks the global dimension match.
295  */
296  CAROM_VERIFY(d_global_dim == num_rows);
297  return d_dim;
298  }
299  else
300  return num_rows;
301 }
302 
303 int
305  const std::string kind)
306 {
307  CAROM_ASSERT((kind == "basis") ||
308  (kind == "snapshot") ||
309  (kind == "temporal_basis"));
310 
311  char tmp[100];
312  int num_cols;
313 
314  if (kind == "basis") sprintf(tmp, "spatial_basis_num_cols");
315  else if (kind == "snapshot") sprintf(tmp, "snapshot_matrix_num_cols");
316  else if (kind == "temporal_basis") sprintf(tmp,
317  "temporal_basis_num_cols");
318 
319  d_database->getInteger(tmp, num_cols);
320  return num_cols;
321 }
322 
323 Matrix*
325 {
326  int num_rows = getDim("snapshot");
327  int num_cols = getNumSamples("snapshot");
328 
329  char tmp[100];
330  Matrix* snapshots = new Matrix(num_rows, num_cols, true);
331  sprintf(tmp, "snapshot_matrix");
332  d_database->getDoubleArray(tmp,
333  &snapshots->item(0, 0),
334  num_rows*num_cols,
335  true);
336  return snapshots;
337 }
338 
339 Matrix*
341  int n)
342 {
343  return getSnapshotMatrix(1, n);
344 }
345 
346 Matrix*
348  int start_col,
349  int end_col)
350 {
351  int num_rows = getDim("snapshot");
352  int num_cols = getNumSamples("snapshot");
353 
354  CAROM_VERIFY(0 < start_col <= num_cols);
355  CAROM_VERIFY(start_col <= end_col && end_col <= num_cols);
356  int num_cols_to_read = end_col - start_col + 1;
357 
358  char tmp[100];
359  Matrix* snapshots = new Matrix(num_rows, num_cols_to_read, true);
360  sprintf(tmp, "snapshot_matrix");
361  d_database->getDoubleArray(tmp,
362  &snapshots->item(0, 0),
363  num_rows*num_cols_to_read,
364  start_col - 1,
365  num_cols_to_read,
366  num_cols,
367  true);
368  return snapshots;
369 }
370 }
Vector * getSingularValues()
Returns the singular values for the requested time.
int getNumSamples(const std::string kind)
Returns the number of samples (columns) in file.
int getDim(const std::string kind)
Returns the dimension of the system on this processor.
Matrix * getSnapshotMatrix()
Returns the snapshot matrix for the requested time.
Matrix * getSpatialBasis()
Returns the spatial basis vectors as a Matrix.
Definition: BasisReader.cpp:76
Matrix * getTemporalBasis()
Returns the temporal basis vectors for the requested time as a Matrix.
~BasisReader()
Destructor.
Definition: BasisReader.cpp:69
void getInteger(const std::string &key, int &data)
Reads an integer associated with the supplied key from the currently open database file.
Definition: Database.h:182
virtual bool close()=0
Closes the currently open database file.
formats
Implemented database file formats. Add to this enum each time a new database format is implemented.
Definition: Database.h:312
virtual void getDoubleArray(const std::string &key, double *data, int nelements, const bool distributed=false)=0
Reads an array of doubles associated with the supplied key from the currently open database file.
virtual bool open(const std::string &file_name, const std::string &type, const MPI_Comm comm=MPI_COMM_NULL)
Opens an existing database file with the supplied name.
Definition: Database.cpp:44
const double & item(int row, int col) const
Const Matrix member access. Matrix data is stored in row-major format.
Definition: Matrix.h:1007
const double & item(int i) const
Const Vector member access.
Definition: Vector.h:656
int dim() const
Returns the dimension of the Vector on this processor.
Definition: Vector.h:266
int get_global_offsets(const int local_dim, std::vector< int > &offsets, const MPI_Comm &comm)
Save integer offsets for each MPI rank under MPI communicator comm, where each rank as the size of lo...
Definition: mpi_utils.cpp:41