1 |
module grid_atob |
module grille_m_m |
2 |
|
|
3 |
! From grid_atob.F,v 1.1.1.1 2004/05/19 12:53:05 |
! From grid_atob.F, v 1.1.1.1, 2004/05/19 12:53:05 |
4 |
|
|
5 |
IMPLICIT none |
IMPLICIT none |
6 |
|
|
8 |
|
|
9 |
function grille_m(xdata, ydata, entree, x, y) |
function grille_m(xdata, ydata, entree, x, y) |
10 |
|
|
11 |
!======================================================================= |
! Z. X. Li (1er avril 1994) (voir aussi A. Harzallah et L. Fairhead) |
|
! Z. X. Li (le 1 avril 1994) (voir aussi A. Harzallah et L. Fairhead) |
|
12 |
|
|
13 |
! Méthode naïve pour transformer un champ d'une grille fine à une |
! M\'ethode na\"ive pour transformer un champ d'une grille fine \`a une |
14 |
! grille grossière. Je considère que les nouveaux points occupent |
! grille grossi\`ere. Je consid\`ere que les nouveaux points occupent |
15 |
! une zone adjacente qui comprend un ou plusieurs anciens points |
! une zone adjacente qui comprend un ou plusieurs anciens points. |
|
|
|
|
! Aucune pondération n'est considérée (voir grille_p) |
|
|
|
|
|
! (c) |
|
|
! ----d----- |
|
|
! | . . . .| |
|
|
! | | |
|
|
! (b)a . * . .b(a) |
|
|
! | | |
|
|
! | . . . .| |
|
|
! ----c----- |
|
|
! (d) |
|
|
!======================================================================= |
|
|
! INPUT: |
|
|
! imdep, jmdep: dimensions X et Y pour depart |
|
|
! xdata, ydata: coordonnees X et Y pour depart |
|
|
! entree: champ d'entree a transformer |
|
|
! OUTPUT: |
|
|
! imar, jmar: dimensions X et Y d'arrivee |
|
|
! x, y: coordonnees X et Y d'arrivee |
|
|
! grille_m: champ de sortie deja transforme |
|
|
!======================================================================= |
|
16 |
|
|
17 |
|
! Aucune pond\'eration n'est consid\'er\'ee (voir |
18 |
|
! grille_p). Cf. grille_m.txt. |
19 |
|
|
20 |
|
use dist_sphe_m, only: dist_sphe |
21 |
use nr_util, only: assert_eq |
use nr_util, only: assert_eq |
22 |
|
|
23 |
REAL, intent(in):: xdata(:),ydata(:) |
! Coordonn\'ees : |
24 |
REAL, intent(in):: entree(:, :) |
REAL, intent(in):: xdata(:) ! (imdep) |
25 |
REAL, intent(in):: x(:), y(:) |
REAL, intent(in):: ydata(:) ! (jmdep) |
26 |
|
|
27 |
|
REAL, intent(in):: entree(:, :) ! (imdep, jmdep) champ \`a transformer |
28 |
|
|
29 |
real grille_m(size(x), size(y)) |
! Coordonn\'ees : |
30 |
|
REAL, intent(in):: x(:) ! (imar) |
31 |
|
REAL, intent(in):: y(:) ! (jmar) |
32 |
|
|
33 |
! Variables local to the procedure: |
real grille_m(size(x), size(y)) ! (imar, jmar) champ transform\'e |
34 |
|
|
35 |
|
! Local: |
36 |
INTEGER imdep, jmdep, imar, jmar |
INTEGER imdep, jmdep, imar, jmar |
37 |
INTEGER i, j, ii, jj |
INTEGER i, j, ii, jj |
38 |
REAL a(2200),b(2200),c(1100),d(1100) |
REAL a(size(x)), b(size(x)) ! (imar) |
39 |
REAL number(2200,1100) |
real c(size(y)), d(size(y)) ! (jmar) |
40 |
REAL distans(2200*1100) |
REAL number(size(x), size(y)) ! (imar, jmar) |
41 |
|
REAL distans(size(xdata) * size(ydata)) ! (imdep * jmdep) |
42 |
INTEGER i_proche, j_proche, ij_proche |
INTEGER i_proche, j_proche, ij_proche |
43 |
REAL zzmin |
REAL zzmin |
44 |
|
|
45 |
!------------------------- |
!------------------------- |
46 |
|
|
|
print *, "Call sequence information: grille_m" |
|
|
|
|
47 |
imdep = assert_eq(size(xdata), size(entree, 1), "grille_m") |
imdep = assert_eq(size(xdata), size(entree, 1), "grille_m") |
48 |
jmdep = assert_eq(size(ydata), size(entree, 2), "grille_m") |
jmdep = assert_eq(size(ydata), size(entree, 2), "grille_m") |
49 |
imar = size(x) |
imar = size(x) |
50 |
jmar = size(y) |
jmar = size(y) |
51 |
|
|
|
IF (imar.GT.2200 .OR. jmar.GT.1100) THEN |
|
|
PRINT*, 'imar ou jmar trop grand', imar, jmar |
|
|
STOP 1 |
|
|
ENDIF |
|
|
|
|
52 |
! Calculer les limites des zones des nouveaux points |
! Calculer les limites des zones des nouveaux points |
53 |
|
|
54 |
a(1) = x(1) - (x(2)-x(1))/2.0 |
a(1) = x(1) - (x(2)-x(1))/2.0 |
71 |
|
|
72 |
DO i = 1, imar |
DO i = 1, imar |
73 |
DO j = 1, jmar |
DO j = 1, jmar |
74 |
number(i,j) = 0.0 |
number(i, j) = 0.0 |
75 |
grille_m(i,j) = 0.0 |
grille_m(i, j) = 0.0 |
76 |
ENDDO |
ENDDO |
77 |
ENDDO |
ENDDO |
78 |
|
|
81 |
DO ii = 1, imar |
DO ii = 1, imar |
82 |
DO jj = 1, jmar |
DO jj = 1, jmar |
83 |
DO i = 1, imdep |
DO i = 1, imdep |
84 |
IF( ( xdata(i)-a(ii) >= 1.e-5.AND.xdata(i)-b(ii) <= 1.e-5 ).OR. & |
IF((xdata(i)-a(ii) >= 1.e-5.AND.xdata(i)-b(ii) <= 1.e-5).OR. & |
85 |
(xdata(i)-a(ii) <= 1.e-5.AND.xdata(i)-b(ii) >= 1.e-5 ) ) & |
(xdata(i)-a(ii) <= 1.e-5.AND.xdata(i)-b(ii) >= 1.e-5)) & |
86 |
THEN |
THEN |
87 |
DO j = 1, jmdep |
DO j = 1, jmdep |
88 |
IF((ydata(j)-c(jj) >= 1.e-5.AND.ydata(j)-d(jj) <= 1.e-5 ) & |
IF((ydata(j)-c(jj) >= 1.e-5.AND.ydata(j)-d(jj) <= 1.e-5) & |
89 |
.OR. (ydata(j)-c(jj) <= 1.e-5 .AND. & |
.OR. (ydata(j)-c(jj) <= 1.e-5 .AND. & |
90 |
ydata(j)-d(jj) >= 1.e-5)) THEN |
ydata(j)-d(jj) >= 1.e-5)) THEN |
91 |
number(ii,jj) = number(ii,jj) + 1.0 |
number(ii, jj) = number(ii, jj) + 1.0 |
92 |
grille_m(ii,jj) = grille_m(ii,jj) + entree(i,j) |
grille_m(ii, jj) = grille_m(ii, jj) + entree(i, j) |
93 |
ENDIF |
ENDIF |
94 |
ENDDO |
ENDDO |
95 |
ENDIF |
ENDIF |
97 |
ENDDO |
ENDDO |
98 |
ENDDO |
ENDDO |
99 |
|
|
|
! Si aucun ancien point ne tombe sur une zone, c'est un probleme |
|
|
|
|
100 |
DO i = 1, imar |
DO i = 1, imar |
101 |
DO j = 1, jmar |
DO j = 1, jmar |
102 |
IF (number(i,j) .GT. 0.001) THEN |
IF (number(i, j) > 0.001) THEN |
103 |
grille_m(i,j) = grille_m(i,j) / number(i,j) |
grille_m(i, j) = grille_m(i, j) / number(i, j) |
104 |
ELSE |
ELSE |
105 |
PRINT*, 'probleme,i,j=', i,j |
! Si aucun ancien point ne tombe sur une zone, c'est un probl\`eme |
106 |
CALL dist_sphe(x(i),y(j),xdata,ydata,imdep,jmdep,distans) |
CALL dist_sphe(x(i), y(j), xdata, ydata, imdep, jmdep, distans) |
107 |
ij_proche = 1 |
ij_proche = 1 |
108 |
zzmin = distans(ij_proche) |
zzmin = distans(ij_proche) |
109 |
DO ii = 2, imdep*jmdep |
DO ii = 2, imdep*jmdep |
110 |
IF (distans(ii).LT.zzmin) THEN |
IF (distans(ii) < zzmin) THEN |
111 |
zzmin = distans(ii) |
zzmin = distans(ii) |
112 |
ij_proche = ii |
ij_proche = ii |
113 |
ENDIF |
ENDIF |
114 |
ENDDO |
ENDDO |
115 |
j_proche = (ij_proche-1)/imdep + 1 |
j_proche = (ij_proche-1)/imdep + 1 |
116 |
i_proche = ij_proche - (j_proche-1)*imdep |
i_proche = ij_proche - (j_proche-1)*imdep |
117 |
PRINT*, "solution:", ij_proche, i_proche, j_proche |
grille_m(i, j) = entree(i_proche, j_proche) |
|
grille_m(i,j) = entree(i_proche,j_proche) |
|
118 |
ENDIF |
ENDIF |
119 |
ENDDO |
ENDDO |
120 |
ENDDO |
ENDDO |
121 |
|
|
122 |
END function grille_m |
if (any(number <= 0.001)) print *, "problem in grille_m" |
123 |
|
|
124 |
!************************************************** |
END function grille_m |
|
|
|
|
SUBROUTINE dist_sphe(rf_lon,rf_lat,rlon,rlat,im,jm,distance) |
|
|
|
|
|
! Auteur: Laurent Li (le 30 decembre 1996) |
|
|
|
|
|
! Ce programme calcule la distance minimale (selon le grand cercle) |
|
|
! entre deux points sur la terre |
|
|
|
|
|
INTEGER, intent(in):: im, jm ! dimensions |
|
|
REAL, intent(in):: rf_lon ! longitude du point de reference (degres) |
|
|
REAL, intent(in):: rf_lat ! latitude du point de reference (degres) |
|
|
REAL, intent(in):: rlon(im), rlat(jm) ! longitude et latitude des points |
|
|
|
|
|
REAL, intent(out):: distance(im,jm) ! distances en metre |
|
|
|
|
|
REAL rlon1, rlat1 |
|
|
REAL rlon2, rlat2 |
|
|
REAL dist |
|
|
REAL pa, pb, p, pi |
|
|
|
|
|
REAL radius |
|
|
PARAMETER (radius=6371229.) |
|
|
integer i, j |
|
|
|
|
|
pi = 4.0 * ATAN(1.0) |
|
|
|
|
|
DO j = 1, jm |
|
|
DO i = 1, im |
|
|
|
|
|
rlon1=rf_lon |
|
|
rlat1=rf_lat |
|
|
rlon2=rlon(i) |
|
|
rlat2=rlat(j) |
|
|
pa = pi/2.0 - rlat1*pi/180.0 ! dist. entre pole n et point a |
|
|
pb = pi/2.0 - rlat2*pi/180.0 ! dist. entre pole n et point b |
|
|
p = (rlon1-rlon2)*pi/180.0 ! angle entre a et b (leurs meridiens) |
|
|
|
|
|
dist = ACOS( COS(pa)*COS(pb) + SIN(pa)*SIN(pb)*COS(p)) |
|
|
dist = radius * dist |
|
|
distance(i,j) = dist |
|
|
|
|
|
end DO |
|
|
end DO |
|
|
|
|
|
END SUBROUTINE dist_sphe |
|
125 |
|
|
126 |
end module grid_atob |
end module grille_m_m |