920 type(time_type),
target,
intent(in) :: Time
921 type(ocean_grid_type),
intent(in) :: G
922 type(verticalGrid_type),
intent(in) :: GV
923 type(unit_scale_type),
intent(in) :: US
924 type(param_file_type),
intent(in) :: param_file
926 type(diag_ctrl),
target,
intent(inout) :: diag
928 type(opacity_CS),
pointer :: CS
930 type(optics_type),
pointer :: optics
933 character(len=200) :: tmpstr
934 character(len=40) :: mdl =
"MOM_opacity" 935 character(len=40) :: bandnum, shortname
936 character(len=200) :: longname
937 character(len=40) :: scheme_string
939 # include "version_variable.h" 940 real :: PenSW_absorb_minthick
942 real :: PenSW_minthick_dflt
943 logical :: default_2018_answers
944 logical :: use_scheme
945 integer :: isd, ied, jsd, jed, nz, n
946 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed ; nz = g%ke
948 if (
associated(cs))
then 949 call mom_error(warning,
"opacity_init called with an associated"// &
950 "associated control structure.")
952 else ;
allocate(cs) ;
endif 957 call log_version(param_file, mdl, version,
'')
960 call get_param(param_file, mdl,
"VAR_PEN_SW", cs%var_pen_sw, &
961 "If true, use one of the CHL_A schemes specified by "//&
962 "OPACITY_SCHEME to determine the e-folding depth of "//&
963 "incoming short wave radiation.", default=.false.)
965 cs%opacity_scheme = no_scheme ; scheme_string =
'' 966 if (cs%var_pen_sw)
then 967 call get_param(param_file, mdl,
"OPACITY_SCHEME", tmpstr, &
968 "This character string specifies how chlorophyll "//&
969 "concentrations are translated into opacities. Currently "//&
970 "valid options include:\n"//&
971 " \t\t MANIZZA_05 - Use Manizza et al., GRL, 2005. \n"//&
972 " \t\t MOREL_88 - Use Morel, JGR, 1988.", &
973 default=manizza_05_string)
974 if (len_trim(tmpstr) > 0)
then 975 tmpstr = uppercase(tmpstr)
977 case (manizza_05_string)
978 cs%opacity_scheme = manizza_05 ; scheme_string = manizza_05_string
979 case (morel_88_string)
980 cs%opacity_scheme = morel_88 ; scheme_string = morel_88_string
982 call mom_error(fatal,
"opacity_init: #DEFINE OPACITY_SCHEME "//&
983 trim(tmpstr) //
"in input file is invalid.")
985 call mom_mesg(
'opacity_init: opacity scheme set to "'//trim(tmpstr)//
'".', 5)
987 if (cs%opacity_scheme == no_scheme)
then 988 call mom_error(warning,
"opacity_init: No scheme has successfully "//&
989 "been specified for the opacity. Using the default MANIZZA_05.")
990 cs%opacity_scheme = manizza_05 ; scheme_string = manizza_05_string
993 call get_param(param_file, mdl,
"BLUE_FRAC_SW", cs%blue_frac, &
994 "The fraction of the penetrating shortwave radiation "//&
995 "that is in the blue band.", default=0.5, units=
"nondim")
997 call get_param(param_file, mdl,
"EXP_OPACITY_SCHEME", tmpstr, &
998 "This character string specifies which exponential "//&
999 "opacity scheme to utilize. Currently "//&
1000 "valid options include:\n"//&
1001 " \t\t SINGLE_EXP - Single Exponent decay. \n"//&
1002 " \t\t DOUBLE_EXP - Double Exponent decay.", &
1003 default=single_exp_string)
1004 if (len_trim(tmpstr) > 0)
then 1005 tmpstr = uppercase(tmpstr)
1006 select case (tmpstr)
1007 case (single_exp_string)
1008 cs%opacity_scheme = single_exp ; scheme_string = single_exp_string
1009 case (double_exp_string)
1010 cs%opacity_scheme = double_exp ; scheme_string = double_exp_string
1012 call mom_mesg(
'opacity_init: opacity scheme set to "'//trim(tmpstr)//
'".', 5)
1014 call get_param(param_file, mdl,
"PEN_SW_SCALE", cs%pen_sw_scale, &
1015 "The vertical absorption e-folding depth of the "//&
1016 "penetrating shortwave radiation.", units=
"m", default=0.0)
1018 if (cs%Opacity_scheme == double_exp )
then 1019 call get_param(param_file, mdl,
"PEN_SW_SCALE_2ND", cs%pen_sw_scale_2nd, &
1020 "The (2nd) vertical absorption e-folding depth of the "//&
1021 "penetrating shortwave radiation "//&
1022 "(use if SW_EXP_MODE==double.)",&
1023 units=
"m", default=0.0)
1024 call get_param(param_file, mdl,
"SW_1ST_EXP_RATIO", cs%sw_1st_exp_ratio, &
1025 "The fraction of 1st vertical absorption e-folding depth "//&
1026 "penetrating shortwave radiation if SW_EXP_MODE==double.",&
1027 units=
"m", default=0.0)
1028 elseif (cs%OPACITY_SCHEME == single_exp)
then 1030 cs%pen_sw_scale_2nd = 0.0
1031 cs%sw_1st_exp_ratio = 1.0
1033 call get_param(param_file, mdl,
"PEN_SW_FRAC", cs%pen_sw_frac, &
1034 "The fraction of the shortwave radiation that penetrates "//&
1035 "below the surface.", units=
"nondim", default=0.0)
1038 call get_param(param_file, mdl,
"PEN_SW_NBANDS", optics%nbands, &
1039 "The number of bands of penetrating shortwave radiation.", &
1041 if (cs%Opacity_scheme == double_exp )
then 1042 if (optics%nbands /= 2)
call mom_error(fatal, &
1043 "set_opacity: \Cannot use a double_exp opacity scheme with nbands!=2.")
1044 elseif (cs%Opacity_scheme == single_exp )
then 1045 if (optics%nbands /= 1)
call mom_error(fatal, &
1046 "set_opacity: \Cannot use a single_exp opacity scheme with nbands!=1.")
1049 call get_param(param_file, mdl,
"DEFAULT_2018_ANSWERS", default_2018_answers, &
1050 "This sets the default value for the various _2018_ANSWERS parameters.", &
1052 call get_param(param_file, mdl,
"OPTICS_2018_ANSWERS", optics%answers_2018, &
1053 "If true, use the order of arithmetic and expressions that recover the "//&
1054 "answers from the end of 2018. Otherwise, use updated expressions for "//&
1055 "handling the absorption of small remaining shortwave fluxes.", &
1056 default=default_2018_answers)
1058 call get_param(param_file, mdl,
"PEN_SW_FLUX_ABSORB", optics%PenSW_flux_absorb, &
1059 "A minimum remaining shortwave heating rate that will be simply absorbed in "//&
1060 "the next sufficiently thick layers for computational efficiency, instead of "//&
1061 "continuing to penetrate. The default, 2.5e-11 degC m s-1, is about 1e-4 W m-2 "//&
1062 "or 0.08 degC m century-1, but 0 is also a valid value.", &
1063 default=2.5e-11, units=
"degC m s-1", scale=gv%m_to_H*us%T_to_s)
1065 if (optics%answers_2018)
then ; pensw_minthick_dflt = 0.001 ;
else ; pensw_minthick_dflt = 1.0 ;
endif 1066 call get_param(param_file, mdl,
"PEN_SW_ABSORB_MINTHICK", pensw_absorb_minthick, &
1067 "A thickness that is used to absorb the remaining penetrating shortwave heat "//&
1068 "flux when it drops below PEN_SW_FLUX_ABSORB.", &
1069 default=pensw_minthick_dflt, units=
"m", scale=gv%m_to_H)
1070 optics%PenSW_absorb_Invlen = 1.0 / (pensw_absorb_minthick + gv%H_subroundoff)
1072 if (.not.
associated(optics%min_wavelength_band)) &
1073 allocate(optics%min_wavelength_band(optics%nbands))
1074 if (.not.
associated(optics%max_wavelength_band)) &
1075 allocate(optics%max_wavelength_band(optics%nbands))
1077 if (cs%opacity_scheme == manizza_05)
then 1078 optics%min_wavelength_band(1) =0
1079 optics%max_wavelength_band(1) =550
1080 if (optics%nbands >= 2)
then 1081 optics%min_wavelength_band(2)=550
1082 optics%max_wavelength_band(2)=700
1084 if (optics%nbands > 2)
then 1085 do n=3,optics%nbands
1086 optics%min_wavelength_band(n) =700
1087 optics%max_wavelength_band(n) =2800
1092 call get_param(param_file, mdl,
"OPACITY_LAND_VALUE", cs%opacity_land_value, &
1093 "The value to use for opacity over land. The default is "//&
1094 "10 m-1 - a value for muddy water.", units=
"m-1", default=10.0)
1096 if (.not.
associated(optics%opacity_band)) &
1097 allocate(optics%opacity_band(optics%nbands,isd:ied,jsd:jed,nz))
1098 if (.not.
associated(optics%sw_pen_band)) &
1099 allocate(optics%sw_pen_band(optics%nbands,isd:ied,jsd:jed))
1100 allocate(cs%id_opacity(optics%nbands)) ; cs%id_opacity(:) = -1
1102 cs%id_sw_pen = register_diag_field(
'ocean_model',
'SW_pen', diag%axesT1, time, &
1103 'Penetrating shortwave radiation flux into ocean',
'W m-2', conversion=us%QRZ_T_to_W_m2)
1104 cs%id_sw_vis_pen = register_diag_field(
'ocean_model',
'SW_vis_pen', diag%axesT1, time, &
1105 'Visible penetrating shortwave radiation flux into ocean',
'W m-2', conversion=us%QRZ_T_to_W_m2)
1106 do n=1,optics%nbands
1107 write(bandnum,
'(i3)') n
1108 shortname =
'opac_'//trim(adjustl(bandnum))
1109 longname =
'Opacity for shortwave radiation in band '//trim(adjustl(bandnum)) &
1110 //
', saved as L^-1 tanh(Opacity * L) for L = 10^-10 m' 1111 cs%id_opacity(n) = register_diag_field(
'ocean_model', shortname, diag%axesTL, time, &