# Solving linear systems

Finite element computations make use of linear solvers to solve assembled linear systems of equations. The libraries Numpy [1], Scipy [2] and Eigen [3] offer capabilities to solve sparse linear systems by different methods. Muscat proposes a single class to wrap all this solvers into one unique simple interface.

## Treatment of kinematic constraints

Equation (1) represents the assembled finite element system to be solved under the kinematic constraints defined the equation (2). This problem can be solved by four different approaches.

The constrains represented by the equation (2) are created from the Dirichlet like boundary conditions (like RBE2 and RBE3). In some cases, this system can have linearly dependent equations, for example when a user specified twice some boundary condition in the same entity (e.g. the shared edge in the case of \(u_x=0\) on 2 adjacent faces).

To be able to treat correctly the constraint defined by (2), we must clean the linearly dependent equations, and find (in some cases) a reduced number of dof to eliminate .

Let extract from \(\CFE\) only the non zero columns (\(\CFE^*\)) and define the augmented matrix of \(\CPFE\) as :

The \(\CPFE^T\) matrix can then be decomposed using a QR decomposition to extract the suitable (orthonormal) base. This is done using the routine of EIGEN SpQR. SpQR is only available if the C++ interface was compiled, a pure Python (using scipy.linalg.qr) backup algorithm is available. This backup approach uses dense linear and can be expensive (in terms of memory and cpu time). This algorithm is capable of finding the rank of the matrix \(\CPFE^T\) (using a prescribed tolerance).

With, \(\mathbf{P}\) is the column permutation, \(\mathbf{Q}\) is the orthogonal matrix represented as Householder reflectors (in the case using Eigen). \(\mathbf{R}\) is the sparse triangular factor.

In many cases the constraints are on a single node or only on a reduced number of nodes. This make the matrix \(\CPFE^T\) very sparse, and we can compute the \(\mathbf{QR}\) decomposition block by block. For this the adjacency matrix of the matrix \(\CFE^*\) is computed (\(abs(\CFE^*)abs(\CFE^*)^T\)). A not zero \((i,j)\) term of the adjacency matrix means the rows \(i\) and \(j\) of \(\CPFE\) share at least one degree of freedom in common. Then we can calculate the connected components of the adjacency matrix and work on each block independently. As each block is treated (computation of the QR decomposition), the rank is identified to remove redundant equations. At the same time for each of the sub-matrices a subset of dofs equal to the rank is stored to created a list of slave dofs for later use.

For example:

For the system of 2 independent springs (4 degrees of freedom) represented in the previous figure, the tangent matrix and the right hand side member are,

The constraints imposed to the problem are: 1) blockage of the first dof (\(u_0\) to the value 0), 2) kinematic relation between \(u_1\) and \(u_2\); \(u_2 - u_1 = 1\), 3) prescribed solution on \(u_3\) equal to 3. To demonstrate the treatment, each constraint was added twice to the matrix \(\CFE\) :

In this case all degrees of freedom are present in matrix \(\CFE\), this means \(\CFE^* = \CFE\). We start by building the adjacency matrix \(\CFE\CFE^T\), we are interested in only the non zero values so we really calculate \(abs(\CFE)abs(\CFE^T) != 0\).

The computation of the connected components can be expressed by the solution vector:

We can see 3 connected components (rows of A). Each of these components can be treated independent (they are orthogonal). For the first component (line 1 and 2), it is evident that the lines are linearly dependent and we have only one emph{real} constraint. This can be detected by the SpQr routine and only the relevant base vectors are kept (we also normalize the vectors). We also store the rank first dofs of each component to define the slave indices. At the end we obtain 1) a vector of slave dofs of the system \([0,1,3]\), and a clean constants system defined by :

## Penalization

The penalization approach is the simplest way to solve the constrained system (in terms of programming). The idea of this method is to add to the original system to be solve a penalization term scaled by a really large value (\(\alpha_p = 10^8\)). The perturbed system becomes :

Because the modified system has the same number of dofs and no base transformation was done the solution of this system gives directly an original system (equations (1) and (2)) solution approximation

## Lagrange Multipliers

This method imposes the constraints by adding one extra dof for each row of equation (2). This yields to the following modified system:

The resolution of this linear system gives the solution vector:

The solution to the original system is then contained in the first part of the vector \(\UFE_{\lambda}\).

In the case that we have an initial a solution \(\UFE^0\), and we want to solve the system \(\KFE_{\lambda}\UFE_{\lambda} = \FFE_{\lambda}\) using this initial guess, we cand define the initial guess \(\UFE_{\lambda}\):

Note

This technique has the disadvantage of losing the positive definite properties of the original system (zeros on the diagonal of the operator \(\KFE_{\lambda}\))

## Substitution

Let decompose the \(\MFE\) (using the indices collected during the QR decomposition) into slave (\(s\)) and master (\(m\)) dofs :

The original system becomes:

Then the constraint equation (2) can be rewritten to solve \(\UFE_s\) :

Now we can rewrite the \(\UFE\) in the form of :

By defying:

And injecting this expression on the original system we obtain:

The modified system involves only \(\UFE_m\) dofs, and can be solved using a standard solver. The solution to the original system is then calculated using equation (3).

## Ainsworth Method

The Ainsworth method [4] proposes a general approach to solve the original system of equations without changing the number of degrees of freedom of the system.

Footnotes