diff --git a/src/language/algorithms/CMakeLists.txt b/src/language/algorithms/CMakeLists.txt index 45c9a5c489271b68e718bace2552b2e02ec56793..e8bdb537aeac576b769a107f8d1d751c4d75b957 100644 --- a/src/language/algorithms/CMakeLists.txt +++ b/src/language/algorithms/CMakeLists.txt @@ -3,6 +3,7 @@ add_library(PugsLanguageAlgorithms AcousticSolverAlgorithm.cpp Heat5PointsAlgorithm.cpp + HeatDiamondAlgorithm.cpp ) diff --git a/src/language/algorithms/HeatDiamondAlgorithm.cpp b/src/language/algorithms/HeatDiamondAlgorithm.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4c2e5d69257abfe17e349ca05f1b695c0ea79f1d --- /dev/null +++ b/src/language/algorithms/HeatDiamondAlgorithm.cpp @@ -0,0 +1,251 @@ +#include <language/algorithms/HeatDiamondAlgorithm.hpp> + +#include <algebra/CRSMatrix.hpp> +#include <algebra/LocalRectangularMatrix.hpp> +#include <algebra/PCG.hpp> +#include <algebra/SparseMatrixDescriptor.hpp> +#include <algebra/TinyVector.hpp> +#include <algebra/Vector.hpp> +#include <language/utils/InterpolateItemValue.hpp> +#include <mesh/Connectivity.hpp> +#include <mesh/ConnectivityToDiamondDualConnectivityDataMapper.hpp> +#include <mesh/DiamondDualConnectivityManager.hpp> +#include <mesh/DiamondDualMeshManager.hpp> +#include <mesh/Mesh.hpp> +#include <mesh/MeshData.hpp> +#include <mesh/MeshDataManager.hpp> +#include <output/VTKWriter.hpp> + +template <size_t Dimension> +HeatDiamondScheme<Dimension>::HeatDiamondScheme( + std::shared_ptr<const IMesh> i_mesh, + const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>& bc_descriptor_list, + const FunctionSymbolId& T_id, + const FunctionSymbolId& kappa_id) +{ + using ConnectivityType = Connectivity<Dimension>; + using MeshType = Mesh<ConnectivityType>; + using MeshDataType = MeshData<Dimension>; + + std::cout << "number of bc descr = " << bc_descriptor_list.size() << '\n'; + std::shared_ptr m_mesh = std::dynamic_pointer_cast<const MeshType>(i_mesh); + + if constexpr (Dimension > 1) { + MeshDataType& mesh_data = MeshDataManager::instance().getMeshData(*m_mesh); + + CellValue<double> Tj = + InterpolateItemValue<double(TinyVector<Dimension>)>::template interpolate<ItemType::cell>(T_id, mesh_data.xj()); + + NodeValue<double> Tr(m_mesh->connectivity()); + const NodeValue<const TinyVector<Dimension>>& xr = m_mesh->xr(); + const CellValue<const TinyVector<Dimension>>& xj = mesh_data.xj(); + const auto& node_to_cell_matrix = m_mesh->connectivity().nodeToCellMatrix(); + CellValuePerNode<double> w_rj{m_mesh->connectivity()}; + + for (NodeId i_node = 0; i_node < m_mesh->numberOfNodes(); ++i_node) { + Vector<double> b{Dimension + 1}; + b[0] = 1; + for (size_t i = 1; i < Dimension + 1; i++) { + b[i] = xr[i_node][i - 1]; + } + const auto& node_to_cell = node_to_cell_matrix[i_node]; + + LocalRectangularMatrix<double> A{Dimension + 1, node_to_cell.size()}; + for (size_t j = 0; j < node_to_cell.size(); j++) { + A(0, j) = 1; + } + for (size_t i = 1; i < Dimension + 1; i++) { + for (size_t j = 0; j < node_to_cell.size(); j++) { + const CellId J = node_to_cell[j]; + A(i, j) = xj[J][i - 1]; + } + } + Vector<double> x{node_to_cell.size()}; + x = 0; + + LocalRectangularMatrix B = transpose(A) * A; + Vector y = transpose(A) * b; + PCG{y, B, B, x, 10, 1e-12}; + + Tr[i_node] = 0; + for (size_t j = 0; j < node_to_cell.size(); j++) { + Tr[i_node] += x[j] * Tj[node_to_cell[j]]; + w_rj(i_node, j) = x[j]; + } + } + + { + VTKWriter vtk_writer("T_" + std::to_string(Dimension), 0.01); + + vtk_writer.write(m_mesh, + {NamedItemValue{"Tr", Tr}, NamedItemValue{"temperature", Tj}, + NamedItemValue{"coords", m_mesh->xr()}, NamedItemValue{"xj", mesh_data.xj()}, + NamedItemValue{"cell_owner", m_mesh->connectivity().cellOwner()}, + NamedItemValue{"node_owner", m_mesh->connectivity().nodeOwner()}}, + 0, true); // forces last output + } + + { + std::shared_ptr diamond_mesh = DiamondDualMeshManager::instance().getDiamondDualMesh(m_mesh); + + MeshDataType& diamond_mesh_data = MeshDataManager::instance().getMeshData(*diamond_mesh); + + std::shared_ptr mapper = + DiamondDualConnectivityManager::instance().getConnectivityToDiamondDualConnectivityDataMapper( + m_mesh->connectivity()); + + NodeValue<double> Trd{diamond_mesh->connectivity()}; + + mapper->toDualNode(Tr, Tj, Trd); + + CellValue<double> kappaj = + InterpolateItemValue<double(TinyVector<Dimension>)>::template interpolate<ItemType::cell>(kappa_id, + mesh_data.xj()); + + CellValue<double> dual_kappaj = + InterpolateItemValue<double(TinyVector<Dimension>)>::template interpolate<ItemType::cell>(kappa_id, + diamond_mesh_data + .xj()); + + VTKWriter vtk_writer("D_" + std::to_string(Dimension), 0.01); + + vtk_writer.write(diamond_mesh, + {NamedItemValue{"kappaj", dual_kappaj}, NamedItemValue{"coords", diamond_mesh->xr()}, + NamedItemValue{"Vj", diamond_mesh_data.Vj()}, NamedItemValue{"xj", diamond_mesh_data.xj()}}, + 0, true); // forces last output + + const CellValue<const double> dual_Vj = diamond_mesh_data.Vj(); + const auto& face_to_node_matrix = m_mesh->connectivity().faceToNodeMatrix(); + + const FaceValue<const double> mes_l = [=] { + FaceValue<double> compute_mes_l{m_mesh->connectivity()}; + const NodeValue<const TinyVector<Dimension>>& xr = m_mesh->xr(); + if constexpr (Dimension == 1) { + compute_mes_l.fill(1); + } else if constexpr (Dimension == 2) { + parallel_for( + m_mesh->numberOfFaces(), PUGS_LAMBDA(FaceId face_id) { + const auto& face_to_node = face_to_node_matrix[face_id]; + const NodeId node_id1 = face_to_node[0]; + const NodeId node_id2 = face_to_node[1]; + const TinyVector<Dimension, double> r = xr[node_id1] - xr[node_id2]; + compute_mes_l[face_id] = l2Norm(r); + }); + } else { + throw NotImplementedError("Not implemented in 3D"); + } + return compute_mes_l; + }(); + + const CellValue<const double> dual_mes_l_j = [=] { + CellValue<double> compute_mes_j{diamond_mesh->connectivity()}; + mapper->toDualCell(mes_l, compute_mes_j); + + return compute_mes_j; + }(); + + FaceValue<const double> alpha_l = [&] { + CellValue<double> alpha_j{diamond_mesh->connectivity()}; + + parallel_for( + diamond_mesh->numberOfCells(), PUGS_LAMBDA(CellId diamond_cell_id) { + alpha_j[diamond_cell_id] = + dual_mes_l_j[diamond_cell_id] * dual_kappaj[diamond_cell_id] / dual_Vj[diamond_cell_id]; + }); + + FaceValue<double> computed_alpha_l{m_mesh->connectivity()}; + mapper->fromDualCell(alpha_j, computed_alpha_l); + + VTKWriter vtk_writer("DD_" + std::to_string(Dimension), 0.01); + + vtk_writer.write(diamond_mesh, + {NamedItemValue{"alphaj", alpha_j}, NamedItemValue{"xj", diamond_mesh_data.xj()}, + NamedItemValue{"Vl", diamond_mesh_data.Vj()}, NamedItemValue{"|l|", dual_mes_l_j}}, + 0, + true); // forces last output + + return computed_alpha_l; + }(); + + SparseMatrixDescriptor S{m_mesh->numberOfCells()}; + const auto& face_to_cell_matrix = m_mesh->connectivity().faceToCellMatrix(); + for (FaceId face_id = 0; face_id < m_mesh->numberOfFaces(); ++face_id) { + const auto& primal_face_to_cell = face_to_cell_matrix[face_id]; + const double beta_l = 0.5 * alpha_l[face_id] * mes_l[face_id]; + const NodeValuePerCell<const TinyVector<Dimension>>& Cjr = mesh_data.Cjr(); + + // CellValue<double> dual_cell_id{diamond_mesh->connectivity()}; + // mapper->toDualCell(face_id, dual_cell_id); + + for (size_t i_cell = 0; i_cell < primal_face_to_cell.size(); ++i_cell) { + const CellId cell_id1 = primal_face_to_cell[i_cell]; + for (size_t j_cell = 0; j_cell < primal_face_to_cell.size(); ++j_cell) { + const CellId cell_id2 = primal_face_to_cell[j_cell]; + if (i_cell == j_cell) { + S(cell_id1, cell_id2) -= beta_l; + } else { + S(cell_id1, cell_id2) += beta_l; + } + // S(cell_id1, cell_id2)+= alpha_l[face_id]*(,Cjr[dual_cell_id,dual_node_j]); + } + } + } + const CellValue<const double> primal_Vj = mesh_data.Vj(); + CRSMatrix A{S}; + Vector<double> b{m_mesh->numberOfCells()}; + double pi = 3.14159265; + for (CellId i_cell = 0; i_cell < m_mesh->numberOfCells(); ++i_cell) { + if constexpr (Dimension == 2) { + b[i_cell] = + -2 * kappaj[i_cell] * pi * pi * sin(pi * xj[i_cell][0]) * sin(pi * xj[i_cell][1]) * primal_Vj[i_cell]; + + } else if constexpr (Dimension == 3) { + b[i_cell] = -3 * kappaj[i_cell] * pi * pi * sin(pi * xj[i_cell][0]) * sin(pi * xj[i_cell][1]) * + sin(pi * xj[i_cell][2]) * primal_Vj[i_cell]; + } + } + + Vector<double> T{m_mesh->numberOfCells()}; + T = 0; + PCG{b, A, A, T, 100, 1e-12}; + + CellValue<double> Temperature{m_mesh->connectivity()}; + + parallel_for( + m_mesh->numberOfCells(), PUGS_LAMBDA(CellId cell_id) { Temperature[cell_id] = T[cell_id]; }); + + Vector<double> error{m_mesh->numberOfCells()}; + parallel_for( + m_mesh->numberOfCells(), PUGS_LAMBDA(CellId cell_id) { error[cell_id] = Temperature[cell_id] - Tj[cell_id]; }); + + std::cout << "||Error||_2 = " << std::sqrt((error, error)) << "\n"; + + { + VTKWriter vtk_writer("Temperature_" + std::to_string(Dimension), 0.01); + + vtk_writer.write(m_mesh, {NamedItemValue{"T", Temperature}}, 0, + true); // forces last output + } + } + } else { + throw NotImplementedError("not done in 3d"); + } +} + +template HeatDiamondScheme<1>::HeatDiamondScheme( + std::shared_ptr<const IMesh>, + const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>&, + const FunctionSymbolId&, + const FunctionSymbolId&); + +template HeatDiamondScheme<2>::HeatDiamondScheme( + std::shared_ptr<const IMesh>, + const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>&, + const FunctionSymbolId&, + const FunctionSymbolId&); + +template HeatDiamondScheme<3>::HeatDiamondScheme( + std::shared_ptr<const IMesh>, + const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>&, + const FunctionSymbolId&, + const FunctionSymbolId&); diff --git a/src/language/algorithms/HeatDiamondAlgorithm.hpp b/src/language/algorithms/HeatDiamondAlgorithm.hpp new file mode 100644 index 0000000000000000000000000000000000000000..9516b8277c8bacdb3550133ca4a15fcf062309c1 --- /dev/null +++ b/src/language/algorithms/HeatDiamondAlgorithm.hpp @@ -0,0 +1,20 @@ +#ifndef HEAT_DIAMOND_ALGORITHM_HPP +#define HEAT_DIAMOND_ALGORITHM_HPP + +#include <language/utils/FunctionSymbolId.hpp> +#include <mesh/IMesh.hpp> +#include <scheme/IBoundaryConditionDescriptor.hpp> + +#include <memory> +#include <vector> + +template <size_t Dimension> +struct HeatDiamondScheme +{ + HeatDiamondScheme(std::shared_ptr<const IMesh> i_mesh, + const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>& bc_descriptor_list, + const FunctionSymbolId& T_id, + const FunctionSymbolId& kappa_id); +}; + +#endif // HEAT_DIAMOND_ALGORITHM_HPP diff --git a/src/language/modules/SchemeModule.cpp b/src/language/modules/SchemeModule.cpp index 6e7bd22fe6490e180bb275c79c2f976e478d68c1..af11321e2b0111aa2e0bff7b076aaa5b003b3636 100644 --- a/src/language/modules/SchemeModule.cpp +++ b/src/language/modules/SchemeModule.cpp @@ -1,256 +1,20 @@ #include <language/modules/SchemeModule.hpp> -#include <algebra/CRSMatrix.hpp> -#include <algebra/LocalRectangularMatrix.hpp> -#include <algebra/PCG.hpp> -#include <algebra/SparseMatrixDescriptor.hpp> -#include <algebra/TinyVector.hpp> -#include <algebra/Vector.hpp> #include <language/algorithms/AcousticSolverAlgorithm.hpp> #include <language/algorithms/Heat5PointsAlgorithm.hpp> +#include <language/algorithms/HeatDiamondAlgorithm.hpp> #include <language/utils/BuiltinFunctionEmbedder.hpp> -#include <language/utils/PugsFunctionAdapter.hpp> #include <language/utils/TypeDescriptor.hpp> -#include <mesh/ConnectivityToDiamondDualConnectivityDataMapper.hpp> -#include <mesh/DiamondDualConnectivityManager.hpp> -#include <mesh/DiamondDualMeshBuilder.hpp> -#include <mesh/DiamondDualMeshManager.hpp> -#include <mesh/Mesh.hpp> -#include <mesh/MeshData.hpp> -#include <mesh/SubItemValuePerItem.hpp> -#include <output/VTKWriter.hpp> -#include <scheme/AcousticSolver.hpp> +#include <mesh/IMesh.hpp> #include <scheme/IBoundaryConditionDescriptor.hpp> #include <scheme/IBoundaryDescriptor.hpp> #include <scheme/NamedBoundaryDescriptor.hpp> #include <scheme/NumberedBoundaryDescriptor.hpp> - -#include <memory> - +#include <scheme/PressureBoundaryConditionDescriptor.hpp> #include <scheme/SymmetryBoundaryConditionDescriptor.hpp> -/////////// TEMPORARY - -template <size_t Dimension> -struct HeatDiamondScheme -{ - using ConnectivityType = Connectivity<Dimension>; - using MeshType = Mesh<ConnectivityType>; - using MeshDataType = MeshData<Dimension>; - using UnknownsType = FiniteVolumesEulerUnknowns<MeshType>; - - std::shared_ptr<const MeshType> m_mesh; - - HeatDiamondScheme(std::shared_ptr<const IMesh> i_mesh, - const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>& bc_descriptor_list, - const FunctionSymbolId& T_id, - const FunctionSymbolId& kappa_id) - : m_mesh{std::dynamic_pointer_cast<const MeshType>(i_mesh)} - { - std::cout << "number of bc descr = " << bc_descriptor_list.size() << '\n'; - - if constexpr (Dimension > 1) { - MeshDataType& mesh_data = MeshDataManager::instance().getMeshData(*m_mesh); - - CellValue<double> Tj = - InterpolateItemValue<double(TinyVector<Dimension>)>::template interpolate<ItemType::cell>(T_id, mesh_data.xj()); - - NodeValue<double> Tr(m_mesh->connectivity()); - const NodeValue<const TinyVector<Dimension>>& xr = m_mesh->xr(); - const CellValue<const TinyVector<Dimension>>& xj = mesh_data.xj(); - const auto& node_to_cell_matrix = m_mesh->connectivity().nodeToCellMatrix(); - CellValuePerNode<double> w_rj{m_mesh->connectivity()}; - - for (NodeId i_node = 0; i_node < m_mesh->numberOfNodes(); ++i_node) { - Vector<double> b{Dimension + 1}; - b[0] = 1; - for (size_t i = 1; i < Dimension + 1; i++) { - b[i] = xr[i_node][i - 1]; - } - const auto& node_to_cell = node_to_cell_matrix[i_node]; - - LocalRectangularMatrix<double> A{Dimension + 1, node_to_cell.size()}; - for (size_t j = 0; j < node_to_cell.size(); j++) { - A(0, j) = 1; - } - for (size_t i = 1; i < Dimension + 1; i++) { - for (size_t j = 0; j < node_to_cell.size(); j++) { - const CellId J = node_to_cell[j]; - A(i, j) = xj[J][i - 1]; - } - } - Vector<double> x{node_to_cell.size()}; - x = 0; - - LocalRectangularMatrix B = transpose(A) * A; - Vector y = transpose(A) * b; - PCG{y, B, B, x, 10, 1e-12}; - - Tr[i_node] = 0; - for (size_t j = 0; j < node_to_cell.size(); j++) { - Tr[i_node] += x[j] * Tj[node_to_cell[j]]; - w_rj(i_node, j) = x[j]; - } - } - - { - VTKWriter vtk_writer("T_" + std::to_string(Dimension), 0.01); - - vtk_writer.write(m_mesh, - {NamedItemValue{"Tr", Tr}, NamedItemValue{"temperature", Tj}, - NamedItemValue{"coords", m_mesh->xr()}, NamedItemValue{"xj", mesh_data.xj()}, - NamedItemValue{"cell_owner", m_mesh->connectivity().cellOwner()}, - NamedItemValue{"node_owner", m_mesh->connectivity().nodeOwner()}}, - 0, true); // forces last output - } - - { - std::shared_ptr diamond_mesh = DiamondDualMeshManager::instance().getDiamondDualMesh(m_mesh); - - MeshDataType& diamond_mesh_data = MeshDataManager::instance().getMeshData(*diamond_mesh); - - std::shared_ptr mapper = - DiamondDualConnectivityManager::instance().getConnectivityToDiamondDualConnectivityDataMapper( - m_mesh->connectivity()); - - NodeValue<double> Trd{diamond_mesh->connectivity()}; - - mapper->toDualNode(Tr, Tj, Trd); - - CellValue<double> kappaj = - InterpolateItemValue<double(TinyVector<Dimension>)>::template interpolate<ItemType::cell>(kappa_id, - mesh_data.xj()); - - CellValue<double> dual_kappaj = - InterpolateItemValue<double(TinyVector<Dimension>)>::template interpolate<ItemType::cell>(kappa_id, - diamond_mesh_data - .xj()); +#include <scheme/VelocityBoundaryConditionDescriptor.hpp> - VTKWriter vtk_writer("D_" + std::to_string(Dimension), 0.01); - - vtk_writer.write(diamond_mesh, - {NamedItemValue{"kappaj", dual_kappaj}, NamedItemValue{"coords", diamond_mesh->xr()}, - NamedItemValue{"Vj", diamond_mesh_data.Vj()}, NamedItemValue{"xj", diamond_mesh_data.xj()}}, - 0, true); // forces last output - - const CellValue<const double> dual_Vj = diamond_mesh_data.Vj(); - const auto& face_to_node_matrix = m_mesh->connectivity().faceToNodeMatrix(); - - const FaceValue<const double> mes_l = [=] { - FaceValue<double> compute_mes_l{m_mesh->connectivity()}; - const NodeValue<const TinyVector<Dimension>>& xr = m_mesh->xr(); - if constexpr (Dimension == 1) { - compute_mes_l.fill(1); - } else if constexpr (Dimension == 2) { - parallel_for( - m_mesh->numberOfFaces(), PUGS_LAMBDA(FaceId face_id) { - const auto& face_to_node = face_to_node_matrix[face_id]; - const NodeId node_id1 = face_to_node[0]; - const NodeId node_id2 = face_to_node[1]; - const TinyVector<Dimension, double> r = xr[node_id1] - xr[node_id2]; - compute_mes_l[face_id] = l2Norm(r); - }); - } else { - throw NotImplementedError("Not implemented in 3D"); - } - return compute_mes_l; - }(); - - const CellValue<const double> dual_mes_l_j = [=] { - CellValue<double> compute_mes_j{diamond_mesh->connectivity()}; - mapper->toDualCell(mes_l, compute_mes_j); - - return compute_mes_j; - }(); - - FaceValue<const double> alpha_l = [&] { - CellValue<double> alpha_j{diamond_mesh->connectivity()}; - - parallel_for( - diamond_mesh->numberOfCells(), PUGS_LAMBDA(CellId diamond_cell_id) { - alpha_j[diamond_cell_id] = - dual_mes_l_j[diamond_cell_id] * dual_kappaj[diamond_cell_id] / dual_Vj[diamond_cell_id]; - }); - - FaceValue<double> computed_alpha_l{m_mesh->connectivity()}; - mapper->fromDualCell(alpha_j, computed_alpha_l); - - VTKWriter vtk_writer("DD_" + std::to_string(Dimension), 0.01); - - vtk_writer.write(diamond_mesh, - {NamedItemValue{"alphaj", alpha_j}, NamedItemValue{"xj", diamond_mesh_data.xj()}, - NamedItemValue{"Vl", diamond_mesh_data.Vj()}, NamedItemValue{"|l|", dual_mes_l_j}}, - 0, - true); // forces last output - - return computed_alpha_l; - }(); - - SparseMatrixDescriptor S{m_mesh->numberOfCells()}; - const auto& face_to_cell_matrix = m_mesh->connectivity().faceToCellMatrix(); - for (FaceId face_id = 0; face_id < m_mesh->numberOfFaces(); ++face_id) { - const auto& primal_face_to_cell = face_to_cell_matrix[face_id]; - const double beta_l = 0.5 * alpha_l[face_id] * mes_l[face_id]; - const NodeValuePerCell<const TinyVector<Dimension>>& Cjr = mesh_data.Cjr(); - - // CellValue<double> dual_cell_id{diamond_mesh->connectivity()}; - // mapper->toDualCell(face_id, dual_cell_id); - - for (size_t i_cell = 0; i_cell < primal_face_to_cell.size(); ++i_cell) { - const CellId cell_id1 = primal_face_to_cell[i_cell]; - for (size_t j_cell = 0; j_cell < primal_face_to_cell.size(); ++j_cell) { - const CellId cell_id2 = primal_face_to_cell[j_cell]; - if (i_cell == j_cell) { - S(cell_id1, cell_id2) -= beta_l; - } else { - S(cell_id1, cell_id2) += beta_l; - } - // S(cell_id1, cell_id2)+= alpha_l[face_id]*(,Cjr[dual_cell_id,dual_node_j]); - } - } - } - const CellValue<const double> primal_Vj = mesh_data.Vj(); - CRSMatrix A{S}; - Vector<double> b{m_mesh->numberOfCells()}; - double pi = 3.14159265; - for (CellId i_cell = 0; i_cell < m_mesh->numberOfCells(); ++i_cell) { - if constexpr (Dimension == 2) { - b[i_cell] = - -2 * kappaj[i_cell] * pi * pi * sin(pi * xj[i_cell][0]) * sin(pi * xj[i_cell][1]) * primal_Vj[i_cell]; - - } else if constexpr (Dimension == 3) { - b[i_cell] = -3 * kappaj[i_cell] * pi * pi * sin(pi * xj[i_cell][0]) * sin(pi * xj[i_cell][1]) * - sin(pi * xj[i_cell][2]) * primal_Vj[i_cell]; - } - } - - Vector<double> T{m_mesh->numberOfCells()}; - T = 0; - PCG{b, A, A, T, 100, 1e-12}; - - CellValue<double> Temperature{m_mesh->connectivity()}; - - parallel_for( - m_mesh->numberOfCells(), PUGS_LAMBDA(CellId cell_id) { Temperature[cell_id] = T[cell_id]; }); - - Vector<double> error{m_mesh->numberOfCells()}; - parallel_for( - m_mesh->numberOfCells(), - PUGS_LAMBDA(CellId cell_id) { error[cell_id] = Temperature[cell_id] - Tj[cell_id]; }); - - std::cout << "||Error||_2 = " << std::sqrt((error, error)) << "\n"; - - { - VTKWriter vtk_writer("Temperature_" + std::to_string(Dimension), 0.01); - - vtk_writer.write(m_mesh, {NamedItemValue{"T", Temperature}}, 0, - true); // forces last output - } - } - } else { - throw NotImplementedError("not done in 3d"); - } - } -}; +#include <memory> SchemeModule::SchemeModule() {