43 std::shared_ptr<T> to_shared(T &&t) {
44 return std::make_shared<T>(std::forward<T>(t));
48template<
class Tvec,
template<
class>
class SPHKernel>
55 Tscal gpart_mass = solver_config.gpart_mass;
58 using namespace shamrock::patch;
70 sink_update.compute_sph_forces();
72 if (solver_config.ext_force_config.ext_forces.empty()) {
76 auto field_xyz = shamrock::solvergraph::FieldRefs<Tvec>::make_shared(
"",
"");
82 auto &field = pdat.get_field<Tvec>(0);
83 field_xyz_refs.
add_obj(p.id_patch, std::ref(field));
85 field_xyz_edge.set_refs(field_xyz_refs);
88 set_field_xyz.evaluate();
90 auto field_axyz_ext = shamrock::solvergraph::FieldRefs<Tvec>::make_shared(
"",
"");
96 auto &field = pdat.get_field<Tvec>(iaxyz_ext);
97 field_axyz_ext_refs.
add_obj(p.id_patch, std::ref(field));
99 field_axyz_ext_edge.set_refs(field_axyz_ext_refs);
101 set_field_axyz_ext.
set_edges(field_axyz_ext);
102 set_field_axyz_ext.evaluate();
104 auto sizes = shamrock::solvergraph::Indexes<u32>::make_shared(
"",
"");
110 sizes.indexes.add_obj(p.id_patch, pdat.get_obj_cnt());
114 set_sizes.evaluate();
116 auto constant_G = shamrock::solvergraph::IDataEdge<Tscal>::make_shared(
"",
"");
117 auto constant_c = shamrock::solvergraph::IDataEdge<Tscal>::make_shared(
"",
"");
121 constant_G.data = solver_config.get_constant_G();
126 constant_c.data = solver_config.get_constant_c();
130 set_constant_c.set_edges(constant_c);
132 std::vector<std::shared_ptr<shamrock::solvergraph::INode>> add_ext_forces_seq{};
134 for (
auto var_force : solver_config.ext_force_config.ext_forces) {
135 if (EF_PointMass *ext_force = std::get_if<EF_PointMass>(&var_force.val)) {
137 auto central_mass = shamrock::solvergraph::IDataEdge<Tscal>::make_shared(
"",
"");
138 auto central_pos = shamrock::solvergraph::IDataEdge<Tvec>::make_shared(
"",
"");
141 set_central_mass([cmass = ext_force->central_mass](
143 central_mass.data = cmass;
145 set_central_mass.
set_edges(central_mass);
149 central_pos.data = {};
154 add_force_central_grav_potential.set_edges(
155 constant_G, central_mass, central_pos, field_xyz, sizes, field_axyz_ext);
157 add_ext_forces_seq.push_back(
158 std::make_shared<shamrock::solvergraph::OperationSequence>(
160 std::vector<std::shared_ptr<shamrock::solvergraph::INode>>{
161 shambase::to_shared(std::move(set_central_pos)),
162 shambase::to_shared(std::move(set_central_mass)),
163 shambase::to_shared(std::move(add_force_central_grav_potential))}));
165 }
else if (EF_PN_PW *ext_force = std::get_if<EF_PN_PW>(&var_force.val)) {
167 auto central_mass = shamrock::solvergraph::IDataEdge<Tscal>::make_shared(
"",
"");
168 auto central_pos = shamrock::solvergraph::IDataEdge<Tvec>::make_shared(
"",
"");
171 set_central_mass([cmass = ext_force->central_mass](
173 central_mass.data = cmass;
175 set_central_mass.
set_edges(central_mass);
178 set_central_pos([cpos = ext_force->central_pos](
180 central_pos.data = cpos;
185 add_force_paczynski_wiita.set_edges(
194 add_ext_forces_seq.push_back(
195 std::make_shared<shamrock::solvergraph::OperationSequence>(
196 "Pseudo-Newtonian PW",
197 std::vector<std::shared_ptr<shamrock::solvergraph::INode>>{
198 shambase::to_shared(std::move(set_central_pos)),
199 shambase::to_shared(std::move(set_central_mass)),
200 shambase::to_shared(std::move(add_force_paczynski_wiita))}));
202 }
else if (EF_LenseThirring *ext_force = std::get_if<EF_LenseThirring>(&var_force.val)) {
204 auto central_mass = shamrock::solvergraph::IDataEdge<Tscal>::make_shared(
"",
"");
205 auto central_pos = shamrock::solvergraph::IDataEdge<Tvec>::make_shared(
"",
"");
208 set_central_mass([cmass = ext_force->central_mass](
210 central_mass.data = cmass;
212 set_central_mass.
set_edges(central_mass);
216 central_pos.data = {};
221 add_force_central_grav_potential.set_edges(
222 constant_G, central_mass, central_pos, field_xyz, sizes, field_axyz_ext);
224 add_ext_forces_seq.push_back(
225 std::make_shared<shamrock::solvergraph::OperationSequence>(
227 std::vector<std::shared_ptr<shamrock::solvergraph::INode>>{
228 shambase::to_shared(std::move(set_central_pos)),
229 shambase::to_shared(std::move(set_central_mass)),
230 shambase::to_shared(std::move(add_force_central_grav_potential))}));
233 EF_ShearingBoxForce *ext_force = std::get_if<EF_ShearingBoxForce>(&var_force.val)) {
235 auto eta = shamrock::solvergraph::IDataEdge<Tscal>::make_shared(
"",
"");
238 eta.data = ext_force->eta;
243 add_force_shearing_box_inertial_part{};
244 add_force_shearing_box_inertial_part.set_edges(eta, field_xyz, sizes, field_axyz_ext);
246 add_ext_forces_seq.push_back(
247 std::make_shared<shamrock::solvergraph::OperationSequence>(
248 "Shearing box force",
249 std::vector<std::shared_ptr<shamrock::solvergraph::INode>>{
250 shambase::to_shared(std::move(set_eta)),
251 shambase::to_shared(std::move(add_force_shearing_box_inertial_part))}));
254 EF_VerticalDiscPotential *ext_force
255 = std::get_if<EF_VerticalDiscPotential>(&var_force.val)) {
257 auto central_mass = shamrock::solvergraph::IDataEdge<Tscal>::make_shared(
"",
"");
258 auto R0 = shamrock::solvergraph::IDataEdge<Tscal>::make_shared(
"",
"");
261 set_central_mass([cmass = ext_force->central_mass](
263 central_mass.data = cmass;
265 set_central_mass.
set_edges(central_mass);
274 add_force_vertical_disc_potential.set_edges(
275 constant_G, central_mass, R0, field_xyz, sizes, field_axyz_ext);
277 add_ext_forces_seq.push_back(
278 std::make_shared<shamrock::solvergraph::OperationSequence>(
279 "Vertical disc potential",
280 std::vector<std::shared_ptr<shamrock::solvergraph::INode>>{
281 shambase::to_shared(std::move(set_R0)),
282 shambase::to_shared(std::move(set_central_mass)),
283 shambase::to_shared(std::move(add_force_vertical_disc_potential))}));
286 EF_VelocityDissipation *ext_force
287 = std::get_if<EF_VelocityDissipation>(&var_force.val)) {
294 set_constant_G.evaluate();
295 set_constant_c.evaluate();
297 if (add_ext_forces_seq.size() > 0) {
299 "Add external forces", std::move(add_ext_forces_seq));
305std::shared_ptr<shamrock::solvergraph::INode> register_constant_set(
313 edge.data = getter();
324template<
class Tvec,
template<
class>
class SPHKernel>
331 Tscal gpart_mass = solver_config.gpart_mass;
334 using namespace shamrock::patch;
348 auto axyz_ext = buf_axyz_ext.get_read_access(depends_list);
350 auto e = q.
submit(depends_list, [&](sycl::handler &cgh) {
351 shambase::parallel_for(
352 cgh, pdat.get_obj_cnt(),
"add ext force acc to acc", [=](
u64 gid) {
353 axyz[gid] += axyz_ext[gid];
358 buf_axyz_ext.complete_event_state(e);
361 if (solver_config.ext_force_config.ext_forces.empty()) {
366 using EF_PointMass =
typename SolverConfigExtForce::PointMass;
367 using EF_PN_PW =
typename SolverConfigExtForce::PN_PW;
368 using EF_LenseThirring =
typename SolverConfigExtForce::LenseThirring;
370 using namespace shamrock::solvergraph;
373 auto set_constant_G = register_constant_set<Tscal>(solver_graph,
"constant_G", [&]() {
374 return solver_config.get_constant_G();
376 auto set_constant_c = register_constant_set<Tscal>(solver_graph,
"constant_c", [&]() {
377 return solver_config.get_constant_c();
380 bool is_G_needed =
false;
381 bool is_c_needed =
false;
383 for (
auto var_force : solver_config.ext_force_config.ext_forces) {
384 if (EF_PointMass *ext_force = std::get_if<EF_PointMass>(&var_force.val)) {
386 }
else if (EF_PN_PW *ext_force = std::get_if<EF_PN_PW>(&var_force.val)) {
389 }
else if (EF_LenseThirring *ext_force = std::get_if<EF_LenseThirring>(&var_force.val)) {
393 EF_ShearingBoxForce *ext_force = std::get_if<EF_ShearingBoxForce>(&var_force.val)) {
395 EF_VerticalDiscPotential *ext_force
396 = std::get_if<EF_VerticalDiscPotential>(&var_force.val)) {
398 EF_VelocityDissipation *ext_force
399 = std::get_if<EF_VelocityDissipation>(&var_force.val)) {
405 std::vector<std::shared_ptr<shamrock::solvergraph::INode>> add_ext_forces_seq{};
408 add_ext_forces_seq.push_back(set_constant_G);
411 add_ext_forces_seq.push_back(set_constant_c);
423 auto &field = pdat.get_field<Tvec>(0);
424 field_xyz_refs.
add_obj(p.id_patch, std::ref(field));
426 field_xyz_edge.set_refs(field_xyz_refs);
434 auto &field = pdat.get_field<Tvec>(ivxyz);
435 field_vxyz_refs.
add_obj(p.id_patch, std::ref(field));
437 field_vxyz_edge.set_refs(field_vxyz_refs);
445 auto &field = pdat.get_field<Tvec>(iaxyz);
446 field_axyz_refs.
add_obj(p.id_patch, std::ref(field));
448 field_axyz_edge.set_refs(field_axyz_refs);
456 sizes.indexes.add_obj(p.id_patch, pdat.get_obj_cnt());
461 add_ext_forces_seq.push_back(set_field_xyz);
462 add_ext_forces_seq.push_back(set_field_vxyz);
463 add_ext_forces_seq.push_back(set_field_axyz);
464 add_ext_forces_seq.push_back(set_field_sizes);
466 for (
u32 i = 0; i < solver_config.ext_force_config.ext_forces.size(); i++) {
468 auto &var_force = solver_config.ext_force_config.ext_forces[i];
470 std::string prefix = shambase::format(
"ext_force_{}_", i);
472 if (EF_PointMass *ext_force = std::get_if<EF_PointMass>(&var_force.val)) {
474 }
else if (EF_PN_PW *ext_force = std::get_if<EF_PN_PW>(&var_force.val)) {
476 }
else if (EF_LenseThirring *ext_force = std::get_if<EF_LenseThirring>(&var_force.val)) {
478 std::string prefix_cmass = prefix +
"cmass_";
479 std::string prefix_central_pos = prefix +
"central_pos_";
480 std::string prefix_a_spin = prefix +
"a_spin_";
481 std::string prefix_dir_spin = prefix +
"dir_spin_";
482 std::string prefix_lt = prefix +
"lt_";
484 auto set_cmass = register_constant_set<Tscal>(solver_graph, prefix_cmass, [&]() {
485 return ext_force->central_mass;
489 = register_constant_set<Tvec>(solver_graph, prefix_central_pos, [&]() {
490 return Tvec{0, 0, 0};
493 auto set_a_spin = register_constant_set<Tscal>(solver_graph, prefix_a_spin, [&]() {
494 return ext_force->a_spin;
497 auto set_dir_spin = register_constant_set<Tvec>(solver_graph, prefix_dir_spin, [&]() {
498 return ext_force->dir_spin;
516 add_ext_forces_seq.push_back(set_cmass);
517 add_ext_forces_seq.push_back(set_central_pos);
518 add_ext_forces_seq.push_back(set_a_spin);
519 add_ext_forces_seq.push_back(set_dir_spin);
523 EF_ShearingBoxForce *ext_force = std::get_if<EF_ShearingBoxForce>(&var_force.val)) {
525 std::string prefix_Omega_0 = prefix +
"Omega_0_";
526 std::string prefix_q = prefix +
"q_";
527 std::string prefix_shearing_box = prefix +
"shearing_box_";
529 auto set_Omega_0 = register_constant_set<Tscal>(solver_graph, prefix_Omega_0, [&]() {
530 return ext_force->Omega_0;
533 auto set_q = register_constant_set<Tscal>(solver_graph, prefix_q, [&]() {
537 auto add_force_shearing_box_non_inertial = solver_graph.
register_node(
549 add_ext_forces_seq.push_back(set_Omega_0);
550 add_ext_forces_seq.push_back(set_q);
551 add_ext_forces_seq.push_back(solver_graph.
get_node_ptr_base(prefix_shearing_box));
554 EF_VerticalDiscPotential *ext_force
555 = std::get_if<EF_VerticalDiscPotential>(&var_force.val)) {
557 EF_VelocityDissipation *ext_force
558 = std::get_if<EF_VelocityDissipation>(&var_force.val)) {
559 std::string prefix_eta = prefix +
"eta_";
560 std::string prefix_velocity_dissipation = prefix +
"velocity_dissipation_";
563 = register_constant_set<Tscal>(solver_graph, prefix_eta, [eta = ext_force->eta]() {
567 auto add_force_velocity_dissipation = solver_graph.
register_node(
568 prefix_velocity_dissipation,
577 add_ext_forces_seq.push_back(set_eta);
578 add_ext_forces_seq.push_back(
586 if (add_ext_forces_seq.size() > 0) {
592template<
class Tvec,
template<
class>
class SPHKernel>
593void shammodels::sph::modules::ExternalForces<Tvec, SPHKernel>::point_mass_accrete_particles() {
597 Tscal gpart_mass = solver_config.gpart_mass;
600 using namespace shamrock::patch;
602 using SolverConfigExtForce =
typename Config::ExtForceConfig;
603 using EF_PointMass =
typename SolverConfigExtForce::PointMass;
604 using EF_LenseThirring =
typename SolverConfigExtForce::LenseThirring;
610 auto dev_sched = shamsys::instance::get_compute_scheduler_ptr();
614 for (
auto var_force : solver_config.ext_force_config.ext_forces) {
619 if (EF_PointMass *ext_force = std::get_if<EF_PointMass>(&var_force.val)) {
620 pos_accretion = {0, 0, 0};
621 Racc = ext_force->Racc;
622 }
else if (EF_PN_PW *ext_force = std::get_if<EF_PN_PW>(&var_force.val)) {
623 pos_accretion = {0, 0, 0};
624 Racc = ext_force->Racc;
625 }
else if (EF_LenseThirring *ext_force = std::get_if<EF_LenseThirring>(&var_force.val)) {
626 pos_accretion = {0, 0, 0};
627 Racc = ext_force->Racc;
633 u32 Nobj = pdat.get_obj_cnt();
638 sycl::buffer<u32> not_accreted(Nobj);
639 sycl::buffer<u32> accreted(Nobj);
644 auto e = q.
submit(depends_list, [&](sycl::handler &cgh) {
645 sycl::accessor not_acc{not_accreted, cgh, sycl::write_only, sycl::no_init};
646 sycl::accessor acc{accreted, cgh, sycl::write_only, sycl::no_init};
648 Tvec r_sink = pos_accretion;
649 Tscal acc_rad2 = Racc * Racc;
651 shambase::parallel_for(cgh, Nobj,
"check accretion", [=](
i32 id_a) {
652 Tvec r =
xyz[id_a] - r_sink;
653 bool not_accreted = sycl::dot(r, r) > acc_rad2;
654 not_acc[id_a] = (not_accreted) ? 1 : 0;
655 acc[id_a] = (!not_accreted) ? 1 : 0;
661 std::tuple<std::optional<sycl::buffer<u32>>,
u32> id_list_keep
664 std::tuple<std::optional<sycl::buffer<u32>>,
u32> id_list_accrete
669 if (std::get<1>(id_list_accrete) > 0) {
671 u32 Naccrete = std::get<1>(id_list_accrete);
673 Tscal acc_mass = gpart_mass * Naccrete;
679 auto vxyz = buf_vxyz.get_read_access(depends_list);
680 auto accretion_p = pxyz_acc.get_write_access(depends_list);
682 auto e = q.
submit(depends_list, [&, gpart_mass](sycl::handler &cgh) {
683 sycl::accessor id_acc{*std::get<0>(id_list_accrete), cgh, sycl::read_only};
685 shambase::parallel_for(
686 cgh, Naccrete,
"compute sum momentum accretion", [=](
i32 id_a) {
687 accretion_p[id_a] = gpart_mass *
vxyz[id_acc[id_a]];
691 buf_vxyz.complete_event_state(e);
692 pxyz_acc.complete_event_state(e);
698 pdat.keep_ids(*std::get<0>(id_list_keep), std::get<1>(id_list_keep));
Adds the acceleration from a central gravitational potential (point mass).
Adds the Lense-Thirring force acceleration.
Adds the acceleration from a Paczynski Wiita (1980) pseudo-newtonian potential.
Adds the inertial part of the acceleration for a shearing box force.
Adds the non-inertial part of the acceleration for a shearing box force.
Adds the acceleration from a velocity dissipation force.
Adds the acceleration from a vertical disc potential.
constexpr const char * vxyz
3-velocity field
constexpr const char * xyz
Position field (3D coordinates).
shambase::DistributedData< PatchDataFieldRef< T > > DDPatchDataFieldRef
Alias for a DistributedData of PatchDataFieldRefs.
Node that applies a custom function to modify connected edges.
Declare a class to register and retrieve nodes and edges from a unique container.
std::uint32_t u32
32 bit unsigned integer
std::uint64_t u64
64 bit unsigned integer
std::int32_t i32
32 bit 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::queue q
The SYCL queue associated with this context.
sycl::event submit(Fct &&fct)
Submits a kernel to the SYCL queue.
Class to manage a list of SYCL events.
iterator add_obj(u64 id, T &&obj)
Adds a new object to the collection.
void add_ext_forces()
add external forces to the particle acceleration, note that forces dependant on velocity shlould be a...
void compute_ext_forces_indep_v()
is ran once per timestep, it computes the forces that are independant of velocity
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.
Interface for a solver graph edge representing a field as spans.
void evaluate()
Evaluate the node.
A node that applies a custom function to modify connected edges.
void set_edges(std::shared_ptr< IEdge > to_set)
Set the edges of the node.
A graph container for managing solver nodes and edges with type-safe access.
std::shared_ptr< INode > & get_node_ptr_base(const std::string &name)
Retrieve a node by name as a shared pointer to the base interface.
std::shared_ptr< T > get_edge_ptr(const std::string &name)
Get a typed shared pointer to an edge by name.
std::shared_ptr< T > register_edge(const std::string &name, T &&edge)
Register an edge with automatic type deduction and shared pointer creation.
std::shared_ptr< IEdge > & get_edge_ptr_base(const std::string &name)
Retrieve an edge by name as a shared pointer to the base interface.
std::shared_ptr< T > register_node(const std::string &name, T &&node)
Register a node with automatic type deduction and shared pointer creation.
T & get_node_ref(const std::string &name)
Get a typed reference to a node by name.
std::tuple< std::optional< sycl::buffer< u32 > >, u32 > stream_compact(sycl::queue &q, sycl::buffer< u32 > &buf_flags, u32 len)
Stream compaction algorithm.
T sum(const sham::DeviceScheduler_ptr &sched, const sham::DeviceBuffer< T > &buf1, u32 start_id, u32 end_id)
Compute the sum of elements in a device buffer within a specified range.
namespace for basic c++ utilities
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...
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
void raw_ln(Types... var2)
Prints a log message with multiple arguments followed by a newline.
shambase::details::BasicStackEntry StackEntry
Alias for shambase::details::BasicStackEntry.
shammodels::ExtForceConfig< Tvec > ExtForceConfig
External force configuration.
Patch object that contain generic patch information.