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

Contents of /trunk/dyn3d/grille_m.f

Parent Directory Parent Directory | Revision Log Revision Log


Revision 22 - (show 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 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 function grille_m(xdata, ydata, entree, x, y)
10
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 use numer_rec, only: assert_eq
41
42 REAL, intent(in):: xdata(:),ydata(:)
43 REAL, intent(in):: entree(:, :)
44 REAL, intent(in):: x(:), y(:)
45
46 real grille_m(size(x), size(y))
47
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 use numer_rec, only: assert_eq
416
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 use numer_rec, only: assert_eq
534
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 ! Calcule la longueur de rugosite liee au relief en utilisant
650 ! l'ecart-type dans une maille de 1x1.
651
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 REAL zzmin
661 REAL amin, AMAX
662 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 !---------------------------------------------------------
676
677 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 cham1tmp(i,j) = 0d0
721 cham2tmp(i,j) = 0d0
722 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 + relief(i,j) * relief(i,j)
742 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 zzzz = cham2tmp(i,j) - cham1tmp(i,j)**2
755 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