Skip to content

Commit 8d5ba2e

Browse files
committed
bugs/feat: finally make dipole orthogonal in p-q
holy crap this has been a week of hunting the smallest bugs and chasing down the most miniscule of errors Dipole looks great now, for realz this time. Works in 1 & 3 dimensions This commit makes baselats_down a global var, and changes how the corners are put in. There are no longer any zeros, nans, etc. note, some configurations of the grid *can* result in nan's at the poles, but these are rare - code beforte this commit would have the last field line shifted one q-step lower than it should be. this makes everything even & makes sure the centers and corners are lined up.
1 parent 98f5831 commit 8d5ba2e

File tree

3 files changed

+28
-36
lines changed

3 files changed

+28
-36
lines changed

include/grid.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ class Grid
247247
void fill_field_lines(arma_vec baseLats, precision_t min_altRe,
248248
precision_t Gamma, Planets planet,
249249
bool isCorner);
250-
void dipole_alt_edges(Planets planet);
250+
void dipole_alt_edges(Planets planet, precision_t min_altRe);
251251
// get the latitude spacing given the quadtree start & size, and the latitude limits
252252
// extent: quadtree up
253253
// origin: quadtree origin

src/grid.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,8 @@ Grid::Grid(std::string gridtype) {
162162
magP_Corner.set_size(nX + 1, nY + 1, nZ + 1);
163163
magQ_Corner.set_size(nX + 1, nY + 1, nZ + 1);
164164

165+
baseLats_down.set_size(nY + 1);
166+
165167
radius_scgc.set_size(nX, nY, nZ);
166168
radius2_scgc.set_size(nX, nY, nZ);
167169
radius2i_scgc.set_size(nX, nY, nZ);

src/init_mag_grid.cpp

Lines changed: 25 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,15 @@ arma_vec Grid::baselat_spacing(precision_t extent,
106106
dlat = (lat_high - lat_low) / (nLats_here+1);
107107
report.print(4, "baselats laydown!");
108108

109+
// edge case for 1-D
110+
// In 1-D, the base latitudes will be 1/2 way between LatMax & minApex,
111+
// dlat is adjustable if it doesn't suit your needs.
112+
if (!HasYdim){
113+
DO_FLIPBACK=false;
114+
dlat=1.0 * cDtoR;
115+
nLats_here = nLats + 1;
116+
}
117+
109118
for (int64_t j = 0; j < nLats_here; j++)
110119
{
111120
ang0 = lat_low + (j + 1) * dlat;
@@ -167,6 +176,7 @@ void Grid::fill_field_lines(arma_vec baseLatsLoc,
167176

168177
// temp holding of results from q,p -> r,theta conversion:
169178
std:: pair<precision_t, precision_t> r_theta;
179+
report.print(3, " calculating lshells!");
170180

171181
// Find L-Shell for each baseLat
172182
// using L=R/sin2(theta), where theta is from north pole
@@ -316,7 +326,7 @@ Planets planet){
316326
// They will not, however, line up from one field line to the next.
317327
// It's not going to be *too* hard to get the corners to line up, but it messes with the
318328
// orthogonality too much for me to figure out right now.
319-
void Grid::dipole_alt_edges(Planets planet){
329+
void Grid::dipole_alt_edges(Planets planet, precision_t min_altRe){
320330

321331
std::string function = "Grid::dipole_alt_edges";
322332
static int iFunction = -1;
@@ -327,7 +337,7 @@ void Grid::dipole_alt_edges(Planets planet){
327337
precision_t pTmp;
328338

329339
for (int64_t iLon = 0; iLon < nLons; iLon++) {
330-
for (int64_t iLat = 0; iLat < nLats; iLat++) {
340+
for (int64_t iLat = 0; iLat < nLats + 1; iLat++) {
331341
pTmp = magP_Down(iLon, iLat, 0);
332342
for (int64_t iAlt = 0; iAlt < nAlts; iAlt ++){
333343
magP_Corner(iLon, iLat, iAlt) = pTmp;
@@ -344,46 +354,36 @@ void Grid::dipole_alt_edges(Planets planet){
344354
magP_Corner(iLon, iLat, nAlts) = magP_Corner(iLon, iLat, nAlts - 1);
345355
}
346356
}
347-
348-
// next, take the final p-value (in lat) to be one more step in p.
349-
// Will not be the same size as prev. cells, but that's (hopefully) ok
350-
// And at high latitudes, that cell is going to be super awkward.
351-
// This is what needs changing when it's supercell time #todo
352-
for (int64_t iLon = 0; iLon < nLons + 1; iLon++) {
353-
for (int64_t iAlt = 0; iAlt < nAlts + 1; iAlt++) {
354-
magP_Corner(iLon, nLats, iAlt) = (magP_Corner(iLon, nLats - 2, iAlt) - magP_Corner(nLons, nLats - 1, iAlt)) / 2
355-
+ magP_Corner(iLon, nLats - 1, iAlt);
356-
}
357-
}
358357

359358
// And final step, use the longitude symmetry.
360359
// It's fine, until the dipole is offset. then the entire fill_field_lines needs to be redone.
361-
for (int64_t iAlt = 0; iAlt < nAlts-1; iAlt++) {
362-
for (int64_t iLat = 0; iLat < nLats-1; iLat++) {
360+
for (int64_t iAlt = 0; iAlt < nAlts+1; iAlt++) {
361+
for (int64_t iLat = 0; iLat < nLats+1; iLat++) {
363362
magP_Corner(nLons, iLat, iAlt) = magP_Corner(nLons-1, iLat, iAlt);
364363
}
365364
}
366365

367-
// For q-coord we'll avg q above and below the point...
366+
// For q-coord we'll avg q_down (from different baseLat) above and below the point...
368367
// May need to change the dipole spacing func's to get this working exactly though.
369-
// With how the field line pts are currently put in, there would be one edge at the equator (r=inf)
370-
// so for the last point we'll take a step in q equal to the final center + the q-dist from the
371-
// previous corner, to ensure the final center is within the final 2 corners.
368+
// With how the field line pts are currently put in, this ends up being quite a hassle.
369+
// Not to mention, there would be a corner at q=0 (so r=A_LOT).
370+
// Top and bottom-most corners take the same q-step as the previous cell.
372371
precision_t qTmp;
373372

374373
for (int64_t iLon = 0; iLon < nLons; iLon++) {
375-
for (int64_t iLat = 0; iLat < nLats; iLat++) {
376-
for (int64_t iAlt = 0; iAlt < nAlts; iAlt ++){
377-
magQ_Corner(iLon, iLat, iAlt) = magQ_Down(iLon, iLat, iAlt);
374+
for (int64_t iLat = 0; iLat < nLats+1; iLat++) {
375+
for (int64_t iAlt = 1; iAlt < nAlts; iAlt ++){
376+
magQ_Corner(iLon, iLat, iAlt) = (magQ_Down(iLon, iLat, iAlt-1) + magQ_Down(iLon, iLat, iAlt))/2;
378377
}
378+
magQ_Corner(iLon, iLat, 0) = (2*magQ_Corner(iLon, iLat, 1) - magQ_Corner(iLon, iLat, 2));
379379
}
380380
}
381381

382382
// for last (alt) corner, take the same step as the prev corner to the highest center.
383383
// this will force the highest corner to be above the last center
384384
for (int64_t iLon = 0; iLon < nLons; iLon++) {
385385
for (int64_t iLat = 0; iLat < nLats; iLat++) {
386-
qTmp = 2*magQ_scgc(iLon, iLat, nAlts - 1) - magQ_Corner(iLon, iLat, nAlts - 1);
386+
qTmp = 2*magQ_Corner(iLon, iLat, nAlts - 1) - magQ_Corner(iLon, iLat, nAlts - 2);
387387
magQ_Corner(iLon, iLat, nAlts) = qTmp;
388388
}
389389
}
@@ -394,14 +394,6 @@ void Grid::dipole_alt_edges(Planets planet){
394394
magQ_Corner(nLons, iLat, iAlt) = magQ_Corner(nLons - 1, iLat, iAlt);
395395
}
396396
}
397-
// last lat corner is tricky. just take another latitude step, I guess.
398-
// Will work for now.
399-
for (int64_t iAlt = 0; iAlt < nAlts + 1; iAlt ++) {
400-
for (int64_t iLon = 0; iLon < nLons + 1; iLon++) {
401-
magQ_Corner(iLon, nLats, iAlt) = (magQ_Corner(iLon, nLats - 2, iAlt) - magQ_Corner(nLons-1, nLats - 1, iAlt)) / 2
402-
+ magQ_Corner(iLon, nLats - 1, iAlt);
403-
}
404-
}
405397

406398
// Now we have (p,q) coords corners, convert to lon/lat/alt and we r off to the races
407399
std::pair <arma_cube, arma_cube> rtheta;
@@ -590,16 +582,14 @@ bool Grid::init_dipole_grid(Quadtree quadtree_ion, Planets planet)
590582
// When the exponential spacing (or something else) is fixed, this needs updating.
591583
precision_t dlat;
592584
dlat = baseLats(1) - baseLats(0);
593-
arma_vec baseLats_down(nLats + 1);
594585

595586
// put one cell halfway btwn each base latitude, leave 1st and last cell for now...
596587
for (int64_t iLat = 1; iLat < nLats; iLat ++){
597588
baseLats_down(iLat) = baseLats(iLat-1) + (dlat * 0.5);
598589
}
599590
// Put in 1st and last cell. Done this way so it's easier to put in supercell or something else
600591
baseLats_down(0) = baseLats(0) - dlat * 0.5;
601-
// baseLats_down(0) = baseLats(nLats-1) + dlat * 0.5;
602-
592+
baseLats_down(nLats) = baseLats(nLats-1) + dlat * 0.5;
603593

604594
report.print(3, "baselats done!");
605595

@@ -611,7 +601,7 @@ bool Grid::init_dipole_grid(Quadtree quadtree_ion, Planets planet)
611601
fill_field_lines(baseLats_down, min_apex_re, Gamma, planet, true);
612602

613603
report.print(4, "Field-aligned Edges");
614-
dipole_alt_edges(planet);
604+
dipole_alt_edges(planet, min_alt_re);
615605

616606
report.print(3, "Done generating symmetric latitude & altitude spacing in dipole.");
617607

0 commit comments

Comments
 (0)