ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
StationSampler Class Reference

#include <ERF_StationSampler.H>

Collaboration diagram for StationSampler:

Public Member Functions

 StationSampler (const std::string &pp_prefix)
 
bool empty () const
 
amrex::Vector< Station > & stations ()
 
const amrex::Vector< Station > & stations () const
 
int numColumns () const
 
void buildColumns ()
 
void appendRow (amrex::Real time, amrex::Real epoch_time, const amrex::Vector< amrex::Real > &values)
 
void flush ()
 
void setRestart (bool is_restart)
 
void checkRestartFiles () const
 
void setWriteTimestamp (bool write_timestamp, const std::string &datetime_format)
 
int bufferSteps () const
 
bool allowUnavailable () const
 
bool lowHeightWarned () const
 
void setLowHeightWarned ()
 
bool levelsReported () const
 
void setLevelsReported ()
 
bool stencilsValidFor (const amrex::Vector< amrex::BoxArray > &ba, int finest_level) const
 
void rememberStencilGrids (const amrex::Vector< amrex::BoxArray > &ba, int finest_level)
 

Private Member Functions

void writeHeader (const Station &station, std::ostream &os) const
 
std::string columnSignature (const Station &station) const
 
void checkHeaderMatches (const Station &station, const std::string &filename) const
 

Private Attributes

amrex::Vector< Station > m_stations
 
int m_ncolumns = 0
 
int m_buffer_steps = 100
 
bool m_allow_unavailable = false
 
amrex::Vector< amrex::Real > m_times
 
amrex::Vector< amrex::Real > m_epoch_times
 
amrex::Vector< amrex::Real > m_rows
 
amrex::Vector< amrex::BoxArray > m_stencil_grids
 
bool m_is_restart = false
 
bool m_low_height_warned = false
 
bool m_levels_reported = false
 
bool m_write_timestamp = false
 
std::string m_datetime_format
 
std::string m_dir = "Output_Stations"
 
bool m_opened = false
 

Constructor & Destructor Documentation

◆ StationSampler()

StationSampler::StationSampler ( const std::string &  pp_prefix)
explicit
224 {
225  ParmParse pp(pp_prefix);
226 
227  Vector<std::string> names;
228  const int nstation = pp.countval("station_names");
229  if (nstation > 0) {
230  pp.getarr("station_names", names, 0, nstation);
231  }
232 
233  pp.queryAdd("station_buffer_steps", m_buffer_steps);
234  if (m_buffer_steps < 1) { m_buffer_steps = 1; }
235 
236  pp.queryAdd("station_output_dir", m_dir);
237 
238  pp.queryAdd("station_allow_unavailable", m_allow_unavailable);
239 
240  for (const auto& name : names)
241  {
242  check_station_name(name);
243  for (const auto& earlier : m_stations) {
244  if (earlier.name == name) {
245  amrex::Abort("Station '" + name + "' is named twice in erf.station_names; the "
246  "two would write the same file");
247  }
248  }
249 
250  Station station;
251  station.name = name;
252 
253  ParmParse pps(pp_prefix + "." + name);
254 
255  const int nfield = pps.countval("field");
256  if (nfield <= 0) {
257  Abort(station_key_error(name, "field", "must name at least one variable"));
258  }
259  Vector<std::string> fields;
260  pps.getarr("field", fields, 0, nfield);
261  for (const auto& field : fields) {
262  StationVar var;
263  var.name = field;
264  station.vars.push_back(var);
265  }
266 
267  // A station is placed either in lat/lon or in domain coordinates, never both.
268  const std::string lon_key = pps.contains("long") ? "long" : "lon";
269  const bool has_lat = pps.contains("lat");
270  const bool has_lon = pps.contains("long") || pps.contains("lon");
271  const bool has_x = pps.contains("x");
272  const bool has_y = pps.contains("y");
273 
274  if ((has_lat || has_lon) && (has_x || has_y)) {
275  Abort("Station '" + name + "': specify either lat/long or x/y, not both");
276  }
277 
278  if (has_lat || has_lon) {
279  if (!has_lat || !has_lon) {
280  Abort("Station '" + name + "': lat and long must both be given");
281  }
282  const int nlat = pps.countval("lat");
283  const int nlon = pps.countval(lon_key.c_str());
284  if (nlat != nlon) {
285  Abort("Station '" + name + "': lat has " + std::to_string(nlat) +
286  " values but " + lon_key + " has " + std::to_string(nlon) +
287  "; they are paired, so the counts must match");
288  }
289  Vector<Real> lat, lon;
290  pps.getarr("lat", lat, 0, nlat);
291  pps.getarr(lon_key.c_str(), lon, 0, nlon);
292  for (int i = 0; i < nlat; ++i) {
293  StationLoc loc;
294  loc.use_latlon = true;
295  loc.req_lat = lat[i];
296  loc.req_lon = lon[i];
297  station.locs.push_back(loc);
298  }
299  } else {
300  if (!has_x || !has_y) {
301  Abort("Station '" + name + "': give either lat/long, or x and y in domain coordinates");
302  }
303  const int nx = pps.countval("x");
304  const int ny = pps.countval("y");
305  if (nx != ny) {
306  Abort("Station '" + name + "': x has " + std::to_string(nx) +
307  " values but y has " + std::to_string(ny) +
308  "; they are paired, so the counts must match");
309  }
310  Vector<Real> xv, yv;
311  pps.getarr("x", xv, 0, nx);
312  pps.getarr("y", yv, 0, ny);
313  for (int i = 0; i < nx; ++i) {
314  StationLoc loc;
315  loc.use_latlon = false;
316  loc.x = xv[i];
317  loc.y = yv[i];
318  station.locs.push_back(loc);
319  }
320  }
321 
322  // Heights come in one of two ways, and the difference is only what the
323  // zero of the column is: .height_agl measures from the local terrain,
324  // .height_abs from the bottom of the domain, in the same z the geometry
325  // is given in. Both are read into the one list the rest of the sampler
326  // uses, with a flag saying which zero it is, so nothing downstream has
327  // to ask which key the user typed.
328  const int n_agl = pps.countval("height_agl");
329  const int n_abs = pps.countval("height_abs");
330 
331  if (n_agl > 0 && n_abs > 0) {
332  Abort("Station '" + name + "': give heights as either erf." + name +
333  ".height_agl (above the local terrain) or erf." + name +
334  ".height_abs (in the model's z coordinate), not both");
335  }
336  if (pps.contains("height")) {
337  Abort("Station '" + name + "': erf." + name + ".height is not a key; say "
338  "erf." + name + ".height_agl for metres above the local terrain, or erf." +
339  name + ".height_abs for metres in the model's z coordinate");
340  }
341 
342  station.heights_are_agl = (n_abs == 0);
343  const char* height_key = station.heights_are_agl ? "height_agl" : "height_abs";
344  const int nheight = std::max(n_agl, n_abs);
345  if (nheight > 0) {
346  pps.getarr(height_key, station.heights, 0, nheight);
347  }
348 
349  m_stations.push_back(std::move(station));
350  }
351 }
const int nx
Definition: ERF_InitCustomPertVels_CloudChamber.H:14
const int ny
Definition: ERF_InitCustomPertVels_CloudChamber.H:15
ParmParse pp("prob")
std::string name
Definition: ERF_Plotfile2DCatalog.cpp:116
amrex::Vector< Station > m_stations
Definition: ERF_StationSampler.H:272
int m_buffer_steps
Definition: ERF_StationSampler.H:274
bool m_allow_unavailable
Definition: ERF_StationSampler.H:275
std::string m_dir
Definition: ERF_StationSampler.H:292
Definition: ERF_StationSampler.H:117
amrex::Real req_lat
Definition: ERF_StationSampler.H:121
amrex::Real req_lon
Definition: ERF_StationSampler.H:122
amrex::Real x
Definition: ERF_StationSampler.H:125
bool use_latlon
Definition: ERF_StationSampler.H:118
amrex::Real y
Definition: ERF_StationSampler.H:126
Definition: ERF_StationSampler.H:71
std::string name
Definition: ERF_StationSampler.H:72
Definition: ERF_StationSampler.H:174
amrex::Vector< StationLoc > locs
Definition: ERF_StationSampler.H:177
bool heights_are_agl
Definition: ERF_StationSampler.H:183
std::string name
Definition: ERF_StationSampler.H:175
amrex::Vector< amrex::Real > heights
Definition: ERF_StationSampler.H:182
amrex::Vector< StationVar > vars
Definition: ERF_StationSampler.H:176
Here is the call graph for this function:

Member Function Documentation

◆ allowUnavailable()

bool StationSampler::allowUnavailable ( ) const
inline
236 { return m_allow_unavailable; }

◆ appendRow()

void StationSampler::appendRow ( amrex::Real  time,
amrex::Real  epoch_time,
const amrex::Vector< amrex::Real > &  values 
)
380 {
381  AMREX_ALWAYS_ASSERT(static_cast<int>(values.size()) == m_ncolumns);
382 
383  if (ParallelDescriptor::IOProcessor()) {
384  m_times.push_back(time);
385  m_epoch_times.push_back(epoch_time);
386  m_rows.insert(m_rows.end(), values.begin(), values.end());
387 
388  if (static_cast<int>(m_times.size()) >= m_buffer_steps) { flush(); }
389  }
390 }
AMREX_ALWAYS_ASSERT(bx.length()[2]==khi+1)
int m_ncolumns
Definition: ERF_StationSampler.H:273
amrex::Vector< amrex::Real > m_epoch_times
Definition: ERF_StationSampler.H:279
amrex::Vector< amrex::Real > m_rows
Definition: ERF_StationSampler.H:280
void flush()
Definition: ERF_StationSampler.cpp:636
amrex::Vector< amrex::Real > m_times
Definition: ERF_StationSampler.H:278
Here is the call graph for this function:

◆ bufferSteps()

int StationSampler::bufferSteps ( ) const
inline
232 { return m_buffer_steps; }

◆ buildColumns()

void StationSampler::buildColumns ( )
360 {
361  m_ncolumns = 0;
362  for (auto& station : m_stations) {
363  station.columns.clear();
364  for (int il = 0; il < static_cast<int>(station.locs.size()); ++il) {
365  station.locs[il].col_begin = static_cast<int>(station.columns.size());
366  for (int iv = 0; iv < static_cast<int>(station.vars.size()); ++iv) {
367  if (station.vars[iv].is_2d) { station.columns.push_back(m_ncolumns++); }
368  }
369  for (int ih = 0; ih < static_cast<int>(station.heights.size()); ++ih) {
370  for (int iv = 0; iv < static_cast<int>(station.vars.size()); ++iv) {
371  if (!station.vars[iv].is_2d) { station.columns.push_back(m_ncolumns++); }
372  }
373  }
374  }
375  }
376 }

◆ checkHeaderMatches()

void StationSampler::checkHeaderMatches ( const Station &  station,
const std::string &  filename 
) const
private
524 {
525  const std::vector<std::string> found = read_station_header(filename);
526  const std::string found_format = find_format_line(found);
527  const std::string want_format = columnSignature(station);
528 
529  if (found_format == want_format) { return; }
530 
531  if (found_format.empty()) {
532  Abort("Station '" + station.name + "': " + filename + " has no '# format:' line, so it "
533  "was not written by this version of ERF's station output and cannot be appended "
534  "to. Move it aside and start a new series.");
535  }
536 
537  // A tag mismatch is a different thing from a hash mismatch and deserves a
538  // different message: nothing about the run is wrong, the file is just old.
539  const std::string found_tag = found_format.substr(0, found_format.find(' '));
540  if (found_tag != std::string(station_format_tag)) {
541  Abort("Station '" + station.name + "': " + filename + " is in station file format '" +
542  found_tag + "' and this ERF writes '" + station_format_tag + "'. Move it aside "
543  "and start a new series.");
544  }
545 
546  // Same format, different columns. Point at the first column line that
547  // differs, which is the useful thing to say; the signature is what decided.
548  std::ostringstream expected;
549  writeHeader(station, expected);
550  std::vector<std::string> want;
551  {
552  std::istringstream is(expected.str());
553  std::string line;
554  while (std::getline(is, line)) { want.push_back(line); }
555  }
556 
557  // The signature lines differ by construction, so they say nothing a reader
558  // does not already know; what is worth reporting is the first column that
559  // differs.
560  auto without_signature = [](const std::vector<std::string>& lines) {
561  std::vector<std::string> out;
562  for (const auto& line : lines) {
563  if (line.compare(0, 10, "# format: ") != 0) { out.push_back(line); }
564  }
565  return out;
566  };
567  const std::vector<std::string> want_cmp = without_signature(want);
568  const std::vector<std::string> found_cmp = without_signature(found);
569 
570  std::string detail = "\n the difference is not one the header spells out";
571  for (std::size_t i = 0; i < want_cmp.size() || i < found_cmp.size(); ++i) {
572  const bool have_want = (i < want_cmp.size());
573  const bool have_found = (i < found_cmp.size());
574  if (have_want && have_found && want_cmp[i] == found_cmp[i]) { continue; }
575  if (have_want && have_found) {
576  detail = "\n the file says: " + found_cmp[i] +
577  "\n this run would write: " + want_cmp[i];
578  } else if (have_found) {
579  detail = "\n the file has a column this run does not: " + found_cmp[i];
580  } else {
581  detail = "\n this run has a column the file does not: " + want_cmp[i];
582  }
583  break;
584  }
585 
586  Abort("Station '" + station.name + "': " + filename + " describes a different set of "
587  "columns than this restart would write -- a changed field, location, height or "
588  "units list -- so appending to it would produce columns its header does not "
589  "describe. Change the configuration back, or move the file aside and start a "
590  "new series." + detail);
591 }
std::string columnSignature(const Station &station) const
Definition: ERF_StationSampler.cpp:406
void writeHeader(const Station &station, std::ostream &os) const
Definition: ERF_StationSampler.cpp:444

◆ checkRestartFiles()

void StationSampler::checkRestartFiles ( ) const
602 {
603  if (!m_is_restart) { return; }
604  if (!ParallelDescriptor::IOProcessor()) { return; }
605 
606  for (const auto& station : m_stations) {
607  const std::string filename = m_dir + "/" + station.name + ".dat";
608  if (FileExists(filename)) { checkHeaderMatches(station, filename); }
609  }
610 }
bool m_is_restart
Definition: ERF_StationSampler.H:286
void checkHeaderMatches(const Station &station, const std::string &filename) const
Definition: ERF_StationSampler.cpp:523

◆ columnSignature()

std::string StationSampler::columnSignature ( const Station &  station) const
private
407 {
408  std::ostringstream os;
409  os << std::setprecision(sigprecision);
410  os << station_format_tag << '|' << station.name
411  << "|ts=" << (m_write_timestamp ? 1 : 0);
412 
413  auto describe = [&](const StationVar& var, Real height, bool with_height)
414  {
415  os << '|' << var.name << ':' << var.units;
416  if (with_height) {
417  os << ':' << height << (station.heights_are_agl ? "agl" : "abs");
418  } else {
419  os << ":2d";
420  }
421  if (var.is_missing) { os << ":na"; }
422  };
423 
424  for (const auto& loc : station.locs) {
425  os << "|@";
426  if (loc.use_latlon) {
427  os << "ll=" << loc.req_lat << ',' << loc.req_lon;
428  } else {
429  os << "xy=" << loc.x << ',' << loc.y;
430  }
431  for (const auto& var : station.vars) {
432  if (var.is_2d) { describe(var, Real(0.0), false); }
433  }
434  for (const auto height : station.heights) {
435  for (const auto& var : station.vars) {
436  if (!var.is_2d) { describe(var, height, true); }
437  }
438  }
439  }
440  return std::string(station_format_tag) + " " + signature_hash(os.str());
441 }
Real height
Definition: ERF_InitCustomPert_SquallLine.H:37
amrex::Real Real
Definition: ERF_ShocInterface.H:19
bool m_write_timestamp
Definition: ERF_StationSampler.H:289
std::string units
Definition: ERF_StationSampler.H:73
bool is_missing
Definition: ERF_StationSampler.H:75
bool is_2d
Definition: ERF_StationSampler.H:74

◆ empty()

bool StationSampler::empty ( ) const
inline
201 { return m_stations.empty(); }

◆ flush()

void StationSampler::flush ( )
637 {
638  if (!ParallelDescriptor::IOProcessor()) { return; }
639 
640  const int nrow = static_cast<int>(m_times.size());
641  if (nrow == 0) { return; }
642 
643  if (!m_opened) {
644  if (!UtilCreateDirectory(m_dir, 0755)) { CreateDirectoryFailed(m_dir); }
645  }
646 
647  for (const auto& station : m_stations)
648  {
649  const std::string filename = m_dir + "/" + station.name + ".dat";
650 
651  // A run that is restarting appends to the file it wrote before, so the
652  // series is continuous; the restart is marked in a comment rather than
653  // by starting a new file. A run that is not restarting starts afresh.
654  const bool append = m_opened || (m_is_restart && FileExists(filename));
655 
656  // The first thing a restart writes into an existing file: drop anything
657  // the earlier run wrote past the checkpoint this run restarted from.
658  // That the file is the same series was settled at setup, by
659  // checkRestartFiles.
660  if (append && !m_opened) {
661  const int dropped = truncate_station_file(filename, m_times[0]);
662  if (dropped > 0) {
663  Print() << "Station output: dropped " << dropped << " row(s) at or after t = "
664  << m_times[0] << " from " << filename << ", written by the run before "
665  << "the restart past the checkpoint it restarted from" << std::endl;
666  }
667  }
668 
669  std::ofstream os(filename, append ? (std::ios::out | std::ios::app)
670  : (std::ios::out | std::ios::trunc));
671  if (!os.good()) { FileOpenFailed(filename); }
672 
673  if (!m_opened) {
674  if (append) {
675  os << "# restarted run resumes at t = "
676  << std::setprecision(timeprecision) << m_times[0] << "\n";
677  } else {
678  writeHeader(station, os);
679  }
680  }
681 
682  for (int irow = 0; irow < nrow; ++irow) {
683  os << std::setw(datwidth) << std::setprecision(timeprecision) << m_times[irow];
684  if (m_write_timestamp) {
685  // Every column has to be one whitespace-delimited field for the
686  // file to be readable by column, and the usual datetime formats
687  // put a space between the date and the time.
688  std::string stamp = getTimestamp(static_cast<double>(m_epoch_times[irow]),
689  m_datetime_format, false);
690  std::replace(stamp.begin(), stamp.end(), ' ', 'T');
691  os << std::setw(datwidth) << stamp;
692  }
693  for (const int icol : station.columns) {
694  os << std::setw(datwidth) << std::setprecision(datprecision)
695  << m_rows[static_cast<std::size_t>(irow)*m_ncolumns + icol];
696  }
697  os << "\n";
698  }
699  os.close();
700  }
701 
702  m_opened = true;
703  m_times.clear();
704  m_epoch_times.clear();
705  m_rows.clear();
706 }
AMREX_FORCE_INLINE std::string getTimestamp(const double epoch_real, const std::string &datetime_format, bool add_long_frac=true)
Definition: ERF_EpochTime.H:125
std::string m_datetime_format
Definition: ERF_StationSampler.H:290
bool m_opened
Definition: ERF_StationSampler.H:293
Here is the call graph for this function:

◆ levelsReported()

bool StationSampler::levelsReported ( ) const
inline
245 { return m_levels_reported; }
bool m_levels_reported
Definition: ERF_StationSampler.H:288

◆ lowHeightWarned()

bool StationSampler::lowHeightWarned ( ) const
inline
240 { return m_low_height_warned; }
bool m_low_height_warned
Definition: ERF_StationSampler.H:287

◆ numColumns()

int StationSampler::numColumns ( ) const
inline
206 { return m_ncolumns; }

◆ rememberStencilGrids()

void StationSampler::rememberStencilGrids ( const amrex::Vector< amrex::BoxArray > &  ba,
int  finest_level 
)
630 {
631  m_stencil_grids.resize(finest_level+1);
632  for (int lev = 0; lev <= finest_level; ++lev) { m_stencil_grids[lev] = ba[lev]; }
633 }
amrex::Vector< amrex::BoxArray > m_stencil_grids
Definition: ERF_StationSampler.H:284

◆ setLevelsReported()

void StationSampler::setLevelsReported ( )
inline
246 { m_levels_reported = true; }

◆ setLowHeightWarned()

void StationSampler::setLowHeightWarned ( )
inline
241 { m_low_height_warned = true; }

◆ setRestart()

void StationSampler::setRestart ( bool  is_restart)
inline
220 { m_is_restart = is_restart; }

◆ setWriteTimestamp()

void StationSampler::setWriteTimestamp ( bool  write_timestamp,
const std::string &  datetime_format 
)
inline
227  {
228  m_write_timestamp = write_timestamp;
229  m_datetime_format = datetime_format;
230  }

◆ stations() [1/2]

amrex::Vector<Station>& StationSampler::stations ( )
inline
203 { return m_stations; }

◆ stations() [2/2]

const amrex::Vector<Station>& StationSampler::stations ( ) const
inline
204 { return m_stations; }

◆ stencilsValidFor()

bool StationSampler::stencilsValidFor ( const amrex::Vector< amrex::BoxArray > &  ba,
int  finest_level 
) const
620 {
621  if (static_cast<int>(m_stencil_grids.size()) != finest_level+1) { return false; }
622  for (int lev = 0; lev <= finest_level; ++lev) {
623  if (m_stencil_grids[lev] != ba[lev]) { return false; }
624  }
625  return true;
626 }

◆ writeHeader()

void StationSampler::writeHeader ( const Station &  station,
std::ostream &  os 
) const
private
445 {
446  // Coordinates are written with enough digits that a reader can tell two
447  // neighbouring stations apart
448  os << std::setprecision(datprecision);
449  os << "# ERF station time series\n";
450  // The one line a restart compares. Everything below it is for the reader.
451  os << "# format: " << columnSignature(station) << "\n";
452  os << "# station: " << station.name << "\n";
453 
454  int col = 1;
455  os << "# column " << col++ << ": time [s]\n";
456  if (m_write_timestamp) {
457  os << "# column " << col++ << ": UTC timestamp (" << m_datetime_format
458  << ", with 'T' where the format has a space, so the column is one field)\n";
459  }
460 
461  const bool station_heights_are_agl = station.heights_are_agl;
462 
463  auto describe = [&](const StationLoc& loc, const StationVar& var, Real height, bool with_height)
464  {
465  os << "# column " << col++ << ": " << var.name;
466  if (!var.units.empty()) { os << " [" << var.units << "]"; }
467  if (loc.use_latlon) {
468  os << " at requested lat=" << loc.req_lat << " long=" << loc.req_lon
469  << " (sampled lat=" << loc.got_lat << " long=" << loc.got_lon << ")";
470  }
471  os << " at x=" << loc.x << " y=" << loc.y;
472  if (with_height) {
473  os << ", height=" << height
474  << (station_heights_are_agl ? " m above local terrain" : " m (absolute, model z)");
475  if (height < loc.first_cc_height) {
476  os << " -- below the first cell centre, so sampled there, at height="
477  << loc.first_cc_height << " m when this file was started";
478  }
479  }
480  if (var.is_missing) { os << " [NOT AVAILABLE in this run: constant " << var.missing_value << "]"; }
481  if (var.earth_wind != StationEarthWind::None) {
482  os << " (earth-relative; grid x axis at "
483  << std::atan2(loc.sin_alpha, loc.cos_alpha) * Real(180.0) / PI
484  << " deg counterclockwise from east";
485  if (var.earth_wind == StationEarthWind::WindDir) {
486  os << "; degrees clockwise from north, wind from; " << var.missing_value << " when calm";
487  }
488  os << ")";
489  }
490  os << "\n";
491  };
492 
493  for (const auto& loc : station.locs) {
494  for (const auto& var : station.vars) {
495  if (var.is_2d) { describe(loc, var, Real(0.0), false); }
496  }
497  for (const auto height : station.heights) {
498  for (const auto& var : station.vars) {
499  if (!var.is_2d) { describe(loc, var, height, true); }
500  }
501  }
502  }
503  os << "#\n";
504  os << "# Values are bilinearly interpolated in the horizontal and linearly\n";
505  os << "# interpolated in the vertical, from the finest level that covers the\n";
506  os << "# interpolation stencil.\n";
507  os << "# A requested height below the first cell centre of that level is\n";
508  os << "# reported as the value at the first cell centre; the columns where that\n";
509  os << "# happens say so above. Their sampled height is the one when this file\n";
510  os << "# was started, and can change if regridding changes the level sampled from.\n";
511 }
constexpr amrex::Real PI
Definition: ERF_NumericalConstants.H:46
amrex::Real cos_alpha
Definition: ERF_StationSampler.H:136
amrex::Real got_lat
Definition: ERF_StationSampler.H:130
amrex::Real sin_alpha
Definition: ERF_StationSampler.H:137
amrex::Real first_cc_height
Definition: ERF_StationSampler.H:155
amrex::Real got_lon
Definition: ERF_StationSampler.H:131

Member Data Documentation

◆ m_allow_unavailable

bool StationSampler::m_allow_unavailable = false
private

Referenced by allowUnavailable().

◆ m_buffer_steps

int StationSampler::m_buffer_steps = 100
private

Referenced by bufferSteps().

◆ m_datetime_format

std::string StationSampler::m_datetime_format
private

Referenced by setWriteTimestamp().

◆ m_dir

std::string StationSampler::m_dir = "Output_Stations"
private

◆ m_epoch_times

amrex::Vector<amrex::Real> StationSampler::m_epoch_times
private

◆ m_is_restart

bool StationSampler::m_is_restart = false
private

Referenced by setRestart().

◆ m_levels_reported

bool StationSampler::m_levels_reported = false
private

◆ m_low_height_warned

bool StationSampler::m_low_height_warned = false
private

◆ m_ncolumns

int StationSampler::m_ncolumns = 0
private

Referenced by numColumns().

◆ m_opened

bool StationSampler::m_opened = false
private

◆ m_rows

amrex::Vector<amrex::Real> StationSampler::m_rows
private

◆ m_stations

amrex::Vector<Station> StationSampler::m_stations
private

Referenced by empty(), and stations().

◆ m_stencil_grids

amrex::Vector<amrex::BoxArray> StationSampler::m_stencil_grids
private

◆ m_times

amrex::Vector<amrex::Real> StationSampler::m_times
private

◆ m_write_timestamp

bool StationSampler::m_write_timestamp = false
private

Referenced by setWriteTimestamp().


The documentation for this class was generated from the following files: