3#include "../../quadrature/quadrature.hpp"
17template <
typename ScalarT,
int VecDim = 3 >
75 , treat_boundary_( treat_boundary )
76 , diagonal_( diagonal )
77 , operator_apply_mode_( operator_apply_mode )
78 , operator_communication_mode_( operator_communication_mode )
79 , operator_stored_matrix_mode_( operator_stored_matrix_mode )
81 , send_buffers_( domain )
82 , recv_buffers_( domain )
92 operator_apply_mode_ = operator_apply_mode;
93 operator_communication_mode_ = operator_communication_mode;
112 KOKKOS_INLINE_FUNCTION
114 const int local_subdomain_id,
119 {
return util::has_flag( mask_( local_subdomain_id, x_cell, y_cell, r_cell ), flag ); }
127 operator_stored_matrix_mode_ = operator_stored_matrix_mode;
133 domain_, operator_stored_matrix_mode_, level_range, GCAElements );
140 KOKKOS_INLINE_FUNCTION
142 const int local_subdomain_id,
150 local_matrix_storage_.
set_matrix( local_subdomain_id, x_cell, y_cell, r_cell, wedge, mat );
156 KOKKOS_INLINE_FUNCTION
158 const int local_subdomain_id,
162 const int wedge )
const
167 if ( !local_matrix_storage_.
has_matrix( local_subdomain_id, x_cell, y_cell, r_cell, wedge ) )
169 Kokkos::abort(
"No matrix found at that spatial index." );
171 return local_matrix_storage_.
get_matrix( local_subdomain_id, x_cell, y_cell, r_cell, wedge );
194 throw std::runtime_error(
"EpsilonDivDiv: src/dst mismatch" );
197 if ( src_.
extent( 1 ) != grid_.extent( 1 ) || src_.
extent( 2 ) != grid_.extent( 2 ) )
199 throw std::runtime_error(
"EpsilonDivDiv: src/dst mismatch" );
202 util::Timer timer_kernel(
"epsilon_divdiv_kernel" );
212 domain_, dst_, send_buffers_, recv_buffers_ );
217 KOKKOS_INLINE_FUNCTION
void
218 operator()(
const int local_subdomain_id,
const int x_cell,
const int y_cell,
const int r_cell )
const
231 A[0] = local_matrix_storage_.
get_matrix( local_subdomain_id, x_cell, y_cell, r_cell, 0 );
232 A[1] = local_matrix_storage_.
get_matrix( local_subdomain_id, x_cell, y_cell, r_cell, 1 );
236 if ( local_matrix_storage_.
has_matrix( local_subdomain_id, x_cell, y_cell, r_cell, 0 ) &&
237 local_matrix_storage_.
has_matrix( local_subdomain_id, x_cell, y_cell, r_cell, 1 ) )
239 A[0] = local_matrix_storage_.
get_matrix( local_subdomain_id, x_cell, y_cell, r_cell, 0 );
240 A[1] = local_matrix_storage_.
get_matrix( local_subdomain_id, x_cell, y_cell, r_cell, 1 );
258 for (
int dimj = 0; dimj < 3; dimj++ )
262 src_d, local_subdomain_id, x_cell, y_cell, r_cell, dimj, src_ );
275 dst[0] = A[0] * src[0];
276 dst[1] = A[1] * src[1];
278 for (
int dimi = 0; dimi < 3; dimi++ )
285 dst_, local_subdomain_id, x_cell, y_cell, r_cell, dimi, dst_d );
295 const ScalarT r_1 = radii_( local_subdomain_id, r_cell );
296 const ScalarT r_2 = radii_( local_subdomain_id, r_cell + 1 );
301 constexpr int hex_offset_x[8] = { 0, 1, 0, 1, 0, 1, 0, 1 };
302 constexpr int hex_offset_y[8] = { 0, 0, 1, 1, 0, 0, 1, 1 };
303 constexpr int hex_offset_r[8] = { 0, 0, 0, 0, 1, 1, 1, 1 };
307 for (
int dimi = 0; dimi < 3; ++dimi )
309 for (
int dimj = 0; dimj < 3; ++dimj )
311 if ( diagonal_ and dimi != dimj )
317 for (
int i = 0; i < 8; i++ )
319 src_local_hex[i] = src_(
321 x_cell + hex_offset_x[i],
322 y_cell + hex_offset_y[i],
323 r_cell + hex_offset_r[i],
328 for (
int q = 0; q < num_quad_points; q++ )
348 jdet_keval_quadweight );
354 jdet_keval_quadweight,
363 for (
int i = 0; i < 8; i++ )
368 x_cell + hex_offset_x[i],
369 y_cell + hex_offset_y[i],
370 r_cell + hex_offset_r[i],
409 const auto det = J.det();
410 const auto abs_det = Kokkos::abs( det );
417 k_eval +=
shape( k, quad_point ) * k_local_hex[wedge]( k );
422 sym_grad_i[k] =
symmetric_grad( J_inv_transposed, quad_point, k, dimi );
423 sym_grad_j[k] =
symmetric_grad( J_inv_transposed, quad_point, k, dimj );
425 jdet_keval_quadweight = quad_weight * k_eval * abs_det;
430 KOKKOS_INLINE_FUNCTION
432 const int local_subdomain_id,
436 const int wedge )
const
444 const ScalarT r_1 = radii_( local_subdomain_id, r_cell );
445 const ScalarT r_2 = radii_( local_subdomain_id, r_cell + 1 );
452 for (
int dimi = 0; dimi < 3; ++dimi )
454 for (
int dimj = 0; dimj < 3; ++dimj )
457 for (
int q = 0; q < num_quad_points; q++ )
474 jdet_keval_quadweight );
482 jdet_keval_quadweight *
484 2.0 / 3.0 * sym_grad_j[j]( dimj, dimj ) * sym_grad_i[i]( dimi, dimi ) );
492 if ( treat_boundary_ )
495 boundary_mask.
fill( 1.0 );
497 for (
int dimi = 0; dimi < 3; ++dimi )
499 for (
int dimj = 0; dimj < 3; ++dimj )
504 for (
int i = 0; i < 6; i++ )
506 for (
int j = 0; j < 6; j++ )
509 if ( ( dimi == dimj && i != j && ( i < 3 || j < 3 ) ) or
510 ( dimi != dimj && ( i < 3 || j < 3 ) ) )
519 if ( r_cell + 1 == radii_.extent( 1 ) - 1 )
522 for (
int i = 0; i < 6; i++ )
524 for (
int j = 0; j < 6; j++ )
527 if ( ( dimi == dimj && i != j && ( i >= 3 || j >= 3 ) ) or
528 ( dimi != dimj && ( i >= 3 || j >= 3 ) ) )
556 constexpr int offset_x[2][6] = { { 0, 1, 0, 0, 1, 0 }, { 1, 0, 1, 1, 0, 1 } };
557 constexpr int offset_y[2][6] = { { 0, 0, 1, 0, 0, 1 }, { 1, 1, 0, 1, 1, 0 } };
558 constexpr int offset_r[2][6] = { { 0, 0, 0, 1, 1, 1 }, { 0, 0, 0, 1, 1, 1 } };
564 const bool at_cmb = r_cell == 0;
565 const bool at_surface = r_cell + 1 == radii_.extent( 1 ) - 1;
567 int surface_shift = 0;
572 if ( treat_boundary_ && at_cmb )
577 else if ( treat_boundary_ && at_surface )
589 sym_grad_i[i] * src_local_hex[4 * offset_r[wedge][i] + 2 * offset_y[wedge][i] + offset_x[wedge][i]];
590 divu += sym_grad_i[i]( dimi, dimi ) *
591 src_local_hex[4 * offset_r[wedge][i] + 2 * offset_y[wedge][i] + offset_x[wedge][i]];
600 dst_local_hex[4 * offset_r[wedge][j] + 2 * offset_y[wedge][j] + offset_x[wedge][j]] +=
601 jdet_keval_quadweight * ( 2 * ( sym_grad_j[j] ).double_contract( grad_u ) -
602 2.0 / 3.0 * sym_grad_j[j]( dimj, dimj ) * divu );
608 if ( diagonal_ || ( dimi == dimj && ( treat_boundary_ && ( at_cmb || at_surface ) ) ) )
613 const auto grad_u_diag =
614 sym_grad_i[i] * src_local_hex[4 * offset_r[wedge][i] + 2 * offset_y[wedge][i] + offset_x[wedge][i]];
615 const auto div_u_diag =
616 sym_grad_i[i]( dimi, dimi ) *
617 src_local_hex[4 * offset_r[wedge][i] + 2 * offset_y[wedge][i] + offset_x[wedge][i]];
619 dst_local_hex[4 * offset_r[wedge][i] + 2 * offset_y[wedge][i] + offset_x[wedge][i]] +=
620 jdet_keval_quadweight * ( 2 * ( sym_grad_j[i] ).double_contract( grad_u_diag ) -
621 2.0 / 3.0 * sym_grad_j[i]( dimj, dimj ) * div_u_diag );
Send and receive buffers for all process-local subdomain boundaries.
Definition communication.hpp:56
Definition epsilon_divdiv.hpp:19
void operator()(const int local_subdomain_id, const int x_cell, const int y_cell, const int r_cell) const
Definition epsilon_divdiv.hpp:218
void set_stored_matrix_mode(linalg::OperatorStoredMatrixMode operator_stored_matrix_mode, int level_range, grid::Grid4DDataScalar< ScalarType > GCAElements)
allocates memory for the local matrices
Definition epsilon_divdiv.hpp:122
linalg::OperatorStoredMatrixMode get_stored_matrix_mode()
Definition epsilon_divdiv.hpp:137
bool has_flag(const int local_subdomain_id, const int x_cell, const int y_cell, const int r_cell, grid::shell::ShellBoundaryFlag flag) const
Getter for mask member.
Definition epsilon_divdiv.hpp:113
static constexpr int LocalMatrixDim
Definition epsilon_divdiv.hpp:24
void assemble_trial_test_vecs(const int wedge, const dense::Vec< ScalarType, VecDim > &quad_point, const ScalarType quad_weight, const ScalarT r_1, const ScalarT r_2, dense::Vec< ScalarT, 3 >(*wedge_phy_surf)[3], const dense::Vec< ScalarT, 6 > *k_local_hex, const int dimi, const int dimj, dense::Mat< ScalarType, VecDim, VecDim > *sym_grad_i, dense::Mat< ScalarType, VecDim, VecDim > *sym_grad_j, ScalarType &jdet_keval_quadweight) const
: For both trial and test space this function sets up a vector: each vector element holds the symmetr...
Definition epsilon_divdiv.hpp:394
ScalarT ScalarType
Definition epsilon_divdiv.hpp:23
grid::Grid2DDataScalar< ScalarT > get_radii() const
Getter for radii member.
Definition epsilon_divdiv.hpp:106
EpsilonDivDiv(const grid::shell::DistributedDomain &domain, const grid::Grid3DDataVec< ScalarT, 3 > &grid, const grid::Grid2DDataScalar< ScalarT > &radii, const grid::Grid4DDataScalar< grid::shell::ShellBoundaryFlag > &mask, const grid::Grid4DDataScalar< ScalarT > &k, bool treat_boundary, bool diagonal, linalg::OperatorApplyMode operator_apply_mode=linalg::OperatorApplyMode::Replace, linalg::OperatorCommunicationMode operator_communication_mode=linalg::OperatorCommunicationMode::CommunicateAdditively, linalg::OperatorStoredMatrixMode operator_stored_matrix_mode=linalg::OperatorStoredMatrixMode::Off)
Definition epsilon_divdiv.hpp:58
void fused_local_mv(ScalarType src_local_hex[8], ScalarType dst_local_hex[8], const int wedge, const ScalarType jdet_keval_quadweight, dense::Mat< ScalarType, 3, 3 > *sym_grad_i, dense::Mat< ScalarType, 3, 3 > *sym_grad_j, const int dimi, const int dimj, int r_cell) const
Definition epsilon_divdiv.hpp:545
void set_operator_apply_and_communication_modes(const linalg::OperatorApplyMode operator_apply_mode, const linalg::OperatorCommunicationMode operator_communication_mode)
Definition epsilon_divdiv.hpp:88
const grid::shell::DistributedDomain & get_domain() const
Getter for domain member.
Definition epsilon_divdiv.hpp:103
grid::Grid3DDataVec< ScalarT, 3 > get_grid()
Getter for grid member.
Definition epsilon_divdiv.hpp:109
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 epsilon_divdiv.hpp:141
dense::Mat< ScalarT, LocalMatrixDim, LocalMatrixDim > assemble_local_matrix(const int local_subdomain_id, const int x_cell, const int y_cell, const int r_cell, const int wedge) const
assemble the local matrix and return it for a given element, wedge, and vectorial component (determin...
Definition epsilon_divdiv.hpp:431
void apply_impl(const SrcVectorType &src, DstVectorType &dst)
Definition epsilon_divdiv.hpp:179
dense::Mat< ScalarT, LocalMatrixDim, LocalMatrixDim > get_local_matrix(const int local_subdomain_id, const int x_cell, const int y_cell, const int r_cell, const int wedge) const
Retrives the local matrix if there is stored local matrices, the desired local matrix is loaded and r...
Definition epsilon_divdiv.hpp:157
terra::grid::Grid4DDataMatrices< ScalarType, LocalMatrixDim, LocalMatrixDim, 2 > Grid4DDataLocalMatrices
Definition epsilon_divdiv.hpp:25
void set_diagonal(bool v)
S/Getter for diagonal member.
Definition epsilon_divdiv.hpp:97
const grid::Grid4DDataScalar< ScalarType > & k_grid_data()
Getter for coefficient.
Definition epsilon_divdiv.hpp:100
Parallel data structure organizing the thick spherical shell metadata for distributed (MPI parallel) ...
Definition spherical_shell.hpp:2518
Static assertion: VectorQ1Scalar satisfies VectorLike concept.
Definition vector_q1.hpp:168
const grid::Grid4DDataVec< ScalarType, VecDim > & grid_data() const
Get const reference to grid data.
Definition vector_q1.hpp:288
bool has_matrix(const int local_subdomain_id, const int x_cell, const int y_cell, const int r_cell, const int wedge) const
Checks for presence of a local matrix for a certain element.
Definition local_matrix_storage.hpp:223
dense::Mat< ScalarT, LocalMatrixDim, LocalMatrixDim > get_matrix(const int local_subdomain_id, const int x_cell, const int y_cell, const int r_cell, const int wedge) const
Retrives the local matrix if there is stored local matrices, the desired local matrix is loaded and r...
Definition local_matrix_storage.hpp:175
void set_matrix(const int local_subdomain_id, const int x_cell, const int y_cell, const int r_cell, const int wedge, dense::Mat< ScalarT, LocalMatrixDim, LocalMatrixDim > mat) const
Set the local matrix stored in the operator.
Definition local_matrix_storage.hpp:118
Timer supporting RAII scope or manual stop.
Definition timer.hpp:342
void stop()
Stop the timer and record elapsed time.
Definition timer.hpp:364
Concept for types that can be used as Galerkin coarse-grid operators in a multigrid hierarchy....
Definition operator.hpp:81
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 int num_nodes_per_wedge_surface
Definition kernel_helpers.hpp:6
constexpr dense::Mat< T, 3, 3 > symmetric_grad(const dense::Mat< T, 3, 3 > &J_inv_transposed, const dense::Vec< T, 3 > &quad_point, const int dof, const int dim)
Returns the symmetric gradient of the shape function of a dof at a quadrature point.
Definition integrands.hpp:685
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
void atomically_add_local_wedge_vector_coefficients(const grid::Grid4DDataVec< T, VecDim > &global_coefficients, const int local_subdomain_id, const int x_cell, const int y_cell, const int r_cell, const int d, 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:465
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
void extract_local_wedge_vector_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 int d, const grid::Grid4DDataVec< T, VecDim > &global_coefficients)
Extracts the local vector coefficients for the two wedges of a hex cell from the global coefficient v...
Definition kernel_helpers.hpp:356
constexpr int num_nodes_per_wedge
Definition kernel_helpers.hpp:7
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:657
ShellBoundaryFlag
FlagLike that indicates boundary types for the thick spherical shell.
Definition shell/bit_masks.hpp:12
Kokkos::MDRangePolicy< Kokkos::Rank< 4 > > local_domain_md_range_policy_cells(const DistributedDomain &distributed_domain)
Definition spherical_shell.hpp:2739
Kokkos::View< dense::Mat< ScalarType, Rows, Cols > ****[NumMatrices], Layout > Grid4DDataMatrices
Definition grid_types.hpp:173
Kokkos::View< ScalarType ***[VecDim], Layout > Grid3DDataVec
Definition grid_types.hpp:42
Kokkos::View< ScalarType ****, Layout > Grid4DDataScalar
Definition grid_types.hpp:27
Kokkos::View< ScalarType **, Layout > Grid2DDataScalar
Definition grid_types.hpp:21
OperatorApplyMode
Modes for applying an operator to a vector.
Definition operator.hpp:30
@ Replace
Overwrite the destination vector.
OperatorStoredMatrixMode
Modes for applying stored matrices.
Definition operator.hpp:47
@ Selective
Use stored matrices on selected, marked elements only, assemble on all others.
@ Full
Use stored matrices on all elements.
@ Off
Do not use stored matrices.
OperatorCommunicationMode
Modes for communication during operator application.
Definition operator.hpp:40
@ CommunicateAdditively
Communicate and add results.
constexpr bool has_flag(E mask_value, E flag) noexcept
Checks if a bitmask value contains a specific flag.
Definition bit_masking.hpp:43
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
T double_contract(const Mat &mat)
Definition mat.hpp:226
SoA (Structure-of-Arrays) 4D vector grid data.
Definition grid_types.hpp:51
auto extent(int i) const
Definition grid_types.hpp:75