8#include <kernel/assembly/base.hpp> 
    9#include <kernel/analytic/function.hpp> 
   10#include <kernel/util/dist.hpp> 
   11#include <kernel/lafem/dense_vector.hpp> 
   12#include <kernel/lafem/dense_vector_blocked.hpp> 
   43    template<
typename DataType_, 
typename ValueType_, 
typename GradientType_, 
typename HessianType_>
 
  168      static void _push_lmax(DataType_& a, 
const DataType_& b)
 
  173      template<
int n_, 
int sn_>
 
  176        for(
int i(0); i < n_; ++i)
 
  180      static void _write_to(DataType_* ptr, std::size_t& k, 
const DataType_& x)
 
  186      template<
int n_, 
int sn_>
 
  187      static void _write_to(DataType_* ptr, std::size_t& k, 
const Tiny::Vector<DataType_, n_, sn_>& x)
 
  189        for(
int i(0); i < n_; ++i, ++k)
 
  193      template<
int m_, 
int n_, 
int sm_, 
int sn_>
 
  194      static void _write_to(DataType_* ptr, std::size_t& k, 
const Tiny::Matrix<DataType_, m_, n_, sm_, sn_>& x)
 
  196        for(
int i(0); i < m_; ++i)
 
  197          _write_to(ptr, k, x[i]);
 
  200      template<
int l_, 
int m_, 
int n_, 
int sl_, 
int sm_, 
int sn_>
 
  201      static void _write_to(DataType_* ptr, std::size_t& k, 
const Tiny::Tensor3<DataType_, l_, m_, n_, sl_, sm_, sn_>& x)
 
  203        for(
int i(0); i < l_; ++i)
 
  204          _write_to(ptr, k, x[i]);
 
  207      static void _read_from(DataType_* ptr, std::size_t& k, DataType_& x)
 
  213      template<
int n_, 
int sn_>
 
  214      static void _read_from(DataType_* ptr, std::size_t& k, Tiny::Vector<DataType_, n_, sn_>& x)
 
  216        for(
int i(0); i < n_; ++i, ++k)
 
  220      template<
int m_, 
int n_, 
int sm_, 
int sn_>
 
  221      static void _read_from(DataType_* ptr, std::size_t& k, Tiny::Matrix<DataType_, m_, n_, sm_, sn_>& x)
 
  223        for(
int i(0); i < m_; ++i)
 
  224          _read_from(ptr, k, x[i]);
 
  227      template<
int l_, 
int m_, 
int n_, 
int sl_, 
int sm_, 
int sn_>
 
  228      static void _read_from(DataType_* ptr, std::size_t& k, Tiny::Tensor3<DataType_, l_, m_, n_, sl_, sm_, sn_>& x)
 
  230        for(
int i(0); i < l_; ++i)
 
  231          _read_from(ptr, k, x[i]);
 
  234      static String _print_val(
const DataType_& x, 
int prec)
 
  239      template<
int n_, 
int sn_>
 
  240      static String _print_val(
const Tiny::Vector<DataType_, n_, sn_>& x, 
int prec)
 
  243        for(
int i(0); i < n_; ++i)
 
  249      static String _print_val_sqrt(
const DataType_& x, 
int prec)
 
  254      template<
int n_, 
int sn_>
 
  255      static String _print_val_sqrt(
const Tiny::Vector<DataType_, n_, sn_>& x, 
int prec)
 
  258        for(
int i(0); i < n_; ++i)
 
  264      static String _print_norm(
const DataType_& x, 
const DataType_&, 
int prec)
 
  266        return _print_val(x, prec);
 
  269      template<
int n_, 
int sn_>
 
  270      static String _print_norm(
const DataType_& x, 
const Tiny::Vector<DataType_, n_, sn_>& v, 
int prec)
 
  272        return _print_val(x, prec) + 
" " + _print_val(v, prec);
 
  275      static String _print_norm_sqrt(
const DataType_& x, 
const DataType_&, 
int prec)
 
  280      template<
int n_, 
int sn_>
 
  281      static String _print_norm_sqrt(
const DataType_& x, 
const Tiny::Vector<DataType_, n_, sn_>& v, 
int prec)
 
  283        return _print_val(
Math::sqrt(x), prec) + 
" " + _print_val_sqrt(v, prec);
 
  286      template<
int m_, 
int n_, 
int sm_, 
int sn_>
 
  287      static DataType _calc_vorticity(
const Tiny::Matrix<DataType, m_, n_, sm_, sn_>&)
 
  293      template<
int sm_, 
int sn_>
 
  294      static DataType _calc_vorticity(
const Tiny::Matrix<DataType, 2, 2, sm_, sn_>& g)
 
  301      template<
int sm_, 
int sn_>
 
  302      static DataType _calc_vorticity(
const Tiny::Matrix<DataType, 3, 3, sm_, sn_>& g)
 
  370        value += other.value;
 
  419      template<
int n_, 
int sn_>
 
  423        for(
int i(0); i < n_; ++i)
 
  447      template<
int n_, 
int sn_>
 
  465      template<
int m_, 
int n_, 
int sm_, 
int sn_>
 
  469        for(
int i(0); i < m_; ++i)
 
  471          const DataType sv = g[i].norm_euclid_sqr();
 
  494      template<
int m_, 
int n_, 
int sm_, 
int sn_>
 
  512      template<
int l_, 
int m_, 
int n_, 
int sl_, 
int sm_, 
int sn_>
 
  516        for(
int i(0); i < l_; ++i)
 
  518          const DataType sv = h[i].norm_hessian_sqr();
 
  539        static constexpr std::size_t max_len = std::size_t(7) +
 
  545        _write_to(v, k, 
value);
 
  546        _write_to(v, k, 
grad);
 
  547        _write_to(v, k, 
hess);
 
  565        _read_from(v, k, 
value);
 
  566        _read_from(v, k, 
grad);
 
  567        _read_from(v, k, 
hess);
 
  678    template<
typename FuncIntInfo_, 
typename CellVector_>
 
  682      FuncIntInfo_ integral_info;
 
  691        integral_info.push(other.integral_info);
 
  698        integral_info.format();
 
  699        integral_info.push(other.integral_info);
 
  707        integral_info.push(info);
 
  712        vec(std::move(in_vec))
 
  714        integral_info.push(info);
 
  731    template<
typename DataType_, 
typename Function_>
 
  758    template<
typename Vector_, 
typename Space_>
 
  762    template<
typename DT_, 
typename IT_, 
typename Space_>
 
  772    template<
typename DT_, 
typename IT_, 
int bs_, 
typename Space_>
 
  784      template<
int max_der_>
 
  785      struct AnaFunIntJobHelper;
 
  788      struct AnaFunIntJobHelper<0>
 
  790        template<
typename FID_, 
typename DT_, 
typename FEV_, 
typename IPT_>
 
  791        static void work(FID_& fid, 
const DT_ omega, FEV_& fev, 
const IPT_& ipt)
 
  793          fid.add_value(omega, fev.value(ipt));
 
  798      struct AnaFunIntJobHelper<1>
 
  800        template<
typename FID_, 
typename DT_, 
typename FEV_, 
typename IPT_>
 
  801        static void work(FID_& fid, 
const DT_ omega, FEV_& fev, 
const IPT_& ipt)
 
  803          fid.add_value(omega, fev.value(ipt));
 
  804          fid.add_grad(omega, fev.gradient(ipt));
 
  809      struct AnaFunIntJobHelper<2>
 
  811        template<
typename FID_, 
typename DT_, 
typename FEV_, 
typename IPT_>
 
  812        static void work(FID_& fid, 
const DT_ omega, FEV_& fev, 
const IPT_& ipt)
 
  814          fid.add_value(omega, fev.value(ipt));
 
  815          fid.add_grad(omega, fev.gradient(ipt));
 
  816          fid.add_hess(omega, fev.hessian(ipt));
 
  820      template<
int max_der_>
 
  821      struct DiscFunIntJobHelper;
 
  824      struct DiscFunIntJobHelper<0>
 
  826        template<
typename FID_, 
typename DT_, 
typename SED_, 
typename VT_, 
int n_, 
int sn_>
 
  827        static void work(FID_& fid, 
const DT_ omega, 
const SED_& sed,
 
  828          const Tiny::Vector<VT_, n_, sn_>& lvec, 
int n)
 
  830          typename FID_::ValueType    v(DT_(0));
 
  831          for(
int i(0); i < n; ++i)
 
  833            v += lvec[i] * sed.phi[i].value;
 
  835          fid.add_value(omega, v);
 
  840      struct DiscFunIntJobHelper<1>
 
  843        template<
typename FID_, 
typename DT_, 
typename SED_, 
int n_, 
int sn_>
 
  844        static void work(FID_& fid, 
const DT_ omega, 
const SED_& sed,
 
  845          const Tiny::Vector<DT_, n_, sn_>& lvec, 
int n)
 
  847          typename FID_::ValueType    v(DT_(0));
 
  848          typename FID_::GradientType g(DT_(0));
 
  849          for(
int i(0); i < n; ++i)
 
  851            v += lvec[i] * sed.phi[i].value;
 
  852            g += lvec[i] * sed.phi[i].grad;
 
  854          fid.add_value(omega, v);
 
  855          fid.add_grad(omega, g);
 
  858        template<
typename FID_, 
typename DT_, 
typename SED_, 
int d_, 
int sd_, 
int n_, 
int sn_>
 
  859        static void work(FID_& fid, 
const DT_ omega, 
const SED_& sed,
 
  860          const Tiny::Vector<Tiny::Vector<DT_, d_, sd_>, n_, sn_>& lvec, 
int n)
 
  862          typename FID_::ValueType    v(DT_(0));
 
  863          typename FID_::GradientType g(DT_(0));
 
  864          for(
int i(0); i < n; ++i)
 
  866            v.axpy(sed.phi[i].value, lvec[i]);
 
  867            g.add_outer_product(lvec[i], sed.phi[i].grad);
 
  869          fid.add_value(omega, v);
 
  870          fid.add_grad(omega, g);
 
  875      struct DiscFunIntJobHelper<2>
 
  878        template<
typename FID_, 
typename DT_, 
typename SED_, 
int n_, 
int sn_>
 
  879        static void work(FID_& fid, 
const DT_ omega, 
const SED_& sed,
 
  880          const Tiny::Vector<DT_, n_, sn_>& lvec, 
int n)
 
  882          typename FID_::ValueType    v(DT_(0));
 
  883          typename FID_::GradientType g(DT_(0));
 
  884          typename FID_::HessianType  h(DT_(0));
 
  885          for(
int i(0); i < n; ++i)
 
  887            v += lvec[i] * sed.phi[i].value;
 
  888            g += lvec[i] * sed.phi[i].grad;
 
  889            h += lvec[i] * sed.phi[i].hess;
 
  892          fid.add_value(omega, v);
 
  893          fid.add_grad(omega, g);
 
  894          fid.add_hess(omega, h);
 
  897        template<
typename FID_, 
typename DT_, 
typename SED_, 
int d_, 
int sd_, 
int n_, 
int sn_>
 
  898        static void work(FID_& fid, 
const DT_ omega, 
const SED_& sed,
 
  899          const Tiny::Vector<Tiny::Vector<DT_, d_, sd_>, n_, sn_>& lvec, 
int n)
 
  901          typename FID_::ValueType v(DT_(0));
 
  902          typename FID_::GradientType g(DT_(0));
 
  903          typename FID_::HessianType h(DT_(0));
 
  904          for(
int i(0); i < n; ++i)
 
  906            v.axpy(sed.phi[i].value, lvec[i]);
 
  907            g.add_outer_product(lvec[i], sed.phi[i].grad);
 
  908            h.add_vec_mat_outer_product(lvec[i], sed.phi[i].hess);
 
  911          fid.add_value(omega, v);
 
  912          fid.add_grad(omega, g);
 
  913          fid.add_hess(omega, h);
 
  917      template<
int max_der_>
 
  918      struct ErrFunIntJobHelper;
 
  921      struct ErrFunIntJobHelper<0>
 
  924        template<
typename FID_, 
typename DT_, 
typename FEV_, 
typename IPT_, 
typename SED_, 
int n_, 
int sn_>
 
  925        static void work(FID_& fid, 
const DT_ omega, FEV_& fev, 
const IPT_& ipt, 
const SED_& sed,
 
  926          const Tiny::Vector<DT_, n_, sn_>& lvec, 
int n)
 
  928          typename FID_::ValueType    v = fev.value(ipt);
 
  929          for(
int i(0); i < n; ++i)
 
  931            v -= lvec[i] * sed.phi[i].value;
 
  934          fid.add_value(omega, v);
 
  938        template<
typename FID_, 
typename DT_, 
typename FEV_, 
typename IPT_, 
typename SED_, 
int d_, 
int sd_, 
int n_, 
int sn_>
 
  939        static void work(FID_& fid, 
const DT_ omega, FEV_& fev, 
const IPT_& ipt, 
const SED_& sed,
 
  940          const Tiny::Vector<Tiny::Vector<DT_, d_, sd_>, n_, sn_>& lvec, 
int n)
 
  942          typename FID_::ValueType    v = fev.value(ipt);
 
  943          for(
int i(0); i < n; ++i)
 
  945            v.axpy(-sed.phi[i].value, lvec[i]);
 
  948          fid.add_value(omega, v);
 
  953      struct ErrFunIntJobHelper<1>
 
  956        template<
typename FID_, 
typename DT_, 
typename FEV_, 
typename IPT_, 
typename SED_, 
int n_, 
int sn_>
 
  957        static void work(FID_& fid, 
const DT_ omega, FEV_& fev, 
const IPT_& ipt, 
const SED_& sed,
 
  958          const Tiny::Vector<DT_, n_, sn_>& lvec, 
int n)
 
  960          typename FID_::ValueType    v = fev.value(ipt);
 
  961          typename FID_::GradientType g = fev.gradient(ipt);
 
  962          for(
int i(0); i < n; ++i)
 
  964            v -= lvec[i] * sed.phi[i].value;
 
  965            g -= lvec[i] * sed.phi[i].grad;
 
  968          fid.add_value(omega, v);
 
  969          fid.add_grad(omega, g);
 
  973        template<
typename FID_, 
typename DT_, 
typename FEV_, 
typename IPT_, 
typename SED_, 
int d_, 
int sd_, 
int n_, 
int sn_>
 
  974        static void work(FID_& fid, 
const DT_ omega, FEV_& fev, 
const IPT_& ipt, 
const SED_& sed,
 
  975          const Tiny::Vector<Tiny::Vector<DT_, d_, sd_>, n_, sn_>& lvec, 
int n)
 
  977          typename FID_::ValueType    v = fev.value(ipt);
 
  978          typename FID_::GradientType g = fev.gradient(ipt);
 
  979          for(
int i(0); i < n; ++i)
 
  981            v.axpy(-sed.phi[i].value, lvec[i]);
 
  982            g.add_outer_product(lvec[i], sed.phi[i].grad, -DT_(1));
 
  985          fid.add_value(omega, v);
 
  986          fid.add_grad(omega, g);
 
  991      struct ErrFunIntJobHelper<2>
 
  994        template<
typename FID_, 
typename DT_, 
typename FEV_, 
typename IPT_, 
typename SED_, 
int n_, 
int sn_>
 
  995        static void work(FID_& fid, 
const DT_ omega, FEV_& fev, 
const IPT_& ipt, 
const SED_& sed,
 
  996          const Tiny::Vector<DT_, n_, sn_>& lvec, 
int n)
 
  998          typename FID_::ValueType    v = fev.value(ipt);
 
  999          typename FID_::GradientType g = fev.gradient(ipt);
 
 1000          typename FID_::HessianType  h = fev.hessian(ipt);
 
 1001          for(
int i(0); i < n; ++i)
 
 1003            v -= lvec[i] * sed.phi[i].value;
 
 1004            g -= lvec[i] * sed.phi[i].grad;
 
 1005            h -= lvec[i] * sed.phi[i].hess;
 
 1008          fid.add_value(omega, v);
 
 1009          fid.add_grad(omega, g);
 
 1010          fid.add_hess(omega, h);
 
 1014        template<
typename FID_, 
typename DT_, 
typename FEV_, 
typename IPT_, 
typename SED_, 
int d_, 
int sd_, 
int n_, 
int sn_>
 
 1015        static void work(FID_& fid, 
const DT_ omega, FEV_& fev, 
const IPT_& ipt, 
const SED_& sed,
 
 1016          const Tiny::Vector<Tiny::Vector<DT_, d_, sd_>, n_, sn_>& lvec, 
int n)
 
 1018          typename FID_::ValueType    v = fev.value(ipt);
 
 1019          typename FID_::GradientType g = fev.gradient(ipt);
 
 1020          typename FID_::HessianType  h = fev.hessian(ipt);
 
 1021          for(
int i(0); i < n; ++i)
 
 1023            v.axpy(-sed.phi[i].value, lvec[i]);
 
 1024            g.add_outer_product(lvec[i], sed.phi[i].grad, -DT_(1));
 
 1025            h.add_vec_mat_outer_product(lvec[i], sed.phi[i].hess, -DT_(1));
 
 1028          fid.add_value(omega, v);
 
 1029          fid.add_grad(omega, g);
 
 1030          fid.add_hess(omega, h);
 
 1035      template<
typename Fun_, 
typename Vec_>
 
 1036      struct ErrCompatHelper
 
 1039        static constexpr bool valid = 
false;
 
 1042      template<
typename Fun_, 
typename DT_, 
typename IT_>
 
 1043      struct ErrCompatHelper<Fun_, LAFEM::DenseVector<DT_, IT_>>
 
 1046        static constexpr bool valid = Fun_::ImageType::is_scalar;
 
 1049      template<
typename Fun_, 
typename DT_, 
typename IT_, 
int dim_>
 
 1050      struct ErrCompatHelper<Fun_, LAFEM::DenseVectorBlocked<DT_, IT_, dim_>>
 
 1052        typedef typename Fun_::ImageType ImageType;
 
 1054        static constexpr bool valid = ImageType::is_vector && (ImageType::image_dim == dim_);
 
#define XASSERT(expr)
Assertion macro definition.
Function cell integral info class.
Function integral info class.
void push(const FunctionIntegralInfo &other)
Assembly helper function: adds another info object.
void add_grad(DataType omega, const Tiny::Matrix< DataType, m_, n_, sm_, sn_ > &g)
Assembly helper function: adds another function gradient.
ValueType_ value
Integral of the function value.
DataType vorticity_l2_sqr
squared L2-norm of the vector field vorticity
ValueType_ ValueType
the function value type
DataType_ norm_lmax
Lmax-norm of the function.
DataType_ norm_h1_sqr
squared H1-semi-norm of the function
DataType_ norm_l1
L1-norm of the function.
void add_hess(DataType omega, const Tiny::Matrix< DataType, m_, n_, sm_, sn_ > &h)
Assembly helper function: adds another function hessian.
ValueType_ norm_lmax_comp
the component-wise Lmax-norm (only for vector fields)
void add_grad(DataType omega, const Tiny::Vector< DataType, n_, sn_ > &g)
Assembly helper function: adds another function gradient.
DataType divergence_l2_sqr
squared L2-norm of the vector field divergence
void synchronize(const Dist::Comm &comm)
Synchronizes the function integral information over a communicator.
int max_der
the maximum derivative for which the integrals have been computed
FunctionIntegralInfo()
Constructor.
HessianType_ hess
Integral of the function hessian.
ValueType_ norm_l1_comp
the component-wise L1-norm (only for vector fields)
void add_value(DataType omega, const Tiny::Vector< DataType, n_, sn_ > &v)
Assembly helper function: adds another function value.
ValueType_ norm_h1_sqr_comp
the component-wise squared H1-semi-norm (only for vector fields)
ValueType_ norm_h2_sqr_comp
the component-wise squared H2-semi-norm (only for vector fields)
String print_norms(int precision=0, std::size_t pad_size=15u, char pad_char='.') const
Prints all (computed) norms to a formatted string and returns it.
HessianType_ HessianType
the function hessian type
DataType_ DataType
the underlying scalar data type
String print_field_info(int precision=0, std::size_t pad_size=15u, char pad_char='.') const
Prints the additional field information to a formatted string and returns it.
DataType_ norm_h0_sqr
squared H0-norm (aka L2-norm) of the function
ValueType_ norm_h0_sqr_comp
the component-wise squared H0-norm (only for vector fields)
void format()
Formats the local values.
GradientType_ GradientType
the function gradient type
DataType_ norm_h2_sqr
squared H2-semi-norm of the function
void add_value(DataType omega, const DataType &v)
Assembly helper function: adds another function value.
GradientType_ grad
Integral of the function gradient.
void add_hess(DataType omega, const Tiny::Tensor3< DataType, l_, m_, n_, sl_, sm_, sn_ > &h)
Assembly helper function: adds another function hessian.
void allreduce(const void *sendbuf, void *recvbuf, std::size_t count, const Datatype &datatype, const Operation &op) const
Blocking All-Reduce.
int size() const
Returns the size of this communicator.
String class implementation.
String pad_back(size_type len, char c=' ') const
Pads the back of the string up to a desired length.
Tiny Matrix class template.
CUDA_HOST_DEVICE DataType trace() const
Returns the trace of the matrix.
CUDA_HOST_DEVICE DataType norm_hessian_sqr() const
Returns the Hessian norm square.
Tiny Tensor3 class template.
Tiny Vector class template.
CUDA_HOST_DEVICE DataType norm_euclid_sqr() const
Computes the squared euclid norm of this vector.
const Operation op_max(MPI_MAX)
Operation wrapper for MPI_MAX.
const Operation op_sum(MPI_SUM)
Operation wrapper for MPI_SUM.
T_ sqrt(T_ x)
Returns the square-root of a value.
T_ abs(T_ x)
Returns the absolute value.
T_ sqr(T_ x)
Returns the square of a value.
T_ max(T_ a, T_ b)
Returns the maximum of two values.
String stringify_fp_sci(DataType_ value, int precision=0, int width=0, bool sign=false)
Prints a floating point value to a string in scientific notation.
Helper class to determine the FunctionIntegralInfo type for analytic functions.
FunctionIntegralInfo< DataType_, typename Analytic::EvalTraits< DataType_, Function_ >::ValueType, typename Analytic::EvalTraits< DataType_, Function_ >::GradientType, typename Analytic::EvalTraits< DataType_, Function_ >::HessianType > Type
the FunctionIntegralInfo type for this analytic function
FunctionIntegralInfo< DT_, DT_, Tiny::Vector< DT_, Space_::shape_dim >, Tiny::Matrix< DT_, Space_::shape_dim, Space_::shape_dim > > Type
the FunctionIntegralInfo type for this scalar discrete function
FunctionIntegralInfo< DT_, Tiny::Vector< DT_, bs_ >, Tiny::Matrix< DT_, bs_, Space_::shape_dim >, Tiny::Tensor3< DT_, bs_, Space_::shape_dim, Space_::shape_dim > > Type
the FunctionIntegralInfo type for this blocked discrete function
Helper class to determine the FunctionIntegralInfo type for discrete functions.