diff --git a/src/language/modules/SchemeModule.cpp b/src/language/modules/SchemeModule.cpp index 788c4ec633c7fd5527c601865a695cb27858d5dc..f2fc4ec5dd6e8593dcad16eea02c405eaa751f8d 100644 --- a/src/language/modules/SchemeModule.cpp +++ b/src/language/modules/SchemeModule.cpp @@ -9,6 +9,7 @@ #include <language/utils/BinaryOperatorProcessorBuilder.hpp> #include <language/utils/BuiltinFunctionEmbedder.hpp> #include <language/utils/TypeDescriptor.hpp> +#include <memory> #include <mesh/Connectivity.hpp> #include <mesh/IBoundaryDescriptor.hpp> #include <mesh/IZoneDescriptor.hpp> @@ -20,6 +21,7 @@ #include <mesh/NumberedBoundaryDescriptor.hpp> #include <scheme/AcousticSolver.hpp> #include <scheme/AxisBoundaryConditionDescriptor.hpp> +#include <scheme/CouplingBoundaryConditionDescriptor.hpp> #include <scheme/DirichletBoundaryConditionDescriptor.hpp> #include <scheme/DiscreteFunctionDescriptorP0.hpp> #include <scheme/DiscreteFunctionDescriptorP0Vector.hpp> @@ -47,8 +49,6 @@ #include <scheme/VectorDiamondScheme.hpp> #include <utils/Socket.hpp> -#include <memory> - SchemeModule::SchemeModule() { this->_addTypeDescriptor(ast_node_data_type_from<std::shared_ptr<const DiscreteFunctionVariant>>); @@ -347,7 +347,14 @@ SchemeModule::SchemeModule() } )); + this->_addBuiltinFunction("coupling", std::function( + [](std::shared_ptr<const IBoundaryDescriptor> boundary) + -> std::shared_ptr<const IBoundaryConditionDescriptor> { + return std::make_shared<CouplingBoundaryConditionDescriptor>(boundary); + } + + )); #ifdef PUGS_HAS_COSTO this->_addBuiltinFunction("cpl_pressure", std::function( @@ -360,32 +367,29 @@ SchemeModule::SchemeModule() } )); -#endif // PUGS_HAS_COSTO - - this->_addBuiltinFunction("normalstress", + this->_addBuiltinFunction("cpl_forces", std::function( [](std::shared_ptr<const IBoundaryDescriptor> boundary, const FunctionSymbolId& normal_stress_id) -> std::shared_ptr<const IBoundaryConditionDescriptor> { - return std::make_shared<DirichletBoundaryConditionDescriptor>("normal-stress", boundary, + return std::make_shared<DirichletBoundaryConditionDescriptor>("cpl_forces", boundary, normal_stress_id); } )); -#ifdef PUGS_HAS_COSTO - this->_addBuiltinFunction("cpl_forces", +#endif // PUGS_HAS_COSTO + this->_addBuiltinFunction("normalstress", std::function( [](std::shared_ptr<const IBoundaryDescriptor> boundary, const FunctionSymbolId& normal_stress_id) -> std::shared_ptr<const IBoundaryConditionDescriptor> { - return std::make_shared<DirichletBoundaryConditionDescriptor>("cpl_forces", boundary, + return std::make_shared<DirichletBoundaryConditionDescriptor>("normal-stress", boundary, normal_stress_id); } )); -#endif // PUGS_HAS_COSTO this->_addBuiltinFunction("velocity", std::function( diff --git a/src/scheme/AcousticSolver.cpp b/src/scheme/AcousticSolver.cpp index f61f27cb46c4ed9dbee0481c433e6f9aa3ea4da0..29f18230abad5fb5cb2b3d99044a5539aed2f3d3 100644 --- a/src/scheme/AcousticSolver.cpp +++ b/src/scheme/AcousticSolver.cpp @@ -7,6 +7,7 @@ #include <mesh/MeshFlatNodeBoundary.hpp> #include <mesh/MeshNodeBoundary.hpp> #include <mesh/SubItemValuePerItemVariant.hpp> +#include <scheme/CouplingBoundaryConditionDescriptor.hpp> #include <scheme/DirichletBoundaryConditionDescriptor.hpp> #include <scheme/DiscreteFunctionP0.hpp> #include <scheme/DiscreteFunctionUtils.hpp> @@ -15,6 +16,7 @@ #include <scheme/IBoundaryConditionDescriptor.hpp> #include <scheme/IDiscreteFunctionDescriptor.hpp> #include <scheme/SymmetryBoundaryConditionDescriptor.hpp> +#include <utils/Messenger.hpp> #include <utils/Socket.hpp> #include <variant> @@ -75,11 +77,13 @@ class AcousticSolverHandler::AcousticSolver final : public AcousticSolverHandler class SymmetryBoundaryCondition; class VelocityBoundaryCondition; class ExternalFSIVelocityBoundaryCondition; + class CouplingBoundaryCondition; using BoundaryCondition = std::variant<FixedBoundaryCondition, PressureBoundaryCondition, SymmetryBoundaryCondition, VelocityBoundaryCondition, + CouplingBoundaryCondition, ExternalFSIVelocityBoundaryCondition>; using BoundaryConditionList = std::vector<BoundaryCondition>; @@ -304,6 +308,12 @@ class AcousticSolverHandler::AcousticSolver final : public AcousticSolverHandler } break; } + case IBoundaryConditionDescriptor::Type::coupling: { + const CouplingBoundaryConditionDescriptor& coupling_bc_descriptor = + dynamic_cast<const CouplingBoundaryConditionDescriptor&>(*bc_descriptor); + bc_list.emplace_back(CouplingBoundaryCondition(getMeshNodeBoundary(mesh, bc_descriptor->boundaryDescriptor()))); + break; + } default: { is_valid_boundary_condition = false; } @@ -321,6 +331,7 @@ class AcousticSolverHandler::AcousticSolver final : public AcousticSolverHandler void _applyPressureBC(const BoundaryConditionList& bc_list, const MeshType& mesh, NodeValue<Rd>& br) const; void _applySymmetryBC(const BoundaryConditionList& bc_list, NodeValue<Rdxd>& Ar, NodeValue<Rd>& br) const; void _applyVelocityBC(const BoundaryConditionList& bc_list, NodeValue<Rdxd>& Ar, NodeValue<Rd>& br) const; + void _applyCouplingBC(const BoundaryConditionList& bc_list, NodeValue<Rdxd>& Ar, NodeValue<Rd>& br) const; void _applyExternalVelocityBC(const BoundaryConditionList& bc_list, const DiscreteScalarFunction& p, NodeValue<Rdxd>& Ar, @@ -405,6 +416,7 @@ class AcousticSolverHandler::AcousticSolver final : public AcousticSolverHandler const BoundaryConditionList bc_list = this->_getBCList(mesh, bc_descriptor_list); this->_applyBoundaryConditions(bc_list, mesh, Ar, br); this->_applyExternalVelocityBC(bc_list, p, Ar, br); + this->_applyCouplingBC(bc_list, Ar, br); synchronize(Ar); synchronize(br); @@ -686,6 +698,87 @@ AcousticSolverHandler::AcousticSolver<Dimension>::_applyExternalVelocityBC(const } } +template <size_t Dimension> +void +AcousticSolverHandler::AcousticSolver<Dimension>::_applyCouplingBC(const BoundaryConditionList& bc_list, + NodeValue<Rdxd>& Ar, + NodeValue<Rd>& br) const +{ + for (const auto& boundary_condition : bc_list) { + std::visit( + [&](auto&& bc) { + using T = std::decay_t<decltype(bc)>; + if constexpr (std::is_same_v<CouplingBoundaryCondition, T>) { + const auto& node_list = bc.nodeList(); + + /* std::cout << "\033[01;31m" */ + /* << "un applyCoupling" */ + /* << "Dimension: " << Dimension << "\033[00;00m" << std::endl; */ + /* std::cout << "\033[01;31m" */ + /* << "node_list.size()" << node_list.size() << "\033[00;00m" << std::endl; */ + +#ifdef PUGS_HAS_COSTO + auto costo = parallel::Messenger::getInstance().myCoupling; + const int dest = costo->myGlobalSize() - 1; + int tag = 200; + std::vector<int> shape; + shape.resize(3); + shape[0] = node_list.size(); + shape[1] = Dimension + Dimension * Dimension; + /* shape[1] = Dimension; */ + shape[2] = 0; + + std::vector<double> data; + data.resize(shape[0] * shape[1] + shape[2]); + Array<TinyVector<Dimension>> br_extracted(node_list.size()); + Array<TinyMatrix<Dimension>> Ar_extracted(node_list.size()); + parallel_for( + node_list.size(), PUGS_LAMBDA(size_t i_node) { + NodeId node_id = node_list[i_node]; + for (size_t i_dim = 0; i_dim < Dimension; i_dim++) { + br_extracted[i_node] = br[node_id]; + Ar_extracted[i_node] = Ar[node_id]; + } + }); + /*TODO: serializer directement Ar et br pour eviter une copie*/ + for (size_t i_node = 0; i_node < node_list.size(); ++i_node) { + for (unsigned short i_dim = 0; i_dim < Dimension; ++i_dim) { + data[i_node * shape[1] + i_dim] = br_extracted[i_node][i_dim]; + for (size_t j_dim = 0; j_dim < Dimension; j_dim++) { + data[i_node * shape[1] + Dimension + i_dim * Dimension + j_dim] = Ar_extracted[i_node](i_dim, j_dim); + } + } + } + costo->sendData(shape, data, dest, tag); + std::vector<double> recv; + + tag = 210; + costo->recvData(recv, dest, tag); + for (size_t i_node = 0; i_node < node_list.size(); ++i_node) { + for (unsigned short i_dim = 0; i_dim < Dimension; ++i_dim) { + br_extracted[i_node][i_dim] = recv[i_node * shape[1] + i_dim]; + for (size_t j_dim = 0; j_dim < Dimension; j_dim++) { + Ar_extracted[i_node](i_dim, j_dim) = recv[i_node * shape[1] + Dimension + i_dim * Dimension + j_dim]; + } + } + } + + parallel_for( + node_list.size(), PUGS_LAMBDA(size_t i_node) { + NodeId node_id = node_list[i_node]; + for (size_t i_dim = 0; i_dim < Dimension; i_dim++) { + br[node_id] = br_extracted[i_node]; + Ar[node_id] = Ar_extracted[i_node]; + } + }); + +#endif PUGS_HAS_COSTO + } + }, + boundary_condition); + } +} + template <size_t Dimension> class AcousticSolverHandler::AcousticSolver<Dimension>::FixedBoundaryCondition { @@ -876,6 +969,28 @@ class AcousticSolverHandler::AcousticSolver<Dimension>::SymmetryBoundaryConditio ~SymmetryBoundaryCondition() = default; }; +template <size_t Dimension> +class AcousticSolverHandler::AcousticSolver<Dimension>::CouplingBoundaryCondition +{ + private: + const MeshNodeBoundary<Dimension> m_mesh_node_boundary; + + public: + const Array<const NodeId>& + nodeList() const + { + return m_mesh_node_boundary.nodeList(); + } + + CouplingBoundaryCondition(const MeshNodeBoundary<Dimension>& mesh_node_boundary) + : m_mesh_node_boundary{mesh_node_boundary} + { + ; + } + + ~CouplingBoundaryCondition() = default; +}; + AcousticSolverHandler::AcousticSolverHandler(const std::shared_ptr<const IMesh>& i_mesh) { if (not i_mesh) { diff --git a/src/scheme/AcousticSolver.hpp b/src/scheme/AcousticSolver.hpp index 36b62a32a1442b18cbe014a9e90ee28ffad08c8a..7d5c5e5900d196142240423ea1ae787ec4c33bf4 100644 --- a/src/scheme/AcousticSolver.hpp +++ b/src/scheme/AcousticSolver.hpp @@ -1,6 +1,4 @@ -#ifndef ACOUSTIC_SOLVER_HPP -#define ACOUSTIC_SOLVER_HPP - +#pragma once #include <memory> #include <tuple> #include <vector> @@ -59,8 +57,8 @@ class AcousticSolverHandler const std::shared_ptr<const DiscreteFunctionVariant>& p, const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>& bc_descriptor_list) const = 0; - IAcousticSolver() = default; - IAcousticSolver(IAcousticSolver&&) = default; + IAcousticSolver() = default; + IAcousticSolver(IAcousticSolver&&) = default; IAcousticSolver& operator=(IAcousticSolver&&) = default; virtual ~IAcousticSolver() = default; @@ -80,5 +78,3 @@ class AcousticSolverHandler AcousticSolverHandler(const std::shared_ptr<const IMesh>& mesh); }; - -#endif // ACOUSTIC_SOLVER_HPP diff --git a/src/scheme/CouplingBoundaryConditionDescriptor.hpp b/src/scheme/CouplingBoundaryConditionDescriptor.hpp new file mode 100644 index 0000000000000000000000000000000000000000..8880dde8e219619abbbaf8d7c40a1ff9600dab78 --- /dev/null +++ b/src/scheme/CouplingBoundaryConditionDescriptor.hpp @@ -0,0 +1,42 @@ +#pragma once +#include <mesh/IBoundaryDescriptor.hpp> +#include <scheme/IBoundaryConditionDescriptor.hpp> + +#include <memory> + +class CouplingBoundaryConditionDescriptor : public IBoundaryConditionDescriptor +{ + private: + std::ostream& + _write(std::ostream& os) const final + { + os << "coupling(" << *m_boundary_descriptor << ")"; + return os; + } + + std::shared_ptr<const IBoundaryDescriptor> m_boundary_descriptor; + + public: + const IBoundaryDescriptor& + boundaryDescriptor() const final + { + return *m_boundary_descriptor; + } + + Type + type() const final + { + return Type::coupling; + } + + CouplingBoundaryConditionDescriptor(std::shared_ptr<const IBoundaryDescriptor> boundary_descriptor) + : m_boundary_descriptor(boundary_descriptor) + { + ; + } + + CouplingBoundaryConditionDescriptor(const CouplingBoundaryConditionDescriptor&) = delete; + CouplingBoundaryConditionDescriptor(CouplingBoundaryConditionDescriptor&&) = delete; + + ~CouplingBoundaryConditionDescriptor() = default; +}; diff --git a/src/scheme/IBoundaryConditionDescriptor.hpp b/src/scheme/IBoundaryConditionDescriptor.hpp index 1350aa4dba4f7f6739b7de6689c10554ceec6971..431f6b47f89360304425c3bb4ae5c79a95feb736 100644 --- a/src/scheme/IBoundaryConditionDescriptor.hpp +++ b/src/scheme/IBoundaryConditionDescriptor.hpp @@ -1,5 +1,4 @@ -#ifndef I_BOUNDARY_CONDITION_DESCRIPTOR_HPP -#define I_BOUNDARY_CONDITION_DESCRIPTOR_HPP +#pragma once #include <iostream> @@ -11,6 +10,7 @@ class IBoundaryConditionDescriptor enum class Type { axis, + coupling, dirichlet, external, fourier, @@ -42,5 +42,3 @@ class IBoundaryConditionDescriptor virtual ~IBoundaryConditionDescriptor() = default; }; - -#endif // I_BOUNDARY_CONDITION_DESCRIPTOR_HPP diff --git a/src/utils/Serializer.cpp b/src/utils/Serializer.cpp index 4e20ab62e0003c99378ce5eefb713fe81f353176..dec86016c6573b68a937daed8194b91ba45e708c 100644 --- a/src/utils/Serializer.cpp +++ b/src/utils/Serializer.cpp @@ -30,6 +30,8 @@ Serializer::apply(std::shared_ptr<const IMesh> i_mesh, const int dest, const int positions[r][i] = xr[r][i]; } }); + + /*TODO: serializer directement position pour eviter une copie*/ pts.resize(mesh->numberOfNodes() * MeshType::Dimension); for (unsigned short r = 0; r < mesh->numberOfNodes(); ++r) { for (unsigned short j = 0; j < MeshType::Dimension; ++j) { @@ -56,6 +58,8 @@ Serializer::apply(std::shared_ptr<const IMesh> i_mesh, const int dest, const int positions[r][i] = xr[r][i]; } }); + + /*TODO: serializer directement position pour eviter une copie*/ pts.resize(mesh->numberOfNodes() * MeshType::Dimension); for (unsigned short r = 0; r < mesh->numberOfNodes(); ++r) { for (unsigned short j = 0; j < MeshType::Dimension; ++j) { @@ -83,7 +87,7 @@ Serializer::apply(std::shared_ptr<const IMesh> i_mesh, const int dest, const int } }); - std::vector<double> pts; + /*TODO: serializer directement position pour eviter une copie*/ pts.resize(mesh->numberOfNodes() * MeshType::Dimension); for (unsigned short r = 0; r < mesh->numberOfNodes(); ++r) { for (unsigned short j = 0; j < MeshType::Dimension; ++j) { @@ -144,6 +148,7 @@ Serializer::apply(const std::shared_ptr<const IBoundaryDescriptor>& boundary, /* } */ }); + /*TODO: serializer directement fposition pour eviter une copie*/ MeshFaceBoundary<1> mesh_face_boundary = getMeshFaceBoundary(*mesh, *boundary); /* mesh_face_boundary.faceList() */ const auto face_list = mesh_face_boundary.faceList(); @@ -183,6 +188,7 @@ Serializer::apply(const std::shared_ptr<const IBoundaryDescriptor>& boundary, /* } */ }); + /*TODO: serializer directement fposition pour eviter une copie*/ MeshFaceBoundary<2> mesh_face_boundary = getMeshFaceBoundary(*mesh, *boundary); /* mesh_face_boundary.faceList() */ const auto face_list = mesh_face_boundary.faceList(); @@ -222,6 +228,7 @@ Serializer::apply(const std::shared_ptr<const IBoundaryDescriptor>& boundary, /* } */ }); + /*TODO: serializer directement fposition pour eviter une copie*/ MeshFaceBoundary<3> mesh_face_boundary = getMeshFaceBoundary(*mesh, *boundary); /* mesh_face_boundary.faceList() */ const auto face_list = mesh_face_boundary.faceList(); @@ -266,6 +273,7 @@ Serializer::apply(const std::shared_ptr<const IBoundaryDescriptor>& boundary, /* } */ }); + /*TODO: serializer directement position pour eviter une copie*/ MeshNodeBoundary<1> mesh_node_boundary = getMeshNodeBoundary(*mesh, *boundary); /* mesh_face_boundary.faceList() */ const auto node_list = mesh_node_boundary.nodeList(); @@ -302,6 +310,7 @@ Serializer::apply(const std::shared_ptr<const IBoundaryDescriptor>& boundary, /* } */ }); + /*TODO: serializer directement position pour eviter une copie*/ MeshNodeBoundary<2> mesh_node_boundary = getMeshNodeBoundary(*mesh, *boundary); /* mesh_face_boundary.faceList() */ const auto node_list = mesh_node_boundary.nodeList(); @@ -337,6 +346,7 @@ Serializer::apply(const std::shared_ptr<const IBoundaryDescriptor>& boundary, /* } */ }); + /*TODO: serializer directement position pour eviter une copie*/ MeshNodeBoundary<3> mesh_node_boundary = getMeshNodeBoundary(*mesh, *boundary); /* mesh_face_boundary.faceList() */ const auto node_list = mesh_node_boundary.nodeList(); @@ -405,6 +415,7 @@ Serializer::apply(std::shared_ptr<const IMesh> i_mesh, /* } */ }); + /*TODO: serializer directement positions pour eviter une copie */ for (size_t i_node = 0; i_node < node_list.size(); ++i_node) { const NodeId node_id = node_list[i_node]; for (unsigned short i_dim = 0; i_dim < MeshType::Dimension; ++i_dim) {