From d935de5d8618569416095c7b94913486435b7144 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Del=20Pino?= <stephane.delpino44@gmail.com> Date: Mon, 19 Jul 2021 16:15:14 +0200 Subject: [PATCH] Reorganize MeshNodeBoundary: objects can no longer be built manually One now must use getMeshNodeBoundary which checks if the boundary exists. This also concerns - MeshFlatNodeBoundary (getMeshFlatNodeBoundary) and - MeshLineNodeBoundary (getMeshLineNodeBoundary) --- src/language/modules/SchemeModule.cpp | 2 +- src/{scheme => mesh}/IBoundaryDescriptor.hpp | 0 src/mesh/MeshNodeBoundary.hpp | 122 ++++++++++++++++- src/mesh/MeshRandomizer.hpp | 68 ++-------- src/scheme/AcousticSolver.cpp | 123 +++++++++--------- .../AxisBoundaryConditionDescriptor.hpp | 4 +- .../DirichletBoundaryConditionDescriptor.hpp | 4 +- .../FixedBoundaryConditionDescriptor.hpp | 4 +- .../FourierBoundaryConditionDescriptor.hpp | 4 +- .../FreeBoundaryConditionDescriptor.hpp | 4 +- src/scheme/IBoundaryConditionDescriptor.hpp | 4 + src/scheme/NamedBoundaryDescriptor.hpp | 2 +- .../NeumannBoundaryConditionDescriptor.hpp | 4 +- src/scheme/NumberedBoundaryDescriptor.hpp | 2 +- .../SymmetryBoundaryConditionDescriptor.hpp | 4 +- 15 files changed, 213 insertions(+), 138 deletions(-) rename src/{scheme => mesh}/IBoundaryDescriptor.hpp (100%) diff --git a/src/language/modules/SchemeModule.cpp b/src/language/modules/SchemeModule.cpp index 634ffe04f..81812defd 100644 --- a/src/language/modules/SchemeModule.cpp +++ b/src/language/modules/SchemeModule.cpp @@ -7,6 +7,7 @@ #include <language/utils/BuiltinFunctionEmbedder.hpp> #include <language/utils/TypeDescriptor.hpp> #include <mesh/Connectivity.hpp> +#include <mesh/IBoundaryDescriptor.hpp> #include <mesh/Mesh.hpp> #include <mesh/MeshData.hpp> #include <mesh/MeshDataManager.hpp> @@ -23,7 +24,6 @@ #include <scheme/FourierBoundaryConditionDescriptor.hpp> #include <scheme/FreeBoundaryConditionDescriptor.hpp> #include <scheme/IBoundaryConditionDescriptor.hpp> -#include <scheme/IBoundaryDescriptor.hpp> #include <scheme/IDiscreteFunction.hpp> #include <scheme/IDiscreteFunctionDescriptor.hpp> #include <scheme/NamedBoundaryDescriptor.hpp> diff --git a/src/scheme/IBoundaryDescriptor.hpp b/src/mesh/IBoundaryDescriptor.hpp similarity index 100% rename from src/scheme/IBoundaryDescriptor.hpp rename to src/mesh/IBoundaryDescriptor.hpp diff --git a/src/mesh/MeshNodeBoundary.hpp b/src/mesh/MeshNodeBoundary.hpp index 0743d2d95..ab98ded0e 100644 --- a/src/mesh/MeshNodeBoundary.hpp +++ b/src/mesh/MeshNodeBoundary.hpp @@ -4,9 +4,11 @@ #include <Kokkos_Vector.hpp> #include <algebra/TinyMatrix.hpp> #include <algebra/TinyVector.hpp> +#include <mesh/Connectivity.hpp> #include <mesh/ConnectivityMatrix.hpp> -#include <mesh/IConnectivity.hpp> +#include <mesh/IBoundaryDescriptor.hpp> #include <mesh/ItemValue.hpp> +#include <mesh/Mesh.hpp> #include <mesh/RefItemList.hpp> #include <utils/Array.hpp> #include <utils/Exceptions.hpp> @@ -23,6 +25,10 @@ class MeshNodeBoundary // clazy:exclude=copyable-polymorphic std::array<TinyVector<Dimension>, Dimension*(Dimension - 1)> _getBounds(const MeshType& mesh) const; public: + template <typename MeshType> + friend MeshNodeBoundary<MeshType::Dimension> getMeshNodeBoundary(const MeshType& mesh, + const IBoundaryDescriptor& boundary_descriptor); + MeshNodeBoundary& operator=(const MeshNodeBoundary&) = default; MeshNodeBoundary& operator=(MeshNodeBoundary&&) = default; @@ -32,6 +38,7 @@ class MeshNodeBoundary // clazy:exclude=copyable-polymorphic return m_node_list; } + protected: template <typename MeshType> MeshNodeBoundary(const MeshType& mesh, const RefFaceList& ref_face_list) : m_boundary_name(ref_face_list.refId().tagName()) @@ -146,6 +153,7 @@ class MeshNodeBoundary // clazy:exclude=copyable-polymorphic static_assert(Dimension == MeshType::Dimension); } + public: MeshNodeBoundary(const MeshNodeBoundary&) = default; MeshNodeBoundary(MeshNodeBoundary&&) = default; @@ -153,6 +161,41 @@ class MeshNodeBoundary // clazy:exclude=copyable-polymorphic virtual ~MeshNodeBoundary() = default; }; +template <typename MeshType> +MeshNodeBoundary<MeshType::Dimension> +getMeshNodeBoundary(const MeshType& mesh, const IBoundaryDescriptor& boundary_descriptor) +{ + for (size_t i_ref_node_list = 0; i_ref_node_list < mesh.connectivity().template numberOfRefItemList<ItemType::node>(); + ++i_ref_node_list) { + const auto& ref_node_list = mesh.connectivity().template refItemList<ItemType::node>(i_ref_node_list); + const RefId& ref = ref_node_list.refId(); + if (ref == boundary_descriptor) { + return MeshNodeBoundary<MeshType::Dimension>{mesh, ref_node_list}; + } + } + for (size_t i_ref_edge_list = 0; i_ref_edge_list < mesh.connectivity().template numberOfRefItemList<ItemType::edge>(); + ++i_ref_edge_list) { + const auto& ref_edge_list = mesh.connectivity().template refItemList<ItemType::edge>(i_ref_edge_list); + const RefId& ref = ref_edge_list.refId(); + if (ref == boundary_descriptor) { + return MeshNodeBoundary<MeshType::Dimension>{mesh, ref_edge_list}; + } + } + for (size_t i_ref_face_list = 0; i_ref_face_list < mesh.connectivity().template numberOfRefItemList<ItemType::face>(); + ++i_ref_face_list) { + const auto& ref_face_list = mesh.connectivity().template refItemList<ItemType::face>(i_ref_face_list); + const RefId& ref = ref_face_list.refId(); + if (ref == boundary_descriptor) { + return MeshNodeBoundary<MeshType::Dimension>{mesh, ref_face_list}; + } + } + + std::ostringstream ost; + ost << "cannot find surface with name " << rang::fgB::red << boundary_descriptor << rang::style::reset; + + throw NormalError(ost.str()); +} + template <> template <typename MeshType> std::array<TinyVector<2>, 2> @@ -372,6 +415,12 @@ class MeshFlatNodeBoundary : public MeshNodeBoundary<Dimension> // clazy:exclu MeshFlatNodeBoundary& operator=(const MeshFlatNodeBoundary&) = default; MeshFlatNodeBoundary& operator=(MeshFlatNodeBoundary&&) = default; + template <typename MeshType> + friend MeshFlatNodeBoundary<MeshType::Dimension> getMeshFlatNodeBoundary( + const MeshType& mesh, + const IBoundaryDescriptor& boundary_descriptor); + + private: template <typename MeshType> MeshFlatNodeBoundary(const MeshType& mesh, const RefFaceList& ref_face_list) : MeshNodeBoundary<Dimension>(mesh, ref_face_list), m_outgoing_normal(_getOutgoingNormal(mesh)) @@ -386,12 +435,40 @@ class MeshFlatNodeBoundary : public MeshNodeBoundary<Dimension> // clazy:exclu ; } + public: MeshFlatNodeBoundary() = default; MeshFlatNodeBoundary(const MeshFlatNodeBoundary&) = default; MeshFlatNodeBoundary(MeshFlatNodeBoundary&&) = default; virtual ~MeshFlatNodeBoundary() = default; }; +template <typename MeshType> +MeshFlatNodeBoundary<MeshType::Dimension> +getMeshFlatNodeBoundary(const MeshType& mesh, const IBoundaryDescriptor& boundary_descriptor) +{ + for (size_t i_ref_node_list = 0; i_ref_node_list < mesh.connectivity().template numberOfRefItemList<ItemType::node>(); + ++i_ref_node_list) { + const auto& ref_node_list = mesh.connectivity().template refItemList<ItemType::node>(i_ref_node_list); + const RefId& ref = ref_node_list.refId(); + if (ref == boundary_descriptor) { + return MeshFlatNodeBoundary<MeshType::Dimension>{mesh, ref_node_list}; + } + } + for (size_t i_ref_face_list = 0; i_ref_face_list < mesh.connectivity().template numberOfRefItemList<ItemType::face>(); + ++i_ref_face_list) { + const auto& ref_face_list = mesh.connectivity().template refItemList<ItemType::face>(i_ref_face_list); + const RefId& ref = ref_face_list.refId(); + if (ref == boundary_descriptor) { + return MeshFlatNodeBoundary<MeshType::Dimension>{mesh, ref_face_list}; + } + } + + std::ostringstream ost; + ost << "cannot find surface with name " << rang::fgB::red << boundary_descriptor << rang::style::reset; + + throw NormalError(ost.str()); +} + template <> template <typename MeshType> PUGS_INLINE TinyVector<1, double> @@ -687,6 +764,12 @@ class MeshLineNodeBoundary : public MeshNodeBoundary<Dimension> // clazy:exclu } public: + template <typename MeshType> + friend MeshLineNodeBoundary<MeshType::Dimension> getMeshLineNodeBoundary( + const MeshType& mesh, + const IBoundaryDescriptor& boundary_descriptor); + + PUGS_INLINE const Rd& direction() const { @@ -696,6 +779,7 @@ class MeshLineNodeBoundary : public MeshNodeBoundary<Dimension> // clazy:exclu MeshLineNodeBoundary& operator=(const MeshLineNodeBoundary&) = default; MeshLineNodeBoundary& operator=(MeshLineNodeBoundary&&) = default; + private: template <typename MeshType> MeshLineNodeBoundary(const MeshType& mesh, const RefEdgeList& ref_edge_list) : MeshNodeBoundary<Dimension>(mesh, ref_edge_list), m_direction(_getDirection(mesh)) @@ -717,12 +801,48 @@ class MeshLineNodeBoundary : public MeshNodeBoundary<Dimension> // clazy:exclu ; } + public: MeshLineNodeBoundary() = default; MeshLineNodeBoundary(const MeshLineNodeBoundary&) = default; MeshLineNodeBoundary(MeshLineNodeBoundary&&) = default; virtual ~MeshLineNodeBoundary() = default; }; +template <typename MeshType> +MeshLineNodeBoundary<MeshType::Dimension> +getMeshLineNodeBoundary(const MeshType& mesh, const IBoundaryDescriptor& boundary_descriptor) +{ + for (size_t i_ref_node_list = 0; i_ref_node_list < mesh.connectivity().template numberOfRefItemList<ItemType::node>(); + ++i_ref_node_list) { + const auto& ref_node_list = mesh.connectivity().template refItemList<ItemType::node>(i_ref_node_list); + const RefId& ref = ref_node_list.refId(); + if (ref == boundary_descriptor) { + return MeshLineNodeBoundary<MeshType::Dimension>{mesh, ref_node_list}; + } + } + for (size_t i_ref_edge_list = 0; i_ref_edge_list < mesh.connectivity().template numberOfRefItemList<ItemType::edge>(); + ++i_ref_edge_list) { + const auto& ref_edge_list = mesh.connectivity().template refItemList<ItemType::edge>(i_ref_edge_list); + const RefId& ref = ref_edge_list.refId(); + if (ref == boundary_descriptor) { + return MeshLineNodeBoundary<MeshType::Dimension>{mesh, ref_edge_list}; + } + } + for (size_t i_ref_face_list = 0; i_ref_face_list < mesh.connectivity().template numberOfRefItemList<ItemType::face>(); + ++i_ref_face_list) { + const auto& ref_face_list = mesh.connectivity().template refItemList<ItemType::face>(i_ref_face_list); + const RefId& ref = ref_face_list.refId(); + if (ref == boundary_descriptor) { + return MeshLineNodeBoundary<MeshType::Dimension>{mesh, ref_face_list}; + } + } + + std::ostringstream ost; + ost << "cannot find surface with name " << rang::fgB::red << boundary_descriptor << rang::style::reset; + + throw NormalError(ost.str()); +} + template <> template <typename MeshType> PUGS_INLINE TinyVector<1> diff --git a/src/mesh/MeshRandomizer.hpp b/src/mesh/MeshRandomizer.hpp index b6bfe625b..aa2258c59 100644 --- a/src/mesh/MeshRandomizer.hpp +++ b/src/mesh/MeshRandomizer.hpp @@ -43,82 +43,32 @@ class MeshRandomizer { BoundaryConditionList bc_list; - constexpr ItemType EdgeType = [] { - if constexpr (Dimension == 3) { - return ItemType::edge; - } else if constexpr (Dimension == 2) { - return ItemType::face; - } else { - return ItemType::node; - } - }(); - - constexpr ItemType FaceType = [] { - if constexpr (Dimension > 1) { - return ItemType::face; - } else { - return ItemType::node; - } - }(); - for (const auto& bc_descriptor : bc_descriptor_list) { - bool is_valid_boundary_condition = true; - switch (bc_descriptor->type()) { case IBoundaryConditionDescriptor::Type::axis: { - const AxisBoundaryConditionDescriptor& axis_bc_descriptor = - dynamic_cast<const AxisBoundaryConditionDescriptor&>(*bc_descriptor); - for (size_t i_ref_edge_list = 0; i_ref_edge_list < mesh.connectivity().template numberOfRefItemList<EdgeType>(); - ++i_ref_edge_list) { - const auto& ref_edge_list = mesh.connectivity().template refItemList<EdgeType>(i_ref_edge_list); - const RefId& ref = ref_edge_list.refId(); - if (ref == axis_bc_descriptor.boundaryDescriptor()) { - if constexpr (Dimension == 1) { - bc_list.emplace_back(FixedBoundaryCondition{MeshNodeBoundary<Dimension>{mesh, ref_edge_list}}); - } else { - bc_list.emplace_back(AxisBoundaryCondition{MeshLineNodeBoundary<Dimension>(mesh, ref_edge_list)}); - } - } + if constexpr (Dimension == 1) { + bc_list.emplace_back(FixedBoundaryCondition{getMeshNodeBoundary(mesh, bc_descriptor->boundaryDescriptor())}); + } else { + bc_list.emplace_back( + AxisBoundaryCondition{getMeshLineNodeBoundary(mesh, bc_descriptor->boundaryDescriptor())}); } - is_valid_boundary_condition = true; break; } case IBoundaryConditionDescriptor::Type::symmetry: { - const SymmetryBoundaryConditionDescriptor& sym_bc_descriptor = - dynamic_cast<const SymmetryBoundaryConditionDescriptor&>(*bc_descriptor); - for (size_t i_ref_face_list = 0; i_ref_face_list < mesh.connectivity().template numberOfRefItemList<FaceType>(); - ++i_ref_face_list) { - const auto& ref_face_list = mesh.connectivity().template refItemList<FaceType>(i_ref_face_list); - const RefId& ref = ref_face_list.refId(); - if (ref == sym_bc_descriptor.boundaryDescriptor()) { - bc_list.emplace_back(SymmetryBoundaryCondition{MeshFlatNodeBoundary<Dimension>(mesh, ref_face_list)}); - } - } - is_valid_boundary_condition = true; + bc_list.emplace_back( + SymmetryBoundaryCondition{getMeshFlatNodeBoundary(mesh, bc_descriptor->boundaryDescriptor())}); break; } case IBoundaryConditionDescriptor::Type::fixed: { - const FixedBoundaryConditionDescriptor& fixed_bc_descriptor = - dynamic_cast<const FixedBoundaryConditionDescriptor&>(*bc_descriptor); - for (size_t i_ref_face_list = 0; i_ref_face_list < mesh.connectivity().template numberOfRefItemList<FaceType>(); - ++i_ref_face_list) { - const auto& ref_face_list = mesh.connectivity().template refItemList<FaceType>(i_ref_face_list); - const RefId& ref = ref_face_list.refId(); - if (ref == fixed_bc_descriptor.boundaryDescriptor()) { - bc_list.emplace_back(FixedBoundaryCondition{MeshNodeBoundary<Dimension>{mesh, ref_face_list}}); - } - } + bc_list.emplace_back(FixedBoundaryCondition{getMeshNodeBoundary(mesh, bc_descriptor->boundaryDescriptor())}); break; } default: { - is_valid_boundary_condition = false; - } - } - if (not is_valid_boundary_condition) { std::ostringstream error_msg; error_msg << *bc_descriptor << " is an invalid boundary condition for mesh randomizer"; throw NormalError(error_msg.str()); } + } } return bc_list; diff --git a/src/scheme/AcousticSolver.cpp b/src/scheme/AcousticSolver.cpp index 0ad9b7901..7bd97aef4 100644 --- a/src/scheme/AcousticSolver.cpp +++ b/src/scheme/AcousticSolver.cpp @@ -6,6 +6,7 @@ #include <scheme/DirichletBoundaryConditionDescriptor.hpp> #include <scheme/DiscreteFunctionP0.hpp> #include <scheme/DiscreteFunctionUtils.hpp> +#include <scheme/FixedBoundaryConditionDescriptor.hpp> #include <scheme/IBoundaryConditionDescriptor.hpp> #include <scheme/IDiscreteFunction.hpp> #include <scheme/IDiscreteFunctionDescriptor.hpp> @@ -68,12 +69,13 @@ class AcousticSolverHandler::AcousticSolver final : public AcousticSolverHandler using DiscreteScalarFunction = DiscreteFunctionP0<Dimension, double>; using DiscreteVectorFunction = DiscreteFunctionP0<Dimension, Rd>; + class FixedBoundaryCondition; class PressureBoundaryCondition; class SymmetryBoundaryCondition; class VelocityBoundaryCondition; - using BoundaryCondition = - std::variant<PressureBoundaryCondition, SymmetryBoundaryCondition, VelocityBoundaryCondition>; + using BoundaryCondition = std:: + variant<FixedBoundaryCondition, PressureBoundaryCondition, SymmetryBoundaryCondition, VelocityBoundaryCondition>; using BoundaryConditionList = std::vector<BoundaryCondition>; @@ -83,22 +85,8 @@ class AcousticSolverHandler::AcousticSolver final : public AcousticSolverHandler NodeValue<const Rd> m_ur; NodeValuePerCell<const Rd> m_Fjr; - CellValue<const double> - _getRhoC(const DiscreteScalarFunction& rho, const DiscreteScalarFunction& c) - { - Assert(rho.mesh() == c.mesh()); - - const MeshType& mesh = dynamic_cast<const MeshType&>(*rho.mesh()); - - CellValue<double> rhoc{mesh.connectivity()}; - parallel_for( - mesh.numberOfCells(), PUGS_LAMBDA(CellId cell_id) { rhoc[cell_id] = rho[cell_id] * c[cell_id]; }); - - return rhoc; - } - NodeValuePerCell<const Rdxd> - _computeGlaceAjr(const MeshType& mesh, const CellValue<const double>& rhoc) + _computeGlaceAjr(const MeshType& mesh, const DiscreteScalarFunction& rhoc) { MeshDataType& mesh_data = MeshDataManager::instance().getMeshData(mesh); @@ -120,7 +108,7 @@ class AcousticSolverHandler::AcousticSolver final : public AcousticSolverHandler } NodeValuePerCell<const Rdxd> - _computeEucclhydAjr(const MeshType& mesh, const CellValue<const double>& rhoc) + _computeEucclhydAjr(const MeshType& mesh, const DiscreteScalarFunction& rhoc) { MeshDataType& mesh_data = MeshDataManager::instance().getMeshData(mesh); @@ -168,7 +156,7 @@ class AcousticSolverHandler::AcousticSolver final : public AcousticSolverHandler } NodeValuePerCell<const Rdxd> - _computeAjr(const MeshType& mesh, const CellValue<const double>& rhoc) + _computeAjr(const MeshType& mesh, const DiscreteScalarFunction& rhoc) { if constexpr (Dimension == 1) { return _computeGlaceAjr(mesh, rhoc); @@ -264,42 +252,26 @@ class AcousticSolverHandler::AcousticSolver final : public AcousticSolverHandler switch (bc_descriptor->type()) { case IBoundaryConditionDescriptor::Type::symmetry: { - const SymmetryBoundaryConditionDescriptor& sym_bc_descriptor = - dynamic_cast<const SymmetryBoundaryConditionDescriptor&>(*bc_descriptor); - for (size_t i_ref_face_list = 0; i_ref_face_list < mesh.connectivity().template numberOfRefItemList<FaceType>(); - ++i_ref_face_list) { - const auto& ref_face_list = mesh.connectivity().template refItemList<FaceType>(i_ref_face_list); - const RefId& ref = ref_face_list.refId(); - if (ref == sym_bc_descriptor.boundaryDescriptor()) { - SymmetryBoundaryCondition{MeshFlatNodeBoundary<Dimension>(mesh, ref_face_list)}; - bc_list.push_back(SymmetryBoundaryCondition{MeshFlatNodeBoundary<Dimension>(mesh, ref_face_list)}); - } - } - is_valid_boundary_condition = true; + bc_list.push_back( + SymmetryBoundaryCondition(getMeshFlatNodeBoundary(mesh, bc_descriptor->boundaryDescriptor()))); + break; + } + case IBoundaryConditionDescriptor::Type::fixed: { + bc_list.push_back(FixedBoundaryCondition(getMeshNodeBoundary(mesh, bc_descriptor->boundaryDescriptor()))); break; } - case IBoundaryConditionDescriptor::Type::dirichlet: { const DirichletBoundaryConditionDescriptor& dirichlet_bc_descriptor = dynamic_cast<const DirichletBoundaryConditionDescriptor&>(*bc_descriptor); if (dirichlet_bc_descriptor.name() == "velocity") { - for (size_t i_ref_face_list = 0; - i_ref_face_list < mesh.connectivity().template numberOfRefItemList<FaceType>(); ++i_ref_face_list) { - const auto& ref_face_list = mesh.connectivity().template refItemList<FaceType>(i_ref_face_list); - const RefId& ref = ref_face_list.refId(); - if (ref == dirichlet_bc_descriptor.boundaryDescriptor()) { - MeshNodeBoundary<Dimension> mesh_node_boundary{mesh, ref_face_list}; - - const FunctionSymbolId velocity_id = dirichlet_bc_descriptor.rhsSymbolId(); - - const auto& node_list = mesh_node_boundary.nodeList(); + MeshNodeBoundary<Dimension> mesh_node_boundary = + getMeshNodeBoundary(mesh, dirichlet_bc_descriptor.boundaryDescriptor()); - Array<const TinyVector<Dimension>> value_list = InterpolateItemValue<TinyVector<Dimension>( - TinyVector<Dimension>)>::template interpolate<ItemType::node>(velocity_id, mesh.xr(), node_list); + Array<const TinyVector<Dimension>> value_list = InterpolateItemValue<TinyVector<Dimension>( + TinyVector<Dimension>)>::template interpolate<ItemType::node>(dirichlet_bc_descriptor.rhsSymbolId(), + mesh.xr(), mesh_node_boundary.nodeList()); - bc_list.push_back(VelocityBoundaryCondition{node_list, value_list}); - } - } + bc_list.push_back(VelocityBoundaryCondition{mesh_node_boundary, value_list}); } else if (dirichlet_bc_descriptor.name() == "pressure") { for (size_t i_ref_face_list = 0; i_ref_face_list < mesh.connectivity().template numberOfRefItemList<FaceType>(); ++i_ref_face_list) { @@ -401,8 +373,7 @@ class AcousticSolverHandler::AcousticSolver final : public AcousticSolverHandler const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>& bc_descriptor_list) : m_solver_type{solver_type}, m_boundary_condition_list{this->_getBCList(mesh, bc_descriptor_list)} { - CellValue<const double> rhoc = this->_getRhoC(rho, c); - NodeValuePerCell<const Rdxd> Ajr = this->_computeAjr(mesh, rhoc); + NodeValuePerCell<const Rdxd> Ajr = this->_computeAjr(mesh, rho * c); NodeValue<Rdxd> Ar = this->_computeAr(mesh, Ajr); NodeValue<Rd> br = this->_computeBr(mesh, Ajr, u, p); @@ -485,10 +456,9 @@ class AcousticSolverHandler::AcousticSolver final : public AcousticSolverHandler throw NormalError("acoustic solver expects P0 functions"); } - return this->apply(dt, dynamic_cast<const MeshType&>(*i_mesh), - *std::dynamic_pointer_cast<const DiscreteScalarFunction>(rho), - *std::dynamic_pointer_cast<const DiscreteVectorFunction>(u), - *std::dynamic_pointer_cast<const DiscreteScalarFunction>(E)); + return this->apply(dt, dynamic_cast<const MeshType&>(*i_mesh), dynamic_cast<const DiscreteScalarFunction&>(*rho), + dynamic_cast<const DiscreteVectorFunction&>(*u), + dynamic_cast<const DiscreteScalarFunction&>(*E)); } AcousticSolver(SolverType solver_type, @@ -500,10 +470,10 @@ class AcousticSolverHandler::AcousticSolver final : public AcousticSolverHandler const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>& bc_descriptor_list) : AcousticSolver{solver_type, dynamic_cast<const MeshType&>(*mesh), - *std::dynamic_pointer_cast<const DiscreteScalarFunction>(rho), - *std::dynamic_pointer_cast<const DiscreteScalarFunction>(c), - *std::dynamic_pointer_cast<const DiscreteVectorFunction>(u), - *std::dynamic_pointer_cast<const DiscreteScalarFunction>(p), + dynamic_cast<const DiscreteScalarFunction&>(*rho), + dynamic_cast<const DiscreteScalarFunction&>(*c), + dynamic_cast<const DiscreteVectorFunction&>(*u), + dynamic_cast<const DiscreteScalarFunction&>(*p), bc_descriptor_list} {} @@ -624,12 +594,41 @@ AcousticSolverHandler::AcousticSolver<Dimension>::_applyVelocityBC(NodeValue<Rdx Ar[node_id] = identity; br[node_id] = value; }); + } else if constexpr (std::is_same_v<FixedBoundaryCondition, T>) { + const auto& node_list = bc.nodeList(); + parallel_for( + node_list.size(), PUGS_LAMBDA(size_t i_node) { + NodeId node_id = node_list[i_node]; + + Ar[node_id] = identity; + br[node_id] = zero; + }); } }, boundary_condition); } } +template <size_t Dimension> +class AcousticSolverHandler::AcousticSolver<Dimension>::FixedBoundaryCondition +{ + private: + const MeshNodeBoundary<Dimension> m_mesh_node_boundary; + + public: + const Array<const NodeId>& + nodeList() const + { + return m_mesh_node_boundary.nodeList(); + } + + FixedBoundaryCondition(const MeshNodeBoundary<Dimension> mesh_node_boundary) + : m_mesh_node_boundary{mesh_node_boundary} + {} + + ~FixedBoundaryCondition() = default; +}; + template <size_t Dimension> class AcousticSolverHandler::AcousticSolver<Dimension>::PressureBoundaryCondition { @@ -688,14 +687,15 @@ template <size_t Dimension> class AcousticSolverHandler::AcousticSolver<Dimension>::VelocityBoundaryCondition { private: + const MeshNodeBoundary<Dimension> m_mesh_node_boundary; + const Array<const TinyVector<Dimension>> m_value_list; - const Array<const NodeId> m_node_list; public: const Array<const NodeId>& nodeList() const { - return m_node_list; + return m_mesh_node_boundary.nodeList(); } const Array<const TinyVector<Dimension>>& @@ -704,8 +704,9 @@ class AcousticSolverHandler::AcousticSolver<Dimension>::VelocityBoundaryConditio return m_value_list; } - VelocityBoundaryCondition(const Array<const NodeId>& node_list, const Array<const TinyVector<Dimension>>& value_list) - : m_value_list{value_list}, m_node_list{node_list} + VelocityBoundaryCondition(const MeshNodeBoundary<Dimension>& mesh_node_boundary, + const Array<const TinyVector<Dimension>>& value_list) + : m_mesh_node_boundary{mesh_node_boundary}, m_value_list{value_list} {} ~VelocityBoundaryCondition() = default; diff --git a/src/scheme/AxisBoundaryConditionDescriptor.hpp b/src/scheme/AxisBoundaryConditionDescriptor.hpp index a03a4bcdd..07ab3be48 100644 --- a/src/scheme/AxisBoundaryConditionDescriptor.hpp +++ b/src/scheme/AxisBoundaryConditionDescriptor.hpp @@ -1,8 +1,8 @@ #ifndef AXIS_BOUNDARY_CONDITION_DESCRIPTOR_HPP #define AXIS_BOUNDARY_CONDITION_DESCRIPTOR_HPP +#include <mesh/IBoundaryDescriptor.hpp> #include <scheme/IBoundaryConditionDescriptor.hpp> -#include <scheme/IBoundaryDescriptor.hpp> #include <memory> @@ -20,7 +20,7 @@ class AxisBoundaryConditionDescriptor : public IBoundaryConditionDescriptor public: const IBoundaryDescriptor& - boundaryDescriptor() const + boundaryDescriptor() const final { return *m_boundary_descriptor; } diff --git a/src/scheme/DirichletBoundaryConditionDescriptor.hpp b/src/scheme/DirichletBoundaryConditionDescriptor.hpp index 5fa6c42f9..36f95df0d 100644 --- a/src/scheme/DirichletBoundaryConditionDescriptor.hpp +++ b/src/scheme/DirichletBoundaryConditionDescriptor.hpp @@ -2,8 +2,8 @@ #define DIRICHLET_BOUNDARY_CONDITION_DESCRIPTOR_HPP #include <language/utils/FunctionSymbolId.hpp> +#include <mesh/IBoundaryDescriptor.hpp> #include <scheme/IBoundaryConditionDescriptor.hpp> -#include <scheme/IBoundaryDescriptor.hpp> #include <memory> @@ -36,7 +36,7 @@ class DirichletBoundaryConditionDescriptor : public IBoundaryConditionDescriptor } const IBoundaryDescriptor& - boundaryDescriptor() const + boundaryDescriptor() const final { return *m_boundary_descriptor; } diff --git a/src/scheme/FixedBoundaryConditionDescriptor.hpp b/src/scheme/FixedBoundaryConditionDescriptor.hpp index 9167c24be..b69648e38 100644 --- a/src/scheme/FixedBoundaryConditionDescriptor.hpp +++ b/src/scheme/FixedBoundaryConditionDescriptor.hpp @@ -2,8 +2,8 @@ #define FIXED_BOUNDARY_CONDITION_DESCRIPTOR_HPP #include <language/utils/FunctionSymbolId.hpp> +#include <mesh/IBoundaryDescriptor.hpp> #include <scheme/IBoundaryConditionDescriptor.hpp> -#include <scheme/IBoundaryDescriptor.hpp> #include <memory> @@ -23,7 +23,7 @@ class FixedBoundaryConditionDescriptor : public IBoundaryConditionDescriptor public: const IBoundaryDescriptor& - boundaryDescriptor() const + boundaryDescriptor() const final { return *m_boundary_descriptor; } diff --git a/src/scheme/FourierBoundaryConditionDescriptor.hpp b/src/scheme/FourierBoundaryConditionDescriptor.hpp index e7aeb830c..c9d75883d 100644 --- a/src/scheme/FourierBoundaryConditionDescriptor.hpp +++ b/src/scheme/FourierBoundaryConditionDescriptor.hpp @@ -2,8 +2,8 @@ #define FOURIER_BOUNDARY_CONDITION_DESCRIPTOR_HPP #include <language/utils/FunctionSymbolId.hpp> +#include <mesh/IBoundaryDescriptor.hpp> #include <scheme/IBoundaryConditionDescriptor.hpp> -#include <scheme/IBoundaryDescriptor.hpp> #include <memory> @@ -43,7 +43,7 @@ class FourierBoundaryConditionDescriptor : public IBoundaryConditionDescriptor } const IBoundaryDescriptor& - boundaryDescriptor() const + boundaryDescriptor() const final { return *m_boundary_descriptor; } diff --git a/src/scheme/FreeBoundaryConditionDescriptor.hpp b/src/scheme/FreeBoundaryConditionDescriptor.hpp index b0eb2ceb2..2d46f2a36 100644 --- a/src/scheme/FreeBoundaryConditionDescriptor.hpp +++ b/src/scheme/FreeBoundaryConditionDescriptor.hpp @@ -1,8 +1,8 @@ #ifndef FREE_BOUNDARY_CONDITION_DESCRIPTOR_HPP #define FREE_BOUNDARY_CONDITION_DESCRIPTOR_HPP +#include <mesh/IBoundaryDescriptor.hpp> #include <scheme/IBoundaryConditionDescriptor.hpp> -#include <scheme/IBoundaryDescriptor.hpp> #include <memory> @@ -20,7 +20,7 @@ class FreeBoundaryConditionDescriptor : public IBoundaryConditionDescriptor public: const IBoundaryDescriptor& - boundaryDescriptor() const + boundaryDescriptor() const final { return *m_boundary_descriptor; } diff --git a/src/scheme/IBoundaryConditionDescriptor.hpp b/src/scheme/IBoundaryConditionDescriptor.hpp index bf92cd450..c0ea161db 100644 --- a/src/scheme/IBoundaryConditionDescriptor.hpp +++ b/src/scheme/IBoundaryConditionDescriptor.hpp @@ -3,6 +3,8 @@ #include <iostream> +class IBoundaryDescriptor; + class IBoundaryConditionDescriptor { public: @@ -27,6 +29,8 @@ class IBoundaryConditionDescriptor return bcd._write(os); } + virtual const IBoundaryDescriptor& boundaryDescriptor() const = 0; + virtual Type type() const = 0; IBoundaryConditionDescriptor() = default; diff --git a/src/scheme/NamedBoundaryDescriptor.hpp b/src/scheme/NamedBoundaryDescriptor.hpp index db88ee4a0..5d8959261 100644 --- a/src/scheme/NamedBoundaryDescriptor.hpp +++ b/src/scheme/NamedBoundaryDescriptor.hpp @@ -1,7 +1,7 @@ #ifndef NAMED_BOUNDARY_DESCRIPTOR_HPP #define NAMED_BOUNDARY_DESCRIPTOR_HPP -#include <scheme/IBoundaryDescriptor.hpp> +#include <mesh/IBoundaryDescriptor.hpp> #include <iostream> #include <string> diff --git a/src/scheme/NeumannBoundaryConditionDescriptor.hpp b/src/scheme/NeumannBoundaryConditionDescriptor.hpp index edc1b1fb3..597ab95e7 100644 --- a/src/scheme/NeumannBoundaryConditionDescriptor.hpp +++ b/src/scheme/NeumannBoundaryConditionDescriptor.hpp @@ -2,8 +2,8 @@ #define NEUMANN_BOUNDARY_CONDITION_DESCRIPTOR_HPP #include <language/utils/FunctionSymbolId.hpp> +#include <mesh/IBoundaryDescriptor.hpp> #include <scheme/IBoundaryConditionDescriptor.hpp> -#include <scheme/IBoundaryDescriptor.hpp> #include <memory> @@ -36,7 +36,7 @@ class NeumannBoundaryConditionDescriptor : public IBoundaryConditionDescriptor } const IBoundaryDescriptor& - boundaryDescriptor() const + boundaryDescriptor() const final { return *m_boundary_descriptor; } diff --git a/src/scheme/NumberedBoundaryDescriptor.hpp b/src/scheme/NumberedBoundaryDescriptor.hpp index 4ed9a2628..47aa7fa53 100644 --- a/src/scheme/NumberedBoundaryDescriptor.hpp +++ b/src/scheme/NumberedBoundaryDescriptor.hpp @@ -1,7 +1,7 @@ #ifndef NUMBERED_BOUNDARY_DESCRIPTOR_HPP #define NUMBERED_BOUNDARY_DESCRIPTOR_HPP -#include <scheme/IBoundaryDescriptor.hpp> +#include <mesh/IBoundaryDescriptor.hpp> #include <iostream> diff --git a/src/scheme/SymmetryBoundaryConditionDescriptor.hpp b/src/scheme/SymmetryBoundaryConditionDescriptor.hpp index f5657ad58..9364090dd 100644 --- a/src/scheme/SymmetryBoundaryConditionDescriptor.hpp +++ b/src/scheme/SymmetryBoundaryConditionDescriptor.hpp @@ -1,8 +1,8 @@ #ifndef SYMMETRY_BOUNDARY_CONDITION_DESCRIPTOR_HPP #define SYMMETRY_BOUNDARY_CONDITION_DESCRIPTOR_HPP +#include <mesh/IBoundaryDescriptor.hpp> #include <scheme/IBoundaryConditionDescriptor.hpp> -#include <scheme/IBoundaryDescriptor.hpp> #include <memory> @@ -20,7 +20,7 @@ class SymmetryBoundaryConditionDescriptor : public IBoundaryConditionDescriptor public: const IBoundaryDescriptor& - boundaryDescriptor() const + boundaryDescriptor() const final { return *m_boundary_descriptor; } -- GitLab