From cfe40c29c4d3f5f3e4db81048f0dead9be29f266 Mon Sep 17 00:00:00 2001 From: Stephane Del Pino <stephane.delpino44@gmail.com> Date: Mon, 27 Jul 2020 23:50:37 +0200 Subject: [PATCH] Add velocity boundary conditions for acoustic solver (Glace) Still requires design improvements and to check data validity --- src/language/modules/SchemeModule.cpp | 62 ++++++++++++++++++- src/scheme/AcousticSolver.hpp | 36 +++++++---- src/scheme/BoundaryCondition.hpp | 32 +++++++++- src/scheme/IBoundaryConditionDescriptor.hpp | 1 + .../VelocityBoundaryConditionDescriptor.hpp | 55 ++++++++++++++++ 5 files changed, 170 insertions(+), 16 deletions(-) create mode 100644 src/scheme/VelocityBoundaryConditionDescriptor.hpp diff --git a/src/language/modules/SchemeModule.cpp b/src/language/modules/SchemeModule.cpp index 7903e6ce4..4e19eb473 100644 --- a/src/language/modules/SchemeModule.cpp +++ b/src/language/modules/SchemeModule.cpp @@ -10,6 +10,7 @@ #include <scheme/NumberedBoundaryDescriptor.hpp> #include <scheme/PressureBoundaryConditionDescriptor.hpp> #include <scheme/SymmetryBoundaryConditionDescriptor.hpp> +#include <scheme/VelocityBoundaryConditionDescriptor.hpp> #include <memory> @@ -140,6 +141,50 @@ struct GlaceScheme } break; } + case IBoundaryConditionDescriptor::Type::velocity: { + const VelocityBoundaryConditionDescriptor& velocity_bc_descriptor = + dynamic_cast<const VelocityBoundaryConditionDescriptor&>(*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 == velocity_bc_descriptor.boundaryDescriptor()) { + const FunctionSymbolId velocity_id = velocity_bc_descriptor.functionSymbolId(); + + if constexpr (Dimension == 1) { + const auto& node_list = ref_face_list.list(); + + Array<const TinyVector<Dimension>> value_list = InterpolateItemValue<TinyVector<Dimension>( + TinyVector<Dimension>)>::template interpolate<FaceType>(velocity_id, m_mesh->xr(), node_list); + + std::shared_ptr bc = + std::make_shared<VelocityBoundaryCondition<MeshType::Dimension>>(node_list, value_list); + bc_list.push_back(BoundaryConditionHandler(bc)); + } else { + const auto& face_list = ref_face_list.list(); + const auto& face_to_node_matrix = m_mesh->connectivity().faceToNodeMatrix(); + std::set<NodeId> node_set; + for (size_t i_face = 0; i_face < face_list.size(); ++i_face) { + FaceId face_id = face_list[i_face]; + const auto& face_nodes = face_to_node_matrix[face_id]; + for (size_t i_node = 0; i_node < face_nodes.size(); ++i_node) { + node_set.insert(face_nodes[i_node]); + } + } + + Array<NodeId> node_list = convert_to_array(node_set); + + Array<const TinyVector<Dimension>> value_list = InterpolateItemValue<TinyVector<Dimension>( + TinyVector<Dimension>)>::template interpolate<ItemType::node>(velocity_id, m_mesh->xr(), node_list); + + std::shared_ptr bc = + std::make_shared<VelocityBoundaryCondition<MeshType::Dimension>>(node_list, value_list); + bc_list.push_back(BoundaryConditionHandler(bc)); + } + } + } + break; + } case IBoundaryConditionDescriptor::Type::pressure: { const PressureBoundaryConditionDescriptor& pressure_bc_descriptor = dynamic_cast<const PressureBoundaryConditionDescriptor&>(*bc_descriptor); @@ -172,7 +217,9 @@ struct GlaceScheme break; } default: { - throw UnexpectedError("Unknown BCDescription\n"); + std::ostringstream error_msg; + error_msg << *bc_descriptor << " is an invalid boundary condition for acoustic solver"; + throw NormalError(error_msg.str()); } } } @@ -325,6 +372,19 @@ SchemeModule::SchemeModule() )); + this->_addBuiltinFunction("velocity", + std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr< + const IBoundaryConditionDescriptor>(std::shared_ptr<const IBoundaryDescriptor>, + const FunctionSymbolId&)>>( + + [](std::shared_ptr<const IBoundaryDescriptor> boundary, + const FunctionSymbolId& velocity_id) + -> std::shared_ptr<const IBoundaryConditionDescriptor> { + return std::make_shared<VelocityBoundaryConditionDescriptor>(boundary, velocity_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 75b8eec54..1fcfa105e 100644 --- a/src/scheme/AcousticSolver.hpp +++ b/src/scheme/AcousticSolver.hpp @@ -123,11 +123,22 @@ class AcousticSolver { for (const auto& handler : m_boundary_condition_list) { switch (handler.boundaryCondition().type()) { - case BoundaryCondition::normal_velocity: { - throw NotImplementedError("normal_velocity BC"); - } case BoundaryCondition::velocity: { - throw NotImplementedError("velocity BC"); + const VelocityBoundaryCondition<Dimension>& velocity_bc = + dynamic_cast<const VelocityBoundaryCondition<Dimension>&>(handler.boundaryCondition()); + + const auto& node_list = velocity_bc.nodeList(); + const auto& value_list = velocity_bc.valueList(); + + parallel_for( + node_list.size(), PUGS_LAMBDA(size_t i_node) { + NodeId node_id = node_list[i_node]; + const auto& value = value_list[i_node]; + + m_Ar[node_id] = identity; + m_br[node_id] = value; + }); + break; } case BoundaryCondition::pressure: { const PressureBoundaryCondition<Dimension>& pressure_bc = @@ -142,16 +153,17 @@ class AcousticSolver 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); + parallel_for( + node_list.size(), PUGS_LAMBDA(size_t 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); + 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); - } + m_br[node_id] -= value_list[i_node] * Cjr(node_cell_id, node_local_number_in_cell); + }); } else { const NodeValuePerFace<const Rd> Nlr = mesh_data.Nlr(); diff --git a/src/scheme/BoundaryCondition.hpp b/src/scheme/BoundaryCondition.hpp index cce2f0636..2bd924974 100644 --- a/src/scheme/BoundaryCondition.hpp +++ b/src/scheme/BoundaryCondition.hpp @@ -15,7 +15,6 @@ class BoundaryCondition // clazy:exclude=copyable-polymorphic enum Type { velocity, - normal_velocity, pressure, symmetry }; @@ -58,7 +57,7 @@ class PressureBoundaryCondition final : public BoundaryCondition // clazy:excl return m_value_list; } - PressureBoundaryCondition(const Array<const FaceId>& face_list, Array<const double> value_list) + PressureBoundaryCondition(const Array<const FaceId>& face_list, const Array<const double>& value_list) : BoundaryCondition{BoundaryCondition::pressure}, m_value_list{value_list}, m_face_list{face_list} {} @@ -85,7 +84,7 @@ class PressureBoundaryCondition<1> final : public BoundaryCondition // clazy:e return m_value_list; } - PressureBoundaryCondition(const Array<const NodeId>& face_list, Array<const double> value_list) + PressureBoundaryCondition(const Array<const NodeId>& face_list, const Array<const double>& value_list) : BoundaryCondition{BoundaryCondition::pressure}, m_value_list{value_list}, m_face_list{face_list} {} @@ -129,6 +128,33 @@ class SymmetryBoundaryCondition : public BoundaryCondition ~SymmetryBoundaryCondition() = default; }; +template <size_t Dimension> +class VelocityBoundaryCondition final : public BoundaryCondition // clazy:exclude=copyable-polymorphic +{ + private: + 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; + } + + const Array<const TinyVector<Dimension>>& + valueList() const + { + return m_value_list; + } + + VelocityBoundaryCondition(const Array<const NodeId>& node_list, const Array<const TinyVector<Dimension>>& value_list) + : BoundaryCondition{BoundaryCondition::velocity}, m_value_list{value_list}, m_node_list{node_list} + {} + + ~VelocityBoundaryCondition() = default; +}; + class BoundaryConditionHandler { private: diff --git a/src/scheme/IBoundaryConditionDescriptor.hpp b/src/scheme/IBoundaryConditionDescriptor.hpp index 8abb25371..95f68bd25 100644 --- a/src/scheme/IBoundaryConditionDescriptor.hpp +++ b/src/scheme/IBoundaryConditionDescriptor.hpp @@ -8,6 +8,7 @@ class IBoundaryConditionDescriptor public: enum class Type { + velocity, pressure, symmetry }; diff --git a/src/scheme/VelocityBoundaryConditionDescriptor.hpp b/src/scheme/VelocityBoundaryConditionDescriptor.hpp new file mode 100644 index 000000000..5ce10e6a5 --- /dev/null +++ b/src/scheme/VelocityBoundaryConditionDescriptor.hpp @@ -0,0 +1,55 @@ +#ifndef VELOCITY_BOUNDARY_CONDITION_DESCRIPTOR_HPP +#define VELOCITY_BOUNDARY_CONDITION_DESCRIPTOR_HPP + +#include <language/utils/FunctionSymbolId.hpp> +#include <scheme/IBoundaryConditionDescriptor.hpp> +#include <scheme/IBoundaryDescriptor.hpp> + +#include <memory> + +class VelocityBoundaryConditionDescriptor : public IBoundaryConditionDescriptor +{ + private: + std::ostream& + _write(std::ostream& os) const final + { + os << "velocity(" << *m_boundary_descriptor << ")"; + return os; + } + + std::shared_ptr<const IBoundaryDescriptor> m_boundary_descriptor; + const FunctionSymbolId m_function_symbol_id; + + public: + FunctionSymbolId + functionSymbolId() const + { + return m_function_symbol_id; + } + + const IBoundaryDescriptor& + boundaryDescriptor() const + { + return *m_boundary_descriptor; + } + + Type + type() const final + { + return Type::velocity; + } + + VelocityBoundaryConditionDescriptor(std::shared_ptr<const IBoundaryDescriptor> boundary_descriptor, + const FunctionSymbolId& function_symbol_id) + : m_boundary_descriptor(boundary_descriptor), m_function_symbol_id{function_symbol_id} + { + ; + } + + VelocityBoundaryConditionDescriptor(const VelocityBoundaryConditionDescriptor&) = delete; + VelocityBoundaryConditionDescriptor(VelocityBoundaryConditionDescriptor&&) = delete; + + ~VelocityBoundaryConditionDescriptor() = default; +}; + +#endif // VELOCITY!_BOUNDARY_CONDITION_DESCRIPTOR_HPP -- GitLab