Attaching data to grid entities¶
Most numerical codes need arrays of values attached to grid entities (for example per-cell coefficients, per-face fluxes, or per-vertex data). This page introduces index sets, id sets, and mappers for this task.
Learning goals
After this page, you should be able to:
- use
indexSetto store data in contiguous vectors, - distinguish
indexSetfromidSet, - use
MultipleCodimMultipleGeomTypeMapperfor mixed geometry types and multiple codimensions.
Index set vs id set¶
For a grid view gv:
const auto& indexSet = gv.indexSet();
const auto& idSet = grid.globalIdSet();
indexSetgives consecutive, zero-based indices for entities in a view,idSetgives globally unique ids, intended to stay persistent under grid changes.
Important detail:
indexSet numbering is defined per codimension and geometry-type class.
In mixed 2D grids, triangles and quads are therefore numbered independently.
If you need one contiguous numbering across both types, use a mapper.
Typical size queries with indexSet:
indexSet.size(0); // elements
indexSet.size(1); // codim-1 entities
indexSet.size(dim); // vertices
Data attached with indexSet¶
For edge-based data in 2D (codim 1):
std::vector<double> edgeLengths(indexSet.size(1), 0.0);
for (const auto& edge : edges(gv))
edgeLengths[indexSet.index(edge)] = edge.geometry().volume();
This is the standard fast storage pattern for many assembly/data loops.
Data attached with a mapper¶
MultipleCodimMultipleGeomTypeMapper creates contiguous indices for selected subsets.
For element-based data:
using Mapper = Dune::MultipleCodimMultipleGeomTypeMapper<GridView>;
Mapper elementMapper(gv, Dune::mcmgElementLayout());
std::vector<double> cellValue(elementMapper.size(), 0.0);
for (const auto& e : elements(gv))
cellValue[elementMapper.index(e)] = e.geometry().center().two_norm();
This pattern is useful if the subset is more specific than plain codim sizes.
One contiguous container over multiple codimensions¶
Mappers are also useful if one container should hold data for several codimensions, for example elements and edges together:
const Dune::MCMGLayout elementAndEdgeLayout = [](Dune::GeometryType gt, int griddim) {
const auto gridDim = static_cast<unsigned int>(griddim);
return (gt.dim() == gridDim) || (gt.dim() + 1 == gridDim);
};
Mapper mixedMapper(gv, elementAndEdgeLayout);
std::vector<double> mixedData(mixedMapper.size(), 0.0);
Here mixedMapper.index(entity) maps all selected entities into a single
contiguous index range, independent of codimension and geometry type.
Runnable example: examples/07_grid_data/grid_data.cc
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | |
Build and run:
source _env/activate.sh
cd examples/07_grid_data
dunecontrol --current all
./build/debug/example07
Output:
elements: 12
edges: 31
vertices: 20
unique vertex ids: 20
mixed mapper size (elements + edges): 43
sum of edge lengths: 9.000000
sum of mapped cell values: 9.111313
sum of mixed data: 74.000000
Summary and next steps¶
You now have the core data-attachment tools used in practical DUNE codes. Continue with Grid hierarchy and refinement, then Integrating functions on a grid.