26#ifndef DUMUX_BENCHMARKRESULT_HH
27#define DUMUX_BENCHMARKRESULT_HH
43 bool contains (Dune::GeometryType gt)
45 return gt.dim() == dim-1;
81 template<
class Gr
id,
class ProblemType,
class SolutionType>
82 void evaluate(
const Grid& grid, ProblemType& problem,
83 SolutionType& solution,
bool pureNeumann =
false)
85 using Entity =
typename Grid::Traits::template Codim<0>::Entity;
86 using Geometry =
typename Entity::Geometry;
87 using GV =
typename Grid::LevelGridView;
88 using IS =
typename GV::IndexSet;
89 using Mapper = Dune::MultipleCodimMultipleGeomTypeMapper<GV>;
90 using ct =
typename Grid::ctype;
92 enum{dim = Grid::dimension};
94 using JacobianInverseTransposed =
typename Geometry::JacobianInverseTransposed;
95 using ReferenceElements = Dune::ReferenceElements<ct, dim>;
96 const GV& gridview(grid.levelGridView(grid.maxLevel()));
97 const IS& indexset(gridview.indexSet());
98 Mapper elementMapper(gridview, Dune::mcmgElementLayout());
99 Mapper faceMapper(gridview, Dune::mcmgLayout(Dune::Codim<1>()));
100 SolutionType& exactSol(grid.levelGridView(grid.maxLevel()));
103 double domainVolume = 0;
104 for (
const auto& element : elements(gridview))
107 double volume = element.geometry().volume();
110 int indexi = elementMapper.index(element);
113 uMean += volume*(problem.variables().cellData(indexi).globalPressure());
116 domainVolume += volume;
118 uMean /= domainVolume;
121 for (
int i = 0; i < (int) problem.variables().pressure().size(); i++)
123 double press = problem.variables().cellData(i).globalPressure() -
uMean;
124 problem.variables().cellData(i).setGlobalPressure(press);
150 double numerator = 0;
151 double denominator = 0;
152 double numeratorGrad = 0;
153 double denominatorGrad = 0;
154 double numeratorFlux = 0;
155 double denominatorFlux = 0;
156 bool exactOutput =
true;
157 for (
const auto& element : elements(gridview))
160 const Geometry& geometry = element.geometry();
163 Dune::GeometryType gt = geometry.type();
166 const Dune::FieldVector<ct,dim>&
167 local = ReferenceElements::general(gt).position(0,0);
170 Dune::FieldVector<ct,dim> globalPos = geometry.global(local);
173 double exactValue = problem.exact(globalPos);
176 int indexi = elementMapper.index(element);
179 exactSol[indexi] = exactValue;
182 double approximateValue = problem.variables().cellData(indexi).globalPressure();
195 double volume = geometry.volume();
198 sumf += volume*(problem.source(globalPos, element, local)[0]);
201 Dune::FieldMatrix<double,dim,dim> K = problem.spatialParams().K(globalPos, element, local);
203 numerator += volume*(exactValue - approximateValue)*(exactValue - approximateValue);
204 denominator += volume*exactValue*exactValue;
207 Dune::FieldVector<ct,2*dim> fluxVector;
208 Dune::FieldVector<ct,dim> exactGradient;
209 for (
const auto& intersection :
intersections(gridview, element))
212 i = intersection.indexInInside();
215 int faceIndex = faceMapper.template map<1>(element, i);
217 Dune::FieldVector<double,dim> faceGlobal = intersection.geometry().center();
218 double faceVol = intersection.geometry().volume();
221 Dune::FieldVector<double,dim> unitOuterNormal = intersection.centerUnitOuterNormal();
224 double approximateFace = (*solution.pressTrace)[faceIndex];
227 exactGradient = problem.exactGrad(faceGlobal);
230 Dune::FieldVector<double,dim> KGrad(0);
231 K.umv(exactGradient, KGrad);
234 double exactFlux = KGrad*unitOuterNormal;
237 double approximateFlux = solution.normalVelocity[indexi][i];
240 double fluxDiff = exactFlux + approximateFlux;
246 numeratorFlux += volume*fluxDiff*fluxDiff;
247 denominatorFlux += volume*exactFlux*exactFlux;
250 exactFlux *= faceVol;
251 approximateFlux *= faceVol;
252 fluxVector[i] = approximateFlux;
255 if (!intersection.neighbor()) {
256 if (abs(faceGlobal[2]) < 1e-6) {
257 fluz0 += approximateFlux;
259 ener2 += -approximateFlux*approximateFace;
261 else if (abs(faceGlobal[2] - 1.0) < 1e-6) {
262 fluz1 += approximateFlux;
264 ener2 += -approximateFlux*approximateFace;
266 if (abs(faceGlobal[1]) < 1e-6) {
267 fluy0 += approximateFlux;
269 ener2 += -approximateFlux*approximateFace;
271 else if (abs(faceGlobal[1] - 1.0) < 1e-6) {
272 fluy1 += approximateFlux;
274 ener2 += -approximateFlux*approximateFace;
276 else if (faceGlobal[0] < 1e-6) {
277 flux0 += approximateFlux;
279 ener2 += -approximateFlux*approximateFace;
281 else if (abs(faceGlobal[0] - 1.0) < 1e-6) {
282 flux1 += approximateFlux;
284 ener2 += -approximateFlux*approximateFace;
291 Dune::FieldVector<double, dim> refVelocity;
293 if (geometry.type().isSimplex()) {
294 for (
int dimIdx = 0; dimIdx < dim; dimIdx++)
296 refVelocity[dimIdx] = -fluxVector[dim - 1 - dimIdx];
297 for (
int fIdx = 0; fIdx < dim + 1; fIdx++)
299 refVelocity[dimIdx] += fluxVector[fIdx]/(dim + 1);
304 else if (geometry.type().isCube()){
305 for (
int j = 0; j < dim; j++)
306 refVelocity[j] = 0.5 * (fluxVector[2*j + 1] - fluxVector[2*j]);
310 DUNE_THROW(Dune::NotImplemented,
"velocity output for prism/pyramid not implemented");
314 const JacobianInverseTransposed& jacobianInv = geometry.jacobianInverseTransposed(local);
315 JacobianInverseTransposed jacobianT(jacobianInv);
319 Dune::FieldVector<ct,dim> elementVelocity(0);
320 jacobianT.umtv(refVelocity, elementVelocity);
321 elementVelocity /= geometry.integrationElement(local);
324 Dune::FieldVector<ct,dim> approximateGradient;
325 K.solve(approximateGradient, elementVelocity);
328 exactGradient = problem.exactGrad(globalPos);
331 Dune::FieldVector<ct,dim> gradDiff(exactGradient);
332 gradDiff += approximateGradient;
335 ener1 += volume*(approximateGradient*elementVelocity);
337 numeratorGrad += volume*(gradDiff*gradDiff);
338 denominatorGrad += volume*(exactGradient*exactGradient);
345 ergrad = sqrt(numeratorGrad/denominatorGrad);
346 ervell2 = sqrt(numeratorFlux/denominatorFlux);
357 Dune::VTKWriter<GV> vtkwriter(gridview);
359 sprintf(fname,
"%d",
"exactSol-numRefine", grid.maxLevel());
360 vtkwriter.addCellData(exactSol,
"exact pressure solution~");
361 vtkwriter.write(fname,Dune::VTK::ascii);
371struct ResultEvaluation
377 bool contains (Dune::GeometryType gt)
379 return gt.dim() == dim-1;
416 template<
class Gr
idView,
class Problem>
418 Problem& problem,
bool consecutiveNumbering =
false)
420 using Grid =
typename GridView::Grid;
421 using Scalar =
typename Grid::ctype;
422 enum {dim=Grid::dimension};
423 using Element =
typename Grid::template Codim<0>::Entity;
424 using Geometry =
typename Element::Geometry;
425 using ElementMapper = Dune::MultipleCodimMultipleGeomTypeMapper<GridView>;
426 using SolVector = Dune::BlockVector<Dune::FieldVector<Scalar, 1> >;
427 using JacobianInverseTransposed =
typename Geometry::JacobianInverseTransposed;
428 using ReferenceElements = Dune::ReferenceElements<Scalar, dim>;
430 ElementMapper elementMapper(gridView, Dune::mcmgElementLayout());
431 SolVector exactSol(gridView.size(0));
455 Scalar numerator = 0;
456 Scalar denominator = 0;
457 Scalar numeratorIn = 0;
458 Scalar denominatorIn = 0;
459 Scalar numeratorOut = 0;
460 Scalar denominatorOut = 0;
461 double numeratorGrad = 0;
462 double denominatorGrad = 0;
463 double numeratorFlux = 0;
464 double denominatorFlux = 0;
465 double numeratorFluxIn = 0;
466 double denominatorFluxIn = 0;
467 bool exactOutput =
true;
468 for (
const auto& element : elements(gridView))
471 const Geometry& geometry = element.geometry();
473 Dune::GeometryType geomType = geometry.type();
475 const Dune::FieldVector<Scalar,dim>& local = ReferenceElements::general(geomType).position(0, 0);
476 Dune::FieldVector<Scalar,dim> globalPos = geometry.global(local);
478 Scalar volume = geometry.volume();
480 int eIdx = problem.variables().index(element);
482 Scalar approxPressure = problem.variables().cellData(eIdx).globalPressure();
483 Scalar exactPressure = problem.exact(globalPos);
486 exactSol[eIdx] = exactPressure;
492 numerator += volume*(approxPressure - exactPressure)*(approxPressure - exactPressure);
493 denominator += volume*exactPressure*exactPressure;
496 bool bndCell =
false;
497 for (
const auto& intersection :
intersections(gridView, element))
499 if (intersection.boundary())
508 numeratorOut += volume*(approxPressure - exactPressure)*(approxPressure - exactPressure);
509 denominatorOut += volume*exactPressure*exactPressure;
513 numeratorIn += volume*(approxPressure - exactPressure)*(approxPressure - exactPressure);
514 denominatorIn += volume*exactPressure*exactPressure;
527 typename Problem::PrimaryVariables sourceVec;
528 problem.source(sourceVec, element);
529 sumf += volume*sourceVec[0];
532 Dune::FieldMatrix<double,dim,dim> K = problem.spatialParams().intrinsicPermeability(element);
535 Dune::FieldVector<Scalar,2*dim> fluxVector;
536 Dune::FieldVector<Scalar,dim> exactGradient;
537 for (
const auto& intersection :
intersections(gridView, element))
540 int fIdx = intersection.indexInInside();
542 if (consecutiveNumbering)
547 Dune::FieldVector<double,dim> faceGlobal = intersection.geometry().center();
548 double faceVol = intersection.geometry().volume();
551 Dune::FieldVector<double,dim> unitOuterNormal = intersection.centerUnitOuterNormal();
554 exactGradient = problem.exactGrad(faceGlobal);
557 Dune::FieldVector<double,dim> KGrad(0);
558 K.umv(exactGradient, KGrad);
561 double exactFlux = KGrad*unitOuterNormal;
564 double approximateFlux = problem.variables().cellData(eIdx).fluxData().velocityTotal(fIdx)*unitOuterNormal;
567 double fluxDiff = exactFlux + approximateFlux;
574 numeratorFlux += volume*fluxDiff*fluxDiff;
575 denominatorFlux += volume*exactFlux*exactFlux;
579 numeratorFluxIn += volume*fluxDiff*fluxDiff;
580 denominatorFluxIn += volume*exactFlux*exactFlux;
584 exactFlux *= faceVol;
585 approximateFlux *= faceVol;
586 fluxVector[fIdx] = approximateFlux;
588 if (!intersection.neighbor()) {
589 if (abs(faceGlobal[2]) < 1e-6) {
590 fluz0 += approximateFlux;
593 else if (abs(faceGlobal[2] - 1.0) < 1e-6) {
594 fluz1 += approximateFlux;
597 if (abs(faceGlobal[1]) < 1e-6) {
598 fluy0 += approximateFlux;
601 else if (abs(faceGlobal[1] - 1.0) < 1e-6) {
602 fluy1 += approximateFlux;
605 else if (faceGlobal[0] < 1e-6) {
606 flux0 += approximateFlux;
609 else if (abs(faceGlobal[0] - 1.0) < 1e-6) {
610 flux1 += approximateFlux;
617 Dune::FieldVector<Scalar,dim> refVelocity;
618 if (geometry.corners() == 8) {
619 refVelocity[0] = 0.5*(fluxVector[1] - fluxVector[0]);
620 refVelocity[1] = 0.5*(fluxVector[3] - fluxVector[2]);
621 refVelocity[2] = 0.5*(fluxVector[5] - fluxVector[4]);
628 const JacobianInverseTransposed& jacobianInv = geometry.jacobianInverseTransposed(local);
629 JacobianInverseTransposed jacobianT(jacobianInv);
633 Dune::FieldVector<Scalar,dim> elementVelocity(0);
634 jacobianT.umtv(refVelocity, elementVelocity);
635 elementVelocity /= geometry.integrationElement(local);
638 Dune::FieldVector<Scalar,dim> approximateGradient;
639 K.solve(approximateGradient, elementVelocity);
642 exactGradient = problem.exactGrad(globalPos);
645 Dune::FieldVector<Scalar,dim> gradDiff(exactGradient);
646 gradDiff += approximateGradient;
649 ener1 += volume*(approximateGradient*elementVelocity);
651 numeratorGrad += volume*(gradDiff*gradDiff);
652 denominatorGrad += volume*(exactGradient*exactGradient);
655 for (
int i = 0; i < element.geometry().corners(); ++i)
657 Dune::FieldVector<Scalar,dim> corner1 = element.geometry().corner(i);
659 for (
int j = 0; j < element.geometry().corners(); ++j)
662 Dune::FieldVector<Scalar,dim> corner2 = element.geometry().corner(j);
665 Dune::FieldVector<Scalar,dim> distVec = corner1 - corner2;
666 Scalar dist = distVec.two_norm();
679 ergrad = sqrt(numeratorGrad/denominatorGrad);
680 ervell2 = sqrt(numeratorFlux/denominatorFlux);
681 ervell2In = sqrt(numeratorFluxIn/denominatorFluxIn);
691 Dune::VTKWriter<GridView> vtkwriter(gridView);
693 sprintf(fname,
"exactSol-numRefine%d", gridView.grid().maxLevel());
694 vtkwriter.addCellData(exactSol,
"exact pressure solution~");
695 vtkwriter.write(fname,Dune::VTK::ascii);
702 template<
class Gr
idView,
class Problem,
class SolVector,
class VelVector>
704 const SolVector& solution,
const VelVector& velocity,
bool switchNormals =
false)
706 using Grid =
typename GridView::Grid;
707 using Scalar =
typename Grid::ctype;
708 enum {dim=Grid::dimension, maxIntersections = 12};
709 using Element =
typename Grid::template Codim<0>::Entity;
710 using Geometry =
typename Element::Geometry;
711 using ElementMapper = Dune::MultipleCodimMultipleGeomTypeMapper<GridView>;
712 using ReferenceElements = Dune::ReferenceElements<Scalar, dim>;
713 using ReferenceFaces = Dune::ReferenceElements<Scalar, dim-1>;
715 ElementMapper elementMapper(gridView, Dune::mcmgElementLayout());
725 Scalar numerator = 0;
726 Scalar denominator = 0;
727 for (
const auto& element : elements(gridView))
730 const Geometry& geometry = element.geometry();
732 Dune::GeometryType geomType = geometry.type();
734 const Dune::FieldVector<Scalar,dim>& local = ReferenceElements::general(geomType).position(0, 0);
735 Dune::FieldVector<Scalar,dim> globalPos = geometry.global(local);
737 Scalar volume = geometry.integrationElement(local)
738 *ReferenceElements::general(geomType).volume();
740 int eIdx = elementMapper.index(element);
742 Scalar approxPressure = solution[eIdx];
743 Scalar exactPressure = problem.exact(globalPos);
744 numerator += volume*(approxPressure - exactPressure)*(approxPressure - exactPressure);
745 denominator += volume*exactPressure*exactPressure;
757 sumf += volume*problem.source(globalPos, element, local)[0];
760 Dune::FieldMatrix<Scalar,dim,dim> K = problem.spatialParams().K(globalPos, element, local);
763 Dune::FieldVector<Scalar,dim> exactGradient;
764 for (
const auto& intersection :
intersections(gridView, element))
767 Dune::GeometryType gtf = intersection.geometryInInside().type();
773 const Dune::FieldVector<Scalar,dim-1>& faceLocalNm1 = ReferenceFaces::general(gtf).position(0,0);
776 Dune::FieldVector<Scalar,dim> faceGlobal = intersection.geometry().global(faceLocalNm1);
779 Dune::FieldVector<Scalar,dim> unitOuterNormal = intersection.unitOuterNormal(faceLocalNm1);
782 unitOuterNormal *= -1.0;
785 exactGradient = problem.exactGrad(faceGlobal);
786 exactGradient.axpy(-problem.wettingPhase().density(), problem.gravity());
789 Dune::FieldVector<Scalar,dim> KGrad(0);
790 K.umv(exactGradient, KGrad);
793 Scalar exactFlux = KGrad*unitOuterNormal;
796 Scalar approximateFlux = problem.cellData(eIdx).fluxData().velocityTotal(i)*unitOuterNormal;
799 Scalar fluxDiff = exactFlux + approximateFlux;
811 maxFlux = max(maxFlux, abs(exactFlux));
821 erflm /= max(1e-6, maxFlux);
Base class for definition of an sequential diffusion (pressure) or transport problem.
Dune::IteratorRange< typename MultiDomainGlue< DomainGridView, TargetGridView, DomainMapper, TargetMapper >::Intersections::const_iterator > intersections(const MultiDomainGlue< DomainGridView, TargetGridView, DomainMapper, TargetMapper > &glue)
Range generator to iterate with range-based for loops over all intersections as follows: for (const a...
Definition: glue.hh:62
make the local view function available whenever we use the grid geometry
Definition: adapt.hh:29
double ener1
Definition: resultevaluation.hh:60
double relativeL2Error
Definition: resultevaluation.hh:40
double exactfluz0
Definition: resultevaluation3d.hh:406
double relativeL2ErrorOut
Definition: resultevaluation3d.hh:386
double fluy0
Definition: resultevaluation.hh:47
double exactfluz1
Definition: resultevaluation3d.hh:407
double uMinExact
Definition: resultevaluation3d.hh:390
double uMin
Definition: resultevaluation.hh:43
double exactflux1
Definition: resultevaluation.hh:52
double errfly0
Definition: resultevaluation.hh:57
double ervell2
Definition: resultevaluation.hh:42
double uMaxExact
Definition: resultevaluation3d.hh:391
double sumf
Definition: resultevaluation.hh:49
double ervell2In
Definition: resultevaluation3d.hh:389
void evaluate(const GridView &gridView, Problem &problem, bool consecutiveNumbering=false)
Definition: resultevaluation3d.hh:417
double flux0
Definition: resultevaluation.hh:45
double erflm
Definition: resultevaluation.hh:59
double fluy1
Definition: resultevaluation.hh:48
double ergrad
Definition: resultevaluation.hh:41
double relativeL2ErrorIn
Definition: resultevaluation3d.hh:385
double errfly1
Definition: resultevaluation.hh:58
double errflx0
Definition: resultevaluation.hh:55
double exactflux0
Definition: resultevaluation.hh:51
double sumflux
Definition: resultevaluation.hh:50
double fluz1
Definition: resultevaluation3d.hh:399
double errflx1
Definition: resultevaluation.hh:56
double exactfluy1
Definition: resultevaluation.hh:54
double uMax
Definition: resultevaluation.hh:44
void evaluateCP(const GridView &gridView, Problem &problem, const SolVector &solution, const VelVector &velocity, bool switchNormals=false)
Definition: resultevaluation3d.hh:703
double hMax
Definition: resultevaluation3d.hh:414
double fluz0
Definition: resultevaluation3d.hh:398
double flux1
Definition: resultevaluation.hh:46
double exactfluy0
Definition: resultevaluation.hh:53
calculate errors for a FVCA5 benchmark problem
Definition: resultevaluation3d.hh:38
double ener1
Definition: resultevaluation3d.hh:76
double ergrad
Definition: resultevaluation3d.hh:51
double errflx1
Definition: resultevaluation3d.hh:72
double fluy0
Definition: resultevaluation3d.hh:59
double fluy1
Definition: resultevaluation3d.hh:60
double uMinExact
Definition: resultevaluation3d.hh:53
double exactfluz0
Definition: resultevaluation3d.hh:69
double flux0
Definition: resultevaluation3d.hh:57
double uMaxExact
Definition: resultevaluation3d.hh:54
double sumflux
Definition: resultevaluation3d.hh:64
double exactflux1
Definition: resultevaluation3d.hh:66
double flux1
Definition: resultevaluation3d.hh:58
double eren
Definition: resultevaluation3d.hh:78
void evaluate(const Grid &grid, ProblemType &problem, SolutionType &solution, bool pureNeumann=false)
Definition: resultevaluation3d.hh:82
double errflx0
Definition: resultevaluation3d.hh:71
double errfly0
Definition: resultevaluation3d.hh:73
double uMax
Definition: resultevaluation3d.hh:56
double fluz0
Definition: resultevaluation3d.hh:61
double ervell2
Definition: resultevaluation3d.hh:52
double sumf
Definition: resultevaluation3d.hh:63
double exactfluz1
Definition: resultevaluation3d.hh:70
double exactfluy1
Definition: resultevaluation3d.hh:68
double relativeL2Error
Definition: resultevaluation3d.hh:50
double uMin
Definition: resultevaluation3d.hh:55
double fluz1
Definition: resultevaluation3d.hh:62
double erflm
Definition: resultevaluation3d.hh:75
double exactfluy0
Definition: resultevaluation3d.hh:67
double errfly1
Definition: resultevaluation3d.hh:74
double exactflux0
Definition: resultevaluation3d.hh:65
double uMean
Definition: resultevaluation3d.hh:79
double ener2
Definition: resultevaluation3d.hh:77