Standing waves

Standing waves#

Introduction#

Wait a few seconds until Python interaction ready! is shown in the top.

After that follow the instructions in the Grasple Exercise.

On this webpage the wave equation

\[ \frac{\partial^2 u}{\partial t^2}=\frac{\partial ^2u}{\partial x^2} \]

for \(x\in (0,\pi),\ t>0\) is considered for an elastic string.

The initial and boundary conditions are

\[\begin{split} \begin{align*} u(0,t) &= 0, \\ u(\pi,t) &= 0, \\ \frac{\partial u}{\partial t}(x,0) &= 0. \end{align*} \end{split}\]

This webpage constructs the natural modes of vibration of the exact solution \(u(x,t)\) of this problem using numpy, and then uses numpy and pyplot to display the obtained exact values.

import micropip
await micropip.install("ipympl")
import matplotlib
if not hasattr(matplotlib.rcParams, '_get'):
    matplotlib.rcParams._get = matplotlib.rcParams.get
%matplotlib widget
import numpy as np
import matplotlib.pyplot as plt
from IPython.display import HTML, Markdown, clear_output
import matplotlib.animation as animation
from matplotlib.lines import Line2D
# matplotlib.rcParams['animation.embed_limit'] = 2**128
import warnings
warnings.filterwarnings("ignore")

class SubplotAnimation(animation.TimedAnimation):
    def __init__(self,n,m):
        
        self.N = n
        self.M = m
        
        fig = plt.figure(4)
        self.ax1 = fig.add_subplot(1, 1, 1)
        
        self.t = np.linspace(0, 4*np.pi, 401)
        
        self.ax1.set_title('$t$ = %1.2f' % (0))
        self.line1 = Line2D([], [], color='black')
        self.line1e = Line2D(
            [], [], color='black', marker='o', markeredgecolor='black',linestyle='None')
        self.ax1.add_line(self.line1)
        self.ax1.add_line(self.line1e)
        self.ax1.set_xlim(-0.1, np.pi+0.1)
        self.ax1.set_ylim(-1.5, 1.5)
        self.ax1.axis('off')
        
        animation.TimedAnimation.__init__(self, fig, interval=100, blit=True,repeat=False)
        
        plt.close(fig);

    def _draw_frame(self, framedata):
        i = framedata
        
        x = np.linspace(0,np.pi,101)
        self.line1.set_data(x, np.sin(self.N*x)*np.cos(self.N*self.t[i])+1/2*np.sin(self.M*x)*np.cos(self.M*self.t[i]))
        if self.M == 0:
            xnodes = np.linspace(0,np.pi,num=self.N+1)
            ynodes = np.zeros_like(xnodes)
        elif self.M % self.N == 0 or self.N % self.M == 0:
            xnodes = np.linspace(0,np.pi,num=np.min([self.N,self.M])+1)
            ynodes = np.zeros_like(xnodes)
        else:
            xnodes = np.array([0,np.pi])
            ynodes = np.zeros_like(xnodes)
        self.line1e.set_data(xnodes,ynodes)
        
        self.ax1.set_title('$t$ = %1.2f$\pi$' % (self.t[i]/np.pi))

        self._drawn_artists = [self.line1, self.line1e]

    def new_frame_seq(self):
        return iter(range(self.t.size))

    def _init_draw(self):
        lines = [self.line1, self.line1e]
        for l in lines:
            l.set_data([], [])

def Standing_waves(n,m):
    
    ani = SubplotAnimation(n,m)
    clear_output()
    display(Markdown('# The animation is being rendered, please be patient.'))
    ani_jshtml = ani.to_jshtml()
    ani_html = HTML(ani_jshtml)
    clear_output()
    display(ani_html)
    display(Markdown('# You can slow down the animation (if you want) by using the - button.'))
    
    pass

INPUT CELL#

In the cell below you should put the values of the parameters you see in Grasple.

Please note: Each attempt in Grasple contains different values for the parameters.

After you run the cell the results of the calculations are shown with the set parameter values.

Blow the figure are controls that you can use to manipulate the animation.

''' Set the given values/functions in the following lines '''
n = 9
m = 3

''' The next line performs the calculations and shows the results. '''
Standing_waves(n,m)