|
5 | 5 |
|
6 | 6 | #include "aether.h"
|
7 | 7 |
|
| 8 | +// ---------------------------------------------------------------------- |
| 9 | +// Create connectivity between the nodes for message passing for dipole |
| 10 | +// (this looks a lot like sphere, since they are very related) |
| 11 | +// ---------------------------------------------------------------------- |
| 12 | + |
| 13 | +void Grid::create_dipole_connection(Quadtree quadtree) { |
| 14 | + |
| 15 | + std::string function = "Grid::create_dipole_connection"; |
| 16 | + static int iFunction = -1; |
| 17 | + report.enter(function, iFunction); |
| 18 | + |
| 19 | + IsLatLonGrid = true; |
| 20 | + |
| 21 | + // Get some coordinates and sizes in normalized coordinates: |
| 22 | + arma_vec lower_left_norm = quadtree.get_vect("LL"); |
| 23 | + arma_vec middle_norm = quadtree.get_vect("MID"); |
| 24 | + arma_vec size_right_norm = quadtree.get_vect("SR"); |
| 25 | + arma_vec size_up_norm = quadtree.get_vect("SU"); |
| 26 | + |
| 27 | + // Move to the next block in 4 directions: |
| 28 | + arma_vec down_norm = middle_norm - 0.51 * size_up_norm; |
| 29 | + arma_vec up_norm = middle_norm + 0.51 * size_up_norm; |
| 30 | + arma_vec left_norm = middle_norm - 0.51 * size_right_norm; |
| 31 | + arma_vec right_norm = middle_norm + 0.51 * size_right_norm; |
| 32 | + |
| 33 | + // The first component could wrap around: |
| 34 | + right_norm(0) = fmod(right_norm(0), quadtree.limit_high(0)); |
| 35 | + left_norm(0) = fmod((left_norm(0) + quadtree.limit_high(0)), |
| 36 | + quadtree.limit_high(0)); |
| 37 | + |
| 38 | + // These should be the exact edge of the face. |
| 39 | + // The from and to processors should get these in the same place, |
| 40 | + // so they can be used to match which processor to send / receive info |
| 41 | + edge_Xp = middle_norm + size_right_norm / 2.0; |
| 42 | + // wrap in longitude: |
| 43 | + edge_Xp(0) = fmod(edge_Xp(0), quadtree.limit_high(0)); |
| 44 | + edge_Xm = middle_norm - size_right_norm / 2.0; |
| 45 | + edge_Yp = middle_norm + size_up_norm / 2.0; |
| 46 | + edge_Ym = middle_norm - size_up_norm / 2.0; |
| 47 | + // by default, edge_Z isn't even an edge, since most processors should |
| 48 | + // not exchange messages in the Z direction. |
| 49 | + edge_Z = middle_norm; |
| 50 | + |
| 51 | + iProcYm = quadtree.find_point(down_norm) + iMember * nGrids; |
| 52 | + iProcYp = quadtree.find_point(up_norm) + iMember * nGrids; |
| 53 | + iProcXm = quadtree.find_point(left_norm) + iMember * nGrids; |
| 54 | + iProcXp = quadtree.find_point(right_norm) + iMember * nGrids; |
| 55 | + iProcZ = iProc; |
| 56 | + |
| 57 | + iRoot = quadtree.find_root(middle_norm); |
| 58 | + iRootYm = quadtree.find_root(down_norm); |
| 59 | + iRootYp = quadtree.find_root(up_norm); |
| 60 | + iRootXm = quadtree.find_root(left_norm); |
| 61 | + iRootXp = quadtree.find_root(right_norm); |
| 62 | + iRootZ = iRoot; |
| 63 | + |
| 64 | + // If we are a closed field-line, then we want to exchange messages |
| 65 | + // along the Z direction, which turns out to be the same processor |
| 66 | + // as the Y direction, so just take that one: |
| 67 | + IsClosed = false; |
| 68 | + if ((middle_norm(1) < 0) && (up_norm(1) > 0)) { |
| 69 | + // We are in the south and need to pass to the north: |
| 70 | + iRootZ = iRootYp; |
| 71 | + iProcZ = iProcYp; |
| 72 | + edge_Z = edge_Yp; |
| 73 | + // To make the point unique, we need to alter the edge location |
| 74 | + // otherwise the message passing will get confused. Since the |
| 75 | + // points are "higher" than the other edges, let's just add some |
| 76 | + // to the 3rd dimension: |
| 77 | + edge_Z(2) = 5.0; |
| 78 | + IsClosed = true; |
| 79 | + } |
| 80 | + if ((middle_norm(1) > 0) && (down_norm(1) < 0)) { |
| 81 | + // We are in the north and need to pass to the south: |
| 82 | + iRootZ = iRootYm; |
| 83 | + iProcZ = iProcYm; |
| 84 | + edge_Z = edge_Ym; |
| 85 | + // See note above... |
| 86 | + edge_Z(2) = 5.0; |
| 87 | + IsClosed = true; |
| 88 | + } |
| 89 | + |
| 90 | + // Check if touching South Pole: |
| 91 | + if (lower_left_norm(1) == quadtree.limit_low(1)) { |
| 92 | + DoesTouchSouthPole = true; |
| 93 | + |
| 94 | + // edges need to be adjusted to deal with longitudes, since the |
| 95 | + // pole will 180deg different for the from and to processors |
| 96 | + if (edge_Ym(0) < 1.0) |
| 97 | + edge_Ym(0) += 0.5; |
| 98 | + else |
| 99 | + edge_Ym(0) -= 0.5; |
| 100 | + } |
| 101 | + |
| 102 | + // Check if touching North Pole: |
| 103 | + if (lower_left_norm(1) + size_up_norm(1) == quadtree.limit_high(1)) { |
| 104 | + DoesTouchNorthPole = true; |
| 105 | + |
| 106 | + // edge need to be adjusted to deal with longitudes, since the |
| 107 | + // pole will 180deg different for the from and to processors |
| 108 | + if (edge_Yp(0) < 1.0) |
| 109 | + edge_Yp(0) += 0.5; |
| 110 | + else |
| 111 | + edge_Yp(0) -= 0.5; |
| 112 | + } |
| 113 | + |
| 114 | + if (report.test_verbose(2)) |
| 115 | + std::cout << "connectivity : " |
| 116 | + << " iProc : " << iProc << "\n" |
| 117 | + << " isnorth : " << DoesTouchNorthPole << "\n" |
| 118 | + << " issouth : " << DoesTouchSouthPole << "\n" |
| 119 | + << " iProcYm : " << iProcYm << "\n" |
| 120 | + << " iProcYp : " << iProcYp << "\n" |
| 121 | + << " iProcXm : " << iProcXm << "\n" |
| 122 | + << " iProcXp : " << iProcXp << "\n"; |
| 123 | + |
| 124 | + report.exit(function); |
| 125 | + return; |
| 126 | +} |
| 127 | + |
| 128 | + |
8 | 129 | // ----------------------------------------------------------------------
|
9 | 130 | // Routine to convert p and q to r and theta. Can be solved iteratively,
|
10 | 131 | // or with approach from (Swisdak, 2006), who solved it analytically:
|
@@ -99,10 +220,9 @@ bool Grid::init_dipole_grid(Quadtree quadtree_ion, Planets planet) {
|
99 | 220 | IsCubeSphereGrid = false;
|
100 | 221 | IsDipole = true;
|
101 | 222 |
|
102 |
| - // report.print(0, "Creating inter-node connections Grid"); |
103 |
| - |
104 |
| - //if (!Is0D & !Is1Dz) |
105 |
| - // create_sphere_connection(quadtree_ion); |
| 223 | + report.print(0, "Creating inter-node dipole connections"); |
| 224 | + if (!Is0D & !Is1Dz) |
| 225 | + create_dipole_connection(quadtree_ion); |
106 | 226 |
|
107 | 227 | report.print(0, "Creating Dipole Grid");
|
108 | 228 |
|
|
0 commit comments