source: trunk/LMDZ.PLUTO/libf/phypluto/spreadglacier_paleo.F90 @ 3572

Last change on this file since 3572 was 3412, checked in by afalco, 6 months ago

Pluto PCM: Imported glaciers & conserv mass routines from pluto.old.
AF

File size: 13.4 KB
Line 
1      subroutine spreadglacier_paleo(ngrid,nq,pqsurf,         &
2          phisfi0,timstep,ptsurf)
3         
4      use callkeys_mod, only: carbox, methane
5      use comcstfi_mod, only: g
6      use comgeomfi_h
7      use geometry_mod, only: latitude, longitude, cell_area
8      use radinc_h, only : naerkind
9      use tracer_h, only: igcm_n2,igcm_ch4_ice,igcm_co_ice
10
11      implicit none
12
13!==================================================================
14!     Purpose
15!     -------
16!     Spreading the glacier : N2, cf Umurhan et al 2017
17
18!     Inputs
19!     ------
20!     ngrid                 Number of vertical columns
21!     pqsurf(ngrid,nq)      N2 ice tracer on surface kg/m2
22!     phisfi0               = phisfinew the geopotential of the bedrock
23!                             below the N2 ice
24!     ptsurf                surface temperature
25!     timstep               dstep = timestep in pluto day for the call of glacial flow
26
27!     Outputs
28!     -------
29!     pqsurf(ngrid,nq)      new value for N2 ice tracer on surface kg/m2
30!     
31!     Authors
32!     -------
33!     Tanguy Bertrand (2015,2022)
34!     
35!==================================================================
36
37#include "dimensions.h"
38
39!-----------------------------------------------------------------------
40!     Arguments
41
42      INTEGER ngrid, nq, ig, i
43      REAL :: pqsurf(ngrid,nq)
44      REAL :: phisfi0(ngrid)
45      REAL :: ptsurf(ngrid)
46      REAL timstep
47!-----------------------------------------------------------------------
48!     Local variables
49      REAL tgla(ngrid),tbase(ngrid)   !temperature at the base of glacier different of ptsurf
50      REAL :: zdqsurf(ngrid)   ! tendency of qsurf
51      REAL massflow  ! function
52      REAL hlim,qlim,difflim,diff,stock,H0,totmasstmp
53      INTEGER compt !compteur
54      INTEGER slid ! option slid 0 or 1
55      INTEGER :: edge(4) ! index of the adjecent points, N,S,E,W
56      INTEGER cas,inddeb,indfin
57      REAL secu,dqch4,dqco
58      REAL :: masstmp(ngrid)   
59
60      REAL :: masstot   
61
62!---------------- INPUT ------------------------------------------------
63
64      difflim=0.5 ! limit height (m) between two adjacent point to start spreading the glacier
65      zdqsurf(:)=0.
66!--------------- Dimensions -------------------------------------
67     
68      ! distance between two adjacent latitude
69      !distlim_lat=pi*rad/jjm/1000.    ! km
70      !distlim_diag=(distlim_lat*distlim_lat+distlim_lon*distlim_lon)**0.5
71
72      !! Threshold for ice thickness for which we activate the glacial flow
73      hlim=10.  !m
74      qlim=hlim*1000. ! kg
75      !! Security for not depleted all ice too fast in one timestep
76      secu=4
77
78      !*************************************
79      ! Loop over all points
80      !*************************************
81      DO ig=1,ngrid
82         !if (ig.eq.ngrid) then
83         !  print*, 'qpole=',pqsurf(ig,igcm_n2),qlim
84         !endif
85
86         !*************************************
87         ! if significant amount of ice, where qsurf > qlim
88         !*************************************
89         IF (pqsurf(ig,igcm_n2).gt.qlim) THEN
90
91              !*************************************
92              ! temp glacier with gradient 15 K / km
93              !*************************************
94              ! surface temperature pts
95              tgla(ig)=ptsurf(ig)
96              ! temperature at the base (we neglect convection)
97              tbase(ig)=tgla(ig)+20.*pqsurf(ig,igcm_n2)/1.e6 ! Umurhan et al.
98              if (tbase(ig).gt.63.) then 
99                 slid=1   ! activate slide
100              else
101                 slid=0
102              endif
103
104              !*************************************
105              ! Selection of the adjacent index depending on the grid point
106              !*************************************
107              !! poles
108              IF (ig.eq.1) then
109                 cas=0
110                 inddeb=2     ! First adj grid point
111                 indfin=iim+1 ! Last adj grid point
112              ELSEIF (ig.eq.ngrid) then
113                 cas=10
114                 inddeb=ngrid-iim
115                 indfin=ngrid-1
116              !! 9 other cases:  edges East, west, or in the center , at edges north south or in the center
117              ELSEIF (mod(ig,iim).eq.2) then ! Edge east :  N,S,W,E
118                 IF (ig.eq.2) then
119                    cas=1
120                    edge = (/1, ig+iim,ig-1+iim,ig+1 /)
121                 ELSEIF (ig.eq.ngrid-iim) then
122                    cas=3
123                    edge = (/ig-iim, ngrid,ig-1+iim,ig+1 /)
124                 ELSE
125                    cas=2
126                    edge = (/ig-iim, ig+iim,ig-1+iim,ig+1 /)
127                 ENDIF
128              ELSEIF (mod(ig,iim).eq.1) then ! Edge west
129                 IF (ig.eq.iim+1) then
130                    cas=7
131                    edge = (/1,ig+iim,ig-1,ig+1-iim /)
132                 ELSEIF (ig.eq.ngrid-1) then
133                    cas=9
134                    edge = (/ig-iim,ngrid,ig-1,ig+1-iim /)
135                 ELSE
136                    cas=8
137                    edge = (/ig-iim,ig+iim,ig-1,ig+1-iim /)
138                 ENDIF
139              ELSE
140                 IF ((ig.gt.2).and.(ig.lt.iim+1)) then
141                    cas=4
142                    edge = (/1,ig+iim,ig-1,ig+1 /)
143                 ELSEIF ((ig.gt.ngrid-iim).and.(ig.lt.ngrid-1)) then
144                    cas=6
145                    edge = (/ig-iim,ngrid,ig-1,ig+1 /)
146                 ELSE
147                    cas=5
148                    edge = (/ig-iim,ig+iim,ig-1,ig+1 /)
149                 ENDIF
150              ENDIF
151
152              masstmp(:)=0. ! mass to be transferred
153              totmasstmp=0. ! total mass to be transferred
154              H0=phisfi0(ig)/g+pqsurf(ig,igcm_n2)/1000. ! height of ice at ig (m)
155
156              !*************************************
157              !!!!!!!!!!!!!!!!! POLE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
158              !*************************************
159              IF ((cas.eq.0).or.(cas.eq.10)) then      ! Mean over all latitudes near the pole
160                 
161                 !call testconservmass2d(ngrid,pqsurf(:,1))
162                 !! 1) Compute Diff H0-H1 and mass to be transferred for each adjacent point
163                 DO i=inddeb,indfin
164                    diff=H0-(phisfi0(i)/g+pqsurf(i,igcm_n2)/1000.)  ! Height difference between ig and adjacent points (m)
165                    if (diff.gt.difflim) then
166                     masstmp(i)=massflow(ig,i,tgla(ig),diff,pqsurf(ig,igcm_n2),timstep,slid) ! Mass to be transferred (kg/m2/s)
167                    else
168                     masstmp(i)=0.
169                    endif
170                    totmasstmp=totmasstmp+masstmp(i)  ! mass totale to be transferred if assume only one adjecent point
171                 ENDDO
172                 if (totmasstmp.gt.0.) then
173                   !! 2) Available mass to be transferred
174                   stock=maxval(masstmp(:))/secu ! kg/m2/s
175                   !! 3) Real amounts of ice to be transferred :
176                   masstmp(:)=masstmp(:)/totmasstmp*stock*cell_area(ig)/cell_area(inddeb)  !kg/m2/s   all area around the pole are the same
177                   !! 4) Tendencies
178                   zdqsurf(ig)=-stock  !kg/m2/s
179                   !! 5) Update PQSURF
180
181                   ! move CH4 and CO too
182                   if (methane) then
183                     !! Variation of CH4 ice
184                     dqch4=pqsurf(ig,igcm_ch4_ice)*(zdqsurf(ig)/pqsurf(ig,igcm_n2)*timstep)  ! amout of ch4 (kg/m2) to be removed at grid ig (negative)
185                     !! remove CH4
186                     pqsurf(ig,igcm_ch4_ice)=pqsurf(ig,igcm_ch4_ice)+dqch4
187                     !! add CH4
188                     do i=inddeb,indfin
189                       pqsurf(i,igcm_ch4_ice)=pqsurf(i,igcm_ch4_ice)-masstmp(i)/stock*dqch4
190                     enddo
191                   endif
192                   if (carbox) then
193                     !! Variation of CO ice
194                     dqco=pqsurf(ig,igcm_co_ice)*(zdqsurf(ig)/pqsurf(ig,igcm_n2)*timstep)  ! amout of co (kg/m2) to be removed at grid ig (negative)
195                     !! remove CO
196                     pqsurf(ig,igcm_co_ice)=pqsurf(ig,igcm_co_ice)+dqco
197                     !! add CO
198                     do i=inddeb,indfin
199                       pqsurf(i,igcm_co_ice)=pqsurf(i,igcm_co_ice)-masstmp(i)/stock*dqco
200                     enddo
201                   endif
202
203                   ! Add N2
204                   do i=inddeb,indfin
205                       pqsurf(i,igcm_n2)=pqsurf(i,igcm_n2)+masstmp(i)*timstep
206                   enddo
207                   ! Remove N2
208                   pqsurf(ig,igcm_n2)=pqsurf(ig,igcm_n2)+zdqsurf(ig)*timstep
209
210                 endif
211                 !call testconservmass2d(ngrid,pqsurf(:,1))
212
213              !!!!!!!!!!!!!!!!!!!! NOT THE POLE !!!!!!!!!!!!!!!!!!!!!!!!
214              ! here: ig = grid point with large amount of ice
215              ! Loop on each adjacent point
216              ! looking for adjacent point
217              ELSE
218
219                 !! 1) Compute Diff H0-H1 and mass to be transferred for each adjacent point
220                 DO compt=1,4
221                    i=edge(compt)
222                    diff=H0-(phisfi0(i)/g+pqsurf(i,igcm_n2)/1000.)  ! (m)
223                    if (diff.gt.difflim) then
224                     masstmp(i)=massflow(ig,i,tgla(ig),diff,pqsurf(ig,igcm_n2),timstep,slid)
225                    else
226                     masstmp(i)=0.
227                    endif
228                    totmasstmp=totmasstmp+masstmp(i)
229                 ENDDO
230                 if (totmasstmp.gt.0) then
231                   !! 2) Available mass to be transferred
232                   stock=maxval(masstmp(:))/secu ! kg/m2/s
233                   !! 3) Real amounts of ice to be transferred :
234                   DO compt=1,4
235                    i=edge(compt)
236                    masstmp(i)=masstmp(i)/totmasstmp*stock*cell_area(ig)/cell_area(i)  !kg/m2/s
237                   ENDDO
238                   !! 4) Tendencies
239                   zdqsurf(ig)=-stock
240                   !! 5) Update PQSURF
241
242                   ! move CH4 and CO too
243                   if (methane) then
244                     !! Variation of CH4 ice
245                     dqch4=pqsurf(ig,igcm_ch4_ice)*(zdqsurf(ig)/pqsurf(ig,igcm_n2)*timstep)  ! amout of ch4 (kg/m2) to be removed at grid ig (negative)
246                     !! remove CH4
247                     pqsurf(ig,igcm_ch4_ice)=pqsurf(ig,igcm_ch4_ice)+dqch4
248                     !! add CH4
249                     DO compt=1,4
250                       i=edge(compt)
251                       pqsurf(i,igcm_ch4_ice)=pqsurf(i,igcm_ch4_ice)-masstmp(i)/stock*dqch4
252                     enddo
253                   endif
254                   if (carbox) then
255                     !! Variation of CO ice
256                     dqco=pqsurf(ig,igcm_co_ice)*(zdqsurf(ig)/pqsurf(ig,igcm_n2)*timstep)  ! amout of co (kg/m2) to be removed at grid ig (negative)
257                     !! remove CO
258                     pqsurf(ig,igcm_co_ice)=pqsurf(ig,igcm_co_ice)+dqco
259                     !! add CO
260                     DO compt=1,4
261                       i=edge(compt)
262                       pqsurf(i,igcm_co_ice)=pqsurf(i,igcm_co_ice)-masstmp(i)/stock*dqco
263                     enddo
264                   endif
265
266                   ! Add N2
267                   totmasstmp=0.
268                   DO compt=1,4
269                       i=edge(compt)
270                       pqsurf(i,igcm_n2)=pqsurf(i,igcm_n2)+masstmp(i)*timstep
271                       totmasstmp=totmasstmp+masstmp(i)*cell_area(i) !! TB22 tmp
272                   enddo
273                   ! Remove N2
274                   pqsurf(ig,igcm_n2)=pqsurf(ig,igcm_n2)+zdqsurf(ig)*timstep
275
276                 endif
277
278                 if (pqsurf(ig,igcm_n2).lt.0) then
279                          print*, pqsurf(ig,igcm_n2)
280                          write(*,*) 'bug in spreadglacier'
281                          stop
282                 endif
283
284              ENDIF  ! cas
285         ENDIF  ! qlim
286               
287      ENDDO  ! ig
288
289      end subroutine spreadglacier_paleo
290
291      real function dist_pluto(lat1,lon1,lat2,lon2)
292      use comcstfi_mod, only: rad
293      implicit none
294      real, intent(in) ::  lat1,lon1,lat2,lon2
295      real dlon,dlat
296      real a,c
297      real radi
298      radi=rad/1000.
299
300      dlon = lon2 - lon1
301      dlat = lat2 - lat1
302      a = (sin(dlat/2))**2 + cos(lat1) * cos(lat2) * (sin(dlon/2))**2
303      c = 2 * atan2( sqrt(a), sqrt(1-a) )
304      dist_pluto = radi * c !! km
305      return
306      end function dist_pluto
307
308      real function massflow(ig1,ig2,pts,dif,pqs,dt,slid)
309      !! Mass of ice to be transferred from one grid point to another
310      use comgeomfi_h
311      use geometry_mod, only: latitude, longitude, cell_area
312      use comcstfi_mod, only: g, rad
313      use tracer_h, only: rho_n2
314
315      implicit none
316#include "dimensions.h"
317
318      real, intent(in) ::  pts,dif,pqs,dt
319      integer, intent(in) ::  ig1,ig2,slid
320      real lref,ac,n,theta,hdelta,ha,tau,qdry,qsl,usl0
321      REAL dist_pluto  ! function
322
323      lref=dist_pluto(latitude(ig2),longitude(ig2),latitude(ig1),longitude(ig1))*1000. ! m
324      usl0=6.3e-6 ! m/s
325      ac=0.005*exp(9.37-422./pts)   !0.005*exp(422./45.-422./pts)
326      n=2.1+0.0155*(pts-45.)
327      theta=atan(dif/(lref))
328      hdelta=pts/20.
329      ha=pts*pts/8440.  !pts*pts/20./422.
330      qdry=ac*(rho_n2*g*1.e-6)**n*(pqs/1000.)**(n+2)/(n+2)*tan(theta)**(n-1)/(1+tan(theta)*tan(theta))**(n/2.)
331      qdry=qdry*0.5*exp( (pqs/1000./ha) / ( 1+ pqs /hdelta) )
332      qsl=(pqs/1000.)/abs(tan(theta))*usl0*slid
333      tau=pqs/1000.*lref/abs((qdry+qsl)*tan(theta))
334      massflow=pqs*(1.-exp(-dt/tau))/dt   
335      return
336      end function massflow
337
338
339
340
Note: See TracBrowser for help on using the repository browser.