/[lmdze]/trunk/dyn3d/grille_m.f
ViewVC logotype

Annotation of /trunk/dyn3d/grille_m.f

Parent Directory Parent Directory | Revision Log Revision Log


Revision 22 - (hide annotations)
Fri Jul 31 15:18:47 2009 UTC (14 years, 10 months ago) by guez
Original Path: trunk/libf/dyn3d/grid_atob.f90
File size: 27666 byte(s)
Superficial modifications
1 guez 3 module grid_atob
2    
3     ! From grid_atob.F,v 1.1.1.1 2004/05/19 12:53:05
4    
5     IMPLICIT none
6    
7     contains
8    
9 guez 15 function grille_m(xdata, ydata, entree, x, y)
10 guez 3
11     !=======================================================================
12     ! Z. X. Li (le 1 avril 1994) (voir aussi A. Harzallah et L. Fairhead)
13    
14     ! Méthode naïve pour transformer un champ d'une grille fine à une
15     ! grille grossière. Je considère que les nouveaux points occupent
16     ! une zone adjacente qui comprend un ou plusieurs anciens points
17    
18     ! Aucune pondération n'est considérée (voir grille_p)
19    
20     ! (c)
21     ! ----d-----
22     ! | . . . .|
23     ! | |
24     ! (b)a . * . .b(a)
25     ! | |
26     ! | . . . .|
27     ! ----c-----
28     ! (d)
29     !=======================================================================
30     ! INPUT:
31     ! imdep, jmdep: dimensions X et Y pour depart
32     ! xdata, ydata: coordonnees X et Y pour depart
33     ! entree: champ d'entree a transformer
34     ! OUTPUT:
35     ! imar, jmar: dimensions X et Y d'arrivee
36     ! x, y: coordonnees X et Y d'arrivee
37     ! grille_m: champ de sortie deja transforme
38     !=======================================================================
39    
40 guez 13 use numer_rec, only: assert_eq
41 guez 3
42     REAL, intent(in):: xdata(:),ydata(:)
43     REAL, intent(in):: entree(:, :)
44     REAL, intent(in):: x(:), y(:)
45    
46 guez 15 real grille_m(size(x), size(y))
47 guez 3
48     ! Variables local to the procedure:
49     INTEGER imdep, jmdep, imar, jmar
50     INTEGER i, j, ii, jj
51     REAL a(2200),b(2200),c(1100),d(1100)
52     REAL number(2200,1100)
53     REAL distans(2200*1100)
54     INTEGER i_proche, j_proche, ij_proche
55     REAL zzmin
56    
57     !-------------------------
58    
59     print *, "Call sequence information: grille_m"
60    
61     imdep = assert_eq(size(xdata), size(entree, 1), "grille_m")
62     jmdep = assert_eq(size(ydata), size(entree, 2), "grille_m")
63     imar = size(x)
64     jmar = size(y)
65    
66     IF (imar.GT.2200 .OR. jmar.GT.1100) THEN
67     PRINT*, 'imar ou jmar trop grand', imar, jmar
68     STOP 1
69     ENDIF
70    
71     ! Calculer les limites des zones des nouveaux points
72    
73     a(1) = x(1) - (x(2)-x(1))/2.0
74     b(1) = (x(1)+x(2))/2.0
75     DO i = 2, imar-1
76     a(i) = b(i-1)
77     b(i) = (x(i)+x(i+1))/2.0
78     ENDDO
79     a(imar) = b(imar-1)
80     b(imar) = x(imar) + (x(imar)-x(imar-1))/2.0
81    
82     c(1) = y(1) - (y(2)-y(1))/2.0
83     d(1) = (y(1)+y(2))/2.0
84     DO j = 2, jmar-1
85     c(j) = d(j-1)
86     d(j) = (y(j)+y(j+1))/2.0
87     ENDDO
88     c(jmar) = d(jmar-1)
89     d(jmar) = y(jmar) + (y(jmar)-y(jmar-1))/2.0
90    
91     DO i = 1, imar
92     DO j = 1, jmar
93     number(i,j) = 0.0
94     grille_m(i,j) = 0.0
95     ENDDO
96     ENDDO
97    
98     ! Determiner la zone sur laquelle chaque ancien point se trouve
99    
100     DO ii = 1, imar
101     DO jj = 1, jmar
102     DO i = 1, imdep
103     IF( ( xdata(i)-a(ii) >= 1.e-5.AND.xdata(i)-b(ii) <= 1.e-5 ).OR. &
104     (xdata(i)-a(ii) <= 1.e-5.AND.xdata(i)-b(ii) >= 1.e-5 ) ) &
105     THEN
106     DO j = 1, jmdep
107     IF((ydata(j)-c(jj) >= 1.e-5.AND.ydata(j)-d(jj) <= 1.e-5 ) &
108     .OR. (ydata(j)-c(jj) <= 1.e-5 .AND. &
109     ydata(j)-d(jj) >= 1.e-5)) THEN
110     number(ii,jj) = number(ii,jj) + 1.0
111     grille_m(ii,jj) = grille_m(ii,jj) + entree(i,j)
112     ENDIF
113     ENDDO
114     ENDIF
115     ENDDO
116     ENDDO
117     ENDDO
118    
119     ! Si aucun ancien point ne tombe sur une zone, c'est un probleme
120    
121     DO i = 1, imar
122     DO j = 1, jmar
123     IF (number(i,j) .GT. 0.001) THEN
124     grille_m(i,j) = grille_m(i,j) / number(i,j)
125     ELSE
126     PRINT*, 'probleme,i,j=', i,j
127     CALL dist_sphe(x(i),y(j),xdata,ydata,imdep,jmdep,distans)
128     ij_proche = 1
129     zzmin = distans(ij_proche)
130     DO ii = 2, imdep*jmdep
131     IF (distans(ii).LT.zzmin) THEN
132     zzmin = distans(ii)
133     ij_proche = ii
134     ENDIF
135     ENDDO
136     j_proche = (ij_proche-1)/imdep + 1
137     i_proche = ij_proche - (j_proche-1)*imdep
138     PRINT*, "solution:", ij_proche, i_proche, j_proche
139     grille_m(i,j) = entree(i_proche,j_proche)
140     ENDIF
141     ENDDO
142     ENDDO
143    
144     END function grille_m
145    
146     SUBROUTINE grille_p(imdep, jmdep, xdata, ydata, entree, &
147     imar, jmar, x, y, sortie)
148     !=======================================================================
149     ! z.x.li (le 1 avril 1994) (voir aussi A. Harzallah et L. Fairhead)
150    
151     ! Methode naive pour transformer un champ d'une grille fine a une
152     ! grille grossiere. Je considere que les nouveaux points occupent
153     ! une zone adjacente qui comprend un ou plusieurs anciens points
154    
155     ! Consideration de la distance des points (voir grille_m)
156    
157     ! (c)
158     ! ----d-----
159     ! | . . . .|
160     ! | |
161     ! (b)a . * . .b(a)
162     ! | |
163     ! | . . . .|
164     ! ----c-----
165     ! (d)
166     !=======================================================================
167     ! INPUT:
168     ! imdep, jmdep: dimensions X et Y pour depart
169     ! xdata, ydata: coordonnees X et Y pour depart
170     ! entree: champ d'entree a transformer
171     ! OUTPUT:
172     ! imar, jmar: dimensions X et Y d'arrivee
173     ! x, y: coordonnees X et Y d'arrivee
174     ! sortie: champ de sortie deja transforme
175     !=======================================================================
176    
177     INTEGER imdep, jmdep
178     REAL xdata(imdep),ydata(jmdep)
179     REAL entree(imdep,jmdep)
180    
181     INTEGER imar, jmar
182     REAL x(imar),y(jmar)
183     REAL sortie(imar,jmar)
184    
185     INTEGER i, j, ii, jj
186     REAL a(400),b(400),c(200),d(200)
187     REAL number(400,200)
188     INTEGER indx(400,200), indy(400,200)
189     REAL dist(400,200), distsom(400,200)
190    
191     IF (imar.GT.400 .OR. jmar.GT.200) THEN
192     PRINT*, 'imar ou jmar trop grand', imar, jmar
193     STOP 1
194     ENDIF
195    
196     IF (imdep.GT.400 .OR. jmdep.GT.200) THEN
197     PRINT*, 'imdep ou jmdep trop grand', imdep, jmdep
198     STOP 1
199     ENDIF
200    
201     ! calculer les bords a et b de la nouvelle grille
202    
203     a(1) = x(1) - (x(2)-x(1))/2.0
204     b(1) = (x(1)+x(2))/2.0
205     DO i = 2, imar-1
206     a(i) = b(i-1)
207     b(i) = (x(i)+x(i+1))/2.0
208     ENDDO
209     a(imar) = b(imar-1)
210     b(imar) = x(imar) + (x(imar)-x(imar-1))/2.0
211    
212     ! calculer les bords c et d de la nouvelle grille
213    
214     c(1) = y(1) - (y(2)-y(1))/2.0
215     d(1) = (y(1)+y(2))/2.0
216     DO j = 2, jmar-1
217     c(j) = d(j-1)
218     d(j) = (y(j)+y(j+1))/2.0
219     ENDDO
220     c(jmar) = d(jmar-1)
221     d(jmar) = y(jmar) + (y(jmar)-y(jmar-1))/2.0
222    
223     ! trouver les indices (indx,indy) de la nouvelle grille sur laquelle
224     ! un point de l'ancienne grille est tombe.
225    
226     ! ..... Modif P. Le Van ( 23/08/95 ) ....
227    
228     DO ii = 1, imar
229     DO jj = 1, jmar
230     DO i = 1, imdep
231     IF( ( xdata(i)-a(ii) >= 1.e-5.AND.xdata(i)-b(ii) <= 1.e-5 ).OR. &
232     ( xdata(i)-a(ii) <= 1.e-5.AND.xdata(i)-b(ii) >= 1.e-5 ) ) &
233     THEN
234     DO j = 1, jmdep
235     IF( (ydata(j)-c(jj) >= 1.e-5.AND.ydata(j)-d(jj) <= 1.e-5 ).OR. &
236     ( ydata(j)-c(jj) <= 1.e-5.AND.ydata(j)-d(jj) >= 1.e-5 ) ) &
237     THEN
238     indx(i,j) = ii
239     indy(i,j) = jj
240     ENDIF
241     ENDDO
242     ENDIF
243     ENDDO
244     ENDDO
245     ENDDO
246    
247     ! faire une verification
248    
249     DO i = 1, imdep
250     DO j = 1, jmdep
251     IF (indx(i,j).GT.imar .OR. indy(i,j).GT.jmar) THEN
252     PRINT*, 'Probleme grave,i,j,indx,indy=', &
253     i,j,indx(i,j),indy(i,j)
254     stop 1
255     ENDIF
256     ENDDO
257     ENDDO
258    
259     ! calculer la distance des anciens points avec le nouveau point,
260     ! on prend ensuite une sorte d'inverse pour ponderation.
261    
262     DO i = 1, imar
263     DO j = 1, jmar
264     number(i,j) = 0.0
265     distsom(i,j) = 0.0
266     ENDDO
267     ENDDO
268     DO i = 1, imdep
269     DO j = 1, jmdep
270     dist(i,j) = SQRT ( (xdata(i)-x(indx(i,j)))**2 &
271     +(ydata(j)-y(indy(i,j)))**2 )
272     distsom(indx(i,j),indy(i,j)) = distsom(indx(i,j),indy(i,j)) &
273     + dist(i,j)
274     number(indx(i,j),indy(i,j)) = number(indx(i,j),indy(i,j)) +1.
275     ENDDO
276     ENDDO
277     DO i = 1, imdep
278     DO j = 1, jmdep
279     dist(i,j) = 1.0 - dist(i,j)/distsom(indx(i,j),indy(i,j))
280     ENDDO
281     ENDDO
282    
283     DO i = 1, imar
284     DO j = 1, jmar
285     number(i,j) = 0.0
286     sortie(i,j) = 0.0
287     ENDDO
288     ENDDO
289     DO i = 1, imdep
290     DO j = 1, jmdep
291     sortie(indx(i,j),indy(i,j)) = sortie(indx(i,j),indy(i,j)) &
292     + entree(i,j) * dist(i,j)
293     number(indx(i,j),indy(i,j)) = number(indx(i,j),indy(i,j)) &
294     + dist(i,j)
295     ENDDO
296     ENDDO
297     DO i = 1, imar
298     DO j = 1, jmar
299     IF (number(i,j) .GT. 0.001) THEN
300     sortie(i,j) = sortie(i,j) / number(i,j)
301     ELSE
302     PRINT*, 'probleme,i,j=', i,j
303     STOP 1
304     ENDIF
305     ENDDO
306     ENDDO
307    
308     RETURN
309     END SUBROUTINE grille_p
310    
311     !******************************************************************
312    
313     SUBROUTINE mask_c_o(imdep, jmdep, xdata, ydata, relief, &
314     imar, jmar, x, y, mask)
315     !=======================================================================
316     ! z.x.li (le 1 avril 1994): A partir du champ de relief, on fabrique
317     ! un champ indicateur (masque) terre/ocean
318     ! terre:1; ocean:0
319    
320     ! Methode naive (voir grille_m)
321     !=======================================================================
322    
323     INTEGER imdep, jmdep
324     REAL xdata(imdep),ydata(jmdep)
325     REAL relief(imdep,jmdep)
326    
327     INTEGER imar, jmar
328     REAL x(imar),y(jmar)
329     REAL mask(imar,jmar)
330    
331     INTEGER i, j, ii, jj
332     REAL a(2200),b(2200),c(1100),d(1100)
333     REAL num_tot(2200,1100), num_oce(2200,1100)
334    
335     IF (imar.GT.2200 .OR. jmar.GT.1100) THEN
336     PRINT*, 'imar ou jmar trop grand', imar, jmar
337     STOP 1
338     ENDIF
339    
340     a(1) = x(1) - (x(2)-x(1))/2.0
341     b(1) = (x(1)+x(2))/2.0
342     DO i = 2, imar-1
343     a(i) = b(i-1)
344     b(i) = (x(i)+x(i+1))/2.0
345     ENDDO
346     a(imar) = b(imar-1)
347     b(imar) = x(imar) + (x(imar)-x(imar-1))/2.0
348    
349     c(1) = y(1) - (y(2)-y(1))/2.0
350     d(1) = (y(1)+y(2))/2.0
351     DO j = 2, jmar-1
352     c(j) = d(j-1)
353     d(j) = (y(j)+y(j+1))/2.0
354     ENDDO
355     c(jmar) = d(jmar-1)
356     d(jmar) = y(jmar) + (y(jmar)-y(jmar-1))/2.0
357    
358     DO i = 1, imar
359     DO j = 1, jmar
360     num_oce(i,j) = 0.0
361     num_tot(i,j) = 0.0
362     ENDDO
363     ENDDO
364    
365     ! ..... Modif P. Le Van ( 23/08/95 ) ....
366    
367     DO ii = 1, imar
368     DO jj = 1, jmar
369     DO i = 1, imdep
370     IF( ( xdata(i)-a(ii) >= 1.e-5.AND.xdata(i)-b(ii) <= 1.e-5 ).OR. &
371     ( xdata(i)-a(ii) <= 1.e-5.AND.xdata(i)-b(ii) >= 1.e-5 ) ) &
372     THEN
373     DO j = 1, jmdep
374     IF( (ydata(j)-c(jj) >= 1.e-5.AND.ydata(j)-d(jj) <= 1.e-5 ).OR. &
375     ( ydata(j)-c(jj) <= 1.e-5.AND.ydata(j)-d(jj) >= 1.e-5 ) ) &
376     THEN
377     num_tot(ii,jj) = num_tot(ii,jj) + 1.0
378     IF (.NOT. ( relief(i,j) - 0.9>= 1.e-5 ) ) &
379     num_oce(ii,jj) = num_oce(ii,jj) + 1.0
380     ENDIF
381     ENDDO
382     ENDIF
383     ENDDO
384     ENDDO
385     ENDDO
386    
387     DO i = 1, imar
388     DO j = 1, jmar
389     IF (num_tot(i,j) .GT. 0.001) THEN
390     IF ( num_oce(i,j)/num_tot(i,j) - 0.5 >= 1.e-5 ) THEN
391     mask(i,j) = 0.
392     ELSE
393     mask(i,j) = 1.
394     ENDIF
395     ELSE
396     PRINT*, 'probleme,i,j=', i,j
397     STOP 1
398     ENDIF
399     ENDDO
400     ENDDO
401    
402     RETURN
403     END SUBROUTINE mask_c_o
404    
405     ! *************************************
406    
407     real function rugosite(xdata, ydata, entree, x, y, mask)
408    
409     ! Z. X. Li (le 1 avril 1994): Transformer la longueur de rugosite d'une
410     ! grille fine a une grille grossiere. Sur l'ocean, on impose une valeur
411     ! fixe (0.001m).
412    
413     ! Methode naive (voir grille_m)
414    
415 guez 13 use numer_rec, only: assert_eq
416 guez 3
417     REAL, intent(in):: xdata(:), ydata(:), entree(:,:), x(:), y(:), mask(:,:)
418    
419     dimension rugosite(size(mask, 1), size(mask, 2))
420    
421     ! Variables local to the procedure:
422     INTEGER imdep, jmdep
423     INTEGER imar, jmar
424     INTEGER i, j, ii, jj
425     REAL a(400),b(400),c(400),d(400)
426     REAL num_tot(400,400)
427     REAL distans(400*400)
428     INTEGER i_proche, j_proche, ij_proche
429     REAL zzmin
430    
431     ! --------------------
432    
433     imdep = assert_eq(size(xdata), size(entree, 1), "rugosite")
434     jmdep = assert_eq(size(ydata), size(entree, 2), "rugosite")
435     imar = assert_eq(size(x), size(mask, 1), "rugosite")
436     jmar = assert_eq(size(y), size(mask, 2), "rugosite")
437    
438     IF (imar.GT.400 .OR. jmar.GT.400) THEN
439     PRINT*, 'imar ou jmar trop grand', imar, jmar
440     STOP 1
441     ENDIF
442    
443     a(1) = x(1) - (x(2)-x(1))/2.0
444     b(1) = (x(1)+x(2))/2.0
445     DO i = 2, imar-1
446     a(i) = b(i-1)
447     b(i) = (x(i)+x(i+1))/2.0
448     ENDDO
449     a(imar) = b(imar-1)
450     b(imar) = x(imar) + (x(imar)-x(imar-1))/2.0
451    
452     c(1) = y(1) - (y(2)-y(1))/2.0
453     d(1) = (y(1)+y(2))/2.0
454     DO j = 2, jmar-1
455     c(j) = d(j-1)
456     d(j) = (y(j)+y(j+1))/2.0
457     ENDDO
458     c(jmar) = d(jmar-1)
459     d(jmar) = y(jmar) + (y(jmar)-y(jmar-1))/2.0
460    
461     DO i = 1, imar
462     DO j = 1, jmar
463     num_tot(i,j) = 0.0
464     rugosite(i,j) = 0.0
465     ENDDO
466     ENDDO
467    
468     ! ..... Modif P. Le Van ( 23/08/95 ) ....
469    
470     DO ii = 1, imar
471     DO jj = 1, jmar
472     DO i = 1, imdep
473     IF( ( xdata(i)-a(ii) >= 1.e-5.AND.xdata(i)-b(ii) <= 1.e-5 ).OR. &
474     ( xdata(i)-a(ii) <= 1.e-5.AND.xdata(i)-b(ii) >= 1.e-5 ) ) &
475     THEN
476     DO j = 1, jmdep
477     IF( (ydata(j)-c(jj) >= 1.e-5.AND.ydata(j)-d(jj) <= 1.e-5 ).OR. &
478     ( ydata(j)-c(jj) <= 1.e-5.AND.ydata(j)-d(jj) >= 1.e-5 ) ) &
479     THEN
480     rugosite(ii,jj) = rugosite(ii,jj) + LOG(entree(i,j))
481     num_tot(ii,jj) = num_tot(ii,jj) + 1.0
482     ENDIF
483     ENDDO
484     ENDIF
485     ENDDO
486     ENDDO
487     ENDDO
488    
489     DO i = 1, imar
490     DO j = 1, jmar
491     IF (NINT(mask(i,j)).EQ.1) THEN
492     IF (num_tot(i,j) .GT. 0.0) THEN
493     rugosite(i,j) = rugosite(i,j) / num_tot(i,j)
494     rugosite(i,j) = EXP(rugosite(i,j))
495     ELSE
496     PRINT*, 'probleme,i,j=', i,j
497     !cc STOP 1
498     CALL dist_sphe(x(i),y(j),xdata,ydata,imdep,jmdep,distans)
499     ij_proche = 1
500     zzmin = distans(ij_proche)
501     DO ii = 2, imdep*jmdep
502     IF (distans(ii).LT.zzmin) THEN
503     zzmin = distans(ii)
504     ij_proche = ii
505     ENDIF
506     ENDDO
507     j_proche = (ij_proche-1)/imdep + 1
508     i_proche = ij_proche - (j_proche-1)*imdep
509     PRINT*, "solution:", ij_proche, i_proche, j_proche
510     rugosite(i,j) = entree(i_proche,j_proche)
511     ENDIF
512     ELSE
513     rugosite(i,j) = 0.001
514     ENDIF
515     ENDDO
516     ENDDO
517    
518     RETURN
519     END function rugosite
520    
521     !************************************
522    
523     real function sea_ice(xdata, ydata, glace01, x, y)
524    
525     !=======================================================================
526     ! z.x.li (le 1 avril 1994): Transformer un champ d'indicateur de la
527     ! glace (1, sinon 0) d'une grille fine a un champ de fraction de glace
528     ! (entre 0 et 1) dans une grille plus grossiere.
529    
530     ! Methode naive (voir grille_m)
531     !=======================================================================
532    
533 guez 13 use numer_rec, only: assert_eq
534 guez 3
535     REAL, intent(in):: xdata(:),ydata(:)
536     REAL, intent(in):: glace01(:,:)
537     REAL, intent(in):: x(:),y(:)
538     dimension sea_ice(size(x), size(y))
539    
540     ! Variables local to the procedure:
541     INTEGER imdep, jmdep
542     INTEGER imar, jmar
543     INTEGER i, j, ii, jj
544     REAL a(400),b(400),c(400),d(400)
545     REAL num_tot(400,400), num_ice(400,400)
546     REAL distans(400*400)
547     INTEGER i_proche, j_proche, ij_proche
548     REAL zzmin
549    
550     !------------------------------
551    
552     imdep = assert_eq(size(xdata), size(glace01, 1), "sea_ice")
553     jmdep = assert_eq(size(ydata), size(glace01, 2), "sea_ice")
554     imar = size(x)
555     jmar = size(y)
556    
557     IF (imar.GT.400 .OR. jmar.GT.400) THEN
558     PRINT*, 'imar ou jmar trop grand', imar, jmar
559     STOP 1
560     ENDIF
561    
562     a(1) = x(1) - (x(2)-x(1))/2.0
563     b(1) = (x(1)+x(2))/2.0
564     DO i = 2, imar-1
565     a(i) = b(i-1)
566     b(i) = (x(i)+x(i+1))/2.0
567     ENDDO
568     a(imar) = b(imar-1)
569     b(imar) = x(imar) + (x(imar)-x(imar-1))/2.0
570    
571     c(1) = y(1) - (y(2)-y(1))/2.0
572     d(1) = (y(1)+y(2))/2.0
573     DO j = 2, jmar-1
574     c(j) = d(j-1)
575     d(j) = (y(j)+y(j+1))/2.0
576     ENDDO
577     c(jmar) = d(jmar-1)
578     d(jmar) = y(jmar) + (y(jmar)-y(jmar-1))/2.0
579    
580     DO i = 1, imar
581     DO j = 1, jmar
582     num_ice(i,j) = 0.0
583     num_tot(i,j) = 0.0
584     ENDDO
585     ENDDO
586    
587     ! ..... Modif P. Le Van ( 23/08/95 ) ....
588    
589     DO ii = 1, imar
590     DO jj = 1, jmar
591     DO i = 1, imdep
592     IF( ( xdata(i)-a(ii) >= 1.e-5.AND.xdata(i)-b(ii) <= 1.e-5 ).OR. &
593     ( xdata(i)-a(ii) <= 1.e-5.AND.xdata(i)-b(ii) >= 1.e-5 ) ) &
594     THEN
595     DO j = 1, jmdep
596     IF( (ydata(j)-c(jj) >= 1.e-5.AND.ydata(j)-d(jj) <= 1.e-5 ).OR. &
597     ( ydata(j)-c(jj) <= 1.e-5.AND.ydata(j)-d(jj) >= 1.e-5 ) ) &
598     THEN
599     num_tot(ii,jj) = num_tot(ii,jj) + 1.0
600     IF (NINT(glace01(i,j)).EQ.1 ) &
601     num_ice(ii,jj) = num_ice(ii,jj) + 1.0
602     ENDIF
603     ENDDO
604     ENDIF
605     ENDDO
606     ENDDO
607     ENDDO
608    
609     DO i = 1, imar
610     DO j = 1, jmar
611     IF (num_tot(i,j) .GT. 0.001) THEN
612     IF (num_ice(i,j).GT.0.001) THEN
613     sea_ice(i,j) = num_ice(i,j) / num_tot(i,j)
614     ELSE
615     sea_ice(i,j) = 0.0
616     ENDIF
617     ELSE
618     PRINT*, 'probleme,i,j=', i,j
619     !cc STOP 1
620     CALL dist_sphe(x(i),y(j),xdata,ydata,imdep,jmdep,distans)
621     ij_proche = 1
622     zzmin = distans(ij_proche)
623     DO ii = 2, imdep*jmdep
624     IF (distans(ii).LT.zzmin) THEN
625     zzmin = distans(ii)
626     ij_proche = ii
627     ENDIF
628     ENDDO
629     j_proche = (ij_proche-1)/imdep + 1
630     i_proche = ij_proche - (j_proche-1)*imdep
631     PRINT*, "solution:", ij_proche, i_proche, j_proche
632     IF (NINT(glace01(i_proche,j_proche)).EQ.1 ) THEN
633     sea_ice(i,j) = 1.0
634     ELSE
635     sea_ice(i,j) = 0.0
636     ENDIF
637     ENDIF
638     ENDDO
639     ENDDO
640    
641     RETURN
642     END function sea_ice
643    
644     !*************************************
645    
646     SUBROUTINE rugsoro(imrel, jmrel, xrel, yrel, relief, immod, jmmod, xmod, &
647     ymod, rugs)
648    
649 guez 22 ! Calcule la longueur de rugosite liee au relief en utilisant
650     ! l'ecart-type dans une maille de 1x1.
651 guez 3
652     INTEGER, intent(in):: imrel, jmrel
653     REAL, intent(in):: xrel(imrel),yrel(jmrel)
654     REAL, intent(in):: relief(imrel,jmrel)
655    
656     INTEGER, intent(in):: immod, jmmod
657     REAL, intent(in):: xmod(immod),ymod(jmmod)
658     REAL, intent(out):: rugs(immod,jmmod)
659    
660 guez 22 REAL zzmin
661     REAL amin, AMAX
662 guez 3 INTEGER imtmp, jmtmp
663     PARAMETER (imtmp=360,jmtmp=180)
664     REAL xtmp(imtmp), ytmp(jmtmp)
665     double precision cham1tmp(imtmp,jmtmp), cham2tmp(imtmp,jmtmp)
666     REAL zzzz
667    
668     INTEGER i, j, ii, jj
669     REAL a(2200),b(2200),c(1100),d(1100)
670     REAL number(2200,1100)
671    
672     REAL distans(400*400)
673     INTEGER i_proche, j_proche, ij_proche
674    
675 guez 22 !---------------------------------------------------------
676    
677 guez 3 IF (immod.GT.2200 .OR. jmmod.GT.1100) THEN
678     PRINT*, 'immod ou jmmod trop grand', immod, jmmod
679     STOP 1
680     ENDIF
681    
682     ! Calculs intermediares:
683    
684     xtmp(1) = -180.0 + 360.0/FLOAT(imtmp) / 2.0
685     DO i = 2, imtmp
686     xtmp(i) = xtmp(i-1) + 360.0/FLOAT(imtmp)
687     ENDDO
688     DO i = 1, imtmp
689     xtmp(i) = xtmp(i) /180.0 * 4.0*ATAN(1.0)
690     ENDDO
691     ytmp(1) = -90.0 + 180.0/FLOAT(jmtmp) / 2.0
692     DO j = 2, jmtmp
693     ytmp(j) = ytmp(j-1) + 180.0/FLOAT(jmtmp)
694     ENDDO
695     DO j = 1, jmtmp
696     ytmp(j) = ytmp(j) /180.0 * 4.0*ATAN(1.0)
697     ENDDO
698    
699     a(1) = xtmp(1) - (xtmp(2)-xtmp(1))/2.0
700     b(1) = (xtmp(1)+xtmp(2))/2.0
701     DO i = 2, imtmp-1
702     a(i) = b(i-1)
703     b(i) = (xtmp(i)+xtmp(i+1))/2.0
704     ENDDO
705     a(imtmp) = b(imtmp-1)
706     b(imtmp) = xtmp(imtmp) + (xtmp(imtmp)-xtmp(imtmp-1))/2.0
707    
708     c(1) = ytmp(1) - (ytmp(2)-ytmp(1))/2.0
709     d(1) = (ytmp(1)+ytmp(2))/2.0
710     DO j = 2, jmtmp-1
711     c(j) = d(j-1)
712     d(j) = (ytmp(j)+ytmp(j+1))/2.0
713     ENDDO
714     c(jmtmp) = d(jmtmp-1)
715     d(jmtmp) = ytmp(jmtmp) + (ytmp(jmtmp)-ytmp(jmtmp-1))/2.0
716    
717     DO i = 1, imtmp
718     DO j = 1, jmtmp
719     number(i,j) = 0.0
720 guez 22 cham1tmp(i,j) = 0d0
721     cham2tmp(i,j) = 0d0
722 guez 3 ENDDO
723     ENDDO
724    
725     ! ..... Modif P. Le Van ( 23/08/95 ) ....
726    
727     DO ii = 1, imtmp
728     DO jj = 1, jmtmp
729     DO i = 1, imrel
730     IF( ( xrel(i)-a(ii) >= 1.e-5.AND.xrel(i)-b(ii) <= 1.e-5 ).OR. &
731     ( xrel(i)-a(ii) <= 1.e-5.AND.xrel(i)-b(ii) >= 1.e-5 ) ) &
732     THEN
733     DO j = 1, jmrel
734     IF ((yrel(j)-c(jj) >= 1.e-5.AND.yrel(j)-d(jj) <= 1.e-5 ) &
735     .OR. (yrel(j)-c(jj) <= 1.e-5 .AND. &
736     yrel(j)-d(jj) >= 1.e-5 ) ) &
737     THEN
738     number(ii,jj) = number(ii,jj) + 1.0
739     cham1tmp(ii,jj) = cham1tmp(ii,jj) + relief(i,j)
740     cham2tmp(ii,jj) = cham2tmp(ii,jj) &
741 guez 22 + relief(i,j) * relief(i,j)
742 guez 3 ENDIF
743     ENDDO
744     ENDIF
745     ENDDO
746     ENDDO
747     ENDDO
748    
749     DO i = 1, imtmp
750     DO j = 1, jmtmp
751     IF (number(i,j) .GT. 0.001) THEN
752     cham1tmp(i,j) = cham1tmp(i,j) / number(i,j)
753     cham2tmp(i,j) = cham2tmp(i,j) / number(i,j)
754 guez 22 zzzz = cham2tmp(i,j) - cham1tmp(i,j)**2
755 guez 3 if (zzzz .lt. 0.0) then
756     if (zzzz .gt. -7.5) then
757     zzzz = 0.0
758     print*,'Pb rugsoro, -7.5 < zzzz < 0, => zzz = 0.0'
759     else
760     stop 'Pb rugsoro, zzzz <-7.5'
761     endif
762     endif
763     cham2tmp(i,j) = SQRT(zzzz)
764     ELSE
765     PRINT*, 'probleme,i,j=', i,j
766     STOP 1
767     ENDIF
768     ENDDO
769     ENDDO
770    
771     amin = cham2tmp(1,1)
772     AMAX = cham2tmp(1,1)
773     DO j = 1, jmtmp
774     DO i = 1, imtmp
775     IF (cham2tmp(i,j).GT.AMAX) AMAX = cham2tmp(i,j)
776     IF (cham2tmp(i,j).LT.amin) amin = cham2tmp(i,j)
777     ENDDO
778     ENDDO
779     PRINT*, 'Ecart-type 1x1:', amin, AMAX
780    
781     a(1) = xmod(1) - (xmod(2)-xmod(1))/2.0
782     b(1) = (xmod(1)+xmod(2))/2.0
783     DO i = 2, immod-1
784     a(i) = b(i-1)
785     b(i) = (xmod(i)+xmod(i+1))/2.0
786     ENDDO
787     a(immod) = b(immod-1)
788     b(immod) = xmod(immod) + (xmod(immod)-xmod(immod-1))/2.0
789    
790     c(1) = ymod(1) - (ymod(2)-ymod(1))/2.0
791     d(1) = (ymod(1)+ymod(2))/2.0
792     DO j = 2, jmmod-1
793     c(j) = d(j-1)
794     d(j) = (ymod(j)+ymod(j+1))/2.0
795     ENDDO
796     c(jmmod) = d(jmmod-1)
797     d(jmmod) = ymod(jmmod) + (ymod(jmmod)-ymod(jmmod-1))/2.0
798    
799     DO i = 1, immod
800     DO j = 1, jmmod
801     number(i,j) = 0.0
802     rugs(i,j) = 0.0
803     ENDDO
804     ENDDO
805    
806     DO ii = 1, immod
807     DO jj = 1, jmmod
808     DO i = 1, imtmp
809     IF( ( xtmp(i)-a(ii) >= 1.e-5.AND.xtmp(i)-b(ii) <= 1.e-5 ).OR. &
810     ( xtmp(i)-a(ii) <= 1.e-5.AND.xtmp(i)-b(ii) >= 1.e-5 ) ) &
811     THEN
812     DO j = 1, jmtmp
813     IF ((ytmp(j) - c(jj) >= 1.e-5 &
814     .AND. ytmp(j) - d(jj) <= 1.e-5) .OR. &
815     (ytmp(j) - c(jj) <= 1.e-5 &
816     .AND. ytmp(j) - d(jj) >= 1.e-5)) &
817     THEN
818     number(ii,jj) = number(ii,jj) + 1.0
819     rugs(ii,jj) = rugs(ii,jj) &
820     + LOG(MAX(0.001d0,cham2tmp(i,j)))
821     ENDIF
822     ENDDO
823     ENDIF
824     ENDDO
825     ENDDO
826     ENDDO
827    
828     DO i = 1, immod
829     DO j = 1, jmmod
830     IF (number(i,j) .GT. 0.001) THEN
831     rugs(i,j) = rugs(i,j) / number(i,j)
832     rugs(i,j) = EXP(rugs(i,j))
833     ELSE
834     PRINT*, 'probleme,i,j=', i,j
835     CALL dist_sphe(xmod(i),ymod(j),xtmp,ytmp,imtmp,jmtmp,distans)
836     ij_proche = 1
837     zzmin = distans(ij_proche)
838     DO ii = 2, imtmp*jmtmp
839     IF (distans(ii).LT.zzmin) THEN
840     zzmin = distans(ii)
841     ij_proche = ii
842     ENDIF
843     ENDDO
844     j_proche = (ij_proche-1)/imtmp + 1
845     i_proche = ij_proche - (j_proche-1)*imtmp
846     PRINT*, "solution:", ij_proche, i_proche, j_proche
847     rugs(i,j) = LOG(MAX(0.001d0,cham2tmp(i_proche,j_proche)))
848     ENDIF
849     ENDDO
850     ENDDO
851    
852     amin = rugs(1,1)
853     AMAX = rugs(1,1)
854     DO j = 1, jmmod
855     DO i = 1, immod
856     IF (rugs(i,j).GT.AMAX) AMAX = rugs(i,j)
857     IF (rugs(i,j).LT.amin) amin = rugs(i,j)
858     ENDDO
859     ENDDO
860     PRINT*, 'Ecart-type du modele:', amin, AMAX
861    
862     DO j = 1, jmmod
863     DO i = 1, immod
864     rugs(i,j) = rugs(i,j) / AMAX * 20.0
865     ENDDO
866     ENDDO
867    
868     amin = rugs(1,1)
869     AMAX = rugs(1,1)
870     DO j = 1, jmmod
871     DO i = 1, immod
872     IF (rugs(i,j).GT.AMAX) AMAX = rugs(i,j)
873     IF (rugs(i,j).LT.amin) amin = rugs(i,j)
874     ENDDO
875     ENDDO
876     PRINT*, 'Longueur de rugosite du modele:', amin, AMAX
877    
878     END SUBROUTINE rugsoro
879     !
880     SUBROUTINE dist_sphe(rf_lon,rf_lat,rlon,rlat,im,jm,distance)
881    
882     ! Auteur: Laurent Li (le 30 decembre 1996)
883    
884     ! Ce programme calcule la distance minimale (selon le grand cercle)
885     ! entre deux points sur la terre
886    
887     INTEGER, intent(in):: im, jm ! dimensions
888     REAL, intent(in):: rf_lon ! longitude du point de reference (degres)
889     REAL, intent(in):: rf_lat ! latitude du point de reference (degres)
890     REAL, intent(in):: rlon(im), rlat(jm) ! longitude et latitude des points
891    
892     REAL, intent(out):: distance(im,jm) ! distances en metre
893    
894     REAL rlon1, rlat1
895     REAL rlon2, rlat2
896     REAL dist
897     REAL pa, pb, p, pi
898    
899     REAL radius
900     PARAMETER (radius=6371229.)
901     integer i, j
902    
903     pi = 4.0 * ATAN(1.0)
904    
905     DO j = 1, jm
906     DO i = 1, im
907    
908     rlon1=rf_lon
909     rlat1=rf_lat
910     rlon2=rlon(i)
911     rlat2=rlat(j)
912     pa = pi/2.0 - rlat1*pi/180.0 ! dist. entre pole n et point a
913     pb = pi/2.0 - rlat2*pi/180.0 ! dist. entre pole n et point b
914     p = (rlon1-rlon2)*pi/180.0 ! angle entre a et b (leurs meridiens)
915    
916     dist = ACOS( COS(pa)*COS(pb) + SIN(pa)*SIN(pb)*COS(p))
917     dist = radius * dist
918     distance(i,j) = dist
919    
920     end DO
921     end DO
922    
923     END SUBROUTINE dist_sphe
924    
925     end module grid_atob

  ViewVC Help
Powered by ViewVC 1.1.21