You are on page 1of 10

Assembly Process

We will now begin to look at the fundamentals of finite element programming. Since the ideas used
in 1D problems (ODEs) are applied to problems in 2D and 3D, we can continue to use our model
problem as a basis of discussion.
Review of Model Problem. Suppose that a, b, f are given functions and consider the ordinary
differential equation: Find u Vp = {w C 2 ([0, 1]) : w(0) = p} such that
(au0 )0 + bu = f,

0 < x < 1,

= d/dx, (au0 + cu)|x=1 = q

where p, q, c are given constants. A boundary condition like the one at x = 1 with c = 0 is called
a natural boundary condition for this ODE (for example, if u is the temperature in a wall and a
the wall conductivity au0 (1) is the heat flux into the wall). I will present here an approach to the
assembly process which starts with the global weak form representation of the solution. Another
approach is possible starting from a weak form developed for an individual element.
Connectivity Matrix. We assume that the basic interval [0,1] is divided into subintervals or elements
using the grid (or mesh or node) points x1 = 0 < x2 < . . . , xne +1 = 1. In our text, these nodes
are generally stored in an array called gcoord. We denote the left and right end points (nodes) of
a typical element Ie = [xe1 , xe2 ]. The correspondence between element end points and grid points is
simply xe1 = xe , xe2 = xe+1 . This can get slightly more complex for elements with interior points so
the correspondence is often stored in a ne k connectivity matrix, say C, where n is the number of
elements, k is the number of points per element, and C(e, i) is the global node number the ith node
of element e. For the current problem (using linear elements)

1
2
2
3

Connectivity Matrix, 1D linear elements: C =


...

ne

ne + 1

Our text stores the connectivity matrix in an array generally called nodes. In two and three dimensions the geometry is more complex. For example, if our domain is the rectangle [0, 1] [0, 1], we
may create a grid using lines parallel to the axes: x1 = 0 < x2 < . . . , xn+1 = 1, y1 = 0 < y2 <
. . . , ym+1 = 1 . The elements in this case can be either ne = n m rectangles or ne = 2n m triangles.
After numbering these elements in a suitable way, the connectivity matrix will have ne rows and
either 4 or 3 columns.
Review of Weak Formulation. We start from the weak form of the equation. To find the weak
form, we proceed in the usual fashion. We define the residual r = (au0 )0 + bu f , and note that
if u Vp is a solution of the differential equation, and w V0 = {w C 2 ([a, b]) : w(0) = 0}
Z

rw dx = 0.

Noting that (au0 )0 w = (au0 w)0 au0 w0 , we find


A(u, w) =

Z
0

(au0 w0 + buw) dx =

f w dx + (q cu)w|x=1 = (f, w) + (q cu(1))w(1).

where the right hand boundary condition has been used.


Numerical Solution. The above expression holds for all test functions w and is equvalent to the
original equation for smooth functions. We generate a numerical approximation as follows: Let V0,n
1

be a linear subspace of V0 of finite dimension n we seek an approximate (or trial) solution u of the
form u
+v with u
Vp a fixed function satisfying the boundary condition at x = 0 and v is an element
of V0,n . At the same time, we take the test functions to lie in V0,n . (This is the Galerkin method. In
1D, the dimension n of the approximating subspace will be ne in cases where the solution function
is specified at one point of the interval. If two natural boundary conditions are given, n = ne + 1.)
For the present, we restrict considerations to the case of continuous piecewise linear functions. This
means that in each element Ie = [xe1 , xe2 ] (where for linear elements xej = xe+j1 , j = 1, 2), the
restriction of the trial function to I e is given by u(x)|I e = ue1 H1e (x) + ue2 H2e (x), with
H1e (x) = (xe2 x)/he ,
H2e (x) = (x xe1 )/he ,
where he = xe2 xe1 is the length of the element, and the Hse are called element shape functions. From
Pne +1
the global point of view, the trial function u can be expressed in the form u = j=1
j uj , where
j1
j
j are the tent functions, j = H1 on element j, j = H2 on element j 1, and j = 0 otherwise
(u1 = p is given). Also from this point of view, the requirement that the weak form hold for all test
functions vanishing at x = 0 is equivalent the requirement that it hold with w = i , i = 2, . . . , n.
To make the book keeping somewhat simpler, we will temporalily ignore the fact that w = 1 is not
allowable (and that also that u1 = p is already known). Thus, well allow all possible i for w. In
this case, we can write the ne + 1 linear equations obtained by substituting w = i into the weak
form as follows

Z 1
Z 1
0
0 T
T
f dx + au0 (1)(1),
a ( ) + b dx U =
0

where = [1 , 2 , . . . , ne +1 ]T , U = [u1 , u2 , . . . , une +1 ]T , and of course, (1) = [0, 0, . . . , 0, 1]T ,


and au0 (1) = cune +1 + q. This system of equations can be written in the form KU = F where
K is called the (global) stiffness or system matrix and F is called the (global) load vector.
Remember that the system KU = F cannot be inverted to give U = K 1 F since the first equation
(corresponding to w = 1 ) must first be eliminated.
R1
Pne R
Element Stiffness and Load Matricies. Using the fact that 0 g dx =
e=1 Ie g dx for any
function g, we write the weak form as
!
ne Z
ne Z
X
X
0
0 T
T
a ( ) + b dx U =
f dx + au0 (1)(1)
e=1

Ie

e=1

Ie

When is restricted to element Ie (we write |Ie for this matrix) only two of the tent functions are
non-zero: e = H1e and e+1 = H2e , that is

0
..
..
.
.

|Ie = H1e component e


e
H2 component e + 1

0
..
..
.
.
We see that on a single element it is possible to focus on a 2 by 2 submatrix of the global n n
matricies.
The contribution to the stiffness matrix from element Ie is the 2 by 2 submatrix with components
Z xe2
e
Krs
=
(a(Hre )0 (Hse )0 + bHre Hse ) dx, e = 1, . . . , ne , r, s = 1, 2,
xe1

where, remaining consistant with our definition of the global stiffenss matrix K, we have ignored
the fact that in element 1 the test function w must vanish at x = x1 = 0 so that w = H11 is not
admissable. The advantage of doing this is clear all element stiffnesses are the same. At the end
of the computation, we will account for our inclusion of this additional term. The contribution to
the load vector from element e is
Z xe2
e
Fr =
f Hre dx, e = 1, . . . , ne , r = 1, 2,
xe1

where we have not included the additional contribution au0 (1)e, ne r, 2 so as to have the same form
for all the element load components. This omission will have to be corrected at the conclusion of
computation prior to solving for the unknown trial function components uj . In matrix form
Z

Z
e
0
T 0
T
e
K =
aHe (He ) + bHe He dx , F =
f He dx, e = 1, . . . , ne
Ie

where He =

Ie

[H1e , H2e ]T .

The element stiffness and load matricies can be computed independently of one another. For example, if the coefficients a, b and f are all constant, then




 
bhe 2 1
he 1
a
1 1
e
e
+
, F =f
K = e
1 1
1 2
h
6
2 1
Let us recapitulate the two simplifying modifications we have introduced. First, we have ignored the
restriction that the test function is required to vanish at x = x1 = 0 in element 1. The motivation for
this was to gain uniformity in the definition of the element stiffness matricies. Second, in element ne
we have omitted the additional contribution to the load vector arising from the boundary condition
again to obtain uniformity in the definition of the load vector components. We can summarize these
two modifications by saying that we have ignored all boundary conditions. After constructing the
global matricies K, F , we will introduce the necessary corrections to insure the boundary conditions
are properly imposed.
Assembly Process and Matrix Inflation. To compute the global stiffness matrix, we first have to
expand or inflate the 2 by 2 element matricies back size (ne + 1) (ne + 1) by padding with zeros.
Then we construct the overall stiffness or system matrix simply by adding together the inflated
matricies recall that the global matrices are just the sums of the (expanded) element local stiffness
matrices. A similar procedure is used with the 2 by 1 load matrices which are inflated to (ne + 1) 1
vectors and summed to obtain the global load vector.
The process of inflating the element matricies and adding to the global or system matricies is much
simpler then it sounds. We simply loop through all the elements, determining for each element what
global nodes correspond to its local nodes. Determination of how the local stiffness and load vectors
of individual elements contribute to the global matrices can easily be made using the connectivity
matrix. We see, for example, that local node 1 of element 2 corresponds to global node 2 and local
node 2 corresponds to global node 3. This shows that F12 should be added to F2 and F22 should be
2
2
2
added to F3 . Similarily, K11
should be added to K22 , K12
should be added to K23 , K22
to K33 ,
2
and K21 to K32 . Proceding in a similar fashion we find the global or system equations are (we take
n = ne + 1 in the equations below).
1
K21
u1
2
K21 u2

1
1
K11
u1 + K12
u2
1
2
2
+ (K22 + K11 )u2 + K12
u3
2
3
3
+ (K22 + K11 )u3 + K12 u4
..
.
n
n
K21
un1 + K22
un

= F1
= F21 + F12
= F22 + F13
..
=
.
=

F2n

or in matrix form
K1
11
1
K21

0
.
.
.
0

1
K12
1
2
(K22
+ K11
)
2
K21

0
2
K12
2
3
(K22
+ K11
)

0
0
3
K12

F1
u1
1
u2 F21 + F12
2

u3 = F2 + F13
.

..
..

.
n
n
un
K22
F2

0
0
0
.
..

The the loop for assembly of the stiffness and load vectors is programmed in the m-file below
borrowed from our text. Before examining this file, lets look at the computation of the matrix
index which is used in the assembly loop. Again this is provided in a file from our text. I have
provided some additional comments intended to clarify the program.
function [index]=feeldof1(iel,nnel,ndof)
%---------------------------------------------------------% Purpose:
%
Compute system dofs associated with each element in one%
dimensional problem
%
% Synopsis:
%
[index]=feeldof1(iel,nnel,ndof)
%
% Variable Description:
%
index - system dof vector associated with element "iel"
%
iel - element number whose system dofs are to be determined
%
nnel - number of nodes per element (nnel=2 for linear elements)
%
ndof - number of dofs per node (ndof=1 for scalar problems)
%-----------------------------------------------------------

edof = nnel*ndof; % =2 for linear elements, scalar problems


start = (iel-1)*(nnel-1)*ndof; % =iel-1 for linear elements, scalar problems
for i=1:edof
index(i)=start+i;
end
% for linear elements, scalar problems: index(1)=iel, index(2)=iel+1
Now were ready for the assembly loop. Again Ive added some extra comments to the program from
the text.
function [kk,ff]=feasmbl2(kk,ff,k,f,index)
%---------------------------------------------------------% Purpose:
%
Assembly of element matrices into the system matrix &
%
Assembly of element vectors into the system vector
%
% Synopsis:
%
[kk,ff]=feasmbl2(kk,ff,k,f,index)
%
4

% Variable Description:
%
kk - system matrix
%
ff - system vector
%
k - element matrix
%
f - element vector
%
index - d.o.f. vector associated with an element
%----------------------------------------------------------edof = length(index); % =2 for linear, scalar problems
for i=1:edof
ii=index(i); % index=[iel,iel+1] for element iel
ff(ii)=ff(ii)+f(i); %[ff(iel);ff(iel+1)]=[f(1);f(2)]
for j=1:edof
jj=index(j);
kk(ii,jj)=kk(ii,jj)+k(i,j);
end
end
For the equation were considering, the index matrix for element Ie would be [e, e+1], so the loop
limits would be 1:2.
Imposition of Boundary Conditions. The global stiffness and load matrices must now be modified
so as to account for the boundary conditions which we have neglected up to this point. We will treat
the left and right hand conditions separately.
Left Boundary. First, we note that the test function w = 1 should not have been used in
K, and this means that the first row of K should be deleted. Second, note that u1 = p is
given so that all the terms ki1 u1 = ki1 p, i = 2, . . . , ne should be moved from the left side of
the equation KU = F and added the the ith components of the load vector on the right side.
These two modifications would change K to an ne ne matrix, but would entail modification
of all load components. The same end can be achieved in a much simpler way as follows
1. Zero out row 1 of K, then set k11 = 1.
2. Redefine F1 = p.
3. Now K remains (ne + 1) (ne + 1), and the first equation becomes u1 = p, i.e., this
equation enforces the boundary condition at x = 0.
Right Boundary. Now, it is the final component of the load vector which must be modified.
We have omitted the terms q cu(1) = q cune from Fne . The remedy is straight forward,
and falls into two categories.
c = 0 In this case we simply use the replacement Fne Fne + q.
c 6= 0 Now we must not only use the modification above Fne Fne + q, but also must modify
kne ne as follows kne ne kne ne + c
We are now ready to view some of the Text book files
function ex351a(n)
%---------------------------------------------------------------------------% EX3.5.1 -- Modified version of Text file
5

% to solve the ordinary differential equation given as


%
a u + b u + c u = 1, 0 < x < 1
%
u(0) = 0 and u(1) = 0
% using n linear elements
%
% Variable descriptions
%
k = element matrix
%
f = element vector
%
kk = system matrix
%
ff = system vector
%
index = a vector containing system dofs associated with each element
%
bcdof = a vector containing dofs associated with boundary conditions
%
bcval = a vector containing boundary condition values associated with
%
the dofs in bcdof
%---------------------------------------------------------------------------%-----------------------------------% input data for control parameters
%-----------------------------------nel=n;
nnel=2;
ndof=1;
nnode=nel+1;
sdof=nnode*ndof;

%
%
%
%
%

number of elements
number of nodes per element
number of dofs per node
total number of nodes in system
total system dofs

%----------------------------------------% input data for nodal coordinate values


%----------------------------------------gcoord=linspace(0,1,nel+1);
%----------------------------------------------------% input data for nodal connectivity for each element
%----------------------------------------------------nodes=[[1:nel] [2:nel+1]];
%----------------------------------------% input data for coefficients of the ODE
%----------------------------------------acoef=1;
bcoef=-3;
ccoef=2;

% coefficient a of the diff eqn


% coefficient b of the diff eqn
% coefficient c of the diff eqn

%------------------------------------% input data for boundary conditions


%------------------------------------bcdof(1)=1;

% first node is constrained

bcval(1)=0;
bcdof(2)=nel+1;
bcval(2)=0;

% whose described value is 0


% last node is constrained
% whose described value is 0

%----------------------------------------% initialization of matrices and vectors


%----------------------------------------ff=zeros(sdof,1);
% initialization of system force vector
kk=zeros(sdof,sdof);
% initialization of system matrix
index=zeros(nnel*ndof,1); % initialization of index vector
%----------------------------------------------------------------% computation of element matrices and vectors and their assembly
%----------------------------------------------------------------for iel=1:nel

% loop for the total number of elements

nl=nodes(iel,1); nr=nodes(iel,2); % extract nodes for (iel)-th element


xl=gcoord(nl); xr=gcoord(nr);% extract nodal coord values for the element
eleng=xr-xl;
% element length
index=feeldof1(iel,nnel,ndof);% extract system dofs associated with element
k=feode2l(acoef,bcoef,ccoef,eleng); % compute element matrix
f=fef1l(xl,xr);
% compute element vector
[kk,ff]=feasmbl2(kk,ff,k,f,index); % assemble element matrices and vectors
end
%----------------------------% Global stiffness and load matrices have been assembled
% now apply boundary conditions
%----------------------------[kk,ff]=feaplyc2(kk,ff,bcdof,bcval);
%---------------------------% solve the matrix equation
%---------------------------fsol=kk\ff;
%--------------------% analytical solution
%--------------------c1=0.5/exp(1);
c2=-0.5*(1+1/exp(1));
for i=1:nnode
x=gcoord(i);
esol(i)=c1*exp(2*x)+c2*exp(x)+1/2;

end
%-----------------------------------% print both exact and fem solutions
%-----------------------------------fprintf(%10s %10s %10s %10s\n,x, fem soln,exac soln,error);
fprintf(%10.2f %10.6f %10.6f %10.6f\n,[gcoord; fsol; esol; abs(fsol-esol)]);
plot(gcoord,fsol,k, gcoord, esol, ko);

%--------------------------------------------------------------function [index]=feeldof1(iel,nnel,ndof)
%---------------------------------------------------------% Purpose:
%
Compute system dofs associated with each element in one%
dimensional problem
%
% Synopsis:
%
[index]=feeldof1(iel,nnel,ndof)
%
% Variable Description:
%
index - system dof vector associated with element "iel"
%
iel - element number whose system dofs are to be determined
%
nnel - number of nodes per element
%
ndof - number of dofs per node
%-----------------------------------------------------------

edof = nnel*ndof;
start = (iel-1)*(nnel-1)*ndof;
for i=1:edof
index(i)=start+i;
end

function [k]=feode2l(acoef,bcoef,ccoef,eleng)
%------------------------------------------------------------------% Purpose:
%
element matrix for (a u + b u + c u)
%
using linear element
%
% Synopsis:
%
[k]=feode2l(acoef,bcoef,ccoef,eleng)
%
% Variable Description:

%
k - element matrix (size of 2x2)
%
acoef - coefficient of the second order derivative term
%
bcoef - coefficient of the first order derivative term
%
ccoef - coefficient of the zero-th order derivative term
%
eleng - element length
%------------------------------------------------------------------% element matrix
a1=-(acoef/eleng); a2=bcoef/2; a3=ccoef*eleng/6;
% k=a1[1 -1; -1 1]+a2[-1 1;-1 1]+a3[2 1;1 2]
k=[ a1-a2+2*a3
-a1+a2+a3;...
-a1-a2+a3
a1+a2+2*a3];

function [f]=fef1l(xl,xr)
%------------------------------------------------------------------% Purpose:
%
element vector for f(x)=1
%
using linear element
%
% Synopsis:
%
[f]=fef1l(xl,xr)
%
% Variable Description:
%
f - element vector (size of 2x1)
%
xl - coordinate value of the left node
%
xr - coordinate value of the right node
%------------------------------------------------------------------% element vector
eleng=xr-xl;
f=[ eleng/2;

% element length
eleng/2];

function [kk,ff]=feasmbl2(kk,ff,k,f,index)
%---------------------------------------------------------% Purpose:
%
Assembly of element matrices into the system matrix &
%
Assembly of element vectors into the system vector
%
% Synopsis:
%
[kk,ff]=feasmbl2(kk,ff,k,f,index)
%
% Variable Description:
%
kk - system matrix
%
ff - system vector
%
k - element matrix
%
f - element vector

%
index - d.o.f. vector associated with an element
%-----------------------------------------------------------

edof = length(index);
for i=1:edof
ii=index(i);
ff(ii)=ff(ii)+f(i);
for j=1:edof
jj=index(j);
kk(ii,jj)=kk(ii,jj)+k(i,j);
end
end

function [kk,ff]=feaplyc2(kk,ff,bcdof,bcval)
%---------------------------------------------------------% Purpose:
%
Apply constraints to matrix equation [kk]{x}={ff}
%
% Synopsis:
%
[kk,ff]=feaplybc(kk,ff,bcdof,bcval)
%
% Variable Description:
%
kk - system matrix before applying constraints
%
ff - system vector before applying constraints
%
bcdof - a vector containing constrained d.o.f
%
bcval - a vector containing contained value
%
%
For example, for homogeneous BC at x=0, 1,
%
bcdof=[1, ne+1], bcval=[0,0]
%----------------------------------------------------------n=length(bcdof);
sdof=size(kk);
for i=1:n
c=bcdof(i);
for j=1:sdof
kk(c,j)=0;
end
kk(c,c)=1;
ff(c)=bcval(i);
end

10