SpECTRE  v2021.11.01
domain::ExpandOverBlocks< T, Dim > Struct Template Reference

Produce a distribution of type T over all blocks and dimensions in the domain, based on values T of variable isotropy and homogeneity. More...

#include <ExpandOverBlocks.hpp>

Public Member Functions

 ExpandOverBlocks (size_t num_blocks)
 
 ExpandOverBlocks (std::vector< std::string > block_names, std::unordered_map< std::string, std::unordered_set< std::string > > block_groups={})
 
std::vector< std::array< T, Dim > > operator() (const T &value) const
 Repeat over all blocks and dimensions (isotropic and homogeneous)
 
std::vector< std::array< T, Dim > > operator() (const std::array< T, Dim > &value) const
 Repeat over all blocks (homogeneous)
 
std::vector< std::array< T, Dim > > operator() (std::vector< std::array< T, Dim > > value) const
 Only check if the size matches the number of blocks, throwing a std::length_error if it doesn't.
 
std::vector< std::array< T, Dim > > operator() (const std::unordered_map< std::string, std::array< T, Dim > > &value) const
 Map block names, or names of block groups, to values. The map must cover all blocks once the groups are expanded. To use this option you must pass the list of block names and groups to the constructor. Here's an example: More...
 

Detailed Description

template<typename T, size_t Dim>
struct domain::ExpandOverBlocks< T, Dim >

Produce a distribution of type T over all blocks and dimensions in the domain, based on values T of variable isotropy and homogeneity.

This class is useful to option-create values for e.g. the initial refinement level or initial number of grid points for domain creators. It can be used with std::visit and a std::variant with (a subset of) these types:

  • T: Repeat over all blocks and dimensions (isotropic and homogeneous).
  • std::array<T, Dim>: Repeat over all blocks (homogeneous).
  • std::vector<std::array<T, Dim>>>: Only check if the size matches the number of blocks, throwing a std::length_error if it doesn't.
  • std::unordered_map<std::string, std::array<T, Dim>>: Map block names, or names of block groups, to values. The map must cover all blocks once the groups are expanded. To use this option you must pass the list of block names and groups to the constructor.

Note that the call-operators throw when they encounter errors, such as mismatches in the number of blocks. The exceptions can be used to output user-facing error messages in an option-parsing context.

Here's an example for using this class:

static constexpr size_t Dim = 3;
const size_t num_blocks = 3;
// This is an example for a variant that represents the distribution of
// initial refinement levels, which might be parsed from options:
using InitialRefinementOptionType =
// In this example the user specified a single number:
const InitialRefinementOptionType initial_refinement_from_options{
size_t{2}};
try {
// Invoke `ExpandOverBlocks`:
const auto initial_refinement =
std::visit(ExpandOverBlocks<size_t, Dim>{num_blocks},
initial_refinement_from_options);
// Since a single number was specified, we expect the vector over blocks
// is homogeneously and isotropically filled with that number:
std::vector<std::array<size_t, Dim>> expected_initial_refinement{
num_blocks, {2, 2, 2}};
CHECK(initial_refinement == expected_initial_refinement);
} catch (const std::length_error& error) {
// This would be a `PARSE_ERROR` in an option-parsing context
ERROR("Invalid 'InitialRefinement': " << error.what());
}
#define ERROR(m)
prints an error message to the standard error stream and aborts the program.
Definition: Error.hpp:37

Here's an example using block names and groups:

static constexpr size_t Dim = 2;
// In this example we name the blocks, representing a cubed-sphere domain:
const std::vector<std::string> block_names{"InnerCube", "East", "North",
"West", "South"};
// The blocks can also be grouped:
block_groups{{"Wedges", {"East", "North", "West", "South"}}};
// Now we can expand values over blocks by giving their names. This can also
// be used with a std::variant like in the other example.
ExpandOverBlocks<size_t, Dim> expand{block_names, block_groups};
CHECK(expand({{"West", {{3, 4}}},
{"InnerCube", {{2, 3}}},
{"South", {{3, 4}}},
{"North", {{5, 6}}},
{"East", {{1, 2}}}}) ==
{{2, 3}}, {{1, 2}}, {{5, 6}}, {{3, 4}}, {{3, 4}}});
// Instead of naming all blocks individually we can also name groups:
CHECK(expand({{"InnerCube", {{2, 3}}}, {"Wedges", {{3, 4}}}}) ==
{{2, 3}}, {{3, 4}}, {{3, 4}}, {{3, 4}}, {{3, 4}}});
Template Parameters
TThe type distributed over the domain
DimThe number of spatial dimensions

Member Function Documentation

◆ operator()()

template<typename T , size_t Dim>
std::vector< std::array< T, Dim > > domain::ExpandOverBlocks< T, Dim >::operator() ( const std::unordered_map< std::string, std::array< T, Dim > > &  value) const

Map block names, or names of block groups, to values. The map must cover all blocks once the groups are expanded. To use this option you must pass the list of block names and groups to the constructor. Here's an example:

static constexpr size_t Dim = 2;
// In this example we name the blocks, representing a cubed-sphere domain:
const std::vector<std::string> block_names{"InnerCube", "East", "North",
"West", "South"};
// The blocks can also be grouped:
block_groups{{"Wedges", {"East", "North", "West", "South"}}};
// Now we can expand values over blocks by giving their names. This can also
// be used with a std::variant like in the other example.
ExpandOverBlocks<size_t, Dim> expand{block_names, block_groups};
CHECK(expand({{"West", {{3, 4}}},
{"InnerCube", {{2, 3}}},
{"South", {{3, 4}}},
{"North", {{5, 6}}},
{"East", {{1, 2}}}}) ==
{{2, 3}}, {{1, 2}}, {{5, 6}}, {{3, 4}}, {{3, 4}}});
// Instead of naming all blocks individually we can also name groups:
CHECK(expand({{"InnerCube", {{2, 3}}}, {"Wedges", {{3, 4}}}}) ==
{{2, 3}}, {{3, 4}}, {{3, 4}}, {{3, 4}}, {{3, 4}}});

The documentation for this struct was generated from the following file: