270 int innerBoundaryRefLvl = -1;
271 int outerBoundaryRefLvl = -1;
275 for (
auto cellId : local_cells) {
280 innerBoundaryCells.insert(cellId);
281 innerBoundaryRefLvl = mpiGrid.get_refinement_level(cellId);
285 for (
auto nbrPair : *nbrPairVector) {
287 innerBoundaryCells.insert(nbrPair.first);
293 outerBoundaryCells.insert(cellId);
294 outerBoundaryRefLvl = mpiGrid.get_refinement_level(cellId);
297 for (
auto nbrPair : *nbrPairVector) {
299 outerBoundaryCells.insert(nbrPair.first);
306 for (
auto cellId : innerBoundaryCells) {
307 if (cellId !=
INVALID_CELLID && mpiGrid.get_refinement_level(cellId) != innerBoundaryRefLvl) {
308 abort_mpi(
"ERROR: inner boundary cells must have identical refinement level!");
312 for (
auto cellId : outerBoundaryCells) {
313 if (cellId !=
INVALID_CELLID && mpiGrid.get_refinement_level(cellId) != outerBoundaryRefLvl) {
314 abort_mpi(
"ERROR: outer boundary cells must have identical refinement level!");
362 const auto rank =
fsgrid.getRank();
365 #pragma omp parallel for
366 for (uint
i = 0;
i < cells.size();
i++) {
370 fsgrid.parallel_for([](
int timerId) -> phiprof::Timer {
return phiprof::Timer{timerId}; },
371 phiprof::initializeTimer(
"classifyCells-init"), technical,
372 [=](
const fsgrid::Coordinates &coordinates,
const fsgrid::FsStencil& stencil,
cuint sysBoundaryFlag,
cuint sysBoundaryLayer) {
373 auto& tech = technical[stencil.ooo()];
376 tech.sysBoundaryLayer = 0;
379 tech.maxFsDt = numeric_limits<Real>::max();
382 tech.fsGridRank = rank;
393 b->assignSysBoundary(mpiGrid, technical,
fsgrid);
402 for (
CellID cell : cells) {
403 mpiGrid[cell]->sysBoundaryLayer = 0;
405 std::array<double, 3>
dx = mpiGrid.geometry.get_length(cell);
406 std::array<double, 3> x = mpiGrid.get_center(cell);
421 if (
j.first == neighbor) {
422 mpiGrid[cell]->sysBoundaryLayer = 1;
438 for (uint layer = 1; layer < maxLayers; layer++) {
439 for (
CellID cell : cells) {
440 if (mpiGrid[cell]->sysBoundaryLayer == 0) {
446 if (neighbor && mpiGrid[neighbor]->sysBoundaryLayer == layer) {
448 if (
j.first == neighbor) {
449 mpiGrid[cell]->sysBoundaryLayer = layer + 1;
463 for (uint
i = 0;
i < cells.size();
i++) {
465 mpiGrid[cells[
i]]->sysBoundaryLayer != 1 && mpiGrid[cells[
i]]->sysBoundaryLayer != 2) {
477 Real ionosphereDownmapRadius = 0;
481 if (ionosphereDownmapRadius < 1000) {
487 const uint MAX_NUMBER_OF_BOUNDARY_LAYERS = 3 * pow(2, mpiGrid.get_maximum_refinement_level());
489 fsgrid.updateGhostCells(technical);
492 for (uint layer = 1; layer <= MAX_NUMBER_OF_BOUNDARY_LAYERS; ++layer) {
495 fsgrid.parallel_for([](
int timerId) -> phiprof::Timer {
return phiprof::Timer{timerId}; },
496 phiprof::initializeTimer(
"classifyCells-pass-1"), technical,
497 [=](
const fsgrid::Coordinates &coordinates,
const fsgrid::FsStencil& stencil,
cuint sysBoundaryFlag,
cuint sysBoundaryLayer) {
498 auto& tech = technical[stencil.ooo()];
503 (layer > 1 && tech.sysBoundaryLayer == 0)) {
505 if (
belongsToLayer(layer, stencil.i, stencil.j, stencil.k, technical, stencil)) {
507 tech.sysBoundaryLayer = layer;
519 fsgrid.updateGhostCells(technical);
525 fsgrid.parallel_for([](
int timerId) -> phiprof::Timer {
return phiprof::Timer{timerId}; },
526 phiprof::initializeTimer(
"classifyCells-pass-2"), technical,
527 [=](
const fsgrid::Coordinates &coordinates,
const fsgrid::FsStencil& stencil,
cuint sysBoundaryFlag,
cuint sysBoundaryLayer) {
528 auto& tech = technical[stencil.ooo()];
535 fsgrid.updateGhostCells(technical);
537 const array<fsgrid::FsSize_t, 3> fsGridDimensions =
fsgrid.getGlobalSize();
538 const std::array<bool, 3> periodic_l = this->
periodic;
541 fsgrid.parallel_for([](
int timerId) -> phiprof::Timer {
return phiprof::Timer{timerId}; },
542 phiprof::initializeTimer(
"classifyCells-pass-3"), technical,
543 [=](
const fsgrid::Coordinates &coordinates,
const fsgrid::FsStencil& stencil,
cuint sysBoundaryFlag,
cuint sysBoundaryLayer) {
544 const auto gid = coordinates.localToGlobal(stencil.i, stencil.j, stencil.k);
545 auto& tech = technical[stencil.ooo()];
548 if (((gid[0] == 0 || gid[0] == fsGridDimensions[0] - 1) && !periodic_l[0]) ||
549 ((gid[1] == 0 || gid[1] == fsGridDimensions[1] - 1) && !periodic_l[1]) ||
550 ((gid[2] == 0 || gid[2] == fsGridDimensions[2] - 1) && !periodic_l[2])) {
589 fsgrid.updateGhostCells(technical);
664 creal& t,
const bool calculate_V_moments) {
682 phiprof::Timer commTimer{
"Start comm of cell and block data", {
"MPI"}};
687 phiprof::Timer computeInnerTimer{
"Compute process inner cells"};
689 vector<CellID> localCells;
692 #pragma omp parallel for
693 for (uint
i = 0;
i < localCells.size();
i++) {
694 cuint sysBoundaryType = mpiGrid[localCells[
i]]->sysBoundaryFlag;
700 if (calculate_V_moments) {
706 computeInnerTimer.stop();
708 phiprof::Timer waitimer {
"Wait for receives", {
"MPI",
"Wait"}};
713 phiprof::Timer computeBoundaryTimer{
"Compute process boundary cells"};
714 vector<CellID> boundaryCells;
716 #pragma omp parallel for
717 for (uint
i = 0;
i < boundaryCells.size();
i++) {
718 cuint sysBoundaryType = mpiGrid[boundaryCells[
i]]->sysBoundaryFlag;
724 if (calculate_V_moments) {
730 computeBoundaryTimer.stop();