@@ -105,6 +105,7 @@ bool Ions::exchange_old(Grid &grid) {
105
105
// 1 - top
106
106
// 2 - left
107
107
// 3 - bottom
108
+ // 4 - vertical (k direction) for closed field lines
108
109
//
109
110
// cells (assume gc = 2):
110
111
// 0 1 | 2 3 4 ... n-gc*2 n-gc-1 | n-gc n-1
@@ -124,6 +125,7 @@ bool pack_border(const arma_cube &value,
124
125
125
126
int64_t iXstart, iXend;
126
127
int64_t iYstart, iYend;
128
+ int64_t iZstart, iZend;
127
129
128
130
// ----------------------------
129
131
// left / right message passing
@@ -159,8 +161,22 @@ bool pack_border(const arma_cube &value,
159
161
}
160
162
}
161
163
164
+ // ----------------------------
165
+ // k-dir (only top)
166
+ if (iDir == 4 ) {
167
+ iXstart = nG;
168
+ iXend = nX - nG;
169
+ iYstart = nG;
170
+ iYend = nY - nG;
171
+ iZstart = nZ - nG;
172
+ iZend = nZ;
173
+ } else {
174
+ iZstart = nG;
175
+ iZend = nZ - nG;
176
+ }
177
+
162
178
try {
163
- for (int64_t iZ = nG ; iZ < nZ - nG ; iZ++) {
179
+ for (int64_t iZ = iZstart ; iZ < iZend ; iZ++) {
164
180
for (int64_t iY = iYstart; iY < iYend; iY++) {
165
181
for (int64_t iX = iXstart; iX < iXend; iX++) {
166
182
packed[*iCounter] = value (iX, iY, iZ);
@@ -186,6 +202,7 @@ bool pack_border(const arma_cube &value,
186
202
// 1 - top
187
203
// 2 - left
188
204
// 3 - bottom
205
+ // 4 - k-dir top
189
206
// DoReverseX and DoReverseY are because packing always happens from
190
207
// lower left to upper right, while face we are unpacking too may
191
208
// have a different (left - right and up - down) geometry
@@ -210,7 +227,8 @@ bool unpack_border(arma_cube &value,
210
227
211
228
int64_t iXstart, iXend;
212
229
int64_t iYstart, iYend;
213
- int64_t xInc = 1 , yInc = 1 ;
230
+ int64_t iZstart, iZend;
231
+ int64_t xInc = 1 , yInc = 1 , zInc = 1 ;
214
232
215
233
int64_t iXOff = 0 ;
216
234
int64_t nCx = nX - 2 * nG;
@@ -261,10 +279,26 @@ bool unpack_border(arma_cube &value,
261
279
}
262
280
}
263
281
282
+ if (iDir == 4 ) {
283
+ iXstart = nG;
284
+ iXend = nX - nG;
285
+ iYstart = nG;
286
+ iYend = nY - nG;
287
+ // need to reverse direction, since packing is from the bottom up,
288
+ // which means unpacking should be from the top down
289
+ iZend = nZ - nG;
290
+ iZstart = nZ;
291
+ zInc = -1 ;
292
+ } else {
293
+ iZstart = nG;
294
+ iZend = nZ - nG;
295
+ }
296
+
264
297
try {
265
298
int64_t iXp, iYp;
266
299
267
- for (int64_t iZ = nG; iZ < nZ - nG; iZ++) {
300
+ for (int64_t iZ = iZstart; iZ < iZend; iZ += zInc) {
301
+
268
302
if (XbecomesY) {
269
303
for (int64_t iX = iXstart; iX < iXend; iX += xInc) {
270
304
iXp = iX;
@@ -311,7 +345,6 @@ bool unpack_border(arma_cube &value,
311
345
} catch (...) {
312
346
DidWork = false ;
313
347
}
314
-
315
348
return DidWork;
316
349
}
317
350
@@ -440,6 +473,12 @@ bool Grid::send_one_var_one_face(int64_t iFace) {
440
473
441
474
bool DidWork = true ;
442
475
476
+ if (report.test_verbose (4 ))
477
+ std::cout << " in send_one_var_one_face : " << iFace << " from: " <<
478
+ iProc << " to: " <<
479
+ interchangesOneVar[iFace].iProc_to << " tag: " <<
480
+ interchangesOneVar[iFace].iTag << " \n " ;
481
+
443
482
MPI_Isend (interchangesOneVar[iFace].buffer ,
444
483
interchangesOneVar[iFace].iSizeTotal ,
445
484
MPI_BYTE,
@@ -480,6 +519,13 @@ bool Grid::receive_one_var_one_face(int64_t iFace) {
480
519
481
520
bool DidWork = true ;
482
521
522
+ if (report.test_verbose (4 ))
523
+ std::cout << " in receive_one_var_one_face : " << iFace << " from: " <<
524
+ iProc << " to: " <<
525
+ interchangesOneVar[iFace].iProc_to << " tag: " <<
526
+ interchangesOneVar[iFace].iTag << " \n " ;
527
+
528
+
483
529
MPI_Recv (interchangesOneVar[iFace].rbuffer ,
484
530
interchangesOneVar[iFace].iSizeTotal ,
485
531
MPI_BYTE,
@@ -508,23 +554,32 @@ Grid::messages_struct Grid::make_new_interconnection(int64_t iDir,
508
554
509
555
int64_t nPtsX = nGCs * (nY - nGCs * 2 ) * (nZ - nGCs * 2 );
510
556
int64_t nPtsY = nGCs * (nX - nGCs * 2 ) * (nZ - nGCs * 2 );
557
+ int64_t nPtsZ = nGCs * (nX - nGCs * 2 ) * (nY - nGCs * 2 );
511
558
512
559
new_inter.iFace = iDir;
513
560
new_inter.DoReverseX = DoReverseX;
514
561
new_inter.DoReverseY = DoReverseY;
515
562
new_inter.IsPole = IsPole;
516
563
new_inter.XbecomesY = XbecomesY;
517
564
565
+ // Along i axis (left or right):
518
566
if (iDir == 0 || iDir == 2 ) {
519
567
new_inter.iSizeTotal = nVars * nPtsX * sizeof (precision_t );
520
568
new_inter.index .set_size (nGCs, nY);
521
569
new_inter.ratio .set_size (nGCs, nY);
522
- } else {
570
+ }
571
+
572
+ // Along j axis (up or down):
573
+ if (iDir == 1 || iDir == 3 ) {
523
574
new_inter.iSizeTotal = nVars * nPtsY * sizeof (precision_t );
524
575
new_inter.index .set_size (nGCs, nX);
525
576
new_inter.ratio .set_size (nGCs, nX);
526
577
}
527
578
579
+ // Along K axis (up only for now):
580
+ if (iDir == 4 )
581
+ new_inter.iSizeTotal = nVars * nPtsZ * sizeof (precision_t );
582
+
528
583
new_inter.buffer = static_cast <precision_t *>(malloc (new_inter.iSizeTotal ));
529
584
new_inter.rbuffer = static_cast <precision_t *>(malloc (new_inter.iSizeTotal ));
530
585
@@ -538,7 +593,6 @@ Grid::messages_struct Grid::make_new_interconnection(int64_t iDir,
538
593
return new_inter;
539
594
}
540
595
541
-
542
596
/*
543
597
// -----------------------------------------------------------------------------
544
598
// Exchange messages for the NEUTRALS:
@@ -772,6 +826,15 @@ bool Neutrals::exchange_really_old(Grid &grid) {
772
826
773
827
// -----------------------------------------------------------------------------
774
828
// Initialize interfaces between horizontal sides on a grid
829
+ // Directions:
830
+ // 0 = + i (right)
831
+ // 1 = + j (up)
832
+ // 2 = - i (left)
833
+ // 3 = - j (down)
834
+ // 4 = + k (vertical) - only along closed dipole field lines
835
+ // For the cubesphere grid:
836
+ // iRoot = 4 is the south polar region
837
+ // iRoot = 5 is the north polar region
775
838
// -----------------------------------------------------------------------------
776
839
777
840
bool exchange_sides_init (Grid &grid, int64_t nVarsToPass) {
@@ -911,6 +974,24 @@ bool exchange_sides_init(Grid &grid, int64_t nVarsToPass) {
911
974
ReverseY,
912
975
XbecomesY));
913
976
977
+ if (grid.get_IsDipole () && grid.get_IsClosed ()) {
978
+ // This operates in the N/S (j or Y) direction:
979
+ ReverseX = false ;
980
+ ReverseY = false ;
981
+ IsPole = false ;
982
+ XbecomesY = false ;
983
+ grid.interchangesOneVar .push_back (
984
+ grid.make_new_interconnection (4 ,
985
+ nVarsToPass,
986
+ grid.iProcZ ,
987
+ grid.edge_Z ,
988
+ IsPole,
989
+ ReverseX,
990
+ ReverseY,
991
+ XbecomesY));
992
+
993
+ }
994
+
914
995
report.exit (function);
915
996
return DidWork;
916
997
}
@@ -942,30 +1023,31 @@ bool exchange_one_var(Grid &grid,
942
1023
943
1024
bool DidWork = true ;
944
1025
945
- int iTag, iDir;
1026
+ int iTag, iDir, nDir ;
946
1027
int iSpecies;
947
1028
948
- static int64_t iX, nX = grid.get_nX ();
949
- static int64_t iY, nY = grid.get_nY ();
950
- static int64_t iZ, nZ = grid.get_nZ ();
1029
+ static int64_t nX = grid.get_nX ();
1030
+ static int64_t nY = grid.get_nY ();
1031
+ static int64_t nZ = grid.get_nZ ();
951
1032
static int64_t nG = grid.get_nGCs ();
952
- static int64_t nPtsX = nG * (nY - nG * 2 ) * (nZ - nG * 2 );
953
- static int64_t nPtsY = nG * (nX - nG * 2 ) * (nZ - nG * 2 );
954
- static bool IsFirstTime = true ;
955
1033
static arma_cube var_scgc;
956
1034
957
1035
static int64_t nVarsToPass = 1 ;
958
1036
959
- if (IsFirstTime ) {
1037
+ if (!grid. isExchangeInitialized ) {
960
1038
DidWork = exchange_sides_init (grid, nVarsToPass);
961
- var_scgc.set_size (nX, nY, nX);
962
- IsFirstTime = false ;
1039
+ grid.isExchangeInitialized = true ;
963
1040
}
1041
+ var_scgc.set_size (nX, nY, nZ);
964
1042
965
1043
int64_t iP;
966
1044
precision_t oneSign = 1.0 ;
967
1045
968
- for (int iDir = 0 ; iDir < 4 ; iDir++) {
1046
+ nDir = 4 ;
1047
+ if (grid.get_IsDipole () && grid.get_IsClosed ())
1048
+ nDir++;
1049
+
1050
+ for (int iDir = 0 ; iDir < nDir; iDir++) {
969
1051
if (report.test_verbose (4 ))
970
1052
std::cout << " packing one var : " << iDir << " " << iProc
971
1053
<< " " << grid.interchangesOneVar [iDir].iProc_to
@@ -991,29 +1073,29 @@ bool exchange_one_var(Grid &grid,
991
1073
}
992
1074
993
1075
// Send all faces asynchronously:
994
- for (int iDir = 0 ; iDir < 4 ; iDir++) {
1076
+ for (int iDir = 0 ; iDir < nDir ; iDir++) {
995
1077
if (grid.interchangesOneVar [iDir].iProc_to >= 0 ) {
996
1078
report.print (4 , " Sending one face" );
997
1079
DidWork = grid.send_one_var_one_face (iDir);
998
1080
}
999
1081
}
1000
1082
1001
1083
// Receive all faces asynchronously:
1002
- for (int iDir = 0 ; iDir < 4 ; iDir++) {
1084
+ for (int iDir = 0 ; iDir < nDir ; iDir++) {
1003
1085
if (grid.interchangesOneVar [iDir].iProc_to >= 0 ) {
1004
1086
report.print (4 , " Receiving one face" );
1005
1087
DidWork = grid.receive_one_var_one_face (iDir);
1006
1088
}
1007
1089
}
1008
1090
1009
1091
// Wait for messages to get there:
1010
- for (int iDir = 0 ; iDir < 4 ; iDir++) {
1092
+ for (int iDir = 0 ; iDir < nDir ; iDir++) {
1011
1093
if (grid.interchangesOneVar [iDir].iProc_to >= 0 )
1012
1094
MPI_Wait (&grid.interchangesOneVar [iDir].requests , MPI_STATUS_IGNORE);
1013
1095
}
1014
1096
1015
1097
// Unpack all faces:
1016
- for (int iDir = 0 ; iDir < 4 ; iDir++) {
1098
+ for (int iDir = 0 ; iDir < nDir ; iDir++) {
1017
1099
if (grid.interchangesOneVar [iDir].iProc_to >= 0 ) {
1018
1100
iP = 0 ;
1019
1101
report.print (4 , " Unpacking Border" );
@@ -1029,9 +1111,6 @@ bool exchange_one_var(Grid &grid,
1029
1111
}
1030
1112
}
1031
1113
1032
- // Wait for all processors to be done.
1033
- MPI_Barrier (aether_comm);
1034
-
1035
1114
// If this is a cubesphere grid, interpolate ghostcells to their proper location
1036
1115
// if (grid.IsCubeSphereGrid & grid.gcInterpolationSet) {
1037
1116
// report.print(3, "Interpolating Ghostcells to Proper Location");
0 commit comments