15template <
typename T,
typename ScalarType,
typename Gr
idScalarType >
17 { self.operator()( x ) } -> std::same_as< ScalarType >;
42template <
typename ScalarType,
typename Gr
idScalarType, FVProjectionFunctor< ScalarType, Gr
idScalarType > Functor >
51 "l2_project_into_fv_function",
52 Kokkos::MDRangePolicy(
54 { fv_grid.extent( 0 ), fv_grid.extent( 1 ) - 1, fv_grid.extent( 2 ) - 1, fv_grid.extent( 3 ) - 1 } ),
56 const int local_subdomain_id,
const int hex_cell_x,
const int hex_cell_y,
const int hex_cell_r ) {
59 ScalarType quad_weights[num_quad_points];
63 ScalarType volume = 0.0;
64 ScalarType integral = 0.0;
69 wedge_phy_surf, coords_shell, local_subdomain_id, hex_cell_x - 1, hex_cell_y - 1 );
71 const auto r_1 = coords_radii( local_subdomain_id, hex_cell_r - 1 );
72 const auto r_2 = coords_radii( local_subdomain_id, hex_cell_r );
76 for (
int q = 0; q < num_quad_points; ++q )
78 const auto J =
fe::wedge::jac( wedge_phy_surf[wedge], r_1, r_2, quad_points[q] );
79 const auto det = J.det();
80 const auto abs_det = Kokkos::abs( det );
81 const auto Jw = abs_det * quad_weights[q];
85 wedge_phy_surf[wedge][0],
86 wedge_phy_surf[wedge][1],
87 wedge_phy_surf[wedge][2],
92 quad_points[q]( 2 ) );
94 integral += src( x ) * Jw;
98 fv_grid( local_subdomain_id, hex_cell_x, hex_cell_y, hex_cell_r ) = integral / volume;
130template <
typename ScalarType,
typename Gr
idScalarType >
139 if ( tmps.size() < 5 )
141 Kokkos::abort(
"At least 5 tmp vectors required." );
151 Kokkos::parallel_for(
152 "l2_project_fv_to_fe_rhs_assembly",
153 Kokkos::MDRangePolicy(
155 { fv_grid.extent( 0 ), fv_grid.extent( 1 ) - 1, fv_grid.extent( 2 ) - 1, fv_grid.extent( 3 ) - 1 } ),
157 const int local_subdomain_id,
const int hex_cell_x,
const int hex_cell_y,
const int hex_cell_r ) {
158 const auto hex_cell_x_no_gl = hex_cell_x - 1;
159 const auto hex_cell_y_no_gl = hex_cell_y - 1;
160 const auto hex_cell_r_no_gl = hex_cell_r - 1;
164 ScalarType quad_weights[num_quad_points];
171 wedge_phy_surf, coords_shell, local_subdomain_id, hex_cell_x - 1, hex_cell_y - 1 );
173 const auto r_1 = coords_radii( local_subdomain_id, hex_cell_r - 1 );
174 const auto r_2 = coords_radii( local_subdomain_id, hex_cell_r );
176 const auto fv_value = fv_grid( local_subdomain_id, hex_cell_x, hex_cell_y, hex_cell_r );
184 for (
int q = 0; q < num_quad_points; ++q )
186 const auto J =
fe::wedge::jac( wedge_phy_surf[wedge], r_1, r_2, quad_points[q] );
187 const auto det = J.det();
188 const auto abs_det = Kokkos::abs( det );
191 b_local[wedge]( i ) += shape_i_q * abs_det * quad_weights[q];
194 b_local[wedge]( i ) *= fv_value;
199 b_grid, local_subdomain_id, hex_cell_x_no_gl, hex_cell_y_no_gl, hex_cell_r_no_gl, b_local );
205 Mass M( domain, coords_shell, coords_radii );
242template <
typename ScalarType,
typename Gr
idScalarType >
251 if ( tmps.size() < 2 )
253 Kokkos::abort(
"At least 2 tmp vectors required." );
266 Kokkos::parallel_for(
267 "l2_project_fv_to_fe_lumped_assembly",
268 Kokkos::MDRangePolicy(
270 { fv_grid.extent( 0 ), fv_grid.extent( 1 ) - 1, fv_grid.extent( 2 ) - 1, fv_grid.extent( 3 ) - 1 } ),
272 const int local_subdomain_id,
const int hex_cell_x,
const int hex_cell_y,
const int hex_cell_r ) {
273 const auto hex_cell_x_no_gl = hex_cell_x - 1;
274 const auto hex_cell_y_no_gl = hex_cell_y - 1;
275 const auto hex_cell_r_no_gl = hex_cell_r - 1;
279 ScalarType quad_weights[num_quad_points];
286 wedge_phy_surf, coords_shell, local_subdomain_id, hex_cell_x - 1, hex_cell_y - 1 );
288 const auto r_1 = coords_radii( local_subdomain_id, hex_cell_r - 1 );
289 const auto r_2 = coords_radii( local_subdomain_id, hex_cell_r );
291 const auto fv_value = fv_grid( local_subdomain_id, hex_cell_x, hex_cell_y, hex_cell_r );
301 for (
int q = 0; q < num_quad_points; ++q )
303 const auto J =
fe::wedge::jac( wedge_phy_surf[wedge], r_1, r_2, quad_points[q] );
304 const auto abs_det = Kokkos::abs( J.det() );
305 const auto phi_i_Jw =
fe::wedge::shape( i, quad_points[q] ) * abs_det * quad_weights[q];
307 d_local[wedge]( i ) += phi_i_Jw;
310 b_local[wedge]( i ) = fv_value * d_local[wedge]( i );
315 b_grid, local_subdomain_id, hex_cell_x_no_gl, hex_cell_y_no_gl, hex_cell_r_no_gl, b_local );
317 d_grid, local_subdomain_id, hex_cell_x_no_gl, hex_cell_y_no_gl, hex_cell_r_no_gl, d_local );
348template <
typename ScalarType,
typename Gr
idScalarType >
359 Kokkos::parallel_for(
360 "l2_project_fe_to_fv",
361 Kokkos::MDRangePolicy(
363 { fv_grid.extent( 0 ), fv_grid.extent( 1 ) - 1, fv_grid.extent( 2 ) - 1, fv_grid.extent( 3 ) - 1 } ),
365 const int local_subdomain_id,
const int hex_cell_x,
const int hex_cell_y,
const int hex_cell_r ) {
367 const auto x_no_gl = hex_cell_x - 1;
368 const auto y_no_gl = hex_cell_y - 1;
369 const auto r_no_gl = hex_cell_r - 1;
373 ScalarType quad_weights[num_quad_points];
380 local_u, local_subdomain_id, x_no_gl, y_no_gl, r_no_gl, q1_grid );
385 wedge_phy_surf, coords_shell, local_subdomain_id, x_no_gl, y_no_gl );
387 const auto r_1 = coords_radii( local_subdomain_id, r_no_gl );
388 const auto r_2 = coords_radii( local_subdomain_id, hex_cell_r );
390 ScalarType volume = ScalarType( 0 );
391 ScalarType integral = ScalarType( 0 );
395 for (
int q = 0; q < num_quad_points; ++q )
397 const auto J =
fe::wedge::jac( wedge_phy_surf[wedge], r_1, r_2, quad_points[q] );
398 const auto abs_det = Kokkos::abs( J.det() );
399 const auto Jw = abs_det * quad_weights[q];
403 ScalarType u_q = ScalarType( 0 );
405 u_q += local_u[wedge]( i ) * fe::wedge::shape< ScalarType >( i, quad_points[q] );
407 integral += u_q * Jw;
411 fv_grid( local_subdomain_id, hex_cell_x, hex_cell_y, hex_cell_r ) = integral / volume;
Definition fe/wedge/operators/shell/mass.hpp:18
Parallel data structure organizing the thick spherical shell metadata for distributed (MPI parallel) ...
Definition spherical_shell.hpp:2518
Finite volume vector on distributed shell grid with one DoF per hex (merging 2 wedges) and ghost-laye...
Definition vector_fv.hpp:23
const grid::Grid4DDataScalar< ScalarType > & grid_data() const
Get const reference to grid data.
Definition vector_fv.hpp:145
const grid::Grid4DDataScalar< ScalarType > & grid_data() const
Get const reference to grid data.
Definition vector_q1.hpp:139
Definition iterative_solver_info.hpp:7
Preconditioned Conjugate Gradient (PCG) iterative solver for symmetric positive definite linear syste...
Definition pcg.hpp:30
Definition conversion.hpp:16
Ghost layer communication for scalar finite volume (FV) fields on the shell grid.
void send_recv(const grid::shell::DistributedDomain &domain, grid::Grid4DDataScalar< ScalarType > &grid, const CommunicationReduction reduction=CommunicationReduction::SUM)
Executes packing, sending, receiving, and unpacking operations for the shell.
Definition communication.hpp:750
void update_fv_ghost_layers(const grid::shell::DistributedDomain &domain, const grid::Grid4DDataScalar< ScalarType > &data, FVGhostLayerBuffers< ScalarType > &bufs)
Fills all ghost layers of a scalar FV field from neighbouring subdomains.
Definition fv_communication.hpp:316
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
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 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 dense::Vec< T, 3 > forward_map(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:596
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
Definition conversion.hpp:13
void l2_project_analytical_to_fv(linalg::VectorFVScalar< ScalarType > &dst, const Functor &src, const grid::Grid3DDataVec< GridScalarType, 3 > &coords_shell, const grid::Grid2DDataScalar< GridScalarType > &coords_radii)
L2 projection of an analytical function into a finite volume function.
Definition conversion.hpp:43
void l2_project_fv_to_fe_lumped(linalg::VectorQ1Scalar< ScalarType > &dst, const linalg::VectorFVScalar< ScalarType > &src, const grid::shell::DistributedDomain &domain, const grid::Grid3DDataVec< GridScalarType, 3 > &coords_shell, const grid::Grid2DDataScalar< GridScalarType > &coords_radii, std::vector< linalg::VectorQ1Scalar< ScalarType > > &tmps)
Bound-preserving FV-to-FE transfer via a lumped mass matrix.
Definition conversion.hpp:243
void l2_project_fv_to_fe(linalg::VectorQ1Scalar< ScalarType > &dst, const linalg::VectorFVScalar< ScalarType > &src, const grid::shell::DistributedDomain &domain, const grid::Grid3DDataVec< GridScalarType, 3 > &coords_shell, const grid::Grid2DDataScalar< GridScalarType > &coords_radii, std::vector< linalg::VectorQ1Scalar< ScalarType > > &tmps)
L2 projection from a finite volume function into a Q1 (wedge) finite element function.
Definition conversion.hpp:131
void l2_project_fe_to_fv(linalg::VectorFVScalar< ScalarType > &dst, const linalg::VectorQ1Scalar< ScalarType > &src, const grid::shell::DistributedDomain &domain, const grid::Grid3DDataVec< GridScalarType, 3 > &coords_shell, const grid::Grid2DDataScalar< GridScalarType > &coords_radii)
L2 projection from a Q1 finite element function into a finite volume function.
Definition conversion.hpp:349
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
void solve(Solver &solver, Operator &A, SolutionVector &x, const RHSVector &b)
Solve a linear system using the given solver and operator. Calls the solver's solve_impl method.
Definition solver.hpp:51
void invert_entries(Vector &y)
Invert the entries of a vector. For each entry , computes .
Definition vector.hpp:127
void scale_in_place(Vector &y, const Vector &x)
Scale a vector in place with another vector. For each entry , computes .
Definition vector.hpp:137
void assign(Vector &y, const ScalarOf< Vector > &c0)
Assign a scalar value to a vector. Implements: .
Definition vector.hpp:97