Initializes the variables mixing coefficients container.
724 type(time_type),
intent(in) :: time
726 type(param_file_type),
intent(in) :: param_file
727 type(diag_ctrl),
target,
intent(inout) :: diag
728 type(varmix_cs),
pointer :: cs
730 real :: khtr_slope_cff, khth_slope_cff, oneortwo, n2_filter_depth
731 real :: khtr_passivity_coeff
732 real,
parameter :: absurdly_small_freq2 = 1e-34
735 logical :: gill_equatorial_ld, use_fgnv_streamfn, use_meke, in_use
736 real :: mle_front_length
738 #include "version_variable.h" 739 character(len=40) :: mdl =
"MOM_lateral_mixing_coeffs" 740 integer :: is, ie, js, je, isq, ieq, jsq, jeq, i, j
741 integer :: isd, ied, jsd, jed, isdb, iedb, jsdb, jedb
742 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
743 isq = g%IscB ; ieq = g%IecB ; jsq = g%JscB ; jeq = g%JecB
744 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
745 isdb = g%IsdB ; iedb = g%IedB ; jsdb = g%JsdB ; jedb = g%JedB
747 if (
associated(cs))
then 748 call mom_error(warning,
"VarMix_init called with an associated "// &
749 "control structure.")
756 cs%calculate_cg1 = .false.
757 cs%calculate_Rd_dx = .false.
758 cs%calculate_res_fns = .false.
759 cs%calculate_Eady_growth_rate = .false.
762 call log_version(param_file, mdl, version,
"")
763 call get_param(param_file, mdl,
"USE_VARIABLE_MIXING", cs%use_variable_mixing,&
764 "If true, the variable mixing code will be called. This \n"//&
765 "allows diagnostics to be created even if the scheme is \n"//&
766 "not used. If KHTR_SLOPE_CFF>0 or KhTh_Slope_Cff>0, \n"//&
767 "this is set to true regardless of what is in the \n"//&
768 "parameter file.", default=.false.)
769 call get_param(param_file, mdl,
"RESOLN_SCALED_KH", cs%Resoln_scaled_Kh, &
770 "If true, the Laplacian lateral viscosity is scaled away \n"//&
771 "when the first baroclinic deformation radius is well \n"//&
772 "resolved.", default=.false.)
773 call get_param(param_file, mdl,
"RESOLN_SCALED_KHTH", cs%Resoln_scaled_KhTh, &
774 "If true, the interface depth diffusivity is scaled away \n"//&
775 "when the first baroclinic deformation radius is well \n"//&
776 "resolved.", default=.false.)
777 call get_param(param_file, mdl,
"RESOLN_SCALED_KHTR", cs%Resoln_scaled_KhTr, &
778 "If true, the epipycnal tracer diffusivity is scaled \n"//&
779 "away when the first baroclinic deformation radius is \n"//&
780 "well resolved.", default=.false.)
781 call get_param(param_file, mdl,
"RESOLN_USE_EBT", cs%Resoln_use_ebt, &
782 "If true, uses the equivalent barotropic wave speed instead\n"//&
783 "of first baroclinic wave for calculating the resolution fn.",&
785 call get_param(param_file, mdl,
"KHTH_USE_EBT_STRUCT", cs%khth_use_ebt_struct, &
786 "If true, uses the equivalent barotropic structure\n"//&
787 "as the vertical structure of thickness diffusivity.",&
789 call get_param(param_file, mdl,
"KHTH_SLOPE_CFF", khth_slope_cff, &
790 "The nondimensional coefficient in the Visbeck formula \n"//&
791 "for the interface depth diffusivity", units=
"nondim", &
793 call get_param(param_file, mdl,
"KHTR_SLOPE_CFF", khtr_slope_cff, &
794 "The nondimensional coefficient in the Visbeck formula \n"//&
795 "for the epipycnal tracer diffusivity", units=
"nondim", &
797 call get_param(param_file, mdl,
"USE_STORED_SLOPES", cs%use_stored_slopes,&
798 "If true, the isopycnal slopes are calculated once and\n"//&
799 "stored for re-use. This uses more memory but avoids calling\n"//&
800 "the equation of state more times than should be necessary.", &
802 call get_param(param_file, mdl,
"KHTH_USE_FGNV_STREAMFUNCTION", use_fgnv_streamfn, &
803 default=.false., do_not_log=.true.)
804 cs%calculate_cg1 = cs%calculate_cg1 .or. use_fgnv_streamfn
805 call get_param(param_file, mdl,
"USE_MEKE", use_meke, &
806 default=.false., do_not_log=.true.)
807 cs%calculate_Eady_growth_rate = cs%calculate_Eady_growth_rate .or. use_meke
808 call get_param(param_file, mdl,
"KHTR_PASSIVITY_COEFF", khtr_passivity_coeff, &
809 default=0., do_not_log=.true.)
810 cs%calculate_Rd_dx = cs%calculate_Rd_dx .or. (khtr_passivity_coeff>0.)
811 call get_param(param_file, mdl,
"MLE_FRONT_LENGTH", mle_front_length, &
812 default=0., do_not_log=.true.)
813 cs%calculate_Rd_dx = cs%calculate_Rd_dx .or. (mle_front_length>0.)
815 call get_param(param_file, mdl,
"DEBUG", cs%debug, default=.false., do_not_log=.true.)
817 if (cs%Resoln_use_ebt .or. cs%khth_use_ebt_struct)
then 819 call get_param(param_file, mdl,
"RESOLN_N2_FILTER_DEPTH", n2_filter_depth, &
820 "The depth below which N2 is monotonized to avoid stratification\n"//&
821 "artifacts from altering the equivalent barotropic mode structure.",&
822 units=
'm', default=2000.)
823 allocate(cs%ebt_struct(isd:ied,jsd:jed,g%ke)) ; cs%ebt_struct(:,:,:) = 0.0
826 if (khtr_slope_cff>0. .or. khth_slope_cff>0.)
then 827 cs%calculate_Eady_growth_rate = .true.
828 call get_param(param_file, mdl,
"VISBECK_MAX_SLOPE", cs%Visbeck_S_max, &
829 "If non-zero, is an upper bound on slopes used in the\n"// &
830 "Visbeck formula for diffusivity. This does not affect the\n"// &
831 "isopycnal slope calculation used within thickness diffusion.", &
832 units=
"nondim", default=0.0)
835 if (cs%use_stored_slopes)
then 837 allocate(cs%slope_x(isdb:iedb,jsd:jed,g%ke+1)) ; cs%slope_x(:,:,:) = 0.0
838 allocate(cs%slope_y(isd:ied,jsdb:jedb,g%ke+1)) ; cs%slope_y(:,:,:) = 0.0
839 call get_param(param_file, mdl,
"KD_SMOOTH", cs%kappa_smooth, &
840 "A diapycnal diffusivity that is used to interpolate \n"//&
841 "more sensible values of T & S into thin layers.", &
845 if (cs%calculate_Eady_growth_rate)
then 847 allocate(cs%SN_u(isdb:iedb,jsd:jed)) ; cs%SN_u(:,:) = 0.0
848 allocate(cs%SN_v(isd:ied,jsdb:jedb)) ; cs%SN_v(:,:) = 0.0
849 cs%id_SN_u = register_diag_field(
'ocean_model',
'SN_u', diag%axesCu1, time, &
850 'Inverse eddy time-scale, S*N, at u-points',
's^-1')
851 cs%id_SN_v = register_diag_field(
'ocean_model',
'SN_v', diag%axesCv1, time, &
852 'Inverse eddy time-scale, S*N, at v-points',
's^-1')
853 call get_param(param_file, mdl,
"VARMIX_KTOP", cs%VarMix_Ktop, &
854 "The layer number at which to start vertical integration \n"//&
855 "of S*N for purposes of finding the Eady growth rate.", &
856 units=
"nondim", default=2)
859 if (khtr_slope_cff>0. .or. khth_slope_cff>0.)
then 861 call get_param(param_file, mdl,
"VISBECK_L_SCALE", cs%Visbeck_L_scale, &
862 "The fixed length scale in the Visbeck formula.", units=
"m", &
864 allocate(cs%L2u(isdb:iedb,jsd:jed)) ; cs%L2u(:,:) = cs%Visbeck_L_scale**2
865 allocate(cs%L2v(isd:ied,jsdb:jedb)) ; cs%L2v(:,:) = cs%Visbeck_L_scale**2
867 cs%id_L2u = register_diag_field(
'ocean_model',
'L2u', diag%axesCu1, time, &
868 'Length scale squared for mixing coefficient, at u-points',
'm^2')
869 cs%id_L2v = register_diag_field(
'ocean_model',
'L2v', diag%axesCv1, time, &
870 'Length scale squared for mixing coefficient, at v-points',
'm^2')
873 if (cs%use_stored_slopes)
then 874 cs%id_N2_u = register_diag_field(
'ocean_model',
'N2_u', diag%axesCui, time, &
875 'Square of Brunt-Vaisala frequency, N^2, at u-points, as used in Visbeck et al.',
's^-2')
876 cs%id_N2_v = register_diag_field(
'ocean_model',
'N2_v', diag%axesCvi, time, &
877 'Square of Brunt-Vaisala frequency, N^2, at v-points, as used in Visbeck et al.',
's^-2')
878 cs%id_S2_u = register_diag_field(
'ocean_model',
'S2_u', diag%axesCu1, time, &
879 'Depth average square of slope magnitude, S^2, at u-points, as used in Visbeck et al.',
's^-2')
880 cs%id_S2_v = register_diag_field(
'ocean_model',
'S2_v', diag%axesCv1, time, &
881 'Depth average square of slope magnitude, S^2, at v-points, as used in Visbeck et al.',
's^-2')
884 if (cs%Resoln_scaled_Kh .or. cs%Resoln_scaled_KhTh .or. cs%Resoln_scaled_KhTr)
then 885 cs%calculate_Rd_dx = .true.
886 cs%calculate_res_fns = .true.
887 allocate(cs%Res_fn_h(isd:ied,jsd:jed)) ; cs%Res_fn_h(:,:) = 0.0
888 allocate(cs%Res_fn_q(isdb:iedb,jsdb:jedb)) ; cs%Res_fn_q(:,:) = 0.0
889 allocate(cs%Res_fn_u(isdb:iedb,jsd:jed)) ; cs%Res_fn_u(:,:) = 0.0
890 allocate(cs%Res_fn_v(isd:ied,jsdb:jedb)) ; cs%Res_fn_v(:,:) = 0.0
891 allocate(cs%beta_dx2_q(isdb:iedb,jsdb:jedb)) ; cs%beta_dx2_q(:,:) = 0.0
892 allocate(cs%beta_dx2_u(isdb:iedb,jsd:jed)) ; cs%beta_dx2_u(:,:) = 0.0
893 allocate(cs%beta_dx2_v(isd:ied,jsdb:jedb)) ; cs%beta_dx2_v(:,:) = 0.0
894 allocate(cs%f2_dx2_q(isdb:iedb,jsdb:jedb)) ; cs%f2_dx2_q(:,:) = 0.0
895 allocate(cs%f2_dx2_u(isdb:iedb,jsd:jed)) ; cs%f2_dx2_u(:,:) = 0.0
896 allocate(cs%f2_dx2_v(isd:ied,jsdb:jedb)) ; cs%f2_dx2_v(:,:) = 0.0
898 cs%id_Res_fn = register_diag_field(
'ocean_model',
'Res_fn', diag%axesT1, time, &
899 'Resolution function for scaling diffusivities',
'Nondim')
901 call get_param(param_file, mdl,
"KH_RES_SCALE_COEF", cs%Res_coef_khth, &
902 "A coefficient that determines how KhTh is scaled away if \n"//&
903 "RESOLN_SCALED_... is true, as \n"//&
904 "F = 1 / (1 + (KH_RES_SCALE_COEF*Rd/dx)^KH_RES_FN_POWER).", &
905 units=
"nondim", default=1.0)
906 call get_param(param_file, mdl,
"KH_RES_FN_POWER", cs%Res_fn_power_khth, &
907 "The power of dx/Ld in the Kh resolution function. Any \n"//&
908 "positive integer may be used, although even integers \n"//&
909 "are more efficient to calculate. Setting this greater \n"//&
910 "than 100 results in a step-function being used.", &
911 units=
"nondim", default=2)
912 call get_param(param_file, mdl,
"VISC_RES_SCALE_COEF", cs%Res_coef_visc, &
913 "A coefficient that determines how Kh is scaled away if \n"//&
914 "RESOLN_SCALED_... is true, as \n"//&
915 "F = 1 / (1 + (KH_RES_SCALE_COEF*Rd/dx)^KH_RES_FN_POWER).\n"//&
916 "This function affects lateral viscosity, Kh, and not KhTh.", &
917 units=
"nondim", default=cs%Res_coef_khth)
918 call get_param(param_file, mdl,
"VISC_RES_FN_POWER", cs%Res_fn_power_visc, &
919 "The power of dx/Ld in the Kh resolution function. Any \n"//&
920 "positive integer may be used, although even integers \n"//&
921 "are more efficient to calculate. Setting this greater \n"//&
922 "than 100 results in a step-function being used.\n"//&
923 "This function affects lateral viscosity, Kh, and not KhTh.", &
924 units=
"nondim", default=cs%Res_fn_power_khth)
925 call get_param(param_file, mdl,
"INTERPOLATE_RES_FN", cs%interpolate_Res_fn, &
926 "If true, interpolate the resolution function to the \n"//&
927 "velocity points from the thickness points; otherwise \n"//&
928 "interpolate the wave speed and calculate the resolution \n"//&
929 "function independently at each point.", default=.true.)
930 call get_param(param_file, mdl,
"USE_VISBECK_SLOPE_BUG", cs%use_Visbeck_slope_bug, &
931 "If true, then retain a legacy bug in the calculation of weights \n"//&
932 "applied to isoneutral slopes. There was an erroneous k-indexing \n"//&
933 "for layer thicknesses. In addition, masking at coastlines was not \n"//&
934 "used which introduced potential restart issues. This flag will be \n"//&
935 "deprecated in a future release.", default=.false.)
936 if (cs%interpolate_Res_fn)
then 937 if (cs%Res_coef_visc .ne. cs%Res_coef_khth)
call mom_error(fatal, &
938 "MOM_lateral_mixing_coeffs.F90, VarMix_init:"//&
939 "When INTERPOLATE_RES_FN=True, VISC_RES_FN_POWER must equal KH_RES_SCALE_COEF.")
940 if (cs%Res_fn_power_visc .ne. cs%Res_fn_power_khth)
call mom_error(fatal, &
941 "MOM_lateral_mixing_coeffs.F90, VarMix_init:"//&
942 "When INTERPOLATE_RES_FN=True, VISC_RES_FN_POWER must equal KH_RES_FN_POWER.")
944 call get_param(param_file, mdl,
"GILL_EQUATORIAL_LD", gill_equatorial_ld, &
945 "If true, uses Gill's definition of the baroclinic\n"//&
946 "equatorial deformation radius, otherwise, if false, use\n"//&
947 "Pedlosky's definition. These definitions differ by a factor\n"//&
948 "of 2 infront of the beta term in the denominator. Gill's"//&
949 "is the more appropriate definition.\n", default=.false.)
950 if (gill_equatorial_ld)
then 956 do j=js-1,jeq ;
do i=is-1,ieq
957 cs%f2_dx2_q(i,j) = (g%dxBu(i,j)**2 + g%dyBu(i,j)**2) * &
958 max(g%CoriolisBu(i,j)**2, absurdly_small_freq2)
959 cs%beta_dx2_q(i,j) = oneortwo * (g%dxBu(i,j)**2 + g%dyBu(i,j)**2) * (sqrt(0.5 * &
960 ( (((g%CoriolisBu(i,j)-g%CoriolisBu(i-1,j)) * g%IdxCv(i,j))**2 + &
961 ((g%CoriolisBu(i+1,j)-g%CoriolisBu(i,j)) * g%IdxCv(i+1,j))**2) + &
962 (((g%CoriolisBu(i,j)-g%CoriolisBu(i,j-1)) * g%IdyCu(i,j))**2 + &
963 ((g%CoriolisBu(i,j+1)-g%CoriolisBu(i,j)) * g%IdyCu(i,j+1))**2) ) ))
966 do j=js,je ;
do i=is-1,ieq
967 cs%f2_dx2_u(i,j) = (g%dxCu(i,j)**2 + g%dyCu(i,j)**2) * &
968 max(0.5*(g%CoriolisBu(i,j)**2+g%CoriolisBu(i,j-1)**2), absurdly_small_freq2)
969 cs%beta_dx2_u(i,j) = oneortwo * (g%dxCu(i,j)**2 + g%dyCu(i,j)**2) * (sqrt( &
970 0.25*( (((g%CoriolisBu(i,j-1)-g%CoriolisBu(i-1,j-1)) * g%IdxCv(i,j-1))**2 + &
971 ((g%CoriolisBu(i+1,j)-g%CoriolisBu(i,j)) * g%IdxCv(i+1,j))**2) + &
972 (((g%CoriolisBu(i+1,j-1)-g%CoriolisBu(i,j-1)) * g%IdxCv(i+1,j-1))**2 + &
973 ((g%CoriolisBu(i,j)-g%CoriolisBu(i-1,j)) * g%IdxCv(i,j))**2) ) + &
974 ((g%CoriolisBu(i,j)-g%CoriolisBu(i,j-1)) * g%IdyCu(i,j))**2 ))
977 do j=js-1,jeq ;
do i=is,ie
978 cs%f2_dx2_v(i,j) = (g%dxCv(i,j)**2 + g%dyCv(i,j)**2) * &
979 max(0.5*(g%CoriolisBu(i,j)**2+g%CoriolisBu(i-1,j)**2), absurdly_small_freq2)
980 cs%beta_dx2_v(i,j) = oneortwo * (g%dxCv(i,j)**2 + g%dyCv(i,j)**2) * (sqrt( &
981 ((g%CoriolisBu(i,j)-g%CoriolisBu(i-1,j)) * g%IdxCv(i,j))**2 + &
982 0.25*( (((g%CoriolisBu(i,j)-g%CoriolisBu(i,j-1)) * g%IdyCu(i,j))**2 + &
983 ((g%CoriolisBu(i-1,j+1)-g%CoriolisBu(i-1,j)) * g%IdyCu(i-1,j+1))**2) + &
984 (((g%CoriolisBu(i,j+1)-g%CoriolisBu(i,j)) * g%IdyCu(i,j+1))**2 + &
985 ((g%CoriolisBu(i-1,j)-g%CoriolisBu(i-1,j-1)) * g%IdyCu(i-1,j))**2) ) ))
991 cs%id_Rd_dx = register_diag_field(
'ocean_model',
'Rd_dx', diag%axesT1, time, &
992 'Ratio between deformation radius and grid spacing',
'Nondim')
993 cs%calculate_Rd_dx = cs%calculate_Rd_dx .or. (cs%id_Rd_dx>0)
995 if (cs%calculate_Rd_dx)
then 996 cs%calculate_cg1 = .true.
997 allocate(cs%Rd_dx_h(isd:ied,jsd:jed)) ; cs%Rd_dx_h(:,:) = 0.0
998 allocate(cs%beta_dx2_h(isd:ied,jsd:jed)); cs%beta_dx2_h(:,:) = 0.0
999 allocate(cs%f2_dx2_h(isd:ied,jsd:jed)) ; cs%f2_dx2_h(:,:) = 0.0
1000 do j=js-1,je+1 ;
do i=is-1,ie+1
1001 cs%f2_dx2_h(i,j) = (g%dxT(i,j)**2 + g%dyT(i,j)**2) * &
1002 max(0.25 * ((g%CoriolisBu(i,j)**2 + g%CoriolisBu(i-1,j-1)**2) + &
1003 (g%CoriolisBu(i-1,j)**2 + g%CoriolisBu(i,j-1)**2)), &
1004 absurdly_small_freq2)
1005 cs%beta_dx2_h(i,j) = oneortwo * (g%dxT(i,j)**2 + g%dyT(i,j)**2) * (sqrt(0.5 * &
1006 ( (((g%CoriolisBu(i,j)-g%CoriolisBu(i-1,j)) * g%IdxCv(i,j))**2 + &
1007 ((g%CoriolisBu(i,j-1)-g%CoriolisBu(i-1,j-1)) * g%IdxCv(i,j-1))**2) + &
1008 (((g%CoriolisBu(i,j)-g%CoriolisBu(i,j-1)) * g%IdyCu(i,j))**2 + &
1009 ((g%CoriolisBu(i-1,j)-g%CoriolisBu(i-1,j-1)) * g%IdyCu(i-1,j))**2) ) ))
1013 if (cs%calculate_cg1)
then 1015 allocate(cs%cg1(isd:ied,jsd:jed)); cs%cg1(:,:) = 0.0
1016 call wave_speed_init(cs%wave_speed_CSp, use_ebt_mode=cs%Resoln_use_ebt, mono_n2_depth=n2_filter_depth)
1021 cs%use_variable_mixing = .true.
Ocean grid type. See mom_grid for details.