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.
p4zsink.F90 in branches/CNRS/dev_r6270_PISCES_QUOTA/NEMOGCM/NEMO/TOP_SRC/PISCES/P4Z – NEMO

source: branches/CNRS/dev_r6270_PISCES_QUOTA/NEMOGCM/NEMO/TOP_SRC/PISCES/P4Z/p4zsink.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

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