generic-kernel.hpp

This header file defines the GenericKernel template class, which simplifies building new custom kernel objects. Kernels for Laplace and Stokes in 3D are defined in kernel_functions.hpp and can be used as a template.

Classes and Types

template<class uKernel>
class GenericKernel : public uKernel

This class is designed to help create new custom kernel objects. Kernel objects for Laplace and Stokes in 3D are defined in kernel_functions.hpp and can be used as a template.

See also

kernel_functions.hpp

Template Parameters:

uKernel – The base class for the kernel.

Static Member Functions:

  • CoordDim(): Returns the coordinate dimension.

  • NormalDim(): Returns the normal dimension.

  • SrcDim(): Returns the source dimension.

  • TrgDim(): Returns the target dimension.

  • Eval(v_trg, r_trg, r_src, n_src, v_src, digits, self): Evaluates the kernel and stores the result in v_trg.

Member Functions:

  • GetCtxPtr() const: Returns a constant pointer to the context.

  • Eval(v_trg, r_trg, r_src, n_src, v_src) const: Evaluates the kernel with optional template parameters for OpenMP and digits.

  • KernelMatrix(M, Xt, Xs, Xn) const: Computes the kernel matrix and stores it in M.

Usage guide: Writing Custom Kernel Objects, kernel_functions.hpp



#ifndef _SCTL_GENERIC_KERNEL_HPP_
#define _SCTL_GENERIC_KERNEL_HPP_

#include "sctl/common.hpp"  // for Integer, sctl
#include "sctl/vec.hpp"     // for Vec

namespace sctl {

template <class ValueType> class Vector;
template <class ValueType> class Matrix;

template <class uKernel, Integer KDIM0, Integer KDIM1, Integer DIM, Integer N_DIM> struct uKerHelper {
  template <Integer digits, class VecType> static void MatEval(VecType (&u)[KDIM0][KDIM1], const VecType (&r)[DIM], const VecType (&n)[N_DIM], const void* ctx_ptr) {
    uKernel::template uKerMatrix<digits>(u, r, n, ctx_ptr);
  }
};
template <class uKernel, Integer KDIM0, Integer KDIM1, Integer DIM> struct uKerHelper<uKernel,KDIM0,KDIM1,DIM,0> {
  template <Integer digits, class VecType, class NormalType> static void MatEval(VecType (&u)[KDIM0][KDIM1], const VecType (&r)[DIM], const NormalType& n, const void* ctx_ptr) {
    uKernel::template uKerMatrix<digits>(u, r, ctx_ptr);
  }
};

/**
 * @class GenericKernel
 * This class is designed to help create new custom kernel objects. Kernel objects for Laplace and Stokes in 3D are defined in `kernel_functions.hpp` and can be used as a template.
 *
 * @tparam uKernel The base class for the kernel.
 *
 * @see kernel_functions.hpp
 */
template <class uKernel> class GenericKernel : public uKernel {

    template <class VecType, Integer K0, Integer K1, Integer D, class ...T> static constexpr Integer get_DIM  (void (*uKer)(VecType (&u)[K0][K1], const VecType (&r)[D], T... args)) { return D;  }
    template <class VecType, Integer K0, Integer K1, Integer D, class ...T> static constexpr Integer get_KDIM0(void (*uKer)(VecType (&u)[K0][K1], const VecType (&r)[D], T... args)) { return K0; }
    template <class VecType, Integer K0, Integer K1, Integer D, class ...T> static constexpr Integer get_KDIM1(void (*uKer)(VecType (&u)[K0][K1], const VecType (&r)[D], T... args)) { return K1; }

    static constexpr Integer DIM   = get_DIM  (uKernel::template uKerMatrix<0,Vec<double,1>>);
    static constexpr Integer KDIM0 = get_KDIM0(uKernel::template uKerMatrix<0,Vec<double,1>>);
    static constexpr Integer KDIM1 = get_KDIM1(uKernel::template uKerMatrix<0,Vec<double,1>>);


    template <Integer cnt> static constexpr Integer argsize_helper() { return 0; }
    template <Integer cnt, class T, class ...T1> static constexpr Integer argsize_helper() { return (cnt == 0 ? sizeof(T) : 0) + argsize_helper<cnt-1, T1...>(); }
    template <Integer idx, class ...T1> static constexpr Integer argsize(void (uKer)(T1... args)) { return argsize_helper<idx, T1...>(); }

    template <Integer cnt> static constexpr Integer argcount_helper() { return cnt; }
    template <Integer cnt, class T, class ...T1> static constexpr Integer argcount_helper() { return argcount_helper<cnt+1, T1...>(); }
    template <class ...T1> static constexpr Integer argcount(void (uKer)(T1... args)) { return argcount_helper<0, T1...>(); }

    static constexpr Integer ARGCNT = argcount(uKernel::template uKerMatrix<0,Vec<double,1>>);
    static constexpr Integer N_DIM = (ARGCNT > 3 ? argsize<2>(uKernel::template uKerMatrix<0,Vec<double,1>>)/sizeof(Vec<double,1>) : 0);
    static constexpr Integer N_DIM_ = (N_DIM?N_DIM:1); // non-zero

  public:

    /**
     * Default constructor.
     */
    GenericKernel();

    /**
     * Returns the coordinate dimension.
     * @return The coordinate dimension.
     */
    static constexpr Integer CoordDim();

    /**
     * Returns the dimensions of the normal vector. It will return zero if the kernel function does
     * not require a normal vector; otherwise it will return DIM.
     *
     * @return The normal dimension.
     */
    static constexpr Integer NormalDim();

    /**
     * Returns the source dimension.
     * @return The source dimension.
     */
    static constexpr Integer SrcDim();

    /**
     * Returns the target dimension.
     * @return The target dimension.
     */
    static constexpr Integer TrgDim();

    /**
     * Set the pointer to the context data.
     */
    void SetCtxPtr(void* ctx);

    /**
     * Returns a constant pointer to the context.
     * @return A constant pointer to the context.
     */
    const void* GetCtxPtr() const;

    /**
     * Evaluates the kernel and stores the result in `v_trg`.
     * @tparam Real The type of the real numbers used.
     * @tparam enable_openmp A boolean flag to enable OpenMP.
     * @param v_trg The vector to store the potential result.
     * @param r_trg The vector of target point coordinates.
     * @param r_src The vector of source point coordinates.
     * @param n_src The vector of source normals.
     * @param v_src The vector of source densities.
     * @param digits The number of significant digits for evaluation.
     * @param self A constant iterator pointing to the self interaction flag.
     */
    template <class Real, bool enable_openmp> static void Eval(Vector<Real>& v_trg, const Vector<Real>& r_trg, const Vector<Real>& r_src, const Vector<Real>& n_src, const Vector<Real>& v_src, Integer digits, ConstIterator<char> self);

    /**
     * Evaluates the kernel and stores the result in `v_trg`.
     * @tparam Real The type of the real numbers used.
     * @tparam enable_openmp A boolean flag to enable OpenMP. Default is false.
     * @tparam digits The number of significant digits for evaluation. Default is -1 for machine-precision.
     * @param v_trg The vector to store the potential result.
     * @param r_trg The vector of target point coordinates.
     * @param r_src The vector of source point coordinates.
     * @param n_src The vector of source normals.
     * @param v_src The vector of source densities.
     */
    template <class Real, bool enable_openmp=false, Integer digits=-1> void Eval(Vector<Real>& v_trg, const Vector<Real>& r_trg, const Vector<Real>& r_src, const Vector<Real>& n_src, const Vector<Real>& v_src) const;

    /**
     * Computes the kernel matrix and stores it in `M`.
     * @tparam Real The type of the real numbers used.
     * @tparam enable_openmp A boolean flag to enable OpenMP. Default is false.
     * @tparam digits The number of significant digits for evaluation. Default is -1.
     * @param M The matrix to store the kernel matrix.
     * @param Xt The vector of target point coordinates.
     * @param Xs The vector of source point coordinates.
     * @param Xn The vector of source normals.
     */
    template <class Real, bool enable_openmp=false, Integer digits=-1> void KernelMatrix(Matrix<Real>& M, const Vector<Real>& Xt, const Vector<Real>& Xs, const Vector<Real>& Xn) const;

    /**
     * Static method for kernel matrix computation.
     * @tparam digits The number of significant digits for evaluation.
     * @tparam VecType The vector type.
     * @tparam NormalType The normal type.
     * @param u The output kernel matrix.
     * @param r The input coordinates.
     * @param n The input normals.
     * @param ctx_ptr The context pointer.
     */
    template <Integer digits, class VecType, class NormalType> static void uKerMatrix(VecType (&u)[KDIM0][KDIM1], const VecType (&r)[DIM], const NormalType& n, const void* ctx_ptr);

  private:
    void* ctx_ptr;
};

}  // end namespace

#endif // _SCTL_GENERIC_KERNEL_HPP_