1 /*
2 XLiFE++ is an extended library of finite elements written in C++
3     Copyright (C) 2014  Lunéville, Eric; Kielbasiewicz, Nicolas; Lafranche, Yvon; Nguyen, Manh-Ha; Chambeyron, Colin
4 
5     This program is free software: you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation, either version 3 of the License, or
8     (at your option) any later version.
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13     You should have received a copy of the GNU General Public License
14     along with this program.  If not, see <http://www.gnu.org/licenses/>.
15  */
16 
17 /*!
18   \file Kernel.hpp
19   \author E. Lunéville
20   \since 20 sep 2013
21   \date  20 sep 2013
22 
23   \brief Definition of the xlifepp::Kernel class
24 
25   Class to handle kernels
26 
27   xlifepp::Kernel class manage K(x,y) function, it manages
28     - a kernel function defined as a Function object
29     - a singularity type (_regular,_r,_logr)
30     - a singularity order as a real (default is 0)
31     - a name
32     - a parameters list as a xlifepp::Parameters object to store any additional user's information
33       this parameters list is automatically associated to the parameters list of kernel function
34 
35   xlifepp::TensorKernel class, inherited from xlifepp::Kernel, manages matrix kernels of the following form
36                   sum_mn psi_n(x) Amn phi_m(y)
37   such kernel allows to deal with DirichletToNeuman operator. Indeed, the usual DtN term in variational form is
38             sum_mn int_Sigma v(x)psi_m(x) Amn int_Gamma u(y)phi_n(y)
39   rewritten
40             int_Gamma intg_Sigma  v(y) [sum_mn phi_n(y) Amn psi_m(x)] v(x)
41   It manages
42      - two function pointers (for phy and psi)
43      - a 'matrix' describing Amn as a scalar vector
44 */
45 
46 
47 #ifndef KERNEL_HPP
48 #define KERNEL_HPP
49 
50 
51 #include "Parameters.hpp"  // Parameters class definitions
52 #include "Function.hpp"    // Function class definitions
53 #include "String.hpp"      // String class definitions
54 #include "VectorEntry.hpp" // generalized vector
55 #include "config.h"        // typedef, enum, ... definitions
56 
57 namespace xlifepp
58 {
59 //forward class declaration
60 class OperatorOn;  //experimental
61 
62 
63 enum KernelType {_generalKernel,_tensorKernel};
64 enum SingularityType {_notsingular, _r, _logr,_loglogr};
65 
66 class TensorKernel;
67 class KernelExpansion;
68 
69 /* ---------------------------------------------------------------------------------------
70                        Kernel class K(x,y)
71    ---------------------------------------------------------------------------------------*/
72 
73 class Kernel
74 {
75   public:
76     Function kernel;              //!< kernel function K(x,y)
77     Function gradx;               //!< x derivative grad_x K(x,y)
78     Function grady;               //!< y derivative grad_y K(x,y)
79     Function gradxy;              //!< x,y derivative grad_x grad_y K(x,y)
80     Function ndotgradx;           //!< nx.gradx
81     Function ndotgrady;           //!< ny.grady
82     Function curlx;               //!< curl_x if available
83     Function curly;               //!< curl_y if available
84     Function curlxy;              //!< curl_x curl_y if available
85     Function divx;                //!< div_x if available
86     Function divy;                //!< div_y if available
87     Function divxy;               //!< div_x div_y if available
88     Function dx1;                 //!< d_x1 if available (useful when matrix kernel)
89     Function dx2;                 //!< d_x2 if available (useful when matrix kernel)
90     Function dx3;                 //!< d_x3 if available (useful when matrix kernel)
91     Kernel* singPart;             //!< singular part of kernel
92     Kernel* regPart;              //!< regular part of kernel
93 
94     SingularityType singularType; //!< type of singularity (_notsingular, _r, _logr,_loglogr)
95     real_t singularOrder;         //!< order of singularity
96     complex_t singularCoefficient;//!< coefficient of singularity
97     KernelExpansion* expansion;   //!< kernel expansion
98     SymType symmetry;             //!< kernel symmetry :_noSymmetry, _symmetric (K(x,y)=K(y,x)), _skewsymmetric,_adjoint,_skewadjoint
99     string_t name;                //!< kernel name
100     string_t shortname;           //!< kernel name
101     Parameters userData;          //!< to store some additional informations
102     dimen_t dimPoint;             //!< dimension of point (default=3)
103 
104   public :
105     //temporary data
106     mutable bool checkType_;      //!< to activate the checking of arguments (see operator ())
107     mutable bool conjugate_;      //!< temporary flag for conjugate operation construction
108     mutable bool transpose_;      //!< temporary flag for transpose operation construction
109     mutable bool xpar;            //!< true means that point x is consider as a parameter (unused for ordinary function)
110     mutable Point xory;           //!< point x or y as parameter of the kernel (unused for ordinary function)
111 
112   public:
113     bool requireNx;                  //!< true if user declares that its function requires normal or x-normal vector
114     bool requireNy;                  //!< true if user declares that its function (kernel) requires y-normal vector
115     bool requireElt;                 //!< true if user declares that its function requires element
116     bool requireDom;                 //!< true if user declares that its function requires domain
117     bool requireDof;                 //!< true if user declares that its function requires dof
118 
119   public:
120     //constructors
Kernel()121     Kernel()   //! basic constructor
122       : singPart(0),regPart(0),singularType(_notsingular),singularOrder(0),name(""), shortname(""),symmetry(_noSymmetry),expansion(0),dimPoint(3),
123         checkType_(false),conjugate_(false),transpose_(false),requireNx(false),requireNy(false),requireElt(false),
124         requireDom(false), requireDof(false) {}
125 
126     // constructors from Function (kernel)
Kernel(const Function & ker,SingularityType st=_notsingular,real_t so=0,SymType sy=_noSymmetry)127     Kernel(const Function& ker,
128            SingularityType st=_notsingular, real_t so=0, SymType sy=_noSymmetry)   //! constructor from Function object
129       : kernel(ker),singularType(st),singularOrder(so),symmetry(sy),singPart(0),regPart(0),name(""),shortname(""),expansion(0),dimPoint(ker.dimPoint_),
130         checkType_(false),conjugate_(false),transpose_(false),requireNx(false),requireNy(false),requireElt(false),
131         requireDom(false), requireDof(false) {initParameters(ker.params_p());}
132 
Kernel(const Function & ker,const string_t & na,SingularityType st=_notsingular,real_t so=0,SymType sy=_noSymmetry)133     Kernel(const Function& ker,
134            const string_t& na, SingularityType st=_notsingular, real_t so=0, SymType sy=_noSymmetry)   //! constructor from Function object with name
135       : kernel(ker),singularType(st),singularOrder(so),symmetry(sy),singPart(0),regPart(0),name(na),shortname(na),expansion(0),dimPoint(ker.dimPoint_),
136         checkType_(false),conjugate_(false),transpose_(false),requireNx(false),requireNy(false),requireElt(false),
137         requireDom(false), requireDof(false) {initParameters(ker.params_p());}
138 
Kernel(const Function & ker,const char * na,SingularityType st=_notsingular,real_t so=0,SymType sy=_noSymmetry)139     Kernel(const Function& ker,
140            const char* na, SingularityType st=_notsingular, real_t so=0, SymType sy=_noSymmetry)   //! constructor from Function object with name
141       : kernel(ker),singularType(st),singularOrder(so),symmetry(sy),singPart(0),regPart(0),name(na),shortname(na),expansion(0),dimPoint(ker.dimPoint_),
142         checkType_(false),conjugate_(false),transpose_(false),requireNx(false),requireNy(false),requireElt(false),
143         requireDom(false), requireDof(false) {initParameters(ker.params_p());}
144 
145     // constructors from fun(Point,Point,Parameters)
146     template <typename T>
Kernel(T (fun)(const Point &,const Point &,Parameters &),SingularityType st=_notsingular,real_t so=0,SymType sy=_noSymmetry)147     Kernel(T(fun)(const Point&, const Point&, Parameters&),
148            SingularityType st=_notsingular, real_t so=0, SymType sy=_noSymmetry) //! constructor from explicit scalar kernel function
149       : kernel(*fun),singularType(st),singularOrder(so),symmetry(sy),singPart(0),regPart(0),name(""),shortname(""),expansion(0),dimPoint(3),
150         checkType_(false),conjugate_(false),transpose_(false),requireNx(false),requireNy(false),requireElt(false),
151         requireDom(false), requireDof(false) {initParameters();}
152     template <typename T>
153 
Kernel(T (fun)(const Point &,const Point &,Parameters &),dimen_t d,SingularityType st=_notsingular,real_t so=0,SymType sy=_noSymmetry)154     Kernel(T(fun)(const Point&, const Point&, Parameters&),dimen_t d,
155            SingularityType st=_notsingular, real_t so=0, SymType sy=_noSymmetry) //! constructor from explicit scalar kernel function
156       : kernel(*fun),singularType(st),singularOrder(so),symmetry(sy),singPart(0),regPart(0),name(""),shortname(""),expansion(0),dimPoint(d),
157         checkType_(false),conjugate_(false),transpose_(false),requireNx(false),requireNy(false),requireElt(false),
158         requireDom(false), requireDof(false) {initParameters();}
159 
160     template <typename T>
Kernel(T (fun)(const Point &,const Point &,Parameters &),const string_t & na,SingularityType st=_notsingular,real_t so=0,SymType sy=_noSymmetry)161     Kernel(T(fun)(const Point&, const Point&, Parameters&), const string_t& na,
162            SingularityType st=_notsingular, real_t so=0, SymType sy=_noSymmetry) //! constructor from explicit scalar kernel function, with name
163       : kernel(*fun),singularType(st),singularOrder(so),symmetry(sy),singPart(0),regPart(0),name(na),shortname(na),expansion(0),dimPoint(3),
164         checkType_(false),conjugate_(false),transpose_(false),requireNx(false),requireNy(false),requireElt(false),
165         requireDom(false), requireDof(false) {initParameters();}
166 
167     template <typename T>
Kernel(T (fun)(const Point &,const Point &,Parameters &),dimen_t d,const string_t & na,SingularityType st=_notsingular,real_t so=0,SymType sy=_noSymmetry)168     Kernel(T(fun)(const Point&, const Point&, Parameters&), dimen_t d, const string_t& na,
169            SingularityType st=_notsingular, real_t so=0, SymType sy=_noSymmetry) //! constructor from explicit scalar kernel function, with name
170       : kernel(*fun),singularType(st),singularOrder(so),symmetry(sy),singPart(0),regPart(0),name(na),shortname(na),expansion(0),dimPoint(d),
171         checkType_(false),conjugate_(false),transpose_(false),requireNx(false),requireNy(false),requireElt(false),
172         requireDom(false), requireDof(false) {initParameters();}
173 
174     template <typename T>
Kernel(T (fun)(const Point &,const Point &,Parameters &),const char * na,SingularityType st=_notsingular,real_t so=0,SymType sy=_noSymmetry)175     Kernel(T(fun)(const Point&, const Point&, Parameters&), const char* na,
176            SingularityType st=_notsingular, real_t so=0, SymType sy=_noSymmetry) //! constructor from explicit scalar kernel function, with name
177       : kernel(*fun),singularType(st),singularOrder(so),symmetry(sy),singPart(0),regPart(0),name(na),shortname(na),expansion(0),dimPoint(3),
178         checkType_(false),conjugate_(false),transpose_(false),requireNx(false),requireNy(false),requireElt(false),
179         requireDom(false), requireDof(false) {initParameters();}
180 
181     template <typename T>
Kernel(T (fun)(const Point &,const Point &,Parameters &),dimen_t d,const char * na,SingularityType st=_notsingular,real_t so=0,SymType sy=_noSymmetry)182     Kernel(T(fun)(const Point&, const Point&, Parameters&), dimen_t d, const char* na,
183            SingularityType st=_notsingular, real_t so=0, SymType sy=_noSymmetry) //! constructor from explicit scalar kernel function, with name
184       : kernel(*fun),singularType(st),singularOrder(so),symmetry(sy),singPart(0),regPart(0),name(na),shortname(na),expansion(0),dimPoint(d),
185         checkType_(false),conjugate_(false),transpose_(false),requireNx(false),requireNy(false),requireElt(false),
186         requireDom(false), requireDof(false) {initParameters();}
187 
188     // constructors from fun(Vector<Point>,Vector<Point>,Parameters)
189     template <typename T>
Kernel(T (fun)(const Vector<Point> &,const Vector<Point> &,Parameters &),SingularityType st=_notsingular,real_t so=0,SymType sy=_noSymmetry)190     Kernel(T(fun)(const Vector<Point>&, const Vector<Point>&, Parameters&),
191            SingularityType st=_notsingular, real_t so=0, SymType sy=_noSymmetry) //! constructor from explicit vector kernel function
192       : kernel(*fun),singularType(st),singularOrder(so),symmetry(sy),singPart(0),regPart(0),name(""),shortname(""),expansion(0),dimPoint(3),
193         checkType_(false),conjugate_(false),transpose_(false),requireNx(false),requireNy(false),requireElt(false),
194         requireDom(false), requireDof(false) {initParameters();}
195 
196     template <typename T>
Kernel(T (fun)(const Vector<Point> &,const Vector<Point> &,Parameters &),dimen_t d,SingularityType st=_notsingular,real_t so=0,SymType sy=_noSymmetry)197     Kernel(T(fun)(const Vector<Point>&, const Vector<Point>&, Parameters&),dimen_t d,
198            SingularityType st=_notsingular, real_t so=0, SymType sy=_noSymmetry) //! constructor from explicit vector kernel function
199       : kernel(*fun),singularType(st),singularOrder(so),symmetry(sy),singPart(0),regPart(0),name(""),shortname(""),expansion(0),dimPoint(d),
200         checkType_(false),conjugate_(false),transpose_(false),requireNx(false),requireNy(false),requireElt(false),
201         requireDom(false), requireDof(false) {initParameters();}
202 
203     template <typename T>
Kernel(T (fun)(const Vector<Point> &,const Vector<Point> &,Parameters &),const string_t & na,SingularityType st=_notsingular,real_t so=0,SymType sy=_noSymmetry)204     Kernel(T(fun)(const Vector<Point>&, const Vector<Point>&, Parameters&), const string_t& na,
205            SingularityType st=_notsingular, real_t so=0, SymType sy=_noSymmetry) //! constructor from explicit vector kernel function, with name
206       : kernel(*fun),singularType(st),singularOrder(so),symmetry(sy),singPart(0),regPart(0),name(na),shortname(na),expansion(0),dimPoint(3),
207         checkType_(false),conjugate_(false),transpose_(false),requireNx(false),requireNy(false),requireElt(false),
208         requireDom(false), requireDof(false) {initParameters();}
209 
210     template <typename T>
Kernel(T (fun)(const Vector<Point> &,const Vector<Point> &,Parameters &),dimen_t d,const string_t & na,SingularityType st=_notsingular,real_t so=0,SymType sy=_noSymmetry)211     Kernel(T(fun)(const Vector<Point>&, const Vector<Point>&, Parameters&), dimen_t d, const string_t& na,
212            SingularityType st=_notsingular, real_t so=0, SymType sy=_noSymmetry) //! constructor from explicit vector kernel function, with name
213       : kernel(*fun),singularType(st),singularOrder(so),symmetry(sy),singPart(0),regPart(0),name(na),shortname(na),expansion(0),dimPoint(d),
214         checkType_(false),conjugate_(false),transpose_(false),requireNx(false),requireNy(false),requireElt(false),
215         requireDom(false), requireDof(false) {initParameters();}
216 
217     template <typename T>
Kernel(T (fun)(const Vector<Point> &,const Vector<Point> &,Parameters &),const char * na,SingularityType st=_notsingular,real_t so=0,SymType sy=_noSymmetry)218     Kernel(T(fun)(const Vector<Point>&, const Vector<Point>&, Parameters&), const char* na,
219            SingularityType st=_notsingular, real_t so=0, SymType sy=_noSymmetry) //! constructor from explicit vector kernel function, with name
220       : kernel(*fun),singularType(st),singularOrder(so),symmetry(sy),singPart(0),regPart(0),name(na),shortname(na),expansion(0),dimPoint(3),
221         checkType_(false),conjugate_(false),transpose_(false),requireNx(false),requireNy(false),requireElt(false),
222         requireDom(false), requireDof(false) {initParameters();}
223 
224     template <typename T>
Kernel(T (fun)(const Vector<Point> &,const Vector<Point> &,Parameters &),dimen_t d,const char * na,SingularityType st=_notsingular,real_t so=0,SymType sy=_noSymmetry)225     Kernel(T(fun)(const Vector<Point>&, const Vector<Point>&, Parameters&), dimen_t d, const char* na,
226            SingularityType st=_notsingular, real_t so=0, SymType sy=_noSymmetry) //! constructor from explicit vector kernel function, with name
227       : kernel(*fun),singularType(st),singularOrder(so),symmetry(sy),singPart(0),regPart(0),name(na),shortname(na),expansion(0),dimPoint(d),
228         checkType_(false),conjugate_(false),transpose_(false),requireNx(false),requireNy(false),requireElt(false),
229         requireDom(false), requireDof(false) {initParameters();}
230 
231     // constructors from fun(Point,Point,Parameters) and Parameters
232     template <typename T>
Kernel(T (fun)(const Point &,const Point &,Parameters &),const Parameters & pa,SingularityType st=_notsingular,real_t so=0,SymType sy=_noSymmetry)233     Kernel(T(fun)(const Point&, const Point&, Parameters&), const Parameters& pa,
234            SingularityType st=_notsingular, real_t so=0, SymType sy=_noSymmetry) //! constructor from explicit scalar kernel function and parameters
235       : kernel(*fun, const_cast<Parameters&>(pa)),singularType(st),singularOrder(so),symmetry(sy),singPart(0),regPart(0),name(""),
236         shortname(""),expansion(0),dimPoint(3),checkType_(false),conjugate_(false),transpose_(false),requireNx(false),requireNy(false),
237         requireElt(false),requireDom(false), requireDof(false) {userData=pa; initParameters(&pa);}
238 
239     template <typename T>
Kernel(T (fun)(const Point &,const Point &,Parameters &),const Parameters & pa,dimen_t d,SingularityType st=_notsingular,real_t so=0,SymType sy=_noSymmetry)240     Kernel(T(fun)(const Point&, const Point&, Parameters&), const Parameters& pa, dimen_t d,
241            SingularityType st=_notsingular, real_t so=0, SymType sy=_noSymmetry) //! constructor from explicit scalar kernel function and parameters
242       : kernel(*fun, const_cast<Parameters&>(pa)),singularType(st),singularOrder(so),symmetry(sy),singPart(0),regPart(0),name(""),
243         shortname(""),expansion(0),dimPoint(d),checkType_(false),conjugate_(false),transpose_(false),requireNx(false),requireNy(false),
244         requireElt(false),requireDom(false), requireDof(false) {userData=pa; initParameters(&pa);}
245 
246     template <typename T>
Kernel(T (fun)(const Point &,const Point &,Parameters &),const Parameters & pa,const string_t & na,SingularityType st=_notsingular,real_t so=0,SymType sy=_noSymmetry)247     Kernel(T(fun)(const Point&, const Point&, Parameters&), const Parameters& pa, const string_t& na,
248            SingularityType st=_notsingular, real_t so=0, SymType sy=_noSymmetry) //! constructor from explicit scalar kernel function and parameters, with name
249       : kernel(*fun, const_cast<Parameters&>(pa)),singularType(st),singularOrder(so),symmetry(sy),singPart(0),regPart(0),name(na),
250         shortname(na),expansion(0),dimPoint(3),checkType_(false),conjugate_(false),transpose_(false),requireNx(false),requireNy(false),
251         requireElt(false),requireDom(false), requireDof(false) {userData=pa; initParameters(&pa);}
252 
253     template <typename T>
Kernel(T (fun)(const Point &,const Point &,Parameters &),const Parameters & pa,dimen_t d,const string_t & na,SingularityType st=_notsingular,real_t so=0,SymType sy=_noSymmetry)254     Kernel(T(fun)(const Point&, const Point&, Parameters&), const Parameters& pa, dimen_t d, const string_t& na,
255            SingularityType st=_notsingular, real_t so=0, SymType sy=_noSymmetry) //! constructor from explicit scalar kernel function and parameters, with name
256       : kernel(*fun, const_cast<Parameters&>(pa)),singularType(st),singularOrder(so),symmetry(sy),singPart(0),regPart(0),name(na),
257         shortname(na),expansion(0),dimPoint(d),checkType_(false),conjugate_(false),transpose_(false),requireNx(false),requireNy(false),
258         requireElt(false),requireDom(false), requireDof(false) {userData=pa; initParameters(&pa);}
259 
260     template <typename T>
Kernel(T (fun)(const Point &,const Point &,Parameters &),const Parameters & pa,const char * na,SingularityType st=_notsingular,real_t so=0,SymType sy=_noSymmetry)261     Kernel(T(fun)(const Point&, const Point&, Parameters&), const Parameters& pa, const char* na,
262            SingularityType st=_notsingular, real_t so=0, SymType sy=_noSymmetry) //! constructor from explicit scalar kernel function and parameters, with name
263      : kernel(*fun, const_cast<Parameters&>(pa)),singularType(st),singularOrder(so),symmetry(sy),singPart(0),regPart(0),name(na),
264        shortname(na),expansion(0),dimPoint(3),checkType_(false),conjugate_(false),transpose_(false),requireNx(false),requireNy(false),
265        requireElt(false),requireDom(false), requireDof(false) {userData=pa; initParameters(&pa);}
266 
267     template <typename T>
Kernel(T (fun)(const Point &,const Point &,Parameters &),const Parameters & pa,dimen_t d,const char * na,SingularityType st=_notsingular,real_t so=0,SymType sy=_noSymmetry)268     Kernel(T(fun)(const Point&, const Point&, Parameters&), const Parameters& pa, dimen_t d, const char* na,
269            SingularityType st=_notsingular, real_t so=0, SymType sy=_noSymmetry) //! constructor from explicit scalar kernel function and parameters, with name
270      : kernel(*fun, const_cast<Parameters&>(pa)),singularType(st),singularOrder(so),symmetry(sy),singPart(0),regPart(0),name(na),
271        shortname(na),expansion(0),dimPoint(d),checkType_(false),conjugate_(false),transpose_(false),requireNx(false),requireNy(false),
272        requireElt(false),requireDom(false), requireDof(false) {userData=pa; initParameters(&pa);}
273 
274     // constructors from fun(Vector<Point>,Vector<Point>,Parameters) and Parameters
275     template <typename T>
Kernel(T (fun)(const Vector<Point> &,const Vector<Point> &,Parameters &),const Parameters & pa,SingularityType st=_notsingular,real_t so=0,SymType sy=_noSymmetry)276     Kernel(T(fun)(const Vector<Point>&, const Vector<Point>&, Parameters&), const Parameters& pa,
277            SingularityType st=_notsingular, real_t so=0, SymType sy=_noSymmetry) //! constructor from explicit vector kernel function and parameters
278       : kernel(*fun, const_cast<Parameters&>(pa)),singularType(st),singularOrder(so),symmetry(sy),singPart(0),regPart(0),name(""),
279         shortname(""),expansion(0),dimPoint(3),checkType_(false),conjugate_(false),transpose_(false),requireNx(false),requireNy(false),
280         requireElt(false),requireDom(false), requireDof(false) {userData=pa; initParameters(&pa);}
281 
282     template <typename T>
Kernel(T (fun)(const Vector<Point> &,const Vector<Point> &,Parameters &),const Parameters & pa,dimen_t d,SingularityType st=_notsingular,real_t so=0,SymType sy=_noSymmetry)283     Kernel(T(fun)(const Vector<Point>&, const Vector<Point>&, Parameters&), const Parameters& pa, dimen_t d,
284            SingularityType st=_notsingular, real_t so=0, SymType sy=_noSymmetry) //! constructor from explicit vector kernel function and parameters
285       : kernel(*fun, const_cast<Parameters&>(pa)),singularType(st),singularOrder(so),symmetry(sy),singPart(0),regPart(0),name(""),
286         shortname(""),expansion(0),dimPoint(d),checkType_(false),conjugate_(false),transpose_(false),requireNx(false),requireNy(false),
287         requireElt(false),requireDom(false), requireDof(false) {userData=pa; initParameters(&pa);}
288 
289     template <typename T>
Kernel(T (fun)(const Vector<Point> &,const Vector<Point> &,Parameters &),const Parameters & pa,const string_t & na,SingularityType st=_notsingular,real_t so=0,SymType sy=_noSymmetry)290     Kernel(T(fun)(const Vector<Point>&, const Vector<Point>&, Parameters&), const Parameters& pa, const string_t& na,
291            SingularityType st=_notsingular, real_t so=0, SymType sy=_noSymmetry) //! constructor from explicit vector kernel function and parameters, with name
292       : kernel(*fun, const_cast<Parameters&>(pa)),singularType(st),singularOrder(so),symmetry(sy),singPart(0),regPart(0),name(na),
293         shortname(na),expansion(0),dimPoint(3),checkType_(false),conjugate_(false),transpose_(false),requireNx(false),requireNy(false),
294         requireElt(false), requireDom(false), requireDof(false) {userData=pa; initParameters(&pa);}
295 
296     template <typename T>
Kernel(T (fun)(const Vector<Point> &,const Vector<Point> &,Parameters &),const Parameters & pa,dimen_t d,const string_t & na,SingularityType st=_notsingular,real_t so=0,SymType sy=_noSymmetry)297     Kernel(T(fun)(const Vector<Point>&, const Vector<Point>&, Parameters&), const Parameters& pa, dimen_t d, const string_t& na,
298            SingularityType st=_notsingular, real_t so=0, SymType sy=_noSymmetry) //! constructor from explicit vector kernel function and parameters, with name
299       : kernel(*fun, const_cast<Parameters&>(pa)),singularType(st),singularOrder(so),symmetry(sy),singPart(0),regPart(0),name(na),
300         shortname(na),expansion(0),dimPoint(d),checkType_(false),conjugate_(false),transpose_(false),requireNx(false),requireNy(false),
301         requireElt(false), requireDom(false), requireDof(false) {userData=pa; initParameters(&pa);}
302 
303     template <typename T>
Kernel(T (fun)(const Vector<Point> &,const Vector<Point> &,Parameters &),const Parameters & pa,const char * na,SingularityType st=_notsingular,real_t so=0,SymType sy=_noSymmetry)304     Kernel(T(fun)(const Vector<Point>&, const Vector<Point>&, Parameters&), const Parameters& pa, const char* na,
305            SingularityType st=_notsingular, real_t so=0, SymType sy=_noSymmetry) //! constructor from explicit vector kernel function and parameters, with name
306       : kernel(*fun, const_cast<Parameters&>(pa)),singularType(st),singularOrder(so),symmetry(sy),singPart(0),regPart(0),name(na),
307         shortname(na),expansion(0),dimPoint(3),checkType_(false),conjugate_(false),transpose_(false),requireNx(false),requireNy(false),
308         requireElt(false), requireDom(false), requireDof(false) {userData=pa; initParameters(&pa);}
309 
310     template <typename T>
Kernel(T (fun)(const Vector<Point> &,const Vector<Point> &,Parameters &),const Parameters & pa,dimen_t d,const char * na,SingularityType st=_notsingular,real_t so=0,SymType sy=_noSymmetry)311     Kernel(T(fun)(const Vector<Point>&, const Vector<Point>&, Parameters&), const Parameters& pa, dimen_t d, const char* na,
312            SingularityType st=_notsingular, real_t so=0, SymType sy=_noSymmetry) //! constructor from explicit vector kernel function and parameters, with name
313       : kernel(*fun, const_cast<Parameters&>(pa)),singularType(st),singularOrder(so),symmetry(sy),singPart(0),regPart(0),name(na),
314         shortname(na),expansion(0),dimPoint(d),checkType_(false),conjugate_(false),transpose_(false),requireNx(false),requireNy(false),
315         requireElt(false), requireDom(false), requireDof(false) {userData=pa; initParameters(&pa);}
316 
317 
318 
319     Kernel(const Kernel&);               //!< copy constructor
320     Kernel& operator=(const Kernel&);    //!< assign operator
321     void copy(const Kernel&);            //!< copy tool used by copy constructor and assign operator
322     virtual Kernel* clone() const;       //!< clone current kernel (virtual)
323     virtual ~Kernel();                   //!< destructor
324 
325     void updateParametersLinks();        //!< update Parameters links
326     void updateDimPoint();               //!< update dimPoint_ of related functions
initParameters(const Parameters * pars=0)327     virtual void initParameters(const Parameters* pars = 0)   //! initialization of Parameters
328     {
329       if(pars!=0) userData.push(*pars);                  //the add user parameters
330       updateParametersLinks();                           //update Parameters links
331       updateDimPoint();
332     }
333 
type() const334     virtual KernelType type() const                 //! return kernel type (_generalKernel, _tensorKernel, ...)
335     {return _generalKernel;}
336 
337     //set and get Kernel parameters
setParameters(const Parameters & par)338     void setParameters(const Parameters& par)       //! add a parameter's list
339     {userData=par;}
setParameter(Parameter & par)340     void setParameter(Parameter& par)               //! add a parameter
341     {userData.push(par);}
342     template<typename T>
setParameter(const string_t & name,T value)343     void setParameter(const string_t& name, T value)//! add a T value in parameter's list
344     {userData.add(name,value);}
345     template<typename T>
getParameter(const string_t & name,T value) const346     T getParameter(const string_t& name, T value) const  //! get parameter by its name
347     {return userData.get(name,value);}
setX(const Point & P) const348     void setX(const Point& P) const                //! specify x=P as a parameter to interpret kernel as a y function (see Function class)
349     {xpar=true; xory=P; kernel.setX(P);}
setY(const Point & P) const350     void setY(const Point& P) const                //! specify y=P as a parameter to interpret kernel as a x function (see Function class)
351     {xpar=false; xory=P; kernel.setY(P);}
operator ()(const string_t & name)352     Parameter& operator()(const string_t& name)
353     {return userData(name);}
354 
355     //Various utilities
isSymbolic() const356     virtual bool isSymbolic() const                    //! return true is there is no explicit kernel function
357     {return kernel.isVoidFunction();}
valueType() const358     virtual ValueType valueType() const                //! return kernel value type (_real or _complex)
359     {return kernel.valueType();}
strucType() const360     virtual StrucType strucType() const                //! return kernel structure type (_scalar, _vector or _matrix)
361     {return kernel.strucType();}
dims() const362     virtual dimPair dims() const                       //! return the dimension of returned values
363     {return kernel.dims();}
no_ndotgradx() const364     bool no_ndotgradx() const                          //! true if ndotgradx is well defined
365     {return ndotgradx.isVoidFunction();}
no_ndotgrady() const366     bool no_ndotgrady() const                          //! true if ndotgrady is well defined
367     {return ndotgrady.isVoidFunction();}
368 
369     //normal requirements
normalRequired() const370     bool normalRequired() const                       //! true if normal required
371       {return requireNx;}
xnormalRequired() const372     bool xnormalRequired() const                      //! true if x-normal required
373       {return requireNx;}
ynormalRequired() const374     bool ynormalRequired() const                      //! true if y-normal required
375       {return requireNy;}
require(UnitaryVector uv,bool tf=true)376     void require(UnitaryVector uv, bool tf=true)
377     {switch(uv)
378         {
379           case _n  :
380           case _nx : requireNx=tf; return;
381           case _ny : requireNy=tf; return;
382           default  :
383             where("Kernel::require(UnitaryVector)");
384             error("unitaryvector_not_handled",words("normal",uv));
385         }
386     }
387 
388     //all requirements
require(const string_t & s,bool tf=true)389     void require(const string_t& s, bool tf=true)
390     {
391          if(s=="_n" || s=="_nx") {requireNx=tf; return;}
392          if(s=="_ny") {requireNy=tf; return;}
393          if(s=="element") {requireElt=tf; return;}
394          if(s=="dof") {requireDof=tf; return;}
395          if(s=="domain") {requireDom=tf; return;}
396          where("Kernel::require(String)");
397          error("data_not_handled",s);
398     }
399 
400     //virtual downcast methods
tensorKernel() const401     virtual const TensorKernel* tensorKernel() const   //! downcast to tensorkernel
402     { error("forbidden","Kernel::tensorKernel()"); return 0; }
tensorKernel()403     virtual TensorKernel* tensorKernel()               //! downcast to tensorkernel
404     { error("forbidden","Kernel::tensorKernel()"); return 0; }
405 
operator ()(const Point & x,VariableName vn) const406     const Function& operator()(const Point& x, VariableName vn) const   //! specify k(x,y) as y->k(x,y)
407     { kernel.setX(x); return kernel; }
operator ()(VariableName vn,const Point & y) const408     const Function& operator()(VariableName vn, const Point& y) const   //! specify k(x,y) as x->k(x,y)
409     { kernel.setY(y); return kernel; }
410     const Function& operator()(VariableName) const;                     //!< specify k(x,y) as x->k(x,y) or y->k(x,y)
411 
412     //compute Kernel values
413     template<typename T>
414     T& operator()(const Point&, const Point&, T&) const;  //!< compute kernel value at (x,y)
415     template<typename T>
416     T& operator()(const Point&, T&) const;                //!< compute kernel value at (x,P) or (P,X) with P=xory
417     template<typename T>
418     Vector<T>& operator()(const Vector<Point>&,const Vector<Point>&, Vector<T>&) const; //!< compute kernel value at a list of points
419     OperatorOn& operator()(VariableName, VariableName) const;   //experimental, to deal with k(_x,_y)
420 
421     //! print utilities
422     virtual void print(std::ostream&) const;
print(PrintStream & os) const423     virtual void print(PrintStream& os) const {print(os.currentStream());}
424 };
425 
426 std::ostream& operator<<(std::ostream&, const Kernel&); //!< print operator
427 
428 //compute Kernel values
429 template<typename T>
operator ()(const Point & x,const Point & y,T & res) const430 T& Kernel::operator()(const Point& x,const Point& y, T& res) const  //! compute kernel value at (x,y)
431 {
432   return kernel(x,y,res);
433 }
434 
435 template<typename T>
operator ()(const Point & x,T & res) const436 T& Kernel::operator()(const Point& x, T& res) const  //! compute kernel value at (x,.) or (.,x)  regarding xory flag
437 {
438   if(xpar) return kernel(xory,x,res);
439   else return kernel(x,xory,res);
440 }
441 
442 template<typename T>
operator ()(const Vector<Point> & x,const Vector<Point> & y,Vector<T> & res) const443 Vector<T>& Kernel::operator()(const Vector<Point>& x,const Vector<Point>& y, Vector<T>& res) const //! compute kernel value at a list of points
444 {
445   return kernel(x,y,res);
446 }
447 
448 /*!
449   \class KernelExpansion
450   Kernel expansion according to singularity exponents :
451   - \f$\displaystyle G(x,y)         = \sum_i F_i(x,y) / |x-y|^{{\alpha_0}_i}\f$
452   - \f$\displaystyle grad_x G(x,y)  = \sum_i GxF_i(x,y).(x-y) / |x-y|^{{\alpha_x}_i}\f$
453   - \f$\displaystyle grad_y G(x,y)  = \sum_i GyF_i(x,y).(x-y) / |x-y|^{{\alpha_y}_i}\f$
454   - \f$\displaystyle grad_{xy} G(x,y) = \sum_i GxyF_i(x,y).(x-y)(x-y)^T / |x-y|^{{\alpha_{xy}}_i} + \sum_i {GxyF_{diag}}_i(x,y) / |x-y|^{{{\alpha_{xy}}_{diag}}_i} *Identity\f$
455 
456   with the convention \f$1/|x-y|^{{\alpha_x}_i} = Log(|x-y|)\f$ when \f${\alpha_x}_i = -1\f$
457 */
458 class KernelExpansion
459 {
460   public:
461     number_t nbterms;           //!< number of terms in expansion
462     std::vector<int_t> alpha;   //!< singularity exponents
463     Function F_i;             //!< coefficients of F expansion
464     Function gradxF_i;        //!< coefficients of gradx F expansion
465     Function gradyF_i;        //!< coefficients of grady F expansion
466     Function gradxyF_i;       //!< coefficients of gradxy F expansion
467 };
468 
469 
470 } // end of namespace xlifepp
471 
472 #endif // KERNEL_HPP
473 
474