diff --git a/src/language/modules/SchemeModule.cpp b/src/language/modules/SchemeModule.cpp index ce1a61e77e19542fadf80d6bc52d9618437af9b8..b950437fae7028efd644f555aca4e55ae1d16dae 100644 --- a/src/language/modules/SchemeModule.cpp +++ b/src/language/modules/SchemeModule.cpp @@ -621,6 +621,44 @@ SchemeModule::SchemeModule() )); + this + ->_addBuiltinFunction("implicit_eucclhyd_euler", + 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::shared_ptr<const DiscreteFunctionVariant>& pi, + const std::shared_ptr<const DiscreteFunctionVariant>& gamma, + const std::shared_ptr<const DiscreteFunctionVariant>& Cv, + const std::shared_ptr<const DiscreteFunctionVariant>& entropy, + const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>& + bc_descriptor_list, + const std::shared_ptr<const DiscreteFunctionVariant>& chi_explicit, + 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 ImplicitAcousticSolverHandler{ImplicitAcousticSolverHandler::SolverType::Eucclhyd, + rho, + c, + u, + p, + pi, + gamma, + Cv, + entropy, + bc_descriptor_list, + chi_explicit, + dt} + .solver() + .apply(dt, rho, u, E, c, p, pi, gamma, Cv, entropy); + } + + )); + this->_addBuiltinFunction( "implicit_eucclhyd_euler", std::function( @@ -655,6 +693,116 @@ SchemeModule::SchemeModule() )); + this->_addBuiltinFunction("implicit_glace_euler", + 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::shared_ptr<const DiscreteFunctionVariant>& pi, + const std::shared_ptr<const DiscreteFunctionVariant>& gamma, + const std::shared_ptr<const DiscreteFunctionVariant>& Cv, + const std::shared_ptr<const DiscreteFunctionVariant>& entropy, + const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>& + bc_descriptor_list, + const std::vector<std::shared_ptr<const IZoneDescriptor>>& explicit_zone_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 ImplicitAcousticSolverHandler{ImplicitAcousticSolverHandler::SolverType:: + Glace2States, + rho, + c, + u, + p, + pi, + gamma, + Cv, + entropy, + bc_descriptor_list, + explicit_zone_list, + dt} + .solver() + .apply(dt, rho, u, E, c, p, pi, gamma, Cv, entropy); + } + + )); + + this->_addBuiltinFunction("implicit_glace_euler", + 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::shared_ptr<const DiscreteFunctionVariant>& pi, + const std::shared_ptr<const DiscreteFunctionVariant>& gamma, + const std::shared_ptr<const DiscreteFunctionVariant>& Cv, + const std::shared_ptr<const DiscreteFunctionVariant>& entropy, + const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>& + bc_descriptor_list, + const std::shared_ptr<const DiscreteFunctionVariant>& chi_explicit, + 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 ImplicitAcousticSolverHandler{ImplicitAcousticSolverHandler::SolverType:: + Glace2States, + rho, + c, + u, + p, + pi, + gamma, + Cv, + entropy, + bc_descriptor_list, + chi_explicit, + dt} + .solver() + .apply(dt, rho, u, E, c, p, pi, gamma, Cv, entropy); + } + + )); + + this->_addBuiltinFunction( + "implicit_glace_euler", + 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::shared_ptr<const DiscreteFunctionVariant>& pi, + const std::shared_ptr<const DiscreteFunctionVariant>& gamma, + const std::shared_ptr<const DiscreteFunctionVariant>& Cv, + const std::shared_ptr<const DiscreteFunctionVariant>& entropy, + 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 ImplicitAcousticSolverHandler{ImplicitAcousticSolverHandler::SolverType::Glace2States, + rho, + c, + u, + p, + pi, + gamma, + Cv, + entropy, + bc_descriptor_list, + std::vector<std::shared_ptr<const IZoneDescriptor>>{}, + dt} + .solver() + .apply(dt, rho, u, E, c, p, pi, gamma, Cv, entropy); + } + + )); + this->_addBuiltinFunction("acoustic_dt", std::function( diff --git a/src/scheme/ImplicitAcousticSolver.cpp b/src/scheme/ImplicitAcousticSolver.cpp index d835bb7e101fc2236cd8dd255239afe85f354e3b..2b74689bf36b506d094ea05198707139a4007f3d 100644 --- a/src/scheme/ImplicitAcousticSolver.cpp +++ b/src/scheme/ImplicitAcousticSolver.cpp @@ -112,6 +112,8 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final NodeValuePerCell<const Rdxd> m_Ajr; NodeValue<const Rdxd> m_inv_Ar; + NodeValuePerCell<const Rd> m_Djr; + CellValue<const Rd> m_predicted_u; CellValue<const double> m_predicted_p; @@ -152,15 +154,14 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final { MeshDataType& mesh_data = MeshDataManager::instance().getMeshData(m_mesh); - const NodeValuePerCell<const Rd> Cjr = mesh_data.Cjr(); - const NodeValuePerCell<const Rd> njr = mesh_data.njr(); + const NodeValuePerCell<const Rd> Cjr_n = mesh_data.Cjr(); + const NodeValuePerCell<const Rd> njr_n = mesh_data.njr(); NodeValuePerCell<Rdxd> Ajr{m_mesh.connectivity()}; const auto& cell_to_node_matrix = m_mesh.connectivity().cellToNodeMatrix(); switch (m_solver_type) { case SolverType::Glace1State: { - std::cout << "Glace 1 state" << '\n'; NodeValue<const double> rhocr = _getRhoCr(rho, c); parallel_for( @@ -168,25 +169,23 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final const size_t& nb_nodes = Ajr.numberOfSubValues(j); for (size_t r = 0; r < nb_nodes; ++r) { const NodeId node_id = cell_to_node_matrix[j][r]; - Ajr(j, r) = tensorProduct(rhocr[node_id] * Cjr(j, r), njr(j, r)); + Ajr(j, r) = tensorProduct(rhocr[node_id] * Cjr_n(j, r), njr_n(j, r)); } }); break; } case SolverType::Glace2States: { - std::cout << "Glace 2 states" << '\n'; parallel_for( m_mesh.numberOfCells(), PUGS_LAMBDA(CellId j) { const size_t& nb_nodes = Ajr.numberOfSubValues(j); for (size_t r = 0; r < nb_nodes; ++r) { - Ajr(j, r) = tensorProduct(rho[j] * c[j] * Cjr(j, r), njr(j, r)); + Ajr(j, r) = tensorProduct(rho[j] * c[j] * Cjr_n(j, r), njr_n(j, r)); } }); break; } case SolverType::Eucclhyd: { - std::cout << "Eucclhyd" << '\n'; if constexpr (Dimension > 1) { const NodeValuePerFace<const Rd> Nlr = mesh_data.Nlr(); const NodeValuePerFace<const Rd> nlr = mesh_data.nlr(); @@ -224,7 +223,6 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final } }); - // std::cout << "Nlr = " << Nlr << '\n'; break; } else { throw NotImplementedError("Eucclhyd switch is not implemented yet in 1d"); @@ -232,8 +230,6 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final } } - // std::cout << "Ajr = " << Ajr << '\n'; - return Ajr; } @@ -246,17 +242,17 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final NodeValue<Rdxd> Ar{m_mesh.connectivity()}; parallel_for( - m_mesh.numberOfNodes(), PUGS_LAMBDA(NodeId r) { + m_mesh.numberOfNodes(), PUGS_LAMBDA(NodeId node_id) { Rdxd sum = zero; - const auto& node_to_cell = node_to_cell_matrix[r]; - const auto& node_local_number_in_its_cells = node_local_numbers_in_their_cells.itemArray(r); + 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]; - sum += Ajr(J, R); + for (size_t i_cell = 0; i_cell < node_to_cell.size(); ++i_cell) { + const unsigned int i_node = node_local_number_in_its_cells[i_cell]; + const CellId cell_id = node_to_cell[i_cell]; + sum += Ajr(cell_id, i_node); } - Ar[r] = sum; + Ar[node_id] = sum; }); NodeValue<int> boundary_node_s(m_mesh.connectivity()); @@ -306,6 +302,7 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final Ar[node_id] = identity; }); + } else if constexpr (std::is_same_v<PressureBoundaryCondition, T>) { } else { throw UnexpectedError("boundary condition not handled 1"); } @@ -331,19 +328,19 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final int mapP(CellId j) const { - // return (1 + Dimension) * m_implicit_cell_index[j]; - return m_implicit_cell_index[j]; + return (1 + Dimension) * m_implicit_cell_index[j]; + // return m_implicit_cell_index[j]; } int mapU(size_t k, CellId j) const { - // return (1 + Dimension) * m_implicit_cell_index[j] + k + 1; - return m_number_of_implicit_cells + k + m_implicit_cell_index[j] * Dimension; + return (1 + Dimension) * m_implicit_cell_index[j] + k + 1; + // return m_number_of_implicit_cells + k + m_implicit_cell_index[j] * Dimension; } CRSMatrixDescriptor<double> - _getA(NodeValuePerCell<const Rd> Cjr_half) const + _getA() const { count_getA++; static bool is_get_A_started = false; @@ -415,8 +412,7 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final const size_t node_nb_in_j = node_local_number_in_its_cells[cell_j]; const int j_index_p = mapP(id_cell_j); - const Rd coef = - m_Ajr(id_cell_i, node_nb_in_i) * m_inv_Ar[node_id] * Cjr_half(id_cell_j, node_nb_in_j); + const Rd coef = m_Ajr(id_cell_i, node_nb_in_i) * m_inv_Ar[node_id] * m_Djr(id_cell_j, node_nb_in_j); A(j_index_p, i_index_u) += coef[i_dimension]; A(i_index_u, j_index_p) -= coef[i_dimension]; } @@ -427,10 +423,6 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final } } - // std::cout << "sans cond limite=" << A << '\n'; - - // NodeValue<Rdxd> inverse_ArxP{m_mesh.connectivity()}; - NodeValue<int> boundary_node_s(m_mesh.connectivity()); boundary_node_s.fill(-1); @@ -458,42 +450,40 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final using T = std::decay_t<decltype(bc)>; if constexpr (std::is_same_v<VelocityBoundaryCondition, T>) { // no changes for velocity conditions - } // else if constexpr (std::is_same_v<PressureBoundaryCondition, T>) { - // const auto& node_list = bc.faceList(); - - // MeshDataType& mesh_data = MeshDataManager::instance().getMeshData(m_mesh); - - // const NodeValuePerCell<const Rd>& Cjr = mesh_data.Cjr(); - - // const auto& node_local_numbers_in_their_cells = m_mesh.connectivity().nodeLocalNumbersInTheirCells(); - - // const auto& node_to_cell_matrix = m_mesh.connectivity().nodeToCellMatrix(); - - // for (size_t i_dimension = 0; i_dimension < Dimension; ++i_dimension) { - // for (size_t i_node = 0; i_node < node_list.size(); ++i_node) { - // const NodeId& node_id = node_list[i_node]; - // // if (m_is_implicit_node[node_id]) { - // const auto& node_cell = node_to_cell_matrix[node_id]; - // for (size_t cell_i = 0; cell_i < node_cell.size(); ++cell_i) { - // const CellId id_cell_i = node_cell[cell_i]; - // if (m_is_implicit_cell[id_cell_i]) { - // const auto& node_local_number_in_its_cells = - // node_local_numbers_in_their_cells.itemArray(node_id); const size_t node_nb_in_i = - // node_local_number_in_its_cells[cell_i]; int index_p = - // mapP(id_cell_i); int index_u = mapU(i_dimension, id_cell_i); - - // const Rd coef = m_Ajr(id_cell_i, node_local_number_in_its_cells[node_nb_in_i]) * - // m_inv_Ar[node_id] * - // Cjr(id_cell_i, node_local_number_in_its_cells[node_nb_in_i]); - // A(index_p, index_u) += coef[i_dimension]; - // A(index_u, index_p) -= coef[i_dimension]; - // //} - // } - // } - // } - // } - // } - else if constexpr (std::is_same_v<SymmetryBoundaryCondition, T>) { + } else if constexpr (std::is_same_v<PressureBoundaryCondition, T>) { + // const auto& face_list = bc.faceList(); + + // const auto& face_local_numbers_in_their_cells = m_mesh.connectivity().faceLocalNumbersInTheirCells(); + + // const auto& face_to_cell_matrix = m_mesh.connectivity().faceToCellMatrix(); + + // for (size_t i_dimension = 0; i_dimension < Dimension; ++i_dimension) { + // for (size_t i_face = 0; i_face < face_list.size(); ++i_face) { + // const FaceId& face_id = face_list[i_face]; + // // if (m_is_implicit_node[node_id]) { + // const auto& face_cell = face_to_cell_matrix[face_id]; + // for (size_t cell_i = 0; cell_i < face_cell.size(); ++cell_i) { + // const CellId id_cell_i = face_cell[cell_i]; + // if (m_is_implicit_cell[id_cell_i]) { + // // const auto& face_local_number_in_its_cells = + // // face_local_numbers_in_their_cells.itemArray(face_id); const size_t node_nb_in_i = + // // face_local_number_in_its_cells[cell_i]; + // int index_p = mapP(id_cell_i); + // int index_u = mapU(i_dimension, id_cell_i); + + // // const Rd coef = m_Ajr(id_cell_i, face_local_number_in_its_cells[node_nb_in_i]) * + // // m_inv_Ar[face_id] * + // // m_Djr(id_cell_i, face_local_number_in_its_cells[node_nb_in_i]); + + // const Rd coef = zero; + // A(index_p, index_u) += coef[i_dimension]; + // A(index_u, index_p) -= coef[i_dimension]; + // //} + // } + // } + // } + // } + } else if constexpr (std::is_same_v<SymmetryBoundaryCondition, T>) { const auto& node_list = bc.nodeList(); const auto& node_local_numbers_in_their_cells = m_mesh.connectivity().nodeLocalNumbersInTheirCells(); @@ -504,7 +494,6 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final const Rdxd P = I - nxn; NodeValue<Rdxd> inverse_ArxP{m_mesh.connectivity()}; - // std::cout << node_list << '\n'; for (size_t i_node = 0; i_node < node_list.size(); ++i_node) { const NodeId& node_id = node_list[i_node]; if (boundary_node_s[node_id] != -1) { @@ -526,7 +515,7 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final const int j_index_p = mapP(id_cell_j); const Rd coef = - m_Ajr(id_cell_i, node_nb_in_i) * inverse_ArxP[node_id] * Cjr_half(id_cell_j, node_nb_in_j); + m_Ajr(id_cell_i, node_nb_in_i) * inverse_ArxP[node_id] * m_Djr(id_cell_j, node_nb_in_j); A(j_index_p, i_index_u) += coef[i_dimension]; A(i_index_u, j_index_p) -= coef[i_dimension]; } @@ -544,8 +533,6 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final } get_A_t.pause(); - // std::cout << "avec cond limite" << A << '\n'; - return A; } @@ -600,12 +587,6 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final computed_tau_iter[j] = m_g_1_exp_S_Cv_inv_g[j] * pow(-Uk[k] + pi[j], -m_inv_gamma[j]); } }); - // for (CellId j = 0; j < m_mesh.numberOfCells(); ++j) { - // // std::cout << "exp=" << m_g_1_exp_S_Cv_inv_g[j] << '\n'; - // // std::cout << "pi=" << pi[j] << '\n'; - // std::cout << "tau_iter=" << computed_tau_iter[j] << '\n'; - // std::cout << "Un=" << Un << '\n'; - // } return computed_tau_iter; }(); @@ -615,16 +596,13 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final computed_gradJ = zero; const auto& node_to_cell_matrix = m_mesh.connectivity().nodeToCellMatrix(); const auto& node_local_numbers_in_their_cells = m_mesh.connectivity().nodeLocalNumbersInTheirCells(); - MeshDataType& mesh_data = MeshDataManager::instance().getMeshData(m_mesh); - - const NodeValuePerCell<const Rd>& Cjr = mesh_data.Cjr(); auto is_boundary_node = m_mesh.connectivity().isBoundaryNode(); for (NodeId node_id = 0; node_id < m_mesh.numberOfNodes(); ++node_id) { if (not is_boundary_node[node_id]) { const auto& node_cell = node_to_cell_matrix[node_id]; const auto& node_local_number_in_its_cells = node_local_numbers_in_their_cells.itemArray(node_id); - Rd sum_Cjrpj = zero; + Rd sum_Djrpj = zero; Rd sum_Ajruj = zero; Rd Uk_i = zero; Rd Uk_j = zero; @@ -633,7 +611,7 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final if (m_is_implicit_cell[id_cell_i]) { const size_t node_nb_in_i = node_local_number_in_its_cells[cell_i]; const size_t i_index_p = mapP(id_cell_i); - sum_Cjrpj += Uk[i_index_p] * Cjr(id_cell_i, node_nb_in_i); + sum_Djrpj += Uk[i_index_p] * m_Djr(id_cell_i, node_nb_in_i); for (size_t i_dimension = 0; i_dimension < Dimension; ++i_dimension) { const size_t i_index_u = mapU(i_dimension, id_cell_i); @@ -649,7 +627,7 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final const size_t node_nb_in_j = node_local_number_in_its_cells[cell_j]; const size_t j_index_p = mapP(id_cell_j); - computed_gradJ[j_index_p] += dot(Cjr(id_cell_j, node_nb_in_j), m_inv_Ar[node_id] * sum_Cjrpj); + computed_gradJ[j_index_p] += dot(m_Djr(id_cell_j, node_nb_in_j), m_inv_Ar[node_id] * sum_Djrpj); for (size_t i_dimension = 0; i_dimension < Dimension; ++i_dimension) { const size_t j_index_u = mapU(i_dimension, id_cell_j); @@ -682,12 +660,12 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final if (m_is_implicit_node[node_id]) { if (not is_boundary_node[node_id]) { const auto& node_cells = node_to_cell_matrix[node_id]; - Rd sum_Cjrpj_exp = zero; + Rd sum_Djrpj_exp = zero; Rd sum_Ajruj_exp = zero; for (size_t i_cell = 0; i_cell < node_cells.size(); ++i_cell) { if (not m_is_implicit_cell[node_cells[i_cell]]) { const size_t node_nb_in_i = node_local_number_in_its_cells[i_cell]; - sum_Cjrpj_exp += p[node_cells[i_cell]] * Cjr(node_cells[i_cell], node_nb_in_i); + sum_Djrpj_exp += p[node_cells[i_cell]] * m_Djr(node_cells[i_cell], node_nb_in_i); sum_Ajruj_exp += m_Ajr(node_cells[i_cell], node_nb_in_i) * u[node_cells[i_cell]]; } } @@ -696,13 +674,13 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final if (m_is_implicit_cell[id_cell_j]) { const size_t node_nb_in_j = node_local_number_in_its_cells[j_cell]; const size_t j_index_p = mapP(id_cell_j); - computed_gradJ[j_index_p] -= dot(Cjr(id_cell_j, node_nb_in_j), m_inv_Ar[node_id] * sum_Cjrpj_exp) + - dot(Cjr(id_cell_j, node_nb_in_j), m_inv_Ar[node_id] * sum_Ajruj_exp); + computed_gradJ[j_index_p] -= dot(m_Djr(id_cell_j, node_nb_in_j), m_inv_Ar[node_id] * sum_Djrpj_exp) + + dot(m_Djr(id_cell_j, node_nb_in_j), m_inv_Ar[node_id] * sum_Ajruj_exp); for (size_t i_dimension = 0; i_dimension < Dimension; ++i_dimension) { const size_t j_index_u = mapU(i_dimension, id_cell_j); computed_gradJ[j_index_u] -= - (m_Ajr(id_cell_j, node_nb_in_j) * m_inv_Ar[node_id] * sum_Cjrpj_exp + + (m_Ajr(id_cell_j, node_nb_in_j) * m_inv_Ar[node_id] * sum_Djrpj_exp + m_Ajr(id_cell_j, node_nb_in_j) * m_inv_Ar[node_id] * sum_Ajruj_exp)[i_dimension]; } } @@ -710,9 +688,6 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final } } } - // std::cout << "gradJ sans cond limit=" << computed_gradJ << '\n'; - // NodeValue<int> boundary_node_sym(m_mesh.connectivity()); - // boundary_node_sym.fill(-1); NodeValue<int> boundary_node_s(m_mesh.connectivity()); boundary_node_s.fill(-1); @@ -745,10 +720,9 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final // const auto& value_list = bc.valueList(); // MeshDataType& mesh_data = MeshDataManager::instance().getMeshData(m_mesh); - // const NodeValuePerCell<const Rd>& Cjr = mesh_data.Cjr(); // const auto& node_local_numbers_in_their_cells = m_mesh.connectivity().nodeLocalNumbersInTheirCells(); // const auto& node_to_cell_matrix = m_mesh.connectivity().nodeToCellMatrix(); - // Rd sum_Cjrpext = zero; + // Rd sum_Djrpext = zero; // for (size_t i_node = 0; i_node < node_list.size(); ++i_node) { // const NodeId& node_id = node_list[i_node]; @@ -761,7 +735,7 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final // node_local_numbers_in_their_cells.itemArray(node_id); const size_t node_nb_in_i = // node_local_number_in_its_cells[cell_i]; - // sum_Cjrpext += value_list[i_node] * Cjr(id_cell_i, node_nb_in_i); + // sum_Djrpext += value_list[i_node] * m_Djr(id_cell_i, node_nb_in_i); // } // } // for (size_t cell_j = 0; cell_j < node_cell.size(); ++cell_j) { @@ -770,11 +744,11 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final // const auto& node_local_number_in_its_cells = // node_local_numbers_in_their_cells.itemArray(node_id); const size_t node_nb_in_j = // node_local_number_in_its_cells[cell_j]; int index_p = - // mapP(id_cell_j); computed_gradJ[index_p] += dot(Cjr(id_cell_j, node_nb_in_j), m_inv_Ar[node_id] - // * sum_Cjrpext); for (size_t i_dimension = 0; i_dimension < Dimension; ++i_dimension) { + // mapP(id_cell_j); computed_gradJ[index_p] += dot(m_Djr(id_cell_j, node_nb_in_j), m_inv_Ar[node_id] + // * sum_Djrpext); for (size_t i_dimension = 0; i_dimension < Dimension; ++i_dimension) { // int index_u = mapU(i_dimension, id_cell_j); // computed_gradJ[index_u] += - // (m_Ajr(id_cell_j, node_nb_in_j) * m_inv_Ar[node_id] * sum_Cjrpext)[i_dimension]; + // (m_Ajr(id_cell_j, node_nb_in_j) * m_inv_Ar[node_id] * sum_Djrpext)[i_dimension]; // } // } // } @@ -782,8 +756,6 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final // } if constexpr (std::is_same_v<SymmetryBoundaryCondition, T>) { const auto& node_list = bc.nodeList(); - MeshDataType& mesh_data = MeshDataManager::instance().getMeshData(m_mesh); - const NodeValuePerCell<const Rd>& Cjr = mesh_data.Cjr(); const auto& node_local_numbers_in_their_cells = m_mesh.connectivity().nodeLocalNumbersInTheirCells(); const auto& node_to_cell_matrix = m_mesh.connectivity().nodeToCellMatrix(); const Rd& n = bc.outgoingNormal(); @@ -800,9 +772,9 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final const auto& node_cell = node_to_cell_matrix[node_id]; inverse_ArxP[node_id] = m_inv_Ar[node_id] * P; - Rd sum_Cjrpj = zero; + Rd sum_Djrpj = zero; Rd sum_Ajruj = zero; - Rd sum_Cjrpj_exp = zero; + Rd sum_Djrpj_exp = zero; Rd sum_Ajruj_exp = zero; Rd Uk_i = zero; const auto& node_local_number_in_its_cells = node_local_numbers_in_their_cells.itemArray(node_id); @@ -812,7 +784,7 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final if (m_is_implicit_cell[id_cell_i]) { const size_t node_nb_in_i = node_local_number_in_its_cells[cell_i]; const size_t i_index_p = mapP(id_cell_i); - sum_Cjrpj += Uk[i_index_p] * Cjr(id_cell_i, node_nb_in_i); + sum_Djrpj += Uk[i_index_p] * m_Djr(id_cell_i, node_nb_in_i); for (size_t i_dimension = 0; i_dimension < Dimension; ++i_dimension) { const size_t i_index_u = mapU(i_dimension, id_cell_i); @@ -825,7 +797,7 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final for (size_t i_cell = 0; i_cell < node_cell.size(); ++i_cell) { if (not m_is_implicit_cell[node_cell[i_cell]]) { const size_t node_nb_in_i = node_local_number_in_its_cells[i_cell]; - sum_Cjrpj_exp += p[node_cell[i_cell]] * Cjr(node_cell[i_cell], node_nb_in_i); + sum_Djrpj_exp += p[node_cell[i_cell]] * m_Djr(node_cell[i_cell], node_nb_in_i); sum_Ajruj_exp += m_Ajr(node_cell[i_cell], node_nb_in_i) * u[node_cell[i_cell]]; } } @@ -837,9 +809,9 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final int index_p = mapP(id_cell_j); computed_gradJ[index_p] += - dot(Cjr(id_cell_j, node_nb_in_j), inverse_ArxP[node_id] * sum_Cjrpj) - - dot(Cjr(id_cell_j, node_nb_in_j), inverse_ArxP[node_id] * sum_Cjrpj_exp) - - dot(Cjr(id_cell_j, node_nb_in_j), inverse_ArxP[node_id] * sum_Ajruj_exp); + dot(m_Djr(id_cell_j, node_nb_in_j), inverse_ArxP[node_id] * sum_Djrpj) - + dot(m_Djr(id_cell_j, node_nb_in_j), inverse_ArxP[node_id] * sum_Djrpj_exp) - + dot(m_Djr(id_cell_j, node_nb_in_j), inverse_ArxP[node_id] * sum_Ajruj_exp); ; for (size_t i_dimension = 0; i_dimension < Dimension; ++i_dimension) { int j_index_u = mapU(i_dimension, id_cell_j); @@ -851,7 +823,7 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final computed_gradJ[index_u] += (-m_Ajr(id_cell_j, node_nb_in_j) * inverse_ArxP[node_id] * sum_Ajruj + m_Ajr(id_cell_j, node_nb_in_j) * Uk_j)[i_dimension] - - (m_Ajr(id_cell_j, node_nb_in_j) * inverse_ArxP[node_id] * sum_Cjrpj_exp + + (m_Ajr(id_cell_j, node_nb_in_j) * inverse_ArxP[node_id] * sum_Djrpj_exp + m_Ajr(id_cell_j, node_nb_in_j) * inverse_ArxP[node_id] * sum_Ajruj_exp)[i_dimension]; } } @@ -862,8 +834,6 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final const auto& node_list = bc.nodeList(); const auto& value_list = bc.valueList(); - MeshDataType& mesh_data = MeshDataManager::instance().getMeshData(m_mesh); - const NodeValuePerCell<const Rd>& Cjr = mesh_data.Cjr(); const auto& node_local_numbers_in_their_cells = m_mesh.connectivity().nodeLocalNumbersInTheirCells(); const auto& node_to_cell_matrix = m_mesh.connectivity().nodeToCellMatrix(); @@ -881,9 +851,6 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final for (size_t i_dimension = 0; i_dimension < Dimension; ++i_dimension) { int i_index_u = mapU(i_dimension, id_cell_i); Uk_i[i_dimension] = Uk[i_index_u]; - // std::cout << "Uk_i[" << i_dimension << "]=" << Uk_i[i_dimension] << '\n'; - // std::cout << "Uk=" << Uk << '\n'; - // std::cout << "Uk[" << i_index_u << "]=" << Uk[i_index_u] << '\n'; } } } @@ -894,32 +861,23 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final const auto& node_local_number_in_its_cells = node_local_numbers_in_their_cells.itemArray(node_id); const size_t node_nb_in_i = node_local_number_in_its_cells[cell_i]; int i_index_p = mapP(id_cell_i); - computed_gradJ[i_index_p] += -dot(Cjr(id_cell_i, node_nb_in_i), value_list[i_node]); - // std::cout << "gradJp[" << i_index_p << "]=" << computed_gradJ[i_index_p] << '\n'; - // std::cout << "Cjr(" << id_cell_i << "," << node_nb_in_i << ")=" << Cjr(id_cell_i, node_nb_in_i) - // << '\n'; std::cout << "value[" << i_node << "]=" << value_list[i_node] << '\n'; + computed_gradJ[i_index_p] += -dot(m_Djr(id_cell_i, node_nb_in_i), value_list[i_node]); for (size_t i_dimension = 0; i_dimension < Dimension; ++i_dimension) { int i_index_u = mapU(i_dimension, id_cell_i); - // Uk_i[i_dimension] = Uk[i_index_u]; - // std::cout << "Uk_i" << Uk_i << '\n'; computed_gradJ[i_index_u] += (m_Ajr(id_cell_i, node_nb_in_i) * (Uk_i - value_list[i_node]))[i_dimension]; - // std::cout << "Ajr(" << id_cell_i << "," << node_nb_in_i << ")=" << m_Ajr(id_cell_i, - // node_nb_in_i) << '\n'; std::cout << "uk-value[" << i_node << "]=" << Uk_i - value_list[i_node] - // << '\n'; std::cout << "gradJu[" << i_index_u << "]=" << computed_gradJ[i_index_u] << '\n'; } } } } } + } else if constexpr (std::is_same_v<PressureBoundaryCondition, T>) { } else { throw UnexpectedError("boundary condition not handled 3"); } }, boundary_condition); } - // std::cout << "gradJ=" << computed_gradJ << '\n'; - // std::exit(0); return computed_gradJ; } @@ -934,13 +892,8 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final { Vector<double> gradJ = this->_getGradJ(Un, Uk, p, pi, u, dt); - // std::cout << "gradJ" << gradJ << '\n'; - // CRSMatrix A_crs{A.getCRSMatrix()}; - // std::exit(0); - // Vector<double> AU = A_crs * Uk; Vector<double> AU = A * Uk; - // std::cout << "AU" << AU << '\n'; Vector<double> F = gradJ - AU; return F; @@ -990,7 +943,6 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final nb_neighboors.clear(); } } - // std::cout << non_zeros << '\n'; CRSMatrixDescriptor Hess_J{(Dimension + 1) * m_number_of_implicit_cells, (Dimension + 1) * m_number_of_implicit_cells, non_zeros}; @@ -1028,58 +980,58 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final const auto& node_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 cell_i = 0; cell_i < node_cell.size(); ++cell_i) { - const CellId id_cell_i = node_cell[cell_i]; - if (m_is_implicit_cell[id_cell_i]) { - const size_t node_nb_in_i = node_local_number_in_its_cells[cell_i]; - const int i_index_p = mapP(id_cell_i); + for (size_t j_cell = 0; j_cell < node_cell.size(); ++j_cell) { + const CellId cell_id_j = node_cell[j_cell]; + if (m_is_implicit_cell[cell_id_j]) { + const size_t node_nb_in_j_cell = node_local_number_in_its_cells[j_cell]; + const int j_index_p = mapP(cell_id_j); - const auto invArCir = inv_Ar * Cjr(id_cell_i, node_nb_in_i); + const auto invArCir = inv_Ar * Cjr(cell_id_j, node_nb_in_j_cell); - for (size_t cell_j = 0; cell_j < node_cell.size(); ++cell_j) { - const CellId id_cell_j = node_cell[cell_j]; - if (m_is_implicit_cell[id_cell_j]) { - const size_t node_nb_in_j = node_local_number_in_its_cells[cell_j]; - const int j_index_p = mapP(id_cell_j); - Hess_J(i_index_p, j_index_p) += dot(invArCir, Cjr(id_cell_j, node_nb_in_j)); + for (size_t i_cell = 0; i_cell < node_cell.size(); ++i_cell) { + const CellId cell_id_i = node_cell[i_cell]; + if (m_is_implicit_cell[cell_id_i]) { + const size_t node_nb_in_cell_i = node_local_number_in_its_cells[i_cell]; + const int i_index_p = mapP(cell_id_i); + Hess_J(j_index_p, i_index_p) += dot(invArCir, Cjr(cell_id_i, node_nb_in_cell_i)); } } } } - for (size_t cell_i = 0; cell_i < node_cell.size(); ++cell_i) { - const CellId id_cell_i = node_cell[cell_i]; - if (m_is_implicit_cell[id_cell_i]) { - const size_t node_nb_in_i = node_local_number_in_its_cells[cell_i]; + for (size_t j_cell = 0; j_cell < node_cell.size(); ++j_cell) { + const CellId cell_id_j = node_cell[j_cell]; + if (m_is_implicit_cell[cell_id_j]) { + const size_t node_nb_in_j_cell = node_local_number_in_its_cells[j_cell]; - const auto Ajr = m_Ajr(id_cell_i, node_nb_in_i); + const auto Ajr = m_Ajr(cell_id_j, node_nb_in_j_cell); - for (size_t i_dimension = 0; i_dimension < Dimension; ++i_dimension) { - const int i_index_u = mapU(i_dimension, id_cell_i); - Hess_J(i_index_u, i_index_u) += Ajr(i_dimension, i_dimension); + for (size_t j_dimension = 0; j_dimension < Dimension; ++j_dimension) { + const int j_index_u = mapU(j_dimension, cell_id_j); + Hess_J(j_index_u, j_index_u) += Ajr(j_dimension, j_dimension); } } } - for (size_t cell_i = 0; cell_i < node_cell.size(); ++cell_i) { - const CellId id_cell_i = node_cell[cell_i]; - if (m_is_implicit_cell[id_cell_i]) { - const size_t node_nb_in_i = node_local_number_in_its_cells[cell_i]; + for (size_t j_cell = 0; j_cell < node_cell.size(); ++j_cell) { + const CellId cell_id_j = node_cell[j_cell]; + if (m_is_implicit_cell[cell_id_j]) { + const size_t node_nb_in_j_cell = node_local_number_in_its_cells[j_cell]; - const auto Air_invAr = m_Ajr(id_cell_i, node_nb_in_i) * inv_Ar; + const auto Ajr_invAr = m_Ajr(cell_id_j, node_nb_in_j_cell) * inv_Ar; - for (size_t cell_j = 0; cell_j < node_cell.size(); ++cell_j) { - const CellId id_cell_j = node_cell[cell_j]; - if (m_is_implicit_cell[id_cell_j]) { - const size_t node_nb_in_j = node_local_number_in_its_cells[cell_j]; + for (size_t i_cell = 0; i_cell < node_cell.size(); ++i_cell) { + const CellId cell_id_i = node_cell[i_cell]; + if (m_is_implicit_cell[cell_id_i]) { + const size_t node_nb_in_i_cell = node_local_number_in_its_cells[i_cell]; - const auto Air_invAr_Ajr = Air_invAr * m_Ajr(id_cell_j, node_nb_in_j); + const auto Ajr_invAr_Air = Ajr_invAr * m_Ajr(cell_id_i, node_nb_in_i_cell); - for (size_t i_dimension = 0; i_dimension < Dimension; ++i_dimension) { - const int i_index_u = mapU(i_dimension, id_cell_i); + for (size_t j_dimension = 0; j_dimension < Dimension; ++j_dimension) { + const int index_u_j = mapU(j_dimension, cell_id_j); for (size_t j_dimension = 0; j_dimension < Dimension; ++j_dimension) { - const int j_index_u = mapU(j_dimension, id_cell_j); - Hess_J(i_index_u, j_index_u) -= Air_invAr_Ajr(i_dimension, j_dimension); + const int index_u_i = mapU(j_dimension, cell_id_i); + Hess_J(index_u_j, index_u_i) -= Ajr_invAr_Air(j_dimension, j_dimension); } } } @@ -1224,70 +1176,68 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final } } } - } - // else if constexpr (std::is_same_v<PressureBoundaryCondition, T>) { - // const auto& node_list = bc.faceList(); - - // const auto& node_local_numbers_in_their_cells = m_mesh.connectivity().nodeLocalNumbersInTheirCells(); - // const auto& node_to_cell_matrix = m_mesh.connectivity().nodeToCellMatrix(); - - // for (size_t i_node = 0; i_node < node_list.size(); ++i_node) { - // const NodeId& node_id = node_list[i_node]; - // // if (m_is_implicit_node[node_id]) { - // const auto& node_cell = node_to_cell_matrix[node_id]; - - // for (size_t cell_i = 0; cell_i < node_cell.size(); ++cell_i) { - // const CellId id_cell_i = node_cell[cell_i]; - // if (m_is_implicit_cell[id_cell_i]) { - // const auto& node_local_number_in_its_cells = - // node_local_numbers_in_their_cells.itemArray(node_id); - - // const size_t node_nb_in_i = node_local_number_in_its_cells[cell_i]; - // const int i_index_p = mapP(id_cell_i); - - // for (size_t cell_j = 0; cell_j < node_cell.size(); ++cell_j) { - // const CellId id_cell_j = node_cell[cell_j]; - // if (m_is_implicit_cell[id_cell_j]) { - // const size_t node_nb_in_j = node_local_number_in_its_cells[cell_j]; - // const int j_index_p = mapP(id_cell_j); - - // Hess_J(i_index_p, j_index_p) += - // dot(Cjr(id_cell_i, node_nb_in_i), m_inv_Ar[node_id] * Cjr(id_cell_j, node_nb_in_j)); - // } - // } - // } - // } - // for (size_t cell_i = 0; cell_i < node_cell.size(); ++cell_i) { - // const CellId id_cell_i = node_cell[cell_i]; - // if (m_is_implicit_cell[id_cell_i]) { - // const auto& node_local_number_in_its_cells = - // node_local_numbers_in_their_cells.itemArray(node_id); - - // const size_t node_nb_in_i = node_local_number_in_its_cells[cell_i]; - // for (size_t i_dimension = 0; i_dimension < Dimension; ++i_dimension) { - // const int i_index_u = mapU(i_dimension, id_cell_i); - - // Hess_J(i_index_u, i_index_u) += m_Ajr(id_cell_i, node_nb_in_i)(i_dimension, i_dimension); - - // for (size_t cell_j = 0; cell_j < node_cell.size(); ++cell_j) { - // const CellId id_cell_j = node_cell[cell_j]; - // if (m_is_implicit_cell[id_cell_j]) { - // const size_t node_nb_in_j = node_local_number_in_its_cells[cell_j]; - // for (size_t j_dimension = 0; j_dimension < Dimension; ++j_dimension) { - // const int j_index_u = mapU(j_dimension, id_cell_j); - - // Hess_J(i_index_u, j_index_u) += -(m_Ajr(id_cell_i, node_nb_in_i) * m_inv_Ar[node_id] * - // m_Ajr(id_cell_j, node_nb_in_j))(i_dimension, - // j_dimension); - // } - // } - // } - // } - // } - // } - // } - // } - else { + } else if constexpr (std::is_same_v<PressureBoundaryCondition, T>) { + // const auto& node_list = bc.faceList(); + + // const auto& node_local_numbers_in_their_cells = m_mesh.connectivity().nodeLocalNumbersInTheirCells(); + // const auto& node_to_cell_matrix = m_mesh.connectivity().nodeToCellMatrix(); + + // for (size_t i_node = 0; i_node < node_list.size(); ++i_node) { + // const NodeId& node_id = node_list[i_node]; + // // if (m_is_implicit_node[node_id]) { + // const auto& node_cell = node_to_cell_matrix[node_id]; + + // for (size_t cell_i = 0; cell_i < node_cell.size(); ++cell_i) { + // const CellId id_cell_i = node_cell[cell_i]; + // if (m_is_implicit_cell[id_cell_i]) { + // const auto& node_local_number_in_its_cells = + // node_local_numbers_in_their_cells.itemArray(node_id); + + // const size_t node_nb_in_i = node_local_number_in_its_cells[cell_i]; + // const int i_index_p = mapP(id_cell_i); + + // for (size_t cell_j = 0; cell_j < node_cell.size(); ++cell_j) { + // const CellId id_cell_j = node_cell[cell_j]; + // if (m_is_implicit_cell[id_cell_j]) { + // const size_t node_nb_in_j = node_local_number_in_its_cells[cell_j]; + // const int j_index_p = mapP(id_cell_j); + + // Hess_J(i_index_p, j_index_p) += + // dot(Cjr(id_cell_i, node_nb_in_i), m_inv_Ar[node_id] * Cjr(id_cell_j, node_nb_in_j)); + // } + // } + // } + // } + // for (size_t cell_i = 0; cell_i < node_cell.size(); ++cell_i) { + // const CellId id_cell_i = node_cell[cell_i]; + // if (m_is_implicit_cell[id_cell_i]) { + // const auto& node_local_number_in_its_cells = + // node_local_numbers_in_their_cells.itemArray(node_id); + + // const size_t node_nb_in_i = node_local_number_in_its_cells[cell_i]; + // for (size_t i_dimension = 0; i_dimension < Dimension; ++i_dimension) { + // const int i_index_u = mapU(i_dimension, id_cell_i); + + // Hess_J(i_index_u, i_index_u) += m_Ajr(id_cell_i, node_nb_in_i)(i_dimension, i_dimension); + + // for (size_t cell_j = 0; cell_j < node_cell.size(); ++cell_j) { + // const CellId id_cell_j = node_cell[cell_j]; + // if (m_is_implicit_cell[id_cell_j]) { + // const size_t node_nb_in_j = node_local_number_in_its_cells[cell_j]; + // for (size_t j_dimension = 0; j_dimension < Dimension; ++j_dimension) { + // const int j_index_u = mapU(j_dimension, id_cell_j); + + // Hess_J(i_index_u, j_index_u) += -(m_Ajr(id_cell_i, node_nb_in_i) * m_inv_Ar[node_id] * + // m_Ajr(id_cell_j, node_nb_in_j))(i_dimension, + // j_dimension); + // } + // } + // } + // } + // } + // } + // } + } else { throw UnexpectedError("boundary condition not handled 4"); } }, @@ -1312,10 +1262,6 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final CRSMatrixDescriptor<double> Hess_J = this->_getHessianJ(dt, pi, Uk); - // std::cout << "hessJ" << Hess_J_crs << '\n'; - // std::exit(0); - // CRSMatrix A_crs{A.getCRSMatrix()}; - CRSMatrix Hess_J_crs = Hess_J.getCRSMatrix(); CRSMatrix gradient_f = Hess_J_crs - A; @@ -1406,8 +1352,7 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final _computeGradJU_AU(const DiscreteVectorFunction& u, const DiscreteScalarFunction& p, const DiscreteScalarFunction& pi, - const double& dt, - const NodeValuePerCell<const Rd>& Cjr_half) + const double& dt) { // const auto node_to_cell_matrix = m_mesh.connectivity().nodeToCellMatrix(); const auto cell_to_node_matrix = m_mesh.connectivity().cellToNodeMatrix(); @@ -1429,12 +1374,6 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final return implicit_cell_index; }(); - // std::cout << "cellules implicites=true" << '\n'; - // std::cout << std::boolalpha << m_is_implicit_cell << '\n'; - // std::cout << "renumerotation cellules implicites" << '\n'; - // std::cout << m_implicit_cell_index << '\n'; - // std::cout << "nb implicit cells" << m_number_of_implicit_cells << '\n'; - m_is_implicit_node = [&] { NodeValue<bool> is_implicit_node(m_mesh.connectivity()); is_implicit_node.fill(false); @@ -1468,25 +1407,13 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final return implicit_node_index; }(); - // std::cout << "noeuds implicites=true" << '\n'; - // std::cout << std::boolalpha << m_is_implicit_node << '\n'; - // std::cout << "renumerotation noeuds implicites" << '\n'; - // std::cout << m_implicit_node_index << '\n'; - - // std::cout << "inv_Ar" << '\n'; - // std::cout << m_inv_Ar << '\n'; - - // const CRSMatrixDescriptor<double>& A = this->_getA(Cjr_half); + std::cout << "building A: "; + const CRSMatrix A = this->_getA().getCRSMatrix(); + std::cout << "done\n"; - const CRSMatrix A = this->_getA(Cjr_half).getCRSMatrix(); - - // std::cout << "A" << A << '\n'; - // std::exit(0); Vector<double> Un = this->_getU(p, u); Vector<double> Uk = copy(Un); - // std::cout << "Un:" << Un << '\n'; - int nb_iter = 0; double norm_inf_sol; @@ -1500,25 +1427,44 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final double norm_inf_Un = max(abs_Un); if (m_number_of_implicit_cells > 0) { do { - // std::cout << "iteration=" << nb_iter << '\n'; nb_iter++; - std::cout << "nb_iter = " << nb_iter << '\n'; Vector<double> f = this->_getF(A, Un, Uk, p, pi, u, dt); - // std::exit(0); + + std::cout << "building gradf: "; CRSMatrix<double> gradient_f = this->_getGradientF(A, Uk, pi, dt); + std::cout << " done\n"; + + // std::cout << "grad f = " << gradient_f << '\n'; + // std::cout << "f=" << f << '\n'; + std::cout << " -> f: [" << min(f) << ", " << max(f) << "]\n"; + // std::cout << "grad f=" << gradient_f << '\n'; + + auto l2Norm = [](const Vector<double>& x) { + double sum2 = 0; + for (size_t i = 0; i < x.size(); ++i) { + sum2 += x[i] * x[i]; + } + return std::sqrt(sum2); + }; - Vector<double> sol = copy(Uk); + Vector<double> sol{Uk.size()}; + sol.fill(0); static bool solver_is_init = false; if (not solver_is_init) { solver_t.stop(); solver_is_init = true; } + solver_t.start(); LinearSolver solver; solver.solveLocalSystem(gradient_f, sol, f); solver_t.pause(); + std::cout << " -> sol: [" << min(sol) << ", " << max(sol) << "]\n"; + std::cout << "l2Norm(f) = " << l2Norm(f) << '\n'; + std::cout << "l2Norm(sol) = " << l2Norm(sol) << '\n'; + std::cout << rang::style::bold << "norm resid = " << l2Norm(f - gradient_f * sol) << rang::style::reset << '\n'; // std::exit(0); Vector<double> U_next = Uk - sol; @@ -1533,28 +1479,32 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final Uk = U_next; - std::cout << "ratio Newton = " << norm_inf_sol / norm_inf_Un << "\n"; + std::cout << "nb_iter= " << nb_iter << " | ratio Newton = " << norm_inf_sol / norm_inf_Un << "\n"; // when it is a hard case we relax newton - // bool neg_pressure = false; - // for (CellId j = 0; j < m_number_of_implicit_cells; ++j) { - // size_t k = mapP(j); - // if (-U_next[k] + pi[j] < 0) { - // U_next[k] = Uk[k]; - // // std::cout << "p est negatif pour la maille " << j << " -Uk[k] + pi[j]=" << -U_next[k] + pi[j] << - // '\n'; neg_pressure = true; - // } - // } - + size_t neg_pressure_count = 0; + double min_pressure = 0; + for (CellId j = 0; j < m_number_of_implicit_cells; ++j) { + size_t k = mapP(j); + if (-U_next[k] + pi[j] < 0) { + ++neg_pressure_count; + min_pressure = std::min(min_pressure, -U_next[k] + pi[j]); + U_next[k] = Uk[k] + sol[k]; + } + } + if (neg_pressure_count > 0) { + std::cout << rang::fgB::magenta << "p est negatif sur " << neg_pressure_count + << " mailles min=" << min_pressure << rang::fg::reset << '\n'; + } // Uk -= sol; // if (neg_pressure) { // std::cout << "HAS NEG PRESSURE, RELAXING\n"; - // Uk -= 0.01 * sol; - // // } else { - // // Uk = U_next; + // Uk -= 0.01 * sol; + // } else { + // Uk -= sol; // } - } while ((norm_inf_sol > 1e-6 * norm_inf_Un) and (nb_iter < 200)); + } while ((norm_inf_sol > 1e-15 * norm_inf_Un) and (nb_iter < 200)); } m_predicted_u = [&] { CellValue<Rd> predicted_u = copy(u.cellValues()); @@ -1629,6 +1579,34 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final }(); } + ImplicitAcousticSolver(const SolverType solver_type, + const std::shared_ptr<const MeshType>& p_mesh, + const DiscreteScalarFunction&, + const DiscreteScalarFunction&, + const DiscreteVectorFunction&, + const DiscreteScalarFunction&, + const DiscreteScalarFunction&, + const DiscreteScalarFunction&, + const DiscreteScalarFunction&, + const DiscreteScalarFunction&, + const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>& bc_descriptor_list, + const DiscreteScalarFunction& chi_explicit, + const double&) + : m_solver_type{solver_type}, + m_boundary_condition_list{this->_getBCList(p_mesh, bc_descriptor_list)}, + m_mesh{*p_mesh} + { + m_is_implicit_cell = [&] { + CellValue<bool> is_implicit_cell(m_mesh.connectivity()); + + parallel_for( + m_mesh.numberOfCells(), + PUGS_LAMBDA(const CellId cell_id) { is_implicit_cell[cell_id] = (chi_explicit[cell_id] == 0); }); + + return is_implicit_cell; + }(); + } + public: std::tuple<std::shared_ptr<const IMesh>, std::shared_ptr<const DiscreteFunctionVariant>, @@ -1653,7 +1631,7 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final MeshDataType& mesh_data = MeshDataManager::instance().getMeshData(*mesh); const NodeValuePerCell<const Rd> Cjr_n = mesh_data.Cjr(); - NodeValuePerCell<Rd> Cjr_half = copy(Cjr_n); + m_Djr = copy(Cjr_n); CellValue<double> new_rho = copy(rho.cellValues()); CellValue<Rd> new_u = copy(u.cellValues()); @@ -1679,18 +1657,8 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final m_Ajr = this->_computeAjr(rho, c); - // for (CellId cell_id = 0; cell_id < m_mesh.numberOfCells(); ++cell_id) { - // const size_t& nb_nodes = m_Ajr.numberOfSubValues(cell_id); - // for (size_t r = 0; r < nb_nodes; ++r) { - // std::cout << "Ajr(" << cell_id << "," << r << ")=" << m_Ajr(cell_id, r) << '\n'; - // } - // } - NodeValue<const Rdxd> Ar = this->_computeAr(m_Ajr); - // std::cout << "Ar=" << '\n'; - // std::cout << Ar << '\n'; - m_inv_Ar = this->_computeInvAr(Ar); m_inv_gamma = [&]() { @@ -1719,7 +1687,7 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final new_u = copy(u.cellValues()); new_E = copy(E.cellValues()); - _computeGradJU_AU(u, p, pi, dt, Cjr_half); + _computeGradJU_AU(u, p, pi, dt); // u_j+1/2 NodeValue<const Rd> ur = [&]() { @@ -1737,7 +1705,7 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final 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]; - br += m_Ajr(J, R) * m_predicted_u[J] + m_predicted_p[J] * Cjr_n(J, R); + br += m_Ajr(J, R) * m_predicted_u[J] + m_predicted_p[J] * m_Djr(J, R); } b[r] = br; @@ -1848,7 +1816,7 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final for (size_t r = 0; r < cell_nodes.size(); ++r) { computed_Fjr(j, r) = - m_Ajr(j, r) * (m_predicted_u[j] - ur[cell_nodes[r]]) + (m_predicted_p[j] * Cjr_n(j, r)); + m_Ajr(j, r) * (m_predicted_u[j] - ur[cell_nodes[r]]) + (m_predicted_p[j] * m_Djr(j, r)); } }); @@ -1889,24 +1857,25 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final new_u[j] -= dt_over_Mj * momentum_fluxes; new_E[j] -= dt_over_Mj * energy_fluxes; }); - // std::cout << "newton converge, mise a jour" << '\n'; - // std::cout << "rho=" << new_rho << '\n'; - // std::cout << MeshDataManager::instance().getMeshData(*mesh).xj() << '\n'; - // std::cout << nouveau_Vj << '\n'; - - CellValue<const double> new_Vj = MeshDataManager::instance().getMeshData(*new_mesh).Vj(); - // std::cout << "volume mis a jour" << '\n'; - // update Cjr_half + // update Djr const NodeValuePerCell<const Rd> new_Cjr = MeshDataManager::instance().getMeshData(*new_mesh).Cjr(); + CellValue<double> new_Vj{m_mesh.connectivity()}; parallel_for( - mesh->numberOfCells(), PUGS_LAMBDA(CellId j) { new_rho[j] *= Vj[j] / new_Vj[j]; }); + mesh->numberOfCells(), PUGS_LAMBDA(CellId j) { + new_Vj[j] = 0; + auto cell_nodes = cell_to_node_matrix[j]; - for (CellId j = 0; j < mesh->numberOfCells(); ++j) { - // std::cout << "rho(" << j << ")=" << rho[j] << '\n'; - // std::cout << "new_rho(" << j << ")=" << new_rho[j] << '\n'; - } + for (size_t i_node = 0; i_node < cell_nodes.size(); ++i_node) { + const NodeId node_id = cell_nodes[i_node]; + new_Vj[j] += dot(new_Cjr[j][i_node], new_xr[node_id]); + } + new_Vj[j] *= 1. / Dimension; + }); + + parallel_for( + mesh->numberOfCells(), PUGS_LAMBDA(CellId j) { new_rho[j] *= Vj[j] / new_Vj[j]; }); CellValue<double> new_tau(m_mesh.connectivity()); @@ -1915,7 +1884,7 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final const auto& cell_nodes = cell_to_node_matrix[j]; for (size_t R = 0; R < cell_nodes.size(); ++R) { const NodeId r = cell_nodes[R]; - new_tau_fluxes += dot(Cjr_half(j, R), ur[r]); + new_tau_fluxes += dot(m_Djr(j, R), ur[r]); } new_tau[j] = m_tau[j] + (dt / m_Mj[j]) * new_tau_fluxes; // std::cout << "new_tau(" << j << ")=" << new_tau[j] << '\n'; @@ -1928,33 +1897,131 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final // const auto& cell_nodes = cell_to_node_matrix[j]; // V_j^n+1/tau_j^n+1 - M_j // sum_tau_rho += std::abs(new_tau[j] - 1. / new_rho[j]); - max_tau_error = std::max(max_tau_error, std::abs(new_tau[j] - 1. / new_rho[j])); + max_tau_error = std::max(max_tau_error, std::abs(1 - new_tau[j] * new_rho[j])); } // std::cout << "sum_tau_rho =" << sum_tau_rho << '\n'; - std::cout << "max_tau_error=" << max_tau_error << '\n'; + // std::cout << "max_tau_error=" << max_tau_error << '\n'; - for (CellId j = 0; j < mesh->numberOfCells(); ++j) { - const auto& cell_nodes = cell_to_node_matrix[j]; - for (size_t R = 0; R < cell_nodes.size(); ++R) { - const NodeId r = cell_nodes[R]; - Cjr_half(j, R) = 0.5 * (Cjr_n(j, R) + new_Cjr(j, R)); - // Cjr_half(j, R) = Cjr_n(j, R); - // std::cout << "Cjr_n(" << j << "," << R << ")=" << Cjr_n(j, R) << '\n'; - // std::cout << "Cjr_new(" << j << "," << R << ")=" << new_Cjr(j, R) << '\n'; - // std::cout << "Cjr_half(" << j << "," << R << ")=" << Cjr_half(j, R) << '\n'; - } + if constexpr (Dimension == 2) { + NodeValuePerCell<Rd> Djr{m_mesh.connectivity()}; + + parallel_for( + mesh->numberOfCells(), PUGS_LAMBDA(CellId cell_id) { + const auto& cell_nodes = cell_to_node_matrix[cell_id]; + if (m_is_implicit_cell[cell_id]) { + for (size_t i_node = 0; i_node < cell_nodes.size(); ++i_node) { + Djr(cell_id, i_node) = 0.5 * (Cjr_n(cell_id, i_node) + new_Cjr(cell_id, i_node)); + } + } else { + for (size_t i_node = 0; i_node < cell_nodes.size(); ++i_node) { + Djr(cell_id, i_node) = Cjr_n(cell_id, i_node); + } + } + }); + + m_Djr = Djr; + } else if constexpr (Dimension == 3) { + NodeValuePerFace<Rd> Nlr_delta(m_mesh.connectivity()); + const auto& face_to_node_matrix = m_mesh.connectivity().faceToNodeMatrix(); + + const auto& xr_n = m_mesh.xr(); + const auto& xr_np1 = new_xr; + + parallel_for( + m_mesh.numberOfFaces(), PUGS_LAMBDA(FaceId l) { + const auto& face_nodes = face_to_node_matrix[l]; + const size_t nb_nodes = face_nodes.size(); + std::vector<Rd> dxr_n(nb_nodes); + std::vector<Rd> dxr_np1(nb_nodes); + for (size_t r = 0; r < nb_nodes; ++r) { + dxr_n[r] = xr_n[face_nodes[(r + 1) % nb_nodes]] - xr_n[face_nodes[(r + nb_nodes - 1) % nb_nodes]]; + dxr_np1[r] = xr_np1[face_nodes[(r + 1) % nb_nodes]] - xr_np1[face_nodes[(r + nb_nodes - 1) % nb_nodes]]; + } + const double inv_12_nb_nodes = 1. / (12. * nb_nodes); + for (size_t r = 0; r < nb_nodes; ++r) { + Rd Nr = zero; + for (size_t s = 0; s < nb_nodes; ++s) { + const Rd two_dxs = 2 * dxr_n[s]; + Nr += + crossProduct(2 * ((dxr_np1[r] - 2 * dxr_np1[s]) - (dxr_n[r] - 2 * dxr_n[s])), xr_n[face_nodes[s]]); + Nr -= crossProduct((1. / 6) * ((2 * dxr_n[r] - dxr_n[s]) - (2 * dxr_n[r] - dxr_n[s])), + xr_np1[face_nodes[s]] - xr_n[face_nodes[s]]); + } + Nr *= inv_12_nb_nodes; + Nlr_delta(l, r) = Nr; + } + }); + + const auto& cell_to_node_matrix = m_mesh.connectivity().cellToNodeMatrix(); + const auto& cell_to_face_matrix = m_mesh.connectivity().cellToFaceMatrix(); + const auto& cell_face_is_reversed = m_mesh.connectivity().cellFaceIsReversed(); + + NodeValuePerCell<Rd> Djr{m_mesh.connectivity()}; + Djr.fill(zero); + + parallel_for( + m_mesh.numberOfCells(), PUGS_LAMBDA(CellId j) { + const auto& cell_nodes = cell_to_node_matrix[j]; + + const auto& cell_faces = cell_to_face_matrix[j]; + const auto& face_is_reversed = cell_face_is_reversed.itemArray(j); + + for (size_t L = 0; L < cell_faces.size(); ++L) { + const FaceId& l = cell_faces[L]; + const auto& face_nodes = face_to_node_matrix[l]; + + auto local_node_number_in_cell = [&](NodeId node_number) { + for (size_t i_node = 0; i_node < cell_nodes.size(); ++i_node) { + if (node_number == cell_nodes[i_node]) { + return i_node; + } + } + return std::numeric_limits<size_t>::max(); + }; + + if (face_is_reversed[L]) { + for (size_t rl = 0; rl < face_nodes.size(); ++rl) { + const size_t R = local_node_number_in_cell(face_nodes[rl]); + Djr(j, R) -= Nlr_delta(l, rl); + } + } else { + for (size_t rl = 0; rl < face_nodes.size(); ++rl) { + const size_t R = local_node_number_in_cell(face_nodes[rl]); + Djr(j, R) += Nlr_delta(l, rl); + } + } + } + }); + + parallel_for( + Djr.numberOfValues(), PUGS_LAMBDA(const size_t i) { Djr[i] += 0.5 * (Cjr_n[i] + new_Cjr[i]); }); + + parallel_for( + m_mesh.numberOfCells(), PUGS_LAMBDA(const CellId cell_id) { + if (not m_is_implicit_cell[cell_id]) { + const auto& cell_nodes = cell_to_node_matrix[cell_id]; + for (size_t i_node = 0; i_node < cell_nodes.size(); ++i_node) { + Djr(cell_id, i_node) = Cjr_n(cell_id, i_node); + } + } + }); + + m_Djr = Djr; + } + + if constexpr (Dimension > 1) { + std::cout << "number_iter_Djr=" << number_iter << " max_tau_error=" << max_tau_error << '\n'; } - std::cout << "number_iter_Cjr=" << number_iter << '\n'; // std::cout << "new rho=" << new_rho << '\n'; - } while ((max_tau_error > 1e-13) and (number_iter < 2)); + } while ((Dimension > 1) and (max_tau_error > 1e-4) and (number_iter < 100)); // std::cout << "prochaine boucle" << '\n'; implicit_t.pause(); - std::cout << "getA=" << get_A_t << "(" << count_getA << ")" - << " getF=" << getF_t << "(" << count_getF << ")" - << " getGradF=" << getGradF_t << "(" << count_getGradF << ")" - << " HJ_A=" << HJ_A_t << '\n'; - std::cout << "solver=" << solver_t << " total= " << implicit_t << '\n'; + // std::cout << "getA=" << get_A_t << "(" << count_getA << ")" + // << " getF=" << getF_t << "(" << count_getF << ")" + // << " getGradF=" << getGradF_t << "(" << count_getGradF << ")" + // << " HJ_A=" << HJ_A_t << '\n'; + // std::cout << "solver=" << solver_t << " total= " << implicit_t << '\n'; return {new_mesh, std::make_shared<DiscreteFunctionVariant>(DiscreteScalarFunction{new_mesh, new_rho}), std::make_shared<DiscreteFunctionVariant>(DiscreteVectorFunction{new_mesh, new_u}), @@ -2020,6 +2087,34 @@ class ImplicitAcousticSolverHandler::ImplicitAcousticSolver final dt) {} + ImplicitAcousticSolver(const SolverType solver_type, + const std::shared_ptr<const IMesh>& mesh, + const std::shared_ptr<const DiscreteFunctionVariant>& rho, + const std::shared_ptr<const DiscreteFunctionVariant>& c, + const std::shared_ptr<const DiscreteFunctionVariant>& u, + const std::shared_ptr<const DiscreteFunctionVariant>& p, + const std::shared_ptr<const DiscreteFunctionVariant>& pi, + const std::shared_ptr<const DiscreteFunctionVariant>& gamma, + const std::shared_ptr<const DiscreteFunctionVariant>& Cv, + const std::shared_ptr<const DiscreteFunctionVariant>& entropy, + const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>& bc_descriptor_list, + const std::shared_ptr<const DiscreteFunctionVariant>& chi_explicit, + const double& dt) + : ImplicitAcousticSolver(solver_type, + std::dynamic_pointer_cast<const Mesh<Connectivity<Dimension>>>(mesh), + rho->get<DiscreteScalarFunction>(), + c->get<DiscreteScalarFunction>(), + u->get<DiscreteFunctionP0<Dimension, const Rd>>(), + p->get<DiscreteScalarFunction>(), + pi->get<DiscreteScalarFunction>(), + gamma->get<DiscreteScalarFunction>(), + Cv->get<DiscreteScalarFunction>(), + entropy->get<DiscreteScalarFunction>(), + bc_descriptor_list, + chi_explicit->get<DiscreteScalarFunction>(), + dt) + {} + ImplicitAcousticSolver() = default; ImplicitAcousticSolver(ImplicitAcousticSolver&&) = default; ~ImplicitAcousticSolver() = default; @@ -2190,3 +2285,51 @@ ImplicitAcousticSolverHandler::ImplicitAcousticSolverHandler( } } } + +ImplicitAcousticSolverHandler::ImplicitAcousticSolverHandler( + const SolverType solver_type, + const std::shared_ptr<const DiscreteFunctionVariant>& rho, + const std::shared_ptr<const DiscreteFunctionVariant>& c, + const std::shared_ptr<const DiscreteFunctionVariant>& u, + const std::shared_ptr<const DiscreteFunctionVariant>& p, + const std::shared_ptr<const DiscreteFunctionVariant>& pi, + const std::shared_ptr<const DiscreteFunctionVariant>& gamma, + const std::shared_ptr<const DiscreteFunctionVariant>& Cv, + const std::shared_ptr<const DiscreteFunctionVariant>& entropy, + const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>& bc_descriptor_list, + const std::shared_ptr<const DiscreteFunctionVariant>& chi_explicit, + const double& dt) +{ + std::shared_ptr i_mesh = getCommonMesh({rho, c, u, p, pi, gamma, Cv, chi_explicit}); + if (not i_mesh) { + throw NormalError("discrete functions are not defined on the same mesh"); + } + + if (not checkDiscretizationType({rho, c, u, p}, DiscreteFunctionType::P0)) { + throw NormalError("acoustic solver expects P0 functions"); + } + + switch (i_mesh->dimension()) { + case 1: { + m_implicit_acoustic_solver = + std::make_unique<ImplicitAcousticSolver<1>>(solver_type, i_mesh, rho, c, u, p, pi, gamma, Cv, entropy, + bc_descriptor_list, chi_explicit, dt); + break; + } + case 2: { + m_implicit_acoustic_solver = + std::make_unique<ImplicitAcousticSolver<2>>(solver_type, i_mesh, rho, c, u, p, pi, gamma, Cv, entropy, + bc_descriptor_list, chi_explicit, dt); + break; + } + case 3: { + m_implicit_acoustic_solver = + std::make_unique<ImplicitAcousticSolver<3>>(solver_type, i_mesh, rho, c, u, p, pi, gamma, Cv, entropy, + bc_descriptor_list, chi_explicit, dt); + break; + } + default: { + throw UnexpectedError("invalid mesh dimension"); + } + } +} diff --git a/src/scheme/ImplicitAcousticSolver.hpp b/src/scheme/ImplicitAcousticSolver.hpp index 2ad0e9f3a66f5f172ff78f808356ea8da69b5f18..c3c7eb4feccf9cedc1ede2fc239ae1ea6805dfdf 100644 --- a/src/scheme/ImplicitAcousticSolver.hpp +++ b/src/scheme/ImplicitAcousticSolver.hpp @@ -90,6 +90,20 @@ class ImplicitAcousticSolverHandler const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>& bc_descriptor_list, const std::vector<std::shared_ptr<const IZoneDescriptor>>& explicit_zone_list, const double& dt); + + ImplicitAcousticSolverHandler( + const SolverType solver_type, + const std::shared_ptr<const DiscreteFunctionVariant>& rho, + const std::shared_ptr<const DiscreteFunctionVariant>& c, + const std::shared_ptr<const DiscreteFunctionVariant>& u, + const std::shared_ptr<const DiscreteFunctionVariant>& p, + const std::shared_ptr<const DiscreteFunctionVariant>& pi, + const std::shared_ptr<const DiscreteFunctionVariant>& gamma, + const std::shared_ptr<const DiscreteFunctionVariant>& Cv, + const std::shared_ptr<const DiscreteFunctionVariant>& entropy, + const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>& bc_descriptor_list, + const std::shared_ptr<const DiscreteFunctionVariant>& chi_explicit, + const double& dt); }; #endif // IMPLICIT_ACOUSTIC_SOLVER_HPP