“Hence if e = 3s − 6, the effect of any external force will be definite in producing tensions or pressures in the different pieces; but if e > 3s − 6, these forces will be indeterminate.”
— James Clerk Maxwell, On the calculation of the equilibrium and stiffness of frames, 1864
Static determinacy counted the reactions against the equations and then checked their lines of action for improper supports. Written as a matrix, the equilibrium equations do both checks in one computation. The rank of the matrix counts the equations that are independent, and the solutions it leaves open are the motions the supports allow and the reactions that equilibrium cannot fix.
The equilibrium matrix
A reaction of size \(\lambda_k\) acts at the point \(P_k = (x_k, y_k)\) along the unit vector \(\bm n_k\). Its force and its moment about the origin are \(\lambda_k\) times the column
and the moment of a fixed support, which has no force, is \(\lambda_k\) times \([0,\ 0,\ 1]^\mathsf{T}\). With the load reduced to the origin, \(\bm f = [F_x,\ F_y,\ M_O]^\mathsf{T}\), the equilibrium equations 8.7.8 read
where the equilibrium matrix\(\bm E\) has three rows and one column for each of the \(m\) unknown reactions. This is the system that sp.linsolve solved in Example 4 of Static equilibrium, with its matrix named.
The same columns describe the motions. A small motion of the body moves the origin by \((u_x, u_y)\) and turns the body by the small angle \(\theta\), so the point \(P_k\) moves by \((u_x - \theta y_k,\ u_y + \theta x_k)\). The support blocks the part of that motion along \(\bm n_k\),
and a fixed support blocks the turn, \(\theta = 0\), which is the same product with its column \([0,\ 0,\ 1]^\mathsf{T}\). All supports together give
\[
\bm E^\mathsf{T}\bm v = \bm 0 .
\tag{5.7.2}\]
The column of a reaction is also the motion it blocks. \(\bm E\bm\lambda = -\bm f\) asks which reactions hold the load, and \(\bm E^\mathsf{T}\bm v = \bm 0\) asks which motions the supports leave free.
Rank decides
The rank \(r\) of \(\bm E\) is the number of its independent columns, and also of its independent rows, so it is at most three. If \(r = 3\), 5.7.2 has no solution but \(\bm v = \bm 0\) and the supports hold the body against every motion. If \(r < 3\), it has \(3 - r\) independent solutions, each a motion the supports allow. The body is then a mechanism, and a load with a component along such a motion has no equilibrium.
If \(m = r\), the columns are independent and 5.7.1 has at most one solution. If \(m > r\), the system \(\bm E\bm\lambda = \bm 0\) has \(m - r\) independent solutions. Each is a set of reactions that balance one another with no load, a state of self-stress, and any multiple of it can be added to a solution of 5.7.1. Equilibrium cannot fix its size, and the body is statically indeterminate of degree \(m - r\).
A body in the plane with \(m\) reactions and the equilibrium matrix \(\bm E\) of rank \(r\) has \(3 - r\) free motions and \(m - r\) redundant reactions. It is statically determinate when both are zero.
The count of Static determinacy compares \(m\) with three, which amounts to assuming \(r = \min(m, 3)\). Improper supports are the cases where the rank falls below that: three reactions of rank two leave one free motion and one self-stress at the same time.
Example 1: The beam, by rank
We write \(\bm E\) for the six sets of supports in Figure 5.4.1, with \(A\) at the origin and \(B\) at \((L, 0)\) as in Example 4 of Static equilibrium, and let SymPy find the rank. Each support contributes the columns of the reactions it gives, and the null spaces of \(\bm E^\mathsf{T}\) and \(\bm E\) are the free motions and the self-stresses.
Code
L = sp.symbols('L', positive=True)def col(P, n):"""Force and moment about the origin of a unit reaction along n at P."""return sp.Matrix([n[0], n[1], P[0]*n[1] - P[1]*n[0]])moment = sp.Matrix([0, 0, 1]) # the moment of a fixed supportex, ey = (1, 0), (0, 1)A, B = (0, 0), (L, 0)beam = {'pin + roller': [col(A, ex), col(A, ey), col(B, ey)],'fixed': [col(A, ex), col(A, ey), moment],'roller + roller': [col(A, ey), col(B, ey)],'pin + roller on a wall': [col(A, ex), col(A, ey), col(B, (-1, 0))],'pin + pin': [col(A, ex), col(A, ey), col(B, ex), col(B, ey)],'fixed + roller': [col(A, ex), col(A, ey), moment, col(B, ey)],}def counts(cases, n_rows=3):"""Unknowns, rank, free motions and self-stresses of each set of supports.""" rows = []for name, cols in cases.items(): E = sp.Matrix.hstack(*cols) m, r = E.shape[1], E.rank() rows.append({'Supports': name, '$m$': m, 'rank': r,'free motions': n_rows - r, 'self-stresses': m - r})return rowsbeam_counts = counts(beam)
The unknowns, the rank and the two counts for each row of Figure 5.4.1 are
Supports
\(m\)
rank
free motions
self-stresses
pin + roller
3
3
0
0
fixed
3
3
0
0
roller + roller
2
2
1
0
pin + roller on a wall
3
2
1
1
pin + pin
4
3
0
1
fixed + roller
4
3
0
1
The table repeats the verdicts of Figure 5.4.1, and the row of the pin with the roller on the wall shows why counting alone missed it: three reactions, but rank two. Its two null spaces say what happens.
Code
E_wall = sp.Matrix.hstack(*beam['pin + roller on a wall'])v_wall = E_wall.T.nullspace()[0]lam_wall = E_wall.nullspace()[0]lam_pins = sp.Matrix.hstack(*beam['pin + pin']).nullspace()[0]
For the pin at \(A\) and the roller on the wall at \(B\), with the reactions in the order \(R_{Ax}\), \(R_{Ay}\), \(R_{Bx}\),
The free motion \(\bm v\) leaves the origin in place and turns the beam, so it turns about \(A\). The self-stress \(\bm\lambda_0\) has equal sizes for \(R_{Ax}\) and \(R_{Bx}\), and since the wall pushes along \(-x\), the pin and the wall squeeze the beam between them. They can do so with any force, and equilibrium does not see it. For the two pins, with the reactions in the order \(R_{Ax}\), \(R_{Ay}\), \(R_{Bx}\), \(R_{By}\), the self-stress is
that is \(R_{Ax} = -R_{Bx}\), the result of Case 5 in Example 4, now read as a set of reactions that can grow without any load.
Example 2: A block on links
A rectangular block, 3.2 m wide and 1.8 m high, is held by links pinned at both ends, in the four arrangements of Figure 5.7.1, which are those of Meriam and Kraige [1]. A link pinned at both ends carries a force along its own line, so each link gives one reaction along the link. We place \(A\), the lower left corner, at the origin.
Links
\(m\)
Behaviour
(a) two links at \(A\), one at the lower right corner
3
held
(b) two links at \(A\), the third pointing at \(A\)
3
turns about \(A\)
(c) three parallel links
3
slides up and down
(d) case (a) and a fourth link
4
held, one link redundant
Figure 5.7.1: A block on links under the load \(\bm F\). A held block gives a little under a push along each motion while the link forces answer it; a mechanism moves along the motion its links leave free, in blue, with the lines of the links dashed. In (d) the fourth link is removed and the block is still held.
Code
w, h = sp.Rational(16, 5), sp.Rational(9, 5) # the block, 3.2 m by 1.8 mtoward_A =-sp.Matrix([w, h])/sp.Matrix([w, h]).norm() # link 3 of case (b) points at Ablock = {'(a)': [col(A, ex), col(A, ey), col((w, 0), ey)],'(b)': [col(A, ex), col(A, ey), col((w, h), toward_A)],'(c)': [col((0, sp.Rational(3, 2)), ex), col((0, sp.Rational(3, 10)), ex), col((w, sp.Rational(9, 10)), (-1, 0))],'(d)': [col(A, ex), col(A, ey), col((w, 0), ey), col((sp.Rational(9, 5), h), (-sp.Rational(3, 5), -sp.Rational(4, 5)))],}block_counts = counts(block)E_b, E_c, E_d = (sp.Matrix.hstack(*block[k]) for k in ('(b)', '(c)', '(d)'))
The counts for the four cases are
Supports
\(m\)
rank
free motions
self-stresses
(a)
3
3
0
0
(b)
3
2
1
1
(c)
3
2
1
1
(d)
4
3
0
1
Cases (b) and (c) have the right number of links and rank two. With the link forces \(S_1\), \(S_2\), \(S_3\) in order, the free motion and the self-stress of case (b) are
The block turns about \(A\), where the three link lines meet, and the self-stress is link 3 pushing towards \(A\) while links 1 and 2 push back, in the ratio \(16 : 9 : \sqrt{337}\) set by the slope of link 3. For case (c),
\[ \bm v = \left[\begin{matrix}0\\1\\0\end{matrix}\right], \qquad \bm\lambda_0 = \left[\begin{matrix}\dfrac{1}{2}\\\dfrac{1}{2}\\1\end{matrix}\right] \]
The block slides up and down, across all three links, and the right link can push against the two left ones with twice the force of each. Case (d) is held, rank three, and its fourth link adds one self-stress,
a set of link forces that the block cannot feel. Their size depends on how the links stretch, and only an analysis of the deformation can give it.
Several bodies
With \(n\) bodies, \(\bm E\) gets three rows for each body, \(3n\) rows in all. A support adds a column in the rows of the body it holds. A joint between two bodies adds one column for each force component it transmits, with the force in the rows of one body and, by Newton’s third law, the opposite force in the rows of the other. The counts become \(3n - r\) free motions and \(m - r\) redundant reactions, where \(m\) now includes the joint forces. Maxwell’s rule in the epigraph is this count for bars joined by pins [2], and the truss chapters of Solid Mechanics build the same matrix for trusses.
Example 3: A three-hinged frame
Two bars, \(AC\) and \(CB\), are pinned together at \(C\) and to the ground at \(A\) and \(B\) (Figure 5.7.2 (a)). The load \(F\) acts downwards at the middle of \(AC\). In metres, \(A\) is at the origin, \(C\) at \((2, 1.5)\) and \(B\) at \((4, 0)\). The unknowns are the pin forces \(A_x\) and \(A_y\) on \(AC\), the joint force \(C_x\), \(C_y\) on \(AC\), which acts on \(CB\) with the opposite sign, and the pin forces \(B_x\) and \(B_y\) on \(CB\).
(a) On two pins.
(b) With a roller at \(B\). Dashed, the free motion from \(\bm E^\mathsf{T}\bm v = \bm 0\), exaggerated.
Figure 5.7.2: A three-hinged frame of two bars pinned at \(C\).
Code
F = sp.symbols('F', positive=True)def col2(P, n, body, sign=1):"""A reaction in the six rows of the two bars, on bar 0 (AC) or bar 1 (CB).""" c = sp.zeros(6, 1) c[3*body:3*body +3, 0] = sign*col(P, n)return cA, C, B = (0, 0), (2, sp.Rational(3, 2)), (4, 0)frame = [col2(A, ex, 0), col2(A, ey, 0), col2(C, ex, 0) + col2(C, ex, 1, -1), # the joint: on AC, and opposite on CB col2(C, ey, 0) + col2(C, ey, 1, -1), col2(B, ex, 1), col2(B, ey, 1)]E_frame = sp.Matrix.hstack(*frame)f_frame = sp.Matrix([0, -F, -F, 0, 0, 0]) # F down at (1, 0.75): moment -F about the originlam_frame = E_frame.LUsolve(-f_frame)E_roller = sp.Matrix.hstack(*frame[:4], frame[5]) # a roller at B: B_x is gonev_roller = E_roller.T.nullspace()[0]
The equilibrium matrix has six rows, three for each bar, and six columns. Its rank and the reactions, in the order \(A_x\), \(A_y\), \(C_x\), \(C_y\), \(B_x\), \(B_y\), are
Six reactions and rank six: the frame is determinate. The pins push the two feet inwards, \(A_x = F/3\) and \(B_x = -F/3\), and the two vertical reactions carry \(3F/4\) and \(F/4\) of the load, as the lever arms of \(F\) about \(B\) and \(A\) require.
With a roller at \(B\) the column of \(B_x\) goes. Five reactions and rank five: no self-stress, and \(6 - 5 = 1\) free motion, which in the order \(u_x\), \(u_y\), \(\theta\) of \(AC\) and then of \(CB\) is
\[ \bm v = \left[\begin{matrix}0\\0\\-1\\3\\-4\\1\end{matrix}\right] \]
Bar \(AC\) turns clockwise about \(A\), and bar \(CB\) moves and turns so that its end at \(C\) follows \(AC\) and its end at \(B\), which moves by \((3, 0)\) for the turn \(1\), slides along the ground. The feet spread and the frame sags, as the dashed line in Figure 5.7.2 (b) shows: the horizontal pin force at \(B\) was what held the feet together.
Further reading
Calladine [3] discusses Maxwell’s rule and the frames that break it, whose rank falls short of the count. Pellegrino and Calladine [4] classify frameworks by the two null spaces of the equilibrium matrix, the free motions and the states of self-stress, and Pellegrino [5] computes them with the singular value decomposition. Meriam and Kraige [1] treat the adequacy of supports with the block on links of Example 2.
Maxwell JC. On the calculation of the equilibrium and stiffness of frames. The London, Edinburgh, and Dublin Philosophical Magazine and Journal of Science 1864;27:294–9. https://doi.org/10.1080/14786446408643668.
[3]
Calladine CR. Buckminster Fuller’s “tensegrity” structures and Clerk Maxwell’s rules for the construction of stiff frames. International Journal of Solids and Structures 1978;14:161–72. https://doi.org/10.1016/0020-7683(78)90052-5.
[4]
Pellegrino S, Calladine CR. Matrix analysis of statically and kinematically indeterminate frameworks. International Journal of Solids and Structures 1986;22:409–28. https://doi.org/10.1016/0020-7683(86)90014-4.
[5]
Pellegrino S. Structural computations with the singular value decomposition of the equilibrium matrix. International Journal of Solids and Structures 1993;30:3025–35. https://doi.org/10.1016/0020-7683(93)90210-X.