Skip to content

Commit

Permalink
Merge pull request #802 from aritorto/splitCode
Browse files Browse the repository at this point in the history
Point ids for refined grids and addLgrsUpdateLeafGridView refactorization
  • Loading branch information
blattms authored Nov 27, 2024
2 parents bd63022 + d36ced5 commit ec75718
Show file tree
Hide file tree
Showing 8 changed files with 957 additions and 317 deletions.
1 change: 1 addition & 0 deletions CMakeLists_files.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ list (APPEND PUBLIC_HEADER_FILES
opm/grid/LookUpData.hh
opm/grid/cpgrid/OrientedEntityTable.hpp
opm/grid/cpgrid/ParentToChildrenCellGlobalIdHandle.hpp
opm/grid/cpgrid/ParentToChildCellToPointGlobalIdHandle.hpp
opm/grid/cpgrid/PartitionIteratorRule.hpp
opm/grid/cpgrid/PartitionTypeIndicator.hpp
opm/grid/cpgrid/PersistentContainer.hpp
Expand Down
109 changes: 90 additions & 19 deletions opm/grid/CpGrid.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -415,28 +415,12 @@ namespace Dune
template <int codim>
cpgrid::Entity<codim> entity(const cpgrid::Entity<codim>& seed) const;

/// @brief Create a grid out of a coarse one and a refinement(LGR) of a selected block-shaped patch of cells from that coarse grid.
///
/// Level0 refers to the coarse grid, assumed to be this-> data_[0]. Level1 refers to the LGR (stored in this->data_[1]).
/// LeafView (stored in this-> data_[2]) is built with the level0-entities which weren't involded in the
/// refinenment, together with the new born entities created in level1.
/// Old-corners and old-faces (from coarse grid) lying on the boundary of the patch, get replaced by new-born-equivalent corners
/// and new-born-faces.
///
/// @param [in] cells_per_dim Number of (refined) cells in each direction that each parent cell should be refined to.
/// @param [in] startIJK Cartesian triplet index where the patch starts.
/// @param [in] endIJK Cartesian triplet index where the patch ends.
/// Last cell part of the lgr will be {endijk[0]-1, ... endIJK[2]-1}.
/// @param [in] lgr_name Name (std::string) for the lgr/level1
void addLgrUpdateLeafView(const std::array<int,3>& cells_per_dim, const std::array<int,3>& startIJK,
const std::array<int,3>& endIJK, const std::string& lgr_name);

/// @brief Create a grid out of a coarse one and (at most) 2 refinements(LGRs) of selected block-shaped disjoint patches
/// of cells from that coarse grid.
///
/// Level0 refers to the coarse grid, assumed to be this-> data_[0]. Level1 and level2 refer to the LGRs (stored in this->data_[1]
/// data_[2]). LeafView (stored in this-> data_[3]) is built with the level0-entities which weren't involded in the
/// refinenment, together with the new born entities created in level1 and level2.
/// refinenment, together with the new born entities created in level1 and level2.
/// Old-corners and old-faces (from coarse grid) lying on the boundary of the patches, get replaced by new-born-equivalent corners
/// and new-born-faces.
///
Expand Down Expand Up @@ -476,7 +460,6 @@ namespace Dune
// from certain LGR
Dune::cpgrid::Intersection getParentIntersectionFromLgrBoundaryFace(const Dune::cpgrid::Intersection& intersection) const;


/// --------------- Adaptivity (begin) ---------------
/// @brief Mark entity for refinement (or coarsening).
///
Expand Down Expand Up @@ -1083,12 +1066,100 @@ namespace Dune
/// @param [in] cells_per_dim: Total children cells in each direction (x-,y-, and z-direction) of the single-cell-refinement.
/// @param [in] faceIdxInLgr: Face index in the single-cell-refinement.
/// @param [in] elemLgr_ptr: Pointer to the elemLgr single-cell-refinement grid.
/// @param [in] elemLgr: Cell index from starting grid, that has been refined into a single-cell-refinement.
/// @param [in] elemLgr: Cell index from starting grid, that has been refined into a single-cell-refinement.
int getParentFaceWhereNewRefinedFaceLiesOn(const std::array<int,3>& cells_per_dim, int faceIdxInLgr,
const std::shared_ptr<cpgrid::CpGridData>& elemLgr_ptr,
int elemLgr) const;

/// --------------- Auxiliary methods to support Adaptivity (end) ---------------

/// @brief Check if there are non neighboring connections on blocks of cells selected for refinement.
///
/// @param [in] startIJK_vec Vector of ijk values denoting the start of each block of cells selected for refinement.
/// @param [in] endIJK_vec Vector of ijk values denoting the end of each block of cells selected for refinement.
///
/// @return True if all blocks of cells do not contain any NNCs (non-neighboring-connection).
/// False if there is a block with at least one cell with a NNC.
bool nonNNCsSelectedCellsLGR( const std::vector<std::array<int,3>>& startIJK_vec,
const std::vector<std::array<int,3>>& endIJK_vec) const;

/// @brief Mark selected elements and assign them their corresponding level.
///
/// Given blocks of cells selected for refinement, Mark selected elements and assign them their corresponding
/// (refined) level (grid). When level zero grid is distributed before refinement, detect which LGRs are active
/// in each process.
///
/// @param [in] startIJK_vec Vector of ijk values denoting the start of each block of cells selected for refinement.
/// @param [in] endIJK_vec Vector of ijk values denoting the end of each block of cells selected for refinement.
/// @param [out] assignRefinedLevel Assign level for the refinement of each marked cell. Example: refined element from
/// LGR1 have level 1, refined element rfom LGR2 have level 2, etc.
/// @param [out] lgr_with_at_least_one_active_cell Determine if an LGR is not empty in a given process, we set
/// lgr_with_at_least_one_active_cell[in that level] to 1 if it contains
/// at least one active cell, and to 0 otherwise.
void markElemAssignLevelDetectActiveLgrs(const std::vector<std::array<int,3>>& startIJK_vec,
const std::vector<std::array<int,3>>& endIJK_vec,
std::vector<int>& assignRefinedLevel,
std::vector<int>& lgr_with_at_least_one_active_cell);

/// @brief Predict minimum cell and point global ids per process.
///
/// Predict how many new cells/points (born in refined level grids) need new globalIds, so we can assign unique
/// new ids ( and anticipate the maximum). At this point, the grid is already refined according to the LGR specification.
///
/// @param [in] assignRefinedLevel Assign level for the refinement of each marked cell. Example: refined element from
/// LGR1 have level 1, refined element rfom LGR2 have level 2, etc.
/// @param [in] cells_per_dim_vec Total child cells in each direction (x-,y-, and z-direction) per block of cells.
/// @param [in] lgr_with_at_least_one_active_cell Determine if an LGR is not empty in a given process:
/// lgr_with_at_least_one_active_cell[level] = 1 if it contains
/// at least one active cell in the current process, and 0 otherwise.
/// @param [out] min_globalId_cell_in_proc
/// @param [out] min_globalId_point_in_proc
void predictMinCellAndPointGlobalIdPerProcess(const std::vector<int>& assignRefinedLevel,
const std::vector<std::array<int,3>>& cells_per_dim_vec,
const std::vector<int>& lgr_with_at_least_one_active_cell,
int& min_globalId_cell_in_proc,
int& min_globalId_point_in_proc) const;

/// @brief Assign cell global ids of new born cell from refined level grids. Assign 'candidate' point global ids
/// for points in refined level grids.
///
/// @param [out] localToGlobal_cells_per_level Relation local element.index() to assigned cell global id.
/// @param [out] localToGlobal_points_per_level Relation local point.index() to assigned 'candidate' global id.
/// @param [in] min_globalId_cell_in_proc Minimum cell global id per process.
/// @param [in] min_globalId_point_in_proc Minimum point global id per process.
/// @param [in] cells_per_dim_vec Total child cells in each direction (x-,y-, and z-direction) per block of cells.
void assignCellIdsAndCandidatePointIds( std::vector<std::vector<int>>& localToGlobal_cells_per_level,
std::vector<std::vector<int>>& localToGlobal_points_per_level,
int min_globalId_cell_in_proc,
int min_globalId_point_in_proc,
const std::vector<std::array<int,3>>& cells_per_dim_vec) const;

/// @brief Select and re-write point global ids.
///
/// After assigning global IDs to points in refined-level grids, a single point may have
/// "multiple unique" global IDs, one in each process to which it belongs.
/// To reduce the unnucesary id assigments, since global IDs must be distinct across the global leaf view
/// and consistent across each refined-level grid, we will rewrite the entries in
/// localToGlobal_points_per_level. Using cell_to_point_ across all refined cells through
/// communication: gathering the 8 corner points of each interior cell and scattering the
/// 8 corner points of overlapping cells, for all child cells of a parent cell in level zero grid.
///
/// @param [out] localToGlobal_points_per_level Relation local point.index() to assigned 'candidate' global id.
/// @param [in] parent_to_children The communication step is based on level zero grid, via the relation parent-children-cells.
/// @param [in] cells_per_dim_vec Total child cells in each direction (x-,y-, and z-direction) per block of cells.
void selectWinnerPointIds(std::vector<std::vector<int>>& localToGlobal_points_per_level,
const std::vector<std::tuple<int,std::vector<int>>>& parent_to_children,
const std::vector<std::array<int,3>>& cells_per_dim_vec) const;

/// @brief For a grid whose level zero has been distributed and then locally refined, populate the cell_index_set_ of each refined level grid.
void populateCellIndexSetRefinedGrid(int level);

/// @brief For a grid whose level zero has been distributed and then locally refined, populate the cell_index_set_ of the leaf grid view.
void populateCellIndexSetLeafGridView();

/// @brief For a grid whose level zero has been distributed and then locally refined, populate the global_id_set_ of the leaf grid view.
void populateLeafGlobalIdSet();

public:

/// @brief Compute for each level grid, a map from the global_cell_[ cell index in level grid ] to the leaf index of the equivalent cell
Expand Down
Loading

0 comments on commit ec75718

Please sign in to comment.