1 #ifndef ERF_HURRICANE_DIAGNOSTICS_H_
2 #define ERF_HURRICANE_DIAGNOSTICS_H_
5 #include <AMReX_MultiFab.H>
6 #include <AMReX_ParallelReduce.H>
16 #define M_PI 3.14159265358979323846
25 const amrex::Vector<amrex::MultiFab>& S_data,
26 const amrex::Vector<amrex::MultiFab>* forecast_state_at_lev,
33 amrex::Vector<std::array<amrex::Real, 2>>& hurricane_eye_track_xy,
34 amrex::Vector<std::array<amrex::Real, 2>>& hurricane_eye_track_latlon)
39 amrex::Gpu::copy(amrex::Gpu::deviceToHost, d_val_min_ptr, d_val_min_ptr + 1, &h_val_min);
40 amrex::Gpu::copy(amrex::Gpu::deviceToHost, d_i_min_ptr, d_i_min_ptr + 1, &h_i_min);
41 amrex::Gpu::copy(amrex::Gpu::deviceToHost, d_j_min_ptr, d_j_min_ptr + 1, &h_j_min);
42 amrex::Gpu::synchronize();
45 int local_i_min = h_i_min;
46 int local_j_min = h_j_min;
48 int rank = amrex::ParallelDescriptor::MyProc();
50 in.value = local_val_min;
54 MPI_Allreduce(&
in, &
out, 1, MPI_DOUBLE_INT, MPI_MINLOC, MPI_COMM_WORLD);
59 global_val_min =
out.value;
60 int owner_rank =
out.rank;
63 global_i_min = local_i_min;
64 global_j_min = local_j_min;
66 amrex::ParallelDescriptor::Bcast(&global_i_min, 1, owner_rank);
67 amrex::ParallelDescriptor::Bcast(&global_j_min, 1, owner_rank);
70 amrex::Print() <<
"Global minimum distance to hurricane eye (k=0): "
71 << global_val_min <<
" at (i,j) = ("
72 << global_i_min <<
", " << global_j_min <<
")\n";
75 amrex::Gpu::DeviceScalar<amrex::Real> d_eye_lat(0.0), d_eye_lon(0.0);
81 if (
rank == owner_rank) {
82 for (amrex::MFIter mfi(S_data[
IntVars::cons]); mfi.isValid(); ++mfi) {
83 const amrex::Box& box = mfi.validbox();
84 const auto latlon_arr = (*forecast_state_at_lev)[4].array(mfi);
85 amrex::ParallelFor(box, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k) {
86 if (i == global_i_min && j == global_j_min && k == 0) {
87 *d_eye_lat_ptr = latlon_arr(i,j,k,0);
88 *d_eye_lon_ptr = latlon_arr(i,j,k,1);
98 amrex::Gpu::synchronize();
100 amrex::ParallelDescriptor::Bcast(&eye_lat, 1, owner_rank);
101 amrex::ParallelDescriptor::Bcast(&eye_lon, 1, owner_rank);
103 const auto dx = geom.CellSizeArray();
104 const auto prob_lo = geom.ProbLoArray();
106 amrex::Real eye_x = prob_lo[0] + (global_i_min+0.5)*dx[0];
107 amrex::Real eye_y = prob_lo[1] + (global_j_min+0.5)*dx[1];
109 hurricane_eye_track_xy.push_back({eye_x, eye_y});
110 hurricane_eye_track_latlon.push_back({eye_lat, eye_lon});
115 amrex::Vector<std::array<amrex::Real, 2>>& hurricane_tracker_circle)
118 if (hurricane_eye_track_xy.empty())
return;
121 const auto [x_last, y_last] = hurricane_eye_track_xy.back();
124 const int n_points = 100;
128 hurricane_tracker_circle.clear();
129 hurricane_tracker_circle.reserve(n_points);
132 for (
int i = 0; i < n_points; ++i) {
136 hurricane_tracker_circle.push_back({
x,
y});
141 const amrex::Vector<amrex::MultiFab>& S_data,
142 const amrex::Vector<amrex::MultiFab>* forecast_state_at_lev,
143 amrex::Vector<std::array<amrex::Real, 2>>& hurricane_eye_track_xy,
144 amrex::Vector<std::array<amrex::Real, 2>>& hurricane_eye_track_latlon,
148 amrex::Gpu::DeviceScalar<amrex::Real> d_val_min(1e10);
149 amrex::Gpu::DeviceScalar<int> d_i_min(-1), d_j_min(-1);
152 int* d_i_min_ptr = d_i_min.dataPtr();
153 int* d_j_min_ptr = d_j_min.dataPtr();
155 for (amrex::MFIter mfi(S_data[
IntVars::cons]); mfi.isValid(); ++mfi) {
156 const amrex::Box& box = mfi.validbox();
157 const auto latlon_arr = (*forecast_state_at_lev)[4].array(mfi);
159 amrex::ParallelFor(box, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k) {
162 amrex::Real dlat = latlon_arr(i,j,k,0) - hurricane_eye_latitude;
163 amrex::Real dlon = latlon_arr(i,j,k,1) - hurricane_eye_longitude;
164 amrex::Real dist = std::sqrt(dlat*dlat + dlon*dlon);
166 amrex::Real old = amrex::Gpu::Atomic::Min(&d_val_min_ptr[0], dist);
178 int global_i_min, global_j_min;
181 d_val_min_ptr, d_i_min_ptr, d_j_min_ptr,
182 global_val_min, global_i_min, global_j_min,
183 hurricane_eye_track_xy,
184 hurricane_eye_track_latlon);
188 const amrex::Vector<amrex::MultiFab>& S_data,
189 MoistureType moisture_type,
190 const amrex::Vector<amrex::MultiFab>* forecast_state_at_lev,
191 amrex::Vector<std::array<amrex::Real, 2>>& hurricane_eye_track_xy,
192 amrex::Vector<std::array<amrex::Real, 2>>& hurricane_eye_track_latlon)
195 if (hurricane_eye_track_xy.empty()) {
196 amrex::Print() <<
"Error: hurricane_eye_track_xy is empty!\n";
197 amrex::Abort(
"Attempted to access hurricane_eye_track_xy[0]");
200 amrex::Real tmp_x_eye = hurricane_eye_track_xy.back()[0];
201 amrex::Real tmp_y_eye = hurricane_eye_track_xy.back()[1];
203 if(amrex::ParallelDescriptor::IOProcessor()){
204 std::cout <<
"The value of x y are " << tmp_x_eye <<
" " << tmp_y_eye << std::endl;
207 amrex::Gpu::DeviceScalar<amrex::Real> d_val_min(1e10);
208 amrex::Gpu::DeviceScalar<int> d_i_min(-1), d_j_min(-1);
211 int* d_i_min_ptr = d_i_min.dataPtr();
212 int* d_j_min_ptr = d_j_min.dataPtr();
214 bool use_moisture = (moisture_type != MoistureType::None);
217 const auto dx = geom.CellSizeArray();
218 const auto prob_lo = geom.ProbLoArray();
220 for (amrex::MFIter mfi(S_data[
IntVars::cons]); mfi.isValid(); ++mfi) {
221 const amrex::Box& box = mfi.validbox();
222 const amrex::Array4<amrex::Real const>& S_arr = S_data[
IntVars::cons].const_array(mfi);
224 amrex::ParallelFor(box,[=] AMREX_GPU_DEVICE(
int i,
int j,
int k) {
228 amrex::Real dist = std::sqrt((
x-tmp_x_eye)*(
x-tmp_x_eye) + (
y-tmp_y_eye)*(
y-tmp_y_eye));
233 amrex::Real old = amrex::Gpu::Atomic::Min(&d_val_min_ptr[0], pressure);
235 if (old > pressure) {
246 int global_i_min, global_j_min;
249 d_val_min_ptr, d_i_min_ptr, d_j_min_ptr,
250 global_val_min, global_i_min, global_j_min,
251 hurricane_eye_track_xy,
252 hurricane_eye_track_latlon);
256 const amrex::Vector<amrex::MultiFab>& S_data,
257 MoistureType moisture_type,
258 const amrex::Vector<amrex::MultiFab>* forecast_state_at_lev,
261 amrex::Vector<std::array<amrex::Real, 2>>& hurricane_eye_track_xy,
262 amrex::Vector<std::array<amrex::Real, 2>>& hurricane_eye_track_latlon,
263 amrex::Vector<std::array<amrex::Real, 2>>& hurricane_tracker_circle)
265 static bool is_start =
true;
268 forecast_state_at_lev, hurricane_eye_track_xy,
269 hurricane_eye_track_latlon,
270 hurricane_eye_latitude, hurricane_eye_longitude);
274 forecast_state_at_lev, hurricane_eye_track_xy,
275 hurricane_eye_track_latlon);
282 const amrex::MultiFab& mf_cc_vel,
284 const amrex::Vector<std::array<amrex::Real, 2>>& hurricane_eye_track_xy,
285 amrex::Vector<std::array<amrex::Real, 2>>& hurricane_maxvel_vs_time)
287 const int ncomp = AMREX_SPACEDIM;
290 amrex::Gpu::DeviceVector<amrex::Real> d_val_max(1, -1.0e30);
291 d_val_max_ptr = d_val_max.data();
293 const auto [x_last, y_last] = hurricane_eye_track_xy.back();
294 const auto dx = geom.CellSizeArray();
295 const auto prob_lo = geom.ProbLoArray();
300 for (amrex::MFIter mfi(mf_cc_vel); mfi.isValid(); ++mfi) {
301 const amrex::Box& box = mfi.validbox();
302 const auto& vel_arr = mf_cc_vel.const_array(mfi);
304 amrex::ParallelFor(box, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k) noexcept {
308 (
y-y_eye)*(
y-y_eye));
309 if(k==1 && dist < 200e3) {
311 for (
int comp = 0; comp < ncomp; ++comp) {
315 velmag = std::sqrt(velmag)*3.6;
316 amrex::Gpu::Atomic::Max(&d_val_max_ptr[0], velmag);
321 amrex::Gpu::synchronize();
324 amrex::Gpu::copy(amrex::Gpu::deviceToHost, d_val_max.begin(), d_val_max.end(), &h_val_max_local);
328 MPI_Allreduce(&h_val_max_local, &h_val_max_global, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD);
329 h_val_max_global = h_val_max_local;
331 h_val_max_global = h_val_max_local;
335 hurricane_maxvel_vs_time.push_back({time_in_hrs, h_val_max_global});
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getPgivenRTh(const amrex::Real rhotheta, const amrex::Real qv=0.)
Definition: ERF_EOS.H:81
void HurricaneTrackerCircle(const amrex::Vector< std::array< amrex::Real, 2 >> &hurricane_eye_track_xy, amrex::Vector< std::array< amrex::Real, 2 >> &hurricane_tracker_circle)
Definition: ERF_HurricaneDiagnostics.H:114
void HurricaneEyeTrackerNotInitial(const amrex::Geometry &geom, const amrex::Vector< amrex::MultiFab > &S_data, MoistureType moisture_type, const amrex::Vector< amrex::MultiFab > *forecast_state_at_lev, amrex::Vector< std::array< amrex::Real, 2 >> &hurricane_eye_track_xy, amrex::Vector< std::array< amrex::Real, 2 >> &hurricane_eye_track_latlon)
Definition: ERF_HurricaneDiagnostics.H:187
void HurricaneMaxVelTracker(const amrex::Geometry &geom, const amrex::MultiFab &mf_cc_vel, const amrex::Real &time, const amrex::Vector< std::array< amrex::Real, 2 >> &hurricane_eye_track_xy, amrex::Vector< std::array< amrex::Real, 2 >> &hurricane_maxvel_vs_time)
Definition: ERF_HurricaneDiagnostics.H:281
void ComputeGlobalMinLocation(const amrex::Geometry &geom, const amrex::Vector< amrex::MultiFab > &S_data, const amrex::Vector< amrex::MultiFab > *forecast_state_at_lev, amrex::Real *d_val_min_ptr, int *d_i_min_ptr, int *d_j_min_ptr, amrex::Real &global_val_min, int &global_i_min, int &global_j_min, amrex::Vector< std::array< amrex::Real, 2 >> &hurricane_eye_track_xy, amrex::Vector< std::array< amrex::Real, 2 >> &hurricane_eye_track_latlon)
Definition: ERF_HurricaneDiagnostics.H:24
int rank
Definition: ERF_HurricaneDiagnostics.H:21
void HurricaneEyeTrackerInitial(const amrex::Geometry &geom, const amrex::Vector< amrex::MultiFab > &S_data, const amrex::Vector< amrex::MultiFab > *forecast_state_at_lev, amrex::Vector< std::array< amrex::Real, 2 >> &hurricane_eye_track_xy, amrex::Vector< std::array< amrex::Real, 2 >> &hurricane_eye_track_latlon, const amrex::Real &hurricane_eye_latitude, const amrex::Real &hurricane_eye_longitude)
Definition: ERF_HurricaneDiagnostics.H:140
amrex::Real value
Definition: ERF_HurricaneDiagnostics.H:20
void HurricaneEyeTracker(const amrex::Geometry &geom, const amrex::Vector< amrex::MultiFab > &S_data, MoistureType moisture_type, const amrex::Vector< amrex::MultiFab > *forecast_state_at_lev, const amrex::Real &hurricane_eye_latitude, const amrex::Real &hurricane_eye_longitude, amrex::Vector< std::array< amrex::Real, 2 >> &hurricane_eye_track_xy, amrex::Vector< std::array< amrex::Real, 2 >> &hurricane_eye_track_latlon, amrex::Vector< std::array< amrex::Real, 2 >> &hurricane_tracker_circle)
Definition: ERF_HurricaneDiagnostics.H:255
#define M_PI
Definition: ERF_HurricaneDiagnostics.H:16
#define Rho_comp
Definition: ERF_IndexDefines.H:36
#define RhoTheta_comp
Definition: ERF_IndexDefines.H:37
#define RhoQ1_comp
Definition: ERF_IndexDefines.H:42
amrex::Real Real
Definition: ERF_ShocInterface.H:19
@ cons
Definition: ERF_IndexDefines.H:158
@ theta
Definition: ERF_MM5.H:20