Skip to content

Commit

Permalink
Add function to copy items from a DataBox to a TaggedTuple
Browse files Browse the repository at this point in the history
This will be used to send data needed to initialize new elements from
their parent or children.
  • Loading branch information
kidder committed Feb 1, 2023
1 parent 77a1177 commit 1fd77ad
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 9 deletions.
61 changes: 61 additions & 0 deletions src/DataStructures/DataBox/DataBox.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "DataStructures/DataBox/Subitems.hpp"
#include "DataStructures/DataBox/TagName.hpp"
#include "DataStructures/DataBox/TagTraits.hpp"
#include "Parallel/Serialize.hpp"
#include "Utilities/CleanupRoutine.hpp"
#include "Utilities/ErrorHandling/Error.hpp"
#include "Utilities/ErrorHandling/StaticAssert.hpp"
Expand Down Expand Up @@ -256,6 +257,11 @@ class DataBox<tmpl::list<Tags...>> : private detail::Item<Tags>... {
template <typename Tag>
const auto& get() const;

/// \brief Copy the items with tags `TagsOfItemsToCopy` from the DataBox
/// into a TaggedTuple, should be called by the free function db::copy_items
template <typename... TagsOfItemsToCopy>
tuples::TaggedTuple<TagsOfItemsToCopy...> copy_items() const;

/// Retrieve a mutable reference to the tag `Tag`, should be called
/// by the free function db::get_mutable_reference
template <typename Tag>
Expand All @@ -274,6 +280,10 @@ class DataBox<tmpl::list<Tags...>> : private detail::Item<Tags>... {
AddImmutableItemTagsList /*meta*/, Args&&... args);

private:
template <typename CopiedItemsTagList, typename DbTagList>
// clang-tidy: redundant declaration
friend auto copy_items(const DataBox<DbTagList>& box);

template <typename... MutateTags, typename TagList, typename Invokable,
typename... Args>
// clang-tidy: redundant declaration
Expand All @@ -298,6 +308,16 @@ class DataBox<tmpl::list<Tags...>> : private detail::Item<Tags>... {
return static_cast<detail::Item<Tag>&>(*this);
}

// copy item correspond to Tag
template <typename Tag>
auto copy_item() const;

// copy items corresponding to CopiedItemsTags
// from the DataBox to a TaggedTuple
template <typename... CopiedItemsTags>
tuples::TaggedTuple<CopiedItemsTags...> copy_items(
tmpl::list<CopiedItemsTags...> /*meta*/) const;

template <typename ParentTag>
constexpr void add_mutable_subitems_to_box(tmpl::list<> /*meta*/) {}

Expand Down Expand Up @@ -787,6 +807,47 @@ SPECTRE_ALWAYS_INLINE const auto& get(const DataBox<TagList>& box) {
return box.template get<Tag>();
}

////////////////////////////////////////////////////////////////
// Copy mutable creation items from the DataBox

/// \cond
template <typename... Tags>
template <typename Tag>
SPECTRE_ALWAYS_INLINE auto DataBox<tmpl::list<Tags...>>::copy_item() const {
using item_tag = detail::first_matching_tag<tags_list, Tag>;
using item_type = typename item_tag::type;
static_assert(tmpl::list_contains_v<mutable_item_creation_tags, item_tag>,
"Can only copy mutable creation items");
return deserialize<item_type>(
serialize<item_type>(get_item<item_tag>().get()).data());
}

template <typename... DbTags>
template <typename... CopiedItemsTags>
tuples::TaggedTuple<CopiedItemsTags...>
DataBox<tmpl::list<DbTags...>>::copy_items(
tmpl::list<CopiedItemsTags...> /*meta*/) const {
return tuples::TaggedTuple<CopiedItemsTags...>{
copy_item<CopiedItemsTags>()...};
}
/// \endcond

/*!
* \ingroup DataBoxGroup
* \brief Copy the items from the DataBox into a TaggedTuple
*
* \return The objects corresponding to CopiedItemsTagList
*
* \note The tags in CopiedItemsTagList must be a subset of
* the mutable_item_creation_tags of the DataBox
*/
template <typename CopiedItemsTagList, typename DbTagList>
SPECTRE_ALWAYS_INLINE auto copy_items(const DataBox<DbTagList>& box) {
return box.copy_items(CopiedItemsTagList{});
}

////////////////////////////////////////////////////////////////
// Get mutable reference from the DataBox
template <typename... Tags>
template <typename Tag>
auto& DataBox<tmpl::list<Tags...>>::get_mutable_reference() {
Expand Down
36 changes: 27 additions & 9 deletions tests/Unit/DataStructures/DataBox/Test_DataBox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2107,6 +2107,13 @@ void serialization_non_subitem_simple_items() {
CHECK(before_2 == &db::get<test_databox_tags::Tag2>(serialization_test_box));
CHECK(before_2 !=
&db::get<test_databox_tags::Tag2>(deserialized_serialization_test_box));

auto copied_items = db::copy_items<
tmpl::list<test_databox_tags::Tag1, test_databox_tags::Tag2>>(
serialization_test_box);
CHECK(get<test_databox_tags::Tag1>(copied_items) ==
std::vector<double>{8.7, 93.2, 84.7});
CHECK(get<test_databox_tags::Tag2>(copied_items) == "My Sample String"s);
}

void serialization_subitems_simple_items() {
Expand Down Expand Up @@ -2527,6 +2534,10 @@ void serialization_compute_items_of_base_tags() {
auto copied_box = serialize_and_deserialize(original_box);
CHECK(db::get<test_databox_tags::Tag2>(copied_box) == "My Sample String");
CHECK(db::get<test_databox_tags::Tag6>(copied_box) == "My Sample String");

auto copied_items =
db::copy_items<tmpl::list<test_databox_tags::Tag2>>(original_box);
CHECK(get<test_databox_tags::Tag2>(copied_items) == "My Sample String");
}

void serialization_of_pointers() {
Expand All @@ -2544,6 +2555,21 @@ void serialization_of_pointers() {
check(serialize_and_deserialize(box)); // before compute items evaluated
check(box);
check(serialize_and_deserialize(box)); // after compute items evaluated

auto copied_items =
db::copy_items<tmpl::list<test_databox_tags::Pointer>>(box);
check(box);
CHECK(*get<test_databox_tags::Pointer>(copied_items) == 3);
CHECK(get<test_databox_tags::Pointer>(copied_items).get() !=
&db::get<test_databox_tags::Pointer>(box));
}

void test_serialization_and_copy_items() {
serialization_non_subitem_simple_items();
serialization_subitems_simple_items();
serialization_subitem_compute_items();
serialization_compute_items_of_base_tags();
serialization_of_pointers();
}

namespace test_databox_tags {
Expand Down Expand Up @@ -2594,14 +2620,6 @@ void test_reference_item() {
CHECK(get<test_databox_tags::Tag2>(box) == "My Sample String"s);
}

void test_serialization() {
serialization_non_subitem_simple_items();
serialization_subitems_simple_items();
serialization_subitem_compute_items();
serialization_compute_items_of_base_tags();
serialization_of_pointers();
}

void test_get_mutable_reference() {
INFO("test get_mutable_reference");
// Make sure the presence of tags that could not be extracted
Expand Down Expand Up @@ -2807,7 +2825,7 @@ SPECTRE_TEST_CASE("Unit.DataStructures.DataBox", "[Unit][DataStructures]") {
test_subitems();
test_overload_compute_tags();
test_with_tagged_tuple();
test_serialization();
test_serialization_and_copy_items();
test_reference_item();
test_get_mutable_reference();
test_output();
Expand Down

0 comments on commit 1fd77ad

Please sign in to comment.