111 bool has_B_field = solver_config.has_field_B_on_rho();
112 bool has_psi_field = solver_config.has_field_psi_on_ch();
113 bool has_epsilon_field = solver_config.dust_config.has_epsilon_field();
114 bool has_deltav_field = solver_config.dust_config.has_deltav_field();
116 using namespace shamrock::solvergraph;
143 if (has_epsilon_field) {
147 if (has_deltav_field) {
155 gpart_mass.value = solver_config.gpart_mass;
165 std::vector<std::shared_ptr<shamrock::solvergraph::INode>> attach_field_sequence;
169 "set_scheduler_patchdata",
172 scheduler().for_each_patchdata_nonempty(
175 scheduler_patchdata.patchdatas.
add_obj(p.id_patch, std::ref(pdat));
180 attach_field_sequence.push_back(set_scheduler_patchdata);
184 auto attach_part_counts
190 attach_field_sequence.push_back(attach_part_counts);
200 attach_field_sequence.push_back(attach_xyz);
210 attach_field_sequence.push_back(attach_vxyz);
220 attach_field_sequence.push_back(attach_axyz);
230 attach_field_sequence.push_back(attach_uint);
240 attach_field_sequence.push_back(attach_duint);
250 attach_field_sequence.push_back(attach_hpart);
260 attach_field_sequence.push_back(attach_B_on_rho);
270 attach_field_sequence.push_back(attach_dB_on_rho);
280 attach_field_sequence.push_back(attach_psi_on_ch);
290 attach_field_sequence.push_back(attach_dpsi_on_ch);
293 if (has_epsilon_field) {
300 attach_field_sequence.push_back(attach_epsilon);
303 if (has_epsilon_field) {
310 attach_field_sequence.push_back(attach_dtepsilon);
313 if (has_deltav_field) {
320 attach_field_sequence.push_back(attach_deltav);
323 if (has_deltav_field) {
330 attach_field_sequence.push_back(attach_dtdeltav);
334 "attach fields to scheduler",
344 auto make_half_step_sequence = [&](std::string prefix) {
345 std::vector<std::shared_ptr<shamrock::solvergraph::INode>> half_step_sequence;
356 half_step_sequence.push_back(half_step_vxyz);
368 half_step_sequence.push_back(half_step_uint);
380 half_step_sequence.push_back(half_step_B_on_rho);
392 half_step_sequence.push_back(half_step_psi_on_ch);
395 if (has_epsilon_field) {
404 half_step_sequence.push_back(half_step_epsilon);
407 if (has_deltav_field) {
416 half_step_sequence.push_back(half_step_deltav);
422 solver_graph.
register_node(
"half_step1", make_half_step_sequence(
"half_step1"));
423 solver_graph.
register_node(
"half_step2", make_half_step_sequence(
"half_step2"));
438 "leapfrog predictor",
440 "leapfrog predictor",
452 bool do_part_killing_step = solver_config.particle_killing.kill_list.size() > 0;
454 if (do_part_killing_step) {
462 std::vector<std::shared_ptr<shamrock::solvergraph::INode>> part_kill_sequence{};
466 auto empty_part_to_remove
469 part_kill_sequence.push_back(empty_part_to_remove);
472 using kill_t =
typename ParticleKillingConfig<Tvec>::kill_t;
476 for (kill_t &kill_obj : solver_config.particle_killing.kill_list) {
477 if (kill_sphere *kill_info = std::get_if<kill_sphere>(&kill_obj)) {
480 kill_info->center, kill_info->radius);
481 node_selector.set_edges(xyz_edge, part_to_remove);
483 part_kill_sequence.push_back(
484 std::make_shared<
decltype(node_selector)>(std::move(node_selector)));
490 node_killer.set_edges(part_to_remove, patchdatas);
492 part_kill_sequence.push_back(
493 std::make_shared<
decltype(node_killer)>(std::move(node_killer)));
502 std::vector<std::shared_ptr<shamrock::solvergraph::INode>> seq{};
507 if (do_part_killing_step) {
516 = std::make_shared<shamrock::solvergraph::Indexes<u32>>(
"part_counts",
"N_{\\rm part}");
518 storage.part_counts_with_ghost = std::make_shared<shamrock::solvergraph::Indexes<u32>>(
519 "part_counts_with_ghost",
"N_{\\rm part, with ghost}");
521 storage.patch_rank_owner = std::make_shared<shamrock::solvergraph::RankGetter>(
522 [&](
u64 patch_id) ->
u32 {
523 return scheduler().get_patch_rank_owner(patch_id);
529 storage.positions_with_ghosts
530 = std::make_shared<shamrock::solvergraph::FieldRefs<Tvec>>(
"part_pos",
"\\mathbf{r}");
531 storage.hpart_with_ghosts
532 = std::make_shared<shamrock::solvergraph::FieldRefs<Tscal>>(
"h_part",
"h");
535 = std::make_shared<shammodels::sph::solvergraph::NeighCache>(
"neigh_cache",
"neigh");
537 storage.omega = std::make_shared<shamrock::solvergraph::Field<Tscal>>(1,
"omega",
"\\Omega");
539 if (solver_config.has_field_alphaAV()) {
540 storage.alpha_av_updated = std::make_shared<shamrock::solvergraph::Field<Tscal>>(
541 1,
"alpha_av_updated",
"\\alpha_{\\rm AV}");
544 storage.pressure = std::make_shared<shamrock::solvergraph::Field<Tscal>>(1,
"pressure",
"P");
546 = std::make_shared<shamrock::solvergraph::Field<Tscal>>(1,
"soundspeed",
"c_s");
548 storage.exchange_gz_alpha
549 = std::make_shared<shamrock::solvergraph::ExchangeGhostField<Tscal>>();
550 storage.exchange_gz_node
551 = std::make_shared<shamrock::solvergraph::ExchangeGhostLayer>(storage.ghost_layout);
552 storage.exchange_gz_positions
553 = std::make_shared<shamrock::solvergraph::ExchangeGhostLayer>(storage.xyzh_ghost_layout);
924 using namespace shamrock::patch;
929 SPHUtils sph_utils(scheduler());
937 auto should_set_omega_mask = std::make_shared<shamrock::solvergraph::Field<u32>>(
938 1,
"should_set_omega_mask",
"should_set_omega_mask");
941 u32 hstep_max = solver_config.h_max_subcycles_count;
942 for (; hstep_cnt < hstep_max; hstep_cnt++) {
944 gen_ghost_handler(time_val + dt);
946 merge_position_ghost();
947 build_merged_pos_trees();
948 compute_presteps_rint();
949 start_neighbors_cache();
952 _h_old = utility.
save_field<Tscal>(ihpart,
"h_old");
956 if (solver_config.gpart_mass == 0) {
958 "invalid gpart_mass {}, this configuration can not converge.\n"
959 "Please set it using either model.set_particle_mass(pmass) or "
960 "cfg.set_particle_mass(pmass)",
961 solver_config.gpart_mass));
965 std::shared_ptr<shamrock::solvergraph::Indexes<u32>> sizes
966 = std::make_shared<shamrock::solvergraph::Indexes<u32>>(
"",
"");
968 sizes->indexes.add_obj(p.id_patch, pdat.get_obj_cnt());
972 auto &neigh_cache = storage.neigh_cache;
975 auto &pos_merged = storage.positions_with_ghosts;
978 std::shared_ptr<shamrock::solvergraph::FieldRefs<Tscal>> hold
979 = std::make_shared<shamrock::solvergraph::FieldRefs<Tscal>>(
"",
"");
982 auto &field = _h_old.get_field(p.id_patch);
983 hold_refs.add_obj(p.id_patch, std::ref(field));
985 hold->set_refs(hold_refs);
988 std::shared_ptr<shamrock::solvergraph::FieldRefs<Tscal>> hnew
989 = std::make_shared<shamrock::solvergraph::FieldRefs<Tscal>>(
"",
"");
992 auto &field = pdat.get_field<Tscal>(ihpart);
993 hnew_refs.add_obj(p.id_patch, std::ref(field));
995 hnew->set_refs(hnew_refs);
998 std::shared_ptr<shamrock::solvergraph::FieldRefs<Tscal>> eps_h
999 = std::make_shared<shamrock::solvergraph::FieldRefs<Tscal>>(
"",
"");
1002 auto &field = _epsilon_h.get_field(p.id_patch);
1003 eps_h_refs.add_obj(p.id_patch, std::ref(field));
1005 eps_h->set_refs(eps_h_refs);
1007 std::shared_ptr<shamrock::solvergraph::INode> smth_h_iter_ptr;
1012 if (h_conf_density_based *conf
1013 = std::get_if<h_conf_density_based>(&solver_config.smoothing_length_config.config)) {
1014 std::shared_ptr<shammodels::sph::modules::IterateSmoothingLengthDensity<Tvec, Kernel>>
1015 smth_h_iter = std::make_shared<
1017 solver_config.gpart_mass,
1018 solver_config.htol_up_coarse_cycle,
1019 solver_config.htol_up_fine_cycle);
1020 smth_h_iter->set_edges(sizes, neigh_cache, pos_merged, hold, hnew, eps_h);
1021 smth_h_iter_ptr = smth_h_iter;
1023 h_conf_neigh_lim *conf
1024 = std::get_if<h_conf_neigh_lim>(&solver_config.smoothing_length_config.config)) {
1027 smth_h_iter_neigh_lim = std::make_shared<
1029 solver_config.gpart_mass,
1030 solver_config.htol_up_coarse_cycle,
1031 solver_config.htol_up_fine_cycle,
1032 conf->max_neigh_count);
1033 smth_h_iter_neigh_lim->set_edges(
1034 sizes, neigh_cache, pos_merged, hold, hnew, eps_h, should_set_omega_mask);
1035 smth_h_iter_ptr = smth_h_iter_neigh_lim;
1041 std::shared_ptr<shamrock::solvergraph::ScalarEdge<bool>> is_converged
1042 = std::make_shared<shamrock::solvergraph::ScalarEdge<bool>>(
"",
"");
1045 smth_h_iter_ptr, solver_config.epsilon_h, solver_config.h_iter_per_subcycles,
false);
1046 loop_smth_h_iter.set_edges(eps_h, is_converged);
1048 loop_smth_h_iter.evaluate();
1050 if (!is_converged->value) {
1052 Tscal largest_h = 0;
1055 largest_h = sham::max(largest_h, pdat.get_field<Tscal>(ihpart).compute_max());
1057 Tscal global_largest_h = shamalgs::collective::allreduce_max(largest_h);
1059 std::string add_info =
"";
1060 u64 cnt_unconverged = 0;
1063 = _epsilon_h.get_field(p.id_patch).get_ids_buf_where([](
auto access,
u32 id) {
1064 return access[id] == -1;
1067 if (hstep_cnt == hstep_max - 1) {
1068 if (std::get<0>(res)) {
1069 add_info +=
"\n patch " + std::to_string(p.id_patch) +
" ";
1070 add_info +=
"errored parts : \n";
1071 sycl::buffer<u32> &idx_err = *std::get<0>(res);
1076 auto pos = xyz.copy_to_stdvec();
1077 auto h = hpart.copy_to_stdvec();
1080 sycl::host_accessor acc{idx_err};
1081 for (
u32 i = 0; i < idx_err.size(); i++) {
1082 add_info += shambase::format(
1083 "{} - pos : {}, hpart : {}\n", acc[i], pos[acc[i]], h[acc[i]]);
1089 cnt_unconverged += std::get<1>(res);
1092 u64 global_cnt_unconverged = shamalgs::collective::allreduce_sum(cnt_unconverged);
1097 "smoothing length is not converged, rerunning the iterator ...\n largest h "
1100 "unconverged cnt =",
1101 global_cnt_unconverged,
1105 reset_ghost_handler();
1106 clear_ghost_cache();
1113 storage.merged_xyzh.reset();
1115 clear_merged_pos_trees();
1116 reset_presteps_rint();
1117 reset_neighbors_cache();
1134 if (hstep_cnt == hstep_max) {
1135 logger::err_ln(
"SPH",
"the h iterator is not converged after", hstep_cnt,
"iterations");
1138 std::shared_ptr<shamrock::solvergraph::FieldRefs<Tscal>> hnew_edge
1139 = std::make_shared<shamrock::solvergraph::FieldRefs<Tscal>>(
"",
"");
1142 auto &field = pdat.get_field<Tscal>(ihpart);
1143 hnew_refs.add_obj(p.id_patch, std::ref(field));
1145 hnew_edge->set_refs(hnew_refs);
1148 compute_omega.set_edges(
1149 storage.part_counts,
1150 storage.neigh_cache,
1151 storage.positions_with_ghosts,
1154 compute_omega.evaluate();
1156 if (solver_config.smoothing_length_config.is_density_based_neigh_lim()) {
1161 set_omega_mask.set_edges(storage.part_counts, should_set_omega_mask, storage.omega);
1162 set_omega_mask.evaluate();
1259 timer_interf.
start();
1262 using namespace shamrock::patch;
1264 bool has_alphaAV_field = solver_config.has_field_alphaAV();
1265 bool has_soundspeed_field = solver_config.ghost_has_soundspeed();
1267 bool has_B_field = solver_config.has_field_B_on_rho();
1268 bool has_psi_field = solver_config.has_field_psi_on_ch();
1269 bool has_curlB_field = solver_config.has_field_curlB();
1270 bool has_epsilon_field = solver_config.dust_config.has_epsilon_field();
1271 bool has_deltav_field = solver_config.dust_config.has_deltav_field();
1281 const u32 ialpha_AV = (has_alphaAV_field) ? pdl.
get_field_idx<Tscal>(
"alpha_AV") : 0;
1282 const u32 isoundspeed = (has_soundspeed_field) ? pdl.
get_field_idx<Tscal>(
"soundspeed") : 0;
1284 const u32 iB_on_rho = (has_B_field) ? pdl.
get_field_idx<Tvec>(
"B/rho") : 0;
1285 const u32 idB_on_rho = (has_B_field) ? pdl.
get_field_idx<Tvec>(
"dB/rho") : 0;
1286 const u32 ipsi_on_ch = (has_psi_field) ? pdl.
get_field_idx<Tscal>(
"psi/ch") : 0;
1287 const u32 idpsi_on_ch = (has_psi_field) ? pdl.
get_field_idx<Tscal>(
"dpsi/ch") : 0;
1288 const u32 icurlB = (has_curlB_field) ? pdl.
get_field_idx<Tvec>(
"curlB") : 0;
1290 bool do_MHD_debug = solver_config.do_MHD_debug();
1291 const u32 imag_pressure = (do_MHD_debug) ? pdl.
get_field_idx<Tvec>(
"mag_pressure") : -1;
1292 const u32 imag_tension = (do_MHD_debug) ? pdl.
get_field_idx<Tvec>(
"mag_tension") : -1;
1293 const u32 igas_pressure = (do_MHD_debug) ? pdl.
get_field_idx<Tvec>(
"gas_pressure") : -1;
1294 const u32 itensile_corr = (do_MHD_debug) ? pdl.
get_field_idx<Tvec>(
"tensile_corr") : -1;
1295 const u32 ipsi_propag = (do_MHD_debug) ? pdl.
get_field_idx<Tscal>(
"psi_propag") : -1;
1296 const u32 ipsi_diff = (do_MHD_debug) ? pdl.
get_field_idx<Tscal>(
"psi_diff") : -1;
1297 const u32 ipsi_cons = (do_MHD_debug) ? pdl.
get_field_idx<Tscal>(
"psi_cons") : -1;
1298 const u32 iu_mhd = (do_MHD_debug) ? pdl.
get_field_idx<Tscal>(
"u_mhd") : -1;
1300 const u32 iepsilon = (has_epsilon_field) ? pdl.
get_field_idx<Tscal>(
"epsilon") : 0;
1301 const u32 ideltav = (has_deltav_field) ? pdl.
get_field_idx<Tvec>(
"deltav") : 0;
1303 auto &ghost_layout_ptr = storage.ghost_layout;
1310 const u32 iaxyz_interf
1311 = (solver_config.has_axyz_in_ghost()) ? ghost_layout.
get_field_idx<Tvec>(
"axyz") : 0;
1313 const u32 isoundspeed_interf
1314 = (has_soundspeed_field) ? ghost_layout.
get_field_idx<Tscal>(
"soundspeed") : 0;
1316 const u32 iB_interf = (has_B_field) ? ghost_layout.
get_field_idx<Tvec>(
"B/rho") : 0;
1317 const u32 ipsi_interf = (has_psi_field) ? ghost_layout.
get_field_idx<Tscal>(
"psi/ch") : 0;
1318 const u32 icurlB_interf = (has_curlB_field) ? ghost_layout.
get_field_idx<Tvec>(
"curlB") : 0;
1320 const u32 iepsilon_interf
1321 = (has_epsilon_field) ? ghost_layout.
get_field_idx<Tscal>(
"epsilon") : 0;
1322 const u32 ideltav_interf = (has_deltav_field) ? ghost_layout.
get_field_idx<Tvec>(
"deltav") : 0;
1329 auto pdat_interf = ghost_handle.template build_interface_native<PatchDataLayer>(
1330 storage.ghost_patch_cache.get(),
1332 PatchDataLayer pdat(ghost_layout_ptr);
1339 ghost_handle.template modify_interface_native<PatchDataLayer>(
1340 storage.ghost_patch_cache.get(),
1344 InterfaceBuildInfos binfo,
1348 PatchDataLayer &sender_patch = scheduler().patch_data.get_pdat(sender);
1349 PatchDataField<Tscal> &sender_omega = omega.get(sender);
1351 sender_patch.get_field<Tscal>(ihpart).append_subset_to(
1352 buf_idx, cnt, pdat.get_field<Tscal>(ihpart_interf));
1353 sender_patch.get_field<Tscal>(iuint).append_subset_to(
1354 buf_idx, cnt, pdat.get_field<Tscal>(iuint_interf));
1356 if (solver_config.has_axyz_in_ghost()) {
1357 sender_patch.get_field<Tvec>(iaxyz).append_subset_to(
1358 buf_idx, cnt, pdat.get_field<Tvec>(iaxyz_interf));
1361 sender_patch.get_field<Tvec>(ivxyz).append_subset_to(
1362 buf_idx, cnt, pdat.get_field<Tvec>(ivxyz_interf));
1364 sender_omega.append_subset_to(buf_idx, cnt, pdat.get_field<Tscal>(iomega_interf));
1366 if (has_soundspeed_field) {
1367 sender_patch.get_field<Tscal>(isoundspeed)
1368 .append_subset_to(buf_idx, cnt, pdat.get_field<Tscal>(isoundspeed_interf));
1372 sender_patch.get_field<Tvec>(iB_on_rho).append_subset_to(
1373 buf_idx, cnt, pdat.get_field<Tvec>(iB_interf));
1376 if (has_psi_field) {
1377 sender_patch.get_field<Tscal>(ipsi_on_ch)
1378 .append_subset_to(buf_idx, cnt, pdat.get_field<Tscal>(ipsi_interf));
1381 if (has_curlB_field) {
1382 sender_patch.get_field<Tvec>(icurlB).append_subset_to(
1383 buf_idx, cnt, pdat.get_field<Tvec>(icurlB_interf));
1386 if (has_epsilon_field) {
1387 sender_patch.get_field<Tscal>(iepsilon).append_subset_to(
1388 buf_idx, cnt, pdat.get_field<Tscal>(iepsilon_interf));
1391 if (has_deltav_field) {
1392 sender_patch.get_field<Tvec>(ideltav).append_subset_to(
1393 buf_idx, cnt, pdat.get_field<Tvec>(ideltav_interf));
1397 ghost_handle.template modify_interface_native<PatchDataLayer>(
1398 storage.ghost_patch_cache.get(),
1402 InterfaceBuildInfos binfo,
1406 if (sycl::length(binfo.offset_speed) > 0) {
1407 pdat.get_field<Tvec>(ivxyz_interf).apply_offset(binfo.offset_speed);
1413 std::move(pdat_interf),
1414 storage.exchange_gz_node,
1415 solver_config.show_ghost_zone_graph);
1417 std::map<u64, u64> sz_interf_map;
1419 sz_interf_map[r] += pdat_interf.get_obj_cnt();
1422 storage.merged_patchdata_ghost.set(
1423 ghost_handle.template merge_native<PatchDataLayer, PatchDataLayer>(
1424 std::move(interf_pdat),
1426 PatchDataLayer pdat_new(ghost_layout_ptr);
1428 u32 or_elem = pdat.get_obj_cnt();
1429 pdat_new.reserve(or_elem + sz_interf_map[p.id_patch]);
1430 u32 total_elements = or_elem;
1432 PatchDataField<Tscal> &cur_omega = omega.get(p.id_patch);
1434 pdat_new.get_field<Tscal>(ihpart_interf).insert(pdat.get_field<Tscal>(ihpart));
1435 pdat_new.get_field<Tscal>(iuint_interf).insert(pdat.get_field<Tscal>(iuint));
1436 pdat_new.get_field<Tvec>(ivxyz_interf).insert(pdat.get_field<Tvec>(ivxyz));
1438 if (solver_config.has_axyz_in_ghost()) {
1439 pdat_new.get_field<Tvec>(iaxyz_interf).insert(pdat.get_field<Tvec>(iaxyz));
1442 pdat_new.get_field<Tscal>(iomega_interf).insert(cur_omega);
1444 if (has_soundspeed_field) {
1445 pdat_new.get_field<Tscal>(isoundspeed_interf)
1446 .insert(pdat.get_field<Tscal>(isoundspeed));
1450 pdat_new.get_field<Tvec>(iB_interf).insert(pdat.get_field<Tvec>(iB_on_rho));
1453 if (has_psi_field) {
1454 pdat_new.get_field<Tscal>(ipsi_interf)
1455 .insert(pdat.get_field<Tscal>(ipsi_on_ch));
1458 if (has_curlB_field) {
1459 pdat_new.get_field<Tvec>(icurlB_interf).insert(pdat.get_field<Tvec>(icurlB));
1462 if (has_epsilon_field) {
1463 pdat_new.get_field<Tscal>(iepsilon_interf)
1464 .insert(pdat.get_field<Tscal>(iepsilon));
1467 if (has_deltav_field) {
1468 pdat_new.get_field<Tvec>(ideltav_interf).insert(pdat.get_field<Tvec>(ideltav));
1471 pdat_new.check_field_obj_cnt_match();
1476 pdat.insert_elements(pdat_interf);
1480 storage.timings_details.interface += timer_interf.elasped_sec();
1584 f64 mpi_timer_start = shamcomm::mpi::get_timer(
"total");
1586 for (
auto &callbacks : timestep_callbacks) {
1587 if (callbacks.step_begin_callback) {
1592 Tscal t_current = solver_config.get_time();
1593 Tscal dt = solver_config.get_dt_sph();
1598 shamcomm::logs::raw_ln(
1599 shambase::format(
"---------------- t = {}, dt = {} ----------------", t_current, dt));
1607 .update_load_balancing();
1608 scheduler().scheduler_step(
true,
true);
1610 .update_load_balancing();
1612 scheduler().scheduler_step(
false,
false);
1618 using namespace shamrock::patch;
1620 bool has_B_field = solver_config.has_field_B_on_rho();
1621 bool has_psi_field = solver_config.has_field_psi_on_ch();
1622 bool has_epsilon_field = solver_config.dust_config.has_epsilon_field();
1623 bool has_deltav_field = solver_config.dust_config.has_deltav_field();
1633 const u32 iB_on_rho = (has_B_field) ? pdl.
get_field_idx<Tvec>(
"B/rho") : 0;
1634 const u32 idB_on_rho = (has_B_field) ? pdl.
get_field_idx<Tvec>(
"dB/rho") : 0;
1635 const u32 ipsi_on_ch = (has_psi_field) ? pdl.
get_field_idx<Tscal>(
"psi/ch") : 0;
1636 const u32 idpsi_on_ch = (has_psi_field) ? pdl.
get_field_idx<Tscal>(
"dpsi/ch") : 0;
1637 const u32 iepsilon = (has_epsilon_field) ? pdl.
get_field_idx<Tscal>(
"epsilon") : 0;
1638 const u32 idtepsilon = (has_epsilon_field) ? pdl.
get_field_idx<Tscal>(
"dtepsilon") : 0;
1639 const u32 ideltav = (has_deltav_field) ? pdl.
get_field_idx<Tvec>(
"deltav") : 0;
1640 const u32 idtdeltav = (has_deltav_field) ? pdl.
get_field_idx<Tvec>(
"dtdeltav") : 0;
1647 sink_update.accrete_particles(dt);
1648 ext_forces.point_mass_accrete_particles();
1650 sink_update.predictor_step(dt);
1655 using namespace shamrock::solvergraph;
1672 sink_update.compute_ext_forces();
1676 gen_serial_patch_tree();
1678 apply_position_boundary(t_current + dt);
1680 u64 Npart_all = scheduler().get_total_obj_count();
1682 if (solver_config.enable_particle_reordering
1683 && solve_logs.step_count % solver_config.particle_reordering_step_freq == 0) {
1684 logger::info_ln(
"SPH",
"Reordering particles at step ", solve_logs.step_count);
1692 using namespace shamrock::solvergraph;
1697 sph_prestep(t_current, dt);
1703 if (solver_config.self_grav_config.is_sg_on()) {
1709 constant_G.data = solver_config.get_constant_G();
1720 auto &field = pdat.get_field<Tvec>(ixyz);
1721 field_xyz_refs.
add_obj(p.id_patch, std::ref(field));
1723 field_xyz_edge.set_refs(field_xyz_refs);
1735 auto &field = pdat.get_field<Tvec>(iaxyz_ext);
1736 field_axyz_ext_refs.
add_obj(p.id_patch, std::ref(field));
1738 field_axyz_ext_edge.set_refs(field_axyz_ext_refs);
1740 set_field_axyz_ext.
set_edges(field_axyz_ext);
1748 sizes.indexes.add_obj(p.id_patch, pdat.get_obj_cnt());
1757 gpart_mass.data = solver_config.gpart_mass;
1762 set_gpart_mass.evaluate();
1763 set_constant_G.evaluate();
1764 set_field_xyz.evaluate();
1765 set_field_axyz_ext.evaluate();
1766 set_sizes.evaluate();
1769 std::get_if<SelfGravConfig::SofteningPlummer>(
1770 &solver_config.self_grav_config.softening_mode))
1773 if (solver_config.self_grav_config.is_none()) {
1775 }
else if (solver_config.self_grav_config.is_direct()) {
1778 std::get_if<SelfGravConfig::Direct>(&solver_config.self_grav_config.config));
1781 eps_grav, direct_config.reference_mode);
1782 self_gravity_direct_node.set_edges(
1783 sizes, gpart_mass, constant_G, field_xyz, field_axyz_ext);
1784 self_gravity_direct_node.
evaluate();
1786 }
else if (solver_config.self_grav_config.is_mm()) {
1789 std::get_if<SelfGravConfig::MM>(&solver_config.self_grav_config.config));
1791 auto run_sg_mm = [&](
auto mm_order_tag) {
1792 constexpr u32 order =
decltype(mm_order_tag)::value;
1794 eps_grav, mm_config.opening_angle, mm_config.reduction_level);
1795 self_gravity_mm_node.set_edges(
1796 sizes, gpart_mass, constant_G, field_xyz, field_axyz_ext);
1800 switch (mm_config.order) {
1801 case 1 : run_sg_mm(std::integral_constant<u32, 1>{});
break;
1802 case 2 : run_sg_mm(std::integral_constant<u32, 2>{});
break;
1803 case 3 : run_sg_mm(std::integral_constant<u32, 3>{});
break;
1804 case 4 : run_sg_mm(std::integral_constant<u32, 4>{});
break;
1805 case 5 : run_sg_mm(std::integral_constant<u32, 5>{});
break;
1809 }
else if (solver_config.self_grav_config.is_fmm()) {
1812 std::get_if<SelfGravConfig::FMM>(&solver_config.self_grav_config.config));
1814 auto run_sg_fmm = [&](
auto fmm_order_tag) {
1815 constexpr u32 order =
decltype(fmm_order_tag)::value;
1817 eps_grav, fmm_config.opening_angle, fmm_config.reduction_level);
1818 self_gravity_mm_node.set_edges(
1819 sizes, gpart_mass, constant_G, field_xyz, field_axyz_ext);
1823 switch (fmm_config.order) {
1824 case 1 : run_sg_fmm(std::integral_constant<u32, 1>{});
break;
1825 case 2 : run_sg_fmm(std::integral_constant<u32, 2>{});
break;
1826 case 3 : run_sg_fmm(std::integral_constant<u32, 3>{});
break;
1827 case 4 : run_sg_fmm(std::integral_constant<u32, 4>{});
break;
1828 case 5 : run_sg_fmm(std::integral_constant<u32, 5>{});
break;
1832 }
else if (solver_config.self_grav_config.is_sfmm()) {
1835 std::get_if<SelfGravConfig::SFMM>(&solver_config.self_grav_config.config));
1837 auto run_sg_sfmm = [&](
auto sfmm_order_tag) {
1838 constexpr u32 order =
decltype(sfmm_order_tag)::value;
1841 sfmm_config.opening_angle,
1842 sfmm_config.leaf_lowering,
1843 sfmm_config.reduction_level);
1844 self_gravity_mm_node.set_edges(
1845 sizes, gpart_mass, constant_G, field_xyz, field_axyz_ext);
1849 switch (sfmm_config.order) {
1850 case 1 : run_sg_sfmm(std::integral_constant<u32, 1>{});
break;
1851 case 2 : run_sg_sfmm(std::integral_constant<u32, 2>{});
break;
1852 case 3 : run_sg_sfmm(std::integral_constant<u32, 3>{});
break;
1853 case 4 : run_sg_sfmm(std::integral_constant<u32, 4>{});
break;
1854 case 5 : run_sg_sfmm(std::integral_constant<u32, 5>{});
break;
1860 "Self gravity config not supported, current state is : \n"
1861 + nlohmann::json{solver_config.self_grav_config}.dump(4));
1866 auto &merged_xyzh = storage.merged_xyzh.get();
1876 u32 iB_on_rho_interf = (has_B_field) ? ghost_layout.
get_field_idx<Tvec>(
"B/rho") : 0;
1877 u32 ipsi_on_rho_interf = (has_psi_field) ? ghost_layout.
get_field_idx<Tscal>(
"psi/ch") : 0;
1884 u32 corrector_iter_cnt = 0;
1885 bool need_rerun_corrector =
false;
1888 reset_merge_ghosts_fields();
1891 if (corrector_iter_cnt == 50) {
1893 "the corrector has made over 50 loops, either their is a bug, either you are using "
1894 "a dt that is too large");
1898 communicate_merge_ghosts_fields();
1900 if (solver_config.has_field_alphaAV()) {
1902 std::shared_ptr<shamrock::solvergraph::PatchDataLayerRefs> patchdatas
1903 = std::make_shared<shamrock::solvergraph::PatchDataLayerRefs>(
1904 "patchdata_layer_ref",
"patchdata_layer_ref");
1906 auto node_set_edge = scheduler().get_node_set_edge_patchdata_layer_refs();
1907 node_set_edge->set_edges(patchdatas);
1908 node_set_edge->evaluate();
1911 scheduler().get_layout_ptr_old(),
"alpha_AV");
1912 node_copy.set_edges(patchdatas, storage.alpha_av_updated);
1916 if (solver_config.has_field_dtdivv()) {
1918 if (solver_config.combined_dtdiv_divcurlv_compute) {
1919 if (solver_config.has_field_dtdivv()) {
1921 .update_dtdivv(
true);
1925 if (solver_config.has_field_divv()) {
1930 if (solver_config.has_field_curlv()) {
1935 if (solver_config.has_field_dtdivv()) {
1937 .update_dtdivv(
false);
1942 if (solver_config.has_field_divv()) {
1947 if (solver_config.has_field_curlv()) {
1962 update_artificial_viscosity(dt);
1964 if (solver_config.has_field_alphaAV()) {
1969 using InterfaceBuildInfos =
1973 time_interf.
start();
1975 auto field_interf = ghost_handle.template build_interface_native<PatchDataField<Tscal>>(
1976 storage.ghost_patch_cache.get(),
1979 InterfaceBuildInfos binfo,
1984 return sender_field.make_new_from_subset(buf_idx, cnt);
1988 = ghost_handle.communicate_pdatfield(
1989 std::move(field_interf), 1, storage.exchange_gz_alpha);
1993 std::move(interf_pdat),
1996 = comp_field_send.
get_field(p.id_patch);
1997 return receiver_field.duplicate();
2000 mpdat.insert(pdat_interf);
2004 storage.timings_details.interface += time_interf.
elasped_sec();
2006 storage.alpha_av_ghost.set(std::move(merged_field));
2010 compute_eos_fields();
2012 constexpr bool debug_interfaces =
false;
2013 if constexpr (debug_interfaces) {
2015 if (solver_config.do_debug_dump) {
2018 = storage.merged_patchdata_ghost.
get();
2025 merged_xyzh.get(cur_p.
id_patch).field_pos.get_buf());
2026 sycl::buffer<Tvec> &buf_vxyz = mpdat.get_field_buf_ref<Tvec>(ivxyz_interf);
2027 sycl::buffer<Tscal> &buf_hpart = mpdat.get_field_buf_ref<Tscal>(ihpart_interf);
2031 SHAM_ASSERT(merged_patch.total_elements == total_elements);
2035 solver_config.gpart_mass,
2042 solver_config.debug_dump_filename);
2043 logger::raw_ln(
"writing : ", solver_config.debug_dump_filename);
2049 shamlog_debug_ln(
"sph::BasicGas",
"compute force");
2052 prepare_corrector();
2056 bool has_luminosity = solver_config.compute_luminosity;
2058 if (has_luminosity) {
2062 .set_refs(storage.merged_xyzh.get()
2065 return std::ref(mpdat.get_field<Tscal>(
2072 .set_refs(storage.merged_xyzh.get()
2075 return std::ref(mpdat.get_field<Tscal>(1));
2079 set_uint_with_ghost_refs(
2082 = storage.merged_patchdata_ghost.
get();
2087 scheduler().for_each_patchdata_nonempty(
2091 auto &field = mpdat.get_field<Tscal>(iuint_interf);
2092 field_uint_with_ghost_refs.
add_obj(p.id_patch, std::ref(field));
2095 field_uint_with_ghost_edge.set_refs(field_uint_with_ghost_refs);
2098 set_uint_with_ghost_refs.
set_edges(uint_with_ghost);
2103 set_luminosity_refs(
2106 = storage.merged_patchdata_ghost.
get();
2111 scheduler().for_each_patchdata_nonempty(
2113 auto &field = pdat.get_field<Tscal>(iluminosity);
2114 field_luminosity_refs.
add_obj(p.id_patch, std::ref(field));
2116 field_luminosity_edge.set_refs(field_luminosity_refs);
2119 set_luminosity_refs.
set_edges(luminosity);
2121 set_uint_with_ghost_refs.evaluate();
2122 set_luminosity_refs.evaluate();
2124 Tscal alpha_u = solver_config.artif_viscosity.get_alpha_u().value();
2127 solver_config.gpart_mass, alpha_u};
2129 compute_luminosity.set_edges(
2130 storage.part_counts,
2131 storage.neigh_cache,
2132 storage.positions_with_ghosts,
2133 storage.hpart_with_ghosts,
2139 compute_luminosity.evaluate();
2151 shamlog_debug_ln(
"sph::BasicGas",
"leapfrog corrector");
2152 utility.fields_leapfrog_corrector<Tvec>(
2153 ivxyz, iaxyz, storage.old_axyz.get(), vepsilon_v_sq, dt / 2);
2154 utility.fields_leapfrog_corrector<Tscal>(
2155 iuint, iduint, storage.old_duint.get(), uepsilon_u_sq, dt / 2);
2157 if (solver_config.has_field_B_on_rho()) {
2160 utility.fields_leapfrog_corrector<Tvec>(
2161 iB_on_rho, idB_on_rho, storage.old_dB_on_rho.get(), BOR_epsilon_BOR_sq, dt / 2);
2163 if (solver_config.has_field_B_on_rho()) {
2166 utility.fields_leapfrog_corrector<Tscal>(
2167 ipsi_on_ch, idpsi_on_ch, storage.old_dpsi_on_ch.get(), POC_epsilon_POC_sq, dt / 2);
2170 if (solver_config.dust_config.has_epsilon_field()) {
2173 utility.fields_leapfrog_corrector<Tscal>(
2174 iepsilon, idtepsilon, storage.old_dtepsilon.get(), epsilon_epsilon_sq, dt / 2);
2177 if (solver_config.dust_config.has_deltav_field()) {
2180 utility.fields_leapfrog_corrector<Tvec>(
2181 ideltav, idtdeltav, storage.old_dtdeltav.get(), epsilon_deltav_sq, dt / 2);
2184 storage.old_axyz.reset();
2185 storage.old_duint.reset();
2186 if (solver_config.has_field_B_on_rho()) {
2187 storage.old_dB_on_rho.reset();
2189 if (solver_config.has_field_B_on_rho()) {
2190 storage.old_dpsi_on_ch.reset();
2193 if (solver_config.dust_config.has_epsilon_field()) {
2194 storage.old_dtepsilon.reset();
2197 if (solver_config.dust_config.has_deltav_field()) {
2198 storage.old_dtdeltav.reset();
2201 Tscal rank_veps_v = sycl::sqrt(vepsilon_v_sq.compute_rank_max());
2206 Tscal sum_vsq = utility.compute_rank_dot_sum<Tvec>(ivxyz);
2208 Tscal vmean_sq = shamalgs::collective::allreduce_sum(sum_vsq) / Tscal(Npart_all);
2210 Tscal vmean = sycl::sqrt(vmean_sq);
2212 Tscal rank_eps_v = rank_veps_v / vmean;
2218 Tscal eps_v = shamalgs::collective::allreduce_max(rank_eps_v);
2220 shamlog_debug_ln(
"BasicGas",
"epsilon v :", eps_v);
2227 "the corrector tolerance are broken the step will "
2228 "be re rerunned\n eps_v = {}",
2231 need_rerun_corrector =
true;
2232 solver_config.time_state.cfl_multiplier /= 2;
2236 need_rerun_corrector =
false;
2239 if (!need_rerun_corrector) {
2241 sink_update.corrector_step(dt);
2244 if (solver_config.has_field_alphaAV()) {
2252 = pdat.get_field<Tscal>(ialpha_AV).get_buf();
2254 = alpha_av_updated.get_field(cur_p.
id_patch).get_buf();
2256 auto &q = shamsys::instance::get_compute_scheduler().
get_queue();
2260 auto alpha_av_updated = buf_alpha_av_updated.
get_read_access(depends_list);
2262 auto e = q.submit(depends_list, [&](sycl::handler &cgh) {
2263 shambase::parallel_for(
2264 cgh, pdat.get_obj_cnt(),
"write back alpha_av", [=](
i32 id_a) {
2265 alpha_av[id_a] = alpha_av_updated[id_a];
2274 shamlog_debug_ln(
"BasicGas",
"computing next CFL");
2277 std::unique_ptr<ComputeField<Tscal>> vclean_dt;
2278 if (has_psi_field) {
2279 vclean_dt = std::make_unique<ComputeField<Tscal>>(
2284 = storage.merged_patchdata_ghost.
get();
2290 = merged_xyzh.get(cur_p.
id_patch).template get_field_buf_ref<Tvec>(0);
2293 = mpdat.get_field_buf_ref<Tscal>(ihpart_interf);
2303 sycl::range range_npart{pdat.get_obj_cnt()};
2312 auto &q = shamsys::instance::get_compute_scheduler().
get_queue();
2317 auto hpart = buf_hpart.get_read_access(depends_list);
2318 auto u = buf_uint.get_read_access(depends_list);
2319 auto pressure = buf_pressure.get_read_access(depends_list);
2322 auto particle_looper_ptrs = pcache.get_read_access(depends_list);
2325 auto e = q.submit(depends_list, [&](sycl::handler &cgh) {
2326 const Tscal pmass = solver_config.gpart_mass;
2327 const Tscal alpha_u = 1.0;
2328 const Tscal alpha_AV = 1.0;
2329 const Tscal beta_AV = 2.0;
2333 constexpr Tscal Rker2 = Kernel::Rkern * Kernel::Rkern;
2335 shambase::parallel_for(
2336 cgh, pdat.get_obj_cnt(),
"compute vsig", [=](
i32 id_a) {
2337 using namespace shamrock::sph;
2339 Tvec sum_axyz = {0, 0, 0};
2341 Tscal h_a = hpart[id_a];
2343 Tvec xyz_a = xyz[id_a];
2344 Tvec vxyz_a = vxyz[id_a];
2346 Tscal rho_a = rho_h(pmass, h_a, Kernel::hfactd);
2347 Tscal rho_a_sq = rho_a * rho_a;
2348 Tscal rho_a_inv = 1. / rho_a;
2350 Tscal P_a = pressure[id_a];
2352 const Tscal u_a = u[id_a];
2354 Tscal cs_a = cs[id_a];
2358 particle_looper.for_each_object(id_a, [&](
u32 id_b) {
2360 Tvec dr = xyz_a - xyz[id_b];
2361 Tscal rab2 = sycl::dot(dr, dr);
2362 Tscal h_b = hpart[id_b];
2364 if (rab2 > h_a * h_a * Rker2 && rab2 > h_b * h_b * Rker2) {
2368 Tscal rab = sycl::sqrt(rab2);
2369 Tvec vxyz_b = vxyz[id_b];
2370 Tvec v_ab = vxyz_a - vxyz_b;
2371 const Tscal u_b = u[id_b];
2373 Tvec r_ab_unit = dr / rab;
2376 r_ab_unit = {0, 0, 0};
2379 Tscal rho_b = rho_h(pmass, h_b, Kernel::hfactd);
2380 Tscal P_b = pressure[id_b];
2381 Tscal cs_b = cs[id_b];
2382 Tscal v_ab_r_ab = sycl::dot(v_ab, r_ab_unit);
2383 Tscal abs_v_ab_r_ab = sycl::fabs(v_ab_r_ab);
2388 const Tscal alpha_a = alpha_AV;
2389 const Tscal alpha_b = alpha_AV;
2391 Tscal vsig_a = alpha_a * cs_a + beta_AV * abs_v_ab_r_ab;
2393 vsig_max = sycl::fmax(vsig_max, vsig_a);
2396 vsig[id_a] = vsig_max;
2400 if (has_psi_field) {
2402 Tscal
const mu_0 = solver_config.get_constant_mu_0();
2406 Tvec *B_on_rho = mpdat.get_field_buf_ref<Tvec>(iB_on_rho_interf)
2407 .get_write_access(depends_list);
2411 auto e = q.submit(depends_list, [&](sycl::handler &cgh) {
2412 const Tscal pmass = solver_config.gpart_mass;
2416 constexpr Tscal Rker2 = Kernel::Rkern * Kernel::Rkern;
2418 shambase::parallel_for(
2419 cgh, pdat.get_obj_cnt(),
"compute vclean", [=](
i32 id_a) {
2420 using namespace shamrock::sph;
2422 Tscal h_a = hpart[id_a];
2423 Tscal rho_a = rho_h(pmass, h_a, Kernel::hfactd);
2424 const Tscal u_a = u[id_a];
2425 Tscal cs_a = cs[id_a];
2426 Tvec B_a = B_on_rho[id_a] * rho_a;
2428 Tscal vclean_a = shamphys::MHD_physics<Tvec, Tscal>::v_shock(
2429 cs_a, B_a, rho_a, mu_0);
2431 vclean[id_a] = vclean_a;
2434 mpdat.get_field_buf_ref<Tvec>(iB_on_rho_interf).complete_event_state(e);
2440 buf_hpart.complete_event_state(e);
2441 buf_uint.complete_event_state(e);
2442 buf_pressure.complete_event_state(e);
2448 pcache.complete_event_state(resulting_events);
2459 = mpdat.get_field<Tscal>(ihpart_interf).get_buf();
2463 auto &q = shamsys::instance::get_compute_scheduler().
get_queue();
2471 auto e = q.submit(depends_list, [&](sycl::handler &cgh) {
2472 Tscal C_cour = solver_config.cfl_config.cfl_cour
2473 * solver_config.time_state.cfl_multiplier;
2474 Tscal C_force = solver_config.cfl_config.cfl_force
2475 * solver_config.time_state.cfl_multiplier;
2477 cgh.parallel_for(sycl::range<1>{pdat.get_obj_cnt()}, [=](sycl::item<1> item) {
2478 Tscal h_a = hpart[item];
2479 Tscal vsig_a = vsig[item];
2480 Tscal abs_a_a = sycl::length(a[item]);
2482 Tscal dt_c = C_cour * h_a / vsig_a;
2483 Tscal dt_f = C_force * sycl::sqrt(h_a / abs_a_a);
2485 cfl_dt[item] = sycl::min(dt_c, dt_f);
2489 if (has_psi_field) {
2493 auto e = q.submit(depends_list, [&](sycl::handler &cgh) {
2494 Tscal C_cour = solver_config.cfl_config.cfl_cour
2495 * solver_config.time_state.cfl_multiplier;
2498 sycl::range<1>{pdat.get_obj_cnt()}, [=](sycl::item<1> item) {
2499 Tscal h_a = hpart[item];
2500 Tscal vclean_a = vclean[item];
2502 Tscal dt_divB_cleaning = C_cour * h_a / vclean_a;
2504 cfl_dt[item] = sycl::min(cfl_dt[item], dt_divB_cleaning);
2516 Tscal rank_dt = cfl_dt.compute_rank_min();
2518 if (solver_config.should_save_dt_to_fields()) {
2524 = pdat.get_field_buf_ref<Tscal>(idt_part);
2527 buf_dt_part.
copy_from(buf_dt, pdat.get_obj_cnt());
2532 if (!storage.sinks.is_empty()) {
2535 Tscal G = solver_config.get_constant_G();
2538 = solver_config.cfl_config.cfl_force * solver_config.time_state.cfl_multiplier;
2539 Tscal eta_phi = solver_config.cfl_config.eta_sink;
2541 std::vector<SinkParticle<Tvec>> &sink_parts = storage.sinks.get();
2543 for (
u32 i = 0; i < sink_parts.size(); i++) {
2547 Tvec f_i = s_i.ext_acceleration;
2549 Tscal grad_phi_i_sq = sham::dot(f_i, f_i);
2551 if (grad_phi_i_sq == 0) {
2555 for (
u32 j = 0; j < sink_parts.size(); j++) {
2562 Tvec rij = s_i.pos - s_j.pos;
2563 Tscal rij_scal = sycl::length(rij);
2565 Tscal phi_ij = G * s_j.mass / rij_scal;
2566 Tscal term_ij = sham::abs(phi_ij) / grad_phi_i_sq;
2567 Tscal dt_ij = C_force * eta_phi * sycl::sqrt(term_ij);
2569 sink_sink_cfl_i = sham::min(sink_sink_cfl_i, dt_ij);
2572 sink_sink_cfl = sham::min(sink_sink_cfl, sink_sink_cfl_i);
2575 sink_sink_cfl = shamalgs::collective::allreduce_min(sink_sink_cfl);
2580 Tscal hydro_cfl = shamalgs::collective::allreduce_min(rank_dt);
2583 shamlog_info_ln(
"SPH",
"CFL hydro =", hydro_cfl,
"sink sink =", sink_sink_cfl);
2586 next_cfl = sham::min(hydro_cfl, sink_sink_cfl);
2594 solver_config.time_state.cfl_multiplier);
2600 if (solver_config.has_field_soundspeed()) {
2611 sycl::range range_npart{pdat.get_obj_cnt()};
2615 auto &q = shamsys::instance::get_compute_scheduler().
get_queue();
2618 auto cs_in = buf_cs_in.get_read_access(depends_list);
2621 auto e = q.submit(depends_list, [&](sycl::handler &cgh) {
2622 const Tscal pmass = solver_config.gpart_mass;
2625 sycl::range<1>{pdat.get_obj_cnt()}, [=](sycl::item<1> item) {
2626 cs[item] = cs_in[item];
2630 buf_cs_in.complete_event_state(e);
2637 corrector_iter_cnt++;
2639 if (solver_config.has_field_alphaAV()) {
2640 storage.alpha_av_ghost.reset();
2643 }
while (need_rerun_corrector);
2645 reset_merge_ghosts_fields();
2652 for (
auto it = timestep_callbacks.rbegin(); it != timestep_callbacks.rend(); ++it) {
2653 if (it->step_end_callback) {
2658 f64 delta_mpi_timer = shamcomm::mpi::get_timer(
"total") - mpi_timer_start;
2666 = (mem_perf_infos_end.
time_alloc_device - mem_perf_infos_start.time_alloc_device)
2667 + (mem_perf_infos_end.
time_free_device - mem_perf_infos_start.time_free_device);
2668 f64 t_host_alloc = (mem_perf_infos_end.
time_alloc_host - mem_perf_infos_start.time_alloc_host)
2669 + (mem_perf_infos_end.
time_free_host - mem_perf_infos_start.time_free_host);
2671 u64 rank_count = scheduler().get_rank_count();
2672 f64 rate =
f64(rank_count) / tstep.elasped_sec();
2674 u64 npatch = scheduler().patch_list.local.size();
2678 std::string log_step = report_perf_timestep(
2682 tstep.elasped_sec(),
2688 system_metrics_delta,
2689 shamsys::has_reporter());
2692 logger::info_ln(
"sph::Model", log_step);
2694 "sph::Model",
"estimated rate :", dt * (3600 / tstep.elasped_sec()),
"(tsim/hr)");
2697 solve_logs.register_log(
2703 tstep.elasped_sec(),
2705 system_metrics_delta});
2707 storage.timings_details.reset();
2709 reset_serial_patch_tree();
2710 reset_ghost_handler();
2716 storage.merged_xyzh.reset();
2718 clear_merged_pos_trees();
2719 clear_ghost_cache();
2720 reset_presteps_rint();
2721 reset_neighbors_cache();
2725 solver_config.set_next_dt(next_cfl);
2726 solver_config.set_time(t_current + dt);
2728 auto get_next_cfl_mult = [&]() {
2729 Tscal cfl_m = solver_config.time_state.cfl_multiplier;
2730 Tscal stiff = solver_config.cfl_config.cfl_multiplier_stiffness;
2732 return (cfl_m * stiff + 1.) / (stiff + 1.);
2735 solver_config.time_state.cfl_multiplier = get_next_cfl_mult();
2740 log.npart = rank_count;
2741 log.tcompute = tstep.elasped_sec();