// Copyright(C) 2021, 2022 National Technology & Engineering Solutions // of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with // NTESS, the U.S. Government retains certain rights in this software. // // See packages/seacas/LICENSE for details #pragma once #include #include #include #include #include "Ioss_Region.h" //! \file enum class Bnd { MIN_I = 0, MAX_I = 1, MIN_J = 2, MAX_J = 3, MIN_K = 4, MAX_K = 5 }; enum class Flg { MIN_I = 1, MAX_I = 4, MIN_J = 2, MAX_J = 8, MIN_K = 16, MAX_K = 32 }; struct GeneratedSideBlock { //! List of faces (10*element_offset + face) in this SideBlock //! indexed by element block name... //! //! Note that the `element_offset` is the 1-based index of the //! element within the element block that it is a member of GeneratedSideBlock() = default; GeneratedSideBlock(const GeneratedSideBlock &) = delete; std::map> m_faces; size_t size() const { size_t count = 0; for (auto &faces : m_faces) { count += faces.second.size(); } return count; } }; class UnitCell { public: explicit UnitCell(std::shared_ptr region); UnitCell(const UnitCell &) = delete; //! Create a vector of `node_count` length which has the following values: //! * 0: Node that is not shared with any neighbors. //! * 1: Node on `min_I` face //! * 2: Node on `min_J` face //! * 3: Node on `min_I-min_J` line //! If `all_faces` is true, then also categorize the max_I (4) and max_J (8) faces and don't //! consider neighbors (want all boundaries marked). std::vector categorize_nodes(bool neighbor_i, bool neighbor_j, bool all_faces = false) const; std::shared_ptr m_region{nullptr}; //!@{ The local node ids of the nodes that are on each face of this //! unit cell. The I/J face nodes are in a structured configuration //! and these vectors are sorted such that the `min_I_face` and //! `max_I_face` nodes are at the same "parametric" location. In //! other words, the nodes in the `max_I_face` of one unit cell will //! line up with the nodes in the `min_I_face` of the neighboring //! cell. They are also ordered such that the first `cell_KK` nodes //! in the `min_I_face` and `min_J_face` lists should be the same //! and are the nodes at the intersection of those two faces. std::vector min_I_face{}; std::vector max_I_face{}; std::vector min_J_face{}; std::vector max_J_face{}; //!@} ///@{ //! A pair containing the //! minimum and maximum coordinate extent in the `x` and `y` //! directions. std::pair minmax_x{}; std::pair minmax_y{}; ///@} void generate_boundary_faces(unsigned int which_faces); //! Used by `generate_boundary_faces()` to categorize nodes on the +/- Z faces of unit cell. void categorize_z_nodes(std::vector &categorized_nodes); std::array boundary_blocks{}; ///@{ //! The outer boundary of a UnitCell has a //! structured-configuration of the boundary faces on the non-K //! faces. The `cell_II`, `cell_JJ`, and `cell_KK` variables give //! the dimensions of this structured face mesh for the `min_I`, //! `max_I`, `min_J`, and `max_J` faces. Note that the `min_K` and //! `max_K` faces are *NOT* structured, but they will have `cell_II` //! and `cell_JJ` nodes on the boundary of the faces. size_t cell_II{}; size_t cell_JJ{}; size_t cell_KK{}; ///@} }; using UnitCellMap = std::map>;