# Linear roll motion analytical solution
As decribed by Journee, Peter Piel etc.


```python
%matplotlib inline
%load_ext autoreload
%autoreload 2
```


```python
#from jupyterthemes import jtplot
#jtplot.style(theme='chesterish', context='notebook', ticks=True, grid=False)
```


```python
import sympy as sp
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

from sympy.physics.mechanics import dynamicsymbols

from rolldecay.symbols import *
from rolldecay import equations
import rolldecayestimators.equations
from rolldecayestimators.substitute_dynamic_symbols import lambdify
from rolldecayestimators import symbols
from rolldecayestimators import direct_linear_estimator

from sympy.physics.vector.printing import vpprint, vlatex
from IPython.display import display, Math, Latex
from rolldecay import paper_writing
```

## General Linear ordinary differential equation:


```python
Math(vlatex(equations.diff_eq))
```


```python
equations.equation_D
```


```python
Math(vlatex(equations.analytical_solution_general))
```


```python
Math(vlatex(equations.analytical_solution))
```


```python
Math(vlatex(equations.analytical_phi1d))
```


```python
Math(vlatex(equations.analytical_phi2d))
```


```python
Math(vlatex(rolldecayestimators.equations.extinction_equation))
```


```python
Math(vlatex(rolldecayestimators.equations.xeta_equation))
```


```python
analytical_solution_lambda = lambdify(sp.solve(equations.analytical_solution,phi)[0])
analytical_solution_phi1d_lambda = lambdify(sp.solve(equations.analytical_phi1d,phi_dot)[0])
analytical_solution_phi2s_lambda = lambdify(sp.solve(equations.analytical_phi2d,phi_dot_dot)[0])
extintion_equation_lambda = lambdify(sp.solve(rolldecayestimators.equations.extinction_equation,symbols.phi_a)[0])
```


```python
time = np.linspace(0,100,1000)
df = pd.DataFrame(index=time)
df['t']=time
df['zeta'] = 0.1
df['omega0'] = 0.5
df['phi_0'] = np.deg2rad(10)
df['phi_01d'] = 0.0

result = df.copy()
result['phi'] = analytical_solution_lambda(**df,)
result['phi1d'] = analytical_solution_phi1d_lambda(**df,)
result['phi2d'] = analytical_solution_phi2s_lambda(**df,)
result['phi_a'] = extintion_equation_lambda(omega0=df['omega0'], t=df['t'], zeta=df['zeta'], 
                                            phi_0=df['phi_0'])
```


```python
fig,ax = plt.subplots()
result['phi_deg']=np.rad2deg(result['phi'])
result['phi_a_deg']=np.rad2deg(result['phi_a'])

result.plot(y='phi_deg', label='motion', ax=ax);
result.plot(y='phi_a_deg', label='amplitude', ax=ax);

ax.grid(True)
ax.set_xlabel('Time [s]')
ax.set_ylabel('Ship roll anlge [deg]')
ax.set_title('Ship roll decay test');


```


```python
with plt.style.context('grayscale'):
    
    fig,ax = plt.subplots()
    result['phi_deg']=np.rad2deg(result['phi'])
    result['phi_a_deg']=np.rad2deg(result['phi_a'])
    
    result.plot(y='phi_deg', label='motion', ax=ax);
    result.plot(y='phi_a_deg', label='amplitude', ax=ax);
    
    ax.grid(True)
    ax.set_xlabel('Time [s]')
    ax.set_ylabel('Ship roll anlge [deg]')
    ax.set_title('Ship roll-decay test')
    fig.savefig(fname='../../../roll-decay-logo.png',dpi=100)
```

### Numerical solution


```python
s0 = df.iloc[0]
linear_estimator = direct_linear_estimator.DirectLinearEstimator.load(omega0=s0['omega0'], 
                                       zeta=s0['zeta'])


time=np.array(df['t'])
result_sim = linear_estimator.simulate(t=time,phi0=s0['phi_0'],
                                       phi1d0=s0['phi_01d'], 
                                       )
result_sim = result_sim.combine_first(df)
```


```python
fig,axes = plt.subplots(nrows = 3)
fig.set_size_inches(15,10)
keys = ['phi','phi1d','phi2d']
labels = ['$\Phi$ [rad]','$\dot{\Phi}$ [rad/s]','$\ddot{\Phi}$ $[rad/s^2]$']
for ax, key, label in zip(axes,keys, labels):
    result.plot(y=key, ax=ax, label='analytical')
    result_sim.plot(y=key, ax=ax, label='numerical',style='--')
    
    
    ax.set_ylabel(label)
    
ax.set_xlabel('Time [s]');
axes[0].set_title('Solutions to linear roll motion ($\omega_0$:%0.1f [rad/s], $\zeta$:%0.1f [-])' % 
             (df.iloc[0]['omega0'], df.iloc[0]['zeta']));

paper_writing.save_fig(fig=fig, name='analytical')
```


```python
from ipywidgets import interactive
```


```python
time = np.linspace(0,100,300)
df = pd.DataFrame(index=time)
df['t']=time
```


```python
def f(zeta=0.1,omega0=0.5,phi_0=10):
    fig,ax = plt.subplots()
    ax.set_xlim(0,time[-1])
    ax.set_ylim(-10,10)
    fig.set_size_inches(15,5)
    
    df['zeta'] = zeta
    df['omega0'] = omega0
    df['phi_0'] = np.deg2rad(phi_0)
    df['phi_01d'] = 0

    result = df.copy()
    result['phi'] = analytical_solution_lambda(**df,)
    result['phi']=np.rad2deg(result['phi'])
    ax.set_ylabel('Roll angle $\Phi$ [deg]')
    ax.set_xlabel('Time [s]')
    result.plot(y='phi', ax=ax)
    
    plt.show()

interactive_plot = interactive(f, zeta=(0.05,0.30, 0.01), omega0=(0.1,1,0.05), phi_0=(1.0,10.0,0.5))
output = interactive_plot.children[-1]
output.layout.height = '350px'
interactive_plot
```


```python

```


```python

```


```python

```

2e0a7976c9b8f707fd749ee6a4efbe42ce8c2004
ipynb
Jupyter Notebook
notebooks/rolldecay/02_roll_damping_DB/00.5_maa_linear_damping_analytical_solution.ipynb
martinlarsalbert/rolldecay
bee335c27e6519bd32ed9488751bc13e7f6fa9b3
MIT
notebooks/rolldecay/02_roll_damping_DB/00.5_maa_linear_damping_analytical_solution.ipynb
martinlarsalbert/rolldecay
bee335c27e6519bd32ed9488751bc13e7f6fa9b3
MIT
2021-02-02T23:07:50.000Z
2022-01-13T03:27:41.000Z
notebooks/rolldecay/02_roll_damping_DB/00.5_maa_linear_damping_analytical_solution.ipynb
martinlarsalbert/rolldecay
bee335c27e6519bd32ed9488751bc13e7f6fa9b3
MIT
Qwen/Qwen-72B
1. YES
2. YES