From d6fcdc9043abcc4015bd0ba12f9fd755c9c0ca79 Mon Sep 17 00:00:00 2001 From: Loic Gouarin Date: Fri, 28 Jul 2023 11:41:25 +0200 Subject: [PATCH] feat: add cell_in in functionBC (#121) - modify template parameter of a Cell - add the cell inside the domain in the method which computes the values in FunctionBC --- demos/FiniteVolume/level_set_from_scratch.cpp | 2 +- demos/FiniteVolume/stokes_2d.cpp | 12 +- demos/highorder/main.cpp | 2 +- demos/multigrid/test_cases.hpp | 27 ++-- demos/p4est/simple_2d.cpp | 4 +- demos/pablo/bubble_2d.cpp | 2 +- .../AMR_1D_Burgers/step_4/update_field.hpp | 2 +- .../AMR_1D_Burgers/step_4/update_mesh.hpp | 2 +- demos/tutorial/graduation_case_3.cpp | 2 +- include/samurai/algorithm.hpp | 29 ++--- include/samurai/algorithm/update.hpp | 4 +- include/samurai/bc.hpp | 119 +++++++++--------- include/samurai/cell.hpp | 56 +++++---- include/samurai/cell_array.hpp | 11 +- include/samurai/field.hpp | 30 ++--- include/samurai/field_expression.hpp | 4 +- include/samurai/graduation.hpp | 2 +- include/samurai/interface.hpp | 6 +- include/samurai/io/from_geometry.hpp | 4 +- include/samurai/level_cell_array.hpp | 12 +- include/samurai/level_cell_list.hpp | 4 +- include/samurai/mesh.hpp | 9 +- include/samurai/numeric/gauss_legendre.hpp | 8 +- .../samurai/petsc/fv/FV_scheme_assembly.hpp | 68 +++++----- include/samurai/stencil.hpp | 23 ++-- test/test_cell.cpp | 7 +- 26 files changed, 225 insertions(+), 226 deletions(-) diff --git a/demos/FiniteVolume/level_set_from_scratch.cpp b/demos/FiniteVolume/level_set_from_scratch.cpp index 6d2d70098..f6b99c883 100644 --- a/demos/FiniteVolume/level_set_from_scratch.cpp +++ b/demos/FiniteVolume/level_set_from_scratch.cpp @@ -334,7 +334,7 @@ bool update_mesh(Field& f, Field_u& u, Tag& tag) samurai::for_each_interval(mesh[SimpleID::cells], [&](std::size_t level, const auto& interval, const auto& index_yz) { - auto itag = static_cast(interval.start + interval.index); + auto itag = interval.start + interval.index; for (int i = interval.start; i < interval.end; ++i) { if (tag[itag] & static_cast(samurai::CellFlag::refine)) diff --git a/demos/FiniteVolume/stokes_2d.cpp b/demos/FiniteVolume/stokes_2d.cpp index ea9373427..6f21b0d05 100644 --- a/demos/FiniteVolume/stokes_2d.cpp +++ b/demos/FiniteVolume/stokes_2d.cpp @@ -230,7 +230,7 @@ int main(int argc, char* argv[]) // Boundary conditions samurai::make_bc(velocity, - [](const auto& coord) + [](const auto&, const auto& coord) { const auto& x = coord[0]; const auto& y = coord[1]; @@ -240,7 +240,7 @@ int main(int argc, char* argv[]) }); samurai::make_bc(pressure, - [](const auto& coord) + [](const auto&, const auto& coord) { const auto& x = coord[0]; const auto& y = coord[1]; @@ -393,12 +393,12 @@ int main(int argc, char* argv[]) // Boundary conditions samurai::make_bc(velocity_np1, - [&](const auto& coord) + [&](const auto&, const auto& coord) { return exact_velocity(0, coord); }); samurai::make_bc(pressure_np1, - [&](const auto& coord) + [&](const auto&, const auto& coord) { return exact_normal_grad_pressure(0, coord); }); @@ -480,13 +480,13 @@ int main(int argc, char* argv[]) // Boundary conditions velocity_np1.get_bc().clear(); samurai::make_bc(velocity_np1, - [&](const auto& coord) + [&](const auto&, const auto& coord) { return exact_velocity(t_np1, coord); }); pressure_np1.get_bc().clear(); samurai::make_bc(pressure_np1, - [&](const auto& coord) + [&](const auto&, const auto& coord) { return exact_normal_grad_pressure(t_np1, coord); }); diff --git a/demos/highorder/main.cpp b/demos/highorder/main.cpp index 5ef594863..1e1c960bd 100644 --- a/demos/highorder/main.cpp +++ b/demos/highorder/main.cpp @@ -267,7 +267,7 @@ int main(int argc, char* argv[]) auto u = samurai::make_field("u", mesh); samurai::make_bc(u, - [](const auto& coord) + [](const auto&, const auto& coord) { const auto& x = coord[0]; const auto& y = coord[1]; diff --git a/demos/multigrid/test_cases.hpp b/demos/multigrid/test_cases.hpp index 1c4c56545..f91afce02 100644 --- a/demos/multigrid/test_cases.hpp +++ b/demos/multigrid/test_cases.hpp @@ -8,11 +8,12 @@ class TestCase public: static constexpr std::size_t dim = Field::dim; - using coords = xt::xtensor_fixed>; + using cell_t = typename Field::cell_t; + using coords_t = typename cell_t::coords_t; - using field_value_t = typename samurai::detail::return_type::type; - using field_function_t = typename samurai::FunctionBc::function_t; - using boundary_cond_t = field_function_t; + using boundary_cond_t = typename samurai::FunctionBc::function_t; + using field_value_t = typename samurai::FunctionBc::value_t; + using field_function_t = std::function; virtual bool solution_is_known() { @@ -41,9 +42,12 @@ class TestCase { if (solution_is_known()) { - return solution(); + return [&](const auto&, const auto& coords) + { + return solution()(coords); + }; } - return [](const coords&) + return [](const cell_t&, const coords_t&) { if constexpr (Field::size == 1) { @@ -80,7 +84,8 @@ class PolynomialTestCase : public TestCase using field_value_t = typename TestCase::field_value_t; using field_function_t = typename TestCase::field_function_t; using boundary_cond_t = typename TestCase::boundary_cond_t; - using coords = typename TestCase::coords; + using coords_t = typename TestCase::coords_t; + using cell_t = typename TestCase::cell_t; bool solution_is_known() override { @@ -145,7 +150,7 @@ class PolynomialTestCase : public TestCase boundary_cond_t dirichlet() override { - return [](const coords&) + return [](const cell_t&, const coords_t&) { if constexpr (Field::size == 1) { @@ -164,7 +169,7 @@ class PolynomialTestCase : public TestCase { if constexpr (dim == 1) { - return [](const coords& coord) + return [](const auto&, const coords_t& coord) { const auto& x = coord[0]; if (x == 0 || x == 1) @@ -180,11 +185,11 @@ class PolynomialTestCase : public TestCase } else if constexpr (dim == 2) { - return [](const auto& coord) + return [](const auto&, const auto& coord) { const auto& x = coord[0]; const auto& y = coord[1]; - double value; + double value = 0.; if (x == 0 || x == 1) { value = y * (y - 1); diff --git a/demos/p4est/simple_2d.cpp b/demos/p4est/simple_2d.cpp index 9c33610ac..9a40380b5 100644 --- a/demos/p4est/simple_2d.cpp +++ b/demos/p4est/simple_2d.cpp @@ -65,7 +65,7 @@ void refine_1(mesh_t& mesh, std::size_t max_level) samurai::for_each_interval(mesh, [&](std::size_t level, const auto& interval, const auto& index_yz) { - auto itag = static_cast(interval.start + interval.index); + auto itag = interval.start + interval.index; for (coord_index_t i = interval.start; i < interval.end; ++i) { if (cell_tag[itag]) @@ -165,7 +165,7 @@ void refine_2(mesh_t& mesh, std::size_t max_level) samurai::for_each_interval(mesh[mesh_id_t::cells], [&](std::size_t level, const auto& interval, const auto& index_yz) { - auto itag = static_cast(interval.start + interval.index); + auto itag = interval.start + interval.index; for (coord_index_t i = interval.start; i < interval.end; ++i) { if (cell_tag[itag]) diff --git a/demos/pablo/bubble_2d.cpp b/demos/pablo/bubble_2d.cpp index 50964e2cb..3b08d06f9 100644 --- a/demos/pablo/bubble_2d.cpp +++ b/demos/pablo/bubble_2d.cpp @@ -85,7 +85,7 @@ void update_mesh(Mesh& mesh, samurai::for_each_interval(mesh, [&](std::size_t level, const auto& interval, const auto& index_yz) { - auto itag = static_cast(interval.start + interval.index); + auto itag = interval.start + interval.index; for (int i = interval.start; i < interval.end; ++i) { if (tag[itag] & static_cast(samurai::CellFlag::refine)) diff --git a/demos/tutorial/AMR_1D_Burgers/step_4/update_field.hpp b/demos/tutorial/AMR_1D_Burgers/step_4/update_field.hpp index d1fafdfd1..696aef945 100644 --- a/demos/tutorial/AMR_1D_Burgers/step_4/update_field.hpp +++ b/demos/tutorial/AMR_1D_Burgers/step_4/update_field.hpp @@ -48,7 +48,7 @@ void update_field(Field& f, const Tag& tag, Mesh& new_mesh) samurai::for_each_interval(mesh[mesh_id_t::cells], [&](std::size_t level, const auto& interval, const auto&) { - auto itag = static_cast(interval.start + interval.index); + auto itag = interval.start + interval.index; for (coord_index_t i = interval.start; i < interval.end; ++i) { if (tag[itag] & static_cast(samurai::CellFlag::refine)) diff --git a/demos/tutorial/AMR_1D_Burgers/step_4/update_mesh.hpp b/demos/tutorial/AMR_1D_Burgers/step_4/update_mesh.hpp index 558595e3d..782161a62 100644 --- a/demos/tutorial/AMR_1D_Burgers/step_4/update_mesh.hpp +++ b/demos/tutorial/AMR_1D_Burgers/step_4/update_mesh.hpp @@ -41,7 +41,7 @@ bool update_mesh(Field& f, const Tag& tag) samurai::for_each_interval(mesh[mesh_id_t::cells], [&](std::size_t level, const auto& interval, const auto&) { - auto itag = static_cast(interval.start + interval.index); + auto itag = interval.start + interval.index; for (int i = interval.start; i < interval.end; ++i) { if (tag[itag] & static_cast(samurai::CellFlag::refine)) diff --git a/demos/tutorial/graduation_case_3.cpp b/demos/tutorial/graduation_case_3.cpp index 73893a106..432141d3e 100644 --- a/demos/tutorial/graduation_case_3.cpp +++ b/demos/tutorial/graduation_case_3.cpp @@ -139,7 +139,7 @@ int main(int argc, char* argv[]) [&](std::size_t level, const auto& interval, const auto& index) { auto j = index[0]; - auto itag = static_cast(interval.start + interval.index); + auto itag = interval.start + interval.index; for (int i = interval.start; i < interval.end; ++i) { if (tag[itag] && level < max_level) diff --git a/include/samurai/algorithm.hpp b/include/samurai/algorithm.hpp index 9147eda3d..5f73a8ee9 100644 --- a/include/samurai/algorithm.hpp +++ b/include/samurai/algorithm.hpp @@ -159,8 +159,9 @@ namespace samurai template inline void for_each_cell(const LevelCellArray& lca, Func&& f) { - using coord_index_t = typename TInterval::coord_index_t; - xt::xtensor_fixed> index; + using cell_t = Cell; + using index_value_t = typename cell_t::value_t; + typename cell_t::indices_t index; for (auto it = lca.cbegin(); it != lca.cend(); ++it) { @@ -169,10 +170,10 @@ namespace samurai index[d + 1] = it.index()[d]; } - for (coord_index_t i = it->start; i < it->end; ++i) + for (index_value_t i = it->start; i < it->end; ++i) { index[0] = i; - Cell cell{lca.level(), index, static_cast(it->index + i)}; + cell_t cell{lca.level(), index, it->index + i}; f(cell); } } @@ -181,10 +182,9 @@ namespace samurai template inline void for_each_cell(const LevelCellArray& lca, subset_operator set, Func&& f) { - using set_t = subset_operator; - using coord_index_t = typename set_t::coord_index_t; - - xt::xtensor_fixed> index; + using cell_t = Cell; + using index_value_t = typename cell_t::value_t; + typename cell_t::indices_t index; set( [&](const auto& interval, const auto& index_yz) @@ -192,10 +192,10 @@ namespace samurai index[0] = interval.start; auto cell_index = lca.get_index(index); xt::view(index, xt::range(1, _)) = index_yz; - for (coord_index_t i = interval.start; i < interval.end; ++i) + for (index_value_t i = interval.start; i < interval.end; ++i) { index[0] = i; - Cell cell{set.level(), index, cell_index++}; + cell_t cell{set.level(), index, cell_index++}; f(cell); } }); @@ -223,18 +223,19 @@ namespace samurai template inline void for_each_cell(const Mesh& mesh, std::size_t level, const typename Mesh::interval_t& i, const coord_type& index, Func&& f) { - using coord_index_t = typename Mesh::interval_t::coord_index_t; static constexpr std::size_t dim = Mesh::dim; + using cell_t = Cell; + using index_value_t = typename cell_t::value_t; + typename cell_t::indices_t coord; - xt::xtensor_fixed> coord; coord[0] = i.start; for (std::size_t d = 0; d < dim - 1; ++d) { coord[d + 1] = index[d]; } auto cell_index = mesh.get_index(level, coord); - Cell cell{level, coord, cell_index}; - for (coord_index_t ii = 0; ii < static_cast(i.size()); ++ii) + cell_t cell{level, coord, cell_index}; + for (index_value_t ii = 0; ii < static_cast(i.size()); ++ii) { f(cell); cell.indices[0]++; // increment x coordinate diff --git a/include/samurai/algorithm/update.hpp b/include/samurai/algorithm/update.hpp index 574dfaa8a..c6d2d924a 100644 --- a/include/samurai/algorithm/update.hpp +++ b/include/samurai/algorithm/update.hpp @@ -489,7 +489,7 @@ namespace samurai for_each_interval(mesh[mesh_id_t::cells], [&](std::size_t level, const auto& interval, const auto& index) { - auto itag = static_cast(interval.start + interval.index); + auto itag = interval.start + interval.index; for (auto i = interval.start; i < interval.end; ++i) { if (tag[itag] & static_cast(CellFlag::refine)) @@ -555,7 +555,7 @@ namespace samurai for_each_interval(mesh[mesh_id_t::cells], [&](std::size_t level, const auto& interval, const auto& index) { - auto itag = static_cast(interval.start + interval.index); + auto itag = interval.start + interval.index; for (value_t i = interval.start; i < interval.end; ++i) { if (tag[itag] & static_cast(CellFlag::refine)) diff --git a/include/samurai/bc.hpp b/include/samurai/bc.hpp index bcc61b6a6..ba3bc9907 100644 --- a/include/samurai/bc.hpp +++ b/include/samurai/bc.hpp @@ -80,11 +80,13 @@ namespace samurai //////////////////////// // BcValue definition // //////////////////////// - template + template struct BcValue { - using value_t = detail::return_type_t; - using coords_t = xt::xtensor_fixed>; + static constexpr std::size_t dim = Field::dim; + using value_t = detail::return_type_t; + using coords_t = xt::xtensor_fixed>; + using cell_t = typename Field::cell_t; virtual ~BcValue() = default; BcValue(const BcValue&) = delete; @@ -92,30 +94,31 @@ namespace samurai BcValue(BcValue&&) = delete; BcValue& operator=(BcValue&&) = delete; - virtual value_t get_value(const coords_t&) const = 0; - virtual std::unique_ptr clone() const = 0; - virtual BCVType type() const = 0; + virtual value_t get_value(const cell_t&, const coords_t&) const = 0; + virtual std::unique_ptr clone() const = 0; + virtual BCVType type() const = 0; protected: BcValue() = default; }; - template - class ConstantBc : public BcValue + template + class ConstantBc : public BcValue { public: - using base_t = BcValue; + using base_t = BcValue; using value_t = typename base_t::value_t; using coords_t = typename base_t::coords_t; + using cell_t = typename base_t::cell_t; template ConstantBc(const CT... v); ConstantBc(); - value_t get_value(const coords_t&) const override; + value_t get_value(const cell_t&, const coords_t&) const override; std::unique_ptr clone() const override; BCVType type() const override; @@ -124,19 +127,20 @@ namespace samurai value_t m_v; }; - template - class FunctionBc : public BcValue + template + class FunctionBc : public BcValue { public: - using base_t = BcValue; + using base_t = BcValue; using value_t = typename base_t::value_t; using coords_t = typename base_t::coords_t; - using function_t = std::function; + using cell_t = typename base_t::cell_t; + using function_t = std::function; FunctionBc(const function_t& f); - value_t get_value(const coords_t& coords) const override; + value_t get_value(const cell_t& cell_in, const coords_t& coords) const override; std::unique_ptr clone() const override; BCVType type() const override; @@ -149,57 +153,57 @@ namespace samurai // BcValue implementation // //////////////////////////// - template + template template - ConstantBc::ConstantBc(const CT... v) + ConstantBc::ConstantBc(const CT... v) : m_v{v...} { } - template - ConstantBc::ConstantBc() + template + ConstantBc::ConstantBc() { - detail::fill(m_v, T{0}); + detail::fill(m_v, typename Field::value_type{0}); } - template - inline auto ConstantBc::get_value(const coords_t&) const -> value_t + template + inline auto ConstantBc::get_value(const cell_t&, const coords_t&) const -> value_t { return m_v; } - template - auto ConstantBc::clone() const -> std::unique_ptr + template + auto ConstantBc::clone() const -> std::unique_ptr { return std::make_unique(m_v); } - template - inline BCVType ConstantBc::type() const + template + inline BCVType ConstantBc::type() const { return BCVType::constant; } - template - FunctionBc::FunctionBc(const function_t& f) + template + FunctionBc::FunctionBc(const function_t& f) : m_func(f) { } - template - inline auto FunctionBc::get_value(const coords_t& coords) const -> value_t + template + inline auto FunctionBc::get_value(const cell_t& cell_in, const coords_t& coords) const -> value_t { - return m_func(coords); + return m_func(cell_in, coords); } - template - auto FunctionBc::clone() const -> std::unique_ptr + template + auto FunctionBc::clone() const -> std::unique_ptr { return std::make_unique(m_func); } - template - inline BCVType FunctionBc::type() const + template + inline BCVType FunctionBc::type() const { return BCVType::function; } @@ -513,10 +517,11 @@ namespace samurai static constexpr std::size_t size = Field::size; using interval_t = typename Field::interval_t; - using bcvalue_t = BcValue; + using bcvalue_t = BcValue; using bcvalue_impl = std::unique_ptr; using value_t = typename bcvalue_t::value_t; using coords_t = typename bcvalue_t::coords_t; + using cell_t = typename bcvalue_t::cell_t; using bcregion_t = BcRegion; using lca_t = typename bcregion_t::lca_t; @@ -550,7 +555,7 @@ namespace samurai xt::xtensor_fixed> index); value_t constant_value(); - value_t value(const coords_t& coords) const; + value_t value(const cell_t& cell_in, const coords_t& coords) const; const auto& value() const; BCVType get_value_type() const; @@ -635,12 +640,16 @@ namespace samurai if (p_bcvalue->type() == BCVType::function) { coords_t coords; + cell_t cell_in; + const double dx = 1. / (1 << level); - coords[0] = dx * i.start + 0.5 * (1 + dir[0]) * dx; + cell_in.level = level; + coords[0] = dx * i.start + 0.5 * (1 + dir[0]) * dx; for (std::size_t d = 1; d < dim; ++d) { - coords[d] = dx * index[d - 1] + 0.5 * (1 + dir[d]) * dx; + coords[d] = dx * index[d - 1] + 0.5 * (1 + dir[d]) * dx; + cell_in.indices[d] = index[d - 1] + dir[d]; } if constexpr (size == 1) @@ -652,10 +661,14 @@ namespace samurai m_value.resize({i.size(), size}); } + cell_in.indices[0] = i.start + dir[0]; + cell_in.index = i.index; for (std::size_t ii = 0; ii < i.size(); ++ii) { - xt::view(m_value, ii) = p_bcvalue->get_value(coords); + xt::view(m_value, ii) = p_bcvalue->get_value(cell_in, coords); coords[0] += dx; + ++cell_in.indices[0]; + ++cell_in.index; } } } @@ -663,7 +676,7 @@ namespace samurai template inline auto Bc::constant_value() -> value_t { - return p_bcvalue->get_value({}); + return p_bcvalue->get_value({}, {}); } template @@ -673,9 +686,9 @@ namespace samurai } template - inline auto Bc::value(const coords_t& coords) const -> value_t + inline auto Bc::value(const cell_t& cell_in, const coords_t& coords) const -> value_t { - return p_bcvalue->get_value(coords); + return p_bcvalue->get_value(cell_in, coords); } template @@ -710,34 +723,22 @@ namespace samurai } template