Loading...
Searching...
No Matches
kmass.hpp
Go to the documentation of this file.
1
2#pragma once
3
5#include "dense/vec.hpp"
10#include "linalg/operator.hpp"
11#include "linalg/vector.hpp"
12#include "linalg/vector_q1.hpp"
13
15
16template < typename ScalarT >
17class KMass
18{
19 public:
22 using ScalarType = ScalarT;
23
24 private:
26
30
31 bool diagonal_;
32 bool lumped_diagonal_;
33
34 linalg::OperatorApplyMode operator_apply_mode_;
35 linalg::OperatorCommunicationMode operator_communication_mode_;
36
39
42
43 public:
49 const bool diagonal,
50 const bool lumped_diagonal = false,
52 linalg::OperatorCommunicationMode operator_communication_mode =
54 : domain_( domain )
55 , grid_( grid )
56 , radii_( radii )
57 , k_( k )
58 , diagonal_( diagonal )
59 , operator_apply_mode_( operator_apply_mode )
60 , operator_communication_mode_( operator_communication_mode )
61 // TODO: we can reuse the send and recv buffers and pass in from the outside somehow
62 , send_buffers_( domain )
63 , recv_buffers_( domain )
64 {}
65
66 /// @brief S/Getter for diagonal member
67 void set_diagonal( bool v ) { diagonal_ = v; }
68
69 /// @brief S/Getter for lumped diagonal member
70 void set_lumped_diagonal( bool v ) { lumped_diagonal_ = v; }
71
72 void apply_impl( const SrcVectorType& src, DstVectorType& dst )
73 {
74 if ( operator_apply_mode_ == linalg::OperatorApplyMode::Replace )
75 {
76 assign( dst, 0 );
77 }
78
79 src_ = src.grid_data();
80 dst_ = dst.grid_data();
81
82 Kokkos::parallel_for( "matvec", grid::shell::local_domain_md_range_policy_cells( domain_ ), *this );
83
84 Kokkos::fence();
85
86 if ( operator_communication_mode_ == linalg::OperatorCommunicationMode::CommunicateAdditively )
87 {
88 std::vector< std::unique_ptr< std::array< int, 11 > > > expected_recvs_metadata;
89 std::vector< std::unique_ptr< MPI_Request > > expected_recvs_requests;
90
92 domain_, dst_, send_buffers_, recv_buffers_ );
94 }
95 }
96
97 KOKKOS_INLINE_FUNCTION void
98 operator()( const int local_subdomain_id, const int x_cell, const int y_cell, const int r_cell ) const
99 {
100 // First all the r-independent stuff.
101 // Gather surface points for each wedge.
102
104 wedge_surface_physical_coords( wedge_phy_surf, grid_, local_subdomain_id, x_cell, y_cell );
105
106 // Compute lateral part of Jacobian.
107
108 constexpr auto num_quad_points = quadrature::quad_felippa_3x2_num_quad_points;
109
110 dense::Vec< ScalarT, 3 > quad_points[num_quad_points];
111 ScalarT quad_weights[num_quad_points];
112
115
116 ScalarT det_jac_lat[num_wedges_per_hex_cell][num_quad_points] = {};
117
118 jacobian_lat_determinant( det_jac_lat, wedge_phy_surf, quad_points );
119
120 // Only now we introduce radially dependent terms.
121 const ScalarT r_1 = radii_( local_subdomain_id, r_cell );
122 const ScalarT r_2 = radii_( local_subdomain_id, r_cell + 1 );
123
124 // For now, compute the local element matrix. We'll improve that later.
126
127 const ScalarT grad_r = grad_forward_map_rad( r_1, r_2 );
128
130 extract_local_wedge_scalar_coefficients( k, local_subdomain_id, x_cell, y_cell, r_cell, k_ );
131
132 for ( int wedge = 0; wedge < num_wedges_per_hex_cell; wedge++ )
133 {
134 for ( int q = 0; q < num_quad_points; q++ )
135 {
136 const ScalarT r = forward_map_rad( r_1, r_2, quad_points[q]( 2 ) );
137
138 ScalarType k_eval = 0.0;
139 for ( int j = 0; j < num_nodes_per_wedge; j++ )
140 {
141 k_eval += shape( j, quad_points[q] ) * k[wedge]( j );
142 }
143
144 for ( int i = 0; i < num_nodes_per_wedge; i++ )
145 {
146 for ( int j = 0; j < num_nodes_per_wedge; j++ )
147 {
148 const ScalarT shape_i = shape_lat( i, quad_points[q] ) * shape_rad( i, quad_points[q] );
149 const ScalarT shape_j = shape_lat( j, quad_points[q] ) * shape_rad( j, quad_points[q] );
150
151 A[wedge]( i, j ) +=
152 quad_weights[q] * k_eval * ( shape_i * shape_j * r * r * grad_r * det_jac_lat[wedge][q] );
153 }
154 }
155 }
156 }
157
158 if ( diagonal_ )
159 {
160 A[0] = A[0].diagonal();
161 A[1] = A[1].diagonal();
162 }
163 else if ( lumped_diagonal_ )
164 {
166 ones.fill( 1.0 );
169 }
170
172 extract_local_wedge_scalar_coefficients( src, local_subdomain_id, x_cell, y_cell, r_cell, src_ );
173
175
176 dst[0] = A[0] * src[0];
177 dst[1] = A[1] * src[1];
178
179 atomically_add_local_wedge_scalar_coefficients( dst_, local_subdomain_id, x_cell, y_cell, r_cell, dst );
180 }
181};
182
183static_assert( linalg::OperatorLike< KMass< float > > );
185
186} // namespace terra::fe::wedge::operators::shell
void set_lumped_diagonal(bool v)
S/Getter for lumped diagonal member.
Definition kmass.hpp:70
KMass(const grid::shell::DistributedDomain &domain, const grid::Grid3DDataVec< ScalarT, 3 > &grid, const grid::Grid2DDataScalar< ScalarT > &radii, const grid::Grid4DDataScalar< ScalarType > &k, const bool diagonal, const bool lumped_diagonal=false, linalg::OperatorApplyMode operator_apply_mode=linalg::OperatorApplyMode::Replace, linalg::OperatorCommunicationMode operator_communication_mode=linalg::OperatorCommunicationMode::CommunicateAdditively)
Definition kmass.hpp:44
void operator()(const int local_subdomain_id, const int x_cell, const int y_cell, const int r_cell) const
Definition kmass.hpp:98
void apply_impl(const SrcVectorType &src, DstVectorType &dst)
Definition kmass.hpp:72
void set_diagonal(bool v)
S/Getter for diagonal member.
Definition kmass.hpp:67
ScalarT ScalarType
Definition kmass.hpp:22
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
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 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 T grad_forward_map_rad(const T r_1, const T r_2)
Definition integrands.hpp:596
constexpr T shape_rad(const int node_idx, const T zeta)
Radial shape function.
Definition integrands.hpp:86
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 T shape_lat(const int node_idx, const T xi, const T eta)
Lateral shape function.
Definition integrands.hpp:118
constexpr T forward_map_rad(const T r_1, const T r_2, const T zeta)
Definition integrands.hpp:579
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 void jacobian_lat_determinant(T(&det_jac_lat)[num_wedges_per_hex_cell][NumQuadPoints], const dense::Vec< T, 3 > wedge_surf_phy_coords[num_wedges_per_hex_cell][num_nodes_per_wedge_surface], const dense::Vec< T, 3 > quad_points[NumQuadPoints])
Like jacobian_lat_inverse_transposed_and_determinant() but only computes the determinant (cheaper if ...
Definition kernel_helpers.hpp:158
constexpr T shape(const int node_idx, const T xi, const T eta, const T zeta)
(Tensor-product) Shape function.
Definition integrands.hpp:146
Kokkos::MDRangePolicy< Kokkos::Rank< 4 > > local_domain_md_range_policy_cells(const DistributedDomain &distributed_domain)
Definition spherical_shell.hpp:2668
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
constexpr Mat diagonal() const
Definition mat.hpp:377
static constexpr Mat diagonal_from_vec(const Vec< T, Rows > &diagonal)
Definition mat.hpp:79
void fill(const T value)
Definition vec.hpp:30