ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_InputSpongeData.H
Go to the documentation of this file.
1 #ifndef ERF_INPUT_SPONGE_DATA_H_
2 #define ERF_INPUT_SPONGE_DATA_H_
3 
4 #include <string>
5 #include <iostream>
6 
7 #include <AMReX_ParmParse.H>
8 #include <AMReX_Print.H>
9 #include <AMReX_Gpu.H>
10 #include <AMReX_Geometry.H>
11 
12 #include <ERF_Constants.H>
13 #include <ERF_Interpolation_1D.H>
14 
15 /**
16  * Data structure storing input sponge data. Also
17  * handles reading the input file for sponge data
18  */
20 public:
22  {
23  // Text input_sounding file
24  amrex::ParmParse pp("erf");
25  pp.query("input_sponge_file", input_sponge_file);
26  }
27 
28  void read_from_file (const amrex::Geometry &geom,
29  const amrex::Vector<amrex::Real>& zlevels_stag)
30  {
31  const int klo = 0;
32  const int khi = geom.Domain().bigEnd()[AMREX_SPACEDIM-1];
33  const int Nz = geom.Domain().size()[AMREX_SPACEDIM-1];
34  const amrex::Real dz = geom.CellSize()[AMREX_SPACEDIM-1];
35 
36  const bool use_terrain = (zlevels_stag.size() > 0);
37  const amrex::Real zbot = (use_terrain) ? zlevels_stag[klo] : geom.ProbLo(AMREX_SPACEDIM-1);
38  const amrex::Real ztop = (use_terrain) ? zlevels_stag[khi+1] : geom.ProbHi(AMREX_SPACEDIM-1);
39 
40  z_inp_sponge.resize(Nz+2);
41  U_inp_sponge.resize(Nz+2);
42  V_inp_sponge.resize(Nz+2);
43 
44  // Read the input_sponge file
45  amrex::Print() << "input_sponge file location : " << input_sponge_file << std::endl;
46  std::ifstream input_sponge_reader(input_sponge_file);
47  if(!input_sponge_reader.is_open()) {
48  amrex::Error("Error opening the input_sponge file.\n");
49  }
50  else {
51  // Read the contents of the input_sponge file
52  amrex::Print() << "Successfully opened the input_sponge file. Now reading... " << std::endl;
53  std::string line;
54 
55  // First, read the input data into temp vectors; then, interpolate vectors to the
56  // domain lo/hi and cell centers (from level 0)
57  amrex::Vector<amrex::Real> z_inp_sponge_tmp, U_inp_sponge_tmp, V_inp_sponge_tmp;
58 
59  // Add surface
60  z_inp_sponge_tmp.push_back(zbot); // height above sea level [m]
61  U_inp_sponge_tmp.push_back(0);
62  V_inp_sponge_tmp.push_back(0);
63 
64  // Read the vertical profile at each given height
65  amrex::Real z, U, V;
66  while(std::getline(input_sponge_reader, line)) {
67  std::istringstream iss_z(line);
68  iss_z >> z >> U >> V;
69  if (z == zbot) {
70  U_inp_sponge_tmp[0] = U;
71  V_inp_sponge_tmp[0] = V;
72  } else {
73  AMREX_ALWAYS_ASSERT(z > z_inp_sponge_tmp[z_inp_sponge_tmp.size()-1]); // sounding is increasing in height
74  z_inp_sponge_tmp.push_back(z);
75  U_inp_sponge_tmp.push_back(U);
76  V_inp_sponge_tmp.push_back(V);
77  if (z >= ztop) break;
78  }
79  }
80 
81  // At this point, we have an input_sponge from zbot up to
82  // z_inp_sponge_tmp[N-1] >= ztop. Now, interpolate to grid level 0 heights
83  const int Ninp = z_inp_sponge_tmp.size();
84  z_inp_sponge[0] = zbot;
85  U_inp_sponge[0] = U_inp_sponge_tmp[0];
86  V_inp_sponge[0] = V_inp_sponge_tmp[0];
87  for (int k=0; k < Nz; ++k) {
88  z_inp_sponge[k+1] = (use_terrain) ? 0.5 * (zlevels_stag[k] + zlevels_stag[k+1])
89  : zbot + (k + 0.5) * dz;
90  U_inp_sponge[k+1] = interpolate_1d(z_inp_sponge_tmp.dataPtr(), U_inp_sponge_tmp.dataPtr(), z_inp_sponge[k+1], Ninp);
91  V_inp_sponge[k+1] = interpolate_1d(z_inp_sponge_tmp.dataPtr(), V_inp_sponge_tmp.dataPtr(), z_inp_sponge[k+1], Ninp);
92  }
93  z_inp_sponge[Nz+1] = ztop;
94  U_inp_sponge[Nz+1] = interpolate_1d(z_inp_sponge_tmp.dataPtr(), U_inp_sponge_tmp.dataPtr(), ztop, Ninp);
95  V_inp_sponge[Nz+1] = interpolate_1d(z_inp_sponge_tmp.dataPtr(), V_inp_sponge_tmp.dataPtr(), ztop, Ninp);
96  }
97 
98  amrex::Print() << "Successfully read the input_sponge file..." << std::endl;
99  input_sponge_reader.close();
100  }
101 
102  int size () const
103  {
104  AMREX_ALWAYS_ASSERT(z_inp_sponge.size() == U_inp_sponge.size());
105  AMREX_ALWAYS_ASSERT(z_inp_sponge.size() == V_inp_sponge.size());
106  return z_inp_sponge.size();
107  }
108 
109  // Members
110 
111  std::string input_sponge_file = "input_sponge_file.txt";
112 
113  // - read from file
114  amrex::Vector<amrex::Real> z_inp_sponge, U_inp_sponge, V_inp_sponge;
115 };
116 #endif
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real interpolate_1d(const amrex::Real *alpha, const amrex::Real *beta, const amrex::Real alpha_interp, const int alpha_size)
Definition: ERF_Interpolation_1D.H:12
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real pp(amrex::Real y)
Definition: ERF_Microphysics_Utils.H:203
@ U
Definition: ERF_IndexDefines.H:97
@ V
Definition: ERF_IndexDefines.H:98
Definition: ERF_InputSpongeData.H:19
InputSpongeData()
Definition: ERF_InputSpongeData.H:21
void read_from_file(const amrex::Geometry &geom, const amrex::Vector< amrex::Real > &zlevels_stag)
Definition: ERF_InputSpongeData.H:28
amrex::Vector< amrex::Real > V_inp_sponge
Definition: ERF_InputSpongeData.H:114
std::string input_sponge_file
Definition: ERF_InputSpongeData.H:111
amrex::Vector< amrex::Real > z_inp_sponge
Definition: ERF_InputSpongeData.H:114
amrex::Vector< amrex::Real > U_inp_sponge
Definition: ERF_InputSpongeData.H:114
int size() const
Definition: ERF_InputSpongeData.H:102