Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit c828f5f

Browse files
hnilbska
authored andcommittedFeb 20, 2025·
Add Experimental Edge Conformal CPG Processing Mode
Initially supported fully only for the 'UnstructuredGrid' (create_grid_cornerpoint() constructor, PolyhedralGrid wrapper), this commit introduces amended logic that aims to create edge conformal cell complexes. Specifically, the faces of the 'processed_grid' structure from 'process_grdecl()' contains *all* vertices along the pillars, not just the top and bottom vertices of the traditional corner-point description. Moreover, the create_grid_cornerpoint() will insert additional vertices in the top and bottom *faces* when the edge conformal mode is activated. This aspect is not yet available in the CpGrid wrapper, though the vertices along the pillars will be included in that case too. Client code may activate this mode by setting the 'edge_conformal' flag to 'true'. The flag is a bool (i.e., _Bool) in both the C and the C++ code, but transmitted as an 'int' across the language boundary. At this time, the mode is intended to support geo-mechanical workflows and should typically not be enabled in production runs of regular reservoir simulations. While here, split some long lines and mark objects 'const' where possible.
1 parent b1c83c3 commit c828f5f

18 files changed

+1264
-412
lines changed
 

‎CMakeLists_files.cmake

+2
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ list (APPEND MAIN_SOURCE_FILES
5858
opm/grid/cornerpoint_grid.c
5959
opm/grid/cpgpreprocess/facetopology.c
6060
opm/grid/cpgpreprocess/geometry.c
61+
opm/grid/cpgpreprocess/make_edge_conformal.cpp
6162
opm/grid/cpgpreprocess/preprocess.c
6263
opm/grid/cpgpreprocess/uniquepoints.c
6364
opm/grid/UnstructuredGrid.c
@@ -247,6 +248,7 @@ list (APPEND PUBLIC_HEADER_FILES
247248
opm/grid/cornerpoint_grid.h
248249
opm/grid/cpgpreprocess/facetopology.h
249250
opm/grid/cpgpreprocess/geometry.h
251+
opm/grid/cpgpreprocess/make_edge_conformal.hpp
250252
opm/grid/cpgpreprocess/preprocess.h
251253
opm/grid/cpgpreprocess/uniquepoints.h
252254
opm/grid/transmissibility/trans_tpfa.h

‎opm/grid/CpGrid.hpp

+98-41
Original file line numberDiff line numberDiff line change
@@ -224,58 +224,115 @@ namespace Dune
224224
#if HAVE_ECL_INPUT
225225
/// Read the Eclipse grid format ('grdecl').
226226
///
227-
/// \return Vector of global indices to the cells which have
228-
/// been removed in the grid processing due to small pore volume. Function only returns
229-
/// indices on rank 0, the vector is empty of other ranks.
230-
/// \param ecl_grid the high-level object from opm-parser which represents the simulation's grid
231-
/// In a parallel run this may be a nullptr on all ranks but rank zero.
232-
/// \param ecl_state the object from opm-parser provide information regarding to pore volume, NNC,
233-
/// aquifer information when ecl_state is available. NNC and aquifer connection
234-
/// information will also be updated during the function call when available and necessary.
235-
/// \param periodic_extension if true, the grid will be (possibly) refined, so that
236-
/// intersections/faces along i and j boundaries will match those on the other
237-
/// side. That is, i- faces will match i+ faces etc.
238-
/// \param turn_normals if true, all normals will be turned. This is intended for handling inputs with wrong orientations.
239-
/// \param clip_z if true, the grid will be clipped so that the top and bottom will be planar.
240-
/// \param pinchActive Force specific pinch behaviour. If true a face will connect two vertical cells, that are
241-
/// topological connected, even if there are cells with zero volume between them. If false these
242-
/// cells will not be connected despite their faces coinciding.
227+
/// \return Vector of global indices to the cells which have been
228+
/// removed in the grid processing due to small pore volume.
229+
/// Function only returns indices on rank 0, the vector is empty of
230+
/// other ranks.
231+
///
232+
/// \param[in] ecl_grid the high-level object from opm-parser which
233+
/// represents the simulation's grid. In a parallel run this may be
234+
/// a nullptr on all ranks but rank zero.
235+
///
236+
/// \param[in,out] ecl_state the object from opm-parser provide
237+
/// information regarding to pore volume, NNC, aquifer information
238+
/// when ecl_state is available. NNC and aquifer connection
239+
/// nformation will also be updated during the function call when
240+
/// available and necessary.
241+
///
242+
/// \param[in] periodic_extension Whether or not to process the
243+
/// resulting grid in order to have intersections/faces along i and
244+
/// j boundaries match those on the other side. That is, i- faces
245+
/// will match i+ faces etc.
246+
///
247+
/// \param[in] turn_normals Whether or not to turn all normals.
248+
/// This is intended for handling inputs with wrong orientations.
249+
///
250+
/// \param[in] clip_z Whether or not to clip the result grid in
251+
/// order to have planar top and bottom surfaces.
252+
///
253+
/// \param[in] pinchActive Whether or not to force specific pinch
254+
/// behaviour. If set, a face will connect two vertical cells, that
255+
/// are topological connected, even if there are cells with zero
256+
/// volume between them. If false these cells will not be connected
257+
/// despite their faces coinciding.
258+
///
259+
/// \param[in] edge_conformal Whether or not to construct an
260+
/// edge-conformal grid. Typically useful in geo-mechanical
261+
/// applications.
243262
std::vector<std::size_t>
244263
processEclipseFormat(const Opm::EclipseGrid* ecl_grid,
245264
Opm::EclipseState* ecl_state,
246-
bool periodic_extension, bool turn_normals, bool clip_z,
247-
bool pinchActive);
265+
bool periodic_extension,
266+
bool turn_normals,
267+
bool clip_z,
268+
bool pinchActive,
269+
bool edge_conformal);
248270

249271
/// Read the Eclipse grid format ('grdecl').
250272
///
251-
/// Pinch behaviour is determind from the parameter ecl_grid. If ecl_grid is a nullptr or PINCH was specified for
252-
/// the grid, then a face will connect two vertical cells, that are topological connected, even if there are
253-
/// cells with zero volume between them, Otherwise these cells will not be connected despite their faces coinciding.
254-
///
255-
/// \return Vector of global indices to the cells which have
256-
/// been removed in the grid processing due to small pore volume. Function only returns
257-
/// indices on rank 0, the vector is empty of other ranks.
258-
/// \param ecl_grid the high-level object from opm-parser which represents the simulation's grid
259-
/// In a parallel run this may be a nullptr on all ranks but rank zero.
260-
/// \param ecl_state the object from opm-parser provide information regarding to pore volume, NNC,
261-
/// aquifer information when ecl_state is available. NNC and aquifer connection
262-
/// information will also be updated during the function call when available and necessary.
263-
/// \param periodic_extension if true, the grid will be (possibly) refined, so that
264-
/// intersections/faces along i and j boundaries will match those on the other
265-
/// side. That is, i- faces will match i+ faces etc.
266-
/// \param turn_normals if true, all normals will be turned. This is intended for handling inputs with wrong orientations.
267-
/// \param clip_z if true, the grid will be clipped so that the top and bottom will be planar.
273+
/// Pinch behaviour is determind from the parameter ecl_grid. If
274+
/// ecl_grid is a nullptr or PINCH was specified for the grid, then
275+
/// a face will connect two vertical cells, that are topological
276+
/// connected, even if there are cells with zero volume between
277+
/// them, Otherwise these cells will not be connected despite their
278+
/// faces coinciding.
279+
///
280+
/// \return Vector of global indices to the cells which have been
281+
/// removed in the grid processing due to small pore
282+
/// volume. Function only returns indices on rank 0, the vector is
283+
/// empty of other ranks.
284+
///
285+
/// \param[in] ecl_grid the high-level object from opm-parser which
286+
/// represents the simulation's grid. In a parallel run this may be
287+
/// a nullptr on all ranks but rank zero.
288+
///
289+
/// \param[in,out] ecl_state the object from opm-parser provide
290+
/// information regarding to pore volume, NNC, aquifer information
291+
/// when ecl_state is available. NNC and aquifer connection
292+
/// nformation will also be updated during the function call when
293+
/// available and necessary.
294+
///
295+
/// \param[in] periodic_extension Whether or not to process the
296+
/// resulting grid in order to have intersections/faces along i and
297+
/// j boundaries match those on the other side. That is, i- faces
298+
/// will match i+ faces etc.
299+
///
300+
/// \param[in] turn_normals Whether or not to turn all normals.
301+
/// This is intended for handling inputs with wrong orientations.
302+
///
303+
/// \param[in] clip_z Whether or not to clip the result grid in
304+
/// order to have planar top and bottom surfaces.
305+
///
306+
/// \param[in] edge_conformal Whether or not to construct an
307+
/// edge-conformal grid. Typically useful in geo-mechanical
308+
/// applications.
268309
std::vector<std::size_t>
269310
processEclipseFormat(const Opm::EclipseGrid* ecl_grid,
270311
Opm::EclipseState* ecl_state,
271-
bool periodic_extension, bool turn_normals = false, bool clip_z = false);
272-
273-
#endif
312+
bool periodic_extension,
313+
bool turn_normals = false,
314+
bool clip_z = false,
315+
bool edge_conformal = false);
316+
#endif // HAVE_ECL_INPUT
274317

275318
/// Read the Eclipse grid format ('grdecl').
276-
/// \param input_data the data in grdecl format, declared in preprocess.h.
277-
/// \param remove_ij_boundary if true, will remove (i, j) boundaries. Used internally.
278-
void processEclipseFormat(const grdecl& input_data, bool remove_ij_boundary, bool turn_normals = false);
319+
///
320+
/// \param[in] input_data the data in grdecl format, declared in
321+
/// preprocess.h.
322+
///
323+
/// \param[in] remove_ij_boundary if true, will remove (i, j)
324+
/// boundaries. Used internally.
325+
///
326+
/// \param[in] turn_normals if true, all normals will be turned. This is
327+
/// intended for handling inputs with wrong orientations.
328+
///
329+
/// \param[in] edge_conformal Whether or not to construct an
330+
/// edge-conformal grid. Typically useful in geo-mechanical
331+
/// applications.
332+
void processEclipseFormat(const grdecl& input_data,
333+
bool remove_ij_boundary,
334+
bool turn_normals = false,
335+
bool edge_conformal = false);
279336

280337
//@}
281338

‎opm/grid/GridManager.cpp

+10-7
Original file line numberDiff line numberDiff line change
@@ -40,18 +40,20 @@ namespace Opm
4040

4141
#if HAVE_ECL_INPUT
4242
/// Construct a 3d corner-point grid from a deck.
43-
GridManager::GridManager(const Opm::EclipseGrid& inputGrid)
43+
GridManager::GridManager(const Opm::EclipseGrid& inputGrid,
44+
const bool edge_conformal)
4445
: ug_(0)
4546
{
46-
initFromEclipseGrid(inputGrid, std::vector<double>());
47+
initFromEclipseGrid(inputGrid, std::vector<double>(), edge_conformal);
4748
}
4849

4950

5051
GridManager::GridManager(const Opm::EclipseGrid& inputGrid,
51-
const std::vector<double>& poreVolumes)
52+
const std::vector<double>& poreVolumes,
53+
const bool edge_conformal)
5254
: ug_(0)
5355
{
54-
initFromEclipseGrid(inputGrid, poreVolumes);
56+
initFromEclipseGrid(inputGrid, poreVolumes, edge_conformal);
5557
}
5658
#endif
5759

@@ -133,9 +135,10 @@ namespace Opm
133135
#if HAVE_ECL_INPUT
134136
// Construct corner-point grid from EclipseGrid.
135137
void GridManager::initFromEclipseGrid(const Opm::EclipseGrid& inputGrid,
136-
const std::vector<double>& poreVolumes)
138+
const std::vector<double>& poreVolumes,
139+
const bool edge_conformal)
137140
{
138-
struct grdecl g;
141+
grdecl g{};
139142

140143
g.dims[0] = inputGrid.getNX();
141144
g.dims[1] = inputGrid.getNY();
@@ -166,7 +169,7 @@ namespace Opm
166169
actnum, opmfil, zcorn.data());
167170
}
168171

169-
ug_ = create_grid_cornerpoint(&g, z_tolerance);
172+
ug_ = create_grid_cornerpoint(&g, z_tolerance, edge_conformal);
170173
if (!ug_) {
171174
OPM_THROW(std::runtime_error, "Failed to construct grid.");
172175
}

‎opm/grid/GridManager.hpp

+6-3
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,17 @@ class EclipseGrid;
4747

4848
#if HAVE_ECL_INPUT
4949
/// Construct a grid from an EclipseState::EclipseGrid instance.
50-
explicit GridManager(const EclipseGrid& inputGrid);
50+
explicit GridManager(const EclipseGrid& inputGrid,
51+
bool edge_conformal = false);
5152

5253
/// Construct a grid from an EclipseState::EclipseGrid instance,
5354
/// giving an explicit set of pore volumes to be used for MINPV
5455
/// considerations.
5556
/// \input[in] eclipseGrid encapsulates a corner-point grid given from a deck
5657
/// \input[in] poreVolumes one element per logical cartesian grid element
5758
GridManager(const EclipseGrid& inputGrid,
58-
const std::vector<double>& poreVolumes);
59+
const std::vector<double>& poreVolumes,
60+
bool edge_conformal);
5961
#endif
6062

6163
/// Construct a 2d cartesian grid with cells of unit size.
@@ -92,7 +94,8 @@ class EclipseGrid;
9294
#if HAVE_ECL_INPUT
9395
// Construct corner-point grid from EclipseGrid.
9496
void initFromEclipseGrid(const EclipseGrid& inputGrid,
95-
const std::vector<double>& poreVolumes);
97+
const std::vector<double>& poreVolumes,
98+
bool edge_conformal);
9699
#endif
97100

98101
// The managed UnstructuredGrid.

0 commit comments

Comments
 (0)
Please sign in to comment.