std::auto_ptr<InterpolatedFunction<ResultType> >
ElementaryPotentialOperator<BasisFunctionType, KernelType, ResultType>::
evaluateOnGrid(
        const GridFunction<BasisFunctionType, ResultType>& argument,
        const Grid& evaluationGrid,
        const QuadratureStrategy& quadStrategy,
        const EvaluationOptions& options) const
{
    if (evaluationGrid.dimWorld() != argument.grid()->dimWorld())
        throw std::invalid_argument(
                "ElementaryPotentialOperator::evaluateOnGrid(): "
                "the evaluation grid and the surface on which the grid "
                "function 'argument' is defined must be embedded in a space "
                "of the same dimension");

    // Get coordinates of interpolation points, i.e. the evaluationGrid's vertices

    std::auto_ptr<GridView> evalView = evaluationGrid.leafView();
    const int evalGridDim = evaluationGrid.dim();
    const int evalPointCount = evalView->entityCount(evalGridDim);
    arma::Mat<CoordinateType> evalPoints(evalGridDim, evalPointCount);

    const IndexSet& evalIndexSet = evalView->indexSet();
    // TODO: extract into template function, perhaps add case evalGridDim == 1
    if (evalGridDim == 2) {
        const int vertexCodim = 2;
        std::auto_ptr<EntityIterator<vertexCodim> > it =
                evalView->entityIterator<vertexCodim>();
        while (!it->finished()) {
            const Entity<vertexCodim>& vertex = it->entity();
            const Geometry& geo = vertex.geometry();
            const int vertexIndex = evalIndexSet.entityIndex(vertex);
            arma::Col<CoordinateType> activeCol(evalPoints.unsafe_col(vertexIndex));
            geo.getCenter(activeCol);
            it->next();
        }
    } else if (evalGridDim == 3) {
        const int vertexCodim = 3;
        std::auto_ptr<EntityIterator<vertexCodim> > it =
                evalView->entityIterator<vertexCodim>();
        while (!it->finished()) {
            const Entity<vertexCodim>& vertex = it->entity();
            const Geometry& geo = vertex.geometry();
            const int vertexIndex = evalIndexSet.entityIndex(vertex);
            arma::Col<CoordinateType> activeCol(evalPoints.unsafe_col(vertexIndex));
            geo.getCenter(activeCol);
            it->next();
        }
    }

    arma::Mat<ResultType> result;
    result = evaluateAtPoints(argument, evalPoints, quadStrategy, options);

    return std::auto_ptr<InterpolatedFunction<ResultType> >(
                new InterpolatedFunction<ResultType>(evaluationGrid, result));
}
arma::Mat<ValueType> DiscreteBoundaryOperator<ValueType>::asMatrix() const {
  // Default brute-force implementation: apply operator to all basis vectors
  const size_t nRows = rowCount();
  const size_t nCols = columnCount();
  arma::Col<ValueType> unit(nCols);
  arma::Mat<ValueType> result(nRows, nCols);
  result.fill(0.); // for safety, in case there was a bug in the handling of
                   // beta == 0. in a particular subclass' applyBuiltInImpl()
                   // override...
  unit.fill(0.);
  for (size_t i = 0; i < nCols; ++i) {
    arma::Col<ValueType> activeCol(result.unsafe_col(i));
    if (i > 0)
      unit(i - 1) = 0.;
    unit(i) = 1.;
    applyBuiltInImpl(NO_TRANSPOSE, unit, activeCol, 1., 0.);
  }

  return result;
}