39#define NODE_EDGES(X_RO, X_RW, X_RO_OPTIONAL, X_RW_OPTIONAL) \
41 X_RO(shamrock::solvergraph::IDataEdge<Tscal>, cs) \
42 X_RO(shamrock::solvergraph::IDataEdge<Tscal>, hfactd) \
43 X_RO(shamrock::solvergraph::IDataEdge<Tscal>, pmass) \
44 X_RO_OPTIONAL(shamrock::solvergraph::IFieldSpan<Tscal>, spans_rho) \
45 X_RO_OPTIONAL(shamrock::solvergraph::IFieldSpan<Tscal>, spans_h) \
46 X_RO(shamrock::solvergraph::Indexes<u32>, sizes) \
49 X_RW(shamrock::solvergraph::IFieldSpan<Tscal>, spans_pressure) \
50 X_RW(shamrock::solvergraph::IFieldSpan<Tscal>, spans_soundspeed)
52namespace shammodels::common::modules {
56 using Tscal = shambase::VecComponent<Tvec>;
59 ComputeEOSIsothermal() =
default;
61 EXPAND_NODE_EDGES_OPTIONAL(NODE_EDGES)
63 inline static void internal_eos(
64 const Tscal &cs,
const Tscal &rho, Tscal &pressure, Tscal &soundspeed)
noexcept {
66 Tscal P_a = EOS::pressure(cs, rho);
75 auto edges = get_edges();
77 bool has_rho = edges.spans_rho.has_value();
78 bool has_h = edges.spans_h.has_value();
81 if ((has_rho && has_h) || (!has_rho && !has_h)) {
83 "Must have either rho or h");
86 edges.spans_pressure.ensure_sizes(edges.sizes.indexes);
87 edges.spans_soundspeed.ensure_sizes(edges.sizes.indexes);
89 Tscal cs = edges.cs.data;
90 Tscal pmass = edges.pmass.data;
91 Tscal hfactd = edges.hfactd.data;
93 auto dev_sched = shamsys::instance::get_compute_scheduler_ptr();
96 edges.spans_pressure.get_spans(), edges.spans_soundspeed.get_spans()};
99 auto &spans_rho = edges.spans_rho.value().get();
100 spans_rho.check_sizes(edges.sizes.indexes);
107 [cs](
u32 gid,
const Tscal *rho, Tscal *pressure, Tscal *soundspeed) {
108 Tscal rho_a = rho[gid];
109 internal_eos(cs, rho_a, pressure[gid], soundspeed[gid]);
112 auto &spans_h = edges.spans_h.value().get();
113 spans_h.check_sizes(edges.sizes.indexes);
121 u32 gid,
const Tscal *h, Tscal *pressure, Tscal *soundspeed) {
122 using namespace shamrock::sph;
123 Tscal rho = rho_h(pmass, h[gid], hfactd);
124 internal_eos(cs, rho, pressure[gid], soundspeed[gid]);
129 inline virtual std::string
_impl_get_label()
const {
return "ComputeEOSIsothermal"; };
137#define NODE_EDGES(X_RO, X_RW, X_RO_OPTIONAL, X_RW_OPTIONAL) \
139 X_RO(shamrock::solvergraph::IDataEdge<Tscal>, gamma) \
140 X_RO(shamrock::solvergraph::IDataEdge<Tscal>, hfactd) \
141 X_RO(shamrock::solvergraph::IDataEdge<Tscal>, pmass) \
142 X_RO_OPTIONAL(shamrock::solvergraph::IFieldSpan<Tscal>, spans_rho) \
143 X_RO_OPTIONAL(shamrock::solvergraph::IFieldSpan<Tscal>, spans_h) \
144 X_RO(shamrock::solvergraph::IFieldSpan<Tscal>, spans_uint) \
145 X_RO(shamrock::solvergraph::Indexes<u32>, sizes) \
148 X_RW(shamrock::solvergraph::IFieldSpan<Tscal>, spans_pressure) \
149 X_RW(shamrock::solvergraph::IFieldSpan<Tscal>, spans_soundspeed)
151namespace shammodels::common::modules {
155 using Tscal = shambase::VecComponent<Tvec>;
158 ComputeEOSAdiabatic() =
default;
160 EXPAND_NODE_EDGES_OPTIONAL(NODE_EDGES)
162 inline static void internal_eos(
167 Tscal &soundspeed)
noexcept {
169 Tscal P_a = EOS::pressure(gamma, rho, uint);
170 Tscal cs_a = EOS::cs_from_p(gamma, rho, P_a);
179 auto edges = get_edges();
181 bool has_rho = edges.spans_rho.has_value();
182 bool has_h = edges.spans_h.has_value();
185 if ((has_rho && has_h) || (!has_rho && !has_h)) {
187 "Must have either rho or h");
190 edges.spans_pressure.ensure_sizes(edges.sizes.indexes);
191 edges.spans_soundspeed.ensure_sizes(edges.sizes.indexes);
193 Tscal gamma = edges.gamma.data;
194 Tscal pmass = edges.pmass.data;
195 Tscal hfactd = edges.hfactd.data;
197 auto dev_sched = shamsys::instance::get_compute_scheduler_ptr();
200 edges.spans_pressure.get_spans(), edges.spans_soundspeed.get_spans()};
203 auto &spans_rho = edges.spans_rho.value().get();
204 spans_rho.check_sizes(edges.sizes.indexes);
217 Tscal rho_a = rho[gid];
218 Tscal uint_a = uint[gid];
219 internal_eos(gamma, rho_a, uint_a, pressure[gid], soundspeed[gid]);
222 auto &spans_h = edges.spans_h.value().get();
223 spans_h.check_sizes(edges.sizes.indexes);
230 [gamma, pmass, hfactd](
236 using namespace shamrock::sph;
237 Tscal rho = rho_h(pmass, h[gid], hfactd);
238 Tscal uint_a = uint[gid];
239 internal_eos(gamma, rho, uint_a, pressure[gid], soundspeed[gid]);
252#define NODE_EDGES(X_RO, X_RW, X_RO_OPTIONAL, X_RW_OPTIONAL) \
254 X_RO(shamrock::solvergraph::IDataEdge<Tscal>, K) \
255 X_RO(shamrock::solvergraph::IDataEdge<Tscal>, gamma) \
256 X_RO(shamrock::solvergraph::IDataEdge<Tscal>, hfactd) \
257 X_RO(shamrock::solvergraph::IDataEdge<Tscal>, pmass) \
258 X_RO_OPTIONAL(shamrock::solvergraph::IFieldSpan<Tscal>, spans_rho) \
259 X_RO_OPTIONAL(shamrock::solvergraph::IFieldSpan<Tscal>, spans_h) \
260 X_RO(shamrock::solvergraph::Indexes<u32>, sizes) \
263 X_RW(shamrock::solvergraph::IFieldSpan<Tscal>, spans_pressure) \
264 X_RW(shamrock::solvergraph::IFieldSpan<Tscal>, spans_soundspeed)
266namespace shammodels::common::modules {
270 using Tscal = shambase::VecComponent<Tvec>;
273 ComputeEOSPolytropic() =
default;
275 EXPAND_NODE_EDGES_OPTIONAL(NODE_EDGES)
277 inline static void internal_eos(
282 Tscal &soundspeed)
noexcept {
284 Tscal P_a = EOS::pressure(gamma, K, rho);
285 Tscal cs_a = EOS::soundspeed(gamma, K, rho);
294 auto edges = get_edges();
296 bool has_rho = edges.spans_rho.has_value();
297 bool has_h = edges.spans_h.has_value();
300 if ((has_rho && has_h) || (!has_rho && !has_h)) {
302 "Must have either rho or h");
305 edges.spans_pressure.ensure_sizes(edges.sizes.indexes);
306 edges.spans_soundspeed.ensure_sizes(edges.sizes.indexes);
308 Tscal K = edges.K.data;
309 Tscal gamma = edges.gamma.data;
310 Tscal pmass = edges.pmass.data;
311 Tscal hfactd = edges.hfactd.data;
313 auto dev_sched = shamsys::instance::get_compute_scheduler_ptr();
316 edges.spans_pressure.get_spans(), edges.spans_soundspeed.get_spans()};
319 auto &spans_rho = edges.spans_rho.value().get();
320 spans_rho.check_sizes(edges.sizes.indexes);
327 [K, gamma](
u32 gid,
const Tscal *rho, Tscal *pressure, Tscal *soundspeed) {
328 Tscal rho_a = rho[gid];
329 internal_eos(K, gamma, rho_a, pressure[gid], soundspeed[gid]);
332 auto &spans_h = edges.spans_h.value().get();
333 spans_h.check_sizes(edges.sizes.indexes);
340 [K, gamma, pmass, hfactd](
341 u32 gid,
const Tscal *h, Tscal *pressure, Tscal *soundspeed) {
342 using namespace shamrock::sph;
343 Tscal rho = rho_h(pmass, h[gid], hfactd);
344 internal_eos(K, gamma, rho, pressure[gid], soundspeed[gid]);
349 inline virtual std::string
_impl_get_label()
const {
return "ComputeEOSPolytropic"; };
357#define NODE_EDGES(X_RO, X_RW, X_RO_OPTIONAL, X_RW_OPTIONAL) \
359 X_RO(shamrock::solvergraph::IDataEdge<Tscal>, hfactd) \
360 X_RO(shamrock::solvergraph::IDataEdge<Tscal>, pmass) \
361 X_RO_OPTIONAL(shamrock::solvergraph::IFieldSpan<Tscal>, spans_rho) \
362 X_RO_OPTIONAL(shamrock::solvergraph::IFieldSpan<Tscal>, spans_h) \
363 X_RO(shamrock::solvergraph::IFieldSpan<Tscal>, spans_cs0) \
364 X_RO(shamrock::solvergraph::Indexes<u32>, sizes) \
367 X_RW(shamrock::solvergraph::IFieldSpan<Tscal>, spans_pressure) \
368 X_RW(shamrock::solvergraph::IFieldSpan<Tscal>, spans_soundspeed)
370namespace shammodels::common::modules {
374 using Tscal = shambase::VecComponent<Tvec>;
377 ComputeEOSLocallyIsothermal() =
default;
379 EXPAND_NODE_EDGES_OPTIONAL(NODE_EDGES)
381 inline static void internal_eos(
382 const Tscal &cs0,
const Tscal &rho, Tscal &pressure, Tscal &soundspeed)
noexcept {
384 pressure = EOS::pressure_from_cs(cs0 * cs0, rho);
392 auto edges = get_edges();
394 bool has_rho = edges.spans_rho.has_value();
395 bool has_h = edges.spans_h.has_value();
398 if ((has_rho && has_h) || (!has_rho && !has_h)) {
400 "Must have either rho or h");
403 edges.spans_pressure.ensure_sizes(edges.sizes.indexes);
404 edges.spans_soundspeed.ensure_sizes(edges.sizes.indexes);
406 Tscal pmass = edges.pmass.data;
407 Tscal hfactd = edges.hfactd.data;
409 auto dev_sched = shamsys::instance::get_compute_scheduler_ptr();
412 edges.spans_pressure.get_spans(), edges.spans_soundspeed.get_spans()};
415 auto &spans_rho = edges.spans_rho.value().get();
416 spans_rho.check_sizes(edges.sizes.indexes);
428 Tscal rho_a = rho[gid];
429 Tscal cs0_a = cs0[gid];
430 internal_eos(cs0_a, rho_a, pressure[gid], soundspeed[gid]);
433 auto &spans_h = edges.spans_h.value().get();
434 spans_h.check_sizes(edges.sizes.indexes);
447 using namespace shamrock::sph;
448 Tscal rho = rho_h(pmass, h[gid], hfactd);
449 Tscal cs0_a = cs0[gid];
450 internal_eos(cs0_a, rho, pressure[gid], soundspeed[gid]);
456 return "ComputeEOSLocallyIsothermal";
465#define NODE_EDGES(X_RO, X_RW, X_RO_OPTIONAL, X_RW_OPTIONAL) \
467 X_RO(shamrock::solvergraph::IDataEdge<Tscal>, mu_e) \
468 X_RO(shamrock::solvergraph::IDataEdge<Tscal>, density_unit) \
469 X_RO(shamrock::solvergraph::IDataEdge<Tscal>, pressure_unit) \
470 X_RO(shamrock::solvergraph::IDataEdge<Tscal>, velocity_unit) \
471 X_RO(shamrock::solvergraph::IDataEdge<Tscal>, hfactd) \
472 X_RO(shamrock::solvergraph::IDataEdge<Tscal>, pmass) \
473 X_RO_OPTIONAL(shamrock::solvergraph::IFieldSpan<Tscal>, spans_rho) \
474 X_RO_OPTIONAL(shamrock::solvergraph::IFieldSpan<Tscal>, spans_h) \
475 X_RO(shamrock::solvergraph::Indexes<u32>, sizes) \
478 X_RW(shamrock::solvergraph::IFieldSpan<Tscal>, spans_pressure) \
479 X_RW(shamrock::solvergraph::IFieldSpan<Tscal>, spans_soundspeed)
481namespace shammodels::common::modules {
485 using Tscal = shambase::VecComponent<Tvec>;
488 ComputeEOSFermi() =
default;
490 EXPAND_NODE_EDGES_OPTIONAL(NODE_EDGES)
492 inline static void internal_eos(
494 const Tscal &density_unit,
495 const Tscal &pressure_unit,
496 const Tscal &velocity_unit,
499 Tscal &soundspeed)
noexcept {
501 auto const res = EOS::pressure_and_soundspeed(mu_e, rho * density_unit);
502 pressure = res.pressure / pressure_unit;
503 soundspeed = res.soundspeed / velocity_unit;
510 auto edges = get_edges();
512 bool has_rho = edges.spans_rho.has_value();
513 bool has_h = edges.spans_h.has_value();
516 if ((has_rho && has_h) || (!has_rho && !has_h)) {
518 "Must have either rho or h");
521 edges.spans_pressure.ensure_sizes(edges.sizes.indexes);
522 edges.spans_soundspeed.ensure_sizes(edges.sizes.indexes);
524 Tscal mu_e = edges.mu_e.data;
525 Tscal density_unit = edges.density_unit.data;
526 Tscal pressure_unit = edges.pressure_unit.data;
527 Tscal velocity_unit = edges.velocity_unit.data;
528 Tscal pmass = edges.pmass.data;
529 Tscal hfactd = edges.hfactd.data;
531 auto dev_sched = shamsys::instance::get_compute_scheduler_ptr();
534 edges.spans_pressure.get_spans(), edges.spans_soundspeed.get_spans()};
537 auto &spans_rho = edges.spans_rho.value().get();
538 spans_rho.check_sizes(edges.sizes.indexes);
545 [mu_e, density_unit, pressure_unit, velocity_unit](
546 u32 gid,
const Tscal *rho, Tscal *pressure, Tscal *soundspeed) {
547 Tscal rho_a = rho[gid];
558 auto &spans_h = edges.spans_h.value().get();
559 spans_h.check_sizes(edges.sizes.indexes);
566 [mu_e, density_unit, pressure_unit, velocity_unit, pmass, hfactd](
567 u32 gid,
const Tscal *h, Tscal *pressure, Tscal *soundspeed) {
568 using namespace shamrock::sph;
569 Tscal rho = rho_h(pmass, h[gid], hfactd);
590template<
class Tvec,
template<
class>
class SPHKernel>
591void shammodels::sph::modules::ComputeEos<Tvec, SPHKernel>::compute_eos_internal(
605 using namespace shamrock::patch;
607 using SolverConfigEOS =
typename Config::EOSConfig;
608 using SolverEOS_Isothermal =
typename SolverConfigEOS::Isothermal;
609 using SolverEOS_Adiabatic =
typename SolverConfigEOS::Adiabatic;
610 using SolverEOS_Polytropic =
typename SolverConfigEOS::Polytropic;
611 using SolverEOS_LocallyIsothermal =
typename SolverConfigEOS::LocallyIsothermal;
612 using SolverEOS_LocallyIsothermalLP07 =
typename SolverConfigEOS::LocallyIsothermalLP07;
613 using SolverEOS_LocallyIsothermalFA2014 =
typename SolverConfigEOS::LocallyIsothermalFA2014;
614 using SolverEOS_LocallyIsothermalFA2014Extended =
615 typename SolverConfigEOS::LocallyIsothermalFA2014Extended;
616 using SolverEOS_Fermi =
typename SolverConfigEOS::Fermi;
619 auto dev_sched = shamsys::instance::get_compute_scheduler_ptr();
626 bool has_rho = spans_rho.has_value();
627 bool has_h = spans_h.has_value();
630 if ((!has_rho || has_h) && (has_rho || !has_h)) {
635 = [](
const std::optional<std::shared_ptr<shamrock::solvergraph::IFieldSpan<Tscal>>> &opt)
637 if (!opt.has_value()) {
644 const std::optional<std::reference_wrapper<shamrock::solvergraph::IFieldSpan<Tscal>>>
646 const std::optional<std::reference_wrapper<shamrock::solvergraph::IFieldSpan<Tscal>>>
648 const std::optional<std::reference_wrapper<shamrock::solvergraph::IFieldSpan<Tscal>>>
650 } edges{map_opt_span(spans_rho), map_opt_span(spans_h), map_opt_span(spans_uint)};
656 if (SolverEOS_Isothermal *eos_config
657 = std::get_if<SolverEOS_Isothermal>(&solver_config.eos_config.config)) {
659 auto cs = shamrock::solvergraph::IDataEdge<Tscal>::make_shared(
"cs",
"c_s");
660 cs->data = eos_config->cs;
664 cs, hfactd, pmass, spans_rho, spans_h, sizes, spans_pressure, spans_soundspeed);
667 SolverEOS_Adiabatic *eos_config
668 = std::get_if<SolverEOS_Adiabatic>(&solver_config.eos_config.config)) {
670 auto gamma = shamrock::solvergraph::IDataEdge<Tscal>::make_shared(
"gamma",
"\\gamma");
671 gamma->data = eos_config->gamma;
686 SolverEOS_Polytropic *eos_config
687 = std::get_if<SolverEOS_Polytropic>(&solver_config.eos_config.config)) {
689 auto K = shamrock::solvergraph::IDataEdge<Tscal>::make_shared(
"K",
"K");
690 auto gamma = shamrock::solvergraph::IDataEdge<Tscal>::make_shared(
"gamma",
"\\gamma");
691 K->data = eos_config->K;
692 gamma->data = eos_config->gamma;
696 K, gamma, hfactd, pmass, spans_rho, spans_h, sizes, spans_pressure, spans_soundspeed);
699 [[maybe_unused]] SolverEOS_LocallyIsothermal *eos_config
700 = std::get_if<SolverEOS_LocallyIsothermal>(&solver_config.eos_config.config)) {
705 = shamrock::solvergraph::FieldRefs<Tscal>::make_shared(
"cs0",
"c_{s,0}");
706 auto refs = storage.merged_patchdata_ghost.get()
707 .template map<shamrock::solvergraph::PatchDataFieldRef<Tscal>>(
710 return mpdat.get_field<Tscal>(isoundspeed_interf);
712 soundspeed_refs->set_refs(refs);
726 SolverEOS_LocallyIsothermalLP07 *eos_config
727 = std::get_if<SolverEOS_LocallyIsothermalLP07>(&solver_config.eos_config.config)) {
729 Tscal cs0 = eos_config->cs0;
730 Tscal r0sq = eos_config->r0 * eos_config->r0;
731 Tscal mq = -eos_config->q;
738 = storage.merged_xyzh.get()
739 .template map<shamrock::solvergraph::PatchDataFieldRef<Tvec>>(
742 return mpdat.get_field<Tvec>(0);
744 xyz_refs.set_refs(refs);
748 auto eos_internal = [](Tvec R,
755 Tscal Rsq = sycl::dot(R, R);
756 Tscal cs_sq = EOS::soundspeed_sq(cs0 * cs0, Rsq / r0sq, mq);
757 Tscal cs_out = sycl::sqrt(cs_sq);
759 Tscal P_a = EOS::pressure_from_cs(cs_sq, rho_a);
766 auto &spans_rho_ = edges.spans_rho.value().get();
767 spans_rho_.check_sizes(sizes_indexes);
773 [cs0, r0sq, mq, eos_internal](
780 Tscal rho_a = rho[gid];
781 eos_internal(R_a, cs0, r0sq, mq, rho_a, pressure[gid], soundspeed[gid]);
784 auto &spans_h_ = edges.spans_h.value().get();
785 spans_h_.check_sizes(sizes_indexes);
791 [cs0, r0sq, mq, pmass_, hfactd_, eos_internal](
793 using namespace shamrock::sph;
795 Tscal rho_a = rho_h(pmass_, h[gid], hfactd_);
796 eos_internal(R_a, cs0, r0sq, mq, rho_a, pressure[gid], soundspeed[gid]);
801 SolverEOS_LocallyIsothermalFA2014 *eos_config
802 = std::get_if<SolverEOS_LocallyIsothermalFA2014>(&solver_config.eos_config.config)) {
804 Tscal G = solver_config.get_constant_G();
805 Tscal h_over_r = eos_config->h_over_r;
811 auto &sink_pos = get_sink_pos<Tvec>(scheduler().synchronized_data);
812 auto &sink_mass = get_sink_mass<Tvec>(scheduler().synchronized_data);
813 u32 sink_cnt = shambase::narrow_or_throw<u32>(sink_pos.size());
817 "No sinks found for the equation of state");
822 = storage.merged_xyzh.get()
823 .template map<shamrock::solvergraph::PatchDataFieldRef<Tvec>>(
826 return mpdat.get_field<Tvec>(0);
828 xyz_refs.set_refs(refs);
833 sink_pos_buf.copy_from_stdvec(sink_pos);
834 sink_mass_buf.copy_from_stdvec(sink_mass);
836 auto eos_internal = [](Tvec R,
845 Tscal mpotential = 0;
846 for (
u32 i = 0; i < scount; i++) {
847 Tvec s_r = spos[i] - R;
848 Tscal s_m = smass[i];
849 Tscal s_r_abs = sycl::length(s_r);
850 mpotential += G * s_m / s_r_abs;
853 Tscal cs_out = h_over_r * sycl::sqrt(mpotential);
854 Tscal P_a = EOS::pressure_from_cs(cs_out * cs_out, rho_a);
861 auto &spans_rho_ = edges.spans_rho.value().get();
862 spans_rho_.check_sizes(sizes_indexes);
864 sizes_indexes.for_each([&](
u64 id,
u32 count) {
868 spans_rho_.get_spans().get(
id),
874 [G, h_over_r, sink_cnt, eos_internal](
883 Tscal rho_a = rho[gid];
898 auto &spans_h_ = edges.spans_h.value().get();
899 spans_h_.check_sizes(sizes_indexes);
901 sizes_indexes.for_each([&](
u64 id,
u32 count) {
905 spans_h_.get_spans().get(
id),
911 [G, h_over_r, sink_cnt, pmass_, hfactd_, eos_internal](
919 using namespace shamrock::sph;
921 Tscal rho_a = rho_h(pmass_, h[gid], hfactd_);
937 SolverEOS_LocallyIsothermalFA2014Extended *eos_config
938 = std::get_if<SolverEOS_LocallyIsothermalFA2014Extended>(
939 &solver_config.eos_config.config)) {
941 Tscal cs0 = eos_config->cs0;
942 Tscal r0 = eos_config->r0;
943 Tscal q_ = eos_config->q;
946 u32 n_sinks = eos_config->n_sinks;
948 Tscal inv_r0_q = 1. / sycl::pow(r0, q_);
952 auto &all_sink_pos = get_sink_pos<Tvec>(scheduler().synchronized_data);
953 auto &all_sink_mass = get_sink_mass<Tvec>(scheduler().synchronized_data);
954 std::vector<Tvec> sink_pos;
955 std::vector<Tscal> sink_mass;
958 for (
size_t i = 0; i < all_sink_pos.size(); i++) {
959 sink_pos.push_back(all_sink_pos[i]);
960 sink_mass.push_back(all_sink_mass[i]);
962 if (sink_pos.size() >= n_sinks) {
969 "No sinks found for the equation of state");
974 = storage.merged_xyzh.get()
975 .template map<shamrock::solvergraph::PatchDataFieldRef<Tvec>>(
978 return mpdat.get_field<Tvec>(0);
980 xyz_refs.set_refs(refs);
985 sink_pos_buf.copy_from_stdvec(sink_pos);
986 sink_mass_buf.copy_from_stdvec(sink_mass);
988 auto eos_internal = [](Tvec R,
998 Tscal sink_mass_sum = 0;
1000 for (
u32 i = 0; i < scount; i++) {
1001 Tvec s_r = spos[i] - R;
1002 Tscal s_m = smass[i];
1003 Tscal s_r_abs = sycl::length(s_r);
1004 sink_mass_sum += s_m;
1005 pot_sum += s_m / s_r_abs;
1008 Tscal cs_out = cs0 * inv_r0_q * sycl::pow(pot_sum / sink_mass_sum, q);
1009 Tscal P_a = EOS::pressure_from_cs(cs_out * cs_out, rho_a);
1016 auto &spans_rho_ = edges.spans_rho.value().get();
1017 spans_rho_.check_sizes(sizes_indexes);
1019 sizes_indexes.for_each([&](
u64 id,
u32 count) {
1023 spans_rho_.get_spans().get(
id),
1029 [cs0, inv_r0_q, q_, sink_cnt, eos_internal](
1036 Tscal *soundspeed) {
1037 Tvec R_a =
xyz[gid];
1038 Tscal rho_a = rho[gid];
1053 auto &spans_h_ = edges.spans_h.value().get();
1054 spans_h_.check_sizes(sizes_indexes);
1056 sizes_indexes.for_each([&](
u64 id,
u32 count) {
1060 spans_h_.get_spans().get(
id),
1066 [cs0, inv_r0_q, q_, sink_cnt, pmass_, hfactd_, eos_internal](
1073 Tscal *soundspeed) {
1074 using namespace shamrock::sph;
1075 Tvec R_a =
xyz[gid];
1076 Tscal rho_a = rho_h(pmass_, h[gid], hfactd_);
1093 SolverEOS_Fermi *eos_config
1094 = std::get_if<SolverEOS_Fermi>(&solver_config.eos_config.config)) {
1097 auto unit_sys = *solver_config.unit_sys;
1099 Tscal mass = unit_sys.template to<units::kilogram>();
1100 Tscal length = unit_sys.template to<units::metre>();
1101 Tscal time = unit_sys.template to<units::second>();
1103 auto mu_e = shamrock::solvergraph::IDataEdge<Tscal>::make_shared(
"mu_e",
"\\mu_e");
1104 mu_e->data = eos_config->mu_e;
1107 = shamrock::solvergraph::IDataEdge<Tscal>::make_shared(
"density_unit",
"\\rho_u");
1108 density_unit->data = mass / (length * length * length);
1111 = shamrock::solvergraph::IDataEdge<Tscal>::make_shared(
"pressure_unit",
"P_u");
1112 pressure_unit->data = mass / length / (time * time);
1115 = shamrock::solvergraph::IDataEdge<Tscal>::make_shared(
"velocity_unit",
"v_u");
1116 velocity_unit->data = length / time;
1137template<
class Tvec,
template<
class>
class SPHKernel>
1142 Tscal gpart_mass = solver_config.gpart_mass;
1145 using namespace shamrock::patch;
1152 auto hfactd = shamrock::solvergraph::IDataEdge<Tscal>::make_shared(
"hfactd",
"hfactd");
1153 auto pmass = shamrock::solvergraph::IDataEdge<Tscal>::make_shared(
"pmass",
"pmass");
1155 hfactd->data = Kernel::hfactd;
1156 pmass->data = gpart_mass;
1158 auto sizes = storage.part_counts_with_ghost;
1160 auto h_refs = shamrock::solvergraph::FieldRefs<Tscal>::make_shared(
"",
"");
1162 auto refs = storage.merged_patchdata_ghost.get()
1163 .template map<shamrock::solvergraph::PatchDataFieldRef<Tscal>>(
1166 return mpdat.get_field<Tscal>(ihpart_interf);
1168 h_refs->set_refs(refs);
1171 auto uint_refs = shamrock::solvergraph::FieldRefs<Tscal>::make_shared(
"",
"");
1173 auto refs = storage.merged_patchdata_ghost.get()
1174 .template map<shamrock::solvergraph::PatchDataFieldRef<Tscal>>(
1177 return mpdat.get_field<Tscal>(iuint_interf);
1179 uint_refs->set_refs(refs);
1182 auto dev_sched = shamsys::instance::get_compute_scheduler_ptr();
1184 if (solver_config.dust_config.has_epsilon_field()) {
1187 u32 nvar_dust = solver_config.dust_config.get_dust_nvar();
1189 auto rho_g = std::make_shared<shamrock::solvergraph::Field<Tscal>>(1,
"rho_g",
"rho_g");
1190 auto uint_g = std::make_shared<shamrock::solvergraph::Field<Tscal>>(1,
"uint_g",
"uint_g");
1196 auto refs = storage.merged_patchdata_ghost.get()
1197 .template map<shamrock::solvergraph::PatchDataFieldRef<Tscal>>(
1200 return mpdat.get_field<Tscal>(iepsilon_interf);
1202 epsilon_refs.set_refs(refs);
1209 [pmass = pmass->data, hfactd = hfactd->data, nvar_dust](
1213 const Tscal *epsilon,
1216 using namespace shamrock::sph;
1217 Tscal rho_a = rho_h(pmass, h[gid], hfactd);
1218 Tscal uint_a = uint[gid];
1220 Tscal epsilon_sum = 0;
1221 for (
u32 j = 0; j < nvar_dust; j++) {
1222 epsilon_sum += epsilon[gid * nvar_dust + j];
1225 Tscal rho_g_a = rho_a * (1 - epsilon_sum);
1226 Tscal uint_g_a = uint_a / (1 - epsilon_sum);
1228 rho_g[gid] = rho_g_a;
1229 uint_g[gid] = uint_g_a;
1232 compute_eos_internal(
1240 storage.soundspeed);
1241 }
else if (solver_config.dust_config.has_s_j_field()) {
1244 u32 nvar_dust = solver_config.dust_config.get_dust_nvar();
1246 auto rho_g = std::make_shared<shamrock::solvergraph::Field<Tscal>>(1,
"rho_g",
"rho_g");
1247 auto uint_g = std::make_shared<shamrock::solvergraph::Field<Tscal>>(1,
"uint_g",
"uint_g");
1253 auto refs = storage.merged_patchdata_ghost.get()
1254 .template map<shamrock::solvergraph::PatchDataFieldRef<Tscal>>(
1257 return mpdat.get_field<Tscal>(is_j_interf);
1259 s_j_refs.set_refs(refs);
1266 [pmass = pmass->data, hfactd = hfactd->data, nvar_dust](
1273 using namespace shamrock::sph;
1274 Tscal rho_a = rho_h(pmass, h[gid], hfactd);
1275 Tscal uint_a = uint[gid];
1277 Tscal epsilon_sum = 0;
1278 for (
u32 j = 0; j < nvar_dust; j++) {
1279 Tscal s = s_j[gid * nvar_dust + j];
1280 epsilon_sum += s * s / rho_a;
1283 Tscal rho_g_a = rho_a * (1 - epsilon_sum);
1284 Tscal uint_g_a = uint_a / (1 - epsilon_sum);
1286 rho_g[gid] = rho_g_a;
1287 uint_g[gid] = uint_g_a;
1290 compute_eos_internal(
1298 storage.soundspeed);
1301 compute_eos_internal(
1309 storage.soundspeed);
constexpr const char * xyz
Position field (3D coordinates).
constexpr const char * soundspeed
Sound speed c_s (derived from EOS).
constexpr const char * pressure
Pressure P (derived from EOS).
std::reference_wrapper< PatchDataField< T > > PatchDataFieldRef
Alias for a reference to a PatchDataField.
std::uint32_t u32
32 bit unsigned integer
std::uint64_t u64
64 bit unsigned integer
A buffer allocated in USM (Unified Shared Memory).
A SYCL queue associated with a device and a context.
virtual std::string _impl_get_label() const
get the label of the node
void _impl_evaluate_internal()
evaluate the node
virtual std::string _impl_get_tex() const
get the tex of the node
virtual std::string _impl_get_label() const
get the label of the node
virtual std::string _impl_get_tex() const
get the tex of the node
void _impl_evaluate_internal()
evaluate the node
void _impl_evaluate_internal()
evaluate the node
virtual std::string _impl_get_label() const
get the label of the node
virtual std::string _impl_get_tex() const
get the tex of the node
void _impl_evaluate_internal()
evaluate the node
virtual std::string _impl_get_tex() const
get the tex of the node
virtual std::string _impl_get_label() const
get the label of the node
virtual std::string _impl_get_label() const
get the label of the node
virtual std::string _impl_get_tex() const
get the tex of the node
void _impl_evaluate_internal()
evaluate the node
Module for computing equation of state quantities.
void compute_eos()
Computes pressure and sound speed from equation of state.
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.
virtual DDPatchDataFieldSpanPointer< T > & get_spans()
Get the DistributedData of spans attached to the underlying field.
Interface for a solver graph edge representing a field as spans.
Inode is node between data edges, takes multiple inputs, multiple outputs.
void evaluate()
Evaluate the node.
This header file contains utility functions related to exception handling in the code.
void distributed_data_kernel_call(sham::DeviceScheduler_ptr dev_sched, RefIn in, RefOut in_out, const shambase::DistributedData< index_t > &thread_counts, Functor &&func)
A variant of sham::kernel_call for distributed data.
void kernel_call(sham::DeviceQueue &q, RefIn in, RefOut in_out, u32 n, Functor &&func, SourceLocation &&callsite=SourceLocation{})
Submit a kernel to a SYCL queue.
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.
void throw_unimplemented(SourceLocation loc=SourceLocation{})
Throw a std::runtime_error saying that the function is unimplemented.
namespace for math utility
namespace for the main framework
namespace containing the units library
Utilities for safe type narrowing conversions.
Helpers to access SPH sink particles stored as SoA synchronized data edges.
#define __shamrock_stack_entry()
Macro to create a stack entry.
shambase::details::NamedBasicStackEntry NamedStackEntry
Alias for shambase::details::NamedBasicStackEntry.
A variant of sham::MultiRef for distributed data.
A class that references multiple buffers or similar objects.
Adiabatic equation of state.
Isothermal equation of state.
Locally isothermal equation of state with radial dependence.
Polytropic equation of state.