Cabana 0.8.0-dev
 
Loading...
Searching...
No Matches
Cabana_Grid_GlobalMesh.hpp
Go to the documentation of this file.
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
16#ifndef CABANA_GRID_GLOBALMESH_HPP
17#define CABANA_GRID_GLOBALMESH_HPP
18
19#include <Cabana_Grid_Types.hpp>
20
21#include <array>
22#include <cmath>
23#include <limits>
24#include <memory>
25#include <stdexcept>
26#include <type_traits>
27#include <vector>
28
29namespace Cabana
30{
31namespace Grid
32{
33//---------------------------------------------------------------------------//
34// Forward declaration of global mesh.
35template <class MeshType>
36class GlobalMesh;
37
38//---------------------------------------------------------------------------//
47template <class MeshType>
49{
50 public:
52 using mesh_type = MeshType;
53
55 using scalar_type = typename mesh_type::scalar_type;
56
58 static constexpr std::size_t num_space_dim = mesh_type::num_space_dim;
59
62 const std::array<scalar_type, num_space_dim>& global_low_corner,
63 const std::array<scalar_type, num_space_dim>& global_high_corner,
64 const scalar_type cell_size )
65 : _global_low_corner( global_low_corner )
66 , _global_high_corner( global_high_corner )
67 {
68 // Check that the domain is evenly divisible by the cell size in each
69 // dimension within round-off error.
70 for ( std::size_t d = 0; d < num_space_dim; ++d )
71 {
72 _cell_size[d] = cell_size;
73 scalar_type ext = globalNumCell( d ) * _cell_size[d];
74 if ( std::abs( ext - extent( d ) ) >
75 scalar_type( 100.0 ) *
76 std::numeric_limits<scalar_type>::epsilon() )
77 throw std::logic_error(
78 "Extent not evenly divisible by uniform cell size" );
79 }
80 }
81
84 const std::array<scalar_type, num_space_dim>& global_low_corner,
85 const std::array<scalar_type, num_space_dim>& global_high_corner,
86 const std::array<scalar_type, num_space_dim>& cell_size )
87 : _global_low_corner( global_low_corner )
88 , _global_high_corner( global_high_corner )
89 , _cell_size( cell_size )
90 {
91 // Check that the domain is evenly divisible by the cell size in each
92 // dimension within round-off error.
93 for ( std::size_t d = 0; d < num_space_dim; ++d )
94 {
95 scalar_type ext = globalNumCell( d ) * _cell_size[d];
96 if ( std::abs( ext - extent( d ) ) >
97 scalar_type( 100.0 ) *
98 std::numeric_limits<scalar_type>::epsilon() )
99 throw std::logic_error(
100 "Extent not evenly divisible by uniform cell size" );
101 }
102 }
103
106 const std::array<scalar_type, num_space_dim>& global_low_corner,
107 const std::array<scalar_type, num_space_dim>& global_high_corner,
108 const std::array<int, num_space_dim>& global_num_cell )
109 : _global_low_corner( global_low_corner )
110 , _global_high_corner( global_high_corner )
111 {
112 // Compute the cell size in each dimension.
113 for ( std::size_t d = 0; d < num_space_dim; ++d )
114 _cell_size[d] = ( _global_high_corner[d] - _global_low_corner[d] ) /
115 global_num_cell[d];
116
117 // Check that the domain is evenly divisible by the cell size in each
118 // dimension within round-off error and that we got the expected
119 // number of cells.
120 for ( std::size_t d = 0; d < num_space_dim; ++d )
121 {
122 scalar_type ext = globalNumCell( d ) * _cell_size[d];
123 if ( std::abs( ext - extent( d ) ) >
124 scalar_type( 100.0 ) *
125 std::numeric_limits<scalar_type>::epsilon() )
126 throw std::logic_error(
127 "Extent not evenly divisible by uniform cell size" );
128 if ( globalNumCell( d ) != global_num_cell[d] )
129 throw std::logic_error( "Global number of cells mismatch" );
130 }
131 }
132
133 // GLOBAL MESH INTERFACE
134
137 scalar_type lowCorner( const std::size_t dim ) const
138 {
139 return _global_low_corner[dim];
140 }
141
144 scalar_type highCorner( const std::size_t dim ) const
145 {
146 return _global_high_corner[dim];
147 }
148
151 scalar_type extent( const std::size_t dim ) const
152 {
153 return highCorner( dim ) - lowCorner( dim );
154 }
155
158 int globalNumCell( const std::size_t dim ) const
159 {
160 return std::rint( extent( dim ) / _cell_size[dim] );
161 }
162
163 // UNIFORM MESH SPECIFIC
164
167 scalar_type cellSize( const std::size_t dim ) const
168 {
169 return _cell_size[dim];
170 }
171
172 private:
173 std::array<scalar_type, num_space_dim> _global_low_corner;
174 std::array<scalar_type, num_space_dim> _global_high_corner;
175 std::array<scalar_type, num_space_dim> _cell_size;
176};
177
188template <class Scalar, std::size_t NumSpaceDim>
189std::shared_ptr<GlobalMesh<UniformMesh<Scalar, NumSpaceDim>>>
191 const std::array<Scalar, NumSpaceDim>& global_low_corner,
192 const std::array<Scalar, NumSpaceDim>& global_high_corner,
193 const Scalar cell_size )
194{
195 return std::make_shared<GlobalMesh<UniformMesh<Scalar, NumSpaceDim>>>(
196 global_low_corner, global_high_corner, cell_size );
197}
198
209template <class Scalar, std::size_t NumSpaceDim>
210std::shared_ptr<GlobalMesh<UniformMesh<Scalar, NumSpaceDim>>>
212 const std::array<Scalar, NumSpaceDim>& global_low_corner,
213 const std::array<Scalar, NumSpaceDim>& global_high_corner,
214 const std::array<Scalar, NumSpaceDim>& cell_size )
215{
216 return std::make_shared<GlobalMesh<UniformMesh<Scalar, NumSpaceDim>>>(
217 global_low_corner, global_high_corner, cell_size );
218}
219
230template <class Scalar, std::size_t NumSpaceDim>
231std::shared_ptr<GlobalMesh<UniformMesh<Scalar, NumSpaceDim>>>
233 const std::array<Scalar, NumSpaceDim>& global_low_corner,
234 const std::array<Scalar, NumSpaceDim>& global_high_corner,
235 const std::array<int, NumSpaceDim>& global_num_cell )
236{
237 return std::make_shared<GlobalMesh<UniformMesh<Scalar, NumSpaceDim>>>(
238 global_low_corner, global_high_corner, global_num_cell );
239}
240
241//---------------------------------------------------------------------------//
252template <class Scalar, std::size_t NumSpaceDim>
253std::shared_ptr<GlobalMesh<SparseMesh<Scalar, NumSpaceDim>>>
255 const std::array<Scalar, NumSpaceDim>& global_low_corner,
256 const std::array<Scalar, NumSpaceDim>& global_high_corner,
257 const Scalar cell_size )
258{
259 return std::make_shared<GlobalMesh<SparseMesh<Scalar, NumSpaceDim>>>(
260 global_low_corner, global_high_corner, cell_size );
261}
262
273template <class Scalar, std::size_t NumSpaceDim>
274std::shared_ptr<GlobalMesh<SparseMesh<Scalar, NumSpaceDim>>>
276 const std::array<Scalar, NumSpaceDim>& global_low_corner,
277 const std::array<Scalar, NumSpaceDim>& global_high_corner,
278 const std::array<Scalar, NumSpaceDim>& cell_size )
279{
280 return std::make_shared<GlobalMesh<SparseMesh<Scalar, NumSpaceDim>>>(
281 global_low_corner, global_high_corner, cell_size );
282}
283
294template <class Scalar, std::size_t NumSpaceDim>
295std::shared_ptr<GlobalMesh<SparseMesh<Scalar, NumSpaceDim>>>
297 const std::array<Scalar, NumSpaceDim>& global_low_corner,
298 const std::array<Scalar, NumSpaceDim>& global_high_corner,
299 const std::array<int, NumSpaceDim>& global_num_cell )
300{
301 return std::make_shared<GlobalMesh<SparseMesh<Scalar, NumSpaceDim>>>(
302 global_low_corner, global_high_corner, global_num_cell );
303}
304
305//---------------------------------------------------------------------------//
315template <class Scalar>
316class GlobalMesh<NonUniformMesh<Scalar, 3>>
317{
318 public:
321
323 using scalar_type = Scalar;
324
326 static constexpr std::size_t num_space_dim = 3;
327
330 GlobalMesh( const std::vector<Scalar>& i_edges,
331 const std::vector<Scalar>& j_edges,
332 const std::vector<Scalar>& k_edges )
333 : _edges( { i_edges, j_edges, k_edges } )
334 {
335 }
336
337 // GLOBAL MESH INTERFACE
338
341 Scalar lowCorner( const std::size_t dim ) const
342 {
343 return _edges[dim].front();
344 }
345
348 Scalar highCorner( const std::size_t dim ) const
349 {
350 return _edges[dim].back();
351 }
352
355 Scalar extent( const std::size_t dim ) const
356 {
357 return highCorner( dim ) - lowCorner( dim );
358 }
359
362 int globalNumCell( const std::size_t dim ) const
363 {
364 return _edges[dim].size() - 1;
365 }
366
367 // NON-UNIFORM MESH SPECIFIC
368
371 const std::vector<Scalar>& nonUniformEdge( const std::size_t dim ) const
372 {
373 return _edges[dim];
374 }
375
376 private:
377 std::array<std::vector<Scalar>, 3> _edges;
378};
379
386template <class Scalar>
387std::shared_ptr<GlobalMesh<NonUniformMesh<Scalar, 3>>>
388createNonUniformGlobalMesh( const std::vector<Scalar>& i_edges,
389 const std::vector<Scalar>& j_edges,
390 const std::vector<Scalar>& k_edges )
391{
392 return std::make_shared<GlobalMesh<NonUniformMesh<Scalar, 3>>>(
393 i_edges, j_edges, k_edges );
394}
395
396//---------------------------------------------------------------------------//
406template <class Scalar>
407class GlobalMesh<NonUniformMesh<Scalar, 2>>
408{
409 public:
412
414 using scalar_type = Scalar;
415
417 static constexpr std::size_t num_space_dim = 2;
418
421 GlobalMesh( const std::vector<Scalar>& i_edges,
422 const std::vector<Scalar>& j_edges )
423 : _edges( { i_edges, j_edges } )
424 {
425 }
426
427 // GLOBAL MESH INTERFACE
428
431 Scalar lowCorner( const std::size_t dim ) const
432 {
433 return _edges[dim].front();
434 }
435
438 Scalar highCorner( const std::size_t dim ) const
439 {
440 return _edges[dim].back();
441 }
442
445 Scalar extent( const std::size_t dim ) const
446 {
447 return highCorner( dim ) - lowCorner( dim );
448 }
449
452 int globalNumCell( const std::size_t dim ) const
453 {
454 return _edges[dim].size() - 1;
455 }
456
457 // NON-UNIFORM MESH SPECIFIC
458
461 const std::vector<Scalar>& nonUniformEdge( const std::size_t dim ) const
462 {
463 return _edges[dim];
464 }
465
466 private:
467 std::array<std::vector<Scalar>, 2> _edges;
468};
469
476template <class Scalar>
477std::shared_ptr<GlobalMesh<NonUniformMesh<Scalar, 2>>>
478createNonUniformGlobalMesh( const std::vector<Scalar>& i_edges,
479 const std::vector<Scalar>& j_edges )
480{
481 return std::make_shared<GlobalMesh<NonUniformMesh<Scalar, 2>>>( i_edges,
482 j_edges );
483}
484
485//---------------------------------------------------------------------------//
486
487} // namespace Grid
488} // namespace Cabana
489
490#endif // end CABANA_GRID_GLOBALMESH_HPP
std::shared_ptr< GlobalMesh< SparseMesh< Scalar, NumSpaceDim > > > createSparseGlobalMesh(const std::array< Scalar, NumSpaceDim > &global_low_corner, const std::array< Scalar, NumSpaceDim > &global_high_corner, const Scalar cell_size)
Create sparse mesh with uniform cell size.
Definition Cabana_Grid_GlobalMesh.hpp:254
std::shared_ptr< GlobalMesh< NonUniformMesh< Scalar, 3 > > > createNonUniformGlobalMesh(const std::vector< Scalar > &i_edges, const std::vector< Scalar > &j_edges, const std::vector< Scalar > &k_edges)
Create a non-uniform 3D mesh.
Definition Cabana_Grid_GlobalMesh.hpp:388
std::shared_ptr< GlobalMesh< UniformMesh< Scalar, NumSpaceDim > > > createUniformGlobalMesh(const std::array< Scalar, NumSpaceDim > &global_low_corner, const std::array< Scalar, NumSpaceDim > &global_high_corner, const Scalar cell_size)
Create uniform mesh with uniform cell size.
Definition Cabana_Grid_GlobalMesh.hpp:190
Grid type tags.
NonUniformMesh< Scalar, 2 > mesh_type
Mesh type.
Definition Cabana_Grid_GlobalMesh.hpp:411
Scalar extent(const std::size_t dim) const
Get the extent of a given dimension.
Definition Cabana_Grid_GlobalMesh.hpp:445
Scalar lowCorner(const std::size_t dim) const
Get the global low corner of the mesh.
Definition Cabana_Grid_GlobalMesh.hpp:431
static constexpr std::size_t num_space_dim
Spatial dimension.
Definition Cabana_Grid_GlobalMesh.hpp:417
int globalNumCell(const std::size_t dim) const
Get the global number of cells in a given dimension.
Definition Cabana_Grid_GlobalMesh.hpp:452
Scalar highCorner(const std::size_t dim) const
Get the global high corner of the mesh.
Definition Cabana_Grid_GlobalMesh.hpp:438
Scalar scalar_type
Scalar type.
Definition Cabana_Grid_GlobalMesh.hpp:414
const std::vector< Scalar > & nonUniformEdge(const std::size_t dim) const
Get the edge array in a given dimension.
Definition Cabana_Grid_GlobalMesh.hpp:461
GlobalMesh(const std::vector< Scalar > &i_edges, const std::vector< Scalar > &j_edges)
2D constructor.
Definition Cabana_Grid_GlobalMesh.hpp:421
static constexpr std::size_t num_space_dim
Spatial dimension.
Definition Cabana_Grid_GlobalMesh.hpp:326
Scalar lowCorner(const std::size_t dim) const
Get the global low corner of the mesh.
Definition Cabana_Grid_GlobalMesh.hpp:341
NonUniformMesh< Scalar, 3 > mesh_type
Mesh type.
Definition Cabana_Grid_GlobalMesh.hpp:320
Scalar scalar_type
Scalar type.
Definition Cabana_Grid_GlobalMesh.hpp:323
int globalNumCell(const std::size_t dim) const
Get the global number of cells in a given dimension.
Definition Cabana_Grid_GlobalMesh.hpp:362
Scalar highCorner(const std::size_t dim) const
Get the global high corner of the mesh.
Definition Cabana_Grid_GlobalMesh.hpp:348
Scalar extent(const std::size_t dim) const
Get the extent of a given dimension.
Definition Cabana_Grid_GlobalMesh.hpp:355
GlobalMesh(const std::vector< Scalar > &i_edges, const std::vector< Scalar > &j_edges, const std::vector< Scalar > &k_edges)
3D constructor.
Definition Cabana_Grid_GlobalMesh.hpp:330
const std::vector< Scalar > & nonUniformEdge(const std::size_t dim) const
Get the edge array in a given dimension.
Definition Cabana_Grid_GlobalMesh.hpp:371
Global mesh partial specialization for uniform mesh.
Definition Cabana_Grid_GlobalMesh.hpp:49
scalar_type lowCorner(const std::size_t dim) const
Get the global low corner of the mesh.
Definition Cabana_Grid_GlobalMesh.hpp:137
static constexpr std::size_t num_space_dim
Spatial dimension.
Definition Cabana_Grid_GlobalMesh.hpp:58
GlobalMesh(const std::array< scalar_type, num_space_dim > &global_low_corner, const std::array< scalar_type, num_space_dim > &global_high_corner, const std::array< int, num_space_dim > &global_num_cell)
Number of global cells constructor.
Definition Cabana_Grid_GlobalMesh.hpp:105
scalar_type extent(const std::size_t dim) const
Get the extent of a given dimension.
Definition Cabana_Grid_GlobalMesh.hpp:151
scalar_type highCorner(const std::size_t dim) const
Get the global high corner of the mesh.
Definition Cabana_Grid_GlobalMesh.hpp:144
MeshType mesh_type
Mesh type.
Definition Cabana_Grid_GlobalMesh.hpp:52
GlobalMesh(const std::array< scalar_type, num_space_dim > &global_low_corner, const std::array< scalar_type, num_space_dim > &global_high_corner, const scalar_type cell_size)
Cell size constructor where all cell dimensions are the same.
Definition Cabana_Grid_GlobalMesh.hpp:61
scalar_type cellSize(const std::size_t dim) const
Get the uniform cell size in a given dimension.
Definition Cabana_Grid_GlobalMesh.hpp:167
GlobalMesh(const std::array< scalar_type, num_space_dim > &global_low_corner, const std::array< scalar_type, num_space_dim > &global_high_corner, const std::array< scalar_type, num_space_dim > &cell_size)
Cell size constructor - each cell dimension can be different.
Definition Cabana_Grid_GlobalMesh.hpp:83
typename mesh_type::scalar_type scalar_type
Scalar type.
Definition Cabana_Grid_GlobalMesh.hpp:55
int globalNumCell(const std::size_t dim) const
Get the global number of cells in a given dimension.
Definition Cabana_Grid_GlobalMesh.hpp:158
Core: particle data structures and algorithms.
Definition Cabana_AoSoA.hpp:36
Non-uniform mesh tag.
Definition Cabana_Grid_Types.hpp:240