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.