diff --git a/include/csg.hpp b/include/csg.hpp index e29b857240b8ae461bd729c2501107525b8a7898..23819fa3c1c3814ec0459f5bf7c3c9ea638c4cd2 100644 --- a/include/csg.hpp +++ b/include/csg.hpp @@ -26,7 +26,7 @@ std::shared_ptr parse_csg(std::string); class CsgIF : GPUable { public: - CsgIF(std::shared_ptr a_state); + CsgIF(std::shared_ptr a_state, bool is_internal_flow = false); CsgIF(const CsgIF &rhs); CsgIF(CsgIF &&rhs) noexcept; CsgIF &operator=(const CsgIF &rhs) = delete; @@ -42,13 +42,18 @@ public: private: std::shared_ptr m_state; + bool m_is_internal_flow; class Impl; std::unique_ptr m_pimpl; }; std::shared_ptr get_csgtree_from_filename(std::string); -std::unique_ptr get_csgif_from_filename(std::string geom_file); +std::unique_ptr +get_csgif_from_filename(std::string geom_file); // TODO: Deprecate once mfix has + // stopped using this call +std::unique_ptr get_csgif(const std::string &geom_file, + bool is_internal_flow = false); } // namespace csg diff --git a/src/csg/csg.cpp b/src/csg/csg.cpp index 8b7c17434a4d15c5683c09b2779a29462a98eb10..7de1dde17764f7320fee2353388e1f75c7c75bc3 100644 --- a/src/csg/csg.cpp +++ b/src/csg/csg.cpp @@ -42,16 +42,22 @@ public: }; CsgIF::CsgIF(const CsgIF &rhs) - : m_state(rhs.m_state), m_pimpl(std::make_unique(*rhs.m_pimpl)) {} + : m_state(rhs.m_state), m_is_internal_flow(rhs.m_is_internal_flow), + m_pimpl(std::make_unique(*rhs.m_pimpl)) {} -CsgIF::CsgIF(std::shared_ptr a_state) - : m_state(a_state), m_pimpl(std::make_unique()) {} +CsgIF::CsgIF(std::shared_ptr a_state, bool is_internal_flow) + : m_state(a_state), m_is_internal_flow(is_internal_flow), + m_pimpl(std::make_unique()) {} CsgIF::CsgIF(CsgIF &&rhs) noexcept = default; CsgIF::~CsgIF() = default; double CsgIF::operator()(double xx, double yy, double zz) const noexcept { - return m_pimpl->call_signed_distance(m_state, xx, yy, zz); + auto sd = m_pimpl->call_signed_distance(m_state, xx, yy, zz); + if (m_is_internal_flow) { + return -sd; + } + return sd; } std::shared_ptr get_csgtree_from_filename(std::string geom_file) { @@ -75,4 +81,17 @@ std::unique_ptr get_csgif_from_filename(std::string geom_file) { return std::make_unique(csg_if); } +std::unique_ptr get_csgif(const std::string &geom_file, + bool is_internal_flow) { + auto csg_obj = get_csgtree_from_filename(geom_file); + + if (!csg_obj) { + std::cout << "Failed to parse .csg file: " << geom_file << std::endl; + return nullptr; + } + + csg::CsgIF csg_if(csg_obj, is_internal_flow); + return std::make_unique(csg_if); +} + } // namespace csg diff --git a/src/csg/tests/CMakeLists.txt b/src/csg/tests/CMakeLists.txt index a5ee6f4baf3bda05e4ed1a1f4c5712782c6c16d7..6679700e6662322525a4e78dcadf9b447b2953ab 100644 --- a/src/csg/tests/CMakeLists.txt +++ b/src/csg/tests/CMakeLists.txt @@ -7,6 +7,7 @@ add_executable(unit_tests_csg EXCLUDE_FROM_ALL levelset/extrude.t.cpp levelset/primitives.t.cpp levelset/transform.t.cpp + levelset/internal_flow.t.cpp parser/boolean.t.cpp parser/extrude.t.cpp parser/nest.cpp diff --git a/src/csg/tests/levelset/internal_flow.t.cpp b/src/csg/tests/levelset/internal_flow.t.cpp new file mode 100644 index 0000000000000000000000000000000000000000..230c7e263de6b2a935356d86ce41b2f5ec7f8daf --- /dev/null +++ b/src/csg/tests/levelset/internal_flow.t.cpp @@ -0,0 +1,71 @@ +#include "catch2/catch.hpp" + +#include +#include + +#include + +namespace { + +TEST_CASE("union internal flow", "[Levelset Internal Flow]") { + // Create a union of a cube of size 12 and a sphere of radius 8 + csg::Cube my_cub{.name = std::nullopt, .size = {12, 12, 12}, .center = true}; + csg::Sphere my_sph{.name = std::nullopt, .radius = 8}; + + auto my_union = csg::Union3D(); + my_union.objs.push_back(my_cub); + my_union.objs.push_back(my_sph); + + auto my_tree = std::make_shared(); + my_tree->top.objs.push_back(my_union); + csg::CsgIF my_ls(my_tree); + csg::CsgIF my_ls_comp(my_tree, true); + + auto check = [&my_ls, &my_ls_comp](double xx, double yy, double zz) { + CHECK(my_ls(xx, yy, zz) == -my_ls_comp(xx, yy, zz)); + }; + + SECTION("Inside") { + check(0, 7, 0); + check(0, 0, -7.5); + } + SECTION("Outside") { + check(0, -9, 0); + check(9, 0, 0); + } +} + +TEST_CASE("CsgIF copy constructor", "[Levelset Internal Flow]") { + + csg::Sphere my_sph{.name = std::nullopt, .radius = 10}; + + auto my_tree = std::make_shared(); + my_tree->top.objs.push_back(my_sph); + csg::CsgIF my_ls1(my_tree); + csg::CsgIF my_ls2(my_ls1); + csg::CsgIF my_ls_comp1(my_tree, true); + csg::CsgIF my_ls_comp2(my_ls_comp1); + + auto check = [&my_ls1, &my_ls2, &my_ls_comp1, + &my_ls_comp2](double xx, double yy, double zz) { + CHECK(my_ls1(xx, yy, zz) == my_ls2(xx, yy, zz)); + CHECK(my_ls_comp1(xx, yy, zz) == my_ls_comp2(xx, yy, zz)); + CHECK(my_ls1(xx, yy, zz) == -my_ls_comp1(xx, yy, zz)); + CHECK(my_ls2(xx, yy, zz) == -my_ls_comp2(xx, yy, zz)); + }; + + SECTION("Outside") { + check(0, 8, 8); + check(-8, 0, 8); + check(0, 8, -8); + } + SECTION("Inside") { + check(0, 0, 0); + check(0, 7, 7); + check(-7, 0, 7); + check(-7, 0, 7); + check(0, 7, -7); + } +} + +} // namespace diff --git a/src/csg/tests/meson.build b/src/csg/tests/meson.build index 3051eab38b68a20003380649a7865d333298d53c..5aac1047ddd73e4fc983f255b5f5a009dccf383c 100644 --- a/src/csg/tests/meson.build +++ b/src/csg/tests/meson.build @@ -4,6 +4,7 @@ test_csg = executable( 'levelset/extrude.t.cpp', 'levelset/primitives.t.cpp', 'levelset/transform.t.cpp', + 'levelset/internal_flow.t.cpp', 'parser/boolean.t.cpp', 'parser/extrude.t.cpp', 'parser/nest.cpp',