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