```
In [1]:
```from sympy import * # use symbolic algebra
init_printing(use_latex='mathjax') # print nice math (use_latex arg is workaround for FormatterWarning messages)
from IPython import display

```
In [2]:
```from sdutil2 import SD, FEF

Analyze the following frame using the method of **slope-deflection**.

```
In [3]:
```display.SVG('frame1.svg')

```
Out[3]:
```

This frame has 5 independant joint displacements - rotations at the four
joints *a*,
*b*,
*c*,
and
*d*,
and a lateral displacement of joints
*b*
and
*c*
together. Actually, we know that joint *d* does not rotate, but we
will pretend it does for now, and will handle that as a displacement constraint
later.

So now we write the slope deflection equations. These express the end moments
as functions of the five unknown displacements. Note also that we do not treat the
pin-ended member *ab* specially -- it is not necessary to do so.

We use a very simple utility function *SD()* to compute the end moments and shears of a segment,
as a function of the end displacements:

```
In [4]:
```help(SD)

```
```

```
In [5]:
```# Slope deflection equations:
# theta_a,b,c,d - rotations of joints
# Delta_ab - horizontal displacement of joint b (and c) relative to a (and d)
var('EI theta_a theta_b theta_c theta_d Delta_ab')
Mab,Mba,Vab,Vba = SD(3,EI,theta_a,theta_b,Delta_ab)
Mbc,Mcb,Vbc,Vcb = SD(6,2*EI,theta_b,theta_c,0) + FEF.udl(6,36)
Mcd,Mdc,Vcd,Vdc = SD(2,EI,theta_c,theta_d,Delta_ab)

```
In [6]:
``````
Mbc
```

```
Out[6]:
```

Now we write five linear equations to solve for the five unknown displacements.
Three are equilibrium equations and involve moments at three of the joints: $Mab = 0$, $Mba+Mbc=0$, and $Mcb+Mcd=0$.
One equation involves the equilibrium of the column shears with the horizontal applied
load: $Vab+Vdc-60=0$. The fifth equation is just the known rotation at joint *d*: $\theta_d=0$.

In sympy, we build a list of the five equations, all expressed as $f(..,..) = 0$ and giving only the left side of each (the right side always being 0 is not given). We then call the solver and give it a list of variables to solve for:

```
In [7]:
```eqns = [Mab, Mba+Mbc, Mcb+Mcd, Vab+Vdc-60, theta_d]
soln = solve(eqns,[theta_a,theta_b,theta_c,theta_d,Delta_ab])
soln

```
Out[7]:
```

The above solution is returned as a Python dictionary, making it easy to substitute for those variables in other equations.

In fact, that is done now, substituting the displacement solutions into each of the slope-deflection equations. The result is a list of the member end moments (and shears).

The '.n(4)' method forces a numerical answer with 4 significant figures.

```
In [8]:
```{v:eval(v).subs(soln).n(4) for v in 'Mab,Mba,Mbc,Mcb,Mcd,Mdc,Vab,Vdc'.split(',')}

```
Out[8]:
```

And now - the reactions at supports *a* and *d*:

```
In [9]:
```Ra = Vbc
Rd = -Vcb
Ha = -Vab
Hd = -Vdc
Md = Mdc
[v.subs(soln).n(4) for v in [Ra,Ha,Rd,Hd,Md]]

```
Out[9]:
```

```
In [10]:
```# sum horizontal forces
(Ha + Hd + 60).subs(soln)

```
Out[10]:
```

```
In [11]:
```# sum vertical forces
(Ra + Rd - 36*6).subs(soln)

```
Out[11]:
```

```
In [12]:
```# sum moments about a
(60*3 + 36*6*3 + Hd*1 + Md - Rd*6).subs(soln)

```
Out[12]:
```

```
In [13]:
```%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt

```
In [14]:
```var('x')
Mbcx = (Ra*x + Vab*3 - 36*x*x/2).subs(soln) # M as a function of x
fn = lambdify((x),Mbcx) # convert moment expression to a function of one argument
z = np.linspace(0,6)
plt.plot(z,fn(z),[0,6],[0,0])
plt.fill_between(z,fn(z),color='lightgrey')
##plt.show()

```
Out[14]:
```

Find the locations along span *bc* of zero moment:

```
In [15]:
```[r.n(4) for r in solve(Mbcx)]

```
Out[15]:
```

Find point of maximum moment and the maximum moment in the span:

```
In [16]:
```xs = solve([Mbcx.diff(x)])
xs

```
Out[16]:
```

```
In [17]:
```xs[x].n(4), Mbcx.subs(xs).n(4)

```
Out[17]:
```

```
In [ ]:
```