virtual void evaluate(const GeometricalData<CoordinateType>& geomData,
                          arma::Mat<ValueType>& result) const {
        const arma::Mat<CoordinateType>& points  = geomData.globals;
        const arma::Mat<CoordinateType>& normals = geomData.normals;

#ifndef NDEBUG
        if ((int)points.n_rows != worldDimension() ||
                (int)points.n_rows != worldDimension())
            throw std::invalid_argument(
                    "SurfaceNormalAndDomainIndexDependentFunction::evaluate(): "
                    "incompatible world dimension");
#endif

        const size_t pointCount = points.n_cols;
        result.set_size(codomainDimension(), pointCount);
        for (size_t i = 0; i < pointCount; ++i) {
            arma::Col<ValueType> activeResultColumn = result.unsafe_col(i);
            m_functor.evaluate(points.unsafe_col(i), normals.unsafe_col(i),
                               geomData.domainIndex, activeResultColumn);
        }
    }
  virtual void evaluate(const GeometricalData<CoordinateType> &geomData,
                        Matrix<ValueType> &result) const {
    const Matrix<CoordinateType> &points = geomData.globals;
    const Matrix<CoordinateType> &normals = geomData.normals;

#ifndef NDEBUG
    if ((int)points.rows() != worldDimension())
      throw std::invalid_argument("SurfaceNormalDependentFunction::evaluate(): "
                                  "incompatible world dimension");
#endif

    const size_t pointCount = points.cols();
    result.resize(codomainDimension(), pointCount);
    for (size_t i = 0; i < pointCount; ++i) {
      Eigen::Map<Vector<ValueType>> activeResultColumn(result.col(i).data(),
                                                       result.rows());
      m_functor.evaluate(points.col(i), normals.col(i), activeResultColumn);
    }
  }