155 const int local_subdomain_id,
156 const int x_coarse_idx,
157 const int y_coarse_idx,
158 const int r_coarse_idx )
const
163 if ( GCAElements_( local_subdomain_id, x_cell_coarsest, y_cell_coarsest, r_cell_coarsest ) > 0 )
176 dense::Vec< int, 4 > coarse_hex_idx = { local_subdomain_id, x_coarse_idx, y_coarse_idx, r_coarse_idx };
177 (void) coarse_hex_idx;
180 local_subdomain_id, 2 * x_coarse_idx, 2 * y_coarse_idx, 2 * r_coarse_idx };
183 A_coarse[num_wedges_per_hex_cell] = {};
184 A_coarse[0].
fill( 0 );
185 A_coarse[1].
fill( 0 );
187 for (
int fine_hex_lidx = 0; fine_hex_lidx < 8; fine_hex_lidx++ )
189 auto fine_hex_idx = coarse_hex_idx_fine + fine_hex_shifts[fine_hex_lidx];
192 for (
int wedge = 0; wedge < num_wedges_per_hex_cell; wedge++ )
203 for (
int fine_dof_lidx = 0; fine_dof_lidx < num_nodes_per_wedge; fine_dof_lidx++ )
205 auto fine_dof_idx = wedge_local_vertex_indices_fine[fine_dof_lidx];
208 if ( fine_dof_idx( 1 ) % 2 == 0 && fine_dof_idx( 2 ) % 2 == 0 && fine_dof_idx( 3 ) % 2 == 0 )
211 P( fine_dof_lidx, fine_dof_lidx ) = 1.0;
216 int r_idx_coarse_bot = fine_dof_idx( 3 ) < radii_fine_.extent( 1 ) - 1 ?
217 fine_dof_idx( 3 ) / 2 :
218 fine_dof_idx( 3 ) / 2 - 1;
219 int r_idx_coarse_top = r_idx_coarse_bot + 1;
220 (void) r_idx_coarse_top;
224 if ( fine_dof_idx( 1 ) % 2 == 0 && fine_dof_idx( 2 ) % 2 == 0 )
227 const auto fine_dof_x_idx_coarse = fine_dof_idx( 1 ) / 2;
228 const auto fine_dof_y_idx_coarse = fine_dof_idx( 2 ) / 2;
236 local_subdomain_id, fine_dof_idx( 1 ), fine_dof_idx( 2 ), fine_dof_idx( 3 ) },
239 fine_dof_x_idx_coarse,
240 fine_dof_y_idx_coarse,
252 Kokkos::abort(
"Unknown interpolation mode." );
255 if ( fine_dof_lidx == 2 or fine_dof_lidx == 5 )
257 P( fine_dof_lidx, 2 ) = weights( 0 );
258 P( fine_dof_lidx, 5 ) = weights( 1 );
260 else if ( fine_dof_lidx == 0 or fine_dof_lidx == 3 )
262 P( fine_dof_lidx, 0 ) = weights( 0 );
263 P( fine_dof_lidx, 3 ) = weights( 1 );
265 else if ( fine_dof_lidx == 1 or fine_dof_lidx == 4 )
267 P( fine_dof_lidx, 1 ) = weights( 0 );
268 P( fine_dof_lidx, 4 ) = weights( 1 );
276 int x0_idx_coarse = -1;
277 int x1_idx_coarse = -1;
278 int y0_idx_coarse = -1;
279 int y1_idx_coarse = -1;
282 int coarse_dof_lindices[4] = { -1 };
284 if ( fine_dof_idx( 1 ) % 2 == 0 )
287 x0_idx_coarse = fine_dof_idx( 1 ) / 2;
288 x1_idx_coarse = fine_dof_idx( 1 ) / 2;
290 y0_idx_coarse = fine_dof_idx( 2 ) / 2;
291 y1_idx_coarse = fine_dof_idx( 2 ) / 2 + 1;
293 coarse_dof_lindices[0] = 0;
294 coarse_dof_lindices[1] = 2;
295 coarse_dof_lindices[2] = 3;
296 coarse_dof_lindices[3] = 5;
298 else if ( fine_dof_idx( 2 ) % 2 == 0 )
301 x0_idx_coarse = fine_dof_idx( 1 ) / 2;
302 x1_idx_coarse = fine_dof_idx( 1 ) / 2 + 1;
304 y0_idx_coarse = fine_dof_idx( 2 ) / 2;
305 y1_idx_coarse = fine_dof_idx( 2 ) / 2;
307 coarse_dof_lindices[0] = 0;
308 coarse_dof_lindices[1] = 1;
309 coarse_dof_lindices[2] = 3;
310 coarse_dof_lindices[3] = 4;
315 x0_idx_coarse = fine_dof_idx( 1 ) / 2 + 1;
316 x1_idx_coarse = fine_dof_idx( 1 ) / 2;
318 y0_idx_coarse = fine_dof_idx( 2 ) / 2;
319 y1_idx_coarse = fine_dof_idx( 2 ) / 2 + 1;
321 coarse_dof_lindices[0] = 1;
322 coarse_dof_lindices[1] = 2;
323 coarse_dof_lindices[2] = 4;
324 coarse_dof_lindices[3] = 5;
331 local_subdomain_id, fine_dof_idx( 1 ), fine_dof_idx( 2 ), fine_dof_idx( 3 ) },
333 local_subdomain_id, x0_idx_coarse, y0_idx_coarse, r_idx_coarse_bot },
335 local_subdomain_id, x1_idx_coarse, y1_idx_coarse, r_idx_coarse_bot },
339 P( fine_dof_lidx, coarse_dof_lindices[0] ) = weights( 0 );
340 P( fine_dof_lidx, coarse_dof_lindices[1] ) = weights( 0 );
341 P( fine_dof_lidx, coarse_dof_lindices[2] ) = weights( 1 );
342 P( fine_dof_lidx, coarse_dof_lindices[3] ) = weights( 1 );
346 P( fine_dof_lidx, coarse_dof_lindices[0] ) =
347 terra::fe::wedge::shell::prolongation_constant_weight< ScalarType >(
354 P( fine_dof_lidx, coarse_dof_lindices[1] ) =
355 terra::fe::wedge::shell::prolongation_constant_weight< ScalarType >(
362 P( fine_dof_lidx, coarse_dof_lindices[2] ) =
363 terra::fe::wedge::shell::prolongation_constant_weight< ScalarType >(
370 P( fine_dof_lidx, coarse_dof_lindices[3] ) =
371 terra::fe::wedge::shell::prolongation_constant_weight< ScalarType >(
381 Kokkos::abort(
"Unknown interpolation mode." );
386 fine_op_.get_local_matrix(
387 local_subdomain_id, fine_hex_idx( 1 ), fine_hex_idx( 2 ), fine_hex_idx( 3 ), wedge );
392 if constexpr ( Operator::LocalMatrixDim == 18 )
395 for (
int dim = 0; dim < 3; ++dim )
397 for (
int i = 0; i < 6; ++i )
399 for (
int j = 0; j < 6; ++j )
401 P_vec( i + dim * num_nodes_per_wedge, j + dim * num_nodes_per_wedge ) = P( i, j );
417 if ( ( wedge == 0 && ( fine_hex_lidx == 0 || fine_hex_lidx == 1 || fine_hex_lidx == 2 ||
418 fine_hex_lidx == 4 || fine_hex_lidx == 5 || fine_hex_lidx == 6 ) ) or
419 ( wedge == 1 && ( fine_hex_lidx == 0 || fine_hex_lidx == 4 ) ) )
424 ( wedge == 1 && ( fine_hex_lidx == 1 || fine_hex_lidx == 2 || fine_hex_lidx == 3 ||
425 fine_hex_lidx == 5 || fine_hex_lidx == 6 || fine_hex_lidx == 7 ) ) or
426 ( wedge == 0 && ( fine_hex_lidx == 3 || fine_hex_lidx == 7 ) ) )
432 Kokkos::abort(
"Unexpected path." );
441 boundary_mask.
fill( 1.0 );
443 if constexpr ( Operator::LocalMatrixDim == 18 )
445 for (
int dimi = 0; dimi < 3; ++dimi )
447 for (
int dimj = 0; dimj < 3; ++dimj )
449 if ( coarse_op_.has_flag(
450 local_subdomain_id, x_coarse_idx, y_coarse_idx, r_coarse_idx, CMB ) )
453 for (
int i = 0; i < num_nodes_per_wedge; i++ )
455 for (
int j = 0; j < num_nodes_per_wedge; j++ )
457 if ( ( dimi == dimj && i != j && ( i < 3 || j < 3 ) ) or
458 ( dimi != dimj && ( i < 3 || j < 3 ) ) )
461 i + dimi * num_nodes_per_wedge, j + dimj * num_nodes_per_wedge ) = 0.0;
467 if ( coarse_op_.has_flag(
468 local_subdomain_id, x_coarse_idx, y_coarse_idx, r_coarse_idx + 1, SURFACE ) )
471 for (
int i = 0; i < num_nodes_per_wedge; i++ )
473 for (
int j = 0; j < num_nodes_per_wedge; j++ )
475 if ( ( dimi == dimj && i != j && ( i >= 3 || j >= 3 ) ) or
476 ( dimi != dimj && ( i >= 3 || j >= 3 ) ) )
479 i + dimi * num_nodes_per_wedge, j + dimj * num_nodes_per_wedge ) = 0.0;
489 if ( coarse_op_.has_flag( local_subdomain_id, x_coarse_idx, y_coarse_idx, r_coarse_idx, CMB ) )
492 for (
int i = 0; i < num_nodes_per_wedge; i++ )
494 for (
int j = 0; j < num_nodes_per_wedge; j++ )
496 if ( i != j && ( i < 3 || j < 3 ) )
498 boundary_mask( i, j ) = 0.0;
504 if ( coarse_op_.has_flag(
505 local_subdomain_id, x_coarse_idx, y_coarse_idx, r_coarse_idx + 1, SURFACE ) )
508 for (
int i = 0; i < num_nodes_per_wedge; i++ )
510 for (
int j = 0; j < num_nodes_per_wedge; j++ )
512 if ( i != j && ( i >= 3 || j >= 3 ) )
514 boundary_mask( i, j ) = 0.0;
520 for (
int wedge = 0; wedge < num_wedges_per_hex_cell; wedge++ )
527 coarse_op_.set_local_matrix( local_subdomain_id, x_coarse_idx, y_coarse_idx, r_coarse_idx, 0, A_coarse[0] );
528 coarse_op_.set_local_matrix( local_subdomain_id, x_coarse_idx, y_coarse_idx, r_coarse_idx, 1, A_coarse[1] );