Skip to content
Snippets Groups Projects
Commit e7e80742 authored by Stéphane Del Pino's avatar Stéphane Del Pino
Browse files

Add a generic external bc descriptor

Use the acoustic solver (in 1d) to check the possibility of exchanging
data through sockets. Here, one provides the pressure on a boundary to
an external solver which in returns provides the boundary velocity.
parent 75dc1d63
No related branches found
No related tags found
1 merge request!126Begin socket handling: core functionalities are available
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include <scheme/DiscreteFunctionUtils.hpp> #include <scheme/DiscreteFunctionUtils.hpp>
#include <scheme/DiscreteFunctionVectorIntegrator.hpp> #include <scheme/DiscreteFunctionVectorIntegrator.hpp>
#include <scheme/DiscreteFunctionVectorInterpoler.hpp> #include <scheme/DiscreteFunctionVectorInterpoler.hpp>
#include <scheme/ExternalBoundaryConditionDescriptor.hpp>
#include <scheme/FixedBoundaryConditionDescriptor.hpp> #include <scheme/FixedBoundaryConditionDescriptor.hpp>
#include <scheme/FourierBoundaryConditionDescriptor.hpp> #include <scheme/FourierBoundaryConditionDescriptor.hpp>
#include <scheme/FreeBoundaryConditionDescriptor.hpp> #include <scheme/FreeBoundaryConditionDescriptor.hpp>
...@@ -36,6 +37,7 @@ ...@@ -36,6 +37,7 @@
#include <scheme/NeumannBoundaryConditionDescriptor.hpp> #include <scheme/NeumannBoundaryConditionDescriptor.hpp>
#include <scheme/NumberedBoundaryDescriptor.hpp> #include <scheme/NumberedBoundaryDescriptor.hpp>
#include <scheme/SymmetryBoundaryConditionDescriptor.hpp> #include <scheme/SymmetryBoundaryConditionDescriptor.hpp>
#include <utils/Socket.hpp>
#include <memory> #include <memory>
...@@ -273,6 +275,20 @@ SchemeModule::SchemeModule() ...@@ -273,6 +275,20 @@ SchemeModule::SchemeModule()
)); ));
this->_addBuiltinFunction("external_fsi_velocity",
std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<
const IBoundaryConditionDescriptor>(std::shared_ptr<const IBoundaryDescriptor>,
const std::shared_ptr<const Socket>&)>>(
[](std::shared_ptr<const IBoundaryDescriptor> boundary,
const std::shared_ptr<const Socket>& socket)
-> std::shared_ptr<const IBoundaryConditionDescriptor> {
return std::make_shared<ExternalBoundaryConditionDescriptor>("external_fsi_velocity",
boundary, socket);
}
));
this->_addBuiltinFunction("glace_solver", this->_addBuiltinFunction("glace_solver",
std::make_shared<BuiltinFunctionEmbedder<std::tuple< std::make_shared<BuiltinFunctionEmbedder<std::tuple<
std::shared_ptr<const IMesh>, std::shared_ptr<const IDiscreteFunction>, std::shared_ptr<const IMesh>, std::shared_ptr<const IDiscreteFunction>,
......
...@@ -8,11 +8,13 @@ ...@@ -8,11 +8,13 @@
#include <scheme/DirichletBoundaryConditionDescriptor.hpp> #include <scheme/DirichletBoundaryConditionDescriptor.hpp>
#include <scheme/DiscreteFunctionP0.hpp> #include <scheme/DiscreteFunctionP0.hpp>
#include <scheme/DiscreteFunctionUtils.hpp> #include <scheme/DiscreteFunctionUtils.hpp>
#include <scheme/ExternalBoundaryConditionDescriptor.hpp>
#include <scheme/FixedBoundaryConditionDescriptor.hpp> #include <scheme/FixedBoundaryConditionDescriptor.hpp>
#include <scheme/IBoundaryConditionDescriptor.hpp> #include <scheme/IBoundaryConditionDescriptor.hpp>
#include <scheme/IDiscreteFunction.hpp> #include <scheme/IDiscreteFunction.hpp>
#include <scheme/IDiscreteFunctionDescriptor.hpp> #include <scheme/IDiscreteFunctionDescriptor.hpp>
#include <scheme/SymmetryBoundaryConditionDescriptor.hpp> #include <scheme/SymmetryBoundaryConditionDescriptor.hpp>
#include <utils/Socket.hpp>
#include <variant> #include <variant>
#include <vector> #include <vector>
...@@ -75,9 +77,13 @@ class AcousticSolverHandler::AcousticSolver final : public AcousticSolverHandler ...@@ -75,9 +77,13 @@ class AcousticSolverHandler::AcousticSolver final : public AcousticSolverHandler
class PressureBoundaryCondition; class PressureBoundaryCondition;
class SymmetryBoundaryCondition; class SymmetryBoundaryCondition;
class VelocityBoundaryCondition; class VelocityBoundaryCondition;
class ExternalFSIVelocityBoundaryCondition;
using BoundaryCondition = std:: using BoundaryCondition = std::variant<FixedBoundaryCondition,
variant<FixedBoundaryCondition, PressureBoundaryCondition, SymmetryBoundaryCondition, VelocityBoundaryCondition>; PressureBoundaryCondition,
SymmetryBoundaryCondition,
VelocityBoundaryCondition,
ExternalFSIVelocityBoundaryCondition>;
using BoundaryConditionList = std::vector<BoundaryCondition>; using BoundaryConditionList = std::vector<BoundaryCondition>;
...@@ -254,6 +260,18 @@ class AcousticSolverHandler::AcousticSolver final : public AcousticSolverHandler ...@@ -254,6 +260,18 @@ class AcousticSolverHandler::AcousticSolver final : public AcousticSolverHandler
bc_list.emplace_back(FixedBoundaryCondition(getMeshNodeBoundary(mesh, bc_descriptor->boundaryDescriptor()))); bc_list.emplace_back(FixedBoundaryCondition(getMeshNodeBoundary(mesh, bc_descriptor->boundaryDescriptor())));
break; break;
} }
case IBoundaryConditionDescriptor::Type::external: {
if constexpr (Dimension == 1) {
const ExternalBoundaryConditionDescriptor& extern_bc_descriptor =
dynamic_cast<const ExternalBoundaryConditionDescriptor&>(*bc_descriptor);
bc_list.emplace_back(
ExternalFSIVelocityBoundaryCondition(mesh, getMeshNodeBoundary(mesh, bc_descriptor->boundaryDescriptor()),
extern_bc_descriptor.socket()));
} else {
throw NotImplementedError("external FSI velocity not implemented for dimension > 1");
}
break;
}
case IBoundaryConditionDescriptor::Type::dirichlet: { case IBoundaryConditionDescriptor::Type::dirichlet: {
const DirichletBoundaryConditionDescriptor& dirichlet_bc_descriptor = const DirichletBoundaryConditionDescriptor& dirichlet_bc_descriptor =
dynamic_cast<const DirichletBoundaryConditionDescriptor&>(*bc_descriptor); dynamic_cast<const DirichletBoundaryConditionDescriptor&>(*bc_descriptor);
...@@ -320,6 +338,7 @@ class AcousticSolverHandler::AcousticSolver final : public AcousticSolverHandler ...@@ -320,6 +338,7 @@ class AcousticSolverHandler::AcousticSolver final : public AcousticSolverHandler
void _applyPressureBC(const MeshType& mesh, NodeValue<Rd>& br); void _applyPressureBC(const MeshType& mesh, NodeValue<Rd>& br);
void _applySymmetryBC(NodeValue<Rdxd>& Ar, NodeValue<Rd>& br); void _applySymmetryBC(NodeValue<Rdxd>& Ar, NodeValue<Rd>& br);
void _applyVelocityBC(NodeValue<Rdxd>& Ar, NodeValue<Rd>& br); void _applyVelocityBC(NodeValue<Rdxd>& Ar, NodeValue<Rd>& br);
void _applyExternalVelocityBC(const DiscreteScalarFunction& p, NodeValue<Rdxd>& Ar, NodeValue<Rd>& br);
void void
_applyBoundaryConditions(const MeshType& mesh, NodeValue<Rdxd>& Ar, NodeValue<Rd>& br) _applyBoundaryConditions(const MeshType& mesh, NodeValue<Rdxd>& Ar, NodeValue<Rd>& br)
...@@ -380,6 +399,7 @@ class AcousticSolverHandler::AcousticSolver final : public AcousticSolverHandler ...@@ -380,6 +399,7 @@ class AcousticSolverHandler::AcousticSolver final : public AcousticSolverHandler
NodeValue<Rd> br = this->_computeBr(mesh, Ajr, u, p); NodeValue<Rd> br = this->_computeBr(mesh, Ajr, u, p);
this->_applyBoundaryConditions(mesh, Ar, br); this->_applyBoundaryConditions(mesh, Ar, br);
this->_applyExternalVelocityBC(p, Ar, br);
synchronize(Ar); synchronize(Ar);
synchronize(br); synchronize(br);
...@@ -610,6 +630,34 @@ AcousticSolverHandler::AcousticSolver<Dimension>::_applyVelocityBC(NodeValue<Rdx ...@@ -610,6 +630,34 @@ AcousticSolverHandler::AcousticSolver<Dimension>::_applyVelocityBC(NodeValue<Rdx
} }
} }
template <size_t Dimension>
void
AcousticSolverHandler::AcousticSolver<Dimension>::_applyExternalVelocityBC(const DiscreteScalarFunction& p,
NodeValue<Rdxd>& Ar,
NodeValue<Rd>& br)
{
for (const auto& boundary_condition : m_boundary_condition_list) {
std::visit(
[&](auto&& bc) {
using T = std::decay_t<decltype(bc)>;
if constexpr (std::is_same_v<ExternalFSIVelocityBoundaryCondition, T>) {
const auto& node_list = bc.nodeList();
const auto& value_list = bc.valueList(p);
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];
Ar[node_id] = identity;
br[node_id] = value;
});
}
},
boundary_condition);
}
}
template <size_t Dimension> template <size_t Dimension>
class AcousticSolverHandler::AcousticSolver<Dimension>::FixedBoundaryCondition class AcousticSolverHandler::AcousticSolver<Dimension>::FixedBoundaryCondition
{ {
...@@ -685,6 +733,55 @@ class AcousticSolverHandler::AcousticSolver<1>::PressureBoundaryCondition ...@@ -685,6 +733,55 @@ class AcousticSolverHandler::AcousticSolver<1>::PressureBoundaryCondition
~PressureBoundaryCondition() = default; ~PressureBoundaryCondition() = default;
}; };
template <size_t Dimension>
class AcousticSolverHandler::AcousticSolver<Dimension>::ExternalFSIVelocityBoundaryCondition
{
private:
const ItemToItemMatrix<ItemType::node, ItemType::cell> m_node_to_cell_matrix;
const MeshNodeBoundary<Dimension> m_mesh_node_boundary;
const Array<TinyVector<Dimension>> m_value_list;
const std::shared_ptr<const Socket> m_socket;
public:
const Array<const NodeId>&
nodeList() const
{
return m_mesh_node_boundary.nodeList();
}
Array<const TinyVector<Dimension>>
valueList(const DiscreteScalarFunction& p) const
{
if (parallel::size() > 1) {
throw NotImplementedError("Parallelism is not supported");
}
if (m_value_list.size() != 1) {
throw NotImplementedError("Non connected boundaries are not supported");
}
const CellId cell_id = m_node_to_cell_matrix[m_mesh_node_boundary.nodeList()[0]][0];
write(*m_socket, p[cell_id]);
read(*m_socket, m_value_list[0]);
return m_value_list;
}
ExternalFSIVelocityBoundaryCondition(const Mesh<Connectivity<Dimension>>& mesh,
const MeshNodeBoundary<Dimension>& mesh_node_boundary,
const std::shared_ptr<const Socket>& socket)
: m_node_to_cell_matrix{mesh.connectivity().nodeToCellMatrix()},
m_mesh_node_boundary{mesh_node_boundary},
m_value_list(mesh_node_boundary.nodeList().size()),
m_socket{socket}
{
if constexpr (Dimension > 1) {
throw NotImplementedError("external FSI velocity bc in dimension > 1");
}
}
~ExternalFSIVelocityBoundaryCondition() = default;
};
template <size_t Dimension> template <size_t Dimension>
class AcousticSolverHandler::AcousticSolver<Dimension>::VelocityBoundaryCondition class AcousticSolverHandler::AcousticSolver<Dimension>::VelocityBoundaryCondition
{ {
......
#ifndef EXTERNAL_BOUNDARY_CONDITION_DESCRIPTOR_HPP
#define EXTERNAL_BOUNDARY_CONDITION_DESCRIPTOR_HPP
#include <mesh/IBoundaryDescriptor.hpp>
#include <scheme/IBoundaryConditionDescriptor.hpp>
#include <utils/Socket.hpp>
#include <memory>
class ExternalBoundaryConditionDescriptor : public IBoundaryConditionDescriptor
{
private:
std::ostream&
_write(std::ostream& os) const final
{
os << "external(" << m_name << ',' << *m_boundary_descriptor << ")";
return os;
}
const std::string_view m_name;
std::shared_ptr<const IBoundaryDescriptor> m_boundary_descriptor;
const std::shared_ptr<const Socket> m_socket;
public:
std::string_view
name() const
{
return m_name;
}
const std::shared_ptr<const Socket>&
socket() const
{
return m_socket;
}
const IBoundaryDescriptor&
boundaryDescriptor() const final
{
return *m_boundary_descriptor;
}
Type
type() const final
{
return Type::external;
}
ExternalBoundaryConditionDescriptor(const std::string_view name,
std::shared_ptr<const IBoundaryDescriptor> boundary_descriptor,
const std::shared_ptr<const Socket>& socket)
: m_name{name}, m_boundary_descriptor(boundary_descriptor), m_socket{socket}
{}
ExternalBoundaryConditionDescriptor(const ExternalBoundaryConditionDescriptor&) = delete;
ExternalBoundaryConditionDescriptor(ExternalBoundaryConditionDescriptor&&) = delete;
~ExternalBoundaryConditionDescriptor() = default;
};
#endif // EXTERNAL_BOUNDARY_CONDITION_DESCRIPTOR_HPP
...@@ -12,6 +12,7 @@ class IBoundaryConditionDescriptor ...@@ -12,6 +12,7 @@ class IBoundaryConditionDescriptor
{ {
axis, axis,
dirichlet, dirichlet,
external,
fourier, fourier,
fixed, fixed,
free, free,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment