Line data Source code
1 : !=======================================================================
2 : !
3 : ! Compute sea ice biogeochemistry (vertical or skeletal layer)
4 : !
5 : ! authors: Nicole Jeffery, LANL
6 : ! Scott Elliot, LANL
7 : ! Elizabeth C. Hunke, LANL
8 : !
9 : module icepack_algae
10 :
11 : use icepack_kinds
12 :
13 : use icepack_parameters, only: p05, p5, c0, c1, c2, c6, c10
14 : use icepack_parameters, only: pi, secday, puny
15 : use icepack_parameters, only: hs_ssl, sk_l
16 :
17 : use icepack_parameters, only: dEdd_algae, solve_zbgc
18 : use icepack_parameters, only: R_dFe2dust, dustFe_sol, algal_vel
19 : use icepack_parameters, only: bgc_flux_type
20 : use icepack_parameters, only: grid_o
21 : use icepack_parameters, only: T_max, fsal , fr_resp
22 : use icepack_parameters, only: op_dep_min , fr_graze_s
23 : use icepack_parameters, only: fr_graze_e , fr_mort2min
24 : use icepack_parameters, only: fr_dFe , k_nitrif
25 : use icepack_parameters, only: t_iron_conv , max_loss
26 : use icepack_parameters, only: max_dfe_doc1 , fr_resp_s
27 : use icepack_parameters, only: y_sk_DMS , t_sk_conv
28 : use icepack_parameters, only: t_sk_ox
29 :
30 : use icepack_tracers, only: ntrcr, bio_index
31 : use icepack_tracers, only: nt_bgc_N, nt_fbri, nt_zbgc_frac
32 : use icepack_tracers, only: tr_brine
33 : use icepack_tracers, only: tr_bgc_Nit, tr_bgc_Am, tr_bgc_Sil
34 : use icepack_tracers, only: tr_bgc_DMS, tr_bgc_PON
35 : use icepack_tracers, only: tr_bgc_N, tr_bgc_C, tr_bgc_chl
36 : use icepack_tracers, only: tr_bgc_DON, tr_bgc_Fe, tr_zaero
37 : use icepack_tracers, only: nlt_bgc_Nit, nlt_bgc_Am, nlt_bgc_Sil
38 : use icepack_tracers, only: nlt_bgc_DMS, nlt_bgc_PON
39 : use icepack_tracers, only: nlt_bgc_N, nlt_bgc_C, nlt_bgc_chl
40 : use icepack_tracers, only: nlt_bgc_DOC, nlt_bgc_DON, nlt_bgc_DIC
41 : use icepack_tracers, only: nlt_zaero , nlt_bgc_DMSPp,nlt_bgc_DMSPd
42 : use icepack_tracers, only: nlt_bgc_Fed, nlt_bgc_Fep
43 :
44 : use icepack_zbgc_shared, only: remap_zbgc, regrid_stationary
45 : use icepack_zbgc_shared, only: merge_bgc_fluxes
46 : use icepack_zbgc_shared, only: merge_bgc_fluxes_skl
47 : use icepack_zbgc_shared, only: phi_sk, bgc_tracer_type
48 : use icepack_zbgc_shared, only: zbgc_init_frac
49 : use icepack_zbgc_shared, only: zbgc_frac_init
50 : use icepack_zbgc_shared, only: tau_rel, tau_ret, thinS
51 : use icepack_zbgc_shared, only: r_Si2N, R_Fe2N, R_S2N, R_chl2N
52 : use icepack_zbgc_shared, only: chlabs, alpha2max_low, beta2max, mu_max
53 : use icepack_zbgc_shared, only: k_exude, K_Nit, K_Am, K_Sil, K_Fe
54 : use icepack_zbgc_shared, only: grow_Tdep, fr_graze, mort_pre, mort_Tdep
55 : use icepack_zbgc_shared, only: f_don, kn_bac, f_don_Am
56 : use icepack_zbgc_shared, only: f_doc, f_exude, k_bac, R_chl2N, R_C2N
57 :
58 : use icepack_warnings, only: warnstr, icepack_warnings_add
59 : use icepack_warnings, only: icepack_warnings_setabort, icepack_warnings_aborted
60 :
61 : use icepack_aerosol, only: update_snow_bgc
62 :
63 : implicit none
64 :
65 : private
66 : public :: zbio, sklbio
67 :
68 : real (kind=dbl_kind), parameter :: &
69 : exp_argmax = c10 ! maximum argument of exponential
70 :
71 : !=======================================================================
72 :
73 : contains
74 :
75 : !=======================================================================
76 :
77 0 : subroutine zbio (dt, nblyr, &
78 : nslyr, nilyr, & ! LCOV_EXCL_LINE
79 : meltt, melts, & ! LCOV_EXCL_LINE
80 : meltb, congel, & ! LCOV_EXCL_LINE
81 : snoice, nbtrcr, & ! LCOV_EXCL_LINE
82 : fsnow, ntrcr, & ! LCOV_EXCL_LINE
83 : trcrn, bio_index, & ! LCOV_EXCL_LINE
84 : aice_old, & ! LCOV_EXCL_LINE
85 : vice_old, vsno_old, & ! LCOV_EXCL_LINE
86 : vicen, vsnon, & ! LCOV_EXCL_LINE
87 : aicen, flux_bio_atm,& ! LCOV_EXCL_LINE
88 : n_cat, n_algae, & ! LCOV_EXCL_LINE
89 : n_doc, n_dic, & ! LCOV_EXCL_LINE
90 : n_don, & ! LCOV_EXCL_LINE
91 : n_fed, n_fep, & ! LCOV_EXCL_LINE
92 : n_zaero, first_ice, & ! LCOV_EXCL_LINE
93 : hice_old, ocean_bio, & ! LCOV_EXCL_LINE
94 : bphin, iphin, & ! LCOV_EXCL_LINE
95 : iDin, & ! LCOV_EXCL_LINE
96 : fswthrul, & ! LCOV_EXCL_LINE
97 : dh_top, dh_bot, & ! LCOV_EXCL_LINE
98 : zfswin, & ! LCOV_EXCL_LINE
99 : hbri, hbri_old, & ! LCOV_EXCL_LINE
100 : ! darcy_V, darcy_V_chl, & ! LCOV_EXCL_LINE
101 : darcy_V, & ! LCOV_EXCL_LINE
102 : bgrid, & ! LCOV_EXCL_LINE
103 : igrid, icgrid, & ! LCOV_EXCL_LINE
104 : bphi_min, & ! LCOV_EXCL_LINE
105 : iTin, & ! LCOV_EXCL_LINE
106 : Zoo, & ! LCOV_EXCL_LINE
107 : flux_bio, dh_direct, & ! LCOV_EXCL_LINE
108 : upNO, upNH, & ! LCOV_EXCL_LINE
109 : fbio_snoice, fbio_atmice, & ! LCOV_EXCL_LINE
110 : PP_net, ice_bio_net, & ! LCOV_EXCL_LINE
111 0 : snow_bio_net, grow_net )
112 :
113 : integer (kind=int_kind), intent(in) :: &
114 : nblyr, & ! number of bio layers ! LCOV_EXCL_LINE
115 : nslyr, & ! number of snow layers ! LCOV_EXCL_LINE
116 : nilyr, & ! number of ice layers ! LCOV_EXCL_LINE
117 : nbtrcr, & ! number of distinct bio tracers ! LCOV_EXCL_LINE
118 : n_cat, & ! category number ! LCOV_EXCL_LINE
119 : n_algae, & ! number of autotrophs ! LCOV_EXCL_LINE
120 : n_zaero, & ! number of aerosols ! LCOV_EXCL_LINE
121 : n_doc, n_dic, n_don, n_fed, n_fep, & ! LCOV_EXCL_LINE
122 : ntrcr ! number of tracers
123 :
124 : integer (kind=int_kind), dimension (nbtrcr), intent(in) :: &
125 : bio_index
126 :
127 : real (kind=dbl_kind), intent(in) :: &
128 : dt, & ! time step ! LCOV_EXCL_LINE
129 : hbri, & ! brine height (m) ! LCOV_EXCL_LINE
130 : bphi_min, & ! surface porosity ! LCOV_EXCL_LINE
131 : meltt, & ! thermodynamic melt/growth rates in dt (m) ! LCOV_EXCL_LINE
132 : melts, & ! LCOV_EXCL_LINE
133 : meltb, & ! LCOV_EXCL_LINE
134 : congel, & ! LCOV_EXCL_LINE
135 : snoice, & ! LCOV_EXCL_LINE
136 : fsnow, & ! snowfall rate (kg/m^2 s) ! LCOV_EXCL_LINE
137 : hice_old, & ! ice height (m) ! LCOV_EXCL_LINE
138 : vicen, & ! ice volume (m) ! LCOV_EXCL_LINE
139 : vsnon, & ! snow volume (m) ! LCOV_EXCL_LINE
140 : aicen, & ! ice area fraction ! LCOV_EXCL_LINE
141 : aice_old, & ! values prior to thermodynamic changes ! LCOV_EXCL_LINE
142 : vice_old, & ! LCOV_EXCL_LINE
143 : vsno_old, & ! LCOV_EXCL_LINE
144 : darcy_V, & ! darcy velocity ! LCOV_EXCL_LINE
145 : ! darcy_V_chl,& ! darcy velocity for algae ! LCOV_EXCL_LINE
146 : dh_bot, & ! change in brine bottom (m) ! LCOV_EXCL_LINE
147 : dh_top, & ! change in brine top (m) ! LCOV_EXCL_LINE
148 : dh_direct ! surface flooding or surface runoff (m)
149 :
150 : real (kind=dbl_kind), dimension (nbtrcr), intent(inout) :: &
151 : snow_bio_net,& ! net bio tracer in snow (mmol/m^2) ! LCOV_EXCL_LINE
152 : ice_bio_net, & ! net bio tracer in ice (mmol/m^2) ! LCOV_EXCL_LINE
153 : fbio_atmice, & ! bio flux from atm to ice (mmol/m^2/s) ! LCOV_EXCL_LINE
154 : fbio_snoice, & ! bio flux from snow to ice (mmol/m^2/s) ! LCOV_EXCL_LINE
155 : flux_bio ! total ocean tracer flux (mmol/m^2/s)
156 :
157 : real (kind=dbl_kind), intent(inout) :: &
158 : hbri_old ! brine height (m)
159 :
160 : real (kind=dbl_kind), dimension (nblyr+2), intent(inout) :: &
161 : bgrid ! biology nondimensional vertical grid points
162 :
163 : real (kind=dbl_kind), dimension (nblyr+1), intent(in) :: &
164 : igrid , & ! biology vertical interface points ! LCOV_EXCL_LINE
165 : iTin , & ! salinity vertical interface points ! LCOV_EXCL_LINE
166 : iphin , & ! Porosity on the igrid ! LCOV_EXCL_LINE
167 : iDin ! Diffusivity/h on the igrid (1/s)
168 :
169 : real (kind=dbl_kind), dimension (nilyr+1), intent(in) :: &
170 : icgrid , & ! CICE interface coordinate ! LCOV_EXCL_LINE
171 : fswthrul ! visible short wave radiation on icgrid (W/m^2)
172 :
173 : real (kind=dbl_kind), dimension(nbtrcr), intent(in) :: &
174 : flux_bio_atm ! aerosol/bgc deposition rate (mmol/m^2 s)
175 :
176 : real (kind=dbl_kind), dimension(ntrcr), intent(inout) :: &
177 : trcrn
178 :
179 : real (kind=dbl_kind), dimension (nblyr+1), intent(inout) :: &
180 : zfswin ! visible Short wave flux on igrid (W/m^2)
181 :
182 : real (kind=dbl_kind), dimension (nblyr+1), intent(inout) :: &
183 : Zoo ! N losses to the system from reaction terms
184 : ! (ie. zooplankton/bacteria) (mmol/m^3)
185 :
186 : real (kind=dbl_kind), dimension (nbtrcr), intent(in) :: &
187 : !change to inout when updating ocean fields
188 : ocean_bio ! ocean concentrations (mmol/m^3)
189 :
190 : real (kind=dbl_kind), dimension (nblyr+2), intent(in) :: &
191 : bphin ! Porosity on the bgrid
192 :
193 : real (kind=dbl_kind), intent(inout):: &
194 : PP_net , & ! net PP (mg C/m^2/d) times aice ! LCOV_EXCL_LINE
195 : grow_net , & ! net specific growth (m/d) times vice ! LCOV_EXCL_LINE
196 : upNO , & ! tot nitrate uptake rate (mmol/m^2/d) times aice ! LCOV_EXCL_LINE
197 : upNH ! tot ammonium uptake rate (mmol/m^2/d) times aice
198 :
199 : logical (kind=log_kind), intent(in) :: &
200 : first_ice ! initialized values should be used
201 :
202 : ! local variables
203 :
204 : integer (kind=int_kind) :: &
205 : mm ! thickness category index
206 :
207 : real (kind=dbl_kind), dimension (nblyr+1,n_algae) :: &
208 : upNOn , & ! algal nitrate uptake rate (mmol/m^3/s) ! LCOV_EXCL_LINE
209 : upNHn , & ! algal ammonium uptake rate (mmol/m^3/s) ! LCOV_EXCL_LINE
210 0 : grow_alg ! algal growth rate (mmol/m^3/s)
211 :
212 : real (kind=dbl_kind), dimension (nbtrcr) :: &
213 0 : flux_bion !tracer flux to ocean
214 :
215 : real (kind=dbl_kind),dimension(nbtrcr) :: &
216 : zbgc_snown, & ! aerosol contribution from snow to ice ! LCOV_EXCL_LINE
217 0 : zbgc_atmn ! and atm to ice concentration * volume (mmol/m^3*m)
218 :
219 : real (kind=dbl_kind), dimension(nbtrcr) :: &
220 : Tot_BGC_i, & ! initial column sum, ice + snow, of BGC tracer (mmol/m^2) ! LCOV_EXCL_LINE
221 : Tot_BGC_f, & ! final column sum ! LCOV_EXCL_LINE
222 0 : flux_bio_sno !
223 :
224 : real (kind=dbl_kind) :: &
225 : hsnow_i, & ! initial snow thickness (m) ! LCOV_EXCL_LINE
226 0 : hsnow_f ! final snow thickness (m)
227 :
228 : logical (kind=log_kind) :: &
229 : write_flux_diag
230 :
231 : real (kind=dbl_kind) :: &
232 0 : a_ice
233 :
234 : character(len=*),parameter :: subname='(zbio)'
235 :
236 0 : zbgc_snown(:) = c0
237 0 : zbgc_atmn (:) = c0
238 0 : flux_bion (:) = c0
239 0 : flux_bio_sno(:) = c0
240 0 : Tot_BGC_i (:) = c0
241 0 : Tot_BGC_f (:) = c0
242 0 : hsnow_i = c0
243 0 : hsnow_f = c0
244 0 : write_flux_diag = .false.
245 :
246 0 : if (write_flux_diag) then
247 0 : if (aice_old > c0) then
248 0 : hsnow_i = vsno_old/aice_old
249 0 : do mm = 1,nbtrcr
250 : call bgc_column_sum (nblyr, nslyr, hsnow_i, hbri_old, &
251 : trcrn(bio_index(mm):bio_index(mm)+nblyr+2), & ! LCOV_EXCL_LINE
252 0 : Tot_BGC_i(mm))
253 0 : if (icepack_warnings_aborted(subname)) return
254 : enddo
255 : endif
256 : endif
257 :
258 : call update_snow_bgc (dt, nblyr, &
259 : nslyr, & ! LCOV_EXCL_LINE
260 : meltt, melts, & ! LCOV_EXCL_LINE
261 : meltb, congel, & ! LCOV_EXCL_LINE
262 : snoice, nbtrcr, & ! LCOV_EXCL_LINE
263 : fsnow, ntrcr, & ! LCOV_EXCL_LINE
264 : trcrn, bio_index, & ! LCOV_EXCL_LINE
265 : aice_old, zbgc_snown, & ! LCOV_EXCL_LINE
266 : vice_old, vsno_old, & ! LCOV_EXCL_LINE
267 : vicen, vsnon, & ! LCOV_EXCL_LINE
268 : aicen, flux_bio_atm, & ! LCOV_EXCL_LINE
269 0 : zbgc_atmn, flux_bio_sno)
270 0 : if (icepack_warnings_aborted(subname)) return
271 :
272 : call z_biogeochemistry (n_cat, dt, &
273 : nilyr, & ! LCOV_EXCL_LINE
274 : nblyr, nbtrcr, & ! LCOV_EXCL_LINE
275 : n_algae, n_doc, & ! LCOV_EXCL_LINE
276 : n_dic, n_don, & ! LCOV_EXCL_LINE
277 : n_fed, n_fep, & ! LCOV_EXCL_LINE
278 : n_zaero, first_ice, & ! LCOV_EXCL_LINE
279 : aicen, vicen, & ! LCOV_EXCL_LINE
280 : hice_old, ocean_bio, & ! LCOV_EXCL_LINE
281 : flux_bion, bphin, & ! LCOV_EXCL_LINE
282 : iphin, trcrn, & ! LCOV_EXCL_LINE
283 : iDin, & ! LCOV_EXCL_LINE
284 : fswthrul, grow_alg, & ! LCOV_EXCL_LINE
285 : upNOn, upNHn, & ! LCOV_EXCL_LINE
286 : dh_top, dh_bot, & ! LCOV_EXCL_LINE
287 : zfswin, hbri, & ! LCOV_EXCL_LINE
288 : hbri_old, darcy_V, & ! LCOV_EXCL_LINE
289 : ! darcy_V_chl, bgrid, & ! LCOV_EXCL_LINE
290 : bgrid, & ! LCOV_EXCL_LINE
291 : igrid, icgrid, & ! LCOV_EXCL_LINE
292 : bphi_min, zbgc_snown,& ! LCOV_EXCL_LINE
293 : zbgc_atmn, & ! LCOV_EXCL_LINE
294 : iTin, dh_direct, & ! LCOV_EXCL_LINE
295 : Zoo, meltb, & ! LCOV_EXCL_LINE
296 0 : congel )
297 0 : if (icepack_warnings_aborted(subname)) return
298 :
299 0 : do mm = 1,nbtrcr
300 0 : flux_bion(mm) = flux_bion(mm) + flux_bio_sno(mm)
301 : enddo
302 :
303 0 : if (write_flux_diag) then
304 0 : if (aicen > c0) then
305 0 : hsnow_f = vsnon/aicen
306 0 : do mm = 1,nbtrcr
307 : call bgc_column_sum (nblyr, nslyr, hsnow_f, hbri, &
308 : trcrn(bio_index(mm):bio_index(mm)+nblyr+2), & ! LCOV_EXCL_LINE
309 0 : Tot_BGC_f(mm))
310 0 : write(warnstr,*) subname, 'mm, Tot_BGC_i(mm), Tot_BGC_f(mm)'
311 0 : call icepack_warnings_add(warnstr)
312 0 : write(warnstr,*) subname, mm, Tot_BGC_i(mm), Tot_BGC_f(mm)
313 0 : call icepack_warnings_add(warnstr)
314 0 : write(warnstr,*) subname, 'flux_bion(mm), flux_bio_atm(mm)'
315 0 : call icepack_warnings_add(warnstr)
316 0 : write(warnstr,*) subname, flux_bion(mm), flux_bio_atm(mm)
317 0 : call icepack_warnings_add(warnstr)
318 0 : write(warnstr,*) subname, 'zbgc_snown(mm),zbgc_atmn(mm)'
319 0 : call icepack_warnings_add(warnstr)
320 0 : write(warnstr,*) subname, zbgc_snown(mm),zbgc_atmn(mm)
321 0 : call icepack_warnings_add(warnstr)
322 0 : write(warnstr,*) subname, 'Tot_BGC_i(mm) + flux_bio_atm(mm)*dt - flux_bion(mm)*dt'
323 0 : call icepack_warnings_add(warnstr)
324 0 : write(warnstr,*) subname, Tot_BGC_i(mm) + flux_bio_atm(mm)*dt - flux_bion(mm)*dt
325 0 : call icepack_warnings_add(warnstr)
326 : enddo
327 : endif
328 : endif
329 :
330 0 : if (icepack_warnings_aborted(subname)) return
331 :
332 : call merge_bgc_fluxes (dt, nblyr, &
333 : nslyr, & ! LCOV_EXCL_LINE
334 : bio_index, n_algae, & ! LCOV_EXCL_LINE
335 : nbtrcr, aicen, & ! LCOV_EXCL_LINE
336 : vicen, vsnon, & ! LCOV_EXCL_LINE
337 : iphin, & ! LCOV_EXCL_LINE
338 : trcrn, & ! LCOV_EXCL_LINE
339 : flux_bion, flux_bio, & ! LCOV_EXCL_LINE
340 : upNOn, upNHn, & ! LCOV_EXCL_LINE
341 : upNO, upNH, & ! LCOV_EXCL_LINE
342 : zbgc_snown, zbgc_atmn, & ! LCOV_EXCL_LINE
343 : fbio_snoice, fbio_atmice,& ! LCOV_EXCL_LINE
344 : PP_net, ice_bio_net,& ! LCOV_EXCL_LINE
345 : snow_bio_net, grow_alg, & ! LCOV_EXCL_LINE
346 0 : grow_net)
347 0 : if (icepack_warnings_aborted(subname)) return
348 :
349 0 : if (write_flux_diag) then
350 0 : if (aicen > c0) then
351 0 : if (n_cat .eq. 1) a_ice = c0
352 0 : a_ice = a_ice + aicen
353 0 : write(warnstr,*) subname, 'after merge_bgc_fluxes, n_cat:', n_cat
354 0 : call icepack_warnings_add(warnstr)
355 0 : do mm = 1,nbtrcr
356 0 : write(warnstr,*) subname, 'mm, flux_bio(mm):',mm,flux_bio(mm)
357 0 : call icepack_warnings_add(warnstr)
358 0 : write(warnstr,*) subname, 'fbio_snoice(mm)',fbio_snoice(mm)
359 0 : call icepack_warnings_add(warnstr)
360 0 : write(warnstr,*) subname, 'fbio_atmice(mm)',fbio_atmice(mm)
361 0 : call icepack_warnings_add(warnstr)
362 0 : write(warnstr,*) subname, 'flux_bio_atm(mm)', flux_bio_atm(mm)
363 0 : call icepack_warnings_add(warnstr)
364 0 : write(warnstr,*) subname, 'flux_bio_atm(mm)*a_ice', flux_bio_atm(mm)*a_ice
365 0 : call icepack_warnings_add(warnstr)
366 : enddo
367 : endif
368 : endif
369 :
370 : end subroutine zbio
371 :
372 : !=======================================================================
373 :
374 0 : subroutine sklbio (dt, ntrcr, &
375 : nbtrcr, n_algae, & ! LCOV_EXCL_LINE
376 : n_doc, & ! LCOV_EXCL_LINE
377 : n_dic, n_don, & ! LCOV_EXCL_LINE
378 : n_fed, n_fep, & ! LCOV_EXCL_LINE
379 : flux_bio, ocean_bio, & ! LCOV_EXCL_LINE
380 : aicen, & ! LCOV_EXCL_LINE
381 : meltb, congel, & ! LCOV_EXCL_LINE
382 : fswthru, first_ice, & ! LCOV_EXCL_LINE
383 : trcrn, & ! LCOV_EXCL_LINE
384 : PP_net, upNO, & ! LCOV_EXCL_LINE
385 : upNH, grow_net )
386 :
387 : integer (kind=int_kind), intent(in) :: &
388 : nbtrcr, & ! number of distinct bio tracers ! LCOV_EXCL_LINE
389 : n_algae, & ! number of autotrophs ! LCOV_EXCL_LINE
390 : n_doc, n_dic, & ! number of dissolved organic, inorganic carbon ! LCOV_EXCL_LINE
391 : n_don, & ! number of dissolved organic nitrogen ! LCOV_EXCL_LINE
392 : n_fed, n_fep, & ! number of iron ! LCOV_EXCL_LINE
393 : ntrcr ! number of tracers
394 :
395 : logical (kind=log_kind), intent(in) :: &
396 : first_ice ! initialized values should be used
397 :
398 : real (kind=dbl_kind), intent(in) :: &
399 : dt, & ! time step ! LCOV_EXCL_LINE
400 : ! hmix, & ! mixed layer depth (m) ! LCOV_EXCL_LINE
401 : aicen, & ! ice area fraction ! LCOV_EXCL_LINE
402 : meltb, & ! bottom melt (m) ! LCOV_EXCL_LINE
403 : congel, & ! bottom growth (m) ! LCOV_EXCL_LINE
404 : fswthru ! visible shortwave passing to ocean(W/m^2)
405 :
406 : real (kind=dbl_kind), dimension(ntrcr), intent(inout) :: &
407 : trcrn ! bulk concentration per m^3
408 :
409 : real (kind=dbl_kind), dimension (nbtrcr), intent(inout) :: &
410 : flux_bio ! ocean tracer flux (mmol/m^2/s) positive into ocean
411 :
412 : real (kind=dbl_kind), dimension (nbtrcr), intent(in) :: &
413 : ocean_bio ! ocean tracer concentration (mmol/m^3)
414 :
415 : ! history output
416 : real (kind=dbl_kind), intent(inout):: &
417 : PP_net , & ! Bulk net PP (mg C/m^2/s) ! LCOV_EXCL_LINE
418 : grow_net, & ! net specific growth (/s) ! LCOV_EXCL_LINE
419 : upNO , & ! tot nitrate uptake rate (mmol/m^2/s) ! LCOV_EXCL_LINE
420 : upNH ! tot ammonium uptake rate (mmol/m^2/s)
421 :
422 : ! local variables
423 :
424 : real (kind=dbl_kind), dimension (n_algae) :: &
425 : upNOn , & ! algal nitrate uptake rate (mmol/m^3/s) ! LCOV_EXCL_LINE
426 : upNHn , & ! algal ammonium uptake rate (mmol/m^3/s) ! LCOV_EXCL_LINE
427 0 : grow_alg ! algal growth rate (mmol/m^3/s)
428 :
429 : real (kind=dbl_kind), dimension (nbtrcr) :: &
430 0 : flux_bion !tracer flux to ocean
431 :
432 : character(len=*),parameter :: subname='(sklbio)'
433 :
434 0 : flux_bion (:) = c0
435 0 : upNOn (:) = c0
436 0 : upNHn (:) = c0
437 0 : grow_alg (:) = c0
438 :
439 : call skl_biogeochemistry (dt, &
440 : n_doc, & ! LCOV_EXCL_LINE
441 : n_dic, n_don, & ! LCOV_EXCL_LINE
442 : n_fed, n_fep, & ! LCOV_EXCL_LINE
443 : nbtrcr, n_algae, & ! LCOV_EXCL_LINE
444 : flux_bion, ocean_bio, & ! LCOV_EXCL_LINE
445 : ! hmix, aicen, & ! LCOV_EXCL_LINE
446 : meltb, congel, & ! LCOV_EXCL_LINE
447 : fswthru, first_ice, & ! LCOV_EXCL_LINE
448 : trcrn, upNOn, & ! LCOV_EXCL_LINE
449 0 : upNHn, grow_alg)
450 0 : if (icepack_warnings_aborted(subname)) return
451 :
452 : call merge_bgc_fluxes_skl (nbtrcr, n_algae, &
453 : aicen, trcrn, & ! LCOV_EXCL_LINE
454 : flux_bion, flux_bio, & ! LCOV_EXCL_LINE
455 : PP_net, upNOn, & ! LCOV_EXCL_LINE
456 : upNHn, upNO, & ! LCOV_EXCL_LINE
457 : upNH, grow_net, & ! LCOV_EXCL_LINE
458 0 : grow_alg)
459 0 : if (icepack_warnings_aborted(subname)) return
460 :
461 : end subroutine sklbio
462 :
463 : !=======================================================================
464 : !
465 : ! skeletal layer biochemistry
466 : !
467 0 : subroutine skl_biogeochemistry (dt, &
468 : n_doc, & ! LCOV_EXCL_LINE
469 : n_dic, n_don, & ! LCOV_EXCL_LINE
470 : n_fed, n_fep, & ! LCOV_EXCL_LINE
471 : nbtrcr, n_algae, & ! LCOV_EXCL_LINE
472 : flux_bio, ocean_bio, & ! LCOV_EXCL_LINE
473 : ! hmix, aicen, & ! LCOV_EXCL_LINE
474 : meltb, congel, & ! LCOV_EXCL_LINE
475 : fswthru, first_ice, & ! LCOV_EXCL_LINE
476 : trcrn, upNOn, & ! LCOV_EXCL_LINE
477 0 : upNHn, grow_alg_skl)
478 :
479 : integer (kind=int_kind), intent(in) :: &
480 : n_doc, n_dic, n_don, n_fed, n_fep, & ! LCOV_EXCL_LINE
481 : nbtrcr , n_algae ! number of bgc tracers and number algae
482 :
483 : real (kind=dbl_kind), intent(in) :: &
484 : dt , & ! time step ! LCOV_EXCL_LINE
485 : ! hmix , & ! mixed layer depth ! LCOV_EXCL_LINE
486 : ! aicen , & ! ice area ! LCOV_EXCL_LINE
487 : meltb , & ! bottom ice melt ! LCOV_EXCL_LINE
488 : congel , & ! bottom ice growth ! LCOV_EXCL_LINE
489 : fswthru ! shortwave passing through ice to ocean
490 :
491 : logical (kind=log_kind), intent(in) :: &
492 : first_ice ! initialized values should be used
493 :
494 : real (kind=dbl_kind), dimension(:), intent(inout) :: &
495 : trcrn ! bulk concentration per m^3
496 :
497 : ! history variables
498 :
499 : real (kind=dbl_kind), dimension (:), intent(out) :: &
500 : flux_bio ! ocean tracer flux (mmol/m^2/s) positive into ocean
501 :
502 : real (kind=dbl_kind), dimension (:), intent(in) :: &
503 : ocean_bio ! ocean tracer concentration (mmol/m^3)
504 :
505 : real (kind=dbl_kind), dimension (:), intent(out) :: &
506 : grow_alg_skl, & ! tot algal growth rate (mmol/m^3/s) ! LCOV_EXCL_LINE
507 : upNOn , & ! algal NO uptake rate (mmol/m^3/s) ! LCOV_EXCL_LINE
508 : upNHn ! algal NH uptake rate (mmol/m^3/s)
509 :
510 : ! local variables
511 :
512 : integer (kind=int_kind) :: nn
513 :
514 : real (kind=dbl_kind), dimension(nbtrcr):: &
515 : react , & ! biological sources and sinks (mmol/m^3) ! LCOV_EXCL_LINE
516 : cinit , & ! initial brine concentration*sk_l (mmol/m^2) ! LCOV_EXCL_LINE
517 : cinit_v , & ! initial brine concentration (mmol/m^3) ! LCOV_EXCL_LINE
518 : congel_alg , & ! congelation flux contribution to ice algae (mmol/m^2 s) ! LCOV_EXCL_LINE
519 : ! (used as initialization)
520 0 : f_meltn , & ! vertical melt fraction of skeletal layer in dt
521 : flux_bio_temp, & ! tracer flux to ocean (mmol/m^2 s) ! LCOV_EXCL_LINE
522 : PVflag , & ! 1 for tracers that flow with the brine, 0 otherwise ! LCOV_EXCL_LINE
523 0 : cling ! 1 for tracers that cling, 0 otherwise
524 :
525 : real (kind=dbl_kind) :: &
526 : Zoo_skl , & ! N losses from zooplankton/bacteria ... (mmol/m^3) ! LCOV_EXCL_LINE
527 : iTin , & ! LCOV_EXCL_LINE
528 : PVt , & ! type 'Jin2006' piston velocity (m/s) ! LCOV_EXCL_LINE
529 : ice_growth , & ! Jin2006 definition: either congel rate or bottom melt rate (m/s) ! LCOV_EXCL_LINE
530 : grow_val , & ! (m/x) ! LCOV_EXCL_LINE
531 : rphi_sk , & ! 1 / skeletal layer porosity ! LCOV_EXCL_LINE
532 : cinit_tmp , & ! temporary variable for concentration (mmol/m^2) ! LCOV_EXCL_LINE
533 0 : Nerror ! change in total nitrogen from reactions
534 :
535 : real (kind=dbl_kind), parameter :: &
536 : PVc = 1.e-6_dbl_kind , & ! type 'constant' piston velocity for interface (m/s) ! LCOV_EXCL_LINE
537 : PV_scale_growth = p5 , & ! scale factor in Jin code PV during ice growth ! LCOV_EXCL_LINE
538 : PV_scale_melt = p05 , & ! scale factor in Jin code PV during ice melt ! LCOV_EXCL_LINE
539 : growth_max = 1.85e-5_dbl_kind , & ! PVt function reaches maximum here. (m/s) ! LCOV_EXCL_LINE
540 : Tin_bot = -1.8_dbl_kind , & ! temperature of the ice bottom (oC) ! LCOV_EXCL_LINE
541 : MJ1 = 9.667e-9_dbl_kind , & ! (m/s) coefficients in Jin2008 ! LCOV_EXCL_LINE
542 : MJ2 = 38.8_dbl_kind , & ! (1) from:4.49e-4_dbl_kind*secday ! LCOV_EXCL_LINE
543 : MJ3 = 1.04e7_dbl_kind , & ! 1/(m/s) from: 1.39e-3_dbl_kind*secday^2 ! LCOV_EXCL_LINE
544 : PV_frac_max = 0.9_dbl_kind ! Maximum Piston velocity is 90% of skeletal layer/dt
545 :
546 : logical (kind=log_kind) :: conserve_N
547 :
548 : character(len=*),parameter :: subname='(skl_biogeochemistry)'
549 :
550 : !-----------------------------------------------------------------
551 : ! Initialize
552 : !-----------------------------------------------------------------
553 :
554 0 : conserve_N = .true.
555 0 : Zoo_skl = c0
556 0 : rphi_sk = c1/phi_sk
557 0 : PVt = c0
558 0 : iTin = Tin_bot
559 :
560 0 : do nn = 1, nbtrcr
561 0 : cinit (nn) = c0
562 0 : cinit_v (nn) = c0
563 0 : congel_alg(nn) = c0
564 0 : f_meltn (nn) = c0
565 0 : react (nn) = c0
566 0 : PVflag (nn) = c1
567 0 : cling (nn) = c0
568 :
569 : !-----------------------------------------------------------------
570 : ! only the dominant tracer_type affects behavior
571 : ! < 0 is purely mobile: > 0 stationary behavior
572 : ! NOTE: retention times are not used in skl model
573 : !-----------------------------------------------------------------
574 :
575 0 : if (bgc_tracer_type(nn) >= c0) then
576 0 : PVflag(nn) = c0
577 0 : cling (nn) = c1
578 : endif
579 :
580 0 : ice_growth = (congel-meltb)/dt
581 0 : if (first_ice) then
582 0 : trcrn(bio_index(nn)) = ocean_bio(nn) ! * sk_l*rphi_sk
583 : endif ! first_ice
584 0 : cinit (nn) = trcrn(bio_index(nn)) * sk_l * rphi_sk
585 0 : cinit_v(nn) = cinit(nn)/sk_l
586 0 : if (cinit(nn) < c0) then
587 0 : write(warnstr,*) subname,'initial sk_bgc < 0, nn,nbtrcr,cinit(nn)', &
588 0 : nn,nbtrcr,cinit(nn)
589 0 : call icepack_warnings_add(warnstr)
590 0 : call icepack_warnings_add(subname//' cinit < c0')
591 0 : call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
592 0 : return
593 : endif
594 : enddo ! nbtrcr
595 :
596 0 : if (icepack_warnings_aborted(subname)) return
597 :
598 0 : if (trim(bgc_flux_type) == 'Jin2006') then
599 :
600 : !-----------------------------------------------------------------
601 : ! 'Jin2006':
602 : ! 1. congel/melt dependent piston velocity (PV) for growth and melt
603 : ! 2. If congel > melt use 'congel'; if melt > congel use 'melt'
604 : ! 3. For algal N, PV for ice growth only provides a seeding concentration
605 : ! 4. Melt affects nutrients and algae in the same manner through PV(melt)
606 : !-----------------------------------------------------------------
607 :
608 0 : if (ice_growth > c0) then ! ice_growth = congel/dt
609 0 : grow_val = min(ice_growth,growth_max)
610 : PVt = -min(abs(PV_scale_growth*(MJ1 + MJ2*grow_val &
611 : - MJ3*grow_val**2)), & ! LCOV_EXCL_LINE
612 0 : PV_frac_max*sk_l/dt)
613 : else ! ice_growth = -meltb/dt
614 : PVt = min(abs(PV_scale_melt *( MJ2*ice_growth &
615 : - MJ3*ice_growth**2)), & ! LCOV_EXCL_LINE
616 0 : PV_frac_max*sk_l/dt)
617 : endif
618 0 : do nn = 1, nbtrcr
619 0 : if (bgc_tracer_type(nn) >= c0) then
620 0 : if (ice_growth < c0) then ! flux from ice to ocean
621 : ! Algae and clinging tracers melt like nutrients
622 0 : f_meltn(nn) = PVt*cinit_v(nn) ! for algae only
623 0 : elseif (ice_growth > c0 .AND. &
624 0 : cinit(nn) < ocean_bio(nn)*sk_l/phi_sk) then
625 : ! Growth only contributes to seeding from ocean
626 0 : congel_alg(nn) = (ocean_bio(nn)*sk_l/phi_sk - cinit(nn))/dt
627 : endif ! PVt > c0
628 : endif
629 : enddo
630 :
631 : else ! bgc_flux_type = 'constant'
632 :
633 : !-----------------------------------------------------------------
634 : ! 'constant':
635 : ! 1. Constant PV for congel > melt
636 : ! 2. For algae, PV for ice growth only provides a seeding concentration
637 : ! 3. Melt loss (f_meltn) affects algae only and is proportional to melt
638 : !-----------------------------------------------------------------
639 :
640 0 : if (ice_growth > c0) PVt = -PVc
641 0 : do nn = 1, nbtrcr
642 0 : if (bgc_tracer_type(nn) >= c0 ) then
643 0 : if (ice_growth >= c0 .AND. cinit_v(nn) < ocean_bio(nn)/phi_sk) then
644 0 : congel_alg(nn) = (ocean_bio(nn)*sk_l/phi_sk - cinit(nn))/dt
645 0 : elseif (ice_growth < c0) then
646 0 : f_meltn(nn) = min(c1, meltb/sk_l)*cinit(nn)/dt
647 : endif
648 : endif
649 : enddo ! nn
650 :
651 : endif ! bgc_flux_type
652 :
653 : !-----------------------------------------------------------------
654 : ! begin building biogeochemistry terms
655 : !-----------------------------------------------------------------
656 :
657 0 : react(:) = c0
658 0 : grow_alg_skl(:) = c0
659 :
660 : call algal_dyn (dt, &
661 : n_doc, n_dic, n_don, n_fed, n_fep, & ! LCOV_EXCL_LINE
662 : dEdd_algae, & ! LCOV_EXCL_LINE
663 : fswthru, react, & ! LCOV_EXCL_LINE
664 : cinit_v, & ! LCOV_EXCL_LINE
665 : grow_alg_skl(:), n_algae, & ! LCOV_EXCL_LINE
666 : iTin, & ! LCOV_EXCL_LINE
667 : upNOn(:), upNHn(:), & ! LCOV_EXCL_LINE
668 : Zoo_skl, & ! LCOV_EXCL_LINE
669 0 : Nerror, conserve_N)
670 0 : if (icepack_warnings_aborted(subname)) return
671 :
672 : !-----------------------------------------------------------------
673 : ! compute new tracer concencentrations
674 : !-----------------------------------------------------------------
675 :
676 0 : do nn = 1, nbtrcr
677 :
678 : !-----------------------------------------------------------------
679 : ! if PVt > 0, ie melt, then ocean_bio term drops out (MJ2006)
680 : ! Combine boundary fluxes
681 : !-----------------------------------------------------------------
682 :
683 0 : PVflag(nn) = SIGN(PVflag(nn),PVt)
684 0 : cinit_tmp = max(c0, cinit_v(nn) + react(nn))
685 0 : flux_bio_temp(nn) = (PVflag(nn)*PVt*cinit_tmp &
686 : - PVflag(nn)*min(c0,PVt)*ocean_bio(nn)) & ! LCOV_EXCL_LINE
687 0 : + f_meltn(nn)*cling(nn) - congel_alg(nn)
688 :
689 0 : if (cinit_tmp*sk_l < flux_bio_temp(nn)*dt) then
690 0 : flux_bio_temp(nn) = cinit_tmp*sk_l/dt*(c1-puny)
691 : endif
692 :
693 0 : cinit(nn) = cinit_tmp*sk_l - flux_bio_temp(nn)*dt
694 0 : flux_bio(nn) = flux_bio(nn) + flux_bio_temp(nn)*phi_sk
695 :
696 : ! Uncomment to update ocean concentration
697 : ! Currently not coupled with ocean biogeochemistry
698 : ! ocean_bio(nn) = ocean_bio(nn) + flux_bio(nn)/hmix*aicen
699 :
700 0 : if (.not. conserve_N) then
701 0 : write(warnstr,*) subname, 'N not conserved in skl_bgc, Nerror:',Nerror
702 0 : call icepack_warnings_add(warnstr)
703 0 : write(warnstr,*) subname, 'sk_bgc < 0 after algal fluxes, nn,cinit,flux_bio',&
704 0 : nn,cinit(nn),flux_bio(nn)
705 0 : call icepack_warnings_add(warnstr)
706 0 : write(warnstr,*) subname, 'cinit_tmp,flux_bio_temp,f_meltn,congel_alg,PVt,PVflag: '
707 0 : call icepack_warnings_add(warnstr)
708 0 : write(warnstr,*) subname, cinit_tmp,flux_bio_temp(nn),f_meltn(nn), &
709 0 : congel_alg(nn),PVt,PVflag(nn)
710 0 : call icepack_warnings_add(warnstr)
711 0 : write(warnstr,*) subname, 'congel, meltb: ',congel,meltb
712 0 : call icepack_warnings_add(warnstr)
713 0 : call icepack_warnings_add(subname//' N not conserved in skl_bgc')
714 0 : call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
715 0 : elseif (cinit(nn) < c0) then
716 0 : write(warnstr,*) subname, 'sk_bgc < 0 after algal fluxes, nn,cinit,flux_bio',&
717 0 : nn,cinit(nn),flux_bio(nn)
718 0 : call icepack_warnings_add(warnstr)
719 0 : write(warnstr,*) subname, 'cinit_tmp,flux_bio_temp,f_meltn,congel_alg,PVt,PVflag: '
720 0 : call icepack_warnings_add(warnstr)
721 0 : write(warnstr,*) subname, cinit_tmp,flux_bio_temp(nn),f_meltn(nn), &
722 0 : congel_alg(nn),PVt,PVflag(nn)
723 0 : call icepack_warnings_add(warnstr)
724 0 : write(warnstr,*) subname, 'congel, meltb: ',congel,meltb
725 0 : call icepack_warnings_add(warnstr)
726 0 : call icepack_warnings_add(subname//'sk_bgc < 0 after algal fluxes')
727 0 : call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
728 : endif
729 :
730 0 : if (icepack_warnings_aborted(subname)) return
731 :
732 : !-----------------------------------------------------------------
733 : ! reload tracer array: Bulk tracer concentration (mmol or mg per m^3)
734 : !-----------------------------------------------------------------
735 :
736 0 : trcrn(bio_index(nn)) = cinit(nn) * phi_sk/sk_l
737 :
738 : enddo !nbtrcr
739 :
740 : end subroutine skl_biogeochemistry
741 :
742 : !=======================================================================
743 : !
744 : ! Solve the scalar vertical diffusion equation implicitly using
745 : ! tridiag_solver. Calculate the diffusivity from temperature and salinity.
746 : !
747 : ! NOTE: In this subroutine, trcrn(nt_fbri) is the volume fraction of ice with
748 : ! dynamic salinity or the height ratio == hinS/vicen*aicen, where hinS is the
749 : ! height of the brine surface relative to the bottom of the ice. This volume fraction
750 : ! may be > 1 in which case there is brine above the ice surface (meltponds).
751 : !
752 :
753 0 : subroutine z_biogeochemistry (n_cat, dt, &
754 : nilyr, & ! LCOV_EXCL_LINE
755 : nblyr, nbtrcr, & ! LCOV_EXCL_LINE
756 : n_algae, n_doc, & ! LCOV_EXCL_LINE
757 : n_dic, n_don, & ! LCOV_EXCL_LINE
758 : n_fed, n_fep, & ! LCOV_EXCL_LINE
759 : n_zaero, first_ice, & ! LCOV_EXCL_LINE
760 : aicen, vicen, & ! LCOV_EXCL_LINE
761 : hice_old, ocean_bio, & ! LCOV_EXCL_LINE
762 : flux_bio, bphin, & ! LCOV_EXCL_LINE
763 : iphin, trcrn, & ! LCOV_EXCL_LINE
764 : iDin, & ! LCOV_EXCL_LINE
765 : fswthrul, grow_alg, & ! LCOV_EXCL_LINE
766 : upNOn, upNHn, & ! LCOV_EXCL_LINE
767 : dh_top, dh_bot, & ! LCOV_EXCL_LINE
768 : zfswin, hbri, & ! LCOV_EXCL_LINE
769 : hbri_old, darcy_V, & ! LCOV_EXCL_LINE
770 : ! darcy_V_chl, bgrid, & ! LCOV_EXCL_LINE
771 : bgrid, & ! LCOV_EXCL_LINE
772 : i_grid, ic_grid, & ! LCOV_EXCL_LINE
773 : bphi_min, zbgc_snow, & ! LCOV_EXCL_LINE
774 : zbgc_atm, & ! LCOV_EXCL_LINE
775 : iTin, dh_direct, & ! LCOV_EXCL_LINE
776 : Zoo, meltb, & ! LCOV_EXCL_LINE
777 : congel )
778 :
779 : integer (kind=int_kind), intent(in) :: &
780 : n_cat, & ! category number ! LCOV_EXCL_LINE
781 : nilyr, & ! number of ice layers ! LCOV_EXCL_LINE
782 : nblyr, & ! number of bio layers ! LCOV_EXCL_LINE
783 : nbtrcr, n_algae, & ! number of bgc tracers, number of autotrophs ! LCOV_EXCL_LINE
784 : n_zaero, & ! number of aerosols ! LCOV_EXCL_LINE
785 : n_doc, n_dic, n_don, n_fed, n_fep
786 :
787 : logical (kind=log_kind), intent(in) :: &
788 : first_ice ! initialized values should be used
789 :
790 : real (kind=dbl_kind), intent(in) :: &
791 : dt , & ! time step ! LCOV_EXCL_LINE
792 : hbri , & ! brine height (m) ! LCOV_EXCL_LINE
793 : bphi_min , & ! surface porosity ! LCOV_EXCL_LINE
794 : aicen , & ! concentration of ice ! LCOV_EXCL_LINE
795 : vicen , & ! volume per unit area of ice (m) ! LCOV_EXCL_LINE
796 : hice_old , & ! ice height (m) ! LCOV_EXCL_LINE
797 : meltb , & ! bottom melt in dt (m) ! LCOV_EXCL_LINE
798 : congel , & ! bottom growth in dt (m) ! LCOV_EXCL_LINE
799 : darcy_V , & ! darcy velocity ! LCOV_EXCL_LINE
800 : ! darcy_V_chl, & ! darcy velocity for algae ! LCOV_EXCL_LINE
801 : dh_bot , & ! change in brine bottom (m) ! LCOV_EXCL_LINE
802 : dh_top , & ! change in brine top (m) ! LCOV_EXCL_LINE
803 : dh_direct ! surface flooding or runoff (m)
804 :
805 : real (kind=dbl_kind), dimension (:), intent(inout) :: &
806 : bgrid , & ! biology nondimensional vertical grid points ! LCOV_EXCL_LINE
807 : flux_bio , & ! total ocean tracer flux (mmol/m^2/s) ! LCOV_EXCL_LINE
808 : zfswin , & ! visible Short wave flux on igrid (W/m^2) ! LCOV_EXCL_LINE
809 : Zoo , & ! N losses to the system from reaction terms ! LCOV_EXCL_LINE
810 : ! (ie. zooplankton/bacteria) (mmol/m^3)
811 : trcrn ! bulk tracer concentration (mmol/m^3)
812 :
813 : real (kind=dbl_kind), dimension (:), intent(in) :: &
814 : i_grid , & ! biology vertical interface points ! LCOV_EXCL_LINE
815 : iTin , & ! salinity vertical interface points ! LCOV_EXCL_LINE
816 : iphin , & ! Porosity on the igrid ! LCOV_EXCL_LINE
817 : iDin , & ! Diffusivity/h on the igrid (1/s) ! LCOV_EXCL_LINE
818 : ic_grid , & ! CICE interface coordinate ! LCOV_EXCL_LINE
819 : fswthrul , & ! visible short wave radiation on icgrid (W/m^2) ! LCOV_EXCL_LINE
820 : zbgc_snow , & ! tracer input from snow (mmol/m^3*m) ! LCOV_EXCL_LINE
821 : zbgc_atm , & ! tracer input from atm (mmol/m^3 *m) ! LCOV_EXCL_LINE
822 : ocean_bio , & ! ocean concentrations (mmol/m^3) ! LCOV_EXCL_LINE
823 : bphin ! Porosity on the bgrid
824 :
825 : real (kind=dbl_kind), intent(inout) :: &
826 : hbri_old ! brine height (m)
827 :
828 : real (kind=dbl_kind), dimension (:,:), intent(out) :: &
829 : upNOn , & ! algal nitrate uptake rate (mmol/m^3/s) ! LCOV_EXCL_LINE
830 : upNHn , & ! algal ammonium uptake rate (mmol/m^3/s) ! LCOV_EXCL_LINE
831 : grow_alg ! algal growth rate (mmol/m^3/s)
832 :
833 : !-----------------------------------------------------------------------------
834 : ! algae absorption coefficient for 0.5 m thick layer
835 : ! Grenfell (1991): SA = specific absorption coefficient= 0.004 m^2/mg Chla
836 : ! generalizing kalg_bio(k) = SA*\sum R_chl2N(m)*trcrn(i,j,nt_bgc_N(m)+k-1)
837 : ! output kalg on the icgrid
838 : !-----------------------------------------------------------------------------
839 :
840 : ! local variables
841 :
842 : integer (kind=int_kind) :: &
843 : k, m, mm ! vertical biology layer index
844 :
845 : real (kind=dbl_kind) :: &
846 : hin , & ! ice thickness (m) ! LCOV_EXCL_LINE
847 : hin_old , & ! ice thickness before current melt/growth (m) ! LCOV_EXCL_LINE
848 : ice_conc , & ! algal concentration in ice above hin > hinS ! LCOV_EXCL_LINE
849 : sum_old , & ! ! LCOV_EXCL_LINE
850 : sum_new , & ! ! LCOV_EXCL_LINE
851 : sum_tot , & ! ! LCOV_EXCL_LINE
852 : zspace , & ! 1/nblyr ! LCOV_EXCL_LINE
853 : darcyV , & ! ! LCOV_EXCL_LINE
854 : dhtop , & ! ! LCOV_EXCL_LINE
855 : dhbot , & ! ! LCOV_EXCL_LINE
856 0 : dhflood ! >=0 (m) surface flooding from the ocean
857 :
858 : real (kind=dbl_kind), dimension (nblyr+2) :: &
859 0 : bphin_N ! porosity for tracer model has minimum
860 : ! bphin_N >= bphimin
861 :
862 : real (kind=dbl_kind), dimension (nblyr+1) :: &
863 : iphin_N , & ! tracer porosity on the igrid ! LCOV_EXCL_LINE
864 : sbdiagz , & ! sub-diagonal matrix elements ! LCOV_EXCL_LINE
865 : diagz , & ! diagonal matrix elements ! LCOV_EXCL_LINE
866 : spdiagz , & ! super-diagonal matrix elements ! LCOV_EXCL_LINE
867 : rhsz , & ! rhs of tri-diagonal matrix equation ! LCOV_EXCL_LINE
868 : ML_diag , & ! lumped mass matrix ! LCOV_EXCL_LINE
869 : D_spdiag , & ! artificial diffusion matrix ! LCOV_EXCL_LINE
870 : D_sbdiag , & ! artificial diffusion matrix ! LCOV_EXCL_LINE
871 : biomat_low , & ! Low order solution ! LCOV_EXCL_LINE
872 0 : Nerror ! Change in N after reactions
873 :
874 : real (kind=dbl_kind), dimension(nblyr+1,nbtrcr):: &
875 0 : react ! biological sources and sinks for equation matrix
876 :
877 : real (kind=dbl_kind), dimension(nblyr+1,nbtrcr):: &
878 : in_init_cons , & ! Initial bulk concentration*h (mmol/m^2) ! LCOV_EXCL_LINE
879 : biomat_cons , & ! Matrix output of (mmol/m^2) ! LCOV_EXCL_LINE
880 0 : biomat_brine ! brine concentration (mmol/m^3)
881 :
882 : real (kind=dbl_kind), dimension(nbtrcr):: &
883 : C_top, & ! bulk top tracer source: h phi C(meltwater) (mmol/m^2) ! LCOV_EXCL_LINE
884 : C_bot, & ! bulk bottom tracer source: h phi C(ocean) (mmol/m^2) ! LCOV_EXCL_LINE
885 : Source_top, & ! For cons: (+) top tracer source into ice (mmol/m^2/s) ! LCOV_EXCL_LINE
886 : Source_bot, & ! For cons: (+) bottom tracer source into ice (mmol/m^2/s) ! LCOV_EXCL_LINE
887 : Sink_bot, & ! For cons: (+ or -) remaining bottom flux into ice(mmol/m^2/s) ! LCOV_EXCL_LINE
888 : Sink_top, & ! For cons: (+ or -) remaining bottom flux into ice(mmol/m^2/s) ! LCOV_EXCL_LINE
889 : exp_ret, & ! exp dt/retention frequency ! LCOV_EXCL_LINE
890 : exp_rel, & ! exp dt/release frequency ! LCOV_EXCL_LINE
891 : atm_add_cons , & ! zbgc_snow+zbgc_atm (mmol/m^3*m) ! LCOV_EXCL_LINE
892 : dust_Fe , & ! contribution of dust surface flux to dFe (umol/m*3*m) ! LCOV_EXCL_LINE
893 0 : source ! mmol/m^2 surface input from snow/atmosphere
894 :
895 : real (kind=dbl_kind), dimension (ntrcr+2) :: &
896 : trtmp0 , & ! temporary, remapped tracers ! LCOV_EXCL_LINE
897 0 : trtmp ! temporary, remapped tracers
898 :
899 : logical (kind=log_kind), dimension(nblyr+1) :: &
900 0 : conserve_N
901 :
902 : real (kind=dbl_kind), dimension(nblyr+1):: & ! temporary variables for
903 : Diff , & ! diffusivity ! LCOV_EXCL_LINE
904 : initcons , & ! initial concentration ! LCOV_EXCL_LINE
905 : biocons , & ! new concentration ! LCOV_EXCL_LINE
906 : dmobile , & ! ! LCOV_EXCL_LINE
907 : initcons_mobile,&! ! LCOV_EXCL_LINE
908 0 : initcons_stationary
909 :
910 : real (kind=dbl_kind):: &
911 0 : top_conc ! 1% (min_bgc) of surface concentration
912 : ! when hin > hbri: just used in sw calculation
913 :
914 : real (kind=dbl_kind):: &
915 : bio_tmp, & ! temporary variable ! LCOV_EXCL_LINE
916 0 : exp_min ! temporary exp var
917 :
918 : real (kind=dbl_kind):: &
919 : Sat_conc , & ! adsorbing saturation concentration (mmols/m^3) ! LCOV_EXCL_LINE
920 : phi_max , & ! maximum porosity ! LCOV_EXCL_LINE
921 : S_col , & ! surface area of collector (um^2) ! LCOV_EXCL_LINE
922 : P_b , & ! projected area of diatoms (um^2) ! LCOV_EXCL_LINE
923 : V_c , & ! volume of collector (um^3) ! LCOV_EXCL_LINE
924 0 : V_alg ! volume of algae (um^3)
925 :
926 : real (kind=dbl_kind), dimension(nbtrcr) :: &
927 0 : mobile ! c1 if mobile, c0 otherwise
928 :
929 : ! local parameters
930 :
931 : real (kind=dbl_kind), parameter :: &
932 : accuracy = 1.0e-14_dbl_kind, & ! LCOV_EXCL_LINE
933 : r_c = 3.0e3_dbl_kind , & ! ice crystal radius (um) ! LCOV_EXCL_LINE
934 : r_bac= 15.0_dbl_kind , & ! diatom large radius (um) ! LCOV_EXCL_LINE
935 : r_alg= 10.0_dbl_kind , & ! diatom small radius (um) ! LCOV_EXCL_LINE
936 : N_vol = 0.04e-12_dbl_kind , & ! (g) Nitrogen per um^3 ! LCOV_EXCL_LINE
937 : Ng_to_mmol =0.0140067_dbl_kind , & ! (g/mmol) Nitrogen ! LCOV_EXCL_LINE
938 : f_s = c1 , & ! fracton of sites available for saturation ! LCOV_EXCL_LINE
939 : f_a = c1 , & ! fraction of collector available for attachment ! LCOV_EXCL_LINE
940 : f_v = 0.7854 ! fraction of algal coverage on area availabel for attachment
941 : ! 4(pi r^2)/(4r)^2 [Johnson et al, 1995, water res. research]
942 :
943 : integer, parameter :: &
944 : nt_zfswin = 1 ! for interpolation of short wave to bgrid
945 :
946 : character(len=*),parameter :: subname='(z_biogeochemistry)'
947 :
948 : !-------------------------------------
949 : ! Initialize
950 : !-----------------------------------
951 :
952 0 : zspace = c1/real(nblyr,kind=dbl_kind)
953 0 : in_init_cons(:,:) = c0
954 0 : atm_add_cons(:) = c0
955 0 : dhtop = c0
956 0 : dhbot = c0
957 0 : darcyV = c0
958 0 : C_top(:) = c0
959 0 : mobile(:) = c0
960 0 : conserve_N(:) = .true.
961 :
962 0 : do m = 1, nbtrcr
963 0 : do k = 1, nblyr+1
964 :
965 0 : bphin_N(nblyr+2) =c1
966 0 : bphin_N(k) = bphin(k)
967 0 : iphin_N(k) = iphin(k)
968 0 : bphin_N(1) = bphi_min
969 :
970 0 : if (first_ice) then
971 0 : trcrn(bio_index(m) + k-1) = ocean_bio(m)*zbgc_init_frac(m)
972 0 : in_init_cons(k,m) = trcrn(bio_index(m) + k-1)*hbri_old
973 0 : elseif (abs(trcrn(bio_index(m) + k-1)) < puny) then
974 0 : trcrn(bio_index(m) + k-1) = c0
975 0 : in_init_cons(k,m) = c0
976 : else
977 0 : in_init_cons(k,m) = trcrn(bio_index(m) + k-1)* hbri_old
978 : endif ! first_ice
979 :
980 0 : if (trcrn(bio_index(m) + k-1) < c0 ) then
981 0 : write(warnstr,*) subname,'zbgc initialization error, first ice = ', first_ice
982 0 : call icepack_warnings_add(warnstr)
983 0 : write(warnstr,*) subname,'Category,m:',n_cat,m
984 0 : call icepack_warnings_add(warnstr)
985 0 : write(warnstr,*) subname,'hbri,hbri_old'
986 0 : call icepack_warnings_add(warnstr)
987 0 : write(warnstr,*) subname, hbri,hbri_old
988 0 : call icepack_warnings_add(warnstr)
989 0 : write(warnstr,*) subname,'trcrn(bio_index(m) + k-1)'
990 0 : call icepack_warnings_add(warnstr)
991 0 : write(warnstr,*) subname, trcrn(bio_index(m) + k-1)
992 0 : call icepack_warnings_add(warnstr)
993 0 : call icepack_warnings_add(subname//' zbgc initialization error')
994 0 : call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
995 : endif
996 0 : if (icepack_warnings_aborted(subname)) return
997 : enddo !k
998 : enddo !m
999 :
1000 : !-----------------------------------------------------------------
1001 : ! boundary conditions
1002 : !-----------------------------------------------------------------
1003 :
1004 0 : ice_conc = c0
1005 0 : hin = vicen/aicen
1006 0 : hin_old = hice_old
1007 :
1008 : !-----------------------------------------------------------------
1009 : ! calculate the saturation concentration for attachment: Sat_conc
1010 : !-----------------------------------------------------------------
1011 :
1012 0 : phi_max = maxval(bphin_N(2:nblyr+1))
1013 0 : S_col = 4.0_dbl_kind*pi*r_c**2
1014 0 : P_b = pi*r_bac**2 !*10-6 for colloids
1015 0 : V_c = 4.0_dbl_kind*pi*r_c**3/3.0_dbl_kind*(1.0e-6_dbl_kind)**3 ! (m^3) sphere
1016 0 : V_alg = pi/6.0_dbl_kind*r_bac*r_alg**2 ! prolate spheroid (*10-9 for colloids)
1017 0 : Sat_conc= f_s*f_a*f_v*(c1-phi_max)/V_c*S_col/P_b*N_vol*V_alg/Ng_to_mmol
1018 : !mmol/m^3 (algae, don, hum...) and umols/m^3 for colloids
1019 :
1020 : !-----------------------------------------------------------------
1021 : ! convert surface dust flux (n_zaero > 2) to dFe(1) flux
1022 : !-----------------------------------------------------------------
1023 :
1024 0 : dust_Fe(:) = c0
1025 :
1026 0 : if (tr_zaero .and. n_zaero > 2 .and. tr_bgc_Fe) then
1027 0 : do m = 3,n_zaero
1028 0 : dust_Fe(nlt_bgc_Fed(1)) = dust_Fe(nlt_bgc_Fed(1)) + &
1029 : (zbgc_snow(nlt_zaero(m)) + zbgc_atm(nlt_zaero(m))) * & ! LCOV_EXCL_LINE
1030 0 : R_dFe2dust * dustFe_sol
1031 : ! dust_Fe(nlt_zaero(m)) = -(zbgc_snow(nlt_zaero(m)) + zbgc_atm(nlt_zaero(m))) * &
1032 : ! dustFe_sol
1033 : enddo
1034 : endif
1035 :
1036 0 : do m = 1,nbtrcr
1037 : !-----------------------------------------------------------------
1038 : ! time constants for mobile/stationary phase changes
1039 : !-----------------------------------------------------------------
1040 :
1041 0 : exp_rel(m) = c0
1042 0 : exp_ret(m) = c0
1043 0 : if (tau_ret(m) > c0) then
1044 0 : exp_min = min(dt/tau_ret(m),exp_argmax)
1045 0 : exp_ret(m) = exp(-exp_min)
1046 : endif
1047 0 : if (tau_rel(m) > c0) then
1048 0 : exp_min = min(dt/tau_rel(m),exp_argmax)
1049 0 : exp_rel(m) = exp(-exp_min)
1050 : endif
1051 0 : if (m .ne. nlt_bgc_N(1)) then
1052 0 : if (hin_old > hin) then !melting
1053 0 : exp_ret(m) = c1
1054 : else !not melting
1055 0 : exp_rel(m) = c1
1056 : endif
1057 0 : elseif (tr_bgc_N .and. hin_old > hin + algal_vel*dt) then
1058 0 : exp_ret(m) = c1
1059 0 : elseif (tr_bgc_N) then
1060 0 : exp_rel(m) = c1
1061 : endif
1062 :
1063 0 : dhtop = dh_top
1064 0 : dhbot = dh_bot
1065 0 : darcyV = darcy_V
1066 0 : C_top(m) = in_init_cons(1,m)*trcrn(nt_zbgc_frac+m-1)!mobile fraction
1067 0 : source(m) = abs(zbgc_snow(m) + zbgc_atm(m) + dust_Fe(m))
1068 0 : dhflood = max(c0,-dh_direct) ! ocean water flooding surface
1069 :
1070 0 : if (dhtop+darcyV/bphin_N(1)*dt < -puny) then !snow/top ice melt
1071 0 : C_top(m) = (zbgc_snow(m)+zbgc_atm(m) + dust_Fe(m))/abs(dhtop &
1072 0 : + darcyV/bphin_N(1)*dt + puny)*hbri_old
1073 0 : elseif (dhtop+darcyV/bphin_N(1)*dt >= -puny .and. &
1074 : abs((zbgc_snow(m)+zbgc_atm(m) + dust_Fe(m)) + & ! LCOV_EXCL_LINE
1075 0 : ocean_bio(m)*bphin_N(1)*dhflood) > puny) then
1076 0 : atm_add_cons(m) = abs(zbgc_snow(m) + zbgc_atm(m)+ dust_Fe(m)) + &
1077 0 : ocean_bio(m)*bphin_N(1)*dhflood
1078 : else ! only positive fluxes
1079 0 : atm_add_cons(m) = abs(zbgc_snow(m) + zbgc_atm(m)+ dust_Fe(m))
1080 : endif
1081 :
1082 0 : C_bot(m) = ocean_bio(m)*hbri_old*iphin_N(nblyr+1)
1083 :
1084 : enddo ! m
1085 :
1086 : !-----------------------------------------------------------------
1087 : ! Interpolate shortwave flux, fswthrul (defined at top to bottom with nilyr+1
1088 : ! evenly spaced with spacing = (1/nilyr) to grid variable zfswin:
1089 : !-----------------------------------------------------------------
1090 :
1091 0 : trtmp(:) = c0
1092 0 : trtmp0(:)= c0
1093 0 : zfswin(:) = c0
1094 :
1095 0 : do k = 1, nilyr+1
1096 : ! contains cice values (fswthrul(1) is surface value)
1097 : ! and fwsthrul(nilyr+1) is output
1098 0 : trtmp0(nt_zfswin+k-1) = fswthrul(k)
1099 : enddo !k
1100 :
1101 : call remap_zbgc(nilyr+1, &
1102 : nt_zfswin, & ! LCOV_EXCL_LINE
1103 : trtmp0(1:ntrcr), trtmp(1:ntrcr+2), & ! LCOV_EXCL_LINE
1104 : 0, nblyr+1, & ! LCOV_EXCL_LINE
1105 : hin, hbri, & ! LCOV_EXCL_LINE
1106 : ic_grid(1:nilyr+1), & ! LCOV_EXCL_LINE
1107 0 : i_grid(1:nblyr+1),ice_conc )
1108 :
1109 0 : if (icepack_warnings_aborted(subname)) return
1110 :
1111 0 : do k = 1,nblyr+1
1112 0 : zfswin(k) = trtmp(nt_zfswin+k-1)
1113 : enddo
1114 :
1115 : !-----------------------------------------------------------------
1116 : ! Initialze Biology
1117 : !-----------------------------------------------------------------
1118 :
1119 0 : do mm = 1, nbtrcr
1120 0 : mobile(mm) = c0
1121 0 : if (bgc_tracer_type(mm) .GE. c0) mobile(mm) = c1
1122 :
1123 0 : do k = 1, nblyr+1
1124 0 : biomat_cons(k,mm) = in_init_cons(k,mm)
1125 : enddo !k
1126 : enddo !mm
1127 :
1128 : !-----------------------------------------------------------------
1129 : ! Compute FCT
1130 : !-----------------------------------------------------------------
1131 :
1132 0 : do mm = 1, nbtrcr
1133 :
1134 0 : if (hbri_old > thinS .and. hbri > thinS) then
1135 0 : do k = 1,nblyr+1
1136 0 : initcons_mobile(k) = in_init_cons(k,mm)*trcrn(nt_zbgc_frac+mm-1)
1137 0 : initcons_stationary(k) = mobile(mm)*(in_init_cons(k,mm)-initcons_mobile(k))
1138 0 : dmobile(k) = mobile(mm)*(initcons_mobile(k)*(exp_ret(mm)-c1) + &
1139 0 : initcons_stationary(k)*(c1-exp_rel(mm)))
1140 0 : initcons_mobile(k) = max(c0,initcons_mobile(k) + dmobile(k))
1141 0 : initcons_stationary(k) = max(c0,initcons_stationary(k) - dmobile(k))
1142 0 : if (initcons_stationary(k)/hbri_old > Sat_conc) then
1143 0 : initcons_mobile(k) = initcons_mobile(k) + initcons_stationary(k) - Sat_conc*hbri_old
1144 0 : initcons_stationary(k) = Sat_conc*hbri_old
1145 : endif
1146 :
1147 0 : Diff(k) = iDin(k)
1148 0 : initcons(k) = initcons_mobile(k)
1149 0 : biocons(k) = initcons_mobile(k)
1150 : enddo
1151 :
1152 : call compute_FCT_matrix &
1153 : (initcons,sbdiagz, dt, nblyr, & ! LCOV_EXCL_LINE
1154 : diagz, spdiagz, rhsz, bgrid, & ! LCOV_EXCL_LINE
1155 : darcyV, dhtop, & ! LCOV_EXCL_LINE
1156 : dhbot, iphin_N, & ! LCOV_EXCL_LINE
1157 : Diff, hbri_old, & ! LCOV_EXCL_LINE
1158 : atm_add_cons(mm), bphin_N, & ! LCOV_EXCL_LINE
1159 : C_top(mm), C_bot(mm), & ! LCOV_EXCL_LINE
1160 : Source_bot(mm), Source_top(mm),& ! LCOV_EXCL_LINE
1161 : Sink_bot(mm),Sink_top(mm), & ! LCOV_EXCL_LINE
1162 0 : D_sbdiag, D_spdiag, ML_diag)
1163 0 : if (icepack_warnings_aborted(subname)) return
1164 :
1165 : call tridiag_solverz &
1166 : (nblyr+1, sbdiagz, & ! LCOV_EXCL_LINE
1167 : diagz, spdiagz, & ! LCOV_EXCL_LINE
1168 0 : rhsz, biocons)
1169 0 : if (icepack_warnings_aborted(subname)) return
1170 :
1171 : call check_conservation_FCT &
1172 : (initcons, & ! LCOV_EXCL_LINE
1173 : biocons, & ! LCOV_EXCL_LINE
1174 : biomat_low, & ! LCOV_EXCL_LINE
1175 : Source_top(mm), & ! LCOV_EXCL_LINE
1176 : Source_bot(mm), & ! LCOV_EXCL_LINE
1177 : Sink_bot(mm), & ! LCOV_EXCL_LINE
1178 : Sink_top(mm), & ! LCOV_EXCL_LINE
1179 : dt, flux_bio(mm), & ! LCOV_EXCL_LINE
1180 : nblyr, & ! LCOV_EXCL_LINE
1181 0 : source(mm))
1182 0 : if (icepack_warnings_aborted(subname)) return
1183 :
1184 : call compute_FCT_corr &
1185 : (initcons, & ! LCOV_EXCL_LINE
1186 : biocons, dt, nblyr, & ! LCOV_EXCL_LINE
1187 0 : D_sbdiag, D_spdiag, ML_diag)
1188 0 : if (icepack_warnings_aborted(subname)) return
1189 :
1190 0 : top_conc = c0 ! or frazil ice concentration
1191 :
1192 : ! assume diatoms actively maintain there relative position in the ice
1193 :
1194 0 : if (mm .ne. nlt_bgc_N(1)) then
1195 :
1196 : call regrid_stationary &
1197 : (initcons_stationary, hbri_old, & ! LCOV_EXCL_LINE
1198 : hbri, dt, & ! LCOV_EXCL_LINE
1199 : ntrcr, & ! LCOV_EXCL_LINE
1200 : nblyr, top_conc, & ! LCOV_EXCL_LINE
1201 : i_grid, flux_bio(mm),& ! LCOV_EXCL_LINE
1202 0 : meltb, congel)
1203 0 : if (icepack_warnings_aborted(subname)) return
1204 :
1205 0 : elseif (tr_bgc_N .and. mm .eq. nlt_bgc_N(1)) then
1206 0 : if (meltb > algal_vel*dt .or. aicen < 0.001_dbl_kind) then
1207 :
1208 : call regrid_stationary &
1209 : (initcons_stationary, hbri_old, & ! LCOV_EXCL_LINE
1210 : hbri, dt, & ! LCOV_EXCL_LINE
1211 : ntrcr, & ! LCOV_EXCL_LINE
1212 : nblyr, top_conc, & ! LCOV_EXCL_LINE
1213 : i_grid, flux_bio(mm),& ! LCOV_EXCL_LINE
1214 0 : meltb, congel)
1215 0 : if (icepack_warnings_aborted(subname)) return
1216 :
1217 : endif
1218 : endif
1219 :
1220 0 : biomat_cons(:,mm) = biocons(:) + initcons_stationary(:)
1221 :
1222 0 : sum_old = (biomat_low(1) + biomat_low(nblyr+1))*zspace/c2
1223 0 : sum_new = (biocons(1)+ biocons(nblyr+1))*zspace/c2
1224 0 : sum_tot = (biomat_cons(1,mm) + biomat_cons(nblyr+1,mm))*zspace/c2
1225 0 : do k = 2,nblyr
1226 0 : sum_old = sum_old + biomat_low(k)*zspace
1227 0 : sum_new = sum_new + biocons(k)*zspace
1228 0 : sum_tot = sum_tot + biomat_cons(k,mm)*zspace
1229 : enddo
1230 0 : trcrn(nt_zbgc_frac+mm-1) = zbgc_frac_init(mm)
1231 0 : if (sum_tot > c0 .and. mobile(mm) > c0) trcrn(nt_zbgc_frac+mm-1) = sum_new/sum_tot
1232 :
1233 : if (abs(sum_new-sum_old) > accuracy*sum_old .or. &
1234 : minval(biocons(:)) < c0 .or. minval(initcons_stationary(:)) < c0 & ! LCOV_EXCL_LINE
1235 0 : .or. icepack_warnings_aborted()) then
1236 0 : write(warnstr,*) subname,'zbgc FCT tracer solution failed'
1237 0 : call icepack_warnings_add(warnstr)
1238 0 : write(warnstr,*) subname,'sum_new,sum_old:',sum_new,sum_old
1239 0 : call icepack_warnings_add(warnstr)
1240 0 : write(warnstr,*) subname,'mm,biocons(:):',mm,biocons(:)
1241 0 : call icepack_warnings_add(warnstr)
1242 0 : write(warnstr,*) subname,'biomat_low:',biomat_low
1243 0 : call icepack_warnings_add(warnstr)
1244 0 : write(warnstr,*) subname,'Diff(:):',Diff(:)
1245 0 : call icepack_warnings_add(warnstr)
1246 0 : write(warnstr,*) subname,'dmobile(:):',dmobile(:)
1247 0 : call icepack_warnings_add(warnstr)
1248 0 : write(warnstr,*) subname,'mobile(mm):',mobile(mm)
1249 0 : call icepack_warnings_add(warnstr)
1250 0 : write(warnstr,*) subname,'initcons_stationary(:):',initcons_stationary(:)
1251 0 : call icepack_warnings_add(warnstr)
1252 0 : write(warnstr,*) subname, 'trcrn(nt_zbgc_frac+mm-1):',trcrn(nt_zbgc_frac+mm-1)
1253 0 : call icepack_warnings_add(warnstr)
1254 0 : write(warnstr,*) subname, 'in_init_cons(:,mm):',in_init_cons(:,mm)
1255 0 : call icepack_warnings_add(warnstr)
1256 0 : write(warnstr,*) subname, 'exp_ret( mm),exp_rel( mm)',exp_ret( mm),exp_rel( mm)
1257 0 : call icepack_warnings_add(warnstr)
1258 0 : write(warnstr,*) subname,'darcyV,dhtop,dhbot'
1259 0 : call icepack_warnings_add(warnstr)
1260 0 : write(warnstr,*) subname,darcyV,dhtop,dhbot
1261 0 : call icepack_warnings_add(warnstr)
1262 0 : write(warnstr,*) subname,'Category,mm:',n_cat,mm
1263 0 : call icepack_warnings_add(warnstr)
1264 0 : call icepack_warnings_add(subname//'zbgc FCT tracer solution failed')
1265 0 : call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
1266 : endif
1267 0 : if (icepack_warnings_aborted(subname)) return
1268 :
1269 : else
1270 :
1271 0 : call thin_ice_flux(hbri,hbri_old,biomat_cons(:,mm), &
1272 : flux_bio(mm),source(mm), & ! LCOV_EXCL_LINE
1273 0 : dt, nblyr,ocean_bio(mm))
1274 0 : if (icepack_warnings_aborted(subname)) return
1275 :
1276 : endif ! thin or not
1277 :
1278 0 : do k = 1,nblyr+1
1279 0 : biomat_brine(k,mm) = biomat_cons(k,mm)/hbri/iphin_N(k)
1280 : enddo ! k
1281 : enddo ! mm
1282 :
1283 0 : react(:,:) = c0
1284 0 : grow_alg(:,:) = c0
1285 :
1286 0 : if (solve_zbgc) then
1287 0 : do k = 1, nblyr+1
1288 : call algal_dyn (dt, &
1289 : n_doc, n_dic, n_don, n_fed, n_fep, & ! LCOV_EXCL_LINE
1290 : dEdd_algae, & ! LCOV_EXCL_LINE
1291 : zfswin(k), react(k,:), & ! LCOV_EXCL_LINE
1292 : biomat_brine(k,:), & ! LCOV_EXCL_LINE
1293 : grow_alg(k,:), n_algae, & ! LCOV_EXCL_LINE
1294 : iTin(k), & ! LCOV_EXCL_LINE
1295 : upNOn(k,:), upNHn(k,:), & ! LCOV_EXCL_LINE
1296 : Zoo(k), & ! LCOV_EXCL_LINE
1297 0 : Nerror(k), conserve_N(k))
1298 0 : if (icepack_warnings_aborted(subname)) return
1299 :
1300 : enddo ! k
1301 : endif ! solve_zbgc
1302 :
1303 : !-----------------------------------------------------------------
1304 : ! Update the tracer variable
1305 : !-----------------------------------------------------------------
1306 :
1307 0 : do m = 1,nbtrcr
1308 0 : do k = 1,nblyr+1 ! back to bulk quantity
1309 0 : bio_tmp = (biomat_brine(k,m) + react(k,m))*iphin_N(k)
1310 :
1311 0 : if (.not. conserve_N(k)) then
1312 0 : write(warnstr,*) subname, 'N in algal_dyn not conserved'
1313 0 : call icepack_warnings_add(warnstr)
1314 0 : write(warnstr,*) subname, 'Nerror(k):', Nerror(k)
1315 0 : call icepack_warnings_add(warnstr)
1316 0 : write(warnstr,*) subname, 'k,m,hbri,hbri_old,bio_tmp,biomat_cons(k,m),ocean_bio(m)'
1317 0 : call icepack_warnings_add(warnstr)
1318 0 : write(warnstr,*) subname, k,m,hbri,hbri_old,bio_tmp,biomat_cons(k,m),ocean_bio(m)
1319 0 : call icepack_warnings_add(warnstr)
1320 0 : write(warnstr,*) subname, 'react(k,m),iphin_N(k),biomat_brine(k,m)'
1321 0 : call icepack_warnings_add(warnstr)
1322 0 : write(warnstr,*) subname, react(k,m),iphin_N(k),biomat_brine(k,m)
1323 0 : call icepack_warnings_add(warnstr)
1324 0 : call icepack_warnings_add(subname//' N in algal_dyn not conserved')
1325 0 : call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
1326 0 : elseif (abs(bio_tmp) < puny) then
1327 0 : bio_tmp = c0
1328 0 : elseif (bio_tmp > 1.0e6_dbl_kind) then
1329 0 : write(warnstr,*) subname, 'very large bgc value'
1330 0 : call icepack_warnings_add(warnstr)
1331 0 : write(warnstr,*) subname, 'k,m,hbri,hbri_old,bio_tmp,biomat_cons(k,m),ocean_bio(m)'
1332 0 : call icepack_warnings_add(warnstr)
1333 0 : write(warnstr,*) subname, k,m,hbri,hbri_old,bio_tmp,biomat_cons(k,m),ocean_bio(m)
1334 0 : call icepack_warnings_add(warnstr)
1335 0 : write(warnstr,*) subname, 'react(k,m),iphin_N(k),biomat_brine(k,m)'
1336 0 : call icepack_warnings_add(warnstr)
1337 0 : write(warnstr,*) subname, react(k,m),iphin_N(k),biomat_brine(k,m)
1338 0 : call icepack_warnings_add(warnstr)
1339 0 : call icepack_warnings_add(subname//' very large bgc value')
1340 0 : call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
1341 0 : elseif (bio_tmp < c0) then
1342 0 : write(warnstr,*) subname, 'negative bgc'
1343 0 : call icepack_warnings_add(warnstr)
1344 0 : write(warnstr,*) subname, 'k,m,nlt_bgc_Nit,hbri,hbri_old'
1345 0 : call icepack_warnings_add(warnstr)
1346 0 : write(warnstr,*) subname, k,m,nlt_bgc_Nit,hbri,hbri_old
1347 0 : call icepack_warnings_add(warnstr)
1348 0 : write(warnstr,*) subname, 'bio_tmp,biomat_cons(k,m),ocean_bio(m)'
1349 0 : call icepack_warnings_add(warnstr)
1350 0 : write(warnstr,*) subname, bio_tmp,biomat_cons(k,m),ocean_bio(m)
1351 0 : call icepack_warnings_add(warnstr)
1352 0 : write(warnstr,*) subname, 'react(k,m),iphin_N(k),biomat_brine(k,m)'
1353 0 : call icepack_warnings_add(warnstr)
1354 0 : write(warnstr,*) subname, react(k,m),iphin_N(k),biomat_brine(k,m)
1355 0 : call icepack_warnings_add(warnstr)
1356 0 : write(warnstr,*) subname, 'exp_ret( m),exp_ret( m)',exp_ret( m),exp_ret( m)
1357 0 : call icepack_warnings_add(warnstr)
1358 0 : call icepack_warnings_add(subname//'negative bgc')
1359 0 : call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
1360 : endif
1361 0 : if (icepack_warnings_aborted()) then
1362 0 : write(warnstr,*) subname, 'trcrn(nt_zbgc_frac+m-1):',trcrn(nt_zbgc_frac+m-1)
1363 0 : call icepack_warnings_add(warnstr)
1364 0 : write(warnstr,*) subname, 'in_init_cons(k,m):',in_init_cons(k,m)
1365 0 : call icepack_warnings_add(warnstr)
1366 0 : write(warnstr,*) subname, 'trcrn(bio_index(m) + k-1)'
1367 0 : call icepack_warnings_add(warnstr)
1368 0 : write(warnstr,*) subname, trcrn(bio_index(m) + k-1)
1369 0 : call icepack_warnings_add(warnstr)
1370 0 : write(warnstr,*) subname, 'Category,m:',n_cat,m
1371 0 : call icepack_warnings_add(warnstr)
1372 0 : return
1373 : endif
1374 0 : trcrn(bio_index(m)+k-1) = max(c0, bio_tmp)
1375 0 : if (ocean_bio(m) .le. c0 .and. flux_bio(m) < c0) then
1376 : ! if (flux_bio(m) < -1.0e-12_dbl_kind) then
1377 : ! write(warnstr,*) subname, 'no ocean_bio but flux_bio < c0'
1378 : ! call icepack_warnings_add(warnstr)
1379 : ! write(warnstr,*) subname, 'm,ocean_bio(m),flux_bio(m)'
1380 : ! call icepack_warnings_add(warnstr)
1381 : ! write(warnstr,*) subname, m,ocean_bio(m),flux_bio(m)
1382 : ! call icepack_warnings_add(warnstr)
1383 : ! write(warnstr,*) subname, 'setting flux_bio(m) = c0'
1384 : ! call icepack_warnings_add(warnstr)
1385 : ! call icepack_warnings_add(subname//' flux_bio < 0 when ocean_bio = 0')
1386 : ! call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
1387 : ! endif
1388 0 : flux_bio(m) = max(c0,flux_bio(m))
1389 : endif
1390 : enddo ! k
1391 : enddo ! m
1392 :
1393 : end subroutine z_biogeochemistry
1394 :
1395 : !=======================================================================
1396 : !
1397 : ! Do biogeochemistry from subroutine algal_dynamics
1398 : ! authors: Scott Elliott, LANL
1399 : ! Nicole Jeffery, LANL
1400 :
1401 0 : subroutine algal_dyn (dt, &
1402 : n_doc, n_dic, n_don, n_fed, n_fep, & ! LCOV_EXCL_LINE
1403 : dEdd_algae, & ! LCOV_EXCL_LINE
1404 : fswthru, reactb, & ! LCOV_EXCL_LINE
1405 : ltrcrn, & ! LCOV_EXCL_LINE
1406 : grow_alg, n_algae, & ! LCOV_EXCL_LINE
1407 : T_bot, & ! LCOV_EXCL_LINE
1408 : upNOn, upNHn, & ! LCOV_EXCL_LINE
1409 : Zoo, & ! LCOV_EXCL_LINE
1410 : Nerror, conserve_N)
1411 :
1412 : integer (kind=int_kind), intent(in) :: &
1413 : n_doc, n_dic, n_don, n_fed, n_fep, & ! LCOV_EXCL_LINE
1414 : n_algae ! number of autotrophic types
1415 :
1416 : real (kind=dbl_kind), intent(in) :: &
1417 : dt , & ! time step ! LCOV_EXCL_LINE
1418 : T_bot , & ! ice temperature (oC) ! LCOV_EXCL_LINE
1419 : fswthru ! average shortwave passing through current ice layer (W/m^2)
1420 :
1421 : real (kind=dbl_kind), intent(inout) :: &
1422 : Zoo, & ! N losses from zooplankton/bacteria... (mmol/m^3) ! LCOV_EXCL_LINE
1423 : Nerror ! Change in N after reactions (mmol/m^3)
1424 :
1425 : real (kind=dbl_kind), dimension (:), intent(out) :: &
1426 : grow_alg,& ! algal growth rate (mmol/m^3/s) ! LCOV_EXCL_LINE
1427 : upNOn, & ! algal NO uptake rate (mmol/m^3/s) ! LCOV_EXCL_LINE
1428 : upNHn ! algal NH uptake rate (mmol/m^3/s)
1429 :
1430 : real (kind=dbl_kind), dimension(:), intent(inout) :: &
1431 : reactb ! biological reaction terms (mmol/m3)
1432 :
1433 : real (kind=dbl_kind), dimension(:), intent(in) :: &
1434 : ltrcrn ! brine concentrations in layer (mmol/m^3)
1435 :
1436 : logical (kind=log_kind), intent(inout) :: &
1437 : conserve_N
1438 :
1439 : logical (kind=log_kind), intent(in) :: &
1440 : dEdd_algae ! .true. chla impact on shortwave computed in dEdd
1441 :
1442 : ! local variables
1443 : !------------------------------------------------------------------------------------
1444 : ! 3 possible autotrophs nt_bgc_N(1:3): diatoms, flagellates, phaeocystis
1445 : ! 2 types of dissolved organic carbon nt_bgc_DOC(1:2):
1446 : ! polysaccharids, lipids
1447 : ! 1 DON (proteins)
1448 : ! 1 particulate iron (nt_bgc_Fe) n_fep
1449 : ! 1 dossp;ved orpm m+fed
1450 : ! Limiting macro/micro nutrients: nt_bgc_Nit -> nitrate, nt_bgc_NH -> ammonium,
1451 : ! nt_bgc_Sil -> silicate, nt_bgc_Fe -> dissolved iron
1452 : ! --------------------------------------------------------------------------------------
1453 :
1454 : ! real (kind=dbl_kind), parameter, dimension(max_algae) :: &
1455 : ! alpha2max_high = (/ 0.25_dbl_kind, 0.25_dbl_kind, 0.25_dbl_kind/) ! light limitation (1/(W/m^2))
1456 :
1457 : integer (kind=int_kind) :: k, n
1458 :
1459 : real (kind=dbl_kind), dimension(n_algae) :: &
1460 : Nin , & ! algal nitrogen concentration on volume (mmol/m^3) ! LCOV_EXCL_LINE
1461 : ! Cin , & ! algal carbon concentration on volume (mmol/m^3) ! LCOV_EXCL_LINE
1462 0 : chlin ! algal chlorophyll concentration on volume (mg/m^3)
1463 :
1464 : real (kind=dbl_kind), dimension(n_doc) :: &
1465 0 : DOCin ! dissolved organic carbon concentration on volume (mmolC/m^3)
1466 :
1467 : ! real (kind=dbl_kind), dimension(n_dic) :: &
1468 : ! DICin ! dissolved inorganic carbon concentration on volume (mmolC/m^3)
1469 :
1470 : real (kind=dbl_kind), dimension(n_don) :: & !proteins
1471 0 : DONin ! dissolved organic nitrogen concentration on volume (mmolN/m^3)
1472 :
1473 : real (kind=dbl_kind), dimension(n_fed) :: & !iron
1474 0 : Fedin ! dissolved iron concentration on volume (umol/m^3)
1475 :
1476 : real (kind=dbl_kind), dimension(n_fep) :: & !iron
1477 0 : Fepin ! algal nitrogen concentration on volume (umol/m^3)
1478 :
1479 : real (kind=dbl_kind) :: &
1480 : Nitin , & ! nitrate concentration on volume (mmol/m^3) ! LCOV_EXCL_LINE
1481 : Amin , & ! ammonia/um concentration on volume (mmol/m^3) ! LCOV_EXCL_LINE
1482 : Silin , & ! silicon concentration on volume (mmol/m^3) ! LCOV_EXCL_LINE
1483 : ! DMSPpin , & ! DMSPp concentration on volume (mmol/m^3) ! LCOV_EXCL_LINE
1484 : DMSPdin , & ! DMSPd concentration on volume (mmol/m^3) ! LCOV_EXCL_LINE
1485 : DMSin , & ! DMS concentration on volume (mmol/m^3) ! LCOV_EXCL_LINE
1486 : ! PONin , & ! PON concentration on volume (mmol/m^3) ! LCOV_EXCL_LINE
1487 : op_dep , & ! bottom layer attenuation exponent (optical depth) ! LCOV_EXCL_LINE
1488 0 : Iavg_loc ! bottom layer attenuated Fswthru (W/m^2)
1489 :
1490 : real (kind=dbl_kind), dimension(n_algae) :: &
1491 : L_lim , & ! overall light limitation ! LCOV_EXCL_LINE
1492 : Nit_lim , & ! overall nitrate limitation ! LCOV_EXCL_LINE
1493 : Am_lim , & ! overall ammonium limitation ! LCOV_EXCL_LINE
1494 : N_lim , & ! overall nitrogen species limitation ! LCOV_EXCL_LINE
1495 : Sil_lim , & ! overall silicon limitation ! LCOV_EXCL_LINE
1496 : Fe_lim , & ! overall iron limitation ! LCOV_EXCL_LINE
1497 : fr_Nit , & ! fraction of local ecological growth as nitrate ! LCOV_EXCL_LINE
1498 : fr_Am , & ! fraction of local ecological growth as ammonia ! LCOV_EXCL_LINE
1499 : growmax_N, & ! maximum growth rate in N currency (mmol/m^3/s) ! LCOV_EXCL_LINE
1500 : grow_N , & ! true growth rate in N currency (mmol/m^3/s) ! LCOV_EXCL_LINE
1501 : ! potU_Nit , & ! potential nitrate uptake (mmol/m^3/s) ! LCOV_EXCL_LINE
1502 : potU_Am , & ! potential ammonium uptake (mmol/m^3/s) ! LCOV_EXCL_LINE
1503 : U_Nit , & ! actual nitrate uptake (mmol/m^3/s) ! LCOV_EXCL_LINE
1504 : U_Am , & ! actual ammonium uptake (mmol/m^3/s) ! LCOV_EXCL_LINE
1505 : U_Sil , & ! actual silicon uptake (mmol/m^3/s) ! LCOV_EXCL_LINE
1506 : U_Fe , & ! actual iron uptake (umol/m^3/s) ! LCOV_EXCL_LINE
1507 : U_Nit_f , & ! fraction of Nit uptake due to each algal species ! LCOV_EXCL_LINE
1508 : U_Am_f , & ! fraction of Am uptake due to each algal species ! LCOV_EXCL_LINE
1509 : U_Sil_f , & ! fraction of Sil uptake due to each algal species ! LCOV_EXCL_LINE
1510 0 : U_Fe_f ! fraction of Fe uptake due to each algal species
1511 :
1512 : real (kind=dbl_kind) :: &
1513 : dTemp , & ! sea ice temperature minus sst (oC) < 0 ! LCOV_EXCL_LINE
1514 : U_Nit_tot , & ! actual nitrate uptake (mmol/m^3/s) ! LCOV_EXCL_LINE
1515 : U_Am_tot , & ! actual ammonium uptake (mmol/m^3/s) ! LCOV_EXCL_LINE
1516 : U_Sil_tot , & ! actual silicon uptake (mmol/m^3/s) ! LCOV_EXCL_LINE
1517 : U_Fe_tot , & ! actual iron uptake (umol/m^3/s) ! LCOV_EXCL_LINE
1518 : nitrif , & ! nitrification (mmol/m^3/s) ! LCOV_EXCL_LINE
1519 : mort_N , & ! total algal mortality (mmol N/m^3) ! LCOV_EXCL_LINE
1520 : mort_C , & ! total algal mortality (mmol C/m^3) ! LCOV_EXCL_LINE
1521 : graze_N , & ! total algae grazed (mmol N/m^3) ! LCOV_EXCL_LINE
1522 : graze_C , & ! total algae grazed (mmol C/m^3) ! LCOV_EXCL_LINE
1523 : exude_C , & ! total carbon exuded by algae (mmol C/m^3) ! LCOV_EXCL_LINE
1524 : resp_N , & ! total N in respiration (mmol N/m^3) ! LCOV_EXCL_LINE
1525 0 : growth_N ! total algal growth (mmol N/m^3)
1526 : ! fr_graze_p , & ! fraction of N grazed that becomes protein
1527 : ! ! (rest is assimilated) < (1-fr_graze_a)
1528 : ! ! and fr_graze_a*fr_graze_e becomes ammonia
1529 : ! fr_mort_p ! fraction of N mortality that becomes protein
1530 : ! ! < (1-fr_mort2min)
1531 :
1532 : real (kind=dbl_kind), dimension(n_algae) :: &
1533 : resp , & ! respiration (mmol/m^3/s) ! LCOV_EXCL_LINE
1534 : graze , & ! grazing (mmol/m^3/s) ! LCOV_EXCL_LINE
1535 0 : mort ! sum of mortality and excretion (mmol/m^3/s)
1536 :
1537 : ! source terms underscore s, removal underscore r
1538 :
1539 : real (kind=dbl_kind), dimension(n_algae) :: &
1540 : N_s , & ! net algal nitrogen sources (mmol/m^3) ! LCOV_EXCL_LINE
1541 0 : N_r ! net algal nitrogen removal (mmol/m^3)
1542 :
1543 : real (kind=dbl_kind), dimension(n_doc) :: &
1544 : DOC_r , & ! net DOC removal (mmol/m^3) ! LCOV_EXCL_LINE
1545 0 : DOC_s ! net DOC sources (mmol/m^3)
1546 :
1547 : real (kind=dbl_kind), dimension(n_don) :: &
1548 : DON_r , & ! net DON removal (mmol/m^3) ! LCOV_EXCL_LINE
1549 0 : DON_s ! net DON sources (mmol/m^3)
1550 :
1551 : real (kind=dbl_kind), dimension(n_fed) :: &
1552 : Fed_r_l , & ! removal due to loss of binding saccharids (nM) ! LCOV_EXCL_LINE
1553 : Fed_r , & ! net Fed removal (nM) ! LCOV_EXCL_LINE
1554 : Fed_s , & ! net Fed sources (nM) ! LCOV_EXCL_LINE
1555 0 : rFed ! ratio of dissolved Fe to tot Fed
1556 :
1557 : real (kind=dbl_kind), dimension(n_fep) :: &
1558 : Fep_r , & ! net Fep removal (nM) ! LCOV_EXCL_LINE
1559 : Fep_s , & ! net Fep sources (nM) ! LCOV_EXCL_LINE
1560 0 : rFep ! ratio of particulate Fe to tot Fep
1561 :
1562 : real (kind=dbl_kind) :: &
1563 : dN , & ! change in N (mmol/m^3) ! LCOV_EXCL_LINE
1564 : ! N_s_p , & ! algal nitrogen photosynthesis (mmol/m^3) ! LCOV_EXCL_LINE
1565 : ! N_r_g , & ! algal nitrogen losses to grazing (mmol/m^3) ! LCOV_EXCL_LINE
1566 : ! N_r_r , & ! algal nitrogen losses to respiration (mmol/m^3) ! LCOV_EXCL_LINE
1567 : ! N_r_mo , & ! algal nitrogen losses to mortality (mmol/m^3) ! LCOV_EXCL_LINE
1568 : Nit_s_n , & ! nitrate from nitrification (mmol/m^3) ! LCOV_EXCL_LINE
1569 : ! Nit_s_r , & ! nitrate from respiration (mmol/m^3) ! LCOV_EXCL_LINE
1570 : Nit_r_p , & ! nitrate uptake by algae (mmol/m^3) ! LCOV_EXCL_LINE
1571 : Nit_s , & ! net nitrate sources (mmol/m^3) ! LCOV_EXCL_LINE
1572 : Nit_r , & ! net nitrate removal (mmol/m^3) ! LCOV_EXCL_LINE
1573 : Am_s_e , & ! ammonium source from excretion (mmol/m^3) ! LCOV_EXCL_LINE
1574 : Am_s_r , & ! ammonium source from respiration (mmol/m^3) ! LCOV_EXCL_LINE
1575 : Am_s_mo , & ! ammonium source from mort/remin (mmol/m^3) ! LCOV_EXCL_LINE
1576 : Am_r_p , & ! ammonium uptake by algae (mmol/m^3) ! LCOV_EXCL_LINE
1577 : Am_s , & ! net ammonium sources (mmol/m^3) ! LCOV_EXCL_LINE
1578 : Am_r , & ! net ammonium removal (mmol/m^3) ! LCOV_EXCL_LINE
1579 : Sil_r_p , & ! silicon uptake by algae (mmol/m^3) ! LCOV_EXCL_LINE
1580 : Sil_r , & ! net silicon removal (mmol/m^3) ! LCOV_EXCL_LINE
1581 0 : Fe_r_p ! iron uptake by algae (nM)
1582 : ! DOC_r_c , & ! net doc removal from bacterial consumption (mmol/m^3)
1583 : ! doc_s_m , & ! protein source due to algal mortality (mmol/m^3) ! LCOV_EXCL_LINE
1584 : ! doc_s_g ! protein source due to grazing (mmol/m^3)
1585 :
1586 : real (kind=dbl_kind) :: &
1587 : DMSPd_s_r , & ! skl dissolved DMSP from respiration (mmol/m^3) ! LCOV_EXCL_LINE
1588 : DMSPd_s_mo, & ! skl dissolved DMSP from MBJ algal mortexc (mmol/m^3) ! LCOV_EXCL_LINE
1589 : DMSPd_r , & ! skl dissolved DMSP conversion (mmol/m^3) DMSPD_sk_r ! LCOV_EXCL_LINE
1590 : DMSPd_s , & ! net skl dissolved DMSP sources (mmol/m^3) ! LCOV_EXCL_LINE
1591 : DMS_s_c , & ! skl DMS source via conversion (mmol/m^3) ! LCOV_EXCL_LINE
1592 : DMS_r_o , & ! skl DMS losses due to oxidation (mmol/m^3) ! LCOV_EXCL_LINE
1593 : DMS_s , & ! net skl DMS sources (mmol/m^3) ! LCOV_EXCL_LINE
1594 : DMS_r , & ! net skl DMS removal (mmol/m^3) ! LCOV_EXCL_LINE
1595 : Fed_tot , & ! total dissolved iron from all sources (nM) ! LCOV_EXCL_LINE
1596 : Fed_tot_r , & ! total dissolved iron losses (nM) ! LCOV_EXCL_LINE
1597 : Fed_tot_s , & ! total dissolved iron sources (nM) ! LCOV_EXCL_LINE
1598 : Fep_tot , & ! total particulate iron from all sources (nM) ! LCOV_EXCL_LINE
1599 : ! Fep_tot_r , & ! total particulate iron losses (nM) ! LCOV_EXCL_LINE
1600 : Fep_tot_s , & ! total particulate iron sources (nM) ! LCOV_EXCL_LINE
1601 : Zoo_s_a , & ! N Losses due to zooplankton assimilation (mmol/m^3) ! LCOV_EXCL_LINE
1602 : Zoo_s_s , & ! N Losses due to grazing spillage (mmol/m^3) ! LCOV_EXCL_LINE
1603 : Zoo_s_m , & ! N Losses due to algal mortality (mmol/m^3) ! LCOV_EXCL_LINE
1604 0 : Zoo_s_b ! N losses due to bacterial recycling of DON (mmol/m^3)
1605 :
1606 : character(len=*),parameter :: subname='(algal_dyn)'
1607 :
1608 : !-----------------------------------------------------------------------
1609 : ! Initialize
1610 : !-----------------------------------------------------------------------
1611 :
1612 0 : conserve_N = .true.
1613 0 : Nin(:) = c0
1614 : ! Cin(:) = c0
1615 0 : chlin(:) = c0
1616 0 : DOCin(:) = c0
1617 : ! DICin(:) = c0
1618 0 : DONin(:) = c0
1619 0 : Fedin(:) = c0
1620 0 : Fepin(:) = c0
1621 0 : Nitin = c0
1622 0 : Amin = c0
1623 0 : Silin = c0
1624 : ! DMSPpin = c0
1625 0 : DMSPdin = c0
1626 0 : DMSin = c0
1627 0 : U_Am_tot = c0
1628 0 : U_Nit_tot = c0
1629 0 : U_Sil_tot = c0
1630 0 : U_Fe_tot = c0
1631 0 : U_Am_f(:) = c0
1632 0 : U_Nit_f(:) = c0
1633 0 : U_Sil_f(:) = c0
1634 0 : U_Fe_f(:) = c0
1635 0 : DOC_s(:) = c0
1636 0 : DOC_r(:) = c0
1637 : ! DOC_r_c = c0
1638 0 : nitrif = c0
1639 0 : mort_N = c0
1640 0 : mort_C = c0
1641 0 : graze_N = c0
1642 0 : graze_C = c0
1643 0 : exude_C = c0
1644 0 : resp_N = c0
1645 0 : growth_N = c0
1646 0 : Nit_r = c0
1647 0 : Am_s = c0
1648 0 : Am_r = c0
1649 0 : Sil_r = c0
1650 0 : Fed_r(:) = c0
1651 0 : Fed_s(:) = c0
1652 0 : Fep_r(:) = c0
1653 0 : Fep_s(:) = c0
1654 0 : DMSPd_s = c0
1655 0 : dTemp = min(T_bot-T_max,c0)
1656 0 : Fed_tot = c0
1657 0 : Fed_tot_r = c0
1658 0 : Fed_tot_s = c0
1659 0 : rFed(:) = c0
1660 0 : Fep_tot = c0
1661 : ! Fep_tot_r = c0
1662 0 : Fep_tot_s = c0
1663 0 : rFep(:) = c0
1664 :
1665 0 : Nitin = ltrcrn(nlt_bgc_Nit)
1666 0 : op_dep = c0
1667 0 : do k = 1, n_algae
1668 0 : Nin(k) = ltrcrn(nlt_bgc_N(k))
1669 0 : chlin(k) = R_chl2N(k)* Nin(k)
1670 0 : op_dep = op_dep + chlabs(k)*chlin(k)
1671 : enddo
1672 0 : if (tr_bgc_C) then
1673 : ! do k = 1, n_algae
1674 : ! Cin(k)= ltrcrn(nlt_bgc_C(k))
1675 : ! enddo
1676 0 : do k = 1, n_doc
1677 0 : DOCin(k)= ltrcrn(nlt_bgc_DOC(k))
1678 : enddo
1679 : ! do k = 1, n_dic
1680 : ! DICin(k)= ltrcrn(nlt_bgc_DIC(k))
1681 : ! enddo
1682 : endif
1683 0 : if (tr_bgc_Am) Amin = ltrcrn(nlt_bgc_Am)
1684 0 : if (tr_bgc_Sil) Silin = ltrcrn(nlt_bgc_Sil)
1685 0 : if (tr_bgc_DMS) then
1686 : ! DMSPpin = ltrcrn(nlt_bgc_DMSPp)
1687 0 : DMSPdin = ltrcrn(nlt_bgc_DMSPd)
1688 0 : DMSin = ltrcrn(nlt_bgc_DMS)
1689 : endif
1690 : ! if (tr_bgc_PON) then
1691 : ! PONin = c0
1692 : ! PONin = ltrcrn(nlt_bgc_PON)
1693 : ! endif
1694 0 : if (tr_bgc_DON) then
1695 0 : do k = 1, n_don
1696 0 : DONin(k) = ltrcrn(nlt_bgc_DON(k))
1697 : enddo
1698 : endif
1699 0 : if (tr_bgc_Fe ) then
1700 0 : do k = 1, n_fed
1701 0 : Fedin(k) = ltrcrn(nlt_bgc_Fed(k))
1702 : enddo
1703 0 : do k = 1, n_fep
1704 0 : Fepin(k) = ltrcrn(nlt_bgc_Fep(k))
1705 : enddo
1706 : endif
1707 :
1708 : !-----------------------------------------------------------------------
1709 : ! Total iron from all pools
1710 : !-----------------------------------------------------------------------
1711 :
1712 0 : do k = 1,n_fed
1713 0 : Fed_tot = Fed_tot + Fedin(k)
1714 : enddo
1715 0 : do k = 1,n_fep
1716 0 : Fep_tot = Fep_tot + Fepin(k)
1717 : enddo
1718 0 : if (Fed_tot > puny) then
1719 0 : do k = 1,n_fed
1720 0 : rFed(k) = Fedin(k)/Fed_tot
1721 : enddo
1722 : endif
1723 0 : if (Fep_tot > puny) then
1724 0 : do k = 1,n_fep
1725 0 : rFep(k) = Fepin(k)/Fep_tot
1726 : enddo
1727 : endif
1728 :
1729 : !-----------------------------------------------------------------------
1730 : ! Light limitation (op_dep) defined above
1731 : !-----------------------------------------------------------------------
1732 :
1733 0 : if (op_dep > op_dep_min .and. .not. dEdd_algae) then
1734 0 : Iavg_loc = fswthru * (c1 - exp(-op_dep)) / op_dep
1735 : else
1736 0 : Iavg_loc = fswthru
1737 : endif
1738 :
1739 0 : do k = 1, n_algae
1740 : ! With light inhibition ! Maybe include light inhibition for diatoms but phaeocystis
1741 0 : L_lim = (c1 - exp(-alpha2max_low(k)*Iavg_loc)) * exp(-beta2max(k)*Iavg_loc)
1742 :
1743 : ! Without light inhibition
1744 : ! L_lim(k) = (c1 - exp(-alpha2max_low(k)*Iavg_loc))
1745 :
1746 : !-----------------------------------------------------------------------
1747 : ! Nutrient limitation
1748 : !-----------------------------------------------------------------------
1749 :
1750 0 : Nit_lim(k) = Nitin/(Nitin + K_Nit(k))
1751 0 : Am_lim(k) = c0
1752 0 : N_lim(k) = Nit_lim(k)
1753 0 : if (tr_bgc_Am) then
1754 0 : Am_lim(k) = Amin/(Amin + K_Am(k))
1755 0 : N_lim(k) = min(c1, Nit_lim(k) + Am_lim(k))
1756 : endif
1757 0 : Sil_lim(k) = c1
1758 0 : if (tr_bgc_Sil .and. K_Sil(k) > c0) Sil_lim(k) = Silin/(Silin + K_Sil(k))
1759 :
1760 : !-----------------------------------------------------------------------
1761 : ! Iron limitation
1762 : !-----------------------------------------------------------------------
1763 :
1764 0 : Fe_lim(k) = c1
1765 0 : if (tr_bgc_Fe .and. K_Fe (k) > c0) Fe_lim (k) = Fed_tot/(Fed_tot + K_Fe(k))
1766 :
1767 : !----------------------------------------------------------------------------
1768 : ! Growth and uptake computed within the bottom layer
1769 : ! Note here per A93 discussions and MBJ model, salinity is a universal
1770 : ! restriction. Comparison with available column nutrients inserted
1771 : ! but in tests had no effect.
1772 : ! Primary production reverts to SE form, see MBJ below and be careful
1773 : !----------------------------------------------------------------------------
1774 :
1775 0 : growmax_N(k) = mu_max(k) / secday * exp(grow_Tdep(k) * dTemp)* Nin(k) *fsal
1776 0 : grow_N(k) = min(L_lim(k), N_lim(k), Sil_lim(k), Fe_lim(k)) * growmax_N(k)
1777 : ! potU_Nit(k) = Nit_lim(k)* growmax_N(k)
1778 0 : potU_Am(k) = Am_lim(k)* growmax_N(k)
1779 0 : U_Am(k) = min(grow_N(k), potU_Am(k))
1780 0 : U_Nit(k) = grow_N(k) - U_Am(k)
1781 0 : U_Sil(k) = R_Si2N(k) * grow_N(k)
1782 0 : U_Fe (k) = R_Fe2N(k) * grow_N(k)
1783 :
1784 0 : U_Am_tot = U_Am_tot + U_Am(k)
1785 0 : U_Nit_tot = U_Nit_tot + U_Nit(k)
1786 0 : U_Sil_tot = U_Sil_tot + U_Sil(k)
1787 0 : U_Fe_tot = U_Fe_tot + U_Fe(k)
1788 : enddo
1789 0 : do k = 1, n_algae
1790 0 : if (U_Am_tot > c0) U_Am_f(k) = U_Am(k)/U_Am_tot
1791 0 : if (U_Nit_tot > c0) U_Nit_f(k) = U_Nit(k)/U_Nit_tot
1792 0 : if (U_Sil_tot > c0) U_Sil_f(k) = U_Sil(k)/U_Sil_tot
1793 0 : if (U_Fe_tot > c0) U_Fe_f(k) = U_Fe(k)/U_Fe_tot
1794 : enddo
1795 :
1796 0 : if (tr_bgc_Sil) U_Sil_tot = min(U_Sil_tot, max_loss * Silin/dt)
1797 0 : if (tr_bgc_Fe) U_Fe_tot = min(U_Fe_tot, max_loss * Fed_tot/dt)
1798 0 : U_Nit_tot = min(U_Nit_tot, max_loss * Nitin/dt)
1799 0 : U_Am_tot = min(U_Am_tot, max_loss * Amin/dt)
1800 :
1801 0 : do k = 1, n_algae
1802 0 : U_Am(k) = U_Am_f(k)*U_Am_tot
1803 0 : U_Nit(k) = U_Nit_f(k)*U_Nit_tot
1804 0 : U_Sil(k) = U_Sil_f(k)*U_Sil_tot
1805 0 : U_Fe(k) = U_Fe_f(k)*U_Fe_tot
1806 :
1807 0 : if (R_Si2N(k) > c0) then
1808 0 : grow_N(k) = min(U_Sil(k)/R_Si2N(k),U_Nit(k) + U_Am(k), U_Fe(k)/R_Fe2N(k))
1809 : else
1810 0 : grow_N(k) = min(U_Nit(k) + U_Am(k),U_Fe(k)/R_Fe2N(k))
1811 : endif
1812 :
1813 0 : fr_Am(k) = c0
1814 0 : if (tr_bgc_Am) then
1815 0 : fr_Am(k) = p5
1816 0 : if (grow_N(k) > c0) fr_Am(k) = min(U_Am(k)/grow_N(k), c1)
1817 : endif
1818 0 : fr_Nit(k) = c1 - fr_Am(k)
1819 0 : U_Nit(k) = fr_Nit(k) * grow_N(k)
1820 0 : U_Am(k) = fr_Am(k) * grow_N(k)
1821 0 : U_Sil(k) = R_Si2N(k) * grow_N(k)
1822 0 : U_Fe (k) = R_Fe2N(k) * grow_N(k)
1823 :
1824 : !-----------------------------------------------------------------------
1825 : ! Define reaction terms
1826 : !-----------------------------------------------------------------------
1827 :
1828 : ! Since the framework remains incomplete at this point,
1829 : ! it is assumed as a starting expedient that
1830 : ! DMSP loss to melting results in 10% conversion to DMS
1831 : ! which is then given a ten day removal constant.
1832 : ! Grazing losses are channeled into rough spillage and assimilation
1833 : ! then following ammonia there is some recycling.
1834 :
1835 : !--------------------------------------------------------------------
1836 : ! Algal reaction term
1837 : ! N_react = (grow_N*(c1 - fr_graze-fr_resp) - mort)*dt
1838 : !--------------------------------------------------------------------
1839 :
1840 0 : resp(k) = fr_resp * grow_N(k)
1841 0 : graze(k) = fr_graze(k) * grow_N(k)
1842 0 : mort(k) = min(max_loss * Nin(k)/dt, &
1843 0 : mort_pre(k)*exp(mort_Tdep(k)*dTemp) * Nin(k)/secday)
1844 :
1845 : ! history variables
1846 0 : grow_alg(k) = grow_N(k)
1847 0 : upNOn(k) = U_Nit(k)
1848 0 : upNHn(k) = U_Am(k)
1849 :
1850 : ! N_s_p = grow_N(k) * dt
1851 : ! N_r_g = graze(k) * dt
1852 : ! N_r_r = resp(k) * dt
1853 : ! N_r_mo = mort(k) * dt
1854 0 : N_s(k) = (c1- fr_resp - fr_graze(k)) * grow_N(k) *dt !N_s_p
1855 0 : N_r(k) = mort(k) * dt !N_r_g + N_r_mo + N_r_r
1856 :
1857 0 : graze_N = graze_N + graze(k)
1858 0 : graze_C = graze_C + R_C2N(k)*graze(k)
1859 0 : mort_N = mort_N + mort(k)
1860 0 : mort_C = mort_C + R_C2N(k)*mort(k)
1861 0 : resp_N = resp_N + resp(k)
1862 0 : growth_N = growth_N + grow_N(k)
1863 :
1864 : enddo ! n_algae
1865 : !--------------------------------------------------------------------
1866 : ! Ammonium source: algal grazing, respiration, and mortality
1867 : !--------------------------------------------------------------------
1868 :
1869 0 : Am_s_e = graze_N*(c1-fr_graze_s)*fr_graze_e*dt
1870 0 : Am_s_mo = mort_N*fr_mort2min*dt
1871 0 : Am_s_r = resp_N*dt
1872 0 : Am_s = Am_s_r + Am_s_e + Am_s_mo
1873 :
1874 : !--------------------------------------------------------------------
1875 : ! Nutrient net loss terms: algal uptake
1876 : !--------------------------------------------------------------------
1877 :
1878 0 : do k = 1, n_algae
1879 0 : Am_r_p = U_Am(k) * dt
1880 0 : Am_r = Am_r + Am_r_p
1881 0 : Nit_r_p = U_Nit(k) * dt
1882 0 : Nit_r = Nit_r + Nit_r_p
1883 0 : Sil_r_p = U_Sil(k) * dt
1884 0 : Sil_r = Sil_r + Sil_r_p
1885 0 : Fe_r_p = U_Fe (k) * dt
1886 0 : Fed_tot_r = Fed_tot_r + Fe_r_p
1887 0 : exude_C = exude_C + k_exude(k)* R_C2N(k)*Nin(k) / secday
1888 : enddo
1889 :
1890 : !--------------------------------------------------------------------
1891 : ! nitrification
1892 : !--------------------------------------------------------------------
1893 :
1894 0 : nitrif = k_nitrif /secday * Amin
1895 0 : Am_r = Am_r + nitrif*dt
1896 0 : Nit_s_n = nitrif * dt ! source from NH4
1897 0 : Nit_s = Nit_s_n
1898 :
1899 : !--------------------------------------------------------------------
1900 : ! PON: currently using PON to shadow nitrate
1901 : !
1902 : ! N Losses are counted in Zoo. These arise from mortality not
1903 : ! remineralized (Zoo_s_m), assimilated grazing not excreted (Zoo_s_a),
1904 : !spilled N not going to DON (Zoo_s_s) and bacterial recycling
1905 : ! of DON (Zoo_s_b).
1906 : !--------------------------------------------------------------------
1907 :
1908 0 : if (tr_bgc_Am) then
1909 0 : Zoo_s_a = graze_N*(c1-fr_graze_e)*(c1-fr_graze_s) *dt
1910 0 : Zoo_s_s = graze_N*fr_graze_s*dt
1911 0 : Zoo_s_m = mort_N*dt - Am_s_mo
1912 : else
1913 0 : Zoo_s_a = graze_N*dt*(c1-fr_graze_s)
1914 0 : Zoo_s_s = graze_N*fr_graze_s*dt
1915 0 : Zoo_s_m = mort_N*dt
1916 : endif
1917 :
1918 0 : Zoo_s_b = c0
1919 :
1920 : !--------------------------------------------------------------------
1921 : ! DON (n_don = 1)
1922 : ! Proteins
1923 : !--------------------------------------------------------------------
1924 :
1925 0 : DON_r(:) = c0
1926 0 : DON_s(:) = c0
1927 :
1928 0 : if (tr_bgc_DON) then
1929 0 : do n = 1, n_don
1930 0 : DON_r(n) = kn_bac(n)/secday * DONin(n) * dt
1931 0 : DON_s(n) = graze_N*f_don(n)*fr_graze_s * dt
1932 0 : Zoo_s_s = Zoo_s_s - DON_s(n)
1933 0 : Zoo_s_b = Zoo_s_b + DON_r(n)*(c1-f_don_Am(n))
1934 : !Am_s = Am_s + DON_r(n)*f_don_Am(n)
1935 : enddo
1936 : endif
1937 :
1938 0 : Zoo = Zoo_s_a + Zoo_s_s + Zoo_s_m + Zoo_s_b
1939 :
1940 : !--------------------------------------------------------------------
1941 : ! DOC
1942 : ! polysaccharids, lipids
1943 : !--------------------------------------------------------------------
1944 :
1945 0 : do n = 1, n_doc
1946 :
1947 0 : DOC_r(n) = k_bac(n)/secday * DOCin(n) * dt
1948 0 : DOC_s(n) = f_doc(n)*(fr_graze_s *graze_C + mort_C)*dt &
1949 0 : + f_exude(n)*exude_C
1950 : enddo
1951 :
1952 : !--------------------------------------------------------------------
1953 : ! Iron sources from remineralization (follows ammonium but reduced)
1954 : ! only Fed_s(1) has remineralized sources
1955 : !--------------------------------------------------------------------
1956 :
1957 0 : Fed_s(1) = Fed_s(1) + Am_s * R_Fe2N(1) * fr_dFe ! remineralization source
1958 :
1959 : !--------------------------------------------------------------------
1960 : ! Conversion to dissolved Fe from Particulate requires DOC(1)
1961 : ! Otherwise the only source of dFe is from remineralization
1962 : !--------------------------------------------------------------------
1963 :
1964 0 : if (tr_bgc_C .and. tr_bgc_Fe) then
1965 0 : if (DOCin(1) > c0) then
1966 0 : if (Fed_tot/DOCin(1) > max_dfe_doc1) then
1967 0 : do n = 1,n_fed ! low saccharid:dFe ratio leads to
1968 0 : Fed_r_l(n) = Fedin(n)/t_iron_conv*dt/secday ! loss of bioavailable Fe to particulate fraction
1969 0 : Fep_tot_s = Fep_tot_s + Fed_r_l(n)
1970 0 : Fed_r(n) = Fed_r_l(n) ! removal due to particulate scavenging
1971 : enddo
1972 0 : do n = 1,n_fep
1973 0 : Fep_s(n) = rFep(n)* Fep_tot_s ! source from dissolved Fe
1974 : enddo
1975 0 : elseif (Fed_tot/DOCin(1) < max_dfe_doc1) then
1976 0 : do n = 1,n_fep ! high saccharid:dFe ratio leads to
1977 0 : Fep_r(n) = Fepin(n)/t_iron_conv*dt/secday ! gain of bioavailable Fe from particulate fraction
1978 0 : Fed_tot_s = Fed_tot_s + Fep_r(n)
1979 : enddo
1980 0 : do n = 1,n_fed
1981 0 : Fed_s(n) = Fed_s(n) + rFed(n)* Fed_tot_s ! source from particulate Fe
1982 : enddo
1983 : endif
1984 : endif !Docin(1) > c0
1985 0 : elseif (tr_bgc_Fe) then
1986 0 : do n = 1,n_fed
1987 0 : Fed_r(n) = Fed_r(n) + rFed(n)*Fed_tot_r ! scavenging + uptake
1988 : enddo
1989 :
1990 : ! source from algal mortality/grazing and fraction of remineralized nitrogen that does
1991 : ! not become immediately bioavailable
1992 :
1993 0 : do n = 1,n_fep
1994 0 : Fep_s(n) = Fep_s(n) + rFep(n)* (Am_s * R_Fe2N(1) * (c1-fr_dFe))
1995 : enddo ! losses not direct to Fed
1996 : endif
1997 :
1998 : !--------------------------------------------------------------------
1999 : ! Sulfur cycle begins here
2000 : !--------------------------------------------------------------------
2001 : ! Grazing losses are channeled into rough spillage and assimilation
2002 : ! then onward and the MBJ mortality channel is included
2003 : ! It is assumed as a starting expedient that
2004 : ! DMSP loss to melting gives partial conversion to DMS in product layer
2005 : ! which then undergoes Stefels removal.
2006 :
2007 : !--------------------------------------------------------------------
2008 : ! DMSPd reaction term (DMSPd conversion is outside the algal loop)
2009 : ! DMSPd_react = R_S2N*((fr_graze_s+fr_excrt_2S*fr_graze_e*fr_graze_a)
2010 : ! *fr_graze*grow_N + fr_mort2min*mort)*dt
2011 : ! - [\DMSPd]/t_sk_conv*dt
2012 : !--------------------------------------------------------------------
2013 0 : do k = 1,n_algae
2014 0 : DMSPd_s_r = fr_resp_s * R_S2N(k) * resp(k) * dt !respiration fraction to DMSPd
2015 0 : DMSPd_s_mo= fr_mort2min * R_S2N(k)* mort(k) * dt !mortality and extracellular excretion
2016 0 : DMSPd_s = DMSPd_s + DMSPd_s_r + DMSPd_s_mo
2017 : enddo
2018 0 : DMSPd_r = (c1/t_sk_conv) * (c1/secday) * (DMSPdin) * dt
2019 :
2020 : !--------------------------------------------------------------------
2021 : ! DMS reaction term + DMSPd loss term
2022 : ! DMS_react = ([\DMSPd]*y_sk_DMS/t_sk_conv - c1/t_sk_ox *[\DMS])*dt
2023 : !--------------------------------------------------------------------
2024 :
2025 0 : DMS_s_c = y_sk_DMS * DMSPd_r
2026 0 : DMS_r_o = DMSin * dt / (t_sk_ox * secday)
2027 0 : DMS_s = DMS_s_c
2028 0 : DMS_r = DMS_r_o
2029 :
2030 : !-----------------------------------------------------------------------
2031 : ! Load reaction array
2032 : !-----------------------------------------------------------------------
2033 :
2034 0 : dN = c0
2035 0 : do k = 1,n_algae
2036 0 : reactb(nlt_bgc_N(k)) = N_s(k) - N_r(k)
2037 0 : dN = dN + reactb(nlt_bgc_N(k))
2038 : enddo
2039 0 : if (tr_bgc_C) then
2040 : ! do k = 1,n_algae
2041 : ! reactb(nlt_bgc_C(k)) = R_C2N(k)*reactb(nlt_bgc_N(k))
2042 : ! enddo
2043 0 : do k = 1,n_doc
2044 0 : reactb(nlt_bgc_DOC(k))= DOC_s(k) - DOC_r(k)
2045 : enddo
2046 : endif
2047 0 : reactb(nlt_bgc_Nit) = Nit_s - Nit_r
2048 0 : dN = dN + reactb(nlt_bgc_Nit)
2049 0 : if (tr_bgc_Am) then
2050 0 : reactb(nlt_bgc_Am) = Am_s - Am_r
2051 0 : dN = dN + reactb(nlt_bgc_Am)
2052 : endif
2053 0 : if (tr_bgc_Sil) then
2054 0 : reactb(nlt_bgc_Sil) = - Sil_r
2055 : endif
2056 0 : if (tr_bgc_DON) then
2057 0 : do k = 1,n_don
2058 0 : reactb(nlt_bgc_DON(k))= DON_s(k) - DON_r(k)
2059 0 : dN = dN + reactb(nlt_bgc_DON(k))
2060 : enddo
2061 : endif
2062 0 : if (tr_bgc_Fe ) then
2063 0 : do k = 1,n_fed
2064 0 : reactb(nlt_bgc_Fed(k))= Fed_s (k) - Fed_r (k)
2065 : enddo
2066 0 : do k = 1,n_fep
2067 0 : reactb(nlt_bgc_Fep(k))= Fep_s (k) - Fep_r (k)
2068 : enddo
2069 : endif
2070 0 : if (tr_bgc_DMS) then
2071 0 : reactb(nlt_bgc_DMSPd) = DMSPd_s - DMSPd_r
2072 0 : reactb(nlt_bgc_DMS) = DMS_s - DMS_r
2073 : endif
2074 0 : Nerror = dN + Zoo
2075 : ! if (abs(Nerror) > max(reactb(:))*1.0e-5) then
2076 : ! conserve_N = .false.
2077 : ! write(warnstr,*) subname, 'Conservation error!'
2078 : ! call icepack_warnings_add(warnstr)
2079 : ! write(warnstr,*) subname, 'Nerror,dN, DONin(1),kn_bac(1),secday,dt,n_doc'
2080 : ! call icepack_warnings_add(warnstr)
2081 : ! write(warnstr,*) subname, Nerror,dN, DONin(1),kn_bac(1),secday,dt,n_doc
2082 : ! call icepack_warnings_add(warnstr)
2083 : ! write(warnstr,*) subname, 'reactb(nlt_bgc_Nit),reactb(nlt_bgc_N(1)),reactb(nlt_bgc_N(2)'
2084 : ! call icepack_warnings_add(warnstr)
2085 : ! write(warnstr,*) subname, reactb(nlt_bgc_Nit),reactb(nlt_bgc_N(1)),reactb(nlt_bgc_N(2))
2086 : ! call icepack_warnings_add(warnstr)
2087 : ! write(warnstr,*) subname, 'reactb(nlt_bgc_Am),reactb(nlt_bgc_DON(1)), DON_r(1),DON_s(1)'
2088 : ! call icepack_warnings_add(warnstr)
2089 : ! write(warnstr,*) subname, reactb(nlt_bgc_Am),reactb(nlt_bgc_DON(1)),DON_r(1),DON_s(1)
2090 : ! call icepack_warnings_add(warnstr)
2091 : ! write(warnstr,*) subname, 'Zoo:',Zoo
2092 : ! endif
2093 :
2094 0 : end subroutine algal_dyn
2095 :
2096 : !=======================================================================
2097 : !
2098 : ! Find ice-ocean flux when ice is thin and internal dynamics/reactions are
2099 : ! assumed to be zero
2100 : !
2101 : ! authors Nicole Jeffery, LANL
2102 :
2103 0 : subroutine thin_ice_flux (hin, hin_old, Cin, flux_o_tot, &
2104 : source, dt, nblyr, & ! LCOV_EXCL_LINE
2105 : ocean_bio)
2106 :
2107 : integer (kind=int_kind), intent(in) :: &
2108 : nblyr ! number of bio layers
2109 :
2110 : real (kind=dbl_kind), dimension(nblyr+1), intent(inout) :: &
2111 : Cin ! initial concentration*hin_old*phin
2112 :
2113 : real (kind=dbl_kind), intent(in) :: &
2114 : hin_old , & ! brine thickness (m) ! LCOV_EXCL_LINE
2115 : hin , & ! new brine thickness (m) ! LCOV_EXCL_LINE
2116 : dt , & ! time step ! LCOV_EXCL_LINE
2117 : source , & ! atm, ocean, dust flux (mmol/m^2) ! LCOV_EXCL_LINE
2118 : ocean_bio ! ocean tracer concentration (mmol/m^3)
2119 :
2120 : real (kind=dbl_kind), intent(inout) :: &
2121 : flux_o_tot ! tracer flux, gravity+molecular drainage flux ,
2122 : ! and boundary flux to ocean (mmol/m^2/s)
2123 : ! positive into the ocean
2124 :
2125 : ! local variables
2126 :
2127 : integer (kind=int_kind) :: &
2128 : k ! vertical biology layer index
2129 :
2130 : real (kind=dbl_kind) :: &
2131 : sum_bio, & ! initial bio mass (mmol/m^2) ! LCOV_EXCL_LINE
2132 : zspace, & ! 1/nblyr ! LCOV_EXCL_LINE
2133 : dC, & ! added ocean bio mass (mmol/m^2) ! LCOV_EXCL_LINE
2134 0 : dh ! change in thickness (m)
2135 :
2136 : character(len=*),parameter :: subname='(thin_ice_flux)'
2137 :
2138 0 : zspace = c1/real(nblyr,kind=dbl_kind)
2139 :
2140 0 : dC = c0
2141 0 : sum_bio = c0
2142 0 : dh = hin-hin_old
2143 :
2144 0 : if (dh .le. c0) then ! keep the brine concentration fixed
2145 0 : sum_bio = (Cin(1)+Cin(nblyr+1))/hin_old*zspace*p5
2146 0 : Cin(1) = Cin(1)/hin_old*hin
2147 0 : Cin(nblyr+1) = Cin(nblyr+1)/hin_old*hin
2148 0 : do k = 2, nblyr
2149 0 : sum_bio = sum_bio + Cin(k)/hin_old*zspace
2150 0 : Cin(k) = Cin(k)/hin_old*hin + dC
2151 : enddo
2152 : else
2153 0 : dC = dh*ocean_bio
2154 0 : do k = 1, nblyr+1
2155 0 : Cin(k) = Cin(k) + dC
2156 : enddo
2157 : endif
2158 :
2159 0 : flux_o_tot = - dh*sum_bio/dt - dC/dt + source/dt
2160 :
2161 0 : end subroutine thin_ice_flux
2162 :
2163 : !=======================================================================
2164 : !
2165 : ! Compute matrix elements for the low order solution of FEM-FCT scheme
2166 : ! Predictor step
2167 : !
2168 : ! July, 2014 by N. Jeffery
2169 : !
2170 0 : subroutine compute_FCT_matrix (C_in, sbdiag, dt, nblyr, &
2171 : diag, spdiag, rhs, bgrid, & ! LCOV_EXCL_LINE
2172 : darcyV, dhtop, dhbot, & ! LCOV_EXCL_LINE
2173 : iphin_N, iDin, hbri_old, & ! LCOV_EXCL_LINE
2174 : atm_add, bphin_N, & ! LCOV_EXCL_LINE
2175 : C_top, C_bot, Qbot, Qtop, & ! LCOV_EXCL_LINE
2176 : Sink_bot, Sink_top, & ! LCOV_EXCL_LINE
2177 0 : D_sbdiag, D_spdiag, ML)
2178 :
2179 : integer (kind=int_kind), intent(in) :: &
2180 : nblyr ! number of bio layers
2181 :
2182 : real (kind=dbl_kind), dimension(nblyr+1), intent(in) :: &
2183 : C_in ! Initial (bulk) concentration*hbri_old (mmol/m^2)
2184 : ! conserved quantity on i_grid
2185 :
2186 : real (kind=dbl_kind), intent(in) :: &
2187 : dt ! time step
2188 :
2189 : real (kind=dbl_kind), dimension (nblyr+1), intent(inout) :: &
2190 : iDin ! Diffusivity on the igrid (1/s)
2191 :
2192 : real (kind=dbl_kind), dimension (nblyr+1), intent(in) :: &
2193 : iphin_N ! Porosity with min condition on igrid
2194 :
2195 : real (kind=dbl_kind), dimension (nblyr+2), intent(in) :: &
2196 : bphin_N, & ! Porosity with min condition on igrid ! LCOV_EXCL_LINE
2197 : bgrid
2198 :
2199 : real (kind=dbl_kind), dimension (nblyr+1), intent(out) :: &
2200 : sbdiag , & ! sub-diagonal matrix elements ! LCOV_EXCL_LINE
2201 : diag , & ! diagonal matrix elements ! LCOV_EXCL_LINE
2202 : spdiag , & ! super-diagonal matrix elements ! LCOV_EXCL_LINE
2203 : rhs , & ! rhs of tri-diagonal matrix eqn. ! LCOV_EXCL_LINE
2204 : ML, & ! lumped mass matrix ! LCOV_EXCL_LINE
2205 : D_spdiag, D_sbdiag ! artificial diffusion matrix
2206 :
2207 : real (kind=dbl_kind), intent(in) :: &
2208 : dhtop , & ! Change in brine top (m) ! LCOV_EXCL_LINE
2209 : dhbot , & ! Change in brine bottom (m) ! LCOV_EXCL_LINE
2210 : hbri_old , & ! brine height (m) ! LCOV_EXCL_LINE
2211 : atm_add , & ! atm-ice flux ! LCOV_EXCL_LINE
2212 : C_top , & ! bulk surface source (mmol/m^2) ! LCOV_EXCL_LINE
2213 : C_bot , & ! bulk bottom source (mmol/m^2) ! LCOV_EXCL_LINE
2214 : darcyV ! Darcy velocity (m/s
2215 :
2216 : real (kind=dbl_kind), intent(inout) :: & ! positive into ice
2217 : Qtop , & ! top flux source (mmol/m^2/s) ! LCOV_EXCL_LINE
2218 : Qbot , & ! bottom flux source (mmol/m^2/s) ! LCOV_EXCL_LINE
2219 : Sink_bot , & ! rest of bottom flux (sink or source) (mmol/m^2/s) ! LCOV_EXCL_LINE
2220 : Sink_top ! rest oftop flux (sink or source) (mmol/m^2/s)
2221 :
2222 : ! local variables
2223 :
2224 : real (kind=dbl_kind) :: &
2225 0 : vel, vel2, dphi_dx, zspace
2226 :
2227 : integer (kind=int_kind) :: &
2228 : k ! vertical index
2229 :
2230 : real (kind=dbl_kind), dimension (nblyr+1) :: &
2231 : Q_top, Q_bot, & ! surface and bottom source ! LCOV_EXCL_LINE
2232 : K_diag, K_spdiag, K_sbdiag, & ! advection matrix ! LCOV_EXCL_LINE
2233 : S_diag, S_spdiag, S_sbdiag, & ! diffusion matrix ! LCOV_EXCL_LINE
2234 0 : D_diag, iDin_phi
2235 :
2236 : real (kind=dbl_kind), dimension (nblyr) :: &
2237 0 : kvector1, kvectorn1
2238 :
2239 : character(len=*),parameter :: subname='(compute_FCT_matrix)'
2240 :
2241 : !---------------------------------------------------------------------
2242 : ! Diag (jj) solve for j = 1:nblyr+1
2243 : ! spdiag(j) == (j,j+1) solve for j = 1:nblyr otherwise 0
2244 : ! sbdiag(j) == (j,j-1) solve for j = 2:nblyr+1 otherwise 0
2245 : !---------------------------------------------------------------------
2246 0 : kvector1(:) = c0
2247 0 : kvector1(1) = c1
2248 0 : kvectorn1(:) = c1
2249 0 : kvectorn1(1) = c0
2250 :
2251 0 : zspace = c1/real(nblyr,kind=dbl_kind)
2252 0 : Qbot = c0
2253 0 : Qtop = c0
2254 0 : Sink_bot = c0
2255 0 : Sink_top = c0
2256 :
2257 : ! compute the lumped mass matrix
2258 :
2259 0 : ML(:) = zspace
2260 0 : ML(1) = zspace/c2
2261 0 : ML(nblyr+1) = zspace/c2
2262 :
2263 : ! compute matrix K: K_diag , K_sbdiag, K_spdiag
2264 : ! compute matrix S: S_diag, S_sbdiag, S_spdiag
2265 :
2266 0 : K_diag(:) = c0
2267 0 : D_diag(:) = c0
2268 0 : D_spdiag(:) = c0
2269 0 : D_sbdiag(:) = c0
2270 0 : K_spdiag(:) = c0
2271 0 : K_sbdiag(:) = c0
2272 0 : S_diag(:) = c0
2273 0 : S_spdiag(:) = c0
2274 0 : S_sbdiag(:) = c0
2275 0 : iDin_phi(:) = c0
2276 :
2277 0 : iDin_phi(1) = c0 !element 1
2278 0 : iDin_phi(nblyr+1) = iDin(nblyr+1)/iphin_N(nblyr+1) !outside ice at bottom
2279 0 : iDin_phi(nblyr) = p5*(iDin(nblyr+1)/iphin_N(nblyr+1)+iDin(nblyr)/iphin_N(nblyr))
2280 :
2281 0 : vel = (bgrid(2)*dhbot - (bgrid(2)-c1)*dhtop)/dt+darcyV/bphin_N(2)
2282 0 : K_diag(1) = p5*vel/hbri_old
2283 0 : dphi_dx = (iphin_N(nblyr+1) - iphin_N(nblyr))/(zspace)
2284 0 : vel = (bgrid(nblyr+1)*dhbot - (bgrid(nblyr+1)-c1)*dhtop)/dt +darcyV/bphin_N(nblyr+1)
2285 0 : vel = vel/hbri_old
2286 0 : vel2 = (dhbot/hbri_old/dt +darcyV/hbri_old)
2287 0 : K_diag(nblyr+1) = min(c0, vel2) - iDin_phi(nblyr+1)/(zspace+ grid_o/hbri_old) &
2288 0 : + p5*(-vel + iDin_phi(nblyr)/bphin_N(nblyr+1)*dphi_dx)
2289 :
2290 0 : do k = 1, nblyr-1
2291 0 : vel = (bgrid(k+1)*dhbot - (bgrid(k+1)-c1)*dhtop)/dt+darcyV/bphin_N(k+1)
2292 0 : iDin_phi(k+1) = p5*(iDin(k+2)/iphin_N(k+2) + iDin(k+1)/iphin_N(k+1))
2293 0 : dphi_dx = (iphin_N(k+1) - iphin_N(k))/(zspace)
2294 0 : K_spdiag(k)= p5*(vel/hbri_old - &
2295 0 : iDin_phi(k)/(bphin_N(k+1))*dphi_dx)
2296 :
2297 0 : vel = (bgrid(k+1)*dhbot - (bgrid(k+1)-c1)*dhtop)/dt +darcyV/bphin_N(k+1)
2298 0 : dphi_dx = c0
2299 0 : dphi_dx = kvectorn1(k)*(iphin_N(k+1) - iphin_N(k))/(zspace)
2300 0 : K_sbdiag(k+1)= -p5*(vel/hbri_old- &
2301 0 : iDin_phi(k)/bphin_N(k+1)*dphi_dx)
2302 0 : K_diag(k) = K_diag(1)*kvector1(k) + (K_spdiag(k) + K_sbdiag(k))*kvectorn1(k)
2303 :
2304 0 : S_diag(k+1) = -(iDin_phi(k)+ iDin_phi(k+1))/zspace
2305 0 : S_spdiag(k) = iDin_phi(k)/zspace
2306 0 : S_sbdiag(k+1) = iDin_phi(k)/zspace
2307 : enddo
2308 :
2309 : ! k = nblyr
2310 :
2311 0 : vel = (bgrid(nblyr+1)*dhbot - (bgrid(nblyr+1)-c1)*dhtop)/dt+darcyV/bphin_N(nblyr+1)
2312 0 : dphi_dx = (iphin_N(nblyr+1) - iphin_N(nblyr))/(zspace)
2313 0 : K_spdiag(nblyr)= p5*(vel/hbri_old - &
2314 0 : iDin_phi(nblyr)/(bphin_N(nblyr+1))*dphi_dx)
2315 0 : vel = (bgrid(nblyr+1)*dhbot - (bgrid(nblyr+1)-c1)*dhtop)/dt +darcyV/bphin_N(nblyr+1)
2316 0 : dphi_dx = kvectorn1(nblyr)*(iphin_N(nblyr+1) - iphin_N(nblyr))/(zspace)
2317 0 : K_sbdiag(nblyr+1)= -p5*(vel/hbri_old- &
2318 0 : iDin_phi(nblyr)/bphin_N(nblyr+1)*dphi_dx)
2319 0 : K_diag(nblyr) = K_spdiag(nblyr) + K_sbdiag(nblyr)
2320 0 : S_diag(nblyr+1) = -iDin_phi(nblyr)/zspace
2321 0 : S_spdiag(nblyr) = iDin_phi(nblyr)/zspace
2322 0 : S_sbdiag(nblyr+1) = iDin_phi(nblyr)/zspace
2323 :
2324 : ! compute matrix artificial D: D_spdiag, D_diag (D_spdiag(k) = D_sbdiag(k+1))
2325 :
2326 0 : do k = 1,nblyr
2327 0 : D_spdiag(k) = max(-K_spdiag(k), c0, -K_sbdiag(k+1))
2328 0 : D_sbdiag(k+1) = D_spdiag(k)
2329 : enddo
2330 0 : do k = 1,nblyr+1
2331 0 : D_diag(k) = D_diag(k) - D_spdiag(k) - D_sbdiag(k)
2332 : enddo
2333 :
2334 : ! compute Q_top and Q_bot: top and bottom sources
2335 :
2336 0 : vel2 = -(dhtop/hbri_old/dt +darcyV/bphin_N(1)/hbri_old)
2337 :
2338 0 : Q_top(:) = c0
2339 0 : Q_top(1) = max(c0,vel2*C_top + atm_add/dt)
2340 0 : Qtop = Q_top(1)
2341 :
2342 0 : vel = (dhbot/hbri_old/dt +darcyV/hbri_old) ! going from iphin_N(nblyr+1) to c1 makes a difference
2343 :
2344 0 : Q_bot(:) = c0
2345 0 : Q_bot(nblyr+1) = max(c0,vel*C_bot) + iDin_phi(nblyr+1)*C_bot&
2346 0 : /(zspace + grid_o/hbri_old)
2347 :
2348 0 : Qbot = Q_bot(nblyr+1)
2349 :
2350 0 : Sink_bot = K_diag(nblyr+1) + K_spdiag(nblyr)
2351 0 : Sink_top = K_diag(1) + K_sbdiag(2)
2352 :
2353 : !compute matrix elements (1 to nblyr+1)
2354 :
2355 0 : spdiag = -dt * (D_spdiag + K_spdiag + S_spdiag)
2356 0 : sbdiag = -dt * (D_sbdiag + K_sbdiag + S_sbdiag)
2357 0 : diag = ML - dt * (D_diag + K_diag + S_diag)
2358 0 : rhs = ML * C_in + dt * Q_top + dt* Q_bot
2359 :
2360 0 : end subroutine compute_FCT_matrix
2361 :
2362 : !=======================================================================
2363 : !
2364 : ! Compute matrices for final solution FCT for passive tracers
2365 : ! Corrector step
2366 : !
2367 : ! July, 2014 by N. Jeffery
2368 : !
2369 0 : subroutine compute_FCT_corr (C_in, C_low, dt, nblyr, &
2370 0 : D_sbdiag, D_spdiag, ML)
2371 :
2372 : integer (kind=int_kind), intent(in) :: &
2373 : nblyr ! number of bio layers
2374 :
2375 : real (kind=dbl_kind), dimension(nblyr+1), intent(in) :: &
2376 : C_in ! Initial (bulk) concentration*hbri_old (mmol/m^2)
2377 : ! conserved quantity on igrid
2378 :
2379 : real (kind=dbl_kind), dimension(nblyr+1), intent(inout) :: &
2380 : C_low ! Low order solution (mmol/m^2) corrected
2381 :
2382 : real (kind=dbl_kind), intent(in) :: &
2383 : dt ! time step
2384 :
2385 : real (kind=dbl_kind), dimension (nblyr+1), intent(in) :: &
2386 : D_sbdiag , & ! sub-diagonal artificial diffusion matrix elements ! LCOV_EXCL_LINE
2387 : ML , & ! Lumped mass diagonal matrix elements ! LCOV_EXCL_LINE
2388 : D_spdiag ! super-diagonal artificial diffusion matrix elements
2389 :
2390 : ! local variables
2391 :
2392 : real (kind=dbl_kind) :: &
2393 0 : zspace
2394 :
2395 : integer (kind=int_kind) :: &
2396 : k ! vertical index
2397 :
2398 : real (kind=dbl_kind), dimension (nblyr+1) :: &
2399 : M_spdiag, M_sbdiag, & ! mass matrix ! LCOV_EXCL_LINE
2400 : F_diag, F_spdiag, F_sbdiag, & ! anti-diffusive matrix ! LCOV_EXCL_LINE
2401 : Pplus, Pminus, & ! ! LCOV_EXCL_LINE
2402 : Qplus, Qminus, & ! ! LCOV_EXCL_LINE
2403 : Rplus, Rminus, & ! ! LCOV_EXCL_LINE
2404 0 : a_spdiag, a_sbdiag ! weightings of F
2405 :
2406 : character(len=*),parameter :: subname='(compute_FCT_corr)'
2407 :
2408 : !---------------------------------------------------------------------
2409 : ! Diag (jj) solve for j = 1:nblyr+1
2410 : ! spdiag(j) == (j,j+1) solve for j = 1:nblyr otherwise 0
2411 : ! sbdiag(j) == (j,j-1) solve for j = 2:nblyr+1 otherwise 0
2412 : !---------------------------------------------------------------------
2413 :
2414 0 : zspace = c1/real(nblyr,kind=dbl_kind)
2415 :
2416 : ! compute the mass matrix
2417 :
2418 0 : M_spdiag(:) = zspace/c6
2419 0 : M_spdiag(nblyr+1) = c0
2420 0 : M_sbdiag(:) = zspace/c6
2421 0 : M_sbdiag(1) = c0
2422 :
2423 : ! compute off matrix F:
2424 :
2425 0 : F_diag(:) = c0
2426 0 : F_spdiag(:) = c0
2427 0 : F_sbdiag(:) = c0
2428 :
2429 0 : do k = 1, nblyr
2430 0 : F_spdiag(k) = M_spdiag(k)*(C_low(k)-C_in(k) - C_low(k+1)+ C_in(k+1))/dt &
2431 0 : + D_spdiag(k)*(C_low(k)-C_low(k+1))
2432 0 : F_sbdiag(k+1) = M_sbdiag(k+1)*(C_low(k+1)-C_in(k+1) - C_low(k)+ C_in(k))/dt &
2433 0 : + D_sbdiag(k+1)*(C_low(k+1)-C_low(k))
2434 :
2435 0 : if (F_spdiag(k)*(C_low(k) - C_low(k+1)) > c0) F_spdiag(k) = c0
2436 0 : if (F_sbdiag(k+1)*(C_low(k+1) - C_low(k)) > c0) F_sbdiag(k+1) = c0
2437 : enddo
2438 :
2439 0 : if (maxval(abs(F_spdiag)) > c0) then
2440 :
2441 : ! compute the weighting factors: a_spdiag, a_sbdiag
2442 :
2443 0 : a_spdiag(:) = c0
2444 0 : a_sbdiag(:) = c0
2445 :
2446 0 : Pplus(1) = max(c0, F_spdiag(1))
2447 0 : Pminus(1) = min(c0, F_spdiag(1))
2448 0 : Pplus(nblyr+1) = max(c0, F_sbdiag(nblyr+1))
2449 0 : Pminus(nblyr+1) = min(c0, F_sbdiag(nblyr+1))
2450 0 : Qplus(1) = max(c0,C_low(2)-C_low(1))
2451 0 : Qminus(1)= min(c0,C_low(2)-C_low(1))
2452 0 : Qplus(nblyr+1) = max(c0,C_low(nblyr)-C_low(nblyr+1))
2453 0 : Qminus(nblyr+1)= min(c0,C_low(nblyr)-C_low(nblyr+1))
2454 0 : Rplus(1) = min(c1, ML(1)*Qplus(1)/dt/(Pplus(1)+puny))
2455 0 : Rminus(1) = min(c1, ML(1)*Qminus(1)/dt/(Pminus(1)-puny))
2456 0 : Rplus(nblyr+1) = min(c1, ML(nblyr+1)*Qplus(nblyr+1)/dt/(Pplus(nblyr+1)+puny))
2457 0 : Rminus(nblyr+1) = min(c1, ML(nblyr+1)*Qminus(nblyr+1)/dt/(Pminus(nblyr+1)-puny))
2458 0 : do k = 2,nblyr
2459 0 : Pplus(k) = max(c0,F_spdiag(k)) + max(c0,F_sbdiag(k))
2460 0 : Pminus(k) = min(c0,F_spdiag(k)) + min(c0,F_sbdiag(k))
2461 0 : Qplus(k) = max(c0, max(C_low(k+1)-C_low(k),C_low(k-1)-C_low(k)))
2462 0 : Qminus(k) = min(c0, min(C_low(k+1)-C_low(k),C_low(k-1)-C_low(k)))
2463 0 : Rplus(k) = min(c1, ML(k)*Qplus(k)/dt/(Pplus(k)+puny))
2464 0 : Rminus(k) = min(c1, ML(k)*Qminus(k)/dt/(Pminus(k)-puny))
2465 : enddo
2466 :
2467 0 : do k = 1, nblyr
2468 0 : a_spdiag(k) = min(Rminus(k),Rplus(k+1))
2469 0 : if (F_spdiag(k) > c0) a_spdiag(k) = min(Rplus(k),Rminus(k+1))
2470 0 : a_sbdiag(k+1) = min(Rminus(k+1),Rplus(k))
2471 0 : if (F_sbdiag(k+1) > c0) a_sbdiag(k+1) = min(Rplus(k+1),Rminus(k))
2472 : enddo
2473 :
2474 : !compute F_diag:
2475 :
2476 0 : F_diag(1) = a_spdiag(1)*F_spdiag(1)
2477 0 : F_diag(nblyr+1) = a_sbdiag(nblyr+1)* F_sbdiag(nblyr+1)
2478 0 : C_low(1) = C_low(1) + dt*F_diag(1)/ML(1)
2479 0 : C_low(nblyr+1) = C_low(nblyr+1) + dt*F_diag(nblyr+1)/ML(nblyr+1)
2480 :
2481 0 : do k = 2,nblyr
2482 0 : F_diag(k) = a_spdiag(k)*F_spdiag(k) + a_sbdiag(k)*F_sbdiag(k)
2483 0 : C_low(k) = C_low(k) + dt*F_diag(k)/ML(k)
2484 : enddo
2485 :
2486 : endif !F_spdiag is nonzero
2487 :
2488 0 : end subroutine compute_FCT_corr
2489 :
2490 : !=======================================================================
2491 : !
2492 : ! Tridiagonal matrix solver-- for salinity
2493 : !
2494 : ! authors William H. Lipscomb, LANL
2495 : ! C. M. Bitz, UW
2496 : !
2497 0 : subroutine tridiag_solverz (nmat, sbdiag, &
2498 : diag, spdiag, & ! LCOV_EXCL_LINE
2499 0 : rhs, xout)
2500 :
2501 : integer (kind=int_kind), intent(in) :: &
2502 : nmat ! matrix dimension
2503 :
2504 : real (kind=dbl_kind), dimension (nmat), intent(in) :: &
2505 : sbdiag , & ! sub-diagonal matrix elements ! LCOV_EXCL_LINE
2506 : diag , & ! diagonal matrix elements ! LCOV_EXCL_LINE
2507 : spdiag , & ! super-diagonal matrix elements ! LCOV_EXCL_LINE
2508 : rhs ! rhs of tri-diagonal matrix eqn.
2509 :
2510 : real (kind=dbl_kind), dimension (nmat), intent(inout) :: &
2511 : xout ! solution vector
2512 :
2513 : ! local variables
2514 :
2515 : integer (kind=int_kind) :: &
2516 : k ! row counter
2517 :
2518 : real (kind=dbl_kind) :: &
2519 0 : wbeta ! temporary matrix variable
2520 :
2521 : real (kind=dbl_kind), dimension(nmat):: &
2522 0 : wgamma ! temporary matrix variable
2523 :
2524 : character(len=*),parameter :: subname='(tridiag_solverz)'
2525 :
2526 0 : wbeta = diag(1)
2527 0 : xout(1) = rhs(1) / wbeta
2528 :
2529 0 : do k = 2, nmat
2530 0 : wgamma(k) = spdiag(k-1) / wbeta
2531 0 : wbeta = diag(k) - sbdiag(k)*wgamma(k)
2532 0 : xout(k) = (rhs(k) - sbdiag(k)*xout(k-1)) / wbeta
2533 : enddo ! k
2534 :
2535 0 : do k = nmat-1, 1, -1
2536 0 : xout(k) = xout(k) - wgamma(k+1)*xout(k+1)
2537 : enddo ! k
2538 :
2539 0 : end subroutine tridiag_solverz
2540 :
2541 : !=======================================================================
2542 : !
2543 : ! authors Nicole Jeffery, LANL
2544 :
2545 0 : subroutine check_conservation_FCT (C_init, C_new, C_low, S_top, &
2546 : S_bot, L_bot, L_top, dt, & ! LCOV_EXCL_LINE
2547 : fluxbio, nblyr, & ! LCOV_EXCL_LINE
2548 : source)
2549 :
2550 : integer (kind=int_kind), intent(in) :: &
2551 : nblyr ! number of bio layers
2552 :
2553 : real (kind=dbl_kind), dimension(nblyr+1), intent(in) :: &
2554 : C_init , & ! initial bulk concentration * h_old (mmol/m^2) ! LCOV_EXCL_LINE
2555 : C_new ! new bulk concentration * h_new (mmol/m^2)
2556 :
2557 : real (kind=dbl_kind), dimension(nblyr+1), intent(out) :: &
2558 : C_low ! define low order solution = C_new
2559 :
2560 : real (kind=dbl_kind), intent(in) :: &
2561 : S_top , & ! surface flux into ice (mmol/m^2/s) ! LCOV_EXCL_LINE
2562 : S_bot , & ! bottom flux into ice (mmol/m^2/s) ! LCOV_EXCL_LINE
2563 : L_bot , & ! remaining bottom flux into ice (mmol/m^2/s) ! LCOV_EXCL_LINE
2564 : L_top , & ! remaining top flux into ice (mmol/m^2/s) ! LCOV_EXCL_LINE
2565 : dt , & ! LCOV_EXCL_LINE
2566 : source ! nutrient source from snow and atmosphere (mmol/m^2)
2567 :
2568 : real (kind=dbl_kind), intent(inout) :: &
2569 : fluxbio ! (mmol/m^2/s) positive down (into the ocean)
2570 :
2571 : ! local variables
2572 :
2573 : integer (kind=int_kind) :: &
2574 : k
2575 :
2576 : real (kind=dbl_kind) :: &
2577 : diff_dt , & ! LCOV_EXCL_LINE
2578 : C_init_tot , & ! LCOV_EXCL_LINE
2579 : C_new_tot , & ! LCOV_EXCL_LINE
2580 : zspace , & !1/nblyr ! LCOV_EXCL_LINE
2581 0 : accuracy ! centered difference is Order(zspace^2)
2582 :
2583 : character(len=*),parameter :: subname='(check_conservation_FCT)'
2584 :
2585 0 : zspace = c1/real(nblyr,kind=dbl_kind)
2586 :
2587 : !-------------------------------------
2588 : ! Ocean flux: positive into the ocean
2589 : !-------------------------------------
2590 0 : C_init_tot = (C_init(1) + C_init(nblyr+1))*zspace*p5
2591 0 : C_new_tot = (C_new(1) + C_new(nblyr+1))*zspace*p5
2592 0 : C_low(1) = C_new(1)
2593 0 : C_low(nblyr+1) = C_new(nblyr+1)
2594 :
2595 0 : do k = 2, nblyr
2596 0 : C_init_tot = C_init_tot + C_init(k)*zspace
2597 0 : C_new_tot = C_new_tot + C_new(k)*zspace
2598 0 : C_low(k) = C_new(k)
2599 : enddo
2600 :
2601 0 : accuracy = 1.0e-14_dbl_kind*max(c1, C_init_tot, C_new_tot)
2602 0 : fluxbio = (C_init_tot - C_new_tot + source)/dt
2603 0 : diff_dt =C_new_tot - C_init_tot - (S_top+S_bot+L_bot*C_new(nblyr+1)+L_top*C_new(1))*dt
2604 :
2605 0 : if (minval(C_low) < c0) then
2606 0 : write(warnstr,*) subname, 'Positivity of zbgc low order solution failed: C_low:',C_low
2607 0 : call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
2608 : endif
2609 :
2610 0 : if (abs(diff_dt) > accuracy ) then
2611 0 : call icepack_warnings_setabort(.true.,__FILE__,__LINE__)
2612 0 : write(warnstr,*) subname, 'Conservation of zbgc low order solution failed: diff_dt:',&
2613 0 : diff_dt
2614 0 : write(warnstr,*) subname, 'Total initial tracer', C_init_tot
2615 0 : write(warnstr,*) subname, 'Total final1 tracer', C_new_tot
2616 0 : write(warnstr,*) subname, 'bottom final tracer', C_new(nblyr+1)
2617 0 : write(warnstr,*) subname, 'top final tracer', C_new(1)
2618 0 : write(warnstr,*) subname, 'Near bottom final tracer', C_new(nblyr)
2619 0 : write(warnstr,*) subname, 'Near top final tracer', C_new(2)
2620 0 : write(warnstr,*) subname, 'Top flux*dt into ice:', S_top*dt
2621 0 : write(warnstr,*) subname, 'Bottom flux*dt into ice:', S_bot*dt
2622 0 : write(warnstr,*) subname, 'Remaining bot flux*dt into ice:', L_bot*C_new(nblyr+1)*dt
2623 0 : write(warnstr,*) subname, 'S_bot*dt + L_bot*C_new(nblyr+1)*dt'
2624 0 : write(warnstr,*) subname, S_bot*dt + L_bot*C_new(nblyr+1)*dt
2625 0 : write(warnstr,*) subname, 'fluxbio*dt:', fluxbio*dt
2626 0 : write(warnstr,*) subname, 'fluxbio:', fluxbio
2627 0 : write(warnstr,*) subname, 'Remaining top flux*dt into ice:', L_top*C_new(1)*dt
2628 : endif
2629 :
2630 0 : end subroutine check_conservation_FCT
2631 :
2632 : !=======================================================================
2633 :
2634 : ! For each grid cell, sum field over all ice and snow layers
2635 : !
2636 : ! author: Nicole Jeffery, LANL
2637 :
2638 0 : subroutine bgc_column_sum (nblyr, nslyr, hsnow, hbrine, xin, xout)
2639 :
2640 : integer (kind=int_kind), intent(in) :: &
2641 : nblyr, & ! number of ice layers ! LCOV_EXCL_LINE
2642 : nslyr ! number of snow layers
2643 :
2644 : real (kind=dbl_kind), dimension(nblyr+3), intent(in) :: &
2645 : xin ! input field
2646 :
2647 : real (kind=dbl_kind), intent(in) :: &
2648 : hsnow, & ! snow thickness ! LCOV_EXCL_LINE
2649 : hbrine ! brine height
2650 :
2651 : real (kind=dbl_kind), intent(out) :: &
2652 : xout ! output field
2653 :
2654 : ! local variables
2655 :
2656 : real (kind=dbl_kind) :: &
2657 : dzssl, & ! snow surface layer (m) ! LCOV_EXCL_LINE
2658 : dzint, & ! snow interior depth (m) ! LCOV_EXCL_LINE
2659 : hslyr, & ! snow layer thickness (m) ! LCOV_EXCL_LINE
2660 0 : zspace ! brine layer thickness/hbrine
2661 :
2662 : integer (kind=int_kind) :: &
2663 : n ! category/layer index
2664 :
2665 : character(len=*),parameter :: subname='(bgc_column_sum)'
2666 :
2667 0 : hslyr = hsnow/real(nslyr,kind=dbl_kind)
2668 0 : dzssl = min(hslyr*p5, hs_ssl)
2669 0 : dzint = max(c0,hsnow - dzssl)
2670 0 : zspace = c1/real(nblyr,kind=dbl_kind)
2671 :
2672 0 : xout = c0
2673 0 : xout = (xin(1) + xin(nblyr+1))*hbrine*p5*zspace
2674 0 : do n = 2, nblyr
2675 0 : xout = xout + xin(n)*zspace*hbrine
2676 : enddo ! n
2677 0 : xout = xout + dzssl*xin(nblyr+2) + dzint*xin(nblyr+3)
2678 :
2679 0 : end subroutine bgc_column_sum
2680 :
2681 : !=======================================================================
2682 :
2683 : end module icepack_algae
2684 :
2685 : !=======================================================================
|