33template<
class Tvec,
template<
class>
class SPHKernel>
34void shammodels::sph::modules::ComputeEos<Tvec, SPHKernel>::compute_eos_internal(
51 using namespace shamrock::patch;
53 using SolverConfigEOS =
typename Config::EOSConfig;
54 using SolverEOS_Isothermal =
typename SolverConfigEOS::Isothermal;
55 using SolverEOS_Adiabatic =
typename SolverConfigEOS::Adiabatic;
56 using SolverEOS_Polytropic =
typename SolverConfigEOS::Polytropic;
57 using SolverEOS_LocallyIsothermal =
typename SolverConfigEOS::LocallyIsothermal;
58 using SolverEOS_LocallyIsothermalLP07 =
typename SolverConfigEOS::LocallyIsothermalLP07;
59 using SolverEOS_LocallyIsothermalFA2014 =
typename SolverConfigEOS::LocallyIsothermalFA2014;
60 using SolverEOS_LocallyIsothermalFA2014Extended =
61 typename SolverConfigEOS::LocallyIsothermalFA2014Extended;
62 using SolverEOS_Fermi =
typename SolverConfigEOS::Fermi;
65 auto dev_sched = shamsys::instance::get_compute_scheduler_ptr();
70 bool has_rho = spans_rho.has_value();
71 bool has_h = spans_h.has_value();
74 if ((!has_rho || has_h) && (has_rho || !has_h)) {
80 if (SolverEOS_Isothermal *eos_config
81 = std::get_if<SolverEOS_Isothermal>(&solver_config.eos_config.config)) {
83 Tscal cs = eos_config->cs;
84 Tscal pmass_ = pmass.data;
85 Tscal hfactd_ = hfactd.data;
96 auto &spans_rho_ = spans_rho.value().get();
97 spans_rho_.check_sizes(
sizes.indexes);
104 Tscal rho_a = rho[gid];
105 eos_internal(cs, rho_a, pressure[gid], soundspeed[gid]);
108 auto &spans_h_ = spans_h.value().get();
109 spans_h_.check_sizes(
sizes.indexes);
115 [cs, pmass_, hfactd_, eos_internal](
117 using namespace shamrock::sph;
118 Tscal rho = rho_h(pmass_, h[gid], hfactd_);
119 eos_internal(cs, rho, pressure[gid], soundspeed[gid]);
123 SolverEOS_Adiabatic *eos_config
124 = std::get_if<SolverEOS_Adiabatic>(&solver_config.eos_config.config)) {
126 Tscal gamma = eos_config->gamma;
127 Tscal pmass_ = pmass.data;
128 Tscal hfactd_ = hfactd.data;
135 Tscal P_a = EOS::pressure(gamma, rho, uint);
136 Tscal cs_a = EOS::cs_from_p(gamma, rho, P_a);
142 auto &spans_rho_ = spans_rho.value().get();
143 spans_rho_.check_sizes(
sizes.indexes);
146 sham::DDMultiRef{spans_rho_.get_spans(), spans_uint.value().get().get_spans()},
149 [gamma, pmass_, hfactd_, eos_internal](
155 Tscal rho_a = rho[gid];
156 Tscal uint_a =
uint[gid];
157 eos_internal(gamma, rho_a, uint_a, pressure[gid], soundspeed[gid]);
160 auto &spans_h_ = spans_h.value().get();
161 spans_h_.check_sizes(
sizes.indexes);
164 sham::DDMultiRef{spans_h_.get_spans(), spans_uint.value().get().get_spans()},
167 [gamma, pmass_, hfactd_, eos_internal](
173 using namespace shamrock::sph;
174 Tscal rho = rho_h(pmass_, h[gid], hfactd_);
175 Tscal uint_a =
uint[gid];
176 eos_internal(gamma, rho, uint_a, pressure[gid], soundspeed[gid]);
181 SolverEOS_Polytropic *eos_config
182 = std::get_if<SolverEOS_Polytropic>(&solver_config.eos_config.config)) {
186 Tscal K = eos_config->K;
187 Tscal gamma = eos_config->gamma;
188 Tscal pmass_ = pmass.data;
189 Tscal hfactd_ = hfactd.data;
194 Tscal P_a = EOS::pressure(gamma, K, rho_a);
195 Tscal cs_a = EOS::soundspeed(gamma, K, rho_a);
201 auto &spans_rho_ = spans_rho.value().get();
202 spans_rho_.check_sizes(
sizes.indexes);
208 [K, gamma, pmass_, hfactd_, eos_internal](
210 Tscal rho_a = rho[gid];
211 eos_internal(K, gamma, rho_a, pressure[gid], soundspeed[gid]);
214 auto &spans_h_ = spans_h.value().get();
215 spans_h_.check_sizes(
sizes.indexes);
221 [K, gamma, pmass_, hfactd_, eos_internal](
223 using namespace shamrock::sph;
224 Tscal rho = rho_h(pmass_, h[gid], hfactd_);
225 eos_internal(K, gamma, rho, pressure[gid], soundspeed[gid]);
230 SolverEOS_LocallyIsothermal *eos_config
231 = std::get_if<SolverEOS_LocallyIsothermal>(&solver_config.eos_config.config)) {
238 auto refs = storage.merged_patchdata_ghost.get()
239 .template map<shamrock::solvergraph::PatchDataFieldRef<Tscal>>(
242 return mpdat.get_field<Tscal>(isoundspeed_interf);
244 soundspeed_refs.set_refs(refs);
246 Tscal pmass_ = pmass.data;
247 Tscal hfactd_ = hfactd.data;
251 pressure = EOS::pressure_from_cs(cs0 * cs0, rho_a);
256 auto &spans_rho_ = spans_rho.value().get();
257 spans_rho_.check_sizes(
sizes.indexes);
269 Tscal rho_a = rho[gid];
270 Tscal cs0_a = cs0[gid];
271 eos_internal(cs0_a, rho_a, pressure[gid], soundspeed[gid]);
274 auto &spans_h_ = spans_h.value().get();
275 spans_h_.check_sizes(
sizes.indexes);
281 [pmass_, hfactd_, eos_internal](
283 using namespace shamrock::sph;
284 Tscal rho = rho_h(pmass_, h[gid], hfactd_);
285 Tscal cs0_a = cs0[gid];
286 eos_internal(cs0_a, rho, pressure[gid], soundspeed[gid]);
291 SolverEOS_LocallyIsothermalLP07 *eos_config
292 = std::get_if<SolverEOS_LocallyIsothermalLP07>(&solver_config.eos_config.config)) {
294 Tscal cs0 = eos_config->cs0;
295 Tscal r0sq = eos_config->r0 * eos_config->r0;
296 Tscal mq = -eos_config->q;
298 Tscal pmass_ = pmass.data;
299 Tscal hfactd_ = hfactd.data;
303 = storage.merged_xyzh.get()
304 .template map<shamrock::solvergraph::PatchDataFieldRef<Tvec>>(
307 return mpdat.get_field<Tvec>(0);
309 xyz_refs.set_refs(refs);
313 auto eos_internal = [](Tvec R,
320 Tscal Rsq = sycl::dot(R, R);
321 Tscal cs_sq = EOS::soundspeed_sq(cs0 * cs0, Rsq / r0sq, mq);
322 Tscal cs_out = sycl::sqrt(cs_sq);
324 Tscal P_a = EOS::pressure_from_cs(cs_sq, rho_a);
331 auto &spans_rho_ = spans_rho.value().get();
332 spans_rho_.check_sizes(
sizes.indexes);
338 [cs0, r0sq, mq, eos_internal](
345 Tscal rho_a = rho[gid];
346 eos_internal(R_a, cs0, r0sq, mq, rho_a, pressure[gid], soundspeed[gid]);
349 auto &spans_h_ = spans_h.value().get();
350 spans_h_.check_sizes(
sizes.indexes);
356 [cs0, r0sq, mq, pmass_, hfactd_, eos_internal](
358 using namespace shamrock::sph;
360 Tscal rho_a = rho_h(pmass_, h[gid], hfactd_);
361 eos_internal(R_a, cs0, r0sq, mq, rho_a, pressure[gid], soundspeed[gid]);
366 SolverEOS_LocallyIsothermalFA2014 *eos_config
367 = std::get_if<SolverEOS_LocallyIsothermalFA2014>(&solver_config.eos_config.config)) {
369 Tscal G = solver_config.get_constant_G();
370 Tscal h_over_r = eos_config->h_over_r;
371 Tscal pmass_ = pmass.data;
372 Tscal hfactd_ = hfactd.data;
376 auto &sink_pos = get_sink_pos<Tvec>(scheduler().synchronized_data);
377 auto &sink_mass = get_sink_mass<Tvec>(scheduler().synchronized_data);
378 u32 sink_cnt = shambase::narrow_or_throw<u32>(sink_pos.size());
382 "No sinks found for the equation of state");
387 = storage.merged_xyzh.get()
388 .template map<shamrock::solvergraph::PatchDataFieldRef<Tvec>>(
391 return mpdat.get_field<Tvec>(0);
393 xyz_refs.set_refs(refs);
398 sink_pos_buf.copy_from_stdvec(sink_pos);
399 sink_mass_buf.copy_from_stdvec(sink_mass);
401 auto eos_internal = [](Tvec R,
410 Tscal mpotential = 0;
411 for (
u32 i = 0; i < scount; i++) {
412 Tvec s_r = spos[i] - R;
413 Tscal s_m = smass[i];
414 Tscal s_r_abs = sycl::length(s_r);
415 mpotential += G * s_m / s_r_abs;
418 Tscal cs_out = h_over_r * sycl::sqrt(mpotential);
419 Tscal P_a = EOS::pressure_from_cs(cs_out * cs_out, rho_a);
426 auto &spans_rho_ = spans_rho.value().get();
427 spans_rho_.check_sizes(
sizes.indexes);
433 spans_rho_.get_spans().get(
id),
439 [G, h_over_r, sink_cnt, eos_internal](
448 Tscal rho_a = rho[gid];
463 auto &spans_h_ = spans_h.value().get();
464 spans_h_.check_sizes(
sizes.indexes);
470 spans_h_.get_spans().get(
id),
476 [G, h_over_r, sink_cnt, pmass_, hfactd_, eos_internal](
484 using namespace shamrock::sph;
486 Tscal rho_a = rho_h(pmass_, h[gid], hfactd_);
502 SolverEOS_LocallyIsothermalFA2014Extended *eos_config
503 = std::get_if<SolverEOS_LocallyIsothermalFA2014Extended>(
504 &solver_config.eos_config.config)) {
506 Tscal cs0 = eos_config->cs0;
507 Tscal r0 = eos_config->r0;
508 Tscal q_ = eos_config->q;
509 Tscal pmass_ = pmass.data;
510 Tscal hfactd_ = hfactd.data;
511 u32 n_sinks = eos_config->n_sinks;
513 Tscal inv_r0_q = 1. / sycl::pow(r0, q_);
517 auto &all_sink_pos = get_sink_pos<Tvec>(scheduler().synchronized_data);
518 auto &all_sink_mass = get_sink_mass<Tvec>(scheduler().synchronized_data);
519 std::vector<Tvec> sink_pos;
520 std::vector<Tscal> sink_mass;
523 for (
size_t i = 0; i < all_sink_pos.size(); i++) {
524 sink_pos.push_back(all_sink_pos[i]);
525 sink_mass.push_back(all_sink_mass[i]);
527 if (sink_pos.size() >= n_sinks) {
534 "No sinks found for the equation of state");
539 = storage.merged_xyzh.get()
540 .template map<shamrock::solvergraph::PatchDataFieldRef<Tvec>>(
543 return mpdat.get_field<Tvec>(0);
545 xyz_refs.set_refs(refs);
550 sink_pos_buf.copy_from_stdvec(sink_pos);
551 sink_mass_buf.copy_from_stdvec(sink_mass);
553 auto eos_internal = [](Tvec R,
563 Tscal sink_mass_sum = 0;
565 for (
u32 i = 0; i < scount; i++) {
566 Tvec s_r = spos[i] - R;
567 Tscal s_m = smass[i];
568 Tscal s_r_abs = sycl::length(s_r);
569 sink_mass_sum += s_m;
570 pot_sum += s_m / s_r_abs;
573 Tscal cs_out = cs0 * inv_r0_q * sycl::pow(pot_sum / sink_mass_sum, q);
574 Tscal P_a = EOS::pressure_from_cs(cs_out * cs_out, rho_a);
581 auto &spans_rho_ = spans_rho.value().get();
582 spans_rho_.check_sizes(
sizes.indexes);
588 spans_rho_.get_spans().get(
id),
594 [cs0, inv_r0_q, q_, sink_cnt, eos_internal](
603 Tscal rho_a = rho[gid];
618 auto &spans_h_ = spans_h.value().get();
619 spans_h_.check_sizes(
sizes.indexes);
625 spans_h_.get_spans().get(
id),
631 [cs0, inv_r0_q, q_, sink_cnt, pmass_, hfactd_, eos_internal](
639 using namespace shamrock::sph;
641 Tscal rho_a = rho_h(pmass_, h[gid], hfactd_);
658 SolverEOS_Fermi *eos_config
659 = std::get_if<SolverEOS_Fermi>(&solver_config.eos_config.config)) {
662 auto unit_sys = *solver_config.unit_sys;
664 Tscal mass = unit_sys.template to<units::kilogram>();
665 Tscal length = unit_sys.template to<units::metre>();
666 Tscal time = unit_sys.template to<units::second>();
668 Tscal pressure_unit = mass / length / (time * time);
669 Tscal density_unit = mass / (length * length * length);
670 Tscal velocity_unit = length / time;
672 Tscal mu_e = eos_config->mu_e;
674 Tscal pmass_ = pmass.data;
675 Tscal hfactd_ = hfactd.data;
677 auto eos_internal = [density_unit, pressure_unit, velocity_unit](
680 auto const res = EOS::pressure_and_soundspeed(mu_e, rho_a * density_unit);
681 pressure = res.pressure / pressure_unit;
686 auto &spans_rho_ = spans_rho.value().get();
687 spans_rho_.check_sizes(
sizes.indexes);
695 Tscal rho_a = rho[gid];
696 eos_internal(mu_e, rho_a, pressure[gid], soundspeed[gid]);
699 auto &spans_h_ = spans_h.value().get();
700 spans_h_.check_sizes(
sizes.indexes);
706 [mu_e, pmass_, hfactd_, eos_internal](
708 using namespace shamrock::sph;
709 Tscal rho_a = rho_h(pmass_, h[gid], hfactd_);
710 eos_internal(mu_e, rho_a, pressure[gid], soundspeed[gid]);
719template<
class Tvec,
template<
class>
class SPHKernel>
724 Tscal gpart_mass = solver_config.gpart_mass;
727 using namespace shamrock::patch;
737 hfactd.data = Kernel::hfactd;
738 pmass.data = gpart_mass;
744 auto refs = storage.merged_patchdata_ghost.get()
745 .template map<shamrock::solvergraph::PatchDataFieldRef<Tscal>>(
748 return mpdat.get_field<Tscal>(ihpart_interf);
750 h_refs.set_refs(refs);
755 auto refs = storage.merged_patchdata_ghost.get()
756 .template map<shamrock::solvergraph::PatchDataFieldRef<Tscal>>(
759 return mpdat.get_field<Tscal>(iuint_interf);
761 uint_refs.set_refs(refs);
764 auto dev_sched = shamsys::instance::get_compute_scheduler_ptr();
766 if (solver_config.dust_config.has_epsilon_field()) {
769 u32 nvar_dust = solver_config.dust_config.get_dust_nvar();
780 auto refs = storage.merged_patchdata_ghost.get()
781 .template map<shamrock::solvergraph::PatchDataFieldRef<Tscal>>(
784 return mpdat.get_field<Tscal>(iepsilon_interf);
786 epsilon_refs.set_refs(refs);
793 [pmass = pmass.data, hfactd = hfactd.data, nvar_dust](
797 const Tscal *epsilon,
800 using namespace shamrock::sph;
801 Tscal rho_a = rho_h(pmass, h[gid], hfactd);
802 Tscal uint_a = uint[gid];
804 Tscal epsilon_sum = 0;
805 for (
u32 j = 0; j < nvar_dust; j++) {
806 epsilon_sum += epsilon[gid * nvar_dust + j];
809 Tscal rho_g_a = rho_a * (1 - epsilon_sum);
810 Tscal uint_g_a = uint_a / (1 - epsilon_sum);
812 rho_g[gid] = rho_g_a;
813 uint_g[gid] = uint_g_a;
816 compute_eos_internal(
825 }
else if (solver_config.dust_config.has_s_j_field()) {
828 u32 nvar_dust = solver_config.dust_config.get_dust_nvar();
839 auto refs = storage.merged_patchdata_ghost.get()
840 .template map<shamrock::solvergraph::PatchDataFieldRef<Tscal>>(
843 return mpdat.get_field<Tscal>(is_j_interf);
845 s_j_refs.set_refs(refs);
852 [pmass = pmass.data, hfactd = hfactd.data, nvar_dust](
859 using namespace shamrock::sph;
860 Tscal rho_a = rho_h(pmass, h[gid], hfactd);
861 Tscal uint_a = uint[gid];
863 Tscal epsilon_sum = 0;
864 for (
u32 j = 0; j < nvar_dust; j++) {
865 Tscal s = s_j[gid * nvar_dust + j];
866 epsilon_sum += s * s / rho_a;
869 Tscal rho_g_a = rho_a * (1 - epsilon_sum);
870 Tscal uint_g_a = uint_a / (1 - epsilon_sum);
872 rho_g[gid] = rho_g_a;
873 uint_g[gid] = uint_g_a;
876 compute_eos_internal(
887 compute_eos_internal(
constexpr const char * uint
Specific internal energy u.
constexpr const char * xyz
Position field (3D coordinates).
constexpr const char * sizes
Temporary sizes for h-iteration.
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.
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.
virtual DDPatchDataFieldSpanPointer< T > & get_spans()
Get the DistributedData of spans attached to the underlying field.
virtual void ensure_sizes(const shambase::DistributedData< u32 > &sizes)
Ensure that the sizes of the patches in the field match the given sizes (Can resize the underlying fi...
Interface for a solver graph edge representing a field as spans.
virtual DDPatchDataFieldSpanPointer< T > & get_spans()=0
Get the DistributedData of spans attached to the underlying field.
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.
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.