diff --git a/src/language/algorithms/HeatDiamondAlgorithm.cpp b/src/language/algorithms/HeatDiamondAlgorithm.cpp index 6a6ff407608598fb0be6cb2dad283235cfa0d92e..3a2424705a4bb35dbac11dced0005bf8d2cf4056 100644 --- a/src/language/algorithms/HeatDiamondAlgorithm.cpp +++ b/src/language/algorithms/HeatDiamondAlgorithm.cpp @@ -1,5 +1,6 @@ #include <language/algorithms/HeatDiamondAlgorithm.hpp> +#include <algebra/BiCGStab.hpp> #include <algebra/CRSMatrix.hpp> #include <algebra/LocalRectangularMatrix.hpp> #include <algebra/PCG.hpp> @@ -22,7 +23,8 @@ HeatDiamondScheme<Dimension>::HeatDiamondScheme( const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>& bc_descriptor_list, const FunctionSymbolId& T_id, const FunctionSymbolId& kappa_id, - const FunctionSymbolId& f_id) + const FunctionSymbolId& f_id, + const FunctionSymbolId& g_id) { using ConnectivityType = Connectivity<Dimension>; using MeshType = Mesh<ConnectivityType>; @@ -271,9 +273,9 @@ HeatDiamondScheme<Dimension>::HeatDiamondScheme( S(i_id, j_id) += weight_rj * alpha_face_id * (nil, Clr); } } - } else { - std::cout << "*** ignore node " << face_node_id << '\n'; - } + } // else { + // std::cout << "*** ignore node " << face_node_id << '\n'; + // } } } } @@ -283,15 +285,60 @@ HeatDiamondScheme<Dimension>::HeatDiamondScheme( CellValue<double> fj = InterpolateItemValue<double(TinyVector<Dimension>)>::template interpolate<ItemType::cell>(f_id, mesh_data.xj()); + NodeValue<double> gr = + InterpolateItemValue<double(TinyVector<Dimension>)>::template interpolate<ItemType::node>(g_id, m_mesh->xr()); + const CellValue<const double> primal_Vj = mesh_data.Vj(); CRSMatrix A{S}; Vector<double> b{m_mesh->numberOfCells()}; - parallel_for( - m_mesh->numberOfCells(), PUGS_LAMBDA(CellId cell_id) { b[cell_id] = fj[cell_id] * primal_Vj[cell_id]; }); + // parallel_for( + // m_mesh->numberOfCells(), PUGS_LAMBDA(CellId cell_id) { b[cell_id] = fj[cell_id] * primal_Vj[cell_id]; }); + + const auto& primal_cell_to_face_matrix = m_mesh->connectivity().cellToFaceMatrix(); + for (CellId cell_id = 0; cell_id < m_mesh->numberOfCells(); ++cell_id) { + b[cell_id] = fj[cell_id] * primal_Vj[cell_id]; + const auto& primal_cell_to_face = primal_cell_to_face_matrix[cell_id]; + + for (size_t face_id = 0; face_id < primal_cell_to_face.size(); ++face_id) { // Num local + FaceId i_cell_face = primal_cell_to_face_matrix[cell_id][face_id]; // Num global + + const bool is_face_reversed_for_cell_i = [=] { + for (size_t i_face = 0; i_face < primal_cell_to_face.size(); ++i_face) { // Num local + FaceId primal_face_id = primal_cell_to_face[i_face]; // Num global + if (primal_face_id == i_cell_face) { + return primal_face_cell_is_reversed(cell_id, i_face); + } + } + }(); + const auto& primal_face_to_node = primal_face_to_node_matrix[i_cell_face]; + for (size_t i_node = 0; i_node < primal_face_to_node.size(); ++i_node) { // Num local + const TinyVector<Dimension> nil = [=] { + if (is_face_reversed_for_cell_i) { + return -primal_nlr(i_cell_face, i_node); + } else { + return primal_nlr(i_cell_face, i_node); + } + }(); + + CellId dual_cell_id = face_dual_cell_id[i_cell_face]; // Num global dual de la face + + NodeId face_node_id = primal_face_to_node[i_node]; // Num global + if (primal_node_is_on_boundary[face_node_id]) { + for (size_t i_dual_node = 0; i_dual_node < dual_Cjr.numberOfSubValues(dual_cell_id); ++i_dual_node) { + const NodeId dual_node_id = dual_cell_to_node_matrix[dual_cell_id][i_dual_node]; + if (dual_node_id == face_node_id) { + const TinyVector<Dimension> Clr = dual_Cjr(dual_cell_id, i_dual_node); + b[cell_id] -= alpha_l[i_cell_face] * gr[face_node_id] * (nil, Clr); + } + } + } + } + } + } Vector<double> T{m_mesh->numberOfCells()}; T = 0; - PCG{b, A, A, T, 100, 1e-12}; + BiCGStab{b, A, T, 1000, 1e-12}; CellValue<double> Temperature{m_mesh->connectivity()}; @@ -322,6 +369,7 @@ template HeatDiamondScheme<1>::HeatDiamondScheme( const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>&, const FunctionSymbolId&, const FunctionSymbolId&, + const FunctionSymbolId&, const FunctionSymbolId&); template HeatDiamondScheme<2>::HeatDiamondScheme( @@ -329,6 +377,7 @@ template HeatDiamondScheme<2>::HeatDiamondScheme( const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>&, const FunctionSymbolId&, const FunctionSymbolId&, + const FunctionSymbolId&, const FunctionSymbolId&); template HeatDiamondScheme<3>::HeatDiamondScheme( @@ -336,4 +385,5 @@ template HeatDiamondScheme<3>::HeatDiamondScheme( const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>&, const FunctionSymbolId&, const FunctionSymbolId&, + const FunctionSymbolId&, const FunctionSymbolId&); diff --git a/src/language/algorithms/HeatDiamondAlgorithm.hpp b/src/language/algorithms/HeatDiamondAlgorithm.hpp index b1753895140fb2d655a530973bd22f934a187c42..fc8885d618f4aa5071ab74e640cad689e9314d71 100644 --- a/src/language/algorithms/HeatDiamondAlgorithm.hpp +++ b/src/language/algorithms/HeatDiamondAlgorithm.hpp @@ -15,7 +15,8 @@ struct HeatDiamondScheme const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>& bc_descriptor_list, const FunctionSymbolId& T_id, const FunctionSymbolId& kappa_id, - const FunctionSymbolId& f_id); + const FunctionSymbolId& f_id, + const FunctionSymbolId& g_id); }; #endif // HEAT_DIAMOND_ALGORITHM_HPP diff --git a/src/language/modules/SchemeModule.cpp b/src/language/modules/SchemeModule.cpp index 64c8fa03b4bd395b3a6d3f985467f506afef0093..cd5d2e42a21e6728d19ca02505d0f23c501d6541 100644 --- a/src/language/modules/SchemeModule.cpp +++ b/src/language/modules/SchemeModule.cpp @@ -176,24 +176,25 @@ SchemeModule::SchemeModule() this->_addBuiltinFunction("heat", std::make_shared<BuiltinFunctionEmbedder< void(std::shared_ptr<const IMesh>, const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>&, - const FunctionSymbolId&, const FunctionSymbolId&, const FunctionSymbolId&)>>( + const FunctionSymbolId&, const FunctionSymbolId&, const FunctionSymbolId&, + const FunctionSymbolId&)>>( [](std::shared_ptr<const IMesh> p_mesh, const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>& bc_descriptor_list, const FunctionSymbolId& T_id, const FunctionSymbolId& kappa_id, - const FunctionSymbolId& f_id) -> void { + const FunctionSymbolId& f_id, const FunctionSymbolId& g_id) -> void { switch (p_mesh->dimension()) { case 1: { - HeatDiamondScheme<1>{p_mesh, bc_descriptor_list, T_id, kappa_id, f_id}; + HeatDiamondScheme<1>{p_mesh, bc_descriptor_list, T_id, kappa_id, f_id, g_id}; break; } case 2: { - HeatDiamondScheme<2>{p_mesh, bc_descriptor_list, T_id, kappa_id, f_id}; + HeatDiamondScheme<2>{p_mesh, bc_descriptor_list, T_id, kappa_id, f_id, g_id}; break; } case 3: { - HeatDiamondScheme<3>{p_mesh, bc_descriptor_list, T_id, kappa_id, f_id}; + HeatDiamondScheme<3>{p_mesh, bc_descriptor_list, T_id, kappa_id, f_id, g_id}; break; } default: {