Operators on unknowns/kernels#
The operator library collects the classes and functionalities related to the description of differential operators acting on unknown or test function in linear, bilinear form and essential condition expressions.
As we wish to propose to end users, a C++ description of such operators as close as possible to the mathematical description, few operators are overloaded and a lot of possibilities are offered, for instance, where u
denotes an unknown, v
a test function, A
a matrix, F
a function and K
a kernel:
mathematical expression |
XLiFE++ translation |
---|---|
\(\nabla(u)\) |
|
\(\nabla(u)\cdot\nabla(v)\) |
|
\((A*\nabla(u))\cdot\nabla(v)\) |
|
\((F(x)*\nabla(u))\cdot\nabla(\overline{v})\) |
|
\(u(x)*K(x, y)*v(y)\) |
|
As a consequence, this library is quite intricate. It is based on
the class of differential operator:
DifferentialOperator
collecting all the differential operators that can be applied to an unknown or a test function,the class of operand:
Operand
, describing the operations performed at left and right of a differential operator acting on an unknown or a test function,the class of operator acting on unknown:
OperatorOnUnknown
which collects the differential operator acting on unknown and the left and right operands if exists.the
OperatorOnUnknowns
which relies two operators on unknown as they appear in a bilinear form.the class of linear combination of operators acting on unknown:
LcOperatorOnUnknown
which manages a list of pair ofOperatorOnUnknown
and complex coefficient. This class is also able to attach geometric domain to each pair.
A linear form will be defined from one OperatorOnUnknown
object and a bilinear form
from OperatorOnUnknowns
objects; see the lib form library.
Besides, this library provides additional classes to deal with expression involving Kernel
functions:
the
OperatorOnKernel
class which handles differential operator applied to a kernel.the
KernelOperatorOnUnknowns
class which relies two operators on unknown and a kernel.the
TensorKernel
class inherited fromKernel
and implementing particular kernel.
Available differential operators#
The complete list of operators is in the following, where u
is either a scalar or vector unknown, x
, y
and z
are the cartesian coordinates and n
is the normal vector:
mathematical |
built-in functions |
unknown structure |
---|---|---|
identity |
|
scalar or vector |
\(\partial_t\) |
|
scalar or vector |
\(\partial_x\) |
|
scalar or vector |
\(\partial_y\) |
|
scalar or vector |
\(\partial_z\) |
|
scalar or vector |
\(\nabla\) |
|
scalar or vector |
\(\mathrm{div}\) |
|
vector |
\(\mathrm{curl}\) |
|
vector |
\(\nabla_\tau\) (surfacic) |
|
scalar or vector |
\(\mathrm{div}_\tau\) (surfacic) |
|
vector |
\(\mathrm{curl}_\tau\) (surfacic) |
|
vector |
\(\nabla_{abc}=(a\partial_x,b\partial_y,c\partial_z)\) |
|
scalar or vector |
\(\nabla_{abc}.\) |
|
vector |
\(\nabla_{abc}\times\) |
|
vector |
\(\varepsilon\) |
|
vector |
\(\varepsilon_{iabc}\) |
|
vector |
\(\varepsilon_{R}\) |
|
vector |
\(\mathrm{voigtToM}\) |
|
vector |
\(n*\) |
|
scalar |
\(n \cdot\) |
|
vector |
\(n\times\) |
|
vector |
\(n\times n\times\) |
|
vector |
\(n \cdot \nabla\) |
|
scalar |
\(n \times \nabla\) |
|
scalar |
\(n\;\mathrm{div}\) |
|
vector |
\(n\times\mathrm{curl}\) |
|
vector |
\([\ ]\) (jump across) |
|
scalar or vector |
\(\{\ \}\) (mean across) |
|
scalar or vector |
The complete list of operators on kernels is the following:
mathematical |
built-in functions |
unknown structure |
---|---|---|
identity |
|
scalar or vector |
\(\nabla_x\) |
|
scalar or vector |
\(\nabla_y\) |
|
scalar or vector |
\(\mathrm{div}_x\) |
|
vector |
\(\mathrm{div}_y\) |
|
vector |
\(\mathrm{curl}_x\) |
|
vector |
\(\mathrm{curl}_y\) |
|
vector |
\(n_x *\) |
|
scalar |
\(n_y *\) |
|
scalar |
\(n_x \cdot\) |
|
vector |
\(n_y \cdot\) |
|
vector |
\(n_x \times\) |
|
vector |
\(n_y \times\) |
|
vector |
\(n_x \times (n_x\times)\) |
|
vector |
\(n_y \times (n_y\times)\) |
|
vector |
\(n_x \cdot \nabla_x\) |
|
scalar |
\(n_y \cdot \nabla_y\) |
|
scalar |
\(n_x \mathrm{div}_x\) |
|
vector |
\(n_y \mathrm{div}_y\) |
|
vector |
\(n_x \times \mathrm{curl}_x\) |
|
vector |
\(n_y \times \mathrm{curl}_y\) |
|
vector |
\(n_x \cdot n_y *\) |
|
scalar or vector |
\((n_x \times n_y) \cdot\) |
|
vector |
\((n_y \times n_x) \cdot\) |
|
vector |
\((n_x \times n_y) \times\) |
|
vector |
\((n_y \times n_x) \times\) |
|
vector |
In operators, the normal vectors _n
, _nx
, _ny
are symbolic ones. They refer to real normal vectors related to the domain involved in integrals where operators appear.
See the section Dealing with normals to know how normal vectors are oriented.
Let’s now explain how these operators are defined.
The DifferentialOperator
class#
The DifferentialOperator
class is intended to describe various operators that can
be act on a scalar function or a vector function. They may be either differential operator
(involving derivatives) or 0 order operators (not involving derivative). The attributes of
this class are the following:
class DifferentialOperator
{
private:
DiffOpType type_; //type of differential operator
Number order_; //derivation order
bool requiresExtension_; //does operator involve non-tangential derivatives
bool requiresNormal_; //is normal vector required for this operator
String name_; //operator name
}
The differential operators supported are listed in the DiffOpType
enumeration, one item per differential operator listed in available operators on unknowns/test functions
There is only one definition of differential operators stored (using their pointers) in the static variable:
static std::vector<DifferentialOperator*> theDifferentialOperators;
There is an explicit constructor of DifferentialOperator
objects, but they are also created
using the find function:
DifferentialOperator* findDifferentialOperator(DiffOpType);
which creates the differential operator of a given type if it does not exist and returns a pointer to the differential operator if it exists or has just been created. This class provides some useful accessors functions (only read):
String name() const { return name_; }
DiffOpType type() const { return type_; }
Number order() const { return order_; }
bool normalRequired() const { return requiresNormal_; }
bool extensionRequired() const { return requiresExtension_; }
and printing facilities:
std::ostream& operator<<(std::ostream&, const DifferentialOperator&);
void printListDiffOp(std::ostream&);
See also
library=operator,
header=DifferentialOperator.hpp,
implementation=DifferentialOperator.cpp,
test=test_operator.cpp,
header dep= config.h, utils.h
The Operand
class#
The Operand
class stores a AlgebraicOperator
, a user data (either Function
or Value
) and conjugate, transpose flags. It is mainly used by the OperatorOnUnknown
class as left or right-hand side of a generalized differential operator (see the next section).
The only allowed algebraic operations defined in the AlgebraicOperator
enumeration, are:
the standard product, operator
*
the inner product (hermitian product), operator
|
the cross product, operator
^
the contracted product, operator
%
enum AlgebraicOperator {_product,_innerProduct,_crossProduct,_contractedProduct};
class Operand
{
protected :
// pointer to operand object (a Value)
const Value* val_p;
// pointer to Function object
const Function * fun_p;
// function flag
bool isFunction_;
// true if the operand has to be conjugated
bool conjugate_;
// true if the operand has to be transposed
bool transpose_;
// operand operator
AlgebraicOperator operation_;
}
This class provides few public constructors:
// from a Function
Operand(const Function&,AlgebraicOperator);
// from a Value (Value is copied)
Operand(const Value&,AlgebraicOperator);
// from a Value* (Value is not copied)
Operand(const Value*,AlgebraicOperator);
// from a scalar, a Vector or a Matrix
template <typename T>
Operand(const T &,AlgebraicOperator);
The templated constructor avoids the user to give explicitly a Value object, “ordinary” objects such scalar, vector or matrix may be passed to the constructor.
The other member functions are some accessors functions:
bool isFunction() const;
bool conjugate() const;
bool& conjugate();
bool transpose() const;
bool& transpose();
AlgebraicOperator operation() const;
const Value& value() const;
const Function& function() const;
template<class T> T& valueT() const;
There are two printing facilities:
void Operand::print(std::ostream&) const;
std::ostream& operator<<(std::ostream&,const Operand &);
Important
- The
Operand
class is an internal class linked to theOperatorOnUnknown
class. -
Normally, an end user does not use this class.
See also
library=operator,
header=Operand.hpp,
implementation=Operand.cpp,
test=test_operator.cpp,
header dep= config.h, utils.h
The OperatorOnUnknown
class#
The OperatorOnUnknown
class is intended to store the description of an expression involving
a differential operator acting on an unknown (or a test function) with possibly operations
at the left and the right. More precisely, the general form of the operator on unknown is:
where
u is an unknown,
dif a differential operator,
data is a user data (value or function),
op an algebraic operation among
*` (product), ``|` (inner product), ``^
(cross product),:
(contracted product),tr a transformation among conj (conjugate), tran (transpose) and adj (adjoint).
All is optional except the unknown u.
The simplest form is u and a more complex one is for instance, something like this (\(f\) a matrix and g a vector):
which mathematically reads:
The class has the following attributes:
class OperatorOnUnknown
{
protected :
//unknown involved in operator
const Unknown * u_p;
//true if the unknown has to be conjugated
bool conjugateUnknown_;
//differential operator involved in operator
DifferentialOperator * difOp_p;
//object before the diff operator
Operand * leftOperand_p;
//object after the diff operator
Operand * rightOperand_p;
//priority order flag, true if left operand is prior
bool leftPriority_;
//coefficients for operator (gradG, divG, curlG)
Vector<Complex> coefs_;
//returned value (_real,_complex)
ValueType type_;
//returned structure (_scalar,_vector,_matrix)
StrucType struct_;
}
Operand
is a class storing a user data (value or function) and an algebraic operation
(* | ^ %
).
The class provides some basic constructors (from unknown and differential operator type), some useful constructors (from unknown and function or value), a copy constructor, the assignment operator and a destructor:
OperatorOnUnknown(const Unknown* un=0,DiffOpType=_id);
OperatorOnUnknown(const Unknown& un,DiffOpType=_id);
OperatorOnUnknown(const Unknown&,const Function&,AlgebraicOperator,bool);
OperatorOnUnknown(const Unknown&,const Value&,AlgebraicOperator,bool);
OperatorOnUnknown(const OperatorOnUnknown &);
~OperatorOnUnknown();
OperatorOnUnknown& operator=(const OperatorOnUnknown &);
Note that the DifferentialOperator
object are created on the fly when creating OperatorOnUnknown
from Unknown
and DiffOpType
.
The class provides some accessors (read or write):
DiffOpType difOpType() const ;
DifferentialOperator*& difOp() ;
ValueType& type();
Operand*& leftOperand();
Operand*& rightOperand();
Vector<Complex>& coefs();
const Vector<Complex>& coefs() const;
bool leftPriority() const;
bool& leftPriority();
and some utilities to update class attributes and print them:
void setReturnedType(const Unknown*,DiffOpType);
void updateReturnedType(AlgebraicOperator,ValueType,StrucType,bool);
void print(std::ostream&) const;
std::ostream& operator<<(std::ostream&,const OperatorOnUnknown &); //extern
The two first one manage the returned types and check consistency of operations and the two
last functions output on stream the class OperatorOnUnknown
characteristics.
To deal with the general syntax of OperatorOnUnknown
, a lot of external functions are required,
in particular some overloaded operators. The first family of functions concerns the creation
of simple OperatorOfUnknown
object from a differential operator and an unknown. Their names
are the names of differential operator type (DiffOpType
enumeration) without the leading underscore.
We give only a few examples here (see OperatorOnUnknown.hpp header file for the complete list):
OperatorOnUnknown& id(const Unknown&);
OperatorOnUnknown& d0(const Unknown&);
...
OperatorOnUnknown& grad(const Unknown&);
OperatorOnUnknown& nabla(const Unknown&);
...
OperatorOnUnknown& nx(const Unknown&);
...
OperatorOnUnknown& gradG (const Unknown&,const Complex&,const Complex&,
const Complex&,const Complex&);
...
OperatorOnUnknown& mean(const Unknown&);
OperatorOnUnknown& jump(const Unknown&);
These functions construct an OperatorOnUnknown
in the heap memory and return a reference in
order to be used in a chained expression. In this context, it may occur a memory leak if
nobody delete explicitly the OperatorOnUnknown
object created on the fly.
To manage general syntax, the following c++ operators have been overloaded:
*
: usual consistent product between scalars, vectors and matrices|
: inner product of vectors, for complex objects it is an hermitian product^
: cross product of vectors%
: contracted product (the second term is transposed)
These operators are enumerated in the AlgebraicOperator
enumeration.
They are overloaded for Unknown
or OperatorOnUnknown
and unitaryVector (UnitaryVector
enumerates the normal vector _n and the tangential vector _t). When differential operators involve operation with normal, you can use the previous function (for instance ndot) or use their mathematical syntax (for instance n*u):
OperatorOnUnknown& operator*(UnitaryVector,const Unknown &); // n*u
OperatorOnUnknown& operator*(const Unknown &,UnitaryVector); // u*n
OperatorOnUnknown& operator|(UnitaryVector,const Unknown &); // n|u
OperatorOnUnknown& operator^(UnitaryVector,const Unknown &); // n^u
OperatorOnUnknown& operator|(const Unknown &,UnitaryVector); // u|n
OperatorOnUnknown& operator|(UnitaryVector,OperatorOnUnknown&); // n|grad(u)
OperatorOnUnknown& operator^(UnitaryVector,OperatorOnUnknown&); // n^(n^u) or n^curl(u)
OperatorOnUnknown& operator*(UnitaryVector,OperatorOnUnknown&); // n*div
OperatorOnUnknown& operator|(OperatorOnUnknown&,UnitaryVector); // grad(u)|n
OperatorOnUnknown& operator*(OperatorOnUnknown&,UnitaryVector); // div*n
Note that all cases are not considered. It should be !?
To deal with left and right-hand side operations, these algebraic operators have been also overloaded
for different types of objects (Unknown
, OperatorOnUnknown
, Function
, Value
, user c++ function or user value). The operator overloading with c++ function or user value avoids the user to explicitly encapsulate its own data (c++ function or scalar, vector, matrix) in Function object
or Value object. There are shortcuts. In the following, only prototypes of * operator are presented.
Operations between Unknown
and Function
#
OperatorOnUnknown& operator*(const Unknown &,const Function&); // u*F
OperatorOnUnknown& operator*(const Function&,const Unknown &); // F*u
template <typename T>
OperatorOnUnknown& operator*(const Unknown &,T( )(const Point&,Parameters&));
OperatorOnUnknown& operator*(T( )(const Point&,Parameters&),const Unknown &);
OperatorOnUnknown& operator*(const Unknown &, T( )(const Vector<Point>&,Parameters&));
OperatorOnUnknown& operator*(T( )(const Vector<Point>&,Parameters&), const Unknown &);
...
The two first one declarations concern Function object encapsulating c++ user functions whereas the templated forms concerns c++ user functions. As mentioned before, it avoids the user to encapsulate his c++ functions. Note that only c++ functions that can be encapsulated in Function object are working in templated forms. Other functions may be accepted in compilation process, but the result during execution may be hazardous!
Warning
Kernel type functions can not be use straightforward in operator. Contrary to the ordinary
functions, they have to be encapsulated in Function
objects!
Operations between Unknown
and Value
#
OperatorOnUnknown& operator*(const Unknown&,const Value&); // u*V
OperatorOnUnknown& operator*(const Value&,const Unknown&); // V*u
template<typename T>
OperatorOnUnknown& operator*(const Unknown& ,const T& ) // u*T
OperatorOnUnknown& operator*(const T& ,const Unknown&) // T*u
...
The two first one declarations concern Value object encapsulating c++ user data and the templated forms concerns c++ user data. Only c++ user data that can be encapsulated in Value object are working in templated forms.
Operations between OperatorOnUnknown
and Function
The principle is the same as in previous cases.
OperatorOnUnknown& operator*(OperatorOnUnknown&,const Function &); // op(u)*F
OperatorOnUnknown& operator*(const Function &,OperatorOnUnknown&); // F*op(u)
template<typename T>
OperatorOnUnknown& operator*(OperatorOnUnknown&, T( )(const Point&,Parameters&))
OperatorOnUnknown& operator*(T( )(const Point&,Parameters&), OperatorOnUnknown&)
OperatorOnUnknown& operator*(OperatorOnUnknown&, T( )(const Vector<Point>&,Parameters&))
OperatorOnUnknown& operator*(T( )(const Vector<Point>&,Parameters&), OperatorOnUnknown&)
...
Operations between OperatorOnUnknown
and Value
OperatorOnUnknown& operator*(OperatorOnUnknown&,const Value &); // op(u)*V
OperatorOnUnknown& operator*(const Value &,OperatorOnUnknown&); // V*op(u)
template<typename T>
OperatorOnUnknown& operator*(OperatorOnUnknown&,const T&); // op(u)*T
OperatorOnUnknown& operator*(const T&,OperatorOnUnknown&); // T*op(u)
...
Most of the previous overloaded operators use the following update functions:
OperatorOnUnknown& updateRight(OperatorOnUnknown&,const Function&,AlgebraicOperator);
OperatorOnUnknown& updateLeft (OperatorOnUnknown&,const Function&,AlgebraicOperator);
OperatorOnUnknown& updateRight(OperatorOnUnknown&,const Value&,AlgebraicOperator);
OperatorOnUnknown& updateLeft (OperatorOnUnknown&,const Value&,AlgebraicOperator);
template<typename T>
OperatorOnUnknown& updateRight(OperatorOnUnknown&,const T&,AlgebraicOperator);
OperatorOnUnknown& updateLeft(OperatorOnUnknown&,const T&,AlgebraicOperator);
Note that it is possible to use the transformations conj, tran and adj
on Unknown, Value or Function. These functions are defined in the files related to these classes.
For simplicity, it is not possible to apply such transformations to an OperatorOnUnknown
object
or a part of the expression. For instance, the syntax conj(grad(u)) is not supported.
Finally, we give some examples to show how this machinery works:
//define some C++ functions
Real F(const Point &P,Parameters& pa = defaultParameters) {...}
Vector<Real> vecF(const Point &P,Parameters& pa = defaultParameters) {...}
Matrix<Real> matF(const Point &P,Parameters& pa = defaultParameters) {...}
//define some constant values
Real pi=3.14159; Complex i(0,1);vector<Real> v(3,1); matrix<Complex> A(3,3,i);
//assume u is an Unknown (a vector of dimension 3)
OperatorOnUnknown opu=u; //the simplest one
opu=grad(u); //involve only differential operator
opu=_n^curl(u); //equivalent to ncrosscurl(u)
opu=v^u; //cross product with vector
opu=vecF^u; //cross product with vector function
opu=A*grad(u); //left product with a matrix
opu=grad(u)*matF; //right product with a matrix function
opu=(matF*grad(u))%A; //product and contracted product
opu=curl(conj(u))|conj(v); //use conj transformation
Be careful with operator priority. The C++ priority rules are applied and not the mathematical ones. In doubt, use parenthesis. The code performs some constancy checking on operand and operator but only on structure (scalar, vector, matrix) not on the dimension (see upadateReturnedType and setReturnedType functions).
See also
library=operator,
header=OperatorOnUnknown.hpp,
implementation=OperatorOnUnknown.cpp,
test=test_operator.cpp,
header dep= config.h, utils.h
The OperatorOnUnknowns
class#
The OperatorOnUnknowns
class deals with a pair of OperatorOnUnknown
objects related by an AlgebraicOperator
(one of product, inner product, cross product or contracted product):
It is useful to store syntax like opu aop opv occurring in bilinear forms.
class OperatorOnUnknowns
{
protected :
OperatorOnUnknown opu_; //left operator on unknown
OperatorOnUnknown opv_; //right operator on unknown (test function)
AlgebraicOperator aop_; //algebraic operation (*,|,%,^)
}
The class provides basic constructor and accessors:
OperatorOnUnknowns(){};
OperatorOnUnknowns(const OperatorOnUnknown& operu, const OperatorOnUnknown& operv, AlgebraicOperator aop);
const OperatorOnUnknown& opu() const;
OperatorOnUnknown& opu();
OperatorOnUnknown& opv();
AlgebraicOperator algop();
ValueType valueType() const;
a function checking the consistancy of expression:
bool checkConsistancy();
The checkConsistancy()
function checks that the given OperatorOnUnknown
objects
are consistent (in structure not in dimension) with the given algebraic operation. If not an
error is handled.
Some print facilities are provided:
void print(std::ostream&) const;
friend std::ostream& operator<<(std::ostream&, const OperatorOnUnknowns&);
Besides, some extern functions acts like constructors:
OperatorOnUnknowns operator*(OperatorOnUnknown&,OperatorOnUnknown&); //opu * opv
OperatorOnUnknowns operator|(OperatorOnUnknown&,OperatorOnUnknown&); //opu | opv
OperatorOnUnknowns operator^(OperatorOnUnknown&,OperatorOnUnknown&); //opu ^ opv
OperatorOnUnknowns operator%(OperatorOnUnknown&,OperatorOnUnknown&); //opu % opv
OperatorOnUnknowns operator*(OperatorOnUnknown&,Unknown&); //opu * v
OperatorOnUnknowns operator|(OperatorOnUnknown&,Unknown&); //opu | v
OperatorOnUnknowns operator^(OperatorOnUnknown&,Unknown&); //opu ^ v
OperatorOnUnknowns operator%(OperatorOnUnknown&,Unknown&); //opu % v
OperatorOnUnknowns operator*(Unknown&,OperatorOnUnknown&); //u * opv
OperatorOnUnknowns operator|(Unknown&,OperatorOnUnknown&); //u | opv
OperatorOnUnknowns operator^(Unknown&,OperatorOnUnknown&); //u ^ opv
OperatorOnUnknowns operator%(Unknown&,OperatorOnUnknown&); //u % opv
OperatorOnUnknowns operator*(Unknown&,Unknown&); //u * v
OperatorOnUnknowns operator|(Unknown&,Unknown&); //u | v
OperatorOnUnknowns operator^(Unknown&,Unknown&); //u ^ v
OperatorOnUnknowns operator%(Unknown&,Unknown&); //u % v
See also
library=operator,
header=OperatorOnUnknowns.hpp,
implementation=OperatorOnUnknowns.cpp,
test=test_operator.cpp,
header dep= OperatorOnUnknown.hpp, config.h, utils.h
The LcOperatorOnUnknown
class#
The LcOperatorOnUnknown
class deals with linear combination of OperatorOnUnknown
objects :
where \(c_i\) is a complex coefficient, \(op(u_i)\) an operator on unknown \(u_i\) (OperatorOnUnknown
object) and possibly a geometrical domain \(dom_i\) (:cpp:class`Domain` object).
LcOperatorOnUnknown
objects are useful to describe essential condition (see Essential conditions library):
LcOperatorOnUnknown
objects are also useful to create LcOperatorOnUnknowns
in a condensed way:
The LcOperatorOnUnknown
class inherits from std::vector
class :
typedef std::pair<OperatorOnUnknown*, Complex> OpuValPair;
class LcOperatorOnUnknown : public std::vector<OpuValPair>
{
public :
std::vector<Domain*> domains_;
}
The class provides some basic constructors and related stuff (copy, clear)
LcOperatorOnUnknown() {};
LcOperatorOnUnknown(const OperatorOnUnknown&, const Real& = 1.);
LcOperatorOnUnknown(const OperatorOnUnknown&, const Complex&);
LcOperatorOnUnknown(const OperatorOnUnknown&, Domain&, const Real& = 1.);
LcOperatorOnUnknown(const OperatorOnUnknown&, Domain&, const Complex&);
LcOperatorOnUnknown(const Unknown&, const Real& = 1.);
LcOperatorOnUnknown(const Unknown&, const Complex&);
LcOperatorOnUnknown(const Unknown&, Domain&, const Real& = 1.);
LcOperatorOnUnknown(const Unknown&, Domain&, const Complex&);
LcOperatorOnUnknown(const LcOperatorOnUnknown&);
~LcOperatorOnUnknown();
LcOperatorOnUnknown& operator =(const LcOperatorOnUnknown&);
void clear();
void copy(const LcOperatorOnUnknown& lc);
To insert new item in the list, there are insertion member functions and overloaded operators:
void insert(const OperatorOnUnknown&, GeomDomain* =0); // insert op(u)
void insert(const Real&, const OperatorOnUnknown&, GeomDomain* =0); // insert a*op(u)
void insert(const Complex&, const OperatorOnUnknown&, GeomDomain* =0); // insert a*op(u)
void insert(const Unknown&, GeomDomain* =0); // insert u on D
void insert(const Real&, const Unknown&, GeomDomain* =0); // insert a*u on D
void insert(const Complex&, const Unknown&, GeomDomain* =0); // insert a*u on D
LcOperatorOnUnknown& operator+=(const OperatorOnUnknown&); // lcop += opu
LcOperatorOnUnknown& operator+=(const Unknown&); // lcop += u
LcOperatorOnUnknown& operator+=(const LcOperatorOnUnknown&); // lcop += lcop
LcOperatorOnUnknown& operator-=(const OperatorOnUnknown&); // lcop -= opu
LcOperatorOnUnknown& operator-=(const Unknown&); // lcop -= u
LcOperatorOnUnknown& operator-=(const LcOperatorOnUnknown&); // lcop -= lcop
LcOperatorOnUnknown& operator*=(const Real&); // lcop *= r
LcOperatorOnUnknown& operator*=(const Complex&); // lcop *= c
LcOperatorOnUnknown& operator/=(const Real&); // lcop /= r
LcOperatorOnUnknown& operator/=(const Complex&); // lcop /= c
Extern operators may also be used :
LcOperatorOnUnknown operator+(const LcOperatorOnUnknown&);
LcOperatorOnUnknown operator-(const LcOperatorOnUnknown&);
LcOperatorOnUnknown operator+(const LcOperatorOnUnknown&, const OperatorOnUnknown&);
LcOperatorOnUnknown operator-(const LcOperatorOnUnknown&, const OperatorOnUnknown&);
LcOperatorOnUnknown operator+(const OperatorOnUnknown&, const LcOperatorOnUnknown&);
LcOperatorOnUnknown operator-(const OperatorOnUnknown&, const LcOperatorOnUnknown&);
LcOperatorOnUnknown operator+(const LcOperatorOnUnknown&, const Unknown&);
LcOperatorOnUnknown operator-(const LcOperatorOnUnknown&, const Unknown&);
LcOperatorOnUnknown operator+(const Unknown&, const LcOperatorOnUnknown&);
LcOperatorOnUnknown operator-(const Unknown&, const LcOperatorOnUnknown&);
LcOperatorOnUnknown operator+(const LcOperatorOnUnknown&, const LcOperatorOnUnknown&);
LcOperatorOnUnknown operator-(const LcOperatorOnUnknown&, const LcOperatorOnUnknown&);
LcOperatorOnUnknown operator*(const LcOperatorOnUnknown&, const Real&);
LcOperatorOnUnknown operator*(const LcOperatorOnUnknown&, const Complex&);
LcOperatorOnUnknown operator*(const Real&, const LcOperatorOnUnknown&);
LcOperatorOnUnknown operator*(const Complex&, const LcOperatorOnUnknown&);
LcOperatorOnUnknown operator/(const LcOperatorOnUnknown&, const Real&);
LcOperatorOnUnknown operator/(const LcOperatorOnUnknown&, const Complex&);
LcOperatorOnUnknown operator+(const OperatorOnUnknown&, const OperatorOnUnknown&);
LcOperatorOnUnknown operator-(const OperatorOnUnknown&, const OperatorOnUnknown&);
LcOperatorOnUnknown operator+(const OperatorOnUnknown&, const Unknown&);
LcOperatorOnUnknown operator-(const OperatorOnUnknown&, const Unknown&);
LcOperatorOnUnknown operator+(const Unknown&, const OperatorOnUnknown&);
LcOperatorOnUnknown operator-(const Unknown&, const OperatorOnUnknown&);
LcOperatorOnUnknown operator+(const Unknown&, const Unknown&);
LcOperatorOnUnknown operator-(const Unknown&, const Unknown&);
GeomDomain
may be affected using SetDomain
or |
operator :
void setDomain(GeomDomain&);
LcOperatorOnUnknown& operator|(GeomDomain&);
LcOperatorOnUnknown operator|(const Unknown&,GeomDomain&);
LcOperatorOnUnknown operator|(const OperatorOnUnknown&,GeomDomain&);
Note that when setting the domain, all previous domain definitions are overwritten.
It provides the following accessors and property accessors:
bool isSingleUnknown() const;
const Unknown* unknown() const;
std::set<const Unknown*> unknowns() const;
bool withDomains() const;
bool isSingleDomain() const;
Domain* domain() const;
std::set<Domain*> domains() const;
Complex coefficient() const;
std::vector<Complex> coefficients() const;
std::set<DiffOpType> diffOperators() const;
void print(std::ostream&, bool withdomain=true) const;
friend std::ostream& operator<<(std::ostream&, const LcOperatorOnUnknown&);
To create essential condition from LcOperatorOnUnknown
, operator =
is overloaded as following:
EssentialCondition operator=(const Real &);
EssentialCondition operator=(const Complex &);
EssentialCondition operator=(const Function &);
These functions are implemented in EssentialCondition.cpp
!
See also
library=operator,
header=LcOperatorOnUnknowns.hpp,
implementation=LcOperatorOnUnknowns.cpp,
test=test_EssentialCondition.cpp,
header dep= LcOperatorOnUnknown.hpp, config.h, utils.h
The LcOperatorOnUnknowns
class#
The LcOperatorOnUnknowns
class deals with linear combination of OperatorOnUnknowns
objects :
where \(c_i\) is a complex coefficient, \(op(u_i)\) an operator on unknown \(u_i\) ( OperatorOnUnknown
object), \(O\) an algebraic operator and \(op(v_i)\) an operator on test function \(v_i\) ( OperatorOnUnknown
object). LcOperatorOnUnknowns
objects are useful to describe linear and bilinear form (see form library):
The LcOperatorOnUnknowns
class inherits from std::vector
class :
typedef std::pair<OperatorOnUnknowns *, complex_t> OpusValPair;
class LcOperatorOnUnknowns : public std::vector<OpusValPair>
The class provides some basic constructors and related stuff (copy, clear)
LcOperatorOnUnknowns() {}
LcOperatorOnUnknowns(const OperatorOnUnknowns &, const real_t & = 1.);
LcOperatorOnUnknowns(const OperatorOnUnknowns &, const complex_t &);
LcOperatorOnUnknowns(const LcOperatorOnUnknowns &);
~LcOperatorOnUnknowns();
LcOperatorOnUnknowns &operator=(const LcOperatorOnUnknowns &);
void clear();
void copy(const LcOperatorOnUnknowns &lc);
To insert new item in the list, there are insertion member functions and overloaded operators:
void insert(const OperatorOnUnknowns &); // insert opuv
void insert(const real_t &, const OperatorOnUnknowns &); // insert a*opuv
void insert(const complex_t &, const OperatorOnUnknowns &); // insert a*opuv
LcOperatorOnUnknowns &operator+=(const OperatorOnUnknowns &); // lcopuv += opuv
LcOperatorOnUnknowns &operator+=(const LcOperatorOnUnknowns &); // lcopuv += lcopuv
LcOperatorOnUnknowns &operator-=(const OperatorOnUnknowns &); // lcopuv -= opuv
LcOperatorOnUnknowns &operator-=(const LcOperatorOnUnknowns &); // lcopuv -= lcopuv
LcOperatorOnUnknowns &operator*=(const real_t &); // lcopuv *= r
LcOperatorOnUnknowns &operator*=(const complex_t &); // lcopuv *= c
LcOperatorOnUnknowns &operator/=(const real_t &); // lcopuv /= r
LcOperatorOnUnknowns &operator/=(const complex_t &); // lcopuv /= c
Extern operators may also be used :
// OperatoronUnknowns and OperatorOnUnknowns
LcOperatorOnUnknowns operator+(const OperatorOnUnknowns &, const OperatorOnUnknowns &);
LcOperatorOnUnknowns operator-(const OperatorOnUnknowns &, const OperatorOnUnknowns &);
// LcOperatorOnUnknowns and LcOperatorOnUnknowns
LcOperatorOnUnknowns operator+(const LcOperatorOnUnknowns &);
LcOperatorOnUnknowns operator-(const LcOperatorOnUnknowns &);
LcOperatorOnUnknowns operator+(const LcOperatorOnUnknowns &, const LcOperatorOnUnknowns &);
LcOperatorOnUnknowns operator-(const LcOperatorOnUnknowns &, const LcOperatorOnUnknowns &);
// LcOperatorOnUnknowns and OperatorOnUnknowns
LcOperatorOnUnknowns operator+(const LcOperatorOnUnknowns &, const OperatorOnUnknowns &);
LcOperatorOnUnknowns operator-(const LcOperatorOnUnknowns &, const OperatorOnUnknowns &);
LcOperatorOnUnknowns operator+(const OperatorOnUnknowns &, const LcOperatorOnUnknowns &);
LcOperatorOnUnknowns operator-(const OperatorOnUnknowns &, const LcOperatorOnUnknowns &);
// LcOperatorOnUnknowns and scalar
LcOperatorOnUnknowns operator*(const LcOperatorOnUnknowns &, const real_t &);
LcOperatorOnUnknowns operator*(const LcOperatorOnUnknowns &, const complex_t &);
LcOperatorOnUnknowns operator*(const real_t &, const LcOperatorOnUnknowns &);
LcOperatorOnUnknowns operator*(const complex_t &, const LcOperatorOnUnknowns &);
LcOperatorOnUnknowns operator/(const LcOperatorOnUnknowns &, const real_t &);
LcOperatorOnUnknowns operator/(const LcOperatorOnUnknowns &, const complex_t &);
// LcOperatorOnUnknown and OperatorOnUnkown
LcOperatorOnUnknowns operator*(const LcOperatorOnUnknown &, const OperatorOnUnknown &);
LcOperatorOnUnknowns operator*(const OperatorOnUnknown &, const LcOperatorOnUnknown &);
LcOperatorOnUnknowns operator%(const LcOperatorOnUnknown &, const OperatorOnUnknown &);
LcOperatorOnUnknowns operator%(const OperatorOnUnknown &, const LcOperatorOnUnknown &);
LcOperatorOnUnknowns operator|(const LcOperatorOnUnknown &, const OperatorOnUnknown &);
LcOperatorOnUnknowns operator|(const OperatorOnUnknown &, const LcOperatorOnUnknown &);
// LcOperatorOnUnknown and Unkown
LcOperatorOnUnknowns operator*(const LcOperatorOnUnknown &, const Unknown &);
LcOperatorOnUnknowns operator*(const Unknown &, const LcOperatorOnUnknown &);
LcOperatorOnUnknowns operator%(const LcOperatorOnUnknown &, const Unknown &);
LcOperatorOnUnknowns operator%(const Unknown &, const LcOperatorOnUnknown &);
LcOperatorOnUnknowns operator|(const LcOperatorOnUnknown &, const Unknown &);
LcOperatorOnUnknowns operator|(const Unknown &, const LcOperatorOnUnknown &);
// LcOperatorOnUnknown and LcOperatorOnUnkown
LcOperatorOnUnknowns operator*(const LcOperatorOnUnknown &, const LcOperatorOnUnknown &);
LcOperatorOnUnknowns operator%(const LcOperatorOnUnknown &, const LcOperatorOnUnknown &);
LcOperatorOnUnknowns operator|(const LcOperatorOnUnknown &, const LcOperatorOnUnknown &);
It provides the following accessors and property accessors:
bool isSingleUVPair() const; // true if all terms involve the same unknown
const OperatorOnUnknown *opu(number_t i = 1) const; // return ith left OperatorOnUnknown involved in LcOperator's
const OperatorOnUnknown *opv(number_t i = 1) const; // return ith right OperatorOnUnknown involved in LcOperator's
const Unknown *unknownu(number_t i = 1) const; // return ith left Unknown involved in LcOperator
const Unknown *unknownv(number_t i = 1) const; // return ith right
Unknown involved in LcOperator
complex_t coefficient(number_t i = 1) const; // return ith coefficient
std::vector<complex_t> coefficients() const; // return vector of coefficients involved in combination
void print(std::ostream &) const;
friend std::ostream &operator<<(std::ostream &, const LcOperatorOnUnknowns &);
See also
library=operator,
header=LcOperatorOnUnknowns.hpp,
implementation=OperatorOnUnknowns.cpp,
test=unit_LcOperatorOnUnknowns.cpp,
header dep= LcOperatorOnUnknown.hpp, OperatorOnUnknown.hpp, config.h, utils.h
The OperatorOnKernel
class#
Kernel objects describes function of two points, say \(K(x,y)\). The OperatorOnKernel
class is intended to store the differential operators acting on Kernel, one for \(x\) derivatives and one for \(y\) derivatives :
class OperatorOnKernel
{
protected :
const Kernel* ker_p; //Kernel involved in operator
DifferentialOperator* xdifOp_p; //x differential operator involved in operator
DifferentialOperator* ydifOp_p; //v differential operator involved in operator
ValueType type_; //type of returned value ( _real, _complex)
StrucType struct_; //structure of returned value (_scalar, _vector, _matrix)
}
A null pointer ker_p means the kernel function \(K(x,y)=1\) and by default xdifOp_p and ydifOp_p point to identity differential operator.
OperatorOnKernel
object are constructed either by constructor members or by external functions:
OperatorOnKernel();
OperatorOnKernel(const Kernel*, DiffOpType = _id, DiffOpType = _id, ValueType vt=_real, StrucType st=_scalar);
OperatorOnKernel(const Kernel&, DiffOpType = _id, DiffOpType = _id);
OperatorOnKernel(const OperatorOnKernel&);
OperatorOnKernel& operator=(const OperatorOnKernel&);
OperatorOnKernel& id(const Kernel&); //id(k)
OperatorOnKernel& grad_x(const Kernel&); //grad_x(k)
OperatorOnKernel& grad_y(const Kernel&); //grad_y(k)
...
OperatorOnKernel& id(OperatorOnKernel&); //id(opk)
OperatorOnKernel& grad_x(OperatorOnKernel&); //grad_x(opk)
OperatorOnKernel& grad_y(OperatorOnKernel&); //grad_y(opk)
...
OperatorOnKernel& operator*(UnitaryVector, const Kernel&); //n*ker
OperatorOnKernel& operator*(const Kernel&, UnitaryVector); //ker*n
OperatorOnKernel& operator|(UnitaryVector, const Kernel&); //n|ker
OperatorOnKernel& operator|(const Kernel&, UnitaryVector); //ker|n
OperatorOnKernel& operator^(UnitaryVector, const Kernel&); //n^ker
OperatorOnKernel& operator*(UnitaryVector, OperatorOnKernel&); //n*opker
OperatorOnKernel& operator*(OperatorOnKernel&, UnitaryVector); //opker*n
OperatorOnKernel& operator|(UnitaryVector, OperatorOnKernel&); //n|opker
OperatorOnKernel& operator|(OperatorOnKernel&, UnitaryVector); //opker|n
OperatorOnKernel& operator^(UnitaryVector, OperatorOnKernel&); //n^opker
Note that operators return reference to object dynamically allocated.
The class provides some member accessors and property accessors
const Kernel* kernel() const;
DiffOpType xdifOpType() const;
DiffOpType ydifOpType() const;
DifferentialOperator*& xdifOp_();
DifferentialOperator& xdifOp() const;
DifferentialOperator*& ydifOp_();
DifferentialOperator& ydifOp() const;
ValueType& valueType();
ValueType valueType()const;
StrucType& strucType();
StrucType strucType() const;
Dimen xdiffOrder() const;
Dimen ydiffOrder() const;
bool voidKernel() const;
and print facilities
void print(std::ostream&) const;
friend std::ostream& operator<<(std::ostream& os, const OperatorOnKernel& opk);
Finally the class interfaces the computation of OperatorOnKernel
at a couple of points or a list of couples of points using template functions:
template <typename T>
T& eval(const Point&,const Point&, T&) const;
template <typename T>
std::vector<T>& eval(const std::vector<Point>&,const std::vector<Point>&, std::vector<T>&) const;
See also
library=operator,
header=OperatorOnUnKernel.hpp,
implementation=OperatorOnKernel.cpp,
test=test_operator.cpp,
header dep= DifferentialOperator.hpp, Operand.hpp, config.h, utils.h
The KernelOperatorOnUnknowns
class#
The KernelOperatorOnUnknowns
class deals with expressions involving two operators on unknown linked with an OperatorOnKernel
class, that is
Such expression appears in integral equation or integral representation, for instance to deal with:
class KernelOperatorOnUnknowns
{
protected :
OperatorOnUnknown opu_;
OperatorOnUnknown opv_;
AlgebraicOperator aopu_;
AlgebraicOperator aopv_;
OperatorOnKernel opker_;
}
The class provides one basic constructor and a lot of extern functions building KernelOperatorOnUnknowns
object:
KernelOperatorOnUnknowns(const OperatorOnUnknown&, AlgebraicOperator, const OperatorOnKernel&, AlgebraicOperator, const OperatorOnUnknown&);
KernelOperatorOnUnknowns operator*(const OperatorOnUnknown&, const OperatorOnKernel&); //opu * opker
KernelOperatorOnUnknowns operator*(const OperatorOnKernel&, const OperatorOnUnknown&); //opker * opv
KernelOperatorOnUnknowns operator*(const OperatorOnUnknown&, const Kernel&); //opu * ker
KernelOperatorOnUnknowns operator*(const Kernel&, const OperatorOnUnknown&); //ker * opv
KernelOperatorOnUnknowns operator*(const Unknown&, const Kernel&); //u * ker
KernelOperatorOnUnknowns operator*(const Kernel&, const Unknown&); //ker * v
KernelOperatorOnUnknowns operator*(const OperatorOnUnknown&, const KernelOperatorOnUnknowns&); //opu * opker
KernelOperatorOnUnknowns operator*(const KernelOperatorOnUnknowns&, const OperatorOnUnknown&); //opker * opv
KernelOperatorOnUnknowns operator*(const Unknown&, const KernelOperatorOnUnknowns&); //u * opker
KernelOperatorOnUnknowns operator*(const KernelOperatorOnUnknowns&, const Unknown&); //opker * v
//same for operation inner product |, cross product ^ and contracted product %
template <typename T>
KernelOperatorOnUnknowns operator*(const Unknown& un, T(fun)(const Point&, const Point&, Parameters&));//u * fun
template <typename T>
KernelOperatorOnUnknowns operator*(T(fun)(const Point&, const Point&, Parameters&), const Unknown& un);//fun * u
template <typename T>
KernelOperatorOnUnknowns operator*(T(fun)(const Vector<Point>&,const Vector<Point>&, Parameters&), const Unknown& un); //fun * u
template <typename T>
KernelOperatorOnUnknowns operator*(const Unknown& un, T(fun)(const Vector<Point>&,const Vector<Point>&, Parameters&)) //! u * func
//same for operation inner product |, cross product ^ and contracted product
It provides also accessors and print facilities
const OperatorOnUnknown& opu() const;
const OperatorOnUnknown& opv() const;
OperatorOnUnknown& opu();
OperatorOnUnknown& opv();
AlgebraicOperator algopu() const;
AlgebraicOperator algopv() const;
AlgebraicOperator& algopu();
AlgebraicOperator& algopv();
const OperatorOnKernel& opker() const;
bool isKernelType() const;
ValueType valueType() const;
void print(std::ostream&) const;
friend std::ostream& operator<<(std::ostream&, const KernelOperatorOnUnknowns&);
See also
library=operator,
header=KernelOperatorOnUnknows.hpp,
implementation=KernelOperatorOnUnknows.cpp,
test=test_operator.cpp,
header dep= OperatorOnUnknown.hpp, OperatorOnKernel.hpp, config.h, utils.h
The TensorKernel
class#
The TensorKernel
class inherited from Kernel
handles some particular kernels, say tensor kernels:
This kernel is involved in DirichletToNeumann map.
Hint
In case of complex basis functions, the TensorKernel
is often involved in integral of the following form:
where appears a conjugate operation on \(\phi_n\) functions.
By default, computation functions do not apply the conjugate operation. So if you have to applied to, there is a flag to enforce the conjugate operation.
Because, Kernel
class uses SpectralBasis
class to handles functions \(\phi_n\) and \(\psi_n\), it can not be located in utils library. It is the reason why it is located in term library.
class TensorKernel : public Kernel
{
protected :
const SpectralBasis* phi_p, *psi_p; //pointers to SpectralBasis object
VectorEntry* matrix_p; //matrix stored as a vector
public :
bool isDiag; //!< true if matrix is diagonal matrix
Function xmap, ymap; //!< maps applied to point x and y
bool isConjugate; //!< conjugate phi_p in IESP computation (default=false)
SpectralBasis
class manages either a family of explicit functions given by a Function
object or a family of interpolated functions given as a vector of TermVector
(see SpectralBasisFun
class and SpectralBasisInt
defined in space library). Stored as a MatrixEntry
object, the matrix \(\mathbb{A}\) may be of real or complex type.
The TensorKernel
class provides some explicit constructors from SpectralBasis
and vector<T>
(matrix \(\mathbb{A}\)) and some implicit constructors from Unknown
associated to a spectral space equipped with a spectral basis, and vector<T>
.
TensorKernel();
template<typename T>
TensorKernel(const SpectralBasis&, const std::vector<T>&, bool =false);
template<typename T>
TensorKernel(const SpectralBasis&, const std::vector<T>&, const SpectralBasis&);
template<typename T>
TensorKernel(const Unknown&, const std::vector<T>&, bool =false);
template<typename T>
TensorKernel(const Unknown&, const std::vector<T>&, const Unknown&);
template<typename T>
TensorKernel(const std::vector<TermVector>&, const std::vector<T>&, bool =false);
template<typename T>
TensorKernel(const std::vector<TermVector>&, const std::vector<T>&, const std::vector<TermVector>&);
~TensorKernel();
Besides it provides some accessors and properties
const VectorEntry& vectorEntry() const {return *matrix_p;}
const SpectralBasis* phip() const {return phi_p;}
const SpectralBasis* psip() const {return psi_p;}
const SpectralBasis& phi() const {return *phi_p;}
const SpectralBasis& psi() const {return *psi_p;}
const TensorKernel* tensorKernel() const;
TensorKernel* tensorKernel();
Dimen dimOfPhi() const;
Dimen dimOfPsi() const;
Number nbOfPhi() const;
Number nbOfPsi() const;
bool phiIsAnalytic() const;
bool psiIsAnalytic() const;
virtual KernelType type() const;
virtual bool isSymbolic() const;
virtual ValueType valueType() const;
virtual StrucType structType() const;
bool sameBasis() const;
It proposes two template functions that compute the product of \(\mathbb{A}_m\) or \(\mathbb{A}_{mn}\) by something of type T, expecting a a result of same type!
template<typename T>
T kernelProduct(Number, const T&) const;
template<typename T>
T kernelProduct(Number, Number, const T&) const;
See also
library=operator,
header=TensorKernel.hpp,
implementation=TensorKernel.cpp,
test=test_EssentialCondition.cpp,
header dep= space.h, OperatorOnKernel.hpp, config.h, utils.h