SimiLie
Loading...
Searching...
No Matches
hamilton_equations.hpp
1// SPDX-FileCopyrightText: 2026 Baptiste Legouix
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4#pragma once
5
6#include <cstddef>
7#include <span>
8#include <type_traits>
9#include <utility>
10
11#include <ddc/ddc.hpp>
12
13#include <Kokkos_Core.hpp>
14
15namespace similie::physics {
16
17namespace detail {
18
19template <class Hamiltonian, class Index>
20inline constexpr bool has_component_dmoments_v
21 = requires(Hamiltonian const& h) { h.template dhamiltonian_dmoments<Index>(0.0); };
22
23template <class Hamiltonian, class Index>
24inline constexpr bool has_span_dmoments_v
25 = requires(Hamiltonian const& h, std::span<double const, Hamiltonian::N> moments) {
26 h.template dhamiltonian_dmoments<Index>(moments);
27 };
28
29template <class Hamiltonian, class Index, class Elem>
30inline constexpr bool has_elem_dmoments_v = requires(Hamiltonian const& h, Elem elem) {
31 h.template dhamiltonian_dmoments<Index>(0.0, elem);
32};
33
34template <class Hamiltonian, class Index, class Elem>
35inline constexpr bool has_elem_span_dmoments_v = requires(
36 Hamiltonian const& h,
37 std::span<double const, Hamiltonian::N> moments,
38 Elem elem) { h.template dhamiltonian_dmoments<Index>(moments, elem); };
39
40template <class Hamiltonian, class Elem>
41inline constexpr bool has_elem_dpotential_v
42 = requires(Hamiltonian const& h, Elem elem) { h.dhamiltonian_dpotential(0.0, elem); };
43
44} // namespace detail
45
46template <class Hamiltonian>
48{
49 Hamiltonian m_hamiltonian;
50
51public:
52 static constexpr bool IS_LINEAR = Hamiltonian::IS_LINEAR;
53
54 KOKKOS_FUNCTION constexpr explicit HamiltonEquations(Hamiltonian hamiltonian)
55 : m_hamiltonian(std::move(hamiltonian))
56 {
57 }
58
59 template <class Index>
60 [[nodiscard]] KOKKOS_FUNCTION constexpr double dpotential_dt(
61 std::span<double const, Hamiltonian::N> spatial_moments) const
62 {
63 if constexpr (detail::has_span_dmoments_v<Hamiltonian, Index>) {
64 return m_hamiltonian.template dhamiltonian_dmoments<Index>(spatial_moments);
65 } else {
66 return m_hamiltonian.template dhamiltonian_dmoments<Index>(spatial_moments);
67 }
68 }
69
70 template <class Index, class Elem>
71 [[nodiscard]] KOKKOS_FUNCTION constexpr double dpotential_dt(
72 std::span<double const, Hamiltonian::N> spatial_moments,
73 Elem elem) const
74 {
75 if constexpr (detail::has_elem_span_dmoments_v<Hamiltonian, Index, Elem>) {
76 return m_hamiltonian.template dhamiltonian_dmoments<Index>(spatial_moments, elem);
77 } else {
78 return m_hamiltonian.template dhamiltonian_dmoments<Index>(spatial_moments, elem);
79 }
80 }
81
82 template <class Index>
83 [[nodiscard]] KOKKOS_FUNCTION constexpr double dpotential_dt(
84 double spatial_moments_component) const
85 {
86 return m_hamiltonian.template dhamiltonian_dmoments<Index>(spatial_moments_component);
87 }
88
89 template <class Index, class Elem>
90 [[nodiscard]] KOKKOS_FUNCTION constexpr double dpotential_dt(
91 double spatial_moments_component,
92 Elem elem) const
93 {
94 if constexpr (detail::has_elem_dmoments_v<Hamiltonian, Index, Elem>) {
95 return m_hamiltonian
96 .template dhamiltonian_dmoments<Index>(spatial_moments_component, elem);
97 } else {
98 return m_hamiltonian.template dhamiltonian_dmoments<Index>(spatial_moments_component);
99 }
100 }
101
102 template <class Index>
103 [[nodiscard]] KOKKOS_FUNCTION constexpr double dmoments_dt(
104 std::span<double const, 1> potential) const
105 {
106 static_cast<void>(sizeof(Index));
107 return -m_hamiltonian.dhamiltonian_dpotential(potential[0]);
108 }
109
110 template <class Index, class Elem>
111 [[nodiscard]] KOKKOS_FUNCTION constexpr double dmoments_dt(
112 std::span<double const, 1> potential,
113 Elem elem) const
114 {
115 static_cast<void>(sizeof(Index));
116 if constexpr (detail::has_elem_dpotential_v<Hamiltonian, Elem>) {
117 return -m_hamiltonian.dhamiltonian_dpotential(potential[0], elem);
118 } else {
119 static_cast<void>(elem);
120 return dmoments_dt<Index>(potential);
121 }
122 }
123
124 template <class Index>
125 [[nodiscard]] KOKKOS_FUNCTION constexpr double dmoments_dt(double potential) const
126 {
127 static_cast<void>(sizeof(Index));
128 return -m_hamiltonian.dhamiltonian_dpotential(potential);
129 }
130
131 template <class Index, class Elem>
132 [[nodiscard]] KOKKOS_FUNCTION constexpr double dmoments_dt(double potential, Elem elem) const
133 {
134 static_cast<void>(sizeof(Index));
135 if constexpr (detail::has_elem_dpotential_v<Hamiltonian, Elem>) {
136 return -m_hamiltonian.dhamiltonian_dpotential(potential, elem);
137 } else {
138 static_cast<void>(elem);
139 return -m_hamiltonian.dhamiltonian_dpotential(potential);
140 }
141 }
142
143 template <class Index, class Elem>
144 [[nodiscard]] KOKKOS_FUNCTION constexpr auto dpotential_dt_value(Elem elem) const
145 {
146 return m_hamiltonian.template dhamiltonian_dmoments_value<Index>(elem);
147 }
148
149 template <class Index, class Elem>
150 requires requires(Hamiltonian const& h, Elem e) { h.dhamiltonian_dpotential_value(e); }
151 [[nodiscard]] KOKKOS_FUNCTION constexpr auto dmoments_dt_value(Elem elem) const
152 {
153 static_cast<void>(sizeof(Index));
154 auto value = m_hamiltonian.dhamiltonian_dpotential_value(elem);
155 if constexpr (std::is_same_v<std::remove_cvref_t<decltype(value)>, double>) {
156 return -value;
157 } else {
158 ddc::device_for_each(value.domain(), [&](auto mem_elem) { value(mem_elem) *= -1.0; });
159 return value;
160 }
161 }
162};
163
164} // namespace similie::physics
KOKKOS_FUNCTION constexpr double dmoments_dt(std::span< double const, 1 > potential, Elem elem) const
KOKKOS_FUNCTION constexpr double dpotential_dt(double spatial_moments_component, Elem elem) const
KOKKOS_FUNCTION constexpr auto dpotential_dt_value(Elem elem) const
KOKKOS_FUNCTION constexpr double dpotential_dt(std::span< double const, Hamiltonian::N > spatial_moments, Elem elem) const
KOKKOS_FUNCTION constexpr auto dmoments_dt_value(Elem elem) const
KOKKOS_FUNCTION constexpr double dpotential_dt(double spatial_moments_component) const
KOKKOS_FUNCTION constexpr HamiltonEquations(Hamiltonian hamiltonian)
KOKKOS_FUNCTION constexpr double dmoments_dt(std::span< double const, 1 > potential) const
KOKKOS_FUNCTION constexpr double dpotential_dt(std::span< double const, Hamiltonian::N > spatial_moments) const
KOKKOS_FUNCTION constexpr double dmoments_dt(double potential) const
KOKKOS_FUNCTION constexpr double dmoments_dt(double potential, Elem elem) const