Skip to content
Snippets Groups Projects
Commit 15aac202 authored by Sander, Oliver's avatar Sander, Oliver
Browse files

Refactor code to make it more flexible

parent 886a9260
No related branches found
No related tags found
No related merge requests found
...@@ -39,9 +39,9 @@ const int blocksize = TargetSpace::TangentVector::dimension; ...@@ -39,9 +39,9 @@ const int blocksize = TargetSpace::TangentVector::dimension;
using namespace Dune; using namespace Dune;
template <class GridView, int order> template <class GridView, int order>
void measureEOC(const GridView gridView, void measureDiscreteEOC(const GridView gridView,
const GridView referenceGridView, const GridView referenceGridView,
const ParameterTree& parameterSet) const ParameterTree& parameterSet)
{ {
typedef std::vector<TargetSpace> SolutionType; typedef std::vector<TargetSpace> SolutionType;
...@@ -51,6 +51,11 @@ void measureEOC(const GridView gridView, ...@@ -51,6 +51,11 @@ void measureEOC(const GridView gridView,
typedef Dune::Functions::PQkNodalBasis<GridView, order> FEBasis; typedef Dune::Functions::PQkNodalBasis<GridView, order> FEBasis;
FEBasis feBasis(gridView); FEBasis feBasis(gridView);
FEBasis referenceFEBasis(referenceGridView);
using FufemFEBasis = DuneFunctionsBasis<FEBasis>;
FufemFEBasis fufemReferenceFEBasis(referenceFEBasis);
FufemFEBasis fufemFEBasis(feBasis);
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
// Read the data whose error is to be measured // Read the data whose error is to be measured
...@@ -70,108 +75,132 @@ void measureEOC(const GridView gridView, ...@@ -70,108 +75,132 @@ void measureEOC(const GridView gridView,
for (size_t i=0; i<x.size(); i++) for (size_t i=0; i<x.size(); i++)
x[i] = TargetSpace(embeddedX[i]); x[i] = TargetSpace(embeddedX[i]);
// The numerical solution, as a grid function
GFE::EmbeddedGlobalGFEFunction<FufemFEBasis, TargetSpace> numericalSolution(fufemFEBasis, x);
///////////////////////////////////////////////////////////////////////////
// Read the reference configuration
///////////////////////////////////////////////////////////////////////////
EmbeddedVectorType embeddedReferenceX(referenceFEBasis.size());
inFile.open(parameterSet.get<std::string>("referenceData"), std::ios_base::binary);
if (not inFile)
DUNE_THROW(IOError, "File " << parameterSet.get<std::string>("referenceData") << " could not be opened.");
GenericVector::readBinary(inFile, embeddedReferenceX);
SolutionType referenceX(embeddedReferenceX.size());
for (size_t i=0; i<referenceX.size(); i++)
referenceX[i] = TargetSpace(embeddedReferenceX[i]);
// The reference solution, as a grid function
GFE::EmbeddedGlobalGFEFunction<FufemFEBasis, TargetSpace> referenceSolution(fufemReferenceFEBasis, referenceX);
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// Measure the discretization error // Measure the discretization error
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
if (parameterSet.get<std::string>("discretizationErrorMode")=="analytical") double l2ErrorSquared = 0;
double h1ErrorSquared = 0;
HierarchicSearch<typename GridView::Grid,typename GridView::IndexSet> hierarchicSearch(gridView.grid(), gridView.indexSet());
for (const auto& rElement : elements(referenceGridView))
{ {
using FufemFEBasis = DuneFunctionsBasis<FEBasis>; const auto& quadRule = QuadratureRules<double, dim>::rule(rElement.type(), 6);
FufemFEBasis fufemFEBasis(feBasis);
for (const auto& qp : quadRule)
{
auto integrationElement = rElement.geometry().integrationElement(qp.position());
// Read reference solution and its derivative into a PythonFunction auto globalPos = rElement.geometry().global(qp.position());
typedef VirtualDifferentiableFunction<FieldVector<double, dim>, TargetSpace::CoordinateType> FBase;
Python::Module module = Python::import(parameterSet.get<std::string>("referenceSolution")); auto element = hierarchicSearch.findEntity(globalPos);
auto referenceSolution = module.get("fdf").toC<std::shared_ptr<FBase>>(); auto localPos = element.geometry().local(globalPos);
// The numerical solution, as a grid function auto diff = referenceSolution(rElement, qp.position()) - numericalSolution(element, localPos);
GFE::EmbeddedGlobalGFEFunction<FufemFEBasis, TargetSpace> numericalSolution(fufemFEBasis, x);
// QuadratureRule for the integral of the L^2 error l2ErrorSquared += integrationElement * qp.weight() * diff.two_norm2();
QuadratureRuleKey quadKey(dim,6);
// Compute the embedded L^2 error auto derDiff = referenceSolution.derivative(rElement, qp.position()) - numericalSolution.derivative(element, localPos);
double l2Error = DiscretizationError<GridView>::computeL2Error(&numericalSolution,
referenceSolution.get(),
quadKey);
// Compute the embedded H^1 error h1ErrorSquared += integrationElement * qp.weight() * derDiff.frobenius_norm2();
double h1Error = DiscretizationError<GridView>::computeH1HalfNormDifferenceSquared(gridView,
&numericalSolution,
referenceSolution.get(),
quadKey);
std::cout << "elements: " << gridView.size(0) }
<< " "
<< "L^2 error: " << l2Error
<< " ";
std::cout << "H^1 error: " << std::sqrt(l2Error*l2Error + h1Error) << std::endl;
} }
if (parameterSet.get<std::string>("discretizationErrorMode")=="discrete") std::cout << "levels: " << gridView.grid().maxLevel()+1
{ << " "
FEBasis referenceFEBasis(referenceGridView); << "L^2 error: " << std::sqrt(l2ErrorSquared)
<< " "
<< "H^1 error: " << std::sqrt(l2ErrorSquared + h1ErrorSquared)
<< std::endl;
}
// Reference configuration template <class GridView, int order>
EmbeddedVectorType embeddedReferenceX(referenceFEBasis.size()); void measureAnalyticalEOC(const GridView gridView,
inFile.open(parameterSet.get<std::string>("referenceData"), std::ios_base::binary); const ParameterTree& parameterSet)
if (not inFile) {
DUNE_THROW(IOError, "File " << parameterSet.get<std::string>("referenceData") << " could not be opened."); typedef std::vector<TargetSpace> SolutionType;
GenericVector::readBinary(inFile, embeddedReferenceX);
SolutionType referenceX(embeddedReferenceX.size()); //////////////////////////////////////////////////////////////////////////////////
for (size_t i=0; i<referenceX.size(); i++) // Construct the scalar function space bases corresponding to the GFE space
referenceX[i] = TargetSpace(embeddedReferenceX[i]); //////////////////////////////////////////////////////////////////////////////////
using FufemFEBasis = DuneFunctionsBasis<FEBasis>; typedef Dune::Functions::PQkNodalBasis<GridView, order> FEBasis;
FufemFEBasis fufemReferenceFEBasis(referenceFEBasis); FEBasis feBasis(gridView);
FufemFEBasis fufemFEBasis(feBasis);
// The numerical solution, as a grid function //////////////////////////////////////////////////////////////////////////////////
GFE::EmbeddedGlobalGFEFunction<FufemFEBasis, TargetSpace> referenceSolution(fufemReferenceFEBasis, referenceX); // Read the data whose error is to be measured
//////////////////////////////////////////////////////////////////////////////////
// The numerical solution, as a grid function // Input data
GFE::EmbeddedGlobalGFEFunction<FufemFEBasis, TargetSpace> numericalSolution(fufemFEBasis, x); typedef BlockVector<TargetSpace::CoordinateType> EmbeddedVectorType;
double l2ErrorSquared = 0; EmbeddedVectorType embeddedX(feBasis.size());
double h1ErrorSquared = 0; std::ifstream inFile(parameterSet.get<std::string>("simulationData"), std::ios_base::binary);
if (not inFile)
DUNE_THROW(IOError, "File " << parameterSet.get<std::string>("simulationData") << " could not be opened.");
GenericVector::readBinary(inFile, embeddedX);
inFile.close();
HierarchicSearch<typename GridView::Grid,typename GridView::IndexSet> hierarchicSearch(gridView.grid(), gridView.indexSet()); SolutionType x(embeddedX.size());
for (size_t i=0; i<x.size(); i++)
x[i] = TargetSpace(embeddedX[i]);
std::cout << "l2: " << l2ErrorSquared << std::endl; /////////////////////////////////////////////////////////////////
for (const auto& rElement : elements(referenceGridView)) // Measure the discretization error
{ /////////////////////////////////////////////////////////////////
const auto& quadRule = QuadratureRules<double, dim>::rule(rElement.type(), 6);
for (const auto& qp : quadRule) using FufemFEBasis = DuneFunctionsBasis<FEBasis>;
{ FufemFEBasis fufemFEBasis(feBasis);
auto integrationElement = rElement.geometry().integrationElement(qp.position());
auto globalPos = rElement.geometry().global(qp.position()); // Read reference solution and its derivative into a PythonFunction
typedef VirtualDifferentiableFunction<FieldVector<double, dim>, TargetSpace::CoordinateType> FBase;
auto element = hierarchicSearch.findEntity(globalPos); Python::Module module = Python::import(parameterSet.get<std::string>("referenceSolution"));
auto localPos = element.geometry().local(globalPos); auto referenceSolution = module.get("fdf").toC<std::shared_ptr<FBase>>();
auto diff = referenceSolution(rElement, qp.position()) - numericalSolution(element, localPos); // The numerical solution, as a grid function
GFE::EmbeddedGlobalGFEFunction<FufemFEBasis, TargetSpace> numericalSolution(fufemFEBasis, x);
l2ErrorSquared += integrationElement * qp.weight() * diff.two_norm2(); // QuadratureRule for the integral of the L^2 error
QuadratureRuleKey quadKey(dim,6);
auto derDiff = referenceSolution.derivative(rElement, qp.position()) - numericalSolution.derivative(element, localPos); // Compute the embedded L^2 error
double l2Error = DiscretizationError<GridView>::computeL2Error(&numericalSolution,
referenceSolution.get(),
quadKey);
h1ErrorSquared += integrationElement * qp.weight() * derDiff.frobenius_norm2(); // Compute the embedded H^1 error
double h1Error = DiscretizationError<GridView>::computeH1HalfNormDifferenceSquared(gridView,
&numericalSolution,
referenceSolution.get(),
quadKey);
} std::cout << "elements: " << gridView.size(0)
} << " "
std::cout << "l2: " << l2ErrorSquared << std::endl; << "L^2 error: " << l2Error
<< " ";
std::cout << "levels: " << gridView.grid().maxLevel()+1 std::cout << "H^1 error: " << std::sqrt(l2Error*l2Error + h1Error) << std::endl;
<< " "
<< "L^2 error: " << std::sqrt(l2ErrorSquared)
<< " "
<< "H^1 error: " << std::sqrt(l2ErrorSquared + h1ErrorSquared)
<< std::endl;
}
} }
...@@ -231,25 +260,53 @@ int main (int argc, char *argv[]) try ...@@ -231,25 +260,53 @@ int main (int argc, char *argv[]) try
referenceGrid->globalRefine(parameterSet.get<int>("numReferenceLevels")-1); referenceGrid->globalRefine(parameterSet.get<int>("numReferenceLevels")-1);
// Do the actual measurement // Do the actual measurement
const int order = parameterSet.get<int>("order"); const int order = parameterSet.get<int>("order");
switch (order)
if (parameterSet.get<std::string>("discretizationErrorMode")=="discrete")
{
switch (order)
{
case 1:
measureDiscreteEOC<GridType::LeafGridView,1>(grid->leafGridView(), referenceGrid->leafGridView(), parameterSet);
break;
case 2:
measureDiscreteEOC<GridType::LeafGridView,2>(grid->leafGridView(), referenceGrid->leafGridView(), parameterSet);
break;
case 3:
measureDiscreteEOC<GridType::LeafGridView,3>(grid->leafGridView(), referenceGrid->leafGridView(), parameterSet);
break;
default:
DUNE_THROW(NotImplemented, "Order '" << order << "' is not implemented");
}
}
if (parameterSet.get<std::string>("discretizationErrorMode")=="analytical")
{ {
case 1: switch (order)
measureEOC<GridType::LeafGridView,1>(grid->leafGridView(), referenceGrid->leafGridView(), parameterSet); {
break; case 1:
measureAnalyticalEOC<GridType::LeafGridView,1>(grid->leafGridView(), parameterSet);
break;
case 2: case 2:
measureEOC<GridType::LeafGridView,2>(grid->leafGridView(), referenceGrid->leafGridView(), parameterSet); measureAnalyticalEOC<GridType::LeafGridView,2>(grid->leafGridView(), parameterSet);
break; break;
case 3: case 3:
measureEOC<GridType::LeafGridView,3>(grid->leafGridView(), referenceGrid->leafGridView(), parameterSet); measureAnalyticalEOC<GridType::LeafGridView,3>(grid->leafGridView(), parameterSet);
break; break;
default: default:
DUNE_THROW(NotImplemented, "Order '" << order << "' is not implemented"); DUNE_THROW(NotImplemented, "Order '" << order << "' is not implemented");
}
} }
return 0; return 0;
} }
catch (Exception e) catch (Exception e)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment