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

Last change on this file since 3436 was 3175, checked in by emillour, 11 months ago

Pluto PCM:
Add the old Pluto LMDZ for reference (required prior step to making
an LMDZ.PLUTO using the same framework as the other physics packages).
TB+EM

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