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.
mocsy_gasflux.F90 in branches/UKMO/dev_r5518_GO6_under_ice_relax_dr_hook/NEMOGCM/NEMO/TOP_SRC/MEDUSA – NEMO

source: branches/UKMO/dev_r5518_GO6_under_ice_relax_dr_hook/NEMOGCM/NEMO/TOP_SRC/MEDUSA/mocsy_gasflux.F90

Last change on this file was 11738, checked in by marc, 5 years ago

The Dr Hook changes from my perl code.

File size: 9.0 KB
Line 
1MODULE mocsy_gasflux
2
3CONTAINS
4
5! --------------------------------------------------------------------
6!  Schmidt CO2 number
7! --------------------------------------------------------------------
8!
9! Title  : Calculates Schmidt number for ocean uptake of CO2
10! Author : Andrew Yool
11! Date   : 14/10/04
12!
13! This function calculates the Schmidt number for CO2 using sea surface
14! temperature.  The code is based upon that developed as part of the
15! OCMIP-2 project (1998-2000).  The coefficients used are taken from
16! Wanninkhof (1992, JGR, 97, 7373-7382).
17!
18! AXY (12/06/2015)
19! UPDATED: coefficients used below are now those from Wanninkhof (2014)
20! update to original 1992 paper. Full reference is:
21!
22! Winninkhof, R. (2014). Relationship between wind speed and gas
23! exchange over the ocean revisited. LIMNOLOGY AND OCEANOGRAPHY-METHODS
24! 12, 351-362, doi:10.4319/lom.2014.12.351
25!
26! Check answer for the function at 20 degrees C is 668.
27!
28! Function inputs are (in order) :
29!     t            temperature (degrees C)
30! (*) co2_schmidt  carbon dioxide Schmidt number
31!
32! Where (*) is the function output.
33!
34      subroutine schmidt_co2(pt, N, co2_schmidt)
35
36      USE mocsy_singledouble
37
38      USE yomhook, ONLY: lhook, dr_hook
39      USE parkind1, ONLY: jprb, jpim
40
41      implicit none
42!
43      INTEGER, INTENT(in) :: N
44      real(kind=wp), INTENT(in),  DIMENSION(N) :: pt
45      real(kind=wp), INTENT(out), DIMENSION(N) :: co2_schmidt
46!
47      real(kind=wp)              :: a0, a1, a2, a3, a4
48!
49!     data a0 /    2073.1 /
50!     data a1 /   -125.62 /
51!     data a2 /    3.6276 /
52!     data a3 / -0.043219 /
53!
54      data a0 /    2116.8 /
55      data a1 /   -136.25 /
56      data a2 /    4.7353 /
57      data a3 / -0.092307 /
58      data a4 / 0.0007555 /
59      INTEGER(KIND=jpim), PARAMETER :: zhook_in = 0
60      INTEGER(KIND=jpim), PARAMETER :: zhook_out = 1
61      REAL(KIND=jprb)               :: zhook_handle
62
63      CHARACTER(LEN=*), PARAMETER :: RoutineName='SCHMIDT_CO2'
64
65      IF (lhook) CALL dr_hook(RoutineName,zhook_in,zhook_handle)
66
67!
68! Wanninkhof (1992)
69!     co2_schmidt = a0 + pt*(a1 + pt*(a2 + pt*a3))
70!
71! Wanninkhof (2014) adds in an extra term
72      co2_schmidt = a0 + pt*(a1 + pt*(a2 + pt*(a3 + pt*a4)))
73!
74      IF (lhook) CALL dr_hook(RoutineName,zhook_out ,zhook_handle)
75      return
76
77      IF (lhook) CALL dr_hook(RoutineName,zhook_out,zhook_handle)
78      end subroutine schmidt_co2
79
80! --------------------------------------------------------------------
81!  Surface K0
82! --------------------------------------------------------------------
83!
84! Title  : Calculates surface K0 from surface T & S
85! Author : Andrew Yool
86! Date   : 18/06/15
87!
88! This function is derived from code included in the MOCSY package
89! produced by Jim Orr.
90!
91      subroutine surface_K0(ptmp, saln, N, K0)
92
93      USE mocsy_singledouble
94
95      USE yomhook, ONLY: lhook, dr_hook
96      USE parkind1, ONLY: jprb, jpim
97
98      implicit none
99!
100      INTEGER, INTENT(in) :: N
101      real(kind=wp), INTENT(in),  DIMENSION(N) :: ptmp, saln
102      real(kind=wp), INTENT(out), DIMENSION(N) :: K0
103!
104      real(kind=wp), DIMENSION(N) :: tk, invtk, tmp
105      real(kind=wp)               :: a0, a1, a2, a3, a4
106      INTEGER(KIND=jpim), PARAMETER :: zhook_in = 0
107      INTEGER(KIND=jpim), PARAMETER :: zhook_out = 1
108      REAL(KIND=jprb)               :: zhook_handle
109
110      CHARACTER(LEN=*), PARAMETER :: RoutineName='SURFACE_K0'
111
112      IF (lhook) CALL dr_hook(RoutineName,zhook_in,zhook_handle)
113
114!
115      tk    = ptmp + 273.15d0
116      invtk = 1.0d0 / tk
117      tmp = (9345.17d0*invtk) - 60.2409d0 + (23.3585d0 * LOG(tk/100.0d0))
118      K0 = EXP( tmp + saln*(0.023517d0 - (0.00023656d0*tk) + (0.0047036e-4_wp*tk*tk)) )
119!
120      IF (lhook) CALL dr_hook(RoutineName,zhook_out ,zhook_handle)
121      return
122
123      IF (lhook) CALL dr_hook(RoutineName,zhook_out,zhook_handle)
124      end subroutine surface_K0
125
126! --------------------------------------------------------------------
127!  Calculate xCO2
128! --------------------------------------------------------------------
129!
130!>    Compute xCO2 from arrays of pCO2atm, in situ T, S, & atm pressure
131SUBROUTINE pCO2atm2xCO2(pCO2atm, temp, salt, Patm, N, xCO2)
132  !    Purpose:
133  !    Compute xCO2 from arrays of pCO2atm, in situ T, S, & atm pressure
134
135  USE mocsy_singledouble
136
137  USE yomhook, ONLY: lhook, dr_hook
138  USE parkind1, ONLY: jprb, jpim
139
140  IMPLICIT NONE
141
142  !> number of records
143  INTEGER, intent(in) :: N
144
145! INPUT variables
146  !> atmospheric partial pressure of CO2 [uatm]
147  ! AXY (22/06/15): amended this next line to "in" as that's what it should be!
148  REAL(kind=wp), INTENT(in), DIMENSION(N) :: pCO2atm
149  !> in situ temperature [C]
150  REAL(kind=wp), INTENT(in), DIMENSION(N) :: temp
151  !> salinity [psu]
152  REAL(kind=wp), INTENT(in), DIMENSION(N) :: salt
153  !> atmospheric pressure [atm]
154  REAL(kind=wp), INTENT(in), DIMENSION(N) :: Patm
155!f2py optional , depend(temp) :: n=len(temp)
156
157! OUTPUT variables:
158  !> mole fraction of CO2 [ppm]
159  REAL(kind=wp), INTENT(out), DIMENSION(N) :: xCO2
160
161! LOCAL variables:
162  REAL(kind=wp) :: dpCO2atm, dPatm
163  REAL(kind=wp), DIMENSION(N) :: pH20
164  REAL(kind=wp) :: dxCO2
165
166  INTEGER :: i
167  INTEGER(KIND=jpim), PARAMETER :: zhook_in = 0
168  INTEGER(KIND=jpim), PARAMETER :: zhook_out = 1
169  REAL(KIND=jprb)               :: zhook_handle
170
171  CHARACTER(LEN=*), PARAMETER :: RoutineName='PCO2ATM2XCO2'
172
173  IF (lhook) CALL dr_hook(RoutineName,zhook_in,zhook_handle)
174
175
176  call vapress(temp, salt, N, pH20)
177
178  DO i = 1,N
179     dpCO2atm  = DBLE(pCO2atm(i))
180     dPatm     = DBLE(Patm(i))
181     dxCO2     = dpCO2atm / (dPatm - pH20(i))
182     xCO2(i) = REAL(dxCO2)
183  END DO
184
185  IF (lhook) CALL dr_hook(RoutineName,zhook_out ,zhook_handle)
186  RETURN
187  IF (lhook) CALL dr_hook(RoutineName,zhook_out,zhook_handle)
188END SUBROUTINE pCO2atm2xCO2
189
190! --------------------------------------------------------------------
191!  Calculate pCO2atm
192! --------------------------------------------------------------------
193!
194!>    Compute pCO2atm from arrays of xCO2, in situ T, S, & atm pressure
195SUBROUTINE x2pCO2atm(xCO2, temp, salt, Patm, N, pCO2atm)
196  !    Purpose:
197  !    Compute pCO2atm from arrays of xCO2, in situ T, S, & atm pressure
198
199  USE mocsy_singledouble
200
201  USE yomhook, ONLY: lhook, dr_hook
202  USE parkind1, ONLY: jprb, jpim
203
204  IMPLICIT NONE
205
206  !> number of records
207  INTEGER, intent(in) :: N
208
209! INPUT variables
210  !> mole fraction of CO2 [ppm]
211  REAL(kind=wp), INTENT(in), DIMENSION(N) :: xCO2
212  !> in situ temperature [C]
213  REAL(kind=wp), INTENT(in), DIMENSION(N) :: temp
214  !> salinity [psu]
215  REAL(kind=wp), INTENT(in), DIMENSION(N) :: salt
216  !> atmospheric pressure [atm]
217  REAL(kind=wp), INTENT(in), DIMENSION(N) :: Patm
218!f2py optional , depend(temp) :: n=len(temp)
219
220! OUTPUT variables:
221  !> oceanic partial pressure of CO2 [uatm]
222  REAL(kind=wp), INTENT(out), DIMENSION(N) :: pCO2atm
223
224! LOCAL variables:
225  REAL(kind=wp) :: dxCO2, dPatm
226  REAL(kind=wp), DIMENSION(N) :: pH20
227  REAL(kind=wp) :: dpCO2atm
228
229  INTEGER :: i
230  INTEGER(KIND=jpim), PARAMETER :: zhook_in = 0
231  INTEGER(KIND=jpim), PARAMETER :: zhook_out = 1
232  REAL(KIND=jprb)               :: zhook_handle
233
234  CHARACTER(LEN=*), PARAMETER :: RoutineName='X2PCO2ATM'
235
236  IF (lhook) CALL dr_hook(RoutineName,zhook_in,zhook_handle)
237
238
239! Compute vapor pressure of seawater [in atm]
240  call vapress(temp, salt, N, pH20)
241
242  DO i = 1,N
243     dxCO2     = DBLE(xCO2(i))
244     dPatm     = DBLE(Patm(i))
245     dpCO2atm = (dPatm - pH20(i)) * dxCO2
246     pCO2atm(i) = REAL(dpCO2atm)
247  END DO
248
249  IF (lhook) CALL dr_hook(RoutineName,zhook_out ,zhook_handle)
250  RETURN
251  IF (lhook) CALL dr_hook(RoutineName,zhook_out,zhook_handle)
252END SUBROUTINE x2pCO2atm
253
254! --------------------------------------------------------------------
255!  Calculate seawater vapor pressure
256! --------------------------------------------------------------------
257!
258!>    Compute vapor pressure of seawater (atm) following preocedure from Weiss & Price (1980)
259SUBROUTINE vapress(temp, salt, N, vpsw)
260  !    Purpose:
261  !    Compute vapor pressure of seawater (atm) following preocedure from Weiss & Price (1980)
262
263  USE mocsy_singledouble
264  USE yomhook, ONLY: lhook, dr_hook
265  USE parkind1, ONLY: jprb, jpim
266
267  IMPLICIT NONE
268
269  !> number of records
270  INTEGER, intent(in) :: N
271
272! INPUT variables
273  !> in situ temperature [C]
274  REAL(kind=wp), INTENT(in), DIMENSION(N) :: temp
275  !> salinity [psu]
276  REAL(kind=wp), INTENT(in), DIMENSION(N) :: salt
277!f2py optional , depend(temp) :: n=len(temp)
278
279! OUTPUT variables:
280  !> vapor pressure of seawater [atm]
281  REAL(kind=wp), INTENT(out), DIMENSION(N) :: vpsw
282
283! LOCAL variables:
284  REAL(kind=wp) :: tk, dsalt
285
286  INTEGER :: i
287  INTEGER(KIND=jpim), PARAMETER :: zhook_in = 0
288  INTEGER(KIND=jpim), PARAMETER :: zhook_out = 1
289  REAL(KIND=jprb)               :: zhook_handle
290
291  CHARACTER(LEN=*), PARAMETER :: RoutineName='VAPRESS'
292
293  IF (lhook) CALL dr_hook(RoutineName,zhook_in,zhook_handle)
294
295
296  DO i = 1,N
297     dsalt = DBLE(salt(i))
298     tk = 273.15d0 + DBLE(temp(i))     !Absolute temperature (Kelvin)
299     vpsw(i) = exp(24.4543d0 - 67.4509d0*(100.0d0/tk) - 4.8489d0*log(tk/100) - 0.000544d0*dsalt)
300  END DO
301
302  IF (lhook) CALL dr_hook(RoutineName,zhook_out ,zhook_handle)
303  RETURN
304  IF (lhook) CALL dr_hook(RoutineName,zhook_out,zhook_handle)
305END SUBROUTINE vapress
306
307END MODULE mocsy_gasflux
Note: See TracBrowser for help on using the repository browser.