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)\)

grad(u)

\(\nabla(u)\cdot\nabla(v)\)

grad(u)|grad(v)

\((A*\nabla(u))\cdot\nabla(v)\)

(A*grad(u))|grad(v)

\((F(x)*\nabla(u))\cdot\nabla(\overline{v})\)

(F*grad(u))|grad(conj(v))

\(u(x)*K(x, y)*v(y)\)

u*K*v

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 of OperatorOnUnknown 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:

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:

Table 4 available operators on unknowns/test functions#

mathematical

built-in functions

unknown structure

identity

id(u) or u

scalar or vector

\(\partial_t\)

d0(u) or dt(u)

scalar or vector

\(\partial_x\)

d1(u) or dx(u)

scalar or vector

\(\partial_y\)

d2(u) or dy(u)

scalar or vector

\(\partial_z\)

d3(u) or dz(u)

scalar or vector

\(\nabla\)

grad(u) or nabla(u)

scalar or vector

\(\mathrm{div}\)

div(u)

vector

\(\mathrm{curl}\)

curl(u) or rot(u)

vector

\(\nabla_\tau\) (surfacic)

gradS(u) or nablaS(u)

scalar or vector

\(\mathrm{div}_\tau\) (surfacic)

divS(u)

vector

\(\mathrm{curl}_\tau\) (surfacic)

curlS(u) or rotS(u)

vector

\(\nabla_{abc}=(a\partial_x,b\partial_y,c\partial_z)\)

gradG(u,a,b,c) or nablaG(u,a,b,c)

scalar or vector

\(\nabla_{abc}.\)

divG(u,a,b,c)

vector

\(\nabla_{abc}\times\)

curlG(u,a,b,c) or rotG(u,a,b,c)

vector

\(\varepsilon\)

epsilon(u)

vector

\(\varepsilon_{iabc}\)

epsilonG(u,i,a,b,c)

vector

\(\varepsilon_{R}\)

epsilonR(u) = (\(\varepsilon_{11}, \varepsilon_{22},\varepsilon_{33}, \varepsilon_{32}, \varepsilon_{31}, \varepsilon_{21}\))

vector

\(\mathrm{voigtToM}\)

voigtToM(u) = [u1 u6 u5; u6 u2 u4; u5 u4 u3]

vector

\(n*\)

nx(u) or _n*u

scalar

\(n \cdot\)

ndot(u) or _n|u

vector

\(n\times\)

ncross(u) or _n^u

vector

\(n\times n\times\)

ncrossncross(u) or _n^_n^u

vector

\(n \cdot \nabla\)

ndotgrad(u) or _n|grad(u)

scalar

\(n \times \nabla\)

ncrossgrad(u) or _n^grad(u)

scalar

\(n\;\mathrm{div}\)

ndiv(u) or _n*div(u)

vector

\(n\times\mathrm{curl}\)

ncrosscurl(u) or _n^curl(u) or ncrossrot(u) or _n^rot(u)

vector

\([\ ]\) (jump across)

jump(u)

scalar or vector

\(\{\ \}\) (mean across)

mean(u)

scalar or vector

The complete list of operators on kernels is the following:

Table 5 available operators on Kernels#

mathematical

built-in functions

unknown structure

identity

id(k) or k

scalar or vector

\(\nabla_x\)

grad_x(k) or nabla_x(k)

scalar or vector

\(\nabla_y\)

grad_y(k) or nabla_y(k)

scalar or vector

\(\mathrm{div}_x\)

div_x(k)

vector

\(\mathrm{div}_y\)

div_y(k)

vector

\(\mathrm{curl}_x\)

curl_x(k) or rot_x(k)

vector

\(\mathrm{curl}_y\)

curl_y(k) or rot_y(k)

vector

\(n_x *\)

ntimes_x(k) or _nx*k

scalar

\(n_y *\)

ntimes_y(k) or _ny*k

scalar

\(n_x \cdot\)

ndot_x(k) or _nx|k

vector

\(n_y \cdot\)

ndot_y(k) or _ny|k

vector

\(n_x \times\)

ncross_x(k) or _nx^k

vector

\(n_y \times\)

ncross_y(k) or _ny^k

vector

\(n_x \times (n_x\times)\)

ncrossncross_x(k) or _nx^(_nx^k)

vector

\(n_y \times (n_y\times)\)

ncrossncross_y(k) or _ny^(_ny^k)

vector

\(n_x \cdot \nabla_x\)

ndotgrad_x(k) or _nx|grad_x(k)

scalar

\(n_y \cdot \nabla_y\)

ndotgrad_y(k) or _ny|grad_y(k)

scalar

\(n_x \mathrm{div}_x\)

ndiv_x(k) or _nx*div_x(k)

vector

\(n_y \mathrm{div}_y\)

ndiv_y(k) or _ny*div_y(k)

vector

\(n_x \times \mathrm{curl}_x\)

ncrosscurl_x(u) or _nx^curl_x(k)

vector

\(n_y \times \mathrm{curl}_y\)

ncrosscurl_y(u) or _ny^curl_y(k)

vector

\(n_x \cdot n_y *\)

nxdotny_times(k) or (_nx|_ny)*k

scalar or vector

\((n_x \times n_y) \cdot\)

nxcrossny_dot(k) or (_nx^_ny)|k

vector

\((n_y \times n_x) \cdot\)

nycrossnx_dot(k) or (_ny^_nx)|k

vector

\((n_x \times n_y) \times\)

nxcrossny_cross(k) or (_nx^_ny)^k

vector

\((n_y \times n_x) \times\)

nycrossnx_cross(k) or (_ny^_nx)^k

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 the OperatorOnUnknown 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:

\[tr(data)\; op\; dif( tr(u) )\; op\; tr(data)\]

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):

\[adj(f)\; *\; grad (conj( u[2]) )\; |\; conj ( g )\]

which mathematically reads:

\[f^*\,\nabla \overline{u}_2\,.\,\overline{g}\]

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 :

\[\sum_{i=1,n} c_i\ op(u_i) | dom_i\]

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):

\[\sum_{i=1,n} c_i\ op(u_i) | dom_i = g.\]

LcOperatorOnUnknown objects are also useful to create LcOperatorOnUnknowns in a condensed way:

\[\left( \sum_{i=1,n} c^u_i\ op(u_i) \right)\ O\ \left( \sum_{j=1,n} c^v_j\ op(u_j) \right) = \sum_{i,j=1,n} c^u_i c^v_jop(u_i)\ op(u_i)\ O\ op(v_j).\]

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 :

\[\sum_{i=1,n} c_i\ op(u_i)\ O\ op(v_i)\]

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):

\[\int_\Omega \sum_{i=1,n} c_i\ op(u_i)\ O\ op(v_i).\]

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

\[op_u\;\; aop_l \;\; op_k \;\; aop_r \;\; op_v\]

Such expression appears in integral equation or integral representation, for instance to deal with:

\[\int_\Gamma \int_\Gamma u(x)*G(x,y)*v(y)\, dx\,dy.\]
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:

\[K(x,y)= \sum_{m,\, n } \phi_n(y) \mathbb{A}_{mn} \psi_m(x).\]

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:

\[\sum _{mn} \mathbb{A}_{mn}\int_\Sigma w_j(y)*\overline{\phi}_n(y)\int_\Gamma \tau_i(x)*\psi_m(x)\]

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