29template<
class Tvec,
class Tgr
idVec>
30template<
class UserAcc,
class... T>
37 using namespace shamrock::patch;
43 auto dev_sched = shamsys::instance::get_compute_scheduler_ptr();
57 UserAcc uacc(depends_list, id_patch, cur_p, pdat,
args...);
59 auto refine_acc = refine_flags.get_write_access(depends_list);
60 auto derefine_acc = derefine_flags.get_write_access(depends_list);
63 auto e = q.
submit(depends_list, [&](sycl::handler &cgh) {
64 cgh.parallel_for(sycl::range<1>(obj_cnt), [=](sycl::item<1> gid) {
65 bool flag_refine =
false;
66 bool flag_derefine =
false;
67 uacc.refine_criterion(gid.get_linear_id(), uacc, flag_refine, flag_derefine);
70 if (flag_refine && flag_derefine) {
71 flag_derefine =
false;
74 refine_acc[gid] = (flag_refine) ? 1 : 0;
75 derefine_acc[gid] = (flag_derefine) ? 1 : 0;
82 refine_flags.complete_event_state(resulting_events);
83 derefine_flags.complete_event_state(resulting_events);
85 uacc.finalize(resulting_events, id_patch, cur_p, pdat,
args...);
93 auto acc_max = buf_cell_max.get_read_access(depends_list);
94 auto acc_merge_flag = derefine_flags.get_write_access(depends_list);
97 auto e = q.
submit(depends_list, [&](sycl::handler &cgh) {
98 cgh.parallel_for(sycl::range<1>(obj_cnt), [=](sycl::item<1> gid) {
99 u32 id = gid.get_linear_id();
101 std::array<BlockCoord, split_count> blocks;
102 bool do_merge =
true;
106 if (
id + split_count <= obj_cnt) {
107 bool all_want_to_merge =
true;
109 for (
u32 lid = 0; lid < split_count; lid++) {
110 blocks[lid] = BlockCoord{acc_min[gid + lid], acc_max[gid + lid]};
111 all_want_to_merge = all_want_to_merge && acc_merge_flag[gid + lid];
114 do_merge = all_want_to_merge && BlockCoord::are_mergeable(blocks);
120 acc_merge_flag[gid] = do_merge;
125 buf_cell_max.complete_event_state(e);
126 derefine_flags.complete_event_state(e);
136 "AMRGrid",
"patch ", id_patch,
"refine block count = ", buf_refine.get_size());
138 tot_refine += buf_refine.get_size();
141 dd_refine_list.add_obj(id_patch, std::move(buf_refine));
151 "AMRGrid",
"patch ", id_patch,
"merge block count = ", buf_derefine.get_size());
153 tot_derefine += buf_derefine.get_size();
156 dd_derefine_list.add_obj(id_patch, std::move(buf_derefine));
159 logger::info_ln(
"AMRGrid",
"on this process", tot_refine,
"blocks were refined");
161 "AMRGrid",
"on this process", tot_derefine * split_count,
"blocks were derefined");
163template<
class Tvec,
class Tgr
idVec>
164template<
class UserAcc>
168 using namespace shamrock::patch;
170 u64 sum_block_count = 0;
172 bool new_cell_were_added =
false;
184 pdat.expand(refine_flags.
get_size() * (split_count - 1));
191 auto block_bound_high = buf_cell_max.get_write_access(depends_list);
192 UserAcc uacc(depends_list, pdat);
196 auto e = q.
submit(depends_list, [&](sycl::handler &cgh) {
197 u32 start_index_push = old_obj_cnt;
199 constexpr u32 new_splits = split_count - 1;
201 cgh.parallel_for(sycl::range<1>(refine_flags.
get_size()), [=](sycl::item<1> gid) {
202 u32 tid = gid.get_linear_id();
204 u32 idx_to_refine = index_to_ref[tid];
207 BlockCoord cur_block{
208 block_bound_low[idx_to_refine], block_bound_high[idx_to_refine]};
210 std::array<BlockCoord, split_count> block_coords
211 = BlockCoord::get_split(cur_block.bmin, cur_block.bmax);
214 std::array<u32, split_count> blocks_ids;
215 blocks_ids[0] = idx_to_refine;
220 for (
u32 pid = 0; pid < new_splits; pid++) {
221 blocks_ids[pid + 1] = start_index_push + tid * new_splits + pid;
227 for (
u32 pid = 0; pid < split_count; pid++) {
228 block_bound_low[blocks_ids[pid]] = block_coords[pid].bmin;
229 block_bound_high[blocks_ids[pid]] = block_coords[pid].bmax;
233 uacc.apply_refine(idx_to_refine, cur_block, blocks_ids, block_coords, uacc);
240 buf_cell_max.complete_event_state(resulting_events);
242 uacc.finalize(resulting_events, pdat);
248 new_cell_were_added = new_cell_were_added || refine_flags.
get_size() > 0;
253 return new_cell_were_added;
256template<
class Tvec,
class Tgr
idVec>
257template<
class UserAcc>
262 using namespace shamrock::patch;
264 bool cell_were_removed =
false;
267 auto dev_sched = shamsys::instance::get_compute_scheduler_ptr();
274 if (derefine_flags.
get_size() > 0) {
278 keep_block_flag.fill(1);
285 auto block_bound_high = buf_cell_max.get_write_access(depends_list);
286 UserAcc uacc(depends_list, pdat);
288 auto flag_keep = keep_block_flag.get_write_access(depends_list);
291 auto e = q.
submit(depends_list, [&](sycl::handler &cgh) {
292 cgh.parallel_for(sycl::range<1>(derefine_flags.
get_size()), [=](sycl::item<1> gid) {
293 u32 tid = gid.get_linear_id();
295 u32 idx_to_derefine = index_to_deref[gid];
298 std::array<u32, split_count> old_indexes;
300 for (u32 pid = 0; pid < split_count; pid++) {
301 old_indexes[pid] = idx_to_derefine + pid;
305 std::array<BlockCoord, split_count> block_coords;
307 for (
u32 pid = 0; pid < split_count; pid++) {
308 block_coords[pid] = BlockCoord{
309 block_bound_low[old_indexes[pid]], block_bound_high[old_indexes[pid]]};
313 BlockCoord merged_block_coord = BlockCoord::get_merge(block_coords);
316 block_bound_low[idx_to_derefine] = merged_block_coord.bmin;
317 block_bound_high[idx_to_derefine] = merged_block_coord.bmax;
321 for (
u32 pid = 1; pid < split_count; pid++) {
322 flag_keep[idx_to_derefine + pid] = 0;
327 old_indexes, block_coords, idx_to_derefine, merged_block_coord, uacc);
334 buf_cell_max.complete_event_state(resulting_events);
336 uacc.finalize(resulting_events, pdat);
338 keep_block_flag.complete_event_state(resulting_events);
349 "derefine block count ",
352 buf_keep.get_size());
354 if (buf_keep.get_size() == 0) {
355 throw std::runtime_error(
"buf keep must contain something at this point");
361 cell_were_removed = cell_were_removed || derefine_flags.
get_size() > 0;
365 return cell_were_removed;
368template<
class Tvec,
class Tgr
idVec>
369template<
class UserAccCrit,
class UserAccSplit,
class UserAccMerge>
374 AMRSortBlocks block_sorter(context, solver_config, storage);
375 block_sorter.reorder_amr_blocks();
381 gen_refine_block_changes<UserAccCrit>(dd_refine_list, dd_derefine_list);
385 internal_refine_grid<UserAccSplit>(std::move(dd_refine_list));
392 internal_derefine_grid<UserAccMerge>(std::move(dd_derefine_list));
395template<
class Tvec,
class Tgr
idVec>
399 class RefineCritBlock {
401 const TgridVec *block_low_bound;
402 const TgridVec *block_high_bound;
403 const Tscal *block_density_field;
405 Tscal one_over_Nside = 1. / AMRBlock::Nside;
411 sham::EventList &depends_list,
413 shamrock::patch::Patch p,
414 shamrock::patch::PatchDataLayer &pdat,
417 : dxfact(dxfact), wanted_mass(wanted_mass) {
419 block_low_bound = pdat.get_field<TgridVec>(0).get_buf().get_read_access(depends_list);
420 block_high_bound = pdat.get_field<TgridVec>(1).get_buf().get_read_access(depends_list);
421 block_density_field = pdat.get_field<Tscal>(pdat.pdl().get_field_idx<Tscal>(
"rho"))
423 .get_read_access(depends_list);
427 sham::EventList &resulting_events,
429 shamrock::patch::Patch p,
430 shamrock::patch::PatchDataLayer &pdat,
434 sham::DeviceBuffer<i64_3> &buf_cell_low_bound = pdat.get_field<i64_3>(0).get_buf();
435 sham::DeviceBuffer<i64_3> &buf_cell_high_bound = pdat.get_field<i64_3>(1).get_buf();
439 pdat.get_field<Tscal>(pdat.pdl().get_field_idx<Tscal>(
"rho"))
441 .complete_event_state(resulting_events);
444 void refine_criterion(
445 u32 block_id, RefineCritBlock acc,
bool &should_refine,
bool &should_derefine)
const {
447 TgridVec low_bound = acc.block_low_bound[block_id];
448 TgridVec high_bound = acc.block_high_bound[block_id];
450 Tvec lower_flt = low_bound.template convert<Tscal>() * dxfact;
451 Tvec upper_flt = high_bound.template convert<Tscal>() * dxfact;
453 Tvec block_cell_size = (upper_flt - lower_flt) * one_over_Nside;
456 for (
u32 i = 0; i < AMRBlock::block_size; i++) {
457 sum_mass += acc.block_density_field[i + block_id * AMRBlock::block_size];
459 sum_mass *= block_cell_size.x() * block_cell_size.y() * block_cell_size.z();
461 if (sum_mass > wanted_mass * 8) {
462 should_refine =
true;
463 should_derefine =
false;
464 }
else if (sum_mass < wanted_mass) {
465 should_refine =
false;
466 should_derefine =
true;
468 should_refine =
false;
469 should_derefine =
false;
472 should_refine = should_refine && (high_bound.x() - low_bound.x() > AMRBlock::Nside);
473 should_refine = should_refine && (high_bound.y() - low_bound.y() > AMRBlock::Nside);
474 should_refine = should_refine && (high_bound.z() - low_bound.z() > AMRBlock::Nside);
478 class RefineCellAccessor {
484 RefineCellAccessor(sham::EventList &depends_list, shamrock::patch::PatchDataLayer &pdat) {
486 rho = pdat.get_field<
f64>(2).get_buf().get_write_access(depends_list);
487 rho_vel = pdat.get_field<f64_3>(3).get_buf().get_write_access(depends_list);
488 rhoE = pdat.get_field<
f64>(4).get_buf().get_write_access(depends_list);
491 void finalize(sham::EventList &resulting_events, shamrock::patch::PatchDataLayer &pdat) {
492 pdat.get_field<
f64>(2).get_buf().complete_event_state(resulting_events);
493 pdat.get_field<f64_3>(3).get_buf().complete_event_state(resulting_events);
494 pdat.get_field<
f64>(4).get_buf().complete_event_state(resulting_events);
499 BlockCoord cur_coords,
500 std::array<u32, 8> new_blocks,
501 std::array<BlockCoord, 8> new_block_coords,
502 RefineCellAccessor acc)
const {
504 auto get_coord_ref = [](
u32 i) -> std::array<u32, dim> {
505 constexpr u32 NsideBlockPow = 1;
506 constexpr u32 Nside = 1U << NsideBlockPow;
508 if constexpr (dim == 3) {
509 const u32 tmp = i >> NsideBlockPow;
510 return {i % Nside, (tmp) % Nside, (tmp) >> NsideBlockPow};
514 auto get_index_block = [](std::array<u32, dim> coord) ->
u32 {
515 constexpr u32 NsideBlockPow = 1;
516 constexpr u32 Nside = 1U << NsideBlockPow;
518 if constexpr (dim == 3) {
519 return coord[0] + Nside * coord[1] + Nside * Nside * coord[2];
523 auto get_gid_write = [&](std::array<u32, dim> &glid) ->
u32 {
524 std::array<u32, dim> bid
525 = {glid[0] >> AMRBlock::NsideBlockPow,
526 glid[1] >> AMRBlock::NsideBlockPow,
527 glid[2] >> AMRBlock::NsideBlockPow};
530 return new_blocks[get_index_block(bid)] * AMRBlock::block_size
531 + AMRBlock::get_index(
532 {glid[0] % AMRBlock::Nside,
533 glid[1] % AMRBlock::Nside,
534 glid[2] % AMRBlock::Nside});
537 std::array<f64, AMRBlock::block_size> old_rho_block;
538 std::array<f64_3, AMRBlock::block_size> old_rho_vel_block;
539 std::array<f64, AMRBlock::block_size> old_rhoE_block;
542 for (
u32 loc_id = 0; loc_id < AMRBlock::block_size; loc_id++) {
544 auto [lx, ly, lz] = get_coord_ref(loc_id);
545 u32 old_cell_idx = cur_idx * AMRBlock::block_size + loc_id;
546 old_rho_block[loc_id] = acc.rho[old_cell_idx];
547 old_rho_vel_block[loc_id] = acc.rho_vel[old_cell_idx];
548 old_rhoE_block[loc_id] = acc.rhoE[old_cell_idx];
551 for (
u32 loc_id = 0; loc_id < AMRBlock::block_size; loc_id++) {
553 auto [lx, ly, lz] = get_coord_ref(loc_id);
554 u32 old_cell_idx = cur_idx * AMRBlock::block_size + loc_id;
556 Tscal rho_block = old_rho_block[loc_id];
557 Tvec rho_vel_block = old_rho_vel_block[loc_id];
558 Tscal rhoE_block = old_rhoE_block[loc_id];
559 for (
u32 subdiv_lid = 0; subdiv_lid < 8; subdiv_lid++) {
561 auto [sx, sy, sz] = get_coord_ref(subdiv_lid);
563 std::array<u32, 3> glid = {lx * 2 + sx, ly * 2 + sy, lz * 2 + sz};
565 u32 new_cell_idx = get_gid_write(glid);
580 acc.rho[new_cell_idx] = rho_block;
581 acc.rho_vel[new_cell_idx] = rho_vel_block;
582 acc.rhoE[new_cell_idx] = rhoE_block;
588 std::array<u32, 8> old_blocks,
589 std::array<BlockCoord, 8> old_coords,
591 BlockCoord new_coord,
593 RefineCellAccessor acc)
const {
595 std::array<f64, AMRBlock::block_size> rho_block;
596 std::array<f64_3, AMRBlock::block_size> rho_vel_block;
597 std::array<f64, AMRBlock::block_size> rhoE_block;
599 for (
u32 cell_id = 0; cell_id < AMRBlock::block_size; cell_id++) {
600 rho_block[cell_id] = {};
601 rho_vel_block[cell_id] = {};
602 rhoE_block[cell_id] = {};
605 for (
u32 pid = 0; pid < 8; pid++) {
606 for (
u32 cell_id = 0; cell_id < AMRBlock::block_size; cell_id++) {
607 rho_block[cell_id] += acc.rho[old_blocks[pid] * AMRBlock::block_size + cell_id];
608 rho_vel_block[cell_id]
609 += acc.rho_vel[old_blocks[pid] * AMRBlock::block_size + cell_id];
611 += acc.rhoE[old_blocks[pid] * AMRBlock::block_size + cell_id];
615 for (
u32 cell_id = 0; cell_id < AMRBlock::block_size; cell_id++) {
616 rho_block[cell_id] /= 8;
617 rho_vel_block[cell_id] /= 8;
618 rhoE_block[cell_id] /= 8;
621 for (
u32 cell_id = 0; cell_id < AMRBlock::block_size; cell_id++) {
622 u32 newcell_idx = new_cell * AMRBlock::block_size + cell_id;
623 acc.rho[newcell_idx] = rho_block[cell_id];
624 acc.rho_vel[newcell_idx] = rho_vel_block[cell_id];
625 acc.rhoE[newcell_idx] = rhoE_block[cell_id];
630 using AMRmode_None =
typename AMRMode<Tvec, TgridVec>::None;
631 using AMRmode_DensityBased =
typename AMRMode<Tvec, TgridVec>::DensityBased;
633 bool has_cell_order_changed =
false;
635 if (AMRmode_None *cfg = std::get_if<AMRmode_None>(&solver_config.amr_mode.config)) {
638 AMRmode_DensityBased *cfg
639 = std::get_if<AMRmode_DensityBased>(&solver_config.amr_mode.config)) {
640 Tscal dxfact(solver_config.grid_coord_to_pos_fact);
646 gen_refine_block_changes_old<RefineCritBlock>(
647 refine_list, derefine_list, dxfact, cfg->crit_mass);
651 bool change_refine = internal_refine_grid_old<RefineCellAccessor>(std::move(refine_list));
659 = internal_derefine_grid_old<RefineCellAccessor>(std::move(derefine_list));
661 has_cell_order_changed = has_cell_order_changed || (change_refine || change_derefine);
664 if (has_cell_order_changed) {
666 AMRSortBlocks block_sorter(context, solver_config, storage);
667 block_sorter.reorder_amr_blocks();
671template<
class Tvec,
class Tgr
idVec>
672template<
class UserAcc,
class... T>
680 auto dev_sched = shamsys::instance::get_compute_scheduler_ptr();
694 UserAcc uacc(depends_list, storage, id_patch, cur_p, pdat,
args...);
700 auto e = q.
submit(depends_list, [&](sycl::handler &cgh) {
701 cgh.parallel_for(sycl::range<1>(obj_cnt), [=](sycl::item<1> gid) {
702 bool flag_refine =
false;
703 bool flag_derefine =
false;
704 uacc.refine_criterion_new(
705 gid.get_linear_id(), uacc, flag_refine, flag_derefine);
708 if (flag_refine && flag_derefine) {
709 flag_derefine =
false;
712 refine_acc[gid] = (flag_refine) ? 1 : 0;
713 derefine_acc[gid] = (flag_derefine) ? 1 : 0;
723 uacc.finalize_new(resulting_events, storage, id_patch, cur_p, pdat,
args...);
726 dd_refine_flags.add_obj(id_patch, std::move(refine_flags));
727 dd_derefine_flags.add_obj(id_patch, std::move(derefine_flags));
737template<
class Tvec,
class Tgr
idVec>
750 .get_refs_dir(Direction_::xp)
753 .get_refs_dir(Direction_::xm)
756 .get_refs_dir(Direction_::yp)
759 .get_refs_dir(Direction_::ym)
762 .get_refs_dir(Direction_::zp)
765 .get_refs_dir(Direction_::zm)
771 std::shared_ptr<sham::DeviceScheduler> dev_sched
772 = shamsys::instance::get_compute_scheduler_ptr();
776 for (
u32 pass = 0; pass < 100; pass++) {
778 changed_buf.set_val_at_idx(0, 0);
781 AMRGraphLinkiterator block_graph_xp
782 = block_graph_neighs_xp.get_read_access(depend_list);
783 AMRGraphLinkiterator block_graph_xm
784 = block_graph_neighs_xm.get_read_access(depend_list);
785 AMRGraphLinkiterator block_graph_yp
786 = block_graph_neighs_yp.get_read_access(depend_list);
787 AMRGraphLinkiterator block_graph_ym
788 = block_graph_neighs_ym.get_read_access(depend_list);
789 AMRGraphLinkiterator block_graph_zp
790 = block_graph_neighs_zp.get_read_access(depend_list);
791 AMRGraphLinkiterator block_graph_zm
792 = block_graph_neighs_zm.get_read_access(depend_list);
794 auto acc_amr_levels = buf_amr_block_levels.
get_read_access(depend_list);
795 auto acc_changed = changed_buf.get_write_access(depend_list);
799 auto e = q.
submit(depend_list, [&](sycl::handler &cgh) {
800 cgh.parallel_for(sycl::range<1>(obj_cnt), [=](sycl::item<1> gid) {
801 u32 block_id = gid.get_linear_id();
803 u32 cur_ref_flag = acc_ref_flags[block_id];
808 auto cur_block_level = acc_amr_levels[block_id];
810 auto check_2To1_ref = [&](
u32 nid) {
815 u32 neigh_ref_flag = acc_ref_flags[nid];
816 auto neigh_block_level = acc_amr_levels[nid];
818 auto cur_future = cur_block_level + (cur_ref_flag ? 1 : 0);
820 auto neigh_future = neigh_block_level + (neigh_ref_flag ? 1 : 0);
822 if (cur_ref_flag && (cur_future > neigh_future + 1)) {
824 if (!neigh_ref_flag) {
827 sycl::memory_order::relaxed,
828 sycl::memory_scope::system>
829 atomic_neigh_flag(acc_ref_flags[nid]);
830 atomic_neigh_flag.exchange(1);
834 sycl::memory_order::relaxed,
835 sycl::memory_scope::system>
836 atomic_changed(acc_changed[0]);
837 atomic_changed.exchange(1);
842 block_graph_xp.for_each_object_link(block_id, check_2To1_ref);
843 block_graph_xm.for_each_object_link(block_id, check_2To1_ref);
844 block_graph_yp.for_each_object_link(block_id, check_2To1_ref);
845 block_graph_ym.for_each_object_link(block_id, check_2To1_ref);
846 block_graph_zp.for_each_object_link(block_id, check_2To1_ref);
847 block_graph_zm.for_each_object_link(block_id, check_2To1_ref);
850 block_graph_neighs_xp.complete_event_state(e);
851 block_graph_neighs_xm.complete_event_state(e);
852 block_graph_neighs_yp.complete_event_state(e);
853 block_graph_neighs_ym.complete_event_state(e);
854 block_graph_neighs_zp.complete_event_state(e);
855 block_graph_neighs_zm.complete_event_state(e);
858 changed_buf.complete_event_state(e);
864 if (changed_buf.get_val_at_idx(0) == 0) {
865 logger::raw_ln(
"Refinement 2:1 balance converged in ", pass + 1,
" sweeps");
879 "AMRGrid",
"patch ", id_patch, dev_buf_ref.get_size(),
"marked for refinement + 2:1");
891template<
class Tvec,
class Tgr
idVec>
897 auto dev_sched = shamsys::instance::get_compute_scheduler_ptr();
910 .get_refs_dir(Direction_::xp)
913 .get_refs_dir(Direction_::xm)
916 .get_refs_dir(Direction_::yp)
919 .get_refs_dir(Direction_::ym)
922 .get_refs_dir(Direction_::zp)
925 .get_refs_dir(Direction_::zm)
938 " Count block's flag for derefinement [No geometry validity check and no 2:1 check] \t "
940 dev_buf_deref_0.get_size(),
950 auto acc_max = buf_cell_max.get_read_access(depends_list);
951 auto acc_amr_levels = buf_amr_block_levels.
get_read_access(depends_list);
954 auto acc_refine_flag = patch_refine_flag.
get_read_access(depends_list);
956 auto e = q.
submit(depends_list, [&](sycl::handler &cgh) {
957 cgh.parallel_for(sycl::range<1>(obj_cnt), [=](sycl::item<1> gid) {
958 u32 id = gid.get_linear_id();
960 std::array<BlockCoord, split_count> blocks;
961 bool do_merge =
true;
962 bool all_same_level =
true;
966 if (
id + split_count <= obj_cnt) {
967 bool all_want_to_merge =
true;
969 auto get_coord = [](
u32 i) -> std::array<u32, dim> {
970 constexpr u32 NsideBlockPow = 1;
971 constexpr u32 Nside = 1U << NsideBlockPow;
973 if constexpr (dim == 3) {
974 const u32 tmp = i >> NsideBlockPow;
977 return {(tmp) >> NsideBlockPow, (tmp) % Nside, i % Nside};
982 = [=](BlockCoord target_block) -> std::array<BlockCoord, split_count> {
983 std::array<BlockCoord, split_count> ret;
984 auto bmin = target_block.bmin;
985 auto bmax = target_block.bmax;
986 auto split = bmin + (bmax - bmin) / 2;
987 std::array<TgridVec, 3> szs = {bmin, split, bmax};
988 for (
u32 i = 0; i < split_count; i++) {
989 auto [lx, ly, lz] = get_coord(i);
991 ret[i].bmin = TgridVec{szs[lx].x(), szs[ly].y(), szs[lz].z()};
993 = TgridVec{szs[lx + 1].x(), szs[ly + 1].y(), szs[lz + 1].z()};
999 for (
u32 b_lid = 0; b_lid < split_count; b_lid++) {
1000 blocks[b_lid] = BlockCoord{acc_min[
id + b_lid], acc_max[
id + b_lid]};
1001 all_want_to_merge = all_want_to_merge && acc_merge_flag[
id + b_lid];
1003 = all_same_level && (acc_amr_levels[id] == acc_amr_levels[
id + b_lid]);
1006 BlockCoord merged = BlockCoord::get_merge(blocks);
1007 std::array<BlockCoord, split_count> splitted = get_split(merged);
1008 for (
u32 lid = 0; lid < split_count; lid++) {
1009 do_merge = do_merge && sham::equals(blocks[lid].bmin, splitted[lid].bmin)
1010 && sham::equals(blocks[lid].bmax, splitted[lid].bmax);
1013 do_merge = do_merge && all_want_to_merge && all_same_level;
1014 if (acc_refine_flag[
id] && do_merge) {
1021 acc_merge_flag[id] = do_merge;
1025 buf_cell_max.complete_event_state(e);
1035 " Count block's flag for derefinement [After geometry validity check and before 2:1 "
1038 buf_derefine_1.get_size(),
1047 std::shared_ptr<sham::DeviceScheduler> dev_sched
1048 = shamsys::instance::get_compute_scheduler_ptr();
1054 patch_derefine_flag.
copy_range(0, obj_cnt, patch_derefine_flag_old);
1059 for (
int it = 0; it < 100; it++) {
1060 changed_buf.set_val_at_idx(0, 0);
1064 AMRGraphLinkiterator block_graph_xp
1065 = block_graph_neighs_xp.get_read_access(depend_list);
1067 AMRGraphLinkiterator block_graph_xm
1068 = block_graph_neighs_xm.get_read_access(depend_list);
1069 AMRGraphLinkiterator block_graph_yp
1070 = block_graph_neighs_yp.get_read_access(depend_list);
1071 AMRGraphLinkiterator block_graph_ym
1072 = block_graph_neighs_ym.get_read_access(depend_list);
1073 AMRGraphLinkiterator block_graph_zp
1074 = block_graph_neighs_zp.get_read_access(depend_list);
1075 AMRGraphLinkiterator block_graph_zm
1076 = block_graph_neighs_zm.get_read_access(depend_list);
1078 auto acc_amr_levels = buf_amr_block_levels.
get_read_access(depend_list);
1080 auto acc_changed = changed_buf.get_write_access(depend_list);
1082 auto acc_deref_old = patch_derefine_flag_old.get_read_access(depend_list);
1083 auto acc_deref_new = patch_derefine_flag_new.get_write_access(depend_list);
1085 auto e_2to1 = q.
submit(depend_list, [&](sycl::handler &cgh) {
1086 cgh.parallel_for(sycl::range<1>(obj_cnt), [=](sycl::item<1> gid) {
1087 auto lid = gid.get_linear_id();
1089 auto old_flag = acc_deref_old[lid];
1090 auto new_flag = old_flag;
1092 auto check_2To1_der = [&](
u32 nid) {
1097 auto neigh_future = acc_amr_levels[nid] + (acc_ref_flag[nid] ? 1 : 0)
1098 - (acc_deref_old[nid] ? 1 : 0);
1100 auto my_future = acc_amr_levels[lid] - 1;
1102 if (neigh_future > my_future + 1) {
1110 for (
u32 i = 0; i < AMRBlock::block_size; i++) {
1111 block_graph_xp.for_each_object_link((lid + i), check_2To1_der);
1112 block_graph_xm.for_each_object_link((lid + i), check_2To1_der);
1113 block_graph_yp.for_each_object_link((lid + i), check_2To1_der);
1114 block_graph_ym.for_each_object_link((lid + i), check_2To1_der);
1115 block_graph_zp.for_each_object_link((lid + i), check_2To1_der);
1116 block_graph_zm.for_each_object_link((lid + i), check_2To1_der);
1119 if (old_flag != new_flag) {
1122 sycl::memory_order::relaxed,
1123 sycl::memory_scope::system>
1124 atomic_changed(acc_changed[0]);
1125 atomic_changed.exchange(1);
1129 acc_deref_new[lid] = new_flag;
1132 block_graph_neighs_xp.complete_event_state(e_2to1);
1133 block_graph_neighs_xm.complete_event_state(e_2to1);
1134 block_graph_neighs_yp.complete_event_state(e_2to1);
1135 block_graph_neighs_ym.complete_event_state(e_2to1);
1136 block_graph_neighs_zp.complete_event_state(e_2to1);
1137 block_graph_neighs_zm.complete_event_state(e_2to1);
1140 changed_buf.complete_event_state(e_2to1);
1142 patch_derefine_flag_old.complete_event_state(e_2to1);
1143 patch_derefine_flag_new.complete_event_state(e_2to1);
1146 std::swap(patch_derefine_flag_old, patch_derefine_flag_new);
1148 if (changed_buf.get_val_at_idx(0) == 0) {
1151 "Derefinement 2:1 balance converge in \t ", it + 1,
"\t sweeps \n\n");
1157 patch_derefine_flag_old.copy_range(0, obj_cnt, patch_derefine_flag);
1167 " Count block's flag for derefinement [After geometry validity check and after 2:1 "
1169 buf_derefine.get_size(),
1173 "AMRGrid",
"patch ", id_patch, buf_derefine.get_size(),
"marked for derefinement ");
1177template<
class Tvec,
class Tgr
idVec>
1178template<
class UserAcc>
1182 const AMRInterpMode amr_refine_interp_mode) {
1184 u64 sum_block_count = 0;
1186 bool new_cell_were_added =
false;
1188 auto dev_sched = shamsys::instance::get_compute_scheduler_ptr();
1193 dev_sched, dd_refine_flags.get(id_patch), old_obj_cnt);
1195 if (stream_compaction_result.get_size() > 0) {
1199 "Will refine \t", stream_compaction_result.get_size(),
" \t blocks \n\n");
1201 pdat.expand(
static_cast<u32>(stream_compaction_result.get_size()) * (split_count - 1));
1207 auto block_bound_high = buf_cell_max.get_write_access(depends_list);
1208 UserAcc uacc(depends_list, storage, id_patch, pdat, amr_refine_interp_mode);
1209 auto index_to_ref = stream_compaction_result.get_read_access(depends_list);
1212 auto e = q.
submit(depends_list, [&](sycl::handler &cgh) {
1213 u32 start_index_push = old_obj_cnt;
1215 constexpr u32 new_splits = split_count - 1;
1218 sycl::range<1>(stream_compaction_result.get_size()), [=](sycl::item<1> gid) {
1219 u32 tid = gid.get_linear_id();
1221 u32 idx_to_refine = index_to_ref[gid];
1224 BlockCoord cur_block{
1225 block_bound_low[idx_to_refine], block_bound_high[idx_to_refine]};
1227 std::array<BlockCoord, split_count> block_coords
1228 = BlockCoord::get_split(cur_block.bmin, cur_block.bmax);
1231 std::array<u32, split_count> blocks_ids;
1232 blocks_ids[0] = idx_to_refine;
1237 for (
u32 pid = 0; pid < new_splits; pid++) {
1238 blocks_ids[pid + 1] = start_index_push + tid * new_splits + pid;
1244 for (
u32 pid = 0; pid < split_count; pid++) {
1245 block_bound_low[blocks_ids[pid]] = block_coords[pid].bmin;
1246 block_bound_high[blocks_ids[pid]] = block_coords[pid].bmax;
1250 uacc.apply_refine_new(
1251 idx_to_refine, cur_block, blocks_ids, block_coords, uacc);
1258 buf_cell_max.complete_event_state(resulting_events);
1259 stream_compaction_result.complete_event_state(e);
1260 uacc.finalize_new(resulting_events, storage, id_patch, pdat, amr_refine_interp_mode);
1263 shamlog_debug_ln(
"AMRGrid",
"patch ", id_patch,
"new block count = ", pdat.
get_obj_cnt());
1265 new_cell_were_added = new_cell_were_added || (stream_compaction_result.get_size() > 0);
1270 return new_cell_were_added;
1273template<
class Tvec,
class Tgr
idVec>
1274template<
class UserAcc>
1278 const AMRInterpMode amr_refine_interp_mode) {
1280 using namespace shamrock::patch;
1282 bool cell_were_removed =
false;
1285 auto dev_sched = shamsys::instance::get_compute_scheduler_ptr();
1289 u32 old_obj_cnt_before_refinement = dd_derefine_flags.get(id_patch).get_size();
1291 dev_sched, dd_derefine_flags.get(id_patch), old_obj_cnt_before_refinement);
1292 if (stream_compact_results.get_size() > 0) {
1294 sycl::buffer<u32> keep_block_flag
1303 auto block_bound_high = buf_cell_max.get_write_access(depends_list);
1304 UserAcc uacc(depends_list, storage, id_patch, pdat, amr_refine_interp_mode);
1305 auto index_to_deref = stream_compact_results.get_read_access(depends_list);
1308 auto e = q.
submit(depends_list, [&](sycl::handler &cgh) {
1309 sycl::accessor flag_keep{keep_block_flag, cgh, sycl::read_write};
1311 sycl::range<1>(stream_compact_results.get_size()), [=](sycl::item<1> gid) {
1312 u32 tid = gid.get_linear_id();
1314 u32 idx_to_derefine = index_to_deref[gid];
1317 std::array<u32, split_count> old_indexes;
1319 for (u32 pid = 0; pid < split_count; pid++) {
1320 old_indexes[pid] = idx_to_derefine + pid;
1324 std::array<BlockCoord, split_count> block_coords;
1326 for (
u32 pid = 0; pid < split_count; pid++) {
1327 block_coords[pid] = BlockCoord{
1328 block_bound_low[old_indexes[pid]],
1329 block_bound_high[old_indexes[pid]]};
1333 BlockCoord merged_block_coord = BlockCoord::get_merge(block_coords);
1336 block_bound_low[idx_to_derefine] = merged_block_coord.bmin;
1337 block_bound_high[idx_to_derefine] = merged_block_coord.bmax;
1341 for (
u32 pid = 1; pid < split_count; pid++) {
1342 flag_keep[idx_to_derefine + pid] = 0;
1347 uacc.apply_derefine_new(
1348 old_indexes, block_coords, idx_to_derefine, merged_block_coord, uacc);
1355 buf_cell_max.complete_event_state(resulting_events);
1356 uacc.finalize_new(resulting_events, storage, id_patch, pdat, amr_refine_interp_mode);
1358 stream_compact_results.complete_event_state(resulting_events);
1368 "derefine block count = ",
1370 "new block count = ",
1374 throw std::runtime_error(
"opt buf must contain something at this point");
1381 cell_were_removed = cell_were_removed || stream_compact_results.get_size() > 0;
1385 return cell_were_removed;
1388template<
class Tvec,
class Tgr
idVec>
1389template<
class UserAccCrit,
class UserAccSplit,
class UserAccMerge>
1394 AMRSortBlocks block_sorter(context, solver_config, storage);
1395 block_sorter.reorder_amr_blocks();
1401 gen_refine_block_changes_new<UserAccCrit>(dd_refine_list, dd_derefine_list);
1405 internal_refine_grid_new<UserAccSplit>(std::move(dd_refine_list), amr_refine_interp_mode);
1412 internal_derefine_grid_new<UserAccMerge>(std::move(dd_derefine_list), amr_refine_interp_mode);
1415template<
class Tvec,
class Tgr
idVec>
1419 class RefineCritBlock {
1421 const TgridVec *block_low_bound;
1422 const TgridVec *block_high_bound;
1423 const Tscal *block_density_field;
1425 Tscal one_over_Nside = 1. / AMRBlock::Nside;
1438 : dxfact(dxfact), wanted_mass(wanted_mass) {
1440 block_low_bound = pdat.get_field<TgridVec>(0).get_buf().get_read_access(depends_list);
1441 block_high_bound = pdat.get_field<TgridVec>(1).get_buf().get_read_access(depends_list);
1442 block_density_field = pdat.get_field<Tscal>(pdat.pdl().get_field_idx<Tscal>(
"rho"))
1444 .get_read_access(depends_list);
1454 Tscal wanted_mass) {
1456 pdat.get_field<TgridVec>(0).get_buf().complete_event_state(resulting_events);
1457 pdat.get_field<TgridVec>(1).get_buf().complete_event_state(resulting_events);
1458 pdat.get_field<Tscal>(pdat.pdl().get_field_idx<Tscal>(
"rho"))
1460 .complete_event_state(resulting_events);
1463 void refine_criterion_new(
1464 u32 block_id, RefineCritBlock acc,
bool &should_refine,
bool &should_derefine)
const {
1466 TgridVec low_bound = acc.block_low_bound[block_id];
1467 TgridVec high_bound = acc.block_high_bound[block_id];
1469 Tvec lower_flt = low_bound.template convert<Tscal>() * dxfact;
1470 Tvec upper_flt = high_bound.template convert<Tscal>() * dxfact;
1472 Tvec block_cell_size = (upper_flt - lower_flt) * one_over_Nside;
1475 for (
u32 i = 0; i < AMRBlock::block_size; i++) {
1476 sum_mass += acc.block_density_field[i + block_id * AMRBlock::block_size];
1478 sum_mass *= block_cell_size.x() * block_cell_size.y() * block_cell_size.z();
1480 if (sum_mass > wanted_mass * 8) {
1481 should_refine =
true;
1482 should_derefine =
false;
1483 }
else if (sum_mass < wanted_mass) {
1484 should_refine =
false;
1485 should_derefine =
true;
1487 should_refine =
false;
1488 should_derefine =
false;
1491 should_refine = should_refine && (high_bound.x() - low_bound.x() > AMRBlock::Nside);
1492 should_refine = should_refine && (high_bound.y() - low_bound.y() > AMRBlock::Nside);
1493 should_refine = should_refine && (high_bound.z() - low_bound.z() > AMRBlock::Nside);
1497 class RefineCellAccessor {
1505 const f64 *rho_old_snap;
1506 const f64_3 *rho_vel_old_snap;
1507 const f64 *rhoE_old_snap;
1509 AMRInterpMode amr_ref_interp_mode;
1512 AMRGraphLinkiterator cell_graph_xp;
1513 AMRGraphLinkiterator cell_graph_xm;
1514 AMRGraphLinkiterator cell_graph_yp;
1515 AMRGraphLinkiterator cell_graph_ym;
1516 AMRGraphLinkiterator cell_graph_zp;
1517 AMRGraphLinkiterator cell_graph_zm;
1524 AMRInterpMode _amr_ref_interp_mode)
1527 .get_refs_dir(Direction::xp)
1530 .get_read_access(depends_list)),
1533 .get_refs_dir(Direction::xm)
1536 .get_read_access(depends_list)),
1539 .get_refs_dir(Direction::yp)
1542 .get_read_access(depends_list)),
1545 .get_refs_dir(Direction::ym)
1548 .get_read_access(depends_list)),
1551 .get_refs_dir(Direction::zp)
1554 .get_read_access(depends_list)),
1557 .get_refs_dir(Direction::zm)
1560 .get_read_access(depends_list)),
1561 amr_ref_interp_mode(_amr_ref_interp_mode)
1570 .get_read_access(depends_list);
1574 .get_read_access(depends_list);
1578 .get_read_access(depends_list);
1581 rho = pdat.get_field<
f64>(2).get_buf().get_write_access(depends_list);
1582 rho_vel = pdat.get_field<f64_3>(3).get_buf().get_write_access(depends_list);
1583 rhoE = pdat.get_field<
f64>(4).get_buf().get_write_access(depends_list);
1586 .get_write_access(depends_list);
1594 AMRInterpMode amr_ref_interp_mode) {
1595 pdat.get_field<
f64>(2).get_buf().complete_event_state(resulting_events);
1596 pdat.get_field<f64_3>(3).get_buf().complete_event_state(resulting_events);
1597 pdat.get_field<
f64>(4).get_buf().complete_event_state(resulting_events);
1600 .get_refs_dir(Direction_::xp)
1603 .complete_event_state(resulting_events);
1605 .get_refs_dir(Direction_::xm)
1608 .complete_event_state(resulting_events);
1610 .get_refs_dir(Direction_::yp)
1613 .complete_event_state(resulting_events);
1615 .get_refs_dir(Direction_::ym)
1618 .complete_event_state(resulting_events);
1620 .get_refs_dir(Direction_::zp)
1623 .complete_event_state(resulting_events);
1625 .get_refs_dir(Direction_::zm)
1628 .complete_event_state(resulting_events);
1632 .complete_event_state(resulting_events);
1638 .complete_event_state(resulting_events);
1642 .complete_event_state(resulting_events);
1646 .complete_event_state(resulting_events);
1649 void apply_refine_new(
1651 BlockCoord cur_coords,
1652 std::array<u32, 8> new_blocks,
1653 std::array<BlockCoord, 8> new_block_coords,
1654 RefineCellAccessor acc)
const {
1656 auto get_coord_ref = [](
u32 i) -> std::array<u32, dim> {
1657 constexpr u32 NsideBlockPow = 1;
1658 constexpr u32 Nside = 1U << NsideBlockPow;
1660 if constexpr (dim == 3) {
1661 const u32 tmp = i >> NsideBlockPow;
1662 return {i % Nside, (tmp) % Nside, (tmp) >> NsideBlockPow};
1666 auto get_index_block = [](std::array<u32, dim> coord) ->
u32 {
1667 constexpr u32 NsideBlockPow = 1;
1668 constexpr u32 Nside = 1U << NsideBlockPow;
1670 if constexpr (dim == 3) {
1671 return coord[0] + Nside * coord[1] + Nside * Nside * coord[2];
1675 auto get_gid_write = [&](std::array<u32, dim> &glid) ->
u32 {
1678 std::array<u32, dim> bid
1679 = {glid[0] >> AMRBlock::NsideBlockPow,
1680 glid[1] >> AMRBlock::NsideBlockPow,
1681 glid[2] >> AMRBlock::NsideBlockPow};
1684 auto new_glob_id = new_blocks[get_index_block(bid)] * AMRBlock::block_size;
1689 + AMRBlock::get_index(
1690 {glid[0] % AMRBlock::Nside,
1691 glid[1] % AMRBlock::Nside,
1692 glid[2] % AMRBlock::Nside});
1695 for (
u32 loc_id = 0; loc_id < AMRBlock::block_size; loc_id++) {
1697 auto [lx, ly, lz] = get_coord_ref(loc_id);
1698 u32 old_cell_idx = cur_idx * AMRBlock::block_size + loc_id;
1701 Tscal delta_cell = cell_sizes[cur_idx];
1702 Tscal c_offset = delta_cell * 0.25;
1703 std::array<f64_3, AMRBlock::block_size> child_center_offsets;
1704 child_center_offsets[0] = {-c_offset, -c_offset, -c_offset};
1705 child_center_offsets[1] = {c_offset, -c_offset, -c_offset};
1706 child_center_offsets[2] = {-c_offset, c_offset, -c_offset};
1707 child_center_offsets[3] = {c_offset, c_offset, -c_offset};
1708 child_center_offsets[4] = {-c_offset, -c_offset, c_offset};
1709 child_center_offsets[5] = {c_offset, -c_offset, c_offset};
1710 child_center_offsets[6] = {-c_offset, c_offset, c_offset};
1711 child_center_offsets[7] = {c_offset, c_offset, c_offset};
1713 auto cons_var_slopes = get_3d_grad_cons<Tvec, Minmod>(
1715 AMRBlock::block_size,
1724 return acc.rho_old_snap[id];
1727 return acc.rho_vel_old_snap[id];
1730 return acc.rhoE_old_snap[id];
1733 std::array<f64, AMRBlock::block_size> _rho_block;
1734 std::array<f64_3, AMRBlock::block_size> _rho_vel_block;
1735 std::array<f64, AMRBlock::block_size> _rhoE_block;
1737 int mul_second_order
1738 = (acc.amr_ref_interp_mode == AMRInterpMode::SECOND_ORDER) ? 1 : 0;
1740 bool do_second_order =
true;
1742 for (
u32 subdiv_lid = 0; subdiv_lid < 8; subdiv_lid++) {
1744 = child_center_offsets[subdiv_lid][0] * cons_var_slopes[0]
1745 + child_center_offsets[subdiv_lid][1] * cons_var_slopes[1]
1746 + child_center_offsets[subdiv_lid][2] * cons_var_slopes[2];
1748 _rho_block[subdiv_lid]
1749 = acc.rho_old_snap[old_cell_idx] + cons_var_interp.rho * mul_second_order;
1750 _rho_vel_block[subdiv_lid] = acc.rho_vel_old_snap[old_cell_idx]
1751 + cons_var_interp.rhovel * mul_second_order;
1752 _rhoE_block[subdiv_lid]
1753 = acc.rhoE_old_snap[old_cell_idx] + cons_var_interp.rhoe * mul_second_order;
1756 = _rhoE_block[subdiv_lid]
1757 - 0.5 * sham::dot(_rho_vel_block[subdiv_lid], _rho_vel_block[subdiv_lid])
1758 / (_rho_block[subdiv_lid]);
1760 = do_second_order && (_rho_block[subdiv_lid] > 0.0) && (e_int > 0.0);
1763 for (
u32 subdiv_lid = 0; subdiv_lid < 8; subdiv_lid++) {
1765 auto [sx, sy, sz] = get_coord_ref(subdiv_lid);
1767 std::array<u32, 3> glid = {lx * 2 + sx, ly * 2 + sy, lz * 2 + sz};
1769 u32 new_cell_idx = get_gid_write(glid);
1771 acc.rho[new_cell_idx] = (do_second_order) ? _rho_block[subdiv_lid]
1772 : acc.rho_old_snap[old_cell_idx];
1773 acc.rho_vel[new_cell_idx] = (do_second_order)
1774 ? _rho_vel_block[subdiv_lid]
1775 : acc.rho_vel_old_snap[old_cell_idx];
1776 acc.rhoE[new_cell_idx] = (do_second_order) ? _rhoE_block[subdiv_lid]
1777 : acc.rhoE_old_snap[old_cell_idx];
1782 void apply_derefine_new(
1783 std::array<u32, 8> old_blocks,
1784 std::array<BlockCoord, 8> old_coords,
1786 BlockCoord new_coord,
1788 RefineCellAccessor acc)
const {
1790 std::array<f64, AMRBlock::block_size> rho_block;
1791 std::array<f64_3, AMRBlock::block_size> rho_vel_block;
1792 std::array<f64, AMRBlock::block_size> rhoE_block;
1794 for (
u32 cell_id = 0; cell_id < AMRBlock::block_size; cell_id++) {
1795 rho_block[cell_id] = {};
1796 rho_vel_block[cell_id] = {};
1797 rhoE_block[cell_id] = {};
1801 for (
u32 pid = 0; pid < 8; pid++) {
1802 auto rho_pid = rho_block[pid];
1803 auto rho_vel_pid = rho_vel_block[pid];
1804 auto rhoe_pid = rhoE_block[pid];
1806 for (
u32 cell_id = 0; cell_id < AMRBlock::block_size; cell_id++) {
1807 rho_pid += acc.rho[old_blocks[pid] * AMRBlock::block_size + cell_id];
1808 rho_vel_pid += acc.rho_vel[old_blocks[pid] * AMRBlock::block_size + cell_id];
1809 rhoe_pid += acc.rhoE[old_blocks[pid] * AMRBlock::block_size + cell_id];
1811 rho_block[pid] = rho_pid * (1. / 8.);
1812 rho_vel_block[pid] = rho_vel_pid * (1. / 8.);
1813 rhoE_block[pid] = rhoe_pid * (1. / 8.);
1816 for (
u32 cell_id = 0; cell_id < AMRBlock::block_size; cell_id++) {
1817 u32 newcell_idx = new_cell * AMRBlock::block_size + cell_id;
1818 acc.rho[newcell_idx] = rho_block[cell_id];
1819 acc.rho_vel[newcell_idx] = rho_vel_block[cell_id];
1820 acc.rhoE[newcell_idx] = rhoE_block[cell_id];
1828 class RefineCritPseudoGradientAccessor {
1830 Tscal one_over_Nside = 1. / AMRBlock::Nside;
1831 const TgridVec *block_low_bound;
1832 const TgridVec *block_high_bound;
1833 const Tscal *block_rho;
1834 const f64 *block_pressure;
1835 const f64_3 *block_velocity;
1837 const Tscal *rho_cons;
1840 u32 nblock_per_patch;
1842 AMRGraphLinkiterator cell_graph_xp;
1843 AMRGraphLinkiterator cell_graph_xm;
1844 AMRGraphLinkiterator cell_graph_yp;
1845 AMRGraphLinkiterator cell_graph_ym;
1846 AMRGraphLinkiterator cell_graph_zp;
1847 AMRGraphLinkiterator cell_graph_zm;
1849 RefineCritPseudoGradientAccessor(
1857 : error_min(err_min), error_max(err_max),
1860 .get_refs_dir(Direction_::xp)
1863 .get_read_access(depends_list)),
1866 .get_refs_dir(Direction_::xm)
1869 .get_read_access(depends_list)),
1872 .get_refs_dir(Direction_::yp)
1875 .get_read_access(depends_list)),
1878 .get_refs_dir(Direction_::ym)
1881 .get_read_access(depends_list)),
1884 .get_refs_dir(Direction_::zp)
1887 .get_read_access(depends_list)),
1890 .get_refs_dir(Direction_::zm)
1893 .get_read_access(depends_list))
1896 block_low_bound = pdat.get_field<TgridVec>(0).get_buf().get_read_access(depends_list);
1897 block_high_bound = pdat.get_field<TgridVec>(1).get_buf().get_read_access(depends_list);
1898 rho_cons = pdat.get_field<Tscal>(pdat.pdl().get_field_idx<Tscal>(
"rho"))
1900 .get_read_access(depends_list);
1906 .get_read_access(depends_list);
1909 .get_read_access(depends_list);
1912 .get_read_access(depends_list);
1924 pdat.get_field<i64_3>(0).get_buf().complete_event_state(resulting_events);
1925 pdat.get_field<i64_3>(1).get_buf().complete_event_state(resulting_events);
1926 pdat.get_field<Tscal>(pdat.pdl().get_field_idx<Tscal>(
"rho"))
1928 .complete_event_state(resulting_events);
1931 .get_refs_dir(Direction_::xp)
1934 .complete_event_state(resulting_events);
1937 .get_refs_dir(Direction_::xm)
1940 .complete_event_state(resulting_events);
1943 .get_refs_dir(Direction_::yp)
1946 .complete_event_state(resulting_events);
1948 .get_refs_dir(Direction_::ym)
1951 .complete_event_state(resulting_events);
1953 .get_refs_dir(Direction_::zp)
1956 .complete_event_state(resulting_events);
1958 .get_refs_dir(Direction_::zm)
1961 .complete_event_state(resulting_events);
1965 .complete_event_state(resulting_events);
1969 .complete_event_state(resulting_events);
1973 .complete_event_state(resulting_events);
1976 void refine_criterion_new(
1978 RefineCritPseudoGradientAccessor acc,
1979 bool &should_refine,
1980 bool &should_derefine)
const {
1981 TgridVec low_bound = acc.block_low_bound[block_id];
1982 TgridVec high_bound = acc.block_high_bound[block_id];
2001 Tscal block_rho_slope = shambase::VectorProperties<Tscal>::get_zero();
2021 Tscal block_press_grad = shambase::VectorProperties<Tscal>::get_zero();
2022 for (
u32 i = 0; i < AMRBlock::block_size; i++) {
2023 block_press_grad = sham::details::g_sycl_max(
2025 get_pseudo_grad<Tscal, Tvec>(
2026 i + block_id * AMRBlock::block_size,
2034 return block_pressure[id];
2038 Tscal error = sham::details::g_sycl_max(
2039 block_press_grad, sham::details::g_sycl_max(block_rho_slope, 0.0));
2041 should_refine =
false;
2042 should_derefine =
false;
2043 if (error > error_max) {
2044 should_refine =
true;
2045 }
else if (error < (error_min * error_max)) {
2046 should_derefine =
true;
2049 should_refine = should_refine && (high_bound.x() - low_bound.x() > AMRBlock::Nside);
2050 should_refine = should_refine && (high_bound.y() - low_bound.y() > AMRBlock::Nside);
2051 should_refine = should_refine && (high_bound.z() - low_bound.z() > AMRBlock::Nside);
2058 class RefineCritShearAccessor {
2060 Tscal one_over_Nside = 1. / AMRBlock::Nside;
2061 const TgridVec *block_low_bound;
2062 const TgridVec *block_high_bound;
2063 const Tscal *block_rho;
2064 const f64 *block_pressure;
2065 const f64_3 *block_velocity;
2071 AMRGraphLinkiterator cell_graph_xp;
2072 AMRGraphLinkiterator cell_graph_xm;
2073 AMRGraphLinkiterator cell_graph_yp;
2074 AMRGraphLinkiterator cell_graph_ym;
2075 AMRGraphLinkiterator cell_graph_zp;
2076 AMRGraphLinkiterator cell_graph_zm;
2078 RefineCritShearAccessor(
2087 : threshold(threshold), gamma(gamma), dxfact(dxfact),
2090 .get_refs_dir(Direction_::xp)
2093 .get_read_access(depends_list)),
2096 .get_refs_dir(Direction_::xm)
2099 .get_read_access(depends_list)),
2102 .get_refs_dir(Direction_::yp)
2105 .get_read_access(depends_list)),
2108 .get_refs_dir(Direction_::ym)
2111 .get_read_access(depends_list)),
2114 .get_refs_dir(Direction_::zp)
2117 .get_read_access(depends_list)),
2120 .get_refs_dir(Direction_::zm)
2123 .get_read_access(depends_list))
2126 block_low_bound = pdat.get_field<TgridVec>(0).get_buf().get_read_access(depends_list);
2127 block_high_bound = pdat.get_field<TgridVec>(1).get_buf().get_read_access(depends_list);
2131 .get_read_access(depends_list);
2134 .get_read_access(depends_list);
2137 .get_read_access(depends_list);
2150 pdat.get_field<i64_3>(0).get_buf().complete_event_state(resulting_events);
2151 pdat.get_field<i64_3>(1).get_buf().complete_event_state(resulting_events);
2154 .get_refs_dir(Direction_::xp)
2157 .complete_event_state(resulting_events);
2160 .get_refs_dir(Direction_::xm)
2163 .complete_event_state(resulting_events);
2166 .get_refs_dir(Direction_::yp)
2169 .complete_event_state(resulting_events);
2171 .get_refs_dir(Direction_::ym)
2174 .complete_event_state(resulting_events);
2176 .get_refs_dir(Direction_::zp)
2179 .complete_event_state(resulting_events);
2181 .get_refs_dir(Direction_::zm)
2184 .complete_event_state(resulting_events);
2188 .complete_event_state(resulting_events);
2192 .complete_event_state(resulting_events);
2196 .complete_event_state(resulting_events);
2199 void refine_criterion_new(
2201 RefineCritShearAccessor acc,
2202 bool &should_refine,
2203 bool &should_derefine)
const {
2204 TgridVec low_bound = acc.block_low_bound[block_id];
2205 TgridVec high_bound = acc.block_high_bound[block_id];
2207 Tvec lower_flt = low_bound.template convert<Tscal>() * dxfact;
2208 Tvec upper_flt = high_bound.template convert<Tscal>() * dxfact;
2210 Tvec block_cell_size = (upper_flt - lower_flt) * one_over_Nside;
2212 Tscal block_normalized_shear = shambase::VectorProperties<Tscal>::get_zero();
2213 for (
u32 i = 0; i < AMRBlock::block_size; i++) {
2214 auto cell_id = i + block_id * AMRBlock::block_size;
2215 auto cs = sycl::sqrt(gamma * acc.block_pressure[cell_id] / acc.block_rho[cell_id]);
2216 block_normalized_shear = sham::details::g_sycl_max(
2217 block_normalized_shear,
2218 normalized_shear<Tvec>(
2230 return acc.block_velocity[id];
2233 should_refine =
false;
2234 should_derefine =
false;
2235 if (block_normalized_shear > threshold * threshold) {
2236 should_refine =
true;
2237 }
else if (block_normalized_shear < 0.25 * threshold * threshold) {
2238 should_derefine =
true;
2241 should_refine = should_refine && (high_bound.x() - low_bound.x() > AMRBlock::Nside);
2242 should_refine = should_refine && (high_bound.y() - low_bound.y() > AMRBlock::Nside);
2243 should_refine = should_refine && (high_bound.z() - low_bound.z() > AMRBlock::Nside);
2250 class RefineCellAccessorAutogravity {
2262 AMRGraphLinkiterator cell_graph_xp;
2263 AMRGraphLinkiterator cell_graph_xm;
2264 AMRGraphLinkiterator cell_graph_yp;
2265 AMRGraphLinkiterator cell_graph_ym;
2266 AMRGraphLinkiterator cell_graph_zp;
2267 AMRGraphLinkiterator cell_graph_zm;
2269 RefineCellAccessorAutogravity(
2276 .get_refs_dir(Direction::xp)
2279 .get_read_access(depends_list)),
2282 .get_refs_dir(Direction::xm)
2285 .get_read_access(depends_list)),
2288 .get_refs_dir(Direction::yp)
2291 .get_read_access(depends_list)),
2294 .get_refs_dir(Direction::ym)
2297 .get_read_access(depends_list)),
2300 .get_refs_dir(Direction::zp)
2303 .get_read_access(depends_list)),
2306 .get_refs_dir(Direction::zm)
2309 .get_read_access(depends_list))
2313 rho = pdat.get_field<
f64>(2).get_buf().get_write_access(depends_list);
2314 rho_vel = pdat.get_field<f64_3>(3).get_buf().get_write_access(depends_list);
2315 rhoE = pdat.get_field<
f64>(4).get_buf().get_write_access(depends_list);
2316 phi_old = pdat.get_field<
f64>(pdat.pdl().get_field_idx<Tscal>(
"phi_old"))
2318 .get_write_access(depends_list);
2319 phi_new = pdat.get_field<
f64>(pdat.pdl().get_field_idx<Tscal>(
"phi"))
2321 .get_write_access(depends_list);
2329 pdat.get_field<
f64>(2).get_buf().complete_event_state(resulting_events);
2330 pdat.get_field<f64_3>(3).get_buf().complete_event_state(resulting_events);
2331 pdat.get_field<
f64>(4).get_buf().complete_event_state(resulting_events);
2332 pdat.get_field<
f64>(pdat.pdl().get_field_idx<Tscal>(
"phi_old"))
2334 .complete_event_state(resulting_events);
2335 pdat.get_field<
f64>(pdat.pdl().get_field_idx<Tscal>(
"phi"))
2337 .complete_event_state(resulting_events);
2340 .get_refs_dir(Direction_::xp)
2343 .complete_event_state(resulting_events);
2345 .get_refs_dir(Direction_::xm)
2348 .complete_event_state(resulting_events);
2350 .get_refs_dir(Direction_::yp)
2353 .complete_event_state(resulting_events);
2355 .get_refs_dir(Direction_::ym)
2358 .complete_event_state(resulting_events);
2360 .get_refs_dir(Direction_::zp)
2363 .complete_event_state(resulting_events);
2365 .get_refs_dir(Direction_::zm)
2368 .complete_event_state(resulting_events);
2371 void apply_refine_new(
2373 BlockCoord cur_coords,
2374 std::array<u32, 8> new_blocks,
2375 std::array<BlockCoord, 8> new_block_coords,
2376 RefineCellAccessorAutogravity acc)
const {
2378 auto get_coord_ref = [](
u32 i) -> std::array<u32, dim> {
2379 constexpr u32 NsideBlockPow = 1;
2380 constexpr u32 Nside = 1U << NsideBlockPow;
2382 if constexpr (dim == 3) {
2383 const u32 tmp = i >> NsideBlockPow;
2384 return {i % Nside, (tmp) % Nside, (tmp) >> NsideBlockPow};
2388 auto get_index_block = [](std::array<u32, dim> coord) ->
u32 {
2389 constexpr u32 NsideBlockPow = 1;
2390 constexpr u32 Nside = 1U << NsideBlockPow;
2392 if constexpr (dim == 3) {
2393 return coord[0] + Nside * coord[1] + Nside * Nside * coord[2];
2397 auto get_gid_write = [&](std::array<u32, dim> &glid) ->
u32 {
2400 std::array<u32, dim> bid
2401 = {glid[0] >> AMRBlock::NsideBlockPow,
2402 glid[1] >> AMRBlock::NsideBlockPow,
2403 glid[2] >> AMRBlock::NsideBlockPow};
2406 auto new_glob_id = new_blocks[get_index_block(bid)] * AMRBlock::block_size;
2411 + AMRBlock::get_index(
2412 {glid[0] % AMRBlock::Nside,
2413 glid[1] % AMRBlock::Nside,
2414 glid[2] % AMRBlock::Nside});
2417 std::array<f64, AMRBlock::block_size> old_rho_block;
2418 std::array<f64_3, AMRBlock::block_size> old_rho_vel_block;
2419 std::array<f64, AMRBlock::block_size> old_rhoE_block;
2420 std::array<f64, AMRBlock::block_size> old_phi_old_block;
2421 std::array<f64, AMRBlock::block_size> old_phi_new_block;
2424 for (
u32 loc_id = 0; loc_id < AMRBlock::block_size; loc_id++) {
2426 auto [lx, ly, lz] = get_coord_ref(loc_id);
2427 u32 old_cell_idx = cur_idx * AMRBlock::block_size + loc_id;
2428 old_rho_block[loc_id] = acc.rho[old_cell_idx];
2429 old_rho_vel_block[loc_id] = acc.rho_vel[old_cell_idx];
2430 old_rhoE_block[loc_id] = acc.rhoE[old_cell_idx];
2431 old_phi_old_block[loc_id] = acc.phi_old[old_cell_idx];
2432 old_phi_new_block[loc_id] = acc.phi_new[old_cell_idx];
2435 for (
u32 loc_id = 0; loc_id < AMRBlock::block_size; loc_id++) {
2437 auto [lx, ly, lz] = get_coord_ref(loc_id);
2438 u32 old_cell_idx = cur_idx * AMRBlock::block_size + loc_id;
2472 Tscal rho_block = old_rho_block[loc_id];
2473 Tvec rho_vel_block = old_rho_vel_block[loc_id];
2474 Tscal rhoE_block = old_rhoE_block[loc_id];
2475 Tscal phi_old_block = old_phi_old_block[loc_id];
2476 Tscal phi_new_block = old_phi_new_block[loc_id];
2478 for (
u32 subdiv_lid = 0; subdiv_lid < 8; subdiv_lid++) {
2480 auto [sx, sy, sz] = get_coord_ref(subdiv_lid);
2482 std::array<u32, 3> glid = {lx * 2 + sx, ly * 2 + sy, lz * 2 + sz};
2484 u32 new_cell_idx = get_gid_write(glid);
2495 acc.rho[new_cell_idx] = rho_block;
2496 acc.rho_vel[new_cell_idx] = rho_vel_block;
2497 acc.rhoE[new_cell_idx] = rhoE_block;
2498 acc.phi_old[new_cell_idx] = phi_old_block;
2499 acc.phi_new[new_cell_idx] = phi_new_block;
2504 void apply_derefine_new(
2505 std::array<u32, 8> old_blocks,
2506 std::array<BlockCoord, 8> old_coords,
2508 BlockCoord new_coord,
2510 RefineCellAccessorAutogravity acc)
const {
2512 std::array<f64, AMRBlock::block_size> rho_block;
2513 std::array<f64_3, AMRBlock::block_size> rho_vel_block;
2514 std::array<f64, AMRBlock::block_size> rhoE_block;
2515 std::array<f64, AMRBlock::block_size> phi_old_block;
2516 std::array<f64, AMRBlock::block_size> phi_new_block;
2518 for (
u32 cell_id = 0; cell_id < AMRBlock::block_size; cell_id++) {
2519 rho_block[cell_id] = {};
2520 rho_vel_block[cell_id] = {};
2521 rhoE_block[cell_id] = {};
2522 phi_old_block[cell_id] = {};
2523 phi_new_block[cell_id] = {};
2527 for (
u32 pid = 0; pid < 8; pid++) {
2528 auto rho_pid = rho_block[pid];
2529 auto rho_vel_pid = rho_vel_block[pid];
2530 auto rhoe_pid = rhoE_block[pid];
2531 auto phi_old_pid = phi_old_block[pid];
2532 auto phi_new_pid = phi_new_block[pid];
2534 for (
u32 cell_id = 0; cell_id < AMRBlock::block_size; cell_id++) {
2535 rho_pid += acc.rho[old_blocks[pid] * AMRBlock::block_size + cell_id];
2536 rho_vel_pid += acc.rho_vel[old_blocks[pid] * AMRBlock::block_size + cell_id];
2537 rhoe_pid += acc.rhoE[old_blocks[pid] * AMRBlock::block_size + cell_id];
2538 phi_old_pid += acc.phi_old[old_blocks[pid] * AMRBlock::block_size + cell_id];
2539 phi_new_pid += acc.phi_new[old_blocks[pid] * AMRBlock::block_size + cell_id];
2541 rho_block[pid] = rho_pid * (1. / 8.);
2542 rho_vel_block[pid] = rho_vel_pid * (1. / 8.);
2543 rhoE_block[pid] = rhoe_pid * (1. / 8.);
2548 for (
u32 cell_id = 0; cell_id < AMRBlock::block_size; cell_id++) {
2549 u32 newcell_idx = new_cell * AMRBlock::block_size + cell_id;
2550 acc.rho[newcell_idx] = rho_block[cell_id];
2551 acc.rho_vel[newcell_idx] = rho_vel_block[cell_id];
2552 acc.rhoE[newcell_idx] = rhoE_block[cell_id];
2566 bool has_cell_order_changed =
false;
2572 if (AMRmode_None *cfg = std::get_if<AMRmode_None>(&solver_config.amr_mode.config)) {
2575 if (AMRmode_DensityBased *cfg
2576 = std::get_if<AMRmode_DensityBased>(&solver_config.amr_mode.config)) {
2578 Tscal dxfact(solver_config.grid_coord_to_pos_fact);
2579 gen_refine_block_changes_new<RefineCritBlock>(
2580 refine_list, derefine_list, dxfact, cfg->crit_mass);
2584 AMRmode_PseudoGradientBased *cfg
2585 = std::get_if<AMRmode_PseudoGradientBased>(&solver_config.amr_mode.config)) {
2587 gen_refine_block_changes_new<RefineCritPseudoGradientAccessor>(
2588 refine_list, derefine_list, cfg->error_min, cfg->error_max);
2592 AMRmode_ShearBased *cfg
2593 = std::get_if<AMRmode_ShearBased>(&solver_config.amr_mode.config)) {
2594 Tscal dxfact(solver_config.grid_coord_to_pos_fact);
2595 Tscal gamma(solver_config.eos_gamma);
2597 gen_refine_block_changes_new<RefineCritShearAccessor>(
2598 refine_list, derefine_list, cfg->threshold, gamma, dxfact);
2602 enforce_two_to_one_refinement_new(std::move(refine_list));
2604 enforce_two_to_one_derefinement_new(std::move(derefine_list), std::move(refine_list));
2607 const AMRInterpMode amr_ref_interp_mode = solver_config.amr_interp_mode;
2608 bool change_refine = internal_refine_grid_new<RefineCellAccessor>(
2609 std::move(refine_list), amr_ref_interp_mode);
2616 bool change_derefine = internal_derefine_grid_new<RefineCellAccessor>(
2617 std::move(derefine_list), amr_ref_interp_mode);
2619 has_cell_order_changed = has_cell_order_changed || (change_refine || change_derefine);
2621 if (has_cell_order_changed) {
2623 AMRSortBlocks block_sorter(context, solver_config, storage);
2624 block_sorter.reorder_amr_blocks();
double f64
Alias for double.
std::uint32_t u32
32 bit unsigned integer
std::uint64_t u64
64 bit unsigned integer
A buffer allocated in USM (Unified Shared Memory).
void complete_event_state(sycl::event e) const
Complete the event state of the buffer.
T * get_write_access(sham::EventList &depends_list, SourceLocation src_loc=SourceLocation{})
Get a read-write pointer to the buffer's data.
void copy_range(size_t begin, size_t end, sham::DeviceBuffer< T, dest_target > &dest) const
Copy a range of elements from the buffer to another buffer.
size_t get_size() const
Gets the number of elements in the buffer.
const T * get_read_access(sham::EventList &depends_list, SourceLocation src_loc=SourceLocation{}) const
Get a read-only pointer to the buffer's data.
A SYCL queue associated with a device and a context.
sycl::queue q
The SYCL queue associated with this context.
sycl::event submit(Fct &&fct)
Submits a kernel to the SYCL queue.
Class to manage a list of SYCL events.
void add_event(sycl::event e)
Add an event to the list of events.
Represents a collection of objects distributed across patches identified by a u64 id.
void update_refinement_new()
PatchDataLayer container class, the layout is described in patchdata_layout.
u32 get_obj_cnt() const
get the number of objects (particles) stored in this layer
void index_remap_resize(sycl::buffer< u32 > &index_map, u32 len)
this function remaps the patchdatafield like so val[id] = val[index_map[id]] This function can be use...
main include file for the shamalgs algorithms
Slope mode enum + json serialization/deserialization.
alias namespace to simplify the use of log functions
sycl::buffer< typename std::invoke_result_t< Fct, u32 > > gen_buffer_device(sycl::queue &q, u32 len, Fct &&func)
generate a buffer from a lambda expression based on the indexes
std::tuple< std::optional< sycl::buffer< u32 > >, u32 > stream_compact(sycl::queue &q, sycl::buffer< u32 > &buf_flags, u32 len)
Stream compaction algorithm.
T & get_check_ref(const std::unique_ptr< T > &ptr, SourceLocation loc=SourceLocation())
Takes a std::unique_ptr and returns a reference to the object it holds. It throws a std::runtime_erro...
std::vector< std::string_view > args
Executable argument list (mapped from argv).
void raw_ln(Types... var2)
Prints a log message with multiple arguments followed by a newline.
void info_ln(std::string module_name, Types... var2)
Prints a log message with multiple arguments followed by a newline.
Patch object that contain generic patch information.
u64 id_patch
unique key that identify the patch