@@ -41,7 +41,7 @@ Subroutine cvmix_kpp_driver()
41
41
real (cvmix_r8 ), parameter :: third = cvmix_one / real (3 ,cvmix_r8 )
42
42
43
43
! CVMix datatypes
44
- type (cvmix_data_type) :: CVmix_vars1, CVmix_vars4, CVmix_vars5
44
+ type (cvmix_data_type) :: CVmix_vars1, CVmix_vars4, CVmix_vars5, CVmix_vars7
45
45
46
46
real (cvmix_r8 ), dimension (:), allocatable , target :: Mdiff, Tdiff, Sdiff
47
47
real (cvmix_r8 ), dimension (:), allocatable , target :: zt, zw_iface, &
@@ -52,19 +52,23 @@ Subroutine cvmix_kpp_driver()
52
52
delta_vel_sqr, &
53
53
buoy_freq_iface
54
54
real (cvmix_r8 ), dimension (:,:), allocatable , target :: hor_vel
55
+ real (cvmix_r8 ), dimension (:), allocatable :: ones
55
56
real (cvmix_r8 ), dimension (2 ) :: ref_vel
56
57
real (cvmix_r8 ), dimension (4 ) :: shape_coeffs
57
- integer :: i, fid, kt, kw, nlev1, nlev3, nlev4, max_nlev4, OBL_levid4, nlev5
58
- real (cvmix_r8 ) :: hmix1, hmix5, ri_crit, layer_thick1, layer_thick4, &
59
- layer_thick5, OBL_depth4, OBL_depth5, N, Nsqr
58
+ integer :: i, fid, kt, kw, nlev1, nlev3, nlev4, max_nlev4, OBL_levid4, &
59
+ nlev5, nlev7
60
+ real (cvmix_r8 ) :: hmix1, hmix5, hmix7, ri_crit, layer_thick1, &
61
+ layer_thick4, layer_thick5, layer_thick7, OBL_depth4, &
62
+ OBL_depth5, OBL_depth7, N, Nsqr
60
63
real (cvmix_r8 ) :: kOBL_depth, Bslope, Vslope
61
64
real (cvmix_r8 ) :: sigma6, OBL_depth6, surf_buoy_force6, surf_fric_vel6, &
62
65
vonkarman6, tao, rho0, grav, alpha, Qnonpen, Cp0, &
63
66
w_m6, w_s6, wm6_true, ws6_true
64
- character (len= cvmix_strlen) :: interp_type_t1, interp_type_t4, interp_type_t5
67
+ character (len= cvmix_strlen) :: interp_type_t1, interp_type_t4, &
68
+ interp_type_t5, interp_type_t7
65
69
character (len= cvmix_strlen) :: filename
66
70
! True => run specified test
67
- logical :: ltest1, ltest2, ltest3, ltest4, ltest5, ltest6
71
+ logical :: ltest1, ltest2, ltest3, ltest4, ltest5, ltest6, ltest7
68
72
logical :: lnoDGat1 ! True => G'(1) = 0 (in test 4)
69
73
70
74
namelist/ kpp_col1_nml/ ltest1, nlev1, layer_thick1, interp_type_t1, hmix1, &
@@ -75,6 +79,7 @@ Subroutine cvmix_kpp_driver()
75
79
namelist/ kpp_col5_nml/ ltest5, nlev5, layer_thick5, hmix5, interp_type_t5
76
80
namelist/ kpp_col6_nml/ ltest6, vonkarman6, tao, rho0, grav, alpha, Qnonpen, &
77
81
Cp0, OBL_depth6
82
+ namelist/ kpp_col7_nml/ ltest7, nlev7, layer_thick7, hmix7, interp_type_t7
78
83
79
84
! Read namelists
80
85
@@ -117,12 +122,20 @@ Subroutine cvmix_kpp_driver()
117
122
Cp0 = real (3992 , cvmix_r8 )
118
123
OBL_depth6 = real (6000 , cvmix_r8 )
119
124
125
+ ! Defaults for test 7
126
+ ltest7 = .false.
127
+ nlev7 = 10
128
+ layer_thick7 = real (5 , cvmix_r8 )
129
+ hmix7 = real (17 , cvmix_r8 )
130
+ interp_type_t7 = " linear"
131
+
120
132
read (* , nml= kpp_col1_nml)
121
133
read (* , nml= kpp_col2_nml)
122
134
read (* , nml= kpp_col3_nml)
123
135
read (* , nml= kpp_col4_nml)
124
136
read (* , nml= kpp_col5_nml)
125
137
read (* , nml= kpp_col6_nml)
138
+ read (* , nml= kpp_col7_nml)
126
139
127
140
! Test 1: user sets up levels via namelist (constant thickness) and specifies
128
141
! critical Richardson number as well as depth parameter hmix1. The
@@ -590,6 +603,139 @@ Subroutine cvmix_kpp_driver()
590
603
591
604
end if ! ltest6
592
605
606
+ ! Test 7: Test 5, but lStokesMOST = .true.
607
+ if (ltest7) then
608
+ print * , " "
609
+ print * , " Test 7: Computing Bulk Richardson number (with StokesMOST)"
610
+ print * , " ----------"
611
+
612
+ ! using linear interpolation, averaging Nsqr, and setting Cv = 1.5 to
613
+ ! match LMD result
614
+ call cvmix_init_kpp(Cv = 1.5_cvmix_r8 , interp_type= interp_type_t7, &
615
+ lStokesMOST= .true. , lMonOb= .true. )
616
+
617
+ ! Set up vertical levels (centers and interfaces) and compute bulk
618
+ ! Richardson number
619
+ allocate (zt(nlev7), zw_iface(nlev7+1 ))
620
+ do kw= 1 ,nlev7+1
621
+ zw_iface(kw) = - layer_thick7* real (kw-1 , cvmix_r8 )
622
+ end do
623
+ do kt= 1 ,nlev7
624
+ zt(kt) = 0.5_cvmix_r8 * (zw_iface(kt)+ zw_iface(kt+1 ))
625
+ end do
626
+
627
+ ! Compute Br-B(d), |Vr-V(d)|^2, and Vt^2
628
+ allocate (buoyancy(nlev7), delta_vel_sqr(nlev7), hor_vel(nlev7,2 ), &
629
+ shear_sqr(nlev7), w_s(nlev7), Ri_bulk(nlev7), Ri_bulk2(nlev7), &
630
+ buoy_freq_iface(nlev7+1 ))
631
+
632
+ ref_vel(1 ) = 0.1_cvmix_r8
633
+ ref_vel(2 ) = cvmix_zero
634
+ N = 0.01_cvmix_r8
635
+ Nsqr = N* N
636
+ Bslope = - Nsqr
637
+ Vslope = - 0.1_cvmix_r8 / (real (nlev7,cvmix_r8 )* layer_thick7- hmix7)
638
+ do kt= 1 ,nlev7
639
+ if ((zt(kt).ge. - hmix7).or. (kt.eq. 1 )) then
640
+ buoyancy(kt) = Nsqr
641
+ hor_vel(kt,1 ) = 0.1_cvmix_r8
642
+ buoy_freq_iface(kt) = cvmix_zero
643
+ else
644
+ if (zw_iface(kt).ge. - hmix7) then
645
+ ! derivatives of buoyancy and horizontal velocity component are
646
+ ! discontinuous in this layer (no change -> non-zero linear change)
647
+ ! so we compute area-average of analytic function over layer
648
+ buoyancy(kt) = Bslope* (- zw_iface(kt+1 )- real (hmix7,cvmix_r8 ))** 2 / &
649
+ (real (2 ,cvmix_r8 )* layer_thick7) + Nsqr
650
+ hor_vel(kt,1 ) = Vslope* (- zw_iface(kt+1 )- real (hmix7,cvmix_r8 ))** 2 / &
651
+ (real (2 ,cvmix_r8 )* layer_thick7) + 0.1_cvmix_r8
652
+ else
653
+ buoyancy(kt) = Nsqr+ Bslope* (- zt(kt)- real (hmix7,cvmix_r8 ))
654
+ hor_vel(kt,1 ) = 0.1_cvmix_r8 + Vslope * &
655
+ (- zt(kt)- real (hmix7,cvmix_r8 ))
656
+ end if
657
+ buoy_freq_iface(kt) = sqrt (- (buoyancy(kt)- buoyancy(kt-1 )) / &
658
+ layer_thick7)
659
+ end if
660
+ ! Compute w_s with zeta=0 per LMD page 393
661
+ ! => w_s = von Karman * surf_fric_vel = 0.4*0.01 = 4e-3
662
+ call cvmix_kpp_compute_turbulent_scales(cvmix_zero, - zt(kt), &
663
+ buoyancy(1 ), 0.01_cvmix_r8 , &
664
+ w_s= w_s(kt))
665
+ hor_vel(kt,2 ) = cvmix_zero
666
+ delta_vel_sqr(kt) = (ref_vel(1 )- hor_vel(kt,1 ))** 2 + &
667
+ (ref_vel(2 )- hor_vel(kt,2 ))** 2
668
+ end do
669
+ buoy_freq_iface(nlev7+1 ) = N
670
+ ! MNL: test both uses of compute_bulk_Richardson
671
+ Ri_bulk = cvmix_kpp_compute_bulk_Richardson(zt, (buoyancy(1 )- buoyancy), &
672
+ delta_vel_sqr, &
673
+ Nsqr_iface = buoy_freq_iface** 2 , &
674
+ ws_cntr = w_s)
675
+
676
+ shear_sqr = cvmix_kpp_compute_unresolved_shear(zt, w_s, &
677
+ Nsqr_iface = buoy_freq_iface** 2 )
678
+ ! Note that Vt_shear_sqr is the fourth argument in compute_bulk_Richardson
679
+ ! so it does not need to declared explicitly (even though it is optional)
680
+ Ri_bulk2 = cvmix_kpp_compute_bulk_Richardson(zt, (buoyancy(1 )- buoyancy), &
681
+ delta_vel_sqr, shear_sqr)
682
+ allocate (ones(nlev7))
683
+ ones(:) = cvmix_one
684
+ call cvmix_kpp_compute_OBL_depth(Ri_bulk, zw_iface, OBL_depth7, &
685
+ kOBL_depth, zt, surf_fric= cvmix_one, &
686
+ surf_buoy= ones, Xi= ones)
687
+ deallocate (ones)
688
+ do kt= 1 ,nlev7
689
+ if (abs (Ri_bulk(kt)- Ri_bulk2(kt)).gt. 1e-12_cvmix_r8 ) then
690
+ print * , " WARNING: two Ri_bulk computations did not match!"
691
+ print * , zt(kt), Ri_bulk(kt), Ri_bulk2(kt)
692
+ else
693
+ print * , zt(kt), Ri_bulk(kt)
694
+ end if
695
+ end do
696
+ print * , " OBL has depth of " , OBL_depth7
697
+ #ifdef _NETCDF
698
+ print * , " Done! Data is stored in test7.nc, run plot_bulk_Rich.ncl " , &
699
+ " to see output."
700
+ #else
701
+ print * , " Done! Data is stored in test7.out, run plot_bulk_Rich.ncl " , &
702
+ " to see output."
703
+ #endif
704
+
705
+ CVmix_vars7% nlev = nlev7
706
+ CVmix_vars7% BoundaryLayerDepth = OBL_depth7
707
+ CVmix_vars7% zt_cntr = > zt
708
+ CVmix_vars7% BulkRichardson_cntr = > Ri_bulk
709
+ CVmix_vars7% Vx_cntr = > hor_vel(:,1 )
710
+ #ifdef _NETCDF
711
+ call cvmix_io_open(fid, " test7.nc" , " nc" )
712
+ #else
713
+ call cvmix_io_open(fid, " test7.out" , " ascii" )
714
+ #endif
715
+ call cvmix_output_write(fid, CVmix_vars7, (/ " zt " , &
716
+ " Ri_bulk " , &
717
+ " Vx " , &
718
+ " buoyancy" / ), buoyancy)
719
+ #ifdef _NETCDF
720
+ call cvmix_output_write_att(fid, " OBL_depth" , &
721
+ CVmix_vars7% BoundaryLayerDepth)
722
+ call cvmix_output_write_att(fid, " longname" , " ocean height (cell center)" ,&
723
+ " zt" )
724
+ call cvmix_output_write_att(fid, " units" , " m" , " zt" )
725
+ call cvmix_output_write_att(fid, " longname" , " horizontal velocity" , " U" )
726
+ call cvmix_output_write_att(fid, " units" , " m/s" , " U" )
727
+ call cvmix_output_write_att(fid, " units" , " m/s^2" , " buoyancy" )
728
+ call cvmix_output_write_att(fid, " longname" , " Bulk Richardson number" , &
729
+ " BulkRichardson" )
730
+ call cvmix_output_write_att(fid, " units" , " unitless" , " BulkRichardson" )
731
+ #endif
732
+ call cvmix_io_close(fid)
733
+
734
+ deallocate (zt, zw_iface)
735
+ deallocate (buoyancy, delta_vel_sqr, hor_vel, shear_sqr, w_s, Ri_bulk, &
736
+ Ri_bulk2, buoy_freq_iface)
737
+ end if ! ltest7
738
+
593
739
! EOC
594
740
595
741
End Subroutine cvmix_kpp_driver
0 commit comments