HyPar  1.0
Finite-Difference Hyperbolic-Parabolic PDE Solver on Cartesian Grids
libROMInterface.cpp
Go to the documentation of this file.
1 #ifdef with_librom
2 
8 #include <string.h>
9 #include <arrayfunctions.h>
10 #include <simulation_object.h>
11 #include <rom_object_dmd.h>
12 #include <librom_interface.h>
13 
40 void libROMInterface::define( void* a_s,
41  int a_nsims,
42  int a_rank,
43  int a_nproc,
44  double a_dt )
45 {
46  const SimulationObject* sim = (const SimulationObject*) a_s;
47 
48  m_rank = a_rank;
49  m_nproc = a_nproc;
50  m_nsims = a_nsims;
51 
52  char mode_c_str[_MAX_STRING_SIZE_];
53  char comp_mode_c_str[_MAX_STRING_SIZE_];
54  char type_c_str[_MAX_STRING_SIZE_];
55  char save_c_str[_MAX_STRING_SIZE_];
56 
57  if (!m_rank) {
58 
59  FILE *in;
60  in = fopen(_LIBROM_INP_FNAME_,"r");
61 
62  if (!in) {
63 
64  strcpy( mode_c_str, _ROM_MODE_NONE_ );
65  strcpy( comp_mode_c_str, _ROM_COMP_MODE_MONOLITHIC_ );
66  strcpy( type_c_str, _ROM_TYPE_NONE_ );
67  strcpy( save_c_str, "false" );
68 
69  m_rdim = -1;
70  m_sampling_freq = 1;
71 
72  } else {
73 
74  strcpy( mode_c_str, _ROM_MODE_TRAIN_ );
75  strcpy( comp_mode_c_str, _ROM_COMP_MODE_MONOLITHIC_ );
76  strcpy( type_c_str,_ROM_TYPE_DMD_ );
77  strcpy( save_c_str, "true" );
78 
79  int ferr;
80  char word[_MAX_STRING_SIZE_];
81  ferr = fscanf(in,"%s", word); if (ferr != 1) return;
82 
83  if (std::string(word) == "begin") {
84  while (std::string(word) != "end") {
85  ferr = fscanf(in,"%s",word); if (ferr != 1) return;
86  if (std::string(word) == "rdim") {
87  ferr = fscanf(in,"%d", &m_rdim); if (ferr != 1) return;
88  } else if (std::string(word) == "sampling_frequency") {
89  ferr = fscanf(in,"%d", &m_sampling_freq); if (ferr != 1) return;
90  } else if (std::string(word) == "mode") {
91  ferr = fscanf(in,"%s", mode_c_str); if (ferr != 1) return;
92  } else if (std::string(word) == "component_mode") {
93  ferr = fscanf(in,"%s", comp_mode_c_str); if (ferr != 1) return;
94  } else if (std::string(word) == "type") {
95  ferr = fscanf(in,"%s", type_c_str); if (ferr != 1) return;
96  } else if (std::string(word) == "save_to_file") {
97  ferr = fscanf(in,"%s", save_c_str); if (ferr != 1) return;
98  }
99  if (ferr != 1) return;
100  }
101  } else {
102  fprintf( stderr, "Error: Illegal format in file \"%s\". Word read is: %s\n",
103  _LIBROM_INP_FNAME_, word);
104  return;
105  }
106 
107  fclose(in);
108 
109  }
110 
111  /* print useful stuff to screen */
112  if (std::string(mode_c_str) != _ROM_MODE_NONE_) {
113  printf("libROMInterface inputs and parameters:\n");
114  printf(" reduced model dimensionality: %d\n", m_rdim);
115  printf(" sampling frequency: %d\n", m_sampling_freq);
116  printf(" mode: %s\n", mode_c_str);
117  printf(" component mode: %s\n", comp_mode_c_str);
118  printf(" type: %s\n", type_c_str);
119  printf(" save to file: %s\n", save_c_str);
120  }
121  }
122 
123 #ifndef serial
124  MPI_Bcast(&m_rdim,1,MPI_INT,0,MPI_COMM_WORLD);
125  MPI_Bcast(&m_sampling_freq,1,MPI_INT,0,MPI_COMM_WORLD);
126  MPI_Bcast(mode_c_str,_MAX_STRING_SIZE_,MPI_CHAR,0,MPI_COMM_WORLD);
127  MPI_Bcast(comp_mode_c_str,_MAX_STRING_SIZE_,MPI_CHAR,0,MPI_COMM_WORLD);
128  MPI_Bcast(type_c_str,_MAX_STRING_SIZE_,MPI_CHAR,0,MPI_COMM_WORLD);
129  MPI_Bcast(save_c_str,_MAX_STRING_SIZE_,MPI_CHAR,0,MPI_COMM_WORLD);
130 #endif
131 
132  m_mode = std::string( mode_c_str );
133  m_comp_mode = std::string( comp_mode_c_str );
134  m_rom_type = std::string( type_c_str );
135 
136  m_save_ROM = (((std::string(save_c_str) == "true")) && (m_mode == _ROM_MODE_TRAIN_));
137 
138  if (m_mode != _ROM_MODE_NONE_) {
139 
140  m_vec_size.resize(m_nsims);
141  for (int ns = 0; ns < m_nsims; ns++) {
142  m_vec_size[ns] = (sim[ns].solver.npoints_local);
144  m_vec_size[ns] *= (sim[ns].solver.nvars);
145  }
146  }
147 
148  m_rom.clear();
149  m_U.clear();
151  for (int ns = 0; ns < m_nsims; ns++) {
152  if (m_rom_type == _ROM_TYPE_DMD_) {
153  m_rom.push_back(new DMDROMObject( m_vec_size[ns],
154  m_sampling_freq*a_dt,
155  m_rdim,
156  m_rank,
157  m_nproc,
158  ns ) );
159  }
160  m_U.push_back(new CAROM::Vector(m_vec_size[ns],true));
161  }
163  for (int ns = 0; ns < m_nsims; ns++) {
164  m_ncomps.push_back(sim[ns].solver.nvars);
165  for (int v = 0; v < sim[ns].solver.nvars; v++) {
166  if (m_rom_type == _ROM_TYPE_DMD_) {
167  m_rom.push_back(new DMDROMObject( m_vec_size[ns],
168  m_sampling_freq*a_dt,
169  m_rdim,
170  m_rank,
171  m_nproc,
172  ns,
173  v ) );
174  }
175  m_U.push_back(new CAROM::Vector(m_vec_size[ns],true));
176  }
177  }
178  }
179 
180  } else {
181 
182  m_rom.clear();
183  m_U.clear();
184  m_ncomps.clear();
185 
186  }
187 
188  m_train_wctime = 0;
189  m_predict_wctime = 0;
190 
191  m_is_defined = true;
192  return;
193 }
194 
198  const double a_t )
199 {
200  if (m_U.size() != m_rom.size()) {
201  printf( "ERROR in libROMInterface::takeSample(): m_U.size != m_rom.size() on rank %d!!\n",
202  m_rank );
203  }
204 
205  copyFromHyPar( m_U, a_s );
206  gettimeofday(&m_train_start, NULL);
207  for (int i = 0; i < m_rom.size(); i++) {
208  m_rom[i]->takeSample( *(m_U[i]), a_t );
209  }
210  gettimeofday(&m_train_end, NULL);
211 
212  long long walltime;
213  walltime = ( (m_train_end.tv_sec*1000000 + m_train_end.tv_usec)
214  - (m_train_start.tv_sec*1000000 + m_train_start.tv_usec) );
215  m_train_wctime += (double) walltime / 1000000.0;
216 
217 #ifndef serial
218  MPI_Allreduce( MPI_IN_PLACE,
220  1,
221  MPI_DOUBLE,
222  MPI_MAX,
223  MPI_COMM_WORLD );
224 #endif
225 }
226 
230 {
231  if (m_U.size() != m_rom.size()) {
232  printf("ERROR in libROMInterface::projectInitialSolution(): m_U.size != m_rom.size() on rank %d!\n",
233  m_rank );
234  }
235 
236  copyFromHyPar( m_U, a_s );
237  for (int i = 0; i < m_rom.size(); i++) {
238  m_rom[i]->projectInitialSolution( *(m_U[i]) );
239  }
240 
241  return;
242 }
243 
246 {
247  gettimeofday(&m_train_start, NULL);
248  for (int i = 0; i < m_rom.size(); i++) {
249  m_rom[i]->train();
250  }
251  gettimeofday(&m_train_end, NULL);
252 
253  long long walltime;
254  walltime = ( (m_train_end.tv_sec*1000000 + m_train_end.tv_usec)
255  - (m_train_start.tv_sec*1000000 + m_train_start.tv_usec) );
256  m_train_wctime += (double) walltime / 1000000.0;
257 #ifndef serial
258  MPI_Allreduce( MPI_IN_PLACE,
260  1,
261  MPI_DOUBLE,
262  MPI_MAX,
263  MPI_COMM_WORLD );
264 #endif
265 }
266 
268 void libROMInterface::predict(void* a_s,
269  const double a_t ) const
270 {
271  m_predict_wctime = 0.0;
272 
274 
275  for (int ns = 0; ns < m_nsims; ns++) {
276  gettimeofday(&m_predict_start, NULL);
277  const CAROM::Vector* const u_predicted = m_rom[ns]->predict(a_t);
278  gettimeofday(&m_predict_end, NULL);
279  copyToHyPar( *u_predicted, a_s, ns );
280 
281  long long walltime;
282  walltime = ( (m_predict_end.tv_sec*1000000 + m_predict_end.tv_usec)
283  - (m_predict_start.tv_sec*1000000 + m_predict_start.tv_usec) );
284  m_predict_wctime += (double) walltime / 1000000.0;
285  }
286 
288 
289  int count(0);
290  for (int ns = 0; ns < m_nsims; ns++) {
291  for (int v = 0; v < m_ncomps[ns]; v++) {
292  gettimeofday(&m_predict_start, NULL);
293  const CAROM::Vector* const u_predicted = m_rom[count]->predict(a_t);
294  gettimeofday(&m_predict_end, NULL);
295  copyToHyPar( *u_predicted, a_s, ns, v );
296 
297  long long walltime;
298  walltime = ( (m_predict_end.tv_sec*1000000 + m_predict_end.tv_usec)
299  - (m_predict_start.tv_sec*1000000 + m_predict_start.tv_usec) );
300  m_predict_wctime += (double) walltime / 1000000.0;
301  count++;
302  }
303  }
304 
305  }
306 
307 #ifndef serial
308  MPI_Allreduce( MPI_IN_PLACE,
310  1,
311  MPI_DOUBLE,
312  MPI_MAX,
313  MPI_COMM_WORLD );
314 #endif
315 }
316 
318 void libROMInterface::saveROM(const std::string& a_fname_root ) const
319 {
320  if (m_save_ROM) {
321 
322  if (!m_rank) {
323  printf("libROMInterface::saveROM() - saving ROM objects.\n");
324  }
325 
327 
328  for (int ns = 0; ns < m_nsims; ns++) {
329  std::string fname_root = a_fname_root;
330  if (m_nsims > 1) {
331  char idx_string[_MAX_STRING_SIZE_];
332  sprintf(idx_string, "sim%03d", ns);
333  fname_root += std::string(idx_string);
334  }
335  m_rom[ns]->save(fname_root);
336  }
337 
339 
340  int count(0);
341  for (int ns = 0; ns < m_nsims; ns++) {
342  for (int v = 0; v < m_ncomps[ns]; v++) {
343  std::string fname_root = a_fname_root;
344  if (m_nsims > 1) {
345  char idx_string[_MAX_STRING_SIZE_];
346  sprintf(idx_string, "sim%03d", ns);
347  fname_root += std::string(idx_string);
348  }
349  if (m_ncomps[ns] > 1) {
350  char idx_string[_MAX_STRING_SIZE_];
351  sprintf(idx_string, "var%03d", v);
352  fname_root += std::string(idx_string);
353  }
354  m_rom[count]->save(fname_root);
355  count++;
356  }
357  }
358 
359  }
360 
361  }
362 
363  return;
364 }
365 
367 void libROMInterface::loadROM(const std::string& a_fname_root )
368 {
369  if (!m_rank) {
370  printf("libROMInterface::loadROM() - loading ROM objects.\n");
371  }
372 
374 
375  for (int ns = 0; ns < m_nsims; ns++) {
376  std::string fname_root = a_fname_root;
377  if (m_nsims > 1) {
378  char idx_string[_MAX_STRING_SIZE_];
379  sprintf(idx_string, "sim%03d", ns);
380  fname_root += std::string(idx_string);
381  }
382  m_rom[ns]->load(fname_root);
383  }
384 
386 
387  int count(0);
388  for (int ns = 0; ns < m_nsims; ns++) {
389  for (int v = 0; v < m_ncomps[ns]; v++) {
390  std::string fname_root = a_fname_root;
391  if (m_nsims > 1) {
392  char idx_string[_MAX_STRING_SIZE_];
393  sprintf(idx_string, "sim%03d", ns);
394  fname_root += std::string(idx_string);
395  }
396  if (m_ncomps[ns] > 1) {
397  char idx_string[_MAX_STRING_SIZE_];
398  sprintf(idx_string, "var%03d", v);
399  fname_root += std::string(idx_string);
400  }
401  m_rom[count]->load(fname_root);
402  count++;
403  }
404  }
405 
406  }
407 
408  return;
409 }
410 
414 void libROMInterface::copyFromHyPar( std::vector<CAROM::Vector*>& a_U,
415  void* a_s )
417 {
418  const SimulationObject* sim = (const SimulationObject*) a_s;
419 
421 
422  for (int ns = 0; ns < m_nsims; ns++) {
423  double* vec = a_U[ns]->getData();
424  const double* u = sim[ns].solver.u;
425 
426  std::vector<int> index(sim[ns].solver.ndims);
427 
428  ArrayCopynD( sim[ns].solver.ndims,
429  u,
430  vec,
431  sim[ns].solver.dim_local,
432  sim[ns].solver.ghosts,
433  0,
434  index.data(),
435  sim[ns].solver.nvars );
436  }
437 
439 
440  int count(0);
441  for (int ns = 0; ns < m_nsims; ns++) {
442  for (int v = 0; v < sim[ns].solver.nvars; v++) {
443  double* vec = a_U[count]->getData();
444  const double* u = sim[ns].solver.u;
445 
446  std::vector<int> index(sim[ns].solver.ndims);
447 
448  ArrayCopynDComponent( sim[ns].solver.ndims,
449  u,
450  vec,
451  sim[ns].solver.dim_local,
452  sim[ns].solver.ghosts,
453  0,
454  index.data(),
455  sim[ns].solver.nvars,
456  1,
457  v,
458  0 );
459  count++;
460  }
461  }
462 
463  }
464 
465  return;
466 }
467 
475 void libROMInterface::copyToHyPar( const CAROM::Vector& a_vec,
476  void* a_s,
478  int a_idx ) const
479 {
480  SimulationObject* sim = (SimulationObject*) a_s;
481 
482  double* u;
483  if (m_mode == _ROM_MODE_TRAIN_) {
484  u = sim[a_idx].solver.u_rom_predicted;
485  } else {
486  u = sim[a_idx].solver.u;
487  }
488  std::vector<int> index(sim[a_idx].solver.ndims);
489 
490  ArrayCopynD( sim[a_idx].solver.ndims,
491  a_vec.getData(),
492  u,
493  sim[a_idx].solver.dim_local,
494  0,
495  sim[a_idx].solver.ghosts,
496  index.data(),
497  sim[a_idx].solver.nvars );
498 
499  return;
500 }
501 
509 void libROMInterface::copyToHyPar( const CAROM::Vector& a_vec,
510  void* a_s,
512  int a_idx ,
513  int a_var ) const
514 {
515  SimulationObject* sim = (SimulationObject*) a_s;
516 
517  double* u;
518  if (m_mode == _ROM_MODE_TRAIN_) {
519  u = sim[a_idx].solver.u_rom_predicted;
520  } else {
521  u = sim[a_idx].solver.u;
522  }
523  std::vector<int> index(sim[a_idx].solver.ndims);
524 
525  ArrayCopynDComponent( sim[a_idx].solver.ndims,
526  a_vec.getData(),
527  u,
528  sim[a_idx].solver.dim_local,
529  0,
530  sim[a_idx].solver.ghosts,
531  index.data(),
532  1,
533  sim[a_idx].solver.nvars,
534  0,
535  a_var );
536 
537  return;
538 }
539 
540 #endif
int nvars
Definition: hypar.h:29
#define _ROM_COMP_MODE_COMPONENTWISE_
Structure defining a simulation.
struct timeval m_train_start
#define _LIBROM_INP_FNAME_
Definition: rom_object.h:15
#define _ROM_COMP_MODE_MONOLITHIC_
void takeSample(void *a_s, const double a_t)
Dynamic Mode Decomposition ROM object.
double * u
Definition: hypar.h:116
void saveROM(const std::string &a_fname_root="") const
int npoints_local
Definition: hypar.h:42
struct timeval m_train_end
std::vector< ROMObject * > m_rom
Simulation object.
struct timeval m_predict_start
struct timeval m_predict_end
void loadROM(const std::string &a_fname_root="")
#define _ROM_MODE_NONE_
#define _MAX_STRING_SIZE_
Definition: basic.h:14
std::string m_mode
#define _ROM_MODE_TRAIN_
void copyFromHyPar(std::vector< CAROM::Vector *> &, void *)
#define _ROM_TYPE_DMD_
INLINE int ArrayCopynDComponent(int ndims, const double *x, double *y, int *dim, int g1, int g2, int *index, int nvars_from, int nvars_to, int var_from, int var_to)
std::vector< CAROM::Vector * > m_U
#define _ROM_TYPE_NONE_
Definition: rom_object.h:12
INLINE int ArrayCopynD(int, const double *, double *, int *, int, int, int *, int)
int * dim_local
Definition: hypar.h:37
void projectInitialSolution(void *a_s)
libROM interface class
int ghosts
Definition: hypar.h:52
std::vector< int > m_ncomps
std::vector< int > m_vec_size
double * u_rom_predicted
Definition: hypar.h:403
void define(void *, int, int, int, double)
void predict(void *a_s, const double a_t) const
Contains macros and function definitions for common array operations.
void copyToHyPar(const CAROM::Vector &, void *, int) const
std::string m_comp_mode
ROM object of type DMD (see libROM)
std::string m_rom_type