43template<
class Tvec,
template<
class>
class SPHKernel>
45 auto tmp = solver.evolve_once_time_expl(t_curr, dt_input);
46 solver.print_timestep_logs();
50template<
class Tvec,
template<
class>
class SPHKernel>
52 return solver.evolve_once();
55template<
class Tvec,
template<
class>
class SPHKernel>
58 if (solver.solver_config.scheduler_conf.split_load_value == 0) {
60 "Scheduler load value should be greater than 0");
63 solver.init_required_fields();
65 solver.solver_config.scheduler_conf.split_load_value,
66 solver.solver_config.scheduler_conf.merge_load_value);
68 using namespace shamrock::patch;
74 shamlog_debug_ln(
"Sys",
"build local scheduler tables");
80 solver.init_ghost_layout();
82 solver.init_solver_graph();
85template<
class Tvec,
template<
class>
class SPHKernel>
88 return shamalgs::collective::allreduce_sum(sched.get_rank_count());
91template<
class Tvec,
template<
class>
class SPHKernel>
93 return totmass / get_total_part_count();
96template<
class Tvec,
template<
class>
class SPHKernel>
100 using namespace shamrock::patch;
108 auto acc = pdat.get_field<Tvec>(0).get_buf().copy_to_stdvec();
110 u32 cnt = pdat.get_obj_cnt();
112 for (
u32 i = 0; i < cnt; i++) {
115 Tscal dist2 = sycl::dot(dr, dr);
116 if (dist2 < best_dist2) {
123 std::vector<Tvec> list_dr{};
133 for (Tvec tmp : list_dr) {
135 Tscal dist2 = sycl::dot(dr, dr);
136 if (dist2 < best_dist2) {
142 return pos + best_dr;
145template<
class Tvec,
template<
class>
class SPHKernel>
147 -> std::pair<Tvec, Tvec> {
149 auto [a, b] = generic::setup::generators::get_ideal_fcc_box<Tscal>(dr, box);
153template<
class Tvec,
template<
class>
class SPHKernel>
157 using namespace shamrock::patch;
161 auto &
xyz = pdat.get_field<Tvec>(0).get_buf();
162 auto acc =
xyz.copy_to_stdvec();
164 u32 cnt = pdat.get_obj_cnt();
166 for (
u32 i = 0; i < cnt; i++) {
167 acc[i] = map(acc[i]);
170 xyz.copy_from_stdvec(acc);
173 modules::ComputeLoadBalanceValue<Tvec, SPHKernel>(ctx, solver.solver_config, solver.storage)
174 .update_load_balancing();
183 reatrib.reatribute_patch_objects(sptree,
"xyz");
184 sched.check_patchdata_locality_correctness();
187 modules::ComputeLoadBalanceValue<Tvec, SPHKernel>(ctx, solver.solver_config, solver.storage)
188 .update_load_balancing();
198 reatrib.reatribute_patch_objects(sptree,
"xyz");
199 sched.check_patchdata_locality_correctness();
216 auto [m, M] = sched.get_box_tranform<Tvec>();
224 reatrib.reatribute_patch_objects(sptree,
"xyz");
225 sched.check_patchdata_locality_correctness();
237 reatrib.reatribute_patch_objects(sptree,
"xyz");
238 sched.check_patchdata_locality_correctness();
241 std::string log =
"";
243 using namespace shamrock::patch;
246 u32 largest_count = 0;
249 u32 tmp = pdat.get_obj_cnt();
250 smallest_count = sham::min(tmp, smallest_count);
251 largest_count = sham::max(tmp, largest_count);
254 smallest_count = shamalgs::collective::allreduce_min(smallest_count);
255 largest_count = shamalgs::collective::allreduce_max(largest_count);
259 "Model",
"current particle counts : min = ", smallest_count,
"max = ", largest_count);
274template<
class Tvec,
template<
class>
class SPHKernel>
276 std::vector<Tvec> &part_pos_insert,
277 std::vector<Tscal> &part_hpart_insert,
278 std::vector<Tscal> &part_u_insert) {
281 using namespace shamrock::patch;
285 std::string log =
"";
292 std::vector<Tvec> vec_acc;
293 std::vector<Tscal> hpart_acc;
294 std::vector<Tscal> u_acc;
295 for (
u32 i = 0; i < part_pos_insert.size(); i++) {
296 Tvec r = part_pos_insert[i];
297 Tscal u = part_u_insert[i];
298 if (patch_coord.contain_pos(r)) {
299 vec_acc.push_back(r);
300 hpart_acc.push_back(part_hpart_insert[i]);
305 if (vec_acc.size() == 0) {
309 log += shambase::format(
310 "\n rank = {} patch id={}, add N={} particles, coords = {} {}",
318 tmp.resize(vec_acc.size());
322 u32 len = vec_acc.size();
324 = tmp.get_field<Tvec>(sched.pdl_old().
get_field_idx<Tvec>(
"xyz"));
325 sycl::buffer<Tvec> buf(vec_acc.data(), len);
326 f.override(buf, len);
330 u32 len = vec_acc.size();
332 = tmp.get_field<Tscal>(sched.pdl_old().
get_field_idx<Tscal>(
"hpart"));
333 sycl::buffer<Tscal> buf(hpart_acc.data(), len);
334 f.override(buf, len);
338 u32 len = u_acc.size();
340 = tmp.get_field<Tscal>(sched.pdl_old().
get_field_idx<Tscal>(
"uint"));
341 sycl::buffer<Tscal> buf(u_acc.data(), len);
342 f.override(buf, len);
345 pdat.insert_elements(tmp);
347 sched.check_patchdata_locality_correctness();
349 std::string log_gathered =
"";
353 logger::info_ln(
"Model",
"Push particles : ", log_gathered);
357 modules::ComputeLoadBalanceValue<Tvec, SPHKernel>(ctx, solver.solver_config, solver.storage)
358 .update_load_balancing();
360 post_insert_data<Tvec>(sched);
364template<
class Tvec,
template<
class>
class SPHKernel>
366 std::vector<Tvec> &part_pos_insert,
367 std::vector<Tscal> &part_hpart_insert,
368 std::vector<Tscal> &part_u_insert,
369 std::vector<Tvec> &part_B_on_rho_insert,
370 std::vector<Tscal> &part_psi_on_ch_insert) {
373 using namespace shamrock::patch;
377 std::string log =
"";
384 std::vector<Tvec> vec_acc;
385 std::vector<Tscal> hpart_acc;
386 std::vector<Tscal> u_acc;
387 std::vector<Tvec> B_on_rho_acc;
388 std::vector<Tscal> psi_on_ch_acc;
389 for (
u32 i = 0; i < part_pos_insert.size(); i++) {
390 Tvec r = part_pos_insert[i];
391 Tscal u = part_u_insert[i];
392 if (patch_coord.contain_pos(r)) {
393 vec_acc.push_back(r);
394 hpart_acc.push_back(part_hpart_insert[i]);
396 B_on_rho_acc.push_back(part_B_on_rho_insert[i]);
397 psi_on_ch_acc.push_back(part_psi_on_ch_insert[i]);
401 if (vec_acc.size() == 0) {
405 log += shambase::format(
406 "\n rank = {} patch id={}, add N={} particles, coords = {} {}",
414 tmp.resize(vec_acc.size());
418 u32 len = vec_acc.size();
420 = tmp.get_field<Tvec>(sched.pdl_old().
get_field_idx<Tvec>(
"xyz"));
421 sycl::buffer<Tvec> buf(vec_acc.data(), len);
422 f.override(buf, len);
426 u32 len = vec_acc.size();
428 = tmp.get_field<Tscal>(sched.pdl_old().
get_field_idx<Tscal>(
"hpart"));
429 sycl::buffer<Tscal> buf(hpart_acc.data(), len);
430 f.override(buf, len);
434 u32 len = u_acc.size();
436 = tmp.get_field<Tscal>(sched.pdl_old().
get_field_idx<Tscal>(
"uint"));
437 sycl::buffer<Tscal> buf(u_acc.data(), len);
438 f.override(buf, len);
442 u32 len = vec_acc.size();
444 = tmp.get_field<Tvec>(sched.pdl_old().
get_field_idx<Tvec>(
"B/rho"));
445 sycl::buffer<Tvec> buf(B_on_rho_acc.data(), len);
446 f.override(buf, len);
450 u32 len = vec_acc.size();
452 = tmp.get_field<Tscal>(sched.pdl_old().
get_field_idx<Tscal>(
"psi/ch"));
453 sycl::buffer<Tscal> buf(psi_on_ch_acc.data(), len);
454 f.override(buf, len);
457 pdat.insert_elements(tmp);
459 sched.check_patchdata_locality_correctness();
461 std::string log_gathered =
"";
465 logger::info_ln(
"Model",
"Push particles MHD : ", log_gathered);
469 modules::ComputeLoadBalanceValue<Tvec, SPHKernel>(ctx, solver.solver_config, solver.storage)
470 .update_load_balancing();
472 post_insert_data<Tvec>(sched);
476template<
class Tvec,
template<
class>
class SPHKernel>
478 Tscal dr, std::pair<Tvec, Tvec> _box) -> std::pair<Tvec, Tvec> {
485 auto [idxs_min, idxs_max] = Lattice::get_box_index_bounds(dr, box.lower, box.upper);
487 auto [idxs_min_per, idxs_max_per] = Lattice::nearest_periodic_box_indices(idxs_min, idxs_max);
491 return {ret.lower, ret.upper};
494template<
class Tvec,
template<
class>
class SPHKernel>
496 Tscal dr, std::pair<Tvec, Tvec> _box) {
504 using namespace shamrock::patch;
511 auto [idxs_min, idxs_max] = Lattice::get_box_index_bounds(dr, box.lower, box.upper);
513 LatticeIter gen = LatticeIter(dr, idxs_min, idxs_max);
517 std::string log =
"";
518 while (!gen.is_done()) {
521 u64 loc_sum_ins_cnt = 0;
523 u64 max_loc_sum_ins_cnt = 0;
527 acc_count += to_ins.size();
534 std::vector<Tvec> vec_acc;
535 for (Tvec r : to_ins) {
536 if (patch_coord.contain_pos(r)) {
537 vec_acc.push_back(r);
542 loc_sum_ins_cnt += vec_acc.size();
544 if (vec_acc.size() == 0) {
548 log += shambase::format(
549 "\n rank = {} patch id={}, add N={} particles, coords = {} {}",
557 pdat.reserve(vec_acc.size());
560 tmp.resize(vec_acc.size());
564 u32 len = vec_acc.size();
566 = tmp.get_field<Tvec>(sched.pdl_old().
get_field_idx<Tvec>(
"xyz"));
568 f.override(vec_acc, len);
573 = tmp.get_field<Tscal>(sched.pdl_old().
get_field_idx<Tscal>(
"hpart"));
577 pdat.insert_elements(tmp);
580 max_loc_sum_ins_cnt = shamalgs::collective::allreduce_max(loc_sum_ins_cnt);
585 "--> insertion loop : max loc insert count = ",
590 }
while (!gen.is_done() && max_loc_sum_ins_cnt < sched.
crit_patch_split * 8);
592 sched.check_patchdata_locality_correctness();
604 modules::ComputeLoadBalanceValue<Tvec, SPHKernel>(ctx, solver.solver_config, solver.storage)
605 .update_load_balancing();
606 post_insert_data<Tvec>(sched);
610 modules::ParticleReordering<Tvec, u32, SPHKernel>(ctx, solver.solver_config, solver.storage)
611 .reorder_particles();
616 logger::info_ln(
"Model",
"add_cube_hcp took :", time_setup.
elasped_sec(),
"s");
620template<
class Tvec,
template<
class>
class SPHKernel>
622 Tscal dr, std::pair<Tvec, Tvec> _box) {
628 using namespace shamrock::patch;
635 auto [idxs_min, idxs_max] = Lattice::get_box_index_bounds(dr, box.lower, box.upper);
637 LatticeIter gen = LatticeIter(dr, idxs_min, idxs_max);
641 auto push_current_data = [&](std::vector<Tvec> pos_data) {
643 tmp.resize(pos_data.size());
647 u32 len = pos_data.size();
649 = tmp.get_field<Tvec>(sched.pdl_old().
get_field_idx<Tvec>(
"xyz"));
651 f.override(pos_data, len);
656 = tmp.get_field<Tscal>(sched.pdl_old().
get_field_idx<Tscal>(
"hpart"));
660 inserter.push_patch_data<Tvec>(tmp,
"xyz", sched.
crit_patch_split * 8, [&]() {
661 modules::ComputeLoadBalanceValue<Tvec, SPHKernel>(
662 ctx, solver.solver_config, solver.storage)
663 .update_load_balancing();
672 auto has_pdat = [&]() {
681 while (!gen.is_done()) {
683 u64 loc_gen_count = (has_pdat()) ? insert_step : 0;
685 auto gen_info = shamalgs::collective::fetch_view(loc_gen_count);
687 u64 skip_start = gen_info.head_offset;
688 u64 gen_cnt = loc_gen_count;
689 u64 skip_end = gen_info.total_byte_count - loc_gen_count - gen_info.head_offset;
698 skip_start + gen_cnt + skip_end);
699 gen.skip(skip_start);
700 auto tmp = gen.next_n(gen_cnt);
703 std::vector<Tvec> pos_data;
705 if (Patch::is_in_patch_converted(r, bmin, bmax)) {
706 pos_data.push_back(r);
710 push_current_data(pos_data);
712 shamlog_debug_ln(
"Gen",
"gen.is_done()", gen.is_done());
717 logger::info_ln(
"Model",
"add_cube_hcp took :", time_setup.
elasped_sec(),
"s");
724 using Tscal = shambase::VecComponent<Tvec>;
744 std::function<Tscal(Tscal)> sigma_profile;
745 std::function<Tscal(Tscal)> cs_profile;
746 std::function<Tscal(Tscal)> rot_profile;
747 std::function<Tscal(Tscal)> vel_full_corr;
762 std::function<Tscal(Tscal)> sigma_profile,
763 std::function<Tscal(Tscal)> cs_profile,
764 std::function<Tscal(Tscal)> rot_profile)
765 : current_index(0), Npart(Npart), center(center), central_mass(central_mass),
766 r_in(r_in), r_out(r_out), disc_mass(disc_mass), p(p), H_r_in(H_r_in), q(q), G(G),
767 eng(eng), sigma_profile(sigma_profile), cs_profile(cs_profile),
768 rot_profile(rot_profile) {
775 inline bool is_done() {
return done; }
779 constexpr Tscal _2pi = 2 * shambase::constants::pi<Tscal>;
781 auto f_func = [&](Tscal r) {
782 return r * sigma_profile(r);
785 Tscal fmax = f_func(r_out);
787 auto find_r = [&]() {
789 Tscal u2 = shamalgs::primitives::mock_value<Tscal>(eng, 0, fmax);
790 Tscal r = shamalgs::primitives::mock_value<Tscal>(eng, r_in, r_out);
791 if (u2 < f_func(r)) {
797 auto theta = shamalgs::primitives::mock_value<Tscal>(eng, 0, _2pi);
798 auto Gauss = shamalgs::random::mock_gaussian<Tscal>(eng);
803 Tscal vk = rot_profile(r);
804 Tscal cs = cs_profile(r);
805 Tscal sigma = sigma_profile(r);
807 Tscal Omega_Kep = sycl::sqrt(G * central_mass / (r * r * r));
811 Tscal H = sycl::sqrt(2.) * 3. * cs
816 auto pos = sycl::vec<Tscal, 3>{r * sycl::cos(theta), z, r * sycl::sin(theta)};
818 auto etheta = sycl::vec<Tscal, 3>{-pos.z(), 0, pos.x()};
819 etheta /= sycl::length(etheta);
821 auto vel = vk * etheta;
826 Tscal fs = 1. - sycl::sqrt(r_in / r);
827 Tscal rho = (sigma * fs) * sycl::exp(-z * z / (2 * H * H));
829 Out out{pos, vel, cs, rho};
833 if (current_index == Npart) {
840 inline std::vector<Out> next_n(
u32 nmax) {
841 std::vector<Out> ret{};
842 for (
u32 i = 0; i < nmax; i++) {
847 ret.push_back(next());
854template<
class Tvec,
template<
class>
class SPHKernel>
868 using Config = SolverConfig;
869 using SolverConfigEOS =
typename Config::EOSConfig;
870 using SolverEOS_Adiabatic =
typename SolverConfigEOS::Adiabatic;
871 if (SolverEOS_Adiabatic *eos_config
872 = std::get_if<SolverEOS_Adiabatic>(&solver.solver_config.eos_config.config)) {
874 eos_gamma = eos_config->gamma;
882 auto sigma_profile = [=](Tscal r) {
884 constexpr Tscal sigma_0 = 1;
885 return sigma_0 * sycl::pow(r / r_in, -p);
888 auto cs_law = [=](Tscal r) {
889 return sycl::pow(r / r_in, -q);
892 auto kep_profile = [&](Tscal r) {
893 Tscal G = solver.solver_config.get_constant_G();
894 return sycl::sqrt(G * central_mass / r);
897 auto rot_profile = [&](Tscal r) -> Tscal {
899 Tscal G = solver.solver_config.get_constant_G();
900 Tscal c = solver.solver_config.get_constant_c();
902 Tscal term = G * central_mass / r;
903 Tscal term_fs = 1. - sycl::sqrt(r_in / r);
905 = -sycl::pown(cs_law(r), 2) * (1.5 + p + q);
907 Tscal det = sycl::pown(term_bh, 2) + 4. * (term + term_pr);
908 Tscal Rg = G * central_mass / sycl::pown(c, 2);
909 Tscal vkep = sqrt(G * central_mass / r);
911 Tscal vphi = 0.5 * (term_bh + sycl::sqrt(det));
916 auto cs_profile = [&](Tscal r) {
917 Tscal cs_in = (H_r_in * r_in / r) * kep_profile(r_in);
918 return cs_law(r) * cs_in;
921 auto get_hfact = []() -> Tscal {
922 return Kernel::hfactd;
925 auto int_rho_h = [&](Tscal h) -> Tscal {
926 return shamrock::sph::rho_h(solver.solver_config.gpart_mass, h, Kernel::hfactd);
929 Tscal part_mass = disc_mass / Npart;
936 using namespace shamrock::patch;
943 Tscal G = solver.solver_config.get_constant_G();
962 std::string log =
"";
963 while (!gen.is_done()) {
966 u64 loc_sum_ins_cnt = 0;
968 u64 max_loc_sum_ins_cnt = 0;
972 acc_count += to_ins.size();
979 std::vector<Out> part_list;
980 for (Out r : to_ins) {
981 if (patch_coord.contain_pos(r.pos)) {
983 part_list.push_back(r);
988 loc_sum_ins_cnt += part_list.size();
990 if (part_list.size() == 0) {
994 log += shambase::format(
995 "\n rank = {} patch id={}, add N={} particles, coords = {} {}",
1003 std::vector<Tvec> vec_pos;
1004 std::vector<Tvec> vec_vel;
1005 std::vector<Tscal> vec_u;
1006 std::vector<Tscal> vec_h;
1007 std::vector<Tscal> vec_cs;
1009 for (Out o : part_list) {
1010 vec_pos.push_back(o.pos);
1011 vec_vel.push_back(o.velocity);
1012 vec_u.push_back(o.cs * o.cs / ( (eos_gamma - 1)));
1013 vec_h.push_back(shamrock::sph::h_rho(part_mass, o.rho * 0.1, Kernel::hfactd));
1014 vec_cs.push_back(o.cs);
1018 pdat.reserve(vec_pos.size());
1021 tmp.resize(vec_pos.size());
1025 u32 len = vec_pos.size();
1027 = tmp.get_field<Tvec>(sched.pdl_old().
get_field_idx<Tvec>(
"xyz"));
1028 sycl::buffer<Tvec> buf(vec_pos.data(), len);
1029 f.override(buf, len);
1033 u32 len = vec_pos.size();
1035 = tmp.get_field<Tscal>(sched.pdl_old().
get_field_idx<Tscal>(
"hpart"));
1036 sycl::buffer<Tscal> buf(vec_h.data(), len);
1037 f.override(buf, len);
1041 u32 len = vec_pos.size();
1043 = tmp.get_field<Tscal>(sched.pdl_old().
get_field_idx<Tscal>(
"uint"));
1044 sycl::buffer<Tscal> buf(vec_u.data(), len);
1045 f.override(buf, len);
1048 if (solver.solver_config.is_eos_locally_isothermal()) {
1049 u32 len = vec_pos.size();
1051 = tmp.get_field<Tscal>(sched.pdl_old().
get_field_idx<Tscal>(
"soundspeed"));
1052 sycl::buffer<Tscal> buf(vec_cs.data(), len);
1053 f.override(buf, len);
1057 u32 len = vec_pos.size();
1059 = tmp.get_field<Tvec>(sched.pdl_old().
get_field_idx<Tvec>(
"vxyz"));
1060 sycl::buffer<Tvec> buf(vec_vel.data(), len);
1061 f.override(buf, len);
1064 pdat.insert_elements(tmp);
1067 max_loc_sum_ins_cnt = shamalgs::collective::allreduce_max(loc_sum_ins_cnt);
1072 "--> insertion loop : max loc insert count = ",
1073 max_loc_sum_ins_cnt,
1077 }
while (!gen.is_done() && max_loc_sum_ins_cnt < sched.
crit_patch_split * 8);
1079 sched.check_patchdata_locality_correctness();
1091 modules::ComputeLoadBalanceValue<Tvec, SPHKernel>(ctx, solver.solver_config, solver.storage)
1092 .update_load_balancing();
1093 post_insert_data<Tvec>(sched);
1097 modules::ParticleReordering<Tvec, u32, SPHKernel>(ctx, solver.solver_config, solver.storage)
1098 .reorder_particles();
1103 logger::info_ln(
"Model",
"add_big_disc took :", time_setup.
elasped_sec(),
"s");
1107template<
class Tvec,
template<
class>
class SPHKernel>
1109 Tscal dr, std::pair<Tvec, Tvec> _box) {
1114 using namespace shamrock::patch;
1118 std::string log =
"";
1120 auto make_sliced = [&]() {
1121 std::vector<Tvec> vec_lst;
1122 generic::setup::generators::add_particles_fcc(
1124 {box.lower, box.upper},
1126 return box.contain_pos(r);
1128 [&](Tvec r, Tscal h) {
1129 vec_lst.push_back(r);
1132 std::vector<std::vector<Tvec>> sliced_buf;
1136 std::vector<Tvec> cur_buf;
1137 for (
u32 i = 0; i < vec_lst.size(); i++) {
1138 cur_buf.push_back(vec_lst[i]);
1140 if (cur_buf.size() > sz_buf) {
1141 sliced_buf.push_back(std::exchange(cur_buf, std::vector<Tvec>{}));
1145 if (cur_buf.size() > 0) {
1146 sliced_buf.push_back(std::exchange(cur_buf, std::vector<Tvec>{}));
1152 std::vector<std::vector<Tvec>> sliced_buf = make_sliced();
1154 for (std::vector<Tvec> to_ins : sliced_buf) {
1161 std::vector<Tvec> vec_acc;
1162 for (Tvec r : to_ins) {
1163 if (patch_coord.contain_pos(r)) {
1164 vec_acc.push_back(r);
1168 if (vec_acc.size() == 0) {
1172 log += shambase::format(
1173 "\n rank = {} patch id={}, add N={} particles, coords = {} {}",
1181 tmp.resize(vec_acc.size());
1185 u32 len = vec_acc.size();
1187 = tmp.get_field<Tvec>(sched.pdl_old().
get_field_idx<Tvec>(
"xyz"));
1188 sycl::buffer<Tvec> buf(vec_acc.data(), len);
1189 f.override(buf, len);
1194 = tmp.get_field<Tscal>(sched.pdl_old().
get_field_idx<Tscal>(
"hpart"));
1198 pdat.insert_elements(tmp);
1201 sched.check_patchdata_locality_correctness();
1203 std::string log_gathered =
"";
1207 logger::info_ln(
"Model",
"Push particles : ", log_gathered);
1211 modules::ComputeLoadBalanceValue<Tvec, SPHKernel>(ctx, solver.solver_config, solver.storage)
1212 .update_load_balancing();
1213 post_insert_data<Tvec>(sched);
1217template<
class Tvec,
template<
class>
class SPHKernel>
1219 PhantomDump &phdump,
bool bypass_error) -> SolverConfig {
1221 SolverConfig conf{};
1223 auto massoftype = phdump.read_header_floats<Tscal>(
"massoftype");
1225 conf.gpart_mass = massoftype[0];
1226 conf.cfl_config.cfl_cour = phdump.read_header_float<Tscal>(
"C_cour");
1227 conf.cfl_config.cfl_force = phdump.read_header_float<Tscal>(
"C_force");
1229 conf.eos_config = get_shamrock_eosconfig<Tvec>(phdump, bypass_error);
1230 conf.artif_viscosity = get_shamrock_avconfig<Tvec>(phdump);
1232 conf.set_units(get_shamrock_units<Tscal>(phdump));
1234 conf.boundary_config = get_shamrock_boundary_config<Tvec>(phdump);
1239template<
class Tvec,
template<
class>
class SPHKernel>
1241 PhantomDump &phdump, Tscal hpart_fact_load) {
1244 bool has_coord_in_header =
true;
1246 Tscal xmin, xmax, ymin, ymax, zmin, zmax;
1247 has_coord_in_header = phdump.has_header_entry(
"xmin");
1249 std::string log =
"";
1252 std::vector<Tscal> h, u, alpha;
1255 std::vector<Tscal> x, y, z, vx, vy, vz;
1257 phdump.blocks[0].fill_vec(
"x", x);
1258 phdump.blocks[0].fill_vec(
"y", y);
1259 phdump.blocks[0].fill_vec(
"z", z);
1261 if (has_coord_in_header) {
1262 xmin = phdump.read_header_float<
f64>(
"xmin");
1263 xmax = phdump.read_header_float<
f64>(
"xmax");
1264 ymin = phdump.read_header_float<
f64>(
"ymin");
1265 ymax = phdump.read_header_float<
f64>(
"ymax");
1266 zmin = phdump.read_header_float<
f64>(
"zmin");
1267 zmax = phdump.read_header_float<
f64>(
"zmax");
1269 resize_simulation_box({{xmin, ymin, zmin}, {xmax, ymax, zmax}});
1271 Tscal box_tolerance = 1.2;
1273 xmin = *std::min_element(x.begin(), x.end());
1274 xmax = *std::max_element(x.begin(), x.end());
1275 ymin = *std::min_element(y.begin(), y.end());
1276 ymax = *std::max_element(y.begin(), y.end());
1277 zmin = *std::min_element(z.begin(), z.end());
1278 zmax = *std::max_element(z.begin(), z.end());
1280 Tvec bm = {xmin, ymin, zmin};
1281 Tvec bM = {xmax, ymax, zmax};
1283 Tvec center = (bm + bM) * 0.5;
1285 Tvec d = (bM - bm) * 0.5;
1290 resize_simulation_box({center - d, center + d});
1293 phdump.blocks[0].fill_vec(
"h", h);
1295 phdump.blocks[0].fill_vec(
"vx", vx);
1296 phdump.blocks[0].fill_vec(
"vy", vy);
1297 phdump.blocks[0].fill_vec(
"vz", vz);
1299 phdump.blocks[0].fill_vec(
"u", u);
1300 phdump.blocks[0].fill_vec(
"alpha", alpha);
1302 for (
u32 i = 0; i < x.size(); i++) {
1303 xyz.push_back({x[i], y[i], z[i]});
1305 for (
u32 i = 0; i < vx.size(); i++) {
1306 vxyz.push_back({vx[i], vy[i], vz[i]});
1311 f64 time_phdump = phdump.read_header_float<
f64>(
"time");
1312 solver.solver_config.set_time(time_phdump);
1314 using namespace shamrock::patch;
1322 std::vector<u64> insert_ranges;
1323 insert_ranges.push_back(0);
1324 for (
u64 i = sz_buf; i < Ntot; i += sz_buf) {
1325 insert_ranges.push_back(i);
1327 insert_ranges.push_back(Ntot);
1329 for (
u64 krange = 0; krange < insert_ranges.size() - 1; krange++) {
1330 u64 start_id = insert_ranges[krange];
1331 u64 end_id = insert_ranges[krange + 1];
1333 u64 Nloc = end_id - start_id;
1340 std::vector<u64> sel_index;
1341 for (
u64 i = start_id; i < end_id; i++) {
1344 if (patch_coord.contain_pos(r) && (h_ >= 0)) {
1345 sel_index.push_back(i);
1349 if (sel_index.size() == 0) {
1353 log += shambase::format(
1354 "\n rank = {} patch id={}, add N={} particles, coords = {} {}",
1361 std::vector<Tvec> ins_xyz, ins_vxyz;
1362 std::vector<Tscal> ins_h, ins_u, ins_alpha;
1363 for (
u64 i : sel_index) {
1364 ins_xyz.push_back(xyz[i]);
1366 for (
u64 i : sel_index) {
1367 ins_vxyz.push_back(vxyz[i]);
1369 for (
u64 i : sel_index) {
1370 ins_h.push_back(h[i] * hpart_fact_load);
1373 for (
u64 i : sel_index) {
1374 ins_u.push_back(u[i]);
1377 if (alpha.size() > 0) {
1378 for (
u64 i : sel_index) {
1379 ins_alpha.push_back(alpha[i]);
1384 ptmp.resize(sel_index.size());
1387 ptmp.override_patch_field(
"xyz", ins_xyz);
1388 ptmp.override_patch_field(
"vxyz", ins_vxyz);
1389 ptmp.override_patch_field(
"hpart", ins_h);
1391 if (ins_alpha.size() > 0) {
1392 ptmp.override_patch_field(
"alpha_AV", ins_alpha);
1395 if (ins_u.size() > 0) {
1396 ptmp.override_patch_field(
"uint", ins_u);
1399 pdat.insert_elements(ptmp);
1402 sched.check_patchdata_locality_correctness();
1404 std::string log_gathered =
"";
1408 logger::info_ln(
"Model",
"Push particles : ", log_gathered);
1412 modules::ComputeLoadBalanceValue<Tvec, SPHKernel>(ctx, solver.solver_config, solver.storage)
1413 .update_load_balancing();
1415 post_insert_data<Tvec>(sched);
1419 PhantomDumpBlock &sink_block = phdump.blocks[1];
1421 std::vector<Tscal> xsink, ysink, zsink;
1422 std::vector<Tscal> vxsink, vysink, vzsink;
1423 std::vector<Tscal> mass;
1424 std::vector<Tscal> Racc;
1426 sink_block.fill_vec(
"x", xsink);
1427 sink_block.fill_vec(
"y", ysink);
1428 sink_block.fill_vec(
"z", zsink);
1429 sink_block.fill_vec(
"vx", vxsink);
1430 sink_block.fill_vec(
"vy", vysink);
1431 sink_block.fill_vec(
"vz", vzsink);
1432 sink_block.fill_vec(
"m", mass);
1433 sink_block.fill_vec(
"h", Racc);
1435 for (
u32 i = 0; i < xsink.size(); i++) {
1438 {xsink[i], ysink[i], zsink[i]},
1439 {vxsink[i], vysink[i], vzsink[i]},
1446template<
class Tvec,
template<
class>
class SPHKernel>
1452 u64 xid = block.get_ref_fort_real(
"x");
1453 u64 yid = block.get_ref_fort_real(
"y");
1454 u64 zid = block.get_ref_fort_real(
"z");
1457 block.blocks_fort_real[xid].vals.push_back(
vec.x());
1458 block.blocks_fort_real[yid].vals.push_back(
vec.y());
1459 block.blocks_fort_real[zid].vals.push_back(
vec.z());
1462 std::vector<Tscal> h = pdat.
fetch_data<Tscal>(
"hpart");
1463 u64 hid = block.get_ref_f32(
"h");
1465 block.blocks_f32[hid].vals.push_back(h_);
1468 if (solver.solver_config.has_field_alphaAV()) {
1469 std::vector<Tscal> alpha = pdat.
fetch_data<Tscal>(
"alpha_AV");
1470 u64 aid = block.get_ref_f32(
"alpha");
1471 for (
auto alp_ : alpha) {
1472 block.blocks_f32[aid].vals.push_back(alp_);
1476 if (solver.solver_config.has_field_divv()) {
1477 std::vector<Tscal> vecdivv = pdat.
fetch_data<Tscal>(
"divv");
1478 u64 divvid = block.get_ref_f32(
"divv");
1479 for (
auto d_ : vecdivv) {
1480 block.blocks_f32[divvid].vals.push_back(d_);
1486 u64 vxid = block.get_ref_fort_real(
"vx");
1487 u64 vyid = block.get_ref_fort_real(
"vy");
1488 u64 vzid = block.get_ref_fort_real(
"vz");
1491 block.blocks_fort_real[vxid].vals.push_back(
vec.x());
1492 block.blocks_fort_real[vyid].vals.push_back(
vec.y());
1493 block.blocks_fort_real[vzid].vals.push_back(
vec.z());
1496 std::vector<Tscal> u = pdat.
fetch_data<Tscal>(
"uint");
1497 u64 uid = block.get_ref_fort_real(
"u");
1499 block.blocks_fort_real[uid].vals.push_back(u_);
1502 block.tot_count = block.blocks_fort_real[xid].vals.size();
1505template<
class Tvec,
template<
class>
class SPHKernel>
1511 bool bypass_error_check =
false;
1513 auto get_sink_count = [&]() ->
int {
1514 if (solver.storage.sinks.is_empty()) {
1517 return int(solver.storage.sinks.get().size());
1521 dump.override_magic_number();
1523 dump.fileid = shambase::format(
"{:100s}",
"FT:Phantom Shamrock writer");
1525 u32 Ntot = get_total_part_count();
1526 dump.table_header_fort_int.add(
"nparttot", Ntot);
1527 dump.table_header_fort_int.add(
"ntypes", 8);
1528 dump.table_header_fort_int.add(
"npartoftype", Ntot);
1529 dump.table_header_fort_int.add(
"npartoftype", 0);
1530 dump.table_header_fort_int.add(
"npartoftype", 0);
1531 dump.table_header_fort_int.add(
"npartoftype", 0);
1532 dump.table_header_fort_int.add(
"npartoftype", 0);
1533 dump.table_header_fort_int.add(
"npartoftype", 0);
1534 dump.table_header_fort_int.add(
"npartoftype", 0);
1535 dump.table_header_fort_int.add(
"npartoftype", 0);
1537 dump.table_header_i64.add(
"nparttot", Ntot);
1538 dump.table_header_i64.add(
"ntypes", 8);
1539 dump.table_header_i64.add(
"npartoftype", Ntot);
1540 dump.table_header_i64.add(
"npartoftype", 0);
1541 dump.table_header_i64.add(
"npartoftype", 0);
1542 dump.table_header_i64.add(
"npartoftype", 0);
1543 dump.table_header_i64.add(
"npartoftype", 0);
1544 dump.table_header_i64.add(
"npartoftype", 0);
1545 dump.table_header_i64.add(
"npartoftype", 0);
1546 dump.table_header_i64.add(
"npartoftype", 0);
1548 dump.table_header_fort_int.add(
"nblocks", 1);
1549 dump.table_header_fort_int.add(
"nptmass", get_sink_count());
1550 dump.table_header_fort_int.add(
"ndustlarge", 0);
1551 dump.table_header_fort_int.add(
"ndustsmall", 0);
1552 dump.table_header_fort_int.add(
"idust", 7);
1553 dump.table_header_fort_int.add(
"idtmax_n", 1);
1554 dump.table_header_fort_int.add(
"idtmax_frac", 0);
1555 dump.table_header_fort_int.add(
"idumpfile", 0);
1556 dump.table_header_fort_int.add(
"majorv", 2023);
1557 dump.table_header_fort_int.add(
"minorv", 0);
1558 dump.table_header_fort_int.add(
"microv", 0);
1559 dump.table_header_fort_int.add(
"isink", 0);
1561 dump.table_header_i32.add(
"iexternalforce", 0);
1565 dump.table_header_fort_real.add(
"time", solver.solver_config.get_time());
1566 dump.table_header_fort_real.add(
"dtmax", solver.solver_config.get_dt_sph());
1568 dump.table_header_fort_real.add(
"rhozero", 0);
1569 dump.table_header_fort_real.add(
"hfact", Kernel::hfactd);
1570 dump.table_header_fort_real.add(
"tolh", 0.0001);
1571 dump.table_header_fort_real.add(
"C_cour", solver.solver_config.cfl_config.cfl_cour);
1572 dump.table_header_fort_real.add(
"C_force", solver.solver_config.cfl_config.cfl_force);
1573 dump.table_header_fort_real.add(
"alpha", 0);
1574 dump.table_header_fort_real.add(
"alphau", 1);
1575 dump.table_header_fort_real.add(
"alphaB", 1);
1577 dump.table_header_fort_real.add(
"massoftype", solver.solver_config.gpart_mass);
1578 dump.table_header_fort_real.add(
"massoftype", 0);
1579 dump.table_header_fort_real.add(
"massoftype", 0);
1580 dump.table_header_fort_real.add(
"massoftype", 0);
1581 dump.table_header_fort_real.add(
"massoftype", 0);
1582 dump.table_header_fort_real.add(
"massoftype", 0);
1583 dump.table_header_fort_real.add(
"massoftype", 0);
1584 dump.table_header_fort_real.add(
"massoftype", 0);
1586 dump.table_header_fort_real.add(
"Bextx", 0);
1587 dump.table_header_fort_real.add(
"Bexty", 0);
1588 dump.table_header_fort_real.add(
"Bextz", 0);
1589 dump.table_header_fort_real.add(
"dum", 0);
1593 auto box_size = sched.get_box_volume<Tvec>();
1595 write_shamrock_boundaries_in_phantom_dump(
1596 solver.solver_config.boundary_config, box_size, dump, bypass_error_check);
1598 dump.table_header_fort_real.add(
"get_conserv", -1);
1599 dump.table_header_fort_real.add(
"etot_in", 0.59762);
1600 dump.table_header_fort_real.add(
"angtot_in", 0.0189694);
1601 dump.table_header_fort_real.add(
"totmom_in", 0.0306284);
1605 PhantomDumpBlock block_part;
1609 std::vector<std::unique_ptr<shamrock::patch::PatchDataLayer>> gathered
1610 = ctx.allgather_data();
1612 for (
auto &dat : gathered) {
1617 dump.blocks.push_back(std::move(block_part));
1619 if (!solver.storage.sinks.is_empty()) {
1621 auto &sinks = solver.storage.sinks.get();
1623 PhantomDumpBlock sink_block;
1625 u64 xid = sink_block.get_ref_fort_real(
"x");
1626 u64 yid = sink_block.get_ref_fort_real(
"y");
1627 u64 zid = sink_block.get_ref_fort_real(
"z");
1628 u64 mid = sink_block.get_ref_fort_real(
"m");
1629 u64 hid = sink_block.get_ref_fort_real(
"h");
1630 u64 vxid = sink_block.get_ref_fort_real(
"vx");
1631 u64 vyid = sink_block.get_ref_fort_real(
"vy");
1632 u64 vzid = sink_block.get_ref_fort_real(
"vz");
1634 for (SinkParticle<Tvec> s : sinks) {
1635 sink_block.blocks_fort_real[xid].vals.push_back(s.pos.x());
1636 sink_block.blocks_fort_real[yid].vals.push_back(s.pos.y());
1637 sink_block.blocks_fort_real[zid].vals.push_back(s.pos.z());
1638 sink_block.blocks_fort_real[mid].vals.push_back(s.mass);
1639 sink_block.blocks_fort_real[hid].vals.push_back(s.accretion_radius);
1640 sink_block.blocks_fort_real[vxid].vals.push_back(s.velocity.x());
1641 sink_block.blocks_fort_real[vyid].vals.push_back(s.velocity.y());
1642 sink_block.blocks_fort_real[vzid].vals.push_back(s.velocity.z());
1645 sink_block.tot_count = sinks.size();
1647 dump.blocks.push_back(std::move(sink_block));
constexpr const char * vxyz
3-velocity field
constexpr const char * xyz
Position field (3D coordinates)
Header file describing a Node Instance.
double f64
Alias for double.
std::uint32_t u32
32 bit unsigned integer
std::uint64_t u64
64 bit unsigned integer
SchedulerPatchData patch_data
handle the data of the patches of the scheduler
u64 crit_patch_split
splitting limit (if load value > crit_patch_split => patch split)
PatchTree patch_tree
handle the tree structure of the patches
void scheduler_step(bool do_split_merge, bool do_load_balancing)
scheduler step
SchedulerPatchList patch_list
handle the list of the patches of the scheduler
std::unordered_set< u64 > owned_patch_id
(owned_patch_id = patch_list.build_local())
void add_root_patch()
add patch to the scheduler
std::unordered_set< u64 > build_local()
select owned patches owned by the node to rebuild local
void build_local_idx_map()
recompute id_patch_to_local_idx
Class Timer measures the time elapsed since the timer was started.
void end()
Stops the timer and stores the elapsed time in nanoseconds.
f64 elasped_sec() const
Converts the stored nanosecond time to a floating point representation in seconds.
void start()
Starts the timer.
Iterator utility to generate the lattice.
Iterator utility to generate the lattice.
utility for generating HCP crystal lattices
Vector class based on std::array storage and mdspan.
void init()
Initialise the model and all the related data structures (patch scheduler in particular)
Class to insert data in the PatchScheduler.
Utility class used to move the objects between patches.
u32 get_field_idx(const std::string &field_name) const
Get the field id if matching name & type.
PatchDataLayer container class, the layout is described in patchdata_layout.
std::vector< T > fetch_data(std::string key)
Fetch data of a patchdata field into a std::vector.
std::tuple< T, T > get_bounding_box() const
Get the stored bounding box of the domain.
PatchCoordTransform< T > get_patch_transform() const
Get a PatchCoordTransform object that describes the conversion between patch coordinates and domain c...
shamrock::patch::SimulationBoxInfo sim_box
simulation box geometry info
shambase::DistributedData< PatchData > owned_data
map container for patchdata owned by the current node (layout : id_patch,data)
This header file contains utility functions related to exception handling in the code.
std::vector< int > vector_allgatherv(const std::vector< T > &send_vec, const MPI_Datatype &send_type, std::vector< T > &recv_vec, const MPI_Datatype &recv_type, const MPI_Comm comm)
allgatherv on vector with size query (size querying variant of vector_allgatherv_ks) //TODO add fault...
void gather_str(const std::string &send_vec, std::string &recv_vec)
Gathers a string from all nodes and store the result in a std::string.
void throw_with_loc(std::string message, SourceLocation loc=SourceLocation{})
Throw an exception and append the source location to it.
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...
i32 world_rank()
Gives the rank of the current process in the MPI communicator.
namespace for math utility
void write_shamrock_units_in_phantom_dump(std::optional< shamunits::UnitSystem< Tscal > > &units, PhantomDump &dump, bool bypass_error)
Write shamrock units config into the phantom dump.
void write_shamrock_eos_in_phantom_dump(EOSConfig< Tvec > &cfg, PhantomDump &dump, bool bypass_error)
Write the eos config to th phantom dump header.
constexpr u32 u32_max
u32 max value
This file contains the definition for the stacktrace related functionality.
Class representing a Phantom dump file.
Patch object that contain generic patch information.