41 Tscal operator()(
u32 i)
const {
42 using namespace shamrock::sph;
43 return rho_h(pmass, h[i], hfact);
48 auto h = buf_h.get_read_access(depends_list);
52 void complete_event_state(sycl::event e) { buf_h.complete_event_state(e); }
65 const Tscal *buf_epsilon;
70 Tscal operator()(
u32 i)
const {
72 Tscal epsilon_sum = 0;
73 for (
u32 j = 0; j < nvar_dust; j++) {
74 epsilon_sum += buf_epsilon[i * nvar_dust + j];
77 using namespace shamrock::sph;
78 return (1 - epsilon_sum) * rho_h(pmass, h[i], hfact);
83 auto h = buf_h.get_read_access(depends_list);
84 auto epsilon = buf_epsilon.get_read_access(depends_list);
86 return accessed{h, epsilon, nvar_dust, pmass, hfact};
89 void complete_event_state(sycl::event e) { buf_h.complete_event_state(e); }
102 const Tscal *buf_s_j;
107 Tscal operator()(
u32 i)
const {
108 using namespace shamrock::sph;
109 Tscal rho = rho_h(pmass, h[i], hfact);
111 Tscal epsilon_sum = 0;
112 for (
u32 j = 0; j < nvar_dust; j++) {
113 Tscal s_j = buf_s_j[i * nvar_dust + j];
114 epsilon_sum += s_j * s_j / rho;
117 return rho * (1 - epsilon_sum);
122 auto h = buf_h.get_read_access(depends_list);
123 auto s_j = buf_s_j.get_read_access(depends_list);
125 return accessed{h, s_j, nvar_dust, pmass, hfact};
128 void complete_event_state(sycl::event e) {
129 buf_h.complete_event_state(e);
130 buf_s_j.complete_event_state(e);
134template<
class Tvec,
template<
class>
class SPHKernel>
135template<
class RhoGetGen>
136void shammodels::sph::modules::ComputeEos<Tvec, SPHKernel>::compute_eos_internal(
137 RhoGetGen &&rho_getter_gen) {
144 using namespace shamrock::patch;
146 using SolverConfigEOS =
typename Config::EOSConfig;
147 using SolverEOS_Isothermal =
typename SolverConfigEOS::Isothermal;
148 using SolverEOS_Adiabatic =
typename SolverConfigEOS::Adiabatic;
149 using SolverEOS_Polytropic =
typename SolverConfigEOS::Polytropic;
150 using SolverEOS_LocallyIsothermal =
typename SolverConfigEOS::LocallyIsothermal;
151 using SolverEOS_LocallyIsothermalLP07 =
typename SolverConfigEOS::LocallyIsothermalLP07;
152 using SolverEOS_LocallyIsothermalFA2014 =
typename SolverConfigEOS::LocallyIsothermalFA2014;
153 using SolverEOS_LocallyIsothermalFA2014Extended =
154 typename SolverConfigEOS::LocallyIsothermalFA2014Extended;
155 using SolverEOS_Fermi =
typename SolverConfigEOS::Fermi;
159 if (SolverEOS_Isothermal *eos_config
160 = std::get_if<SolverEOS_Isothermal>(&solver_config.eos_config.config)) {
164 storage.merged_patchdata_ghost.get().for_each([&](
u64 id,
PatchDataLayer &mpdat) {
169 auto rho_getter = rho_getter_gen(mpdat);
180 = eos_config->cs](
u32 i,
auto rho, Tscal *__restrict P, Tscal *__restrict cs) {
181 using namespace shamrock::sph;
182 Tscal rho_a = rho(i);
183 Tscal P_a = EOS::pressure(cs_cfg, rho_a);
189 SolverEOS_Adiabatic *eos_config
190 = std::get_if<SolverEOS_Adiabatic>(&solver_config.eos_config.config)) {
194 storage.merged_patchdata_ghost.get().for_each([&](
u64 id,
PatchDataLayer &mpdat) {
200 auto rho_getter = rho_getter_gen(mpdat);
210 [gamma = eos_config->gamma](
213 const Tscal *__restrict U,
215 Tscal *__restrict cs) {
216 using namespace shamrock::sph;
217 Tscal rho_a = rho(i);
218 Tscal P_a = EOS::pressure(gamma, rho_a, U[i]);
219 Tscal cs_a = EOS::cs_from_p(gamma, rho_a, P_a);
226 SolverEOS_Polytropic *eos_config
227 = std::get_if<SolverEOS_Polytropic>(&solver_config.eos_config.config)) {
231 storage.merged_patchdata_ghost.get().for_each([&](
u64 id,
PatchDataLayer &mpdat) {
236 auto rho_getter = rho_getter_gen(mpdat);
246 [K = eos_config->K, gamma = eos_config->gamma](
247 u32 i,
auto rho, Tscal *__restrict P, Tscal *__restrict cs) {
248 using namespace shamrock::sph;
249 Tscal rho_a = rho(i);
250 Tscal P_a = EOS::pressure(gamma, K, rho_a);
251 Tscal cs_a = EOS::soundspeed(gamma, K, rho_a);
258 SolverEOS_LocallyIsothermal *eos_config
259 = std::get_if<SolverEOS_LocallyIsothermal>(&solver_config.eos_config.config)) {
265 storage.merged_patchdata_ghost.get().for_each([&](
u64 id,
PatchDataLayer &mpdat) {
271 auto rho_getter = rho_getter_gen(mpdat);
284 const Tscal *__restrict U,
285 const Tscal *__restrict cs0,
287 Tscal *__restrict cs) {
288 using namespace shamrock::sph;
290 Tscal cs_out = cs0[i];
291 Tscal rho_a = rho(i);
293 Tscal P_a = EOS::pressure_from_cs(cs_out * cs_out, rho_a);
301 SolverEOS_LocallyIsothermalLP07 *eos_config
302 = std::get_if<SolverEOS_LocallyIsothermalLP07>(&solver_config.eos_config.config)) {
306 storage.merged_patchdata_ghost.get().for_each([&](
u64 id,
PatchDataLayer &mpdat) {
307 auto &mfield = storage.merged_xyzh.get().get(
id);
316 auto rho_getter = rho_getter_gen(mpdat);
318 Tscal cs0 = eos_config->cs0;
319 Tscal r0sq = eos_config->r0 * eos_config->r0;
320 Tscal mq = -eos_config->q;
333 const Tscal *__restrict U,
334 const Tvec *__restrict
xyz,
336 Tscal *__restrict cs) {
337 using namespace shamrock::sph;
340 Tscal rho_a = rho(i);
342 Tscal Rsq = sycl::dot(R, R);
343 Tscal cs_sq = EOS::soundspeed_sq(cs0 * cs0, Rsq / r0sq, mq);
344 Tscal cs_out = sycl::sqrt(cs_sq);
346 Tscal P_a = EOS::pressure_from_cs(cs_sq, rho_a);
354 SolverEOS_LocallyIsothermalFA2014 *eos_config
355 = std::get_if<SolverEOS_LocallyIsothermalFA2014>(&solver_config.eos_config.config)) {
357 Tscal _G = solver_config.get_constant_G();
361 auto &sink_parts = storage.sinks.get();
362 std::vector<Tvec> sink_pos;
363 std::vector<Tscal> sink_mass;
366 for (
auto &s : sink_parts) {
367 sink_pos.push_back(s.pos);
368 sink_mass.push_back(s.mass);
372 sycl::buffer<Tvec> sink_pos_buf{sink_pos};
373 sycl::buffer<Tscal> sink_mass_buf{sink_mass};
375 storage.merged_patchdata_ghost.get().for_each([&](
u64 id,
PatchDataLayer &mpdat) {
376 auto &mfield = storage.merged_xyzh.get().get(
id);
385 auto rho_getter = rho_getter_gen(mpdat);
393 auto rho = rho_getter.get_read_access(depends_list);
400 auto e = q.
submit(depends_list, [&](sycl::handler &cgh) {
401 sycl::accessor spos{sink_pos_buf, cgh, sycl::read_only};
402 sycl::accessor smass{sink_mass_buf, cgh, sycl::read_only};
403 u32 scount = sink_cnt;
405 Tscal h_over_r = eos_config->h_over_r;
408 cgh.parallel_for(sycl::range<1>{total_elements}, [=](sycl::item<1> item) {
409 using namespace shamrock::sph;
412 Tscal rho_a = rho(item.get_linear_id());
414 Tscal mpotential = 0;
415 for (
u32 i = 0; i < scount; i++) {
416 Tvec s_r = spos[i] - R;
417 Tscal s_m = smass[i];
418 Tscal s_r_abs = sycl::length(s_r);
419 mpotential += G * s_m / s_r_abs;
422 Tscal cs_out = h_over_r * sycl::sqrt(mpotential);
423 Tscal P_a = EOS::pressure_from_cs(cs_out * cs_out, rho_a);
432 rho_getter.complete_event_state(e);
438 SolverEOS_LocallyIsothermalFA2014Extended *eos_config
439 = std::get_if<SolverEOS_LocallyIsothermalFA2014Extended>(
440 &solver_config.eos_config.config)) {
442 Tscal _cs0 = eos_config->cs0;
443 Tscal _r0 = eos_config->r0;
444 Tscal _q = eos_config->q;
445 u32 n_sinks = eos_config->n_sinks;
449 auto &sink_parts = storage.sinks.get();
450 std::vector<Tvec> sink_pos;
451 std::vector<Tscal> sink_mass;
454 for (
auto &s : sink_parts) {
455 sink_pos.push_back(s.pos);
456 sink_mass.push_back(s.mass);
458 if (sink_pos.size() >= n_sinks) {
465 "No sinks found for the equation of state");
468 sycl::buffer<Tvec> sink_pos_buf{sink_pos};
469 sycl::buffer<Tscal> sink_mass_buf{sink_mass};
471 storage.merged_patchdata_ghost.get().for_each([&](
u64 id,
PatchDataLayer &mpdat) {
472 auto &mfield = storage.merged_xyzh.get().get(
id);
481 auto rho_getter = rho_getter_gen(mpdat);
489 auto rho = rho_getter.get_read_access(depends_list);
496 auto e = q.
submit(depends_list, [&](sycl::handler &cgh) {
497 sycl::accessor spos{sink_pos_buf, cgh, sycl::read_only};
498 sycl::accessor smass{sink_mass_buf, cgh, sycl::read_only};
499 u32 scount = sink_cnt;
505 Tscal inv_r0_q = 1. / sycl::pow(r0, q);
507 cgh.parallel_for(sycl::range<1>{total_elements}, [=](sycl::item<1> item) {
508 using namespace shamrock::sph;
511 Tscal rho_a = rho(item.get_linear_id());
513 Tscal sink_mass_sum = 0;
515 for (
u32 i = 0; i < scount; i++) {
516 Tvec s_r = spos[i] - R;
517 Tscal s_m = smass[i];
518 Tscal s_r_abs = sycl::length(s_r);
519 sink_mass_sum += s_m;
520 pot_sum += s_m / s_r_abs;
523 Tscal cs_out = cs0 * inv_r0_q * sycl::pow(pot_sum / sink_mass_sum, q);
524 Tscal P_a = EOS::pressure_from_cs(cs_out * cs_out, rho_a);
533 rho_getter.complete_event_state(e);
539 SolverEOS_Fermi *eos_config
540 = std::get_if<SolverEOS_Fermi>(&solver_config.eos_config.config)) {
544 storage.merged_patchdata_ghost.get().for_each([&](
u64 id,
PatchDataLayer &mpdat) {
549 auto rho_getter = rho_getter_gen(mpdat);
555 auto unit_sys = *solver_config.unit_sys;
557 Tscal mass = unit_sys.template to<units::kilogram>();
558 Tscal length = unit_sys.template to<units::metre>();
559 Tscal time = unit_sys.template to<units::second>();
561 Tscal pressure_unit = mass / length / (time * time);
562 Tscal density_unit = mass / (length * length * length);
563 Tscal velocity_unit = length / time;
570 [mu_e = eos_config->mu_e, density_unit, pressure_unit, velocity_unit](
571 u32 i,
auto rho, Tscal *__restrict P, Tscal *__restrict cs) {
572 Tscal rho_a = rho(i);
573 auto const res = EOS::pressure_and_soundspeed(mu_e, rho_a * density_unit);
574 P[i] = res.pressure / pressure_unit;
575 cs[i] = res.soundspeed / velocity_unit;
584template<
class Tvec,
template<
class>
class SPHKernel>
589 Tscal gpart_mass = solver_config.gpart_mass;
592 using namespace shamrock::patch;
606 if (solver_config.dust_config.has_epsilon_field()) {
609 u32 nvar_dust = solver_config.dust_config.get_dust_nvar();
613 mpdat.get_field_buf_ref<Tscal>(ihpart_interf),
614 mpdat.get_field_buf_ref<Tscal>(iepsilon_interf),
619 }
else if (solver_config.dust_config.has_s_j_field()) {
622 u32 nvar_dust = solver_config.dust_config.get_dust_nvar();
626 mpdat.get_field_buf_ref<Tscal>(ihpart_interf),
627 mpdat.get_field_buf_ref<Tscal>(is_j_interf),
635 mpdat.get_field_buf_ref<Tscal>(ihpart_interf), gpart_mass, Kernel::hfactd};
constexpr const char * xyz
Position field (3D coordinates).
std::uint32_t u32
32 bit unsigned integer
std::uint64_t u64
64 bit unsigned integer
A buffer allocated in USM (Unified Shared Memory).
void complete_event_state(sycl::event e) const
Complete the event state of the buffer.
T * get_write_access(sham::EventList &depends_list, SourceLocation src_loc=SourceLocation{})
Get a read-write pointer to the buffer's data.
const T * get_read_access(sham::EventList &depends_list, SourceLocation src_loc=SourceLocation{}) const
Get a read-only pointer to the buffer's data.
A SYCL queue associated with a device and a context.
sycl::event submit(Fct &&fct)
Submits a kernel to the SYCL queue.
Class to manage a list of SYCL events.
Represents a collection of objects distributed across patches identified by a u64 id.
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.
This header file contains utility functions related to exception handling in the code.
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
shambase::details::NamedBasicStackEntry NamedStackEntry
Alias for shambase::details::NamedBasicStackEntry.
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.