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.
sedsol.F90 in NEMO/branches/2021/dev_r14383_PISCES_NEWDEV_PISCO/src/TOP/PISCES/SED – NEMO

source: NEMO/branches/2021/dev_r14383_PISCES_NEWDEV_PISCO/src/TOP/PISCES/SED/sedsol.F90 @ 15297

Last change on this file since 15297 was 15297, checked in by aumont, 3 years ago

major update of the sediment module

File size: 10.1 KB
Line 
1MODULE sedsol
2   !!======================================================================
3   !!              ***  MODULE  sedsol  ***
4   !!    Sediment : dissolution and reaction in pore water related
5   !!    related to organic matter
6   !!    Diffusion of solutes in pore water
7   !!=====================================================================
8   !! * Modules used
9   USE sed     ! sediment global variable
10   USE sed_oce
11   USE sedini
12   USE sedfunc
13   USE seddsr
14   USE sedjac
15   USE sedbtb
16   USE sedco3
17   USE sedmat
18   USE sedorg
19   USE tros
20   USE lib_mpp         ! distribued memory computing library
21   USE lib_fortran
22
23   IMPLICIT NONE
24   PRIVATE
25
26   PUBLIC sed_sol
27
28   !! $Id: sedsol.F90 5215 2015-04-15 16:11:56Z nicolasmartin $
29CONTAINS
30   
31   SUBROUTINE sed_sol( kt ) 
32      !!----------------------------------------------------------------------
33      !!                   ***  ROUTINE sed_sol  ***
34      !!
35      !!  ** Purpose :  computes pore water diffusion and reactions
36      !!
37      !!  ** Methode :  Computation of the redox and dissolution reactions
38      !!                in the sediment.
39      !!                The main redox reactions are solved in sed_dsr whereas
40      !!                the secondary reactions are solved in sed_dsr_redoxb.
41      !!                Inorganic dissolution is solved in sed_inorg
42      !!                A strand spliting approach is being used here (see
43      !!                sed_dsr_redoxb for more information).
44      !!                Diffusive fluxes are computed in sed_diff
45      !!
46      !!   History :
47      !!        !  98-08 (E. Maier-Reimer, Christoph Heinze )  Original code
48      !!        !  04-10 (N. Emprin, M. Gehlen ) f90
49      !!        !  06-04 (C. Ethe)  Re-organization
50      !!        !  19-08 (O. Aumont) Debugging and improvement of the model.
51      !!                             The original method is replaced by a
52      !!                             Strand splitting method which deals
53      !!                             well with stiff reactions.
54      !!----------------------------------------------------------------------
55      !! Arguments
56      INTEGER, INTENT(in) ::   kt
57      ! --- local variables
58      INTEGER  :: ji, jk, js, jw, jn, neq   ! dummy looop indices
59      REAL(wp), DIMENSION( jpoce, jpvode * jpksed ) :: ZXIN, FVAL
60      REAL(wp), DIMENSION(jpoce,jpksed) :: preac
61      INTEGER :: JINDEX, ITOL, IJAC, MLJAC, IMAX
62      INTEGER :: MUJAC,LE1, LJAC, LWORK
63      INTEGER :: IDID, NMAXSTP, ROSM
64      REAL(wp) :: X, XEND
65      REAL(wp),DIMENSION(jpoce) :: H
66      INTEGER, DIMENSION(jpoce) :: accmask
67      REAL(wp), DIMENSION(jpvode * jpksed) :: RTOL, ATOL
68      REAL(wp), POINTER :: WORK(:)
69      INTEGER, DIMENSION(jpoce,3)   :: ISTAT
70      REAL(wp), DIMENSION(jpoce,2)  :: RSTAT
71      !!
72      !!----------------------------------------------------------------------
73
74      IF( ln_timing )  CALL timing_start('sed_sol')
75!
76      IF( kt == nitsed000 ) THEN
77         IF (lwp) THEN
78            WRITE(numsed,*) ' sed_sol : Organic/inorganic degradation related reactions and diffusion'
79            WRITE(numsed,*) ' '
80         ENDIF
81!         !
82      ENDIF
83
84      ! 1. Change of geometry
85      !    Increase of dz3d(2) thickness : dz3d(2) = dz3d(2)+dzdep
86      !    Warning : no change for dz(2)
87      !---------------------------------------------------------
88      dz3d(1:jpoce,2) = dz3d(1:jpoce,2) + dzdep(1:jpoce)
89
90      ! New values for volw3d(:,2) and vols3d(:,2)
91      ! Warning : no change neither for volw(2) nor  vols(2)
92      !------------------------------------------------------
93      volw3d(1:jpoce,2) = dz3d(1:jpoce,2) * por(2)
94      vols3d(1:jpoce,2) = dz3d(1:jpoce,2) * por1(2)
95
96      ! 2. Change of previous solid fractions (due to volum changes) for k=2
97      !---------------------------------------------------------------------
98      DO js = 1, jpsol
99         solcp(:,2,js) = solcp(:,2,js) * dz(2) / dz3d(:,2)
100      END DO
101
102      ! 3. New solid fractions (including solid rain fractions) for k=2
103      !------------------------------------------------------------------
104      DO js = 1, jpsol
105         DO ji = 1, jpoce
106            IF (dzdep(ji) .ne. 0) THEN
107               solcp(ji,2,js) = solcp(ji,2,js) + rainrg(ji,js) * dtsed / ( por1(2) * dz3d(ji,2) )
108               ! rainrm are temporary cancel
109            ENDIF
110         END DO
111      ENDDO
112
113      ! 4.  Adjustment of bottom water concen.(pwcp(1)):
114      !     We impose that pwcp(2) is constant. Including dzdep in dz3d(:,2) we assume
115      !     that dzdep has got a porosity of por(2). So pore water volum of jk=2 increase.
116      !     To keep pwcp(2) cste we must compensate this "increase" by a slight adjusment
117      !     of bottom water concentration.
118      !     This adjustment is compensate at the end of routine
119      !-------------------------------------------------------------
120      DO jw = 1, jpwat
121         pwcp(:,1,jw) = pwcp(:,1,jw) - pwcp(:,2,jw) * dzdep(:) * por(2) / dzkbot(:)
122      ENDDO
123
124      ! --------------------------------------------------
125      ! Computation of the diffusivities
126      ! --------------------------------------------------
127      DO js = 1, jpwat
128         DO jk = 1, jpksed
129            diff(:,jk,js) = ( diff1(js) + diff2(js) * temp(:) ) / ( 1.0 - 2.0 * log( por(jk) ) )
130         END DO
131      END DO
132
133      ! Impact of bioirrigation and adsorption on diffusion
134      ! ---------------------------------------------------
135      diff(:,:,jwsil) = diff(:,:,jwsil) * ( 1.0 + irrig(:,:) )
136      diff(:,:,jwoxy) = diff(:,:,jwoxy) * ( 1.0 + irrig(:,:) )
137      diff(:,:,jwdic) = diff(:,:,jwdic) * ( 1.0 + irrig(:,:) )
138      diff(:,:,jwno3) = diff(:,:,jwno3) * ( 1.0 + irrig(:,:) )
139      diff(:,:,jwpo4) = diff(:,:,jwpo4) * ( 1.0 + irrig(:,:) )
140      diff(:,:,jwalk) = diff(:,:,jwalk) * ( 1.0 + irrig(:,:) )
141      diff(:,:,jwh2s) = diff(:,:,jwh2s) * ( 1.0 + irrig(:,:) )
142      diff(:,:,jwso4) = diff(:,:,jwso4) * ( 1.0 + irrig(:,:) )
143      diff(:,:,jwlgw) = diff(:,:,jwlgw) * ( 1.0 + irrig(:,:) )
144      diff(:,:,jwnh4) = diff(:,:,jwnh4) * ( 1.0 + irrig(:,:) )
145      diff(:,:,jwfe2) = diff(:,:,jwfe2) * ( 1.0 + 0.1 * irrig(:,:) )
146
147      ! Conversion of volume units
148      !----------------------------
149      DO js = 1, jpsol
150         DO jk = 1, jpksed
151            volc(:,jk,js) = ( vols3d(:,jk) / mol_wgt(js) ) /  &
152            &                 ( volw3d(:,jk) * 1.e-3 )
153         ENDDO
154      ENDDO
155
156      ! Compute coefficients commonly used in diffusion
157      CALL sed_mat_coef
158      ! Apply bioturbation and compute the impact of the slow SMS on species
159      CALL sed_btb( kt )
160      ! Recompute pH after bioturbation and slow chemistry
161      CALL sed_co3( kt )
162
163      ! The following part deals with the stiff ODEs
164      ! This is the expensive part of the code and should be carefully
165      ! chosen. We use the DVODE solver after many trials to find a cheap
166      ! way to solve the ODEs. This is not necessarily the most efficient
167      ! but this is the one that was not too much of a pain to code and that
168      ! was the most precise and quick.
169      ! The ones I tried : operator splitting (Strang), hybrid spectral methods
170      ! Brent, Powell's hybrid method, ...
171      ! ---------------------------------------------------------------------
172      NEQ  = jpvode * jpksed
173      XEND = dtsed 
174      RTOL = rosrtol
175      ATOL = rosatol
176      ITOL = 1
177      IJAC = 1
178      DO jn = 1, NEQ
179         js = jarr(jn,2)
180         IF (js == jwfe2) ATOL(jn) = rosatol / 100.0
181      END DO
182      MLJAC = jpvode
183      MUJAC = jpvode
184      LE1  = 2*MLJAC+MUJAC+1
185      LJAC = MLJAC+MUJAC+1
186      LWORK = NEQ*(LJAC+LE1+8) + 5
187      ALLOCATE(WORK(LWORK) )
188
189      X    = 0.0
190      H(:)    = dtsed
191      WORK  = 0.
192
193      ! Put all the species in one local array (nb of tracers * vertical
194      ! dimension
195      DO jn = 1, NEQ
196         jk = jarr(jn,1)
197         js = jarr(jn,2)
198         IF (js <= jpwat) THEN
199            zxin(:,jn) = pwcp(:,jk,js) * 1E6
200         ELSE
201            zxin(:,jn) = solcp(:,jk,js-jpwat) * 1E6
202         ENDIF
203      END DO
204
205      ! Set options for VODE : banded matrix. SParse option is much more
206      ! expensive except if one computes the sparse Jacobian explicitly
207      ! To speed up the computation, one way is to reduce ATOL and RTOL
208      ! which may be a good option at the beginning of the simulations
209      ! during the spin up
210      ! ----------------------------------------------------------------
211      CALL ROSK(NROSORDER, NEQ,X,zxin,XEND,H,RTOL,ATOL,ITOL, sed_jac,  &
212           &   MLJAC,MUJAC,WORK,LWORK,IDID,ISTAT,RSTAT)
213
214      accmask(:) = 0.0
215      CALL sed_func( NEQ, ZXIN, FVAL, ACCMASK )
216
217      DO jn = 1, NEQ
218         jk = jarr(jn,1)
219         js = jarr(jn,2)
220         IF (js <= jpwat) THEN
221            pwcp(:,jk,js) = zxin(:,jn) * 1E-6
222         ELSE
223            solcp(:,jk,js-jpwat) = zxin(:,jn) * 1E-6
224         ENDIF
225      END DO
226      rstepros(:) = ISTAT(:,3)
227
228      DEALLOCATE( WORK )
229
230      preac(:,:) = 0.
231      CALL sed_mat_dsri( jwpo4, preac, pwcpa(:,:,jwpo4), dtsed, pwcp(:,:,jwpo4) )
232      CALL sed_mat_dsri( jwalk, preac, pwcpa(:,:,jwalk), dtsed, pwcp(:,:,jwalk) )
233
234      CALL sed_org( kt )
235
236      !----------------------------------
237      !   Back to initial geometry
238      !-----------------------------
239
240      !---------------------------------------------------------------------
241      !   1/ Compensation for ajustement of the bottom water concentrations
242      !      (see note n� 1 about *por(2))
243      !--------------------------------------------------------------------
244      DO jw = 1, jpwat
245         pwcp(:,1,jw) = pwcp(:,1,jw) + pwcp(:,2,jw) * dzdep(:) * por(2) / dzkbot(:)
246      ENDDO
247
248      ! 2. Change of previous solid fractions (due to volum changes) for k=2
249      !---------------------------------------------------------------------
250      DO js = 1, jpsol
251         solcp(:,2,js) = solcp(:,2,js) * dz3d(:,2) / dz(2)
252      END DO
253
254      !--------------------------------
255      !    3/ back to initial geometry
256      !--------------------------------
257      dz3d  (:,2) = dz(2)
258      volw3d(:,2) = dz3d(:,2) * por(2)
259      vols3d(:,2) = dz3d(:,2) * por1(2)
260
261      IF( ln_timing )  CALL timing_stop('sed_sol')
262!     
263   END SUBROUTINE sed_sol
264
265   SUBROUTINE JACFAC
266 
267   END SUBROUTINE JACFAC
268
269END MODULE sedsol
Note: See TracBrowser for help on using the repository browser.