@@ -17,7 +17,7 @@ module MOM_opacity
17
17
18
18
#include < MOM_memory.h>
19
19
20
- public set_opacity, opacity_init, opacity_end, opacity_manizza, opacity_morel
20
+ public set_opacity, opacity_init, opacity_end
21
21
public extract_optics_slice, extract_optics_fields, optics_nbands
22
22
public absorbRemainingSW, sumSWoverBands
23
23
@@ -66,8 +66,21 @@ module MOM_opacity
66
66
! ! radiation that is in the blue band [nondim].
67
67
real :: opacity_land_value ! < The value to use for opacity over land [Z-1 ~> m-1].
68
68
! ! The default is 10 m-1 - a value for muddy water.
69
+ real , allocatable , dimension (:,:) &
70
+ :: opacity_coef ! < Groups of coefficients, in [Z-1 ~> m-1] or [Z ~> m] depending on the
71
+ ! ! scheme, in expressions for opacity, with the second index being the
72
+ ! ! wavelength band. For example, when OPACITY_SCHEME = MANIZZA_05,
73
+ ! ! these are coef_1 and coef_2 in the
74
+ ! ! expression opacity = coef_1 + coef_2 * chl**pow.
75
+ real , allocatable , dimension (:) &
76
+ :: sw_pen_frac_coef ! < Coefficients in the expression for the penetrating shortwave
77
+ ! ! fracetion [nondim]
78
+ real , allocatable , dimension (:) &
79
+ :: chl_power ! < Powers of chlorophyll [nondim] for each band for expressions for
80
+ ! ! opacity of the form opacity = coef_1 + coef_2 * chl**pow.
69
81
type (diag_ctrl), pointer :: diag = > NULL () ! < A structure that is used to
70
82
! ! regulate the timing of diagnostic output.
83
+ integer :: chl_dep_bands ! < The number of bands that depend on the Chlorophyll concentrations.
71
84
logical :: warning_issued ! < A flag that is used to avoid repetitive warnings.
72
85
73
86
! >@{ Diagnostic IDs
@@ -344,9 +357,9 @@ subroutine opacity_from_chl(optics, sw_total, sw_vis_dir, sw_vis_dif, sw_nir_dir
344
357
SW_pen_tot = 0.0
345
358
if (G% mask2dT(i,j) > 0.0 ) then
346
359
if (multiband_vis_input) then
347
- SW_pen_tot = SW_pen_frac_morel(chl_data(i,j)) * (sw_vis_dir(i,j) + sw_vis_dif(i,j))
360
+ SW_pen_tot = SW_pen_frac_morel(chl_data(i,j), CS ) * (sw_vis_dir(i,j) + sw_vis_dif(i,j))
348
361
elseif (total_sw_input) then
349
- SW_pen_tot = SW_pen_frac_morel(chl_data(i,j)) * 0.5 * sw_total(i,j)
362
+ SW_pen_tot = SW_pen_frac_morel(chl_data(i,j), CS ) * 0.5 * sw_total(i,j)
350
363
endif
351
364
endif
352
365
@@ -372,19 +385,21 @@ subroutine opacity_from_chl(optics, sw_total, sw_vis_dir, sw_vis_dif, sw_nir_dir
372
385
optics% opacity_band(n,i,j,k) = CS% opacity_land_value
373
386
enddo
374
387
else
375
- ! Band 1 is Manizza blue.
376
- optics% opacity_band(1 ,i,j,k) = (0.0232 + 0.074 * chl_data(i,j)** 0.674 ) * US% Z_to_m
377
- if (nbands >= 2 ) & ! Band 2 is Manizza red.
378
- optics% opacity_band(2 ,i,j,k) = (0.225 + 0.037 * chl_data(i,j)** 0.629 ) * US% Z_to_m
379
- ! All remaining bands are NIR, for lack of something better to do.
380
- do n= 3 ,nbands ; optics% opacity_band(n,i,j,k) = 2.86 * US% Z_to_m ; enddo
388
+ do n= 1 ,CS% chl_dep_bands
389
+ optics% opacity_band(n,i,j,k) = CS% opacity_coef(1 ,n) + &
390
+ CS% opacity_coef(2 ,n) * chl_data(i,j)** CS% chl_power(n)
391
+ enddo
392
+ do n= CS% chl_dep_bands+1 ,optics% nbands ! These bands do not depend on the chlorophyll.
393
+ ! Any nonzero values that were in opacity_coef(2,n) have been added to opacity_coef(1,n).
394
+ optics% opacity_band(n,i,j,k) = CS% opacity_coef(1 ,n)
395
+ enddo
381
396
endif
382
397
enddo ; enddo
383
398
case (MOREL_88)
384
399
do j= js,je ; do i= is,ie
385
400
optics% opacity_band(1 ,i,j,k) = CS% opacity_land_value
386
401
if (G% mask2dT(i,j) > 0.0 ) &
387
- optics% opacity_band(1 ,i,j,k) = US % Z_to_m * opacity_morel(chl_data(i,j))
402
+ optics% opacity_band(1 ,i,j,k) = opacity_morel(chl_data(i,j), CS )
388
403
389
404
do n= 2 ,optics% nbands
390
405
optics% opacity_band(n,i,j,k) = optics% opacity_band(1 ,i,j,k)
@@ -401,28 +416,25 @@ end subroutine opacity_from_chl
401
416
402
417
! > This sets the blue-wavelength opacity according to the scheme proposed by
403
418
! ! Morel and Antoine (1994).
404
- function opacity_morel (chl_data )
419
+ function opacity_morel (chl_data , CS )
405
420
real , intent (in ) :: chl_data ! < The chlorophyll-A concentration in [mg m-3]
406
- real :: opacity_morel ! < The returned opacity [m-1]
421
+ type (opacity_CS) :: CS ! < Opacity control structure
422
+ real :: opacity_morel ! < The returned opacity [Z-1 ~> m-1]
407
423
408
- ! The following are coefficients for the optical model taken from Morel and
409
- ! Antoine (1994). These coefficients represent a non uniform distribution of
410
- ! chlorophyll-a through the water column. Other approaches may be more
411
- ! appropriate when using an interactive ecosystem model that predicts
412
- ! three-dimensional chl-a values.
413
- real , dimension (6 ), parameter :: &
414
- Z2_coef = (/ 7.925 , - 6.644 , 3.662 , - 1.815 , - 0.218 , 0.502 / ) ! Extinction length coefficients [m]
415
424
real :: Chl, Chl2 ! The log10 of chl_data (in mg m-3), and Chl^2 [nondim]
416
425
417
426
Chl = log10 (min (max (chl_data,0.02 ),60.0 )) ; Chl2 = Chl* Chl
418
- opacity_morel = 1.0 / ( (Z2_coef(1 ) + Z2_coef(2 )* Chl) + Chl2 * &
419
- ((Z2_coef(3 ) + Chl* Z2_coef(4 )) + Chl2* (Z2_coef(5 ) + Chl* Z2_coef(6 ))) )
420
- end function
427
+ ! All frequency bands currently use the same opacities.
428
+ opacity_morel = 1.0 / ( (CS% opacity_coef(1 ,1 ) + CS% opacity_coef(2 ,1 )* Chl) + Chl2 * &
429
+ ((CS% opacity_coef(3 ,1 ) + Chl* CS% opacity_coef(4 ,1 )) + &
430
+ Chl2* (CS% opacity_coef(5 ,1 ) + Chl* CS% opacity_coef(6 ,1 ))) )
431
+ end function opacity_morel
421
432
422
433
! > This sets the penetrating shortwave fraction according to the scheme proposed by
423
434
! ! Morel and Antoine (1994).
424
- function SW_pen_frac_morel (chl_data )
435
+ function SW_pen_frac_morel (chl_data , CS )
425
436
real , intent (in ) :: chl_data ! < The chlorophyll-A concentration [mg m-3]
437
+ type (opacity_CS) :: CS ! < Opacity control structure
426
438
real :: SW_pen_frac_morel ! < The returned penetrating shortwave fraction [nondim]
427
439
428
440
! The following are coefficients for the optical model taken from Morel and
@@ -431,24 +443,13 @@ function SW_pen_frac_morel(chl_data)
431
443
! appropriate when using an interactive ecosystem model that predicts
432
444
! three-dimensional chl-a values.
433
445
real :: Chl, Chl2 ! The log10 of chl_data in mg m-3, and Chl^2 [nondim]
434
- real , dimension (6 ), parameter :: &
435
- V1_coef = (/ 0.321 , 0.008 , 0.132 , 0.038 , - 0.017 , - 0.007 / ) ! Penetrating fraction coefficients [nondim]
436
446
437
447
Chl = log10 (min (max (chl_data,0.02 ),60.0 )) ; Chl2 = Chl* Chl
438
- SW_pen_frac_morel = 1.0 - ( (V1_coef(1 ) + V1_coef(2 )* Chl) + Chl2 * &
439
- ((V1_coef(3 ) + Chl* V1_coef(4 )) + Chl2* (V1_coef(5 ) + Chl* V1_coef(6 ))) )
448
+ SW_pen_frac_morel = 1.0 - ( (CS% SW_pen_frac_coef(1 ) + CS% SW_pen_frac_coef(2 )* Chl) + Chl2 * &
449
+ ((CS% SW_pen_frac_coef(3 ) + Chl* CS% SW_pen_frac_coef(4 )) + &
450
+ Chl2* (CS% SW_pen_frac_coef(5 ) + Chl* CS% SW_pen_frac_coef(6 ))) )
440
451
end function SW_pen_frac_morel
441
452
442
- ! > This sets the blue-wavelength opacity according to the scheme proposed by
443
- ! ! Manizza, M. et al, 2005.
444
- function opacity_manizza (chl_data )
445
- real , intent (in ) :: chl_data ! < The chlorophyll-A concentration [mg m-3]
446
- real :: opacity_manizza ! < The returned opacity [m-1]
447
- ! This sets the blue-wavelength opacity according to the scheme proposed by Manizza, M. et al, 2005.
448
-
449
- opacity_manizza = 0.0232 + 0.074 * chl_data** 0.674
450
- end function
451
-
452
453
! > This subroutine returns a 2-d slice at constant j of fields from an optics_type, with the potential
453
454
! ! for rescaling these fields.
454
455
subroutine extract_optics_slice (optics , j , G , GV , opacity , opacity_scale , penSW_top , penSW_scale , SpV_avg )
@@ -973,9 +974,25 @@ subroutine opacity_init(Time, G, GV, US, param_file, diag, CS, optics)
973
974
character (len= 40 ) :: scheme_string
974
975
! This include declares and sets the variable "version".
975
976
# include " version_variable.h"
977
+ real :: opacity_coefs(6 ) ! Pairs of opacity coefficients [Z-1 ~> m-1] for blue, red and
978
+ ! near-infrared radiation with parameterizations following the
979
+ ! functional form from Manizza et al., GRL 2005, namely in the form
980
+ ! opacity = coef_1 + coef_2 * chl**pow for each band.
981
+ real :: opacity_powers(3 ) ! Powers of chlorophyll [nondim] for blue, red and near-infrared
982
+ ! radiation bands, in expressions for opacity of the form
983
+ ! opacity = coef_1 + coef_2 * chl**pow.
984
+ real :: extinction_coefs(6 ) ! Extinction length coefficients [Z ~> m] for penetrating shortwave
985
+ ! radiation in the form proposed by Morel and Antoine (1994), namely
986
+ ! opacity = 1 / (sum(n=1:6, Coef(n) * log10(Chl)**(n-1)))
987
+ real :: sw_pen_frac_coefs(6 ) ! Coefficients for the shortwave radiation fraction [nondim] in a
988
+ ! fifth order polynomial fit as a funciton of log10(Chlorophyll).
976
989
real :: PenSW_absorb_minthick ! A thickness that is used to absorb the remaining shortwave heat
977
990
! flux when that flux drops below PEN_SW_FLUX_ABSORB [H ~> m or kg m-2]
978
- real :: PenSW_minthick_dflt ! The default for PenSW_absorb_minthick [m]
991
+ real :: PenSW_minthick_dflt ! The default for PenSW_absorb_minthick [m]
992
+ real :: I_NIR_bands ! The inverse of the number of near-infrared bands being used [nondim]
993
+ real , allocatable :: band_wavelengths(:) ! The bounding wavelengths for the penetrating shortwave
994
+ ! radiation bands [nm]
995
+ real , allocatable :: band_wavelen_default(:) ! The defaults for band_wavelengths [nm]
979
996
integer :: default_answer_date ! The default setting for the various ANSWER_DATE flags
980
997
integer :: isd, ied, jsd, jed, nz, n
981
998
isd = G% isd ; ied = G% ied ; jsd = G% jsd ; jed = G% jed ; nz = GV% ke
@@ -1098,25 +1115,104 @@ subroutine opacity_init(Time, G, GV, US, param_file, diag, CS, optics)
1098
1115
default= PenSW_minthick_dflt, units= " m" , scale= GV% m_to_H)
1099
1116
optics% PenSW_absorb_Invlen = 1.0 / (PenSW_absorb_minthick + GV% H_subroundoff)
1100
1117
1118
+ ! The defaults for the following coefficients are taken from Manizza et al., GRL, 2005.
1119
+ call get_param(param_file, mdl, " OPACITY_VALUES_MANIZZA" , opacity_coefs, &
1120
+ " Pairs of opacity coefficients for blue, red and near-infrared radiation with " // &
1121
+ " parameterizations following the functional form from Manizza et al., GRL 2005, " // &
1122
+ " namely in the form opacity = coef_1 + coef_2 * chl**pow for each band. Although " // &
1123
+ " coefficients are set for 3 bands, more or less bands may actually be used, with " // &
1124
+ " extra bands following the same properties as band 3." , &
1125
+ units= " m-1" , scale= US% Z_to_m, defaults= (/ 0.0232 , 0.074 , 0.225 , 0.037 , 2.86 , 0.0 / ), &
1126
+ do_not_log= (CS% opacity_scheme/= MANIZZA_05))
1127
+ call get_param(param_file, mdl, " CHOROPHYLL_POWER_MANIZZA" , opacity_powers, &
1128
+ " Powers of chlorophyll for blue, red and near-infrared radiation bands in " // &
1129
+ " expressions for opacity of the form opacity = coef_1 + coef_2 * chl**pow." , &
1130
+ units= " nondim" , defaults= (/ 0.674 , 0.629 , 0.0 / ), &
1131
+ do_not_log= (CS% opacity_scheme/= MANIZZA_05))
1132
+
1133
+ ! The defaults for the following coefficients are taken from Morel and Antoine (1994).
1134
+ call get_param(param_file, mdl, " OPACITY_VALUES_MOREL" , extinction_coefs, &
1135
+ " Shortwave extinction length coefficients for shortwave radiation in the form " // &
1136
+ " proposed by Morel (1988), opacity = 1 / (sum(Coef(n) * log10(Chl)**(n-1)))." , &
1137
+ units= " m" , scale= US% m_to_Z, defaults= (/ 7.925 , - 6.644 , 3.662 , - 1.815 , - 0.218 , 0.502 / ), &
1138
+ do_not_log= (CS% opacity_scheme/= MOREL_88))
1139
+ call get_param(param_file, mdl, " SW_PEN_FRAC_COEFS_MOREL" , sw_pen_frac_coefs, &
1140
+ " Coefficients for the shortwave radiation fraction in a fifth order polynomial " // &
1141
+ " fit as a function of log10(Chlorophyll)." , &
1142
+ units= " nondim" , defaults= (/ 0.321 , 0.008 , 0.132 , 0.038 , - 0.017 , - 0.007 / ), &
1143
+ do_not_log= (CS% opacity_scheme/= MOREL_88))
1144
+
1101
1145
if (.not. allocated (optics% min_wavelength_band)) &
1102
1146
allocate (optics% min_wavelength_band(optics% nbands))
1103
1147
if (.not. allocated (optics% max_wavelength_band)) &
1104
1148
allocate (optics% max_wavelength_band(optics% nbands))
1105
1149
1150
+ ! Set the wavelengths of the opacity bands
1151
+ allocate (band_wavelengths(optics% nbands+1 ), source= 0.0 )
1152
+ allocate (band_wavelen_default(optics% nbands+1 ), source= 0.0 )
1106
1153
if (CS% opacity_scheme == MANIZZA_05) then
1107
- optics% min_wavelength_band(1 ) = 0
1108
- optics% max_wavelength_band(1 ) = 550
1109
- if (optics% nbands >= 2 ) then
1110
- optics% min_wavelength_band(2 )= 550
1111
- optics% max_wavelength_band(2 )= 700
1112
- endif
1113
- if (optics% nbands > 2 ) then
1154
+ if (optics% nbands >= 1 ) band_wavelen_default(2 ) = 550.0
1155
+ if (optics% nbands >= 2 ) band_wavelen_default(3 ) = 700.0
1156
+ if (optics% nbands >= 3 ) then
1157
+ I_NIR_bands = 1.0 / real (optics% nbands - 2 )
1114
1158
do n= 3 ,optics% nbands
1115
- optics% min_wavelength_band(n) = 700
1116
- optics% max_wavelength_band(n) = 2800
1159
+ band_wavelen_default(n+1 ) = 2800 . - (optics% nbands- n)* 2100.0 * I_NIR_bands
1117
1160
enddo
1118
1161
endif
1119
1162
endif
1163
+ call get_param(param_file, mdl, " OPACITY_BAND_WAVELENGTHS" , band_wavelengths, &
1164
+ " The bounding wavelengths for the various bands of shortwave radiation, with " // &
1165
+ " defaults that depend on the setting for OPACITY_SCHEME." , &
1166
+ units= " nm" , defaults= band_wavelen_default, do_not_log= (optics% nbands< 2 ))
1167
+ do n= 1 ,optics% nbands
1168
+ optics% min_wavelength_band(n) = band_wavelengths(n)
1169
+ optics% max_wavelength_band(n) = band_wavelengths(n+1 )
1170
+ enddo
1171
+ deallocate (band_wavelengths, band_wavelen_default)
1172
+
1173
+ ! Set opacity scheme dependent parameters.
1174
+
1175
+ if (CS% opacity_scheme == MANIZZA_05) then
1176
+ allocate (CS% opacity_coef(2 ,optics% nbands))
1177
+ allocate (CS% chl_power(optics% nbands))
1178
+ do n= 1 ,min (3 ,optics% nbands)
1179
+ CS% opacity_coef(1 ,n) = opacity_coefs(2 * n-1 ) ; CS% opacity_coef(2 ,n) = opacity_coefs(2 * n)
1180
+ CS% chl_power(n) = opacity_powers(n)
1181
+ enddo
1182
+ ! All remaining bands use the same properties as NIR, for lack of something better to do.
1183
+ do n= 4 ,optics% nbands
1184
+ CS% opacity_coef(1 ,n) = CS% opacity_coef(1 ,n-1 ) ; CS% opacity_coef(2 ,n) = CS% opacity_coef(2 ,n-1 )
1185
+ CS% chl_power(n) = CS% chl_power(n-1 )
1186
+ enddo
1187
+ ! Determine the last band that is dependent on chlorophyll.
1188
+ CS% chl_dep_bands = optics% nbands
1189
+ do n= optics% nbands,1 ,- 1
1190
+ if (CS% chl_power(n) /= 0.0 ) exit
1191
+ CS% chl_dep_bands = n - 1
1192
+ enddo
1193
+ do n= CS% chl_dep_bands+1 ,optics% nbands
1194
+ if (CS% opacity_coef(2 ,n) /= 0.0 ) then
1195
+ call MOM_error(WARNING, " set_opacity: A non-zero value of the chlorophyll dependence in " // &
1196
+ " OPACITY_VALUES_MANIZZA was set for a band with zero power in its chlorophyll dependence " // &
1197
+ " as set by CHOROPHYLL_POWER_MANIZZA." )
1198
+ CS% opacity_coef(1 ,n) = CS% opacity_coef(1 ,n) + CS% opacity_coef(2 ,n)
1199
+ CS% opacity_coef(2 ,n) = 0.0
1200
+ endif
1201
+ enddo
1202
+
1203
+ elseif (CS% opacity_scheme == MOREL_88) then
1204
+ ! The Morel opacity scheme represents a non uniform distribution of chlorophyll-a through the
1205
+ ! water column. Other approaches may be more appropriate when using an interactive ecosystem
1206
+ ! model that predicts three-dimensional chl-a values.
1207
+ allocate (CS% opacity_coef(6 , optics% nbands))
1208
+ allocate (CS% sw_pen_frac_coef(6 ))
1209
+
1210
+ ! As presently implemented, all frequency bands use the same opacities.
1211
+ do n= 1 ,optics% nbands
1212
+ CS% opacity_coef(1 :6 ,n) = extinction_coefs(1 :6 )
1213
+ enddo
1214
+ CS% sw_pen_frac_coef(:) = sw_pen_frac_coefs(:)
1215
+ endif
1120
1216
1121
1217
call get_param(param_file, mdl, " OPACITY_LAND_VALUE" , CS% opacity_land_value, &
1122
1218
" The value to use for opacity over land. The default is " // &
@@ -1152,6 +1248,12 @@ subroutine opacity_end(CS, optics)
1152
1248
1153
1249
if (allocated (CS% id_opacity)) &
1154
1250
deallocate (CS% id_opacity)
1251
+ if (allocated (CS% opacity_coef)) &
1252
+ deallocate (CS% opacity_coef)
1253
+ if (allocated (CS% sw_pen_frac_coef)) &
1254
+ deallocate (CS% sw_pen_frac_coef)
1255
+ if (allocated (CS% chl_power)) &
1256
+ deallocate (CS% chl_power)
1155
1257
if (allocated (optics% sw_pen_band)) &
1156
1258
deallocate (optics% sw_pen_band)
1157
1259
if (allocated (optics% opacity_band)) &
0 commit comments