43template<
class Tvec,
template<
class>
class SPHKernel>
44f64 shammodels::sph::Model<Tvec, SPHKernel>::evolve_once_time_expl(
f64 t_curr,
f64 dt_input) {
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>
86u64 shammodels::sph::Model<Tvec, SPHKernel>::get_total_part_count() {
88 return shamalgs::collective::allreduce_sum(sched.get_rank_count());
91template<
class Tvec,
template<
class>
class SPHKernel>
92f64 shammodels::sph::Model<Tvec, SPHKernel>::total_mass_to_part_mass(
f64 totmass) {
93 return totmass / get_total_part_count();
96template<
class Tvec,
template<
class>
class SPHKernel>
97auto shammodels::sph::Model<Tvec, SPHKernel>::get_closest_part_to(Tvec pos) -> Tvec {
100 using namespace shamrock::patch;
102 Tvec best_dr = shambase::VectorProperties<Tvec>::get_max();
103 Tscal best_dist2 = shambase::VectorProperties<Tscal>::get_max();
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{};
130 best_dr = shambase::VectorProperties<Tvec>::get_max();
131 best_dist2 = shambase::VectorProperties<Tscal>::get_max();
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>
146void shammodels::sph::Model<Tvec, SPHKernel>::remap_positions(std::function<Tvec(Tvec)> map) {
149 using namespace shamrock::patch;
153 auto &
xyz = pdat.get_field<Tvec>(0).get_buf();
154 auto acc =
xyz.copy_to_stdvec();
156 u32 cnt = pdat.get_obj_cnt();
158 for (
u32 i = 0; i < cnt; i++) {
159 acc[i] = map(acc[i]);
162 xyz.copy_from_stdvec(acc);
165 modules::ComputeLoadBalanceValue<Tvec, SPHKernel>(ctx, solver.solver_config, solver.storage)
166 .update_load_balancing();
175 reatrib.reatribute_patch_objects(sptree,
"xyz");
176 sched.check_patchdata_locality_correctness();
179 modules::ComputeLoadBalanceValue<Tvec, SPHKernel>(ctx, solver.solver_config, solver.storage)
180 .update_load_balancing();
190 reatrib.reatribute_patch_objects(sptree,
"xyz");
191 sched.check_patchdata_locality_correctness();
208 auto [m, M] = sched.get_box_tranform<Tvec>();
216 reatrib.reatribute_patch_objects(sptree,
"xyz");
217 sched.check_patchdata_locality_correctness();
229 reatrib.reatribute_patch_objects(sptree,
"xyz");
230 sched.check_patchdata_locality_correctness();
233 std::string log =
"";
235 using namespace shamrock::patch;
238 u32 largest_count = 0;
241 u32 tmp = pdat.get_obj_cnt();
242 smallest_count = sham::min(tmp, smallest_count);
243 largest_count = sham::max(tmp, largest_count);
246 smallest_count = shamalgs::collective::allreduce_min(smallest_count);
247 largest_count = shamalgs::collective::allreduce_max(largest_count);
251 "Model",
"current particle counts : min = ", smallest_count,
"max = ", largest_count);
266template<
class Tvec,
template<
class>
class SPHKernel>
267void shammodels::sph::Model<Tvec, SPHKernel>::push_particle(
268 std::vector<Tvec> &part_pos_insert,
269 std::vector<Tscal> &part_hpart_insert,
270 std::vector<Tscal> &part_u_insert) {
273 using namespace shamrock::patch;
277 std::string log =
"";
284 std::vector<Tvec> vec_acc;
285 std::vector<Tscal> hpart_acc;
286 std::vector<Tscal> u_acc;
287 for (
u32 i = 0; i < part_pos_insert.size(); i++) {
288 Tvec r = part_pos_insert[i];
289 Tscal u = part_u_insert[i];
290 if (patch_coord.contain_pos(r)) {
291 vec_acc.push_back(r);
292 hpart_acc.push_back(part_hpart_insert[i]);
297 if (vec_acc.size() == 0) {
301 log += shambase::format(
302 "\n rank = {} patch id={}, add N={} particles, coords = {} {}",
310 tmp.resize(vec_acc.size());
314 u32 len = vec_acc.size();
316 = tmp.get_field<Tvec>(sched.pdl_old().get_field_idx<Tvec>(
"xyz"));
317 sycl::buffer<Tvec> buf(vec_acc.data(), len);
318 f.override(buf, len);
322 u32 len = vec_acc.size();
324 = tmp.get_field<Tscal>(sched.pdl_old().get_field_idx<Tscal>(
"hpart"));
325 sycl::buffer<Tscal> buf(hpart_acc.data(), len);
326 f.override(buf, len);
330 u32 len = u_acc.size();
332 = tmp.get_field<Tscal>(sched.pdl_old().get_field_idx<Tscal>(
"uint"));
333 sycl::buffer<Tscal> buf(u_acc.data(), len);
334 f.override(buf, len);
337 pdat.insert_elements(tmp);
339 sched.check_patchdata_locality_correctness();
341 std::string log_gathered =
"";
349 modules::ComputeLoadBalanceValue<Tvec, SPHKernel>(ctx, solver.solver_config, solver.storage)
350 .update_load_balancing();
352 post_insert_data<Tvec>(sched);
356template<
class Tvec,
template<
class>
class SPHKernel>
357void shammodels::sph::Model<Tvec, SPHKernel>::push_particle_mhd(
358 std::vector<Tvec> &part_pos_insert,
359 std::vector<Tscal> &part_hpart_insert,
360 std::vector<Tscal> &part_u_insert,
361 std::vector<Tvec> &part_B_on_rho_insert,
362 std::vector<Tscal> &part_psi_on_ch_insert) {
365 using namespace shamrock::patch;
369 std::string log =
"";
376 std::vector<Tvec> vec_acc;
377 std::vector<Tscal> hpart_acc;
378 std::vector<Tscal> u_acc;
379 std::vector<Tvec> B_on_rho_acc;
380 std::vector<Tscal> psi_on_ch_acc;
381 for (
u32 i = 0; i < part_pos_insert.size(); i++) {
382 Tvec r = part_pos_insert[i];
383 Tscal u = part_u_insert[i];
384 if (patch_coord.contain_pos(r)) {
385 vec_acc.push_back(r);
386 hpart_acc.push_back(part_hpart_insert[i]);
388 B_on_rho_acc.push_back(part_B_on_rho_insert[i]);
389 psi_on_ch_acc.push_back(part_psi_on_ch_insert[i]);
393 if (vec_acc.size() == 0) {
397 log += shambase::format(
398 "\n rank = {} patch id={}, add N={} particles, coords = {} {}",
406 tmp.resize(vec_acc.size());
410 u32 len = vec_acc.size();
412 = tmp.get_field<Tvec>(sched.pdl_old().get_field_idx<Tvec>(
"xyz"));
413 sycl::buffer<Tvec> buf(vec_acc.data(), len);
414 f.override(buf, len);
418 u32 len = vec_acc.size();
420 = tmp.get_field<Tscal>(sched.pdl_old().get_field_idx<Tscal>(
"hpart"));
421 sycl::buffer<Tscal> buf(hpart_acc.data(), len);
422 f.override(buf, len);
426 u32 len = u_acc.size();
428 = tmp.get_field<Tscal>(sched.pdl_old().get_field_idx<Tscal>(
"uint"));
429 sycl::buffer<Tscal> buf(u_acc.data(), len);
430 f.override(buf, len);
434 u32 len = vec_acc.size();
436 = tmp.get_field<Tvec>(sched.pdl_old().get_field_idx<Tvec>(
"B/rho"));
437 sycl::buffer<Tvec> buf(B_on_rho_acc.data(), len);
438 f.override(buf, len);
442 u32 len = vec_acc.size();
444 = tmp.get_field<Tscal>(sched.pdl_old().get_field_idx<Tscal>(
"psi/ch"));
445 sycl::buffer<Tscal> buf(psi_on_ch_acc.data(), len);
446 f.override(buf, len);
449 pdat.insert_elements(tmp);
451 sched.check_patchdata_locality_correctness();
453 std::string log_gathered =
"";
461 modules::ComputeLoadBalanceValue<Tvec, SPHKernel>(ctx, solver.solver_config, solver.storage)
462 .update_load_balancing();
464 post_insert_data<Tvec>(sched);
468template<
class Tvec,
template<
class>
class SPHKernel>
469void shammodels::sph::Model<Tvec, SPHKernel>::add_cube_hcp_3d(
470 Tscal dr, std::pair<Tvec, Tvec> _box) {
478 using namespace shamrock::patch;
485 auto [idxs_min, idxs_max] = Lattice::get_box_index_bounds(dr, box.lower, box.upper);
487 LatticeIter gen = LatticeIter(dr, idxs_min, idxs_max);
491 std::string log =
"";
492 while (!gen.is_done()) {
495 u64 loc_sum_ins_cnt = 0;
497 u64 max_loc_sum_ins_cnt = 0;
501 acc_count += to_ins.size();
508 std::vector<Tvec> vec_acc;
509 for (Tvec r : to_ins) {
510 if (patch_coord.contain_pos(r)) {
511 vec_acc.push_back(r);
516 loc_sum_ins_cnt += vec_acc.size();
518 if (vec_acc.size() == 0) {
522 log += shambase::format(
523 "\n rank = {} patch id={}, add N={} particles, coords = {} {}",
531 pdat.reserve(vec_acc.size());
534 tmp.resize(vec_acc.size());
538 u32 len = vec_acc.size();
540 = tmp.get_field<Tvec>(sched.pdl_old().get_field_idx<Tvec>(
"xyz"));
542 f.override(vec_acc, len);
547 = tmp.get_field<Tscal>(sched.pdl_old().get_field_idx<Tscal>(
"hpart"));
551 pdat.insert_elements(tmp);
554 max_loc_sum_ins_cnt = shamalgs::collective::allreduce_max(loc_sum_ins_cnt);
559 "--> insertion loop : max loc insert count = ",
564 }
while (!gen.is_done() && max_loc_sum_ins_cnt < sched.
crit_patch_split * 8);
566 sched.check_patchdata_locality_correctness();
578 modules::ComputeLoadBalanceValue<Tvec, SPHKernel>(ctx, solver.solver_config, solver.storage)
579 .update_load_balancing();
580 post_insert_data<Tvec>(sched);
584 modules::ParticleReordering<Tvec, u32, SPHKernel>(ctx, solver.solver_config, solver.storage)
585 .reorder_particles();
594template<
class Tvec,
template<
class>
class SPHKernel>
595void shammodels::sph::Model<Tvec, SPHKernel>::add_cube_hcp_3d_v2(
596 Tscal dr, std::pair<Tvec, Tvec> _box) {
602 using namespace shamrock::patch;
609 auto [idxs_min, idxs_max] = Lattice::get_box_index_bounds(dr, box.lower, box.upper);
611 LatticeIter gen = LatticeIter(dr, idxs_min, idxs_max);
615 auto push_current_data = [&](std::vector<Tvec> pos_data) {
617 tmp.resize(pos_data.size());
621 u32 len = pos_data.size();
623 = tmp.get_field<Tvec>(sched.pdl_old().get_field_idx<Tvec>(
"xyz"));
625 f.override(pos_data, len);
630 = tmp.get_field<Tscal>(sched.pdl_old().get_field_idx<Tscal>(
"hpart"));
634 inserter.push_patch_data<Tvec>(tmp,
"xyz", sched.
crit_patch_split * 8, [&]() {
635 modules::ComputeLoadBalanceValue<Tvec, SPHKernel>(
636 ctx, solver.solver_config, solver.storage)
637 .update_load_balancing();
646 auto has_pdat = [&]() {
655 while (!gen.is_done()) {
657 u64 loc_gen_count = (has_pdat()) ? insert_step : 0;
659 auto gen_info = shamalgs::collective::fetch_view(loc_gen_count);
661 u64 skip_start = gen_info.head_offset;
662 u64 gen_cnt = loc_gen_count;
663 u64 skip_end = gen_info.total_byte_count - loc_gen_count - gen_info.head_offset;
672 skip_start + gen_cnt + skip_end);
673 gen.skip(skip_start);
674 auto tmp = gen.next_n(gen_cnt);
677 std::vector<Tvec> pos_data;
680 pos_data.push_back(r);
684 push_current_data(pos_data);
686 shamlog_debug_ln(
"Gen",
"gen.is_done()", gen.is_done());
698 using Tscal = shambase::VecComponent<Tvec>;
718 std::function<Tscal(Tscal)> sigma_profile;
719 std::function<Tscal(Tscal)> cs_profile;
720 std::function<Tscal(Tscal)> rot_profile;
721 std::function<Tscal(Tscal)> vel_full_corr;
736 std::function<Tscal(Tscal)> sigma_profile,
737 std::function<Tscal(Tscal)> cs_profile,
738 std::function<Tscal(Tscal)> rot_profile)
739 : current_index(0), Npart(Npart), center(center), central_mass(central_mass),
740 r_in(r_in), r_out(r_out), disc_mass(disc_mass), p(p), H_r_in(H_r_in), q(q), G(G),
741 eng(eng), sigma_profile(sigma_profile), cs_profile(cs_profile),
742 rot_profile(rot_profile) {
749 inline bool is_done() {
return done; }
753 constexpr Tscal _2pi = 2 * shambase::constants::pi<Tscal>;
755 auto f_func = [&](Tscal r) {
756 return r * sigma_profile(r);
759 Tscal fmax = f_func(r_out);
761 auto find_r = [&]() {
765 if (u2 < f_func(r)) {
772 auto Gauss = shamalgs::random::mock_gaussian<Tscal>(eng);
777 Tscal vk = rot_profile(r);
778 Tscal cs = cs_profile(r);
779 Tscal sigma = sigma_profile(r);
781 Tscal Omega_Kep = sycl::sqrt(G * central_mass / (r * r * r));
785 Tscal H = sycl::sqrt(2.) * 3. * cs
790 auto pos = sycl::vec<Tscal, 3>{r * sycl::cos(theta), z, r * sycl::sin(theta)};
792 auto etheta = sycl::vec<Tscal, 3>{-pos.z(), 0, pos.x()};
793 etheta /= sycl::length(etheta);
795 auto vel = vk * etheta;
800 Tscal fs = 1. - sycl::sqrt(r_in / r);
801 Tscal rho = (sigma * fs) * sycl::exp(-z * z / (2 * H * H));
803 Out out{pos, vel, cs, rho};
807 if (current_index == Npart) {
814 inline std::vector<Out> next_n(
u32 nmax) {
815 std::vector<Out> ret{};
816 for (
u32 i = 0; i < nmax; i++) {
821 ret.push_back(next());
828template<
class Tvec,
template<
class>
class SPHKernel>
829void shammodels::sph::Model<Tvec, SPHKernel>::add_big_disc_3d(
842 using Config = SolverConfig;
843 using SolverConfigEOS =
typename Config::EOSConfig;
844 using SolverEOS_Adiabatic =
typename SolverConfigEOS::Adiabatic;
845 if (SolverEOS_Adiabatic *eos_config
846 = std::get_if<SolverEOS_Adiabatic>(&solver.solver_config.eos_config.config)) {
848 eos_gamma = eos_config->gamma;
856 auto sigma_profile = [=](Tscal r) {
858 constexpr Tscal sigma_0 = 1;
859 return sigma_0 * sycl::pow(r / r_in, -p);
862 auto cs_law = [=](Tscal r) {
863 return sycl::pow(r / r_in, -q);
866 auto kep_profile = [&](Tscal r) {
867 Tscal G = solver.solver_config.get_constant_G();
868 return sycl::sqrt(G * central_mass / r);
871 auto rot_profile = [&](Tscal r) -> Tscal {
873 Tscal G = solver.solver_config.get_constant_G();
874 Tscal c = solver.solver_config.get_constant_c();
876 Tscal term = G * central_mass / r;
877 Tscal term_fs = 1. - sycl::sqrt(r_in / r);
879 = -sycl::pown(cs_law(r), 2) * (1.5 + p + q);
881 Tscal det = sycl::pown(term_bh, 2) + 4. * (term + term_pr);
882 Tscal Rg = G * central_mass / sycl::pown(c, 2);
883 Tscal vkep = sqrt(G * central_mass / r);
885 Tscal vphi = 0.5 * (term_bh + sycl::sqrt(det));
890 auto cs_profile = [&](Tscal r) {
891 Tscal cs_in = (H_r_in * r_in / r) * kep_profile(r_in);
892 return cs_law(r) * cs_in;
895 auto get_hfact = []() -> Tscal {
896 return Kernel::hfactd;
899 auto int_rho_h = [&](Tscal h) -> Tscal {
900 return shamrock::sph::rho_h(solver.solver_config.gpart_mass, h, Kernel::hfactd);
903 Tscal part_mass = disc_mass / Npart;
910 using namespace shamrock::patch;
917 Tscal G = solver.solver_config.get_constant_G();
936 std::string log =
"";
937 while (!gen.is_done()) {
940 u64 loc_sum_ins_cnt = 0;
942 u64 max_loc_sum_ins_cnt = 0;
946 acc_count += to_ins.size();
953 std::vector<Out> part_list;
954 for (Out r : to_ins) {
955 if (patch_coord.contain_pos(r.pos)) {
957 part_list.push_back(r);
962 loc_sum_ins_cnt += part_list.size();
964 if (part_list.size() == 0) {
968 log += shambase::format(
969 "\n rank = {} patch id={}, add N={} particles, coords = {} {}",
977 std::vector<Tvec> vec_pos;
978 std::vector<Tvec> vec_vel;
979 std::vector<Tscal> vec_u;
980 std::vector<Tscal> vec_h;
981 std::vector<Tscal> vec_cs;
983 for (Out o : part_list) {
984 vec_pos.push_back(o.pos);
985 vec_vel.push_back(o.velocity);
986 vec_u.push_back(o.cs * o.cs / ( (eos_gamma - 1)));
987 vec_h.push_back(shamrock::sph::h_rho(part_mass, o.rho * 0.1, Kernel::hfactd));
988 vec_cs.push_back(o.cs);
992 pdat.reserve(vec_pos.size());
995 tmp.resize(vec_pos.size());
999 u32 len = vec_pos.size();
1001 = tmp.get_field<Tvec>(sched.pdl_old().get_field_idx<Tvec>(
"xyz"));
1002 sycl::buffer<Tvec> buf(vec_pos.data(), len);
1003 f.override(buf, len);
1007 u32 len = vec_pos.size();
1009 = tmp.get_field<Tscal>(sched.pdl_old().get_field_idx<Tscal>(
"hpart"));
1010 sycl::buffer<Tscal> buf(vec_h.data(), len);
1011 f.override(buf, len);
1015 u32 len = vec_pos.size();
1017 = tmp.get_field<Tscal>(sched.pdl_old().get_field_idx<Tscal>(
"uint"));
1018 sycl::buffer<Tscal> buf(vec_u.data(), len);
1019 f.override(buf, len);
1022 if (solver.solver_config.is_eos_locally_isothermal()) {
1023 u32 len = vec_pos.size();
1025 = tmp.get_field<Tscal>(sched.pdl_old().get_field_idx<Tscal>(
"soundspeed"));
1026 sycl::buffer<Tscal> buf(vec_cs.data(), len);
1027 f.override(buf, len);
1031 u32 len = vec_pos.size();
1033 = tmp.get_field<Tvec>(sched.pdl_old().get_field_idx<Tvec>(
"vxyz"));
1034 sycl::buffer<Tvec> buf(vec_vel.data(), len);
1035 f.override(buf, len);
1038 pdat.insert_elements(tmp);
1041 max_loc_sum_ins_cnt = shamalgs::collective::allreduce_max(loc_sum_ins_cnt);
1046 "--> insertion loop : max loc insert count = ",
1047 max_loc_sum_ins_cnt,
1051 }
while (!gen.is_done() && max_loc_sum_ins_cnt < sched.
crit_patch_split * 8);
1053 sched.check_patchdata_locality_correctness();
1065 modules::ComputeLoadBalanceValue<Tvec, SPHKernel>(ctx, solver.solver_config, solver.storage)
1066 .update_load_balancing();
1067 post_insert_data<Tvec>(sched);
1071 modules::ParticleReordering<Tvec, u32, SPHKernel>(ctx, solver.solver_config, solver.storage)
1072 .reorder_particles();
1081template<
class Tvec,
template<
class>
class SPHKernel>
1082void shammodels::sph::Model<Tvec, SPHKernel>::add_cube_fcc_3d(
1083 Tscal dr, std::pair<Tvec, Tvec> _box) {
1088 using namespace shamrock::patch;
1092 std::string log =
"";
1094 auto make_sliced = [&]() {
1095 std::vector<Tvec> vec_lst;
1096 generic::setup::generators::add_particles_fcc(
1098 {box.lower, box.upper},
1100 return box.contain_pos(r);
1102 [&](Tvec r, Tscal h) {
1103 vec_lst.push_back(r);
1106 std::vector<std::vector<Tvec>> sliced_buf;
1110 std::vector<Tvec> cur_buf;
1111 for (
u32 i = 0; i < vec_lst.size(); i++) {
1112 cur_buf.push_back(vec_lst[i]);
1114 if (cur_buf.size() > sz_buf) {
1115 sliced_buf.push_back(std::exchange(cur_buf, std::vector<Tvec>{}));
1119 if (cur_buf.size() > 0) {
1120 sliced_buf.push_back(std::exchange(cur_buf, std::vector<Tvec>{}));
1126 std::vector<std::vector<Tvec>> sliced_buf = make_sliced();
1128 for (std::vector<Tvec> to_ins : sliced_buf) {
1135 std::vector<Tvec> vec_acc;
1136 for (Tvec r : to_ins) {
1137 if (patch_coord.contain_pos(r)) {
1138 vec_acc.push_back(r);
1142 if (vec_acc.size() == 0) {
1146 log += shambase::format(
1147 "\n rank = {} patch id={}, add N={} particles, coords = {} {}",
1155 tmp.resize(vec_acc.size());
1159 u32 len = vec_acc.size();
1161 = tmp.get_field<Tvec>(sched.pdl_old().get_field_idx<Tvec>(
"xyz"));
1162 sycl::buffer<Tvec> buf(vec_acc.data(), len);
1163 f.override(buf, len);
1168 = tmp.get_field<Tscal>(sched.pdl_old().get_field_idx<Tscal>(
"hpart"));
1172 pdat.insert_elements(tmp);
1175 sched.check_patchdata_locality_correctness();
1177 std::string log_gathered =
"";
1185 modules::ComputeLoadBalanceValue<Tvec, SPHKernel>(ctx, solver.solver_config, solver.storage)
1186 .update_load_balancing();
1187 post_insert_data<Tvec>(sched);
1191template<
class Tvec,
template<
class>
class SPHKernel>
1192auto shammodels::sph::Model<Tvec, SPHKernel>::gen_config_from_phantom_dump(
1193 PhantomDump &phdump,
bool bypass_error) -> SolverConfig {
1195 SolverConfig conf{};
1197 auto massoftype = phdump.read_header_floats<Tscal>(
"massoftype");
1199 conf.gpart_mass = massoftype[0];
1200 conf.cfl_config.cfl_cour = phdump.read_header_float<Tscal>(
"C_cour");
1201 conf.cfl_config.cfl_force = phdump.read_header_float<Tscal>(
"C_force");
1203 conf.eos_config = get_shamrock_eosconfig<Tvec>(phdump, bypass_error);
1204 conf.artif_viscosity = get_shamrock_avconfig<Tvec>(phdump);
1206 conf.set_units(get_shamrock_units<Tscal>(phdump));
1208 conf.boundary_config = get_shamrock_boundary_config<Tvec>(phdump);
1213template<
class Tvec,
template<
class>
class SPHKernel>
1214void shammodels::sph::Model<Tvec, SPHKernel>::init_from_phantom_dump(
1215 PhantomDump &phdump, Tscal hpart_fact_load) {
1218 bool has_coord_in_header =
true;
1220 Tscal xmin, xmax, ymin, ymax, zmin, zmax;
1221 has_coord_in_header = phdump.has_header_entry(
"xmin");
1223 std::string log =
"";
1226 std::vector<Tscal> h, u, alpha;
1229 std::vector<Tscal> x, y, z, vx, vy, vz;
1231 phdump.blocks[0].fill_vec(
"x", x);
1232 phdump.blocks[0].fill_vec(
"y", y);
1233 phdump.blocks[0].fill_vec(
"z", z);
1235 if (has_coord_in_header) {
1236 xmin = phdump.read_header_float<
f64>(
"xmin");
1237 xmax = phdump.read_header_float<
f64>(
"xmax");
1238 ymin = phdump.read_header_float<
f64>(
"ymin");
1239 ymax = phdump.read_header_float<
f64>(
"ymax");
1240 zmin = phdump.read_header_float<
f64>(
"zmin");
1241 zmax = phdump.read_header_float<
f64>(
"zmax");
1243 resize_simulation_box({{xmin, ymin, zmin}, {xmax, ymax, zmax}});
1245 Tscal box_tolerance = 1.2;
1247 xmin = *std::min_element(x.begin(), x.end());
1248 xmax = *std::max_element(x.begin(), x.end());
1249 ymin = *std::min_element(y.begin(), y.end());
1250 ymax = *std::max_element(y.begin(), y.end());
1251 zmin = *std::min_element(z.begin(), z.end());
1252 zmax = *std::max_element(z.begin(), z.end());
1254 Tvec bm = {xmin, ymin, zmin};
1255 Tvec bM = {xmax, ymax, zmax};
1257 Tvec center = (bm + bM) * 0.5;
1259 Tvec d = (bM - bm) * 0.5;
1264 resize_simulation_box({center - d, center + d});
1267 phdump.blocks[0].fill_vec(
"h", h);
1269 phdump.blocks[0].fill_vec(
"vx", vx);
1270 phdump.blocks[0].fill_vec(
"vy", vy);
1271 phdump.blocks[0].fill_vec(
"vz", vz);
1273 phdump.blocks[0].fill_vec(
"u", u);
1274 phdump.blocks[0].fill_vec(
"alpha", alpha);
1276 for (
u32 i = 0; i < x.size(); i++) {
1277 xyz.push_back({x[i], y[i], z[i]});
1279 for (
u32 i = 0; i < vx.size(); i++) {
1280 vxyz.push_back({vx[i], vy[i], vz[i]});
1285 f64 time_phdump = phdump.read_header_float<
f64>(
"time");
1286 solver.solver_config.set_time(time_phdump);
1288 using namespace shamrock::patch;
1296 std::vector<u64> insert_ranges;
1297 insert_ranges.push_back(0);
1298 for (
u64 i = sz_buf; i < Ntot; i += sz_buf) {
1299 insert_ranges.push_back(i);
1301 insert_ranges.push_back(Ntot);
1303 for (
u64 krange = 0; krange < insert_ranges.size() - 1; krange++) {
1304 u64 start_id = insert_ranges[krange];
1305 u64 end_id = insert_ranges[krange + 1];
1307 u64 Nloc = end_id - start_id;
1314 std::vector<u64> sel_index;
1315 for (
u64 i = start_id; i < end_id; i++) {
1318 if (patch_coord.contain_pos(r) && (h_ >= 0)) {
1319 sel_index.push_back(i);
1323 if (sel_index.size() == 0) {
1327 log += shambase::format(
1328 "\n rank = {} patch id={}, add N={} particles, coords = {} {}",
1335 std::vector<Tvec> ins_xyz, ins_vxyz;
1336 std::vector<Tscal> ins_h, ins_u, ins_alpha;
1337 for (
u64 i : sel_index) {
1338 ins_xyz.push_back(xyz[i]);
1340 for (
u64 i : sel_index) {
1341 ins_vxyz.push_back(vxyz[i]);
1343 for (
u64 i : sel_index) {
1344 ins_h.push_back(h[i] * hpart_fact_load);
1347 for (
u64 i : sel_index) {
1348 ins_u.push_back(u[i]);
1351 if (alpha.size() > 0) {
1352 for (
u64 i : sel_index) {
1353 ins_alpha.push_back(alpha[i]);
1358 ptmp.resize(sel_index.size());
1361 ptmp.override_patch_field(
"xyz", ins_xyz);
1362 ptmp.override_patch_field(
"vxyz", ins_vxyz);
1363 ptmp.override_patch_field(
"hpart", ins_h);
1365 if (ins_alpha.size() > 0) {
1366 ptmp.override_patch_field(
"alpha_AV", ins_alpha);
1369 if (ins_u.size() > 0) {
1370 ptmp.override_patch_field(
"uint", ins_u);
1373 pdat.insert_elements(ptmp);
1376 sched.check_patchdata_locality_correctness();
1378 std::string log_gathered =
"";
1386 modules::ComputeLoadBalanceValue<Tvec, SPHKernel>(ctx, solver.solver_config, solver.storage)
1387 .update_load_balancing();
1389 post_insert_data<Tvec>(sched);
1393 PhantomDumpBlock &sink_block = phdump.blocks[1];
1395 std::vector<Tscal> xsink, ysink, zsink;
1396 std::vector<Tscal> vxsink, vysink, vzsink;
1397 std::vector<Tscal> mass;
1398 std::vector<Tscal> Racc;
1400 sink_block.fill_vec(
"x", xsink);
1401 sink_block.fill_vec(
"y", ysink);
1402 sink_block.fill_vec(
"z", zsink);
1403 sink_block.fill_vec(
"vx", vxsink);
1404 sink_block.fill_vec(
"vy", vysink);
1405 sink_block.fill_vec(
"vz", vzsink);
1406 sink_block.fill_vec(
"m", mass);
1407 sink_block.fill_vec(
"h", Racc);
1409 for (
u32 i = 0; i < xsink.size(); i++) {
1412 {xsink[i], ysink[i], zsink[i]},
1413 {vxsink[i], vysink[i], vzsink[i]},
1420template<
class Tvec,
template<
class>
class SPHKernel>
1421void shammodels::sph::Model<Tvec, SPHKernel>::add_pdat_to_phantom_block(
1426 u64 xid = block.get_ref_fort_real(
"x");
1427 u64 yid = block.get_ref_fort_real(
"y");
1428 u64 zid = block.get_ref_fort_real(
"z");
1430 for (
auto vec : xyz) {
1431 block.blocks_fort_real[xid].vals.push_back(
vec.x());
1432 block.blocks_fort_real[yid].vals.push_back(
vec.y());
1433 block.blocks_fort_real[zid].vals.push_back(
vec.z());
1436 std::vector<Tscal> h = pdat.
fetch_data<Tscal>(
"hpart");
1437 u64 hid = block.get_ref_f32(
"h");
1439 block.blocks_f32[hid].vals.push_back(h_);
1442 if (solver.solver_config.has_field_alphaAV()) {
1443 std::vector<Tscal> alpha = pdat.
fetch_data<Tscal>(
"alpha_AV");
1444 u64 aid = block.get_ref_f32(
"alpha");
1445 for (
auto alp_ : alpha) {
1446 block.blocks_f32[aid].vals.push_back(alp_);
1450 if (solver.solver_config.has_field_divv()) {
1451 std::vector<Tscal> vecdivv = pdat.
fetch_data<Tscal>(
"divv");
1452 u64 divvid = block.get_ref_f32(
"divv");
1453 for (
auto d_ : vecdivv) {
1454 block.blocks_f32[divvid].vals.push_back(d_);
1460 u64 vxid = block.get_ref_fort_real(
"vx");
1461 u64 vyid = block.get_ref_fort_real(
"vy");
1462 u64 vzid = block.get_ref_fort_real(
"vz");
1464 for (
auto vec : vxyz) {
1465 block.blocks_fort_real[vxid].vals.push_back(
vec.x());
1466 block.blocks_fort_real[vyid].vals.push_back(
vec.y());
1467 block.blocks_fort_real[vzid].vals.push_back(
vec.z());
1470 std::vector<Tscal> u = pdat.
fetch_data<Tscal>(
"uint");
1471 u64 uid = block.get_ref_fort_real(
"u");
1473 block.blocks_fort_real[uid].vals.push_back(u_);
1476 block.tot_count = block.blocks_fort_real[xid].vals.size();
1479template<
class Tvec,
template<
class>
class SPHKernel>
1485 bool bypass_error_check =
false;
1487 auto get_sink_count = [&]() ->
int {
1488 if (solver.storage.sinks.is_empty()) {
1491 return int(solver.storage.sinks.get().size());
1495 dump.override_magic_number();
1497 dump.fileid = shambase::format(
"{:100s}",
"FT:Phantom Shamrock writer");
1499 u32 Ntot = get_total_part_count();
1500 dump.table_header_fort_int.add(
"nparttot", Ntot);
1501 dump.table_header_fort_int.add(
"ntypes", 8);
1502 dump.table_header_fort_int.add(
"npartoftype", Ntot);
1503 dump.table_header_fort_int.add(
"npartoftype", 0);
1504 dump.table_header_fort_int.add(
"npartoftype", 0);
1505 dump.table_header_fort_int.add(
"npartoftype", 0);
1506 dump.table_header_fort_int.add(
"npartoftype", 0);
1507 dump.table_header_fort_int.add(
"npartoftype", 0);
1508 dump.table_header_fort_int.add(
"npartoftype", 0);
1509 dump.table_header_fort_int.add(
"npartoftype", 0);
1511 dump.table_header_i64.add(
"nparttot", Ntot);
1512 dump.table_header_i64.add(
"ntypes", 8);
1513 dump.table_header_i64.add(
"npartoftype", Ntot);
1514 dump.table_header_i64.add(
"npartoftype", 0);
1515 dump.table_header_i64.add(
"npartoftype", 0);
1516 dump.table_header_i64.add(
"npartoftype", 0);
1517 dump.table_header_i64.add(
"npartoftype", 0);
1518 dump.table_header_i64.add(
"npartoftype", 0);
1519 dump.table_header_i64.add(
"npartoftype", 0);
1520 dump.table_header_i64.add(
"npartoftype", 0);
1522 dump.table_header_fort_int.add(
"nblocks", 1);
1523 dump.table_header_fort_int.add(
"nptmass", get_sink_count());
1524 dump.table_header_fort_int.add(
"ndustlarge", 0);
1525 dump.table_header_fort_int.add(
"ndustsmall", 0);
1526 dump.table_header_fort_int.add(
"idust", 7);
1527 dump.table_header_fort_int.add(
"idtmax_n", 1);
1528 dump.table_header_fort_int.add(
"idtmax_frac", 0);
1529 dump.table_header_fort_int.add(
"idumpfile", 0);
1530 dump.table_header_fort_int.add(
"majorv", 2023);
1531 dump.table_header_fort_int.add(
"minorv", 0);
1532 dump.table_header_fort_int.add(
"microv", 0);
1533 dump.table_header_fort_int.add(
"isink", 0);
1535 dump.table_header_i32.add(
"iexternalforce", 0);
1539 dump.table_header_fort_real.add(
"time", solver.solver_config.get_time());
1540 dump.table_header_fort_real.add(
"dtmax", solver.solver_config.get_dt_sph());
1542 dump.table_header_fort_real.add(
"rhozero", 0);
1543 dump.table_header_fort_real.add(
"hfact", Kernel::hfactd);
1544 dump.table_header_fort_real.add(
"tolh", 0.0001);
1545 dump.table_header_fort_real.add(
"C_cour", solver.solver_config.cfl_config.cfl_cour);
1546 dump.table_header_fort_real.add(
"C_force", solver.solver_config.cfl_config.cfl_force);
1547 dump.table_header_fort_real.add(
"alpha", 0);
1548 dump.table_header_fort_real.add(
"alphau", 1);
1549 dump.table_header_fort_real.add(
"alphaB", 1);
1551 dump.table_header_fort_real.add(
"massoftype", solver.solver_config.gpart_mass);
1552 dump.table_header_fort_real.add(
"massoftype", 0);
1553 dump.table_header_fort_real.add(
"massoftype", 0);
1554 dump.table_header_fort_real.add(
"massoftype", 0);
1555 dump.table_header_fort_real.add(
"massoftype", 0);
1556 dump.table_header_fort_real.add(
"massoftype", 0);
1557 dump.table_header_fort_real.add(
"massoftype", 0);
1558 dump.table_header_fort_real.add(
"massoftype", 0);
1560 dump.table_header_fort_real.add(
"Bextx", 0);
1561 dump.table_header_fort_real.add(
"Bexty", 0);
1562 dump.table_header_fort_real.add(
"Bextz", 0);
1563 dump.table_header_fort_real.add(
"dum", 0);
1567 auto box_size = sched.get_box_volume<Tvec>();
1569 write_shamrock_boundaries_in_phantom_dump(
1570 solver.solver_config.boundary_config, box_size, dump, bypass_error_check);
1572 dump.table_header_fort_real.add(
"get_conserv", -1);
1573 dump.table_header_fort_real.add(
"etot_in", 0.59762);
1574 dump.table_header_fort_real.add(
"angtot_in", 0.0189694);
1575 dump.table_header_fort_real.add(
"totmom_in", 0.0306284);
1579 PhantomDumpBlock block_part;
1583 std::vector<std::unique_ptr<shamrock::patch::PatchDataLayer>> gathered
1584 = ctx.allgather_data();
1586 for (
auto &dat : gathered) {
1591 dump.blocks.push_back(std::move(block_part));
1593 if (!solver.storage.sinks.is_empty()) {
1595 auto &sinks = solver.storage.sinks.get();
1597 PhantomDumpBlock sink_block;
1599 u64 xid = sink_block.get_ref_fort_real(
"x");
1600 u64 yid = sink_block.get_ref_fort_real(
"y");
1601 u64 zid = sink_block.get_ref_fort_real(
"z");
1602 u64 mid = sink_block.get_ref_fort_real(
"m");
1603 u64 hid = sink_block.get_ref_fort_real(
"h");
1604 u64 vxid = sink_block.get_ref_fort_real(
"vx");
1605 u64 vyid = sink_block.get_ref_fort_real(
"vy");
1606 u64 vzid = sink_block.get_ref_fort_real(
"vz");
1608 for (SinkParticle<Tvec> s : sinks) {
1609 sink_block.blocks_fort_real[xid].vals.push_back(s.pos.x());
1610 sink_block.blocks_fort_real[yid].vals.push_back(s.pos.y());
1611 sink_block.blocks_fort_real[zid].vals.push_back(s.pos.z());
1612 sink_block.blocks_fort_real[mid].vals.push_back(s.mass);
1613 sink_block.blocks_fort_real[hid].vals.push_back(s.accretion_radius);
1614 sink_block.blocks_fort_real[vxid].vals.push_back(s.velocity.x());
1615 sink_block.blocks_fort_real[vyid].vals.push_back(s.velocity.y());
1616 sink_block.blocks_fort_real[vzid].vals.push_back(s.velocity.z());
1619 sink_block.tot_count = sinks.size();
1621 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.
f64 elapsed_sec() const
Converts the stored nanosecond time to a floating point representation in seconds.
void start()
Starts the timer.
void stop()
Stops the timer and stores the elapsed time in nanoseconds.
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.
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.
T mock_value(Engine &eng, T min_bound, T max_bound)
Generates a random mock value within specified bounds.
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...
ExcptTypes make_except_with_loc(std::string message, SourceLocation loc=SourceLocation{})
Create an exception with a message and a location.
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
void info_ln(std::string module_name, Types... var2)
Prints a log message with multiple arguments followed by a newline.
This file contains the definition for the stacktrace related functionality.
shambase::details::NamedBasicStackEntry NamedStackEntry
Alias for shambase::details::NamedBasicStackEntry.
shambase::details::BasicStackEntry StackEntry
Alias for shambase::details::BasicStackEntry.
Class representing a Phantom dump file.
Patch object that contain generic patch information.
static bool is_in_patch_converted(sycl::vec< T, 3 > val, sycl::vec< T, 3 > min_val, sycl::vec< T, 3 > max_val)
check if particle is in the asked range, given the output of @convert_coord