source: LMDZ5/trunk/libf/dyn3d_common/grid_atob.F @ 2153

Last change on this file since 2153 was 2088, checked in by lguez, 10 years ago

Control the output from ce0l.

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