From 78007f5df59196469772320474754e53b73e440b Mon Sep 17 00:00:00 2001 From: Michael Tao Date: Sat, 23 Nov 2024 17:38:16 -0500 Subject: [PATCH] adding get_attribute with tools for finding missing attributes --- .../multimesh/utils/AttributeDescription.cpp | 34 +++- .../multimesh/utils/AttributeDescription.hpp | 21 +- .../multimesh/utils/get_attribute.cpp | 116 ++++++++++- .../multimesh/utils/get_attribute.hpp | 9 +- components/multimesh/tests/CMakeLists.txt | 7 +- components/multimesh/tests/get_attributes.cpp | 188 +++++++++++++++++ .../multimesh/tests/named_multimesh.cpp | 191 +----------------- components/multimesh/tests/utils.cpp | 33 +++ components/multimesh/tests/utils.hpp | 9 + src/wmtk/utils/primitive_range_iter.hpp | 3 +- 10 files changed, 401 insertions(+), 210 deletions(-) create mode 100644 components/multimesh/tests/get_attributes.cpp create mode 100644 components/multimesh/tests/utils.cpp create mode 100644 components/multimesh/tests/utils.hpp diff --git a/components/multimesh/src/wmtk/components/multimesh/utils/AttributeDescription.cpp b/components/multimesh/src/wmtk/components/multimesh/utils/AttributeDescription.cpp index 9e662097da..e254258035 100644 --- a/components/multimesh/src/wmtk/components/multimesh/utils/AttributeDescription.cpp +++ b/components/multimesh/src/wmtk/components/multimesh/utils/AttributeDescription.cpp @@ -1,10 +1,11 @@ #include "AttributeDescription.hpp" #include +#include namespace wmtk::attribute { // TODO: this definitely will cause a conflict someday if someone else wants to serialize // attributetype -NLOHMANN_JSON_SERIALIZE_ENUM( +WMTK_NLOHMANN_JSON_SERIALIZE_ENUM( AttributeType, { {AttributeType::Char, "char"}, @@ -31,18 +32,39 @@ NLOHMANN_JSON_SERIALIZE_ENUM( } // namespace WMTK_NLOHMANN_JSON_FRIEND_TO_JSON_PROTOTYPE(AttributeDescription) { - WMTK_NLOHMANN_ASSIGN_TYPE_TO_JSON(path, dimension, type); + WMTK_NLOHMANN_ASSIGN_TYPE_TO_JSON(path); + if (nlohmann_json_t.dimension.has_value()) { + nlohmann_json_j["dimension"] = nlohmann_json_t.dimension.value(); + } + if (nlohmann_json_t.type.has_value()) { + nlohmann_json_j["type"] = nlohmann_json_t.type.value(); + } } WMTK_NLOHMANN_JSON_FRIEND_FROM_JSON_PROTOTYPE(AttributeDescription) { - WMTK_NLOHMANN_ASSIGN_TYPE_FROM_JSON(path, dimension, type); + if (nlohmann_json_j.is_string()) { + nlohmann_json_t.path = nlohmann_json_j.get(); + } else { + nlohmann_json_t.path = nlohmann_json_j["path"]; + } + if (nlohmann_json_j.contains("dimension")) { + nlohmann_json_t.dimension = nlohmann_json_j["dimension"]; + } + if (nlohmann_json_j.contains("type")) { + nlohmann_json_t.type = nlohmann_json_j["type"]; + } } -PrimitiveType AttributeDescription::primitive_type() const +std::optional AttributeDescription::primitive_type() const { - assert(dimension < 4); + if (this->dimension.has_value()) { + int8_t d = this->dimension.value(); + assert(d < 4); - return get_primitive_type_from_id(dimension); + return get_primitive_type_from_id(d); + } else { + return {}; + } } } // namespace wmtk::components::multimesh::utils diff --git a/components/multimesh/src/wmtk/components/multimesh/utils/AttributeDescription.hpp b/components/multimesh/src/wmtk/components/multimesh/utils/AttributeDescription.hpp index 05b0811889..ce9675389d 100644 --- a/components/multimesh/src/wmtk/components/multimesh/utils/AttributeDescription.hpp +++ b/components/multimesh/src/wmtk/components/multimesh/utils/AttributeDescription.hpp @@ -1,9 +1,14 @@ #pragma once #include +#include #include #include #include +namespace wmtk::attribute { +WMTK_NLOHMANN_JSON_DECLARATION(AttributeType) +} + namespace wmtk::components::multimesh::utils { @@ -11,18 +16,18 @@ namespace wmtk::components::multimesh::utils { struct AttributeDescription { // Avoiding defining any constructors to enable aggregate construction - //AttributeDescription() = default; - //AttributeDescription(const AttributeDescription&) = default; - //AttributeDescription(AttributeDescription&&) = default; - //AttributeDescription& operator=(const AttributeDescription&) = default; - //AttributeDescription& operator=(AttributeDescription&&) = default; + // AttributeDescription() = default; + // AttributeDescription(const AttributeDescription&) = default; + // AttributeDescription(AttributeDescription&&) = default; + // AttributeDescription& operator=(const AttributeDescription&) = default; + // AttributeDescription& operator=(AttributeDescription&&) = default; //~AttributeDescription() = default; std::string path; - uint8_t dimension; // internally the primitive type - attribute::AttributeType type; + std::optional dimension; + std::optional type; - PrimitiveType primitive_type() const; + std::optional primitive_type() const; auto operator<=>(const AttributeDescription&) const -> std::strong_ordering; auto operator==(const AttributeDescription&) const -> bool; diff --git a/components/multimesh/src/wmtk/components/multimesh/utils/get_attribute.cpp b/components/multimesh/src/wmtk/components/multimesh/utils/get_attribute.cpp index 984ea7542d..e948cc9611 100644 --- a/components/multimesh/src/wmtk/components/multimesh/utils/get_attribute.cpp +++ b/components/multimesh/src/wmtk/components/multimesh/utils/get_attribute.cpp @@ -2,6 +2,7 @@ #include "get_attribute.hpp" #include #include +#include #include "..//MeshCollection.hpp" #include "../NamedMultiMesh.hpp" #include "AttributeDescription.hpp" @@ -9,6 +10,68 @@ #include "wmtk/utils/Logger.hpp" namespace wmtk::components::multimesh::utils { +class attribute_missing_error : public std::range_error +{ +public: + static std::string make_message( + std::string path, + std::optional dimension, + std::optional type) + { + std::string typestr; + if (type.has_value()) { + nlohmann::json j; + j = type.value(); // just using the fact we can generate a strnig for this using json + // to get a printable string + typestr = j; + } + if (type.has_value() && dimension.has_value()) { + return fmt::format( + "Could not find attribute named {} on {}-simplices of type {}", + path, + dimension.value(), + typestr); + } else if (type.has_value()) { + return fmt::format( + "Could not find attribute named {} on {}-simplices", + path, + dimension.value()); + } else if (dimension.has_value()) { + return fmt::format("Could not find attribute named {} of type {}", path, typestr); + } else { + return fmt::format("Could not find attribute named {}", path); + } + } + static std::string make_message(const AttributeDescription& ad) + { + return make_message(ad.path, ad.dimension, ad.type); + } + + attribute_missing_error(const std::string_view& message, const AttributeDescription& ad) + : std::range_error(std::string(message)) + , description(ad) + {} + attribute_missing_error(const AttributeDescription& ad) + : attribute_missing_error(make_message(ad), ad) + {} + attribute_missing_error( + const std::string_view& path, + const std::optional& dimension, + const std::optional& type) + : attribute_missing_error(AttributeDescription(std::string(path), dimension, type)) + {} + attribute_missing_error( + const std::string_view& path, + const std::optional& pt, + const std::optional& type) + : attribute_missing_error( + path, + pt.has_value() ? std::optional{wmtk::get_primitive_type_id(pt.value())} + : std::optional{}, + type) + {} + AttributeDescription description; +}; namespace detail { @@ -66,7 +129,14 @@ template wmtk::attribute::MeshAttributeHandle get_attribute(const Mesh& mesh, const std::string_view& name, PrimitiveType pt) { - return mesh.get_attribute_handle(std::string(name), pt); + if (mesh.has_attribute(std::string(name), pt)) { + return mesh.get_attribute_handle(std::string(name), pt); + } else { + throw attribute_missing_error( + std::string(name), + wmtk::get_primitive_type_id(pt), + wmtk::attribute ::attribute_type_enum_from_type()); + } } wmtk::attribute::MeshAttributeHandle get_attribute( @@ -92,6 +162,50 @@ wmtk::attribute::MeshAttributeHandle get_attribute( } return {}; } +wmtk::attribute::MeshAttributeHandle get_attribute( + const Mesh& mesh, + const std::string_view& name, + std::optional pt, + std::optional type) +{ + using AT = attribute::AttributeType; + // This order matches wmtk::components::utils::get_attributes + constexpr static std::array types{{AT::Char, AT::Int64, AT::Double, AT::Rational}}; + // constexpr static std::array types{{AT::Int64, AT::Double, AT::Char, AT::Rational}}; + if (pt.has_value() && type.has_value()) { + return get_attribute(mesh, name, pt.value(), type.value()); + } else if (pt.has_value()) { + for (AT at : types) { + try { + return get_attribute(mesh, name, pt.value(), at); + } catch (const attribute_missing_error& e) { + continue; + } + } + } else if (type.has_value()) { + for (PrimitiveType p : wmtk::utils::primitive_below(mesh.top_simplex_type())) { + try { + return get_attribute(mesh, name, p, type.value()); + } catch (const attribute_missing_error& e) { + continue; + } + } + } else { + for (AT at : types) { + for (PrimitiveType p : wmtk::utils::primitive_below(mesh.top_simplex_type())) { + try { + return get_attribute(mesh, name, p, at); + } catch (const attribute_missing_error& e) { + continue; + } + } + } + } + + + throw attribute_missing_error(name, pt, type); + return {}; +} } // namespace detail wmtk::attribute::MeshAttributeHandle get_attribute( diff --git a/components/multimesh/src/wmtk/components/multimesh/utils/get_attribute.hpp b/components/multimesh/src/wmtk/components/multimesh/utils/get_attribute.hpp index 6780e82bb3..2d2b7df48b 100644 --- a/components/multimesh/src/wmtk/components/multimesh/utils/get_attribute.hpp +++ b/components/multimesh/src/wmtk/components/multimesh/utils/get_attribute.hpp @@ -7,7 +7,7 @@ class Mesh; namespace components::multimesh { class NamedMultiMesh; class MeshCollection; -} +} // namespace components::multimesh } // namespace wmtk namespace wmtk::components::multimesh { @@ -21,6 +21,9 @@ struct AttributeDescription; // * simplex (int, dimension attribute belongs to // if type and simplex are missing code will search in lexicographical of (primitive_type, type) // where double < int < char < rational for type +// +// this is somewhat redundant to wmtk::components::utils::get_attributes, but is designed around +// supporting multimesh paths. wmtk::attribute::MeshAttributeHandle get_attribute( const NamedMultiMesh& mesh, @@ -32,5 +35,5 @@ wmtk::attribute::MeshAttributeHandle get_attribute( const Mesh& mesh, const AttributeDescription& description); -} -} // namespace wmtk::components::multimesh::utils +} // namespace utils +} // namespace wmtk::components::multimesh diff --git a/components/multimesh/tests/CMakeLists.txt b/components/multimesh/tests/CMakeLists.txt index 919b8f4eda..e25795edf4 100644 --- a/components/multimesh/tests/CMakeLists.txt +++ b/components/multimesh/tests/CMakeLists.txt @@ -1,4 +1,9 @@ -add_component_test(wmtk::${COMPONENT_NAME} named_multimesh.cpp) +add_component_test(wmtk::${COMPONENT_NAME} + named_multimesh.cpp + get_attributes.cpp + utils.hpp + utils.cpp +) target_link_libraries(${WMTK_COMPONENT_TEST_TARGET} PRIVATE wmtk::input) diff --git a/components/multimesh/tests/get_attributes.cpp b/components/multimesh/tests/get_attributes.cpp new file mode 100644 index 0000000000..ab3a4e70b9 --- /dev/null +++ b/components/multimesh/tests/get_attributes.cpp @@ -0,0 +1,188 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "wmtk/components/multimesh/MeshCollection.hpp" + +#include "utils.hpp" + +using json = nlohmann::json; + +TEST_CASE("named_multimesh_parse_attributes", "[components][multimesh]") +{ + { + auto m = make_mesh(); + wmtk::components::multimesh::MeshCollection mc; + wmtk::components::multimesh::NamedMultiMesh& named_mm = + mc.emplace_mesh(*m, std::string("roo")); + + auto double_test_handle = + m->register_attribute("double_test", wmtk::PrimitiveType::Vertex, 1); + auto char_test_handle = + m->register_attribute("char_test", wmtk::PrimitiveType::Vertex, 1); + auto int_test_handle = + m->register_attribute("int_test", wmtk::PrimitiveType::Vertex, 1); + auto rational_test_handle = + m->register_attribute("rational_test", wmtk::PrimitiveType::Vertex, 1); + + using AT = wmtk::attribute::AttributeType; + +using AD = wmtk::components::multimesh::utils::AttributeDescription; + { // double check that path extraction is working + std::vector double_ads; + double_ads.emplace_back(AD{"double_test", 0, AT::Double}); + double_ads.emplace_back(AD{"/double_test", 0, AT::Double}); + double_ads.emplace_back(AD{"roo/double_test", 0, AT::Double}); + + + for (const auto& ad : double_ads) { + auto h = wmtk::components::multimesh::utils::get_attribute(named_mm, ad); + CHECK(double_test_handle == h); + // just on mesh also works + auto h2 = wmtk::components::multimesh::utils::get_attribute(*m, ad); + CHECK(double_test_handle == h2); + //// meshcollection too + auto h3 = wmtk::components::multimesh::utils::get_attribute(mc, ad); + CHECK(double_test_handle == h3); + } + } + { // check that other types work + CHECK( + rational_test_handle == wmtk::components::multimesh::utils::get_attribute( + named_mm, + AD{"rational_test", 0, AT::Rational})); + CHECK( + int_test_handle == wmtk::components::multimesh::utils::get_attribute( + named_mm, + AD{"int_test", 0, AT::Int64})); + CHECK( + char_test_handle == wmtk::components::multimesh::utils::get_attribute( + named_mm, + AD{"char_test", 0, AT::Char})); + } + { // check that other simplex types work + auto edge_handle = + m->register_attribute("double_test", wmtk::PrimitiveType::Edge, 1); + auto tri_handle = + m->register_attribute("double_test", wmtk::PrimitiveType::Triangle, 1); + CHECK( + edge_handle == wmtk::components::multimesh::utils::get_attribute( + named_mm, + AD{"double_test", 1, AT::Double})); + CHECK( + tri_handle == wmtk::components::multimesh::utils::get_attribute( + named_mm, + AD{"double_test", 2, AT::Double})); + // TODO: lazy about testing tet + } + } + + + { + using AD = wmtk::components::multimesh::utils::AttributeDescription; + auto m = make_mesh(); + auto children = make_child(*m, {0}); + REQUIRE(children.size() == 1); + auto child = children[0]; + + + wmtk::components::multimesh::NamedMultiMesh named_mm; + named_mm.set_mesh(*m); + { + nlohmann::json js; + js["roo"] = nlohmann::json::array({"child"}); + named_mm.set_names(js); + } + CHECK(std::vector{} == named_mm.get_id("roo")); + CHECK(std::vector{0} == named_mm.get_id("roo.child")); + auto attr_handle = + m->register_attribute("double_test", wmtk::PrimitiveType::Vertex, 1); + auto child_attr_handle = + child->register_attribute("double_test", wmtk::PrimitiveType::Vertex, 1); + using AT = wmtk::attribute::AttributeType; + CHECK( + attr_handle == wmtk::components::multimesh::utils::get_attribute( + named_mm, + AD{"double_test", 0, AT::Double})); + CHECK( + attr_handle == wmtk::components::multimesh::utils::get_attribute( + named_mm, + AD{"/double_test", 0, AT::Double})); + CHECK( + attr_handle == wmtk::components::multimesh::utils::get_attribute( + named_mm, + AD{"roo/double_test", 0, AT::Double})); + CHECK( + child_attr_handle == wmtk::components::multimesh::utils::get_attribute( + named_mm, + AD{"roo.child/double_test", 0, AT::Double})); + CHECK( + child_attr_handle == wmtk::components::multimesh::utils::get_attribute( + named_mm, + AD{".child/double_test", 0, AT::Double})); + } +} + +TEST_CASE("multimesh_attribute_description_json", "[components][multimesh]") +{ + using AT = wmtk::attribute::AttributeType; + using AD = wmtk::components::multimesh::utils::AttributeDescription; + using JS = nlohmann::json; + auto check = [](const AD& ad, const JS& js) { + JS js2 = ad; + auto ad2 = js.get(); + CHECK(js2 == js); + CHECK(ad == js.get()); + }; + { + AD ad{"double_test", 0, AT::Double}; + JS js{{"path", "double_test"}, {"dimension", 0}, {"type", "double"}}; + check(ad, js); + } + { + AD ad{"rational_test", 0, AT::Rational}; + JS js{{"path", "rational_test"}, {"dimension", 0}, {"type", "rational"}}; + check(ad, js); + } + { + AD ad{"int_test", 0, AT::Int64}; + JS js{{"path", "int_test"}, {"dimension", 0}, {"type", "int"}}; + check(ad, js); + } + { + AD ad{"char_test", 0, AT::Char}; + JS js{{"path", "char_test"}, {"dimension", 0}, {"type", "char"}}; + check(ad, js); + } + { + AD ad{"double_test", 1, AT::Double}; + JS js{{"path", "double_test"}, {"dimension", 1}, {"type", "double"}}; + check(ad, js); + } + { + AD ad{"double_test", 2, AT::Double}; + JS js{{"path", "double_test"}, {"dimension", 2}, {"type", "double"}}; + check(ad, js); + } + + { + AD ad{"double_test", {}, AT::Double}; + JS js{{"path", "double_test"}, {"type", "double"}}; + check(ad, js); + } + { + AD ad{"double_test", 2, {}}; + JS js{{"path", "double_test"}, {"dimension", 2}}; + check(ad, js); + } + { + AD ad{"double_test", {}, {}}; + JS js{{"path", "double_test"}}; + check(ad, js); + } +} diff --git a/components/multimesh/tests/named_multimesh.cpp b/components/multimesh/tests/named_multimesh.cpp index 0f6c05b723..cc8e34a761 100644 --- a/components/multimesh/tests/named_multimesh.cpp +++ b/components/multimesh/tests/named_multimesh.cpp @@ -7,45 +7,12 @@ #include #include #include -#include "tools/TriMesh_examples.hpp" -#include "wmtk/components/multimesh/MeshCollection.hpp" -#include +#include "utils.hpp" using json = nlohmann::json; -namespace { -const std::filesystem::path data_dir = WMTK_DATA_DIR; -auto make_mesh() -{ - return wmtk::tests::disk(5); -} - -auto make_child(wmtk::Mesh& m, const std::vector& path) - -> std::vector> -{ - if (path.size() == 0) { - // multimesh root mesh already exists so nothing to be done - return {}; - } - std::vector> meshes; - for (size_t j = 0; j < path.size(); ++j) { - std::vector p(path.begin(), path.begin() + j); - auto& cur_mesh = m.get_multi_mesh_mesh(p); - int64_t child_index = path[j]; - const auto child_meshes = cur_mesh.get_child_meshes(); - for (int64_t index = child_meshes.size(); index <= child_index; ++index) { - auto new_mesh = make_mesh(); - auto map = wmtk::multimesh::same_simplex_dimension_bijection(cur_mesh, *new_mesh); - - cur_mesh.register_child_mesh(new_mesh, map); - meshes.emplace_back(new_mesh); - } - } - return meshes; -} -} // namespace TEST_CASE("named_multimesh_parse", "[components][multimesh]") @@ -137,159 +104,3 @@ TEST_CASE("named_multimesh_parse", "[components][multimesh]") } } -TEST_CASE("named_multimesh_parse_attributes", "[components][multimesh]") -{ - { - auto m = make_mesh(); - wmtk::components::multimesh::MeshCollection mc; - wmtk::components::multimesh::NamedMultiMesh& named_mm = - mc.emplace_mesh(*m, std::string("roo")); - - auto double_test_handle = - m->register_attribute("double_test", wmtk::PrimitiveType::Vertex, 1); - auto char_test_handle = - m->register_attribute("char_test", wmtk::PrimitiveType::Vertex, 1); - auto int_test_handle = - m->register_attribute("int_test", wmtk::PrimitiveType::Vertex, 1); - auto rational_test_handle = - m->register_attribute("rational_test", wmtk::PrimitiveType::Vertex, 1); - - using AT = wmtk::attribute::AttributeType; - -using AD = wmtk::components::multimesh::utils::AttributeDescription; - { // double check that path extraction is working - std::vector double_ads; - double_ads.emplace_back(AD{"double_test", 0, AT::Double}); - double_ads.emplace_back(AD{"/double_test", 0, AT::Double}); - double_ads.emplace_back(AD{"roo/double_test", 0, AT::Double}); - - - for (const auto& ad : double_ads) { - auto h = wmtk::components::multimesh::utils::get_attribute(named_mm, ad); - CHECK(double_test_handle == h); - // just on mesh also works - auto h2 = wmtk::components::multimesh::utils::get_attribute(*m, ad); - CHECK(double_test_handle == h2); - //// meshcollection too - auto h3 = wmtk::components::multimesh::utils::get_attribute(mc, ad); - CHECK(double_test_handle == h3); - } - } - { // check that other types work - CHECK( - rational_test_handle == wmtk::components::multimesh::utils::get_attribute( - named_mm, - AD{"rational_test", 0, AT::Rational})); - CHECK( - int_test_handle == wmtk::components::multimesh::utils::get_attribute( - named_mm, - AD{"int_test", 0, AT::Int64})); - CHECK( - char_test_handle == wmtk::components::multimesh::utils::get_attribute( - named_mm, - AD{"char_test", 0, AT::Char})); - } - { // check that other simplex types work - auto edge_handle = - m->register_attribute("double_test", wmtk::PrimitiveType::Edge, 1); - auto tri_handle = - m->register_attribute("double_test", wmtk::PrimitiveType::Triangle, 1); - CHECK( - edge_handle == wmtk::components::multimesh::utils::get_attribute( - named_mm, - AD{"double_test", 1, AT::Double})); - CHECK( - tri_handle == wmtk::components::multimesh::utils::get_attribute( - named_mm, - AD{"double_test", 2, AT::Double})); - // TODO: lazy about testing tet - } - } - - - { - using AD = wmtk::components::multimesh::utils::AttributeDescription; - auto m = make_mesh(); - auto children = make_child(*m, {0}); - REQUIRE(children.size() == 1); - auto child = children[0]; - - - wmtk::components::multimesh::NamedMultiMesh named_mm; - named_mm.set_mesh(*m); - { - nlohmann::json js; - js["roo"] = nlohmann::json::array({"child"}); - named_mm.set_names(js); - } - CHECK(std::vector{} == named_mm.get_id("roo")); - CHECK(std::vector{0} == named_mm.get_id("roo.child")); - auto attr_handle = - m->register_attribute("double_test", wmtk::PrimitiveType::Vertex, 1); - auto child_attr_handle = - child->register_attribute("double_test", wmtk::PrimitiveType::Vertex, 1); - using AT = wmtk::attribute::AttributeType; - CHECK( - attr_handle == wmtk::components::multimesh::utils::get_attribute( - named_mm, - AD{"double_test", 0, AT::Double})); - CHECK( - attr_handle == wmtk::components::multimesh::utils::get_attribute( - named_mm, - AD{"/double_test", 0, AT::Double})); - CHECK( - attr_handle == wmtk::components::multimesh::utils::get_attribute( - named_mm, - AD{"roo/double_test", 0, AT::Double})); - CHECK( - child_attr_handle == wmtk::components::multimesh::utils::get_attribute( - named_mm, - AD{"roo.child/double_test", 0, AT::Double})); - CHECK( - child_attr_handle == wmtk::components::multimesh::utils::get_attribute( - named_mm, - AD{".child/double_test", 0, AT::Double})); - } -} - -TEST_CASE("multimesh_attribute_description_json", "[components][multimesh]") -{ - using AT = wmtk::attribute::AttributeType; - using AD = wmtk::components::multimesh::utils::AttributeDescription; - using JS = nlohmann::json; - auto check = [](const AD& ad, const JS& js) { - JS js2 = ad; - CHECK(js2 == js); - CHECK(ad == js.get()); - }; - { - AD ad{"double_test", 0, AT::Double}; - JS js{{"path", "double_test"}, {"dimension", 0}, {"type", "double"}}; - check(ad, js); - } - { - AD ad{"rational_test", 0, AT::Rational}; - JS js{{"path", "rational_test"}, {"dimension", 0}, {"type", "rational"}}; - check(ad, js); - } - { - AD ad{"int_test", 0, AT::Int64}; - JS js{{"path", "int_test"}, {"dimension", 0}, {"type", "int"}}; - check(ad, js); - } - { - AD ad{"char_test", 0, AT::Char}; - JS js{{"path", "char_test"}, {"dimension", 0}, {"type", "char"}}; - check(ad, js); - } - { - AD ad{"double_test", 1, AT::Double}; - JS js{{"path", "double_test"}, {"dimension", 1}, {"type", "double"}}; - check(ad, js); - } - { - AD ad{"double_test", 2, AT::Double}; - JS js{{"path", "double_test"}, {"dimension", 2}, {"type", "double"}}; - check(ad, js); - } -} diff --git a/components/multimesh/tests/utils.cpp b/components/multimesh/tests/utils.cpp new file mode 100644 index 0000000000..119ce0bc1c --- /dev/null +++ b/components/multimesh/tests/utils.cpp @@ -0,0 +1,33 @@ +#include +#include "tools/TriMesh_examples.hpp" +#include "utils.hpp" +#include + +std::shared_ptr make_mesh() +{ + return wmtk::tests::disk(5); +} + +auto make_child(wmtk::Mesh& m, const std::vector& path) + -> std::vector> +{ + if (path.size() == 0) { + // multimesh root mesh already exists so nothing to be done + return {}; + } + std::vector> meshes; + for (size_t j = 0; j < path.size(); ++j) { + std::vector p(path.begin(), path.begin() + j); + auto& cur_mesh = m.get_multi_mesh_mesh(p); + int64_t child_index = path[j]; + const auto child_meshes = cur_mesh.get_child_meshes(); + for (int64_t index = child_meshes.size(); index <= child_index; ++index) { + auto new_mesh = make_mesh(); + auto map = wmtk::multimesh::same_simplex_dimension_bijection(cur_mesh, *new_mesh); + + cur_mesh.register_child_mesh(new_mesh, map); + meshes.emplace_back(new_mesh); + } + } + return meshes; +} diff --git a/components/multimesh/tests/utils.hpp b/components/multimesh/tests/utils.hpp new file mode 100644 index 0000000000..cf8f747adf --- /dev/null +++ b/components/multimesh/tests/utils.hpp @@ -0,0 +1,9 @@ +#pragma once +#include +#include +namespace wmtk { + class Mesh; +} +std::shared_ptr make_mesh(); +auto make_child(wmtk::Mesh& m, const std::vector& path) + -> std::vector>; diff --git a/src/wmtk/utils/primitive_range_iter.hpp b/src/wmtk/utils/primitive_range_iter.hpp index f3c4351ef8..e7424076af 100644 --- a/src/wmtk/utils/primitive_range_iter.hpp +++ b/src/wmtk/utils/primitive_range_iter.hpp @@ -13,6 +13,7 @@ template < bool Inverted = (Start > End)> class PrimitiveTypeRange { + public: using integral_type = std::underlying_type_t; class iterator { @@ -103,7 +104,7 @@ auto primitive_above() } // returns a vector of primitives including the endpoint template -primitive_below() +auto primitive_below() { constexpr static PrimitiveType Start = PrimitiveType::Vertex; using integral_type = std::underlying_type_t;