Line data Source code
1 0 : // Distributed under the MIT License. 2 : // See LICENSE.txt for details. 3 : 4 : #pragma once 5 : 6 : #include <cstddef> 7 : #include <memory> 8 : #include <string> 9 : #include <unordered_set> 10 : 11 : #include "DataStructures/DataBox/Tag.hpp" 12 : #include "Domain/Creators/DomainCreator.hpp" 13 : #include "Domain/Creators/OptionTags.hpp" 14 : #include "Domain/Domain.hpp" 15 : #include "Options/String.hpp" 16 : #include "Utilities/Algorithm.hpp" 17 : #include "Utilities/ErrorHandling/Error.hpp" 18 : #include "Utilities/PrettyType.hpp" 19 : #include "Utilities/StdHelpers.hpp" 20 : 21 : namespace OptionTags { 22 : /*! 23 : * \ingroup OptionGroupsGroup 24 : * \brief Groups the filtering configurations in the input file. 25 : */ 26 1 : struct FilteringGroup { 27 0 : static std::string name() { return "Filtering"; } 28 0 : static constexpr Options::String help = "Options for filtering"; 29 : }; 30 : 31 : /*! 32 : * \ingroup OptionTagsGroup 33 : * \brief The option tag that retrieves the parameters for the filter 34 : * from the input file 35 : */ 36 : template <typename FilterType> 37 1 : struct Filter { 38 0 : static std::string name() { return pretty_type::name<FilterType>(); } 39 0 : static constexpr Options::String help = "Options for the filter"; 40 0 : using type = FilterType; 41 0 : using group = FilteringGroup; 42 : }; 43 : } // namespace OptionTags 44 : 45 0 : namespace Filters { 46 0 : namespace Tags { 47 : /*! 48 : * \brief The global cache tag for the filter 49 : * 50 : * Also checks if the specified blocks are actually in the domain. 51 : */ 52 : template <typename FilterType> 53 1 : struct Filter : db::SimpleTag { 54 0 : using type = FilterType; 55 : template <typename Metavariables> 56 0 : using option_tags = 57 : tmpl::list<::OptionTags::Filter<FilterType>, 58 : domain::OptionTags::DomainCreator<Metavariables::volume_dim>>; 59 : 60 0 : static constexpr bool pass_metavariables = true; 61 : template <typename Metavariables> 62 0 : static FilterType create_from_options( 63 : const FilterType& filter, 64 : const std::unique_ptr<DomainCreator<Metavariables::volume_dim>>& 65 : domain_creator) { 66 : const auto& blocks_to_filter = filter.blocks_to_filter(); 67 : 68 : // If this is nullopt, then we use all blocks 69 : if (blocks_to_filter.has_value()) { 70 : const auto& block_names = domain_creator->block_names(); 71 : const auto& block_groups = domain_creator->block_groups(); 72 : 73 : if (block_names.size() == 0) { 74 : ERROR( 75 : "The domain chosen doesn't use block names, but the Filter tag has " 76 : "specified block names to use."); 77 : } 78 : 79 : // The name must either be a block or a block group 80 : for (const std::string& block_to_filter : blocks_to_filter.value()) { 81 : const auto block_name_iter = alg::find(block_names, block_to_filter); 82 : if (block_name_iter == block_names.end() and 83 : block_groups.count(block_to_filter) == 0) { 84 : ERROR("Specified block (group) name '" 85 : << block_to_filter 86 : << "' is not a block name or a block " 87 : "group. Existing blocks are:\n" 88 : << block_names << "\nExisting block groups are:\n" 89 : << keys_of(block_groups)); 90 : } 91 : } 92 : } 93 : 94 : return filter; 95 : } 96 : }; 97 : } // namespace Tags 98 : } // namespace Filters