Loading...
Searching...
No Matches
div_k_grad_simple.hpp
Go to the documentation of this file.
1
2#pragma once
3
4#include "../../quadrature/quadrature.hpp"
6#include "dense/vec.hpp"
9#include "grid/grid_types.hpp"
11#include "linalg/operator.hpp"
12#include "linalg/vector.hpp"
13#include "linalg/vector_q1.hpp"
14
16
17template < typename ScalarT >
19{
20 public:
23 using ScalarType = ScalarT;
25 static constexpr int LocalMatrixDim = 6;
26
27 private:
28 bool storeLMatrices_ =
29 false; // set to let apply_impl() know, that it should store the local matrices after assembling them
30 bool applyStoredLMatrices_ =
31 false; // set to make apply_impl() load and use the stored LMatrices for the operator application
32 Grid4DDataLocalMatrices lmatrices_;
33 bool single_quadpoint_ = false;
34
36
40
41 bool treat_boundary_;
42 bool diagonal_;
43
44 linalg::OperatorApplyMode operator_apply_mode_;
45 linalg::OperatorCommunicationMode operator_communication_mode_;
46
49
52
54 ScalarT quad_weights_3x2_[quadrature::quad_felippa_3x2_num_quad_points];
56 ScalarT quad_weights_1x1_[quadrature::quad_felippa_1x1_num_quad_points];
57
58
59 public:
65 bool treat_boundary,
66 bool diagonal,
68 linalg::OperatorCommunicationMode operator_communication_mode =
70 : domain_( domain )
71 , grid_( grid )
72 , radii_( radii )
73 , k_( k )
74 , treat_boundary_( treat_boundary )
75 , diagonal_( diagonal )
76 , operator_apply_mode_( operator_apply_mode )
77 , operator_communication_mode_( operator_communication_mode )
78 // TODO: we can reuse the send and recv buffers and pass in from the outside somehow
79 , send_buffers_( domain )
80 , recv_buffers_( domain )
81 {
86 }
87
88 /// @brief Getter for domain member
89 const grid::shell::DistributedDomain& get_domain() const { return domain_; }
90
91 /// @brief Getter for radii member
93
94 /// @brief Getter for grid member
96
97 /// @brief S/Getter for diagonal member
98 void set_diagonal( bool v ) { diagonal_ = v; }
99
100 /// @brief S/Getter for quadpoint member
101 void set_single_quadpoint( bool v ) { single_quadpoint_ = v; }
102
103 /// @brief Retrives the local matrix stored in the operator
104 KOKKOS_INLINE_FUNCTION
106 const int local_subdomain_id,
107 const int x_cell,
108 const int y_cell,
109 const int r_cell,
110 const int wedge )
111 {
112 assert( lmatrices_.data() != nullptr );
113
114 return lmatrices_( local_subdomain_id, x_cell, y_cell, r_cell, wedge );
115 }
116
117 /// @brief Set the local matrix stored in the operator
118 KOKKOS_INLINE_FUNCTION
120 const int local_subdomain_id,
121 const int x_cell,
122 const int y_cell,
123 const int r_cell,
124 const int wedge,
126 { Kokkos::abort( "Not implemented." ); }
127
128 /// @brief Setter/Getter for app applyStoredLMatrices_: usage of stored local matrices during apply
129 void setApplyStoredLMatrices( bool v ) { applyStoredLMatrices_ = v; }
130
131 /// @brief
132 /// allocates memory for the local matrices
133 /// calls kernel with storeLMatrices_ = true to assemble and store the local matrices
134 /// sets applyStoredLMatrices_, such that future applies use the stored local matrices
136 {
137 storeLMatrices_ = true;
138 if ( lmatrices_.data() == nullptr )
139 {
140 lmatrices_ = Grid4DDataLocalMatrices(
141 "LaplaceSimple::lmatrices_",
142 domain_.subdomains().size(),
146 Kokkos::parallel_for(
147 "assemble_store_lmatrices", grid::shell::local_domain_md_range_policy_cells( domain_ ), *this );
148 Kokkos::fence();
149 }
150 storeLMatrices_ = false;
151 applyStoredLMatrices_ = true;
152 }
153
154 void apply_impl( const SrcVectorType& src, DstVectorType& dst )
155 {
156 if ( storeLMatrices_ or applyStoredLMatrices_ )
157 assert( lmatrices_.data() != nullptr );
158
159 if ( operator_apply_mode_ == linalg::OperatorApplyMode::Replace )
160 {
161 assign( dst, 0 );
162 }
163
164 src_ = src.grid_data();
165 dst_ = dst.grid_data();
166
167 if ( src_.extent( 0 ) != dst_.extent( 0 ) || src_.extent( 1 ) != dst_.extent( 1 ) ||
168 src_.extent( 2 ) != dst_.extent( 2 ) || src_.extent( 3 ) != dst_.extent( 3 ) )
169 {
170 throw std::runtime_error( "LaplaceSimple: src/dst mismatch" );
171 }
172
173 if ( src_.extent( 1 ) != grid_.extent( 1 ) || src_.extent( 2 ) != grid_.extent( 2 ) )
174 {
175 throw std::runtime_error( "LaplaceSimple: src/dst mismatch" );
176 }
177
178 Kokkos::parallel_for( "matvec", grid::shell::local_domain_md_range_policy_cells( domain_ ), *this );
179
180 if ( operator_communication_mode_ == linalg::OperatorCommunicationMode::CommunicateAdditively )
181 {
183 domain_, dst_, send_buffers_, recv_buffers_ );
185 }
186 }
187
188 KOKKOS_INLINE_FUNCTION void
189 operator()( const int local_subdomain_id, const int x_cell, const int y_cell, const int r_cell ) const
190 {
192 if ( !applyStoredLMatrices_ )
193 {
194 // Gather surface points for each wedge.
196 wedge_surface_physical_coords( wedge_phy_surf, grid_, local_subdomain_id, x_cell, y_cell );
197
198 // Gather wedge radii.
199 const ScalarT r_1 = radii_( local_subdomain_id, r_cell );
200 const ScalarT r_2 = radii_( local_subdomain_id, r_cell + 1 );
201
202 // Quadrature points.
203 int num_quad_points = single_quadpoint_ ? quadrature::quad_felippa_1x1_num_quad_points :
205
207 extract_local_wedge_scalar_coefficients( k, local_subdomain_id, x_cell, y_cell, r_cell, k_ );
208
209 // Compute the local element matrix.
210
211 for ( int q = 0; q < num_quad_points; q++ )
212 {
213 const auto w = single_quadpoint_ ? quad_weights_1x1_[q] : quad_weights_3x2_[q];
214 const auto qp = single_quadpoint_ ? quad_points_1x1_[q] : quad_points_3x2_[q];
215
216 for ( int wedge = 0; wedge < num_wedges_per_hex_cell; wedge++ )
217 {
218 const auto J = jac( wedge_phy_surf[wedge], r_1, r_2, qp );
219 const auto det = Kokkos::abs( J.det() );
220 const auto J_inv_transposed = J.inv().transposed();
221 ScalarType k_eval = 0.0;
222 for ( int j = 0; j < num_nodes_per_wedge; j++ )
223 {
224 k_eval += shape( j, qp ) * k[wedge]( j );
225 }
226
227 for ( int i = 0; i < num_nodes_per_wedge; i++ )
228 {
229 const auto grad_i = grad_shape( i, qp );
230
231 for ( int j = 0; j < num_nodes_per_wedge; j++ )
232 {
233 const auto grad_j = grad_shape( j, qp );
234
235 A[wedge]( i, j ) +=
236 w * k_eval * ( ( J_inv_transposed * grad_i ).dot( J_inv_transposed * grad_j ) * det );
237 }
238 }
239 }
240 }
241
242 if ( treat_boundary_ )
243 {
244 for ( int wedge = 0; wedge < num_wedges_per_hex_cell; wedge++ )
245 {
246 dense::Mat< ScalarT, 6, 6 > boundary_mask;
247 boundary_mask.fill( 1.0 );
248 if ( r_cell == 0 )
249 {
250 // Inner boundary (CMB).
251 for ( int i = 0; i < 6; i++ )
252 {
253 for ( int j = 0; j < 6; j++ )
254 {
255 if ( i != j && ( i < 3 || j < 3 ) )
256 {
257 boundary_mask( i, j ) = 0.0;
258 }
259 }
260 }
261 }
262
263 if ( r_cell + 1 == radii_.extent( 1 ) - 1 )
264 {
265 // Outer boundary (surface).
266 for ( int i = 0; i < 6; i++ )
267 {
268 for ( int j = 0; j < 6; j++ )
269 {
270 if ( i != j && ( i >= 3 || j >= 3 ) )
271 {
272 boundary_mask( i, j ) = 0.0;
273 }
274 }
275 }
276 }
277
278 A[wedge].hadamard_product( boundary_mask );
279 }
280 }
281 }
282 else
283 {
284 // load LMatrix for both local wedges
285 A[0] = lmatrices_( local_subdomain_id, x_cell, y_cell, r_cell, 0 );
286 A[1] = lmatrices_( local_subdomain_id, x_cell, y_cell, r_cell, 1 );
287 }
288
289 if ( diagonal_ )
290 {
291 A[0] = A[0].diagonal();
292 A[1] = A[1].diagonal();
293 }
294
295 if ( storeLMatrices_ )
296 {
297 // write local matrices to mem
298 lmatrices_( local_subdomain_id, x_cell, y_cell, r_cell, 0 ) = A[0];
299 lmatrices_( local_subdomain_id, x_cell, y_cell, r_cell, 1 ) = A[1];
300 }
301 else
302 {
303 // apply local matrices to local DoFs
305 extract_local_wedge_scalar_coefficients( src, local_subdomain_id, x_cell, y_cell, r_cell, src_ );
306
308
309 dst[0] = A[0] * src[0];
310 dst[1] = A[1] * src[1];
311
312 atomically_add_local_wedge_scalar_coefficients( dst_, local_subdomain_id, x_cell, y_cell, r_cell, dst );
313 }
314 }
315};
316
319
320} // namespace terra::fe::wedge::operators::shell
Definition div_k_grad_simple.hpp:19
void operator()(const int local_subdomain_id, const int x_cell, const int y_cell, const int r_cell) const
Definition div_k_grad_simple.hpp:189
grid::Grid3DDataVec< ScalarT, 3 > get_grid() const
Getter for grid member.
Definition div_k_grad_simple.hpp:95
void setApplyStoredLMatrices(bool v)
Setter/Getter for app applyStoredLMatrices_: usage of stored local matrices during apply.
Definition div_k_grad_simple.hpp:129
const grid::shell::DistributedDomain & get_domain() const
Getter for domain member.
Definition div_k_grad_simple.hpp:89
void store_lmatrices()
allocates memory for the local matrices calls kernel with storeLMatrices_ = true to assemble and stor...
Definition div_k_grad_simple.hpp:135
void set_single_quadpoint(bool v)
S/Getter for quadpoint member.
Definition div_k_grad_simple.hpp:101
grid::Grid2DDataScalar< ScalarT > get_radii() const
Getter for radii member.
Definition div_k_grad_simple.hpp:92
dense::Mat< ScalarT, 6, 6 > get_local_matrix(const int local_subdomain_id, const int x_cell, const int y_cell, const int r_cell, const int wedge)
Retrives the local matrix stored in the operator.
Definition div_k_grad_simple.hpp:105
DivKGradSimple(const grid::shell::DistributedDomain &domain, const grid::Grid3DDataVec< ScalarT, 3 > &grid, const grid::Grid2DDataScalar< ScalarT > &radii, const grid::Grid4DDataScalar< ScalarType > &k, bool treat_boundary, bool diagonal, linalg::OperatorApplyMode operator_apply_mode=linalg::OperatorApplyMode::Replace, linalg::OperatorCommunicationMode operator_communication_mode=linalg::OperatorCommunicationMode::CommunicateAdditively)
Definition div_k_grad_simple.hpp:60
ScalarT ScalarType
Definition div_k_grad_simple.hpp:23
void set_diagonal(bool v)
S/Getter for diagonal member.
Definition div_k_grad_simple.hpp:98
terra::grid::Grid4DDataMatrices< ScalarType, 6, 6, 2 > Grid4DDataLocalMatrices
Definition div_k_grad_simple.hpp:24
void set_local_matrix(const int local_subdomain_id, const int x_cell, const int y_cell, const int r_cell, const int wedge, const dense::Mat< ScalarT, LocalMatrixDim, LocalMatrixDim > &mat) const
Set the local matrix stored in the operator.
Definition div_k_grad_simple.hpp:119
void apply_impl(const SrcVectorType &src, DstVectorType &dst)
Definition div_k_grad_simple.hpp:154
static constexpr int LocalMatrixDim
Definition div_k_grad_simple.hpp:25
Parallel data structure organizing the thick spherical shell metadata for distributed (MPI parallel) ...
Definition spherical_shell.hpp:2498
const std::map< SubdomainInfo, std::tuple< LocalSubdomainIdx, SubdomainNeighborhood > > & subdomains() const
Definition spherical_shell.hpp:2580
const DomainInfo & domain_info() const
Returns a const reference.
Definition spherical_shell.hpp:2577
int subdomain_num_nodes_radially() const
Equivalent to calling subdomain_num_nodes_radially( subdomain_refinement_level() )
Definition spherical_shell.hpp:861
int subdomain_num_nodes_per_side_laterally() const
Equivalent to calling subdomain_num_nodes_per_side_laterally( subdomain_refinement_level() )
Definition spherical_shell.hpp:852
Q1 scalar finite element vector on a distributed shell grid.
Definition vector_q1.hpp:21
const grid::Grid4DDataScalar< ScalarType > & grid_data() const
Get const reference to grid data.
Definition vector_q1.hpp:137
Concept for types that behave like linear operators.
Definition operator.hpp:57
void unpack_and_reduce_local_subdomain_boundaries(const grid::shell::DistributedDomain &domain, const GridDataType &data, SubdomainNeighborhoodSendRecvBuffer< typename GridDataType::value_type, grid::grid_data_vec_dim< GridDataType >() > &boundary_recv_buffers, CommunicationReduction reduction=CommunicationReduction::SUM)
Unpacks and reduces local subdomain boundaries.
Definition communication.hpp:672
void pack_send_and_recv_local_subdomain_boundaries(const grid::shell::DistributedDomain &domain, const GridDataType &data, SubdomainNeighborhoodSendRecvBuffer< typename GridDataType::value_type, grid::grid_data_vec_dim< GridDataType >() > &boundary_send_buffers, SubdomainNeighborhoodSendRecvBuffer< typename GridDataType::value_type, grid::grid_data_vec_dim< GridDataType >() > &boundary_recv_buffers)
Packs, sends and recvs local subdomain boundaries using two sets of buffers.
Definition communication.hpp:242
Definition boundary_mass.hpp:14
constexpr void quad_felippa_3x2_quad_weights(T(&quad_weights)[quad_felippa_3x2_num_quad_points])
Definition wedge/quadrature/quadrature.hpp:93
constexpr int quad_felippa_3x2_num_quad_points
Definition wedge/quadrature/quadrature.hpp:66
constexpr void quad_felippa_3x2_quad_points(dense::Vec< T, 3 >(&quad_points)[quad_felippa_3x2_num_quad_points])
Definition wedge/quadrature/quadrature.hpp:70
constexpr void quad_felippa_1x1_quad_points(dense::Vec< T, 3 >(&quad_points)[quad_felippa_1x1_num_quad_points])
Definition wedge/quadrature/quadrature.hpp:36
constexpr void quad_felippa_1x1_quad_weights(T(&quad_weights)[quad_felippa_1x1_num_quad_points])
Definition wedge/quadrature/quadrature.hpp:43
constexpr int quad_felippa_1x1_num_quad_points
Definition wedge/quadrature/quadrature.hpp:32
constexpr int num_nodes_per_wedge_surface
Definition kernel_helpers.hpp:6
void atomically_add_local_wedge_scalar_coefficients(const grid::Grid4DDataScalar< T > &global_coefficients, const int local_subdomain_id, const int x_cell, const int y_cell, const int r_cell, const dense::Vec< T, 6 >(&local_coefficients)[2])
Performs an atomic add of the two local wedge coefficient vectors of a hex cell into the global coeff...
Definition kernel_helpers.hpp:407
void wedge_surface_physical_coords(dense::Vec< T, 3 >(&wedge_surf_phy_coords)[num_wedges_per_hex_cell][num_nodes_per_wedge_surface], const grid::Grid3DDataVec< T, 3 > &lateral_grid, const int local_subdomain_id, const int x_cell, const int y_cell)
Extracts the (unit sphere) surface vertex coords of the two wedges of a hex cell.
Definition kernel_helpers.hpp:26
constexpr int num_wedges_per_hex_cell
Definition kernel_helpers.hpp:5
void extract_local_wedge_scalar_coefficients(dense::Vec< T, 6 >(&local_coefficients)[2], const int local_subdomain_id, const int x_cell, const int y_cell, const int r_cell, const grid::Grid4DDataScalar< T > &global_coefficients)
Extracts the local vector coefficients for the two wedges of a hex cell from the global coefficient v...
Definition kernel_helpers.hpp:306
constexpr int num_nodes_per_wedge
Definition kernel_helpers.hpp:7
constexpr dense::Vec< T, 3 > grad_shape(const int node_idx, const T xi, const T eta, const T zeta)
Gradient of the full shape function:
Definition integrands.hpp:228
constexpr T shape(const int node_idx, const T xi, const T eta, const T zeta)
(Tensor-product) Shape function.
Definition integrands.hpp:146
constexpr dense::Mat< T, 3, 3 > jac(const dense::Vec< T, 3 > &p1_phy, const dense::Vec< T, 3 > &p2_phy, const dense::Vec< T, 3 > &p3_phy, const T r_1, const T r_2, const T xi, const T eta, const T zeta)
Definition integrands.hpp:643
Kokkos::MDRangePolicy< Kokkos::Rank< 4 > > local_domain_md_range_policy_cells(const DistributedDomain &distributed_domain)
Definition spherical_shell.hpp:2668
Kokkos::View< dense::Mat< ScalarType, Rows, Cols > ****[NumMatrices], Layout > Grid4DDataMatrices
Definition grid_types.hpp:46
Kokkos::View< ScalarType ***[VecDim], Layout > Grid3DDataVec
Definition grid_types.hpp:40
Kokkos::View< ScalarType ****, Layout > Grid4DDataScalar
Definition grid_types.hpp:25
Kokkos::View< ScalarType **, Layout > Grid2DDataScalar
Definition grid_types.hpp:19
OperatorApplyMode
Modes for applying an operator to a vector.
Definition operator.hpp:30
@ Replace
Overwrite the destination vector.
OperatorCommunicationMode
Modes for communication during operator application.
Definition operator.hpp:40
@ CommunicateAdditively
Communicate and add results.
Definition mat.hpp:10
void fill(const T value)
Definition mat.hpp:201
constexpr Mat diagonal() const
Definition mat.hpp:377
Mat & hadamard_product(const Mat &mat)
Definition mat.hpp:213