diff --git a/src/language/modules/SchemeModule.cpp b/src/language/modules/SchemeModule.cpp index c04f29ad41df122df252cdc9e7009b49241e8ed2..8ff18d22f45c273e38ed907d5ff23fa9809ae7e8 100644 --- a/src/language/modules/SchemeModule.cpp +++ b/src/language/modules/SchemeModule.cpp @@ -8,6 +8,7 @@ #include <scheme/IBoundaryDescriptor.hpp> #include <scheme/NamedBoundaryDescriptor.hpp> #include <scheme/NumberedBoundaryDescriptor.hpp> +#include <scheme/PressureBoundaryConditionDescriptor.hpp> #include <scheme/SymmetryBoundaryConditionDescriptor.hpp> #include <memory> @@ -106,6 +107,25 @@ struct GlaceScheme } break; } + case IBoundaryConditionDescriptor::Type::pressure: { + const PressureBoundaryConditionDescriptor& pressure_bc_descriptor = + dynamic_cast<const PressureBoundaryConditionDescriptor&>(*bc_descriptor); + for (size_t i_ref_face_list = 0; + i_ref_face_list < m_mesh->connectivity().template numberOfRefItemList<FaceType>(); ++i_ref_face_list) { + const auto& ref_face_list = m_mesh->connectivity().template refItemList<FaceType>(i_ref_face_list); + const RefId& ref = ref_face_list.refId(); + if (ref == pressure_bc_descriptor.boundaryDescriptor()) { + const auto& face_list = ref_face_list.list(); + Array<double> face_values{face_list.size()}; + face_values.fill(1); + + std::shared_ptr bc = + std::make_shared<PressureBoundaryCondition<MeshType::Dimension>>(face_list, face_values); + bc_list.push_back(BoundaryConditionHandler(bc)); + } + } + break; + } default: { throw UnexpectedError("Unknown BCDescription\n"); } @@ -247,6 +267,19 @@ SchemeModule::SchemeModule() )); + this->_addBuiltinFunction("pressure", + std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr< + const IBoundaryConditionDescriptor>(std::shared_ptr<const IBoundaryDescriptor>, + const FunctionSymbolId&)>>( + + [](std::shared_ptr<const IBoundaryDescriptor> boundary, + const FunctionSymbolId& pressure_id) + -> std::shared_ptr<const IBoundaryConditionDescriptor> { + return std::make_shared<PressureBoundaryConditionDescriptor>(boundary, pressure_id); + } + + )); + this->_addBuiltinFunction("glace", std::make_shared<BuiltinFunctionEmbedder< void(std::shared_ptr<const IMesh>, diff --git a/src/scheme/AcousticSolver.hpp b/src/scheme/AcousticSolver.hpp index d0eb4d0b699709e0cddff74035e6b2263b7fffd2..622b998931ff08f9db141469da71b6f1aaf0105b 100644 --- a/src/scheme/AcousticSolver.hpp +++ b/src/scheme/AcousticSolver.hpp @@ -130,7 +130,31 @@ class AcousticSolver throw NotImplementedError("velocity BC"); } case BoundaryCondition::pressure: { - throw NotImplementedError("pressure BC"); + const PressureBoundaryCondition<Dimension>& pressure_bc = + dynamic_cast<const PressureBoundaryCondition<Dimension>&>(handler.boundaryCondition()); + if constexpr (Dimension == 1) { + MeshData<Dimension>& mesh_data = MeshDataManager::instance().getMeshData(*m_mesh); + const NodeValuePerCell<const Rd> Cjr = mesh_data.Cjr(); + + const auto& node_to_cell_matrix = m_connectivity.nodeToCellMatrix(); + const auto& node_local_numbers_in_their_cells = m_connectivity.nodeLocalNumbersInTheirCells(); + + const auto& node_list = pressure_bc.faceList(); + const auto& value_list = pressure_bc.valueList(); + for (size_t i_node = 0; i_node < node_list.size(); ++i_node) { + const NodeId node_id = node_list[i_node]; + const auto& node_cell_list = node_to_cell_matrix[node_id]; + Assert(node_cell_list.size() == 1); + + CellId node_cell_id = node_cell_list[0]; + size_t node_local_number_in_cell = node_local_numbers_in_their_cells(node_id, 0); + + m_br[node_id] -= value_list[i_node] * Cjr(node_cell_id, node_local_number_in_cell); + } + } else { + throw NotImplementedError("pressure bc in dimension>1"); + } + break; } case BoundaryCondition::symmetry: { const SymmetryBoundaryCondition<Dimension>& symmetry_bc = diff --git a/src/scheme/BoundaryCondition.hpp b/src/scheme/BoundaryCondition.hpp index 3d3332fc92cfa88792ecf556cb97781de007a104..cce2f0636e84a8206081614733ba88488b19bed7 100644 --- a/src/scheme/BoundaryCondition.hpp +++ b/src/scheme/BoundaryCondition.hpp @@ -38,42 +38,57 @@ class BoundaryCondition // clazy:exclude=copyable-polymorphic virtual ~BoundaryCondition() = default; }; +template <size_t Dimension> class PressureBoundaryCondition final : public BoundaryCondition // clazy:exclude=copyable-polymorphic { private: - const double m_value; - - const size_t m_number_of_faces; - Array<const unsigned int> m_face_list; + const Array<const double> m_value_list; + const Array<const FaceId> m_face_list; public: - double - value() const + const Array<const FaceId>& + faceList() const { - return m_value; + return m_face_list; } - const size_t& - numberOfFaces() const + const Array<const double>& + valueList() const { - return m_number_of_faces; + return m_value_list; } - const Array<const unsigned int>& + PressureBoundaryCondition(const Array<const FaceId>& face_list, Array<const double> value_list) + : BoundaryCondition{BoundaryCondition::pressure}, m_value_list{value_list}, m_face_list{face_list} + {} + + ~PressureBoundaryCondition() = default; +}; + +template <> +class PressureBoundaryCondition<1> final : public BoundaryCondition // clazy:exclude=copyable-polymorphic +{ + private: + const Array<const double> m_value_list; + const Array<const NodeId> m_face_list; + + public: + const Array<const NodeId>& faceList() const { return m_face_list; } - PressureBoundaryCondition(double value, const std::vector<unsigned int>& faces) - : BoundaryCondition(BoundaryCondition::pressure), m_value(value), m_number_of_faces(faces.size()) + const Array<const double>& + valueList() const { - Array<unsigned int> face_list(faces.size()); - parallel_for( - m_number_of_faces, PUGS_LAMBDA(int f) { face_list[f] = faces[f]; }); - m_face_list = face_list; + return m_value_list; } + PressureBoundaryCondition(const Array<const NodeId>& face_list, Array<const double> value_list) + : BoundaryCondition{BoundaryCondition::pressure}, m_value_list{value_list}, m_face_list{face_list} + {} + ~PressureBoundaryCondition() = default; }; diff --git a/src/scheme/IBoundaryConditionDescriptor.hpp b/src/scheme/IBoundaryConditionDescriptor.hpp index 0814c9e8580f6c36ad1152c3143d5877bff45dbc..8abb2537141d1356bbbe6404242434225644ba11 100644 --- a/src/scheme/IBoundaryConditionDescriptor.hpp +++ b/src/scheme/IBoundaryConditionDescriptor.hpp @@ -8,6 +8,7 @@ class IBoundaryConditionDescriptor public: enum class Type { + pressure, symmetry }; diff --git a/src/scheme/PressureBoundaryConditionDescriptor.hpp b/src/scheme/PressureBoundaryConditionDescriptor.hpp new file mode 100644 index 0000000000000000000000000000000000000000..28cdb204e1db9a87c52b84aedc7c1ee9b0b503e6 --- /dev/null +++ b/src/scheme/PressureBoundaryConditionDescriptor.hpp @@ -0,0 +1,49 @@ +#ifndef PRESSURE_BOUNDARY_CONDITION_DESCRIPTOR_HPP +#define PRESSURE_BOUNDARY_CONDITION_DESCRIPTOR_HPP + +#include <language/utils/FunctionSymbolId.hpp> +#include <scheme/IBoundaryConditionDescriptor.hpp> +#include <scheme/IBoundaryDescriptor.hpp> + +#include <memory> + +class PressureBoundaryConditionDescriptor : public IBoundaryConditionDescriptor +{ + private: + std::ostream& + _write(std::ostream& os) const final + { + os << "pressure(" << *m_boundary_descriptor << ")"; + return os; + } + + std::shared_ptr<const IBoundaryDescriptor> m_boundary_descriptor; + const FunctionSymbolId m_function_symbol_id; + + public: + const IBoundaryDescriptor& + boundaryDescriptor() const + { + return *m_boundary_descriptor; + } + + Type + type() const final + { + return Type::pressure; + } + + PressureBoundaryConditionDescriptor(std::shared_ptr<const IBoundaryDescriptor> boundary_descriptor, + const FunctionSymbolId& function_symbol_id) + : m_boundary_descriptor(boundary_descriptor), m_function_symbol_id{function_symbol_id} + { + ; + } + + PressureBoundaryConditionDescriptor(const PressureBoundaryConditionDescriptor&) = delete; + PressureBoundaryConditionDescriptor(PressureBoundaryConditionDescriptor&&) = delete; + + ~PressureBoundaryConditionDescriptor() = default; +}; + +#endif // PRESSURE_BOUNDARY_CONDITION_DESCRIPTOR_HPP