SpECTRE  v2024.05.11
domain::ExpandOverBlocks< T > Struct Template Reference

Produce a std::vector<T> over all blocks of the domain. 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< T > operator() (const T &value) const
 Repeat over all blocks (homogeneous)
 
std::vector< T > operator() (const std::vector< T > &value) const
 Only check if the size matches the number of blocks, throwing a std::length_error if it doesn't.
 
std::vector< T > operator() (const std::unordered_map< std::string, T > &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...
 
template<typename U , Requires< ExpandOverBlocks_detail::is_value_type< T, U >::value > = nullptr>
std::vector< T > operator() (const U &value) const
 Repeat over all blocks and dimensions (isotropic and homogeneous)
 

Detailed Description

template<typename T>
struct domain::ExpandOverBlocks< T >

Produce a std::vector<T> over all blocks of the domain.

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 the given value over all blocks (homogeneous).
  • std::vector<T>: Only check if the size matches the number of blocks, throwing a std::length_error if it doesn't.
  • std::unordered_map<std::string, T>: 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.
  • T::value_type: Repeat the given value over all blocks and dimensions (isotropic and homogeneous). Only works if T is a std::array. For example, if T is std::array<size_t, 3>, this will produce a std::vector<std::array<size_t, 3>> with the same value repeated num_blocks x 3 times.

If T is a std::unique_ptr, the class will clone the value for each block using T::get_clone().

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<std::array<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:66

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<std::array<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

Member Function Documentation

◆ operator()()

template<typename T >
std::vector< T > domain::ExpandOverBlocks< T >::operator() ( const std::unordered_map< std::string, T > &  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<std::array<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: