Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve refinement and partially support adaptivity for CpGrid #723

Merged
merged 1 commit into from
Jun 27, 2024

Conversation

aritorto
Copy link
Member

@aritorto aritorto commented May 23, 2024

This PR

Cells can be marked for refinement, without any assumption on the shape of the total cells to be refined. Previously, only a block of cells.

The adapted grid is the mix of coarse cells (not involved in refinement) and the refined entities.

Copy link
Member

@blattms blattms left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work!
I will try to do this review iteratively. This is the review of CpGridData.cpp

opm/grid/CpGrid.hpp Outdated Show resolved Hide resolved
// Refined cells in parent cell: k*cells_per_dim[0]*cells_per_dim[1] + j*cells_per_dim[0] + i
std::array<int,3> ijk = {0,0,0};
ijk[0] = idxInParentCell % cells_per_dim[0];
idxInParentCell -= ijk[0]; // k*cells_per_dim[0]*cells_per_dim[1] + j*cells_per_dim[0]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick:
The subtractions don't hurt, but I think they are not needed.
Integer devision should make sure that (M+n)/N == M/N holds for n<N and M being a multiple of N.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I skip this one for now, might come back once I'm done with the other comments

opm/grid/cpgrid/CpGridData.cpp Outdated Show resolved Hide resolved
opm/grid/cpgrid/CpGridData.cpp Show resolved Hide resolved
opm/grid/cpgrid/CpGridData.cpp Outdated Show resolved Hide resolved
opm/grid/cpgrid/CpGridData.cpp Show resolved Hide resolved
opm/grid/cpgrid/CpGridData.cpp Outdated Show resolved Hide resolved
opm/grid/cpgrid/CpGridData.cpp Outdated Show resolved Hide resolved
opm/grid/cpgrid/CpGridData.cpp Outdated Show resolved Hide resolved
opm/grid/cpgrid/CpGridData.cpp Show resolved Hide resolved
Copy link
Member

@blattms blattms left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Next batch of comments. Still two files to comment on.

{
const auto& elem = Dune::cpgrid::Entity<0>(*(coarse_grid.chooseData()[startingGridIdx]), elemIdx, true);
coarse_grid.mark(1, elem);
coarse_grid.getMark(elem);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line could be removed. The check of the return value is 2 lines below, anyway.

Comment on lines 139 to 142
auto equiv_cell_iter = blockRefinement_leaf.geomVector<3>().begin();
while (cell.center() != equiv_cell_iter->center()) {
++equiv_cell_iter;
}
CHECK_COORDINATES(cell.center(), equiv_cell_iter->center());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
auto equiv_cell_iter = blockRefinement_leaf.geomVector<3>().begin();
while (cell.center() != equiv_cell_iter->center()) {
++equiv_cell_iter;
}
CHECK_COORDINATES(cell.center(), equiv_cell_iter->center());
auto equiv_cell_iter = std::find_if(blockRefinement_leaf.geomVector<3>().begin(),
blockRefinement_leaf.geomVector<3>().end(),
[center1 = cell.center](const auto& center1){
return center1 == equiv_cell_iter->center())
});
BOOST_CHECK( equiv_cell_iter != blockRefinement_leaf.geomVector<3>().end());

The last line was already checked in the loop.
We should probably allow the centers to differ a bit inside of the lambda and use some tolerance when comparing.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had some trouble with that lambda, but I did add the check of the iterator not being at the end.

CHECK_COORDINATES(cell.center(), equiv_cell_iter->center());
for(const auto& coord: cell.center())
BOOST_TEST(std::isfinite(coord));
BOOST_CHECK_CLOSE(cell.volume(), equiv_cell_iter->volume(), 1e-6);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could try to lower the tolerance here.

Comment on lines 158 to 166
bool closedCenter = (std::abs(element.geometry().center()[0] - equiv_element_iter->geometry().center()[0]) < 1e-12) &&
(std::abs(element.geometry().center()[1] - equiv_element_iter->geometry().center()[1]) < 1e-12) &&
(std::abs(element.geometry().center()[2] - equiv_element_iter->geometry().center()[2])< 1e-12);

while (!closedCenter) {
++equiv_element_iter;
closedCenter = (std::abs(element.geometry().center()[0] - equiv_element_iter->geometry().center()[0]) < 1e-12) &&
(std::abs(element.geometry().center()[1] - equiv_element_iter->geometry().center()[1]) < 1e-12) &&
(std::abs(element.geometry().center()[2] - equiv_element_iter->geometry().center()[2])< 1e-12);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To make the bullet-proof we should check whether the equiv_element_iter is valid:
while (equiv_element_iter != equiv_grid_view.end<0>() && !closedCenter)

Maybe even use std::find_if from the STL instead like suggested above? The we only need to check the return value of it.

Copy link
Member Author

@aritorto aritorto Jun 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm adding the check that the iterator is not the end one (in many places). With the lambda-expression suggested, I'm having some issues. I postpone that change for now. Thanks!

referenceElem_entity_center[c] /= cells_per_dim[0]*cells_per_dim[1]*cells_per_dim[2];
referenceElem_entity_center_it[c] /= cells_per_dim[0]*cells_per_dim[1]*cells_per_dim[2];
}
BOOST_CHECK_CLOSE(referenceElemOneParent_volume, 1, 1e-6);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could try to tighten the tolerance a bit here. On the other hand the grid is large enough, so there is probably no change for now.

Comment on lines 734 to 737
while (!closedCenter) {
++equiv_element_iter;
closedCenter = (std::abs(element.geometry().center()[0] - equiv_element_iter->geometry().center()[0]) < 1e-12) &&
(std::abs(element.geometry().center()[1] - equiv_element_iter->geometry().center()[1]) < 1e-12) &&
(std::abs(element.geometry().center()[2] - equiv_element_iter->geometry().center()[2])< 1e-12);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment here as for the other test file. Check whether equiv_element_iter is invalid or even better use an STL algorithm,

// To determine that, we track the level of the Entity and
// check if it was marked for refinement in the previos state
// of current_view_data_
return (isLeaf() && hasFather());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed this is WIP but works for only refining once. For multiple refinement we need to do this differently

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually the WIP is accidentally still there. From your comment, I'm assuming I should keep it. Maybe this is also related to my potentially wrong interpretation of preAdapt, adapt, postAdapt...

bool Entity<codim>::mightVanish() const
{
const auto refinementMark = pgrid_ -> getMark(*this);
return (refinementMark == 1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I this tested?
Shouldn't this be `return refinementMark < 0?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is probably again related to my interpretation of how the marking-elements process goes. I assume that when your stating grid is certain_grid with N cells, you marked some element on that grid, let's sat n1< ... < nr < N. Those marked element get mark equal to 1 when they will vanished and replaced by their refined children cells. Is this correct? When the mark is 0 or -1, it means "do nothing" or "coarsening (not supported yet, and in this case, this cell and "all its siblings cells" will vanish)".

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a few comments in some of the places where mightVanish() get tested, in adapted_cpgrid_test.cpp

opm/grid/cpgrid/Entity.hpp Show resolved Hide resolved
opm/grid/cpgrid/Entity.hpp Outdated Show resolved Hide resolved
Copy link
Member

@blattms blattms left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One file to go.

opm/grid/CpGrid.hpp Show resolved Hide resolved
const std::shared_ptr<cpgrid::CpGridData>& elemLgr_ptr) const;

/// @brief Determine if a refined corner is located on the boundary of the single-cell-refinement, and does not coincide with
/// a preApradt-existing corner.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// a preApradt-existing corner.
/// a preAdapt-existing corner.

opm/grid/CpGrid.hpp Outdated Show resolved Hide resolved
opm/grid/CpGrid.hpp Outdated Show resolved Hide resolved
opm/grid/CpGrid.hpp Outdated Show resolved Hide resolved
Copy link
Member

@blattms blattms left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is the next portion of my review.
Last file (CpGrid.cpp) is the largest to review. This is the first part. I am at defineChildToParentAndIdxInParentCell

opm/grid/cpgrid/CpGrid.cpp Outdated Show resolved Hide resolved
Comment on lines 1484 to 1489
if(data_.size()>1) {
// Get the level where the element was born and its index in that level.
const auto& elemLevel = element.level();
const auto& elemInLevel = (elemLevel == 0) ? element.getOrigin() : element.getLevelElem();
// Mark element in its level
data_[elemLevel] -> mark(refCount, elemInLevel);
}
// Mark element (also) in current_view_data_
return current_view_data_-> mark(refCount, element);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't we make sure that CpGridData::mark is written such that it allows us to write (please skip if we can't):

Suggested change
if(data_.size()>1) {
// Get the level where the element was born and its index in that level.
const auto& elemLevel = element.level();
const auto& elemInLevel = (elemLevel == 0) ? element.getOrigin() : element.getLevelElem();
// Mark element in its level
data_[elemLevel] -> mark(refCount, elemInLevel);
}
// Mark element (also) in current_view_data_
return current_view_data_-> mark(refCount, element);
const auto& elemLevel = element.level();
return data_[elemLevel] -> mark(refCount, elemInLevel);

Note that I removed marking on the current_view_data_. Do we need that? If that is the case then please keep it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I skip this comment until we meet and define how to design the adapt process ( in which grid we are allowed to mark elements, etc)


bool CpGrid::adapt()
{
const std::vector<std::array<int,3>>& cells_per_dim_vec = {{3,3,3}}; // Arbitrary chosen values.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think {2, 2, 2} would be more intuitive, at least for me. Might not be the case for others.

Copy link
Member Author

@aritorto aritorto Jun 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's trust in your intuition then :)

const auto& preAdaptMaxLevel = this ->maxLevel();
for (int elemIdx = 0; elemIdx < static_cast<int>(current_view_data_->size(0)); ++elemIdx) {
const auto& element = cpgrid::Entity<0>(*current_view_data_, elemIdx, true);
assignRefinedLevel[elemIdx] = (this->getMark(element) == 1) ? (preAdaptMaxLevel +1) : 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe more future proof for the case of multiple levels.

Suggested change
assignRefinedLevel[elemIdx] = (this->getMark(element) == 1) ? (preAdaptMaxLevel +1) : 0;
assignRefinedLevel[elemIdx] = (this->getMark(element) == 1) ? (element.level() + 1) : element.level();

Note that the purpose of assignRefinedLevel is not 100% clear to me. So I could very well be wrong

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clearer now. It is the level where the kids will be.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great! I'll add this in the list of things to be discussed, just in case

opm/grid/cpgrid/CpGrid.cpp Show resolved Hide resolved
opm/grid/cpgrid/CpGrid.cpp Show resolved Hide resolved
opm/grid/cpgrid/CpGrid.cpp Show resolved Hide resolved
Copy link
Member

@blattms blattms left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Next batch of comments.

I am still in CpGrid.cpp. Now function CpGrid::identifyRefinedCornersPerLevel

opm/grid/cpgrid/CpGrid.cpp Outdated Show resolved Hide resolved
opm/grid/cpgrid/CpGrid.cpp Outdated Show resolved Hide resolved
opm/grid/cpgrid/CpGrid.cpp Outdated Show resolved Hide resolved
opm/grid/cpgrid/CpGrid.cpp Outdated Show resolved Hide resolved
opm/grid/cpgrid/CpGridData.cpp Show resolved Hide resolved
opm/grid/cpgrid/CpGrid.cpp Outdated Show resolved Hide resolved
opm/grid/cpgrid/CpGrid.cpp Outdated Show resolved Hide resolved
opm/grid/cpgrid/CpGrid.cpp Outdated Show resolved Hide resolved
opm/grid/cpgrid/CpGrid.cpp Outdated Show resolved Hide resolved
opm/grid/cpgrid/CpGrid.cpp Outdated Show resolved Hide resolved
Copy link
Member

@blattms blattms left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Next batch.

I still want to check the functions in line 3440 and below (CpGrid::isRefinedCornerInInteriorLgr, etc.).

opm/grid/cpgrid/CpGrid.cpp Outdated Show resolved Hide resolved
opm/grid/cpgrid/CpGrid.cpp Outdated Show resolved Hide resolved
opm/grid/cpgrid/CpGrid.cpp Outdated Show resolved Hide resolved
opm/grid/cpgrid/CpGrid.cpp Show resolved Hide resolved
opm/grid/cpgrid/CpGrid.cpp Show resolved Hide resolved
opm/grid/cpgrid/CpGrid.cpp Outdated Show resolved Hide resolved
opm/grid/cpgrid/CpGrid.cpp Outdated Show resolved Hide resolved
opm/grid/cpgrid/CpGrid.cpp Outdated Show resolved Hide resolved
opm/grid/cpgrid/CpGrid.cpp Outdated Show resolved Hide resolved
opm/grid/cpgrid/CpGrid.cpp Outdated Show resolved Hide resolved
@aritorto
Copy link
Member Author

@blattms many thanks for your valuable feedback! I believe I handled all/most of your comments (being the main: (1) change count-argument with find-approach, and (2) solve the dangling pointers issue via swap).

I would say this PR is ready for a "final review"

@aritorto
Copy link
Member Author

jenkins build this please

opm/grid/cpgrid/CpGrid.cpp Outdated Show resolved Hide resolved
opm/grid/cpgrid/CpGrid.cpp Outdated Show resolved Hide resolved
opm/grid/cpgrid/CpGrid.cpp Outdated Show resolved Hide resolved
opm/grid/cpgrid/CpGrid.cpp Outdated Show resolved Hide resolved
@aritorto
Copy link
Member Author

@blattms Changes are pushed now! Many thanks again!

@aritorto
Copy link
Member Author

jenkins build this please

Copy link
Member

@blattms blattms left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot for the updates.

@aritorto
Copy link
Member Author

jenkins build this please

@blattms blattms merged commit 3912465 into OPM:master Jun 27, 2024
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants