Skip to content

Commit e986c88

Browse files
authored
Merge pull request #145 from AetherModel/IEaddition
Add Fortran IE models such as Weimer and FTA
2 parents 3f931fe + 0003b19 commit e986c88

13 files changed

+219
-111
lines changed

include/neutrals.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -178,9 +178,6 @@ class Neutrals {
178178
/// Vector of all species-specific items:
179179
std::vector<species_chars> species;
180180

181-
/// when computing dt, derive a dt for neutrals:
182-
precision_t dt;
183-
184181
/// Maximum Chapman integral (will give nearly infinite tau in EUV)
185182
precision_t max_chapman = 1.0e26;
186183

include/tools.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@ struct mat_2x2{
1515
arma_mat A22;
1616
};
1717

18+
// ----------------------------------------------------------------------------
19+
// Fix corners in an arma cube
20+
// - basically fill in the corners with values near them
21+
// ----------------------------------------------------------------------------
22+
23+
void fill_corners(arma_cube &values, int64_t nGCs);
24+
1825
// -----------------------------------------------------------------------------
1926
// add cMember into a string just before last period
2027
// -----------------------------------------------------------------------------

src/advance.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ bool advance(Planets &planet,
3535
report.print(-1, "(1) What function is this " +
3636
input.get_student_name() + "?");
3737

38+
if (didWork & input.get_check_for_nans())
39+
didWork = neutrals.check_for_nonfinites();
40+
3841
gGrid.calc_sza(planet, time);
3942
neutrals.calc_mass_density();
4043
neutrals.calc_mean_major_mass();
@@ -56,11 +59,17 @@ bool advance(Planets &planet,
5659
// first
5760

5861
neutrals.calc_scale_height(gGrid);
59-
didWork = neutrals.set_bcs(gGrid, time, indices);
62+
63+
if (didWork)
64+
didWork = neutrals.set_bcs(gGrid, time, indices);
6065

6166
if (input.get_nAltsGeo() > 1)
6267
neutrals.advect_vertical(gGrid, time);
6368

69+
if (didWork & input.get_check_for_nans())
70+
didWork = neutrals.check_for_nonfinites();
71+
72+
6473
// ------------------------------------
6574
// Calculate source terms next:
6675

@@ -97,9 +106,6 @@ bool advance(Planets &planet,
97106
if (input.get_NO_cooling())
98107
neutrals.calc_NO_cool();
99108

100-
neutrals.calc_conduction(gGrid, time);
101-
chemistry.calc_chemistry(neutrals, ions, time, gGrid);
102-
103109
neutrals.vertical_momentum_eddy(gGrid);
104110
calc_ion_collisions(neutrals, ions);
105111
calc_neutral_friction(neutrals);
@@ -124,6 +130,9 @@ bool advance(Planets &planet,
124130
}
125131
}
126132

133+
if (didWork & input.get_check_for_nans())
134+
didWork = neutrals.check_for_nonfinites();
135+
127136
if (didWork)
128137
didWork = output(neutrals, ions, gGrid, time, planet);
129138

src/calc_chemical_sources.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ void Chemistry::calc_chemical_sources(Neutrals &neutrals,
3939

4040
for (iReaction = 0; iReaction < nReactions; iReaction++) {
4141

42-
if (report.test_verbose(3)) {
42+
if (report.test_verbose(4)) {
4343
std::cout << "===> Reaction : " << iReaction
4444
<< " of " << nReactions << "\n";
4545
display_reaction(reactions[iReaction]);

src/calc_neutral_derived.cpp

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,8 @@ precision_t Neutrals::calc_dt(Grid grid) {
337337
static int iFunction = -1;
338338
report.enter(function, iFunction);
339339

340+
precision_t dt;
341+
340342
if (input.get_is_cubesphere())
341343
dt = calc_dt_cubesphere(grid);
342344
else {
@@ -382,6 +384,7 @@ precision_t Neutrals::calc_dt_cubesphere(Grid grid) {
382384
static int iFunction = -1;
383385
report.enter(function, iFunction);
384386

387+
precision_t dt;
385388
int iDir;
386389

387390
arma_vec dta(4);
@@ -390,7 +393,7 @@ precision_t Neutrals::calc_dt_cubesphere(Grid grid) {
390393
int64_t nAlts = grid.get_nAlts();
391394
int64_t nXs = grid.get_nLons();
392395
int64_t nYs = grid.get_nLats();
393-
396+
394397
// dtx dty for reference coordinate system
395398
arma_cube dtx(size(cMax_vcgc[0]));
396399
arma_cube dty(size(cMax_vcgc[0]));
@@ -401,11 +404,18 @@ precision_t Neutrals::calc_dt_cubesphere(Grid grid) {
401404
// Loop through altitudes
402405
for (int iAlt = 0; iAlt < nAlts; iAlt++) {
403406
// Conver cMax to contravariant velocity first
404-
arma_mat u1 = cMax_vcgc[0].slice(iAlt) % grid.A11_inv_scgc.slice(iAlt) + cMax_vcgc[1].slice(iAlt) % grid.A12_inv_scgc.slice(iAlt);
405-
arma_mat u2 = cMax_vcgc[0].slice(iAlt) % grid.A21_inv_scgc.slice(iAlt) + cMax_vcgc[1].slice(iAlt) % grid.A22_inv_scgc.slice(iAlt);
406-
407-
dtx.slice(iAlt) = grid.drefx(iAlt)*dummy_1 / u1;
408-
dty.slice(iAlt) = grid.drefy(iAlt)*dummy_1 / u2;
407+
arma_mat u1 = sqrt(
408+
cMax_vcgc[0].slice(iAlt) % grid.A11_inv_scgc.slice(iAlt) %
409+
cMax_vcgc[0].slice(iAlt) % grid.A11_inv_scgc.slice(iAlt) +
410+
cMax_vcgc[1].slice(iAlt) % grid.A12_inv_scgc.slice(iAlt) %
411+
cMax_vcgc[1].slice(iAlt) % grid.A12_inv_scgc.slice(iAlt));
412+
arma_mat u2 = sqrt(
413+
cMax_vcgc[0].slice(iAlt) % grid.A21_inv_scgc.slice(iAlt) %
414+
cMax_vcgc[0].slice(iAlt) % grid.A21_inv_scgc.slice(iAlt) +
415+
cMax_vcgc[1].slice(iAlt) % grid.A22_inv_scgc.slice(iAlt) %
416+
cMax_vcgc[1].slice(iAlt) % grid.A22_inv_scgc.slice(iAlt));
417+
dtx.slice(iAlt) = grid.drefx(iAlt) * dummy_1 / u1;
418+
dty.slice(iAlt) = grid.drefy(iAlt) * dummy_1 / u2;
409419
}
410420

411421
// simply some things, and just take the bulk value for now:

src/electrodynamics.cpp

Lines changed: 79 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66

77
// -----------------------------------------------------------------------------
8-
// Call (fortran) ionospheric electrodynamics if we enable this
8+
// Call (fortran) ionospheric electrodynamics if we enable this
99
// in the cmake file
1010
// -----------------------------------------------------------------------------
1111

@@ -27,36 +27,40 @@ Electrodynamics::Electrodynamics(Times time) {
2727
HaveFortranIe = false;
2828
isSet = false;
2929

30-
#ifdef FORTRAN
31-
// Initialize IE components (reading in the data files):
32-
std::string ieDir = input.get_electrodynamics_dir();
33-
int* ieDir_iArray = copy_string_to_int(ieDir);
34-
std::string efield = input.get_potential_model();
35-
std::string aurora = input.get_diffuse_auroral_model();
30+
#ifdef FORTRAN
31+
// Initialize IE components (reading in the data files):
32+
std::string ieDir = input.get_electrodynamics_dir();
33+
int* ieDir_iArray = copy_string_to_int(ieDir);
34+
std::string efield = input.get_potential_model();
35+
std::string aurora = input.get_diffuse_auroral_model();
3636

37-
if (efield.length() == 0 & aurora.length() == 0) {
38-
HaveFortranIe = false;
37+
if (efield.length() == 0 & aurora.length() == 0)
38+
HaveFortranIe = false;
39+
40+
else {
41+
int* efield_iArray = copy_string_to_int(efield);
42+
int* aurora_iArray = copy_string_to_int(aurora);
43+
ie_init_library(ieDir_iArray, efield_iArray, aurora_iArray, &iError);
44+
45+
if (iError > 0) {
46+
report.print(0, "Error in setting fortran IE!");
47+
IsOk = false;
3948
} else {
40-
int* efield_iArray = copy_string_to_int(efield);
41-
int* aurora_iArray = copy_string_to_int(aurora);
42-
ie_init_library(ieDir_iArray, efield_iArray, aurora_iArray, &iError);
43-
if (iError > 0) {
44-
report.print(0,"Error in setting fortran IE!");
45-
IsOk = false;
46-
} else {
47-
HaveFortranIe = true;
48-
isSet = true;
49-
}
49+
HaveFortranIe = true;
50+
isSet = true;
5051
}
51-
isCompiled = true;
52-
#else
53-
isCompiled = false;
54-
#endif
52+
}
53+
54+
isCompiled = true;
55+
#else
56+
isCompiled = false;
57+
#endif
5558

5659
// If we don't set IE through Fortran, then try to set it through a file:
5760

5861
if (!HaveFortranIe) {
5962
std::string electrodynamics_file = input.get_electrodynamics_file();
63+
6064
if (electrodynamics_file.length() > 0 &
6165
electrodynamics_file != "none") {
6266
// This function sets HaveElectrodynamicsFile = true.
@@ -83,7 +87,7 @@ Electrodynamics::Electrodynamics(Times time) {
8387
// -----------------------------------------------------------------------------
8488

8589
void Electrodynamics::set_all_indices_for_ie(Times time,
86-
Indices &indices) {
90+
Indices &indices) {
8791
std::string function = "Electrodynamics::set_all_indices_for_ie";
8892
static int iFunction = -1;
8993
report.enter(function, iFunction);
@@ -111,17 +115,18 @@ void Electrodynamics::set_all_indices_for_ie(Times time,
111115
std::cout << "sw v : " << iVx_ << " " << swv << "\n";
112116
std::cout << "sw n : " << iN_ << " " << swn << "\n";
113117
}
114-
#ifdef FORTRAN
115-
ie_set_time(&time_now);
116-
ie_set_imfby(&imfby);
117-
ie_set_imfbz(&imfbz);
118-
ie_set_swv(&swv);
119-
ie_set_swn(&swn);
120-
ie_set_ae(&ae);
121-
ie_set_au(&au);
122-
ie_set_al(&al);
123-
ie_set_hp_from_ae(&ae);
124-
#endif
118+
119+
#ifdef FORTRAN
120+
ie_set_time(&time_now);
121+
ie_set_imfby(&imfby);
122+
ie_set_imfbz(&imfbz);
123+
ie_set_swv(&swv);
124+
ie_set_swn(&swn);
125+
ie_set_ae(&ae);
126+
ie_set_au(&au);
127+
ie_set_al(&al);
128+
ie_set_hp_from_ae(&ae);
129+
#endif
125130

126131
report.exit(function);
127132
return;
@@ -154,60 +159,62 @@ bool Electrodynamics::update(Planets planet,
154159
ions.eflux.zeros();
155160
ions.avee.ones();
156161

157-
#ifdef FORTRAN
158-
if (HaveFortranIe) {
159-
report.print(3, "Using Fortran Electrodynamics!");
160-
set_all_indices_for_ie(time, indices);
161-
162-
if (!IsAllocated) {
163-
int nXs = gGrid.get_nX();
164-
ie_set_nxs(&nXs);
165-
int nYs = gGrid.get_nY();
166-
ie_set_nys(&nYs);
167-
int64_t iTotal = nXs * nYs;
168-
mlt2d = static_cast<float*>(malloc(iTotal * sizeof(float)));
169-
lat2d = static_cast<float*>(malloc(iTotal * sizeof(float)));
170-
pot2d = static_cast<float*>(malloc(iTotal * sizeof(float)));
171-
eflux2d = static_cast<float*>(malloc(iTotal * sizeof(float)));
172-
avee2d = static_cast<float*>(malloc(iTotal * sizeof(float)));
173-
IsAllocated = true;
174-
}
162+
#ifdef FORTRAN
163+
164+
if (HaveFortranIe) {
165+
report.print(3, "Using Fortran Electrodynamics!");
166+
set_all_indices_for_ie(time, indices);
167+
168+
if (!IsAllocated) {
169+
int nXs = gGrid.get_nX();
170+
ie_set_nxs(&nXs);
171+
int nYs = gGrid.get_nY();
172+
ie_set_nys(&nYs);
173+
int64_t iTotal = nXs * nYs;
174+
mlt2d = static_cast<float*>(malloc(iTotal * sizeof(float)));
175+
lat2d = static_cast<float*>(malloc(iTotal * sizeof(float)));
176+
pot2d = static_cast<float*>(malloc(iTotal * sizeof(float)));
177+
eflux2d = static_cast<float*>(malloc(iTotal * sizeof(float)));
178+
avee2d = static_cast<float*>(malloc(iTotal * sizeof(float)));
179+
IsAllocated = true;
180+
}
175181

176-
int64_t nZs = gGrid.get_nZ();
177-
int64_t iZ;
182+
int64_t nZs = gGrid.get_nZ();
183+
int64_t iZ;
178184

179-
int iError;
185+
int iError;
180186

181-
for (iZ = 0; iZ < nZs; iZ++) {
182-
copy_mat_to_array(gGrid.magLocalTime_scgc.slice(iZ), mlt2d, true);
183-
copy_mat_to_array(gGrid.magLat_scgc.slice(iZ), lat2d, true);
187+
for (iZ = 0; iZ < nZs; iZ++) {
188+
copy_mat_to_array(gGrid.magLocalTime_scgc.slice(iZ), mlt2d, true);
189+
copy_mat_to_array(gGrid.magLat_scgc.slice(iZ), lat2d, true);
184190

185-
ie_set_mlts(mlt2d, &iError);
186-
ie_set_lats(lat2d, &iError);
187-
ie_update_grid(&iError);
191+
ie_set_mlts(mlt2d, &iError);
192+
ie_set_lats(lat2d, &iError);
193+
ie_update_grid(&iError);
188194

189-
ie_get_potential(pot2d, &iError);
190-
copy_array_to_mat(pot2d, ions.potential_scgc.slice(iZ), true);
195+
ie_get_potential(pot2d, &iError);
196+
copy_array_to_mat(pot2d, ions.potential_scgc.slice(iZ), true);
191197

192-
if (iZ == nZs-1) {
193-
ie_get_electron_diffuse_aurora(eflux2d, avee2d, &iError);
194-
copy_array_to_mat(avee2d, ions.avee, true);
195-
copy_array_to_mat(eflux2d, ions.eflux, true);
196-
}
198+
if (iZ == nZs - 1) {
199+
ie_get_electron_diffuse_aurora(eflux2d, avee2d, &iError);
200+
copy_array_to_mat(avee2d, ions.avee, true);
201+
copy_array_to_mat(eflux2d, ions.eflux, true);
197202
}
198203
}
199-
#endif
204+
}
205+
206+
#endif
200207

201208
if (HaveElectrodynamicsFile) {
202209
report.print(3, "Setting electrodynamics from file!");
203210
auto electrodynamics_values =
204211
get_electrodynamics(gGrid.magLat_scgc,
205-
gGrid.magLocalTime_scgc);
212+
gGrid.magLocalTime_scgc);
206213
ions.potential_scgc = std::get<0>(electrodynamics_values);
207214
ions.eflux = std::get<1>(electrodynamics_values);
208215
ions.avee = std::get<2>(electrodynamics_values);
209216
}
210-
}
217+
}
211218

212219
report.exit(function);
213220
return true;

src/exchange_messages_v2.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -601,16 +601,27 @@ void Grid::exchange(arma_cube &data, const bool pole_inverse) {
601601

602602
bool Neutrals::exchange(Grid &grid) {
603603
// For each species, exchange if its DoAdvect is true
604+
int64_t nGCs = grid.get_nGCs();
605+
604606
for (int i = 0; i < nSpecies; ++i) {
605607
if (species[i].DoAdvect)
606608
grid.exchange(species[i].density_scgc, false);
609+
610+
fill_corners(species[i].density_scgc, nGCs);
607611
}
608612

609613
// Exchange temperature
610614
grid.exchange(temperature_scgc, false);
615+
// Fix corners:
616+
fill_corners(temperature_scgc, nGCs);
617+
611618
// Exchange velocity
612619
grid.exchange(velocity_vcgc[0], true);
613620
grid.exchange(velocity_vcgc[1], true);
614621
grid.exchange(velocity_vcgc[2], false);
622+
623+
for (int iDir = 0; iDir < 3; iDir++)
624+
fill_corners(velocity_vcgc[iDir], nGCs);
625+
615626
return true;
616627
}

src/init_geo_grid.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -984,6 +984,12 @@ bool Grid::init_geo_grid(Quadtree quadtree,
984984

985985
// Calculate the radius (for spherical or non-spherical)
986986
fill_grid_radius(planet);
987+
988+
// Correct the reference grid with correct length scale:
989+
// (with R = actual radius)
990+
if (input.get_is_cubesphere())
991+
correct_xy_grid(planet);
992+
987993
// Calculate grid spacing
988994
calc_grid_spacing(planet);
989995
//calculate radial unit vector (for spherical or oblate planet)
@@ -994,11 +1000,6 @@ bool Grid::init_geo_grid(Quadtree quadtree,
9941000
// Calculate magnetic field and magnetic coordinates:
9951001
fill_grid_bfield(planet);
9961002

997-
// Correct the reference grid with correct length scale:
998-
// (with R = actual radius)
999-
if (input.get_is_cubesphere())
1000-
correct_xy_grid(planet);
1001-
10021003
// Throw a little message for students:
10031004
report.student_checker_function_name(input.get_is_student(),
10041005
input.get_student_name(),

0 commit comments

Comments
 (0)