Loading...
Searching...
No Matches
prolongation_constant.hpp
Go to the documentation of this file.
1
2
3#pragma once
4
6#include "dense/vec.hpp"
8#include "linalg/operator.hpp"
9#include "linalg/vector.hpp"
10#include "linalg/vector_q1.hpp"
11
13
14template < typename ScalarT >
16{
17 public:
20 using ScalarType = ScalarT;
21
22 private:
23 linalg::OperatorApplyMode operator_apply_mode_;
24
27
28 public:
30 : operator_apply_mode_( operator_apply_mode )
31 {}
32
33 void apply_impl( const SrcVectorType& src, DstVectorType& dst )
34 {
35 if ( operator_apply_mode_ == linalg::OperatorApplyMode::Replace )
36 {
37 assign( dst, 0 );
38 }
39
40 src_ = src.grid_data();
41 dst_ = dst.grid_data();
42
43 if ( src_.extent( 0 ) != dst_.extent( 0 ) )
44 {
45 throw std::runtime_error( "Prolongation: src and dst must have the same number of subdomains." );
46 }
47
48 for ( int i = 1; i <= 3; i++ )
49 {
50 if ( 2 * ( src_.extent( i ) - 1 ) != dst_.extent( i ) - 1 )
51 {
52 throw std::runtime_error( "Prolongation: src and dst must have a compatible number of cells." );
53 }
54 }
55
56 // Looping over the coarse grid.
57 Kokkos::parallel_for(
58 "matvec",
59 Kokkos::MDRangePolicy< Kokkos::Rank< 4 > >(
60 { 0, 0, 0, 0 },
61 {
62 src_.extent( 0 ),
63 src_.extent( 1 ),
64 src_.extent( 2 ),
65 src_.extent( 3 ),
66 } ),
67 *this );
68
69 Kokkos::fence();
70 }
71
72 KOKKOS_INLINE_FUNCTION void
73 operator()( const int local_subdomain_id, const int x_coarse, const int y_coarse, const int r_coarse ) const
74 {
75 const auto x_fine = 2 * x_coarse;
76 const auto y_fine = 2 * y_coarse;
77 const auto r_fine = 2 * r_coarse;
78
79 dense::Vec< int, 3 > offsets[21];
81
82 for ( const auto& offset : offsets )
83 {
84 const auto fine_stencil_x = x_fine + offset( 0 );
85 const auto fine_stencil_y = y_fine + offset( 1 );
86 const auto fine_stencil_r = r_fine + offset( 2 );
87
88 if ( fine_stencil_x >= 0 && fine_stencil_x < dst_.extent( 1 ) && fine_stencil_y >= 0 &&
89 fine_stencil_y < dst_.extent( 2 ) && fine_stencil_r >= 0 && fine_stencil_r < dst_.extent( 3 ) )
90 {
91 const auto weight = wedge::shell::prolongation_constant_weight< ScalarType >(
92 fine_stencil_x, fine_stencil_y, fine_stencil_r, x_coarse, y_coarse, r_coarse );
93
94 Kokkos::atomic_add(
95 &dst_( local_subdomain_id, fine_stencil_x, fine_stencil_y, fine_stencil_r ),
96 weight * src_( local_subdomain_id, x_coarse, y_coarse, r_coarse ) );
97 }
98 }
99 }
100};
101
102template < typename ScalarT, int VecDim = 3 >
104{
105 public:
108 using ScalarType = ScalarT;
109
110 private:
111 linalg::OperatorApplyMode operator_apply_mode_;
112
115
116 public:
119 : operator_apply_mode_( operator_apply_mode )
120 {}
121
122 void apply_impl( const SrcVectorType& src, DstVectorType& dst )
123 {
124 if ( operator_apply_mode_ == linalg::OperatorApplyMode::Replace )
125 {
126 assign( dst, 0 );
127 }
128
129 src_ = src.grid_data();
130 dst_ = dst.grid_data();
131
132 if ( src_.extent( 0 ) != dst_.extent( 0 ) )
133 {
134 throw std::runtime_error( "Prolongation: src and dst must have the same number of subdomains." );
135 }
136
137 for ( int i = 1; i <= 3; i++ )
138 {
139 if ( 2 * ( src_.extent( i ) - 1 ) != dst_.extent( i ) - 1 )
140 {
141 throw std::runtime_error( "Prolongation: src and dst must have a compatible number of cells." );
142 }
143 }
144
145 // Looping over the coarse grid.
146 Kokkos::parallel_for(
147 "matvec",
148 Kokkos::MDRangePolicy< Kokkos::Rank< 4 > >(
149 { 0, 0, 0, 0 },
150 {
151 src_.extent( 0 ),
152 src_.extent( 1 ),
153 src_.extent( 2 ),
154 src_.extent( 3 ),
155 } ),
156 *this );
157
158 Kokkos::fence();
159 }
160
161 KOKKOS_INLINE_FUNCTION void
162 operator()( const int local_subdomain_id, const int x_coarse, const int y_coarse, const int r_coarse ) const
163 {
164 const auto x_fine = 2 * x_coarse;
165 const auto y_fine = 2 * y_coarse;
166 const auto r_fine = 2 * r_coarse;
167
168 dense::Vec< int, 3 > offsets[21];
170
171 for ( const auto& offset : offsets )
172 {
173 const auto fine_stencil_x = x_fine + offset( 0 );
174 const auto fine_stencil_y = y_fine + offset( 1 );
175 const auto fine_stencil_r = r_fine + offset( 2 );
176
177 if ( fine_stencil_x >= 0 && fine_stencil_x < dst_.extent( 1 ) && fine_stencil_y >= 0 &&
178 fine_stencil_y < dst_.extent( 2 ) && fine_stencil_r >= 0 && fine_stencil_r < dst_.extent( 3 ) )
179 {
180 const auto weight = wedge::shell::prolongation_constant_weight< ScalarType >(
181 fine_stencil_x, fine_stencil_y, fine_stencil_r, x_coarse, y_coarse, r_coarse );
182
183 for ( int d = 0; d < VecDim; ++d )
184 {
185 Kokkos::atomic_add(
186 &dst_( local_subdomain_id, fine_stencil_x, fine_stencil_y, fine_stencil_r, d ),
187 weight * src_( local_subdomain_id, x_coarse, y_coarse, r_coarse, d ) );
188 }
189 }
190 }
191 }
192};
193
194} // namespace terra::fe::wedge::operators::shell
Definition prolongation_constant.hpp:16
void operator()(const int local_subdomain_id, const int x_coarse, const int y_coarse, const int r_coarse) const
Definition prolongation_constant.hpp:73
void apply_impl(const SrcVectorType &src, DstVectorType &dst)
Definition prolongation_constant.hpp:33
ScalarT ScalarType
Definition prolongation_constant.hpp:20
ProlongationConstant(linalg::OperatorApplyMode operator_apply_mode=linalg::OperatorApplyMode::Replace)
Definition prolongation_constant.hpp:29
Definition prolongation_constant.hpp:104
void operator()(const int local_subdomain_id, const int x_coarse, const int y_coarse, const int r_coarse) const
Definition prolongation_constant.hpp:162
void apply_impl(const SrcVectorType &src, DstVectorType &dst)
Definition prolongation_constant.hpp:122
ScalarT ScalarType
Definition prolongation_constant.hpp:108
ProlongationVecConstant(linalg::OperatorApplyMode operator_apply_mode=linalg::OperatorApplyMode::Replace)
Definition prolongation_constant.hpp:117
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
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
Definition boundary_mass.hpp:14
constexpr void prolongation_constant_fine_grid_stencil_offsets_at_coarse_vertex(dense::Vec< int, 3 >(&offsets)[21])
Definition grid_transfer_constant.hpp:9
Kokkos::View< ScalarType ****[VecDim], Layout > Grid4DDataVec
Definition grid_types.hpp:43
Kokkos::View< ScalarType ****, Layout > Grid4DDataScalar
Definition grid_types.hpp:25
OperatorApplyMode
Modes for applying an operator to a vector.
Definition operator.hpp:30
@ Replace
Overwrite the destination vector.
Definition vec.hpp:9