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 BilinearForm.hpp
19 \author E. Lunéville
20 \since 23 mar 2012
21 \date 9 may 2012
22
23 \brief Definition of the xlifepp::BilinearForm classes
24
25 This file declares all the classes related to bilinear forms management.
26 The more general bilinear form under consideration is a list of linear combinations of basic bilinear forms.
27 The list is indexed by the unknowns of the linear combination.
28
29 Basic bilinear forms are, for the moment, integral or double integral type.
30 The bilinear form may have multiple unknowns but a linear combination is related to a unique unknown
31
32 - xlifepp::BiLinearForm is the end user class, it is a map of <Unknown*,LCBilinearForm>
33 - xlifepp::SuBilinearForm deals with linear combination of basic bilinear forms, it is a vector of pairs of <BasicBilinearForm*,complex>
34 - xlifepp::BasicBilinearForm is the mother class (abstract) of classes
35 - xlifepp::IntgBilinearForm for single integral bilinear form (generally in FEM method)
36 - xlifepp::DoubleIngBilinearForm for double integral bilinear form (generally in BEM method)
37 - xlifepp::ComposedBilinearForm for composition of bilinear forms (generally DtN operator)
38 - xlifepp::MatrixBilinearForm for explicit bilinear form given by a TermMatrix
39
40 As example :
41 \code
42 BilinearForm l=intg(Omega,f*u*v); //a single unknown (u) linear form
43 BilinearForm l=intg(Omega,f*u*v)+2*intg(Omega,grad(u)|grad(w)); //a multiple unknowns (u,v), (u,w) bilinear form
44 \endcode
45
46 All linear algebraic operations are allowed on xlifepp::BilinearForm objects
47
48 It is possible to impose the quadrature rule to an integral linear form by specifying a quadrature rule type and its order
49 \code
50 BilinearForm l=intg(Omega,f*u*v,Gauss_Legendre,5); //a single unknown (u) linear form
51 \endcode
52 see Quadrature class for the list of quadrature rules available
53 */
54
55 #ifndef BILINEAR_FORM_HPP
56 #define BILINEAR_FORM_HPP
57
58 #include "config.h"
59 #include "space.h"
60 #include "operator.h"
61 #include "finiteElements.h"
62 #include "largeMatrix.h"
63
64 #include <utility>
65
66 namespace xlifepp
67 {
68
69 class IntgBilinearForm;
70 class DoubleIntgBilinearForm;
71 class ComposedBilinearForm;
72 class MatrixBilinearForm;
73
74 //=========================================================================================
75 /*!
76 \class BasicBilinearForm
77 describes the base class of bilinear form on a space.
78 It is an abstract class
79 */
80 //=========================================================================================
81 class BasicBilinearForm
82 {
83 protected:
84 const Unknown* u_p; //!< pointer to unknown u
85 const Unknown* v_p; //!< pointer to unknown v (test function)
86 const GeomDomain* domainu_p; //!< geometric domain of unknown u
87 const GeomDomain* domainv_p; //!< geometric domain of unknown v (test function)
88 ComputationType compuType; //!< computation type (_FEComputation, _IEComputation, _SPComputation, ...)
89 public:
90 SymType symmetry; //!< symmetry of the bilinear form ((_noSymmetry , _symmetric, _skewSymmetric, _selfAdjoint, _skewAdjoint)
91
92 public:
93 //constructor/destructor
BasicBilinearForm(const Unknown * up=0,const GeomDomain * dup=0,const Unknown * vp=0,const GeomDomain * dvp=0)94 BasicBilinearForm(const Unknown* up=0, const GeomDomain* dup=0,
95 const Unknown* vp=0, const GeomDomain* dvp=0) //! basic and default constructor
96 :u_p(up), v_p(vp), domainu_p(dup), domainv_p(dvp), compuType(_undefComputation), symmetry(_undefSymmetry) {}
~BasicBilinearForm()97 virtual ~BasicBilinearForm() {} //!< virtual destructor
98
99 //accessors
up() const100 const Unknown& up() const //! return the unknown
101 {return *u_p;}
vp() const102 const Unknown& vp() const //! return the test function
103 {return *v_p;}
dom_up() const104 const GeomDomain& dom_up() const //! return the unknown domain
105 {return *domainu_p;}
dom_vp() const106 const GeomDomain& dom_vp() const //! return the test function domain
107 {return *domainv_p;}
computationType() const108 ComputationType computationType() const //! return the computation type
109 {return compuType;}
110
111 Space* subSpace_up(); //!< return the u subspace of the bilinear form, construct it if does not exist
112 Space* subSpace_vp(); //!< return the v subspace of the bilinear form, construct it if does not exist
113
114 void checkUnknowns() const; //!< check the Unknown/TestFunction status of u_p and v_p
115
116 // virtual member functions
117 virtual BasicBilinearForm* clone() const = 0; //!< clone of the bilinear form
118 virtual LinearFormType type() const = 0; //!< return the type of the bilinear form
119 virtual ValueType valueType() const = 0; //!< return the value type of the bilinear form
120 IntgBilinearForm* asIntgForm(); //!< downcast as IntgBilinearForm*
121 const IntgBilinearForm* asIntgForm() const; //!< downcast as const IntgBilinearForm*
122 DoubleIntgBilinearForm* asDoubleIntgForm(); //!< downcast as DoubleIntgBilinearForm*
123 const DoubleIntgBilinearForm* asDoubleIntgForm() const; //!< downcast as const DoubleIntgBilinearForm*
124 //virtual SymType symType() const =0; //!< find symmetry property
125 virtual void print(std::ostream&) const = 0; //!< print utility
126 virtual void print(PrintStream&) const = 0;
127 virtual string_t asString() const = 0; //!< interpret as string for print purpose
setUnknowns(const Unknown & u,const Unknown & v)128 virtual void setUnknowns(const Unknown&u, const Unknown&v) //! set (change) the unknowns
129 {u_p=&u; v_p=&v;}
130 };
131
132 /*!
133 \class IntgBilinearForm
134 describes a bilinear form based on a single integral
135
136 intg_domain opu aopu opv
137
138 with opu, opv : operator on u and v
139 aopu, aopv : algebraic operation (*,|,%,^)
140 */
141 class IntgBilinearForm : public BasicBilinearForm
142 {
143 protected :
144 const OperatorOnUnknowns* opus_p; //!< pointer to the operator on unknowns
145 const IntegrationMethod* intgMethod_p; //!< pointer to integration method
146
147 public :
148 IntgBilinearForm(const GeomDomain&, const OperatorOnUnknowns&, const IntegrationMethod&, SymType); //!< constructor from OperatorOnUnknowns
149 IntgBilinearForm(const GeomDomain&, const OperatorOnUnknowns&, QuadRule, number_t, SymType ); //!< constructor from OperatorOnUnknowns
150 IntgBilinearForm(const GeomDomain&, const OperatorOnUnknown&, AlgebraicOperator,
151 const OperatorOnUnknown&, const IntegrationMethod&, SymType); //!< constructor from explicit operators
152 IntgBilinearForm(const GeomDomain&, const OperatorOnUnknown&, AlgebraicOperator,
153 const OperatorOnUnknown&, QuadRule, number_t, SymType); //!< constructor from explicit operators
154 IntgBilinearForm(const IntgBilinearForm&); //!< copy constructor
155 ~IntgBilinearForm(); //!< destructor
156 IntgBilinearForm& operator=(const IntgBilinearForm&); //!< assign operator
157
158 void setIntegrationMethod(const GeomDomain&, const OperatorOnUnknowns&, QuadRule , number_t); //!< set integration method
159 void setComputationType(); //!< set computation type (_FEComputation,_SPComputation, _FESPComputation)
160
opu() const161 const OperatorOnUnknown& opu() const //! return the reference to the operator on unknown
162 {return opus_p->opu();}
opv() const163 const OperatorOnUnknown& opv() const //! return the reference to the operator on unknown
164 {return opus_p->opv();}
opu_p() const165 const OperatorOnUnknown* opu_p() const //! return the pointer to the operator on unknown
166 {return opus_p->opu_p();}
opv_p() const167 const OperatorOnUnknown* opv_p() const //! return the pointer to the operator on unknown
168 {return opus_p->opv_p();}
algop() const169 AlgebraicOperator algop()const //! return the algebraic operator
170 {return opus_p->algop();}
domain() const171 const GeomDomain* domain() const //! return the pointer to the domain
172 {return domainu_p;}
type() const173 virtual LinearFormType type() const //! return the type of the linear form
174 {return _intg;}
valueType() const175 virtual ValueType valueType() const //! return the value type of the linear form
176 {return opus_p->valueType();}
intgMethod() const177 const IntegrationMethod* intgMethod() const //! pointer to integration method object
178 {return intgMethod_p;}
179 SymType symType() const; //!< find symmetry property (used to set symmetry)
180 virtual BasicBilinearForm* clone() const; //!< clone of the linear form
181 virtual void setUnknowns(const Unknown&, const Unknown&); //!< set (change) the unknowns
182
183 //print stuff
184 virtual void print(std::ostream&) const; //!< print utility
print(PrintStream & os) const185 virtual void print(PrintStream& os) const {print(os.currentStream());}
186 virtual string_t asString() const; //!< interpret as string for print purpose
187 };
188
189 /*!
190 \class DoubleIntgBilinearForm
191 describes a bilinear form based on a double integral
192
193 intg_domain_v intg_domain_u opu(y) aopu opker(x,y) aopv opv(x) dy dx
194
195 with opu, opv : operator on u and v
196 aopu, aopv : algebraic operation (*,|,%,^)
197 opker : operator on a kernel function
198
199 note : when kernel = 1 the pointer to kernel function in opker is ker_p=0 !
200 Be cautious with order of domain, first if for v-domain, second for u-domain
201
202 Actually, two ways to handle some integration methods :
203 by pointer to an IntegrationMethod object, so only one integration method (old way, should disappear in futur)
204 by an IntegrationMethods object that handles some IntegrationMethod (new way)
205 */
206 class DoubleIntgBilinearForm : public BasicBilinearForm
207 {
208 protected:
209 const KernelOperatorOnUnknowns* kopus_p; //!< pointer to the operator on unknowns with kernel
210 const IntegrationMethod* intgMethod_p; //!< pointer to an integration method
211
212 public:
213 IntegrationMethods intgMethods; //!< list of integration methods
214
215 public:
216 //copy constructor
217 DoubleIntgBilinearForm(const DoubleIntgBilinearForm&); //!< copy constructor
218 DoubleIntgBilinearForm& operator=(const DoubleIntgBilinearForm&); //!< assign operator
219 ~DoubleIntgBilinearForm(); //!< destructor
220
221 //constructors from IntegrationMethod
222 DoubleIntgBilinearForm(const GeomDomain&, const GeomDomain&, const KernelOperatorOnUnknowns&,
223 const IntegrationMethod&, SymType); //!< basic constructor
224
225 DoubleIntgBilinearForm(const GeomDomain&, const GeomDomain&, const OperatorOnUnknown&, AlgebraicOperator, const OperatorOnUnknown&,
226 const IntegrationMethod&, SymType); //!< constructor from unknown operators (no kernel)
227
228 DoubleIntgBilinearForm(const GeomDomain&, const GeomDomain&, const OperatorOnUnknown&, AlgebraicOperator,const OperatorOnKernel&,
229 AlgebraicOperator, const OperatorOnUnknown&,
230 const IntegrationMethod&, SymType); //!< constructor from unknown operators and operator on kernel
231
232 DoubleIntgBilinearForm(const GeomDomain&, const GeomDomain&, const OperatorOnUnknown&, AlgebraicOperator,const Kernel&,
233 AlgebraicOperator, const OperatorOnUnknown&,
234 const IntegrationMethod&, SymType); //!< constructor from unknown operators and kernel
235
236 //constructors from IntegrationMethods
237 DoubleIntgBilinearForm(const GeomDomain&, const GeomDomain&, const KernelOperatorOnUnknowns&,
238 const IntegrationMethods&, SymType); //!< basic constructor
239
240 DoubleIntgBilinearForm(const GeomDomain&, const GeomDomain&, const OperatorOnUnknown&, AlgebraicOperator, const OperatorOnUnknown&,
241 const IntegrationMethods&, SymType); //!< constructor from unknown operators (no kernel)
242
243 DoubleIntgBilinearForm(const GeomDomain&, const GeomDomain&, const OperatorOnUnknown&, AlgebraicOperator,const OperatorOnKernel&,
244 AlgebraicOperator, const OperatorOnUnknown&,
245 const IntegrationMethods&, SymType); //!< constructor from unknown operators and operator on kernel
246
247 DoubleIntgBilinearForm(const GeomDomain&, const GeomDomain&, const OperatorOnUnknown&, AlgebraicOperator,const Kernel&,
248 AlgebraicOperator, const OperatorOnUnknown&,
249 const IntegrationMethods&, SymType); //!< constructor from unknown operators and kernel
250
251 //constructors from Quadrule's
252 DoubleIntgBilinearForm(const GeomDomain&, const GeomDomain&, const KernelOperatorOnUnknowns&,
253 QuadRule, number_t, QuadRule, number_t, SymType); //!< basic constructor
254
255 DoubleIntgBilinearForm(const GeomDomain&, const GeomDomain&, const OperatorOnUnknown&, AlgebraicOperator, const OperatorOnUnknown&,
256 QuadRule, number_t, QuadRule, number_t, SymType); //!< constructor from unknown operators (no kernel)
257
258 DoubleIntgBilinearForm(const GeomDomain&, const GeomDomain&, const OperatorOnUnknown&, AlgebraicOperator,const OperatorOnKernel&,
259 AlgebraicOperator, const OperatorOnUnknown&,
260 QuadRule, number_t, QuadRule, number_t, SymType); //!< constructor from unknown operators and operator on kernel
261
262 DoubleIntgBilinearForm(const GeomDomain&, const GeomDomain&, const OperatorOnUnknown&, AlgebraicOperator,const Kernel&,
263 AlgebraicOperator, const OperatorOnUnknown&,
264 QuadRule, number_t, QuadRule, number_t, SymType); //!< constructor from unknown operators and kernel//accessors
265
266 void setIntegrationMethod(const GeomDomain&, const GeomDomain&, const KernelOperatorOnUnknowns&,
267 QuadRule, number_t, QuadRule, number_t); //!< set IntegrationMethod for quadrature product rule
268 void setComputationType(); //!< set computation type (_IEComputation,_IEExtComputation,IEHMatrixComputation, ..)
269 void setIntegrationMethods(); //!< check and update quadrature pointers of IntegrationsMethods
270 void setHMIntegrationMethods(); //!< check and update quadrature pointers of IntegrationsMethods when a HMatrixIM
271
272 //accessors
kopus() const273 const KernelOperatorOnUnknowns& kopus()const //! return KernelOperatorOnUnknowns reference (const)
274 {return *kopus_p;}
kopusp() const275 const KernelOperatorOnUnknowns* kopusp()const //! return KernelOperatorOnUnknowns pointer (const)
276 {return kopus_p;}
opu() const277 const OperatorOnUnknown& opu() const //! return the pointer to the operator on unknown
278 {return kopus_p->opu();}
opv() const279 const OperatorOnUnknown& opv() const //! return the pointer to the operator on unknown
280 {return kopus_p->opv();}
opker() const281 const OperatorOnKernel& opker() const //! return the pointer to the operator on kernel
282 {return kopus_p->opker();}
algopu() const283 AlgebraicOperator algopu()const //! return the algebraic operator on u
284 {return kopus_p->algopu();}
algopv() const285 AlgebraicOperator algopv()const //! return the algebraic operator on v
286 {return kopus_p->algopv();}
intgMethod() const287 const IntegrationMethod* intgMethod() const //! return the pointer to the integration method
288 {return intgMethod_p;}
domainx() const289 const GeomDomain* domainx() const //! return the pointer to the x domain, say u-domain
290 {return domainv_p;}
domainy() const291 const GeomDomain* domainy() const //! return the pointer to the y domain, say v-domain
292 {return domainu_p;}
domains() const293 DomainPair domains() const //! return the pair of domain pointers
294 {return DomainPair(domainu_p,domainv_p);}
type() const295 virtual LinearFormType type() const //! return the type of the linear form
296 {return _doubleIntg;}
valueType() const297 virtual ValueType valueType() const //! return the value type of the bilinear form
298 {return kopus_p->valueType();}
299 SymType symType() const; //!< return symmetry property (_noSymmetry , _symmetric, _skewSymmetric, _selfAdjoint, _skewAdjoint)
300 virtual BasicBilinearForm* clone() const; //!< clone of the linear form
301 virtual void setUnknowns(const Unknown&, const Unknown&); //!< set (change) the unknowns
302
303 //print tools
304 string_t asString() const; //!< interpret as string for print purpose
305 virtual void print(std::ostream&) const; //!< print utility
print(PrintStream & os) const306 virtual void print(PrintStream& os) const {print(os.currentStream());}
operator <<(std::ostream & os,const DoubleIntgBilinearForm & dibf)307 friend std::ostream& operator<<(std::ostream& os,const DoubleIntgBilinearForm& dibf)
308 {dibf.print(os);return os;} //!< print operator
309 };
310
311 //@{
312 //! useful typedefs to MatrixBilinearForm class
313 typedef std::pair<BasicBilinearForm*, complex_t> blfPair;
314 typedef std::vector<blfPair>::iterator it_vblfp;
315 typedef std::vector<blfPair>::const_iterator cit_vblfp;
316 //@}
317
318 /*!
319 \class MatrixBilinearForm
320 describes a bilinear forms given by an explicit matrix
321 explicit matrix is handled by a MatrixEntry object
322 MatrixEntry pointer may be assigned from :
323 - MatrixEntry pointer or reference : no hard copy to save memory
324 - Matrix : matrix is copied as a dense matrix MatrixEntry
325 - Vector : vector is copied as a diagonal MatrixEntry
326 when hard copy is involved, newMatrixEntry flag is set to true in order to free memory when deleting MatrixBilinearForm
327 */
328 class MatrixBilinearForm : public BasicBilinearForm
329 {
330 protected :
331 const MatrixEntry* matrix_p; //!< pointer to a MatrixEntry
332 bool newMatrixEntry_; //!< useful flag to clean memory
333
334 public :
335 //constructors/destructor
MatrixBilinearForm()336 MatrixBilinearForm() //! default constructor
337 : BasicBilinearForm(0,0), matrix_p(0), newMatrixEntry_(false) {}
MatrixBilinearForm(const Unknown & u,const GeomDomain & du,const Unknown & v,const GeomDomain & dv,const MatrixEntry * mp)338 MatrixBilinearForm(const Unknown& u, const GeomDomain& du,
339 const Unknown& v, const GeomDomain& dv, const MatrixEntry* mp) //! basic constructor
340 : BasicBilinearForm(&u, &du, &v, &dv), matrix_p(mp), newMatrixEntry_(false) {}
MatrixBilinearForm(const Unknown & u,const GeomDomain & du,const Unknown & v,const GeomDomain & dv,const MatrixEntry & m)341 MatrixBilinearForm(const Unknown& u, const GeomDomain& du,
342 const Unknown& v, const GeomDomain& dv, const MatrixEntry & m) //! basic constructor
343 : BasicBilinearForm(&u, &du, &v, &dv), matrix_p(&m), newMatrixEntry_(false) {}
344 template <typename T>
345 MatrixBilinearForm(const Unknown&, const GeomDomain&,
346 const Unknown&, const GeomDomain&,
347 const Matrix<T>& , SymType=_noSymmetry); //!< constructor from a Matrix<T>
348 template <typename T>
349 MatrixBilinearForm(const Unknown&, const GeomDomain&,
350 const Matrix<T>& , SymType=_noSymmetry); //!< constructor from a Matrix<T>
351 template <typename T>
352 MatrixBilinearForm(const Unknown&, const GeomDomain&,const std::vector<T>&); //!< constructor from a diagonal matrix(vector)
353 ~MatrixBilinearForm(); //!< destructor
354
type() const355 virtual LinearFormType type() const //! return the type of the linear form
356 {return _explicitLf;}
357 };
358
359 //-------------------------------------------------------------------------------
360 // External functions of MatrixBiLinearForm class
361 //-------------------------------------------------------------------------------
362 //constructor from a Matrix<T>
363 template <typename T>
MatrixBilinearForm(const Unknown & u,const GeomDomain & du,const Matrix<T> & m,SymType sy)364 MatrixBilinearForm::MatrixBilinearForm(const Unknown& u, const GeomDomain& du, const Matrix<T>& m, SymType sy)
365 : BasicBilinearForm(&u, &du, &u, &du)
366 {
367 //create dense storage
368 MatrixStorage* sto= new RowDenseStorage(m.numberOfRows(), m.numberOfColumns(),"");
369 matrix_p= new MatrixEntry(m.valueType(), m.strucType(), sto, m.elementSize(), sy);
370 newMatrixEntry_=true;
371 }
372
373 //constructor from a Matrix<T>
374 template <typename T>
MatrixBilinearForm(const Unknown & u,const GeomDomain & du,const Unknown & v,const GeomDomain & dv,const Matrix<T> & m,SymType sy)375 MatrixBilinearForm::MatrixBilinearForm(const Unknown& u, const GeomDomain& du,
376 const Unknown& v, const GeomDomain& dv, const Matrix<T>& m, SymType sy)
377 : BasicBilinearForm(&u, &du, &v, &dv)
378 {
379 //create dense storage
380 MatrixStorage* sto= new RowDenseStorage(m.numberOfRows(), m.numberOfColumns(),"");
381 matrix_p= new MatrixEntry(m.valueType(), m.strucType(), sto, m.elementSize(), sy);
382 matrix_p->add(m.begin(),m.end()); //fill matrix
383 newMatrixEntry_=true;
384 }
385
386 template <typename T>
MatrixBilinearForm(const Unknown & u,const GeomDomain & d,const std::vector<T> & v)387 MatrixBilinearForm::MatrixBilinearForm(const Unknown& u, const GeomDomain& d, const std::vector<T>& v)
388 {
389 //create csr storage
390 MatrixStorage* sto= new RowCsStorage(v.size(), v.size(),"");
391 matrix_p= new MatrixEntry(v.valueType(), v.strucType(), sto, v.elementSize());
392 matrix_p->add(v.begin(),v.end()); //fill matrix
393 newMatrixEntry_=true;
394 }
395
396 /*!
397 \class SuBilinearForm
398 describes a linear combination of bilinear forms
399 with the same pair of Unknowns.
400 */
401 class SuBilinearForm
402 {
403 protected:
404 std::vector<blfPair> blfs_; //!< list of pairs of bilinear form and coefficient
405 public:
SuBilinearForm()406 SuBilinearForm() {} //!< default constructor
407 SuBilinearForm(const SuBilinearForm&); //!< copy constructor
408 SuBilinearForm(const std::vector<blfPair>&); //!< full constructor from a list of BasicBilinearForms
409 ~SuBilinearForm(); //!< destructor
410 SuBilinearForm& operator=(const SuBilinearForm&); //!< assignment operator
411
size() const412 number_t size() const //! number of elements of the linear combination
413 {return blfs_.size();}
blfs()414 std::vector<blfPair>& blfs() //! access to the list of linear forms
415 {return blfs_;}
blfs() const416 const std::vector<blfPair>& blfs() const //! access to the list of linear forms
417 {return blfs_;}
operator ()(number_t n)418 blfPair& operator()(number_t n) //! access to n-th pair
419 {return blfs_[n - 1];}
operator ()(number_t n) const420 const blfPair& operator()(number_t n) const //! access to n-th pair
421 {return blfs_[n - 1];}
begin()422 it_vblfp begin() //! iterator to the first element of vector of basic bilinear forms
423 {return blfs_.begin();}
begin() const424 cit_vblfp begin() const //! const iterator to the first element of vector of basic bilinear forms
425 {return blfs_.begin();}
end()426 it_vblfp end() //! iterator to the last+1 element of vector of basic bilinear forms
427 {return blfs_.end();}
end() const428 cit_vblfp end() const //! const iterator to the last+1 element of vector of basic bilinear forms
429 {return blfs_.end();}
430 const Unknown* up() const; //!< return the first unknown of the bilinear form
431 const Unknown* vp() const; //!< return the second unknown of the bilinear form
432 const GeomDomain* dom_up() const; //!< return the u-domain of the FIRST basic bilinear form
433 const GeomDomain* dom_vp() const; //!< return the v-domain of the FIRST basic bilinear form
434 const Space* uSpace() const; //!< return the u space of the bilinear form
435 const Space* vSpace() const; //!< return the v space of the bilinear form
436 LinearFormType type() const; //!< return the type of the bilinear form (intg,doubleIntg,linearCombination)
437 ValueType valueType() const; //!< return the value type of the bilinear form
438 SymType symType() const; //!< return the symmetry of bilinear form
439 void setUnknowns(const Unknown&, const Unknown&); //!< set unknowns of SuBilinearForm
440
441 bool checkConsistancy(const SuBilinearForm&) const; //!< check consitancy of Unknown
442 SuBilinearForm& operator +=(const SuBilinearForm&); //!< sum of bilinear forms
443 SuBilinearForm& operator -=(const SuBilinearForm&); //!< difference of linear forms
444 SuBilinearForm& operator *=(const complex_t&); //!< multiply by a complex
445 SuBilinearForm& operator /=(const complex_t&); //!< divide by a complex
446
447 void print(std::ostream&) const; //!< print utility
448 string_t asString() const; //!< as symbolic string
449
450 }; // end of BilinearForm class
451
452 //-------------------------------------------------------------------------------
453 // External functions of SuBilinearForm class
454 //-------------------------------------------------------------------------------
455 std::ostream& operator<<(std::ostream&, const SuBilinearForm&); //!< output SuBilinearForm
456
457 // operations on bilinear form to construct linear combination of forms
458 SuBilinearForm operator-(const SuBilinearForm&); //!< opposite of bilinear form
459 SuBilinearForm operator+(const SuBilinearForm&, const SuBilinearForm&); //!< sum of bilinear forms
460 SuBilinearForm operator-(const SuBilinearForm&, const SuBilinearForm&); //!< difference of bilinear forms
461 SuBilinearForm operator*(const complex_t&, const SuBilinearForm&); //!< multiply(left) by a scalar
462 SuBilinearForm operator*(const SuBilinearForm&, const complex_t&); //!< multiply(right) by a scalar
463 SuBilinearForm operator/(const SuBilinearForm&, const complex_t&); //!< divide by a scalar
464
465 //@{
466 //! useful typedefs to BilinearForm class
467 typedef std::pair<const Unknown*, const Unknown*> uvPair;
468 typedef std::map<uvPair, SuBilinearForm>::iterator it_mublc;
469 typedef std::map<uvPair, SuBilinearForm>::const_iterator cit_mublc;
470 //@}
471
472 /*!
473 \class BilinearForm
474 describes a general bilinear form, that is a list of linear combinations of basic bilinear forms.
475 It is intend to collect linear forms with different unknowns, using a map<uvPair,SuBilinearForm>.
476 It is the enduser's class
477 */
478 class BilinearForm
479 {
480 protected:
481 std::map<uvPair, SuBilinearForm> mlcblf_; //!< list of linear combinations of basic bilinear forms
482
483 public:
484 SuBilinearForm& operator[](const uvPair&); //!< access to the bilinear form associated to an unknown
485 const SuBilinearForm& operator[](const uvPair&) const; //!< access to the bilinear form associated to a pair of unknowns
BilinearForm()486 BilinearForm() {} //!< default constructor
487 BilinearForm(const SuBilinearForm& lc); //!< constructor from a linear combination
clear()488 void clear() //! clear the map of bilinear form
489 {mlcblf_.clear();}
490 bool isEmpty() const; //!< true if no bilinear form
begin()491 it_mublc begin() //! iterator to the first element of map
492 {return mlcblf_.begin();}
begin() const493 cit_mublc begin() const //! const iterator to the first element of map
494 {return mlcblf_.begin();}
end()495 it_mublc end() //! iterator to the last+1 element of map
496 {return mlcblf_.end();}
end() const497 cit_mublc end() const //! const iterator to the last+1 element of map
498 {return mlcblf_.end();}
499 bool singleUnknown() const; //!< true if only one unknown
500 const SuBilinearForm& first() const; //!< return first linear combination
501 BilinearForm operator()(const Unknown&, const Unknown&) const; //!< access to the bilinear form associated to a pair of unknowns
502 BasicBilinearForm& operator()(const Unknown&, const Unknown&, number_t); //!< access to the n-th basic bilinear form associated to a pair of unknowns
503 const BasicBilinearForm& operator()(const Unknown&, const Unknown&, number_t) const; //!< access to the n-th basic bilinear form associated to a pair of unknowns
504 const SuBilinearForm* subLfp(const uvPair& uv) const; //!< access to SuBiLinearForm pointers related to unknown
505 SuBilinearForm* subLfp(const uvPair& uv); //!< access to SuBiLinearForm pointers related to unknown (non const)
506 void setUnknowns(const Unknown&, const Unknown&); //!< set the unknowns of bilinear forms (only for single unknown bf)
507
508 void print(std::ostream&) const; //!< print utility
print(PrintStream & os) const509 void print(PrintStream& os) const {print(os.currentStream());}
510
511 BilinearForm& operator+=(const BilinearForm&); //!< sum of linear forms
512 BilinearForm& operator-=(const BilinearForm&); //!< difference of linear forms
513 BilinearForm& operator*=(const complex_t&); //!< multiply by a complex
514 BilinearForm& operator/=(const complex_t&); //!< divide by a complex
515 };
516
517 //-------------------------------------------------------------------------------
518 // External functions of BiLinearForm class
519 //-------------------------------------------------------------------------------
520
521 // Single integral user functions like constructors
522 // ------------------------------------------------
523 // using IntegrationMethod object
524 BilinearForm intg(const GeomDomain&, const OperatorOnUnknown&, AlgebraicOperator, const OperatorOnUnknown&,
525 const IntegrationMethod&, SymType = _undefSymmetry); //!< construct a simple intg bilinear form
526 BilinearForm intg(const GeomDomain&, const OperatorOnUnknowns&,
527 const IntegrationMethod&, SymType = _undefSymmetry); //!< construct a simple intg bilinear form
528 // using explicit quadrature rule as IntegrationMethod
529 BilinearForm intg(const GeomDomain&, const OperatorOnUnknown&, AlgebraicOperator, const OperatorOnUnknown&,
530 QuadRule, number_t =0, SymType = _undefSymmetry); //!< construct a simple intg bilinear form
531 BilinearForm intg(const GeomDomain&, const OperatorOnUnknowns&,
532 QuadRule, number_t =0, SymType = _undefSymmetry); //!< construct a simple intg bilinear form
533 // using default quadrature rule as IntegrationMethod
534 BilinearForm intg(const GeomDomain&, const OperatorOnUnknown&, AlgebraicOperator, const OperatorOnUnknown&,
535 SymType = _undefSymmetry); //!< construct a simple intg bilinear form
536 BilinearForm intg(const GeomDomain&, const OperatorOnUnknowns&,
537 SymType = _undefSymmetry); //!< construct a simple intg bilinear form
538
539 // Double integral user functions like constructors
540 // ------------------------------------------------
541 // using IntegrationMethod object
542 BilinearForm intg(const GeomDomain&, const GeomDomain&, const OperatorOnUnknown&, AlgebraicOperator, const OperatorOnUnknown&,
543 const IntegrationMethod&, SymType = _undefSymmetry); //!< construct a double intg bilinear form (kernel=1)
544 BilinearForm intg(const GeomDomain&, const GeomDomain&, const OperatorOnUnknowns&,
545 const IntegrationMethod&, SymType = _undefSymmetry); //!< construct a double intg bilinear form (kernel=1)
546 BilinearForm intg(const GeomDomain&, const GeomDomain&, const OperatorOnUnknown&, AlgebraicOperator,
547 const Kernel&, AlgebraicOperator, const OperatorOnUnknown&,
548 const IntegrationMethod&, SymType = _undefSymmetry); //!< construct a double intg bilinear form from kernel
549 BilinearForm intg(const GeomDomain&, const GeomDomain&, const OperatorOnUnknown&, AlgebraicOperator,
550 const OperatorOnKernel&, AlgebraicOperator, const OperatorOnUnknown&,
551 const IntegrationMethod&, SymType = _undefSymmetry); //!< construct a double intg bilinear form from operator on kernel
552 BilinearForm intg(const GeomDomain&, const GeomDomain&, const KernelOperatorOnUnknowns&,
553 const IntegrationMethod&, SymType = _undefSymmetry); //!< construct a double intg bilinear form from kernel operator
554 // using IntegrationMethods object
555 BilinearForm intg(const GeomDomain&, const GeomDomain&, const OperatorOnUnknown&, AlgebraicOperator, const OperatorOnUnknown&,
556 const IntegrationMethods&, SymType = _undefSymmetry); //!< construct a double intg bilinear form (kernel=1)
557 BilinearForm intg(const GeomDomain&, const GeomDomain&, const OperatorOnUnknowns&,
558 const IntegrationMethods&, SymType = _undefSymmetry); //!< construct a double intg bilinear form (kernel=1)
559 BilinearForm intg(const GeomDomain&, const GeomDomain&, const OperatorOnUnknown&, AlgebraicOperator,
560 const Kernel&, AlgebraicOperator, const OperatorOnUnknown&,
561 const IntegrationMethods&, SymType = _undefSymmetry); //!< construct a double intg bilinear form from kernel
562 BilinearForm intg(const GeomDomain&, const GeomDomain&, const OperatorOnUnknown&, AlgebraicOperator,
563 const OperatorOnKernel&, AlgebraicOperator, const OperatorOnUnknown&,
564 const IntegrationMethods&, SymType = _undefSymmetry); //!< construct a double intg bilinear form from operator on kernel
565 BilinearForm intg(const GeomDomain&, const GeomDomain&, const KernelOperatorOnUnknowns&,
566 const IntegrationMethods&, SymType = _undefSymmetry); //!< construct a double intg bilinear form from kernel operator
567 // using an explicit quadrature rule
568 BilinearForm intg(const GeomDomain&, const GeomDomain&, const OperatorOnUnknown&, AlgebraicOperator, const OperatorOnUnknown&,
569 QuadRule, number_t =0, SymType = _undefSymmetry); //!< construct a double intg bilinear form (kernel=1)
570 BilinearForm intg(const GeomDomain&, const GeomDomain&, const OperatorOnUnknowns&,
571 QuadRule, number_t =0, SymType = _undefSymmetry); //!< construct a double intg bilinear form (kernel=1)
572 BilinearForm intg(const GeomDomain&, const GeomDomain&, const OperatorOnUnknown&, AlgebraicOperator,
573 const Kernel&, AlgebraicOperator, const OperatorOnUnknown&,
574 QuadRule, number_t =0, SymType = _undefSymmetry); //!< construct a double intg bilinear form from kernel
575 BilinearForm intg(const GeomDomain&, const GeomDomain&, const OperatorOnUnknown&, AlgebraicOperator,
576 const OperatorOnKernel&, AlgebraicOperator, const OperatorOnUnknown&,
577 QuadRule, number_t =0, SymType = _undefSymmetry); //!< construct a double intg bilinear form from operator on kernel
578 BilinearForm intg(const GeomDomain&, const GeomDomain&, const KernelOperatorOnUnknowns&,
579 QuadRule, number_t =0, SymType = _undefSymmetry); //!< construct a double intg bilinear form from kernel operator
580 // using default quadrature rule
581 BilinearForm intg(const GeomDomain&, const GeomDomain&, const OperatorOnUnknown&, AlgebraicOperator, const OperatorOnUnknown&,
582 SymType = _undefSymmetry); //!< construct a double intg bilinear form (kernel=1)
583 BilinearForm intg(const GeomDomain&, const GeomDomain&, const OperatorOnUnknowns&,
584 SymType = _undefSymmetry); //!< construct a double intg bilinear form (kernel=1)
585 BilinearForm intg(const GeomDomain&, const GeomDomain&, const OperatorOnUnknown&, AlgebraicOperator,
586 const Kernel&, AlgebraicOperator, const OperatorOnUnknown&,
587 SymType = _undefSymmetry); //!< construct a double intg bilinear form from kernel
588 BilinearForm intg(const GeomDomain&, const GeomDomain&, const OperatorOnUnknown&, AlgebraicOperator,
589 const OperatorOnKernel&, AlgebraicOperator, const OperatorOnUnknown&,
590 SymType = _undefSymmetry); //!< construct a double intg bilinear form from operator on kernel
591 BilinearForm intg(const GeomDomain&, const GeomDomain&, const KernelOperatorOnUnknowns&,
592 SymType = _undefSymmetry); //!< construct a double intg bilinear form from kernel operator
593
594 // -------------------------------------------------------------
595 // algebraic operations on BilinearForms
596 // -------------------------------------------------------------
597 const BilinearForm& operator+(const BilinearForm&); //!< same bilinear form
598 BilinearForm operator-(const BilinearForm&); //!< opposite of a bilinear form
599 BilinearForm operator+(const BilinearForm&, const BilinearForm&); //!< sum of bilinear forms
600 BilinearForm operator-(const BilinearForm&, const BilinearForm&); //!< difference of bilinear forms
601 BilinearForm operator*(const int_t&, const BilinearForm&); //!< product(left) by an integer scalar
602 BilinearForm operator*(const int&, const BilinearForm&); //!< product(left) by an integer scalar
603 BilinearForm operator*(const number_t&, const BilinearForm&); //!< product(left) by an integer scalar
604 BilinearForm operator*(const real_t&, const BilinearForm&); //!< product(left) by a real scalar
605 BilinearForm operator*(const complex_t&, const BilinearForm&); //!< product(left) by a complex scalar
606 BilinearForm operator*(const BilinearForm&, const int_t&); //!< product(right) by an integer scalar
607 BilinearForm operator*(const BilinearForm&, const int&); //!< product(right) by an integer scalar
608 BilinearForm operator*(const BilinearForm&, const number_t&); //!< product(right) by an integer scalar
609 BilinearForm operator*(const BilinearForm&, const real_t&); //!< product(right) by a real scalar
610 BilinearForm operator*(const BilinearForm&, const complex_t&); //!< product(right) by a complex scalar
611 BilinearForm operator/(const BilinearForm&, const int_t&); //!< division by an integer scalar
612 BilinearForm operator/(const BilinearForm&, const int&); //!< division by an integer scalar
613 BilinearForm operator/(const BilinearForm&, const number_t&); //!< division by an integer scalar
614 BilinearForm operator/(const BilinearForm&, const real_t&); //!< division by a real scalar
615 BilinearForm operator/(const BilinearForm&, const complex_t&); //!< division by a complex scalar
616
617 //composition of bilinear forms
618 BasicBilinearForm& operator*(const BasicBilinearForm&, const BasicBilinearForm&); //!< compose two basic bilinear forms
619 BilinearForm operator*(const BilinearForm&, const BilinearForm&); //!< compose two bilinear forms, have to be basic linear forms
620
621 // print utility
622 std::ostream& operator<<(std::ostream&, const BilinearForm&); //!< output BilinearForm
623
624 } // end of namespace xlifepp
625
626 #endif /* BILINEAR_FORM_HPP */
627