4#include "../../quadrature/quadrature.hpp"
29template <
typename ScalarT >
45 BoundaryConditions bcs_;
63 BoundaryConditions bcs,
67 : domain_fine_( domain_fine )
68 , domain_coarse_( domain_coarse )
69 , grid_fine_( grid_fine )
70 , radii_( radii_fine )
71 , boundary_mask_fine_( boundary_mask_fine )
72 , operator_apply_mode_( operator_apply_mode )
73 , operator_communication_mode_( operator_communication_mode )
75 , send_buffers_( domain_coarse )
76 , recv_buffers_( domain_coarse )
86 operator_apply_mode_ = operator_apply_mode;
87 operator_communication_mode_ = operator_communication_mode;
112 domain_coarse_, dst_, send_buffers_, recv_buffers_ );
117 KOKKOS_INLINE_FUNCTION
void
118 operator()(
const int local_subdomain_id,
const int x_cell,
const int y_cell,
const int r_cell )
const
125 const ScalarT r_1 = radii_( local_subdomain_id, r_cell );
126 const ScalarT r_2 = radii_( local_subdomain_id, r_cell + 1 );
132 ScalarT quad_weights[num_quad_points];
137 const int fine_radial_wedge_index = r_cell % 2;
142 for (
int q = 0; q < num_quad_points; q++ )
148 const auto J =
jac( wedge_phy_surf[wedge], r_1, r_2, quad_points[q] );
149 const auto det = Kokkos::abs( J.det() );
150 const auto J_inv_transposed = J.inv().transposed();
155 shape_coarse( i, fine_radial_wedge_index, fine_lateral_wedge_index, quad_points[q] );
159 const auto grad_j =
grad_shape( j, quad_points[q] );
161 for (
int d = 0; d < 3; d++ )
163 A[wedge]( i, d * 6 + j ) +=
164 quad_weights[q] * ( -( J_inv_transposed * grad_j )(d) *shape_i * det );
171 bool at_cmb =
util::has_flag( boundary_mask_fine_( local_subdomain_id, x_cell, y_cell, r_cell ), CMB );
173 util::has_flag( boundary_mask_fine_( local_subdomain_id, x_cell, y_cell, r_cell + 1 ), SURFACE );
176 for (
int d = 0; d < 3; d++ )
185 src[wedge]( d * 6 + i ) = src_d[wedge]( i );
192 boundary_mask.
fill( 1.0 );
196 if ( at_cmb || at_surface )
199 ShellBoundaryFlag sbf = at_cmb ? CMB : SURFACE;
200 BoundaryConditionFlag bcf = get_boundary_condition_flag( bcs_, sbf );
202 if ( bcf == DIRICHLET )
204 for (
int dimj = 0; dimj < 3; ++dimj )
210 if ( at_cmb && ( j < 3 ) || at_surface && ( j >= 3 ) )
218 else if ( bcf == FREESLIP )
224 for (
int wedge = 0; wedge < 2; ++wedge )
228 for (
int dimj = 0; dimj < 3; ++dimj )
232 A_tmp[wedge]( node_idxi, node_idxj * 3 + dimj ) =
244 constexpr int layer_hex_offset_x[2][3] = { { 0, 1, 0 }, { 1, 0, 1 } };
245 constexpr int layer_hex_offset_y[2][3] = { { 0, 0, 1 }, { 1, 1, 0 } };
247 for (
int wedge = 0; wedge < 2; ++wedge )
250 for (
int i = 0; i < 18; ++i )
252 R[wedge]( i, i ) = 1.0;
255 for (
int boundary_node_idx = 0; boundary_node_idx < 3; boundary_node_idx++ )
260 x_cell + layer_hex_offset_x[wedge][boundary_node_idx],
261 y_cell + layer_hex_offset_y[wedge][boundary_node_idx],
262 r_cell + ( at_cmb ? 0 : 1 ),
268 auto R_i = trafo_mat_cartesian_to_normal_tangential( normal );
271 int offset_in_R = at_cmb ? 0 : 9;
272 for (
int dimi = 0; dimi < 3; ++dimi )
274 for (
int dimj = 0; dimj < 3; ++dimj )
277 offset_in_R + boundary_node_idx * 3 + dimi,
278 offset_in_R + boundary_node_idx * 3 + dimj ) = R_i( dimi, dimj );
285 A[wedge] = A_tmp[wedge] * R[wedge].
transposed();
287 auto src_tmp = R[wedge] * src[wedge];
288 for (
int i = 0; i < 18; ++i )
290 src[wedge]( i ) = src_tmp( i );
294 int node_start = at_surface ? 3 : 0;
295 int node_end = at_surface ? 6 : 3;
296 for (
int node_idx = node_start; node_idx < node_end; node_idx++ )
298 int idx = node_idx * 3;
299 for (
int k = 0; k < 6; ++k )
301 boundary_mask( k, idx ) = 0.0;
306 else if ( bcf == NEUMANN ) {}
317 dst[0] = A[0] * src[0];
318 dst[1] = A[1] * src[1];
324 dst_, local_subdomain_id, x_cell / 2, y_cell / 2, r_cell / 2, dst );
Definition divergence.hpp:31
Divergence(const grid::shell::DistributedDomain &domain_fine, const grid::shell::DistributedDomain &domain_coarse, const grid::Grid3DDataVec< ScalarT, 3 > &grid_fine, const grid::Grid2DDataScalar< ScalarT > &radii_fine, const grid::Grid4DDataScalar< grid::shell::ShellBoundaryFlag > &boundary_mask_fine, BoundaryConditions bcs, linalg::OperatorApplyMode operator_apply_mode=linalg::OperatorApplyMode::Replace, linalg::OperatorCommunicationMode operator_communication_mode=linalg::OperatorCommunicationMode::CommunicateAdditively)
Definition divergence.hpp:57
void set_operator_apply_and_communication_modes(const linalg::OperatorApplyMode operator_apply_mode, const linalg::OperatorCommunicationMode operator_communication_mode)
Definition divergence.hpp:82
void apply_impl(const SrcVectorType &src, DstVectorType &dst)
Definition divergence.hpp:90
ScalarT ScalarType
Definition divergence.hpp:35
void operator()(const int local_subdomain_id, const int x_cell, const int y_cell, const int r_cell) const
Definition divergence.hpp:118
Parallel data structure organizing the thick spherical shell metadata for distributed (MPI parallel) ...
Definition spherical_shell.hpp:2498
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
const grid::Grid4DDataVec< ScalarType, VecDim > & grid_data() const
Get const reference to grid data.
Definition vector_q1.hpp:280
Timer supporting RAII scope or manual stop.
Definition timer.hpp:270
void stop()
Stop the timer and record elapsed time.
Definition timer.hpp:289
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_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
constexpr int fine_lateral_wedge_idx(const int x_cell_fine, const int y_cell_fine, const int wedge_idx_fine)
Returns the lateral wedge index with respect to a coarse grid wedge from the fine wedge indices.
Definition kernel_helpers.hpp:601
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 void reorder_local_dofs(const DoFOrdering doo_from, const DoFOrdering doo_to, dense::Vec< ScalarT, 18 > &dofs)
Definition kernel_helpers.hpp:619
constexpr T shape_coarse(const int coarse_node_idx, const int fine_radial_wedge_idx, const int fine_lateral_wedge_idx, const T xi_fine, const T eta_fine, const T zeta_fine)
Definition integrands.hpp:373
constexpr int num_wedges_per_hex_cell
Definition kernel_helpers.hpp:5
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 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 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
dense::Vec< typename CoordsShellType::value_type, 3 > coords(const int subdomain, const int x, const int y, const int r, const CoordsShellType &coords_shell, const CoordsRadiiType &coords_radii)
Definition spherical_shell.hpp:2789
BoundaryConditionMapping[2] BoundaryConditions
Definition shell/bit_masks.hpp:37
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:2668
BoundaryConditionFlag get_boundary_condition_flag(const BoundaryConditions bcs, ShellBoundaryFlag sbf)
Retrieve the boundary condition flag that is associated with a location in the shell e....
Definition shell/bit_masks.hpp:42
BoundaryConditionFlag
FlagLike that indicates the type of boundary condition
Definition shell/bit_masks.hpp:25
Kokkos::View< ScalarType ***[VecDim], Layout > Grid3DDataVec
Definition grid_types.hpp:40
Kokkos::View< ScalarType ****[VecDim], Layout > Grid4DDataVec
Definition grid_types.hpp:43
Kokkos::View< ScalarType ****, Layout > Grid4DDataScalar
Definition grid_types.hpp:25
Kokkos::View< ScalarType **, Layout > Grid2DDataScalar
Definition grid_types.hpp:19
dense::Mat< ScalarType, 3, 3 > trafo_mat_cartesian_to_normal_tangential(const dense::Vec< ScalarType, 3 > &n_input)
Constructs a robust orthonormal transformation matrix from Cartesian to (normal–tangential–tangential...
Definition local_basis_trafo_normal_tangential.hpp:36
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.
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< T, Cols, Rows > transposed() const
Definition mat.hpp:187
Mat & hadamard_product(const Mat &mat)
Definition mat.hpp:213