diff --git a/src/scheme/EulerKineticSolverAcoustic2LagrangeFVOrder2.cpp b/src/scheme/EulerKineticSolverAcoustic2LagrangeFVOrder2.cpp index 6c188eec384938f2a80d377a9c5c9d04da21e0d5..5a3164385581a51460f0213d3a4c41e7d09a6c2b 100644 --- a/src/scheme/EulerKineticSolverAcoustic2LagrangeFVOrder2.cpp +++ b/src/scheme/EulerKineticSolverAcoustic2LagrangeFVOrder2.cpp @@ -771,61 +771,96 @@ class EulerKineticSolverAcoustic2LagrangeFVOrder2 NodeArray<double> p_flux(m_mesh.connectivity(), m_timeOrder); CellValue<double> new_p{m_mesh.connectivity()}; + CellValue<TinyVector<Dimension>> new_u{m_mesh.connectivity()}; + std::shared_ptr<const MeshType> new_mesh; - for (size_t i_time = 0; i_time < m_timeOrder; ++i_time) { - if (i_time == 0) { - vec_F = compute_M(m_p, m_u); - } else { - vec_F = compute_M(p, u); - } - F_p = get<0>(vec_F); - F_u = get<1>(vec_F); - F0_p = copy(F_p); - F0_u = copy(F_u); - - NodeArray<double> Flux_Fn_p(m_mesh.connectivity(), nb_waves); - NodeArray<double> Flux_Fn_u(m_mesh.connectivity(), nb_waves); - - if (m_spaceOrder == 1) { - Flux_Fn_p = compute_Flux1(F_p); - Flux_Fn_u = compute_Flux1(F_u); - } else if (m_spaceOrder == 2) { - Flux_Fn_p = compute_Polynomial_reconstruction_2(F_p); - Flux_Fn_u = compute_Polynomial_reconstruction_2(F_u); - } else if (m_spaceOrder == 3) { - Flux_Fn_p = compute_Polynomial_reconstruction_3(F_p); - Flux_Fn_u = compute_Polynomial_reconstruction_3(F_u); - } else { - throw NotImplementedError("Only implemented for space orders 1, 2 and 3"); - } + while (Mood_activation) { + Mood_activation = false; - if (m_TVDLimitation == 1) { - Flux_Fn_p = TVD(Flux_Fn_p, F0_p, c[i_time]); - Flux_Fn_u = TVD(Flux_Fn_u, F0_u, c[i_time]); - } + for (size_t i_time = 0; i_time < m_timeOrder; ++i_time) { + if (i_time == 0) { + vec_F = compute_M(m_p, m_u); + } else { + vec_F = compute_M(p, u); + } + F_p = get<0>(vec_F); + F_u = get<1>(vec_F); + F0_p = copy(F_p); + F0_u = copy(F_u); + + NodeArray<double> Flux_Fn_p(m_mesh.connectivity(), nb_waves); + NodeArray<double> Flux_Fn_u(m_mesh.connectivity(), nb_waves); + NodeArray<double> Flux1_Fn_p = compute_Flux1(F_p); + NodeArray<double> Flux1_Fn_u = compute_Flux1(F_u); + + if (m_spaceOrder == 1) { + Flux_Fn_p = compute_Flux1(F_p); + Flux_Fn_u = compute_Flux1(F_u); + } else if (m_spaceOrder == 2) { + Flux_Fn_p = compute_Polynomial_reconstruction_2(F_p); + Flux_Fn_u = compute_Polynomial_reconstruction_2(F_u); + } else if (m_spaceOrder == 3) { + Flux_Fn_p = compute_Polynomial_reconstruction_3(F_p); + Flux_Fn_u = compute_Polynomial_reconstruction_3(F_u); + } else { + throw NotImplementedError("Only implemented for space orders 1, 2 and 3"); + } - if (i_time == 0) { - for (size_t j_time = 0; j_time < m_timeOrder; ++j_time) { + if (m_MOODLimitation) { for (NodeId node_id = 0; node_id < m_mesh.numberOfNodes(); ++node_id) { - au_flux[node_id][j_time][0] = 0; - p_flux[node_id][j_time] = 0; + if (not node_is_valid[node_id]) { + for (size_t i_wave = 0; i_wave < nb_waves; ++i_wave) { + Flux_Fn_p[node_id][i_wave] = Flux1_Fn_p[node_id][i_wave]; + Flux_Fn_u[node_id][i_wave] = Flux1_Fn_u[node_id][i_wave]; + } + } + } + } + + if (m_TVDLimitation == 1) { + Flux_Fn_p = TVD(Flux_Fn_p, F0_p, c[i_time]); + Flux_Fn_u = TVD(Flux_Fn_u, F0_u, c[i_time]); + } + + if (i_time == 0) { + for (size_t j_time = 0; j_time < m_timeOrder; ++j_time) { + for (NodeId node_id = 0; node_id < m_mesh.numberOfNodes(); ++node_id) { + au_flux[node_id][j_time][0] = 0; + p_flux[node_id][j_time] = 0; + for (size_t i_wave = 0; i_wave < nb_waves; ++i_wave) { + au_flux[node_id][j_time][0] += m_lambda_vector[i_wave] * Flux_Fn_p[node_id][i_wave]; + p_flux[node_id][j_time] += m_lambda_vector[i_wave] * Flux_Fn_u[node_id][i_wave]; + } + u_flux[node_id][j_time][0] = au_flux[node_id][j_time][0] / (lambda * lambda); + } + } + + } else { + for (NodeId node_id = 0; node_id < m_mesh.numberOfNodes(); ++node_id) { + au_flux[node_id][i_time][0] = 0; + p_flux[node_id][i_time] = 0; for (size_t i_wave = 0; i_wave < nb_waves; ++i_wave) { - au_flux[node_id][j_time][0] += m_lambda_vector[i_wave] * Flux_Fn_p[node_id][i_wave]; - p_flux[node_id][j_time] += m_lambda_vector[i_wave] * Flux_Fn_u[node_id][i_wave]; + au_flux[node_id][i_time][0] += m_lambda_vector[i_wave] * Flux_Fn_p[node_id][i_wave]; + p_flux[node_id][i_time] += m_lambda_vector[i_wave] * Flux_Fn_u[node_id][i_wave]; } - u_flux[node_id][j_time][0] = au_flux[node_id][j_time][0] / (lambda * lambda); + u_flux[node_id][i_time][0] = au_flux[node_id][i_time][0] / (lambda * lambda); } } - } else { - for (NodeId node_id = 0; node_id < m_mesh.numberOfNodes(); ++node_id) { - au_flux[node_id][i_time][0] = 0; - p_flux[node_id][i_time] = 0; - for (size_t i_wave = 0; i_wave < nb_waves; ++i_wave) { - au_flux[node_id][i_time][0] += m_lambda_vector[i_wave] * Flux_Fn_p[node_id][i_wave]; - p_flux[node_id][i_time] += m_lambda_vector[i_wave] * Flux_Fn_u[node_id][i_wave]; + for (CellId cell_id = 0; cell_id < m_mesh.numberOfCells(); ++cell_id) { + const double dt_over_Mj = (m_dt * m_inv_Mj[cell_id]); + const auto& cell_nodes = cell_to_node_matrix[cell_id]; + const NodeId left_node_id = cell_nodes[0]; + const NodeId right_node_id = cell_nodes[1]; + u[cell_id][0] = m_u[cell_id][0]; + tau[cell_id] = 1. / m_rho[cell_id]; + for (size_t j_time = 0; j_time < m_timeOrder; ++j_time) { + u[cell_id][0] -= B[j_time] * dt_over_Mj * (p_flux[right_node_id][j_time] - p_flux[left_node_id][j_time]); + + tau[cell_id] += + B[j_time] * dt_over_Mj * (u_flux[right_node_id][j_time][0] - u_flux[left_node_id][j_time][0]); } - u_flux[node_id][i_time][0] = au_flux[node_id][i_time][0] / (lambda * lambda); + p[cell_id] = m_p[cell_id] / std::pow(m_rho[cell_id] * tau[cell_id], m_gamma); } } @@ -834,55 +869,70 @@ class EulerKineticSolverAcoustic2LagrangeFVOrder2 const auto& cell_nodes = cell_to_node_matrix[cell_id]; const NodeId left_node_id = cell_nodes[0]; const NodeId right_node_id = cell_nodes[1]; - u[cell_id][0] = m_u[cell_id][0]; - tau[cell_id] = 1. / m_rho[cell_id]; + + u[cell_id][0] = m_u[cell_id][0]; + E[cell_id] = m_E[cell_id]; for (size_t j_time = 0; j_time < m_timeOrder; ++j_time) { u[cell_id][0] -= B[j_time] * dt_over_Mj * (p_flux[right_node_id][j_time] - p_flux[left_node_id][j_time]); - tau[cell_id] += B[j_time] * dt_over_Mj * (u_flux[right_node_id][j_time][0] - u_flux[left_node_id][j_time][0]); + E[cell_id] -= B[j_time] * dt_over_Mj * + (p_flux[right_node_id][j_time] * u_flux[right_node_id][j_time][0] - + p_flux[left_node_id][j_time] * u_flux[left_node_id][j_time][0]); } - p[cell_id] = m_p[cell_id] / std::pow(m_rho[cell_id] * tau[cell_id], m_gamma); } - } - for (CellId cell_id = 0; cell_id < m_mesh.numberOfCells(); ++cell_id) { - const double dt_over_Mj = (m_dt * m_inv_Mj[cell_id]); - const auto& cell_nodes = cell_to_node_matrix[cell_id]; - const NodeId left_node_id = cell_nodes[0]; - const NodeId right_node_id = cell_nodes[1]; + NodeValue<TinyVector<Dimension>> new_xr = copy(m_mesh.xr()); + parallel_for( + m_mesh.numberOfNodes(), PUGS_LAMBDA(NodeId node_id) { + for (size_t j_time = 0; j_time < m_timeOrder; ++j_time) { + new_xr[node_id][0] += B[j_time] * m_dt * u_flux[node_id][j_time][0]; + } + }); - u[cell_id][0] = m_u[cell_id][0]; - E[cell_id] = m_E[cell_id]; - for (size_t j_time = 0; j_time < m_timeOrder; ++j_time) { - u[cell_id][0] -= B[j_time] * dt_over_Mj * (p_flux[right_node_id][j_time] - p_flux[left_node_id][j_time]); + new_mesh = std::make_shared<MeshType>(m_mesh.shared_connectivity(), new_xr); - E[cell_id] -= B[j_time] * dt_over_Mj * - (p_flux[right_node_id][j_time] * u_flux[right_node_id][j_time][0] - - p_flux[left_node_id][j_time] * u_flux[left_node_id][j_time][0]); - } - } + CellValue<const double> new_Vj = MeshDataManager::instance().getMeshData(*new_mesh).Vj(); - NodeValue<TinyVector<Dimension>> new_xr = copy(m_mesh.xr()); - parallel_for( - m_mesh.numberOfNodes(), PUGS_LAMBDA(NodeId node_id) { - for (size_t j_time = 0; j_time < m_timeOrder; ++j_time) { - new_xr[node_id][0] += B[j_time] * m_dt * u_flux[node_id][j_time][0]; - } - }); + parallel_for( + m_mesh.numberOfCells(), PUGS_LAMBDA(CellId cell_id) { rho[cell_id] = m_Mj[cell_id] / new_Vj[cell_id]; }); - std::shared_ptr<const MeshType> new_mesh = std::make_shared<MeshType>(m_mesh.shared_connectivity(), new_xr); + new_u = copy(u.cellValues()); - CellValue<const double> new_Vj = MeshDataManager::instance().getMeshData(*new_mesh).Vj(); + parallel_for( + m_mesh.numberOfCells(), PUGS_LAMBDA(CellId cell_id) { + new_p[cell_id] = (m_gamma - 1) * rho[cell_id] * (E[cell_id] - 0.5 * new_u[cell_id][0] * new_u[cell_id][0]); + }); - parallel_for( - m_mesh.numberOfCells(), PUGS_LAMBDA(CellId cell_id) { rho[cell_id] = m_Mj[cell_id] / new_Vj[cell_id]; }); + if (m_MOODLimitation) { + for (CellId cell_id = 0; cell_id < m_mesh.numberOfCells(); ++cell_id) { + const auto& cell_to_node = cell_to_node_matrix[cell_id]; + NodeId left_node = cell_to_node[0]; + NodeId right_node = cell_to_node[1]; + const size_t N = m_mesh.numberOfCells(); - CellValue<TinyVector<Dimension>> new_u = copy(u.cellValues()); + const CellId prev_cell_id = (cell_id + N - 1) % N; + const CellId next_cell_id = (cell_id + 1) % N; - parallel_for( - m_mesh.numberOfCells(), PUGS_LAMBDA(CellId cell_id) { - new_p[cell_id] = (m_gamma - 1) * rho[cell_id] * (E[cell_id] - 0.5 * new_u[cell_id][0] * new_u[cell_id][0]); - }); + if (rho[cell_id] <= 0) { + Mood_activation = true; + cell_is_valid[cell_id] = false; + cell_is_valid[prev_cell_id] = false; + cell_is_valid[next_cell_id] = false; + node_is_valid[left_node] = false; + node_is_valid[right_node] = false; + } else { + if (new_p[cell_id] <= 0) { + Mood_activation = true; + cell_is_valid[cell_id] = false; + cell_is_valid[prev_cell_id] = false; + cell_is_valid[next_cell_id] = false; + node_is_valid[left_node] = false; + node_is_valid[right_node] = false; + } + } + } + } + } return std::make_tuple(std::make_shared<MeshVariant>(new_mesh), std::make_shared<DiscreteFunctionVariant>(DiscreteFunctionP0<const double>(new_mesh, rho)), diff --git a/src/scheme/EulerKineticSolverLagrangeMultiDLocalOrder2.cpp b/src/scheme/EulerKineticSolverLagrangeMultiDLocalOrder2.cpp index 260520c197989e9e8639220f6f64f437316c5274..a639a0a342744dd1f2d9331685c67f098e1f011b 100644 --- a/src/scheme/EulerKineticSolverLagrangeMultiDLocalOrder2.cpp +++ b/src/scheme/EulerKineticSolverLagrangeMultiDLocalOrder2.cpp @@ -1062,8 +1062,8 @@ class EulerKineticSolverLagrangeMultiDLocalOrder2 if (limitation) { const CellValue<const TinyMatrix<Dimension>> grad_u = compute_grad_u(u_lim); scalar_limiter(p, p_lim); - vector_limiter_symmetry(u, u_lim, grad_u); - // vector_limiter(u, u_lim); + // vector_limiter_symmetry(u, u_lim, grad_u); + vector_limiter(u, u_lim); synchronize(p_lim.cellArrays()); synchronize(u_lim.cellArrays()); @@ -1124,8 +1124,8 @@ class EulerKineticSolverLagrangeMultiDLocalOrder2 if (limitation) { const CellValue<const TinyMatrix<Dimension>> grad_u = compute_grad_u(u_star_lim); scalar_limiter(pj_star, p_star_lim); - vector_limiter_symmetry(uj_star, u_star_lim, grad_u); - // vector_limiter(uj_star, u_star_lim); + // vector_limiter_symmetry(uj_star, u_star_lim, grad_u); + vector_limiter(uj_star, u_star_lim); synchronize(p_star_lim.cellArrays()); synchronize(u_star_lim.cellArrays());