void evaluateOnGridPeter(std::string str, const GeometricalData<CoordinateType> &testGeomData, const GeometricalData<CoordinateType> &trialGeomData, CollectionOf4dArrays<ValueType> &result) const {
  const size_t testPointCount = testGeomData.pointCount();
  const size_t trialPointCount = trialGeomData.pointCount();
  const size_t kernelCount = m_functor.kernelCount();
  result.set_size(kernelCount);
  for (size_t k = 0; k < kernelCount; ++k)
    result[k].set_size(m_functor.kernelRowCount(k), m_functor.kernelColCount(k),
                       testPointCount, trialPointCount);

#pragma ivdep
  for (size_t trialIndex = 0; trialIndex < trialPointCount; ++trialIndex)
    for (size_t testIndex = 0; testIndex < testPointCount; ++testIndex)
//      m_functor.evaluate(testGeomData.const_slice(testIndex), trialGeomData.const_slice(trialIndex), result.slice(testIndex, trialIndex).self());
      m_functor.evaluatePeter(str,testGeomData.const_slice(testIndex), trialGeomData.const_slice(trialIndex), result.slice(testIndex, trialIndex).self());
}
//Peter:
//template <typename Functor>
//template <template <typename T> class CollectionOf2dSlicesOfNdArrays>
void evaluateAtPointPairsPeter(std::string str, const GeometricalData<CoordinateType> &testGeomData, const GeometricalData<CoordinateType> &trialGeomData, CollectionOf3dArrays<ValueType> &result) const {
  assert(testGeomData.pointCount() == trialGeomData.pointCount());
  const size_t pointCount = testGeomData.pointCount();
  const size_t kernelCount = m_functor.kernelCount();
  result.set_size(kernelCount);
//std::cout << "evalAtPointPairsPeter\n";
//  CoordinateType m_waveNumber = m_functor.waveNumber();
//  ValueType m_waveNumber = m_functor.waveNumber();
//	std::string::size_type sz;     // alias of size_t
//  double earth = std::stod (orbits,&sz);
//  double moon = std::stod (orbits.substr(sz));
//	ValueType waveK = static_cast<CoordinateType>(std::stod(str,&sz) );
//	std::cerr << "In defColKern, str = " << str << std::endl;
//	ValueType waveK = static_cast<CoordinateType>(str);

  for (size_t k = 0; k < kernelCount; ++k)
    result[k].set_size(m_functor.kernelRowCount(k), m_functor.kernelColCount(k),
                       pointCount);

  for (size_t p = 0; p < pointCount; ++p) {
/*	if(std::is_same<Functor,ModifiedHelmholtz3dSingleLayerPotentialKernelFunctor<ValueType>>::value) {
		std::cout << "Right kernel" << std::endl;
		m_functor.evaluatePeter(str, testGeomData.const_slice(p), trialGeomData.const_slice(p), result.slice(p).self());		
	}
	else {
		std::cerr << "Wrong kernel" << std::endl;
		std::terminate();
	}*/
//		(m_functor*)->evaluatePeter(str, testGeomData.const_slice(p), trialGeomData.const_slice(p), result.slice(p).self());		
//std::unique_ptr<ModifiedHelmholtz3dSingleLayerPotentialKernelFunctor<ValueType> >(m_functor)->evaluatePeter(str, testGeomData.const_slice(p), trialGeomData.const_slice(p), result.slice(p).self());
//	const ModifiedHelmholtz3dSingleLayerPotentialKernelFunctor<ValueType>& tmp = dynamic_cast<const ModifiedHelmholtz3dSingleLayerPotentialKernelFunctor<ValueType>& >(m_functor);
//	ModifiedHelmholtz3dSingleLayerPotentialKernelFunctor<ValueType> tmp = static_cast<ModifiedHelmholtz3dSingleLayerPotentialKernelFunctor<ValueType> >(m_functor);
//		static_cast<ModifiedHelmholtz3dSingleLayerPotentialKernelFunctor<ValueType> >(m_functor).evaluatePeter(str, testGeomData.const_slice(p), trialGeomData.const_slice(p), result.slice(p).self());
		m_functor.evaluatePeter(str, testGeomData.const_slice(p), trialGeomData.const_slice(p), result.slice(p).self());

//	const ModifiedHelmholtz3dSingleLayerPotentialKernelFunctor<ValueType> bla = dynamic_cast<const ModifiedHelmholtz3dSingleLayerPotentialKernelFunctor<ValueType>& > (m_functor);
//	bla.evaluatePeter(str, testGeomData.const_slice(p), trialGeomData.const_slice(p), result.slice(p).self());

////    m_functor.evaluate(testGeomData.const_slice(p),
////                      trialGeomData.const_slice(p), result.slice(p).self());
/*
	const ConstGeometricalDataSlice<CoordinateType> &testGeomDataSl = testGeomData.const_slice(p);
	const ConstGeometricalDataSlice<CoordinateType> &trialGeomDataSl = trialGeomData.const_slice(p);
//	CollectionOf2dSlicesOfNdArrays<ValueType> &resultSl = result.slice(p).self();
	CollectionOf2dSlicesOf3dArrays<ValueType> &resultSl = result.slice(p).self();
	const int coordCount = 3;
	CoordinateType sum = 0;
	for (int coordIndex = 0; coordIndex < coordCount; ++coordIndex) {
		CoordinateType diff = testGeomDataSl.global(coordIndex) - trialGeomDataSl.global(coordIndex);
		sum += diff * diff;
	}
	CoordinateType distance = sqrt(sum);
	if (distance >= 2) {
		std::cerr << "Error, 2 <= distance =" << distance <<  std::endl;
	}
	CoordinateType wind = static_cast<CoordinateType>(1.0);
	CoordinateType cuto = static_cast<CoordinateType>(0.1);
	CoordinateType cutoSP = static_cast<CoordinateType>(0.3);
	if (false) {
		if (distance >= cuto*2) {
			wind = static_cast<CoordinateType>(0.0);
		}
		else if (distance >= cuto) {
			wind = exp(2*exp(-cuto/(distance-2*cuto) )/( (distance-2*cuto)/cuto-1) );
		} 
	}
//	result[0](0, 0) = static_cast<CoordinateType>(1.0 / (4.0 * M_PI)) / distance * exp(-m_waveNumber * distance)*wind;
//    result(0, 0) = static_cast<CoordinateType>(1.0 / (4.0 * M_PI)) / distance * exp(-m_waveNumber * distance)*wind;
	resultSl[0](0, 0) = static_cast<CoordinateType>(1.0 / (4.0 * M_PI)) / distance * exp(-waveK * distance)*wind;
*/
	}
}