3.2-git
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
discretization/box/fvgridgeometry.hh
Go to the documentation of this file.
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3/*****************************************************************************
4 * See the file COPYING for full copying permissions. *
5 * *
6 * This program is free software: you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation, either version 3 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
18 *****************************************************************************/
26#ifndef DUMUX_DISCRETIZATION_BOX_GRID_FVGEOMETRY_HH
27#define DUMUX_DISCRETIZATION_BOX_GRID_FVGEOMETRY_HH
28
29#include <unordered_map>
30
31#include <dune/geometry/referenceelements.hh>
32#include <dune/localfunctions/lagrange/pqkfactory.hh>
33
42
43namespace Dumux {
44
51template<class GridView, class MapperTraits = DefaultMapperTraits<GridView>>
53: public MapperTraits
54{
57
58 template<class GridGeometry, bool enableCache>
60};
61
68template<class Scalar,
69 class GridView,
70 bool enableGridGeometryCache = false,
73
80template<class Scalar, class GV, class Traits>
81class BoxFVGridGeometry<Scalar, GV, true, Traits>
82: public BaseGridGeometry<GV, Traits>
83{
86 using GridIndexType = typename IndexTraits<GV>::GridIndex;
87 using LocalIndexType = typename IndexTraits<GV>::LocalIndex;
88
89 using Element = typename GV::template Codim<0>::Entity;
90 using CoordScalar = typename GV::ctype;
91 static const int dim = GV::dimension;
92 static const int dimWorld = GV::dimensionworld;
93
94 using ReferenceElements = typename Dune::ReferenceElements<CoordScalar, dim>;
95
96 using GeometryHelper = BoxGeometryHelper<GV, dim,
97 typename Traits::SubControlVolume,
98 typename Traits::SubControlVolumeFace>;
99
100public:
102 static constexpr DiscretizationMethod discMethod = DiscretizationMethod::box;
103
105 using LocalView = typename Traits::template LocalView<ThisType, true>;
107 using SubControlVolume = typename Traits::SubControlVolume;
109 using SubControlVolumeFace = typename Traits::SubControlVolumeFace;
111 using DofMapper = typename Traits::VertexMapper;
113 using FeCache = Dune::PQkLocalFiniteElementCache<CoordScalar, Scalar, dim, 1>;
115 using GridView = GV;
116
119 : ParentType(gridView)
120 {}
121
124 const DofMapper& dofMapper() const
125 { return this->vertexMapper(); }
126
128 std::size_t numScv() const
129 { return numScv_; }
130
132 std::size_t numScvf() const
133 { return numScvf_; }
134
137 std::size_t numBoundaryScvf() const
138 { return numBoundaryScvf_; }
139
141 std::size_t numDofs() const
142 { return this->vertexMapper().size(); }
143
145 void update()
146 {
147 ParentType::update();
148
149 scvs_.clear();
150 scvfs_.clear();
151
152 auto numElements = this->gridView().size(0);
153 scvs_.resize(numElements);
154 scvfs_.resize(numElements);
155 hasBoundaryScvf_.resize(numElements, false);
156
157 boundaryDofIndices_.assign(numDofs(), false);
158
159 numScv_ = 0;
160 numScvf_ = 0;
161 numBoundaryScvf_ = 0;
162 // Build the SCV and SCV faces
163 for (const auto& element : elements(this->gridView()))
164 {
165 // fill the element map with seeds
166 auto eIdx = this->elementMapper().index(element);
167
168 // count
169 numScv_ += element.subEntities(dim);
170 numScvf_ += element.subEntities(dim-1);
171
172 // get the element geometry
173 auto elementGeometry = element.geometry();
174 const auto referenceElement = ReferenceElements::general(elementGeometry.type());
175
176 // instantiate the geometry helper
177 GeometryHelper geometryHelper(elementGeometry);
178
179 // construct the sub control volumes
180 scvs_[eIdx].resize(elementGeometry.corners());
181 for (LocalIndexType scvLocalIdx = 0; scvLocalIdx < elementGeometry.corners(); ++scvLocalIdx)
182 {
183 const auto dofIdxGlobal = this->vertexMapper().subIndex(element, scvLocalIdx, dim);
184
185 scvs_[eIdx][scvLocalIdx] = SubControlVolume(geometryHelper,
186 scvLocalIdx,
187 eIdx,
188 dofIdxGlobal);
189 }
190
191 // construct the sub control volume faces
192 LocalIndexType scvfLocalIdx = 0;
193 scvfs_[eIdx].resize(element.subEntities(dim-1));
194 for (; scvfLocalIdx < element.subEntities(dim-1); ++scvfLocalIdx)
195 {
196 // find the global and local scv indices this scvf is belonging to
197 std::vector<LocalIndexType> localScvIndices({static_cast<LocalIndexType>(referenceElement.subEntity(scvfLocalIdx, dim-1, 0, dim)),
198 static_cast<LocalIndexType>(referenceElement.subEntity(scvfLocalIdx, dim-1, 1, dim))});
199
200 scvfs_[eIdx][scvfLocalIdx] = SubControlVolumeFace(geometryHelper,
201 element,
202 elementGeometry,
203 scvfLocalIdx,
204 std::move(localScvIndices),
205 false);
206 }
207
208 // construct the sub control volume faces on the domain boundary
209 for (const auto& intersection : intersections(this->gridView(), element))
210 {
211 if (intersection.boundary() && !intersection.neighbor())
212 {
213 const auto isGeometry = intersection.geometry();
214 hasBoundaryScvf_[eIdx] = true;
215
216 // count
217 numScvf_ += isGeometry.corners();
218 numBoundaryScvf_ += isGeometry.corners();
219
220 for (unsigned int isScvfLocalIdx = 0; isScvfLocalIdx < isGeometry.corners(); ++isScvfLocalIdx)
221 {
222 // find the scvs this scvf is belonging to
223 const LocalIndexType insideScvIdx = static_cast<LocalIndexType>(referenceElement.subEntity(intersection.indexInInside(), 1, isScvfLocalIdx, dim));
224 std::vector<LocalIndexType> localScvIndices = {insideScvIdx, insideScvIdx};
225
226 scvfs_[eIdx].emplace_back(geometryHelper,
227 intersection,
228 isGeometry,
229 isScvfLocalIdx,
230 scvfLocalIdx,
231 std::move(localScvIndices),
232 true);
233
234 // increment local counter
235 scvfLocalIdx++;
236 }
237
238 // add all vertices on the intersection to the set of
239 // boundary vertices
240 const auto fIdx = intersection.indexInInside();
241 const auto numFaceVerts = referenceElement.size(fIdx, 1, dim);
242 for (int localVIdx = 0; localVIdx < numFaceVerts; ++localVIdx)
243 {
244 const auto vIdx = referenceElement.subEntity(fIdx, 1, localVIdx, dim);
245 const auto vIdxGlobal = this->vertexMapper().subIndex(element, vIdx, dim);
246 boundaryDofIndices_[vIdxGlobal] = true;
247 }
248 }
249
250 // inform the grid geometry if we have periodic boundaries
251 else if (intersection.boundary() && intersection.neighbor())
252 {
253 this->setPeriodic();
254
255 // find the mapped periodic vertex of all vertices on periodic boundaries
256 const auto fIdx = intersection.indexInInside();
257 const auto numFaceVerts = referenceElement.size(fIdx, 1, dim);
258 const auto eps = 1e-7*(elementGeometry.corner(1) - elementGeometry.corner(0)).two_norm();
259 for (int localVIdx = 0; localVIdx < numFaceVerts; ++localVIdx)
260 {
261 const auto vIdx = referenceElement.subEntity(fIdx, 1, localVIdx, dim);
262 const auto vIdxGlobal = this->vertexMapper().subIndex(element, vIdx, dim);
263 const auto vPos = elementGeometry.corner(vIdx);
264
265 const auto& outside = intersection.outside();
266 const auto outsideGeometry = outside.geometry();
267 for (const auto& isOutside : intersections(this->gridView(), outside))
268 {
269 // only check periodic vertices of the periodic neighbor
270 if (isOutside.boundary() && isOutside.neighbor())
271 {
272 const auto fIdxOutside = isOutside.indexInInside();
273 const auto numFaceVertsOutside = referenceElement.size(fIdxOutside, 1, dim);
274 for (int localVIdxOutside = 0; localVIdxOutside < numFaceVertsOutside; ++localVIdxOutside)
275 {
276 const auto vIdxOutside = referenceElement.subEntity(fIdxOutside, 1, localVIdxOutside, dim);
277 const auto vPosOutside = outsideGeometry.corner(vIdxOutside);
278 const auto shift = std::abs((this->bBoxMax()-this->bBoxMin())*intersection.centerUnitOuterNormal());
279 if (std::abs((vPosOutside-vPos).two_norm() - shift) < eps)
280 periodicVertexMap_[vIdxGlobal] = this->vertexMapper().subIndex(outside, vIdxOutside, dim);
281 }
282 }
283 }
284 }
285 }
286 }
287 }
288
289 // error check: periodic boundaries currently don't work for box in parallel
290 if (this->isPeriodic() && this->gridView().comm().size() > 1)
291 DUNE_THROW(Dune::NotImplemented, "Periodic boundaries for box method for parallel simulations!");
292 }
293
295 const FeCache& feCache() const
296 { return feCache_; }
297
299 const std::vector<SubControlVolume>& scvs(GridIndexType eIdx) const
300 { return scvs_[eIdx]; }
301
303 const std::vector<SubControlVolumeFace>& scvfs(GridIndexType eIdx) const
304 { return scvfs_[eIdx]; }
305
307 bool dofOnBoundary(GridIndexType dofIdx) const
308 { return boundaryDofIndices_[dofIdx]; }
309
311 bool dofOnPeriodicBoundary(GridIndexType dofIdx) const
312 { return periodicVertexMap_.count(dofIdx); }
313
315 GridIndexType periodicallyMappedDof(GridIndexType dofIdx) const
316 { return periodicVertexMap_.at(dofIdx); }
317
319 const std::unordered_map<GridIndexType, GridIndexType>& periodicVertexMap() const
320 { return periodicVertexMap_; }
321
323 bool hasBoundaryScvf(GridIndexType eIdx) const
324 { return hasBoundaryScvf_[eIdx]; }
325
326private:
327
328 const FeCache feCache_;
329
330 std::vector<std::vector<SubControlVolume>> scvs_;
331 std::vector<std::vector<SubControlVolumeFace>> scvfs_;
332 // TODO do we need those?
333 std::size_t numScv_;
334 std::size_t numScvf_;
335 std::size_t numBoundaryScvf_;
336
337 // vertices on the boudary
338 std::vector<bool> boundaryDofIndices_;
339 std::vector<bool> hasBoundaryScvf_;
340
341 // a map for periodic boundary vertices
342 std::unordered_map<GridIndexType, GridIndexType> periodicVertexMap_;
343};
344
352template<class Scalar, class GV, class Traits>
353class BoxFVGridGeometry<Scalar, GV, false, Traits>
354: public BaseGridGeometry<GV, Traits>
355{
358 using GridIndexType = typename IndexTraits<GV>::GridIndex;
359
360 static const int dim = GV::dimension;
361 static const int dimWorld = GV::dimensionworld;
362
363 using Element = typename GV::template Codim<0>::Entity;
364 using CoordScalar = typename GV::ctype;
365
366 using ReferenceElements = typename Dune::ReferenceElements<CoordScalar, dim>;
367
368public:
370 static constexpr DiscretizationMethod discMethod = DiscretizationMethod::box;
371
373 using LocalView = typename Traits::template LocalView<ThisType, false>;
375 using SubControlVolume = typename Traits::SubControlVolume;
377 using SubControlVolumeFace = typename Traits::SubControlVolumeFace;
379 using DofMapper = typename Traits::VertexMapper;
381 using FeCache = Dune::PQkLocalFiniteElementCache<CoordScalar, Scalar, dim, 1>;
383 using GridView = GV;
384
387 : ParentType(gridView)
388 {}
389
392 const DofMapper& dofMapper() const
393 { return this->vertexMapper(); }
394
396 std::size_t numScv() const
397 { return numScv_; }
398
400 std::size_t numScvf() const
401 { return numScvf_; }
402
405 std::size_t numBoundaryScvf() const
406 { return numBoundaryScvf_; }
407
409 std::size_t numDofs() const
410 { return this->vertexMapper().size(); }
411
413 void update()
414 {
415 ParentType::update();
416
417 boundaryDofIndices_.assign(numDofs(), false);
418
419 // save global data on the grid's scvs and scvfs
420 // TODO do we need those information?
421 numScv_ = 0;
422 numScvf_ = 0;
423 numBoundaryScvf_ = 0;
424 for (const auto& element : elements(this->gridView()))
425 {
426 numScv_ += element.subEntities(dim);
427 numScvf_ += element.subEntities(dim-1);
428
429 const auto elementGeometry = element.geometry();
430 const auto referenceElement = ReferenceElements::general(elementGeometry.type());
431
432 // store the sub control volume face indices on the domain boundary
433 for (const auto& intersection : intersections(this->gridView(), element))
434 {
435 if (intersection.boundary() && !intersection.neighbor())
436 {
437 const auto isGeometry = intersection.geometry();
438 numScvf_ += isGeometry.corners();
439 numBoundaryScvf_ += isGeometry.corners();
440
441 // add all vertices on the intersection to the set of
442 // boundary vertices
443 const auto fIdx = intersection.indexInInside();
444 const auto numFaceVerts = referenceElement.size(fIdx, 1, dim);
445 for (int localVIdx = 0; localVIdx < numFaceVerts; ++localVIdx)
446 {
447 const auto vIdx = referenceElement.subEntity(fIdx, 1, localVIdx, dim);
448 const auto vIdxGlobal = this->vertexMapper().subIndex(element, vIdx, dim);
449 boundaryDofIndices_[vIdxGlobal] = true;
450 }
451 }
452
453 // inform the grid geometry if we have periodic boundaries
454 else if (intersection.boundary() && intersection.neighbor())
455 {
456 this->setPeriodic();
457
458 // find the mapped periodic vertex of all vertices on periodic boundaries
459 const auto fIdx = intersection.indexInInside();
460 const auto numFaceVerts = referenceElement.size(fIdx, 1, dim);
461 const auto eps = 1e-7*(elementGeometry.corner(1) - elementGeometry.corner(0)).two_norm();
462 for (int localVIdx = 0; localVIdx < numFaceVerts; ++localVIdx)
463 {
464 const auto vIdx = referenceElement.subEntity(fIdx, 1, localVIdx, dim);
465 const auto vIdxGlobal = this->vertexMapper().subIndex(element, vIdx, dim);
466 const auto vPos = elementGeometry.corner(vIdx);
467
468 const auto& outside = intersection.outside();
469 const auto outsideGeometry = outside.geometry();
470 for (const auto& isOutside : intersections(this->gridView(), outside))
471 {
472 // only check periodic vertices of the periodic neighbor
473 if (isOutside.boundary() && isOutside.neighbor())
474 {
475 const auto fIdxOutside = isOutside.indexInInside();
476 const auto numFaceVertsOutside = referenceElement.size(fIdxOutside, 1, dim);
477 for (int localVIdxOutside = 0; localVIdxOutside < numFaceVertsOutside; ++localVIdxOutside)
478 {
479 const auto vIdxOutside = referenceElement.subEntity(fIdxOutside, 1, localVIdxOutside, dim);
480 const auto vPosOutside = outsideGeometry.corner(vIdxOutside);
481 const auto shift = std::abs((this->bBoxMax()-this->bBoxMin())*intersection.centerUnitOuterNormal());
482 if (std::abs((vPosOutside-vPos).two_norm() - shift) < eps)
483 periodicVertexMap_[vIdxGlobal] = this->vertexMapper().subIndex(outside, vIdxOutside, dim);
484 }
485 }
486 }
487 }
488 }
489 }
490 }
491
492 // error check: periodic boundaries currently don't work for box in parallel
493 if (this->isPeriodic() && this->gridView().comm().size() > 1)
494 DUNE_THROW(Dune::NotImplemented, "Periodic boundaries for box method for parallel simulations!");
495 }
496
498 const FeCache& feCache() const
499 { return feCache_; }
500
502 bool dofOnBoundary(GridIndexType dofIdx) const
503 { return boundaryDofIndices_[dofIdx]; }
504
506 bool dofOnPeriodicBoundary(GridIndexType dofIdx) const
507 { return periodicVertexMap_.count(dofIdx); }
508
510 GridIndexType periodicallyMappedDof(GridIndexType dofIdx) const
511 { return periodicVertexMap_.at(dofIdx); }
512
514 const std::unordered_map<GridIndexType, GridIndexType>& periodicVertexMap() const
515 { return periodicVertexMap_; }
516
517private:
518
519 const FeCache feCache_;
520
521 // Information on the global number of geometries
522 // TODO do we need those information?
523 std::size_t numScv_;
524 std::size_t numScvf_;
525 std::size_t numBoundaryScvf_;
526
527 // vertices on the boudary
528 std::vector<bool> boundaryDofIndices_;
529
530 // a map for periodic boundary vertices
531 std::unordered_map<GridIndexType, GridIndexType> periodicVertexMap_;
532};
533
534} // end namespace Dumux
535
536#endif
Defines the default element and vertex mapper types.
Defines the index types used for grid and local indices.
Helper class constructing the dual grid finite volume geometries for the box discretizazion method.
The available discretization methods in Dumux.
Base class for grid geometries.
DiscretizationMethod
The available discretization methods in Dumux.
Definition: method.hh:37
Definition: adapt.hh:29
Struture to define the index types used for grid and local indices.
Definition: indextraits.hh:38
Base class for all finite volume grid geometries.
Definition: basegridgeometry.hh:49
GV GridView
export the grid view type
Definition: basegridgeometry.hh:64
Create sub control volumes and sub control volume face geometries.
Definition: boxgeometryhelper.hh:37
Base class for the finite volume geometry vector for box models This builds up the sub control volume...
Definition: discretization/box/fvelementgeometry.hh:48
The default traits for the box finite volume grid geometry Defines the scv and scvf types and the map...
Definition: discretization/box/fvgridgeometry.hh:54
Base class for the finite volume geometry vector for box schemes This builds up the sub control volum...
Definition: discretization/box/fvgridgeometry.hh:72
Base class for the finite volume geometry vector for box schemes This builds up the sub control volum...
Definition: discretization/box/fvgridgeometry.hh:83
const std::vector< SubControlVolume > & scvs(GridIndexType eIdx) const
Get the local scvs for an element.
Definition: discretization/box/fvgridgeometry.hh:299
Dune::PQkLocalFiniteElementCache< CoordScalar, Scalar, dim, 1 > FeCache
export the finite element cache type
Definition: discretization/box/fvgridgeometry.hh:113
const std::vector< SubControlVolumeFace > & scvfs(GridIndexType eIdx) const
Get the local scvfs for an element.
Definition: discretization/box/fvgridgeometry.hh:303
const std::unordered_map< GridIndexType, GridIndexType > & periodicVertexMap() const
Returns the map between dofs across periodic boundaries.
Definition: discretization/box/fvgridgeometry.hh:319
GridIndexType periodicallyMappedDof(GridIndexType dofIdx) const
The index of the vertex / d.o.f. on the other side of the periodic boundary.
Definition: discretization/box/fvgridgeometry.hh:315
bool hasBoundaryScvf(GridIndexType eIdx) const
Returns whether one of the geometry's scvfs lies on a boundary.
Definition: discretization/box/fvgridgeometry.hh:323
std::size_t numDofs() const
The total number of degrees of freedom.
Definition: discretization/box/fvgridgeometry.hh:141
std::size_t numScv() const
The total number of sub control volumes.
Definition: discretization/box/fvgridgeometry.hh:128
void update()
update all fvElementGeometries (do this again after grid adaption)
Definition: discretization/box/fvgridgeometry.hh:145
const FeCache & feCache() const
The finite element cache for creating local FE bases.
Definition: discretization/box/fvgridgeometry.hh:295
std::size_t numBoundaryScvf() const
Definition: discretization/box/fvgridgeometry.hh:137
typename Traits::SubControlVolumeFace SubControlVolumeFace
export the type of sub control volume
Definition: discretization/box/fvgridgeometry.hh:109
const DofMapper & dofMapper() const
Definition: discretization/box/fvgridgeometry.hh:124
typename Traits::template LocalView< ThisType, true > LocalView
export the type of the fv element geometry (the local view type)
Definition: discretization/box/fvgridgeometry.hh:105
BoxFVGridGeometry(const GridView gridView)
Constructor.
Definition: discretization/box/fvgridgeometry.hh:118
bool dofOnBoundary(GridIndexType dofIdx) const
If a vertex / d.o.f. is on the boundary.
Definition: discretization/box/fvgridgeometry.hh:307
std::size_t numScvf() const
The total number of sun control volume faces.
Definition: discretization/box/fvgridgeometry.hh:132
bool dofOnPeriodicBoundary(GridIndexType dofIdx) const
If a vertex / d.o.f. is on a periodic boundary.
Definition: discretization/box/fvgridgeometry.hh:311
typename Traits::SubControlVolume SubControlVolume
export the type of sub control volume
Definition: discretization/box/fvgridgeometry.hh:107
typename Traits::VertexMapper DofMapper
export dof mapper type
Definition: discretization/box/fvgridgeometry.hh:111
Base class for the finite volume geometry vector for box schemes This builds up the sub control volum...
Definition: discretization/box/fvgridgeometry.hh:355
std::size_t numBoundaryScvf() const
Definition: discretization/box/fvgridgeometry.hh:405
bool dofOnPeriodicBoundary(GridIndexType dofIdx) const
If a vertex / d.o.f. is on a periodic boundary.
Definition: discretization/box/fvgridgeometry.hh:506
typename Traits::template LocalView< ThisType, false > LocalView
export the type of the fv element geometry (the local view type)
Definition: discretization/box/fvgridgeometry.hh:373
typename Traits::SubControlVolumeFace SubControlVolumeFace
export the type of sub control volume
Definition: discretization/box/fvgridgeometry.hh:377
void update()
update all fvElementGeometries (do this again after grid adaption)
Definition: discretization/box/fvgridgeometry.hh:413
typename Traits::SubControlVolume SubControlVolume
export the type of sub control volume
Definition: discretization/box/fvgridgeometry.hh:375
GridIndexType periodicallyMappedDof(GridIndexType dofIdx) const
The index of the vertex / d.o.f. on the other side of the periodic boundary.
Definition: discretization/box/fvgridgeometry.hh:510
Dune::PQkLocalFiniteElementCache< CoordScalar, Scalar, dim, 1 > FeCache
export the finite element cache type
Definition: discretization/box/fvgridgeometry.hh:381
const FeCache & feCache() const
The finite element cache for creating local FE bases.
Definition: discretization/box/fvgridgeometry.hh:498
std::size_t numScvf() const
The total number of sun control volume faces.
Definition: discretization/box/fvgridgeometry.hh:400
typename Traits::VertexMapper DofMapper
export dof mapper type
Definition: discretization/box/fvgridgeometry.hh:379
bool dofOnBoundary(GridIndexType dofIdx) const
If a vertex / d.o.f. is on the boundary.
Definition: discretization/box/fvgridgeometry.hh:502
BoxFVGridGeometry(const GridView gridView)
Constructor.
Definition: discretization/box/fvgridgeometry.hh:386
const DofMapper & dofMapper() const
Definition: discretization/box/fvgridgeometry.hh:392
std::size_t numDofs() const
The total number of degrees of freedom.
Definition: discretization/box/fvgridgeometry.hh:409
const std::unordered_map< GridIndexType, GridIndexType > & periodicVertexMap() const
Returns the map between dofs across periodic boundaries.
Definition: discretization/box/fvgridgeometry.hh:514
std::size_t numScv() const
The total number of sub control volumes.
Definition: discretization/box/fvgridgeometry.hh:396
the sub control volume for the box scheme
Definition: discretization/box/subcontrolvolume.hh:88
Class for a sub control volume face in the box method, i.e a part of the boundary of a sub control vo...
Definition: discretization/box/subcontrolvolumeface.hh:93
Base class for the local finite volume geometry for box models This builds up the sub control volumes...
the sub control volume for the box scheme
Base class for a sub control volume face.