Aether  0.0
Ionosphere-Thermosphere model
electrodynamics.h
1 // Copyright 2020, the Aether Development Team (see doc/dev_team.md for members)
2 // Full license can be found in License.md
3 
4 #ifndef INCLUDE_ELECTRODYNAMICS_H_
5 #define INCLUDE_ELECTRODYNAMICS_H_
6 
7 /**************************************************************
8  * This is the electrodynamics class for Aether.
9 
10  To use this, you have to:
11  1. initialize it, which reads in the electrodynamics file (if used).
12  2. set the time to use.
13  3. set any indices to you need for the electrodynmics.
14  4. set the magnetic latitudes (2d) you need
15  5. set the magnetic local times (2d) you need
16  6. call get_potential or get_eflux or ... to get the electrodynamics
17  on the grid that was specified.
18  2-6 can all be called as many times as you want.
19  *
20  **************************************************************/
21 
22 #include <vector>
23 
24 #include "aether.h"
25 
27 
28  public:
29 
30  /**************************************************************
31  \brief Initialize electrodynamics variables and routines
32 
33  This does the following:
34  - initialize all variables to missing values
35  - read in file if it exists
36 
37  \param input Need to pass Input class, so code can get info
38  about how user has configured things. Inside
39  input, the function uses .efield_model, .auroral_model,
40  .electrodynamics_file.
41 
42  \param report Need to pass Report class, so reporting can occur
43  **/
44  Electrodynamics(Inputs input, Report &report);
45 
46  /**************************************************************
47  \brief update the potential and aurora
48 
49  \param planet need info about SZA and stuff to get MLTs
50  \param gGrid need grid
51  \param time need current time
52  \param ions Going to set the potential and aurora
53 
54  \param report Need to pass Report class, so reporting can occur
55  **/
56 
57  int update(Planets planet,
58  Grid gGrid,
59  Times time,
60  Ions &ions,
61  Report &report);
62 
63  /**************************************************************
64  \brief used in main.cpp to ensure electrodynamics times and
65  aether input times match up. Returns false if times are
66  misaligned, true if they are aligned
67 
68  \param inputStartTime input file starting time
69 
70  \param inputEndTime input file ending time
71  **/
72 
73  bool check_times(double inputStartTime, double inputEndTime);
74 
75  /**************************************************************
76  \brief used in advance.cpp to get potential, eflux, avee
77 
78  \param magLat magnetic latitude
79 
80  \param magLocalTime magnetic local time
81 
82  \param report reporting
83  **/
84 
85  std::tuple<arma_cube,
86  arma_mat,
87  arma_mat> get_electrodynamics(arma_cube magLat,
88  arma_cube magLocalTime,
89  Report &report);
90 
91  /**************************************************************
92  \brief Gets interpolation indices
93 
94  Performs 2d interpolation over search vector to get indices
95 
96  \param vals the 2d array that needs indices
97  \param search The vector of values to interpolate over
98  **/
99 
100  arma_mat get_interpolation_indices(arma_mat vals, arma_vec search);
101 
102  /**************************************************************
103  \brief Sets time needed for electrodynamics
104 
105  Internally, if there is a file read, this function:
106  - finds interpolation indices in time
107  - interpolates the primaary quantities (pot, avee, eflux, etc) to
108  the given time, creating internal states of these quantities. This
109  is done for all relavant grids.
110 
111  \param time the time requested.
112  \param report Need to pass Report class, so reporting can occur
113  **/
114 
115  void set_time(double time, Report &report);
116 
117  /**************************************************************
118  \brief Sets the current grid to request data on
119 
120  Internally, if there is a file read, this function finds the
121  interpolation indices in space for each relevant grid
122 
123  \param lats a 2D matrix of magnetic latitudes to interpolate to
124  \param mlts a 2D matrix of magnetic local times to interpolate to
125  \param report Need to pass Report class, so reporting can occur
126  **/
127  void set_grid(arma_mat lats, arma_mat mlts, Report &report);
128 
129  /**************************************************************
130  \brief Set the IMF Bx for internal usage
131  \param value Value to assign to IMF Bx (nT)
132  **/
133  void set_imf_bx(precision_t value);
134 
135  /**************************************************************
136  \brief Set the IMF By for internal usage
137  \param value Value to assign to IMF By (nT)
138  **/
139  void set_imf_by(precision_t value);
140 
141  /**************************************************************
142  \brief Set the IMF Bz for internal usage
143  \param value Value to assign to IMF Bz (nT)
144  **/
145  void set_imf_bz(precision_t value);
146 
147  /**************************************************************
148  \brief Set the Solar Wind Velocity for internal usage
149  \param value Value to assign to Solar wind velocity (km/s)
150  **/
151  void set_sw_v(precision_t value);
152 
153  /**************************************************************
154  \brief Set the Solar Wind Density for internal usage
155  \param value Value to assign to Solar Wind Density (/cc)
156  **/
157  void set_sw_n(precision_t value);
158 
159  /**************************************************************
160  \brief Set the Hemispheric Power for internal usage
161  \param value Value to assign to Hemispheric Power (GW)
162  \param
163  **/
164  void set_hp(precision_t value);
165 
166  /**************************************************************
167  \brief Set the AU index for internal usage
168  \param value Value to assign to Auroral Upper Index (nT)
169  **/
170  void set_au(precision_t value);
171 
172  /**************************************************************
173  \brief Set the AL index for internal usage
174  \param value Value to assign to Auroral Lower Index (nT)
175  **/
176  void set_al(precision_t value);
177 
178  /**************************************************************
179  \brief Set the AE Index for internal usage
180  \param value Value to assign to Auroral Electrojet Index (nT)
181  **/
182  void set_ae(precision_t value);
183 
184  /**************************************************************
185  \brief Set the Kp Index for internal usage
186  \param value Value to assign to Kp index
187  **/
188  void set_kp(precision_t value);
189 
190  /**************************************************************
191  \brief Get 2D electric potential on specified grid
192 
193  This function returns the electric potential on the requested
194  grid at the requested time (with the requested indices, if
195  applicable)
196 
197  This function does the following:
198  - creates an empty potential matrix ok, I see to return
199  - Loops through the grids in priority order calling set_values
200  with the potentials in the grids
201 
202  \param report Need to pass Report class, so reporting can occur
203  **/
204  arma_cube get_potential(arma_cube magLat,
205  arma_cube magLocalTime,
206  Report &report);
207 
208  /**************************************************************
209  \brief Get 2D electron energy flux on specified grid
210 
211  This function returns the electron energy flux on the requested
212  grid at the requested time (with the requested indices, if
213  applicable)
214 
215  This function does the following:
216  - creates an empty eflux matrix to return
217  - Loops through the grids in priority order calling set_values
218  with the eflux in the grids
219 
220  \param report Need to pass Report class, so reporting can occur
221  **/
222  arma_mat get_eflux(arma_cube magLat, arma_cube magLocalTime, Report &report);
223 
224  /**************************************************************
225  \brief Get 2D electron average energy on specified grid
226 
227  This function returns the electron average energy on the requested
228  grid at the requested time (with the requested indices, if
229  applicable)
230 
231  This function does the following:
232  - creates an empty avee matrix to return
233  - Loops through the grids in priority order calling set_values
234  with the avee in the grids
235 
236  \param report Need to pass Report class, so reporting can occur
237  **/
238  arma_mat get_avee(arma_cube magLat, arma_cube magLocalTime, Report &report);
239 
240  /**************************************************************
241  \brief Get 2D ion energy flux on specified grid
242 
243  This function returns the ion energy flux on the requested
244  grid at the requested time (with the requested indices, if
245  applicable)
246 
247  This function does the following:
248  - creates an empty ion eflux matrix to return
249  - Loops through the grids in priority order calling set_values
250  with the ion eflux in the grids
251 
252  \param report Need to pass Report class, so reporting can occur
253  **/
254  arma_mat get_ion_eflux(Report &report);
255 
256  /**************************************************************
257  \brief Get 2D ion average energy on specified grid
258 
259  This function returns the ion average energy on the requested
260  grid at the requested time (with the requested indices, if
261  applicable)
262 
263  This function does the following:
264  - creates an empty ion avee matrix to return
265  - Loops through the grids in priority order calling set_values
266  with the ion avee in the grids
267 
268  \param report Need to pass Report class, so reporting can occur
269  **/
270  arma_mat get_ion_avee(Report &report);
271 
272  private:
273 
275  int iTimeInterpolationMethod;
279  const int iPrevious_ = 1;
281  const int iNext_ = 2;
282  // Use the closest value:
283  const int iClosest_ = 3;
285  const int iInterp_ = 4;
286 
288  std::string input_file;
289 
291  bool HaveElectrodynamics;
292 
294 
296  double time_needed;
297 
300  arma_mat lats_needed;
301 
304  arma_mat mlts_needed;
305 
307  precision_t imf_bx_needed;
308  precision_t imf_by_needed;
309  precision_t imf_bz_needed;
310  precision_t sw_v_needed;
311  precision_t sw_n_needed;
312  precision_t hp_needed;
313  precision_t au_needed;
314  precision_t al_needed;
315  precision_t ae_needed;
316  precision_t kp_needed;
317 
320  int iUseGridBasedModel;
321 
324  std::string efield_model_to_use;
325 
328  std::string auroral_model_to_use;
329 
337  precision_t time_index;
338 
339  /**************************************************************
340  * input_electrodynamics_struct is a structure that contains
341  * information about the electrodynamics on a magnetic latitude /
342  * local time grid. It is assumed that the quantities are on a
343  * regular grid, in that the lat and mlt can be described with 1D
344  * arrays and the quantities can be described with 2D arrays.
345  * Time then makes these matrices into vectors. The quantities
346  * stored are energy flux, average energy, electric potential,
347  * ion energy flux, ion average energy.
348  **/
349  struct input_electrodynamics_struct {
350 
352  int nLats;
353  int nMlts;
354 
356  arma_vec mlats;
357  arma_vec mlts;
358 
360  std::vector<double> times;
361 
363  std::vector<arma_mat> potential;
364 
366  arma_mat potential_current;
367 
369  std::vector<arma_mat> energy_flux;
371  arma_mat energy_flux_current;
372 
374  std::vector<arma_mat> average_energy;
376  arma_mat average_energy_current;
377 
379  std::vector<arma_mat> ion_energy_flux;
381  arma_mat ion_energy_flux_current;
382 
384  std::vector<arma_mat> ion_average_energy;
386  arma_mat ion_average_energy_current;
387 
389  int DoesIncludeIonPrecip;
390 
398  int grid_priority;
399 
403  arma_mat lats_indices;
407  arma_mat mlts_indices;
408 
409  };
410 
416  std::vector<input_electrodynamics_struct> input_electrodynamics;
417 
422  std::vector<int> grid_order;
423 
425  int nElectrodynamicsGrids;
426 
427  /**************************************************************
428  \brief Reads a netcdf file that has the electrodynamics specification
429 
430  Reads a netcdf file that contains at a minimum:
431  - Potential
432  - Auroral energy flux
433  - Auroral average energy
434  May contain:
435  - Ion energy flux
436  - Ion average energy
437 
438  These are on a magnetic lat/mlt grid as a function of time, and
439  should be put into the input_electrodynamics structure.
440 
441  \param filename
442  \param report Need to pass Report class, so reporting can occur
443  **/
444  void read_netcdf_electrodynamics_file(std::string filename,
445  Report &report);
446 
447  /**************************************************************
448  \brief Takes the pot/eflux/avee/etc and interpolates to the grid
449 
450  This function takes values from the input_electrodynamics
451  structure and interpolates the values onto the user specified
452  grid. The tricky bit is that there can be multiple overlapping
453  grids. So, this needs to be called for each of the existing
454  grids, so that the values are overwritten. To keep it
455  "functional", we pass in the last round of values and those are
456  moved into the output values and then the overlapping region is
457  overwritten (e.g., in the get_potential function, the
458  grids need to be cycled through calling get_values with the
459  potential on that grid and the interpolation indices for the grid.
460 
461  \param values_current the pot/eflux/avee/etc from
462  input_electrodynamics grid
463 
464  \param lats_indices the interpolation indices for the current
465  grid latitudes
466 
467  \param mlts_indices the interpolation indices for the current
468  grid mlts
469 
470  \param values_old the output of this function for the last grid
471  **/
472 
473  arma_mat get_values(arma_mat matToInterpolateOn, int rows, int cols);
474 };
475 
476 #endif // INCLUDE_ELECTRODYNAMICS_H_
Planets
Definition: planets.h:16
Inputs
Definition: inputs.h:10
Electrodynamics
Definition: electrodynamics.h:26
Report
Definition: report.h:28
Ions
Definition: ions.h:10
Times
Definition: times.h:21
Grid
Definition: arm_vars.h:11