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( "Impl: Only 1 or -1 allowed" );
306 }
307 // Upper neighbor.
308 else if ( 1 == off_ijk[d] )
309 {
310 minmax[d] = owned_space.max( d ) + upper_shift;
311 }
312 else
313 {
314 throw std::runtime_error( "Neighbor offset must be 1, 0, or -1" );
315 }
316 }
317 return minmax;
318}
319
320// Return the bound for a shared/boundary index space given an owned space.
321// Overload for face/edge with different range per dimension.
322template <class MeshType>
323template <int Dir, class OwnedIndexSpace>
324auto LocalGrid<MeshType>::getBound(
325 OwnedIndexSpace owned_space, const int upper_lower,
326 const std::array<int, num_space_dim>& off_ijk, const int lower_shift_dir,
327 const int lower_shift, const int upper_shift_dir,
328 const int upper_shift ) const
329{
330 // Compute the lower bound.
331 std::array<long, num_space_dim> minmax;
332 for ( std::size_t d = 0; d < num_space_dim; ++d )
333 {
334 // Lower neighbor.
335 if ( -1 == off_ijk[d] )
336 {
337 minmax[d] = ( Dir == d ) ? owned_space.min( d ) + lower_shift_dir
338 : owned_space.min( d ) + lower_shift;
339 }
340 // Middle neighbor.
341 else if ( 0 == off_ijk[d] )
342 {
343 if ( upper_lower < 0 )
344 minmax[d] = owned_space.min( d );
345 else if ( upper_lower > 0 )
346 minmax[d] = owned_space.max( d );
347 else
348 throw std::runtime_error( "Impl: Only 1 or -1 allowed" );
349 }
350 // Upper neighbor.
351 else if ( 1 == off_ijk[d] )
352 {
353 minmax[d] = ( Dir == d ) ? owned_space.max( d ) + upper_shift_dir
354 : owned_space.max( d ) + upper_shift;
355 }
356 else
357 {
358 throw std::runtime_error( "Neighbor offset must be 1, 0, or -1" );
359 }
360 }
361 return minmax;
362}
363
364//---------------------------------------------------------------------------//
365// Given a relative set of indices of a neighbor get the set of local cell
366// indices we own that we share with that neighbor to use as ghosts.
367template <class MeshType>
368auto LocalGrid<MeshType>::sharedIndexSpaceImpl(
369 Own, Cell, const std::array<int, num_space_dim>& off_ijk,
370 const int halo_width ) const -> IndexSpace<num_space_dim>
371{
372 // Get the owned local index space.
373 auto owned_space = indexSpaceImpl( Own(), Cell(), Local() );
374
375 auto min = getBound( owned_space, -1, off_ijk, 0, -halo_width );
376 auto max = getBound( owned_space, 1, off_ijk, halo_width, 0 );
377
378 return IndexSpace<num_space_dim>( min, max );
379}
380
381//---------------------------------------------------------------------------//
382// Given a relative set of indices of a neighbor get set of local cell
383// indices owned by that neighbor that are shared with us to use as
384// ghosts.
385template <class MeshType>
386auto LocalGrid<MeshType>::sharedIndexSpaceImpl(
387 Ghost, Cell, const std::array<int, num_space_dim>& off_ijk,
388 const int halo_width ) const -> IndexSpace<num_space_dim>
389{
390 // Get the owned local index space.
391 auto owned_space = indexSpaceImpl( Own(), Cell(), Local() );
392
393 auto min = getBound( owned_space, -1, off_ijk, -halo_width, 0 );
394 auto max = getBound( owned_space, 1, off_ijk, 0, halo_width );
395
396 return IndexSpace<num_space_dim>( min, max );
397}
398
399//---------------------------------------------------------------------------//
400// Given the relative offset of a boundary relative to this local grid's
401// get the set of local cell indices we own that we share with that boundary
402// to use as ghosts. This case is equivalent to sharedIndexSpaceImpl.
403template <class MeshType>
404auto LocalGrid<MeshType>::boundaryIndexSpaceImpl(
405 Own, Cell, const std::array<int, num_space_dim>& off_ijk,
406 const int halo_width ) const -> IndexSpace<num_space_dim>
407{
408 return sharedIndexSpaceImpl( Own(), Cell(), off_ijk, halo_width );
409}
410
411//---------------------------------------------------------------------------//
412// Given the relative offset of a boundary relative to this local grid's
413// get the set of local cell indices owned by that boundary that are shared
414// with us to use as ghosts. This case is equivalent to sharedIndexSpaceImpl.
415template <class MeshType>
416auto LocalGrid<MeshType>::boundaryIndexSpaceImpl(
417 Ghost, Cell, const std::array<int, num_space_dim>& off_ijk,
418 const int halo_width ) const -> IndexSpace<num_space_dim>
419{
420 return sharedIndexSpaceImpl( Ghost(), Cell(), off_ijk, halo_width );
421}
422
423//---------------------------------------------------------------------------//
424// Get the local index space of the owned nodes.
425template <class MeshType>
426auto LocalGrid<MeshType>::indexSpaceImpl( Own, Node, Local ) const
428{
429 // Compute the lower bound.
430 std::array<long, num_space_dim> min;
431 for ( std::size_t d = 0; d < num_space_dim; ++d )
432 min[d] = _halo_cell_width;
433
434 // Compute the upper bound. Resolve the shared node if the dimension is
435 // periodic.
436 std::array<long, num_space_dim> max;
437 for ( std::size_t d = 0; d < num_space_dim; ++d )
438 max[d] = ( _global_grid->isPeriodic( d ) ||
439 _global_grid->dimBlockId( d ) <
440 _global_grid->dimNumBlock( d ) - 1 )
441 ? min[d] + _global_grid->ownedNumCell( d )
442 : min[d] + _global_grid->ownedNumCell( d ) + 1;
443
444 return IndexSpace<num_space_dim>( min, max );
445}
446
447//---------------------------------------------------------------------------//
448// Get the local index space of the owned and ghosted nodes.
449template <class MeshType>
450auto LocalGrid<MeshType>::indexSpaceImpl( Ghost, Node, Local ) const
452{
453 // Compute the size.
454 std::array<long, num_space_dim> size;
455 for ( std::size_t d = 0; d < num_space_dim; ++d )
456 {
457 size[d] = totalNumCell( d ) + 1;
458 }
459
461}
462
463//---------------------------------------------------------------------------//
464// Get the global index space of the owned nodes.
465template <class MeshType>
466auto LocalGrid<MeshType>::indexSpaceImpl( Own t1, Node t2, Global ) const
468{
469 return globalIndexSpace( t1, t2 );
470}
471
472//---------------------------------------------------------------------------//
473// Given a relative set of indices of a neighbor get the set of local node
474// indices we own that we share with that neighbor to use as ghosts.
475template <class MeshType>
476auto LocalGrid<MeshType>::sharedIndexSpaceImpl(
477 Own, Node, const std::array<int, num_space_dim>& off_ijk,
478 const int halo_width ) const -> IndexSpace<num_space_dim>
479{
480 // Get the owned local index space.
481 auto owned_space = indexSpaceImpl( Own(), Node(), Local() );
482
483 auto min = getBound( owned_space, -1, off_ijk, 0, -halo_width );
484 auto max = getBound( owned_space, 1, off_ijk, halo_width + 1, 0 );
485
486 return IndexSpace<num_space_dim>( min, max );
487}
488
489//---------------------------------------------------------------------------//
490// Given a relative set of indices of a neighbor get set of local node
491// indices owned by that neighbor that are shared with us to use as
492// ghosts.
493template <class MeshType>
494auto LocalGrid<MeshType>::sharedIndexSpaceImpl(
495 Ghost, Node, const std::array<int, num_space_dim>& off_ijk,
496 const int halo_width ) const -> IndexSpace<num_space_dim>
497{
498 // Get the owned local index space.
499 auto owned_space = indexSpaceImpl( Own(), Node(), Local() );
500
501 auto min = getBound( owned_space, -1, off_ijk, -halo_width, 0 );
502 auto max = getBound( owned_space, 1, off_ijk, 0, halo_width + 1 );
503
504 return IndexSpace<num_space_dim>( min, max );
505}
506
507//---------------------------------------------------------------------------//
508// Given the relative offset of a boundary relative to this local grid's
509// get the set of local node indices we own that we share with that boundary
510// to use as ghosts.
511template <class MeshType>
512auto LocalGrid<MeshType>::boundaryIndexSpaceImpl(
513 Own, Node, const std::array<int, num_space_dim>& off_ijk,
514 const int halo_width ) const -> IndexSpace<num_space_dim>
515{
516 // Get the owned local index space.
517 auto owned_space = indexSpaceImpl( Own(), Node(), Local() );
518
519 auto min = getBound( owned_space, -1, off_ijk, 0, -halo_width - 1 );
520 auto max = getBound( owned_space, 1, off_ijk, halo_width + 1, 0 );
521
522 return IndexSpace<num_space_dim>( min, max );
523}
524
525//---------------------------------------------------------------------------//
526// Given the relative offset of a boundary relative to this local grid's
527// get the set of local node indices owned by that boundary that are shared
528// with us to use as ghosts.
529template <class MeshType>
530auto LocalGrid<MeshType>::boundaryIndexSpaceImpl(
531 Ghost, Node, const std::array<int, num_space_dim>& off_ijk,
532 const int halo_width ) const -> IndexSpace<num_space_dim>
533{
534 // Get the owned local index space.
535 auto owned_space = indexSpaceImpl( Own(), Node(), Local() );
536
537 auto min = getBound( owned_space, -1, off_ijk, -halo_width, 0 );
538 auto max = getBound( owned_space, 1, off_ijk, 0, halo_width );
539
540 return IndexSpace<num_space_dim>( min, max );
541}
542
543//---------------------------------------------------------------------------//
544template <class MeshType>
545auto LocalGrid<MeshType>::indexSpaceImpl( Own t1, Face<Dim::I> t2,
546 Local t3 ) const
548{
549 return faceIndexSpace( t1, t2, t3 );
550}
551
552//---------------------------------------------------------------------------//
553template <class MeshType>
554auto LocalGrid<MeshType>::indexSpaceImpl( Ghost t1, Face<Dim::I> t2,
555 Local t3 ) const
557{
558 return faceIndexSpace( t1, t2, t3 );
559}
560
561//---------------------------------------------------------------------------//
562template <class MeshType>
563auto LocalGrid<MeshType>::indexSpaceImpl( Own t1, Face<Dim::I> t2,
564 Global t3 ) const
566{
567 return faceIndexSpace( t1, t2, t3 );
568}
569
570//---------------------------------------------------------------------------//
571template <class MeshType>
572auto LocalGrid<MeshType>::sharedIndexSpaceImpl(
573 Own t1, Face<Dim::I> t2, const std::array<int, num_space_dim>& off_ijk,
574 const int halo_width ) const -> IndexSpace<num_space_dim>
575{
576 return faceSharedIndexSpace( t1, t2, off_ijk, halo_width );
577}
578
579//---------------------------------------------------------------------------//
580template <class MeshType>
581auto LocalGrid<MeshType>::sharedIndexSpaceImpl(
582 Ghost t1, Face<Dim::I> t2, const std::array<int, num_space_dim>& off_ijk,
583 const int halo_width ) const -> IndexSpace<num_space_dim>
584{
585 return faceSharedIndexSpace( t1, t2, off_ijk, halo_width );
586}
587
588//---------------------------------------------------------------------------//
589template <class MeshType>
590auto LocalGrid<MeshType>::boundaryIndexSpaceImpl(
591 Own t1, Face<Dim::I> t2, const std::array<int, num_space_dim>& off_ijk,
592 const int halo_width ) const -> IndexSpace<num_space_dim>
593{
594 return faceBoundaryIndexSpace( t1, t2, off_ijk, halo_width );
595}
596
597//---------------------------------------------------------------------------//
598template <class MeshType>
599auto LocalGrid<MeshType>::boundaryIndexSpaceImpl(
600 Ghost t1, Face<Dim::I> t2, const std::array<int, num_space_dim>& off_ijk,
601 const int halo_width ) const -> IndexSpace<num_space_dim>
602{
603 return faceBoundaryIndexSpace( t1, t2, off_ijk, halo_width );
604}
605
606//---------------------------------------------------------------------------//
607template <class MeshType>
608auto LocalGrid<MeshType>::indexSpaceImpl( Own t1, Face<Dim::J> t2,
609 Local t3 ) const
611{
612 return faceIndexSpace( t1, t2, t3 );
613}
614
615//---------------------------------------------------------------------------//
616template <class MeshType>
617auto LocalGrid<MeshType>::indexSpaceImpl( Ghost t1, Face<Dim::J> t2,
618 Local t3 ) const
620{
621 return faceIndexSpace( t1, t2, t3 );
622}
623
624//---------------------------------------------------------------------------//
625template <class MeshType>
626auto LocalGrid<MeshType>::indexSpaceImpl( Own t1, Face<Dim::J> t2,
627 Global t3 ) const
629{
630 return faceIndexSpace( t1, t2, t3 );
631}
632
633//---------------------------------------------------------------------------//
634template <class MeshType>
635auto LocalGrid<MeshType>::sharedIndexSpaceImpl(
636 Own t1, Face<Dim::J> t2, const std::array<int, num_space_dim>& off_ijk,
637 const int halo_width ) const -> IndexSpace<num_space_dim>
638{
639 return faceSharedIndexSpace( t1, t2, off_ijk, halo_width );
640}
641
642//---------------------------------------------------------------------------//
643template <class MeshType>
644auto LocalGrid<MeshType>::sharedIndexSpaceImpl(
645 Ghost t1, Face<Dim::J> t2, const std::array<int, num_space_dim>& off_ijk,
646 const int halo_width ) const -> IndexSpace<num_space_dim>
647{
648 return faceSharedIndexSpace( t1, t2, off_ijk, halo_width );
649}
650
651//---------------------------------------------------------------------------//
652template <class MeshType>
653auto LocalGrid<MeshType>::boundaryIndexSpaceImpl(
654 Own t1, Face<Dim::J> t2, const std::array<int, num_space_dim>& off_ijk,
655 const int halo_width ) const -> IndexSpace<num_space_dim>
656{
657 return faceBoundaryIndexSpace( t1, t2, off_ijk, halo_width );
658}
659
660//---------------------------------------------------------------------------//
661template <class MeshType>
662auto LocalGrid<MeshType>::boundaryIndexSpaceImpl(
663 Ghost t1, Face<Dim::J> t2, const std::array<int, num_space_dim>& off_ijk,
664 const int halo_width ) const -> IndexSpace<num_space_dim>
665{
666 return faceBoundaryIndexSpace( t1, t2, off_ijk, halo_width );
667}
668
669//---------------------------------------------------------------------------//
670template <class MeshType>
671template <std::size_t NSD>
672std::enable_if_t<3 == NSD, IndexSpace<3>>
673LocalGrid<MeshType>::indexSpaceImpl( Own t1, Face<Dim::K> t2, Local t3 ) const
674{
675 return faceIndexSpace( t1, t2, t3 );
676}
677
678//---------------------------------------------------------------------------//
679template <class MeshType>
680template <std::size_t NSD>
681std::enable_if_t<3 == NSD, IndexSpace<3>>
682LocalGrid<MeshType>::indexSpaceImpl( Ghost t1, Face<Dim::K> t2, Local t3 ) const
683{
684 return faceIndexSpace( t1, t2, t3 );
685}
686
687//---------------------------------------------------------------------------//
688template <class MeshType>
689template <std::size_t NSD>
690std::enable_if_t<3 == NSD, IndexSpace<3>>
691LocalGrid<MeshType>::indexSpaceImpl( Own t1, Face<Dim::K> t2, Global t3 ) const
692{
693 return faceIndexSpace( t1, t2, t3 );
694}
695
696//---------------------------------------------------------------------------//
697template <class MeshType>
698template <std::size_t NSD>
699std::enable_if_t<3 == NSD, IndexSpace<3>>
700LocalGrid<MeshType>::sharedIndexSpaceImpl( Own t1, Face<Dim::K> t2,
701 const std::array<int, 3>& off_ijk,
702 const int halo_width ) const
703{
704 return faceSharedIndexSpace( t1, t2, off_ijk, halo_width );
705}
706
707//---------------------------------------------------------------------------//
708template <class MeshType>
709template <std::size_t NSD>
710std::enable_if_t<3 == NSD, IndexSpace<3>>
711LocalGrid<MeshType>::sharedIndexSpaceImpl( Ghost t1, Face<Dim::K> t2,
712 const std::array<int, 3>& off_ijk,
713 const int halo_width ) const
714{
715 return faceSharedIndexSpace( t1, t2, off_ijk, halo_width );
716}
717
718//---------------------------------------------------------------------------//
719template <class MeshType>
720template <std::size_t NSD>
721std::enable_if_t<3 == NSD, IndexSpace<3>>
722LocalGrid<MeshType>::boundaryIndexSpaceImpl( Own t1, Face<Dim::K> t2,
723 const std::array<int, 3>& off_ijk,
724 const int halo_width ) const
725{
726 return faceBoundaryIndexSpace( t1, t2, off_ijk, halo_width );
727}
728
729//---------------------------------------------------------------------------//
730template <class MeshType>
731template <std::size_t NSD>
732std::enable_if_t<3 == NSD, IndexSpace<3>>
733LocalGrid<MeshType>::boundaryIndexSpaceImpl( Ghost t1, Face<Dim::K> t2,
734 const std::array<int, 3>& off_ijk,
735 const int halo_width ) const
736{
737 return faceBoundaryIndexSpace( t1, t2, off_ijk, halo_width );
738}
739
740//---------------------------------------------------------------------------//
741template <class MeshType>
742template <std::size_t NSD>
743std::enable_if_t<3 == NSD, IndexSpace<3>>
744LocalGrid<MeshType>::indexSpaceImpl( Own t1, Edge<Dim::I> t2, Local t3 ) const
745{
746 return edgeIndexSpace( t1, t2, t3 );
747}
748
749//---------------------------------------------------------------------------//
750template <class MeshType>
751template <std::size_t NSD>
752std::enable_if_t<3 == NSD, IndexSpace<3>>
753LocalGrid<MeshType>::indexSpaceImpl( Ghost t1, Edge<Dim::I> t2, Local t3 ) const
754{
755 return edgeIndexSpace( t1, t2, t3 );
756}
757
758//---------------------------------------------------------------------------//
759template <class MeshType>
760template <std::size_t NSD>
761std::enable_if_t<3 == NSD, IndexSpace<3>>
762LocalGrid<MeshType>::indexSpaceImpl( Own t1, Edge<Dim::I> t2, Global t3 ) const
763{
764 return edgeIndexSpace( t1, t2, t3 );
765}
766
767//---------------------------------------------------------------------------//
768template <class MeshType>
769template <std::size_t NSD>
770std::enable_if_t<3 == NSD, IndexSpace<3>>
771LocalGrid<MeshType>::sharedIndexSpaceImpl( Own t1, Edge<Dim::I> t2,
772 const std::array<int, 3>& off_ijk,
773 const int halo_width ) const
774{
775 return edgeSharedIndexSpace( t1, t2, off_ijk, halo_width );
776}
777
778//---------------------------------------------------------------------------//
779template <class MeshType>
780template <std::size_t NSD>
781std::enable_if_t<3 == NSD, IndexSpace<3>>
782LocalGrid<MeshType>::sharedIndexSpaceImpl( Ghost t1, Edge<Dim::I> t2,
783 const std::array<int, 3>& off_ijk,
784 const int halo_width ) const
785{
786 return edgeSharedIndexSpace( t1, t2, off_ijk, halo_width );
787}
788
789//---------------------------------------------------------------------------//
790template <class MeshType>
791template <std::size_t NSD>
792std::enable_if_t<3 == NSD, IndexSpace<3>>
793LocalGrid<MeshType>::boundaryIndexSpaceImpl( Own t1, Edge<Dim::I> t2,
794 const std::array<int, 3>& off_ijk,
795 const int halo_width ) const
796{
797 return edgeBoundaryIndexSpace( t1, t2, off_ijk, halo_width );
798}
799
800//---------------------------------------------------------------------------//
801template <class MeshType>
802template <std::size_t NSD>
803std::enable_if_t<3 == NSD, IndexSpace<3>>
804LocalGrid<MeshType>::boundaryIndexSpaceImpl( Ghost t1, Edge<Dim::I> t2,
805 const std::array<int, 3>& off_ijk,
806 const int halo_width ) const
807{
808 return edgeBoundaryIndexSpace( t1, t2, off_ijk, halo_width );
809}
810
811//---------------------------------------------------------------------------//
812template <class MeshType>
813template <std::size_t NSD>
814std::enable_if_t<3 == NSD, IndexSpace<3>>
815LocalGrid<MeshType>::indexSpaceImpl( Own t1, Edge<Dim::J> t2, Local t3 ) const
816{
817 return edgeIndexSpace( t1, t2, t3 );
818}
819
820//---------------------------------------------------------------------------//
821template <class MeshType>
822template <std::size_t NSD>
823std::enable_if_t<3 == NSD, IndexSpace<3>>
824LocalGrid<MeshType>::indexSpaceImpl( Ghost t1, Edge<Dim::J> t2, Local t3 ) const
825{
826 return edgeIndexSpace( t1, t2, t3 );
827}
828
829//---------------------------------------------------------------------------//
830template <class MeshType>
831template <std::size_t NSD>
832std::enable_if_t<3 == NSD, IndexSpace<3>>
833LocalGrid<MeshType>::indexSpaceImpl( Own t1, Edge<Dim::J> t2, Global t3 ) const
834{
835 return edgeIndexSpace( t1, t2, t3 );
836}
837
838//---------------------------------------------------------------------------//
839template <class MeshType>
840template <std::size_t NSD>
841std::enable_if_t<3 == NSD, IndexSpace<3>>
842LocalGrid<MeshType>::sharedIndexSpaceImpl( Own t1, Edge<Dim::J> t2,
843 const std::array<int, 3>& off_ijk,
844 const int halo_width ) const
845{
846 return edgeSharedIndexSpace( t1, t2, off_ijk, halo_width );
847}
848
849//---------------------------------------------------------------------------//
850template <class MeshType>
851template <std::size_t NSD>
852std::enable_if_t<3 == NSD, IndexSpace<3>>
853LocalGrid<MeshType>::sharedIndexSpaceImpl( Ghost t1, Edge<Dim::J> t2,
854 const std::array<int, 3>& off_ijk,
855 const int halo_width ) const
856{
857 return edgeSharedIndexSpace( t1, t2, off_ijk, halo_width );
858}
859
860//---------------------------------------------------------------------------//
861template <class MeshType>
862template <std::size_t NSD>
863std::enable_if_t<3 == NSD, IndexSpace<3>>
864LocalGrid<MeshType>::boundaryIndexSpaceImpl( Own t1, Edge<Dim::J> t2,
865 const std::array<int, 3>& off_ijk,
866 const int halo_width ) const
867{
868 return edgeBoundaryIndexSpace( t1, t2, off_ijk, halo_width );
869}
870
871//---------------------------------------------------------------------------//
872template <class MeshType>
873template <std::size_t NSD>
874std::enable_if_t<3 == NSD, IndexSpace<3>>
875LocalGrid<MeshType>::boundaryIndexSpaceImpl( Ghost t1, Edge<Dim::J> t2,
876 const std::array<int, 3>& off_ijk,
877 const int halo_width ) const
878{
879 return edgeBoundaryIndexSpace( t1, t2, off_ijk, halo_width );
880}
881//---------------------------------------------------------------------------//
882template <class MeshType>
883template <std::size_t NSD>
884std::enable_if_t<3 == NSD, IndexSpace<3>>
885LocalGrid<MeshType>::indexSpaceImpl( Own t1, Edge<Dim::K> t2, Local t3 ) const
886{
887 return edgeIndexSpace( t1, t2, t3 );
888}
889
890//---------------------------------------------------------------------------//
891template <class MeshType>
892template <std::size_t NSD>
893std::enable_if_t<3 == NSD, IndexSpace<3>>
894LocalGrid<MeshType>::indexSpaceImpl( Ghost t1, Edge<Dim::K> t2, Local t3 ) const
895{
896 return edgeIndexSpace( t1, t2, t3 );
897}
898
899//---------------------------------------------------------------------------//
900template <class MeshType>
901template <std::size_t NSD>
902std::enable_if_t<3 == NSD, IndexSpace<3>>
903LocalGrid<MeshType>::indexSpaceImpl( Own t1, Edge<Dim::K> t2, Global t3 ) const
904{
905 return edgeIndexSpace( t1, t2, t3 );
906}
907
908//---------------------------------------------------------------------------//
909template <class MeshType>
910template <std::size_t NSD>
911std::enable_if_t<3 == NSD, IndexSpace<3>>
912LocalGrid<MeshType>::sharedIndexSpaceImpl( Own t1, Edge<Dim::K> t2,
913 const std::array<int, 3>& off_ijk,
914 const int halo_width ) const
915{
916 return edgeSharedIndexSpace( t1, t2, off_ijk, halo_width );
917}
918
919//---------------------------------------------------------------------------//
920template <class MeshType>
921template <std::size_t NSD>
922std::enable_if_t<3 == NSD, IndexSpace<3>>
923LocalGrid<MeshType>::sharedIndexSpaceImpl( Ghost t1, Edge<Dim::K> t2,
924 const std::array<int, 3>& off_ijk,
925 const int halo_width ) const
926{
927 return edgeSharedIndexSpace( t1, t2, off_ijk, halo_width );
928}
929
930//---------------------------------------------------------------------------//
931template <class MeshType>
932template <std::size_t NSD>
933std::enable_if_t<3 == NSD, IndexSpace<3>>
934LocalGrid<MeshType>::boundaryIndexSpaceImpl( Own t1, Edge<Dim::K> t2,
935 const std::array<int, 3>& off_ijk,
936 const int halo_width ) const
937{
938 return edgeBoundaryIndexSpace( t1, t2, off_ijk, halo_width );
939}
940
941//---------------------------------------------------------------------------//
942template <class MeshType>
943template <std::size_t NSD>
944std::enable_if_t<3 == NSD, IndexSpace<3>>
945LocalGrid<MeshType>::boundaryIndexSpaceImpl( Ghost t1, Edge<Dim::K> t2,
946 const std::array<int, 3>& off_ijk,
947 const int halo_width ) const
948{
949 return edgeBoundaryIndexSpace( t1, t2, off_ijk, halo_width );
950}
951
952//---------------------------------------------------------------------------//
953// Get the global index space of the owned entities.
954template <class MeshType>
955template <class EntityType>
956auto LocalGrid<MeshType>::globalIndexSpace( Own, EntityType ) const
958{
959 auto local_space = indexSpaceImpl( Own(), EntityType(), Local() );
960 std::array<long, num_space_dim> min;
961 std::array<long, num_space_dim> max;
962 for ( std::size_t d = 0; d < num_space_dim; ++d )
963 {
964 min[d] = _global_grid->globalOffset( d );
965 max[d] = min[d] + local_space.extent( d );
966 }
967
968 return IndexSpace<num_space_dim>( min, max );
969}
970
971//---------------------------------------------------------------------------//
972// Get the local index space of the owned Dir-direction faces.
973template <class MeshType>
974template <int Dir>
975auto LocalGrid<MeshType>::faceIndexSpace( Own, Face<Dir>, Local ) const
977{
978 static_assert( Dir < num_space_dim, "Spatial dimension out of bounds" );
979
980 // Compute the lower bound.
981 std::array<long, num_space_dim> min;
982 for ( std::size_t d = 0; d < num_space_dim; ++d )
983 min[d] = _halo_cell_width;
984
985 // Compute the upper bound.
986 std::array<long, num_space_dim> max;
987 for ( std::size_t d = 0; d < num_space_dim; ++d )
988 {
989 if ( Dir == d )
990 {
991 max[d] = ( _global_grid->isPeriodic( d ) ||
992 _global_grid->dimBlockId( d ) <
993 _global_grid->dimNumBlock( d ) - 1 )
994 ? min[d] + _global_grid->ownedNumCell( d )
995 : min[d] + _global_grid->ownedNumCell( d ) + 1;
996 }
997 else
998 {
999 max[d] = min[d] + _global_grid->ownedNumCell( d );
1000 }
1001 }
1002
1003 return IndexSpace<num_space_dim>( min, max );
1004}
1005
1006//---------------------------------------------------------------------------//
1007// Get the local index space of the owned and ghosted Dir-direction faces.
1008template <class MeshType>
1009template <int Dir>
1010auto LocalGrid<MeshType>::faceIndexSpace( Ghost, Face<Dir>, Local ) const
1012{
1013 static_assert( Dir < num_space_dim, "Spatial dimension out of bounds" );
1014
1015 // Compute the size.
1016 std::array<long, num_space_dim> size;
1017 for ( std::size_t d = 0; d < num_space_dim; ++d )
1018 {
1019 if ( Dir == d )
1020 {
1021 size[d] = totalNumCell( d ) + 1;
1022 }
1023 else
1024 {
1025 size[d] = totalNumCell( d );
1026 }
1027 }
1028
1030}
1031
1032//---------------------------------------------------------------------------//
1033// Get the global index space of the owned Dir-direction faces.
1034template <class MeshType>
1035template <int Dir>
1036auto LocalGrid<MeshType>::faceIndexSpace( Own t1, Face<Dir> t2, Global ) const
1038{
1039 static_assert( Dir < num_space_dim, "Spatial dimension out of bounds" );
1040 return globalIndexSpace( t1, t2 );
1041}
1042
1043//---------------------------------------------------------------------------//
1044// Given a relative set of indices of a neighbor get the set of local
1045// Dir-direction face indices we own that we share with that neighbor to use
1046// as ghosts.
1047template <class MeshType>
1048template <int Dir>
1049auto LocalGrid<MeshType>::faceSharedIndexSpace(
1050 Own, Face<Dir>, const std::array<int, num_space_dim>& off_ijk,
1051 const int halo_width ) const -> IndexSpace<num_space_dim>
1052{
1053 static_assert( Dir < num_space_dim, "Spatial dimension out of bounds" );
1054
1055 // Get the owned local index space.
1056 auto owned_space = indexSpaceImpl( Own(), Face<Dir>(), Local() );
1057
1058 auto min = getBound( owned_space, -1, off_ijk, 0, -halo_width );
1059 auto max = getBound<Dir>( owned_space, 1, off_ijk, halo_width + 1,
1060 halo_width, 0, 0 );
1061
1062 return IndexSpace<num_space_dim>( min, max );
1063}
1064
1065//---------------------------------------------------------------------------//
1066// Given a relative set of indices of a neighbor get set of local
1067// Dir-direction face indices owned by that neighbor that are shared with us
1068// to use as ghosts.
1069template <class MeshType>
1070template <int Dir>
1071auto LocalGrid<MeshType>::faceSharedIndexSpace(
1072 Ghost, Face<Dir>, const std::array<int, num_space_dim>& off_ijk,
1073 const int halo_width ) const -> IndexSpace<num_space_dim>
1074{
1075 static_assert( Dir < num_space_dim, "Spatial dimension out of bounds" );
1076
1077 // Get the owned local index space.
1078 auto owned_space = indexSpaceImpl( Own(), Face<Dir>(), Local() );
1079
1080 auto min = getBound( owned_space, -1, off_ijk, -halo_width, 0 );
1081 auto max = getBound<Dir>( owned_space, 1, off_ijk, 0, 0, halo_width + 1,
1082 halo_width );
1083
1084 return IndexSpace<num_space_dim>( min, max );
1085}
1086
1087//---------------------------------------------------------------------------//
1088// Given the relative offset of a boundary relative to this local grid's
1089// get the set of local Dir-direction face indices we own that we share
1090// with that boundary to use as ghosts.
1091template <class MeshType>
1092template <int Dir>
1093auto LocalGrid<MeshType>::faceBoundaryIndexSpace(
1094 Own, Face<Dir>, const std::array<int, num_space_dim>& off_ijk,
1095 const int halo_width ) const -> IndexSpace<num_space_dim>
1096{
1097 static_assert( Dir < num_space_dim, "Spatial dimension out of bounds" );
1098
1099 // Get the owned local index space.
1100 auto owned_space = indexSpaceImpl( Own(), Face<Dir>(), Local() );
1101
1102 auto min = getBound<Dir>( owned_space, -1, off_ijk, 0, 0, -halo_width - 1,
1103 -halo_width );
1104 auto max = getBound<Dir>( owned_space, 1, off_ijk, halo_width + 1,
1105 halo_width, 0, 0 );
1106
1107 return IndexSpace<num_space_dim>( min, max );
1108}
1109
1110//---------------------------------------------------------------------------//
1111// Given the relative offset of a boundary relative to this local grid's
1112// get the set of local Dir-direction face indices owned by that boundary
1113// that are shared with us to use as ghosts.
1114template <class MeshType>
1115template <int Dir>
1116auto LocalGrid<MeshType>::faceBoundaryIndexSpace(
1117 Ghost, Face<Dir>, const std::array<int, num_space_dim>& off_ijk,
1118 const int halo_width ) const -> IndexSpace<num_space_dim>
1119{
1120 static_assert( Dir < num_space_dim, "Spatial dimension out of bounds" );
1121
1122 // Get the owned local index space.
1123 auto owned_space = indexSpaceImpl( Own(), Face<Dir>(), Local() );
1124
1125 auto min = getBound( owned_space, -1, off_ijk, -halo_width, 0 );
1126 auto max = getBound( owned_space, 1, off_ijk, 0, halo_width );
1127
1128 return IndexSpace<num_space_dim>( min, max );
1129}
1130//---------------------------------------------------------------------------//
1131// Get the local index space of the owned Dir-direction edges.
1132template <class MeshType>
1133template <int Dir, std::size_t NSD>
1134std::enable_if_t<3 == NSD, IndexSpace<3>>
1135LocalGrid<MeshType>::edgeIndexSpace( Own, Edge<Dir>, Local ) const
1136{
1137 // Compute the lower bound.
1138 std::array<long, 3> min;
1139 for ( std::size_t d = 0; d < 3; ++d )
1140 min[d] = _halo_cell_width;
1141
1142 // Compute the upper bound.
1143 std::array<long, 3> max;
1144 for ( std::size_t d = 0; d < 3; ++d )
1145 {
1146 if ( Dir == d )
1147 {
1148 max[d] = min[d] + _global_grid->ownedNumCell( d );
1149 }
1150 else
1151 {
1152 max[d] = ( _global_grid->isPeriodic( d ) ||
1153 _global_grid->dimBlockId( d ) <
1154 _global_grid->dimNumBlock( d ) - 1 )
1155 ? min[d] + _global_grid->ownedNumCell( d )
1156 : min[d] + _global_grid->ownedNumCell( d ) + 1;
1157 }
1158 }
1159
1160 return IndexSpace<3>( min, max );
1161}
1162
1163//---------------------------------------------------------------------------//
1164// Get the local index space of the owned and ghosted Dir-direction edges.
1165template <class MeshType>
1166template <int Dir, std::size_t NSD>
1167std::enable_if_t<3 == NSD, IndexSpace<3>>
1168LocalGrid<MeshType>::edgeIndexSpace( Ghost, Edge<Dir>, Local ) const
1169{
1170 // Compute the size.
1171 std::array<long, 3> size;
1172 for ( std::size_t d = 0; d < 3; ++d )
1173 {
1174 if ( Dir == d )
1175 {
1176 size[d] = totalNumCell( d );
1177 }
1178 else
1179 {
1180 size[d] = totalNumCell( d ) + 1;
1181 }
1182 }
1183
1184 return IndexSpace<3>( size );
1185}
1186
1187//---------------------------------------------------------------------------//
1188// Get the global index space of the owned nodes.
1189template <class MeshType>
1190template <int Dir, std::size_t NSD>
1191std::enable_if_t<3 == NSD, IndexSpace<3>>
1192LocalGrid<MeshType>::edgeIndexSpace( Own t1, Edge<Dir> t2, Global ) const
1193{
1194 return globalIndexSpace( t1, t2 );
1195}
1196
1197//---------------------------------------------------------------------------//
1198// Given a relative set of indices of a neighbor get the set of local
1199// Dir-direction edge indices we own that we share with that neighbor to use
1200// as ghosts.
1201template <class MeshType>
1202template <int Dir, std::size_t NSD>
1203std::enable_if_t<3 == NSD, IndexSpace<3>>
1204LocalGrid<MeshType>::edgeSharedIndexSpace( Own, Edge<Dir>,
1205 const std::array<int, 3>& off_ijk,
1206 const int halo_width ) const
1207{
1208 // Get the owned local index space.
1209 auto owned_space = indexSpaceImpl( Own(), Edge<Dir>(), Local() );
1210
1211 auto min = getBound( owned_space, -1, off_ijk, 0, -halo_width );
1212 auto max = getBound<Dir>( owned_space, 1, off_ijk, halo_width,
1213 halo_width + 1, 0, 0 );
1214
1215 return IndexSpace<3>( min, max );
1216}
1217
1218//---------------------------------------------------------------------------//
1219// Given a relative set of indices of a neighbor get set of local
1220// Dir-direction edge indices owned by that neighbor that are shared with us
1221// to use as ghosts.
1222template <class MeshType>
1223template <int Dir, std::size_t NSD>
1224std::enable_if_t<3 == NSD, IndexSpace<3>>
1225LocalGrid<MeshType>::edgeSharedIndexSpace( Ghost, Edge<Dir>,
1226 const std::array<int, 3>& off_ijk,
1227 const int halo_width ) const
1228{
1229 // Get the owned local index space.
1230 auto owned_space = indexSpaceImpl( Own(), Edge<Dir>(), Local() );
1231
1232 auto min = getBound( owned_space, -1, off_ijk, -halo_width, 0 );
1233 auto max = getBound<Dir>( owned_space, 1, off_ijk, 0, 0, halo_width,
1234 halo_width + 1 );
1235
1236 return IndexSpace<3>( min, max );
1237}
1238
1239//---------------------------------------------------------------------------//
1240// Given the relative offset of a boundary relative to this local grid's
1241// get the set of local Dir-direction edge indices we own that we share
1242// with that boundary to use as ghosts.
1243template <class MeshType>
1244template <int Dir, std::size_t NSD>
1245std::enable_if_t<3 == NSD, IndexSpace<3>>
1246LocalGrid<MeshType>::edgeBoundaryIndexSpace( Own, Edge<Dir>,
1247 const std::array<int, 3>& off_ijk,
1248 const int halo_width ) const
1249{
1250 // Get the owned local index space.
1251 auto owned_space = indexSpaceImpl( Own(), Edge<Dir>(), Local() );
1252
1253 auto min = getBound<Dir>( owned_space, -1, off_ijk, 0, 0, -halo_width,
1254 -halo_width - 1 );
1255 auto max = getBound<Dir>( owned_space, 1, off_ijk, halo_width,
1256 halo_width + 1, 0, 0 );
1257
1258 return IndexSpace<3>( min, max );
1259}
1260
1261//---------------------------------------------------------------------------//
1262// Given the relative offset of a boundary relative to this local grid's
1263// get the set of local Dir-direction edge indices owned by that boundary
1264// that are shared with us to use as ghosts.
1265template <class MeshType>
1266template <int Dir, std::size_t NSD>
1267std::enable_if_t<3 == NSD, IndexSpace<3>>
1268LocalGrid<MeshType>::edgeBoundaryIndexSpace( Ghost, Edge<Dir>,
1269 const std::array<int, 3>& off_ijk,
1270 const int halo_width ) const
1271{
1272 // Get the owned local index space.
1273 auto owned_space = indexSpaceImpl( Own(), Edge<Dir>(), Local() );
1274
1275 auto min = getBound( owned_space, -1, off_ijk, -halo_width, 0 );
1276 auto max = getBound( owned_space, 1, off_ijk, 0, halo_width );
1277
1278 return IndexSpace<3>( min, max );
1279}
1281
1282//---------------------------------------------------------------------------//
1283
1284} // namespace Grid
1285} // namespace Cabana
1286
1287#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