Skip to content

Commit b9de1be

Browse files
committed
[FEAT]: Support ghost cells in dipole grid
- I can't test in 1D since things break in the geographic grid. If the dipole grid is broken in 1D, let me know! The altitude (along-field-line) ghost cells are treated as standard grid points. - At low altitudes, points are close enough this is OK. - At high altitudes, it's going to be hard to get ghost cells. - For example, if they extend along the field line, there will be points at +25 Re (L-shell of max_lat) - If they are scaled to lower radius, or just not as far along the field line, they will not be perpendicular to B anymore! > Maybe specify where field lines should be separated btwn open/closed? Then closed field lines will overlap across equator, and open field lines will not be perpendicular to B in the ghost cells? IDK yet! ---- Ghost cells in latitude currently go over the poles. Discussion is happening on whether this is a good idea or not. ---
1 parent 0514208 commit b9de1be

File tree

1 file changed

+35
-14
lines changed

1 file changed

+35
-14
lines changed

src/init_mag_grid.cpp

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ void Grid::init_dipole_grid(Quadtree quadtree, Planets planet)
5959

6060
Inputs::grid_input_struct grid_input = input.get_grid_inputs("ionGrid");
6161

62+
// Number of ghost cells:
63+
int64_t nGCs = get_nGCs();
64+
6265
// Get inputs
6366
report.print(3, "Setting inputs in dipole grid");
6467
precision_t min_apex = grid_input.min_apex * cKMtoM;
@@ -85,6 +88,11 @@ void Grid::init_dipole_grid(Quadtree quadtree, Planets planet)
8588
precision_t dlon = size_right_norm(0) * cPI / (nLons - 2 * nGCs);
8689
precision_t lon0 = lower_left_norm(0) * cPI;
8790
arma_vec lon1d(nLons);
91+
92+
// Quick 1D check for longitudes:
93+
// Same as geo_grid here...
94+
if (!HasXdim) dlon = 1.0 * cDtoR;
95+
8896
for (iLon = 0; iLon < nLons; iLon++)
8997
lon1d(iLon) = lon0 + (iLon - nGCs + 0.5) * dlon;
9098

@@ -96,7 +104,7 @@ void Grid::init_dipole_grid(Quadtree quadtree, Planets planet)
96104

97105
geoLon_scgc = magLon_scgc;
98106

99-
// LATITUDES
107+
// LATITUDES:
100108

101109
// min_latitude calculated from min_lshell (min_apex input)
102110
precision_t min_lat = get_lat_from_r_and_lshell(1.0, min_lshell);
@@ -105,38 +113,44 @@ void Grid::init_dipole_grid(Quadtree quadtree, Planets planet)
105113
// some intermediates:
106114
precision_t del_lat, blat_min_, blat_max_, tmp_lat;
107115
// Integers for field-line loops:
108-
// - nF=nLats/2 (so nLarts MUST be even)
109-
// - nZ=nAlts
110-
// - nZby2 = nZ/2
111-
int64_t nF = nLats / 2, nZ = nAlts*2, nZby2 = nAlts;
116+
// - nF=nLats/2 (so nLats MUST be even)
117+
// - nZ=nAlts*2 - (we fill up HALF field lines)
118+
// - nZby2 = nAlts
119+
// -> Plus, experinemtal support for altitude ghost cells...
120+
int64_t nF = (nLats) / 2 , nZ = (nAlts) * 2, nZby2 = (nAlts);
112121
// lShells and baseLats are currently set for southern hemisphere then mirrored
113122
arma_vec Lshells(nF), baseLats(nF);
114123

124+
blat_min_ = cos(pow(min_lat, 1.0 / LatStretch));
125+
blat_max_ = cos(pow(max_lat, 1.0 / LatStretch));
126+
del_lat = (blat_max_ - blat_min_) / (nF - nGCs * 2.0);
127+
115128
// now make sure the user used 1 or an even number for nLats
116129
if (nLats % 2 != 0)
117130
{
118-
if (nLats == 1)
131+
if (!HasYdim)
119132
{
120-
report.print(0, ">> Running in 1D. Experinental!!");
133+
del_lat = 1.0 * cDtoR;
134+
report.print(0, "Running in single latitude dimension. Experinental!!");
121135
nF = 1;
122136
}
123137
else
124138
report.error("Cannot use odd nLats with dipole grid!");
125139
}
126140

127-
blat_min_ = cos(pow(min_lat, 1.0 / LatStretch));
128-
blat_max_ = cos(pow(max_lat, 1.0 / LatStretch));
129-
del_lat = (blat_max_ - blat_min_) / (nF - nGCs * 2.0);
130-
141+
// loop over all cells - everything including the ghost cells
142+
// -> This means some points will go over the pole (baseLat > +- 90 degrees)
143+
// They're taken care of in the conversion to geographic coordinates.
131144
for (int i = 0; i < nF; i++)
132145
{
133146
// first put down "linear" spacing
134147
tmp_lat = blat_min_ + del_lat * (i - nGCs + 0.5);
135-
// then scale it according to the exponent & acos it
148+
// then scale it according to the exponent & acos
136149
tmp_lat = pow(acos(tmp_lat), LatStretch);
137150
// place values in array backwards, South pole -> equator.
138151
baseLats(nF - i - 1) = -tmp_lat;
139152
}
153+
report.print(3, "Done setting base latitudes for dipole grid.");
140154

141155
// Find L-Shell for each baseLat
142156
// using L=R/sin2(theta), where theta is from north pole
@@ -176,8 +190,7 @@ void Grid::init_dipole_grid(Quadtree quadtree, Planets planet)
176190
// inlo loop thru southern hemisphere, mirror in north.
177191
for (int i_nZ = 0; i_nZ < nAlts; i_nZ++)
178192
{
179-
// Should be using lshell_to_qn_qs, but it wasn't working right.
180-
// This does the same, but won't work for offset dipoles.
193+
// This won't work for offset dipoles.
181194
// Doesn't have any lat/lon dependence.
182195
delqp = (q_N - q_S) / (nZ + 1);
183196
qp0 = q_S + i_nZ * (delqp);
@@ -194,6 +207,7 @@ void Grid::init_dipole_grid(Quadtree quadtree, Planets planet)
194207
bLats(i_nF, i_nZ) = r_theta.second;
195208
}
196209
}
210+
report.print(3, "Done generating q-spacing for dipole grid.");
197211

198212
arma_vec rNorm1d(nAlts), lat1dAlong(nAlts);
199213
arma_cube r3d(nLons, nLats, nAlts);
@@ -218,11 +232,13 @@ void Grid::init_dipole_grid(Quadtree quadtree, Planets planet)
218232
magLat_scgc.tube(iLon, nLats - iLat - 1) = -lat1dAlong;
219233
}
220234
}
235+
report.print(3, "Done generating symmetric latitude & altitude spacing in dipole.");
221236

222237
geoLat_scgc = magLat_scgc;
223238
magAlt_scgc = r3d - planetRadius;
224239
geoAlt_scgc = magAlt_scgc;
225240

241+
report.print(4, "Beginning coordinate transformations of the dipole grid.");
226242
// Calculate the radius, of planet
227243
fill_grid_radius(planet);
228244

@@ -256,6 +272,8 @@ void Grid::init_dipole_grid(Quadtree quadtree, Planets planet)
256272
gravity_vcgc[1] % gravity_vcgc[1] +
257273
gravity_vcgc[2] % gravity_vcgc[2]);
258274

275+
report.print(4, "Done gravity calculations for the dipole grid.");
276+
259277
std::vector<arma_cube> llr, xyz, xyzRot1, xyzRot2;
260278
llr.push_back(magLon_scgc);
261279
llr.push_back(magLat_scgc);
@@ -275,11 +293,14 @@ void Grid::init_dipole_grid(Quadtree quadtree, Planets planet)
275293
geoLon_scgc = llr[0];
276294
geoLat_scgc = llr[1];
277295
geoAlt_scgc = llr[2] - planetRadius;
296+
report.print(4, "Done dipole -> geographic transformations for the dipole grid.");
278297

279298
calc_alt_grid_spacing();
299+
report.print(4, "Done altitude spacing for the dipole grid.");
280300

281301
// Calculate magnetic field and magnetic coordinates:
282302
fill_grid_bfield(planet);
303+
report.print(4, "Done filling dipole grid with b-field!");
283304

284305
report.exit(function);
285306
return;

0 commit comments

Comments
 (0)