Skip to content
Snippets Groups Projects
Select Git revision
  • 3369b1f2a70de3702f353e14cd4a625ce6ad06b6
  • develop default protected
  • feature/advection
  • feature/composite-scheme-other-fluxes
  • origin/stage/bouguettaia
  • save_clemence
  • feature/local-dt-fsi
  • feature/variational-hydro
  • feature/gmsh-reader
  • feature/reconstruction
  • feature/kinetic-schemes
  • feature/composite-scheme-sources
  • feature/serraille
  • feature/composite-scheme
  • hyperplastic
  • feature/polynomials
  • feature/gks
  • feature/implicit-solver-o2
  • feature/coupling_module
  • feature/implicit-solver
  • feature/merge-local-dt-fsi
  • 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

ASTNodeJumpPlacementChecker.cpp

Blame
  • PolynomialReconstruction.hpp 11.51 KiB
    #ifndef POLYNOMIAL_RECONSTRUCTION_HPP
    #define POLYNOMIAL_RECONSTRUCTION_HPP
    
    #include <algebra/ShrinkMatrixView.hpp>
    #include <algebra/ShrinkVectorView.hpp>
    #include <algebra/SmallMatrix.hpp>
    #include <algebra/SmallVector.hpp>
    #include <mesh/MeshTraits.hpp>
    #include <scheme/DiscreteFunctionDPkVariant.hpp>
    
    #warning MOVE TO .cpp WHEN FINISHED
    #include <algebra/Givens.hpp>
    #include <analysis/GaussLegendreQuadratureDescriptor.hpp>
    #include <analysis/QuadratureFormula.hpp>
    #include <analysis/QuadratureManager.hpp>
    #include <geometry/LineTransformation.hpp>
    #include <mesh/MeshData.hpp>
    #include <mesh/MeshDataManager.hpp>
    #include <mesh/StencilManager.hpp>
    
    class DiscreteFunctionDPkVariant;
    class DiscreteFunctionVariant;
    
    class PolynomialReconstruction
    {
     private:
      class MutableDiscreteFunctionDPkVariant;
    
      template <MeshConcept MeshType>
      [[nodiscard]] std::vector<std::shared_ptr<const DiscreteFunctionDPkVariant>> _build(
        const size_t degree,
        const std::shared_ptr<const MeshType>& p_mesh,
        const std::vector<std::shared_ptr<const DiscreteFunctionVariant>>& discrete_function_variant_list) const;
    
     public:
      template <MeshConcept MeshType, typename DataType>
      PUGS_INLINE DiscreteFunctionDPk<MeshType::Dimension, std::remove_const_t<DataType>>
      build(const MeshType& mesh, const DiscreteFunctionP0<DataType> p0_function) const
      {
        using Rd = TinyVector<MeshType::Dimension>;
    
        const size_t degree    = 1;
        const Stencil& stencil = StencilManager::instance().getStencil(mesh.connectivity());
    
        auto xj = MeshDataManager::instance().getMeshData(mesh).xj();
    
        auto cell_is_owned = mesh.connectivity().cellIsOwned();
    
        const size_t max_stencil_size = [&]() {
          size_t max_size = 0;
          for (CellId cell_id = 0; cell_id < mesh.numberOfCells(); ++cell_id) {
            auto stencil_cell_list = stencil[cell_id];
            if (cell_is_owned[cell_id] and stencil_cell_list.size() > max_size) {
              max_size = stencil_cell_list.size();
            }
          }
          return max_size;
        }();
    
        Kokkos::Experimental::UniqueToken<Kokkos::DefaultExecutionSpace::execution_space,
                                          Kokkos::Experimental::UniqueTokenScope::Global>
          tokens;
    
        DiscreteFunctionDPk<MeshType::Dimension, std::remove_const_t<DataType>> dpk{mesh.meshVariant(), degree};
    
        if constexpr (is_polygonal_mesh_v<MeshType>) {
          if constexpr (std::is_arithmetic_v<DataType>) {
            SmallArray<SmallMatrix<double>> A_pool(Kokkos::DefaultExecutionSpace::concurrency());
            SmallArray<SmallVector<double>> b_pool(Kokkos::DefaultExecutionSpace::concurrency());
            for (size_t i = 0; i < A_pool.size(); ++i) {
              A_pool[i] = SmallMatrix<double>(max_stencil_size, MeshType::Dimension);
              b_pool[i] = SmallVector<double>(max_stencil_size);
            }
    
            parallel_for(
              mesh.numberOfCells(), PUGS_LAMBDA(const CellId cell_j_id) {
                if (cell_is_owned[cell_j_id]) {
                  const int32_t t = tokens.acquire();
    
                  auto stencil_cell_list = stencil[cell_j_id];
    
                  ShrinkVectorView b(b_pool[t], stencil_cell_list.size());
    
                  const double pj = p0_function[cell_j_id];
                  for (size_t i = 0; i < stencil_cell_list.size(); ++i) {
                    const CellId cell_i_id = stencil_cell_list[i];
    
                    b[i] = p0_function[cell_i_id] - pj;
                  }
    
                  ShrinkMatrixView A(A_pool[t], stencil_cell_list.size());
    
                  const Rd& Xj = xj[cell_j_id];
    
                  for (size_t i = 0; i < stencil_cell_list.size(); ++i) {
                    const CellId cell_i_id = stencil_cell_list[i];
                    const Rd Xi_Xj         = xj[cell_i_id] - Xj;
                    for (size_t l = 0; l < MeshType::Dimension; ++l) {
                      A(i, l) = Xi_Xj[l];
                    }
                  }
    
                  for (size_t i = 0; i < stencil_cell_list.size(); ++i) {
                    const CellId cell_i_id = stencil_cell_list[i];
                    const double weight    = 1. / l2Norm(xj[cell_i_id] - Xj);
                    for (size_t l = 0; l < MeshType::Dimension; ++l) {
                      A(i, l) *= weight;
                    }
                    b[i] *= weight;
                  }
    
                  SmallVector<double> x(MeshType::Dimension);
                  Givens::solveInPlace(A, x, b);
    
                  auto dpk_j = dpk.coefficients(cell_j_id);
    
                  dpk_j[0] = pj;
    
                  for (size_t l = 0; l < MeshType::Dimension; ++l) {
                    dpk_j[1 + l] = x[l];
                  }
    
                  tokens.release(t);
                }
              });
          } else if constexpr (is_tiny_vector_v<DataType>) {
            SmallArray<SmallMatrix<double>> A_pool(Kokkos::DefaultExecutionSpace::concurrency());
            SmallArray<SmallMatrix<double>> B_pool(Kokkos::DefaultExecutionSpace::concurrency());
            for (size_t i = 0; i < A_pool.size(); ++i) {
              A_pool[i] = SmallMatrix<double>(max_stencil_size, MeshType::Dimension);
              B_pool[i] = SmallMatrix<double>(max_stencil_size, DataType::Dimension);
            }
    
            parallel_for(
              mesh.numberOfCells(), PUGS_LAMBDA(const CellId cell_j_id) {
                if (cell_is_owned[cell_j_id]) {
                  const int32_t t = tokens.acquire();
    
                  auto stencil_cell_list = stencil[cell_j_id];
                  ShrinkMatrixView B(B_pool[t], stencil_cell_list.size());
    
                  const DataType& pj = p0_function[cell_j_id];
                  for (size_t i = 0; i < stencil_cell_list.size(); ++i) {
                    const CellId cell_i_id = stencil_cell_list[i];
                    const DataType& pi_pj  = p0_function[cell_i_id] - pj;
                    for (size_t k = 0; k < DataType::Dimension; ++k) {
                      B(i, k) = pi_pj[k];
                    }
                  }
    
                  ShrinkMatrixView A(A_pool[t], stencil_cell_list.size());
    
                  const Rd& Xj = xj[cell_j_id];
                  for (size_t i = 0; i < stencil_cell_list.size(); ++i) {
                    const CellId cell_i_id = stencil_cell_list[i];
                    const Rd Xi_Xj         = xj[cell_i_id] - Xj;
                    for (size_t l = 0; l < MeshType::Dimension; ++l) {
                      A(i, l) = Xi_Xj[l];
                    }
                  }
    
                  for (size_t i = 0; i < stencil_cell_list.size(); ++i) {
                    const CellId cell_i_id = stencil_cell_list[i];
                    const double weight    = 1. / l2Norm(xj[cell_i_id] - Xj);
                    for (size_t l = 0; l < MeshType::Dimension - 1; ++l) {
                      A(i, l) *= weight;
                    }
                    for (size_t l = 0; l < DataType::Dimension; ++l) {
                      B(i, l) *= weight;
                    }
                  }
    
                  TinyMatrix<MeshType::Dimension, DataType::Dimension> X;
                  Givens::solveCollectionInPlace(A, X, B);
    
                  auto dpk_j = dpk.coefficients(cell_j_id);
    
                  dpk_j[0] = pj;
                  for (size_t i = 0; i < MeshType::Dimension; ++i) {
                    auto& dpk_j_ip1 = dpk_j[i + 1];
                    for (size_t k = 0; k < DataType::Dimension; ++k) {
                      dpk_j_ip1[k] = X(i, k);
                    }
                  }
    
                  tokens.release(t);
                }
              });
          } else if constexpr (is_tiny_matrix_v<DataType>) {
            SmallArray<SmallMatrix<double>> A_pool(Kokkos::DefaultExecutionSpace::concurrency());
            SmallArray<SmallMatrix<double>> B_pool(Kokkos::DefaultExecutionSpace::concurrency());
            for (size_t i = 0; i < A_pool.size(); ++i) {
              A_pool[i] = SmallMatrix<double>(max_stencil_size, MeshType::Dimension);
              B_pool[i] = SmallMatrix<double>(max_stencil_size, DataType::Dimension);
            }
    
            parallel_for(
              mesh.numberOfCells(), PUGS_LAMBDA(const CellId cell_j_id) {
                if (cell_is_owned[cell_j_id]) {
                  const int32_t t = tokens.acquire();
    
                  auto stencil_cell_list = stencil[cell_j_id];
                  ShrinkMatrixView B(B_pool[t], stencil_cell_list.size());
    
                  const DataType& pj = p0_function[cell_j_id];
                  for (size_t i = 0; i < stencil_cell_list.size(); ++i) {
                    const CellId cell_i_id = stencil_cell_list[i];
                    const DataType& pi_pj  = p0_function[cell_i_id] - pj;
                    for (size_t k = 0; k < DataType::NumberOfRows; ++k) {
                      for (size_t l = 0; l < DataType::NumberOfColumns; ++l) {
                        B(i, k * DataType::NumberOfColumns + l) = pi_pj(k, l);
                      }
                    }
                  }
    
                  ShrinkMatrixView A(A_pool[t], stencil_cell_list.size());
    
                  const Rd& Xj = xj[cell_j_id];
    
                  for (size_t i = 0; i < stencil_cell_list.size(); ++i) {
                    const CellId cell_i_id = stencil_cell_list[i];
                    const Rd Xi_Xj         = xj[cell_i_id] - Xj;
                    for (size_t l = 0; l < MeshType::Dimension; ++l) {
                      A(i, l) = Xi_Xj[l];
                    }
                  }
    
                  for (size_t i = 0; i < stencil_cell_list.size(); ++i) {
                    const CellId cell_i_id = stencil_cell_list[i];
                    const double weight    = 1. / l2Norm(xj[cell_i_id] - Xj);
                    for (size_t l = 0; l < MeshType::Dimension - 1; ++l) {
                      A(i, l) *= weight;
                    }
                    for (size_t l = 0; l < DataType::Dimension; ++l) {
                      B(i, l) *= weight;
                    }
                  }
    
                  TinyMatrix<MeshType::Dimension, DataType::Dimension> X;
                  Givens::solveCollectionInPlace(A, X, B);
    
                  auto dpk_j = dpk.coefficients(cell_j_id);
                  dpk_j[0]   = pj;
    
                  for (size_t i = 0; i < MeshType::Dimension; ++i) {
                    auto& dpk_j_ip1 = dpk_j[i + 1];
                    for (size_t k = 0; k < DataType::NumberOfRows; ++k) {
                      for (size_t l = 0; l < DataType::NumberOfColumns; ++l) {
                        dpk_j_ip1(k, l) = X(i, k * DataType::NumberOfColumns + l);
                      }
                    }
                  }
    
                  tokens.release(t);
                }
              });
          } else {
            throw NotImplementedError("dealing with " + demangle<DataType>());
          }
        }
    
        synchronize(dpk.cellArrays());
        return dpk;
      }
    
      [[nodiscard]] std::vector<std::shared_ptr<const DiscreteFunctionDPkVariant>> build(
        const size_t degree,
        const std::vector<std::shared_ptr<const DiscreteFunctionVariant>>& discrete_function_variant_list) const;
    
      template <typename... DiscreteFunctionT>
      [[nodiscard]] std::vector<std::shared_ptr<const DiscreteFunctionDPkVariant>>
      build(const size_t degree, DiscreteFunctionT... input) const
      {
        std::vector<std::shared_ptr<const DiscreteFunctionVariant>> variant_vector;
        auto convert = [&variant_vector](auto&& df) {
          using DF_T = std::decay_t<decltype(df)>;
          if constexpr (is_discrete_function_v<DF_T> or std::is_same_v<DiscreteFunctionVariant, DF_T>) {
            variant_vector.push_back(std::make_shared<DiscreteFunctionVariant>(df));
          } else if constexpr (is_shared_ptr_v<DF_T>) {
            using DF_Value_T = std::decay_t<typename DF_T::element_type>;
            if constexpr (is_discrete_function_v<DF_Value_T> or std::is_same_v<DiscreteFunctionVariant, DF_Value_T>) {
              variant_vector.push_back(std::make_shared<DiscreteFunctionVariant>(*df));
            } else {
              static_assert(is_false_v<DF_T>, "unexpected type");
            }
          } else {
            static_assert(is_false_v<DF_T>, "unexpected type");
          }
        };
    
        (convert(std::forward<DiscreteFunctionT>(input)), ...);
        return this->build(degree, variant_vector);
      }
    
      PolynomialReconstruction() {}
    };
    
    #endif   // POLYNOMIAL_RECONSTRUCTION_HPP