73void writeVelMesh(
const dccrg::Dccrg<SpatialCell, dccrg::Cartesian_Geometry>& mpiGrid) {
76 static int counter = 0;
82 fname << counter <<
".vlsv";
84 vlsv::Writer vlsvWriter;
85 vlsvWriter.open(fname.str(), MPI_COMM_WORLD, 0, MPI_INFO_NULL);
95 dccrg::Dccrg<SpatialCell, dccrg::Cartesian_Geometry>& mpiGrid,
96 fsgrid::FsData<std::array<Real, fsgrids::bfield::N_BFIELD>>& perb,
97 fsgrid::FsData<std::array<Real, fsgrids::bgbfield::N_BGB>>& bgb,
98 fsgrid::FsData<std::array<Real, fsgrids::moments::N_MOMENTS>>& moments,
99 fsgrid::FsData<std::array<Real, fsgrids::moments::N_MOMENTS>>& momentsdt2,
100 fsgrid::FsData<std::array<Real, fsgrids::dmoments::N_DMOMENTS>>& dmoments,
101 fsgrid::FsData<std::array<Real, fsgrids::efield::N_EFIELD>>& e,
102 fsgrid::FsData<std::array<Real, fsgrids::egradpe::N_EGRADPE>>& egradpe,
103 fsgrid::FsData<std::array<Real, fsgrids::volfields::N_VOL>>& vol,
109 MPI_Comm_rank(MPI_COMM_WORLD, &
myRank);
113 if (Zoltan_Initialize(argn, argc, &zoltanVersion) != ZOLTAN_OK) {
114 if (
myRank ==
MASTER_RANK) cerr <<
"\t ERROR: Zoltan initialization failed." << endl;
117 logFile <<
"\t Zoltan " << zoltanVersion <<
" initialized successfully" << std::endl <<
writeVerbose;
120 MPI_Comm comm = MPI_COMM_WORLD;
121 int neighborhood_size = VLASOV_STENCIL_WIDTH;
128 dccrg::Cartesian_Geometry::Parameters geom_params;
129 geom_params.start[0] =
P::xmin;
130 geom_params.start[1] =
P::ymin;
131 geom_params.start[2] =
P::zmin;
132 geom_params.level_0_cell_length[0] =
P::dx_ini;
133 geom_params.level_0_cell_length[1] =
P::dy_ini;
134 geom_params.level_0_cell_length[2] =
P::dz_ini;
136 phiprof::Timer dccrgTimer {
"Initialize DCCRG grid"};
137 mpiGrid.set_initial_length(grid_length)
139 .set_neighborhood_length(neighborhood_size)
145 .set_geometry(geom_params);
148 phiprof::Timer refineTimer {
"Refine spatial cells"};
154 mpiGrid.balance_load();
162 if (restartSuccess) {
163 mpiGrid.balance_load();
172 mpiGrid.set_partitioning_option(key, value);
174 phiprof::Timer initialLBTimer {
"Initial load-balancing"};
176 mpiGrid.balance_load();
186 initialLBTimer.stop();
192 phiprof::Timer initialStateTimer {
"Set initial state"};
194 phiprof::Timer setCoordsTimer {
"Set spatial cell coordinates"};
196 setCoordsTimer.stop();
198 phiprof::Timer initBoundaryTimer {
"Initialize system boundary conditions"};
200 initBoundaryTimer.stop();
208 phiprof::Timer classifyTimer {
"Classify cells (sys boundary conditions)"};
210 classifyTimer.stop();
214 phiprof::Timer restartReadTimer {
"Read restart"};
216 logFile <<
"(MAIN) ERROR: restarting failed" << endl;
219 restartReadTimer.stop();
223 phiprof::Timer timer {
"Restart refinement"};
227 cerr <<
"(MAIN) ERROR: Forcing refinement takes too much memory" << endl;
234 phiprof::Timer timer {
"Restart refinement"};
243 phiprof::Timer boundaryCheckTimer {
"Check boundary refinement"};
245 boundaryCheckTimer.stop();
253 fsgrid.updateGhostCells(technical.view());
261 phiprof::Timer applyInitialTimer {
"Apply initial state"};
270 phiprof::Timer setCellTimer {
"setCell"};
271 #pragma omp parallel for schedule(dynamic)
272 for (
size_t i = 0;
i < cells.size(); ++
i) {
283 #pragma omp parallel for schedule(static)
284 for (
size_t i = 0;
i < cells.size(); ++
i) {
291 #pragma omp parallel for schedule(static)
292 for (
size_t i = 0;
i < cells.size(); ++
i) {
318 for (
size_t i = 0;
i < cells.size(); ++
i) {
329 phiprof::Timer fetchNeighbourTimer {
"Fetch Neighbour data", {
"MPI"}};
333 fetchNeighbourTimer.stop();
335 phiprof::Timer setBTimer {
"project.setProjectBField"};
344 phiprof::Timer fsGridGhostTimer {
"fsgrid-ghost-updates"};
345 fsgrid.updateGhostCells(perb.view());
346 fsgrid.updateGhostCells(bgb.view());
347 fsgrid.updateGhostCells(e.view());
350 fsgrid.updateGhostCells(vol.view());
351 fsGridGhostTimer.stop();
352 phiprof::Timer getFieldsTimer {
"getFieldsFromFsGrid"};
354 getFieldsTimer.stop();
368 phiprof::Timer timer {
"Init moments"};
371 phiprof::Timer timer {
"Init moments"};
372 #pragma omp parallel for schedule(guided,1)
373 for (
size_t i = 0;
i < cells.size(); ++
i) {
383 phiprof::Timer finishFSGridTimer {
"Finish fsgrid setup"};
391 fsgrid.updateGhostCells(moments.view());
392 fsgrid.updateGhostCells(momentsdt2.view());
393 finishFSGridTimer.stop();
408 initialStateTimer.stop();
412 vector<CellID> cells = mpiGrid.get_cells();
413 #pragma omp parallel for
414 for (
size_t i = 0;
i < cells.size(); ++
i) {
415 std::array<double, 3> cell_min = mpiGrid.geometry.get_min(cells[
i]);
416 std::array<double, 3> cell_length = mpiGrid.geometry.get_length(cells[
i]);
437 for (
const auto& cellid : cells) {
447 for (
const auto& [neighbor, dir] : mpiGrid.get_face_neighbors_of(cellid)) {
473 cerr <<
"Invalid face neighbor dimension: " << dir <<
" in " << __FILE__ <<
":" << __LINE__ << std::endl;
483inline uint64_t
get_transfer_part(dccrg::Dccrg<SpatialCell, dccrg::Cartesian_Geometry>& mpiGrid, uint64_t num_part_transfers,
CellID cell)
486 return (mpiGrid.mapping.get_refinement_level(cell) ? mpiGrid.mapping.get_parent(cell) : cell) % num_part_transfers;
490void transferInParts(dccrg::Dccrg<SpatialCell, dccrg::Cartesian_Geometry>& mpiGrid, std::vector<CellID>& incoming_cells_list, std::vector<CellID>& outgoing_cells_list,
bool refinement =
false)
492 phiprof::Timer transfersTimer {
"Data transfers"};
497 creal transfer_block_fraction_limit = 0.1;
498 uint64_t num_part_transfers_local = 1, num_part_transfers, outgoing_block_count = 0, total_block_count = 0;
499 bool count_determined =
false;
500 Real outgoing_block_fraction;
503 for (
unsigned int i = 0;
i < outgoing_cells_list.size();
i++) {
504 CellID cell_id=outgoing_cells_list[
i];
508 for (
unsigned int i = 0;
i < cells.size();
i++) {
513 outgoing_block_fraction = (
Real)outgoing_block_count / ((
Real)total_block_count + 1);
515 if (outgoing_block_fraction < transfer_block_fraction_limit) {
516 count_determined =
true;
519 while(!count_determined) {
520 uint64_t transfer_part;
521 for (transfer_part=0; transfer_part<num_part_transfers_local; transfer_part++) {
522 uint64_t transfer_part_block_count=0;
523 for (
unsigned int i = 0;
i < outgoing_cells_list.size();
i++){
524 CellID cell_id=outgoing_cells_list[
i];
525 if (
get_transfer_part(mpiGrid, num_part_transfers_local, cell_id) == transfer_part) {
526 transfer_part_block_count += mpiGrid[cell_id]->get_number_of_all_velocity_blocks();
529 outgoing_block_fraction = (
Real)transfer_part_block_count / ((
Real)total_block_count + 1);
530 if (outgoing_block_fraction > transfer_block_fraction_limit) {
531 num_part_transfers_local *= 2;
535 if ((transfer_part == num_part_transfers_local
536 && outgoing_block_fraction <= transfer_block_fraction_limit)
537 || num_part_transfers_local >= cells.size()) {
538 count_determined =
true;
542 MPI_Allreduce(&num_part_transfers_local, &num_part_transfers, 1, MPI_UINT64_T, MPI_MAX, MPI_COMM_WORLD);
544 for (uint64_t transfer_part=0; transfer_part<num_part_transfers; transfer_part++) {
546 for (
const CellID& cell_id : incoming_cells_list) {
556 for (
const CellID cell_id : outgoing_cells_list) {
573 mpiGrid.continue_balance_load();
575 mpiGrid.continue_refining();
582 mpiGrid.continue_balance_load();
584 mpiGrid.continue_refining();
590 int prepareReceives {phiprof::initializeTimer(
"Preparing receives")};
592 #pragma omp parallel for schedule(guided)
593 for (
const CellID cell_id : incoming_cells_list) {
598 phiprof::Timer timer {prepareReceives};
600 timer.stop(1,
"Spatial cells");
606 phiprof::Timer timer {prepareReceives};
607 timer.stop(0,
"Spatial cells");
611 phiprof::Timer transferTimer {
"transfer_all_data"};
614 mpiGrid.continue_balance_load();
616 mpiGrid.continue_refining();
618 transferTimer.stop();
621 for (
const CellID cell_id : outgoing_cells_list){
628 cell->
clear(popID,
true);
634 phiprof::Timer copyParentsTimer {
"copy to parents"};
635 std::set<CellID> processed;
636 for (
CellID id : mpiGrid.get_removed_cells()) {
638 CellID parent = mpiGrid.get_existing_cell(mpiGrid.get_center(
id));
639 if (!processed.count(parent)) {
640 std::vector<CellID> children = mpiGrid.get_all_children(parent);
642 *mpiGrid[parent] = *mpiGrid[id];
651 processed.insert(parent);
653 for (
const CellID child : children) {
654 mpiGrid[child]->clear(popID,
true);
659 copyParentsTimer.stop(processed.size(),
"Spatial cells");
667 for (
const CellID cell_id : incoming_cells_list) {
668 mpiGrid[cell_id]->set_mpi_transfer_enabled(
true);
677 phiprof::Timer balanceLoadTimer {
"Balancing load", {
"Load balance"}};
679 phiprof::Timer deallocTimer {
"deallocate boundary data"};
686 for (
size_t i = 0;
i < cells.size(); ++
i){
694 phiprof::Timer initLBTimer {
"dccrg.initialize_balance_load"};
695 mpiGrid.initialize_balance_load(
true);
698 const std::unordered_set<CellID>& incoming_cells = mpiGrid.get_cells_added_by_balance_load();
699 std::vector<CellID> incoming_cells_list (incoming_cells.begin(),incoming_cells.end());
701 const std::unordered_set<CellID>& outgoing_cells = mpiGrid.get_cells_removed_by_balance_load();
702 std::vector<CellID> outgoing_cells_list (outgoing_cells.begin(),outgoing_cells.end());
708 phiprof::Timer finishLBTimer {
"dccrg.finish_balance_load"};
709 mpiGrid.finish_balance_load();
710 finishLBTimer.stop();
715 #pragma omp parallel for
716 for (uint
i = 0;
i < cells.size(); ++
i) {
717 mpiGrid[cells[
i]]->set_mpi_transfer_enabled(
true);
728 phiprof::Timer updateBlocksTimer {
"update block lists"};
737 updateBlocksTimer.stop();
739 phiprof::Timer updateBoundariesTimer {
"update sysboundaries"};
741 updateBoundariesTimer.stop();
744 if (doTranslationLists) {
750 phiprof::Timer timer {
"set face neighbor ranks"};
755 phiprof::Timer gpuReservationsTimer(
"GPU LB set cell reservations");
756 uint gpuMaxBlockCount = 0;
760 const uint newCellsSize = newCells.size();
761 const std::vector<CellID>& remote_cells = mpiGrid.get_remote_cells_on_process_boundary(
Neighborhoods::FULL);
762 for (uint
i = 0;
i < newCellsSize+remote_cells.size(); ++
i) {
764 if (
i < newCells.size()) {
765 SC = mpiGrid[newCells[
i]];
767 SC = mpiGrid[remote_cells[
i - newCells.size()]];
772 gpuBlockCount =
vmesh->size();
773 if (gpuBlockCount > gpuMaxBlockCount) {
774 gpuMaxBlockCount = gpuBlockCount;
783 gpuReservationsTimer.stop();
786 phiprof::Timer gpuAllocationsTimer(
"GPU LB set buffer allocations");
790 gpuAllocationsTimer.stop();
800 phiprof::Timer ghostTimer {
"prepare_ghost_translation_lists"};
803 phiprof::Timer updateRemoteNeighborsTimer {
"update neighbor lists of remote cells"};
806 mpiGrid.force_update_cell_neighborhoods(remote_cells);
807 updateRemoteNeighborsTimer.stop();
809 phiprof::Timer ghostListsTimer {
"update active cell lists for ghost translation"};
812 ghostListsTimer.stop();
814 phiprof::Timer barrierTimer {
"MPI barrier"};
815 MPI_Barrier(MPI_COMM_WORLD);
831 const vector<CellID>& cellsToAdjust,
832 bool doPrepareToReceiveBlocks,
834 phiprof::Timer readjustBlocksTimer {
"re-adjust blocks", {
"Block adjustment"}};
838 vector<CellID> validCells;
839 for (
CellID cid: cellsToAdjust) {
842 validCells.push_back(cid);
850 phiprof::Timer transferTimer {
"Transfer with_content_list", {
"MPI"}};
855 transferTimer.stop();
861 if (doPrepareToReceiveBlocks) {
876 const std::vector<CellID>& remote_cells = mpiGrid.get_remote_cells_on_process_boundary();
877 #pragma omp parallel for
878 for (
size_t i = 0;
i < cells.size() + remote_cells.size(); ++
i) {
879 if (
i < cells.size()) {
881 if (target !=
nullptr) {
885 SpatialCell* target= mpiGrid[remote_cells[
i - cells.size()]];
886 if (target !=
nullptr) {
903 const std::vector<uint64_t> incoming_cells = mpiGrid.get_remote_cells_on_process_boundary();
904 for(
unsigned int i = 0;
i < incoming_cells.size();
i++){
905 uint64_t cell_id=incoming_cells[
i];
909 cell->
clear(popID,
true);
920 dccrg::Dccrg<SpatialCell, dccrg::Cartesian_Geometry>& mpiGrid,
922 const uint neighborhood
930 phiprof::Timer updateTimer {
"Velocity block list update", {
"MPI"}};
932 mpiGrid.update_copies_of_remote_neighbors(neighborhood);
934 mpiGrid.update_copies_of_remote_neighbors(neighborhood);
938 phiprof::Timer receivesTimer {
"Preparing receives"};
939 const std::vector<uint64_t> incoming_cells = mpiGrid.get_remote_cells_on_process_boundary(neighborhood);
944 #pragma omp parallel for
946 for (
unsigned int i = 0;
i < incoming_cells.size(); ++
i) {
947 uint64_t cell_id = incoming_cells[
i];
950 #ifdef DEBUG_VLASIATOR
951 for (
const auto& cell: mpiGrid.local_cells) {
952 if (cell.id == cell_id) {
953 cerr << __FILE__ <<
":" << __LINE__ << std::endl;
956 for (
const auto& neighbor: cell.neighbors_of) {
957 if (neighbor.id == cell_id) {
958 cerr << __FILE__ <<
":" << __LINE__ << std::endl;
969 receivesTimer.stop(incoming_cells.size(),
"SpatialCells");
1039 typedef dccrg::Types<3>::neighborhood_item_t neigh_t;
1042 std::vector<neigh_t> neighborhood;
1043 for (
int z = -1; z <= 1; z++) {
1044 for (
int y = -1; y <= 1; y++) {
1045 for (
int x = -1; x <= 1; x++) {
1046 if (x == 0 && y == 0 && z == 0) {
1049 neigh_t offsets = {{x, y, z}};
1050 neighborhood.push_back(offsets);
1055 std::cerr <<
"Failed to add neighborhood Neighborhoods::NEAREST \n";
1059 std::cerr <<
"Failed to add neighborhood Neighborhoods::SYSBOUNDARIES \n";
1063 neighborhood.clear();
1064 for (
int z = -2; z <= 2; z++) {
1065 for (
int y = -2; y <= 2; y++) {
1066 for (
int x = -2; x <= 2; x++) {
1067 if (x == 0 && y == 0 && z == 0) {
1070 neigh_t offsets = {{x, y, z}};
1071 neighborhood.push_back(offsets);
1076 std::cerr <<
"Failed to add neighborhood Neighborhoods::SYSBOUNDARIES_EXTENDED \n";
1080 int full_neighborhood_size =
max(2, VLASOV_STENCIL_WIDTH);
1083 full_neighborhood_size++;
1085 neighborhood.clear();
1086 for (
int z = -full_neighborhood_size; z <= full_neighborhood_size; z++) {
1087 for (
int y = -full_neighborhood_size; y <= full_neighborhood_size; y++) {
1088 for (
int x = -full_neighborhood_size; x <= full_neighborhood_size; x++) {
1089 if (x == 0 && y == 0 && z == 0) {
1092 neigh_t offsets = {{x, y, z}};
1093 neighborhood.push_back(offsets);
1099 std::cerr <<
"Failed to add neighborhood Neighborhoods::FULL \n";
1104 neighborhood.clear();
1105 for (
int d = -VLASOV_STENCIL_WIDTH; d <= VLASOV_STENCIL_WIDTH; d++) {
1107 neighborhood.push_back({{d, 0, 0}});
1108 neighborhood.push_back({{0, d, 0}});
1109 neighborhood.push_back({{0, 0, d}});
1113 std::cerr <<
"Failed to add neighborhood Neighborhoods::VLASOV_SOLVER \n";
1118 for (
int z = -1; z <= 1; z++) {
1119 for (
int y = -1; y <= 1; y++) {
1120 for (
int x = -1; x <= 1; x++) {
1122 if (x == 0 && y == 0)
continue;
1123 if (x == 0 && z == 0)
continue;
1124 if (y == 0 && z == 0)
continue;
1125 neigh_t offsets = {{x, y, z}};
1126 neighborhood.push_back(offsets);
1131 std::cerr <<
"Failed to add neighborhood Neighborhoods::DIST_FUNC \n";
1135 neighborhood.clear();
1136 for (
int d = -VLASOV_STENCIL_WIDTH; d <= VLASOV_STENCIL_WIDTH; d++) {
1138 neighborhood.push_back({{d, 0, 0}});
1142 std::cerr <<
"Failed to add neighborhood Neighborhoods::VLASOV_SOLVER_X \n";
1146 neighborhood.clear();
1147 for (
int d = -VLASOV_STENCIL_WIDTH; d <= VLASOV_STENCIL_WIDTH; d++) {
1149 neighborhood.push_back({{0, d, 0}});
1153 std::cerr <<
"Failed to add neighborhood Neighborhoods::VLASOV_SOLVER_Y \n";
1157 neighborhood.clear();
1158 for (
int d = -VLASOV_STENCIL_WIDTH; d <= VLASOV_STENCIL_WIDTH; d++) {
1160 neighborhood.push_back({{0, 0, d}});
1164 std::cerr <<
"Failed to add neighborhood Neighborhoods::VLASOV_SOLVER_Z \n";
1169 neighborhood.clear();
1170 for (
int d = -VLASOV_STENCIL_WIDTH-1; d <= VLASOV_STENCIL_WIDTH+1; d++) {
1172 neighborhood.push_back({{d, 0, 0}});
1176 std::cerr <<
"Failed to add neighborhood Neighborhoods::VLASOV_SOLVER_X_GHOST \n";
1180 neighborhood.clear();
1181 for (
int d = -VLASOV_STENCIL_WIDTH-1; d <= VLASOV_STENCIL_WIDTH+1; d++) {
1183 neighborhood.push_back({{0, d, 0}});
1187 std::cerr <<
"Failed to add neighborhood Neighborhoods::VLASOV_SOLVER_Y_GHOST \n";
1191 neighborhood.clear();
1192 for (
int d = -VLASOV_STENCIL_WIDTH-1; d <= VLASOV_STENCIL_WIDTH+1; d++) {
1194 neighborhood.push_back({{0, 0, d}});
1198 std::cerr <<
"Failed to add neighborhood Neighborhoods::VLASOV_SOLVER_Z_GHOST \n";
1203 neighborhood.clear();
1205 for (
int dy = -VLASOV_STENCIL_WIDTH-1; dy <= VLASOV_STENCIL_WIDTH+1; dy++){
1207 neighborhood.push_back({{0, dy, 0}});
1212 for (
int dx = -VLASOV_STENCIL_WIDTH-1;
dx <= VLASOV_STENCIL_WIDTH+1;
dx++){
1214 neighborhood.push_back({{
dx, dy, 0}});
1221 for (
int dz = -VLASOV_STENCIL_WIDTH-1; dz <= VLASOV_STENCIL_WIDTH+1; dz++){
1223 neighborhood.push_back({{
dx, dy, dz}});
1229 std::cerr <<
"Failed to add neighborhood Neighborhoods::VLASOV_SOLVER_GHOST \n";
1234 neighborhood.clear();
1238 if ((dz==0) && (dy==0) && (
dx==0)) {
1241 neighborhood.push_back({{
dx, dy, dz}});
1246 std::cerr <<
"Failed to add neighborhood Neighborhoods::VLASOV_SOLVER_GHOST_REQNEIGH \n";
1251 neighborhood.clear();
1252 for (
int d = -1; d <= 1; d++) {
1254 neighborhood.push_back({{d, 0, 0}});
1258 std::cerr <<
"Failed to add neighborhood Neighborhoods::VLASOV_SOLVER_TARGET_X \n";
1262 neighborhood.clear();
1263 for (
int d = -1; d <= 1; d++) {
1265 neighborhood.push_back({{0, d, 0}});
1269 std::cerr <<
"Failed to add neighborhood Neighborhoods::VLASOV_SOLVER_TARGET_Y \n";
1273 neighborhood.clear();
1274 for (
int d = -1; d <= 1; d++) {
1276 neighborhood.push_back({{0, 0, d}});
1280 std::cerr <<
"Failed to add neighborhood Neighborhoods::VLASOV_SOLVER_TARGET_Z \n";
1284 neighborhood.clear();
1285 neighborhood.push_back({{1, 0, 0}});
1287 std::cerr <<
"Failed to add neighborhood Neighborhoods::SHIFT_M_X \n";
1290 neighborhood.clear();
1291 neighborhood.push_back({{0, 1, 0}});
1293 std::cerr <<
"Failed to add neighborhood Neighborhoods::SHIFT_M_Y \n";
1296 neighborhood.clear();
1297 neighborhood.push_back({{0, 0, 1}});
1299 std::cerr <<
"Failed to add neighborhood Neighborhoods::SHIFT_M_Z \n";
1302 neighborhood.clear();
1303 neighborhood.push_back({{-1, 0, 0}});
1305 std::cerr <<
"Failed to add neighborhood Neighborhoods::SHIFT_P_X \n";
1308 neighborhood.clear();
1309 neighborhood.push_back({{0, -1, 0}});
1311 std::cerr <<
"Failed to add neighborhood Neighborhoods::SHIFT_P_Y \n";
1314 neighborhood.clear();
1315 neighborhood.push_back({{0, 0, -1}});
1317 std::cerr <<
"Failed to add neighborhood Neighborhoods::SHIFT_P_Z \n";
1323 const auto maxRefLevel = mpiGrid.mapping.get_maximum_refinement_level();
1324 fsgrid.parallel_for([](
int timerId) -> phiprof::Timer {
return phiprof::Timer{timerId}; },
1325 phiprof::initializeTimer(
"Map Refinement Level to FsGrid"), technical,
1326 [=, &mpiGrid](
const fsgrid::Coordinates &coordinates,
const fsgrid::FsStencil& stencil,
cuint sysBoundaryFlag,
cuint sysBoundaryLayer) {
1327 const std::array<fsgrid::FsSize_t, 3> mapIndices = coordinates.localToGlobal(stencil.i, stencil.j, stencil.k);
1328 const dccrg::Types<3>::indices_t indices = {
1329 {(uint64_t)mapIndices[0], (uint64_t)mapIndices[1], (uint64_t)mapIndices[2]}};
1330 const CellID dccrgCellID2 =
1331 mpiGrid.get_existing_cell(indices, 0, maxRefLevel);
1332 const int amrLevel = mpiGrid.get_refinement_level(dccrgCellID2);
1333 technical[stencil.ooo()].refLevel = amrLevel;
1338 phiprof::Timer amrTimer {
"Re-refine spatial cells"};
1339 uint64_t refines {0};
1340 if (useStatic > -1) {
1354 MPI_Allreduce(MPI_IN_PLACE, &refines, 1, MPI_UINT64_T, MPI_SUM, MPI_COMM_WORLD);
1355 MPI_Allreduce(MPI_IN_PLACE, &cells, 1, MPI_UINT64_T, MPI_SUM, MPI_COMM_WORLD);
1356 double ratio_refines =
static_cast<double>(refines) /
static_cast<double>(cells);
1357 logFile <<
"(AMR) Refining " << refines <<
" cells, " << 100.0 * ratio_refines <<
"% of grid" << std::endl;
1359 phiprof::Timer dccrgTimer {
"dccrg refinement"};
1361 phiprof::Timer initTimer {
"initialize refines"};
1362 mpiGrid.initialize_refines();
1365 refines = mpiGrid.get_cells_to_refine_count();
1366 uint64_t coarsens {mpiGrid.get_cells_to_unrefine_count()};
1367 ratio_refines =
static_cast<double>(refines) /
static_cast<double>(cells);
1368 double ratio_coarsens =
static_cast<double>(coarsens) /
static_cast<double>(cells);
1369 logFile <<
"(AMR) Refining " << refines <<
" cells to " << refines*8 <<
" children after induces, " << 100.0 * ratio_refines <<
"% of grid" << std::endl;
1370 logFile <<
"(AMR) Coarsening " << coarsens <<
" cells to " << coarsens/8 <<
" parents after induces, " << 100.0 * ratio_coarsens <<
"% of grid" << std::endl;
1373 phiprof::Timer estimateMemoryTimer {
"Estimate memory usage"};
1374 for (
auto id : mpiGrid.get_local_cells_to_refine()) {
1375 newBytes += 8 * mpiGrid[id]->get_cell_memory_capacity();
1380 for (
auto id : mpiGrid.get_local_cells_to_unrefine()) {
1381 newBytes += mpiGrid[id]->get_cell_memory_capacity();
1385 estimateMemoryTimer.stop();
1392 phiprof::Timer bailoutAllreduceTimer {
"Bailout-allreduce"};
1394 bailoutAllreduceTimer.stop();
1401 phiprof::Timer executeTimer {
"execute refines"};
1402 auto newChildren = mpiGrid.execute_refines();
1403 executeTimer.stop();
1406 std::vector<CellID> incoming_cells_list;
1407 for (
auto const& [key, val] : mpiGrid.get_cells_to_receive()) {
1408 for (
auto i : val) {
1409 incoming_cells_list.push_back(
i.first);
1413 std::vector<CellID> outgoing_cells_list;
1414 for (
auto const& [key, val] : mpiGrid.get_cells_to_send()) {
1415 for (
auto i : val) {
1416 outgoing_cells_list.push_back(
i.first);
1420 transferInParts(mpiGrid, incoming_cells_list, outgoing_cells_list,
true);
1422 phiprof::Timer copyChildrenTimer {
"copy to children"};
1423 for (
CellID id : newChildren) {
1424 *mpiGrid[id] = *mpiGrid[mpiGrid.get_parent(
id)];
1431 mpiGrid[id]->setReservation(popID,mpiGrid[
id]->get_velocity_mesh(popID)->size());
1432 mpiGrid[id]->applyReservation(popID);
1436 copyChildrenTimer.stop(newChildren.size(),
"Spatial cells");
1438 phiprof::Timer finishTimer {
"finish refining"};
1439 mpiGrid.finish_refining();
1472 fsgrid.updateGhostCells(technical);
#define gpuDeviceSynchronize
void calculateCellMoments(spatial_cell::SpatialCell *cell, const bool &computeSecond, const bool &computePopulationMomentsOnly, const bool &doNotSkip)
SysBoundary contains the SysBoundaryConditions used in the simulation.
void initSysBoundaries(Project &project, creal &t)
Initialise all system boundary conditions actually used.
bool isPeriodic(uint direction) const
void classifyCells(dccrg::Dccrg< spatial_cell::SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid, fsgrids::technicalspan technical, FieldSolverGrid &fsgrid)
Classify all simulation cells with respect to the system boundary conditions.
void checkRefinement(dccrg::Dccrg< spatial_cell::SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid)
void applyInitialState(dccrg::Dccrg< spatial_cell::SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid, fsgrids::technicalspan technical, FieldSolverGrid &fsgrid, fsgrids::perbspan perb, fsgrids::bgbspan bgb, Project &project)
Apply the initial state to all system boundary cells. Loops through all SysBoundaryConditions and cal...
void applySysBoundaryVlasovConditions(dccrg::Dccrg< spatial_cell::SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid, creal &t, const bool calculate_V_moments)
Apply the Vlasov system boundary conditions to all system boundary cells at time t.
void updateSysBoundariesAfterLoadBalance(dccrg::Dccrg< spatial_cell::SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid)
virtual void setupBeforeSetCell(const std::vector< CellID > &cells)
virtual bool forceRefinement(dccrg::Dccrg< spatial_cell::SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid, int n) const
Refine/unrefine spatial cells one level to the static criteria in the config.
virtual uint64_t adaptRefinement(dccrg::Dccrg< spatial_cell::SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid) const
Adapts refinement by one level according to the project. Returns true if any cells were refined,...
virtual void setProjectBField(fsgrids::perbspan perb, fsgrids::bgbspan bgb, fsgrids::technicalspan technical, FieldSolverGrid &fsgrid)
virtual bool refineSpatialCells(dccrg::Dccrg< spatial_cell::SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid) const
virtual bool filterRefined(dccrg::Dccrg< spatial_cell::SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid) const
Boxcar filters spatial cells that were recently refined.
void setCell(spatial_cell::SpatialCell *cell)
Set the perturbed fields and distribution of a cell according to the default simulation settings....
vmesh::LocalID get_number_of_velocity_blocks(const uint popID) const
vmesh::VelocityMesh * get_velocity_mesh(const size_t &popID)
vmesh::VelocityBlockContainer * get_velocity_blocks(const size_t &popID)
void dev_upload_population(const uint popID)
void set_mpi_transfer_enabled(bool transferEnabled)
static bool setCommunicatedSpecies(const uint popID)
void clear(const uint popID, bool shrink=false)
void prepare_to_receive_blocks(const uint popID)
vmesh::LocalID get_number_of_all_velocity_blocks() const
static void set_mpi_transfer_type(const uint64_t type, bool atSysBoundaries=false)
void applyReservation(const uint popID)
std::array< Real, CellParams::N_SPATIAL_CELL_PARAMS > parameters
void setReservation(const uint popID, const vmesh::LocalID reservationsize, bool force=false)
std::map< int, std::set< int > > face_neighbor_ranks
void bailout(const bool condition, const std::string &message, const char *const file, const int line)
A function to stop the simulation if the boolean condition is true. Raises a flag which gets MPI_Redu...
const std::vector< CellID > & getLocalCells()
void prepareGhostTranslationCellLists(const dccrg::Dccrg< SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid, const vector< CellID > &localPropagatedCells)
void prepareSeedIdsAndPencils(const dccrg::Dccrg< SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid)
fsgrid::FsGrid< FS_STENCIL_WIDTH > FieldSolverGrid
void calculateScaledDeltasSimple(dccrg::Dccrg< SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid)
High-level scaled gradient calculation wrapper function.
__host__ void gpu_acc_allocate(uint maxBlockCount)
__host__ void gpu_calculateProbeAllocation(const uint maxBlockCount)
__host__ void gpu_vlasov_allocate(const uint maxBlockCount)
void deallocateRemoteCellBlocks(dccrg::Dccrg< SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid)
void initializeStencils(dccrg::Dccrg< SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid)
void recalculateLocalCellsCache(const dccrg::Dccrg< SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid)
void initSpatialCellCoordinates(dccrg::Dccrg< SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid)
void writeVelMesh(const dccrg::Dccrg< SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid)
bool adjustVelocityBlocks(dccrg::Dccrg< SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid, const vector< CellID > &cellsToAdjust, bool doPrepareToReceiveBlocks, const uint popID)
bool adaptRefinement(dccrg::Dccrg< SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid, fsgrids::technicalspan technical, FieldSolverGrid &fsgrid, SysBoundary &sysBoundaries, Project &project, int useStatic)
void shrink_to_fit_grid_data(dccrg::Dccrg< SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid)
void initializeGrids(int argn, char **argc, dccrg::Dccrg< SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid, fsgrid::FsData< std::array< Real, fsgrids::bfield::N_BFIELD > > &perb, fsgrid::FsData< std::array< Real, fsgrids::bgbfield::N_BGB > > &bgb, fsgrid::FsData< std::array< Real, fsgrids::moments::N_MOMENTS > > &moments, fsgrid::FsData< std::array< Real, fsgrids::moments::N_MOMENTS > > &momentsdt2, fsgrid::FsData< std::array< Real, fsgrids::dmoments::N_DMOMENTS > > &dmoments, fsgrid::FsData< std::array< Real, fsgrids::efield::N_EFIELD > > &e, fsgrid::FsData< std::array< Real, fsgrids::egradpe::N_EGRADPE > > &egradpe, fsgrid::FsData< std::array< Real, fsgrids::volfields::N_VOL > > &vol, fsgrid::FsData< fsgrids::technical > &technical, FieldSolverGrid &fsgrid, SysBoundary &sysBoundaries, Project &project)
Initialize DCCRG and fsgrids.
void transferInParts(dccrg::Dccrg< SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid, std::vector< CellID > &incoming_cells_list, std::vector< CellID > &outgoing_cells_list, bool refinement=false)
void initVelocityGridGeometry(dccrg::Dccrg< SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid)
void mapRefinement(dccrg::Dccrg< SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid, fsgrids::technicalspan technical, FieldSolverGrid &fsgrid)
void prepareAMRLists(dccrg::Dccrg< SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid)
void updateRemoteVelocityBlockLists(dccrg::Dccrg< SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid, const uint popID, const uint neighborhood)
void balanceLoad(dccrg::Dccrg< SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid, SysBoundary &sysBoundaries, fsgrids::technicalspan technical, FieldSolverGrid &fsgrid, bool doTranslationLists)
Balance load.
void setFaceNeighborRanks(dccrg::Dccrg< SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid)
uint64_t get_transfer_part(dccrg::Dccrg< SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid, uint64_t num_part_transfers, CellID cell)
void feedMomentsIntoFsGrid(dccrg::Dccrg< SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid, const std::vector< CellID > &cells, fsgrid::FsData< std::array< Real, fsgrids::moments::N_MOMENTS > > &moments, fsgrids::technicalspan technical, FieldSolverGrid &fsgrid, bool dt2)
void getFieldsFromFsGrid(fsgrids::constvolspan volumefields, fsgrids::constbgbspan bgb, fsgrids::constegradpespan egradpe, fsgrids::constdmomentsspan dmoments, fsgrids::consttechnicalspan technical, FieldSolverGrid &fsgrid, dccrg::Dccrg< SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid, const std::vector< CellID > &cells)
void computeCoupling(dccrg::Dccrg< SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid, const std::vector< CellID > &cells, fsgrid::FsGrid< STENCIL > &fsgrid, fsgrids::technicalspan technical)
ObjectWrapper & getObjectWrapper()
bool readFileCells(dccrg::Dccrg< SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid, const std::string &name)
Refine the grid to be identical to the file's.
bool readGrid(dccrg::Dccrg< SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid, fsgrids::perbspan perb, fsgrids::efieldspan e, fsgrids::technicalspan technical, FieldSolverGrid &fsgrid, const std::string &name)
Read in state from a vlsv file in order to restart simulations.
bool writeVelocityDistributionData(const uint popID, Writer &vlsvWriter, const dccrg::Dccrg< SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid, const std::vector< CellID > &cells, MPI_Comm comm)
Logger & writeVerbose(Logger &logger)
void report_memory_consumption(const dccrg::Dccrg< SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid, double extra_bytes)
@ VLASOV_SOLVER_GHOST_REQNEIGH
void averageCellData(const dccrg::Dccrg< SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid, const vector< CellID > cellList, SpatialCell *to, const uint popID, const creal fluffiness)
std::span< technical > technicalspan
static const uint64_t REFINEMENT_PARAMETERS
static const uint64_t CELL_SYSBOUNDARYFLAG
static const uint64_t ALL_DATA
static const uint64_t VEL_BLOCK_LIST_STAGE2
static const uint64_t VEL_BLOCK_LIST_STAGE1
static const uint64_t VEL_BLOCK_WITH_CONTENT_STAGE1
static const uint64_t ALL_SPATIAL_DATA
static const uint64_t VEL_BLOCK_DATA
static const uint64_t VEL_BLOCK_WITH_CONTENT_STAGE2
static const uint64_t CELL_PARAMETERS
static const uint64_t CELL_DIMENSIONS
void adjust_velocity_blocks_in_cells(dccrg::Dccrg< spatial_cell::SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid, const vector< CellID > &cellsToAdjust, const uint popID)
void update_velocity_block_content_lists(dccrg::Dccrg< SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid, const vector< CellID > &cells, const uint popID)
const uint64_t INVALID_CELLID
std::vector< species::Species > particleSpecies
static std::vector< CellID > localCells
static bool vlasovSolverGhostTranslate
static int amrMaxSpatialRefLevel
static bool refineOnRestart
static std::map< std::string, std::string > loadBalanceOptions
static std::string loadBalanceAlgorithm
static bool meshRepartitioned
static std::string restartFileName
static bool forceRefinement
static bool propagateVlasovAcceleration
static uint vlasovSolverGhostTranslateExtent
static Real bailout_min_dt
static ARCH_HOSTDEV VecSimple< T > max(VecSimple< T > const &l, VecSimple< T > const &r)
void calculateAcceleration(const uint popID, const uint globalMaxSubcycles, const uint step, dccrg::Dccrg< SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid, const std::vector< CellID > &acceleratedCells, const Real dt)
void calculateInitialVelocityMoments(dccrg::Dccrg< SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid)
Compute 0th, 1st and 2nd velocity moments (RHO,VX,VY,VZ,P_11,P_22,P_33 and *_DT2) for all cells in th...