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 @ 15075

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

major update of the sediment module

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