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

ASTPrinter.cpp

Blame
  • DiamondDualMeshBuilder.cpp 13.36 KiB
    #include <mesh/DiamondDualMeshBuilder.hpp>
    
    #include <mesh/Connectivity.hpp>
    #include <mesh/ConnectivityDescriptor.hpp>
    #include <mesh/ConnectivityDispatcher.hpp>
    #include <mesh/ItemValueUtils.hpp>
    #include <mesh/Mesh.hpp>
    #include <mesh/MeshData.hpp>
    #include <mesh/RefId.hpp>
    #include <utils/Array.hpp>
    #include <utils/Messenger.hpp>
    
    template <size_t Dimension>
    void
    DiamondDualMeshBuilder::_buildDiamondConnectivityDescriptor(const Connectivity<Dimension>& primal_connectivity,
                                                                ConnectivityDescriptor& diamond_descriptor)
    {
      const size_t primal_number_of_nodes = primal_connectivity.numberOfNodes();
      const size_t primal_number_of_cells = primal_connectivity.numberOfCells();
    
      const size_t diamond_number_of_nodes = primal_number_of_cells + primal_number_of_nodes;
    
      diamond_descriptor.node_number_vector.resize(diamond_number_of_nodes);
    
      const auto& primal_node_number = primal_connectivity.nodeNumber();
    
      for (NodeId primal_node_id = 0; primal_node_id < primal_connectivity.numberOfNodes(); ++primal_node_id) {
        diamond_descriptor.node_number_vector[primal_node_id] = primal_node_number[primal_node_id];
      }
    
      const auto& primal_cell_number = primal_connectivity.cellNumber();
    
      const size_t max_node_number = max(primal_node_number);
    
      for (CellId primal_cell_id = 0; primal_cell_id < primal_number_of_cells; ++primal_cell_id) {
        diamond_descriptor.node_number_vector[primal_number_of_nodes + primal_cell_id] =
          primal_cell_number[primal_cell_id] + max_node_number;
      }
    
      const size_t diamond_number_of_cells = primal_connectivity.numberOfFaces();
      diamond_descriptor.cell_number_vector.resize(diamond_number_of_cells);
    
      const auto& primal_face_number = primal_connectivity.faceNumber();
    
      for (FaceId i_primal_face = 0; i_primal_face < primal_connectivity.numberOfFaces(); ++i_primal_face) {
        diamond_descriptor.cell_number_vector[i_primal_face] = primal_face_number[i_primal_face];
      }
    
      diamond_descriptor.cell_to_node_vector.resize(diamond_number_of_cells);
    
      diamond_descriptor.cell_type_vector.resize(diamond_number_of_cells);
    
      const auto& primal_face_to_cell_matrix = primal_connectivity.faceToCellMatrix();
    
      for (FaceId i_face = 0; i_face < primal_connectivity.numberOfFaces(); ++i_face) {
        const size_t i_cell               = i_face;
        const auto& primal_face_cell_list = primal_face_to_cell_matrix[i_face];
    
        if constexpr (Dimension == 1) {
          throw NotImplementedError("dimension 1");
        } else if constexpr (Dimension == 2) {
          if (primal_face_cell_list.size() == 1) {
            diamond_descriptor.cell_type_vector[i_cell] = CellType::Triangle;
          } else {
            Assert(primal_face_cell_list.size() == 2);
            diamond_descriptor.cell_type_vector[i_cell] = CellType::Quadrangle;
          }
        } else {
          static_assert(Dimension == 3, "unexpected dimension");
    
          if (primal_face_cell_list.size() == 1) {
            diamond_descriptor.cell_type_vector[i_cell] = CellType::Pyramid;
          } else {
            Assert(primal_face_cell_list.size() == 2);
            diamond_descriptor.cell_type_vector[i_cell] = CellType::Diamond;
          }
        }
      }
    
      diamond_descriptor.cell_to_node_vector.resize(diamond_number_of_cells);
    
      const auto& primal_face_to_node_matrix              = primal_connectivity.faceToNodeMatrix();
      const auto& primal_face_local_number_in_their_cells = primal_connectivity.faceLocalNumbersInTheirCells();
      const auto& cell_face_is_reversed                   = primal_connectivity.cellFaceIsReversed();
      for (FaceId i_face = 0; i_face < primal_connectivity.numberOfFaces(); ++i_face) {
        const size_t& i_diamond_cell      = i_face;
        const auto& primal_face_cell_list = primal_face_to_cell_matrix[i_face];
        const auto& primal_face_node_list = primal_face_to_node_matrix[i_face];
        if (primal_face_cell_list.size() == 1) {
          diamond_descriptor.cell_to_node_vector[i_diamond_cell].resize(primal_face_node_list.size() + 1);
    
          const CellId cell_id      = primal_face_cell_list[0];
          const auto i_face_in_cell = primal_face_local_number_in_their_cells(i_face, 0);
    
          for (size_t i_node = 0; i_node < primal_face_node_list.size(); ++i_node) {
            diamond_descriptor.cell_to_node_vector[i_diamond_cell][i_node] = primal_face_node_list[i_node];
          }
          diamond_descriptor.cell_to_node_vector[i_diamond_cell][primal_face_node_list.size()] =
            primal_number_of_nodes + cell_id;
    
          if (cell_face_is_reversed(cell_id, i_face_in_cell)) {
            if constexpr (Dimension == 2) {
              std::swap(diamond_descriptor.cell_to_node_vector[i_diamond_cell][0],
                        diamond_descriptor.cell_to_node_vector[i_diamond_cell][1]);
    
            } else {
              for (size_t i_node = 0; i_node < primal_face_node_list.size() / 2; ++i_node) {
                std::swap(diamond_descriptor.cell_to_node_vector[i_diamond_cell][i_node],
                          diamond_descriptor
                            .cell_to_node_vector[i_diamond_cell][primal_face_node_list.size() - 1 - i_node]);
              }
            }
          }
        } else {
          Assert(primal_face_cell_list.size() == 2);
          diamond_descriptor.cell_to_node_vector[i_diamond_cell].resize(primal_face_node_list.size() + 2);
    
          const CellId cell0_id     = primal_face_cell_list[0];
          const CellId cell1_id     = primal_face_cell_list[1];
          const auto i_face_in_cell = primal_face_local_number_in_their_cells(i_face, 0);
    
          if constexpr (Dimension == 2) {
            Assert(primal_face_node_list.size() == 2);
            diamond_descriptor.cell_to_node_vector[i_diamond_cell][0] = primal_number_of_nodes + cell0_id;
            diamond_descriptor.cell_to_node_vector[i_diamond_cell][1] = primal_face_node_list[0];
            diamond_descriptor.cell_to_node_vector[i_diamond_cell][2] = primal_number_of_nodes + cell1_id;
            diamond_descriptor.cell_to_node_vector[i_diamond_cell][3] = primal_face_node_list[1];
    
            if (cell_face_is_reversed(cell0_id, i_face_in_cell)) {
              std::swap(diamond_descriptor.cell_to_node_vector[i_diamond_cell][1],
                        diamond_descriptor.cell_to_node_vector[i_diamond_cell][3]);
            }
          } else {
            diamond_descriptor.cell_to_node_vector[i_diamond_cell][0] = primal_number_of_nodes + cell0_id;
            for (size_t i_node = 0; i_node < primal_face_node_list.size(); ++i_node) {
              diamond_descriptor.cell_to_node_vector[i_diamond_cell][i_node + 1] = primal_face_node_list[i_node];
            }
            diamond_descriptor.cell_to_node_vector[i_diamond_cell][primal_face_node_list.size() + 1] =
              primal_number_of_nodes + cell1_id;
    
            if (cell_face_is_reversed(cell0_id, i_face_in_cell)) {
              std::swap(diamond_descriptor.cell_to_node_vector[i_diamond_cell][0],
                        diamond_descriptor.cell_to_node_vector[i_diamond_cell][primal_face_node_list.size() + 1]);
            }
          }
        }
      }
    }
    
    template <size_t Dimension>
    void
    DiamondDualMeshBuilder::_buildDiamondMeshFrom(const std::shared_ptr<const IMesh>& p_mesh)
    {
      static_assert(Dimension <= 3, "invalid mesh dimension");
      using ConnectivityType = Connectivity<Dimension>;
      using MeshType         = Mesh<ConnectivityType>;
    
      const MeshType& primal_mesh = dynamic_cast<const MeshType&>(*p_mesh);
    
      const ConnectivityType& primal_connectivity = primal_mesh.connectivity();
    
      ConnectivityDescriptor diamond_descriptor;
    
      this->_buildDiamondConnectivityDescriptor(primal_connectivity, diamond_descriptor);
    
      MeshBuilderBase::_computeCellFaceAndFaceNodeConnectivities<Dimension>(diamond_descriptor);
    
      {
        const auto& primal_face_to_node_matrix = primal_connectivity.faceToNodeMatrix();
    
        using Face = ConnectivityFace<Dimension>;
    
        const std::unordered_map<Face, FaceId, typename Face::Hash> face_to_id_map = [&] {
          std::unordered_map<Face, FaceId, typename Face::Hash> face_to_id_map;
          for (FaceId l = 0; l < diamond_descriptor.face_to_node_vector.size(); ++l) {
            const auto& node_vector = diamond_descriptor.face_to_node_vector[l];
    
            face_to_id_map[Face(node_vector, diamond_descriptor.node_number_vector)] = l;
          }
          return face_to_id_map;
        }();
    
        for (size_t i_face_list = 0; i_face_list < primal_connectivity.template numberOfRefItemList<ItemType::face>();
             ++i_face_list) {
          const auto& primal_ref_face_list = primal_connectivity.template refItemList<ItemType::face>(i_face_list);
          std::cout << "treating " << primal_ref_face_list.refId() << '\n';
          const auto& primal_face_list = primal_ref_face_list.list();
    
          const std::vector<FaceId> diamond_face_list = [&]() {
            std::vector<FaceId> diamond_face_list;
            diamond_face_list.reserve(primal_face_list.size());
            for (size_t i = 0; i < primal_face_list.size(); ++i) {
              FaceId primal_face_id = primal_face_list[i];
    
              const auto& primal_face_node_list = primal_face_to_node_matrix[primal_face_id];
    
              const auto i_diamond_face = [&]() {
                std::vector<unsigned int> node_list(primal_face_node_list.size());
                for (size_t i = 0; i < primal_face_node_list.size(); ++i) {
                  node_list[i] = primal_face_node_list[i];
                }
                return face_to_id_map.find(Face(node_list, diamond_descriptor.node_number_vector));
              }();
    
              if (i_diamond_face != face_to_id_map.end()) {
                diamond_face_list.push_back(i_diamond_face->second);
              }
            }
            return diamond_face_list;
          }();
    
          if (parallel::allReduceOr(diamond_face_list.size() > 0)) {
            Array<FaceId> face_array(diamond_face_list.size());
            for (size_t i = 0; i < diamond_face_list.size(); ++i) {
              face_array[i] = diamond_face_list[i];
            }
            diamond_descriptor.addRefItemList(RefFaceList{primal_ref_face_list.refId(), face_array});
          }
        }
      }
    
      const size_t primal_number_of_nodes = primal_connectivity.numberOfNodes();
      const size_t primal_number_of_cells = primal_connectivity.numberOfCells();
    
      diamond_descriptor.node_owner_vector.resize(diamond_descriptor.node_number_vector.size());
    
      const auto& primal_node_owner = primal_connectivity.nodeOwner();
      for (NodeId primal_node_id = 0; primal_node_id < primal_connectivity.numberOfNodes(); ++primal_node_id) {
        diamond_descriptor.node_owner_vector[primal_node_id] = primal_node_owner[primal_node_id];
      }
      const auto& primal_cell_owner = primal_connectivity.cellOwner();
      for (CellId primal_cell_id = 0; primal_cell_id < primal_number_of_cells; ++primal_cell_id) {
        diamond_descriptor.node_owner_vector[primal_number_of_nodes + primal_cell_id] = primal_cell_owner[primal_cell_id];
      }
    
      diamond_descriptor.cell_owner_vector.resize(diamond_descriptor.cell_number_vector.size());
      const auto& primal_face_owner = primal_connectivity.faceOwner();
      for (FaceId primal_face_id = 0; primal_face_id < primal_number_of_cells; ++primal_face_id) {
        diamond_descriptor.cell_owner_vector[primal_face_id] = primal_face_owner[primal_face_id];
      }
    
      {
        std::vector<int> face_cell_owner(diamond_descriptor.face_number_vector.size());
        std::fill(std::begin(face_cell_owner), std::end(face_cell_owner), parallel::size());
    
        for (size_t i_cell = 0; i_cell < diamond_descriptor.cell_to_face_vector.size(); ++i_cell) {
          const auto& cell_face_list = diamond_descriptor.cell_to_face_vector[i_cell];
          for (size_t i_face = 0; i_face < cell_face_list.size(); ++i_face) {
            const size_t face_id     = cell_face_list[i_face];
            face_cell_owner[face_id] = std::min(face_cell_owner[face_id], diamond_descriptor.cell_number_vector[i_cell]);
          }
        }
    
        diamond_descriptor.face_owner_vector.resize(face_cell_owner.size());
        for (size_t i_face = 0; i_face < face_cell_owner.size(); ++i_face) {
          diamond_descriptor.face_owner_vector[i_face] = diamond_descriptor.cell_owner_vector[face_cell_owner[i_face]];
        }
      }
    
      std::shared_ptr p_diamond_connectivity = ConnectivityType::build(diamond_descriptor);
      ConnectivityType& diamond_connectivity = *p_diamond_connectivity;
    
      NodeValue<TinyVector<Dimension>> diamond_xr{diamond_connectivity};
    
      const auto primal_xr = primal_mesh.xr();
      MeshData<MeshType> primal_mesh_data{primal_mesh};
      const auto primal_xj = primal_mesh_data.xj();
    
      {
    #warning define transfer functions
        NodeId i_node = 0;
        for (; i_node < primal_number_of_nodes; ++i_node) {
          diamond_xr[i_node] = primal_xr[i_node];
        }
    
        for (CellId i_cell = 0; i_cell < primal_number_of_cells; ++i_cell) {
          diamond_xr[i_node++] = primal_xj[i_cell];
        }
      }
    
      std::shared_ptr p_diamond_mesh = std::make_shared<MeshType>(p_diamond_connectivity, diamond_xr);
    
    #warning USELESS TEST
      // -->>
      MeshData<MeshType> dual_mesh_data{*p_diamond_mesh};
    
      double sum = 0;
      for (CellId cell_id = 0; cell_id < p_diamond_mesh->numberOfCells(); ++cell_id) {
        sum += dual_mesh_data.Vj()[cell_id];
      }
    
      std::cout << "volume = " << sum << '\n';
      // <<--
    
      m_mesh = std::make_shared<MeshType>(p_diamond_connectivity, diamond_xr);
    }
    
    template <>
    [[deprecated]] void
    DiamondDualMeshBuilder::_buildDiamondMeshFrom<1>(const std::shared_ptr<const IMesh>&)
    {
      m_mesh = 0;
    }
    
    DiamondDualMeshBuilder::DiamondDualMeshBuilder(const std::shared_ptr<const IMesh>& p_mesh)
    {
      switch (p_mesh->dimension()) {
      case 1: {
        this->_buildDiamondMeshFrom<1>(p_mesh);
        break;
      }
      case 2: {
        this->_buildDiamondMeshFrom<2>(p_mesh);
        break;
      }
      case 3: {
        this->_buildDiamondMeshFrom<3>(p_mesh);
        break;
      }
      default: {
        throw UnexpectedError("invalid mesh dimension: " + std::to_string(p_mesh->dimension()));
      }
      }
    }