ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_ReadCustomBinaryIC.H File Reference
#include <array>
#include <fstream>
#include <limits>
#include "ERF_DataStruct.H"
Include dependency graph for ERF_ReadCustomBinaryIC.H:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void ReadCustomBinaryIC (const std::string filename, amrex::Vector< amrex::Real > &latvec_h, amrex::Vector< amrex::Real > &lonvec_h, amrex::Vector< amrex::Real > &xvec_h, amrex::Vector< amrex::Real > &yvec_h, amrex::Vector< amrex::Real > &zvec_h, amrex::Vector< amrex::Real > &rho_h, amrex::Vector< amrex::Real > &uvel_h, amrex::Vector< amrex::Real > &vvel_h, amrex::Vector< amrex::Real > &wvel_h, amrex::Vector< amrex::Real > &theta_h, amrex::Vector< amrex::Real > &qv_h, amrex::Vector< amrex::Real > &qc_h, amrex::Vector< amrex::Real > &qr_h)
 

Function Documentation

◆ ReadCustomBinaryIC()

void ReadCustomBinaryIC ( const std::string  filename,
amrex::Vector< amrex::Real > &  latvec_h,
amrex::Vector< amrex::Real > &  lonvec_h,
amrex::Vector< amrex::Real > &  xvec_h,
amrex::Vector< amrex::Real > &  yvec_h,
amrex::Vector< amrex::Real > &  zvec_h,
amrex::Vector< amrex::Real > &  rho_h,
amrex::Vector< amrex::Real > &  uvel_h,
amrex::Vector< amrex::Real > &  vvel_h,
amrex::Vector< amrex::Real > &  wvel_h,
amrex::Vector< amrex::Real > &  theta_h,
amrex::Vector< amrex::Real > &  qv_h,
amrex::Vector< amrex::Real > &  qc_h,
amrex::Vector< amrex::Real > &  qr_h 
)
inline
30 {
31  int nx = 0, ny = 0, nz = 0, ndata = 0;
32  float value;
33 
34  // Open the binary file in input mode
35  std::ifstream infile(filename, std::ios::binary);
36  if (!infile) {
37  amrex::Abort("Error: Could not open file " + filename);
38  }
39 
40  auto read_or_abort = [&](auto& dest, const std::string& field_name) {
41  infile.read(reinterpret_cast<char*>(&dest), sizeof(dest));
42  if (!infile) {
43  amrex::Abort("Error reading " + field_name + " from " + filename);
44  }
45  };
46 
47  auto read_float_vector = [&](amrex::Vector<amrex::Real>& dest,
48  amrex::Long count,
49  const std::string& field_name)
50  {
51  if (count < 0) {
52  amrex::Abort("Error: negative element count for " + field_name + " in " + filename);
53  }
54 
55  dest.reserve(dest.size() + count);
56  for (amrex::Long idx = 0; idx < count; ++idx) {
57  read_or_abort(value, field_name);
58  dest.emplace_back(value);
59  }
60  };
61 
62  // Read the four integers
63  read_or_abort(nx, "nx");
64  read_or_abort(ny, "ny");
65  read_or_abort(nz, "nz");
66  read_or_abort(ndata, "ndata");
67 
68  if (nx <= 0 || ny <= 0 || nz <= 0) {
69  amrex::Abort("Error: invalid custom binary dimensions in " + filename);
70  }
71 
72  if (ndata < 0 || ndata > 8) {
73  amrex::Abort("Error: unsupported number of data fields in " + filename);
74  }
75 
76  // The dimensions come from the file: form the element counts in 64 bits, refusing any
77  // whose byte count would overflow, and check the file holds that many values before
78  // reserving room for them
79  constexpr amrex::Long max_count = std::numeric_limits<amrex::Long>::max()
80  / static_cast<amrex::Long>(sizeof(float));
81  const amrex::Long nxy = static_cast<amrex::Long>(nx) * ny;
82  if (nz > max_count / nxy) {
83  amrex::Abort("Error: custom binary dimensions too large in " + filename);
84  }
85  const amrex::Long nxyz = nxy * nz;
86 
87  // 2 nxy + nx + ny + nz + ndata nxyz values, without overflowing
88  amrex::Long nvalues = 2*nxy + nx + ny + nz;
89  if (nvalues > max_count || (ndata > 0 && nxyz > (max_count - nvalues) / ndata)) {
90  amrex::Abort("Error: custom binary dimensions too large in " + filename);
91  }
92  nvalues += ndata * nxyz;
93 
94  const auto data_start = infile.tellg();
95  infile.seekg(0, std::ios::end);
96  const auto bytes_left = static_cast<amrex::Long>(infile.tellg() - data_start);
97  infile.seekg(data_start);
98  if (!infile || bytes_left < nvalues * static_cast<amrex::Long>(sizeof(float))) {
99  amrex::Abort("Error: " + filename + " is shorter than its dimensions say");
100  }
101 
102  read_float_vector(latvec_h, nxy, "latitude");
103  read_float_vector(lonvec_h, nxy, "longitude");
104  read_float_vector(xvec_h, nx, "x coordinates");
105  read_float_vector(yvec_h, ny, "y coordinates");
106  read_float_vector(zvec_h, nz, "z coordinates");
107 
108  std::array<amrex::Vector<amrex::Real>*, 8> data_fields = {
109  &rho_h, &uvel_h, &vvel_h, &wvel_h, &theta_h, &qv_h, &qc_h, &qr_h
110  };
111 
112  // Read the file
113  for (int idx = 0; idx < ndata; ++idx) {
114  read_float_vector(*data_fields[idx], nxyz,
115  "data field " + std::to_string(idx));
116  }
117 }
const int nx
Definition: ERF_InitCustomPertVels_CloudChamber.H:14
const int ny
Definition: ERF_InitCustomPertVels_CloudChamber.H:15
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE int idx(int i, int j, int k, int nx, int ny)
Definition: ERF_InitForEnsemble.cpp:404
Vector< Real > rho_h(khi+1, zero)

Referenced by ERF::FillForecastStateMultiFabs().

Here is the call graph for this function:
Here is the caller graph for this function: