Cabana 0.8.0-dev
 
Loading...
Searching...
No Matches
Cabana_Grid_LocalGrid_impl.hpp
1/****************************************************************************
2 * Copyright (c) 2018-2023 by the Cabana authors *
3 * All rights reserved. *
4 * *
5 * This file is part of the Cabana library. Cabana is distributed under a *
6 * BSD 3-clause license. For the licensing terms see the LICENSE file in *
7 * the top-level directory. *
8 * *
9 * SPDX-License-Identifier: BSD-3-Clause *
10 ****************************************************************************/
11
12#ifndef CABANA_GRID_LOCALGRID_IMPL_HPP
13#define CABANA_GRID_LOCALGRID_IMPL_HPP
14
15namespace Cabana
16{
17namespace Grid
18{
19//---------------------------------------------------------------------------//
20// Constructor.
21template <class MeshType>
23 const std::shared_ptr<GlobalGrid<MeshType>>& global_grid,
24 const int halo_cell_width )
25 : _global_grid( global_grid )
26 , _halo_cell_width( halo_cell_width )
27{
28}
29
30//---------------------------------------------------------------------------//
31// Get the global grid that owns the local grid.
32template <class MeshType>
34{
35 return *_global_grid;
36}
37
38//---------------------------------------------------------------------------//
39// Get a mutable version of the global grid that own the local grid.
40template <class MeshType>
42{
43 return *_global_grid;
44}
45
46//---------------------------------------------------------------------------//
47// Get the halo size.
48template <class MeshType>
50{
51 return _halo_cell_width;
52}
53
54//---------------------------------------------------------------------------//
55// Get the total number of local cells in a given dimension (owned + halo).
56template <class MeshType>
57int LocalGrid<MeshType>::totalNumCell( const int d ) const
58{
59 return _global_grid->ownedNumCell( d ) + 2 * _halo_cell_width;
60}
61
62//---------------------------------------------------------------------------//
63// Given the relative offsets of a neighbor rank relative to this local grid's
64// indices get the of the neighbor.
65template <class MeshType>
67 const std::array<int, num_space_dim>& off_ijk ) const
68{
69 std::array<int, num_space_dim> nijk;
70 for ( std::size_t d = 0; d < num_space_dim; ++d )
71 nijk[d] = _global_grid->dimBlockId( d ) + off_ijk[d];
72 return _global_grid->blockRank( nijk );
73}
74
75template <class MeshType>
76template <std::size_t NSD>
77std::enable_if_t<3 == NSD, int>
78LocalGrid<MeshType>::neighborRank( const int off_i, const int off_j,
79 const int off_k ) const
80{
81 std::array<int, num_space_dim> off_ijk = { off_i, off_j, off_k };
82 return neighborRank( off_ijk );
83}
84
85template <class MeshType>
86template <std::size_t NSD>
87std::enable_if_t<2 == NSD, int>
88LocalGrid<MeshType>::neighborRank( const int off_i, const int off_j ) const
89{
90 std::array<int, num_space_dim> off_ijk = { off_i, off_j };
91 return neighborRank( off_ijk );
92}
93
95//---------------------------------------------------------------------------//
96// Get the index space for a given combination of decomposition, entity, and
97// index types.
98template <class MeshType>
99template <class DecompositionTag, class EntityType, class IndexType>
100auto LocalGrid<MeshType>::indexSpace( DecompositionTag t1, EntityType t2,
101 IndexType t3 ) const
103{
104 return indexSpaceImpl( t1, t2, t3 );
105}
106
107//---------------------------------------------------------------------------//
108// Given the relative offsets of a neighbor rank relative to this local
109// grid's indices get the set of local entity indices shared with that
110// neighbor in the given decomposition. Optionally provide a halo width
111// for the shared space. This halo width must be less than or equal to the
112// halo width of the local grid. The default behavior is to use the halo
113// width of the local grid.
114template <class MeshType>
115template <class DecompositionTag, class EntityType>
117 DecompositionTag t1, EntityType t2,
118 const std::array<int, num_space_dim>& off_ijk, const int halo_width ) const
119 -> IndexSpace<num_space_dim>
120{
121 // If we got the default halo width of -1 this means we want to use the
122 // default of the entire halo.
123 int hw = ( -1 == halo_width ) ? _halo_cell_width : halo_width;
124
125 // Check that the offsets are valid.
126 for ( std::size_t d = 0; d < num_space_dim; ++d )
127 if ( off_ijk[d] < -1 || 1 < off_ijk[d] )
128 throw std::logic_error( "Neighbor indices out of bounds" );
129
130 // Check that the requested halo width is valid.
131 if ( hw > _halo_cell_width )
132 throw std::logic_error(
133 "Requested halo width larger than local grid halo" );
134
135 // Check to see if this is a valid neighbor. If not, return a shared space
136 // of size 0.
137 if ( neighborRank( off_ijk ) < 0 )
138 {
139 std::array<long, num_space_dim> zero_size;
140 for ( std::size_t d = 0; d < num_space_dim; ++d )
141 zero_size[d] = 0;
142 return IndexSpace<num_space_dim>( zero_size, zero_size );
143 }
144
145 // Call the underlying implementation.
146 return sharedIndexSpaceImpl( t1, t2, off_ijk, hw );
147}
148
149template <class MeshType>
150template <class DecompositionTag, class EntityType, std::size_t NSD>
151std::enable_if_t<3 == NSD, IndexSpace<3>> LocalGrid<MeshType>::sharedIndexSpace(
152 DecompositionTag t1, EntityType t2, const int off_i, const int off_j,
153 const int off_k, const int halo_width ) const
154{
155 std::array<int, 3> off_ijk = { off_i, off_j, off_k };
156 return sharedIndexSpace( t1, t2, off_ijk, halo_width );
157}
158
159template <class MeshType>
160template <class DecompositionTag, class EntityType, std::size_t NSD>
161std::enable_if_t<2 == NSD, IndexSpace<2>>
162LocalGrid<MeshType>::sharedIndexSpace( DecompositionTag t1, EntityType t2,
163 const int off_i, const int off_j,
164 const int halo_width ) const
165{
166 std::array<int, 2> off_ijk = { off_i, off_j };
167 return sharedIndexSpace( t1, t2, off_ijk, halo_width );
168}
169
170//---------------------------------------------------------------------------//
171// Given the relative offsets of a boundary relative to this local grid's
172// indices get the set of local entity indices associated with that boundary
173// in the given decomposition. Optionally provide a halo width for the shared
174// space. This halo width must be less than or equal to the halo width of the
175// local grid. The default behavior is to use the halo width of the local
176// grid. For example, if the Own decomposition is used, the interior entities
177// that would be affected by a boundary operation are provided whereas if the
178// Ghost decomposition is used the halo entities on the boundary are provided.
179template <class MeshType>
180template <class DecompositionTag, class EntityType>
182 DecompositionTag t1, EntityType t2,
183 const std::array<int, num_space_dim>& off_ijk, const int halo_width ) const
185{
186 // If we got the default halo width of -1 this means we want to use the
187 // default of the entire halo.
188 int hw = ( -1 == halo_width ) ? _halo_cell_width : halo_width;
189
190 // Check that the offsets are valid.
191 for ( std::size_t d = 0; d < num_space_dim; ++d )
192 if ( off_ijk[d] < -1 || 1 < off_ijk[d] )
193 throw std::logic_error( "Boundary indices out of bounds" );
194
195 // Check that the requested halo width is valid.
196 if ( hw > _halo_cell_width )
197 throw std::logic_error(
198 "Requested halo width larger than local grid halo" );
199
200 // Check to see if this is not a communication neighbor. If it is, return
201 // a boundary space of size 0 because there is no boundary.
202 if ( neighborRank( off_ijk ) >= 0 )
203 {
204 std::array<long, num_space_dim> zero_size;
205 for ( std::size_t d = 0; d < num_space_dim; ++d )
206 zero_size[d] = 0;
207 return IndexSpace<num_space_dim>( zero_size, zero_size );
208 }
209
210 return boundaryIndexSpaceImpl( t1, t2, off_ijk, hw );
211}
212
213template <class MeshType>
214template <class DecompositionTag, class EntityType, std::size_t NSD>
215std::enable_if_t<3 == NSD, IndexSpace<3>>
216LocalGrid<MeshType>::boundaryIndexSpace( DecompositionTag t1, EntityType t2,
217 const int off_i, const int off_j,
218 const int off_k,
219 const int halo_width ) const
220{
221 std::array<int, 3> off_ijk = { off_i, off_j, off_k };
222 return boundaryIndexSpace( t1, t2, off_ijk, halo_width );
223}
224
225template <class MeshType>
226template <class DecompositionTag, class EntityType, std::size_t NSD>
227std::enable_if_t<2 == NSD, IndexSpace<2>>
228LocalGrid<MeshType>::boundaryIndexSpace( DecompositionTag t1, EntityType t2,
229 const int off_i, const int off_j,
230 const int halo_width ) const
231{
232 std::array<int, 2> off_ijk = { off_i, off_j };
233 return boundaryIndexSpace( t1, t2, off_ijk, halo_width );
234}
235
236//---------------------------------------------------------------------------//
237// Get the local index space of the owned cells.
238template <class MeshType>
239auto LocalGrid<MeshType>::indexSpaceImpl( Own, Cell, Local ) const
241{
242 // Compute the lower bound.
243 std::array<long, num_space_dim> min;
244 for ( std::size_t d = 0; d < num_space_dim; ++d )
245 min[d] = _halo_cell_width;
246
247 // Compute the upper bound.
248 std::array<long, num_space_dim> max;
249 for ( std::size_t d = 0; d < num_space_dim; ++d )
250 max[d] = min[d] + _global_grid->ownedNumCell( d );
251
252 return IndexSpace<num_space_dim>( min, max );
253}
254
255//---------------------------------------------------------------------------//
256// Get the local index space of the owned and ghosted cells.
257template <class MeshType>
258auto LocalGrid<MeshType>::indexSpaceImpl( Ghost, Cell, Local ) const
260{
261 // Compute the size.
262 std::array<long, num_space_dim> size;
263 for ( std::size_t d = 0; d < num_space_dim; ++d )
264 {
265 size[d] = totalNumCell( d );
266 }
267
269}
270
271//---------------------------------------------------------------------------//
272// Get the global index space of the owned cells.
273template <class MeshType>
274auto LocalGrid<MeshType>::indexSpaceImpl( Own t1, Cell t2, Global ) const
276{
277 return globalIndexSpace( t1, t2 );
278}
279
280// Return the bound for a shared/boundary index space given an owned space.
281template <class MeshType>
282template <class OwnedIndexSpace>
283auto LocalGrid<MeshType>::getBound(
284 OwnedIndexSpace owned_space, const int upper_lower,
285 const std::array<int, num_space_dim>& off_ijk, const int lower_shift,
286 const int upper_shift ) const
287{
288 // Compute the lower bound.
289 std::array<long, num_space_dim> minmax;
290 for ( std::size_t d = 0; d < num_space_dim; ++d )
291 {
292 // Lower neighbor.
293 if ( -1 == off_ijk[d] )
294 {
295 minmax[d] = owned_space.min( d ) + lower_shift;
296 }
297 // Middle neighbor.
298 else if ( 0 == off_ijk[d] )
299 {
300 if ( upper_lower < 0 )
301 minmax[d] = owned_space.min( d );
302 else if ( upper_lower > 0 )
303 minmax[d] = owned_space.max( d );
304 else
305 throw std::runtime_error( "Cabana::Grid::LocalGrid::getBound::"
306 "Impl: Only 1 or -1 allowed" );
307 }
308 // Upper neighbor.
309 else if ( 1 == off_ijk[d] )
310 {
311 minmax[d] = owned_space.max( d ) + upper_shift;
312 }
313 else
314 {
315 throw std::runtime_error( "Cabana::Grid::LocalGrid::getBound: "
316 "Neighbor offset must be 1, 0, or -1" );
317 }
318 }
319 return minmax;
320}
321
322// Return the bound for a shared/boundary index space given an owned space.
323// Overload for face/edge with different range per dimension.
324template <class MeshType>
325template <int Dir, class OwnedIndexSpace>
326auto LocalGrid<MeshType>::getBound(
327 OwnedIndexSpace owned_space, const int upper_lower,
328 const std::array<int, num_space_dim>& off_ijk, const int lower_shift_dir,
329 const int lower_shift, const int upper_shift_dir,
330 const int upper_shift ) const
331{
332 // Compute the lower bound.
333 std::array<long, num_space_dim> minmax;
334 for ( std::size_t d = 0; d < num_space_dim; ++d )
335 {
336 // Lower neighbor.
337 if ( -1 == off_ijk[d] )
338 {
339 minmax[d] = ( Dir == d ) ? owned_space.min( d ) + lower_shift_dir
340 : owned_space.min( d ) + lower_shift;
341 }
342 // Middle neighbor.
343 else if ( 0 == off_ijk[d] )
344 {
345 if ( upper_lower < 0 )
346 minmax[d] = owned_space.min( d );
347 else if ( upper_lower > 0 )
348 minmax[d] = owned_space.max( d );
349 else
350 throw std::runtime_error( "Cabana::Grid::LocalGrid::getBound::"
351 "Impl: Only 1 or -1 allowed" );
352 }
353 // Upper neighbor.
354 else if ( 1 == off_ijk[d] )
355 {
356 minmax[d] = ( Dir == d ) ? owned_space.max( d ) + upper_shift_dir
357 : owned_space.max( d ) + upper_shift;
358 }
359 else
360 {
361 throw std::runtime_error( "Cabana::Grid::LocalGrid::getBound: "
362 "Neighbor offset must be 1, 0, or -1" );
363 }
364 }
365 return minmax;
366}
367
368//---------------------------------------------------------------------------//
369// Given a relative set of indices of a neighbor get the set of local cell
370// indices we own that we share with that neighbor to use as ghosts.
371template <class MeshType>
372auto LocalGrid<MeshType>::sharedIndexSpaceImpl(
373 Own, Cell, const std::array<int, num_space_dim>& off_ijk,
374 const int halo_width ) const -> IndexSpace<num_space_dim>
375{
376 // Get the owned local index space.
377 auto owned_space = indexSpaceImpl( Own(), Cell(), Local() );
378
379 auto min = getBound( owned_space, -1, off_ijk, 0, -halo_width );
380 auto max = getBound( owned_space, 1, off_ijk, halo_width, 0 );
381
382 return IndexSpace<num_space_dim>( min, max );
383}
384
385//---------------------------------------------------------------------------//
386// Given a relative set of indices of a neighbor get set of local cell
387// indices owned by that neighbor that are shared with us to use as
388// ghosts.
389template <class MeshType>
390auto LocalGrid<MeshType>::sharedIndexSpaceImpl(
391 Ghost, Cell, const std::array<int, num_space_dim>& off_ijk,
392 const int halo_width ) const -> IndexSpace<num_space_dim>
393{
394 // Get the owned local index space.
395 auto owned_space = indexSpaceImpl( Own(), Cell(), Local() );
396
397 auto min = getBound( owned_space, -1, off_ijk, -halo_width, 0 );
398 auto max = getBound( owned_space, 1, off_ijk, 0, halo_width );
399
400 return IndexSpace<num_space_dim>( min, max );
401}
402
403//---------------------------------------------------------------------------//
404// Given the relative offset of a boundary relative to this local grid's
405// get the set of local cell indices we own that we share with that boundary
406// to use as ghosts. This case is equivalent to sharedIndexSpaceImpl.
407template <class MeshType>
408auto LocalGrid<MeshType>::boundaryIndexSpaceImpl(
409 Own, Cell, const std::array<int, num_space_dim>& off_ijk,
410 const int halo_width ) const -> IndexSpace<num_space_dim>
411{
412 return sharedIndexSpaceImpl( Own(), Cell(), off_ijk, halo_width );
413}
414
415//---------------------------------------------------------------------------//
416// Given the relative offset of a boundary relative to this local grid's
417// get the set of local cell indices owned by that boundary that are shared
418// with us to use as ghosts. This case is equivalent to sharedIndexSpaceImpl.
419template <class MeshType>
420auto LocalGrid<MeshType>::boundaryIndexSpaceImpl(
421 Ghost, Cell, const std::array<int, num_space_dim>& off_ijk,
422 const int halo_width ) const -> IndexSpace<num_space_dim>
423{
424 return sharedIndexSpaceImpl( Ghost(), Cell(), off_ijk, halo_width );
425}
426
427//---------------------------------------------------------------------------//
428// Get the local index space of the owned nodes.
429template <class MeshType>
430auto LocalGrid<MeshType>::indexSpaceImpl( Own, Node, Local ) const
432{
433 // Compute the lower bound.
434 std::array<long, num_space_dim> min;
435 for ( std::size_t d = 0; d < num_space_dim; ++d )
436 min[d] = _halo_cell_width;
437
438 // Compute the upper bound. Resolve the shared node if the dimension is
439 // periodic.
440 std::array<long, num_space_dim> max;
441 for ( std::size_t d = 0; d < num_space_dim; ++d )
442 max[d] = ( _global_grid->isPeriodic( d ) ||
443 _global_grid->dimBlockId( d ) <
444 _global_grid->dimNumBlock( d ) - 1 )
445 ? min[d] + _global_grid->ownedNumCell( d )
446 : min[d] + _global_grid->ownedNumCell( d ) + 1;
447
448 return IndexSpace<num_space_dim>( min, max );
449}
450
451//---------------------------------------------------------------------------//
452// Get the local index space of the owned and ghosted nodes.
453template <class MeshType>
454auto LocalGrid<MeshType>::indexSpaceImpl( Ghost, Node, Local ) const
456{
457 // Compute the size.
458 std::array<long, num_space_dim> size;
459 for ( std::size_t d = 0; d < num_space_dim; ++d )
460 {
461 size[d] = totalNumCell( d ) + 1;
462 }
463
465}
466
467//---------------------------------------------------------------------------//
468// Get the global index space of the owned nodes.
469template <class MeshType>
470auto LocalGrid<MeshType>::indexSpaceImpl( Own t1, Node t2, Global ) const
472{
473 return globalIndexSpace( t1, t2 );
474}
475
476//---------------------------------------------------------------------------//
477// Given a relative set of indices of a neighbor get the set of local node
478// indices we own that we share with that neighbor to use as ghosts.
479template <class MeshType>
480auto LocalGrid<MeshType>::sharedIndexSpaceImpl(
481 Own, Node, const std::array<int, num_space_dim>& off_ijk,
482 const int halo_width ) const -> IndexSpace<num_space_dim>
483{
484 // Get the owned local index space.
485 auto owned_space = indexSpaceImpl( Own(), Node(), Local() );
486
487 auto min = getBound( owned_space, -1, off_ijk, 0, -halo_width );
488 auto max = getBound( owned_space, 1, off_ijk, halo_width + 1, 0 );
489
490 return IndexSpace<num_space_dim>( min, max );
491}
492
493//---------------------------------------------------------------------------//
494// Given a relative set of indices of a neighbor get set of local node
495// indices owned by that neighbor that are shared with us to use as
496// ghosts.
497template <class MeshType>
498auto LocalGrid<MeshType>::sharedIndexSpaceImpl(
499 Ghost, Node, const std::array<int, num_space_dim>& off_ijk,
500 const int halo_width ) const -> IndexSpace<num_space_dim>
501{
502 // Get the owned local index space.
503 auto owned_space = indexSpaceImpl( Own(), Node(), Local() );
504
505 auto min = getBound( owned_space, -1, off_ijk, -halo_width, 0 );
506 auto max = getBound( owned_space, 1, off_ijk, 0, halo_width + 1 );
507
508 return IndexSpace<num_space_dim>( min, max );
509}
510
511//---------------------------------------------------------------------------//
512// Given the relative offset of a boundary relative to this local grid's
513// get the set of local node indices we own that we share with that boundary
514// to use as ghosts.
515template <class MeshType>
516auto LocalGrid<MeshType>::boundaryIndexSpaceImpl(
517 Own, Node, const std::array<int, num_space_dim>& off_ijk,
518 const int halo_width ) const -> IndexSpace<num_space_dim>
519{
520 // Get the owned local index space.
521 auto owned_space = indexSpaceImpl( Own(), Node(), Local() );
522
523 auto min = getBound( owned_space, -1, off_ijk, 0, -halo_width - 1 );
524 auto max = getBound( owned_space, 1, off_ijk, halo_width + 1, 0 );
525
526 return IndexSpace<num_space_dim>( min, max );
527}
528
529//---------------------------------------------------------------------------//
530// Given the relative offset of a boundary relative to this local grid's
531// get the set of local node indices owned by that boundary that are shared
532// with us to use as ghosts.
533template <class MeshType>
534auto LocalGrid<MeshType>::boundaryIndexSpaceImpl(
535 Ghost, Node, const std::array<int, num_space_dim>& off_ijk,
536 const int halo_width ) const -> IndexSpace<num_space_dim>
537{
538 // Get the owned local index space.
539 auto owned_space = indexSpaceImpl( Own(), Node(), Local() );
540
541 auto min = getBound( owned_space, -1, off_ijk, -halo_width, 0 );
542 auto max = getBound( owned_space, 1, off_ijk, 0, halo_width );
543
544 return IndexSpace<num_space_dim>( min, max );
545}
546
547//---------------------------------------------------------------------------//
548template <class MeshType>
549auto LocalGrid<MeshType>::indexSpaceImpl( Own t1, Face<Dim::I> t2,
550 Local t3 ) const
552{
553 return faceIndexSpace( t1, t2, t3 );
554}
555
556//---------------------------------------------------------------------------//
557template <class MeshType>
558auto LocalGrid<MeshType>::indexSpaceImpl( Ghost t1, Face<Dim::I> t2,
559 Local t3 ) const
561{
562 return faceIndexSpace( t1, t2, t3 );
563}
564
565//---------------------------------------------------------------------------//
566template <class MeshType>
567auto LocalGrid<MeshType>::indexSpaceImpl( Own t1, Face<Dim::I> t2,
568 Global t3 ) const
570{
571 return faceIndexSpace( t1, t2, t3 );
572}
573
574//---------------------------------------------------------------------------//
575template <class MeshType>
576auto LocalGrid<MeshType>::sharedIndexSpaceImpl(
577 Own t1, Face<Dim::I> t2, const std::array<int, num_space_dim>& off_ijk,
578 const int halo_width ) const -> IndexSpace<num_space_dim>
579{
580 return faceSharedIndexSpace( t1, t2, off_ijk, halo_width );
581}
582
583//---------------------------------------------------------------------------//
584template <class MeshType>
585auto LocalGrid<MeshType>::sharedIndexSpaceImpl(
586 Ghost t1, Face<Dim::I> t2, const std::array<int, num_space_dim>& off_ijk,
587 const int halo_width ) const -> IndexSpace<num_space_dim>
588{
589 return faceSharedIndexSpace( t1, t2, off_ijk, halo_width );
590}
591
592//---------------------------------------------------------------------------//
593template <class MeshType>
594auto LocalGrid<MeshType>::boundaryIndexSpaceImpl(
595 Own t1, Face<Dim::I> t2, const std::array<int, num_space_dim>& off_ijk,
596 const int halo_width ) const -> IndexSpace<num_space_dim>
597{
598 return faceBoundaryIndexSpace( t1, t2, off_ijk, halo_width );
599}
600
601//---------------------------------------------------------------------------//
602template <class MeshType>
603auto LocalGrid<MeshType>::boundaryIndexSpaceImpl(
604 Ghost t1, Face<Dim::I> t2, const std::array<int, num_space_dim>& off_ijk,
605 const int halo_width ) const -> IndexSpace<num_space_dim>
606{
607 return faceBoundaryIndexSpace( t1, t2, off_ijk, halo_width );
608}
609
610//---------------------------------------------------------------------------//
611template <class MeshType>
612auto LocalGrid<MeshType>::indexSpaceImpl( Own t1, Face<Dim::J> t2,
613 Local t3 ) const
615{
616 return faceIndexSpace( t1, t2, t3 );
617}
618
619//---------------------------------------------------------------------------//
620template <class MeshType>
621auto LocalGrid<MeshType>::indexSpaceImpl( Ghost t1, Face<Dim::J> t2,
622 Local t3 ) const
624{
625 return faceIndexSpace( t1, t2, t3 );
626}
627
628//---------------------------------------------------------------------------//
629template <class MeshType>
630auto LocalGrid<MeshType>::indexSpaceImpl( Own t1, Face<Dim::J> t2,
631 Global t3 ) const
633{
634 return faceIndexSpace( t1, t2, t3 );
635}
636
637//---------------------------------------------------------------------------//
638template <class MeshType>
639auto LocalGrid<MeshType>::sharedIndexSpaceImpl(
640 Own t1, Face<Dim::J> t2, const std::array<int, num_space_dim>& off_ijk,
641 const int halo_width ) const -> IndexSpace<num_space_dim>
642{
643 return faceSharedIndexSpace( t1, t2, off_ijk, halo_width );
644}
645
646//---------------------------------------------------------------------------//
647template <class MeshType>
648auto LocalGrid<MeshType>::sharedIndexSpaceImpl(
649 Ghost t1, Face<Dim::J> t2, const std::array<int, num_space_dim>& off_ijk,
650 const int halo_width ) const -> IndexSpace<num_space_dim>
651{
652 return faceSharedIndexSpace( t1, t2, off_ijk, halo_width );
653}
654
655//---------------------------------------------------------------------------//
656template <class MeshType>
657auto LocalGrid<MeshType>::boundaryIndexSpaceImpl(
658 Own t1, Face<Dim::J> t2, const std::array<int, num_space_dim>& off_ijk,
659 const int halo_width ) const -> IndexSpace<num_space_dim>
660{
661 return faceBoundaryIndexSpace( t1, t2, off_ijk, halo_width );
662}
663
664//---------------------------------------------------------------------------//
665template <class MeshType>
666auto LocalGrid<MeshType>::boundaryIndexSpaceImpl(
667 Ghost t1, Face<Dim::J> t2, const std::array<int, num_space_dim>& off_ijk,
668 const int halo_width ) const -> IndexSpace<num_space_dim>
669{
670 return faceBoundaryIndexSpace( t1, t2, off_ijk, halo_width );
671}
672
673//---------------------------------------------------------------------------//
674template <class MeshType>
675template <std::size_t NSD>
676std::enable_if_t<3 == NSD, IndexSpace<3>>
677LocalGrid<MeshType>::indexSpaceImpl( Own t1, Face<Dim::K> t2, Local t3 ) const
678{
679 return faceIndexSpace( t1, t2, t3 );
680}
681
682//---------------------------------------------------------------------------//
683template <class MeshType>
684template <std::size_t NSD>
685std::enable_if_t<3 == NSD, IndexSpace<3>>
686LocalGrid<MeshType>::indexSpaceImpl( Ghost t1, Face<Dim::K> t2, Local t3 ) const
687{
688 return faceIndexSpace( t1, t2, t3 );
689}
690
691//---------------------------------------------------------------------------//
692template <class MeshType>
693template <std::size_t NSD>
694std::enable_if_t<3 == NSD, IndexSpace<3>>
695LocalGrid<MeshType>::indexSpaceImpl( Own t1, Face<Dim::K> t2, Global t3 ) const
696{
697 return faceIndexSpace( t1, t2, t3 );
698}
699
700//---------------------------------------------------------------------------//
701template <class MeshType>
702template <std::size_t NSD>
703std::enable_if_t<3 == NSD, IndexSpace<3>>
704LocalGrid<MeshType>::sharedIndexSpaceImpl( Own t1, Face<Dim::K> t2,
705 const std::array<int, 3>& off_ijk,
706 const int halo_width ) const
707{
708 return faceSharedIndexSpace( t1, t2, off_ijk, halo_width );
709}
710
711//---------------------------------------------------------------------------//
712template <class MeshType>
713template <std::size_t NSD>
714std::enable_if_t<3 == NSD, IndexSpace<3>>
715LocalGrid<MeshType>::sharedIndexSpaceImpl( Ghost t1, Face<Dim::K> t2,
716 const std::array<int, 3>& off_ijk,
717 const int halo_width ) const
718{
719 return faceSharedIndexSpace( t1, t2, off_ijk, halo_width );
720}
721
722//---------------------------------------------------------------------------//
723template <class MeshType>
724template <std::size_t NSD>
725std::enable_if_t<3 == NSD, IndexSpace<3>>
726LocalGrid<MeshType>::boundaryIndexSpaceImpl( Own t1, Face<Dim::K> t2,
727 const std::array<int, 3>& off_ijk,
728 const int halo_width ) const
729{
730 return faceBoundaryIndexSpace( t1, t2, off_ijk, halo_width );
731}
732
733//---------------------------------------------------------------------------//
734template <class MeshType>
735template <std::size_t NSD>
736std::enable_if_t<3 == NSD, IndexSpace<3>>
737LocalGrid<MeshType>::boundaryIndexSpaceImpl( Ghost t1, Face<Dim::K> t2,
738 const std::array<int, 3>& off_ijk,
739 const int halo_width ) const
740{
741 return faceBoundaryIndexSpace( t1, t2, off_ijk, halo_width );
742}
743
744//---------------------------------------------------------------------------//
745template <class MeshType>
746template <std::size_t NSD>
747std::enable_if_t<3 == NSD, IndexSpace<3>>
748LocalGrid<MeshType>::indexSpaceImpl( Own t1, Edge<Dim::I> t2, Local t3 ) const
749{
750 return edgeIndexSpace( t1, t2, t3 );
751}
752
753//---------------------------------------------------------------------------//
754template <class MeshType>
755template <std::size_t NSD>
756std::enable_if_t<3 == NSD, IndexSpace<3>>
757LocalGrid<MeshType>::indexSpaceImpl( Ghost t1, Edge<Dim::I> t2, Local t3 ) const
758{
759 return edgeIndexSpace( t1, t2, t3 );
760}
761
762//---------------------------------------------------------------------------//
763template <class MeshType>
764template <std::size_t NSD>
765std::enable_if_t<3 == NSD, IndexSpace<3>>
766LocalGrid<MeshType>::indexSpaceImpl( Own t1, Edge<Dim::I> t2, Global t3 ) const
767{
768 return edgeIndexSpace( t1, t2, t3 );
769}
770
771//---------------------------------------------------------------------------//
772template <class MeshType>
773template <std::size_t NSD>
774std::enable_if_t<3 == NSD, IndexSpace<3>>
775LocalGrid<MeshType>::sharedIndexSpaceImpl( Own t1, Edge<Dim::I> t2,
776 const std::array<int, 3>& off_ijk,
777 const int halo_width ) const
778{
779 return edgeSharedIndexSpace( t1, t2, off_ijk, halo_width );
780}
781
782//---------------------------------------------------------------------------//
783template <class MeshType>
784template <std::size_t NSD>
785std::enable_if_t<3 == NSD, IndexSpace<3>>
786LocalGrid<MeshType>::sharedIndexSpaceImpl( Ghost t1, Edge<Dim::I> t2,
787 const std::array<int, 3>& off_ijk,
788 const int halo_width ) const
789{
790 return edgeSharedIndexSpace( t1, t2, off_ijk, halo_width );
791}
792
793//---------------------------------------------------------------------------//
794template <class MeshType>
795template <std::size_t NSD>
796std::enable_if_t<3 == NSD, IndexSpace<3>>
797LocalGrid<MeshType>::boundaryIndexSpaceImpl( Own t1, Edge<Dim::I> t2,
798 const std::array<int, 3>& off_ijk,
799 const int halo_width ) const
800{
801 return edgeBoundaryIndexSpace( t1, t2, off_ijk, halo_width );
802}
803
804//---------------------------------------------------------------------------//
805template <class MeshType>
806template <std::size_t NSD>
807std::enable_if_t<3 == NSD, IndexSpace<3>>
808LocalGrid<MeshType>::boundaryIndexSpaceImpl( Ghost t1, Edge<Dim::I> t2,
809 const std::array<int, 3>& off_ijk,
810 const int halo_width ) const
811{
812 return edgeBoundaryIndexSpace( t1, t2, off_ijk, halo_width );
813}
814
815//---------------------------------------------------------------------------//
816template <class MeshType>
817template <std::size_t NSD>
818std::enable_if_t<3 == NSD, IndexSpace<3>>
819LocalGrid<MeshType>::indexSpaceImpl( Own t1, Edge<Dim::J> t2, Local t3 ) const
820{
821 return edgeIndexSpace( t1, t2, t3 );
822}
823
824//---------------------------------------------------------------------------//
825template <class MeshType>
826template <std::size_t NSD>
827std::enable_if_t<3 == NSD, IndexSpace<3>>
828LocalGrid<MeshType>::indexSpaceImpl( Ghost t1, Edge<Dim::J> t2, Local t3 ) const
829{
830 return edgeIndexSpace( t1, t2, t3 );
831}
832
833//---------------------------------------------------------------------------//
834template <class MeshType>
835template <std::size_t NSD>
836std::enable_if_t<3 == NSD, IndexSpace<3>>
837LocalGrid<MeshType>::indexSpaceImpl( Own t1, Edge<Dim::J> t2, Global t3 ) const
838{
839 return edgeIndexSpace( t1, t2, t3 );
840}
841
842//---------------------------------------------------------------------------//
843template <class MeshType>
844template <std::size_t NSD>
845std::enable_if_t<3 == NSD, IndexSpace<3>>
846LocalGrid<MeshType>::sharedIndexSpaceImpl( Own t1, Edge<Dim::J> t2,
847 const std::array<int, 3>& off_ijk,
848 const int halo_width ) const
849{
850 return edgeSharedIndexSpace( t1, t2, off_ijk, halo_width );
851}
852
853//---------------------------------------------------------------------------//
854template <class MeshType>
855template <std::size_t NSD>
856std::enable_if_t<3 == NSD, IndexSpace<3>>
857LocalGrid<MeshType>::sharedIndexSpaceImpl( Ghost t1, Edge<Dim::J> t2,
858 const std::array<int, 3>& off_ijk,
859 const int halo_width ) const
860{
861 return edgeSharedIndexSpace( t1, t2, off_ijk, halo_width );
862}
863
864//---------------------------------------------------------------------------//
865template <class MeshType>
866template <std::size_t NSD>
867std::enable_if_t<3 == NSD, IndexSpace<3>>
868LocalGrid<MeshType>::boundaryIndexSpaceImpl( Own t1, Edge<Dim::J> t2,
869 const std::array<int, 3>& off_ijk,
870 const int halo_width ) const
871{
872 return edgeBoundaryIndexSpace( t1, t2, off_ijk, halo_width );
873}
874
875//---------------------------------------------------------------------------//
876template <class MeshType>
877template <std::size_t NSD>
878std::enable_if_t<3 == NSD, IndexSpace<3>>
879LocalGrid<MeshType>::boundaryIndexSpaceImpl( Ghost t1, Edge<Dim::J> t2,
880 const std::array<int, 3>& off_ijk,
881 const int halo_width ) const
882{
883 return edgeBoundaryIndexSpace( t1, t2, off_ijk, halo_width );
884}
885//---------------------------------------------------------------------------//
886template <class MeshType>
887template <std::size_t NSD>
888std::enable_if_t<3 == NSD, IndexSpace<3>>
889LocalGrid<MeshType>::indexSpaceImpl( Own t1, Edge<Dim::K> t2, Local t3 ) const
890{
891 return edgeIndexSpace( t1, t2, t3 );
892}
893
894//---------------------------------------------------------------------------//
895template <class MeshType>
896template <std::size_t NSD>
897std::enable_if_t<3 == NSD, IndexSpace<3>>
898LocalGrid<MeshType>::indexSpaceImpl( Ghost t1, Edge<Dim::K> t2, Local t3 ) const
899{
900 return edgeIndexSpace( t1, t2, t3 );
901}
902
903//---------------------------------------------------------------------------//
904template <class MeshType>
905template <std::size_t NSD>
906std::enable_if_t<3 == NSD, IndexSpace<3>>
907LocalGrid<MeshType>::indexSpaceImpl( Own t1, Edge<Dim::K> t2, Global t3 ) const
908{
909 return edgeIndexSpace( t1, t2, t3 );
910}
911
912//---------------------------------------------------------------------------//
913template <class MeshType>
914template <std::size_t NSD>
915std::enable_if_t<3 == NSD, IndexSpace<3>>
916LocalGrid<MeshType>::sharedIndexSpaceImpl( Own t1, Edge<Dim::K> t2,
917 const std::array<int, 3>& off_ijk,
918 const int halo_width ) const
919{
920 return edgeSharedIndexSpace( t1, t2, off_ijk, halo_width );
921}
922
923//---------------------------------------------------------------------------//
924template <class MeshType>
925template <std::size_t NSD>
926std::enable_if_t<3 == NSD, IndexSpace<3>>
927LocalGrid<MeshType>::sharedIndexSpaceImpl( Ghost t1, Edge<Dim::K> t2,
928 const std::array<int, 3>& off_ijk,
929 const int halo_width ) const
930{
931 return edgeSharedIndexSpace( t1, t2, off_ijk, halo_width );
932}
933
934//---------------------------------------------------------------------------//
935template <class MeshType>
936template <std::size_t NSD>
937std::enable_if_t<3 == NSD, IndexSpace<3>>
938LocalGrid<MeshType>::boundaryIndexSpaceImpl( Own t1, Edge<Dim::K> t2,
939 const std::array<int, 3>& off_ijk,
940 const int halo_width ) const
941{
942 return edgeBoundaryIndexSpace( t1, t2, off_ijk, halo_width );
943}
944
945//---------------------------------------------------------------------------//
946template <class MeshType>
947template <std::size_t NSD>
948std::enable_if_t<3 == NSD, IndexSpace<3>>
949LocalGrid<MeshType>::boundaryIndexSpaceImpl( Ghost t1, Edge<Dim::K> t2,
950 const std::array<int, 3>& off_ijk,
951 const int halo_width ) const
952{
953 return edgeBoundaryIndexSpace( t1, t2, off_ijk, halo_width );
954}
955
956//---------------------------------------------------------------------------//
957// Get the global index space of the owned entities.
958template <class MeshType>
959template <class EntityType>
960auto LocalGrid<MeshType>::globalIndexSpace( Own, EntityType ) const
962{
963 auto local_space = indexSpaceImpl( Own(), EntityType(), Local() );
964 std::array<long, num_space_dim> min;
965 std::array<long, num_space_dim> max;
966 for ( std::size_t d = 0; d < num_space_dim; ++d )
967 {
968 min[d] = _global_grid->globalOffset( d );
969 max[d] = min[d] + local_space.extent( d );
970 }
971
972 return IndexSpace<num_space_dim>( min, max );
973}
974
975//---------------------------------------------------------------------------//
976// Get the local index space of the owned Dir-direction faces.
977template <class MeshType>
978template <int Dir>
979auto LocalGrid<MeshType>::faceIndexSpace( Own, Face<Dir>, Local ) const
981{
982 static_assert( Dir < num_space_dim, "Spatial dimension out of bounds" );
983
984 // Compute the lower bound.
985 std::array<long, num_space_dim> min;
986 for ( std::size_t d = 0; d < num_space_dim; ++d )
987 min[d] = _halo_cell_width;
988
989 // Compute the upper bound.
990 std::array<long, num_space_dim> max;
991 for ( std::size_t d = 0; d < num_space_dim; ++d )
992 {
993 if ( Dir == d )
994 {
995 max[d] = ( _global_grid->isPeriodic( d ) ||
996 _global_grid->dimBlockId( d ) <
997 _global_grid->dimNumBlock( d ) - 1 )
998 ? min[d] + _global_grid->ownedNumCell( d )
999 : min[d] + _global_grid->ownedNumCell( d ) + 1;
1000 }
1001 else
1002 {
1003 max[d] = min[d] + _global_grid->ownedNumCell( d );
1004 }
1005 }
1006
1007 return IndexSpace<num_space_dim>( min, max );
1008}
1009
1010//---------------------------------------------------------------------------//
1011// Get the local index space of the owned and ghosted Dir-direction faces.
1012template <class MeshType>
1013template <int Dir>
1014auto LocalGrid<MeshType>::faceIndexSpace( Ghost, Face<Dir>, Local ) const
1016{
1017 static_assert( Dir < num_space_dim, "Spatial dimension out of bounds" );
1018
1019 // Compute the size.
1020 std::array<long, num_space_dim> size;
1021 for ( std::size_t d = 0; d < num_space_dim; ++d )
1022 {
1023 if ( Dir == d )
1024 {
1025 size[d] = totalNumCell( d ) + 1;
1026 }
1027 else
1028 {
1029 size[d] = totalNumCell( d );
1030 }
1031 }
1032
1034}
1035
1036//---------------------------------------------------------------------------//
1037// Get the global index space of the owned Dir-direction faces.
1038template <class MeshType>
1039template <int Dir>
1040auto LocalGrid<MeshType>::faceIndexSpace( Own t1, Face<Dir> t2, Global ) const
1042{
1043 static_assert( Dir < num_space_dim, "Spatial dimension out of bounds" );
1044 return globalIndexSpace( t1, t2 );
1045}
1046
1047//---------------------------------------------------------------------------//
1048// Given a relative set of indices of a neighbor get the set of local
1049// Dir-direction face indices we own that we share with that neighbor to use
1050// as ghosts.
1051template <class MeshType>
1052template <int Dir>
1053auto LocalGrid<MeshType>::faceSharedIndexSpace(
1054 Own, Face<Dir>, const std::array<int, num_space_dim>& off_ijk,
1055 const int halo_width ) const -> IndexSpace<num_space_dim>
1056{
1057 static_assert( Dir < num_space_dim, "Spatial dimension out of bounds" );
1058
1059 // Get the owned local index space.
1060 auto owned_space = indexSpaceImpl( Own(), Face<Dir>(), Local() );
1061
1062 auto min = getBound( owned_space, -1, off_ijk, 0, -halo_width );
1063 auto max = getBound<Dir>( owned_space, 1, off_ijk, halo_width + 1,
1064 halo_width, 0, 0 );
1065
1066 return IndexSpace<num_space_dim>( min, max );
1067}
1068
1069//---------------------------------------------------------------------------//
1070// Given a relative set of indices of a neighbor get set of local
1071// Dir-direction face indices owned by that neighbor that are shared with us
1072// to use as ghosts.
1073template <class MeshType>
1074template <int Dir>
1075auto LocalGrid<MeshType>::faceSharedIndexSpace(
1076 Ghost, Face<Dir>, const std::array<int, num_space_dim>& off_ijk,
1077 const int halo_width ) const -> IndexSpace<num_space_dim>
1078{
1079 static_assert( Dir < num_space_dim, "Spatial dimension out of bounds" );
1080
1081 // Get the owned local index space.
1082 auto owned_space = indexSpaceImpl( Own(), Face<Dir>(), Local() );
1083
1084 auto min = getBound( owned_space, -1, off_ijk, -halo_width, 0 );
1085 auto max = getBound<Dir>( owned_space, 1, off_ijk, 0, 0, halo_width + 1,
1086 halo_width );
1087
1088 return IndexSpace<num_space_dim>( min, max );
1089}
1090
1091//---------------------------------------------------------------------------//
1092// Given the relative offset of a boundary relative to this local grid's
1093// get the set of local Dir-direction face indices we own that we share
1094// with that boundary to use as ghosts.
1095template <class MeshType>
1096template <int Dir>
1097auto LocalGrid<MeshType>::faceBoundaryIndexSpace(
1098 Own, Face<Dir>, const std::array<int, num_space_dim>& off_ijk,
1099 const int halo_width ) const -> IndexSpace<num_space_dim>
1100{
1101 static_assert( Dir < num_space_dim, "Spatial dimension out of bounds" );
1102
1103 // Get the owned local index space.
1104 auto owned_space = indexSpaceImpl( Own(), Face<Dir>(), Local() );
1105
1106 auto min = getBound<Dir>( owned_space, -1, off_ijk, 0, 0, -halo_width - 1,
1107 -halo_width );
1108 auto max = getBound<Dir>( owned_space, 1, off_ijk, halo_width + 1,
1109 halo_width, 0, 0 );
1110
1111 return IndexSpace<num_space_dim>( min, max );
1112}
1113
1114//---------------------------------------------------------------------------//
1115// Given the relative offset of a boundary relative to this local grid's
1116// get the set of local Dir-direction face indices owned by that boundary
1117// that are shared with us to use as ghosts.
1118template <class MeshType>
1119template <int Dir>
1120auto LocalGrid<MeshType>::faceBoundaryIndexSpace(
1121 Ghost, Face<Dir>, const std::array<int, num_space_dim>& off_ijk,
1122 const int halo_width ) const -> IndexSpace<num_space_dim>
1123{
1124 static_assert( Dir < num_space_dim, "Spatial dimension out of bounds" );
1125
1126 // Get the owned local index space.
1127 auto owned_space = indexSpaceImpl( Own(), Face<Dir>(), Local() );
1128
1129 auto min = getBound( owned_space, -1, off_ijk, -halo_width, 0 );
1130 auto max = getBound( owned_space, 1, off_ijk, 0, halo_width );
1131
1132 return IndexSpace<num_space_dim>( min, max );
1133}
1134//---------------------------------------------------------------------------//
1135// Get the local index space of the owned Dir-direction edges.
1136template <class MeshType>
1137template <int Dir, std::size_t NSD>
1138std::enable_if_t<3 == NSD, IndexSpace<3>>
1139LocalGrid<MeshType>::edgeIndexSpace( Own, Edge<Dir>, Local ) const
1140{
1141 // Compute the lower bound.
1142 std::array<long, 3> min;
1143 for ( std::size_t d = 0; d < 3; ++d )
1144 min[d] = _halo_cell_width;
1145
1146 // Compute the upper bound.
1147 std::array<long, 3> max;
1148 for ( std::size_t d = 0; d < 3; ++d )
1149 {
1150 if ( Dir == d )
1151 {
1152 max[d] = min[d] + _global_grid->ownedNumCell( d );
1153 }
1154 else
1155 {
1156 max[d] = ( _global_grid->isPeriodic( d ) ||
1157 _global_grid->dimBlockId( d ) <
1158 _global_grid->dimNumBlock( d ) - 1 )
1159 ? min[d] + _global_grid->ownedNumCell( d )
1160 : min[d] + _global_grid->ownedNumCell( d ) + 1;
1161 }
1162 }
1163
1164 return IndexSpace<3>( min, max );
1165}
1166
1167//---------------------------------------------------------------------------//
1168// Get the local index space of the owned and ghosted Dir-direction edges.
1169template <class MeshType>
1170template <int Dir, std::size_t NSD>
1171std::enable_if_t<3 == NSD, IndexSpace<3>>
1172LocalGrid<MeshType>::edgeIndexSpace( Ghost, Edge<Dir>, Local ) const
1173{
1174 // Compute the size.
1175 std::array<long, 3> size;
1176 for ( std::size_t d = 0; d < 3; ++d )
1177 {
1178 if ( Dir == d )
1179 {
1180 size[d] = totalNumCell( d );
1181 }
1182 else
1183 {
1184 size[d] = totalNumCell( d ) + 1;
1185 }
1186 }
1187
1188 return IndexSpace<3>( size );
1189}
1190
1191//---------------------------------------------------------------------------//
1192// Get the global index space of the owned nodes.
1193template <class MeshType>
1194template <int Dir, std::size_t NSD>
1195std::enable_if_t<3 == NSD, IndexSpace<3>>
1196LocalGrid<MeshType>::edgeIndexSpace( Own t1, Edge<Dir> t2, Global ) const
1197{
1198 return globalIndexSpace( t1, t2 );
1199}
1200
1201//---------------------------------------------------------------------------//
1202// Given a relative set of indices of a neighbor get the set of local
1203// Dir-direction edge indices we own that we share with that neighbor to use
1204// as ghosts.
1205template <class MeshType>
1206template <int Dir, std::size_t NSD>
1207std::enable_if_t<3 == NSD, IndexSpace<3>>
1208LocalGrid<MeshType>::edgeSharedIndexSpace( Own, Edge<Dir>,
1209 const std::array<int, 3>& off_ijk,
1210 const int halo_width ) const
1211{
1212 // Get the owned local index space.
1213 auto owned_space = indexSpaceImpl( Own(), Edge<Dir>(), Local() );
1214
1215 auto min = getBound( owned_space, -1, off_ijk, 0, -halo_width );
1216 auto max = getBound<Dir>( owned_space, 1, off_ijk, halo_width,
1217 halo_width + 1, 0, 0 );
1218
1219 return IndexSpace<3>( min, max );
1220}
1221
1222//---------------------------------------------------------------------------//
1223// Given a relative set of indices of a neighbor get set of local
1224// Dir-direction edge indices owned by that neighbor that are shared with us
1225// to use as ghosts.
1226template <class MeshType>
1227template <int Dir, std::size_t NSD>
1228std::enable_if_t<3 == NSD, IndexSpace<3>>
1229LocalGrid<MeshType>::edgeSharedIndexSpace( Ghost, Edge<Dir>,
1230 const std::array<int, 3>& off_ijk,
1231 const int halo_width ) const
1232{
1233 // Get the owned local index space.
1234 auto owned_space = indexSpaceImpl( Own(), Edge<Dir>(), Local() );
1235
1236 auto min = getBound( owned_space, -1, off_ijk, -halo_width, 0 );
1237 auto max = getBound<Dir>( owned_space, 1, off_ijk, 0, 0, halo_width,
1238 halo_width + 1 );
1239
1240 return IndexSpace<3>( min, max );
1241}
1242
1243//---------------------------------------------------------------------------//
1244// Given the relative offset of a boundary relative to this local grid's
1245// get the set of local Dir-direction edge indices we own that we share
1246// with that boundary to use as ghosts.
1247template <class MeshType>
1248template <int Dir, std::size_t NSD>
1249std::enable_if_t<3 == NSD, IndexSpace<3>>
1250LocalGrid<MeshType>::edgeBoundaryIndexSpace( Own, Edge<Dir>,
1251 const std::array<int, 3>& off_ijk,
1252 const int halo_width ) const
1253{
1254 // Get the owned local index space.
1255 auto owned_space = indexSpaceImpl( Own(), Edge<Dir>(), Local() );
1256
1257 auto min = getBound<Dir>( owned_space, -1, off_ijk, 0, 0, -halo_width,
1258 -halo_width - 1 );
1259 auto max = getBound<Dir>( owned_space, 1, off_ijk, halo_width,
1260 halo_width + 1, 0, 0 );
1261
1262 return IndexSpace<3>( min, max );
1263}
1264
1265//---------------------------------------------------------------------------//
1266// Given the relative offset of a boundary relative to this local grid's
1267// get the set of local Dir-direction edge indices owned by that boundary
1268// that are shared with us to use as ghosts.
1269template <class MeshType>
1270template <int Dir, std::size_t NSD>
1271std::enable_if_t<3 == NSD, IndexSpace<3>>
1272LocalGrid<MeshType>::edgeBoundaryIndexSpace( Ghost, Edge<Dir>,
1273 const std::array<int, 3>& off_ijk,
1274 const int halo_width ) const
1275{
1276 // Get the owned local index space.
1277 auto owned_space = indexSpaceImpl( Own(), Edge<Dir>(), Local() );
1278
1279 auto min = getBound( owned_space, -1, off_ijk, -halo_width, 0 );
1280 auto max = getBound( owned_space, 1, off_ijk, 0, halo_width );
1281
1282 return IndexSpace<3>( min, max );
1283}
1285
1286//---------------------------------------------------------------------------//
1287
1288} // namespace Grid
1289} // namespace Cabana
1290
1291#endif // end CABANA_GRID_LOCALGRID_IMPL_HPP
Global logical grid.
Definition Cabana_Grid_GlobalGrid.hpp:39
int ownedNumCell(const int dim) const
Get the owned number of cells in a given dimension of this block.
Definition Cabana_Grid_GlobalGrid_impl.hpp:302
Structured index space.
Definition Cabana_Grid_IndexSpace.hpp:37
IndexSpace< num_space_dim > sharedIndexSpace(DecompositionTag t1, EntityType t2, const std::array< int, num_space_dim > &off_ijk, const int halo_width=-1) const
Given the relative offsets of a neighbor rank relative to this local grid's indices get the set of lo...
IndexSpace< num_space_dim > indexSpace(DecompositionTag t1, EntityType t2, IndexType t3) const
Given a decomposition type, entity type, and index type, get the contiguous set of indices that span ...
int haloCellWidth() const
Get the number of cells in the halo.
Definition Cabana_Grid_LocalGrid_impl.hpp:49
LocalGrid(const std::shared_ptr< GlobalGrid< MeshType > > &global_grid, const int halo_cell_width)
Constructor.
Definition Cabana_Grid_LocalGrid_impl.hpp:22
const GlobalGrid< MeshType > & globalGrid() const
Get the global grid that owns the local grid.
Definition Cabana_Grid_LocalGrid_impl.hpp:33
static constexpr std::size_t num_space_dim
Spatial dimension.
Definition Cabana_Grid_LocalGrid.hpp:45
int neighborRank(const std::array< int, num_space_dim > &off_ijk) const
Get the global index of a neighbor given neighbor rank offsets relative to this local grid.
Definition Cabana_Grid_LocalGrid_impl.hpp:66
int totalNumCell(const int d) const
Get the total number of local cells per dimension (owned + halo).
Definition Cabana_Grid_LocalGrid_impl.hpp:57
IndexSpace< num_space_dim > boundaryIndexSpace(DecompositionTag t1, EntityType t2, const std::array< int, num_space_dim > &off_ijk, const int halo_width=-1) const
Given the relative offsets of a boundary relative to this local grid's indices get the set of local e...
Core: particle data structures and algorithms.
Definition Cabana_AoSoA.hpp:36
auto size(SliceType slice, typename std::enable_if< is_slice< SliceType >::value, int >::type *=0)
Check slice size (differs from Kokkos View).
Definition Cabana_Slice.hpp:1012
Mesh cell tag.
Definition Cabana_Grid_Types.hpp:49
Mesh edge tag.
Definition Cabana_Grid_Types.hpp:95
Mesh face tag.
Definition Cabana_Grid_Types.hpp:64
Ghosted decomposition tag.
Definition Cabana_Grid_Types.hpp:197
Global index tag.
Definition Cabana_Grid_Types.hpp:215
Local index tag.
Definition Cabana_Grid_Types.hpp:208
Mesh node tag.
Definition Cabana_Grid_Types.hpp:56
Owned decomposition tag.
Definition Cabana_Grid_Types.hpp:190