ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_PlotfileSelection.H
Go to the documentation of this file.
1 /**
2  * \file ERF_PlotfileSelection.H
3  */
4 #ifndef ERF_PLOTFILE_SELECTION_H_
5 #define ERF_PLOTFILE_SELECTION_H_
6 
7 #include <algorithm>
8 #include <string>
9 
10 #include <AMReX_Vector.H>
11 
12 #include "ERF_DataStruct.H"
13 
14 namespace erf_plotfile
15 {
16 
18 {
19  bool vapor = false;
20  bool cloud_liquid = false;
21  bool cloud_ice = false;
22  bool rain = false;
23  bool snow = false;
24  bool graupel = false;
25 
26  bool cloud_number = false;
27  bool ice_number = false;
28  bool rain_number = false;
29  bool snow_number = false;
30  bool graupel_number = false;
31 
32  bool rain_accumulation = false;
33  bool snow_accumulation = false;
34  bool graupel_accumulation = false;
37 };
38 
40 {
44  int qmoist_size = 0;
45  MoistureType moisture_type = MoistureType::None;
46 
48 
49  bool time_average_storage = false;
52  bool dissipation_storage = false;
53  bool wall_distance_storage = false;
54 };
55 
57 {
58  int first_q = 0;
59  int last_q = -1;
60 
61  [[nodiscard]] bool valid () const noexcept
62  {
63  return first_q >= 1 && last_q >= first_q;
64  }
65 };
66 
67 inline Plot3DMoistureCapabilities
68 plot3d_moisture_capabilities (const MoistureType moisture_type)
69 {
71 
72  switch (moisture_type) {
73  case MoistureType::None:
74  break;
75  case MoistureType::MoistNoCondensation:
76  caps.vapor = true;
77  // The second moist conserved component is the canonical cloud-water
78  // state even when this model supplies no condensation source.
79  caps.cloud_liquid = true;
80  break;
81  case MoistureType::SatAdj:
82  caps.vapor = true;
83  caps.cloud_liquid = true;
84  caps.relative_humidity_diagnostic = true;
85  break;
86  case MoistureType::Kessler_NoRain:
87  caps.vapor = true;
88  caps.cloud_liquid = true;
89  break;
90  case MoistureType::Kessler:
91  caps.vapor = true;
92  caps.cloud_liquid = true;
93  caps.rain = true;
94  caps.rain_accumulation = true;
95  break;
96  case MoistureType::SAM_NoPrecip_NoIce:
97  caps.vapor = true;
98  caps.cloud_liquid = true;
99  break;
100  case MoistureType::SAM_NoIce:
101  caps.vapor = true;
102  caps.cloud_liquid = true;
103  caps.rain = true;
104  caps.rain_accumulation = true;
105  break;
106  case MoistureType::SAM:
107  caps.vapor = true;
108  caps.cloud_liquid = true;
109  caps.cloud_ice = true;
110  caps.rain = true;
111  caps.snow = true;
112  caps.graupel = true;
113  caps.rain_accumulation = true;
114  caps.snow_accumulation = true;
115  caps.graupel_accumulation = true;
116  break;
117  case MoistureType::Morrison_NoIce:
118  caps.vapor = true;
119  caps.cloud_liquid = true;
120  caps.rain = true;
121  caps.cloud_number = true;
122  caps.rain_number = true;
123  caps.rain_accumulation = true;
124  break;
125  case MoistureType::Morrison:
126  caps.vapor = true;
127  caps.cloud_liquid = true;
128  caps.cloud_ice = true;
129  caps.rain = true;
130  caps.snow = true;
131  caps.graupel = true;
132  caps.cloud_number = true;
133  caps.ice_number = true;
134  caps.rain_number = true;
135  caps.snow_number = true;
136  caps.graupel_number = true;
137  caps.rain_accumulation = true;
138  caps.snow_accumulation = true;
139  caps.graupel_accumulation = true;
140  break;
141  case MoistureType::WSM6:
142  caps.vapor = true;
143  caps.cloud_liquid = true;
144  caps.cloud_ice = true;
145  caps.rain = true;
146  caps.snow = true;
147  caps.graupel = true;
148  caps.rain_accumulation = true;
149  caps.snow_accumulation = true;
150  caps.graupel_accumulation = true;
151  break;
152  case MoistureType::SuperDroplets:
153  caps.vapor = true;
154  caps.cloud_liquid = true;
155  caps.rain = true;
156  caps.rain_accumulation = true;
157  caps.relative_humidity_diagnostic = true;
158  caps.condensation_rate_diagnostic = true;
159  break;
160  default:
161  amrex::Abort("Unknown MoistureType in plot3d_moisture_capabilities");
162  }
163 
164  return caps;
165 }
166 
167 inline int
169 {
170  if (q < 1 || q > 11) return -1;
171  return 3 + q; // RhoQ1_comp + q - 1 in the fixed conserved layout.
172 }
173 
174 inline int
176 {
177  if (name == "density") return 0;
178  if (name == "rhotheta") return 1;
179  if (name == "rhoKE") return 2;
180  if (name == "rhoadv_0") return 3;
181 
182  if (name.size() > 4 && name.compare(0, 4, "rhoQ") == 0) {
183  const std::string suffix = name.substr(4);
184  if (!suffix.empty() && std::all_of(suffix.cbegin(), suffix.cend(),
185  [] (const char c) { return c >= '0' && c <= '9'; })) {
186  const int q = std::stoi(suffix);
188  }
189  }
190 
191  return -1;
192 }
193 
194 inline bool
196 {
197  return caps.moisture_type != MoistureType::None && caps.moist_state_size > 0;
198 }
199 
200 inline bool
202  const int q)
203 {
204  const int comp = plot3d_q_conserved_component_index(q);
205  return plot3d_has_moist_state(caps) && comp >= 0 && comp < caps.conserved_state_size;
206 }
207 
208 inline bool
210  const int q)
211 {
212  return q >= 1 && q <= caps.moist_state_size &&
214 }
215 
216 inline Plot3DQRange
217 plot3d_total_mass_q_range (const int moist_state_size,
218  const int moist_numconc_size)
219 {
220  if (moist_state_size <= 0 || moist_numconc_size < 0 ||
221  moist_numconc_size > moist_state_size) {
222  return {};
223  }
224 
225  const int mass_count = moist_state_size - moist_numconc_size;
226  if (mass_count <= 0) return {};
227  return {1, mass_count};
228 }
229 
230 inline Plot3DQRange
231 plot3d_nonprecipitating_q_range (const int moist_state_size)
232 {
233  if (moist_state_size < 2) return {};
234  return {1, moist_state_size > 3 ? 3 : 2};
235 }
236 
237 inline Plot3DQRange
238 plot3d_precipitating_q_range (const int moist_state_size,
239  const int moist_numconc_size)
240 {
241  const Plot3DQRange total =
242  plot3d_total_mass_q_range(moist_state_size, moist_numconc_size);
243  if (!total.valid()) return {};
244 
245  const int first_precip_q = moist_state_size > 3 ? 4 : 3;
246  if (total.last_q < first_precip_q) return {};
247  return {first_precip_q, total.last_q};
248 }
249 
250 inline bool
252  const Plot3DQRange range)
253 {
254  return range.valid() &&
257 }
258 
259 inline bool
261 {
262  static constexpr const char* names[] = {
263  "temp", "theta", "KE", "scalar", "soundspeed", "reflectivity",
264  "max_reflectivity", "mucape", "vorticity_x", "vorticity_y", "vorticity_z",
265  "helicity", "local_helicity", "magvel", "divU", "pres_hse", "dens_hse",
266  "theta_hse", "qv_hse", "pressure", "pert_pres", "pert_dens", "buoyancy",
267  "eq_pot_temp", "VPD", "dpdx", "dpdy", "dpdz", "pres_hse_x", "pres_hse_y",
268  "pres_hse_z", "z_phys", "detJ", "mapfac", "lat_m", "lon_m", "pblh",
269  "shoc_cldfrac", "shoc_ql", "shoc_ql2", "shoc_cond", "wqls_sec", "wthv_sec",
270  "w_sec", "thl_sec", "qw_sec", "qwthl_sec", "wthl_sec", "wqw_sec", "w3",
271  "brunt", "isotropy", "shear_prod", "buoy_prod", "diss_tke",
272  "terrain_IB_mask", "volfrac"
273  };
274 
275  for (const char* candidate : names) {
276  if (name == candidate) return true;
277  }
278 
279 #ifdef ERF_COMPUTE_ERROR
280  if (name == "xvel_err" || name == "yvel_err" || name == "zvel_err" ||
281  name == "pp_err") return true;
282 #endif
283 
284  return false;
285 }
286 
287 inline bool
289  const Plot3DSelectionCapabilities& caps)
290 {
291  const int cons_comp = plot3d_conserved_component_index(name);
292  if (cons_comp >= 0) return cons_comp < caps.conserved_state_size;
293 
294  if (name == "u_t_avg" || name == "v_t_avg" || name == "w_t_avg" ||
295  name == "umag_t_avg") {
296  return caps.time_average_storage;
297  }
298  if (name == "qsrc_sw" || name == "qsrc_lw") {
299  return caps.radiation_heating_storage;
300  }
301  if (name == "nut" || name == "Kmv" || name == "Kmh" ||
302  name == "Khv" || name == "Khh" || name == "Lturb") {
303  return caps.eddy_diffusivity_storage;
304  }
305  if (name == "diss") return caps.dissipation_storage;
306  if (name == "walldist") return caps.wall_distance_storage;
307 
308  const auto& moisture = caps.moisture;
309  if (name == "moist_density") {
310  return moisture.vapor && moisture.cloud_liquid &&
313  }
314  if (name == "qv") return moisture.vapor && plot3d_moist_q_component_available(caps, 1);
315  if (name == "qc") return moisture.cloud_liquid && plot3d_moist_q_component_available(caps, 2);
316  if (name == "qi") return moisture.cloud_ice && plot3d_moist_q_component_available(caps, 3);
317  if (name == "qrain") return moisture.rain && plot3d_moist_q_component_available(
318  caps, caps.moist_state_size > 3 ? 4 : 3);
319  if (name == "qsnow") return moisture.snow && plot3d_moist_q_component_available(caps, 5);
320  if (name == "qgraup") return moisture.graupel && plot3d_moist_q_component_available(caps, 6);
321  if (name == "nc") return moisture.cloud_number && plot3d_moist_q_component_available(caps, 7);
322  if (name == "ni") return moisture.ice_number && plot3d_moist_q_component_available(caps, 8);
323  if (name == "nr") return moisture.rain_number && plot3d_moist_q_component_available(caps, 9);
324  if (name == "ns") return moisture.snow_number && plot3d_moist_q_component_available(caps, 10);
325  if (name == "ng") return moisture.graupel_number && plot3d_moist_q_component_available(caps, 11);
326  if (name == "qt") {
327  return moisture.vapor &&
331  }
332  if (name == "qn") {
333  return moisture.cloud_liquid &&
336  }
337  if (name == "qp") {
338  return moisture.rain &&
342  }
343  if (name == "qsat") return moisture.vapor && plot3d_moist_q_component_available(caps, 1);
344  if (name == "precipitable") return moisture.vapor && plot3d_moist_q_component_available(caps, 1);
345 
346  if (name == "rain_accum") return moisture.rain_accumulation &&
347  caps.qmoist_size >= (caps.moisture_type == MoistureType::SuperDroplets ? 7 : 1);
348  if (name == "snow_accum") return moisture.snow_accumulation && caps.qmoist_size >= 2;
349  if (name == "graup_accum") return moisture.graupel_accumulation && caps.qmoist_size >= 3;
350  if (name == "rel_humidity") return moisture.relative_humidity_diagnostic &&
351  (caps.moisture_type == MoistureType::SatAdj || caps.qmoist_size >= 6);
352  if (name == "condensation_rate") return moisture.condensation_rate_diagnostic && caps.qmoist_size >= 4;
353 
355 }
356 
357 inline bool
358 plot3d_needs_pressure (const amrex::Vector<std::string>& names)
359 {
360  for (const auto& name : names) {
361  if (name == "pressure" || name == "pert_pres" ||
362  name == "dpdx" || name == "dpdy" || name == "dpdz" ||
363  name == "eq_pot_temp" || name == "VPD" || name == "qsat" ||
364  name == "rel_humidity") {
365  return true;
366  }
367 #ifdef ERF_COMPUTE_ERROR
368  if (name == "pp_err") return true;
369 #endif
370  }
371  return false;
372 }
373 
374 inline amrex::Vector<std::string>
375 plot3d_selected_particle_count_names (const amrex::Vector<std::string>& requested,
376  const amrex::Vector<std::string>& configured)
377 {
378  amrex::Vector<std::string> selected;
379  for (const auto& count_name : requested) {
380  constexpr std::size_t suffix_size = 6; // "_count"
381  if (count_name.size() > suffix_size &&
382  count_name.compare(count_name.size() - suffix_size, suffix_size, "_count") == 0) {
383  const std::string container = count_name.substr(0, count_name.size() - suffix_size);
384  if (std::find(configured.cbegin(), configured.cend(), container) == configured.cend() ||
385  std::find(selected.cbegin(), selected.cend(), container) != selected.cend()) {
386  continue;
387  }
388  selected.push_back(container);
389  }
390  }
391  return selected;
392 }
393 
394 } // namespace erf_plotfile
395 
396 #endif
std::string name
Definition: ERF_Plotfile2DCatalog.cpp:101
@ total
Definition: ERF_NOAHMP_Fields.H:130
@ q
Definition: ERF_WSM6.H:184
Definition: ERF_PlotfileSelection.H:15
int plot3d_q_conserved_component_index(const int q)
Definition: ERF_PlotfileSelection.H:168
bool plot3d_moist_q_component_available(const Plot3DSelectionCapabilities &caps, const int q)
Definition: ERF_PlotfileSelection.H:209
int plot3d_conserved_component_index(const std::string &name)
Definition: ERF_PlotfileSelection.H:175
bool plot3d_source_component_available(const Plot3DSelectionCapabilities &caps, const int q)
Definition: ERF_PlotfileSelection.H:201
Plot3DQRange plot3d_precipitating_q_range(const int moist_state_size, const int moist_numconc_size)
Definition: ERF_PlotfileSelection.H:238
Plot3DMoistureCapabilities plot3d_moisture_capabilities(const MoistureType moisture_type)
Definition: ERF_PlotfileSelection.H:68
Plot3DQRange plot3d_nonprecipitating_q_range(const int moist_state_size)
Definition: ERF_PlotfileSelection.H:231
Plot3DQRange plot3d_total_mass_q_range(const int moist_state_size, const int moist_numconc_size)
Definition: ERF_PlotfileSelection.H:217
bool plot3d_has_moist_state(const Plot3DSelectionCapabilities &caps)
Definition: ERF_PlotfileSelection.H:195
bool plot3d_needs_pressure(const amrex::Vector< std::string > &names)
Definition: ERF_PlotfileSelection.H:358
bool plot3d_fixed_variable_available(const std::string &name, const Plot3DSelectionCapabilities &caps)
Definition: ERF_PlotfileSelection.H:288
bool plot3d_q_range_available(const Plot3DSelectionCapabilities &caps, const Plot3DQRange range)
Definition: ERF_PlotfileSelection.H:251
amrex::Vector< std::string > plot3d_selected_particle_count_names(const amrex::Vector< std::string > &requested, const amrex::Vector< std::string > &configured)
Definition: ERF_PlotfileSelection.H:375
bool plot3d_fixed_unconditional_diagnostic(const std::string &name)
Definition: ERF_PlotfileSelection.H:260
Definition: ERF_PlotfileSelection.H:18
bool snow_number
Definition: ERF_PlotfileSelection.H:29
bool rain_accumulation
Definition: ERF_PlotfileSelection.H:32
bool rain_number
Definition: ERF_PlotfileSelection.H:28
bool cloud_liquid
Definition: ERF_PlotfileSelection.H:20
bool cloud_number
Definition: ERF_PlotfileSelection.H:26
bool relative_humidity_diagnostic
Definition: ERF_PlotfileSelection.H:35
bool graupel
Definition: ERF_PlotfileSelection.H:24
bool snow_accumulation
Definition: ERF_PlotfileSelection.H:33
bool snow
Definition: ERF_PlotfileSelection.H:23
bool graupel_number
Definition: ERF_PlotfileSelection.H:30
bool condensation_rate_diagnostic
Definition: ERF_PlotfileSelection.H:36
bool ice_number
Definition: ERF_PlotfileSelection.H:27
bool vapor
Definition: ERF_PlotfileSelection.H:19
bool graupel_accumulation
Definition: ERF_PlotfileSelection.H:34
bool rain
Definition: ERF_PlotfileSelection.H:22
bool cloud_ice
Definition: ERF_PlotfileSelection.H:21
Definition: ERF_PlotfileSelection.H:57
int first_q
Definition: ERF_PlotfileSelection.H:58
bool valid() const noexcept
Definition: ERF_PlotfileSelection.H:61
int last_q
Definition: ERF_PlotfileSelection.H:59
Definition: ERF_PlotfileSelection.H:40
bool eddy_diffusivity_storage
Definition: ERF_PlotfileSelection.H:51
Plot3DMoistureCapabilities moisture
Definition: ERF_PlotfileSelection.H:47
int moist_state_size
Definition: ERF_PlotfileSelection.H:42
bool dissipation_storage
Definition: ERF_PlotfileSelection.H:52
int moist_numconc_size
Definition: ERF_PlotfileSelection.H:43
MoistureType moisture_type
Definition: ERF_PlotfileSelection.H:45
bool radiation_heating_storage
Definition: ERF_PlotfileSelection.H:50
int qmoist_size
Definition: ERF_PlotfileSelection.H:44
bool wall_distance_storage
Definition: ERF_PlotfileSelection.H:53
bool time_average_storage
Definition: ERF_PlotfileSelection.H:49
int conserved_state_size
Definition: ERF_PlotfileSelection.H:41