Skip to content
Snippets Groups Projects
Select Git revision
  • 39e8b549fc85056334c7890c026e6a55c34c4ff3
  • develop default protected
  • origin/stage/bouguettaia
  • feature/kinetic-schemes
  • feature/reconstruction
  • feature/local-dt-fsi
  • feature/composite-scheme-sources
  • feature/composite-scheme-other-fluxes
  • feature/serraille
  • feature/variational-hydro
  • feature/composite-scheme
  • hyperplastic
  • feature/polynomials
  • feature/gks
  • feature/implicit-solver-o2
  • feature/coupling_module
  • feature/implicit-solver
  • feature/merge-local-dt-fsi
  • master protected
  • feature/escobar-smoother
  • feature/hypoelasticity-clean
  • v0.5.0 protected
  • v0.4.1 protected
  • v0.4.0 protected
  • v0.3.0 protected
  • v0.2.0 protected
  • v0.1.0 protected
  • Kidder
  • v0.0.4 protected
  • v0.0.3 protected
  • v0.0.2 protected
  • v0 protected
  • v0.0.1 protected
33 results

UnaryOperatorRegisterForB.cpp

Blame
  • Heat5PointsAlgorithm.cpp 7.71 KiB
    #include <language/algorithms/Heat5PointsAlgorithm.hpp>
    
    #include <algebra/CRSMatrix.hpp>
    #include <algebra/CRSMatrixDescriptor.hpp>
    #include <algebra/LeastSquareSolver.hpp>
    #include <algebra/LinearSolver.hpp>
    #include <algebra/LinearSolverOptions.hpp>
    #include <algebra/SmallMatrix.hpp>
    #include <algebra/TinyVector.hpp>
    #include <algebra/Vector.hpp>
    #include <language/utils/InterpolateItemValue.hpp>
    #include <mesh/Connectivity.hpp>
    #include <mesh/DualConnectivityManager.hpp>
    #include <mesh/DualMeshManager.hpp>
    #include <mesh/Mesh.hpp>
    #include <mesh/MeshData.hpp>
    #include <mesh/MeshDataManager.hpp>
    #include <mesh/PrimalToDiamondDualConnectivityDataMapper.hpp>
    
    template <size_t Dimension>
    Heat5PointsAlgorithm<Dimension>::Heat5PointsAlgorithm(
      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,
      const FunctionSymbolId& f_id)
    {
      using ConnectivityType = Connectivity<Dimension>;
      using MeshType         = Mesh<ConnectivityType>;
      using MeshDataType     = MeshData<Dimension>;
    
      std::shared_ptr mesh = std::dynamic_pointer_cast<const MeshType>(i_mesh);
    
      std::cout << "number of bc descr = " << bc_descriptor_list.size() << '\n';
    
      if constexpr (Dimension == 2) {
        MeshDataType& mesh_data = MeshDataManager::instance().getMeshData(*mesh);
    
        CellValue<double> Tj =
          InterpolateItemValue<double(TinyVector<Dimension>)>::template interpolate<ItemType::cell>(T_id, mesh_data.xj());
    
        NodeValue<double> Tr(mesh->connectivity());
        const NodeValue<const TinyVector<Dimension>>& xr = mesh->xr();
        const CellValue<const TinyVector<Dimension>>& xj = mesh_data.xj();
        const auto& node_to_cell_matrix                  = mesh->connectivity().nodeToCellMatrix();
        CellValuePerNode<double> w_rj{mesh->connectivity()};
    
        for (NodeId i_node = 0; i_node < mesh->numberOfNodes(); ++i_node) {
          SmallVector<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];
    
          SmallMatrix<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];
            }
          }
          SmallVector<double> x{node_to_cell.size()};
          x = zero;
    
          LeastSquareSolver ls_solver;
          ls_solver.solveLocalSystem(A, x, b);
    
          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];
          }
        }
    
        {
          std::shared_ptr diamond_mesh = DualMeshManager::instance().getDiamondDualMesh(*mesh);
    
          MeshDataType& diamond_mesh_data = MeshDataManager::instance().getMeshData(*diamond_mesh);
    
          std::shared_ptr mapper =
            DualConnectivityManager::instance().getPrimalToDiamondDualConnectivityDataMapper(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());
    
          const CellValue<const double> dual_Vj = diamond_mesh_data.Vj();
    
          const FaceValue<const double> mes_l = [&] {
            if constexpr (Dimension == 1) {
              FaceValue<double> compute_mes_l{mesh->connectivity()};
              compute_mes_l.fill(1);
              return compute_mes_l;
            } else {
              return mesh_data.ll();
            }
          }();
    
          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{mesh->connectivity()};
            mapper->fromDualCell(alpha_j, computed_alpha_l);
    
            return computed_alpha_l;
          }();
    
          const Array<int> non_zeros{mesh->numberOfCells()};
          non_zeros.fill(Dimension);
          CRSMatrixDescriptor<double> S(mesh->numberOfCells(), mesh->numberOfCells(), non_zeros);
    
          const auto& face_to_cell_matrix = mesh->connectivity().faceToCellMatrix();
          for (FaceId face_id = 0; face_id < 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];
    
            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;
                }
              }
            }
          }
          CellValue<double> fj =
            InterpolateItemValue<double(TinyVector<Dimension>)>::template interpolate<ItemType::cell>(f_id, mesh_data.xj());
    
          const CellValue<const double> primal_Vj = mesh_data.Vj();
          CRSMatrix A{S.getCRSMatrix()};
          Vector<double> b{mesh->numberOfCells()};
          parallel_for(
            mesh->numberOfCells(), PUGS_LAMBDA(CellId cell_id) { b[cell_id] = fj[cell_id] * primal_Vj[cell_id]; });
    
          Vector<double> T{mesh->numberOfCells()};
          T = zero;
    
          LinearSolver solver;
          solver.solveLocalSystem(A, T, b);
    
          CellValue<double> Temperature{mesh->connectivity()};
    
          parallel_for(
            mesh->numberOfCells(), PUGS_LAMBDA(CellId cell_id) { Temperature[cell_id] = T[cell_id]; });
    
          Vector<double> error{mesh->numberOfCells()};
          parallel_for(
            mesh->numberOfCells(),
            PUGS_LAMBDA(CellId cell_id) { error[cell_id] = (Temperature[cell_id] - Tj[cell_id]) * primal_Vj[cell_id]; });
    
          std::cout << "||Error||_2 = " << std::sqrt(dot(error, error)) << "\n";
        }
      } else {
        throw NotImplementedError("not done in this dimension");
      }
    }
    
    template Heat5PointsAlgorithm<1>::Heat5PointsAlgorithm(
      std::shared_ptr<const IMesh>,
      const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>&,
      const FunctionSymbolId&,
      const FunctionSymbolId&,
      const FunctionSymbolId&);
    
    template Heat5PointsAlgorithm<2>::Heat5PointsAlgorithm(
      std::shared_ptr<const IMesh>,
      const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>&,
      const FunctionSymbolId&,
      const FunctionSymbolId&,
      const FunctionSymbolId&);
    
    template Heat5PointsAlgorithm<3>::Heat5PointsAlgorithm(
      std::shared_ptr<const IMesh>,
      const std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>>&,
      const FunctionSymbolId&,
      const FunctionSymbolId&,
      const FunctionSymbolId&);