Skip to content

Commit add4362

Browse files
committed
WIP: Add communication in Z
The actual significant changes are quite small, but these have big knock-on effects in the tests. Main changes: - Z is still periodic, but this is now implemented using guard cells instead of modulus in `SpecificInd::zp/zm` - Adds a new `Mesh` method `sendZ` - `NZPE` is now a user-settable option - Domain decomposition is done in Z before the usual X-Y decomposition - The X/Y _boundary_ regions do not include the Z guards - These corners should be filled in by `Mesh::communicate` Changes to the tests: - `FakeMesh` now has 1 Z guard cell, which changes the size of the interior domain, and requires many of the `Field*` tests to be updated - `IndexOffsetTest` needs to skip the Z guards, just like X, Y - Derivative tests need extra point for interior + 2 * guards - The Petsc and Hypre Laplace unit tests require the Z guards to be communicated in order to fill in the global indices. This requires `FakeMesh` to actually implement `sendZ`. This just copies the relevant points into the Z guards - Also, we should not check the result in the Z guards - I've also pulled out a bunch of common machinery between these two tests - `BoutMeshTest` now needs to understand Z guards and Z processors
1 parent 9d0ff3a commit add4362

30 files changed

Lines changed: 1074 additions & 798 deletions

include/bout/mesh.hxx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,9 @@ public:
349349
/// Send only the y-guard cells
350350
virtual comm_handle sendY(FieldGroup& g, comm_handle handle = nullptr) = 0;
351351

352+
/// Send only the z-guard cells
353+
virtual comm_handle sendZ(FieldGroup& g, comm_handle handle = nullptr) = 0;
354+
352355
/// Wait for the handle, return error code
353356
virtual int wait(comm_handle handle) = 0; ///< Wait for the handle, return error code
354357

@@ -812,9 +815,9 @@ protected:
812815
/// Read a 1D array of integers
813816
const std::vector<int> readInts(const std::string& name, int n);
814817

815-
/// Calculates the size of a message for a given x and y range
816-
int msg_len(const std::vector<FieldData*>& var_list, int xge, int xlt, int yge,
817-
int ylt);
818+
/// Calculates the size of a message for a given (x, y, z) range
819+
int msg_len(const std::vector<FieldData*>& var_list, int xge, int xlt, int yge, int ylt,
820+
int zge, int zlt);
818821

819822
/// Initialise derivatives
820823
void derivs_init(Options* options);

include/bout/region.hxx

Lines changed: 14 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,8 @@ struct SpecificInd {
170170
int ny = -1, nz = -1; ///< Sizes of y and z dimensions
171171

172172
SpecificInd() = default;
173-
SpecificInd(int i, int ny, int nz) : ind(i), ny(ny), nz(nz){};
174-
explicit SpecificInd(int i) : ind(i){};
173+
SpecificInd(int i, int ny, int nz) : ind(i), ny(ny), nz(nz) {};
174+
explicit SpecificInd(int i) : ind(i) {};
175175

176176
/// Allow explicit conversion to an int
177177
explicit operator int() const { return ind; }
@@ -290,26 +290,15 @@ struct SpecificInd {
290290
}
291291
/// The index one point -1 in y
292292
inline SpecificInd ym(int dy = 1) const { return yp(-dy); }
293-
/// The index one point +1 in z. Wraps around zend to zstart
294-
/// An alternative, non-branching calculation is :
295-
/// ind + dz - nz * ((ind + dz) / nz - ind / nz)
296-
/// but this appears no faster (and perhaps slower).
293+
/// The index one point +1 in z
297294
inline SpecificInd zp(int dz = 1) const {
298-
ASSERT3(dz >= 0);
299-
dz = dz <= nz ? dz : dz % nz; //Fix in case dz > nz, if not force it to be in range
300-
return {(ind + dz) % nz < dz ? ind - nz + dz : ind + dz, ny, nz};
301-
}
302-
/// The index one point -1 in z. Wraps around zstart to zend
303-
/// An alternative, non-branching calculation is :
304-
/// ind - dz + nz * ( (nz + ind) / nz - (nz + ind - dz) / nz)
305-
/// but this appears no faster (and perhaps slower).
306-
inline SpecificInd zm(int dz = 1) const {
307-
dz = dz <= nz ? dz : dz % nz; //Fix in case dz > nz, if not force it to be in range
308-
ASSERT3(dz >= 0);
309-
return {(ind) % nz < dz ? ind + nz - dz : ind - dz, ny, nz};
295+
if constexpr (N == IND_TYPE::IND_2D) {
296+
return *this;
297+
}
298+
return {ind + dz, ny, nz};
310299
}
311-
/// Automatically select zm or zp depending on sign
312-
inline SpecificInd zpm(int dz) const { return dz > 0 ? zp(dz) : zm(-dz); }
300+
/// The index one point -1 in z
301+
inline SpecificInd zm(int dz = 1) const { return zp(-dz); }
313302

314303
// and for 2 cells
315304
inline SpecificInd xpp() const { return xp(2); }
@@ -320,9 +309,7 @@ struct SpecificInd {
320309
inline SpecificInd zmm() const { return zm(2); }
321310

322311
/// Generic offset of \p index in multiple directions simultaneously
323-
inline SpecificInd offset(int dx, int dy, int dz) const {
324-
return zpm(dz).yp(dy).xp(dx);
325-
}
312+
inline SpecificInd offset(int dx, int dy, int dz) const { return zp(dz).yp(dy).xp(dx); }
326313
};
327314

328315
/// Relational operators
@@ -490,10 +477,9 @@ template <typename T = Ind3D>
490477
class Region {
491478
// Following prevents a Region being created with anything other
492479
// than Ind2D, Ind3D or IndPerp as template type
493-
static_assert(
494-
std::is_base_of_v<
495-
Ind2D, T> || std::is_base_of_v<Ind3D, T> || std::is_base_of_v<IndPerp, T>,
496-
"Region must be templated with one of IndPerp, Ind2D or Ind3D");
480+
static_assert(std::is_base_of_v<Ind2D, T> || std::is_base_of_v<Ind3D, T>
481+
|| std::is_base_of_v<IndPerp, T>,
482+
"Region must be templated with one of IndPerp, Ind2D or Ind3D");
497483

498484
public:
499485
using data_type = T;
@@ -569,7 +555,7 @@ public:
569555
};
570556

571557
Region(RegionIndices& indices, int maxregionblocksize = MAXREGIONBLOCKSIZE)
572-
: indices(indices), blocks(getContiguousBlocks(maxregionblocksize)){};
558+
: indices(indices), blocks(getContiguousBlocks(maxregionblocksize)) {};
573559

574560
// We need to first set the blocks, and only after that call getRegionIndices.
575561
// Do not put in the member initialisation

src/invert/laplace/impls/hypre3d/hypre3d_laplace.cxx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -436,8 +436,7 @@ OperatorStencil<Ind3D> LaplaceHypre3d::getStencil(Mesh* localmesh,
436436
std::transform(pw.begin(), pw.end(), std::back_inserter(interpPattern),
437437
[localmesh](ParallelTransform::PositionsAndWeights p) -> OffsetInd3D {
438438
return {localmesh->xstart - p.i, localmesh->ystart - p.j,
439-
localmesh->LocalNz - p.k < p.k ? p.k - localmesh->LocalNz
440-
: p.k};
439+
localmesh->zstart - p.k};
441440
});
442441

443442
OffsetInd3D zero;

src/invert/laplace/impls/petsc3damg/petsc3damg.cxx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -490,9 +490,7 @@ OperatorStencil<Ind3D> LaplacePetsc3dAmg::getStencil(Mesh* localmesh,
490490
std::back_inserter(interpPattern),
491491
[localmesh](ParallelTransform::PositionsAndWeights position) -> OffsetInd3D {
492492
return {localmesh->xstart - position.i, localmesh->ystart - position.j,
493-
((localmesh->LocalNz - position.k) < position.k)
494-
? position.k - localmesh->LocalNz
495-
: position.k};
493+
localmesh->zstart - position.k};
496494
});
497495

498496
const OffsetInd3D zero;

0 commit comments

Comments
 (0)