ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_ObsNudging.H
Go to the documentation of this file.
1 /**
2  * \file ERF_ObsNudging.H
3  */
4 #ifndef ERF_OBSNUDGING_H_
5 #define ERF_OBSNUDGING_H_
6 
7 #include <AMReX_BoxArray.H>
8 #include <AMReX_DistributionMapping.H>
9 #include <AMReX_Geometry.H>
10 #include <AMReX_GpuContainers.H>
11 #include <AMReX_MultiFab.H>
12 #include <AMReX_REAL.H>
13 #include <AMReX_Vector.H>
14 
15 #include <memory>
16 #include <string>
17 
18 #include "ERF_DataStruct.H"
19 #include "ERF_LatLonMap.H"
20 #include "ERF_ObsNudgingKernel.H"
21 #include "ERF_ObsNudgingSeries.H"
22 
23 class ProblemBase;
24 
25 //
26 // Nudging towards observations at stations (met masts, lidars, profilers).
27 //
28 // Each station is a horizontal position and a time series of measured
29 // profiles (see ERF_ObsNudgingSeries.H for the file). Near a station the
30 // velocity components and the potential temperature relax towards the
31 // measurements, with a weight that falls off with the distance from the
32 // station horizontally and from its measured height range vertically, and
33 // only the part of the local value outside the measured variability, mean +-
34 // alpha sigma, is relaxed (see ERF_ObsNudgingKernel.H for the formula).
35 //
36 // Heights are measured above the local terrain (or, per station, above the
37 // model's z = 0): on a terrain-fitted mesh the terrain is the bottom of the
38 // mesh, with immersed-forcing terrain it is the terrain surface the immersed
39 // boundary is built from, and cells inside the immersed terrain or buildings
40 // are not nudged. A station can be placed by x/y in domain coordinates or, in
41 // a run with latitude/longitude arrays, by lat/long; an earth-relative wind is
42 // rotated into the grid frame with the orientation of the grid at the station.
43 //
44 // Inputs are under erf.obs_nudging; see the Inputs section of the docs.
45 //
47 {
48  std::string name;
49  std::string file;
50 
51  bool use_latlon = false;
54 
55  // Domain coordinates, given or resolved from lat/long
58 
59  // The lat/lon actually reached, for a station placed by lat/long
62 
63  bool earth_frame = true; // the wind in the file is east/north
64  bool agl = true; // heights are above the local terrain
65 
66  // Rotation from the frame of the file to the grid frame
69 
71 };
72 
74 {
75 public:
76  // Reads erf.obs_nudging.* and every station file. prob supplies the
77  // terrain surface of immersed-forcing terrain; start_time is the epoch time
78  // of t = 0, used when use_datetime is true and the files give epoch times.
79  ObsNudging (TerrainType terrain_type, ProblemBase* prob,
80  bool use_datetime, double start_time);
81 
82  // Does any station need the latitude/longitude arrays (placed by lat/long,
83  // or an earth-relative wind to rotate)?
84  [[nodiscard]] bool wants_latlon () const;
85 
86  // Place the stations and set the wind rotation. latlon may be null only
87  // when the run has no latitude/longitude arrays, in which case a station
88  // placed by lat/long aborts and the grid is taken to be aligned with east
89  // and north. Collective.
90  void resolve_positions (const amrex::Geometry& geom0, const LatLonMap* latlon);
91 
92  void print_summary () const;
93 
94  // Find the terrain under level lev now rather than at its first step, so
95  // that a level the nudging cannot handle is refused at start-up
96  void prepare_level (int lev, const amrex::Geometry& geom, const amrex::MultiFab& cons,
97  const amrex::MultiFab* z_phys_nd, double time);
98 
99  // Add rho * d(theta)/dt to the RhoTheta component of cc_src at level lev.
100  // z_phys_nd may be null on a flat mesh; blank is the cell-centred terrain
101  // blanking of immersed forcing, or null.
102  void add_theta_source (int lev, double time, amrex::Real dt, const amrex::Geometry& geom,
103  const amrex::MultiFab& cons, amrex::MultiFab& cc_src,
104  const amrex::MultiFab* z_phys_nd, const amrex::MultiFab* blank);
105 
106  // Add rho * d(u,v,w)/dt to the momentum sources at level lev.
107  void add_momentum_sources (int lev, double time, amrex::Real dt, const amrex::Geometry& geom,
108  const amrex::MultiFab& cons,
109  const amrex::MultiFab& xvel, const amrex::MultiFab& yvel,
110  const amrex::MultiFab& zvel,
111  amrex::MultiFab& xmom_src, amrex::MultiFab& ymom_src,
112  amrex::MultiFab& zmom_src,
113  const amrex::MultiFab* z_phys_nd,
114  const amrex::MultiFab* blank_x, const amrex::MultiFab* blank_y,
115  const amrex::MultiFab* blank_z);
116 
117 private:
118  // Interpolate every station in time and copy the profiles to the device
119  void update_targets (double time);
120 
121  // The terrain height under level lev, on the nodes of a k = 0 slab of its
122  // grids; rebuilt when the grids change or the terrain moves
123  const amrex::MultiFab& surface (int lev, const amrex::Geometry& geom,
124  const amrex::MultiFab& cons,
125  const amrex::MultiFab* z_phys_nd, double time);
126 
127  [[nodiscard]] obs_nudging::ObsNudgingView view (amrex::Real dt, const amrex::Geometry& geom) const;
128 
129  amrex::Vector<ObsNudgingStation> m_stations;
130 
132  ProblemBase* m_prob = nullptr;
133 
134  // Parameters
141  bool m_nudge_wind = true;
142  bool m_nudge_w = true;
143  bool m_nudge_theta = true;
144  double m_time_origin = 0.0; // added to the run time to get the time of the files
145 
146  // The profiles at the time last asked for, on the device
147  bool m_have_targets = false;
148  double m_targets_time = 0.0;
149  amrex::Gpu::DeviceVector<amrex::Real> m_d_x, m_d_y, m_d_z, m_d_mean, m_d_sigma;
150  amrex::Gpu::DeviceVector<int> m_d_agl, m_d_offset, m_d_count;
151 
152  // Terrain height per level, with the grids it was built for. On a moving
153  // fitted mesh the terrain is also a function of the stage time, so that is
154  // part of the key too; on every other mesh the terrain does not move and
155  // the time is ignored.
156  amrex::Vector<std::unique_ptr<amrex::MultiFab>> m_zsurf;
157  amrex::Vector<amrex::BoxArray> m_zsurf_ba;
158  amrex::Vector<amrex::DistributionMapping> m_zsurf_dm;
159  amrex::Vector<double> m_zsurf_time;
160 };
161 
162 #endif
amrex::Real Real
Definition: ERF_ShocInterface.H:19
Definition: ERF_LatLonMap.H:142
Definition: ERF_ObsNudging.H:74
void add_momentum_sources(int lev, double time, amrex::Real dt, const amrex::Geometry &geom, const amrex::MultiFab &cons, const amrex::MultiFab &xvel, const amrex::MultiFab &yvel, const amrex::MultiFab &zvel, amrex::MultiFab &xmom_src, amrex::MultiFab &ymom_src, amrex::MultiFab &zmom_src, const amrex::MultiFab *z_phys_nd, const amrex::MultiFab *blank_x, const amrex::MultiFab *blank_y, const amrex::MultiFab *blank_z)
Definition: ERF_ObsNudging.cpp:603
bool m_have_targets
Definition: ERF_ObsNudging.H:147
bool m_nudge_w
Definition: ERF_ObsNudging.H:142
amrex::Vector< ObsNudgingStation > m_stations
Definition: ERF_ObsNudging.H:129
amrex::Real m_sigma_factor
Definition: ERF_ObsNudging.H:139
void print_summary() const
Definition: ERF_ObsNudging.cpp:381
amrex::Real m_horizontal_radius
Definition: ERF_ObsNudging.H:136
amrex::Vector< std::unique_ptr< amrex::MultiFab > > m_zsurf
Definition: ERF_ObsNudging.H:156
amrex::Gpu::DeviceVector< amrex::Real > m_d_z
Definition: ERF_ObsNudging.H:149
void resolve_positions(const amrex::Geometry &geom0, const LatLonMap *latlon)
Definition: ERF_ObsNudging.cpp:335
amrex::Real m_vertical_radius
Definition: ERF_ObsNudging.H:137
amrex::Gpu::DeviceVector< amrex::Real > m_d_y
Definition: ERF_ObsNudging.H:149
amrex::Gpu::DeviceVector< amrex::Real > m_d_sigma
Definition: ERF_ObsNudging.H:149
void update_targets(double time)
Definition: ERF_ObsNudging.cpp:409
amrex::Gpu::DeviceVector< int > m_d_agl
Definition: ERF_ObsNudging.H:150
ProblemBase * m_prob
Definition: ERF_ObsNudging.H:132
amrex::Vector< double > m_zsurf_time
Definition: ERF_ObsNudging.H:159
void add_theta_source(int lev, double time, amrex::Real dt, const amrex::Geometry &geom, const amrex::MultiFab &cons, amrex::MultiFab &cc_src, const amrex::MultiFab *z_phys_nd, const amrex::MultiFab *blank)
Definition: ERF_ObsNudging.cpp:568
amrex::Gpu::DeviceVector< amrex::Real > m_d_mean
Definition: ERF_ObsNudging.H:149
obs_nudging::ObsNudgingView view(amrex::Real dt, const amrex::Geometry &geom) const
Definition: ERF_ObsNudging.cpp:466
amrex::Real m_tau
Definition: ERF_ObsNudging.H:135
bool m_nudge_theta
Definition: ERF_ObsNudging.H:143
amrex::Vector< amrex::DistributionMapping > m_zsurf_dm
Definition: ERF_ObsNudging.H:158
amrex::Vector< amrex::BoxArray > m_zsurf_ba
Definition: ERF_ObsNudging.H:157
void prepare_level(int lev, const amrex::Geometry &geom, const amrex::MultiFab &cons, const amrex::MultiFab *z_phys_nd, double time)
Definition: ERF_ObsNudging.cpp:561
const amrex::MultiFab & surface(int lev, const amrex::Geometry &geom, const amrex::MultiFab &cons, const amrex::MultiFab *z_phys_nd, double time)
Definition: ERF_ObsNudging.cpp:493
amrex::Gpu::DeviceVector< int > m_d_offset
Definition: ERF_ObsNudging.H:150
amrex::Gpu::DeviceVector< int > m_d_count
Definition: ERF_ObsNudging.H:150
bool wants_latlon() const
Definition: ERF_ObsNudging.cpp:326
TerrainType m_terrain_type
Definition: ERF_ObsNudging.H:131
ObsNudging(TerrainType terrain_type, ProblemBase *prob, bool use_datetime, double start_time)
Definition: ERF_ObsNudging.cpp:161
double m_time_origin
Definition: ERF_ObsNudging.H:144
amrex::Gpu::DeviceVector< amrex::Real > m_d_x
Definition: ERF_ObsNudging.H:149
bool m_nudge_wind
Definition: ERF_ObsNudging.H:141
double m_targets_time
Definition: ERF_ObsNudging.H:148
amrex::Real m_missing_value
Definition: ERF_ObsNudging.H:140
amrex::Real m_cutoff
Definition: ERF_ObsNudging.H:138
Definition: ERF_ProbCommon.H:60
@ None
Definition: ERF_LSM_Types.H:6
@ xvel
Definition: ERF_IndexDefines.H:218
@ cons
Definition: ERF_IndexDefines.H:217
@ zvel
Definition: ERF_IndexDefines.H:220
@ yvel
Definition: ERF_IndexDefines.H:219
Definition: ERF_ObsNudging.H:47
amrex::Real got_lat
Definition: ERF_ObsNudging.H:60
amrex::Real req_lat
Definition: ERF_ObsNudging.H:52
amrex::Real cos_alpha
Definition: ERF_ObsNudging.H:67
bool use_latlon
Definition: ERF_ObsNudging.H:51
amrex::Real x
Definition: ERF_ObsNudging.H:56
bool earth_frame
Definition: ERF_ObsNudging.H:63
amrex::Real req_lon
Definition: ERF_ObsNudging.H:53
std::string name
Definition: ERF_ObsNudging.H:48
bool agl
Definition: ERF_ObsNudging.H:64
amrex::Real sin_alpha
Definition: ERF_ObsNudging.H:68
obs_nudging::StationSeries series
Definition: ERF_ObsNudging.H:70
std::string file
Definition: ERF_ObsNudging.H:49
amrex::Real got_lon
Definition: ERF_ObsNudging.H:61
amrex::Real y
Definition: ERF_ObsNudging.H:57
Definition: ERF_ObsNudgingKernel.H:26
Definition: ERF_ObsNudgingSeries.H:51