L'équation différentielle du mouvement d'un pendule pesant non dissipatif est :
Pour le calcul numérique, on posera une période d'oscillations harmoniques égale à 1, c'est-à-dire :
L'intégrale première (énergie mécanique) est :
La fonction suivante effectue l'intégration numérique pour un angle initial non nul thetaInit et une vitesse initiale nulle, pendant une durée tmax.
solution[thetaInit_,tmax_]:=Module[{sys}, sys={theta'[t]==dtheta[t],dtheta'[t]==-4*Pi^2*Sin[theta[t]], theta[0]==thetaInit,dtheta[0]==0}; NDSolve[sys,{theta,dtheta},{t,0,tmax}, Method->{'ExplicitRungeKutta',DifferenceOrder->4}, AccuracyGoal->5,MaxSteps->Infinity] ]
On définit une fonction pour tracer le spectre en décibel, avec en argument : la sortie de la fonction solution ci-dessus, la durée totale tmax et la période d'échantillonnage te. La transformée de Fourier discrète et son utilisation avec Mathematica sont expliquées ici.
spectre[solution_,tmax_,te_]:=Module[{n,echant,tfd,sp}, n=tmax/te; echant=Table[First[theta[(k-1)*te]/.solution],{k,n}]; tfd=Fourier[echant,FourierParameters->{-1,-1}]; sp=Table[{(k-1)/tmax,20*Log[10,Abs[tfd[[k]]]]},{k,n}]; ListPlot[sp,PlotRange->{{0,1/te/2},{-100,0}},Joined->True] ]
Voici un exemple pour un angle initial de 0.1 radians. On trace la trajectoire dans le plan de phase.
tmax=100;
s1=solution[0.1,tmax]
p1=ParametricPlot[{theta[t],dtheta[t]/(2*Pi)}/.s1,{t,0,10},AxesLabel->{'theta','dtheta'}]plotA.pdf
Le spectre avec une période d'échantillonnage de 0.1 :
spectre[s1,tmax,0.1]plotB.pdf
Un angle plus grand donne lieu a des oscillations non harmoniques :
s2=solution[Pi/2,tmax]
p2=ParametricPlot[{theta[t],dtheta[t]/(2*Pi)}/.s2,{t,0,10},AxesLabel->{'theta','dtheta'}]plotC.pdf
Le spectre avec une période d'échantillonnage de 0.1 :
spectre[s2,tmax,0.1]plotD.pdf
On remarque une baisse de la fréquence d'oscillation et l'apparition d'une harmonique de rang 3. Voyons le résutat avec un angle initial proche de π :
s3=solution[3.1,tmax]
p3=ParametricPlot[{theta[t],dtheta[t]/(2*Pi)}/.s3,{t,0,10},AxesLabel->{'theta','dtheta'}]plotE.pdf
Le spectre avec une période d'échantillonnage de 0.1 :
spectre[s3,tmax,0.1]plotF.pdf
Pour ce dernier cas, traçons aussi l'énergie pour vérifier sa conservation :
Plot[0.5*dtheta[t]^2-(2*Pi)^2*Cos[theta[t]]/.s3,{t,0,tmax},PlotRange->{{0,tmax},{30,50}}, AxesLabel->{'t','Energie'}]plotG.pdf
Pour finir, les trois trajectoires dans l'espace des phases :
Show[p1,p2,p3,PlotRange->{{-3,3},{-3,3}}]plotH.pdf
Ci-dessous la fonction d'intégration numérique fournissant trois vecteurs (temps t, angle et dérivée y, énergie e). L'angle initial, le temps final et la période d'échantillonnage sont donnés en argument :
function [t,y,e]=solution(thetaInit,tmax,te), function [deriv]=systeme(t,y), deriv(1)=y(2), deriv(2)=-4*%pi^2*sin(y(1)), endfunction t=[0:te:tmax]; tolA=1d-7; tolR=1d-10; y=ode('adams',[thetaInit;0],0,t,tolR,tolA,systeme); n=length(y(1,:)); e=zeros(1,n); for k=1:n, e(k)=0.5*y(2,k)^2-4*%pi^2*cos(y(1,k)); end; endfunction
Fonction de tracé du spectre :
function spectre(y,tmax,te) tfd=fft(y); n=length(y); sp=zeros(1,n); f=zeros(1,n); for k=1:n, sp(k)=20*log10(abs(tfd(k))); f(k)=(k-1)/tmax; end; plot2d(f,sp,rect=[0,-50,1/te/2,100]); endfunction
Exemple pour un angle initial de 3.1 radians :
tmax=100;
[t,y1,e1]=solution(3.1,tmax,0.01);
plotK=scf(); plot2d(t,y1(1,:),rect=[0,-%pi,5,%pi]); xtitle('','t','theta');plotK.pdf
plotL=scf(); plot2d(t,e1,rect=[0,30,tmax,50]); xtitle('','t','energie');plotL.pdf
plotI=scf(); plot2d(y1(1,:),y1(2,:)) xtitle('','theta','dtheta');plotI.pdf
[t,y1,e1]=solution(3.1,tmax,0.1);
plotJ=scf(); spectre(y1(1,:),tmax,0.1); xtitle('','f','|Cn|');plotJ.pdf