diff --git a/src/language/modules/SchemeModule.cpp b/src/language/modules/SchemeModule.cpp index 4447fdc4f22fdee97a8ae24dad75410c1aef0051..e0bd1af64b6b657686b9168dd9eb05b2469ebbfe 100644 --- a/src/language/modules/SchemeModule.cpp +++ b/src/language/modules/SchemeModule.cpp @@ -38,6 +38,7 @@ #include <scheme/LocalDtAcousticSolver.hpp> #include <scheme/NeumannBoundaryConditionDescriptor.hpp> #include <scheme/SymmetryBoundaryConditionDescriptor.hpp> +#include <scheme/CouplingBoundaryConditionDescriptor.hpp> #include <utils/Socket.hpp> #include <memory> @@ -266,6 +267,15 @@ SchemeModule::SchemeModule() )); + this->_addBuiltinFunction("coupling", std::function( + + [](std::shared_ptr<const IBoundaryDescriptor> boundary) + -> std::shared_ptr<const IBoundaryConditionDescriptor> { + return std::make_shared<CouplingBoundaryConditionDescriptor>(boundary); + } + + )); + this->_addBuiltinFunction("pressure", std::function( [](std::shared_ptr<const IBoundaryDescriptor> boundary, @@ -398,21 +408,33 @@ SchemeModule::SchemeModule() this->_addBuiltinFunction("local_dt_glace_solver", std::function( - [](const std::shared_ptr<const DiscreteFunctionVariant>& rho, - const std::shared_ptr<const DiscreteFunctionVariant>& u, - const std::shared_ptr<const DiscreteFunctionVariant>& E, - const std::shared_ptr<const DiscreteFunctionVariant>& c, - const std::shared_ptr<const DiscreteFunctionVariant>& p, - const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>& - bc_descriptor_list, - const double& dt) -> std::tuple<std::shared_ptr<const IMesh>, - std::shared_ptr<const DiscreteFunctionVariant>, - std::shared_ptr<const DiscreteFunctionVariant>, - std::shared_ptr<const DiscreteFunctionVariant>> { - return LocalDtAcousticSolverHandler{getCommonMesh({rho, u, E, c, p})} + [](const std::shared_ptr<const DiscreteFunctionVariant>& rho1, + const std::shared_ptr<const DiscreteFunctionVariant>& u1, + const std::shared_ptr<const DiscreteFunctionVariant>& E1, + const std::shared_ptr<const DiscreteFunctionVariant>& c1, + const std::shared_ptr<const DiscreteFunctionVariant>& p1, + const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>& + bc_descriptor_list1, + const double& dt1, + const std::shared_ptr<const DiscreteFunctionVariant>& rho2, + const std::shared_ptr<const DiscreteFunctionVariant>& u2, + const std::shared_ptr<const DiscreteFunctionVariant>& E2, + const std::shared_ptr<const DiscreteFunctionVariant>& c2, + const std::shared_ptr<const DiscreteFunctionVariant>& p2, + const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>& + bc_descriptor_list2, + const size_t& q) -> std::tuple<std::shared_ptr<const IMesh>, + std::shared_ptr<const DiscreteFunctionVariant>, + std::shared_ptr<const DiscreteFunctionVariant>, + std::shared_ptr<const DiscreteFunctionVariant>, + std::shared_ptr<const IMesh>, + std::shared_ptr<const DiscreteFunctionVariant>, + std::shared_ptr<const DiscreteFunctionVariant>, + std::shared_ptr<const DiscreteFunctionVariant>> { + return LocalDtAcousticSolverHandler{getCommonMesh({rho1, u1, E1, c1, p1}),getCommonMesh({rho2, u2, E2, c2, p2})} .solver() - .apply(LocalDtAcousticSolverHandler::SolverType::Glace, dt, rho, u, E, c, p, - bc_descriptor_list); + .apply(LocalDtAcousticSolverHandler::SolverType::Glace, dt1, q, rho1, rho2, u1, u2, E1, E2, c1, c2, p1, p2, + bc_descriptor_list1, bc_descriptor_list2); } )); @@ -420,21 +442,33 @@ SchemeModule::SchemeModule() this->_addBuiltinFunction("local_dt_eucclhyd_solver", std::function( - [](const std::shared_ptr<const DiscreteFunctionVariant>& rho, - const std::shared_ptr<const DiscreteFunctionVariant>& u, - const std::shared_ptr<const DiscreteFunctionVariant>& E, - const std::shared_ptr<const DiscreteFunctionVariant>& c, - const std::shared_ptr<const DiscreteFunctionVariant>& p, - const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>& - bc_descriptor_list, - const double& dt) -> std::tuple<std::shared_ptr<const IMesh>, - std::shared_ptr<const DiscreteFunctionVariant>, - std::shared_ptr<const DiscreteFunctionVariant>, - std::shared_ptr<const DiscreteFunctionVariant>> { - return LocalDtAcousticSolverHandler{getCommonMesh({rho, u, E, c, p})} + [](const std::shared_ptr<const DiscreteFunctionVariant>& rho1, + const std::shared_ptr<const DiscreteFunctionVariant>& u1, + const std::shared_ptr<const DiscreteFunctionVariant>& E1, + const std::shared_ptr<const DiscreteFunctionVariant>& c1, + const std::shared_ptr<const DiscreteFunctionVariant>& p1, + const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>& + bc_descriptor_list1, + const double& dt1, + const std::shared_ptr<const DiscreteFunctionVariant>& rho2, + const std::shared_ptr<const DiscreteFunctionVariant>& u2, + const std::shared_ptr<const DiscreteFunctionVariant>& E2, + const std::shared_ptr<const DiscreteFunctionVariant>& c2, + const std::shared_ptr<const DiscreteFunctionVariant>& p2, + const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>& + bc_descriptor_list2, + const size_t& q) -> std::tuple<std::shared_ptr<const IMesh>, + std::shared_ptr<const DiscreteFunctionVariant>, + std::shared_ptr<const DiscreteFunctionVariant>, + std::shared_ptr<const DiscreteFunctionVariant>, + std::shared_ptr<const IMesh>, + std::shared_ptr<const DiscreteFunctionVariant>, + std::shared_ptr<const DiscreteFunctionVariant>, + std::shared_ptr<const DiscreteFunctionVariant>> { + return LocalDtAcousticSolverHandler{getCommonMesh({rho1, u1, E1, c1, p1}),getCommonMesh({rho2, u2, E2, c2, p2})} .solver() - .apply(LocalDtAcousticSolverHandler::SolverType::Eucclhyd, dt, rho, u, E, c, p, - bc_descriptor_list); + .apply(LocalDtAcousticSolverHandler::SolverType::Eucclhyd, dt1, q, rho1, rho2, u1, u2, E1, E2, c1, c2, p1, p2, + bc_descriptor_list1, bc_descriptor_list2); } )); diff --git a/src/scheme/CouplingBoundaryConditionDescriptor.hpp b/src/scheme/CouplingBoundaryConditionDescriptor.hpp new file mode 100644 index 0000000000000000000000000000000000000000..3b4b26d320ab5318efee7ad95b00d34b53e78c67 --- /dev/null +++ b/src/scheme/CouplingBoundaryConditionDescriptor.hpp @@ -0,0 +1,46 @@ +#ifndef COUPLING_BOUNDARY_CONDITION_DESCRIPTOR_HPP +#define COUPLING_BOUNDARY_CONDITION_DESCRIPTOR_HPP + +#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; +}; + +#endif // COUPLING_BOUNDARY_CONDITION_DESCRIPTOR_HPP diff --git a/src/scheme/IBoundaryConditionDescriptor.hpp b/src/scheme/IBoundaryConditionDescriptor.hpp index f99eff9355f6fdf6fbd65ad1898f3cba655af284..5092f1973a9988be5342c48ebbdf0445ecb9d5b4 100644 --- a/src/scheme/IBoundaryConditionDescriptor.hpp +++ b/src/scheme/IBoundaryConditionDescriptor.hpp @@ -17,7 +17,8 @@ class IBoundaryConditionDescriptor fixed, free, neumann, - symmetry + symmetry, + coupling }; protected: diff --git a/src/scheme/LocalDtAcousticSolver.cpp b/src/scheme/LocalDtAcousticSolver.cpp index ade62e0e25736800a9b6f4bd56c7d8a2e3f88cf2..e535c6e8dae0eddb2ebbc7d06ebe7d36cb5e4f43 100644 --- a/src/scheme/LocalDtAcousticSolver.cpp +++ b/src/scheme/LocalDtAcousticSolver.cpp @@ -15,6 +15,7 @@ #include <scheme/IBoundaryConditionDescriptor.hpp> #include <scheme/IDiscreteFunctionDescriptor.hpp> #include <scheme/SymmetryBoundaryConditionDescriptor.hpp> +#include <scheme/CouplingBoundaryConditionDescriptor.hpp> #include <utils/Socket.hpp> #include <variant> @@ -39,12 +40,14 @@ class LocalDtAcousticSolverHandler::LocalDtAcousticSolver final class SymmetryBoundaryCondition; class VelocityBoundaryCondition; class ExternalFSIVelocityBoundaryCondition; + class CouplingBoundaryCondition; using BoundaryCondition = std::variant<FixedBoundaryCondition, PressureBoundaryCondition, SymmetryBoundaryCondition, VelocityBoundaryCondition, - ExternalFSIVelocityBoundaryCondition>; + ExternalFSIVelocityBoundaryCondition, + CouplingBoundaryCondition>; using BoundaryConditionList = std::vector<BoundaryCondition>; @@ -268,6 +271,11 @@ class LocalDtAcousticSolverHandler::LocalDtAcousticSolver final } break; } + case IBoundaryConditionDescriptor::Type::coupling: { + bc_list.emplace_back( + CouplingBoundaryCondition(getMeshFlatNodeBoundary(mesh, bc_descriptor->boundaryDescriptor()))); + break; + } default: { is_valid_boundary_condition = false; } @@ -289,6 +297,20 @@ class LocalDtAcousticSolverHandler::LocalDtAcousticSolver final const DiscreteScalarFunction& p, NodeValue<Rdxd>& Ar, NodeValue<Rd>& br) const; + void _applyCouplingBC(const BoundaryConditionList& bc_list1, + const BoundaryConditionList& bc_list2, + const MeshType& mesh1, + const MeshType& mesh2, + NodeValue<Rdxd>& Ar1, + NodeValue<Rdxd>& Ar2, + NodeValue<Rd>& br1, + NodeValue<Rd>& br2) const; + void _applyCouplingBC(const BoundaryConditionList& bc_list, + const MeshType& mesh, + NodeValue<Rd>& ur, + NodeValue<Rd>& CR_ur, + NodeValuePerCell<Rd>& Fjr, + NodeValuePerCell<Rd>& CR_Fjr) const; void _applyBoundaryConditions(const BoundaryConditionList& bc_list, @@ -301,7 +323,7 @@ class LocalDtAcousticSolverHandler::LocalDtAcousticSolver final this->_applyVelocityBC(bc_list, Ar, br); } - NodeValue<const Rd> + NodeValue<Rd> _computeUr(const MeshType& mesh, const NodeValue<Rdxd>& Ar, const NodeValue<Rd>& br) const { NodeValue<Rd> u{mesh.connectivity()}; @@ -380,10 +402,140 @@ class LocalDtAcousticSolverHandler::LocalDtAcousticSolver final std::make_shared<const SubItemValuePerItemVariant>(Fjr)); } + std::tuple<const std::shared_ptr<const ItemValueVariant>, + const std::shared_ptr<const SubItemValuePerItemVariant>, + const std::shared_ptr<const ItemValueVariant>, + const std::shared_ptr<const SubItemValuePerItemVariant>, + NodeValue<Rd>, + NodeValuePerCell<Rd>> + compute_fluxes(const SolverType& solver_type, + const std::shared_ptr<const DiscreteFunctionVariant>& rho1_v, + const std::shared_ptr<const DiscreteFunctionVariant>& c1_v, + const std::shared_ptr<const DiscreteFunctionVariant>& u1_v, + const std::shared_ptr<const DiscreteFunctionVariant>& p1_v, + const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>& bc_descriptor_list1, + const std::shared_ptr<const DiscreteFunctionVariant>& rho2_v, + const std::shared_ptr<const DiscreteFunctionVariant>& c2_v, + const std::shared_ptr<const DiscreteFunctionVariant>& u2_v, + const std::shared_ptr<const DiscreteFunctionVariant>& p2_v, + const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>& bc_descriptor_list2) const + { + std::shared_ptr i_mesh1 = getCommonMesh({rho1_v, c1_v, u1_v, p1_v}); + std::shared_ptr i_mesh2 = getCommonMesh({rho2_v, c2_v, u2_v, p2_v}); + if (not i_mesh1) { + throw NormalError("discrete functions are not defined on the same mesh"); + } + + if (not checkDiscretizationType({rho1_v, c1_v, u1_v, p1_v}, DiscreteFunctionType::P0)) { + throw NormalError("acoustic solver expects P0 functions"); + } + + if (not i_mesh2) { + throw NormalError("discrete functions are not defined on the same mesh"); + } + + if (not checkDiscretizationType({rho2_v, c2_v, u2_v, p2_v}, DiscreteFunctionType::P0)) { + throw NormalError("acoustic solver expects P0 functions"); + } + + const MeshType& mesh1 = dynamic_cast<const MeshType&>(*i_mesh1); + const DiscreteScalarFunction& rho1 = rho1_v->get<DiscreteScalarFunction>(); + const DiscreteScalarFunction& c1 = c1_v->get<DiscreteScalarFunction>(); + const DiscreteVectorFunction& u1 = u1_v->get<DiscreteVectorFunction>(); + const DiscreteScalarFunction& p1 = p1_v->get<DiscreteScalarFunction>(); + + const MeshType& mesh2 = dynamic_cast<const MeshType&>(*i_mesh2); + const DiscreteScalarFunction& rho2 = rho2_v->get<DiscreteScalarFunction>(); + const DiscreteScalarFunction& c2 = c2_v->get<DiscreteScalarFunction>(); + const DiscreteVectorFunction& u2 = u2_v->get<DiscreteVectorFunction>(); + const DiscreteScalarFunction& p2 = p2_v->get<DiscreteScalarFunction>(); + + NodeValuePerCell<const Rdxd> Ajr1 = this->_computeAjr(solver_type, mesh1, rho1 * c1); + NodeValuePerCell<const Rdxd> Ajr2 = this->_computeAjr(solver_type, mesh2, rho2 * c2); + + NodeValue<Rdxd> Ar1 = this->_computeAr(mesh1, Ajr1); + NodeValue<Rd> br1 = this->_computeBr(mesh1, Ajr1, u1, p1); + NodeValue<Rdxd> Ar2 = this->_computeAr(mesh2, Ajr2); + NodeValue<Rd> br2 = this->_computeBr(mesh2, Ajr2, u2, p2); + + const BoundaryConditionList bc_list1 = this->_getBCList(mesh1, bc_descriptor_list1); + const BoundaryConditionList bc_list2 = this->_getBCList(mesh2, bc_descriptor_list2); + this->_applyBoundaryConditions(bc_list1, mesh1, Ar1, br1); + this->_applyBoundaryConditions(bc_list2, mesh2, Ar2, br2); + this->_applyExternalVelocityBC(bc_list1, p1, Ar1, br1); + this->_applyExternalVelocityBC(bc_list2, p2, Ar2, br2); + this->_applyCouplingBC(bc_list1,bc_list2,mesh1,mesh2,Ar1,Ar2,br1,br2); + + synchronize(Ar1); + synchronize(br1); + synchronize(Ar2); + synchronize(br2); + + NodeValue<Rd> ur1 = this->_computeUr(mesh1, Ar1, br1); + NodeValuePerCell<Rd> Fjr1 = this->_computeFjr(mesh1, Ajr1, ur1, u1, p1); + NodeValue<Rd> ur2 = this->_computeUr(mesh2, Ar2, br2); + NodeValuePerCell<Rd> Fjr2 = this->_computeFjr(mesh2, Ajr2, ur2, u2, p2); + NodeValue<Rd> CR_ur = this->_computeUr(mesh2, Ar2, br2); + NodeValuePerCell<Rd> CR_Fjr = this->_computeFjr(mesh2, Ajr2, ur2, u2, p2); + + return std::make_tuple(std::make_shared<const ItemValueVariant>(ur1), + std::make_shared<const SubItemValuePerItemVariant>(Fjr1), + std::make_shared<const ItemValueVariant>(ur2), + std::make_shared<const SubItemValuePerItemVariant>(Fjr2), + CR_ur, + CR_Fjr); + } + + std::tuple<const std::shared_ptr<const ItemValueVariant>, const std::shared_ptr<const SubItemValuePerItemVariant>> + compute_fluxes(const SolverType& solver_type, + const std::shared_ptr<const DiscreteFunctionVariant>& rho_v, + const std::shared_ptr<const DiscreteFunctionVariant>& c_v, + const std::shared_ptr<const DiscreteFunctionVariant>& u_v, + const std::shared_ptr<const DiscreteFunctionVariant>& p_v, + const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>& bc_descriptor_list, + NodeValue<Rd> CR_ur, + NodeValuePerCell<Rd> CR_Fjr) const + { + std::shared_ptr i_mesh = getCommonMesh({rho_v, c_v, u_v, p_v}); + if (not i_mesh) { + throw NormalError("discrete functions are not defined on the same mesh"); + } + + if (not checkDiscretizationType({rho_v, c_v, u_v, p_v}, DiscreteFunctionType::P0)) { + throw NormalError("acoustic solver expects P0 functions"); + } + + const MeshType& mesh = dynamic_cast<const MeshType&>(*i_mesh); + const DiscreteScalarFunction& rho = rho_v->get<DiscreteScalarFunction>(); + const DiscreteScalarFunction& c = c_v->get<DiscreteScalarFunction>(); + const DiscreteVectorFunction& u = u_v->get<DiscreteVectorFunction>(); + const DiscreteScalarFunction& p = p_v->get<DiscreteScalarFunction>(); + + NodeValuePerCell<const Rdxd> Ajr = this->_computeAjr(solver_type, mesh, rho * c); + + NodeValue<Rdxd> Ar = this->_computeAr(mesh, Ajr); + NodeValue<Rd> br = this->_computeBr(mesh, Ajr, u, p); + + const BoundaryConditionList bc_list = this->_getBCList(mesh, bc_descriptor_list); + this->_applyBoundaryConditions(bc_list, mesh, Ar, br); + this->_applyExternalVelocityBC(bc_list, p, Ar, br); + + synchronize(Ar); + synchronize(br); + + NodeValue<Rd> ur = this->_computeUr(mesh, Ar, br); + NodeValuePerCell<Rd> Fjr = this->_computeFjr(mesh, Ajr, ur, u, p); + + this->_applyCouplingBC(bc_list,mesh,ur,CR_ur,Fjr,CR_Fjr); + + return std::make_tuple(std::make_shared<const ItemValueVariant>(ur), + std::make_shared<const SubItemValuePerItemVariant>(Fjr)); + } + std::tuple<std::shared_ptr<const IMesh>, std::shared_ptr<const DiscreteFunctionVariant>, std::shared_ptr<const DiscreteFunctionVariant>, - std::shared_ptr<const DiscreteFunctionVariant>> + std::shared_ptr<const DiscreteFunctionVariant>> apply_fluxes(const double& dt, const MeshType& mesh, const DiscreteScalarFunction& rho, @@ -457,6 +609,7 @@ class LocalDtAcousticSolverHandler::LocalDtAcousticSolver final throw NormalError("acoustic solver expects P0 functions"); } + return this->apply_fluxes(dt, // dynamic_cast<const MeshType&>(*i_mesh), // rho_v->get<DiscreteScalarFunction>(), // @@ -469,18 +622,55 @@ class LocalDtAcousticSolverHandler::LocalDtAcousticSolver final std::tuple<std::shared_ptr<const IMesh>, std::shared_ptr<const DiscreteFunctionVariant>, std::shared_ptr<const DiscreteFunctionVariant>, - std::shared_ptr<const DiscreteFunctionVariant>> + std::shared_ptr<const DiscreteFunctionVariant>, + std::shared_ptr<const IMesh>, + std::shared_ptr<const DiscreteFunctionVariant>, + std::shared_ptr<const DiscreteFunctionVariant>, + std::shared_ptr<const DiscreteFunctionVariant>> apply(const SolverType& solver_type, - const double& dt, - const std::shared_ptr<const DiscreteFunctionVariant>& rho, - const std::shared_ptr<const DiscreteFunctionVariant>& u, - const std::shared_ptr<const DiscreteFunctionVariant>& E, - const std::shared_ptr<const DiscreteFunctionVariant>& c, - const std::shared_ptr<const DiscreteFunctionVariant>& p, - const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>& bc_descriptor_list) const + const double& dt1, + const size_t& q, + const std::shared_ptr<const DiscreteFunctionVariant>& rho1, + const std::shared_ptr<const DiscreteFunctionVariant>& rho2, + const std::shared_ptr<const DiscreteFunctionVariant>& u1, + const std::shared_ptr<const DiscreteFunctionVariant>& u2, + const std::shared_ptr<const DiscreteFunctionVariant>& E1, + const std::shared_ptr<const DiscreteFunctionVariant>& E2, + const std::shared_ptr<const DiscreteFunctionVariant>& c1, + const std::shared_ptr<const DiscreteFunctionVariant>& c2, + const std::shared_ptr<const DiscreteFunctionVariant>& p1, + const std::shared_ptr<const DiscreteFunctionVariant>& p2, + const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>& bc_descriptor_list1, + const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>& bc_descriptor_list2) const { - auto [ur, Fjr] = compute_fluxes(solver_type, rho, c, u, p, bc_descriptor_list); - return apply_fluxes(dt, rho, u, E, ur, Fjr); + std::shared_ptr<const IMesh> new_m2 = getCommonMesh({rho2, c2, u2, p2}); + std::shared_ptr<const DiscreteFunctionVariant> new_rho2 = rho2; + std::shared_ptr<const DiscreteFunctionVariant> new_u2 = u2; + std::shared_ptr<const DiscreteFunctionVariant> new_E2 = E2; + + auto [ur1, Fjr1, ur2, Fjr2,CR_ur,CR_Fjr] = compute_fluxes(solver_type, rho1, c1, u1, p1, bc_descriptor_list1, rho2, c2, u2, p2, bc_descriptor_list2); + auto [new_m1,new_rho1,new_u1,new_E1] = apply_fluxes(dt1, rho1, u1, E1, ur1, Fjr1); + + const double& dt2 = dt1/q; + const double& gamma = 1.4; + + for(size_t i = 0; i<q; i++){ + std::tie(new_m2,new_rho2,new_u2,new_E2) = apply_fluxes(dt2,new_rho2,new_u2,new_E2,ur2,Fjr2); + + DiscreteScalarFunction rho_d = new_rho2->get<DiscreteScalarFunction>(); + DiscreteVectorFunction u_d = new_u2->get<DiscreteVectorFunction>(); + DiscreteScalarFunction E_d = new_E2->get<DiscreteScalarFunction>(); + DiscreteScalarFunction eps = E_d - 0.5 * dot(u_d,u_d); + DiscreteScalarFunction p_d = (gamma-1) * rho_d * eps; + DiscreteScalarFunction c_d = sqrt(gamma * p_d / rho_d); + + std::shared_ptr<const DiscreteFunctionVariant> new_p2 = std::make_shared<DiscreteFunctionVariant>(p_d); + std::shared_ptr<const DiscreteFunctionVariant> new_c2 = std::make_shared<DiscreteFunctionVariant>(c_d); + + auto [ur2,Fjr2] = compute_fluxes(solver_type,new_rho2,new_c2,new_u2,new_p2,bc_descriptor_list2,CR_ur,CR_Fjr); + } + + return {new_m1,new_rho1,new_u1,new_E1,new_m2,new_rho2,new_u2,new_E2}; } LocalDtAcousticSolver() = default; @@ -651,6 +841,125 @@ LocalDtAcousticSolverHandler::LocalDtAcousticSolver<Dimension>::_applyExternalVe } } +template <size_t Dimension> +void LocalDtAcousticSolverHandler::LocalDtAcousticSolver<Dimension>::_applyCouplingBC(const BoundaryConditionList& bc_list1, + const BoundaryConditionList& bc_list2, + const MeshType& mesh1, + const MeshType& mesh2, + NodeValue<Rdxd>& Ar1, + NodeValue<Rdxd>& Ar2, + NodeValue<Rd>& br1, + NodeValue<Rd>& br2) const +{ + NodeValue<Rd> xr1 = copy(mesh1.xr()); + NodeValue<Rd> xr2 = copy(mesh2.xr()); + for(const auto& boundary_condition1 : bc_list1){ + std::visit([&](auto&& bc1) { + using T1 = std::decay_t<decltype(bc1)>; + if constexpr (std::is_same_v<CouplingBoundaryCondition,T1>){ + const auto& node_list1 = bc1.nodeList(); + for(const auto& boundary_condition2 : bc_list2){ + std::visit([&](auto&& bc2) { + using T2 = std::decay_t<decltype(bc2)>; + if constexpr (std::is_same_v<CouplingBoundaryCondition,T2>){ + const auto& node_list2 = bc2.nodeList(); + if constexpr (Dimension == 1){ + for(size_t i = 0; i<node_list1.size(); i++){ + NodeId node_id1 = node_list1[i]; + NodeId node_id2; + for(size_t j = 0; j<node_list2.size(); j++){ + node_id2 = node_list2[j]; + if(abs(xr1[node_id1][0] - xr2[node_id2][0]) < 1e-14){ + Ar1[node_id1] += Ar2[node_id2]; + Ar2[node_id2] = Ar1[node_id1]; + + br1[node_id1] += br2[node_id2]; + br2[node_id2] = br1[node_id1]; + + break; + } + } + } + } else if constexpr (Dimension == 2){ + for(size_t i = 0; i<node_list1.size(); i++){ + NodeId node_id1 = node_list1[i]; + NodeId node_id2; + for(size_t j = 0; j<node_list2.size(); j++){ + node_id2 = node_list2[j]; + if((abs(xr1[node_id1][0] - xr2[node_id2][0]) < 1e-14) and + (abs(xr1[node_id1][1] - xr2[node_id2][1]) < 1e-14)){ + Ar1[node_id1] += Ar2[node_id2]; + Ar2[node_id2] = Ar1[node_id1]; + + br1[node_id1] += br2[node_id2]; + br2[node_id2] = br1[node_id1]; + + break; + } + } + } + } else { + for(size_t i = 0; i<node_list1.size(); i++){ + NodeId node_id1 = node_list1[i]; + NodeId node_id2; + for(size_t j = 0; j<node_list2.size(); j++){ + node_id2 = node_list2[j]; + if((abs(xr1[node_id1][0] - xr2[node_id2][0]) < 1e-14) and + (abs(xr1[node_id1][1] - xr2[node_id2][1]) < 1e-14) and + (abs(xr1[node_id1][2] - xr2[node_id2][2]) < 1e-14)){ + Ar1[node_id1] += Ar2[node_id2]; + Ar2[node_id2] = Ar1[node_id1]; + + br1[node_id1] += br2[node_id2]; + br2[node_id2] = br1[node_id1]; + + break; + } + } + } + } + } + },boundary_condition2); + } + } + }, boundary_condition1); + } +} + +template <size_t Dimension> +void LocalDtAcousticSolverHandler::LocalDtAcousticSolver<Dimension>::_applyCouplingBC(const BoundaryConditionList& bc_list, + const MeshType& mesh, + NodeValue<Rd>& ur, + NodeValue<Rd>& CR_ur, + NodeValuePerCell<Rd>& Fjr, + NodeValuePerCell<Rd>& CR_Fjr) 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(); + const auto& node_to_cell_matrix = mesh.connectivity().nodeToCellMatrix(); + const auto& node_local_numbers_in_their_cells = mesh.connectivity().nodeLocalNumbersInTheirCells(); + + for(size_t i = 0; i < node_list.size(); i++){ + NodeId node_id = node_list[i]; + const auto& node_to_cell = node_to_cell_matrix[node_id]; + const auto& node_local_number_in_its_cells = node_local_numbers_in_their_cells.itemArray(node_id); + + for(size_t j = 0; j < node_to_cell.size(); j++){ + const CellId J = node_to_cell[j]; + const unsigned int R = node_local_number_in_its_cells[j]; + Fjr(J,R) = CR_Fjr(J,R); + } + ur[node_id] = CR_ur[node_id]; + } + } + }, boundary_condition); + } +} + template <size_t Dimension> class LocalDtAcousticSolverHandler::LocalDtAcousticSolver<Dimension>::FixedBoundaryCondition { @@ -841,13 +1150,45 @@ class LocalDtAcousticSolverHandler::LocalDtAcousticSolver<Dimension>::SymmetryBo ~SymmetryBoundaryCondition() = default; }; -LocalDtAcousticSolverHandler::LocalDtAcousticSolverHandler(const std::shared_ptr<const IMesh>& i_mesh) +template <size_t Dimension> +class LocalDtAcousticSolverHandler::LocalDtAcousticSolver<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; + +}; + +LocalDtAcousticSolverHandler::LocalDtAcousticSolverHandler(const std::shared_ptr<const IMesh>& i_mesh1, const std::shared_ptr<const IMesh>& i_mesh2) { - if (not i_mesh) { - throw NormalError("discrete functions are not defined on the same mesh"); + if (not i_mesh1) { + throw NormalError("mesh1 not defined"); } - switch (i_mesh->dimension()) { + if (not i_mesh2) { + throw NormalError("mesh2 not defined"); + } + + if (not (i_mesh1->dimension()==i_mesh2->dimension())) { + throw NormalError("mesh1 and mesh2 must have the same dimension"); + } + + + switch (i_mesh1->dimension()) { case 1: { m_acoustic_solver = std::make_unique<LocalDtAcousticSolver<1>>(); break; diff --git a/src/scheme/LocalDtAcousticSolver.hpp b/src/scheme/LocalDtAcousticSolver.hpp index 101054f7974aa360c16e655b0f3b9f95781fa426..3f84ae440822e22c8be14ddcb6dc60d1858e3723 100644 --- a/src/scheme/LocalDtAcousticSolver.hpp +++ b/src/scheme/LocalDtAcousticSolver.hpp @@ -47,15 +47,26 @@ class LocalDtAcousticSolverHandler virtual std::tuple<std::shared_ptr<const IMesh>, std::shared_ptr<const DiscreteFunctionVariant>, std::shared_ptr<const DiscreteFunctionVariant>, - std::shared_ptr<const DiscreteFunctionVariant>> + std::shared_ptr<const DiscreteFunctionVariant>, + std::shared_ptr<const IMesh>, + std::shared_ptr<const DiscreteFunctionVariant>, + std::shared_ptr<const DiscreteFunctionVariant>, + std::shared_ptr<const DiscreteFunctionVariant>> apply(const SolverType& solver_type, - const double& dt, - const std::shared_ptr<const DiscreteFunctionVariant>& rho, - const std::shared_ptr<const DiscreteFunctionVariant>& u, - const std::shared_ptr<const DiscreteFunctionVariant>& E, - const std::shared_ptr<const DiscreteFunctionVariant>& c, - const std::shared_ptr<const DiscreteFunctionVariant>& p, - const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>& bc_descriptor_list) const = 0; + const double& dt1, + const size_t& q, + const std::shared_ptr<const DiscreteFunctionVariant>& rho1, + const std::shared_ptr<const DiscreteFunctionVariant>& rho2, + const std::shared_ptr<const DiscreteFunctionVariant>& u1, + const std::shared_ptr<const DiscreteFunctionVariant>& u2, + const std::shared_ptr<const DiscreteFunctionVariant>& E1, + const std::shared_ptr<const DiscreteFunctionVariant>& E2, + const std::shared_ptr<const DiscreteFunctionVariant>& c1, + const std::shared_ptr<const DiscreteFunctionVariant>& c2, + const std::shared_ptr<const DiscreteFunctionVariant>& p1, + const std::shared_ptr<const DiscreteFunctionVariant>& p2, + const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>& bc_descriptor_list1, + const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>& bc_descriptor_list2) const = 0; ILocalDtAcousticSolver() = default; ILocalDtAcousticSolver(ILocalDtAcousticSolver&&) = default; @@ -76,7 +87,7 @@ class LocalDtAcousticSolverHandler return *m_acoustic_solver; } - LocalDtAcousticSolverHandler(const std::shared_ptr<const IMesh>& mesh); + LocalDtAcousticSolverHandler(const std::shared_ptr<const IMesh>& mesh1,const std::shared_ptr<const IMesh>& mesh2); }; #endif // LOCAL_DT_ACOUSTIC_SOLVER_HPP