1%%%%%%%%%%%%%%%%%%% 2% XLiFE++ is an extended library of finite elements written in C++ 3% Copyright (C) 2014 Lunéville, Eric; Kielbasiewicz, Nicolas; Lafranche, Yvon; Nguyen, Manh-Ha; Chambeyron, Colin 4% 5% This program is free software: you can redistribute it and/or modify 6% it under the terms of the GNU General Public License as published by 7% the Free Software Foundation, either version 3 of the License, or 8% (at your option) any later version. 9% This program is distributed in the hope that it will be useful, 10% but WITHOUT ANY WARRANTY; without even the implied warranty of 11% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12% GNU General Public License for more details. 13% You should have received a copy of the GNU General Public License 14% along with this program. If not, see <http://www.gnu.org/licenses/>. 15%%%%%%%%%%%%%%%%%%% 16 17To take into account linear essential conditions (conditions acting on unknown or test function spaces), \xlifepp proposes a general approach based on an abstract algebraic representation of essential conditions, say 18$$\displaystyle \mathbb{C}U=G$$ 19where $U$ represents the vector of components of a function $u$ in space ${\cal U}=\left\{\sum_{i=1,n}U_i\,w_i\right\}$, $(w_i)_{i=1,n}$ the basis of discrete space, $\mathbb{C}$ a $p\times n$ matrix and $G$ a $p$ vector. In other words, we consider the discrete constrained space : 20\begin{equation} \label{cons_Uspace} 21\displaystyle \widetilde{\cal U}=\left\{\sum_{i=1,n}U_i\,w_i,\ \mathbb{C}U=G\right\}. 22\end{equation} 23Such representation may be also used for constraints on test function : 24\begin{equation} \label{cons_Vspace} 25\displaystyle \widetilde{\cal V}=\left\{\sum_{i=1,m}V_i\tau_i,\ \mathbb{D}V=0\right\}. 26\end{equation} 27Both may exist in the same time and may be different. Nevertheless, constraints on test functions are always homogeneous ones! In usual cases, the test function constraints are the linear part of unknown constraints ($\mathbb{C}=\mathbb{D}$). 28 29\section{A general process} 30 31The first step consists in writing essential conditions given in a symbolic form (see documentation of {\class EssentialConditions} class) as a constraints system, details being exposed in documentation of {\class Constraints} class). As constraints may be redundant, the constraints system has to be reduced to a minimal system, eliminating redundant conditions or identifying conflicts in constraints. This is achieved using QR factorization. Once the constraints systems are reduced, the main work consists to use them in matrix problems we deal with. As we will see, it is possible to consider different techniques : \emph{real reduction} (some rows and columns of system are deleted), \emph{pseudo reduction} (some rows and columns of system are replaced), \emph{penalization} (some rows and columns of system are penalized) and \emph{duality} (constraints system and new dual unknowns are introduced in the problem). 32 33\subsection*{Reinterpretation of a linear system with constraints} 34 35We consider a general discrete variational problem : 36\begin{equation} \label{fv1} 37\displaystyle \text{find } u\in \widetilde{\cal U} \text{ such that } a(u,v)=l(v)\ \ \forall v\in \widetilde{\cal V}, 38\end{equation} 39where the spaces $\widetilde{\cal U}$ and $\widetilde{\cal V}$ are given by (\ref{cons_Uspace}-\ref{cons_Vspace}), $a(.,.)$ a bilinear form on ${\cal U}\times {\cal V}$ and $l(.)$ a linear form on ${\cal V}$. 40 41We assume in the following, that the constraints systems $\mathbb{C}U=G$ and $\mathbb{D}V=0$ are reduced, so the $m\times n$ matrix $\mathbb{C}$ and the $p\times q$ matrix $\mathbb{D}$ have the following representation : 42\begin{equation} \label{fv2} 43\displaystyle \mathbb{C} = [\mathbb{E}\ \mathbb{R}] \text{ and } \mathbb{D} = [\mathbb{F}\ \mathbb{S}] 44\end{equation} 45where $\mathbb{E}$ is a $m\times m$ upper triangular matrix (invertible), $\mathbb{R}$ a $m\times n-m$ matrix (may be null, $n\geq m$), $\mathbb{F}$ a $p\times p$ upper triangular matrix (invertible) and $\mathbb{S}$ a $p\times q-p$ matrix (may be null, $q\geq p$). The column indices ${\cal E}$ (resp.${\cal F}$) of $\mathbb{E}$ (resp. $\mathbb{F}$) correspond to the eliminated unknowns (resp. test functions) and the column indices ${\cal R}$ (resp. ${\cal S}$) of $\mathbb{R}$ (resp. $\mathbb{S}$) correspond to reduced unknowns (resp. test functions). 46 47Introducing $\mathbb{X}=\mathbb{E}^{-1}\,\mathbb{R}$ and $\mathbb{Y}=\mathbb{F}^{-1}\,\mathbb{S}$, the constraints read : 48\begin{equation} \label{cons_Ured} 49\displaystyle U_{\cal E} + \mathbb{X}\,U_{\cal R} = \mathbb{E}^{-1}G \text{ and } V_{\cal F} + \mathbb{Y}\,V_{\cal S} = 0 50\end{equation} 51where $U_{\cal E}$ (resp. $U_{\cal R}$) denotes the unknown components restricted to indices ${\cal E}$ (resp. ${\cal R}$) and $V_{\cal F}$ (resp. $V_{\cal S}$) denotes the test function components restricted to indices ${\cal F}$ (resp. ${\cal S}$). 52 53The space $\widetilde{\cal U}$ may be reinterpreted by eliminating the components $U_{\cal E}$ : 54$$ 55\begin{array}{ll} 56\displaystyle \sum_{i=1,n}U_i\,w_i & \displaystyle=\sum_{i\in \cal E}U_i\,w_i+\sum_{i\notin {\cal E}}U_i\,w_i\\ 57&\displaystyle =-\sum_{i\in \cal E}\sum_{j\in {\cal R}}\mathbb{X}_{ij}U_j\,w_i+\sum_{j\notin {\cal E}}U_j\,w_j +\sum_{i\in \cal E}(\mathbb{E}^{-1}G)_iw_i\\ 58&\displaystyle =\sum_{j\notin {\cal E}}u_j\left(w_j-\sum_{i\in \cal E}\mathbb{X}_{ij}w_i\right)+\sum_{i\in \cal E}(\mathbb{E}^{-1}G)_iw_i 59\ \ (\text{setting } \mathbb{X}_{ij}=0\ \forall i,\ \forall j\notin \cal E). \\ 60\end{array} 61$$ 62Considering the functions 63\begin{equation} \label{fun_cu} 64\widetilde{w}_j=w_j-\sum_{i\in \cal E}\mathbb{X}_{ij}w_i\ \ j\notin \cal E, 65\end{equation} 66the vector space $\widetilde{\cal U}_0$ associated to $\widetilde{\cal U}$ is generated by the functions $\widetilde{w}_j$ : 67$$\displaystyle \widetilde{\cal U}_0=\left\{\sum_{i\notin \cal E}U_i\widetilde{w}_i\right\}.$$ 68In a same way, the vector space $\widetilde{\cal V}$ is generated by the functions : 69\begin{equation} \label{fun_cv} 70\widetilde{\tau}_j=\tau_j-\sum_{i\in \cal F}\mathbb{Y}_{ij}w_i\ \ j\notin \cal F, 71\end{equation} 72and 73$$\displaystyle \widetilde{\cal V}=\left\{\sum_{i\notin \cal F}U_i\widetilde{\tau}_i\right\}.$$ 74Setting $g=\sum_{i\in \cal E}(\mathbb{E}^{-1}G)_iw_i$, the problem (\ref{fv1}) is equivalent to 75\begin{equation} \label{fv0} 76\displaystyle \text{find } \widetilde{u}\in \widetilde{\cal U}_0 \text{ such that } a(\widetilde{u},\overline{\widetilde{v}})= 77l(\overline{\widetilde{v}})-a(g,\overline{\widetilde{v}})\ \ \forall v\in \widetilde{\cal V} 78\end{equation} 79equivalent to 80\begin{equation} \label{sys0} 81\displaystyle \text{find } \widetilde{u}=\sum_{j\notin \cal E}\widetilde{U}_j\widetilde{w}_j \text{ such that } 82\sum_{j\notin \cal E}\widetilde{U}_j a(\widetilde{w}_j,\overline{\widetilde{\tau}}_i)=l(\overline{\widetilde{\tau}}_i)-a(g,\overline{\widetilde{\tau}}_i)\ \ \forall i \notin \cal F. 83\end{equation} 84 85The system (\ref{sys0}) may be explicited by using (assuming $\tau_i$ is a real function) : 86\begin{equation} \label{mat_el} 87a(\widetilde{w}_j,\overline{\widetilde{\tau}}_i)=a(w_j,\tau_i) 88-\sum_{k\in {\cal E}}\mathbb{X}_{kj}a(w_k,\tau_i) 89-\sum_{k\in {\cal F}}\overline{\mathbb{Y}}_{ki}a(w_j,\tau_k) 90+\sum_{k\in {\cal E}}\sum_{l\in {\cal F}}\mathbb{X}_{kj}\overline{\mathbb{Y}}_{li}a(w_k,\tau_l) 91\end{equation} 92and 93\begin{equation} \label{rhs_el} 94l(\overline{\widetilde{\tau}}_i)=l(\tau_i)-\sum_{k\in {\cal F}}\overline{\mathbb{Y}}_{ki}l(\tau_k). 95\end{equation} 96 97Finally, from the knowledge of all $a(w_j,\tau_i)$ and $l(\tau_i)$ corresponding to the computation without essential conditions, it is possible to construct the system (\ref{sys0}). In terms of matrix, the different operations are mainly row or column combinations. \xlifepp implements this general scheme. In a simple case, the Dirichlet problem for instance, the previous expression are trivial because $\mathbb{X}=\mathbb{Y}=0$, $\widetilde{w}_j=w_j,\ \forall j\notin {\cal E}$ and $\tau_j=w_j$. 98 99When condition is not homogeneous ($g\neq 0$), there is a contribution from $g$ and a part of matrix representing $a(.,.)$ (columns with index in $\cal E$). In order to avoid additional reduction process when an other data $g$ is considered, it is possible to keep in memory this part of matrix. 100 101\subsection*{Overview of classes involved} 102To describe essential conditions, \xlifepp uses : 103\begin{itemize} 104\item some classes used to describe (bi)linearform : {\class Unknown DifferentialOperator OperatorOnUnknown} 105\item the class {\class LcOperatorOnUnknown} which handles linear combination of OperatorOnUnknown and allow to associate geometric domains ({\class GeomDomain}). The general syntaxes look like ($\diamond$ represent any algebraic operation consistant with objects involved) : 106$$a_1*op_1(f_1\diamond u_1\diamond g_1)|dom_1 + a_2*op_2(f_2\diamond u_2\diamond g_2)|dom_2 + ...$$ 107$$(a_1*op_1(f_1\diamond u_1\diamond g_1) + a_2*op_2(f_2\diamond u_2\diamond g_2)+ ...)|dom$$ 108This class supports a lot of expressions but just a few ones could be used as essential condition ! This class belongs to the {\lib Operator} library. 109\item To transform a previous expression as an essential condition, it is required to give a right hand side : 110\begin{center} 111LcOperatorOnUnknown = constant or LcOperatorOnUnknown = function 112\end{center} 113it produces an object of {\class EssentialCondition} class. 114\item Concatanating {\class EssentialCondition} objects using the operator \& produces a set of essential conditions managed by {\class EssentialConditions} class. 115\end{itemize} 116 117All these classes are user classes!\\ 118 119{\class Constraints} is the core class implementing most of the algorithms : transformation of symbolic conditions into constraints system, reduction of constraints system, reduction or pseudo-reduction of matrix, right hand side correction. 120 121\section{The {\classtitle EssentialCondition} class} 122 123The {\class EssentialCondition} class handles the symbolic representation of an essential condition in the form $expression(u_1|dom_1,u_2|dom_2,...) = f$ where $expression(...)$ is a {\class LcOperatorOnUnknown} object and $f$ is a {\class Function} object. 124\vspace{.3cm} 125\begin{lstlisting}[]{} 126class EssentialCondition 127{ 128 protected : 129 LcOperatorOnUnknown ecTerms_; // combination of operator on unknown 130 Function *fun_p; // function defining data of EC 131 // (=0 when EC is homogeneous) 132 EcType type_; // type of essential condition 133} 134\end{lstlisting} 135\vspace{.3cm} 136The type of essential condition are listed in the \emph{EcType} enumeration: 137\begin{lstlisting}[]{} 138enum EcType {_undefEcType, //undefined type 139 _DirichletEc, //one unknown, one domain 140 _transmissionEc, //two unknowns, one domain 141 _periodicEc, //one unknown, two domains 142 _crackEc, //two unknowns, two domains 143 _meanEc //intg_D(opu)=f 144 }; 145\end{lstlisting} 146\vspace{.3cm} 147The class proposes basic constructors which do full copy of {\class LcOperatorOnUnknown} and {\class Function} objects: 148\begin{lstlisting}[]{} 149EssentialCondition() 150EssentialCondition(const LcOperatorOnUnknown&); 151EssentialCondition(const LcOperatorOnUnknown&, const Function&); 152EssentialCondition(Domain&, const LcOperatorOnUnknown&); 153EssentialCondition(Domain&, const LcOperatorOnUnknown&, const Function&); 154EssentialCondition(const EssentialCondition&); 155EssentialCondition& operator=(const EssentialCondition&); 156\end{lstlisting} 157\vspace{.3cm} 158some accessors or shotrcuts : 159\begin{lstlisting}[]{} 160const std::vector<OpuValPair>& bcTerms() const; 161const Function& fun() const; 162Function*& funp(); 163it_opuval begin(); 164cit_opuval begin() const; 165it_opuval end(); 166cit_opuval end() const; 167Number size() const; 168EcType type() const; 169\end{lstlisting} 170\vspace{.3cm} 171some function giving properties 172\begin{lstlisting}[]{} 173bool isSingleUnknown() const; 174Dimen nbOfUnknowns() const; 175const Unknown* unknown() const; 176std::set<const Unknown*> unknowns() const; 177bool isSingleDomain() const; 178Domain* domain() const; 179std::set<Domain*> domains() const; 180Dimen nbOfDomains() const; 181Number nbTerms() const; 182Complex coefficient() const; 183std::vector<Complex> coefficients() const; 184std::set<DiffOpType> diffOperators() const; 185bool nbOfDifOp() const; 186DiffOpType diffOperator() const; 187bool isHomogeneous() const; 188String name() const; 189\end{lstlisting} 190\vspace{.3cm} 191some functions to set type and domain: 192\begin{lstlisting}[]{} 193EcType setType(); //set the type of the Essential condition 194void setDomain(Domain& dom) //affect domain to EC 195EssentialCondition& operator |(Domain&) //affect domain of EC 196\end{lstlisting} 197\vspace{.3cm} 198When affect the domain using \emph{setDomain} function or | operator, all the domains defined in EcTerms are reset to the new domain. This domain affectation is also done by the non member function: 199\begin{lstlisting}[]{} 200EssentialCondition on(const Domain&, const EssentialCondition&); 201\end{lstlisting} 202\vspace{.3cm} 203and printing facilities: 204\begin{lstlisting}[]{} 205void print(std::ostream&) const; 206friend std::ostream& operator<<(std::ostream&, const EssentialCondition&); 207\end{lstlisting} 208\vspace{.3cm} 209To construct essential condition on the fly, the = operator of classes {\class Unknown}, {\class OperatorOnUnknown} and {\class LcOperatorOnUnknown} are overloaded: 210\begin{lstlisting}[]{} 211EssentialCondition LcOperatorOnUnknown::operator = (const Real &): 212EssentialCondition LcOperatorOnUnknown::operator = (const Complex &); 213EssentialCondition LcOperatorOnUnknown::operator = (const Function &); 214EssentialCondition OperatorOnUnknown::operator = (const Real &); 215EssentialCondition OperatorOnUnknown::operator = (const Complex &); 216EssentialCondition OperatorOnUnknown::operator = (const Function &); 217EssentialCondition Unknown::operator = (const Real &); 218EssentialCondition Unknown::operator = (const Complex &); 219EssentialCondition Unknown::operator = (const Function &); 220\end{lstlisting} 221\vspace{.3cm} 222All these member functions are implemented in the file \emph{EssentialCondition.cpp}.\\ 223 224\displayInfos{ 225library=essentialCondition, 226header=EssentialCondition.hpp, 227implementation=EssentialCondition.cpp, 228test={test\_EssentialCondition.cpp}, 229header dep={Operator.h, config.h, utils.h} 230} 231 232\section{The {\classtitle EssentialConditions} class} 233 234The {\class EssentialConditions} class manages a list of {\class EssentialCondition}. It inherits from {\class list<EssentialConditions>} with no additional member data: 235\vspace{.3cm} 236\begin{lstlisting}[deletekeywords={[3] list}] 237class EssentialConditions : public std::list<EssentialCondition> 238\end{lstlisting} 239\vspace{.3cm} 240As it is a user class, it mainly interfaces function of {\class list} class 241\begin{lstlisting}[]{} 242//constructors and assign 243EssentialConditions() {} 244EssentialConditions(const EssentialCondition&); 245EssentialConditions(const EssentialCondition&, const EssentialCondition&); 246EssentialConditions(const EssentialConditions&); 247EssentialConditions& operator = (const EssentialConditions&); 248//utilities 249bool coupledUnknowns() const; 250std::set<const Unknown*> unknowns() const; 251const Unknown* unknown() const; 252void print(std::ostream&) const; 253friend std::ostream& operator << (std::ostream&, const EssentialConditions &); 254\end{lstlisting} 255\vspace{.3cm} 256It overloads the \& operator to concatenate {\class EssentialCondition}: 257\begin{lstlisting}[]{} 258EssentialConditions operator & (const EssentialCondition&, const EssentialCondition&); 259EssentialConditions operator & (const EssentialCondition&, const EssentialConditions&); 260EssentialConditions operator & (const EssentialConditions&, const EssentialCondition&); 261EssentialConditions operator & (const EssentialConditions&, const EssentialConditions&); 262\end{lstlisting} 263\displayInfos{ 264library=essentialCondition, 265header=EssentialConditions.hpp, 266implementation=EssentialConditions.cpp, 267test={test\_EssentialCondition.cpp}, 268header dep={EssentialCondition.hpp, Operator.h, config.h, utils.h} 269} 270 271\section{The {\classtitle Constraints} class} 272 273The {\class Constraints} class handles the algebraic representation $\mathbb{C}U=G$ of a set of essential conditions ({\class EssentialConditions}) : 274 275\begin{lstlisting}[deletekeywords={[3] map}] 276class Constraints 277{ 278 protected : 279 MatrixEntry* matrix_p; //constraints matrix 280 VectorEntry* rhs_p; //constraints right hand side 281 public : 282 EssentialConditions conditions_; //list of essential conditions 283 std::vector<DofComponent> cdofsr_; //row DofComponent's of matrix_p 284 std::vector<DofComponent> cdofsc_; //col DofComponent's of matrix_p 285 std::map<DofComponent, Number> elcdofs_; //map of eliminated cdofs 286 std::map<DofComponent, Number> recdofs_; //map of reduced cdofs 287 bool reduced; //true if reduced system 288 bool local; //true if local conditions 289 bool symmetric; //true if keep symmetry 290 bool isId; //true if Id matrix 291} 292\end{lstlisting} 293\vspace{.3cm} 294Even if unknowns involved in constraints system are vector unknowns, the representation uses scalar unknown numbering (\emph{cdofsc\_} vector). The \emph{cdofsr\_} handles row numbering, each row corresponding to one constraint equation linked to an "artificial" test function. The \emph{elcdofs\_} map carries the eliminated index set ${\cal E}$ and \emph{recdofs\_} map carries the reduced index set ${\cal R}$ . {\class Constraints} is processed in two steps : 295\begin{itemize} 296\item construction of the constraint system from the list of essential conditions : each condition are translated in its matrix representation, then all the matrix representations are merged in a large one 297\item reduction of the large constraints system using QR algorithm with removing the redundant constraints and identifying the conflicting constraints 298\end{itemize} 299A constraint is local (\emph{local = true}) if it involves only one dof. Dirichlet conditions are local and transmission or periodic conditions are not. 300The class proposes mainly the constructor from a list of essential conditions and usual copy and delete stuff (full copy): 301\begin{lstlisting}[]{} 302Constraints(MatrixEntry* =0, VectorEntry* =0); 303Constraints(const EssentialCondition&); 304Constraints(const Constraints&); 305Constraints& operator=(const Constraints&); 306void copy(const Constraints&); 307~Constraints(); 308void clear(); 309\end{lstlisting} 310\vspace{.3cm} 311some accessors and property functions : 312\begin{lstlisting}[deletekeywords={[3] set}] 313const MatrixEntry* matrixp() const; 314const VectorEntry* rhsp() const; 315bool coupledUnknowns() const; 316const Unknown* unknown() const; 317std::set<const Unknown*> unknowns() const; 318\end{lstlisting} 319\vspace{.3cm} 320The fundamental functions are the building functions 321\begin{lstlisting}[]{} 322bool createDirichlet(const EssentialCondition&);//create from Dirichlet cond. 323void createLf(const EssentialCondition&); //create from linear form cond. 324void createNodal(const EssentialCondition&); //create general condition 325MatrixEntry* constraintsMatrix(const OperatorOnUnknown&, const GeomDomain*, 326 Space*, const complex_t&, vector<Point>&, const Function*, 327 vector<DofComponent>&); //create submatrix of a constraint 328void concatenateMatrix(MatrixEntry&, std::vector<DofComponent>&, const MatrixEntry&, 329 const std::vector<DofComponent>&); //concatenate 2 constraints matrices 330void reduceConstraints(real_t aszero); //reduce constraints matrix 331template <typename T> 332void buildRhs(const Function*, vector<Point>&, const T&); //tool building rhs 333\end{lstlisting} 334\vspace{.3cm} 335Functions \emph{createXXX(const EssentialCondition\&)} build the matrix representation for \emph{XXX} condition. Now, there exist Dirichlet, transmission and periodic type. It is quite easy to add new translation functions to take into account new ones. The \emph{reduceConstraints} function processes the reduction of any constraints sytem using QR algorithm. The \emph{asZero} variable is used to round to zero very small values induced by rounding errors in QR algorithm. This function modifies the current matrix and right hand side vector. So the original representation is lost after reduction!\\ 336 337To build the matrix representation of a set of essential conditions, two cases have to be considered: 338\begin{itemize} 339\item no condition that couples two unknowns (independent conditions); in that case one constraints system is built for each unknown 340\item there exists one coupling condition (coupled conditions); in that case a unique constraints system for all unknowns is built 341\end{itemize} 342For instance, the conditions ($u_1$, $u_2$ two unknowns): 343$$ u_1=0|\Sigma\ \ u_1=0|\Gamma\ \ u_2=0|\Gamma$$ 344gives two constraints system, one merging $u_1$ conditions and an other one for $u_2$. While the conditions : 345$$ u_1=0|\Sigma\ \ u_1=0|\Gamma\ \ u_2-u_1=g|\Gamma$$ 346gives a global constraints system merging all conditions.\\ 347 348The merging and building process is done by an external functions that return a list of {\class Constraints} indexed by unknown ({\class Unknown} pointer). In case of coupled conditions, the list contains only one {\class Constraints} indexed by 0. 349\begin{lstlisting}[deletekeywords={[3] map}] 350map<const Unknown*, Constraints*> mergeConstraints(vector<Constraints*>&); 351map<const Unknown*, Constraints*> buildConstraints(const EssentialConditions&); 352\end{lstlisting} 353\vspace{.3cm} 354The \emph{buildConstraints} function looks like (iterator declaration omitted): 355\begin{lstlisting}[deletekeywords={[3] map}] 356map<const Unknown*, Constraints*> buildConstraints(const EssentialConditions& ecs){ 357map<const Unknown*, Constraints*> mconstraints 358vector<Constraints *> constraints(ecs.size()); 359itc=constraints.begin(); 360//translate conditions into constraints 361for(ite=ecs.begin(); ite!=ecs.end(); ite++, itc++) 362 *itc=new Constraints(*ite); 363//merge constraints 364mconstraints = mergeConstraints(constraints); 365//reduce constraints 366for(itm=mconstraints.begin(); itm!=mconstraints.end(); itm++) 367 itm->second->reduceConstraints(); 368return mconstraints;} 369\end{lstlisting} 370\vspace{.3cm} 371The {\class Constraints} class provides important tools that take into account essential conditions in linear systems: 372\begin{lstlisting}[deletekeywords={[3] map}] 373void pseudoColReduction(MatrixEntry*, vector<DofComponent>&, 374 vector<DofComponent>&, MatrixEntry*&); 375void pseudoRowReduction(MatrixEntry*, vector<DofComponent>&, 376 vector<DofComponent>&); 377friend void extendStorage(MatrixEntry*, vector<DofComponent>&, 378 vector<DofComponent>&, const Constraints*, const Constraints*); 379void extractCdofs(const vector<DofComponent>&, map<DofComponent, Number>&, 380 map<DofComponent, Number>&, bool useDual=false) const; 381friend void appliedRhsCorrectorTo(VectorEntry*, vector<DofComponent>&, 382 MatrixEntry*, const Constraints*, const Constraints*, 383 ReductionMethod); 384\end{lstlisting} 385\vspace{.3cm} 386The functions \emph{pseudoColReduction} and \emph{pseudoRowReduction} performs the reduction of system matrix according to relation \ref{mat_el}. The \emph{pseudoColReduction} also stores the part of matrix system to be memorized to process right hand side correction. If case of non homogeneous constraints, the function \emph{appliedRhsCorrectorTo} modifies the system right hand side according to relation \ref{rhs_el}. Regarding unknown and test function constraints, \emph{extendStorage} function extends the storage of a matrix. This extension occurs when constraints are not local. \emph{extractCdofs} function is a facility to localized eliminated or reduced rows/columns in matrix. All of these functions are called by compute functions of {\class TermMatrix} class.\\ 387 388In order to deal with constraints acting on different matrix blocs, the {\class SetOfConstraints} class is provided. It manages mainly a map relating unknown and constraint: 389\begin{lstlisting}[deletekeywords={[3] map}] 390class SetOfConstraints : public map<const Unknown*, Constraints*> 391{ 392public: 393SetOfConstraints(const Unknown*, Constraints*); //from a constraints pointer 394SetOfConstraints(const map<const Unknown*, Constraints*>& mc); //from pointers 395SetOfConstraints(const EssentialConditions&); //from EssentialConditions 396SetOfConstraints(const SetOfConstraints&); //copy constructor with full copy 397SetOfConstraints& operator = (const SetOfConstraints&);//assignment with copy 398~SetOfConstraints(); //destructor deallocating constraints pointers 399void clear(); //deallocate constraints pointer and reset the map 400 401Constraints* operator()(const Unknown*) const; //acces operator from unknown 402bool isGlobal() const; //true if a unique global constraint 403bool isReduced() const; //true if all constraints have been reduced 404void print(std::ostream&) const; //print utility 405friend std::ostream& operator<<(std::ostream&, const SetOfConstraints&); 406}; 407\end{lstlisting} 408\vspace{.2cm} 409The {\class SetOfConstraints} objects are very important because they are used by the {\class TermMatrix} objects when they have to deal with essential conditions! 410 411\vspace{.1cm} 412\displayInfos{ 413library=essentialCondition, 414header=Constraints.hpp, 415implementation=Constraints.cpp, 416test=test\_Constraints.cpp, 417header dep={EssentialCondition.hpp, EssentialConditions.hpp, LargeMatrix.h, config.h, utils.h} 418} 419