MSA Using Scilab
MSA Using Scilab
MSA Using Scilab
using Scilab
by
Satish Annigeri Ph.D.
Professor of Civil Engineering
B.V. Bhoomaraddi College of Engineering & Technology, Hubli
[email protected]
1 1 2P
2
0.75L
3
x
L 0.5P 0.5P
Scilab Tutorial Tutorial 1 – Data Organization for Matrix Analysis of Plane Frames | 2
The input data for the example in Fig. 3 is given below. The numbers L=100 in
within the tables constitute the data and are shown shaded. The rest are labels P=10 kips
to help you interpret the data.
E=10,000 ksi
xy x y
A=10 in2
1 100 75
I=1000 in4
2 0 75
3 200 0
bc Node ux uy rz
1 2 1 1 1
2 3 1 1 1
mprop E A I
4
1 1x10 10 1x103
jtloads Node Fx Fy Mz
1 1 0 -10 -1000
memloads Member Fx Fy Mz Fx Fy Mz
1 1 0 12 200 0 12 -200
2 2 -6 8 250 -6 8 -250
Note that the units for the above data are kips (kilo pounds) and inches, as a result, E is in
ksi (kilo pounds per square inch) and I is in in 4. The units used must be consistent and it is the
responsibility of the user to ensure this. The functions work well for any consistent system of
units.
One thing that must be clearly understood is the definition of the local axis of the member.
The local axis is defined with its origin at the start node of the member and the positive direction
of the local x-axis is defined by the end node of the member. For example, member 1 in the
above example has its x-axis starting from 1 and going towards 2, that is from right to left. The
local y-axis is taken perpendicular to the x-axis and the local z-axis is kept the same as the
global z-axis in the case of a plane frame.
The sign convention for the member fixed end forces is dependent on the member local
x-axis, and the right-hand rule is used in deciding the positive sign convention for the forces and
moments at the ends of the member.
Scilab Tutorial Tutorial 1 – Data Organization for Matrix Analysis of Plane Frames | 3
Tutorial 2 – Location Matrix for a Plane Frame
In a plane frame, the number of degrees of freedom (dof) per node is 3, namely ux, uy and rz,
and therefore the total number of degrees of freedom is 3 times the number of nodes ('n').
However, every structure has supports with certain degrees of freedom constrained (otherwise
the structure would be a free body capable of undergoing rigid-body motion). These constrained
dof have zero displacements or non-zero prescribed displacements (such as support settlement
problems). As a result, the number of unknown degrees of freedom ('ndof') is smaller than 3xn.
In the direct stiffness matrix method, the portion of the stiffness matrix corresponding to
zero displacements is not assembled as it does not affect the calculation of the nodal
displacements. In case of non-zero prescribed displacements, the stiffness matrix must include
the rows and columns corresponding to non-zero prescribed displacements, but before solving
the stiffness equation, a rearrangement of the matrices is necessary. This however is not
attempted here and is left as an exercise for the student.
A generalized representation of the dof numbering is called the location matrix. It has a size
nx3, where 'n' is the number of nodes in the plane frame. Columns 1 to 3 store the constraint
code for displacements along the 3 possible dof, namely, ux, uy and rz for each node. The code is
0 for unconstrained dof and 1 for constrained dof.
The location matrix 'lm' is compiled in 2 stages. In the first stage, 'lm' is initialized to a zero
matrix, implying that all dof are unconstrained. The number of nodes with constrained dof is
available in column 1 of matrix 'bc'. For each of these nodes, the zeros in the corresponding rows
of the location matrix are replaced by the constraint codes from 'bc'.
In the second stage, the variable representing the number of dof of the plane frame ('ndof')
is initialized to 0 and 'lm' is processed row by row, For each constraint code 0 (unconstrained
dof), 'ndof' is incremented by 1 and stored in the place of the 0. If the constraint code is 1
(constrained dof), it is set to 0 indicating the corresponding displacement to be 0.
At the end of this stage, 'ndof' will be the total number of dof of the plane frame and 'lm'
will have zeros for a dof with zero displacement or a unique dof number for an unconstrained
dof. The size of structure stiffness matrix must therefore be ndof x ndof. The interface for a
function to compute the location matrix is given below:
Interface: [lm, nd]=pf_calclm(n, bc)
Input Parameters: n=number of nodes in the plane frame, bc=Boundary constraint matrix.
Output Parameter: lm=Location matrix of a plane frame, nd=number of dof of the plane frame.
The function to carry out this computation is given below:
function [lm, nd]=pf_calclm(n, bc)
lm=zeros(n,3);
[ns dummy]=size(bc); // ns=number of supports
for i=1:ns
nn=bc(i,1); // node number of ith support
lm(nn, 1:3) = bc(i, 2:4); // constraint codes of ith support
end;
nd=0; // initialize number of dof to zero
for i=1:n
for j=1:3
if lm(i,j) == 1 then // constrained dof
lm(i,j) = 0;
else // unconstrained dof
nd = nd + 1;
lm(i,j) = nd;
end
end
end
endfunction
[ ]
The stiffness matrix of
EA −EA a plane frame member with
0 0 0 0
L L reference to its local axes is
12EI 6EI −12EI 6EI of size 6x6 and is given as
0 0 shown on the left.
L3 L2 L3 L2
6EI 4EI −6EI 2EI This can be generated
0 0 by first defining a zero
L2 L L2 L
k= matrix of size 6x6, then
−EA EA defining the elements of the
0 0 0 0
L L upper triangular matrix and
−12EI −6EI 12EI −6EI finally copying the upper
0 0
L3 L2 L3 L2 triangle into the lower
6EI 2EI −6EI 4EI triangle. The description of
0 0 the function that will be
L2 L L L
developed for this purpose
is as follows:
Interface: [k]=pf_stiff(E, A, I, L)
Input Parameters: E = Modulus of elasticity, A = Cross sectional area of the member,
I = Second moment of area of the cross section about the neutral axis and L = Length of the
member.
Output Parameter: k = Local stiffness matrix of a plane frame element of size 6x6.
The code for the function is as follows:
function [k] = pf_stiff(E, A, I, L)
k = zeros(6,6);
k(1,1) = E*A/L; k(1,4) = -k(1,1);
k(3,3) = (4*E*I)/L;
k(3,5) = -k(2,3); k(3,6) = k(3,3)/2;
k(4,4) = k(1,1);
k(6,6) = k(3,3);
for i = 2:6
for j = 1:i-1
k(i,j) = k(j,i);
end
end
endfunction
Load this function into Scilab and test it with the following input:
-->k = pf_stiff(1,1,1,1)
The output is given on the next page. Another test is the following input, which gives the
local stiffness matrix of member 2:
-->k = pf_stiff(1e4,10,1e3,125)
The output of this second command is also shown on the next page.
[ ]
800 0 0 −800 0 0 This is the stiffness matrix
generated by the second
0 61.44 3840 0 −61.44 3840
command where E=1x104,
0 3840 320000 0 −3840 160000
k= A=10, I=1x103 and L=125.
−800 0 0 800 0 0
0 −61.44 −3840 0 61.44 −3840
0 3840 160000 0 −3840 320000
You will note that this function takes the length of the member as one of the input. We
therefore need a function to calculate the length of a member. Later on, we will also need to do a
related calculation, the direction cosines of the member. We will write a function that can do
both these things. Its interface is as follows:
Interface: [l, cx, cy]=pf_calclen(imem, xy, conn)
Input Parameters: imem = number of the member whose length and direction cosines are to be
calculated, xy = Coordinates matrix, conn = Connectivity matrix.
Output Parameters: l = Length of the member, cx = x direction cosine, cy = y direction
cosine.
The code for the function is given below and the comments (which need not be typed when
you try out the function yourself) are self-explanatory.
function [l, cx, cy]=pf_calclen(imem, xy, conn)
n=conn(imem,:); // start and end nodes of member number i
p1 = xy(n(1),:); // x,y coordinates of start node
p2 = xy(n(2),:); // x,y coordinates of end node
dxdy=p2-p1; // x,y projections of member
dxdy2=dxdy.^2; // square of the projections
l=sqrt(sum(dxdy2)); // length of member
endfunction
With this function available, we can compute the local stiffness matrix of any member by
first calculating its length, extracting its material properties from 'mprop' and then computing its
local stiffness matrix. For member 1, the commands would be:
-->[L cx cy]=pf_calclen(1,xy,conn)
-->iprop=conn(1,3)
-->E=mprop(iprop,1);A=mprop(iprop,2);I=mprop(iprop,3);
-->k=pf_stiff(E,A,I,L)
[ ]
Cx C y 0 0 0 0 where Cx and Cy are the direction cosines of the member
dx x − x
−C y C x 0 0 0 0 and are calculated as C x = = 2 1 and
l l
0 0 1 0 0 0 y − y
r= dy
0 0 0 C x Cy 0 C y= =
2 1
where l = dx 2dy 2 .
l l
0 0 0 −C y C x 0
0 0 0 0 0 1
The interface for the function is as follows:
Interface: [r]=pf_calcrot(cx, cy)
Input Parameters: cx = x direction cosine, cy = y direction cosine.
Output Parameters: r = Rotation matrix.
The code for the function is as follows:
function [r] = pf_calcrot(cx, cy)
r(1,1) = cx;
r(1,2) = cy;
r(2,1) = -r(1,2);
r(2,2) = r(1,1);
r(3,3) = 1;
r(4:6, 4:6) = r(1:3, 1:3); // copy rows and columns 1:3, 1:3 into 4:6, 4:6
endfunction
Note that the direction cosines of the member must first be calculated using the
pf_calclen() function and only then should the function to calculate the rotation matrix must
be called. The commands to calculate the rotation matrix for member 2 are as follows:
-->[l cx cy]=pf_calclen(2,xy,conn)
-->r=pf_calcrot(cx,cy)
The output of these commands must be as follows:
[ ]
0.8 −0.6 0 0 0 0
−0.6 0.8 0 0 0 0
0 0 1 0 0 0
r=
0 0 0 0.8 −0.6 0
0 0 0 0.6 0.8 0
0 0 0 0 0 1
[ ]
534.1184 −354.5088 2304 −534.1184 354.5088 2304
−354.5088 327.3216 3072 354.5088 −327.3216 3072
2304 3072.0000 320000 −2304 −3072 160000
r=
−534.1184 354.5088 −2304 534.1184 −354.5088 −2304
354.5088 −327.3216 −3072 −354.5088 327.3216 −3072
2304 3072 160000 −2304 −3072 320000
nj = conn(imem,1); nk = conn(imem,2);
dof(1:3) = lm(nj,1:3);
dof(4:6) = lm(nk,1:3);
for i=1:6
ii = dof(i);
if ii == 0 then
else
for j=1:6
jj = dof(j);
if jj == 0 then
else
tmp = ssm(ii,jj) + K(i,j);
ssm(ii,jj) = tmp;
end
end
end
end
endfunction
Note that ssm appears both as an input as well as an output parameter, as this function
superposes the global stiffness matrix of one member onto the existing structure stiffness matrix,
which is initialized to zero to start with. To compute the structure stiffness matrix considering all
members, we need to call this function inside a for loop. The interface to the function that does
this is shown below:
Interface: [K]=pf_ssm(xy, conn, mprop, lm, ndof)
Input Parameters: xy = coordinates matrix, conn = connectivity matrix and mprop = material
property matrix, lm = location matrix of the member and nd = number of degrees of freedom of
the plane frame.
Output Parameters: K = structure stiffness matrix of the plane frame.
The code for the function is given below:
function [K]=pf_ssm(xy, conn, mprop, lm, ndof)
K=zeros(ndof,ndof);
Scilab Tutorial Tutorial 6 – Assembling the Plane Frame Structure Stiffness Matrix | 10
[nmem dummy]=size(conn);
for imem = 1:nmem
K = pf_assemssm(imem, xy, conn, mprop, lm, K);
end
endfunction
The input data xy, conn, mprop must first be read and the number of degrees of
freedom (ndof) and location matrix (lm) must be computed before the function pf_ssm() is
called. This function returns the structure stiffness matrix (K) of the plane frame.
To illustrate the steps for member 1, the start end end nodes are 2 and 1 respectively, as can
be seen from the 'conn' matrix. The dof numbers for these nodes are obtained from the location
matrix 'lm', and are seen to be [0 0 0] and [1 2 3] for nodes 2 and 1 respectively. This
implies that rows and columns of the global stiffness matrix of member 1 correspond to rows
[0 0 0 1 2 3] of the global stiffness matrix of the structure. Rows and columns with dof
number zero correspond to zero displacement and therefore need not be assembled into the
structure stiffness matrix. The elements of the member global stiffness matrix where both the
row and column dof numbers are non-zero are superposed on the elements in the corresponding
row and column of the structure stiffness matrix.
Scilab Tutorial Tutorial 6 – Assembling the Plane Frame Structure Stiffness Matrix | 11
Tutorial 7 – Assembling the Load Vector
The load vector has the same number of rows as the number of degrees of freedom (dof) of
the structure ('ndof'). Each element of the load vector represents the load applied
corresponding to a dof number. Loads applied on a plane frame can be either loads applied at the
nodes of the frame or loads applied on the members. The two different types of loads have to be
processed differently before assembling the load vector.
Joint loads are an input data to the program and are specified as components in global
coordinate system (components along x, y axes and moment about z axis). Knowing the node
number at which the load is applied, it is easy to identify the dof numbers corresponding to the
node from the location matrix. The components of the load at a node are then superposed with
the corresponding element in the load vector.
The interface to the function that assembles the load vector for loads applied at the joints is
given below:
Interface: [P]=pf_assemloadvec_jl(lm, jtloads, P)
Input Parameters: lm = location matrix of the member and jtloads =matrix of joint loads,
P = load vector.
Output Parameters: P = load vector.
This function assembles the load vector for a plane frame from the loads applied directly on
the nodes.
function [P]=pf_assemloadvec_jl(lm, jtloads, P)
[nloads dummy] = size(jtloads);
printf('Loads = %d\n', nloads);
for i=1:nloads
n=jtloads(i,1);
printf('Load applied at joint %d', n);
dof=lm(n,:);
disp(dof, ' with dof = ');
for j=1:3
jj = dof(j);
if jj == 0 then
else
tmp = P(jj) + jtloads(i, j+1);
P(jj) = tmp;
end
end
end
endfunction
This function returns a 1x6 vector containing the dof numbers of the start and end nodes of
member number imem. The degree of freedom (dof) numbers in the first 3 rows correspond to
the start node and the last 3 to the end node.
function [dof]=pf_getdof(imem, conn, lm)
dof=zeros(1,6);
n1 = conn(imem,1);
dof(1:3) = lm(n1,:);
n2 = conn(imem,2);
dof(4:6) = lm(n2,:);
endfunction
This interface to the function that assembles the load vector for a plane frame from the loads
applied on the members is given below:
Interface: [P]=pf_assemloadvec_ml(iload, xy, conn, lm, memloads, P)
Input Parameters: iload = number of the member load being processed, xy = coordinates
matrix, conn = connectivity matrix, lm = location matrix of the member and memloads = matrix
[nodes dummy]=size(xy);
[lm ndof]=pf_calclm(nodes,bc);
ssm=pf_ssm(xy,conn,mprop,lm,ndof);
P=zeros(ndof,1);
x=zeros(ndof,1);
[nmemlds dummy]=size(memloads);
for iload=1:nmemlds
[P]=pf_assemloadvec_ml(iload, xy, conn, lm, memloads, P);
end
x=zeros(ndof,1);
x=inv(ssm)*P;
endfunction
All the input data must be gathered before calling this function. After this function is called,
the nodal displacements are known and the task that remains is to extract the member end forces
from the calculated nodal displacements.
f = zeros(6,1);
f = k * uu; // Member end forces in local axes
[nmemloads,dummy] = size(memloads);
for i = 1:nmemloads
if memloads(i,1) == imem
f = f + memloads(i,2:$)';
end
end
endfunction
This function has to be called once for each member and the results stored. This can be done
at the Scilab command prompt.
-->[k,x,P]=pf(xy,conn,bc,mprop,jtloads,memloads)
-->[nodes dummy]=size(xy);
-->lm=pf_calclm(nodes,bc);
-->f1=pf_memendforces(1,xy,conn,mprop,lm,x,memloads)
-->f2=pf_memendforces(2,xy,conn,mprop,lm,x,memlodas)
Data for the problem shown has been stored in a file called pf.bin, and you can load it with
the command:
-->load('pf.bin')
Ensure that pf.bin is located in your working directory. The output of the Scilab functions
is compared with the results from the book:
Scilab Tutorial