New URL for NEMO forge!   http://forge.nemo-ocean.eu

Since March 2022 along with NEMO 4.2 release, the code development moved to a self-hosted GitLab.
This present forge is now archived and remained online for history.
p5zsink.F90 in branches/CNRS/dev_r6270_PISCES_QUOTA/NEMOGCM/NEMO/TOP_SRC/PISCES/P5Z – NEMO

source: branches/CNRS/dev_r6270_PISCES_QUOTA/NEMOGCM/NEMO/TOP_SRC/PISCES/P5Z/p5zsink.F90 @ 8003

Last change on this file since 8003 was 8003, checked in by aumont, 7 years ago

modification in the code to remove unnecessary parts such as kriest and non iomput options

  • Property svn:executable set to *
File size: 17.8 KB
Line 
1MODULE p5zsink
2   !!======================================================================
3   !!                         ***  MODULE p5zsink  ***
4   !! TOP :  PISCES  vertical flux of particulate matter due to gravitational sinking
5   !!======================================================================
6   !! History :   1.0  !  2004     (O. Aumont) Original code
7   !!             2.0  !  2007-12  (C. Ethe, G. Madec)  F90
8   !!             3.4  !  2011-06  (O. Aumont, C. Ethe) Change aggregation formula
9   !!             3.5  !  2012-07  (O. Aumont) Introduce potential time-splitting
10   !!             3.6  !  2015-05  (O. Aumont) PISCES quota
11   !!----------------------------------------------------------------------
12#if defined key_pisces_quota
13   !!----------------------------------------------------------------------
14   !!   p5z_sink       :  Compute vertical flux of particulate matter due to gravitational sinking
15   !!   p5z_sink_init  :  Unitialisation of sinking speed parameters
16   !!   p5z_sink_alloc :  Allocate sinking speed variables
17   !!----------------------------------------------------------------------
18   USE oce_trc         !  shared variables between ocean and passive tracers
19   USE trc             !  passive tracers common variables
20   USE sms_pisces      !  PISCES Source Minus Sink variables
21   USE prtctl_trc      !  print control for debugging
22   USE iom             !  I/O manager
23   USE lib_mpp
24
25   IMPLICIT NONE
26   PRIVATE
27
28   PUBLIC   p5z_sink         ! called in p5zbio.F90
29   PUBLIC   p5z_sink_init    ! called in trcsms_pisces.F90
30   PUBLIC   p5z_sink_alloc
31
32   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   wsbio3   !: POC sinking speed
33   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   wsbio4   !: GOC sinking speed
34   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   wscal    !: Calcite and BSi sinking speeds
35
36   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   sinking, sinking2  !: POC sinking fluxes
37   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   sinkingn, sinking2n  !: POC sinking fluxes
38   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   sinkingp, sinking2p  !: POC sinking fluxes
39   !                                                          !  (different meanings depending on the parameterization)
40   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   sinkcal, sinksil   !: CaCO3 and BSi sinking fluxes
41   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   sinkfer            !: Small BFe sinking fluxes
42   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   sinkfer2           !: Big iron sinking fluxes
43#if defined key_ligand
44   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   sinkfep      !: Fep sinking fluxes
45   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   wsfep
46#endif
47
48   INTEGER  :: ik100
49
50   !!* Substitution
51#  include "top_substitute.h90"
52   !!----------------------------------------------------------------------
53   !! NEMO/TOP 3.3 , NEMO Consortium (2010)
54   !! $Id: p4zsink.F90 3160 2011-11-20 14:27:18Z cetlod $
55   !! Software governed by the CeCILL licence     (NEMOGCM/NEMO_CeCILL.txt)
56   !!----------------------------------------------------------------------
57CONTAINS
58
59   !!----------------------------------------------------------------------
60   !!   'standard sinking parameterisation'                  ???
61   !!----------------------------------------------------------------------
62
63   SUBROUTINE p5z_sink ( kt, knt )
64      !!---------------------------------------------------------------------
65      !!                     ***  ROUTINE p5z_sink  ***
66      !!
67      !! ** Purpose :   Compute vertical flux of particulate matter due to
68      !!                gravitational sinking
69      !!
70      !! ** Method  : - ???
71      !!---------------------------------------------------------------------
72      INTEGER, INTENT(in) :: kt, knt
73      INTEGER  ::   ji, jj, jk, jit
74      INTEGER  ::   iiter1, iiter2
75      REAL(wp) ::   zfact, zwsmax, zmax
76      CHARACTER (len=25) :: charout
77      REAL(wp), POINTER, DIMENSION(:,:,:) :: zw3d
78      REAL(wp), POINTER, DIMENSION(:,:  ) :: zw2d
79      !!---------------------------------------------------------------------
80      !
81      IF( nn_timing == 1 )  CALL timing_start('p5z_sink')
82
83      ! Initialization of some global variables
84      ! ---------------------------------------
85      prodpoc(:,:,:) = 0.
86      conspoc(:,:,:) = 0.
87      prodgoc(:,:,:) = 0.
88      consgoc(:,:,:) = 0.
89      !
90      !    Sinking speeds of detritus is increased with depth as shown
91      !    by data and from the coagulation theory
92      !    -----------------------------------------------------------
93      DO jk = 1, jpkm1
94         DO jj = 1, jpj
95            DO ji = 1,jpi
96               zmax  = MAX( heup_01(ji,jj), hmld(ji,jj) )
97               zfact = MAX( 0., fsdepw(ji,jj,jk+1) - zmax ) / wsbio2scale
98               wsbio4(ji,jj,jk) = wsbio2 + MAX(0., ( wsbio2max - wsbio2 )) * zfact
99            END DO
100         END DO
101      END DO
102
103      ! limit the values of the sinking speeds to avoid numerical instabilities 
104      wsbio3(:,:,:) = wsbio
105#if defined key_ligand
106      wsfep (:,:,:) = wfep
107#endif
108      !
109      ! OA This is (I hope) a temporary solution for the problem that may
110      ! OA arise in specific situation where the CFL criterion is broken
111      ! OA for vertical sedimentation of particles. To avoid this, a time
112      ! OA splitting algorithm has been coded. A specific maximum
113      ! OA iteration number is provided and may be specified in the namelist
114      ! OA This is to avoid very large iteration number when explicit free
115      ! OA surface is used (for instance). When niter?max is set to 1,
116      ! OA this computation is skipped. The crude old threshold method is
117      ! OA then applied. This also happens when niter exceeds nitermax.
118      IF( MAX( niter1max, niter2max ) == 1 ) THEN
119        iiter1 = 1
120        iiter2 = 1
121      ELSE
122        iiter1 = 1
123        iiter2 = 1
124        DO jk = 1, jpkm1
125          DO jj = 1, jpj
126             DO ji = 1, jpi
127                IF( tmask(ji,jj,jk) == 1) THEN
128                   zwsmax =  0.5 * fse3t(ji,jj,jk) / xstep
129                   iiter1 =  MAX( iiter1, INT( wsbio3(ji,jj,jk) / zwsmax ) )
130                   iiter2 =  MAX( iiter2, INT( wsbio4(ji,jj,jk) / zwsmax ) )
131                ENDIF
132             END DO
133          END DO
134        END DO
135        IF( lk_mpp ) THEN
136           CALL mpp_max( iiter1 )
137           CALL mpp_max( iiter2 )
138        ENDIF
139        iiter1 = MIN( iiter1, niter1max )
140        iiter2 = MIN( iiter2, niter2max )
141      ENDIF
142
143      DO jk = 1,jpkm1
144         DO jj = 1, jpj
145            DO ji = 1, jpi
146               IF( tmask(ji,jj,jk) == 1 ) THEN
147                 zwsmax = 0.5 * fse3t(ji,jj,jk) / xstep
148                 wsbio3(ji,jj,jk) = MIN( wsbio3(ji,jj,jk), zwsmax * FLOAT( iiter1 ) )
149                 wsbio4(ji,jj,jk) = MIN( wsbio4(ji,jj,jk), zwsmax * FLOAT( iiter2 ) )
150#if defined key_ligand
151                 wsfep(ji,jj,jk) = MIN( wsfep(ji,jj,jk), zwsmax * FLOAT( iiter1 ) )
152#endif
153               ENDIF
154            END DO
155         END DO
156      END DO
157
158      wscal (:,:,:) = wsbio4(:,:,:)
159
160      !  Initializa to zero all the sinking arrays
161      !   -----------------------------------------
162      sinking (:,:,:) = 0.e0
163      sinking2(:,:,:) = 0.e0
164      sinkingn (:,:,:) = 0.e0
165      sinking2n(:,:,:) = 0.e0
166      sinkingp (:,:,:) = 0.e0
167      sinking2p(:,:,:) = 0.e0
168      sinkcal (:,:,:) = 0.e0
169      sinkfer (:,:,:) = 0.e0
170      sinksil (:,:,:) = 0.e0
171      sinkfer2(:,:,:) = 0.e0
172#if defined key_ligand
173      sinkfep(:,:,:) = 0.e0
174#endif
175
176      !   Compute the sedimentation term using p4zsink2 for all the sinking particles
177      !   -----------------------------------------------------
178      DO jit = 1, iiter1
179        CALL p4z_sink2( wsbio3, sinking , jppoc, iiter1 )
180        CALL p4z_sink2( wsbio3, sinkingn , jppon, iiter1 )
181        CALL p4z_sink2( wsbio3, sinkingp , jppop, iiter1 )
182        CALL p4z_sink2( wsbio3, sinkfer , jpsfe, iiter1 )
183#if defined key_ligand
184        CALL p4z_sink2( wsfep, sinkfep , jpfep, iiter1 )
185#endif
186      END DO
187
188      DO jit = 1, iiter2
189        CALL p4z_sink2( wsbio4, sinking2, jpgoc, iiter2 )
190        CALL p4z_sink2( wsbio4, sinking2n, jpgon, iiter2 )
191        CALL p4z_sink2( wsbio4, sinking2p, jpgop, iiter2 )
192        CALL p4z_sink2( wsbio4, sinkfer2, jpbfe, iiter2 )
193        CALL p4z_sink2( wsbio4, sinksil , jpgsi, iiter2 )
194        CALL p4z_sink2( wscal, sinkcal , jpcal, iiter2 )
195      END DO
196
197     ! Total carbon export per year
198     IF( iom_use( "tcexp" ) .OR. ( ln_check_mass .AND. kt == nitend .AND. knt == nrdttrc )  )  &
199        &   t_oce_co2_exp = glob_sum( ( sinking(:,:,ik100) + sinking2(:,:,ik100) ) * e1e2t(:,:) * tmask(:,:,1) )
200     !
201     IF( lk_iomput ) THEN
202       IF( knt == nrdttrc ) THEN
203          CALL wrk_alloc( jpi, jpj,      zw2d )
204          CALL wrk_alloc( jpi, jpj, jpk, zw3d )
205          zfact = 1.e+3 * rfact2r  !  conversion from mol/l/kt to  mol/m3/s
206          !
207          IF( iom_use( "EPC100" ) )  THEN
208              zw2d(:,:) = ( sinking(:,:,ik100) + sinking2(:,:,ik100) ) * zfact * tmask(:,:,1) ! Export of carbon at 100m
209              CALL iom_put( "EPC100"  , zw2d )
210          ENDIF
211          IF( iom_use( "EPFE100" ) )  THEN
212              zw2d(:,:) = ( sinkfer(:,:,ik100) + sinkfer2(:,:,ik100) ) * zfact * tmask(:,:,1) ! Export of iron at 100m
213              CALL iom_put( "EPFE100"  , zw2d )
214          ENDIF
215          IF( iom_use( "EPCAL100" ) )  THEN
216              zw2d(:,:) = sinkcal(:,:,ik100) * zfact * tmask(:,:,1) ! Export of calcite at 100m
217              CALL iom_put( "EPCAL100"  , zw2d )
218          ENDIF
219          IF( iom_use( "EPSI100" ) )  THEN
220              zw2d(:,:) =  sinksil(:,:,ik100) * zfact * tmask(:,:,1) ! Export of bigenic silica at 100m
221              CALL iom_put( "EPSI100"  , zw2d )
222          ENDIF
223          IF( iom_use( "EXPC" ) )  THEN
224              zw3d(:,:,:) = ( sinking(:,:,:) + sinking2(:,:,:) ) * zfact * tmask(:,:,:) ! Export of carbon in the water column
225              CALL iom_put( "EXPC"  , zw3d )
226          ENDIF
227          IF( iom_use( "EXPFE" ) )  THEN
228              zw3d(:,:,:) = ( sinkfer(:,:,:) + sinkfer2(:,:,:) ) * zfact * tmask(:,:,:) ! Export of iron
229              CALL iom_put( "EXPFE"  , zw3d )
230          ENDIF
231          IF( iom_use( "EXPCAL" ) )  THEN
232              zw3d(:,:,:) = sinkcal(:,:,:) * zfact * tmask(:,:,:) ! Export of calcite
233              CALL iom_put( "EXPCAL"  , zw3d )
234          ENDIF
235          IF( iom_use( "EXPSI" ) )  THEN
236              zw3d(:,:,:) = sinksil(:,:,:) * zfact * tmask(:,:,:) ! Export of bigenic silica
237              CALL iom_put( "EXPSI"  , zw3d )
238          ENDIF
239          IF( iom_use( "tcexp" ) )  CALL iom_put( "tcexp" , t_oce_co2_exp * zfact )   ! molC/s
240          !
241          CALL wrk_dealloc( jpi, jpj,      zw2d )
242          CALL wrk_dealloc( jpi, jpj, jpk, zw3d )
243        ENDIF
244      ELSE
245         IF( ln_diatrc ) THEN
246            zfact = 1.e3 * rfact2r
247            trc2d(:,:,jp_pcs0_2d + 4) = sinking (:,:,ik100) * zfact * tmask(:,:,1)
248            trc2d(:,:,jp_pcs0_2d + 5) = sinking2(:,:,ik100) * zfact * tmask(:,:,1)
249            trc2d(:,:,jp_pcs0_2d + 6) = sinkfer (:,:,ik100) * zfact * tmask(:,:,1)
250            trc2d(:,:,jp_pcs0_2d + 7) = sinkfer2(:,:,ik100) * zfact * tmask(:,:,1)
251            trc2d(:,:,jp_pcs0_2d + 8) = sinksil (:,:,ik100) * zfact * tmask(:,:,1)
252            trc2d(:,:,jp_pcs0_2d + 9) = sinkcal (:,:,ik100) * zfact * tmask(:,:,1)
253         ENDIF
254      ENDIF
255      !
256      IF(ln_ctl)   THEN  ! print mean trends (used for debugging)
257         WRITE(charout, FMT="('sink')")
258         CALL prt_ctl_trc_info(charout)
259         CALL prt_ctl_trc(tab4d=tra, mask=tmask, clinfo=ctrcnm)
260      ENDIF
261      !
262      IF( nn_timing == 1 )  CALL timing_stop('p5z_sink')
263      !
264   END SUBROUTINE p5z_sink
265
266   SUBROUTINE p5z_sink_init
267      !!----------------------------------------------------------------------
268      !!                  ***  ROUTINE p5z_sink_init  ***
269      !!----------------------------------------------------------------------
270
271      INTEGER :: jk
272
273      ik100 = 10        !  last level where depth less than 100 m
274      DO jk = jpkm1, 1, -1
275         IF( gdept_1d(jk) > 100. )  ik100 = jk - 1
276      END DO
277      IF (lwp) WRITE(numout,*)
278      IF (lwp) WRITE(numout,*) ' Level corresponding to 100m depth ',  ik100 + 1
279      IF (lwp) WRITE(numout,*)
280      !
281      t_oce_co2_exp = 0._wp
282      !
283   END SUBROUTINE p5z_sink_init
284
285   SUBROUTINE p4z_sink2( pwsink, psinkflx, jp_tra, kiter )
286      !!---------------------------------------------------------------------
287      !!                     ***  ROUTINE p4z_sink2  ***
288      !!
289      !! ** Purpose :   Compute the sedimentation terms for the various sinking
290      !!     particles. The scheme used to compute the trends is based
291      !!     on MUSCL.
292      !!
293      !! ** Method  : - this ROUTINE compute not exactly the advection but the
294      !!      transport term, i.e.  div(u*tra).
295      !!---------------------------------------------------------------------
296      !
297      INTEGER , INTENT(in   )                         ::   jp_tra    ! tracer index index     
298      INTEGER , INTENT(in   )                         ::   kiter     ! number of iterations for time-splitting
299      REAL(wp), INTENT(in   ), DIMENSION(jpi,jpj,jpk) ::   pwsink    ! sinking speed
300      REAL(wp), INTENT(inout), DIMENSION(jpi,jpj,jpk) ::   psinkflx  ! sinking fluxe
301      !!
302      INTEGER  ::   ji, jj, jk, jn
303      REAL(wp) ::   zigma,zew,zign, zflx, zstep
304      REAL(wp), POINTER, DIMENSION(:,:,:) :: ztraz, zakz, zwsink2, ztrb 
305      !!---------------------------------------------------------------------
306      !
307      IF( nn_timing == 1 )  CALL timing_start('p4z_sink2')
308      !
309      ! Allocate temporary workspace
310      CALL wrk_alloc( jpi, jpj, jpk, ztraz, zakz, zwsink2, ztrb )
311
312      zstep = rfact2 / FLOAT( kiter ) / 2.
313
314      ztraz(:,:,:) = 0.e0
315      zakz (:,:,:) = 0.e0
316      ztrb (:,:,:) = trb(:,:,:,jp_tra)
317
318      DO jk = 1, jpkm1
319         zwsink2(:,:,jk+1) = -pwsink(:,:,jk) / rday * tmask(:,:,jk+1) 
320      END DO
321      zwsink2(:,:,1) = 0.e0
322      IF( lk_degrad ) THEN
323         zwsink2(:,:,:) = zwsink2(:,:,:) * facvol(:,:,:)
324      ENDIF
325
326
327      ! Vertical advective flux
328      DO jn = 1, 2
329         !  first guess of the slopes interior values
330         DO jk = 2, jpkm1
331            ztraz(:,:,jk) = ( trb(:,:,jk-1,jp_tra) - trb(:,:,jk,jp_tra) ) * tmask(:,:,jk)
332         END DO
333         ztraz(:,:,1  ) = 0.0
334         ztraz(:,:,jpk) = 0.0
335
336         ! slopes
337         DO jk = 2, jpkm1
338            DO jj = 1,jpj
339               DO ji = 1, jpi
340                  zign = 0.25 + SIGN( 0.25, ztraz(ji,jj,jk) * ztraz(ji,jj,jk+1) )
341                  zakz(ji,jj,jk) = ( ztraz(ji,jj,jk) + ztraz(ji,jj,jk+1) ) * zign
342               END DO
343            END DO
344         END DO
345         
346         ! Slopes limitation
347         DO jk = 2, jpkm1
348            DO jj = 1, jpj
349               DO ji = 1, jpi
350                  zakz(ji,jj,jk) = SIGN( 1., zakz(ji,jj,jk) ) *        &
351                     &             MIN( ABS( zakz(ji,jj,jk) ), 2. * ABS(ztraz(ji,jj,jk+1)), 2. * ABS(ztraz(ji,jj,jk) ) )
352               END DO
353            END DO
354         END DO
355         
356         ! vertical advective flux
357         DO jk = 1, jpkm1
358            DO jj = 1, jpj     
359               DO ji = 1, jpi   
360                  zigma = zwsink2(ji,jj,jk+1) * zstep / fse3w(ji,jj,jk+1)
361                  zew   = zwsink2(ji,jj,jk+1)
362                  psinkflx(ji,jj,jk+1) = -zew * ( trb(ji,jj,jk,jp_tra) - 0.5 * ( 1 + zigma ) * zakz(ji,jj,jk) ) * zstep
363               END DO
364            END DO
365         END DO
366         !
367         ! Boundary conditions
368         psinkflx(:,:,1  ) = 0.e0
369         psinkflx(:,:,jpk) = 0.e0
370         
371         DO jk=1,jpkm1
372            DO jj = 1,jpj
373               DO ji = 1, jpi
374                  zflx = ( psinkflx(ji,jj,jk) - psinkflx(ji,jj,jk+1) ) / fse3t(ji,jj,jk)
375                  trb(ji,jj,jk,jp_tra) = trb(ji,jj,jk,jp_tra) + zflx
376               END DO
377            END DO
378         END DO
379
380      ENDDO
381
382      DO jk = 1,jpkm1
383         DO jj = 1,jpj
384            DO ji = 1, jpi
385               zflx = ( psinkflx(ji,jj,jk) - psinkflx(ji,jj,jk+1) ) / fse3t(ji,jj,jk)
386               ztrb(ji,jj,jk) = ztrb(ji,jj,jk) + 2. * zflx
387            END DO
388         END DO
389      END DO
390
391      trb(:,:,:,jp_tra) = ztrb(:,:,:)
392      psinkflx(:,:,:)   = 2. * psinkflx(:,:,:)
393      !
394      CALL wrk_dealloc( jpi, jpj, jpk, ztraz, zakz, zwsink2, ztrb )
395      !
396      IF( nn_timing == 1 )  CALL timing_stop('p4z_sink2')
397      !
398   END SUBROUTINE p4z_sink2
399
400   INTEGER FUNCTION p5z_sink_alloc()
401      !!----------------------------------------------------------------------
402      !!                     ***  ROUTINE p5z_sink_alloc  ***
403      !!----------------------------------------------------------------------
404      ALLOCATE( wsbio3 (jpi,jpj,jpk) , wsbio4  (jpi,jpj,jpk)   , wscal(jpi,jpj,jpk) ,     &
405         &      sinking(jpi,jpj,jpk) , sinking2(jpi,jpj,jpk)   ,     &               
406         &      sinkingn(jpi,jpj,jpk) , sinking2n(jpi,jpj,jpk) ,     &
407         &      sinkingp(jpi,jpj,jpk) , sinking2p(jpi,jpj,jpk) ,     &
408
409         &      sinkcal(jpi,jpj,jpk) , sinksil (jpi,jpj,jpk)   ,     &   
410         &      sinkfer2(jpi,jpj,jpk)                                             ,     &               
411#if defined key_ligand
412         &      wsfep(jpi,jpj,jpk)  , sinkfep(jpi,jpj,jpk)     ,     &
413#endif
414         &      sinkfer(jpi,jpj,jpk)     , STAT=p5z_sink_alloc )               
415         !
416      IF( p5z_sink_alloc /= 0 ) CALL ctl_warn('p5z_sink_alloc : failed to allocate arrays.')
417      !
418   END FUNCTION p5z_sink_alloc
419   
420#else
421   !!======================================================================
422   !!  Dummy module :                                   No PISCES bio-model
423   !!======================================================================
424CONTAINS
425   SUBROUTINE p5z_sink                    ! Empty routine
426   END SUBROUTINE p5z_sink
427#endif 
428
429   !!======================================================================
430END MODULE  p5zsink
Note: See TracBrowser for help on using the repository browser.