G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsFunctionSet.h
Go to the documentation of this file.
1 
18 #pragma once
19 
20 #include <gsCore/gsLinearAlgebra.h>
21 //#include <gsCore/gsForwardDeclarations.h> // included by gsLinearAlgebra.h
22 
23 // The following macros are a design pattern to solve the problem with
24 // unique::memory pointers as return value of virtual functions in base/derived
25 // classes. It is expected that a class where this macros are used is derived
26 // from gsFunctionSet or its derivatives. It assumes that a concrete
27 // implementation has the suffix "_impl". From outside that class, some can
28 // call that function by its name and get back a pointer inside a
29 // memory::unique_ptr (aka. uPtr) of the correct type. If casts are needed
30 // afterward, use memory::convert_ptr<toType>(from).
31 
32 // NOTE: One has to add for the DOXYGEN documentation the signature by hand
33 // and "comment out" the _impl method in the hpp file. This can be done with
34 // the preprocessor definition __DOXYGEN__. Commenting out is done with @cond
35 // till @endcond as a doxygen comment.
36 
37 // Example:
38 
39 // #ifdef __DOXYGEN__
40 // /// @briefSome Method
41 // /// @param a
42 // /// @param b
43 // /// @return gsBasis<T>::uPtr
44 // gsBasis<T>::uPtr someMethod(int a, const int b)
45 // #endif
46 //
47 // GISMO_UPTR_FUNCTION_PURE(gsBasis<T>, someMethod, int, const int)
48 
49 // /// @cond
50 // gsBasis<T>* someClass<T>::someMethod_impl(int a, const int b) { .... }
51 // /// @endcond
52 
53 // Helper macros for counting arguments, works till highest number in PP_RSEQ_N
54 // Call with PP_NARG(__VA_ARGS__)
55 // For upgrade, add values to PP_ARG_N, PP_RSEQ_N and PP_COMMASEQ_N
56 #define PP_EXPAND(x) x
57 
58 #define PP_ARG_N(_1,_2,_3,N,...) N
59 #define PP_RSEQ_N() 3,2,1,0
60 #define PP_NARG_(...) PP_EXPAND(PP_ARG_N(__VA_ARGS__))
61 #define PP_COMMASEQ_N() 1,1,0,0
62 #define PP_COMMA(...) ,
63 #define PP_HASCOMMA(...) PP_NARG_(__VA_ARGS__,PP_COMMASEQ_N())
64 #define PP_NARG(...) PP_NARG_HELPER1(PP_HASCOMMA(__VA_ARGS__),PP_HASCOMMA(PP_COMMA __VA_ARGS__ ()),PP_NARG_(__VA_ARGS__, PP_RSEQ_N()))
65 #define PP_NARG_HELPER1(a,b,N) PP_NARG_HELPER2(a, b, N)
66 #define PP_NARG_HELPER2(a,b,N) PP_NARG_HELPER3_ ## a ## b(N)
67 #define PP_NARG_HELPER3_01(N) 0
68 #define PP_NARG_HELPER3_00(N) 1
69 #define PP_NARG_HELPER3_11(N) N
70 
71 // Declaration prototypes. Followed by: { ";" , "= 0;" , "{ ... }" }
72 #define __DECn(n, type, name, ...) __DEC ## n(type, name, __VA_ARGS__)
73 #define __DEC0(type, name, void) private: virtual type * name##_impl() const
74 #define __DEC1(type, name, t1) private: virtual type * name##_impl(t1 n1) const
75 #define __DEC2(type, name, t1, t2) private: virtual type * name##_impl(t1 n1, t2 n2) const
76 
77 // Definition prototypes
78 #define __DEFn(n, type, name, ...) __DEF ## n(type, name, __VA_ARGS__)
79 #define __DEF0(type, name, void) public: inline memory::unique_ptr< type > name() const { return memory::unique_ptr< type >(name##_impl()); }
80 #define __DEF1(type, name, t1) public: inline memory::unique_ptr< type > name(t1 n1) const { return memory::unique_ptr< type >(name##_impl(n1)); }
81 #define __DEF2(type, name, t1, t2) public: inline memory::unique_ptr< type > name(t1 n1, t2 n2) const { return memory::unique_ptr< type >(name##_impl(n1, n2)); }
82 
83 // Declaration of virtual function
84 // 1st: return type
85 // 2nd: function name
86 // 3rd: types of parameter arguments
87 // Definition of real the implementation in the form "type * name_impl(...)"
88 // should be done in the corresponding .hpp file.
89 #define GISMO_UPTR_FUNCTION_DEC(type, name, ...) \
90  GISMO_UPTR_FUNCTION_DEC_(PP_NARG(__VA_ARGS__), type, name, __VA_ARGS__)
91 #define GISMO_UPTR_FUNCTION_DEC_(n, type, name, ...) \
92  __DECn(n, type, name, __VA_ARGS__); \
93  __DEFn(n, type, name, __VA_ARGS__)
94 
95 // Declaration and start of definition of virtual function
96 // 1st: return type
97 // 2nd: function name
98 // 3rd: types of parameter arguments
99 // must be finished with a block of { return type * your implementation }
100 // don't forget that your in "private:" afterward
101 #define GISMO_UPTR_FUNCTION_DEF(type, name, ...) \
102  GISMO_UPTR_FUNCTION_DEF_(PP_NARG(__VA_ARGS__), type, name, __VA_ARGS__)
103 #define GISMO_UPTR_FUNCTION_DEF_(n, type, name, ...) \
104  __DEFn(n, type, name, __VA_ARGS__) \
105  __DECn(n, type, name, __VA_ARGS__)
106 
107 // Declaration of pure virtual function
108 // 1st: return type
109 // 2nd: function name
110 // 3rd: types of parameter arguments
111 #define GISMO_UPTR_FUNCTION_PURE(type, name, ...) \
112  GISMO_UPTR_FUNCTION_PURE_(PP_NARG(__VA_ARGS__), type, name, __VA_ARGS__)
113 #define GISMO_UPTR_FUNCTION_PURE_(n, type, name, ...) \
114  __DECn(n, type, name, __VA_ARGS__) = 0; \
115  __DEFn(n, type, name, __VA_ARGS__)
116 
117 // Declaration and definition with GISMO_NO_IMPLEMENTATION
118 // 1st: return type
119 // 2nd: function name
120 // 3rd: types of parameter arguments
121 #define GISMO_UPTR_FUNCTION_NO_IMPLEMENTATION(type, name, ...) \
122  GISMO_UPTR_FUNCTION_NO_IMPLEMENTATION_(PP_NARG(__VA_ARGS__), type, name, __VA_ARGS__)
123 #define GISMO_UPTR_FUNCTION_NO_IMPLEMENTATION_(n, type, name, ...) \
124  __DECn(n, type, name, __VA_ARGS__) { GISMO_NO_IMPLEMENTATION } \
125  __DEFn(n, type, name, __VA_ARGS__)
126 
127 // Declaration, definition and implementation of clone function
128 // 1st: return type
129 #define GISMO_CLONE_FUNCTION(type) \
130  __DEC0(type, clone, void) { return new type(*this); } \
131  __DEF0(type, clone, void)
132 
133 // Declaration, definition and implementation of clone function which overrides
134 // 1st: return type
135 #define GISMO_OVERRIDE_CLONE_FUNCTION(type) \
136  __DEC0(type, clone, void) override { return new type(*this); } \
137  __DEF0(type, clone, void)
138 
139 
140 namespace gismo {
141 
217 template <typename T>
218 class gsFunctionSet
219 {
220 public:
221 
223  typedef memory::shared_ptr< gsFunctionSet > Ptr;
224 
226  typedef memory::unique_ptr< gsFunctionSet > uPtr;
227 
228 public:
229 
230  virtual ~gsFunctionSet();
231 
232 #ifdef __DOXYGEN__
233  uPtr clone();
235 #endif
236  GISMO_UPTR_FUNCTION_NO_IMPLEMENTATION(gsFunctionSet, clone)
237 
238 
239  virtual const gsFunctionSet & piece(const index_t) const {return *this;}
240 
243  const gsFunction<T> & function(const index_t k) const;
244 
247  const gsBasis<T> & basis(const index_t k) const;
248 
249 public:
250 
251  /*
252  @brief Returns (a bounding box for) the support of the function(s).
253 
254  Returns either a zero-sized matrix or a dx2 matrix, containing
255  the two diagonally extreme corners of a hypercube.
256 
257  If the returned matrix is empty, it is understood that the domain
258  of definition is the whole of \f$R^{domainDim}\f$
259  */
260  virtual gsMatrix<T> support() const;
261  virtual gsMatrix<T> supportOf(const index_t & i) const;
262 
274  virtual void active_into (const gsMatrix<T> & u, gsMatrix<index_t> &result) const;
275 
276 public:
309  virtual void eval_into (const gsMatrix<T> & u, gsMatrix<T> &result) const;
310 
349  virtual void deriv_into (const gsMatrix<T> & u, gsMatrix<T> &result) const;
350 
403  virtual void deriv2_into (const gsMatrix<T> & u, gsMatrix<T> &result) const;
404 
423  virtual void evalAllDers_into(const gsMatrix<T> & u, int n,
424  std::vector<gsMatrix<T> > & result,
425  bool sameElement = false) const;
426 
428  std::vector<gsMatrix<T> > evalAllDers(const gsMatrix<T> & u, int n, bool sameElement = false) const;
429 
431  gsMatrix<T> eval(const gsMatrix<T>& u) const;
432 
434  gsMatrix<T> deriv(const gsMatrix<T>& u) const;
435 
447  gsMatrix<T> deriv2(const gsMatrix<T>& u) const;
448 
449 
454  {
455  gsMatrix<index_t> rvo;
456  this->active_into(u, rvo);
457  return rvo;
458  }
459 
460  /*
461  @brief Divergence (of vector-valued functions).
462 
463  This makes sense only for vector valued functions whose target dimension is a multiple of the domain dimension
464  \f[\left[
465  \begin{array}{ccccc}
466  \text{div} f_1(p_1) & \text{div} f_1(p_2) & \ldots & \text{div} f_1(p_N)\\
467  \text{div} f_2(p_1) & \text{div} f_2(p_2) & \ldots & \text{div} f_2(p_N)\\
468  \vdots & \vdots & & \vdots\\
469  \text{div} f_S(p_1) & \text{div} f_S(p_2) & \ldots & \text{div} f_S(p_N)
470  \end{array}
471  \right]
472  \f]
473  If the target dimension is an integer multiple of the domain dimension, \f$\text{div} f(p)\f$ contains
474  <em>(target dim)/(domain dim)</em> rows, each row is the divergence of a <em>(domain dim)</em>-tuple of entries of \f$f\f$.
475  Equivalently, \f$f\f$ is interpreted as a matrix valued function in column maior standard and
476  the divergence corresponding vector valued divergence is returned.
477 
478  If the target dimension is not an integer multiple of the domain dimension calling this function results in an error.
479 
480  @param u
481  @param result
482  virtual void div_into (const gsMatrix<T> & u, gsMatrix<T> &result) const;
483  */
484 
485 
486  /*
487  @brief Curl (of vector-valued functions).
488 
489  This makes sense only for vector-valued functions whose target dimension is a multiple of the domain dimension.
490  \f[\left[
491  \begin{array}{ccccc}
492  \text{curl} f_1(p_1) & \text{curl} f_1(p_2) & \ldots & \text{curl} f_1(p_N)\\
493  \text{curl} f_2(p_1) & \text{curl} f_2(p_2) & \ldots & \text{curl} f_2(p_N)\\
494  \vdots & \vdots & & \vdots\\
495  \text{curl} f_S(p_1) & \text{curl} f_S(p_2) & \ldots & \text{curl} f_S(p_N)
496  \end{array}
497  \right]
498  \f]
499  If the target dimension is an integer multiple of the domain dimension, \f$\text{curl} f(p)\f$ contains
500  <em>(target dim)/(domain dim)</em> rows, each row is the rotor of a <em>(domain dim)</em>-tuple of entries of \f$f\f$.
501  Equivalently, \f$ f\f$ is interpreted as a matrix valued function in column maior standard and
502  the rotor corresponding vector valued rotor is returned.
503 
504  If the target dimension is not an integer multiple of the domain dimension calling this function results in an error.
505  @param u
506  @param result
507  virtual void curl_into (const gsMatrix<T> & u, gsMatrix<T> &result) const;
508  */
509 
510 
511  /*
512  @brief Laplacian (of vector-valued functions).
513 
514  \f[\left[
515  \begin{array}{ccccc}
516  \Delta f_1(p_1) & \Delta f_1(p_2) & \ldots & \Delta f_1(p_N)\\
517  \Delta f_2(p_1) & \Delta f_2(p_2) & \ldots & \Delta f_2(p_N)\\
518  \vdots & \vdots & & \vdots\\
519  \Delta f_S(p_1) & \Delta f_S(p_2) & \ldots & \Delta f_S(p_N)
520  \end{array}
521  \right]
522  \f]
523  If the target dimension is different from 1, then each \f$\Delta f_i(p_j)\f$ is a block of target
524  dimension rows containing the component wise Laplacian.
525  @param u
526  @param result
527  virtual void laplacian_into (const gsMatrix<T> & u, gsMatrix<T> &result) const;
528  */
529 
530 
531 
547  virtual void compute(const gsMatrix<T> & in, gsFuncData<T> & out) const;
548 
549 public:
554  virtual short_t domainDim () const = 0;
555 
560  virtual short_t targetDim () const {return 1;}
561 
562  /*
563  @brief Dimension of domain and target
564  @return the pair of integers domainDim() and targetDim()
565  */
566  std::pair<short_t, short_t> dimensions() const {return std::make_pair(domainDim(),targetDim());}
567 
578  virtual index_t size() const //= 0;
580 
584  virtual index_t nPieces() const {return 1;}
585 
587  virtual std::ostream &print(std::ostream &os) const// = 0;
588  {
589  os << "gsFunctionSet\n";
590  return os;
591  }
592 
593 };
594 
596 template<class T>
597 std::ostream &operator<<(std::ostream &os, const gsFunctionSet<T>& b)
598 {return b.print(os); }
599 
600 #ifdef GISMO_WITH_PYBIND11
601 
605  void pybind11_init_gsFunctionSet(pybind11::module &m);
606 
607 #endif // GISMO_WITH_PYBIND11
608 
609 } // namespace gismo
610 
611 
612 #ifndef GISMO_BUILD_LIB
613 #include GISMO_HPP_HEADER(gsFunctionSet.hpp)
614 #endif
gsMatrix< T > deriv2(const gsMatrix< T > &u) const
Evaluates the second derivatives of active (i.e., non-zero) functions at points u.
Definition: gsFunctionSet.hpp:138
virtual std::ostream & print(std::ostream &os) const
Prints the object as a string.
Definition: gsFunctionSet.h:587
#define GISMO_NO_IMPLEMENTATION
Definition: gsDebug.h:129
virtual void compute(const gsMatrix< T > &in, gsFuncData< T > &out) const
Computes function data.
Definition: gsFunctionSet.hpp:175
gsMatrix< index_t > active(const gsMatrix< T > &u) const
Returns the indices of active (nonzero) functions at points u, as a list of indices.
Definition: gsFunctionSet.h:453
#define short_t
Definition: gsConfig.h:35
virtual void evalAllDers_into(const gsMatrix< T > &u, int n, std::vector< gsMatrix< T > > &result, bool sameElement=false) const
Evaluate the nonzero functions and their derivatives up to order n at points u into result...
Definition: gsFunctionSet.hpp:81
gsMatrix< T > deriv(const gsMatrix< T > &u) const
Evaluate the derivatives,.
Definition: gsFunctionSet.hpp:129
virtual index_t size() const
size
Definition: gsFunctionSet.h:578
gsMatrix< T > eval(const gsMatrix< T > &u) const
Evaluate the function,.
Definition: gsFunctionSet.hpp:120
#define index_t
Definition: gsConfig.h:32
A function from a n-dimensional domain to an m-dimensional image.
Definition: gsFunction.h:59
memory::shared_ptr< gsFunctionSet > Ptr
Shared pointer for gsFunctionSet.
Definition: gsFunctionSet.h:223
virtual short_t targetDim() const
Dimension of the target space.
Definition: gsFunctionSet.h:560
virtual const gsFunctionSet & piece(const index_t) const
Returns the piece(s) of the function(s) at subdomain k.
Definition: gsFunctionSet.h:239
memory::unique_ptr< gsFunctionSet > uPtr
Unique pointer for gsFunctionSet.
Definition: gsFunctionSet.h:226
virtual void active_into(const gsMatrix< T > &u, gsMatrix< index_t > &result) const
Indices of active (non-zero) function(s) for each point.
Definition: gsFunctionSet.hpp:56
const gsBasis< T > & basis(const index_t k) const
Helper which casts and returns the k-th piece of this function set as a gsBasis.
Definition: gsFunctionSet.hpp:33
virtual short_t domainDim() const =0
Dimension of the (source) domain.
Interface for the set of functions defined on a domain (the total number of functions in the set equa...
Definition: gsFuncData.h:23
virtual void deriv2_into(const gsMatrix< T > &u, gsMatrix< T > &result) const
Second derivatives.
Definition: gsFunctionSet.hpp:77
uPtr clone()
Clone methode. Produceds a deep copy inside a uPtr.
virtual index_t nPieces() const
Number of pieces in the domain of definition.
Definition: gsFunctionSet.h:584
This is the main header file that collects wrappers of Eigen for linear algebra.
std::vector< gsMatrix< T > > evalAllDers(const gsMatrix< T > &u, int n, bool sameElement=false) const
Evaluate all derivatives upto order n,.
Definition: gsFunctionSet.hpp:111
virtual void deriv_into(const gsMatrix< T > &u, gsMatrix< T > &result) const
First derivatives.
Definition: gsFunctionSet.hpp:73
A basis represents a family of scalar basis functions defined over a common parameter domain...
Definition: gsBasis.h:78
virtual void eval_into(const gsMatrix< T > &u, gsMatrix< T > &result) const
Evaluates the function(s).
Definition: gsFunctionSet.hpp:66