|
9 | 9 | namespace specfem::assembly { |
10 | 10 |
|
11 | 11 | /** |
12 | | - * @brief 2D spectral element edge classification and coupling management |
13 | | - * |
14 | | - * This template specialization provides storage and management for edge |
15 | | - * information in 2D spectral element meshes. It handles edge connectivity, |
16 | | - * interface types, and boundary conditions for coupling between different |
17 | | - * media types in 2D wave propagation problems. |
| 12 | + * @brief Individual 2D edge representation with quadrature point access |
18 | 13 | * |
19 | | - * @code |
20 | | - * // Construct 2D edge types from mesh data |
21 | | - * specfem::assembly::edge_types<specfem::element::dimension_tag::dim2> edges( |
22 | | - * ngllx, ngllz, mesh, element_types); |
| 14 | + * This structure represents a single edge in the 2D spectral element mesh, |
| 15 | + * providing access to quadrature points along the edge for coupling |
| 16 | + * computations, boundary condition enforcement, and flux calculations. |
23 | 17 | * |
24 | | - * // Get elastic-acoustic coupling edges on device |
25 | | - * auto [self_edges, coupled_edges] = edges.get_edges_on_device( |
26 | | - * specfem::connections::type::weakly_conforming, |
27 | | - * specfem::interface::interface_tag::elastic_acoustic, |
28 | | - * specfem::element::boundary_tag::none); |
29 | | - * @endcode |
| 18 | + * @tparam ExecutionSpace Kokkos execution space (host or device) |
30 | 19 | */ |
31 | | -template <> struct edge_types<specfem::element::dimension_tag::dim2> { |
32 | | - |
33 | | -public: |
34 | | - constexpr static auto dimension_tag = |
35 | | - specfem::element::dimension_tag::dim2; ///< Dimension tag |
36 | | - |
37 | | - /** |
38 | | - * @brief Individual 2D edge representation with quadrature point access |
39 | | - * |
40 | | - * This structure represents a single edge in the 2D spectral element mesh, |
41 | | - * providing access to quadrature points along the edge for coupling |
42 | | - * computations, boundary condition enforcement, and flux calculations. |
43 | | - * |
44 | | - * @tparam ExecutionSpace Kokkos execution space (host or device) |
45 | | - */ |
46 | 20 | template <typename ExecutionSpace> struct Edge { |
47 | 21 | int n_points; ///< Number of quadrature points on this edge |
48 | 22 | using IndexView = Kokkos::View<int *, Kokkos::LayoutStride, |
@@ -88,114 +62,142 @@ template <> struct edge_types<specfem::element::dimension_tag::dim2> { |
88 | 62 | } |
89 | 63 | }; |
90 | 64 |
|
| 65 | +/** |
| 66 | + * @brief Collection of 2D edges with parallel access capabilities |
| 67 | + * |
| 68 | + * This structure manages collections of edges for efficient parallel |
| 69 | + * processing of edge-based operations such as coupling computations, |
| 70 | + * boundary condition enforcement, and flux calculations in 2D. |
| 71 | + * |
| 72 | + * @tparam ExecutionSpace Kokkos execution space (host or device) |
| 73 | + * @tparam Layout Memory layout for Kokkos views |
| 74 | + */ |
| 75 | +template <typename ExecutionSpace, |
| 76 | + typename Layout = typename ExecutionSpace::array_layout> |
| 77 | +struct EdgeView { |
| 78 | + int n_edges; ///< Number of edges in this view |
| 79 | + int n_points; ///< Number of quadrature points per edge |
| 80 | + using IndexView = |
| 81 | + Kokkos::View<int *, Layout, ExecutionSpace>; ///< View type for integer |
| 82 | + ///< indices |
| 83 | + using QPView = |
| 84 | + Kokkos::View<int **, Layout, ExecutionSpace>; ///< View type for |
| 85 | + ///< quadrature point |
| 86 | + ///< arrays |
| 87 | + using EdgeTypeView = ///< View type for 2D edge classifications |
| 88 | + Kokkos::View<specfem::mesh_entity::dim2::type *, ExecutionSpace>; |
| 89 | + |
| 90 | + using HostMirror = std::conditional_t< |
| 91 | + std::is_same<typename ExecutionSpace::memory_space, |
| 92 | + Kokkos::HostSpace>::value, |
| 93 | + EdgeView, EdgeView<Kokkos::DefaultHostExecutionSpace, Layout> >; |
| 94 | + |
91 | 95 | /** |
92 | | - * @brief Collection of 2D edges with parallel access capabilities |
93 | | - * |
94 | | - * This structure manages collections of edges for efficient parallel |
95 | | - * processing of edge-based operations such as coupling computations, |
96 | | - * boundary condition enforcement, and flux calculations in 2D. |
| 96 | + * @brief Default constructor creating empty edge view. |
| 97 | + */ |
| 98 | + EdgeView() : n_edges(0), n_points(0) {} |
| 99 | + |
| 100 | + /** |
| 101 | + * @brief Construct edge view with allocated storage. |
97 | 102 | * |
98 | | - * @tparam ExecutionSpace Kokkos execution space (host or device) |
99 | | - * @tparam Layout Memory layout for Kokkos views |
| 103 | + * @param label Base label for Kokkos view names |
| 104 | + * @param n_edges Number of edges to allocate |
| 105 | + * @param n_points Number of quadrature points per edge |
100 | 106 | */ |
101 | | - template <typename ExecutionSpace, |
102 | | - typename Layout = typename ExecutionSpace::array_layout> |
103 | | - struct EdgeView { |
104 | | - int n_edges; ///< Number of edges in this view |
105 | | - int n_points; ///< Number of quadrature points per edge |
106 | | - using IndexView = |
107 | | - Kokkos::View<int *, Layout, ExecutionSpace>; ///< View type for integer |
108 | | - ///< indices |
109 | | - using QPView = |
110 | | - Kokkos::View<int **, Layout, ExecutionSpace>; ///< View type for |
111 | | - ///< quadrature point |
112 | | - ///< arrays |
113 | | - using EdgeTypeView = ///< View type for 2D edge classifications |
114 | | - Kokkos::View<specfem::mesh_entity::dim2::type *, ExecutionSpace>; |
| 107 | + EdgeView(const std::string &label, const int n_edges, const int n_points) |
| 108 | + : n_edges(n_edges), n_points(n_points), |
| 109 | + element_index(label + "_element_index", n_edges), |
| 110 | + edge_index(label + "_edge_index", n_edges), |
| 111 | + edge_types(label + "_edge_types", n_edges), |
| 112 | + iz(label + "_iz", n_edges, n_points), |
| 113 | + ix(label + "_ix", n_edges, n_points) {} |
115 | 114 |
|
116 | | - using HostMirror = std::conditional_t< |
117 | | - std::is_same<typename ExecutionSpace::memory_space, |
118 | | - Kokkos::HostSpace>::value, |
119 | | - EdgeView, EdgeView<Kokkos::DefaultHostExecutionSpace, Layout> >; |
| 115 | + IndexView element_index; ///< Element indices for each edge |
| 116 | + IndexView edge_index; ///< Local edge indices within elements |
| 117 | + EdgeTypeView edge_types; ///< 2D edge type classifications |
| 118 | + QPView iz; ///< Z-direction quadrature indices for all edges |
| 119 | + QPView ix; ///< X-direction quadrature indices for all edges |
120 | 120 |
|
121 | | - /** |
122 | | - * @brief Default constructor creating empty edge view. |
123 | | - */ |
124 | | - EdgeView() : n_edges(0), n_points(0) {} |
| 121 | + /** |
| 122 | + * @brief Device-side constructor from existing views. |
| 123 | + * |
| 124 | + * @param n_edges Number of edges |
| 125 | + * @param n_points Number of quadrature points per edge |
| 126 | + * @param element_index Element indices view |
| 127 | + * @param edge_index Edge indices view |
| 128 | + * @param edge_types Edge types view |
| 129 | + * @param iz Z-direction quadrature indices |
| 130 | + * @param ix X-direction quadrature indices |
| 131 | + */ |
| 132 | + KOKKOS_INLINE_FUNCTION |
| 133 | + EdgeView(const int n_edges, const int n_points, |
| 134 | + const IndexView &element_index, const IndexView &edge_index, |
| 135 | + const EdgeTypeView &edge_types, const QPView &iz, const QPView &ix) |
| 136 | + : n_edges(n_edges), n_points(n_points), element_index(element_index), |
| 137 | + edge_index(edge_index), edge_types(edge_types), iz(iz), ix(ix) {} |
125 | 138 |
|
126 | | - /** |
127 | | - * @brief Construct edge view with allocated storage. |
128 | | - * |
129 | | - * @param label Base label for Kokkos view names |
130 | | - * @param n_edges Number of edges to allocate |
131 | | - * @param n_points Number of quadrature points per edge |
132 | | - */ |
133 | | - EdgeView(const std::string &label, const int n_edges, const int n_points) |
134 | | - : n_edges(n_edges), n_points(n_points), |
135 | | - element_index(label + "_element_index", n_edges), |
136 | | - edge_index(label + "_edge_index", n_edges), |
137 | | - edge_types(label + "_edge_types", n_edges), |
138 | | - iz(label + "_iz", n_edges, n_points), |
139 | | - ix(label + "_ix", n_edges, n_points) {} |
| 139 | + /** |
| 140 | + * @brief Access individual edge by index. |
| 141 | + * |
| 142 | + * @param edge_id Index of the edge to access |
| 143 | + * @return Edge structure for the specified edge |
| 144 | + */ |
| 145 | + KOKKOS_INLINE_FUNCTION |
| 146 | + Edge<ExecutionSpace> operator()(const int edge_id) const { |
| 147 | + return { n_points, |
| 148 | + element_index(edge_id), |
| 149 | + edge_index(edge_id), |
| 150 | + edge_types(edge_id), |
| 151 | + Kokkos::subview(iz, edge_id, Kokkos::ALL()), |
| 152 | + Kokkos::subview(ix, edge_id, Kokkos::ALL()) }; |
| 153 | + } |
140 | 154 |
|
141 | | - IndexView element_index; ///< Element indices for each edge |
142 | | - IndexView edge_index; ///< Local edge indices within elements |
143 | | - EdgeTypeView edge_types; ///< 2D edge type classifications |
144 | | - QPView iz; ///< Z-direction quadrature indices for all edges |
145 | | - QPView ix; ///< X-direction quadrature indices for all edges |
| 155 | + /** |
| 156 | + * @brief Access subrange of edges. |
| 157 | + * |
| 158 | + * @param edge_range Pair specifying start and end indices |
| 159 | + * @return EdgeView containing the specified range of edges |
| 160 | + */ |
| 161 | + KOKKOS_INLINE_FUNCTION |
| 162 | + EdgeView<ExecutionSpace> |
| 163 | + operator()(const Kokkos::pair<int, int> &edge_range) const { |
| 164 | + return { edge_range.second - edge_range.first, |
| 165 | + n_points, |
| 166 | + Kokkos::subview(element_index, edge_range), |
| 167 | + Kokkos::subview(edge_index, edge_range), |
| 168 | + Kokkos::subview(edge_types, edge_range), |
| 169 | + Kokkos::subview(iz, edge_range, Kokkos::ALL()), |
| 170 | + Kokkos::subview(ix, edge_range, Kokkos::ALL()) }; |
| 171 | + } |
| 172 | +}; |
146 | 173 |
|
147 | | - /** |
148 | | - * @brief Device-side constructor from existing views. |
149 | | - * |
150 | | - * @param n_edges Number of edges |
151 | | - * @param n_points Number of quadrature points per edge |
152 | | - * @param element_index Element indices view |
153 | | - * @param edge_index Edge indices view |
154 | | - * @param edge_types Edge types view |
155 | | - * @param iz Z-direction quadrature indices |
156 | | - * @param ix X-direction quadrature indices |
157 | | - */ |
158 | | - KOKKOS_INLINE_FUNCTION |
159 | | - EdgeView(const int n_edges, const int n_points, |
160 | | - const IndexView &element_index, const IndexView &edge_index, |
161 | | - const EdgeTypeView &edge_types, const QPView &iz, const QPView &ix) |
162 | | - : n_edges(n_edges), n_points(n_points), element_index(element_index), |
163 | | - edge_index(edge_index), edge_types(edge_types), iz(iz), ix(ix) {} |
164 | 174 |
|
165 | | - /** |
166 | | - * @brief Access individual edge by index. |
167 | | - * |
168 | | - * @param edge_id Index of the edge to access |
169 | | - * @return Edge structure for the specified edge |
170 | | - */ |
171 | | - KOKKOS_INLINE_FUNCTION |
172 | | - Edge<ExecutionSpace> operator()(const int edge_id) const { |
173 | | - return { n_points, |
174 | | - element_index(edge_id), |
175 | | - edge_index(edge_id), |
176 | | - edge_types(edge_id), |
177 | | - Kokkos::subview(iz, edge_id, Kokkos::ALL()), |
178 | | - Kokkos::subview(ix, edge_id, Kokkos::ALL()) }; |
179 | | - } |
| 175 | +/** |
| 176 | + * @brief 2D spectral element edge classification and coupling management |
| 177 | + * |
| 178 | + * This template specialization provides storage and management for edge |
| 179 | + * information in 2D spectral element meshes. It handles edge connectivity, |
| 180 | + * interface types, and boundary conditions for coupling between different |
| 181 | + * media types in 2D wave propagation problems. |
| 182 | + * |
| 183 | + * @code |
| 184 | + * // Construct 2D edge types from mesh data |
| 185 | + * specfem::assembly::edge_types<specfem::element::dimension_tag::dim2> edges( |
| 186 | + * ngllx, ngllz, mesh, element_types); |
| 187 | + * |
| 188 | + * // Get elastic-acoustic coupling edges on device |
| 189 | + * auto [self_edges, coupled_edges] = edges.get_edges_on_device( |
| 190 | + * specfem::connections::type::weakly_conforming, |
| 191 | + * specfem::interface::interface_tag::elastic_acoustic, |
| 192 | + * specfem::element::boundary_tag::none); |
| 193 | + * @endcode |
| 194 | + */ |
| 195 | +template <> struct edge_types<specfem::element::dimension_tag::dim2> { |
| 196 | + |
| 197 | +public: |
| 198 | + constexpr static auto dimension_tag = |
| 199 | + specfem::element::dimension_tag::dim2; ///< Dimension tag |
180 | 200 |
|
181 | | - /** |
182 | | - * @brief Access subrange of edges. |
183 | | - * |
184 | | - * @param edge_range Pair specifying start and end indices |
185 | | - * @return EdgeView containing the specified range of edges |
186 | | - */ |
187 | | - KOKKOS_INLINE_FUNCTION |
188 | | - EdgeView<ExecutionSpace> |
189 | | - operator()(const Kokkos::pair<int, int> &edge_range) const { |
190 | | - return { edge_range.second - edge_range.first, |
191 | | - n_points, |
192 | | - Kokkos::subview(element_index, edge_range), |
193 | | - Kokkos::subview(edge_index, edge_range), |
194 | | - Kokkos::subview(edge_types, edge_range), |
195 | | - Kokkos::subview(iz, edge_range, Kokkos::ALL()), |
196 | | - Kokkos::subview(ix, edge_range, Kokkos::ALL()) }; |
197 | | - } |
198 | | - }; |
199 | 201 |
|
200 | 202 | public: |
201 | 203 | /** |
|
0 commit comments