source: trunk/SOURCES/flottab2-0.7.f90 @ 243

Last change on this file since 243 was 237, checked in by aquiquet, 6 years ago

Sealevel is now treated as a 2D variable (sealevel_2d while sealevel remains the eustatic sea level), results should remain identical as sealevel_2d is equal to sealevel in this revision.

File size: 42.9 KB
Line 
1!> \file flottab2-0.7.f90
2!! Module pour determiner les endroits ou la glace
3!! flotte , les iles, et la position du front de glace
4!<
5
6!> \namespace flottab_mod
7!! Determine les endroits ou la glace
8!! flotte , les iles, et la position du front de glace
9!! \author Vincent & Cat
10!! \date 10 juillet 2005
11!! @note Used module
12!! @note   - use module3D_phy
13!! @note   - use module_choix
14!! @todo "nasty Island". If the bedrock is above sealevel force grounded (mk_init)
15!<
16module flottab_mod
17 
18  !$ USE OMP_LIB
19USE module3D_phy
20use module_choix
21
22
23
24 IMPLICIT NONE
25
26 real ::  surnet !< surnet hauteur de glace au dessus de la mer
27 real ::  archim !< test de flottaison
28! real, parameter :: Hmin=1.001   !< Hmin pour être considere comme point ice
29
30 integer:: itestf
31
32 logical,dimension(nx,ny) ::  gz1mx,gz1my
33 logical,dimension(nx,ny) ::  fl1mx,fl1my
34
35
36 real,dimension(nx,ny) ::  uxs1   !< uxbar a l'entree de flottab
37 real,dimension(nx,ny) ::  uys1   !< uybar a l'entree de flottab
38
39
40 integer pmx,pmy !pm=plus-moins -1 ou 1 pour x et y
41
42
43! Variables pour la determination des differents shelfs/stream
44! (representés comme des taches ou l'on resoud l'eq elliptique)
45!________________________________________________________________
46 integer,parameter               :: n_ta_max=2000!< nombre de tache max
47 integer,dimension(nx,ny)        :: table_out    !< pour les numeros des taches
48 integer,dimension(nx,ny)        :: tablebis     !< pour les numeros des taches
49 integer,dimension(0:n_ta_max)     :: compt        !< contient les equivalence entre les taches
50 integer,dimension(0:n_ta_max)     :: nb_pts_tache !< indique le nombre de points par tache
51 logical,dimension(0:n_ta_max)     :: iceberg1D      !< T si iceberg, F si calotte posee
52 
53 logical,dimension(nx,ny)        :: mask_tache_ij !< masque de travail
54                                                  !< vrai pour toute la tache de i,j
55 integer,dimension(2)            :: smax_coord    !< pour le maxloc des iles
56
57!  Variables pour determiner le point le plus haut (surf)
58!  d'une ile completement stream
59!_________________________________________________________
60
61! icetrim : T si ice stream, F si calotte posee(vertical shear)
62 logical,dimension(n_ta_max) :: icetrim 
63
64 integer ::  ii,jj
65 integer ::  smax_i
66 integer ::  smax_j
67 real    ::  smax_
68 integer ::  numtache
69 integer ::  nb_pt
70 real    ::  petit_H=0.001 ! pour test ice sur zone flottante
71contains
72! -----------------------------------------------------------------------------------
73!> SUBROUTINE: flottab()
74!! Cette routine determine les endroits ou la glace
75!! flotte , les iles, et la position du front de glace
76!! @note Il y a 4 sortes de zone
77!! @note    - Pose
78!  @note    - Grounding zone et streams    gzmx et gzmy
79!  @note    - Iles             ilemx, ilemy
80!  @note    - flottant  flot sur le noeud majeur, flotmx sur le noeud mineur
81!>
82  subroutine flottab()
83    !
84    !                                   Vince 5 Jan 95
85    !                                       Modifie 20 Jan 95
86    !                                       Modifie le 30 Novembre 98
87    !    Passage f90 + determination des fronts Vincent dec 2003
88    !    nettoyage et nouvelle détermination de gzmx et gzmy Cat le 10 juillet 2005
89    !    Re-nettoyage par Cat en aout 2006.
90    !    Le calcul de gzmx et gzmy pour les points intérieurs passe dans la subroutine dragging
91    !    pour les points cotiers, toujours fait dans flottab
92    !
93    !                                       -----------------
94    !
95    !      Cette routine determine les endroits ou la glace
96    !      flotte , les iles, et la position du front de glace
97    !
98    !      Il y a 4 sortes de zone
99    !      Pose
100    !      Grounding zone et streams    gzmx et gzmy
101    !      Iles             ilemx, ilemy
102    !      flottant  flot sur le noeud majeur, flotmx sur le noeud mineur
103
104    !   passage dans flottab tous les pas de temps dt  !
105    !
106    ! _________________________________________________________
107
108    !~ print*,'debut flottab',S(132,183),H(132,183),BSOC(132,183),B(132,183),sealevel
109    !~ print*,'debut flottab',flot(132,183),ice(132,183)
110!print*,'H(90,179) flottab 1',H(90,179),ice(90,179), flot(90,179)
111
112    if (itracebug.eq.1)  call tracebug(' Entree dans routine flottab')
113
114    SHELFY = .FALSE.
115
116
117    ! cas particulier des runs paleo ou on impose un masque grounded
118
119    !$OMP PARALLEL PRIVATE(archim,surnet)
120    if (igrdline.eq.2) then
121       !$OMP WORKSHARE
122       where ( mk_init(:,:).eq.1)                 ! pose
123          flot(:,:) = .False.
124          H(:,:)=max(H(:,:),(10.+sealevel_2d(:,:)-Bsoc(:,:))*row/ro)  ! pour avoir archim=10
125          S(:,:) = Bsoc(:,:) + H(:,:) 
126       elsewhere
127          flot(:,:) = .True.
128       end where
129       !$OMP END WORKSHARE
130    end if
131
132
133    ! 1-INITIALISATION
134    ! ----------------
135    ! initialisation des variables pour detecter les points qui se mettent
136    ! a flotter entre 2 dtt
137
138    appel_new_flot=.false.
139    !$OMP DO
140    do j=1,ny
141       do i=1,nx
142          new_flot_point(i,j)=.false.
143          new_flotmx(i,j)=.false.
144          new_flotmy(i,j)=.false.
145       enddo
146    enddo
147    !$OMP END DO
148
149    ! ICE(:,:)=(H(:,:).gt.1) ! ice=.true. si epaisseur > 1m
150
151    !$OMP WORKSHARE
152    ICE(:,:)=0
153    front(:,:)=0
154    frontfacex(:,:)=0
155    frontfacey(:,:)=0
156    isolx(:,:)=.false.
157    isoly(:,:)=.false.
158    cotemx(:,:)=.false.
159    cotemy(:,:)=.false.
160    boost=.false.
161    iceberg(:,:)=.false.
162    !$OMP END WORKSHARE
163
164    ! fin de l'initialisation
165    !_____________________________________________________________________
166
167    ! 2-TESTE LES NOUVEAUX POINTS FLOTTANTS
168    ! -------------------------------------
169
170    !$OMP DO
171    do j=1,ny
172       do i=1,nx
173
174          uxs1(i,j)=uxbar(i,j)
175          uys1(i,j)=uybar(i,j)
176
177          archim = Bsoc(i,j)+H(i,j)*ro/row -sealevel_2d(i,j)
178          !      if ((i.eq.132).and.(j.eq.183)) print*,'archim=',archim
179
180
181          arch: if ((ARCHIM.LT.0.).and.(H(I,J).gt.1.e-3)) then    ! le point flotte
182             mk(i,j)=1
183
184
185             ex_pose: if ((.not.FLOT(I,J)).and.(isynchro.eq.1)) then  !  il ne flottait pas avant
186                FLOT(I,J)=.true.
187                BOOST=.false.
188
189                if (igrdline.eq.1) then   ! en cas de grounding line prescrite
190                   flot(i,j)=.false.
191                   H(i,j)=(10.+sealevel_2d(i,j)-Bsoc(i,j))*row/ro  ! pour avoir archim=10
192                   new_flot_point(i,j)=.false.
193                endif
194
195             else                                       ! isynchro=0 ou il flottait déja
196
197                if (.not.FLOT(I,J)) then               ! il ne flottait pas (isynchro=0)
198                   new_flot_point(i,j)=.true.          ! signale un point qui ne flottait pas
199                   ! au pas de temps precedent
200                   flot(i,j)=.true.
201
202                   if (igrdline.eq.1) then   ! en cas de grounding line prescrite
203                      flot(i,j)=.false.
204                      H(i,j)=(10.+sealevel_2d(i,j)-Bsoc(i,j))*row/ro  ! pour avoir archim=10
205                      new_flot_point(i,j)=.false.
206                   endif
207
208                endif
209             endif ex_pose
210
211
212          else if ((H(i,j).ge.0.).and.(archim.GE.0.)) then    !    le point ne flotte pas et est englace
213             mk(i,j)=0
214
215             if(FLOT(I,J)) then         !  mais il flottait avant
216                FLOT(I,J)=.false.
217                BOOST=.false.
218             endif
219             !cdc correction topo pour suivre  variations sealevel
220             !cdd           S(i,j)=Bsoc(i,j)+H(i,j)
221             S(i,j)=Bsoc(i,j)+H(i,j)
222             B(i,j)=Bsoc(i,j)
223
224          else if  ((H(i,j).LE.0.).and.(archim.LT.0.)) then    !    terre deglace qui devient ocean
225!cdc             ice(i,j)=0
226!cdc         H(i,j)=1.
227!cdc  1m           H(i,j)=min(1.,max(0.,(sealevel - Bsoc(i,j))*row/ro-0.01))
228             flot(i,j)=.true.  !cdc points ocean sont flot meme sans glace
229             H(i,j)=0.
230             S(i,j)=sealevel_2d(i,j) !afq -- WARNING: est-ce qu'on veut vraiment mettre S a la valeur locale du niveau marin?
231             B(i,j)=S(i,j)-H(i,j)
232          endif arch
233
234          !   Si la glace flotte -> PRUDENCE !!!
235          !   S et B sont alors determines avec la condition de flottabilite
236
237          if (flot(i,j)) then
238             shelfy = .true.
239
240             surnet=H(i,j)*(1.-ro/row)
241             S(i,j)=surnet+sealevel_2d(i,j) !afq -- WARNING: est-ce qu'on veut vraiment mettre S a la valeur locale du niveau marin?
242             B(i,j)=S(i,j)-H(i,j)
243          end if
244
245       end do
246    end do
247    !$OMP END DO
248       
249!!$ do i=1,nx
250!!$    do j=1,ny
251!!$       if (flot(i,j)) then
252!!$          mk(i,j)=1
253!!$       else
254!!$          mk(i,j)=0
255!!$       endif
256!!$    end do
257!!$ end do
258
259
260
261    !-----------------------------------------------------------------------
262    !$OMP DO
263    domain_x: do j=1,ny       
264       do i=2,nx
265
266          !    3_x    A- NOUVELLE DEFINITION DE FLOTMX, LES POINTS
267          !            AYANT UN DES VOISINS FLOTTANTS SONT FLOTMX ET GZMX
268          !         -------------------------------------------
269
270          !            fl1 est l'ancienne valeur de flotmx
271          gz1mx(i,j)=gzmx(i,j)         !     gz1 est l'ancienne valeur de gzmx
272          fl1mx(i,j)=flotmx(i,j)       !     fl1 est l'ancienne valeur de flotmx
273
274          flotmx(i,j)=flot(i,j).and.flot(i-1,j)
275
276          ! test pour detecter les nouveaux flotmx entre 2 dtt :
277
278          if (flotmx(i,j).and.(new_flot_point(i,j).or. &
279               new_flot_point(i-1,j))) then
280             appel_new_flot=.true.
281             new_flotmx(i,j)=.true.
282          endif
283
284
285          !   premiere determination de gzmx
286          !__________________________________________________________________________
287
288          ! gzmx si un des deux voisins est flottant et l'autre posé
289          !                                                                   i-1   i
290          gzmx(i,j)=((flot(i,j).and..not.flot(i-1,j)) & !         F    P
291               .or.(.not.flot(i,j).and.flot(i-1,j)))         !         P    F
292
293          !                 A condition d'etre assez proche de la flottaison
294          !                 sur le demi noeud condition archim < 100 m
295
296          archim=(Bsoc(i,j)+Bsoc(i-1,j))*0.5-(sealevel_2d(i,j)+sealevel_2d(i-1,j))*0.5+ro/row*Hmx(i,j)
297          gzmx(i,j)=gzmx(i,j).and.(archim.le.100.) 
298          cotemx(i,j)=gzmx(i,j)
299
300       end do
301    end do domain_x
302    !$OMP END DO
303    !if (itracebug.eq.1)  call tracebug('  routine flottab apres domain_x')
304
305    !     3_y    B- NOUVELLE DEFINITION DE FLOTMY
306    !         --------------------------------
307    !$OMP DO
308    domain_y: do j=2,ny       
309       do i=1,nx
310
311          gz1my(i,j)=gzmy(i,j)           !       gz1 est l'ancienne valeur de gzmy
312          fl1my(i,j)=flotmy(i,j)         !       fl1 est l'ancienne valeur de flotmy
313
314          flotmy(i,j)=flot(i,j).and.flot(i,j-1)
315
316          ! test pour detecter les nouveaux flotmy entre 2 dtt :
317
318          if (flotmy(i,j).and.(new_flot_point(i,j).or.     &
319               new_flot_point(i,j-1))) then
320             appel_new_flot=.true.
321             new_flotmy(i,j)=.true.
322          endif
323
324          !   premiere determination de gzmy
325          !__________________________________________________________________________
326
327          ! gzmy si un des deux voisins est flottant et l'autre posé
328
329          gzmy(i,j)=((flot(i,j).and..not.flot(i,j-1))          &
330               .or.(.not.flot(i,j).and.flot(i,j-1)))                 
331
332          !                 A condition d'etre assez proche de la flottaison
333          !                 sur le demi noeud condition archim > 100 m
334
335          archim=(Bsoc(i,j)+Bsoc(i,j-1))*0.5-(sealevel_2d(i,j)+sealevel_2d(i,j-1))*0.5+ro/row*Hmy(i,j)
336          gzmy(i,j)=gzmy(i,j).and.(archim.le.100.) 
337          cotemy(i,j)=gzmy(i,j)
338
339       end do
340    end do domain_y
341    !$OMP END DO
342
343
344    !-------------------------------------------------------------------------------------
345    ! attention : pour expériences Heino
346    !             gzmy(i,j)=gzmy_heino(i,j)
347    !             shelfy=.true.
348    !             shelfy=.false.
349    !____________________________________________________________________________________
350
351
352!!$
353!!$
354!!$! 4- Condition sur les bords
355!!$
356!!$     
357!!$       do i=2,nx
358!!$         flotmx(i,1) = (flot(i,1).or.flot(i-1,1))
359!!$         flotmy(i,1) = .false.
360!!$       end do
361!!$       
362!!$       do j=2,ny
363!!$          flotmy(1,j) = (flot(1,j).or.flot(1,j-1))
364!!$          flotmx(1,j) = .false.
365!!$       end do
366!!$
367!!$       flotmx(1,1) = .false.
368!!$       flotmy(1,1) = .false.
369!!$
370
371
372    !      4- determination des iles
373    !      -------------------------
374    !$OMP WORKSHARE
375    ilemx(:,:)=.false.
376    ilemy(:,:)=.false.
377    !$OMP END WORKSHARE
378
379    !       selon x
380    !$OMP DO
381    ilesx:  do j=2,ny-1
382       do i=3,nx-2
383          !                       F   G   F   
384          !                           x
385          ! modif tof 26/08/02 limite sur la pente (si diff S > 400 m)
386          if ((flot(i-1,j).and..not.flot(i,j).and.flot(i+1,j)).and. &
387               (sdx(i,j).LT.1.E-02)) then
388             ilemx(i,j)=.true.
389             ilemx(i+1,j)=.true.
390
391             !                      F  G   G   F
392             !                         x
393             ! modif tof 26/08/02 limite sur la pente (si diff S > 400 m)
394          else if ((flot(i-1,j).and..not.flot(i,j)                  &
395               .and..not.flot(i+1,j)).and.flot(i+2,j).and.           &
396               (sdx(i,j).LT.1.E-02.and.sdx(i+1,j).LT.1.E-02)) then
397             ilemx(i,j)=.true.
398             ilemx(i+1,j)=.true.
399             ilemx(i+2,j)=.true.
400
401             !                      F   G   G   F
402             !                              x
403             ! modif tof 26/08/02 limite sur la pente (si diff S > 400 m)
404          else if ((flot(i-2,j).and..not.flot(i-1,j)                &
405               .and..not.flot(i,j)).and.flot(i+1,j).and.             &
406               (sdx(i,j).LT.1.E-02.and.sdx(i-1,j).LT.1.E-02)) then
407             ilemx(i-1,j)=.true.
408             ilemx(i,j)=.true.
409             ilemx(i+1,j)=.true.
410
411             !                      F   G   G   G    F
412             !                              x
413             ! modif tof 26/08/02 limite sur la pente (si diff S > 400 m)
414          else if ((i.lt.nx-2)                                      &
415               .and.(flot(i-2,j).and..not.flot(i-1,j)                &
416               .and..not.flot(i,j)).and..not.flot(i+1,j)             &
417               .and.flot(i+2,j).and.                                &
418               (sdx(i,j).LT.1.E-02.and.sdx(i-1,j).LT.1.E-02         &
419               .and.sdx(i+1,j).LT.1.E-02)) then
420             ilemx(i-1,j)=.true.
421             ilemx(i,j)=.true.
422             ilemx(i+1,j)=.true.
423             ilemx(i+2,j)=.true.
424
425          endif
426
427       end do
428    end do ilesx
429    !$OMP END DO
430
431    !       selon y
432    !$OMP DO
433    ilesy: do j=3,ny-2
434       do i=2,nx-1
435          !                       F   G   F   
436          !                           x
437          ! modif tof 26/08/02 limite sur la pente (si diff S > 400 m)
438          if ((flot(i,j-1).and..not.flot(i,j).and.flot(i,j+1)).and. &
439               (sdy(i,j).LT.1.E-02)) then
440             ilemy(i,j)=.true.
441             ilemy(i,j+1)=.true.
442
443             !                      F  G   G   F
444             !                         x
445             ! modif tof 26/08/02 limite sur la pente (si diff S > 400 m)
446          else if ((flot(i,j-1).and..not.flot(i,j)                  &
447               .and..not.flot(i,j+1)).and.flot(i,j+2).and.           &
448               (sdy(i,j).LT.1.E-02.and.sdy(i,j+1).LT.1.E-02)) then
449             ilemy(i,j)=.true.
450             ilemy(i,j+1)=.true.
451             ilemy(i,j+2)=.true.
452
453             !                      F   G   G   F
454             !                              x
455             ! modif tof 26/08/02 limite sur la pente (si diff S > 400 m)
456          else if ((flot(i,j-2).and..not.flot(i,j-1)                 &
457               .and..not.flot(i,j)).and.flot(i,j+1).and.              &
458               (sdy(i,j).LT.1.E-02.and.sdy(i,j-1).LT.1.E-02)) then
459             ilemy(i,j-1)=.true.
460             ilemy(i,j)=.true.
461             ilemy(i,j+1)=.true.
462
463             !                      F   G   G   G    F
464             !                              x
465             ! modif tof 26/08/02 limite sur la pente (si diff S > 400 m)
466          else if ((j.lt.ny-2)                                      &
467               .and.(flot(i,j-2).and..not.flot(i,j-1)                &
468               .and..not.flot(i,j)).and..not.flot(i,j+1)             &
469               .and.flot(i,j+2).and.                                &
470               (sdy(i,j).LT.1.E-02.and.sdy(i,j-1).LT.1.E-02         &
471               .and.sdy(i,j+1).LT.1.E-02)) then
472             ilemy(i,j-1)=.true.
473             ilemy(i,j)=.true.
474             ilemy(i,j+1)=.true.
475             ilemy(i,j+2)=.true.
476          endif
477       end do
478    end do ilesy
479    !$OMP END DO
480    !$OMP END PARALLEL
481    ! fin des iles
482
483!!$call detect_assym(nx,ny,0,41,1,0,1,0,H,itestf)
484!!$if (itestf.gt.0) then
485!!$   write(6,*) 'dans flottab avant dragging asymetrie sur H  pour time=',time
486!!$   stop
487!!$else
488!!$   write(6,*) 'dans flottab avant dragging pas d asymetrie sur H  pour time=',time
489!!$
490!!$end if
491
492    ! 5- calcule les noeuds qui sont streams a l'interieur et donne le betamx et betamy
493    !----------------------------------------------------------------------------------
494    call dragging         
495   
496    if (itracebug.eq.1)  call tracebug(' routine flottab apres call dragging')
497!!$call detect_assym(nx,ny,0,41,1,0,1,0,H,itestf)
498!!$if (itestf.gt.0) then
499!!$   write(6,*) 'dans flottab apres dragging asymetrie sur H  pour time=',time
500!!$   stop
501!!$else
502!!$   write(6,*) 'dans flottab aapres dragging pas d asymetrie sur H  pour time=',time
503!!$
504!!$end if
505
506    !   6- calcule les vitesses des points qui sont devenus gzm
507    !$OMP PARALLEL
508    !$OMP DO         
509    do j=1,ny
510       do i=2,nx-1
511          !      si le point etait posé (non gz) et devient gzmx
512          !      definir la direction de la vitesse (moyenne des points)
513
514          if ((.not.gz1mx(i,j)).and.(.not.fl1mx(i,j)).and.gzmx(i,j).and. &
515               (i.gt.2).and.(i.lt.nx))  then
516             uxs1(i,j)=(uxbar(i+1,j)+uxbar(i-1,j))/2.
517          endif
518
519       end do
520    end do
521    !$OMP END DO
522
523    !$OMP DO
524    do j=2,ny-1
525       do i=1,nx
526          !      si le point etait posé (non gz) et devient gzmy
527          !      definir la direction de la vitesse (moyenne des points)
528          if ((.not.gz1my(i,j)).and.(.not.fl1my(i,j)).and.gzmy(i,j).and. &
529               (j.gt.2).and.(j.lt.ny))  then
530             uys1(i,j)=(uybar(i,j+1)+uybar(i,j-1))/2.
531          endif
532
533       end do
534    end do
535    !$OMP END DO
536
537
538    !  7-On determine finalement la position des noeuds stream ou shelf
539    !  -------------------------------------------------------------
540
541    if (nt.ge.2) then   ! pour ne pas faire ce calcul lors du premier passage
542       !$OMP WORKSHARE
543       uxbar(:,:)=uxs1(:,:)
544       uybar(:,:)=uys1(:,:)
545       !$OMP END WORKSHARE
546    endif
547
548    !$OMP WORKSHARE
549    flgzmx(:,:)=(marine.and.(flotmx(:,:).or.gzmx(:,:).or.ilemx(:,:)))   &
550         .or.(.not.marine.and.flotmx(:,:))
551    where (hmx(:,:).eq.0.)
552      flgzmx(:,:) = .false.
553    endwhere
554    flgzmy(:,:)=(marine.and.(flotmy(:,:).or.gzmy(:,:).or.ilemy(:,:)))   &
555         .or.(.not.marine.and.flotmy(:,:))
556    where (hmy(:,:).eq.0.)
557      flgzmy(:,:) = .false.
558    endwhere
559    !$OMP END WORKSHARE
560
561
562    ! 8- Pour la fusion basale sous les ice shelves- region proche de la grounding line
563    !---------------------------------------------------------------------------------
564    !       fbm est vrai si le point est flottant mais un des voisins est pose
565    !_________________________________________________________________________
566    !$OMP DO
567    do j=2,ny-1
568       do i=2,nx-1
569
570          ! if (i.gt.2.AND.i.lt.nx) then   
571          fbm(i,j)=flot(i,j).and.      & 
572               ((.not.flot(i+1,j)).or.(.not.flot(i,j+1)) &
573               .or.(.not.flot(i-1,j)).or.(.not.flot(i,j-1)))
574          !     endif
575       end do
576    end do
577    !$OMP END DO
578
579
580    !  9-On determine maintenant la position du front de glace
581    !  -------------------------------------------------------
582    !  C'est ici que l'on determine la position et le type de front
583    !       print*,'on est dans flottab pour definir les fronts'
584
585
586
587!!$do i=3,nx-2
588!!$   do j=3,ny-2
589!!$      if (h(i,j).gt.1.1) ice(i,j)=1       
590!!$   end do
591!!$end do
592!                       print*, 'flolottab debug', H(71,25),flot(71,25),bm(71,25),ice(71,25),time
593!print*,'H(90,179) flottab 2',H(90,179),ice(90,179),flot(90,179)
594    !$OMP WORKSHARE
595    where (flot(:,:))
596!cdc 1m       where (H(:,:).gt.max(Hmin,Hmin+BM(:,:)-Bmelt(:,:)))
597      where (H(:,:).gt.max(BM(:,:)-Bmelt(:,:)+petit_H,0.)*dt)
598!cdc                     where (H(:,:).gt.0.)
599          ice(:,:)=1
600       elsewhere 
601          ice(:,:)=0
602          H(:,:)=0.
603          S(:,:)=H(:,:)*(1.-ro/row) + sealevel_2d(:,:)
604          B(:,:)=S(:,:) - H(:,:)
605       end where
606    elsewhere
607       where (H(:,:).gt.0.) 
608          ice(:,:)=1
609       elsewhere 
610          ice(:,:)=0
611       end where
612    end where
613    !$OMP END WORKSHARE
614    !$OMP END PARALLEL
615!    print*,'flottab',time,H(191,81),bm(191,81),bmelt(191,81),(BM(191,81)-Bmelt(191,81)+petit_H)*dt,ice(191,81)
616!print*,'H(90,179) flottab 3',H(90,179),ice(90,179),flot(90,179),Bsoc(90,179)+H(90,179)*ro/row -sealevel
617 
618    !call determin_front ! cette version ne conserve pas la masse !!!
619    call determin_front_tof ! version simplifiee
620
621    ! pour sorties initMIP:
622    debug_3D(:,:,118) = ice(:,:)*(1-mk(:,:))
623    debug_3D(:,:,119) = ice(:,:)*mk(:,:)
624
625   
626  end subroutine flottab
627!-------------------------------------------------------------------- 
628
629!> SUBROUTINE: determin_tache
630!! Routine pour la dtermination du numero de tache a effectuer
631!>
632subroutine determin_tache
633
634!$ USE OMP_LIB
635
636implicit none
637integer :: indice
638integer :: label         ! no des taches rencontrées dans le mask
639integer :: label_max     ! no temporaire maxi de tache rencontrées
640!      integer :: mask_nb = 4
641integer,parameter :: mask_nb = 2   ! version ou on ne compte pas les diagonales
642!     integer,dimension(mask_nb) :: mask
643integer,dimension(mask_nb) :: mask
644
645
646! 1-initialisation
647!-----------------
648label_max=1      ! numero de la tache, la premiere tache est notée 1
649label=1
650do i=1,n_ta_max
651   compt(i)=i
652enddo
653!      table_in  = .false.
654!$OMP PARALLEL
655!$OMP WORKSHARE
656table_out(:,:) = 0
657iceberg1D(:)  = .true.
658icetrim (:) = .true.
659nb_pts_tache(:) = 0
660!$OMP END WORKSHARE
661!$OMP END PARALLEL
662!    open(unit=100,file="tache.data",status='replace')
663
664! 2-reperage des taches
665!----------------------
666
667do j=2,ny-1
668  do i=2,nx-1
669
670     IF (ice(i,j).ge.1) THEN ! on est sur la glace-----------------------------!
671                       
672        if ((ice(i-1,j).ge.1).or.(ice(i,j-1).ge.1)) then   !masque de 2 cases adjacentes
673           !      un des voisins est deja en glace
674           mask(1) = table_out(i-1,j)
675           mask(2) = table_out(i,j-1) 
676           label = label_max
677
678           !on determine la valeur de la tache minimun (>0) presente ds le masque
679           do indice=1,mask_nb
680              if (mask(indice).gt.0) label=min(label,mask(indice))
681           enddo
682!cdc       label=min(label,minval(mask(:), mask=mask > 0))
683
684           !on fixe la valeur de la tache voisine minimun au point etudie (via label)
685           table_out(i,j)=label
686           !si ce noeud est posé, alors la tache n'est pas un iceberg et iceberg=.F.
687           if (.not.FLOT(I,J)) then
688              iceberg1D(label)=.false.
689           endif
690
691           !si ce noeud est posé, alors la tache n'est pas un ice stream et icestrim=.F.
692           if ((.not.gzmx(i,j).and..not.gzmx(i+1,j)).and.  &
693               (.not.gzmy(i,j).and..not.gzmy(i,j+1))) then
694              icetrim(label)=.false.
695           endif
696
697           ! si 2 taches differentes sont dans le masque, il faut les identifier dans compt
698           ! on lui affecte le numero de la tache fondamentale
699
700           do indice=1,mask_nb
701              if(mask(indice).gt.label) then
702                 compt(mask(indice))=-label
703              endif
704           enddo
705                                                                   ! exemple on est sur le point X : 5  X
706          do indice=1,mask_nb                                      !                                   20
707            if(mask(indice).gt.label) then                         ! mask(2)=20 > 5             
708              compt(mask(indice))=label                            ! compt(20)=5
709              if (.not.iceberg1D(mask(indice))) iceberg1D(label)=.false. ! si la tache n'etais pas un iceberg => iceberg =.false.  iceberg(5)=.false.               
710              if (.not.icetrim(mask(indice))) icetrim(label)=.false.
711              where (table_out(:,:).eq.mask(indice))               ! where table_out(:,:)=mask(2)=20
712                table_out(:,:)=label                        ! table_out(:,:)=label=5                 
713              endwhere
714            endif
715          enddo   
716
717        else !aucun des voisins est une tache
718           table_out(i,j)= label_max
719           compt(label_max)=label_max
720           !si ce noeud est posé, alors la ache n'est pas un iceberg et iceberg=.F.
721           if (.not.FLOT(I,J)) then
722              iceberg1D(label_max)=.false.
723           endif
724
725           !si ce noeud est posé, alors le tache n'est pas un ice stream et icestrim=.F.
726           if ((.not.gzmx(i,j).and..not.gzmx(i+1,j)).and.  &
727               (.not.gzmy(i,j).and..not.gzmy(i,j+1))) then
728              icetrim(label)=.false.
729           endif
730             
731           label_max  = label_max+1
732           if (label_max.gt.n_ta_max) print*,'ATTENTION trop de taches icebergs=',label_max 
733        endif
734
735
736     else           !on est pas sur une tache----------------------------------------------
737        table_out(i,j)=0    ! Pas necessaire (reecrit 0 sur 0)             
738     endif          !---------------------------------------------------------------------
739
740
741  enddo
742enddo
743
744
745
746! On reorganise compt en ecrivant le numero de la tache fondamentale
747! i.e. du plus petit numero present sur la tache (Sans utiliser de recursivité)
748! On indique aussi le nb de point que contient chaque taches (nb_pts_tache)
749
750  !$OMP PARALLEL
751  !$OMP DO
752  do j=1,ny
753    do i=1,nx
754      if (table_out(i,j).ne.0) then
755        nb_pts_tache(compt(table_out(i,j)))= nb_pts_tache(compt(table_out(i,j)))+1
756      endif
757    enddo
758  enddo
759  !$OMP END DO
760  !$OMP END PARALLEL
761
762  !On compte comme englacé uniquement les calottes dont une partie est posée     
763  !$OMP PARALLEL PRIVATE(smax_,smax_coord,smax_i,smax_j,mask_tache_ij)
764  !$OMP DO
765  do j=3,ny-2
766    do i=3,nx-2
767      test1: if (.not.iceberg1D(table_out(i,j))) then ! on est pas sur un iceberg
768        if (nb_pts_tache(table_out(i,j)).ge.1) then
769          ice(i,j)=1
770          ! ici on est sur une tache non iceberg >= 5 points                       
771          ! on teste si la tache n'est pas completement ice stream
772   
773          test2: if (icetrim(table_out(i,j))) then   ! on a une ile d'ice stream
774   
775            mask_tache_ij(:,:)=.false.
776            mask_tache_ij(:,:)=(table_out(:,:).eq.table_out(i,j))       ! pour toute la tache
777   
778            smax_=maxval(S(:,:),MASK=mask_tache_ij(:,:))
779            smax_coord(:)=maxloc(S(:,:),MASK=mask_tache_ij(:,:))
780            smax_i=smax_coord(1)
781            smax_j=smax_coord(2)
782 
783            gzmx(smax_i,smax_j)=.false. ; gzmx(smax_i+1,smax_j)=.false.
784            gzmy(smax_i,smax_j)=.false. ; gzmx(smax_i,smax_j+1)=.false.
785            flgzmx(smax_i,smax_j)=.false. ; flgzmx(smax_i+1,smax_j)=.false.
786            flgzmy(smax_i,smax_j)=.false. ; flgzmx(smax_i,smax_j+1)=.false.
787     
788            if (Smax_.le.sealevel) then  ! afq -- WARNING: en fait avec le niveau marin local cest plus complique que ca!
789            !if (Smax_.le.sealevel_2d(i,j)) then ! afq --WARNING: il faudrait regarder point par point sur la tache...
790              write(num_tracebug,*)'Attention, une ile avec la surface sous l eau'
791              write(num_tracebug,*)'time=',time,'   coord:',smax_i,smax_j
792            end if   
793          endif test2 
794        end if                                             ! endif deplace
795!cdc transfere dans calving :             
796      else ! on est sur un iceberg                          !   test1
797        iceberg(i,j)=iceberg1D(table_out(i,j))
798!~        ice(i,j)=0
799!~        h(i,j)=0. !1. afq, we should put everything in calving!
800!~        surnet=H(i,j)*(1.-ro/row)
801!~        S(i,j)=surnet+sealevel
802!~        B(i,j)=S(i,j)-H(i,j)             
803      endif test1   
804    end do
805  end do   
806  !$OMP END DO
807  !$OMP END PARALLEL
808
809debug_3D(:,:,121)=real(table_out(:,:))
810
811end subroutine determin_tache
812!----------------------------------------------------------------------
813!> SUBROUTINE: determin_front
814!!Routine pour la determination du front
815!>
816subroutine determin_front
817!!$ USE OMP_LIB
818integer :: i_moins1,i_plus1,i_plus2
819integer :: j_moins1,j_plus1,j_plus2
820     
821      !$OMP PARALLEL
822      !$OMP DO
823      do j=3,ny-2
824        do i=3,nx-2
825
826 surice:if  (ice(i,j).eq.0) then
827         do pmx=-1,1,2
828          do pmy=-1,1,2
829
830 diagice :  if (ice(i+pmx,j+pmy).eq.1) then
831
832              if ((ice(i+pmx,j)+ice(i,j+pmy).eq.2)) then    ! test (i) pour eviter les langues
833                                                            ! de glaces diagonales en coin(26dec04)
834                   if ((ice(i+2*pmx,j).eq.1.and.ice(i+2*pmx,j+pmy).eq.0).or.&
835                       (ice(i,j+2*pmy).eq.1.and.ice(i+pmx,j+2*pmy).eq.0)) then
836                           ice(i,j)=1
837                           h(i,j)=max(1.,h(i,j))
838                   endif         
839
840! test (i) pour eviter les langues de glaces diagonales :
841!                        mouvement du cheval aux echecs 
842
843               if ((ice(i+2*pmx,j+pmy)+ice(i+pmx,j+2*pmy).eq.1)) then
844                   if (ice(i+2*pmx,j+pmy).eq.1.and. &
845                      (ice(i+2*pmx,j+2*pmy)+ice(i,j+2*pmy)).ge.1) then
846                           ice(i,j)=1
847                           h(i,j)=max(1.,h(i,j))
848                   endif       
849                   if (ice(i+pmx,j+2*pmy).eq.1.and. &
850                      (ice(i+2*pmx,j+2*pmy)+ice(i+2*pmx,j)).ge.1) then
851                           ice(i,j)=1
852                           h(i,j)=max(1.,h(i,j))
853                   endif       
854
855! test (ii) pour eviter les langues de glaces diagonales :
856!            le point glace ice(i+pmx,j+pmy) a :
857!                          - ses 4 voisins frontaux en glace
858!                          - mais 2 voisins vides diagonalement opposes   
859           
860               elseif ((ice(i+2*pmx,j+pmy)+ice(i+pmx,j+2*pmy).eq.2)  &
861                                .and.ice(i+2*pmx,j+2*pmy).eq.0) then
862
863! test (iii) pour faire les tests (i) et (ii)
864                    ice(i,j)=1
865                    h(i,j)=max(1.,h(i,j))
866                    ice(i+2*pmx,j+2*pmy)=1
867                    h(i+2*pmx,j+2*pmy)=max(1.,h(i+2*pmx,j+2*pmy))
868               endif
869            endif
870           endif diagice   
871          enddo
872         enddo
873         endif surice       
874       end do
875      end do
876      !$OMP END DO
877      !$OMP ENd PARALLEL
878
879!!$call detect_assym(nx,ny,0,41,1,0,1,0,H,itestf)
880!!$if (itestf.gt.0) then
881!!$   write(6,*) 'dans front avant remplissage baies asymetrie sur H  pour time=',time
882!!$   stop
883!!$else
884!!$   write(6,*) 'dans front avant remplissage baies pas d asymetrie sur H  pour time=',time
885!!$
886!!$end if
887
888
889!     print*,'dans remplissage baies',time
890       
891baies: do k=1,2
892!$OMP PARALLEL
893!$OMP DO PRIVATE(i_moins1,j_moins1,i_plus1,j_plus1,i_plus2,j_plus2)
894do j=1,ny
895   do i=1,nx
896
897surice_xy: if  (ice(i,j).eq.0) then
898   i_moins1=max(i-1,1)
899   j_moins1=max(j-1,1)
900   i_plus1=min(i+1,nx)
901   j_plus1=min(j+1,ny)
902   i_plus2=min(i+2,nx)
903   j_plus2=min(j+2,ny)
904 
905! test (iii) pour trouver les baies de largeur 1 ou 2 cases
906! et combler les trous si ce sont des baies
907! si ce ne sont pas des baies, ne pas combler et creer des langues de glaces artificielles             
908! baies horizontales 
909 
910         if (ice(i_moins1,j).eq.1.and.(ice(i_plus1,j).eq.1.or.ice(i_plus2,j).eq.1)) then
911            if (ice(i,j_moins1).eq.1.or.ice(i,j_plus1).eq.1)  then    ! ice(i,j)=1
912               ice(i,j)=1
913               H(i,j)=max(1.,H(i,j))
914            endif
915         endif
916
917
918         if (ice(i,j_moins1).eq.1.and.(ice(i,j_plus1).eq.1.or.ice(i,j_plus2).eq.1)) then
919            if (ice(i_moins1,j).eq.1.or.ice(i_plus1,j).eq.1) then !ice(i,j)=1
920               ice(i,j)=1
921               H(i,j)=max(1.,H(i,j))
922            endif
923         endif
924
925      endif surice_xy
926   end do
927end do
928!$OMP END DO
929!$OMP END PARALLEL
930end do baies
931
932!!$call detect_assym(nx,ny,0,41,1,0,1,0,H,itestf)
933!!$if (itestf.gt.0) then
934!!$   write(6,*) 'dans front apres remplissage baies asymetrie sur H  pour time=',time
935!!$   stop
936!!$else
937!!$   write(6,*) 'dans front apres remplissage baies pas d asymetrie sur H  pour time=',time
938!!$
939!!$end if
940
941!$OMP PARALLEL
942!$OMP DO
943do j=2,ny-1
944   do i=2,nx-1
945
946      if (ice(i,j).eq.1) then     !         test si ice=1
947
948! if ice, on determine front...
949! ainsi, front=0 sur les zones = 0
950
951         front(i,j)=(ice(i-1,j)+ice(i+1,j)+ice(i,j+1)+ice(i,j-1))
952         !front= le nb de faces en contact avec un voisin englacé
953      endif
954   end do
955end do
956!$OMP END DO
957
958! traitement des bords. On considere que l'exterieur n'a pas de glace
959! attention ce n'est vrai que sur la grande grille
960
961!$OMP DO PRIVATE(i)
962do j=2,ny-1
963   i=1
964   front(i,j)=(ice(i+1,j)+ice(i,j+1)+ice(i,j-1))
965   i=nx
966   front(i,j)=(ice(i-1,j)+ice(i,j+1)+ice(i,j-1))
967end do
968!$OMP END DO
969
970!$OMP DO PRIVATE(j)
971do i=2,nx-1
972   j=1 
973   front(i,j)=(ice(i-1,j)+ice(i+1,j)+ice(i,j+1))
974   j=ny
975   front(i,j)=(ice(i-1,j)+ice(i+1,j)+ice(i,j-1))
976end do
977!$OMP END DO
978
979! traitement des coins
980
981front(1,1)=ice(2,1)+ice(2,1)
982front(1,ny)=ice(2,ny)+ice(1,ny-1)
983front(nx,1)=ice(nx,2)+ice(nx-1,1)
984front(nx,ny)=ice(nx,ny-1)+ice(nx-1,ny)
985
986!!$call detect_assym(nx,ny,0,41,1,0,1,0,H,itestf)
987!!$if (itestf.gt.0) then
988!!$   write(6,*) 'dans front apres front asymetrie sur H  pour time=',time
989!!$   stop
990!!$else
991!!$   write(6,*) 'dans front apres front pas d asymetrie sur H  pour time=',time
992!!$
993!!$end if
994
995!   on ne compte pas les taches de glace de 2 cases (horizontales ou verticales)
996!   en fait, si ces deux cases sont flottantes, il faut enlever les icebergs
997!   de n'importe quelle taille).
998!   si ces deux taches sont posées (ou une des deux), il n'y a pas assez de conditions aux limites
999
1000!$OMP DO
1001do j=1,ny
1002   do i=1,nx-1
1003      if (front(i,j).eq.1) then
1004         if (front(i+1,j).eq.1) then
1005            ice(i,j)=0
1006            ice(i+1,j)=0
1007            front(i,j)=0
1008            front(i+1,j)=0
1009         endif
1010      endif
1011   end do
1012end do
1013!$OMP END DO
1014
1015!$OMP DO
1016do j=1,ny-1
1017   do i=1,nx
1018      if (front(i,j).eq.1) then
1019         if (front(i,j+1).eq.1) then
1020            ice(i,j)=0
1021            ice(i,j+1)=0
1022            front(i,j)=0
1023            front(i,j+1)=0
1024         endif
1025      end if
1026   end do
1027end do
1028!$OMP END DO
1029
1030!isolx signifie pas de voisins en x
1031!isoly signifie pas de voisins en y
1032!remarque :
1033!si isolx/y=.true. alors frontfacex/y=0 (a la fois +1 & -1 or +1-1=0)
1034
1035! calcul de frontfacex et isolx
1036!$OMP DO
1037do j=1,ny
1038   do i=2,nx-1
1039
1040      if (front(i,j).ge.1.and.front(i,j).le.3) then    !front(entre 1 et 3)
1041         
1042         if ((ice(i-1,j)+ice(i+1,j)).lt.2) then        ! il y a un front // a x
1043         
1044            if ((ice(i-1,j)+ice(i+1,j)).eq.0) then
1045               isolx(i,j)=.true.
1046            elseif (ice(i-1,j).eq.0) then
1047               frontfacex(i,j)=-1                      ! front  i-1 |i  i+1
1048            else
1049               frontfacex(i,j)=+1                      ! front  i-1  i| i+1
1050            endif
1051         endif
1052      end if !fin du test il y a un front
1053         
1054   end do
1055end do
1056!$OMP END DO
1057
1058! calcul de frontfacey et isoly
1059!$OMP DO
1060do j=2,ny-1
1061   do i=1,nx
1062
1063      if (front(i,j).ge.1.and.front(i,j).le.3) then   !front(entre 1 et 3)
1064         
1065         if ((ice(i,j-1)+ice(i,j+1)).lt.2) then       ! il y a un front // a y
1066             
1067            if ((ice(i,j-1)+ice(i,j+1)).eq.0) then
1068               isoly(i,j)=.true.                      !front   j-1 |j| j+1
1069            elseif (ice(i,j-1).eq.0) then
1070               frontfacey(i,j)=-1                     !front   j-1 |j j+1
1071            else
1072               frontfacey(i,j)=+1                     !front   j-1  j| j+1
1073            endif
1074         endif
1075     end if !fin du test il y a un front
1076         
1077   end do
1078end do
1079!$OMP END DO
1080
1081
1082! traitement des bords. On considere que l'exterieur n'a pas de glace
1083! attention ce n'est vrai que sur la grande grille
1084
1085!$OMP DO PRIVATE(i)
1086do j=2,ny-1
1087   i=1
1088   if (front(i,j).ge.1)  then
1089      if (ice(i+1,j).eq.0) then
1090         isolx(i,j)=.true.
1091      else
1092         frontfacex(i,j)=-1
1093      endif
1094   end if
1095   i=nx
1096   if (front(i,j).ge.1)  then
1097      if (ice(i-1,j).eq.0) then
1098         isolx(i,j)=.true.
1099      else
1100         frontfacex(i,j)=1
1101      endif
1102   end if
1103end do
1104!$OMP END DO
1105
1106!$OMP DO PRIVATE(j)
1107do i=2,nx-1
1108   j=1 
1109   if (front(i,j).ge.1)  then
1110      if (ice(i,j+1).eq.0) then
1111         isoly(i,j)=.true.
1112      else
1113         frontfacey(i,j)=-1
1114      endif
1115   end if
1116   j=ny
1117   if (front(i,j).ge.1)  then
1118      if (ice(i,j-1).eq.0) then
1119         isoly(i,j)=.true.
1120      else
1121         frontfacey(i,j)=1
1122      endif
1123   end if
1124end do
1125!$OMP END DO
1126!$OMP END PARALLEL
1127
1128return
1129end subroutine determin_front
1130!------------------------------------------------------------------------------
1131
1132subroutine determin_front_tof
1133
1134integer,dimension(nx,ny) :: nofront ! tableau de travail (points au dela du front)
1135!$OMP PARALLEL
1136!$OMP DO
1137do j=2,ny-1
1138   do i=2,nx-1
1139
1140      if (ice(i,j).eq.1) then     !         test si ice=1
1141
1142! if ice, on determine front...
1143! ainsi, front=0 sur les zones = 0
1144
1145         front(i,j)=(ice(i-1,j)+ice(i+1,j)+ice(i,j+1)+ice(i,j-1))
1146         !front= le nb de faces en contact avec un voisin englacé
1147      endif
1148   end do
1149end do
1150!$OMP END DO
1151
1152! traitement des bords. On considere que l'exterieur n'a pas de glace
1153! attention ce n'est vrai que sur la grande grille
1154
1155!$OMP DO PRIVATE(i)
1156do j=2,ny-1
1157   i=1
1158   front(i,j)=(ice(i+1,j)+ice(i,j+1)+ice(i,j-1))
1159   i=nx
1160   front(i,j)=(ice(i-1,j)+ice(i,j+1)+ice(i,j-1))
1161end do
1162!$OMP END DO
1163
1164!$OMP DO PRIVATE(j)
1165do i=2,nx-1
1166   j=1 
1167   front(i,j)=(ice(i-1,j)+ice(i+1,j)+ice(i,j+1))
1168   j=ny
1169   front(i,j)=(ice(i-1,j)+ice(i+1,j)+ice(i,j-1))
1170end do
1171!$OMP END DO
1172!$OMP BARRIER
1173! traitement des coins
1174
1175front(1,1)=ice(2,1)+ice(2,1)
1176front(1,ny)=ice(2,ny)+ice(1,ny-1)
1177front(nx,1)=ice(nx,2)+ice(nx-1,1)
1178front(nx,ny)=ice(nx,ny-1)+ice(nx-1,ny)
1179
1180! Les points à plus d'un point de grille du bord sont front=-1
1181!$OMP WORKSHARE
1182nofront(:,:)=0
1183!$OMP END WORKSHARE
1184!$OMP BARRIER
1185
1186!$OMP DO
1187do j=2,ny-1
1188        do i=2,nx-1
1189                if ((ice(i,j).eq.0).and.(front(i-1,j)+front(i+1,j)+front(i,j-1)+front(i,j+1)).eq.0) then
1190                        nofront(i,j)=-1
1191                endif
1192        enddo
1193enddo
1194!$OMP END DO
1195!$OMP BARRIER
1196
1197!$OMP WORKSHARE
1198where (nofront(:,:).eq.-1)
1199        front(:,:)=-1
1200endwhere
1201!$OMP END WORKSHARE
1202!$OMP END PARALLEL             
1203
1204end subroutine determin_front_tof
1205
1206
1207!> SUBROUTINE: determin_marais
1208!! afq -- Routine pour l'identification des "marais"
1209!! Un marais est une tache "shelf" entouré de points grounded
1210!! Copie sauvage de determin_tache, adapte au probleme du marais
1211!>
1212subroutine determin_marais
1213
1214  !$ USE OMP_LIB
1215
1216  implicit none
1217 
1218  integer :: indice
1219  integer :: label         ! no des taches rencontrées dans le mask
1220  integer :: label_max     ! no temporaire maxi de tache rencontrées
1221  integer,parameter :: mask_nb = 2   ! version ou on ne compte pas les diagonales
1222  integer,dimension(mask_nb) :: mask ! numero de tache des points adjacents
1223
1224  integer,dimension(nx,ny)          :: table_out_marais    !< numeros de tache d'un point ij
1225  integer,dimension(0:n_ta_max)     :: compt_marais        !< contient les equivalence entre les taches
1226  integer,dimension(0:n_ta_max)     :: nb_pts_marais       !< indique le nombre de points par tache
1227  logical,dimension(0:n_ta_max)     :: marais              !< T si flottants entoure de poses, F sinon
1228
1229
1230! 1-initialisation
1231!-----------------
1232  label_max=1      ! numero de la tache, la premiere tache est notée 1
1233  label=1
1234  do i=1,n_ta_max
1235    compt_marais(i)=i
1236  enddo
1237  !$OMP PARALLEL
1238  !$OMP WORKSHARE
1239  table_out_marais(:,:) = 0
1240  marais(:)  = .true.
1241  nb_pts_marais(:) = 0
1242  !$OMP END WORKSHARE
1243  !$OMP END PARALLEL
1244
1245! 2-reperage des taches
1246!----------------------
1247
1248  do j=2,ny-1
1249    do i=2,nx-1
1250      if ((ice(i,j).ge.1).and.flot(i,j)) then ! on est sur la glace qui flotte-------------------!
1251
1252        if (((ice(i-1,j).ge.1).and.flot(i-1,j)).or.((ice(i,j-1).ge.1).and.flot(i,j-1))) then   !masque de 2 cases adjacentes
1253          !  un des voisins est deja en glace
1254          mask(1) = table_out_marais(i-1,j)
1255          mask(2) = table_out_marais(i,j-1) 
1256          label = label_max
1257
1258          ! on determine la valeur de la tache minimun (>0) presente ds le masque
1259          do indice=1,mask_nb
1260            if (mask(indice).gt.0) label=min(label,mask(indice))
1261          enddo
1262
1263          ! on fixe la valeur de la tache voisine minimun au point etudie (via label)
1264          table_out_marais(i,j)=label
1265           
1266          !si un des voisins n'est pas glace alors la tache n'est pas un marais
1267          if ( (ice(i+1,j).eq.0) .or. (ice(i,j+1).eq.0) .or. (ice(i-1,j).eq.0) .or. (ice(i,j-1).eq.0) ) then
1268            marais(label)=.false.
1269          endif
1270
1271          ! si 2 taches differentes sont dans le masque, il faut les identifier dans compt_marais
1272          ! on lui affecte le numero de la tache fondamentale
1273
1274                                                                   ! exemple on est sur le point X : 5  X
1275          do indice=1,mask_nb                                      !                                   20
1276            if(mask(indice).gt.label) then                         ! mask(2)=20 > 5             
1277              compt_marais(mask(indice))=label                     ! compt_marais(20)=5
1278              if (.not.marais(mask(indice))) marais(label)=.false. ! si la tache n'etais pas un marais => marais =.false.  marais(-(-5))=.false.               
1279              where (table_out_marais(:,:).eq.mask(indice))        ! where table_out_marais(:,:)=mask(2)=20
1280                table_out_marais(:,:)=label                        ! table_out_marais(:,:)=label=5                 
1281              endwhere                                               
1282            endif
1283          enddo
1284           
1285        else !aucun des voisins est une tache
1286          table_out_marais(i,j)= label_max
1287          compt_marais(label_max)=label_max
1288           
1289          ! si un des voisins n'est pas glace alors la tache n'est pas un marais
1290          if ( (ice(i+1,j).eq.0) .or. (ice(i,j+1).eq.0) .or. (ice(i-1,j).eq.0) .or. (ice(i,j-1).eq.0) ) then
1291            marais(label_max)=.false.
1292          endif
1293          label_max  = label_max+1
1294          if (label_max.gt.n_ta_max) print*,'ATTENTION trop de taches=',label_max 
1295        endif
1296      else          ! on est pas sur une tache--------------------------------------------
1297        table_out_marais(i,j)=0    ! Pas necessaire (reecrit 0 sur 0)             
1298      endif         !---------------------------------------------------------------------
1299    enddo
1300  enddo
1301
1302  marais(0)=.false.
1303
1304  !$OMP PARALLEL
1305  !$OMP DO
1306  do j=1,ny
1307    do i=1,nx
1308      if (table_out_marais(i,j).ne.0) then
1309        nb_pts_marais(compt_marais(table_out_marais(i,j)))= nb_pts_marais(compt_marais(table_out_marais(i,j)))+1   
1310      endif
1311      flot_marais(i,j) = marais(table_out_marais(i,j))
1312    enddo
1313  enddo
1314  !$OMP END DO
1315  !$OMP END PARALLEL
1316
1317  debug_3D(:,:,122)=real(table_out_marais(:,:))
1318
1319end subroutine determin_marais
1320
1321end module flottab_mod
1322
1323
Note: See TracBrowser for help on using the repository browser.