Skip to content

Commit 889d68d

Browse files
authored
Merge pull request #185 from AetherModel/fism
Merge Fism Branch into Develop - this is the last open branch, so development can be completely synched up at this point.
2 parents ce962ed + 47c430f commit 889d68d

File tree

10 files changed

+1164
-6
lines changed

10 files changed

+1164
-6
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,7 @@ _deps
3939
#vs code settings
4040
.vscode
4141
.DS_Store
42+
43+
# fism files
44+
srcPython/FISM*.nc
45+
srcPython/fism*.txt

doc/internals/fism.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# FISM-2
2+
3+
FISM-2 can be used as a EUV model.
4+
5+
Needs the FISM-2 files automatically made by `srcPython/fism.py`.
6+
7+
FISM-2 contains the binned flux already, however Aether must still be provided with an
8+
EUV csv file containing the cross-sections.
9+
10+
The different fism models available in fism.py contain different numbers of bins, so
11+
the euv file must be different.
12+
13+
| Model | number of bins | euv file |
14+
| :--- | :-------------: | -------: |
15+
| HFG | 23 | euv_solomon.csv |
16+
| Solomon | 23 | euv_solomon.csv |
17+
| NEUVAC | 37/59 | euv.csv / euv_59.csv |
18+
| EUVAC | 37 | euv.csv |
19+
20+
The input format, when using fism data:
21+
22+
"Euv" : {
23+
"doUse" : true,
24+
"Model" : "fism",
25+
"File" : "UA/inputs/euv_59.csv",
26+
"fismFile": "fism2_file_59.txt",
27+
"IncludePhotoElectrons" : true,
28+
"HeatingEfficiency" : 0.05,
29+
"dt" : 60.0
30+
},
31+
32+
To generate FISM-2 irradiances between two dates, one may call fism.py like so:
33+
34+
srcPython/fism.py 20110319 20110321 -b neuvac
35+
36+
Note that the optional argument '-b' defaults to the binning scheme of the NEUVAC model,
37+
which employs 59 bins. To use the 37 bins of the EUVAC model, the argument should be
38+
'euvac', while to use the 23 bins used by the HFG model, the argument should be 'solomon'.
39+
40+
fism.py should always be run before Aether is run using the FISM-2 model. Even though the
41+
entire FISM-2 irradiances are stored in the repository, Aether will need a separate .csv
42+
file containing the temporal subset of FISM-2 irradiances in the desired binning scheme.

include/euv.h

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,11 @@ class Euv {
9494
/// NEUVAC model intercept:
9595
std::vector<float> neuvac_int;
9696

97+
// To avoid having to start from 0 each iteration:
98+
int fism_prev_index = 0;
99+
// Declare this so it is not passed between function:
100+
index_file_output_struct fismData;
101+
97102
// --------------------------------------------------------------------
98103
// Functions:
99104

@@ -109,13 +114,26 @@ class Euv {
109114
**/
110115
bool euvac(Times time, Indices indices);
111116

117+
/**********************************************************************
118+
\brief Compute the EUV spectrum given F107 and F107a
119+
\param time The times within the model (dt is needed)
120+
\param indices Need the F107 and F107a
121+
**/
122+
bool solomon_hfg(Times time, Indices indices);
123+
112124
/**********************************************************************
113-
\brief Compute the EUV spectrum given F107 and F107a
114-
\param time The times within the model (dt is needed)
115-
\param indices Need the F107 and F107a
116-
**/
117-
bool solomon_hfg(Times time, Indices indices);
125+
\brief returns the FISM spectrum for a given time
126+
127+
Unlike the other EUV models ([N]EUVAC, Solomon, etc.), the spectrum
128+
is read from a file (stored in fismData). This does the same thing
129+
as get_index, however FISM is not stored in Indices since it can
130+
have variable # of bins
131+
132+
\param time The times within the model (dt is needed)
133+
**/
118134

135+
bool get_fism(Times time);
136+
119137
/**********************************************************************
120138
\brief Compute the EUV spectrum given F107 and F107a (new version)
121139
\param time The times within the model (dt is needed)
@@ -161,6 +179,17 @@ class Euv {
161179
**/
162180
bool read_file();
163181

182+
/**********************************************************************
183+
\brief Read in the FISM file
184+
185+
Read in the CSV file with FISM data. This can be made with
186+
srcPython/fism.py. The data are read into a index_file_output_struct,
187+
where each row is one time, and each col is a "variable". These should
188+
match the number of bins in the provided EUV file.
189+
**/
190+
index_file_output_struct read_fism(std::string fism_filename);
191+
192+
164193
/**********************************************************************
165194
\brief Interprets the EUV CSV rows and returns the relevant row
166195

include/inputs.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,12 @@ class Inputs {
228228
\brief returns settings["
229229
\param
230230
**/
231+
std::string get_euv_fismfile();
232+
233+
/**********************************************************************
234+
\brief returns settings["
235+
\param
236+
**/
231237
bool get_euv_douse();
232238

233239
/**********************************************************************

share/run/UA/inputs/euv_59_v2.csv

Lines changed: 43 additions & 0 deletions
Large diffs are not rendered by default.

src/calc_euv.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ bool calc_euv(Planets planet,
4949
didWork = euv.neuvac(time, indices);
5050
else if (euvModel == "hfg")
5151
didWork = euv.solomon_hfg(time, indices);
52+
else if (euvModel == "fism"){
53+
didWork = euv.get_fism(time);
54+
}
5255

5356
if (didWork)
5457
euv.scale_from_1au(planet, time);

src/euv.cpp

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ Euv::Euv() {
4444
}
4545
}
4646

47+
// Read in FISM data - does not need to be "slotted"
48+
if (input.get_euv_model() == "fism")
49+
fismData = read_fism(input.get_euv_fismfile());
50+
// Read in NEUVAC data - also does not need to be "slotted"
51+
4752
// Slot the EUVAC model coefficients:
4853
if (input.get_euv_model() == "euvac") {
4954
IsOk = slot_euv("F74113", "", euvac_f74113);
@@ -167,6 +172,62 @@ bool Euv::read_file() {
167172
return DidWork;
168173
}
169174

175+
// -------------------------------------------------------------------------------
176+
// Read in FISM data. FISM files are created with srcPython/fism.py,
177+
// and the data are read in to an index_file_output_struct.
178+
// Inside the struct, we have time & each of the "variables" correspond to a
179+
// FISM bin. This number of bins should match the number of bins in the EUV file
180+
// -------------------------------------------------------------------------------
181+
182+
index_file_output_struct Euv::read_fism(std::string fism_filename) {
183+
184+
std::ifstream fismfstream;
185+
fismfstream.open(fism_filename);
186+
std::vector<std::vector<std::string>> fism_file;
187+
fism_file = read_csv(fismfstream);
188+
189+
index_file_output_struct fism_contents;
190+
191+
// one row per time
192+
fism_contents.nTimes = fism_file.size();
193+
// first six cols are the YYYY,MM,DD,HH,mm,ss (no ms)
194+
// the rest are the binned fism data
195+
fism_contents.nVars = fism_file[0].size() - 6;
196+
197+
// check that the user provided the correct EUV file
198+
// The number of bins in euv file should match the number of fism bins ("nVars")
199+
if (fism_contents.nVars != nWavelengths) {
200+
report.error("Number of FISM wavelengths does not match the EUV file provided!");
201+
report.error("Either change EUV file or check your FISM file is correct.");
202+
IsOk = false;
203+
}
204+
205+
std::vector<int> itime(7, 0);
206+
std::vector<std::vector<float>> values; // holds all values
207+
std::vector<float> values_tmp(fism_contents.nVars); // holds values in each row
208+
209+
for (int iLine = 0; iLine < fism_file.size(); iLine ++) {
210+
211+
itime[0] = stoi(fism_file[iLine][0]);
212+
itime[1] = stoi(fism_file[iLine][1]);
213+
itime[2] = stoi(fism_file[iLine][2]);
214+
itime[3] = stoi(fism_file[iLine][3]);
215+
itime[4] = stoi(fism_file[iLine][4]);
216+
itime[5] = stoi(fism_file[iLine][5]);
217+
itime[6] = 0; // 0 ms
218+
fism_contents.times.push_back(time_int_to_real(itime));
219+
220+
for (int iVar = 0; iVar < fism_contents.nVars; iVar++)
221+
values_tmp[iVar] = stof(fism_file[iLine][iVar + 6]);
222+
223+
values.push_back(values_tmp);
224+
}
225+
226+
fism_contents.values = values;
227+
228+
return fism_contents;
229+
}
230+
170231
// ---------------------------------------------------------------------------
171232
// Match rows in EUV file to different types of things, such as cross
172233
// sections and spectra
@@ -371,6 +432,52 @@ bool Euv::euvac(Times time,
371432
return didWork;
372433
}
373434

435+
// --------------------------------------------------------------------------
436+
// From the FISM file, interpolate the nearest 2 data to the current time
437+
// --------------------------------------------------------------------------
438+
439+
bool Euv::get_fism(Times time) {
440+
// This is functionally similar to get_indices, however we do not store FISM in
441+
// the Indices class since it has variable number of bins.
442+
443+
std::string function = "Euv::get_fism";
444+
static int iFunction = -1;
445+
report.enter(function, iFunction);
446+
447+
double time_now = time.get_current();
448+
bool didWork = true;
449+
450+
if (fism_prev_index == 0) {
451+
// This is probably the first time we're "running" fism.
452+
// Make sure the file covers the entire time range of the run.
453+
double end_time = time.get_end();
454+
455+
if (time_now < fismData.times[0] && end_time > fismData.times[-1]) {
456+
report.error("FISM data does not cover the entire time range!");
457+
report.error("Please check that your FISM file is correct.");
458+
didWork = false;
459+
}
460+
}
461+
462+
// Get the index prior to the current time
463+
while (fismData.times[fism_prev_index + 1] <= time_now)
464+
fism_prev_index ++;
465+
466+
// Determine time-interpolation weighting factor
467+
precision_t dt_fism;
468+
dt_fism = fismData.times[fism_prev_index + 1] - fismData.times[fism_prev_index];
469+
precision_t x = (time_now - fismData.times[fism_prev_index]) / dt_fism;
470+
471+
// store the wavelength:
472+
for (int iWave = 0; iWave < nWavelengths; iWave ++)
473+
wavelengths_intensity_1au[iWave] =
474+
(1.0 - x) * fismData.values[fism_prev_index][iWave]
475+
+ x * fismData.values[fism_prev_index + 1][iWave];
476+
477+
report.exit(function);
478+
return didWork;
479+
}
480+
374481
// --------------------------------------------------------------------------
375482
// Calculate EUVAC
376483
// --------------------------------------------------------------------------

src/inputs.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -936,13 +936,22 @@ std::string Inputs::get_diffuse_auroral_model() {
936936
}
937937

938938
// -----------------------------------------------------------------------
939-
// Return the EUV model used (EUVAC only option now)
939+
// Return the EUV model used (EUVAC, NEUVAC, FISM, etc.)
940940
// -----------------------------------------------------------------------
941941

942942
std::string Inputs::get_euv_model() {
943943
return mklower(check_settings_str("Euv", "Model"));
944944
}
945945

946+
947+
// -----------------------------------------------------------------------
948+
// Return the FISM data file
949+
// -----------------------------------------------------------------------
950+
951+
std::string Inputs::get_euv_fismfile(){
952+
return get_setting_str("Euv", "fismFile");
953+
}
954+
946955
// -----------------------------------------------------------------------
947956
// Return the heating efficiency of the neutrals for EUV
948957
// -----------------------------------------------------------------------

0 commit comments

Comments
 (0)