Loading...
Searching...
No Matches
vector_laplace_simple.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, int VecDim = 3 >
18{
19 public:
22 using ScalarType = ScalarT;
23
24 private:
26
29
30 bool treat_boundary_;
31 bool diagonal_;
32
33 linalg::OperatorApplyMode operator_apply_mode_;
34 linalg::OperatorCommunicationMode operator_communication_mode_;
35
38
41
42 public:
47 bool treat_boundary,
48 bool diagonal,
50 linalg::OperatorCommunicationMode operator_communication_mode =
52 : domain_( domain )
53 , grid_( grid )
54 , radii_( radii )
55 , treat_boundary_( treat_boundary )
56 , diagonal_( diagonal )
57 , operator_apply_mode_( operator_apply_mode )
58 , operator_communication_mode_( operator_communication_mode )
59 // TODO: we can reuse the send and recv buffers and pass in from the outside somehow
60 , send_buffers_( domain )
61 , recv_buffers_( domain )
62 {}
63
65 const linalg::OperatorApplyMode operator_apply_mode,
66 const linalg::OperatorCommunicationMode operator_communication_mode )
67 {
68 operator_apply_mode_ = operator_apply_mode;
69 operator_communication_mode_ = operator_communication_mode;
70 }
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 if ( operator_communication_mode_ == linalg::OperatorCommunicationMode::CommunicateAdditively )
85 {
87 domain_, dst_, send_buffers_, recv_buffers_ );
89 }
90 }
91
92 KOKKOS_INLINE_FUNCTION void
93 operator()( const int local_subdomain_id, const int x_cell, const int y_cell, const int r_cell ) const
94 {
95 // First all the r-independent stuff.
96 // Gather surface points for each wedge.
97
99 wedge_surface_physical_coords( wedge_phy_surf, grid_, local_subdomain_id, x_cell, y_cell );
100
101 // Compute lateral part of Jacobian.
102
103 constexpr auto num_quad_points = quadrature::quad_felippa_3x2_num_quad_points;
104
105 dense::Vec< ScalarT, 3 > quad_points[num_quad_points];
106 ScalarT quad_weights[num_quad_points];
107
110
111 dense::Mat< ScalarT, 3, 3 > jac_lat_inv_t[num_wedges_per_hex_cell][num_quad_points] = {};
112 ScalarT det_jac_lat[num_wedges_per_hex_cell][num_quad_points] = {};
113
114 jacobian_lat_inverse_transposed_and_determinant( jac_lat_inv_t, det_jac_lat, wedge_phy_surf, quad_points );
115
118
119 lateral_parts_of_grad_phi( g_rad, g_lat, jac_lat_inv_t, quad_points );
120
121 // Only now we introduce radially dependent terms.
122 const ScalarT r_1 = radii_( local_subdomain_id, r_cell );
123 const ScalarT r_2 = radii_( local_subdomain_id, r_cell + 1 );
124
125 // For now, compute the local element matrix. We'll improve that later.
127
128 // TODO: this can be absorbed into g_lat.
129 // TODO: ALSO we can sometimes avoid division if we pull the r^2 and grad_r out of the determinant and replace
130 // the prefactors for the g_lat and g_rad but this is very form-specific.
131 const ScalarT grad_r = grad_forward_map_rad( r_1, r_2 );
132 const ScalarT grad_r_inv = 1.0 / grad_r;
133
134 for ( int q = 0; q < num_quad_points; q++ )
135 {
136 // TODO: We could precompute that per quadrature point and store in a View globally to avoid the division.
137 const ScalarT r = forward_map_rad( r_1, r_2, quad_points[q]( 2 ) );
138 const ScalarT r_inv = 1.0 / r;
139
140 for ( int wedge = 0; wedge < num_wedges_per_hex_cell; wedge++ )
141 {
142 for ( int i = 0; i < num_nodes_per_wedge; i++ )
143 {
144 for ( int j = 0; j < num_nodes_per_wedge; j++ )
145 {
146 const auto grad_i = grad_shape_full( g_rad, g_lat, r_inv, grad_r_inv, wedge, i, q );
147 const auto grad_j = grad_shape_full( g_rad, g_lat, r_inv, grad_r_inv, wedge, j, q );
148
149 const auto det = det_full( det_jac_lat, r, grad_r, wedge, q );
150
151 A[wedge]( i, j ) += quad_weights[q] * ( grad_i.dot( grad_j ) * det );
152 }
153 }
154 }
155 }
156
157 if ( treat_boundary_ )
158 {
159 for ( int wedge = 0; wedge < num_wedges_per_hex_cell; wedge++ )
160 {
161 dense::Mat< ScalarT, 6, 6 > boundary_mask;
162 boundary_mask.fill( 1.0 );
163 if ( r_cell == 0 )
164 {
165 // Inner boundary (CMB).
166 for ( int i = 0; i < 6; i++ )
167 {
168 for ( int j = 0; j < 6; j++ )
169 {
170 if ( i != j && ( i < 3 || j < 3 ) )
171 {
172 boundary_mask( i, j ) = 0.0;
173 }
174 }
175 }
176 }
177
178 if ( r_cell + 1 == radii_.extent( 1 ) - 1 )
179 {
180 // Outer boundary (surface).
181 for ( int i = 0; i < 6; i++ )
182 {
183 for ( int j = 0; j < 6; j++ )
184 {
185 if ( i != j && ( i >= 3 || j >= 3 ) )
186 {
187 boundary_mask( i, j ) = 0.0;
188 }
189 }
190 }
191 }
192
193 A[wedge].hadamard_product( boundary_mask );
194 }
195 }
196
197 if ( diagonal_ )
198 {
199 A[0] = A[0].diagonal();
200 A[1] = A[1].diagonal();
201 }
202
203 for ( int d = 0; d < VecDim; d++ )
204 {
206 extract_local_wedge_vector_coefficients( src, local_subdomain_id, x_cell, y_cell, r_cell, d, src_ );
207
209
210 dst[0] = A[0] * src[0];
211 dst[1] = A[1] * src[1];
212
213 atomically_add_local_wedge_vector_coefficients( dst_, local_subdomain_id, x_cell, y_cell, r_cell, d, dst );
214 }
215 }
216};
217
220
221} // namespace terra::fe::wedge::operators::shell
Send and receive buffers for all process-local subdomain boundaries.
Definition communication.hpp:56
Definition vector_laplace_simple.hpp:18
void operator()(const int local_subdomain_id, const int x_cell, const int y_cell, const int r_cell) const
Definition vector_laplace_simple.hpp:93
void set_operator_apply_and_communication_modes(const linalg::OperatorApplyMode operator_apply_mode, const linalg::OperatorCommunicationMode operator_communication_mode)
Definition vector_laplace_simple.hpp:64
VectorLaplaceSimple(const grid::shell::DistributedDomain &domain, const grid::Grid3DDataVec< ScalarT, 3 > &grid, const grid::Grid2DDataScalar< ScalarT > &radii, bool treat_boundary, bool diagonal, linalg::OperatorApplyMode operator_apply_mode=linalg::OperatorApplyMode::Replace, linalg::OperatorCommunicationMode operator_communication_mode=linalg::OperatorCommunicationMode::CommunicateAdditively)
Definition vector_laplace_simple.hpp:43
ScalarT ScalarType
Definition vector_laplace_simple.hpp:22
void apply_impl(const SrcVectorType &src, DstVectorType &dst)
Definition vector_laplace_simple.hpp:72
Parallel data structure organizing the thick spherical shell metadata for distributed (MPI parallel) ...
Definition spherical_shell.hpp:2498
Static assertion: VectorQ1Scalar satisfies VectorLike concept.
Definition vector_q1.hpp:162
const grid::Grid4DDataVec< ScalarType, VecDim > & grid_data() const
Get const reference to grid data.
Definition vector_q1.hpp:280
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
constexpr void lateral_parts_of_grad_phi(dense::Vec< T, 3 >(&g_rad)[num_wedges_per_hex_cell][num_nodes_per_wedge][NumQuadPoints], dense::Vec< T, 3 >(&g_lat)[num_wedges_per_hex_cell][num_nodes_per_wedge][NumQuadPoints], const dense::Mat< T, 3, 3 > jac_lat_inv_t[num_wedges_per_hex_cell][NumQuadPoints], const dense::Vec< T, 3 > quad_points[NumQuadPoints])
Computes the radially independent parts of the physical shape function gradients.
Definition kernel_helpers.hpp:208
constexpr dense::Vec< T, 3 > grad_shape_full(const dense::Vec< T, 3 > g_rad[num_wedges_per_hex_cell][num_nodes_per_wedge][NumQuadPoints], const dense::Vec< T, 3 > g_lat[num_wedges_per_hex_cell][num_nodes_per_wedge][NumQuadPoints], const T r_inv, const T grad_r_inv, const int wedge_idx, const int node_idx, const int quad_point_idx)
Computes and returns J^-T grad(N_j).
Definition kernel_helpers.hpp:247
constexpr T det_full(const T det_jac_lat[num_wedges_per_hex_cell][NumQuadPoints], const T r, const T grad_r, const int wedge_idx, const int quad_point_idx)
Computes |det(J)|.
Definition kernel_helpers.hpp:270
constexpr T grad_forward_map_rad(const T r_1, const T r_2)
Definition integrands.hpp:596
constexpr void jacobian_lat_inverse_transposed_and_determinant(dense::Mat< T, 3, 3 >(&jac_lat_inv_t)[num_wedges_per_hex_cell][NumQuadPoints], 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])
Computes the transposed inverse of the Jacobian of the lateral forward map from the reference triangl...
Definition kernel_helpers.hpp:126
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 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_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
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 ****[VecDim], Layout > Grid4DDataVec
Definition grid_types.hpp:43
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