2 % propagation visqueuse totale ou partielle
4 % pour le moment, il n'y a pas distinction entre les deux axes horizontaux,
5 % c'est du 3D planaire disons
16 % atmospheric data from USSA76
20 % altitude (0 - 500km)
22 % dérivée de la density
23 % dérivée du logarithme de la density
25 % tests à résolution variable
26 res = 1 % 10, 100, etc.
29 Z = modele1(binf:res:bsup,1);
30 rho = modele1(binf:res:bsup,2);
31 drho = modele1(binf:res:bsup,3);
32 dlgrho = modele1(binf:res:bsup,4);
35 n_mod = xx(1) % 9999 le nombre de modes (autant que de tranches
39 % calcul de la dérivée spatiale verticale
40 % TODO à vectoriser ^^
42 dz(j) = (Z(j+1)-Z(j))*1.e3; % pas spatial en mètres, utilisé dans les
43 end % dérivées en dz j'imagine
44 dz(n_mod) = dz(n_mod-1); % FIXME ajouté pour la version vectorisée, bof
45 dz = dz'; % multiplication matricielle plus bas
47 % conditions limites sur la vitesse horizontale : pour le calcul du gradient de vent
48 u0b = -50; % vitesse en bas (bottom)
49 u0t = -52; % vitesse en haut (top)
50 % en l'absence de profil des vents externes, on s'en crée un linéaire, basique
51 % coefficient d'un gradient linéaire des vents, égal à d(u0)/dz
52 alpha = (u0t-u0b)/((Z(n_mod)-Z(1))*1.e3);
53 % FIXME gruik pour le gradient linéaire
54 alpha_local = alpha.*ones(n_mod,1);
55 % profil des vitesses moyennes qui en découle
56 u0 = Z.*(1.e3*alpha) + u0b;
58 M = 5.9768e+24; % masse de la Terre
59 G = 6.67e-11; % constante gravitationnelle
60 R = 6378.e3; % rayon de la Terre
62 %----------------------------------
63 % omega, kx et ky à la main
64 %----------------------------------
66 T = [50 100 150].*60 % trois périodes de temps : 3000, 6000, 9000 secondes
67 wn = 2*pi./T; % les trois fréquences associées...
69 h = 2500; % hauteur de ?
71 c = sqrt(g*h); % vitesse de phase des ondes tsunamigéniques
72 % elle est imposée par continuité à l'interface, c'est
73 % une condition initiale/limite si on peut dire
74 kx = wn./c; % nombres d'ondes horizontaux
77 %----------------------------------
78 % itérateurs spatio-temporels
80 nlat = max(size(ky)); % en fait, on a fait en sorte que nlon = nlat...
84 %----------------------------------
86 % viscosité cinématique
87 % FIXME à récupérer comme data du modèle d'atmosphère
88 visc = 1.3e-5; % valeur moyenne pour commencer
91 %----------------------------------
93 % L'objectif est de calculer les modes pour les IGW, ie. la valeur des paramètres
94 % des équations du système à chaque altitude (« mode ») pour laquelle est fixé
95 % un kz approprié, sous la contrainte des conditions limites. La condition limite
96 % bottom fait office de condition initiale, couplée à une condition sur w, une
97 % condition sur P (continuité à l'interface).
99 % On considère trois périodes de temps, donc trois fréquences wn, donc trois
100 % nombre d'ondes k à travers la vitesse de phase imposée comme condition au limite
101 % implicite par continuité à l'interface. Il y a donc trois cas étudiés (ik).
102 % Pour chaque cas, on analyse les trois fréquences (iw). La boucle sur les iw
103 % résout le propagateur, sous les conditions initiales/limites.
104 %----------------------------------
108 %----------------------------------
112 % {{{ boucle sur les nombres d'onde (sur les longeurs d'onde), ici trois.
113 % une figure par mode ik
114 for ik = 1:nlon % (nlon-1)/2 + 2:nlon
116 drawnow; % DRAWNOW causes figure windows and their children to update and
117 % flushes the system event queue. Any callbacks generated by incoming
118 % events - e.g. mouse or key events - will be dispatched before
121 k = kx(ik) % nombre d'onde horizontal courant
123 figure(2*ik); % FIGURE(H) makes H the current figure, forces it to become visible,
124 % and raises it above all other figures on the screen. If Figure H
125 % does not exist, and H is an integer, a new figure is created with
127 set(2*ik, 'position', [44 250 500 750]);
128 set(gcf, 'Color', 'w');
129 set(gca, 'LineWidth', [2])
130 set(gca, 'fontsize', 18);
132 title(['Hwater = ', num2str(h), ' m and kx = ', num2str(k), ' rad/m'], 'fontsize', 18);
133 % xlabel('omega w (rad/s)', 'fontsize', 18);
134 xlabel('period T (min)', 'fontsize', 18);
135 ylabel('Vertical V_r_e_a_l (m/s)', 'fontsize', 18);
136 zlabel('altitude (km)', 'fontsize', 18);
141 set(2*ik+1, 'position', [44 250 500 750]);
142 set(gcf, 'Color', 'w');
143 set(gca, 'LineWidth', [2])
144 set(gca, 'fontsize', 18);
146 title(['Hwater = ', num2str(h), ' m and kx = ', num2str(k), ' rad/m'], 'fontsize', 18);
147 % xlabel('omega (rad/s)', 'fontsize', 18);
148 xlabel('period T (min)', 'fontsize', 18);
149 ylabel('Vertical V_i_m_a_g (m/s)', 'fontsize', 18);
150 zlabel('altitude (km)', 'fontsize', 18);
154 % FIXME relou ces figures :)
160 % {{{ boucle sur les trois fréquences par mode, sachant qu'un mode est une altitude ici
161 % avec nt = max(size(wn)) == 3 ici
162 for iw = 1:nt %(nt-1)/2 + 2:nt
164 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
165 % vectorisation en K*X = B
166 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
168 % {{{ constantes et utilitaires
171 N2over2g = (N2./(2*g)).^2;
173 BigOmega = omega - k.*u0; % FIXME k à vectoriser quand je passerai en full 3D
174 kxy2 = k^2; % FIXME no full 3D
175 phase = k - omega; % (pas unitaires) FIXME à modifier pour la full 3D
176 expniphase = exp(-i*phase); % FIXME vérifier cette formule
177 kz2 = k.*k.*(N2./omega./omega - 1) - N2over2g;
179 % pour le cas visqueux
180 BigGamma = BigOmega + i*visc*kxy2;
181 BigGammadz = BigGamma.*dz;
182 BigGammadz2 = BigGammadz.*dz;
183 phi = 2.*visc.*sqrt(rho);
184 phiOverBigGammadz2 = phi./BigGammadz2;
188 % {{{ résolution vectorielle en différences finies
190 % {{{ coefficients de propagation non visqueuse, hors des conditions initiales
192 c1 = -(-k.*alpha.*2.*dz./BigOmega + dlgrho.*dz);
193 c2 = -i.*k.*k.*2.*dz./BigOmega;
195 c4 = -(i.*2.*dz.*(BigOmega + dlgrho.*g./BigOmega)); % }}}
197 % {{{ coefficients de propagation visqueuse, hors des conditions initiales
199 % coefficients pour la perturbation de la vitesse horizontale
200 cu1 = 1 + i.*phiOverBigGammadz2;
201 cu2 = i./2.*phiOverBigGammadz2;
205 cu5(j) = (i*(u0(j+1) - u0(j-1)))/(2*BigGammadz(j));
207 % TODO FIXME à terme, il faudra peut-être adopter cette technique du step-forward d'orde 1 pour les conditions au sommet pour d'autres coefficients ?
208 cu5(n_mod) = (i*(u0(n_mod) - u0(n_mod-1)))/(BigGammadz(n_mod));
211 % coefficients pour la perturbation de la vitesse verticale
212 cw1 = -(dz.*dlgrho - 2.*k.*alpha./BigGamma);
213 cw2 = 2.*i.*kxy2.*dz./BigGamma;
214 cw3 = -(k.*phiOverBigGammadz2);
215 cw4 = 2.*k.*phiOverBigGammadz2;
216 cw5 = -(phiOverBigGammadz2);
218 % coefficients pour la perturbation de pression
220 cp2 = 2.*i.*(BigOmega + g./BigOmega.*dlgrho + i.*visc.*kxy2) + 2.*phi./dz;
224 % {{{ conditions initiales et coefficients associés
228 % C.I.1 pour les perturbations de vitesse verticale et de pression
229 % on se donne une perturbation unitaire, dans l'optique de l'étude des modes
234 kz2 = k*k*(-g/omega/omega*dlgrho(1) - 1) - 0.25/6.4e7;
236 if N2(1) >= omega*omega
237 % cas d'une onde propagative
238 p(1) = i/(k*k)*(alpha_local(1)*k - i*sqrt(kz2(1))*(omega - k*u0(1)) - 0.5*(omega - k*u0(1))*dlgrho(1))*w1;
240 % cas d'une onde non propagative
241 p(1) = i/(k*k)*(alpha_local(1)*k - sqrt(kz2(1))*(omega - k*u0(1)) - 0.5*(omega - k*u0(1))*dlgrho(1))*w1;
244 % C.I.1 pour la perturbation de la vitesse horizontale
245 % FIXME je trouve un facteur 1/rho0 pour u(j)
246 % u(j) = 1/BigOmega(j) * (k*p(j) - i*alpha*w(j));
247 % d'où les coefficients :
248 ui1 = -i*alpha_local(1)*w(1);
250 % par ailleurs, ces valeurs explicites sont nécessaires :
251 % C.I.1 perturbation horizontale
252 u(1) = 1/BigOmega(1) * (k*p(1) - i*alpha*w(1));
256 % {{{ C.I. au premier pas de temps (2)
258 b1 = -(-i*k*dz(1) * (1 / BigOmega(1) * (-i*alpha)) + 0.5*dlgrho(1)*dz(1) + 1);
259 b2 = -(-i*k*dz(1) * (1 / BigOmega(1) * (k)));
260 b3 = -(-0.5*dlgrho(1)*dz(1) + 1);
261 b4 = -(i*BigOmega(1)*dz(1) + i/BigOmega(1)*dlgrho(1)*dz(1)*g);
262 ui3 = -i*alpha_local(2)/BigOmega(2);
265 % C.I. au premier pas de temps (2) }}}
267 % conditions initiales et coefficients associés }}}
269 % {{{ construction de la matrice creuse
271 % construction des diagonales i.e. des vecteurs colonnes alternés, pour spdiags()
273 % attention, il faut faire une permutation circulaire* pour les diagonales d'indices impairs, de façon à avoir le bon coefficient sur la première ligne. Ici, permutations d'ordre 3, selon le numéro de colonne
275 % construction : deux lignes, puis lecture globale (colonne par colonne, donc en alternant les valeurs -- ex. si une ligne de 1 et une ligne de 0, donnera une suite de 1 et 0 alternés)
276 % {{{ FIXME diagonales pour le cas non visqueux
278 %C2 = [zeros(1, size(c2,1)); c2']; % *
279 %C4 = [c4'; zeros(1, size(c4,1))]; % *
283 %% FIXME pb de signe ici ! en attendant, je mets un moins pour retrouver
284 %% des parties imaginaires positives...
287 %% matrice des conditions limites
289 %cl1 = [b1 b2 1 0; b4 b3 0 1];
290 %%cl = [cl0 zeros(size(cl0,1), n_mod-size(cl0,1)) ; cl1 zeros(size(cl1,1), n_mod-size(cl1,1))]
292 %cl = [cl0 zeros(2, n_mod2-2) ; cl1 zeros(2, n_mod2-4)];
294 %% construction de la matrice creuse des coefficients du système linéaire pour
295 %% l'itération en différences finies
296 %% partie utile de la matrice diagonale à laquelle sont ajoutées les 2*2
297 %% conditions limites/initiales
299 %plop = ones(n_mod2, 1);
300 %preK = spdiags([-plop diagC4 diagC13 diagC2 plop], 0:4, n_mod2, n_mod2);
301 %preK = preK(1:n_mod2 - 4, :);
309 %%Kf(n_mod2-7:end,n_mod2-7:end)
313 % {{{ diagonales pour le cas visqueux
316 dimvisc = size(cu1, 1);
317 myones = ones(1, dimvisc);
318 myzeros = zeros(1,dimvisc);
320 % diagonales alternées (les * dénotent celles affectées d'une permutation circulaire)
321 diag1 = [cw5'; cw4'; myzeros]; % *
324 diag2 = [cu2'; -myones; -myones];
327 diag3 = [myzeros myzeros myzeros]; % *
330 diag4 = [cp2'; myzeros; cw4']; %*
333 diag5 = [cu1'; cw1'; cp2'];
336 diag6 = [cw2'; myzeros; cu5']; % *
339 diag7 = [cp3'; cu4'; cw3']; % *
342 diag8 = [cu3'; myones; myones];
347 % {{{ matrices des conditions initiales
349 ci0 = [1 ui1 ui2; ...
353 ci1 = [0 0 0 1 ui3 ui4; ...
358 ci = [ci0 zeros(3, n_mod3-3) ; ci1 zeros(3, n_mod3-6)];
362 % {{{ construction effective de la matrice creuse
364 % construction de la matrice creuse des coefficients du système linéaire pour
365 % l'itération en différences finies
366 % partie utile de la matrice diagonale à laquelle sont ajoutées les 2*2
367 % conditions limites/initiales
369 preK = spdiags([diag1 diag2 diag3 diag4 diag5 diag6 diag7 diag8], ...
370 -1:6, n_mod3, n_mod3);
371 preK = preK(1:n_mod3 - 6, :);
381 %Kf(n_mod2-7:end,n_mod2-7:end)
384 % construction de la matrice creuse }}}
386 % {{{ construction du second membre
388 % on construit le vecteur B des seconds membres (SM), avec :
389 % - une partie conditions initiales
390 % - TODO éventuellement, une partie de propagation non visqueuse (SM = 0)
391 % ce qui nécessite de modifier K !
392 % - une partie de propagation visqueuse avec les SM appropriés
394 % {{{ calculs des seconds membres visqueux
396 % TODO il faut éventuellement calculer un linspace des u0 à partir du gradient linéaire, si on utilise pas de profil de vents. Pour les profils de vents, s'il n'y a pas le même nombre de pas en espace, il faut également faire des linspaces entre les points de donnée (interpolations linéaires)
398 sm_tmp = (phi(j)/(BigGamma(j)*dz(j)))*expniphase*(u0(j+1) - 2*u0(j) + u0(j-1));
400 sm_tmp(n_mod) = (phi(n_mod)/(BigGamma(n_mod)*dz(n_mod-1)))*expniphase*(u0(n_mod) - 2*u0(n_mod-1) + u0(n_mod-2));
404 sm_p = zeros(1,n_mod-6);
406 % vecteur des valeurs alternées
407 sm = [sm_u'; sm_w'; sm_p'];
415 B = [u(1); w(1); p(1); ... % conditions initiales
416 0; 0; 0; ... % le premier pas est non visqueux
417 sm ... % la propagation visqueuse implique des termes non nuls,
418 ]; % tous calculés a priori avec les données du problème
423 % construction du second membre }}}
425 % {{{ résolution du système linéaire K*X = B
436 % résolution de K*X = B }}}
438 % résolution vectorielle en différences finies }}}
440 % {{{ résultats et calculs finaux
442 % récupération des résultats en w et p
447 % calcul des kz explicites
448 % FIXME coefficient à remplacer par la formule analytique, non ?
449 kz2 = (k*k).*((-g/omega/omega).*dlgrho-1) - 0.25/6.4e7;
451 % calcul des rho1 explicites
452 rho1 = (-i.*dlgrho.*w)./BigOmega;
454 % résultats et calculs finaux }}}
456 % {{{ post-processing pour le pas courant
458 wmax(ik, iw) = max(abs(real(w)));
459 umax(ik, iw) = max(abs(real(u)));
460 pmax(ik, iw) = max(abs(real(p)));
461 rhomax(ik, iw) = max(abs(real(rho1)));
462 KZ(ik, iw, :) = sqrt(kz2);
464 if max(abs(real(w))) >= 2.
470 if sqrt(kz2(j)) >= 2*pi/50.e3
477 set(100, 'position', [10 1 750 600])
478 set(gcf, 'Color', 'w');
484 plot(real(w), Z, 'r', 'linewidth', 2);
486 plot(imag(w), Z, 'g', 'linewidth', 2);
488 %axis([-2 2 0 max(Z)])
490 axis([v(1) v(2) Zmin Zmax])
491 xlabel('Vertical V (m/s)', 'fontsize', 12);
492 ylabel('Altitude (km)', 'fontsize', 16);
493 title(['omega = ', num2str(omega), ' rad/s'], 'fontsize', 12);
495 plot(real(u), Z, 'r', 'linewidth', 2);
497 plot(imag(u), Z, 'g', 'linewidth', 2);
499 %axis([-20 20 0 max(Z)])
501 axis([v(1) v(2) Zmin Zmax]);
502 xlabel('Horizontal V (m/s)', 'fontsize', 12);
504 plot(real(p), Z, 'r', 'linewidth', 2);
506 plot(imag(p), Z, 'g', 'linewidth', 2);
508 %axis([-3000 3000 0 max(Z)])
510 axis([v(1) v(2) Zmin Zmax]);
511 xlabel('Pressure (Pa)', 'fontsize', 12);
513 plot(real(rho1), Z, 'r', 'linewidth', 2);
515 plot(imag(rho1), Z, 'g', 'linewidth', 2);
517 %axis([-0.1 0.1 0 max(Z)])
519 axis([v(1) v(2) Zmin Zmax]);
520 xlabel('Density (kg/m3)', 'fontsize', 12);
521 title(['kx = ', num2str(k), ' rad/m'], 'fontsize', 12);
525 [X, Map] = frame2im(F);
526 file = ['Earth_Mode_L' num2str(round(1/k*1.e-3)) '_T_' num2str(2*pi/omega/60) '.tif'];
527 imwrite(X, file, 'tif', 'Compression', 'none');
529 disp('PRESS ENTER TO CONTINUE...');
535 plot(real(sqrt(kz2)), Z, 'r');
537 plot(imag(sqrt(kz2)), Z, 'g');
538 xlabel('kz (rad/m)', 'fontsize', 12);
539 ylabel('Altitude (km)', 'fontsize', 16);
542 plot(sqrt(N2), Z, 'r');
545 plot([omega omega], [v(3) v(4)], 'g');
547 xlabel('N and omega (rad/s)', 'fontsize', 12);
549 plot(2*pi./real(sqrt(kz2))*1.e-3, Z, 'r');
551 plot(2*pi./imag(sqrt(kz2))*1.e-3, Z, 'g');
553 xlabel('lambda Z (km)', 'fontsize', 12);
559 plot3(I*2*pi/omega/60, real(w), Z, 'k');
560 plot3(I*2*pi/omega/60, imag(w), Z, 'r');
563 plot3(I*2*pi/omega/60, imag(w), Z, 'k');
567 % post-processing pour le pas courant }}}
572 % boucle sur les trois fréquences }}}
574 % {{{ post-processing
577 Nmax = max(sqrt(N2));
578 Nmin = min(sqrt(N2));
587 set(h, 'position', [2 700 800 600]);
588 set(gcf, 'Color', 'w');
592 flag_plot = input('-Plot omega-k or T-lambda ? (0 or 1) ');
596 pcolor(wn(n1:nt), kx(n2:nlon), log10(wmax(:,1+njump:njump2(2))));
598 pcolor(2*pi./wn(n1:nt)/60, 2*pi./kx(n2:nlon)*1.e-3, log10(wmax(:,1+njump:njump2(2))));
603 plot([Nmax Nmax], [v(3) v(4)], 'k');
604 plot([Nsol Nsol], [v(3) v(4)], 'k');
605 plot([Nmin Nmin], [v(3) v(4)], 'k');
607 title('W_r_e_a_l', 'fontsize', font_size);
609 ylabel('kx (rad/m)', 'fontsize', font_size);
611 ylabel('lambda (km)', 'fontsize', font_size);
613 set(gca, 'LineWidth', [2])
614 set(gca, 'fontsize', font_sizeN);
618 pcolor(wn(n1:nt), kx(n2:nlon), log10(umax(:,1+njump:njump2(2))));
620 pcolor(2*pi./wn(n1:nt)/60, 2*pi./kx(n2:nlon)*1.e-3, log10(umax(:,1+njump:njump2(2))));
625 plot([Nmax Nmax], [v(3) v(4)], 'k');
626 plot([Nsol Nsol], [v(3) v(4)], 'k');
627 plot([Nmin Nmin], [v(3) v(4)], 'k');
629 title('U_r_e_a_l', 'fontsize', font_size);
630 set(gca, 'LineWidth', [2])
631 set(gca, 'fontsize', font_sizeN);
635 pcolor(wn(n1:nt), kx(n2:nlon), log10(pmax(:,1+njump:njump2(2))));
637 pcolor(2*pi./wn(n1:nt)/60, 2*pi./kx(n2:nlon)*1.e-3, log10(pmax(:,1+njump:njump2(2))));
642 plot([Nmax Nmax], [v(3) v(4)], 'k');
643 plot([Nsol Nsol], [v(3) v(4)], 'k');
644 plot([Nmin Nmin], [v(3) v(4)], 'k');
647 ylabel('kx (rad/m)', 'fontsize', font_size);
648 xlabel('omega (rad/s)', 'fontsize', font_size);
650 ylabel('lambda (km)', 'fontsize', font_size);
651 xlabel('period T (min)', 'fontsize', font_size);
653 title('P_r_e_a_l', 'fontsize', font_size);
654 set(gca, 'LineWidth', [2])
655 set(gca, 'fontsize', font_sizeN);
659 pcolor(wn(n1:nt), kx(n2:nlon), log10(rhomax(:,1+njump:njump2(2))));
661 pcolor(2*pi./wn(n1:nt)/60, 2*pi./kx(n2:nlon)*1.e-3, log10(rhomax(:,1+njump:njump2(2))));
666 plot([Nmax Nmax], [v(3) v(4)], 'k');
667 plot([Nsol Nsol], [v(3) v(4)], 'k');
668 plot([Nmin Nmin], [v(3) v(4)], 'k');
671 xlabel('omega (rad/s)', 'fontsize', font_size);
673 xlabel('period T (min)', 'fontsize', font_size);
675 title('Rho_r_e_a_l', 'fontsize', font_size);
676 set(gca, 'LineWidth', [2])
677 set(gca, 'fontsize', font_sizeN);
679 % post-processing }}}