```python
import matplotlib.pyplot as plt
import numpy as np
from scipy import optimize
```

To solve the complicated, typically transcendental equations we come across, we can use the `scipy.optimize.root_scalar()` function. To do this, we need to create a function that returns the difference between the left-hand and right-hand sides of the equation we're solving.

In this example, let's solve the equation relating $M_1$, $M_2$, $A_2/A_1$, and $\gamma$:
\begin{equation}
\frac{A_2}{A_1} = \frac{M_1}{M_2} \left[ \frac{1 + \frac{\gamma-1}{2} M_2^2}{1 + \frac{\gamma-1}{2} M_1^2} \right]^{\frac{\gamma+1}{2(\gamma-1)}} e^{\Delta s/R}
\end{equation}
for $M_2$ if we know $M_1$, $A_2/A_1$, and $\gamma$.

To do this, we'll create a function `fA()` that takes as arguments $M_2$, $M_1$, $A_2/A_1$, and $\gamma$. It codes the Equation 1 as
\begin{equation}
\frac{A_2}{A_1} - \frac{M_1}{M_2} \left[ \frac{1 + \frac{\gamma-1}{2} M_2^2}{1 + \frac{\gamma-1}{2} M_1^2} \right]^{\frac{\gamma+1}{2(\gamma-1)}} e^{\Delta s/R} = 0
\end{equation}


```python
def fA(M2, M1, A_ratio, gamma):
    '''Function for equation relating Mach numbers and area ratio.
    '''
    return A_ratio - (M1/M2) * ((1 + ((gamma-1)/2.)*M2**2)/(1 + ((gamma-1)/2.)*M1**2))**((gamma + 1)/(2*(gamma-1)))
```

Then, we'll specify the known quantities and call the `root_scalar()` function, specifying the function to solve `fA` as the first parameter.

`root_scalar()` expects the first parameter in the function `fA` to be the unknown it is solving for. We can also pass through the other arguments as known constants using the `args` parameter. We can also help it find the correct solution by indicating a subsonic or supersonic solution with the `bracket` parameter.


```python
M1 = 0.5
A_ratio = 5/2
gamma = 1.4
root = optimize.root_scalar(fA, # This is the function we are solving
                            args=(M1, A_ratio, gamma),
                            # give a range for the solution
                            bracket=[1.0001, 10.0]
                            )
print(root)
```

          converged: True
               flag: 'converged'
     function_calls: 15
         iterations: 14
               root: 2.753763176695055


Instead of solving equations directly, we can use the helpful tabulated results available in the back of the textbook (as long as we are dealing with air, or at least an ideal diatomic gas where $\gamma = 1.4$). 

However, often our problems don't fall exactly on the numbers provided, so we need to use interpolation for an accurate answer. We can do this easily with the `numpy.interp()` function.

In this example, we want to find the ratio $\frac{p}{p_t}$ associated with $M = 1.715$. To do that, we create lists of $M$ and $\frac{p}{p_t}$ surrounding the point of interest, t


```python
machs = [1.70, 1.71, 1.72, 1.73, 1.74]
p_ratios = [0.20259, 0.19956, 0.19656, 0.19361, 0.19070]
np.interp(1.715, machs, p_ratios)
```




    0.19805999999999996



You can also work the other way, but the `np.interp()` function expects the x list to be *increasing*, so we need to reverse the order of both lists.


```python
np.interp(0.198, p_ratio[::-1], M[::-1])
```




    1.7151999999999998




```python

```

a71fd0854701f250bb5c6c3b74d06aa63d4aafd2
ipynb
Jupyter Notebook
solution-approaches.ipynb
kyleniemeyer/gasdynamics
50dce7a030daa2757aa55cf6c9a5ae66d079ab72
MIT
2019-10-17T18:21:23.000Z
2021-08-17T19:30:07.000Z
solution-approaches.ipynb
kyleniemeyer/gasdynamics
50dce7a030daa2757aa55cf6c9a5ae66d079ab72
MIT
solution-approaches.ipynb
kyleniemeyer/gasdynamics
50dce7a030daa2757aa55cf6c9a5ae66d079ab72
MIT
Qwen/Qwen-72B
1. YES
2. YES