Skip to content

Commit c2c18c1

Browse files
committed
Store a variant in the geometry
To avoid copying a shared pointer, which is rather costly, the geometry now stores a variant holding either the ownership or a non-owning view to the entity variable. In the case of entity variables owned by the grid, a non-owning storage is fine as the geometry should not outlive the grid. On grid refinement the grid points are only owned by the geometry, so a move into the geometry is preferred.
1 parent a771513 commit c2c18c1

6 files changed

Lines changed: 60 additions & 28 deletions

File tree

opm/grid/cpgrid/CpGrid.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3845,7 +3845,7 @@ void CpGrid::populateLeafGridCells(Dune::cpgrid::EntityVariableBase<cpgrid::Geom
38453845

38463846
// Create a pointer to the first element of "adapted_cell_to_point" (required as the fourth argement to construct a Geometry<3,3> type object).
38473847
int* indices_storage_ptr = adapted_cell_to_point[cell].data();
3848-
adapted_cells[cell] = cpgrid::Geometry<3,3>(cellGeom.center(), cellGeom.volume(), allCorners, indices_storage_ptr);
3848+
adapted_cells[cell] = cpgrid::Geometry<3,3>(cellGeom.center(), cellGeom.volume(), allCorners.get(), indices_storage_ptr);
38493849
} // adapted_cells
38503850

38513851
// Adapted/Leaf-grid-view face to cell.
@@ -3966,7 +3966,7 @@ void CpGrid::populateRefinedCells(std::vector<Dune::cpgrid::EntityVariableBase<c
39663966

39673967
// Create a pointer to the first element of "refined_cell_to_point" (required as the fourth argement to construct a Geometry<3,3> type object).
39683968
int* indices_storage_ptr = refined_cell_to_point_vec[shiftedLevel][cell].data();
3969-
refined_cells_vec[shiftedLevel][cell] = cpgrid::Geometry<3,3>(elemLgrGeom.center(), elemLgrGeom.volume(), allLevelCorners, indices_storage_ptr);
3969+
refined_cells_vec[shiftedLevel][cell] = cpgrid::Geometry<3,3>(elemLgrGeom.center(), elemLgrGeom.volume(), allLevelCorners.get(), indices_storage_ptr);
39703970
} // refined_cells
39713971
// Refined face to cell.
39723972
refined_cell_to_face_vec[shiftedLevel].makeInverseRelation(refined_face_to_cell_vec[shiftedLevel]);

opm/grid/cpgrid/CpGridData.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -535,7 +535,7 @@ struct CellGeometryHandle
535535
buffer.read(pos[i]);
536536

537537
buffer.read(vol);
538-
scatterCont_[t] = Geom(pos, vol, pointGeom_, cell2Points_[t.index()].data());
538+
scatterCont_[t] = Geom(pos, vol, pointGeom_.get(), cell2Points_[t.index()].data());
539539
double isAquifer;
540540
buffer.read(isAquifer);
541541
if (isAquifer == 1.0)
@@ -1577,8 +1577,8 @@ void CpGridData::distributeGlobalGrid(CpGrid& grid,
15771577

15781578
// Compute partition type for points
15791579
computePointPartitionType();
1580-
1581-
computeCommunicationInterfaces(noExistingPoints);
1580+
1581+
computeCommunicationInterfaces(noExistingPoints);
15821582
#else // #if HAVE_MPI
15831583
static_cast<void>(grid);
15841584
static_cast<void>(view_data);
@@ -2065,9 +2065,9 @@ int CpGridData::sharedFaceTag(const std::vector<std::array<int,3>>& startIJK_2Pa
20652065
assert(endIJK_2Patches.size() == 2);
20662066

20672067
int faceTag = -1; // 0 represents I_FACE, 1 J_FACE, and 2 K_FACE. Use -1 for no sharing face case.
2068-
2068+
20692069
if (patchesShareFace(startIJK_2Patches, endIJK_2Patches)) {
2070-
2070+
20712071
const auto& detectSharing = [](const std::vector<int>& faceIdxs, const std::vector<int>& otherFaceIdxs){
20722072
bool faceIsShared = false;
20732073
for (const auto& face : faceIdxs) {
@@ -2080,7 +2080,7 @@ int CpGridData::sharedFaceTag(const std::vector<std::array<int,3>>& startIJK_2Pa
20802080
}
20812081
return faceIsShared; // should be false here
20822082
};
2083-
2083+
20842084
const auto& [iFalse, iTrue, jFalse, jTrue, kFalse, kTrue] = this->getBoundaryPatchFaces(startIJK_2Patches[0], endIJK_2Patches[0]);
20852085
const auto& [iFalseOther, iTrueOther, jFalseOther, jTrueOther, kFalseOther, kTrueOther] =
20862086
this->getBoundaryPatchFaces(startIJK_2Patches[1], endIJK_2Patches[1]);
@@ -2306,7 +2306,7 @@ Geometry<3,3> CpGridData::cellifyPatch(const std::array<int,3>& startIJK, const
23062306
const int* cellifiedPatch_indices_storage_ptr = &allcorners_cellifiedPatch[0];
23072307
// Construct (and return) the Geometry<3,3> of the 'cellified patch'.
23082308
return Geometry<3,3>(cellifiedPatch_center, cellifiedPatch_volume,
2309-
cellifiedPatch_geometry.geomVector(std::integral_constant<int,3>()),
2309+
cellifiedPatch_geometry.geomVector(std::integral_constant<int,3>()).get(),
23102310
cellifiedPatch_indices_storage_ptr);
23112311
}
23122312
}
@@ -2699,7 +2699,7 @@ bool CpGridData::preAdapt()
26992699
if (local_empty)
27002700
mark_.resize(size(0));
27012701
}
2702-
2702+
27032703
// Detect the maximum mark across processes, and rewrite
27042704
// the local entry in mark_, i.e.,
27052705
// mark_[ element.index() ] = max{ local marks in processes where this element belongs to}.

opm/grid/cpgrid/Entity.hpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -539,10 +539,9 @@ Dune::cpgrid::Geometry<3,3> Dune::cpgrid::Entity<codim>::geometryInFather() cons
539539
const auto& auxArr = pgrid_ -> getReferenceRefinedCorners(idx_in_parent_cell, cells_per_dim);
540540
FieldVector<double, 3> corners_in_father_reference_elem_temp[8] =
541541
{ auxArr[0], auxArr[1], auxArr[2], auxArr[3], auxArr[4], auxArr[5], auxArr[6], auxArr[7]};
542-
auto in_father_reference_elem_corners = std::make_shared<EntityVariable<cpgrid::Geometry<0, 3>, 3>>();
543-
EntityVariableBase<cpgrid::Geometry<0, 3>>& mutable_in_father_reference_elem_corners = *in_father_reference_elem_corners;
542+
EntityVariable<cpgrid::Geometry<0, 3>, 3> in_father_reference_elem_corners;
544543
// Assign the corners. Make use of the fact that pointers behave like iterators.
545-
mutable_in_father_reference_elem_corners.assign(corners_in_father_reference_elem_temp,
544+
in_father_reference_elem_corners.assign(corners_in_father_reference_elem_temp,
546545
corners_in_father_reference_elem_temp + 8);
547546
// Compute the center of the 'local-entity'.
548547
Dune::FieldVector<double, 3> center_in_father_reference_elem = {0., 0.,0.};
@@ -556,7 +555,7 @@ Dune::cpgrid::Geometry<3,3> Dune::cpgrid::Entity<codim>::geometryInFather() cons
556555
double volume_in_father_reference_elem = double(1)/(cells_per_dim[0]*cells_per_dim[1]*cells_per_dim[2]);
557556
// Construct (and return) the Geometry<3,3> of 'child-cell in the reference element of its father (unit cube)'.
558557
return Dune::cpgrid::Geometry<3,3>(center_in_father_reference_elem, volume_in_father_reference_elem,
559-
in_father_reference_elem_corners, in_father_reference_elem_corner_indices.data());
558+
std::move(in_father_reference_elem_corners), in_father_reference_elem_corner_indices.data());
560559
}
561560
else {
562561
OPM_THROW(std::logic_error, "Entity has no father.");

opm/grid/cpgrid/Geometry.hpp

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,13 @@
3838
#define OPM_GEOMETRY_HEADER
3939

4040
#include <cmath>
41+
#include <variant>
4142

4243
// Warning suppression for Dune includes.
4344
#include <opm/grid/utility/platform_dependent/disable_warnings.h>
4445

4546
#include <dune/common/version.hh>
47+
#include <dune/common/overloadset.hh>
4648
#include <dune/geometry/referenceelements.hh>
4749
#include <dune/grid/common/geometry.hh>
4850

@@ -405,6 +407,10 @@ namespace Dune
405407

406408
/// @brief Construct from center, volume (1- and 0-moments) and
407409
/// corners.
410+
/// @warning This constructor does not own the corners or indices,
411+
/// thus, the pointers must remain valid for the lifetime of
412+
/// the Geometry object.
413+
///
408414
/// @param pos the centroid of the entity
409415
/// @param vol the volume(area) of the entity
410416
/// @param allcorners pointer of all corner positions in the grid
@@ -413,17 +419,34 @@ namespace Dune
413419
/// by (kji), i.e. i running fastest.
414420
Geometry(const GlobalCoordinate& pos,
415421
ctype vol,
416-
std::shared_ptr<const EntityVariable<cpgrid::Geometry<0, 3>, 3>> allcorners_ptr,
422+
EntityVariable<cpgrid::Geometry<0, 3>, 3> const * allcorners_view,
417423
const int* corner_indices)
418424
: pos_(pos), vol_(vol),
419-
allcorners_(allcorners_ptr), cor_idx_(corner_indices)
425+
allcorners_(allcorners_view), cor_idx_(corner_indices)
420426
{
421-
assert(allcorners_ && corner_indices);
427+
assert(allcorners_view && corner_indices);
422428
}
423429

430+
/// @brief Construct from center, volume (1- and 0-moments) and
431+
/// corners.
432+
///
433+
/// @param pos the centroid of the entity
434+
/// @param vol the volume(area) of the entity
435+
/// @param allcorners pointer of all corner positions in the grid
436+
/// @param corner_indices array of 8 indices into allcorners. The
437+
/// indices must be given in lexicographical order
438+
/// by (kji), i.e. i running fastest.
439+
Geometry(const GlobalCoordinate& pos,
440+
ctype vol,
441+
const EntityVariable<cpgrid::Geometry<0, 3>, 3>& allcorners_storage,
442+
const int* corner_indices)
443+
: pos_(pos), vol_(vol),
444+
allcorners_(allcorners_storage), cor_idx_(corner_indices)
445+
{}
446+
424447
/// Default constructor, giving a non-valid geometry.
425448
Geometry()
426-
: pos_(0.0), vol_(0.0), allcorners_(0), cor_idx_(0)
449+
: pos_(0.0), vol_(0.0), allcorners_(nullptr), cor_idx_(nullptr)
427450
{
428451
}
429452

@@ -511,8 +534,16 @@ namespace Dune
511534
/// @brief Get the cor-th of 8 corners of the hexahedral base cell.
512535
GlobalCoordinate corner(int cor) const
513536
{
514-
assert(allcorners_ && cor_idx_);
515-
return (allcorners_->data())[cor_idx_[cor]].center();
537+
return std::visit(
538+
Dune::overload(
539+
[](const EntityVariable<Geometry<0, 3>, 3>& corners) -> const EntityVariable<Geometry<0, 3>, 3>& {
540+
return corners;
541+
},
542+
[](EntityVariable<Geometry<0, 3>, 3> const * corners) -> const EntityVariable<Geometry<0, 3>, 3>& {
543+
return *corners;
544+
}
545+
), allcorners_
546+
).data()[cor_idx_[cor]].center();
516547
}
517548

518549
/// Cell volume.
@@ -1022,7 +1053,7 @@ namespace Dune
10221053
refined_cells[refined_cell_idx] =
10231054
Geometry<3,cdim>(refined_cell_center,
10241055
refined_cell_volume,
1025-
all_geom.geomVector(std::integral_constant<int,3>()),
1056+
all_geom.geomVector(std::integral_constant<int,3>()).get(),
10261057
indices_storage_ptr);
10271058
} // end i-for-loop
10281059
} // end j-for-loop
@@ -1043,8 +1074,10 @@ namespace Dune
10431074
private:
10441075
GlobalCoordinate pos_;
10451076
double vol_;
1046-
std::shared_ptr<const EntityVariable<Geometry<0, 3>,3>> allcorners_; // For dimension 3 only
1047-
const int* cor_idx_; // For dimension 3 only
1077+
1078+
// store either a (view) pointer or the variable itself. For dimension 3 only
1079+
std::variant<EntityVariable<Geometry<0, 3>,3> const *, EntityVariable<Geometry<0, 3>,3>> allcorners_;
1080+
int const * cor_idx_; // For dimension 3 only
10481081

10491082
/// @brief
10501083
/// Auxiliary function to get refined_face information: tag, index, face_to_point_, face_to_cell, face centroid,

opm/grid/cpgrid/processEclipseFormat.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1223,7 +1223,7 @@ namespace cpgrid
12231223
double vol,
12241224
const std::array<int,8>& corner_indices)
12251225
{
1226-
return cpgrid::Geometry<3, 3>(pos, vol, allcorners_, &corner_indices[0]);
1226+
return cpgrid::Geometry<3, 3>(pos, vol, allcorners_.get(), &corner_indices[0]);
12271227
}
12281228
};
12291229

tests/cpgrid/geometry_test.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ BOOST_AUTO_TEST_CASE(cellgeom)
152152
}
153153

154154
int cor_idx[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
155-
Geometry g(c, v, pg, cor_idx);
155+
Geometry g(c, v, pg.get(), cor_idx);
156156

157157
// Verification of properties.
158158
BOOST_CHECK(g.type().isCube());
@@ -206,7 +206,7 @@ BOOST_AUTO_TEST_CASE(cellgeom)
206206
{
207207
(*pg1).push_back(cpgrid::Geometry<0, 3>(crn));
208208
}
209-
g = Geometry(c, v, pg1, cor_idx);
209+
g = Geometry(c, v, pg1.get(), cor_idx);
210210

211211
// Verification of properties.
212212
BOOST_CHECK(g.type().isCube());
@@ -525,7 +525,7 @@ BOOST_AUTO_TEST_CASE(refine_simple_cube)
525525
}
526526

527527
int cor_idx[8] = {0, 1, 2, 3, 4, 5, 6, 7};
528-
Geometry g(c, v, pg, cor_idx);
528+
Geometry g(c, v, pg.get(), cor_idx);
529529

530530
refine_and_check(g, {1, 1, 1}, true);
531531
refine_and_check(g, {2, 3, 4}, true);
@@ -567,7 +567,7 @@ BOOST_AUTO_TEST_CASE(refine_distorted_cube)
567567
}
568568

569569
int cor_idx[8] = {0, 1, 2, 3, 4, 5, 6, 7};
570-
Geometry g(center, v, pg, cor_idx);
570+
Geometry g(center, v, pg.get(), cor_idx);
571571
refine_and_check(g, {1, 1, 1});
572572
refine_and_check(g, {2, 3, 4});
573573

0 commit comments

Comments
 (0)