13 #include "DataStructures/DataBox/Tag.hpp"
14 #include "Domain/BlockLogicalCoordinates.hpp"
15 #include "Domain/Creators/Shell.hpp"
17 #include "Domain/ElementLogicalCoordinates.hpp"
18 #include "Domain/ElementMap.hpp"
20 #include "Domain/Structure/InitialElementIds.hpp"
21 #include "Framework/ActionTesting.hpp"
23 #include "NumericalAlgorithms/Interpolation/Actions/InterpolationTargetVarsFromElement.hpp"
24 #include "NumericalAlgorithms/Interpolation/InterpolationTarget.hpp"
25 #include "NumericalAlgorithms/Interpolation/PointInfoTag.hpp"
26 #include "NumericalAlgorithms/Interpolation/Tags.hpp"
28 #include "Parallel/PhaseDependentActionList.hpp"
30 #include "Time/Tags.hpp"
48 using type = tnsr::I<DataVector, 3, Frame::Inertial>;
57 get<>(*result) = get<>(x) * 2.0;
60 using argument_tags = tmpl::list<TestSolution>;
65 template <
typename TagName,
typename VarsTagList>
68 const tnsr::I<DataVector, 3, Frame::Inertial>& coords) noexcept {
71 auto& solution = get<TagName>(*vars);
73 (2.0 * get<0>(coords) + 3.0 * get<1>(coords) + 5.0 * get<2>(coords));
75 if constexpr (std::is_same_v<TagName, Tags::MultiplyByTwo>) {
77 }
else if constexpr (not std::is_same_v<TagName, Tags::TestSolution>) {
78 ERROR(
"Do not understand the given TagName");
82 template <
typename InterpolationTargetTag>
85 typename ParallelComponent,
typename DbTags,
typename Metavariables,
86 typename ArrayIndex,
typename TemporalId,
89 db::DataBox<DbTags>& box,
93 typename InterpolationTargetTag::vars_to_interpolate_to_target>>&
96 const TemporalId& ) noexcept {
97 CHECK(global_offsets.size() == vars_src.size());
101 CHECK(global_offsets.size() == 1);
104 const size_t num_pts_received = global_offsets[0].size();
107 const auto& all_target_points = db::get<Tags::TestTargetPoints>(box);
108 tnsr::I<DataVector, 3, Frame::Inertial> target_points(num_pts_received);
109 for (
size_t i = 0; i < num_pts_received; ++i) {
110 for (
size_t d = 0; d < 3; ++d) {
111 target_points.get(d)[i] =
112 all_target_points.get(d)[global_offsets[0][i]];
117 tmpl::count<
typename InterpolationTargetTag::
118 vars_to_interpolate_to_target>::value == 1,
119 "For this test, we assume only a single interpolated variable");
120 using solution_tag = tmpl::front<
121 typename InterpolationTargetTag::vars_to_interpolate_to_target>;
122 const auto& test_solution = get<solution_tag>(vars_src[0]);
125 Variables<tmpl::list<solution_tag>> expected_vars(vars_src[0].size());
126 fill_variables<solution_tag>(
make_not_null(&expected_vars), target_points);
127 const auto& expected_solution = get<solution_tag>(expected_vars);
131 Approx custom_approx = Approx::custom().epsilon(1.e-5).scale(1.0);
137 template <
typename Metavariables,
typename InterpolationTargetTag>
139 using metavariables = Metavariables;
141 using array_index = size_t;
144 using simple_tags = tmpl::list<Tags::TestTargetPoints>;
146 typename Metavariables::Phase, Metavariables::Phase::Initialization,
147 tmpl::list<ActionTesting::InitializeDataBox<simple_tags>>>>;
148 using replace_these_simple_actions =
150 InterpolationTargetTag>>;
151 using with_these_simple_actions = tmpl::list<
155 template <
typename DomainCreator>
157 make_volume_data_and_mesh(
const DomainCreator& domain_creator,
160 const auto& block = domain.blocks()[element_id.block_id()];
161 Mesh<3> mesh{domain_creator.initial_extents()[element_id.block_id()],
162 Spectral::Basis::Legendre, Spectral::Quadrature::GaussLobatto};
163 if (block.is_time_dependent()) {
164 ERROR(
"The block must be time-independent");
169 block.stationary_map().get_clone()};
171 Variables<tmpl::list<Tags::TestSolution>> vars(mesh.number_of_grid_points());
172 fill_variables<Tags::TestSolution>(
make_not_null(&vars), inertial_coords);
173 return std::make_tuple(std::move(vars), mesh);
178 template <
typename Metavariables,
typename elem_component,
typename Functor,
179 typename... GlobalCacheTypes>
180 void test_interpolate_on_element(
181 Functor initialize_elements_and_queue_simple_actions,
182 GlobalCacheTypes... global_cache_items) noexcept {
183 using metavars = Metavariables;
184 using target_component =
185 mock_interpolation_target<metavars,
186 typename metavars::InterpolationTargetA>;
188 const auto domain_creator =
190 const auto domain = domain_creator.create_domain();
196 for (
const auto& block : domain.blocks()) {
197 const auto initial_ref_levs =
198 domain_creator.initial_refinement_levels()[block.id()];
200 element_ids.insert(element_ids.end(), elem_ids.begin(), elem_ids.end());
204 const size_t num_points = 10;
205 tnsr::I<DataVector, 3, Frame::Inertial> target_points(num_points);
207 metavars>::type interp_point_info = [&domain, &target_points]() {
212 for (
size_t i = 0; i < num_points; ++i) {
213 const double r = r_dist(gen);
214 const double theta = theta_dist(gen);
215 const double phi = phi_dist(gen);
216 get<0>(target_points)[i] = r *
sin(theta) *
cos(
phi);
217 get<1>(target_points)[i] = r *
sin(theta) *
sin(
phi);
218 get<2>(target_points)[i] = r *
cos(theta);
220 typename intrp::Tags::InterpPointInfo<metavars>::type interp_point_info_l{};
221 get<intrp::Vars::PointInfoTag<typename metavars::InterpolationTargetA, 3>>(
223 return interp_point_info_l;
228 tuples::tagged_tuple_from_typelist<
230 std::move(global_cache_items)...}};
232 metavars::Phase::Initialization);
233 ActionTesting::emplace_component_and_initialize<target_component>(
234 &runner, 0, {target_points});
236 initialize_elements_and_queue_simple_actions(domain_creator, domain,
237 element_ids, interp_point_info,
238 runner, temporal_id);
243 while (not ActionTesting::is_simple_action_queue_empty<target_component>(
245 runner.template invoke_queued_simple_action<target_component>(0);