Skip to content
Snippets Groups Projects
Commit a3077054 authored by Carsten Gräser's avatar Carsten Gräser
Browse files

Remove SumFunction and SumGridFunction

These classes implement the old function interface
and are no longer needed.
parent 56cc66fe
Branches
Tags
1 merge request!138Remove some Dune::VirtualFunction related stuff
......@@ -28,7 +28,7 @@
`dune-common` 2.7.
- The following implementations of the deprecated `Dune::VirtualFunction` interface
have been removed: `ConstantFunction`.
have been removed: `ConstantFunction`, `SumFunction`, `SumGridFunction`.
# 2.9 Release
......
......@@ -12,8 +12,6 @@ install(FILES
polynomial.hh
portablegreymap.hh
portablepixelmap.hh
sumfunction.hh
sumgridfunction.hh
vintagebasisgridfunction.hh
virtualdifferentiablefunction.hh
virtualgridfunction.hh
......
// -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set ts=8 sw=4 et sts=4:
#ifndef SUM_FUNCTION_HH
#define SUM_FUNCTION_HH
#include <vector>
#include <dune/common/exceptions.hh>
#include <dune/common/function.hh>
/** \brief A class implementing linear combinations of several functions.
*
* The function \f$ \sum a_if_i:A\rightarrow B \f$ where \f$ (\sum a_if_i)(x) = \sum a_i\cdot f_i(x) \f$
* is implemented.
* \tparam DT type of \f$ domain(f_i)\f$
* \tparam RT type of \f$ range(f_i)\f$
*/
template <typename DT, typename RT>
class SumFunction :
virtual public Dune::VirtualFunction<DT, RT>
{
typedef Dune::VirtualFunction<DT,RT> BaseType;
public:
typedef typename BaseType::DomainType DomainType;
typedef typename BaseType::RangeType RangeType;
/** \brief Default Constructor
*
*/
SumFunction()
{}
/** \brief Constructor
*
*/
SumFunction(std::vector<const BaseType*>& functions, std::vector<double>& coefficients):
functions_(functions),
coefficients_(coefficients)
{
if (functions_.size() != coefficients.size())
DUNE_THROW(Dune::Exception,"You have not supplied the correct number of coefficients in SumFunction::SumFunction(std::vector<BaseType*>&, std::vector<double>&) (sumfunction.hh)");
}
/** \brief evaluation using evaluate of the respective functions
*
* \param x point in \f$ A \f$ at which to evaluate
* \param y variable to store the function value in
*/
virtual void evaluate(const DomainType& x, RangeType& y) const
{
y = 0.0;
if (functions_.size()==0)
DUNE_THROW(Dune::Exception,"No function has been registered for summed evaluation in SumFunction::evaluate (sumfunction.hh)");
RangeType ytemp;
for (size_t i=0; i<functions_.size(); ++i)
{
functions_[i]->evaluate(x,ytemp);
ytemp *= coefficients_[i];
y += ytemp;
}
return;
}
/** \brief register functions to be summed up
*
* \param coefficient for summand function
* \param function summand function to register
*/
virtual void registerFunction(double coefficient, const BaseType& function)
{
functions_.push_back(&function);
coefficients_.push_back(coefficient);
}
~SumFunction(){}
private:
std::vector<const BaseType*> functions_;
std::vector<double> coefficients_;
};
#endif
// -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set ts=8 sw=4 et sts=4:
#ifndef SUM_GRID_FUNCTION_HH
#define SUM_GRID_FUNCTION_HH
#include <vector>
#include <dune/fufem/functions/virtualgridfunction.hh>
/** \brief A class implementing linear combinations of several GridFunctions.
*
* The function \f$ \sum a_if_i:GridType:[...]:GlobalCoordinate\rightarrow B \f$ where \f$ (\sum a_if_i)(x) = \sum a_i\cdot f_i(x) \f$
* is implemented.
* \tparam GridType the GridType of the grid on which the GridFunctions are given
* \tparam RT type of \f$ range(f_i)\f$
*/
template <typename GridType, typename RT>
class SumGridFunction:
public VirtualGridFunction<GridType, RT>
{
typedef VirtualGridFunction<GridType, RT> BaseType;
typedef typename GridType::Traits::template Codim<0>::Entity Element;
public:
typedef typename BaseType::LocalDomainType LocalDomainType;
typedef typename BaseType::DomainType DomainType;
typedef typename BaseType::RangeType RangeType;
typedef typename BaseType::DerivativeType DerivativeType;
/** \brief Default Constructor
*
*/
SumGridFunction(const GridType& grid):
BaseType(grid)
{}
/** \brief summed up local evaluation using evaluateLocal of the registered functions
*
* \param e Grid Element on which to evaluate locally
* \param x point at which to evaluate
* \param y object to store the function value in
*/
virtual void evaluateLocal(const Element& e, const LocalDomainType& x, RangeType& y) const
{
if (not(isDefinedOn(e)))
DUNE_THROW(Dune::Exception, "SumGridFunction not defined on given element.");
y = 0.0;
if (functions_.size()==0)
DUNE_THROW(Dune::Exception,"No function has been registered for summed evaluation");
RangeType ytemp;
for (size_t i=0; i<functions_.size(); ++i)
{
functions_[i]->evaluateLocal(e,x,ytemp);
ytemp *= coefficients_[i];
y += ytemp;
}
return;
}
/** \brief evaluation of derivative in local coordinates
*
* \param e Evaluate in local coordinates with respect to this element.
* \param x point in local coordinates at which to evaluate the derivative
* \param d will contain the derivative at x after return
*/
virtual void evaluateDerivativeLocal(const Element& e, const LocalDomainType& x, DerivativeType& d) const
{
if (not(isDefinedOn(e)))
DUNE_THROW(Dune::Exception, "SumGridFunction not defined on given element.");
d = 0.0;
if (functions_.size()==0)
DUNE_THROW(Dune::Exception,"No function has been registered for summed evaluation");
DerivativeType dtemp;
for (size_t i=0; i<functions_.size(); ++i)
{
functions_[i]->evaluateDerivativeLocal(e,x,dtemp);
dtemp *= coefficients_[i];
d += dtemp;
}
return;
}
/**
* \brief Check whether local evaluation is possible
*
* \param e Return true if local evaluation is possible on this element.
*/
virtual bool isDefinedOn(const Element& e) const
{
bool r=true;
for (size_t i=0; i<functions_.size(); ++i)
r = r and functions_[i]->isDefinedOn(e);
return r;
}
/** \brief register functions to be summed up
*
* \param coefficient of summand function
* \param function summand (grid-)function to register
*/
virtual void registerFunction(double coefficient, const BaseType& function)
{
functions_.push_back(&function);
coefficients_.push_back(coefficient);
}
~SumGridFunction(){}
private:
std::vector<const BaseType*> functions_;
std::vector<double> coefficients_;
};
#endif
......@@ -24,7 +24,6 @@ set(GRID_BASED_TESTS
polynomialtest
secondorderassemblertest
subgridxyfunctionalassemblertest
sumfunctiontest
tensortest
transferoperatorassemblertest
vintagebasisgridfunctiontest
......
#include <config.h>
#include <cmath>
#include <cstdio>
#include <dune/common/parallel/mpihelper.hh>
#include <dune/common/exceptions.hh>
#include <dune/common/fvector.hh>
#include <dune/common/function.hh>
#include <dune/fufem/functions/sumfunction.hh>
#include <dune/fufem/functions/sumgridfunction.hh>
#include <dune/fufem/functions/basisgridfunction.hh>
#include <dune/fufem/functions/virtualgridfunction.hh>
#include <dune/fufem/functiontools/basisinterpolator.hh>
#include <dune/fufem/functionspacebases/dunefunctionsbasis.hh>
#include <dune/functions/functionspacebases/lagrangebasis.hh>
#include "common.hh"
/** \brief sin^2(comp) or cos^2(comp) as specified in constructor
*
*/
template <class DT, class RT>
class TrigFunctionSquared:
public Dune::VirtualFunction<DT,RT>
{
typedef Dune::VirtualFunction<DT,RT> BaseType;
public:
enum Trig {
SIN,
COS
};
typedef typename BaseType::DomainType DomainType;
typedef typename BaseType::RangeType RangeType;
TrigFunctionSquared(int comp, Trig basic_trig):
trig_(basic_trig),
comp_(comp)
{}
virtual void evaluate(const DomainType& x, RangeType& y) const
{
double temp{0};
switch (trig_) {
case SIN:
temp=sin(x[comp_]);
break;
case COS:
temp=cos(x[comp_]);
break;
}
y = temp*temp;
}
private:
Trig trig_;
int comp_;
};
/** \brief TestSuite for SumFunction
*
* Takes a '2D partition of 1', here 1 = (0.5*sin^2(x)+0.5*sin^2(y)) + (0.5*cos^2(x)+0.5*cos^2(y)), and implement it as nested SumFunction.
* Validation against 1.
*/
struct SumFunctionTestSuite
{
bool check()
{
const int DDIM=2;
const int RDIM=2;
const int n_testpoints=100;
typedef Dune::FieldVector<double,DDIM> DomainType;
typedef Dune::FieldVector<double,RDIM> RangeType;
typedef TrigFunctionSquared<DomainType,RangeType> TFType;
TFType sin2x(0,TFType::SIN);
TFType sin2y(1,TFType::SIN);
TFType cos2x(0,TFType::COS);
TFType cos2y(1,TFType::COS);
SumFunction<DomainType,RangeType> sumfunction1;
sumfunction1.registerFunction(0.5, sin2x);
sumfunction1.registerFunction(0.5, sin2y);
SumFunction<DomainType,RangeType> sumfunction2;
sumfunction2.registerFunction(0.5, cos2x);
sumfunction2.registerFunction(0.5, cos2y);
SumFunction<DomainType,RangeType> sumfunction;
sumfunction.registerFunction(1.0,sumfunction1);
sumfunction.registerFunction(1.0,sumfunction2);
SumFunction<DomainType,RangeType> checkfunction;
checkfunction.registerFunction(1.0,sin2x);
checkfunction.registerFunction(1.0,cos2x);
DomainType x(0.0);
RangeType y(0.0),
ycheck(0.0);
for (int run=0; run<n_testpoints; ++run)
{
for (int dcomp=0; dcomp<DDIM; ++dcomp)
x[dcomp] = (6.3*rand())/RAND_MAX - 3.15;
sumfunction.evaluate(x,y);
checkfunction.evaluate(x,ycheck);
for (int rcomp=0; rcomp<RDIM; ++rcomp)
if (y[rcomp]-1.0>1e-12)
{
std::cout << "(0.5*sin^2(x)+0.5*sin^2(y)) + (0.5*cos^2(x)+0.5*cos^2(y)) = " << y[rcomp] << std::endl;
std::cout << "check: sin^2(x)+cos^2(x) = " << ycheck[rcomp] << std::endl;
return false;
}
}
return true;
}
};
/** \brief TestSuite for SumGridFunction
*
* Use partition of 1 as above for P1 GridFunctions. They still should add up to 1 everywhere.
*
*/
struct SumGridFunctionTestSuite
{
template <class GridType>
bool check(GridType& grid)
{
const int RDIM=2;
typedef typename GridType::template Codim<0>::Geometry::GlobalCoordinate DomainType;
typedef Dune::FieldVector<double,RDIM> RangeType;
typedef TrigFunctionSquared<DomainType,RangeType> TFType;
TFType sin2x(0,TFType::SIN);
TFType sin2y(1,TFType::SIN);
TFType cos2x(0,TFType::COS);
TFType cos2y(1,TFType::COS);
typedef DuneFunctionsBasis<Dune::Functions::LagrangeBasis<typename GridType::LeafGridView,1 > > Basis;
Basis basis(grid.leafGridView());
typedef Dune::BlockVector<RangeType> CoeffType;
CoeffType coeffs1(basis.size()),
coeffs2(basis.size()),
coeffs3(basis.size()),
coeffs4(basis.size());
typedef BasisGridFunction<Basis,CoeffType> GridFunctionType;
CoeffType sumVector;
Functions::interpolate(basis,coeffs1,sin2x);
GridFunctionType summand1(basis,coeffs1);
sumVector = coeffs1;
Functions::interpolate(basis,coeffs2,sin2y);
GridFunctionType summand2(basis,coeffs2);
sumVector += coeffs2;
Functions::interpolate(basis,coeffs3,cos2x);
GridFunctionType summand3(basis,coeffs3);
sumVector += coeffs3;
Functions::interpolate(basis,coeffs4,cos2y);
GridFunctionType summand4(basis,coeffs4);
sumVector += coeffs4;
for (size_t i=0; i<basis.size();++i)
for (int j=0; j<RDIM; ++j)
if (std::abs(sumVector[i][j]-2.0) > 1e-12 )
{
std::cout << i << ", " << j << ": " << sumVector[i][j] << std::endl;
return false;
}
SumGridFunction<GridType,RangeType> sumfunction1(grid);
sumfunction1.registerFunction(0.5, summand1);
sumfunction1.registerFunction(0.5, summand2);
SumGridFunction<GridType,RangeType> sumfunction2(grid);
sumfunction2.registerFunction(0.5, summand3);
sumfunction2.registerFunction(0.5, summand4);
SumGridFunction<GridType,RangeType> sumfunction(grid);
sumfunction.registerFunction(1.0,sumfunction1);
sumfunction.registerFunction(1.0,sumfunction2);
SumGridFunction<GridType,RangeType> checkfunction(grid);
checkfunction.registerFunction(1.0, summand1);
checkfunction.registerFunction(1.0, summand3);
std::function<RangeType(DomainType)> one = [](DomainType x) -> RangeType { return RangeType(1.0); };
return compareEvaluateByGridViewQuadrature(sumfunction, one, grid.leafGridView(), 3);
}
};
int main(int argc, char** argv)
{
Dune::MPIHelper::instance(argc, argv);
std::cout << "This is the SumFunctionTest" << std::endl;
SumFunctionTestSuite sftests;
SumGridFunctionTestSuite sgftests;
bool passed = sftests.check();
if (passed)
std::cout << "SumFunction test passed" << std::endl;
else
std::cout << "SumFunction test failed" << std::endl;
#if HAVE_DUNE_UGGRID
passed = passed and checkWithAdaptiveGrid<Dune::UGGrid<2> >(sgftests, 3, 3);
if (not passed)
std::cout << "SumGridFunction test failed on locally refined UGGrid<2>." << std::endl;
#if HAVE_DUNE_SUBGRID
passed = passed and checkWithSubGrid<Dune::UGGrid<2> >(sgftests, 3, 3, "SubGrid< 2,UGGrid<2> >");
if (not passed)
std::cout << "SumGridFunction test failed on locally refined SubGrid< 2,UGGrid<2> >." << std::endl;
#endif
#endif
#if HAVE_DUNE_ALUGRID
passed = passed and checkWithAdaptiveGrid<Dune::ALUGrid<2,2, Dune::simplex, Dune::nonconforming> >(sgftests, 3, 3);
if (not passed)
std::cout << "SumGridFunction test failed on locally refined ALUGrid<2,2,simplex,nonconforming>." << std::endl;
#if HAVE_DUNE_SUBGRID
passed = passed and checkWithSubGrid<Dune::ALUGrid<2,2, Dune::simplex, Dune::nonconforming> >(sgftests, 3, 3, "SubGrid< 3,ALUGrid<...> >");
if (not passed)
std::cout << "SumGridFunction test failed on locally refined SubGrid< 2,ALUGrid<2,2,simplex,nonconforming> >." << std::endl;
#endif
#endif
return passed ? 0 : 1;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment