source: trunk/SOURCES/Old-sources/conserv-mass-adv-diff_mod-EGU-2009.f90 @ 334

Last change on this file since 334 was 4, checked in by dumas, 10 years ago

initial import GRISLI trunk

File size: 13.8 KB
Line 
1!> \file conserv-mass-adv-diff_mod-EGU-2009.f90
2!! Module qui calcule l evolution de l epaisseur en resolvant
3!! une equation d'advection diffusion
4!<
5
6!> \namespace equat_adv_diff_2D 
7!! Module qui calcule l evolution de l epaisseur en resolvant
8!! une equation d'advection diffusion
9!! \author Cat
10!! \date Fevrier 2007
11!! @note Used modules
12!! @note   - use module3D_phy
13!! @note   - use reso_adv_diff_2D
14!<
15module equat_adv_diff_2D                             ! Cat Fevrier 2007
16
17use module3D_phy
18use reso_adv_diff_2D
19
20
21implicit none
22
23real, dimension(nx,ny) :: advmx           !< partie advective en x
24real, dimension(nx,ny) :: advmy           !< partie advective en y
25real, dimension(nx,ny) :: dmx             !< partie advective en x
26real, dimension(nx,ny) :: dmy             !< partie advective en y
27real, dimension(nx,ny) :: VieuxH          !< ancienne valeur de H
28logical, dimension(nx,ny) :: zonemx       !< pour separer advection-diffusion
29logical,  dimension(nx,ny) :: zonemy      !< pour separer advection-diffusion
30real :: adv_frac                          !< fraction du flux traitee en advection
31integer :: itesti
32integer :: itour
33
34! test d'epaisseur prescrite
35real,dimension(nx,ny) :: H_p      !< H value if prescribed
36integer,dimension(nx,ny) :: i_Hp  !< 1 if H is prescribed on this node, else 0
37real ::itest                      !< variable travail
38real :: dh_gael                   !< variation d'epaisseur imposee
39contains
40!> SUBROUTINE: init_icethick 
41!! Routine qui permet d'initialiser les parametres icethick
42!! @note  definition du parametre qui gerent la repartition advection diffusion
43!>
44subroutine init_icethick
45
46
47write(num_rep_42,*)'Conservation de la masse avec equation advection-diffusion '
48write(num_rep_42,*)'la repartition depend de adv_frac'
49write(num_rep_42,*)'>1  -> advection seule'
50write(num_rep_42,*)'0   -> diffusion seule'
51write(num_rep_42,*)'0<*<1   -> fraction de l advection'
52write(num_rep_42,*) '-1 -> zones diffusion + zones advecttion'
53
54!varname='adv_frac'
55
56adv_frac=2. ! 0.8
57
58!adv_frac=0
59write(num_rep_42,*)'adv_frac=',adv_frac
60
61 call init_reso_adv_diff_2D
62
63 Dx1=1./Dx
64
65itour=0
66
67
68! lecture des points prescrits (à mettre ensuite dans les lectures standard)  16 avril 2009
69
70!Version avec la ligne actuelle
71goto 78
72open(123,file="../INPUT/ANTEIS1/grounding-line-gael-40km.ijg")
73
74
75i_HP(:,:)=0
76H_p(:,:)=-9999.
77
78
79do k=1,nx*ny
80   read(123,*,end=77) i,j
81   i_HP(i,j)=1
82   H_p(i,j)=H0(i,j)
83   if (H0(i,j) .lt.-Bsoc(i,j)*row/ro) then
84      write(6,*) i,j,H0(i,j),Bsoc(i,j),mk(i,j)
85   endif
86   H_p(i,j)=max(H0(i,j),-Bsoc(i,j)*row/ro+50.) ! pour etre sur que le point ne flotte pas.
87end do
8877 continue
89
90close(123)
91
9278 continue ! version avec la perturbation de Gael
93open(123,file="../INPUT/ANTEIS1/delta-H-Gael-ij.ijz")
94
95i_HP(:,:)=0
96H_p(:,:)=-9999.
97
98do k=1,nx*ny
99   read(123,*,end=79) i,j,dH_gael   ! attention il faut enlever dh_gael
100   i_HP(i,j)=1
101   H_p(i,j)=H(i,j)-dH_gael          ! on enleve la perturbation Gael de la topo reprise dans le cptr
102                                    ! il peut être devenu flottant ou pas
103   H(i,j)=H_p(i,j)
104end do
10579 continue
106close(123)
107
108end subroutine init_icethick
109
110!------------------------------------------------------------------
111!> SUBROUTINE: icethick3
112!! Routine de calcul de l'epaisseur de glace
113!>
114subroutine icethick3
115
116  implicit none
117  real,dimension(nx,ny) :: Dminx,Dminy
118  real,dimension(nx,ny) :: Uxdiff,Uydiff           ! vitesse due a la diffusion
119  integer :: it1,it2,it3
120
121  real aux                                         ! pour le calcul du critere
122  real maxdia                                      ! sur le pas de temps
123  integer imaxdia,jmaxdia
124
125
126
127
128
129  if (itracebug.eq.1)  call tracebug(' Entree dans routine icethick')
130
131
132  ! Copie de H sur vieuxH
133  ! --------------------
134  where (mk0(:,:).eq.0)
135     vieuxH(:,:)=0.
136  elsewhere 
137     vieuxH(:,:)=H(:,:)
138  end where
139
140  ! mk0 est le masque à ne jamais dépasser
141  ! mk0=0  ->  pas de glace
142  ! mk0=-1 ->  on garde la même epaisseur
143  ! pour l'Antarctique masque mko=1 partout
144
145
146  Maxdia = -1.0
147  imaxdia=0
148  jmaxdia=0
149
150  ! le pas de temps est choisi pour rendre la matrice advective diagonale dominante
151  do i=2,nx-1
152     do j=2,ny-1
153        aux = (abs(uxbar(i,j)) + abs(uxbar(i+1,j))) &
154             + (abs(uybar(i,j)) + abs(uybar(i,j+1)))
155        aux=aux*dx1*0.5
156        if (aux.gt.maxdia) then
157           maxdia=aux
158           imaxdia=i
159           jmaxdia=j
160        endif
161     end do
162  end do
163
164
165  if (maxdia.ge.(testdiag/dtmax)) then
166     dt = testdiag/Maxdia
167     dt=max(dt,dtmin)
168  else
169     dt = dtmax
170  end if
171
172  ! next_time ajuste le pas de temps pour faciliter la synchronisation
173  ! avec le pas de temps long (dtt)
174
175  call next_time(time,dt,dtt,dtmax,dtmin,isynchro,itracebug,num_tracebug)
176
177
178!!$write(166,*)'--------------------------------------------------------'
179!!$write(166,*)'apres old calcul de dt',time,dt
180
181  ! calcul diffusivite - vitesse
182  !-----------------------------------------------------------------
183
184  Uxdiff(:,:)=diffmx(:,:)*(-sdx(:,:))   ! vitesse qui peut s'exprimer en terme diffusif
185  Uydiff(:,:)=diffmy(:,:)*(-sdy(:,:))   ! dans les where qui suivent elle est limitee a uxbar
186  ! pour eviter des problemes dans le cas 0< adv_frac <1
187  dmx(:,:)=diffmx(:,:)
188  dmy(:,:)=diffmy(:,:)
189
190  ! schema amont pour la diffusion en x
191  where (Uxbar(:,:).ge.0.)
192     dmx(:,:)=diffmx(:,:)*eoshift(H(:,:),shift=-1,boundary=0.,dim=1)
193     uxdiff(:,:)=min(uxdiff(:,:),uxbar(:,:))       ! pour tenir compte limitation utot
194  elsewhere
195     dmx(:,:)=diffmx(:,:)*H(:,:)
196     uxdiff(:,:)=max(uxdiff(:,:),uxbar(:,:))       ! pour tenir compte limitation utot
197  end where
198
199
200
201  ! schema amont pour la diffusion en y
202  where (uybar(:,:).ge.0.)
203     dmy(:,:)=diffmy(:,:)*eoshift(H(:,:),shift=-1,boundary=0.,dim=2)
204     uydiff(:,:)=min(uydiff(:,:),uybar(:,:))       ! pour tenir compte limitation utot
205  elsewhere
206     dmy(:,:)=dmy(:,:)*H(:,:)
207     uydiff(:,:)=max(uydiff(:,:),uybar(:,:))       ! pour tenir compte limitation utot
208  end where
209
210
211
212  ! tests pour la répartition advection - diffusion
213  !------------------------------------------------
214
215  if (adv_frac.gt.1.) then ! advection seulement
216     advmx(:,:)=Uxbar(:,:)
217     advmy(:,:)=Uybar(:,:)
218     Dmx(:,:)=0.
219     Dmy(:,:)=0.
220
221  else if (abs(adv_frac).lt.1.e-8) then   ! diffusion seulement
222     advmx(:,:)=0.
223     advmy(:,:)=0.
224
225     ! D reste la valeur au dessus)
226
227  else if ((adv_frac.ge.1.e-8).and.(adv_frac.le.1.)) then        ! advection-diffusion)
228
229     ! selon x --------------------------------
230
231     ! advection = adv_frac* tout ce qui n'est pas diffusion
232     ! diffusion = ce qui peut être exprime en diffusion
233     !             + une partie (1-adv_frac) de l'advection
234
235     where ((abs(sdx(:,:)).gt.1.e-8).and.(Hmx(:,:).gt.2.))      ! cas general
236        advmx(:,:)=(Uxbar(:,:)-Uxdiff(:,:))                   ! tout ce qui n'est pas diffusion
237        advmx(:,:)=advmx(:,:)*adv_frac                         ! la fraction adv_frac du precedent
238        Dminx(:,:)=-(Uxbar(:,:)-advmx(:,:))/sdx(:,:)          ! ce qui reste exprime en diffusivite
239        ! a multiplier par H
240
241        ! schema amont pour la diffusivite
242        where (uxbar(:,:).ge.0.)
243           dmx(:,:)=dminx(:,:)*eoshift(H(:,:),shift=-1,boundary=0.,dim=1)
244        elsewhere
245           dmx(:,:)=dminx(:,:)*H(:,:)
246        end where
247
248
249     elsewhere   ! zones trop plates ou trop fines
250        Dmx(:,:)=0.
251        advmx(:,:)=Uxbar(:,:)
252     end where
253
254
255     ! selon y --------------------------------
256
257     ! advection = adv_frac* tout ce qui n'est pas diffusion
258     ! diffusion = ce qui peut être exprime en diffusion
259     !             + une partie (1-adv_frac) de l'advection
260
261     where ((abs(sdy(:,:)).gt.1.e-8).and.(Hmy(:,:).gt.2.))      ! cas general
262        advmy(:,:)=(Uybar(:,:)-Uydiff(:,:))                   ! tout ce qui n'est pas diffusion
263        advmy(:,:)=advmy(:,:)*adv_frac                         ! la fraction adv_frac du precedent
264        Dminy(:,:)=-(Uybar(:,:)-advmy(:,:))/sdy(:,:)          ! ce qui reste exprime en diffusivite
265        ! a multiplier par H
266
267        ! schema amont pour la diffusivite
268        where (uybar(:,:).ge.0.)
269           dmy(:,:)=dminy(:,:)*eoshift(H(:,:),shift=-1,boundary=0.,dim=2)
270        elsewhere
271           dmy(:,:)=dminy(:,:)*H(:,:)
272        end where
273
274
275
276     elsewhere   ! zones trop plates ou trop fines
277        Dmy(:,:)=0.
278        advmy(:,:)=Uybar(:,:)
279     end where
280
281
282  else if (adv_frac.lt.0) then                  ! diffusif dans zones SIA, advectif ailleurs
283
284     zonemx(:,:)=flgzmx(:,:)
285     zonemy(:,:)=flgzmy(:,:)
286
287     ! selon x --------------
288     where (zonemx(:,:))
289        advmx(:,:)=Uxbar(:,:)
290        Dmx(:,:)=0.
291     elsewhere
292        advmx(:,:)=0.
293     end where
294
295     ! selon y --------------
296     where (zonemy(:,:))
297        advmy(:,:)=Uybar(:,:)
298        Dmy(:,:)=0.
299     elsewhere
300        advmy(:,:)=0.
301     end where
302
303  end if
304
305
306  where (flot(:,:) )
307     tabtest(:,:)=1.
308  elsewhere
309     tabtest(:,:)=0.
310  end where
311
312  !------------------------------------------------------------------detect
313!!$ tabtest(:,:)=dmx(:,:)
314!!$
315!!$call detect_assym(nx,ny,0,41,1,0,1,0,tabtest,itesti)
316!!$
317!!$if (itesti.gt.0) then
318!!$   write(6,*) 'asymetrie sur dmx avant resol pour time=',time,itesti
319!!$   stop
320!!$else
321!!$   write(6,*) ' pas d asymetrie sur dmx avant resol pour time=',time,itesti
322!!$end if
323  !----------------------------------------------------------- fin detect 
324
325
326  !------------------------------------------------------------------detect
327!!$ tabtest(:,:)=dmy(:,:)
328!!$
329!!$call detect_assym(nx,ny,0,41,1,0,1,1,tabtest,itesti)
330!!$
331!!$if (itesti.gt.0) then
332!!$   write(6,*) 'asymetrie sur dmy avant resol pour time=',time,itesti
333!!$   stop
334!!$else
335!!$   write(6,*) ' pas d asymetrie sur dmy avant resol pour time=',time,itesti
336!!$end if
337  !----------------------------------------------------------- fin detect 
338
339  !------------------------------------------------------------------detect
340!!$ tabtest(:,:)=advmx(:,:)
341!!$
342!!$call detect_assym(nx,ny,0,41,1,0,1,0,tabtest,itesti)
343!!$
344!!$if (itesti.gt.0) then
345!!$   write(6,*) 'asymetrie sur advmx avant resol pour time=',time,itesti
346!!$   stop
347!!$else
348!!$   write(6,*) ' pas d asymetrie sur advdmx avant resol pour time=',time,itesti
349!!$end if
350  !----------------------------------------------------------- fin detect 
351
352  !------------------------------------------------------------------detect
353!!$ tabtest(:,:)=advmy(:,:)
354!!$
355!!$call detect_assym(nx,ny,0,41,1,0,-1,1,tabtest,itesti)
356!!$
357!!$if (itesti.gt.0) then
358!!$   write(6,*) 'asymetrie sur advmy avant resol pour time=',time,itesti
359!!$   stop
360!!$else
361!!$   write(6,*) ' pas d asymetrie sur advmy avant resol pour time=',time,itesti
362!!$end if
363  !----------------------------------------------------------- fin detect 
364
365  ! nouveau calcul de dt
366  aux=maxval( (abs(advmx(:,:))+abs(advmy(:,:)))/dx+(abs(dmx(:,:))+abs(dmy(:,:)))/dx/dx)
367
368  ! write(166,*) 'critere pour dt',time-dt,testdiag/aux,dt
369
370  if (aux.gt.1.e-20) then
371     if (testdiag/aux.lt.dt) then
372        time=time-dt
373        dt=testdiag/aux*4.
374        call next_time(time,dt,dtt,dtmax,dtmin,isynchro,itracebug,num_tracebug)
375     end if
376  end if
377
378
379  !      print*,'Iteration =',nt,' temps = ',time-dt,' dt = ',dt
380
381  ! vient de step
382!!$     if (time.lt.timemax-100) then
383!!$        print*,'le modele remonte le temps de',timemax,'a',time
384!!$        stop
385!!$     endif
386  timemax=time
387
388  if (time.lt.TGROUNDED) then
389     MARINE=.false.
390  else
391     MARINE=.true.
392  endif
393
394  ! fin vient de step
395
396  ! les variables dtdx et dtdx2 sont globales
397  Dtdx2=Dt/(Dx**2)
398  dtdx=dt/dx
399
400!!$write(166,*) 'time=',time
401!!$
402!!$
403!!$write(166,*) 'advmx,uxbar'
404!!$do j=43,45
405!!$   write(166,*) advmx(118:122,j)
406!!$end do
407!!$
408!!$write(166,*) 'advmy,uybar'
409!!$do j=43,45
410!!$   write(166,*) advmy(118:122,j)
411!!$end do
412!!$
413!!$write(166,*) 'vieuxH,hdot'
414!!$do j=43,45
415!!$   write(166,*) vieuxH(118:122,j)
416!!$   write(166,*) Hdot(118:122,j)
417!!$
418!!$end do
419
420  debug_3D(:,:,45)=dmx(:,:)
421  debug_3D(:,:,46)=dmy(:,:)
422  debug_3D(:,:,47)=advmx(:,:)
423  debug_3D(:,:,48)=advmy(:,:)
424
425
426
427  ! call resol_adv_diff_2D (Dmx,Dmy,advmx,advmy,vieuxH)
428
429  ! test epaisseur prescrite : se rajoute au i_hp et h_p déja donnés. déclaré dans init
430  where (flot(:,:))
431     H_p(:,:)   = H0(:,:)
432     i_hp(:,:) = 1
433     !   elsewhere   
434     !      i_hp(:,:) = 0
435  endwhere
436
437
438
439  call resol_adv_diff_2D_Hpresc (Dmx,Dmy,advmx,advmy,vieuxH,H_p,i_Hp)
440
441  ! post traitements
442  !--------------------
443
444  ! epaisseur nulle sur les bords
445  H(1,:)=0.
446  H(nx,:)=0.
447  H(:,1)=0.
448  H(:,ny)=0.
449
450  ! attention le bloc suivant sert a garder les ice-shelves stationnaires
451
452  if (igrdline.eq.1) then
453     where (flot(:,:))
454        Hdot(:,:)=(H(:,:)-vieuxH(:,:))/dt
455        H(:,:)=vieuxH(:,:)
456     end where
457  end if
458
459  ! remise à 0 des epaisseurs negatives, on garde la difference dans ablbord
460  where (H(:,:).lt.0.)
461     ablbord(:,:)=H(:,:)/dt
462  elsewhere
463     ablbord(:,:)=0.
464  endwhere
465
466  H(:,:)=max(H(:,:),0.)       ! pas d'epaisseur negative
467
468
469  ! calcul du masque "ice"
470  where (flot(:,:))        ! points flottants, sera éventuellement réévalué dans flottab
471     H(:,:)=max(H(:,:),1.) ! dans la partie marine l'épaisseur mini est 1 m
472     where(H(:,:).gt.1.)
473        ice(:,:)=1
474     elsewhere
475        ice(:,:)=0
476     endwhere
477  elsewhere            ! points posés
478     where(H(:,:).gt.0.)
479        ice(:,:)=1
480     elsewhere
481        ice(:,:)=0
482     endwhere
483  endwhere
484
485  ! calcul de hdot. Quand igrdline=1, on garde hdot pour l'estimation du bmelt d'equilibre
486
487  if (igrdline.eq.1) then
488     where (.not.flot(:,:))
489        Hdot(:,:)=(H(:,:)-vieuxH(:,:))/dt
490     endwhere
491  else
492     Hdot(:,:)=(H(:,:)-vieuxH(:,:))/dt
493  endif
494
495
496  ! si mk0=-1, on garde l'epaisseur precedente
497  ! en attendant un masque plus propre
498
499  where(mk0(:,:).eq.-1)
500     H(:,:)=vieuxH(:,:)
501     Hdot(:,:)=0.
502  end where
503
504
505
506  !calul de l'ablation sur les bords (pourrait n'être appelé que pour les sorties courtes)
507  if (isynchro.eq.1) call ablation_bord
508
509
510
511  if (itracebug.eq.1)  call tracebug(' Fin routine icethick')! maxval(H)',maxval(H(:,:))
512end subroutine icethick3
513
514end module equat_adv_diff_2D
Note: See TracBrowser for help on using the repository browser.