diff --git a/src/language/modules/SchemeModule.cpp b/src/language/modules/SchemeModule.cpp index e1af0c003f55eff3855b1a16ae9a0c452d6ce8d4..7d144f7e981313141f16ad40f5da0baa4211fb6a 100644 --- a/src/language/modules/SchemeModule.cpp +++ b/src/language/modules/SchemeModule.cpp @@ -941,17 +941,13 @@ SchemeModule::SchemeModule() const std::shared_ptr<const DiscreteFunctionVariant>& F_rho_u1, const std::shared_ptr<const DiscreteFunctionVariant>& F_rho_u2, const std::shared_ptr<const DiscreteFunctionVariant>& F_E, - const std::shared_ptr<const DiscreteFunctionVariant>& rho_ex, - const std::shared_ptr<const DiscreteFunctionVariant>& rho_u_ex, - const std::shared_ptr<const DiscreteFunctionVariant>& rho_E_ex, const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>& bc_descriptor_list) -> std::tuple<std::shared_ptr<const DiscreteFunctionVariant>, std::shared_ptr<const DiscreteFunctionVariant>, std::shared_ptr<const DiscreteFunctionVariant>, std::shared_ptr<const DiscreteFunctionVariant>> { return eulerKineticSolver2D(dt, gamma, lambda_vector, eps, SpaceOrder, F_rho, F_rho_u1, - F_rho_u2, F_E, rho_ex, rho_u_ex, rho_E_ex, - bc_descriptor_list); + F_rho_u2, F_E, bc_descriptor_list); } )); diff --git a/src/scheme/EulerKineticSolver2D.cpp b/src/scheme/EulerKineticSolver2D.cpp index f2130599b3b744015108d7514ad2fc1e8d137844..281db07dc6b593de71798d906a764043e3136bf6 100644 --- a/src/scheme/EulerKineticSolver2D.cpp +++ b/src/scheme/EulerKineticSolver2D.cpp @@ -217,13 +217,9 @@ class EulerKineticSolver2D const double m_eps; const std::vector<TinyVector<Dimension>>& m_lambda_vector; const size_t m_SpaceOrder; - const DiscreteFunctionP0Vector<const double> m_Fn_rho; - const DiscreteFunctionP0Vector<const double> m_Fn_rho_u1; - const DiscreteFunctionP0Vector<const double> m_Fn_rho_u2; - const DiscreteFunctionP0Vector<const double> m_Fn_rho_E; - const DiscreteFunctionP0<const double> m_rho_ex; - const DiscreteFunctionP0<const TinyVector<Dimension>> m_rho_u_ex; - const DiscreteFunctionP0<const double> m_rho_E_ex; + const CellArray<const double> m_Fn_rho; + const CellArray<TinyVector<Dimension>> m_Fn_rho_u; + const CellArray<const double> m_Fn_rho_E; const double m_gamma; const std::shared_ptr<const MeshType> p_mesh; const MeshType& m_mesh; @@ -344,43 +340,123 @@ class EulerKineticSolver2D return vec_A; } - DiscreteFunctionP0Vector<double> - compute_M(const DiscreteFunctionP0<const double>& u, const DiscreteFunctionP0<TinyVector<MeshType::Dimension>> A_u) + const CellValue<const TinyVector<Dimension>> + getA_rho(const CellValue<const TinyVector<Dimension>>& rho_u) const { - const size_t nb_waves = m_lambda_vector.size(); - DiscreteFunctionP0Vector<double> M{p_mesh, nb_waves}; + return rho_u; + } - TinyVector<MeshType::Dimension> inv_S = zero; - for (size_t i = 0; i < nb_waves; ++i) { - for (size_t d = 0; d < MeshType::Dimension; ++d) { - inv_S[d] += std::pow(m_lambda_vector[i][d], 2); + const CellValue<const TinyMatrix<Dimension>> + getA_rho_u(const CellValue<const double>& rho, + const CellValue<const TinyVector<Dimension>>& rho_u, + const CellValue<const double>& rho_E) const + { + CellValue<TinyMatrix<Dimension>> vec_A{m_mesh.connectivity()}; + const TinyMatrix<Dimension> I = identity; + CellValue<double> rho_e{m_mesh.connectivity()}; + CellValue<double> p{m_mesh.connectivity()}; + + parallel_for( + m_mesh.numberOfCells(), PUGS_LAMBDA(const CellId cell_id) { + rho_e[cell_id] = rho_E[cell_id] - 0.5 * (1. / rho[cell_id]) * dot(rho_u[cell_id], rho_u[cell_id]); + p[cell_id] = (m_gamma - 1) * rho_e[cell_id]; + + vec_A[cell_id] = 1. / rho[cell_id] * tensorProduct(rho_u[cell_id], rho_u[cell_id]) + p[cell_id] * I; + }); + + return vec_A; + } + + const CellValue<const TinyVector<Dimension>> + getA_rho_E(const CellValue<const double>& rho, + const CellValue<const TinyVector<Dimension>>& rho_u, + const CellValue<const double>& rho_E) const + { + CellValue<TinyVector<Dimension>> vec_A{m_mesh.connectivity()}; + + parallel_for( + m_mesh.numberOfCells(), PUGS_LAMBDA(const CellId cell_id) { + double rho_e = rho_E[cell_id] - 0.5 * (1. / rho[cell_id]) * dot(rho_u[cell_id], rho_u[cell_id]); + double p = (m_gamma - 1) * rho_e; + + vec_A[cell_id] = (rho_E[cell_id] + p) / rho[cell_id] * rho_u[cell_id]; + }); + + return vec_A; + } + + const CellArray<const double> + compute_scalar_M(const CellValue<const double>& u, const CellValue<const TinyVector<Dimension>>& A_u) + { + const size_t nb_waves = m_lambda_vector.size(); + CellArray<double> M{p_mesh->connectivity(), nb_waves}; + TinyVector<Dimension> inv_S = zero; + for (size_t d = 0; d < MeshType::Dimension; ++d) { + for (size_t i = 0; i < nb_waves; ++i) { + inv_S[d] += m_lambda_vector[i][d] * m_lambda_vector[i][d]; } + inv_S[d] = 1. / inv_S[d]; } + + parallel_for( + m_mesh.numberOfCells(), PUGS_LAMBDA(const CellId cell_id) { + for (size_t i = 0; i < nb_waves; ++i) { + M[cell_id][i] = (1. / nb_waves) * u[cell_id]; + + for (size_t d = 0; d < Dimension; ++d) { + M[cell_id][i] += inv_S[d] * m_lambda_vector[i][d] * A_u[cell_id][d]; + } + } + }); + + return M; + } + + const CellArray<const TinyVector<Dimension>> + compute_vector_M(const CellValue<const TinyVector<Dimension>>& u, const CellValue<const TinyMatrix<Dimension>>& A_u) + { + const size_t nb_waves = m_lambda_vector.size(); + CellArray<TinyVector<Dimension>> M{p_mesh->connectivity(), nb_waves}; + TinyVector<MeshType::Dimension> inv_S = zero; for (size_t d = 0; d < MeshType::Dimension; ++d) { + for (size_t i = 0; i < nb_waves; ++i) { + inv_S[d] += m_lambda_vector[i][d] * m_lambda_vector[i][d]; + } inv_S[d] = 1. / inv_S[d]; } + parallel_for( m_mesh.numberOfCells(), PUGS_LAMBDA(const CellId cell_id) { - for (size_t i = 0; i < nb_waves; ++i) { - M[cell_id][i] = (1. / nb_waves) * u[cell_id] + inv_S[0] * A_u[cell_id][0] * m_lambda_vector[i][0] + - inv_S[1] * A_u[cell_id][1] * m_lambda_vector[i][1]; + for (size_t i_wave = 0; i_wave < nb_waves; ++i_wave) { + M[cell_id][i_wave] = 1. / nb_waves * u[cell_id]; + for (size_t d1 = 0; d1 < Dimension; ++d1) { + for (size_t d2 = 0; d2 < Dimension; ++d2) { + M[cell_id][i_wave][d1] += inv_S[d2] * m_lambda_vector[i_wave][d2] * A_u[cell_id](d2, d1); + } + } } }); return M; } - DiscreteFunctionP0<double> - compute_PFnp1(const DiscreteFunctionP0Vector<const double>& Fn, DiscreteFunctionP0Vector<double>& deltaLFn) + template <typename T> + const CellValue<const T> + compute_PFnp1(const CellArray<const T>& Fn, const CellArray<const T>& deltaLFn) { - DiscreteFunctionP0<double> PFnp1{p_mesh}; + CellValue<T> PFnp1{p_mesh->connectivity()}; + + if constexpr (is_tiny_vector_v<T>) { + PFnp1.fill(zero); + } else { + PFnp1.fill(0.); + } parallel_for( m_mesh.numberOfCells(), PUGS_LAMBDA(const CellId cell_id) { const double inv_Vj = m_inv_Vj[cell_id]; const double dt_over_Vj = m_dt * inv_Vj; - PFnp1[cell_id] = 0; for (size_t i_wave = 0; i_wave < m_lambda_vector.size(); ++i_wave) { PFnp1[cell_id] += Fn[cell_id][i_wave] - dt_over_Vj * deltaLFn[cell_id][i_wave]; } @@ -389,37 +465,49 @@ class EulerKineticSolver2D return PFnp1; } - DiscreteFunctionP0<double> - compute_PFn(const DiscreteFunctionP0Vector<const double> F) + template <typename T> + const CellValue<const T> + compute_PFn(const CellArray<const T>& F) { - DiscreteFunctionP0<double> PFn{p_mesh}; + const size_t nb_waves = m_lambda_vector.size(); + CellValue<T> PFn{p_mesh->connectivity()}; + if constexpr (is_tiny_vector_v<T>) { + PFn.fill(zero); + } else { + PFn.fill(0.); + } parallel_for( m_mesh.numberOfCells(), PUGS_LAMBDA(const CellId cell_id) { - double PF = 0; - for (size_t i = 0; i < m_lambda_vector.size(); ++i) { - PF += F[cell_id][i]; + for (size_t i = 0; i < nb_waves; ++i) { + PFn[cell_id] += F[cell_id][i]; } - PFn[cell_id] = PF; }); return PFn; } - NodeArray<double> - compute_Flux1(DiscreteFunctionP0Vector<double> Fn) + template <typename T> + NodeArray<T> + compute_Flux1(CellArray<T>& Fn) { const size_t nb_waves = m_lambda_vector.size(); - NodeArray<double> Fr(m_mesh.connectivity(), nb_waves); + NodeArray<T> Fr(m_mesh.connectivity(), nb_waves); const auto& node_local_numbers_in_their_cells = p_mesh->connectivity().nodeLocalNumbersInTheirCells(); const auto& node_to_cell_matrix = p_mesh->connectivity().nodeToCellMatrix(); + if constexpr (is_tiny_vector_v<T>) { + Fr.fill(zero); + } else { + Fr.fill(0.); + } + parallel_for( p_mesh->numberOfNodes(), PUGS_LAMBDA(NodeId node_id) { const auto& node_local_number_in_its_cell = node_local_numbers_in_their_cells.itemArray(node_id); const auto& node_to_cell = node_to_cell_matrix[node_id]; for (size_t i_wave = 0; i_wave < nb_waves; ++i_wave) { - double sum_li_njr = 0; - Fr[node_id][i_wave] = 0; + double sum_li_njr = 0; + for (size_t i_cell = 0; i_cell < node_to_cell.size(); ++i_cell) { const CellId cell_id = node_to_cell[i_cell]; const unsigned int i_node = node_local_number_in_its_cell[i_cell]; @@ -439,17 +527,24 @@ class EulerKineticSolver2D return Fr; } - FaceArrayPerNode<double> - compute_Flux1_eucchlyd(DiscreteFunctionP0Vector<double> Fn) + template <typename T> + FaceArrayPerNode<T> + compute_Flux1_eucchlyd(CellArray<T> Fn) { const size_t nb_waves = m_lambda_vector.size(); - FaceArrayPerNode<double> Fr(m_mesh.connectivity(), nb_waves); + FaceArrayPerNode<T> Flr(m_mesh.connectivity(), nb_waves); const auto& node_local_numbers_in_their_faces = p_mesh->connectivity().nodeLocalNumbersInTheirFaces(); const auto& face_local_numbers_in_their_cells = p_mesh->connectivity().faceLocalNumbersInTheirCells(); const auto& node_to_face_matrix = p_mesh->connectivity().nodeToFaceMatrix(); const auto& face_to_cell_matrix = p_mesh->connectivity().faceToCellMatrix(); const auto& face_cell_is_reversed = p_mesh->connectivity().cellFaceIsReversed(); + if constexpr (is_tiny_vector_v<T>) { + Flr.fill(zero); + } else { + Flr.fill(0.); + } + parallel_for( p_mesh->numberOfNodes(), PUGS_LAMBDA(NodeId node_id) { const auto& node_local_number_in_its_face = node_local_numbers_in_their_faces.itemArray(node_id); @@ -461,8 +556,8 @@ class EulerKineticSolver2D const auto& face_local_number_in_its_cell = face_local_numbers_in_their_cells.itemArray(face_id); const auto& face_to_cell = face_to_cell_matrix[face_id]; const size_t i_node_face = node_local_number_in_its_face[i_face]; - Fr[node_id][i_face][i_wave] = 0; - double sum = 0; + + double sum = 0; for (size_t i_cell = 0; i_cell < face_to_cell.size(); ++i_cell) { const CellId cell_id = face_to_cell[i_cell]; @@ -474,37 +569,42 @@ class EulerKineticSolver2D double li_nlr = sign * dot(m_lambda_vector[i_wave], n_face); if (li_nlr > 0) { - Fr[node_id][i_face][i_wave] += Fn[cell_id][i_wave] * li_nlr; + Flr[node_id][i_face][i_wave] += Fn[cell_id][i_wave] * li_nlr; sum += li_nlr; } } if (sum != 0) { - Fr[node_id][i_face][i_wave] /= sum; + Flr[node_id][i_face][i_wave] /= sum; } } } }); - return Fr; + return Flr; } - FaceArray<double> - compute_Flux1_face(const DiscreteFunctionP0Vector<const double> Fn) + template <typename T> + FaceArray<T> + compute_Flux1_face(const CellArray<const T> Fn) { const size_t nb_waves = m_lambda_vector.size(); - FaceArray<double> Fl(m_mesh.connectivity(), nb_waves); + FaceArray<T> Fl(m_mesh.connectivity(), nb_waves); const auto& face_local_numbers_in_their_cells = p_mesh->connectivity().faceLocalNumbersInTheirCells(); const auto& face_to_cell_matrix = p_mesh->connectivity().faceToCellMatrix(); const auto& face_cell_is_reversed = p_mesh->connectivity().cellFaceIsReversed(); + if constexpr (is_tiny_vector_v<T>) { + Fl.fill(zero); + } else { + Fl.fill(0.); + } + parallel_for( p_mesh->numberOfFaces(), PUGS_LAMBDA(FaceId face_id) { for (size_t i_wave = 0; i_wave < nb_waves; ++i_wave) { const auto& face_local_number_in_its_cell = face_local_numbers_in_their_cells.itemArray(face_id); const auto& face_to_cell = face_to_cell_matrix[face_id]; - Fl[face_id][i_wave] = 0; - for (size_t i_cell = 0; i_cell < face_to_cell.size(); ++i_cell) { const CellId cell_id = face_to_cell[i_cell]; const size_t i_face_cell = face_local_number_in_its_cell[i_cell]; @@ -525,15 +625,13 @@ class EulerKineticSolver2D } void - apply_scalar_bc(FaceArray<double> Fl_rho, - FaceArray<double> Fl_rho_u1, - FaceArray<double> Fl_rho_u2, - FaceArray<double> Fl_rho_E, - const DiscreteFunctionP0<const double> rho, - const DiscreteFunctionP0<const double> rho_u1, - const DiscreteFunctionP0<const double> rho_u2, - const DiscreteFunctionP0<const double> rho_E, - const BoundaryConditionList& bc_list) + apply_symmetry_bc(FaceArray<double> Fl_rho, + FaceArray<TinyVector<Dimension>> Fl_rho_u, + FaceArray<double> Fl_rho_E, + const CellValue<const double> rho, + const CellValue<const TinyVector<Dimension>> rho_u, + const CellValue<const double> rho_E, + const BoundaryConditionList& bc_list) { const size_t nb_waves = m_lambda_vector.size(); const auto& face_local_numbers_in_their_cells = p_mesh->connectivity().faceLocalNumbersInTheirCells(); @@ -541,12 +639,10 @@ class EulerKineticSolver2D const auto& face_cell_is_reversed = p_mesh->connectivity().cellFaceIsReversed(); TinyVector<MeshType::Dimension> inv_S = zero; - for (size_t i = 0; i < nb_waves; ++i) { - for (size_t d = 0; d < MeshType::Dimension; ++d) { - inv_S[d] += std::pow(m_lambda_vector[i][d], 2); - } - } for (size_t d = 0; d < MeshType::Dimension; ++d) { + for (size_t i = 0; i < nb_waves; ++i) { + inv_S[d] += m_lambda_vector[i][d] * m_lambda_vector[i][d]; + } inv_S[d] = 1. / inv_S[d]; } @@ -577,39 +673,33 @@ class EulerKineticSolver2D double li_nl = sign * dot(m_lambda_vector[i_wave], n_face); if (li_nl < 0) { - double rhoj_prime = rho[cell_id]; - TinyVector<Dimension> rho_uj{rho_u1[cell_id], rho_u2[cell_id]}; + double rhoj_prime = rho[cell_id]; + TinyVector<Dimension> rho_uj = rho_u[cell_id]; TinyVector<Dimension> rho_uj_prime = txt * rho_uj - nxn * rho_uj; double rho_Ej_prime = rho_E[cell_id]; - double rho_e = - rho_E[cell_id] - 0.5 * (1. / rho[cell_id]) * - (rho_u1[cell_id] * rho_u1[cell_id] + rho_u2[cell_id] * rho_u2[cell_id]); - double p = (m_gamma - 1) * rho_e; + double rho_e = rho_E[cell_id] - 0.5 * (1. / rho[cell_id]) * dot(rho_u[cell_id], rho_u[cell_id]); + double p = (m_gamma - 1) * rho_e; TinyVector<Dimension> A_rho_prime = rho_uj_prime; - TinyVector<Dimension> A_rho_u1_prime{rho_uj_prime[0] * rho_uj_prime[0] / rhoj_prime + p, - rho_uj_prime[0] * rho_uj_prime[1] / rhoj_prime}; - TinyVector<Dimension> A_rho_u2_prime{rho_uj_prime[0] * rho_uj_prime[1] / rhoj_prime, - rho_uj_prime[1] * rho_uj_prime[1] / rhoj_prime + p}; + TinyMatrix<Dimension> A_rho_u_prime = + 1. / rhoj_prime * tensorProduct(rho_uj_prime, rho_uj_prime) + p * I; TinyVector<Dimension> A_rho_E_prime = (rho_Ej_prime + p) / rhoj_prime * rho_uj_prime; - double Fn_rho_prime = rhoj_prime / nb_waves + - inv_S[0] * m_lambda_vector[i_wave][0] * A_rho_prime[0] + - inv_S[1] * m_lambda_vector[i_wave][1] * A_rho_prime[1]; - double Fn_rho_u1_prime = rho_uj_prime[0] / nb_waves + - inv_S[0] * m_lambda_vector[i_wave][0] * A_rho_u1_prime[0] + - inv_S[1] * m_lambda_vector[i_wave][1] * A_rho_u1_prime[1]; - double Fn_rho_u2_prime = rho_uj_prime[1] / nb_waves + - inv_S[0] * m_lambda_vector[i_wave][0] * A_rho_u2_prime[0] + - inv_S[1] * m_lambda_vector[i_wave][1] * A_rho_u2_prime[1]; - double Fn_rho_E_prime = rho_Ej_prime / nb_waves + - inv_S[0] * m_lambda_vector[i_wave][0] * A_rho_E_prime[0] + - inv_S[1] * m_lambda_vector[i_wave][1] * A_rho_E_prime[1]; + double Fn_rho_prime = rhoj_prime / nb_waves; + TinyVector<Dimension> Fn_rho_u_prime = 1. / nb_waves * rho_uj_prime; + double Fn_rho_E_prime = rho_Ej_prime / nb_waves; + + for (size_t d1 = 0; d1 < Dimension; ++d1) { + Fn_rho_prime += inv_S[d1] * m_lambda_vector[i_wave][d1] * A_rho_prime[d1]; + for (size_t d2 = 0; d2 < Dimension; ++d2) { + Fn_rho_u_prime[d1] += inv_S[d2] * m_lambda_vector[i_wave][d2] * A_rho_u_prime(d2, d1); + } + Fn_rho_E_prime += inv_S[d1] * m_lambda_vector[i_wave][d1] * A_rho_E_prime[d1]; + } Fl_rho[face_id][i_wave] += Fn_rho_prime; - Fl_rho_u1[face_id][i_wave] += Fn_rho_u1_prime; - Fl_rho_u2[face_id][i_wave] += Fn_rho_u2_prime; + Fl_rho_u[face_id][i_wave] += Fn_rho_u_prime; Fl_rho_E[face_id][i_wave] += Fn_rho_E_prime; } } @@ -695,22 +785,27 @@ class EulerKineticSolver2D return deltaLFn; } - DiscreteFunctionP0Vector<double> - compute_deltaLFn_face(FaceArray<double> Fl) + template <typename T> + CellArray<T> + compute_deltaLFn_face(FaceArray<T> Fl) { const size_t nb_waves = m_lambda_vector.size(); - DiscreteFunctionP0Vector<double> deltaLFn(p_mesh, nb_waves); + CellArray<T> deltaLFn(p_mesh->connectivity(), nb_waves); const auto& cell_to_face_matrix = p_mesh->connectivity().cellToFaceMatrix(); const auto& face_cell_is_reversed = p_mesh->connectivity().cellFaceIsReversed(); + if constexpr (is_tiny_vector_v<T>) { + deltaLFn.fill(zero); + } else { + deltaLFn.fill(0.); + } + parallel_for( p_mesh->numberOfCells(), PUGS_LAMBDA(CellId cell_id) { const auto& cell_to_face = cell_to_face_matrix[cell_id]; for (size_t i_wave = 0; i_wave < nb_waves; ++i_wave) { - deltaLFn[cell_id][i_wave] = 0; - for (size_t i_face_cell = 0; i_face_cell < cell_to_face.size(); ++i_face_cell) { const FaceId face_id = cell_to_face[i_face_cell]; @@ -718,7 +813,7 @@ class EulerKineticSolver2D const double li_Nl = sign * dot(m_lambda_vector[i_wave], Nl[face_id]); - deltaLFn[cell_id][i_wave] += Fl[face_id][i_wave] * li_Nl; + deltaLFn[cell_id][i_wave] += li_Nl * Fl[face_id][i_wave]; } } }); @@ -733,8 +828,6 @@ class EulerKineticSolver2D is_boundary_cell.fill(false); - auto node_to_cell_matrix = m_mesh.connectivity().nodeToCellMatrix(); - for (auto&& bc_v : bc_list) { std::visit( [=](auto&& bc) { @@ -765,14 +858,12 @@ class EulerKineticSolver2D CellValue<bool> is_boundary_cell = getBoundaryCells(bc_list); - DiscreteFunctionP0<double> rho_ex{p_mesh}; - DiscreteFunctionP0<double> rho_u1_ex{p_mesh}; - DiscreteFunctionP0<double> rho_u2_ex{p_mesh}; - DiscreteFunctionP0<double> rho_E_ex{p_mesh}; + const CellValue<double> rho_ex{p_mesh->connectivity()}; + const CellValue<TinyVector<Dimension>> rho_u_ex{p_mesh->connectivity()}; + const CellValue<double> rho_E_ex{p_mesh->connectivity()}; - rho_ex.fill(1); - rho_u1_ex.fill(0); - rho_u2_ex.fill(0); + rho_ex.fill(1); // !! A modifier en ne parcourant que les bords + rho_u_ex.fill(zero); rho_E_ex.fill(0); for (auto&& bc_v : bc_list) { @@ -785,8 +876,8 @@ class EulerKineticSolver2D for (size_t i_cell = 0; i_cell < cell_list.size(); ++i_cell) { const CellId cell_id = cell_list[i_cell]; rho_ex[cell_id] = cell_array_list[i_cell][0]; - rho_u1_ex[cell_id] = cell_array_list[i_cell][1]; - rho_u2_ex[cell_id] = cell_array_list[i_cell][2]; + rho_u_ex[cell_id][0] = cell_array_list[i_cell][1]; + rho_u_ex[cell_id][1] = cell_array_list[i_cell][2]; rho_E_ex[cell_id] = cell_array_list[i_cell][3]; } } @@ -794,29 +885,17 @@ class EulerKineticSolver2D bc_v); } - const CellArray<const TinyVector<Dimension>> APFn_ex = getA(rho_ex, rho_u1_ex, rho_u2_ex, rho_E_ex); - const DiscreteFunctionP0<TinyVector<Dimension>> A_rho_ex{p_mesh}; - const DiscreteFunctionP0<TinyVector<Dimension>> A_rho_u1_ex{p_mesh}; - const DiscreteFunctionP0<TinyVector<Dimension>> A_rho_u2_ex{p_mesh}; - const DiscreteFunctionP0<TinyVector<Dimension>> A_rho_E_ex{p_mesh}; - - parallel_for( - m_mesh.numberOfCells(), PUGS_LAMBDA(const CellId cell_id) { - A_rho_ex[cell_id] = APFn_ex[cell_id][0]; - A_rho_u1_ex[cell_id] = APFn_ex[cell_id][1]; - A_rho_u2_ex[cell_id] = APFn_ex[cell_id][2]; - A_rho_E_ex[cell_id] = APFn_ex[cell_id][3]; - }); + const CellValue<const TinyVector<Dimension>> A_rho_ex = getA_rho(rho_u_ex); + const CellValue<const TinyMatrix<Dimension>> A_rho_u_ex = getA_rho_u(rho_ex, rho_u_ex, rho_E_ex); + const CellValue<const TinyVector<Dimension>> A_rho_E_ex = getA_rho_E(rho_ex, rho_u_ex, rho_E_ex); - DiscreteFunctionP0Vector<double> Fn_rho_ex = compute_M(rho_ex, A_rho_ex); - DiscreteFunctionP0Vector<double> Fn_rho_u1_ex = compute_M(rho_u1_ex, A_rho_u1_ex); - DiscreteFunctionP0Vector<double> Fn_rho_u2_ex = compute_M(rho_u2_ex, A_rho_u2_ex); - DiscreteFunctionP0Vector<double> Fn_rho_E_ex = compute_M(rho_E_ex, A_rho_E_ex); + const CellArray<const double> Fn_rho_ex = compute_scalar_M(rho_ex, A_rho_ex); + const CellArray<const TinyVector<Dimension>> Fn_rho_u_ex = compute_vector_M(rho_u_ex, A_rho_u_ex); + const CellArray<const double> Fn_rho_E_ex = compute_scalar_M(rho_E_ex, A_rho_E_ex); - DiscreteFunctionP0Vector<double> Fn_rho = copy(m_Fn_rho); - DiscreteFunctionP0Vector<double> Fn_rho_u1 = copy(m_Fn_rho_u1); - DiscreteFunctionP0Vector<double> Fn_rho_u2 = copy(m_Fn_rho_u2); - DiscreteFunctionP0Vector<double> Fn_rho_E = copy(m_Fn_rho_E); + const CellArray<const double> Fn_rho = copy(m_Fn_rho); + const CellArray<const TinyVector<Dimension>> Fn_rho_u = copy(m_Fn_rho_u); + const CellArray<const double> Fn_rho_E = copy(m_Fn_rho_E); DiscreteFunctionP0Vector<double> Fnp1_rho(p_mesh, nb_waves); DiscreteFunctionP0Vector<double> Fnp1_rho_u1(p_mesh, nb_waves); @@ -825,105 +904,82 @@ class EulerKineticSolver2D // Compute first order F - const DiscreteFunctionP0<const double> rho = compute_PFn(Fn_rho); - const DiscreteFunctionP0<const double> rho_u1 = compute_PFn(Fn_rho_u1); - const DiscreteFunctionP0<const double> rho_u2 = compute_PFn(Fn_rho_u2); - const DiscreteFunctionP0<const double> rho_E = compute_PFn(Fn_rho_E); + const CellValue<const double> rho = compute_PFn<double>(Fn_rho); + const CellValue<const TinyVector<Dimension>> rho_u = compute_PFn<TinyVector<Dimension>>(Fn_rho_u); + const CellValue<const double> rho_E = compute_PFn<double>(Fn_rho_E); std::vector<std::shared_ptr<const IBoundaryDescriptor>> symmetry_boundary_descriptor_list; - // Reconstruction uniquement à l'intérieur + // Reconstruction uniquement à l'intérieur donc pas utile // for (auto&& bc_descriptor : bc_descriptor_list) { // if (bc_descriptor->type() == IBoundaryConditionDescriptor::Type::symmetry) { // symmetry_boundary_descriptor_list.push_back(bc_descriptor->boundaryDescriptor_shared()); // } // } - PolynomialReconstructionDescriptor reconstruction_descriptor(IntegrationMethodType::cell_center, 1, - symmetry_boundary_descriptor_list); + // PolynomialReconstructionDescriptor reconstruction_descriptor(IntegrationMethodType::cell_center, 1, + // symmetry_boundary_descriptor_list); - auto reconstruction = - PolynomialReconstruction{reconstruction_descriptor}.build(Fn_rho, Fn_rho_u1, Fn_rho_u2, Fn_rho_E); - auto DPk_Fn_rho = reconstruction[0]->get<DiscreteFunctionDPkVector<Dimension, const double>>(); + // auto reconstruction = PolynomialReconstruction{reconstruction_descriptor}.build(Fn_rho, Fn_rho_u, Fn_rho_E); + // auto DPk_Fn_rho = reconstruction[0]->get<DiscreteFunctionDPkVector<Dimension, const double>>(); + // auto DPk_Fn_rho_u = reconstruction[1]->get<DiscreteFunctionDPkVector<Dimension, const + // TinyVector<Dimension>>>(); auto DPk_Fn_rho_E = reconstruction[2]->get<DiscreteFunctionDPkVector<Dimension, + // const double>>(); // NodeArray<double> Fr_rho = compute_Flux1(Fn_rho); // NodeArray<double> Fr_rho_u1 = compute_Flux1(Fn_rho_u1); // NodeArray<double> Fr_rho_u2 = compute_Flux1(Fn_rho_u2); // NodeArray<double> Fr_rho_E = compute_Flux1(Fn_rho_E); - // FaceArrayPerNode<double> Fr_rho = compute_Flux1_eucchlyd(Fn_rho); - // FaceArrayPerNode<double> Fr_rho_u1 = compute_Flux1_eucchlyd(Fn_rho_u1); - // FaceArrayPerNode<double> Fr_rho_u2 = compute_Flux1_eucchlyd(Fn_rho_u2); - // FaceArrayPerNode<double> Fr_rho_E = compute_Flux1_eucchlyd(Fn_rho_E); + // FaceArrayPerNode<double> Flr_rho = compute_Flux1_eucchlyd(Fn_rho); + // FaceArrayPerNode<double> Flr_rho_u1 = compute_Flux1_eucchlyd(Fn_rho_u1); + // FaceArrayPerNode<double> Flr_rho_u2 = compute_Flux1_eucchlyd(Fn_rho_u2); + // FaceArrayPerNode<double> Flr_rho_E = compute_Flux1_eucchlyd(Fn_rho_E); - FaceArray<double> Fr_rho = compute_Flux1_face(Fn_rho); - FaceArray<double> Fr_rho_u1 = compute_Flux1_face(Fn_rho_u1); - FaceArray<double> Fr_rho_u2 = compute_Flux1_face(Fn_rho_u2); - FaceArray<double> Fr_rho_E = compute_Flux1_face(Fn_rho_E); + FaceArray<double> Fl_rho = compute_Flux1_face<double>(Fn_rho); + FaceArray<TinyVector<Dimension>> Fl_rho_u = compute_Flux1_face<TinyVector<Dimension>>(Fn_rho_u); + FaceArray<double> Fl_rho_E = compute_Flux1_face<double>(Fn_rho_E); - apply_scalar_bc(Fr_rho, Fr_rho_u1, Fr_rho_u2, Fr_rho_E, rho, rho_u1, rho_u2, rho_E, bc_list); + apply_symmetry_bc(Fl_rho, Fl_rho_u, Fl_rho_E, rho, rho_u, rho_E, bc_list); - synchronize(Fr_rho); - synchronize(Fr_rho_u1); - synchronize(Fr_rho_u2); - synchronize(Fr_rho_E); + synchronize(Fl_rho); + synchronize(Fl_rho_u); + synchronize(Fl_rho_E); // DiscreteFunctionP0Vector<double> deltaLFn_rho = compute_deltaLFn(Fr_rho); // DiscreteFunctionP0Vector<double> deltaLFn_rho_u1 = compute_deltaLFn(Fr_rho_u1); // DiscreteFunctionP0Vector<double> deltaLFn_rho_u2 = compute_deltaLFn(Fr_rho_u2); // DiscreteFunctionP0Vector<double> deltaLFn_rho_E = compute_deltaLFn(Fr_rho_E); - // DiscreteFunctionP0Vector<double> deltaLFn_rho = compute_deltaLFn_eucclhyd(Fr_rho); - // DiscreteFunctionP0Vector<double> deltaLFn_rho_u1 = compute_deltaLFn_eucclhyd(Fr_rho_u1); - // DiscreteFunctionP0Vector<double> deltaLFn_rho_u2 = compute_deltaLFn_eucclhyd(Fr_rho_u2); - // DiscreteFunctionP0Vector<double> deltaLFn_rho_E = compute_deltaLFn_eucclhyd(Fr_rho_E); + // DiscreteFunctionP0Vector<double> deltaLFn_rho = compute_deltaLFn_eucclhyd(Flr_rho); + // DiscreteFunctionP0Vector<double> deltaLFn_rho_u1 = compute_deltaLFn_eucclhyd(Flr_rho_u1); + // DiscreteFunctionP0Vector<double> deltaLFn_rho_u2 = compute_deltaLFn_eucclhyd(Flr_rho_u2); + // DiscreteFunctionP0Vector<double> deltaLFn_rho_E = compute_deltaLFn_eucclhyd(Flr_rho_E); - DiscreteFunctionP0Vector<double> deltaLFn_rho = compute_deltaLFn_face(Fr_rho); - DiscreteFunctionP0Vector<double> deltaLFn_rho_u1 = compute_deltaLFn_face(Fr_rho_u1); - DiscreteFunctionP0Vector<double> deltaLFn_rho_u2 = compute_deltaLFn_face(Fr_rho_u2); - DiscreteFunctionP0Vector<double> deltaLFn_rho_E = compute_deltaLFn_face(Fr_rho_E); + const CellArray<const double> deltaLFn_rho = compute_deltaLFn_face<double>(Fl_rho); + const CellArray<const TinyVector<Dimension>> deltaLFn_rho_u = + compute_deltaLFn_face<TinyVector<Dimension>>(Fl_rho_u); + const CellArray<const double> deltaLFn_rho_E = compute_deltaLFn_face<double>(Fl_rho_E); - const CellArray<const TinyVector<Dimension>> APFn = getA(rho, rho_u1, rho_u2, rho_E); - const DiscreteFunctionP0<TinyVector<Dimension>> APFn_rho{p_mesh}; - const DiscreteFunctionP0<TinyVector<Dimension>> APFn_rho_u1{p_mesh}; - const DiscreteFunctionP0<TinyVector<Dimension>> APFn_rho_u2{p_mesh}; - const DiscreteFunctionP0<TinyVector<Dimension>> APFn_rho_E{p_mesh}; + const CellValue<const TinyVector<Dimension>> A_rho = getA_rho(rho_u); + const CellValue<const TinyMatrix<Dimension>> A_rho_u = getA_rho_u(rho, rho_u, rho_E); + const CellValue<const TinyVector<Dimension>> A_rho_E = getA_rho_E(rho, rho_u, rho_E); - parallel_for( - m_mesh.numberOfCells(), PUGS_LAMBDA(const CellId cell_id) { - APFn_rho[cell_id] = APFn[cell_id][0]; - APFn_rho_u1[cell_id] = APFn[cell_id][1]; - APFn_rho_u2[cell_id] = APFn[cell_id][2]; - APFn_rho_E[cell_id] = APFn[cell_id][3]; - }); + const CellArray<const double> M_rho = compute_scalar_M(rho, A_rho); + const CellArray<const TinyVector<Dimension>> M_rho_u = compute_vector_M(rho_u, A_rho_u); + const CellArray<const double> M_rho_E = compute_scalar_M(rho_E, A_rho_E); - const DiscreteFunctionP0Vector<const double> MPFn_rho = compute_M(rho, APFn_rho); - const DiscreteFunctionP0Vector<const double> MPFn_rho_u1 = compute_M(rho_u1, APFn_rho_u1); - const DiscreteFunctionP0Vector<const double> MPFn_rho_u2 = compute_M(rho_u2, APFn_rho_u2); - const DiscreteFunctionP0Vector<const double> MPFn_rho_E = compute_M(rho_E, APFn_rho_E); + const CellValue<const double> rho_np1 = compute_PFnp1<double>(Fn_rho, deltaLFn_rho); + const CellValue<const TinyVector<Dimension>> rho_u_np1 = + compute_PFnp1<TinyVector<Dimension>>(Fn_rho_u, deltaLFn_rho_u); + const CellValue<const double> rho_E_np1 = compute_PFnp1<double>(Fn_rho_E, deltaLFn_rho_E); - const DiscreteFunctionP0<const double> rho_np1 = compute_PFnp1(Fn_rho, deltaLFn_rho); - const DiscreteFunctionP0<const double> rho_u1_np1 = compute_PFnp1(Fn_rho_u1, deltaLFn_rho_u1); - const DiscreteFunctionP0<const double> rho_u2_np1 = compute_PFnp1(Fn_rho_u2, deltaLFn_rho_u2); - const DiscreteFunctionP0<const double> rho_E_np1 = compute_PFnp1(Fn_rho_E, deltaLFn_rho_E); + const CellValue<const TinyVector<Dimension>> A_rho_np1 = getA_rho(rho_u_np1); + const CellValue<const TinyMatrix<Dimension>> A_rho_u_np1 = getA_rho_u(rho_np1, rho_u_np1, rho_E_np1); + const CellValue<const TinyVector<Dimension>> A_rho_E_np1 = getA_rho_E(rho_np1, rho_u_np1, rho_E_np1); - const CellArray<const TinyVector<Dimension>> APFnp1 = getA(rho_np1, rho_u1_np1, rho_u2_np1, rho_E_np1); - const DiscreteFunctionP0<TinyVector<Dimension>> APFnp1_rho{p_mesh}; - const DiscreteFunctionP0<TinyVector<Dimension>> APFnp1_rho_u1{p_mesh}; - const DiscreteFunctionP0<TinyVector<Dimension>> APFnp1_rho_u2{p_mesh}; - const DiscreteFunctionP0<TinyVector<Dimension>> APFnp1_rho_E{p_mesh}; - - parallel_for( - m_mesh.numberOfCells(), PUGS_LAMBDA(const CellId cell_id) { - APFnp1_rho[cell_id] = APFnp1[cell_id][0]; - APFnp1_rho_u1[cell_id] = APFnp1[cell_id][1]; - APFnp1_rho_u2[cell_id] = APFnp1[cell_id][2]; - APFnp1_rho_E[cell_id] = APFnp1[cell_id][3]; - }); - - const DiscreteFunctionP0Vector<const double> MPFnp1_rho = compute_M(rho_np1, APFnp1_rho); - const DiscreteFunctionP0Vector<const double> MPFnp1_rho_u1 = compute_M(rho_u1_np1, APFnp1_rho_u1); - const DiscreteFunctionP0Vector<const double> MPFnp1_rho_u2 = compute_M(rho_u2_np1, APFnp1_rho_u2); - const DiscreteFunctionP0Vector<const double> MPFnp1_rho_E = compute_M(rho_E_np1, APFnp1_rho_E); + const CellArray<const double> M_rho_np1 = compute_scalar_M(rho_np1, A_rho_np1); + const CellArray<const TinyVector<Dimension>> M_rho_u_np1 = compute_vector_M(rho_u_np1, A_rho_u_np1); + const CellArray<const double> M_rho_E_np1 = compute_scalar_M(rho_E_np1, A_rho_E_np1); parallel_for( p_mesh->numberOfCells(), PUGS_LAMBDA(CellId cell_id) { @@ -932,22 +988,22 @@ class EulerKineticSolver2D const double c2 = m_eps * m_dt * m_inv_Vj[cell_id]; for (size_t i_wave = 0; i_wave < nb_waves; ++i_wave) { Fnp1_rho[cell_id][i_wave] = c1 * (m_eps * Fn_rho[cell_id][i_wave] - c2 * deltaLFn_rho[cell_id][i_wave] + - m_dt * MPFnp1_rho[cell_id][i_wave]); + m_dt * M_rho_np1[cell_id][i_wave]); Fnp1_rho_u1[cell_id][i_wave] = - c1 * (m_eps * Fn_rho_u1[cell_id][i_wave] - c2 * deltaLFn_rho_u1[cell_id][i_wave] + - m_dt * MPFnp1_rho_u1[cell_id][i_wave]); + c1 * (m_eps * Fn_rho_u[cell_id][i_wave][0] - c2 * deltaLFn_rho_u[cell_id][i_wave][0] + + m_dt * M_rho_u_np1[cell_id][i_wave][0]); Fnp1_rho_u2[cell_id][i_wave] = - c1 * (m_eps * Fn_rho_u2[cell_id][i_wave] - c2 * deltaLFn_rho_u2[cell_id][i_wave] + - m_dt * MPFnp1_rho_u2[cell_id][i_wave]); + c1 * (m_eps * Fn_rho_u[cell_id][i_wave][1] - c2 * deltaLFn_rho_u[cell_id][i_wave][1] + + m_dt * M_rho_u_np1[cell_id][i_wave][1]); Fnp1_rho_E[cell_id][i_wave] = c1 * (m_eps * Fn_rho_E[cell_id][i_wave] - c2 * deltaLFn_rho_E[cell_id][i_wave] + - m_dt * MPFnp1_rho_E[cell_id][i_wave]); + m_dt * M_rho_E_np1[cell_id][i_wave]); } } else { for (size_t i_wave = 0; i_wave < nb_waves; ++i_wave) { Fnp1_rho[cell_id][i_wave] = Fn_rho_ex[cell_id][i_wave]; - Fnp1_rho_u1[cell_id][i_wave] = Fn_rho_u1_ex[cell_id][i_wave]; - Fnp1_rho_u2[cell_id][i_wave] = Fn_rho_u2_ex[cell_id][i_wave]; + Fnp1_rho_u1[cell_id][i_wave] = Fn_rho_u_ex[cell_id][i_wave][0]; + Fnp1_rho_u2[cell_id][i_wave] = Fn_rho_u_ex[cell_id][i_wave][1]; Fnp1_rho_E[cell_id][i_wave] = Fn_rho_E_ex[cell_id][i_wave]; } } @@ -965,30 +1021,23 @@ class EulerKineticSolver2D const double& gamma, const std::vector<TinyVector<2>>& lambda_vector, const size_t& SpaceOrder, - const DiscreteFunctionP0Vector<const double>& Fn_rho, - const DiscreteFunctionP0Vector<const double>& Fn_rho_u1, - const DiscreteFunctionP0Vector<const double>& Fn_rho_u2, - const DiscreteFunctionP0Vector<const double>& Fn_rho_E, - const DiscreteFunctionP0<const double>& rho_n_ex, - const DiscreteFunctionP0<const TinyVector<2>>& rho_u_n_ex, - const DiscreteFunctionP0<const double>& rho_E_n_ex) + const CellArray<const double>& Fn_rho, + const CellArray<TinyVector<2>>& Fn_rho_u, + const CellArray<const double>& Fn_rho_E) : m_dt{dt}, m_eps{eps}, m_lambda_vector{lambda_vector}, m_SpaceOrder{SpaceOrder}, m_Fn_rho{Fn_rho}, - m_Fn_rho_u1{Fn_rho_u1}, - m_Fn_rho_u2{Fn_rho_u2}, + m_Fn_rho_u{Fn_rho_u}, m_Fn_rho_E{Fn_rho_E}, - m_rho_ex{rho_n_ex}, - m_rho_u_ex{rho_u_n_ex}, - m_rho_E_ex{rho_E_n_ex}, m_gamma{gamma}, p_mesh{mesh}, m_mesh{*mesh} { - if ((lambda_vector.size() != Fn_rho.size()) or (lambda_vector.size() != Fn_rho_u1.size()) or - (lambda_vector.size() != Fn_rho_u2.size()) or ((lambda_vector.size() != Fn_rho_E.size()))) { + if ((lambda_vector.size() != Fn_rho[CellId(0)].size()) or (lambda_vector.size() != Fn_rho_u[CellId(0)].size()) or + (lambda_vector.size() != Fn_rho_u[CellId(0)].size()) or + ((lambda_vector.size() != Fn_rho_E[CellId(0)].size()))) { throw NormalError("Incompatible dimensions of lambda vector and Fn"); } @@ -1003,58 +1052,6 @@ class EulerKineticSolver2D ~EulerKineticSolver2D() = default; }; -std::tuple<std::shared_ptr<const DiscreteFunctionVariant>, - std::shared_ptr<const DiscreteFunctionVariant>, - std::shared_ptr<const DiscreteFunctionVariant>, - std::shared_ptr<const DiscreteFunctionVariant>> -eulerKineticSolver2D(const double& dt, - const double& gamma, - const std::vector<TinyVector<2>>& lambda_vector, - const double& eps, - const size_t& SpaceOrder, - const std::shared_ptr<const DiscreteFunctionVariant>& F_rho, - const std::shared_ptr<const DiscreteFunctionVariant>& F_rho_u1, - const std::shared_ptr<const DiscreteFunctionVariant>& F_rho_u2, - const std::shared_ptr<const DiscreteFunctionVariant>& F_rho_E, - const std::shared_ptr<const DiscreteFunctionVariant>& rho_ex, - const std::shared_ptr<const DiscreteFunctionVariant>& rho_u_ex, - const std::shared_ptr<const DiscreteFunctionVariant>& rho_E_ex, - const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>& bc_descriptor_list) -{ - const std::shared_ptr<const MeshVariant> mesh_v = - getCommonMesh({F_rho, F_rho_u1, F_rho_u2, F_rho_E, rho_ex, rho_u_ex, rho_E_ex}); - if (mesh_v.use_count() == 0) { - throw NormalError("F_rho, F_rho_u1, F_rho_u2 and F_rho_E have to be defined on the same mesh"); - } - if (SpaceOrder > 1) { - throw NotImplementedError("Euler kinetic solver in 2D not implemented at order > 1"); - } - - return std::visit( - [&](auto&& p_mesh) - -> std::tuple<std::shared_ptr<const DiscreteFunctionVariant>, std::shared_ptr<const DiscreteFunctionVariant>, - std::shared_ptr<const DiscreteFunctionVariant>, std::shared_ptr<const DiscreteFunctionVariant>> { - using MeshType = mesh_type_t<decltype(p_mesh)>; - if constexpr (is_polygonal_mesh_v<MeshType> and (MeshType::Dimension == 2)) { - auto Fn_rho = F_rho->get<DiscreteFunctionP0Vector<const double>>(); - auto Fn_rho_u1 = F_rho_u1->get<DiscreteFunctionP0Vector<const double>>(); - auto Fn_rho_u2 = F_rho_u2->get<DiscreteFunctionP0Vector<const double>>(); - auto Fn_rho_E = F_rho_E->get<DiscreteFunctionP0Vector<const double>>(); - auto rho_n_ex = rho_ex->get<DiscreteFunctionP0<const double>>(); - auto rho_u_n_ex = rho_u_ex->get<DiscreteFunctionP0<const TinyVector<MeshType::Dimension>>>(); - auto rho_E_n_ex = rho_E_ex->get<DiscreteFunctionP0<const double>>(); - - EulerKineticSolver2D solver(p_mesh, dt, eps, gamma, lambda_vector, SpaceOrder, Fn_rho, Fn_rho_u1, Fn_rho_u2, - Fn_rho_E, rho_n_ex, rho_u_n_ex, rho_E_n_ex); - - return solver.apply(bc_descriptor_list); - } else { - throw NotImplementedError("Invalid mesh type for 2D Euler Kinetic solver"); - } - }, - mesh_v->variant()); -} - template <MeshConcept MeshType> class EulerKineticSolver2D<MeshType>::SymmetryBoundaryCondition { @@ -1147,3 +1144,61 @@ class EulerKineticSolver2D<MeshType>::InflowListBoundaryCondition ~InflowListBoundaryCondition() = default; }; + +std::tuple<std::shared_ptr<const DiscreteFunctionVariant>, + std::shared_ptr<const DiscreteFunctionVariant>, + std::shared_ptr<const DiscreteFunctionVariant>, + std::shared_ptr<const DiscreteFunctionVariant>> +eulerKineticSolver2D(const double& dt, + const double& gamma, + const std::vector<TinyVector<2>>& lambda_vector, + const double& eps, + const size_t& SpaceOrder, + const std::shared_ptr<const DiscreteFunctionVariant>& F_rho, + const std::shared_ptr<const DiscreteFunctionVariant>& F_rho_u1, + const std::shared_ptr<const DiscreteFunctionVariant>& F_rho_u2, + const std::shared_ptr<const DiscreteFunctionVariant>& F_rho_E, + const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>& bc_descriptor_list) +{ + const std::shared_ptr<const MeshVariant> mesh_v = getCommonMesh({F_rho, F_rho_u1, F_rho_u2, F_rho_E}); + if (mesh_v.use_count() == 0) { + throw NormalError("F_rho, F_rho_u1, F_rho_u2 and F_rho_E have to be defined on the same mesh"); + } + if (SpaceOrder > 1) { + throw NotImplementedError("Euler kinetic solver in 2D not implemented at order > 1"); + } + + return std::visit( + [&](auto&& p_mesh) + -> std::tuple<std::shared_ptr<const DiscreteFunctionVariant>, std::shared_ptr<const DiscreteFunctionVariant>, + std::shared_ptr<const DiscreteFunctionVariant>, std::shared_ptr<const DiscreteFunctionVariant>> { + using MeshType = mesh_type_t<decltype(p_mesh)>; + if constexpr (is_polygonal_mesh_v<MeshType> and (MeshType::Dimension == 2)) { + auto Fn_rho = F_rho->get<DiscreteFunctionP0Vector<const double>>(); + auto Fn_rho_u1 = F_rho_u1->get<DiscreteFunctionP0Vector<const double>>(); + auto Fn_rho_u2 = F_rho_u2->get<DiscreteFunctionP0Vector<const double>>(); + auto Fn_rho_E = F_rho_E->get<DiscreteFunctionP0Vector<const double>>(); + + const double nb_waves = lambda_vector.size(); + CellArray<const double> Fn_rho_array = Fn_rho.cellArrays(); + CellArray<TinyVector<MeshType::Dimension>> Fn_rho_u_array(p_mesh->connectivity(), nb_waves); + CellArray<const double> Fn_rho_E_array = Fn_rho_E.cellArrays(); + + parallel_for( + p_mesh->numberOfCells(), PUGS_LAMBDA(const CellId cell_id) { + for (size_t i_wave = 0; i_wave < nb_waves; ++i_wave) { + Fn_rho_u_array[cell_id][i_wave][0] = Fn_rho_u1[cell_id][i_wave]; + Fn_rho_u_array[cell_id][i_wave][1] = Fn_rho_u2[cell_id][i_wave]; + } + }); + + EulerKineticSolver2D solver(p_mesh, dt, eps, gamma, lambda_vector, SpaceOrder, Fn_rho_array, Fn_rho_u_array, + Fn_rho_E_array); + + return solver.apply(bc_descriptor_list); + } else { + throw NotImplementedError("Invalid mesh type for 2D Euler Kinetic solver"); + } + }, + mesh_v->variant()); +} diff --git a/src/scheme/EulerKineticSolver2D.hpp b/src/scheme/EulerKineticSolver2D.hpp index 76d024c82658527ee2fe895ada184929fabbb6ef..a7937ee7ae067059b671d10b05674e109b7d9b88 100644 --- a/src/scheme/EulerKineticSolver2D.hpp +++ b/src/scheme/EulerKineticSolver2D.hpp @@ -38,9 +38,6 @@ eulerKineticSolver2D(const double& dt, const std::shared_ptr<const DiscreteFunctionVariant>& F_rho_u1, const std::shared_ptr<const DiscreteFunctionVariant>& F_rho_u2, const std::shared_ptr<const DiscreteFunctionVariant>& F_rho_E, - const std::shared_ptr<const DiscreteFunctionVariant>& rho_ex, - const std::shared_ptr<const DiscreteFunctionVariant>& rho_u_ex, - const std::shared_ptr<const DiscreteFunctionVariant>& rho_E_ex, const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>& bc_descriptor_list); #endif // EULER_KINETIC_SOLVER_2D_HPP