@@ -14,9 +14,7 @@ module Idealized_hurricane
14
14
! w/ T/S initializations in CVMix_tests (which should be moved
15
15
! into the main state_initialization to their utility
16
16
! for multiple example cases).
17
- ! To do
18
- ! 1. Remove the legacy SCM_idealized_hurricane_wind_forcing code
19
- !
17
+ ! December 2024: Removed the legacy subroutine SCM_idealized_hurricane_wind_forcing
20
18
21
19
use MOM_error_handler, only : MOM_error, FATAL
22
20
use MOM_file_parser, only : get_param, log_version, param_file_type
@@ -37,8 +35,6 @@ module Idealized_hurricane
37
35
! hurricane wind profile.
38
36
public idealized_hurricane_wind_forcing ! Public interface to update the idealized
39
37
! hurricane wind profile.
40
- public SCM_idealized_hurricane_wind_forcing ! Public interface to the legacy idealized
41
- ! hurricane wind profile for SCM.
42
38
43
39
! > Container for parameters describing idealized wind structure
44
40
type, public :: idealized_hurricane_CS ; private
@@ -656,196 +652,6 @@ subroutine idealized_hurricane_wind_profile(CS, US, absf, YY, XX, UOCN, VOCN, Tx
656
652
TY = US% L_to_Z * CS% rho_a * Cd * du10 * dV
657
653
end subroutine idealized_hurricane_wind_profile
658
654
659
- ! > This subroutine is primarily needed as a legacy for reproducing answers.
660
- ! ! It is included as an additional subroutine rather than padded into the previous
661
- ! ! routine with flags to ease its eventual removal. Its functionality is replaced
662
- ! ! with the new routines and it can be deleted when answer changes are acceptable.
663
- subroutine SCM_idealized_hurricane_wind_forcing (sfc_state , forces , day , G , US , CS )
664
- type (surface), intent (in ) :: sfc_state ! < Surface state structure
665
- type (mech_forcing), intent (inout ) :: forces ! < A structure with the driving mechanical forces
666
- type (time_type), intent (in ) :: day ! < Time in days
667
- type (ocean_grid_type), intent (inout ) :: G ! < Grid structure
668
- type (unit_scale_type), intent (in ) :: US ! < A dimensional unit scaling type
669
- type (idealized_hurricane_CS), pointer :: CS ! < Container for SCM parameters
670
- ! Local variables
671
- integer :: i, j, is, ie, js, je, Isq, Ieq, Jsq, Jeq
672
- integer :: isd, ied, jsd, jed, IsdB, IedB, JsdB, JedB
673
- real :: du10 ! The magnitude of the difference between the 10 m wind and the ocean flow [L T-1 ~> m s-1]
674
- real :: U10 ! The 10 m wind speed [L T-1 ~> m s-1]
675
- real :: A ! The radius of the maximum winds raised to the power given by B, used in the
676
- ! wind profile expression, in [km^B]
677
- real :: B ! A power used in the wind profile expression [nondim]
678
- real :: C ! A temporary variable in units of the square root of a specific volume [sqrt(m3 kg-1)]
679
- real :: rad ! The distance from the hurricane center [L ~> m]
680
- real :: radius10 ! The distance from the hurricane center to its edge [L ~> m]
681
- real :: rkm ! The distance from the hurricane center, sometimes scaled to km [L ~> m] or [1000 L ~> km]
682
- real :: f_local ! The local Coriolis parameter [T-1 ~> s-1]
683
- real :: xx ! x-position [L ~> m]
684
- real :: t0 ! Time at which the eye crosses the origin [T ~> s]
685
- real :: dP ! The pressure difference across the hurricane [R L2 T-2 ~> Pa]
686
- real :: rB ! The distance from the center raised to the power given by B, in [m^B]
687
- ! or [km^B] if BR_Bench is true.
688
- real :: Cd ! Air-sea drag coefficient [nondim]
689
- real :: Uocn, Vocn ! Surface ocean velocity components [L T-1 ~> m s-1]
690
- real :: dU, dV ! Air-sea differential motion [L T-1 ~> m s-1]
691
- ! Wind angle variables
692
- real :: Alph ! The wind inflow angle (positive outward) [radians]
693
- real :: Rstr ! A function of the position normalized by the radius of maximum winds [nondim]
694
- real :: A0 ! The axisymmetric inflow angle [degrees]
695
- real :: A1 ! The inflow angle asymmetry [degrees]
696
- real :: P1 ! The angle difference between the translation direction and the inflow direction [radians]
697
- real :: Adir ! The angle of the direction from the center to a point [radians]
698
- real :: transdir ! Translation direction [radians]
699
- real :: V_TS, U_TS ! Components of the translation speed [L T-1 ~> m s-1]
700
-
701
- ! Bounds for loops and memory allocation
702
- is = G% isc ; ie = G% iec ; js = G% jsc ; je = G% jec
703
- Isq = G% IscB ; Ieq = G% IecB ; Jsq = G% JscB ; Jeq = G% JecB
704
- isd = G% isd ; ied = G% ied ; jsd = G% jsd ; jed = G% jed
705
- IsdB = G% IsdB ; IedB = G% IedB ; JsdB = G% JsdB ; JedB = G% JedB
706
-
707
- ! Allocate the forcing arrays, if necessary.
708
- call allocate_mech_forcing(G, forces, stress= .true. , ustar= .true. , tau_mag= .true. )
709
-
710
- ! Implementing Holland (1980) parameteric wind profile
711
- !- -----------------------------------------------------------|
712
- t0 = 129600 .* US% s_to_T ! TC 'eye' crosses (0,0) at 36 hours |
713
- transdir = CS% pi ! translation direction (-x) |
714
- !- -----------------------------------------------------------|
715
- dP = CS% pressure_ambient - CS% pressure_central
716
- if (CS% answer_date < 20190101 ) then
717
- C = CS% max_windspeed / sqrt ( US% R_to_kg_m3* dP )
718
- B = C** 2 * US% R_to_kg_m3* CS% rho_a * exp (1.0 )
719
- if (CS% BR_Bench) then ! rho_a reset to value used in generated wind for benchmark test
720
- B = C** 2 * 1.2 * exp (1.0 )
721
- endif
722
- else
723
- B = (CS% max_windspeed** 2 / dP ) * CS% rho_a * exp (1.0 )
724
- endif
725
-
726
- if (CS% BR_Bench) then
727
- A = (US% L_to_m* CS% rad_max_wind / 1000 .)** B
728
- else
729
- A = (US% L_to_m* CS% rad_max_wind)** B
730
- endif
731
- ! f_local = f(x,y), but in the SCM it is constant
732
- if (CS% BR_Bench) then ! (CS%SCM_mode) then
733
- f_local = CS% f_column
734
- else
735
- f_local = G% CoriolisBu(is,js)
736
- endif
737
-
738
- ! Calculate x position relative to hurricane center as a function of time.
739
- xx = (t0 - time_type_to_real(day)* US% s_to_T) * CS% hurr_translation_spd * cos (transdir)
740
- rad = sqrt ((xx** 2 ) + (CS% dy_from_center** 2 ))
741
-
742
- ! rkm - rad converted to km for Holland prof.
743
- ! used in km due to error, correct implementation should
744
- ! not need rkm, but to match winds w/ experiment this must
745
- ! be maintained. Causes winds far from storm center to be a
746
- ! couple of m/s higher than the correct Holland prof.
747
- if (CS% BR_Bench) then
748
- rkm = rad/ 1000 .
749
- rB = (US% L_to_m* rkm)** B
750
- else
751
- ! if not comparing to benchmark, then use correct Holland prof.
752
- rkm = rad
753
- rB = (US% L_to_m* rad)** B
754
- endif
755
-
756
- ! Calculate U10 in the interior (inside of the hurricane edge radius),
757
- ! while adjusting U10 to 0 outside of the ambient wind radius.
758
- if (rad > 0.001 * CS% rad_max_wind .AND. rad < CS% rad_edge* CS% rad_max_wind) then
759
- U10 = sqrt ( A* B* dP* exp (- A/ rB)/ (CS% rho_a* rB) + 0.25 * (rkm* f_local)** 2 ) - 0.5 * rkm* f_local
760
- elseif (rad > CS% rad_edge* CS% rad_max_wind .AND. rad < CS% rad_ambient* CS% rad_max_wind) then
761
- radius10 = CS% rad_max_wind* CS% rad_edge
762
- if (CS% BR_Bench) then
763
- rkm = radius10/ 1000 .
764
- rB = (US% L_to_m* rkm)** B
765
- else
766
- rkm = radius10
767
- rB = (US% L_to_m* radius10)** B
768
- endif
769
- if (CS% edge_taper_bug) rad = radius10
770
- U10 = ( sqrt ( A* B* dP* exp (- A/ rB)/ (CS% rho_a* rB) + 0.25 * (rkm* f_local)** 2 ) - 0.5 * rkm* f_local) &
771
- * (CS% rad_ambient - rad/ CS% rad_max_wind)/ (CS% rad_ambient - CS% rad_edge)
772
- else
773
- U10 = 0 .
774
- endif
775
- Adir = atan2 (CS% dy_from_center,xx)
776
-
777
- ! Wind angle model following Zhang and Ulhorn (2012)
778
- ! ALPH is inflow angle positive outward.
779
- RSTR = min (CS% rad_edge, rad / CS% rad_max_wind)
780
- A0 = CS% A0_Rnorm* RSTR + CS% A0_speed* CS% max_windspeed + CS% A0_0
781
- A1 = - A0* (CS% A1_Rnorm* RSTR + CS% A1_speed* CS% hurr_translation_spd + CS% A1_0)
782
- P1 = (CS% P1_Rnorm* RSTR + CS% P1_speed* CS% hurr_translation_spd + CS% P1_0) * CS% pi/ 180 .
783
- ALPH = A0 - A1* cos ( (TRANSDIR - ADIR ) - P1)
784
- if (rad > CS% rad_edge* CS% rad_max_wind .AND. rad < CS% rad_ambient* CS% rad_max_wind) then
785
- ALPH = ALPH* (CS% rad_ambient - rad/ CS% rad_max_wind) / (CS% rad_ambient - CS% rad_edge)
786
- elseif (rad > CS% rad_ambient* CS% rad_max_wind) then
787
- ALPH = 0.0
788
- endif
789
- ALPH = ALPH * CS% Deg2Rad
790
-
791
- ! Prepare for wind calculation
792
- ! X_TS is component of translation speed added to wind vector
793
- ! due to background steering wind.
794
- U_TS = CS% hurr_translation_spd* 0.5 * cos (transdir)
795
- V_TS = CS% hurr_translation_spd* 0.5 * sin (transdir)
796
-
797
- ! Set the surface wind stresses, in [R L Z T-2 ~> Pa]. A positive taux
798
- ! accelerates the ocean to the (pseudo-)east.
799
- ! The i-loop extends to is-1 so that taux can be used later in the
800
- ! calculation of ustar - otherwise the lower bound would be Isq.
801
- do j= js,je ; do I= is-1 ,Ieq
802
- ! Turn off surface current for stress calculation to be
803
- ! consistent with test case.
804
- Uocn = 0 . ! sfc_state%u(I,j)
805
- Vocn = 0 . ! 0.25*( (sfc_state%v(i,J) + sfc_state%v(i+1,J-1)) + &
806
- ! (sfc_state%v(i+1,J) + sfc_state%v(i,J-1)) )
807
- ! Wind vector calculated from location/direction (sin/cos flipped b/c
808
- ! cyclonic wind is 90 deg. phase shifted from position angle).
809
- dU = U10* sin (Adir - CS% pi - Alph) - Uocn + U_TS
810
- dV = U10* cos (Adir - Alph) - Vocn + V_TS
811
- ! /----------------------------------------------------|
812
- ! Add a simple drag coefficient as a function of U10 |
813
- ! /----------------------------------------------------|
814
- du10 = sqrt ((du** 2 ) + (dv** 2 ))
815
- Cd = simple_wind_scaled_Cd(u10, du10, CS)
816
-
817
- forces% taux(I,j) = CS% rho_a * US% L_to_Z * G% mask2dCu(I,j) * Cd* du10* dU
818
- enddo ; enddo
819
-
820
- ! See notes above
821
- do J= js-1 ,Jeq ; do i= is,ie
822
- Uocn = 0 . ! 0.25*( (sfc_state%u(I,j) + sfc_state%u(I-1,j+1)) + &
823
- ! (sfc_state%u(I-1,j) + sfc_state%u(I,j+1)) )
824
- Vocn = 0 . ! sfc_state%v(i,J)
825
- dU = U10* sin (Adir - CS% pi - Alph) - Uocn + U_TS
826
- dV = U10* cos (Adir- Alph) - Vocn + V_TS
827
- du10 = sqrt ((du** 2 ) + (dv** 2 ))
828
- Cd = simple_wind_scaled_Cd(u10, du10, CS)
829
- forces% tauy(I,j) = CS% rho_a * US% L_to_Z * G% mask2dCv(I,j) * Cd* dU10* dV
830
- enddo ; enddo
831
-
832
- ! Set the surface friction velocity [Z T-1 ~> m s-1]. ustar is always positive.
833
- if (associated (forces% ustar)) then ; do j= js,je ; do i= is,ie
834
- ! This expression can be changed if desired, but need not be.
835
- forces% ustar(i,j) = G% mask2dT(i,j) * sqrt (US% L_to_Z * (CS% gustiness/ CS% Rho0 + &
836
- sqrt (0.5 * ((forces% taux(I-1 ,j)** 2 ) + (forces% taux(I,j)** 2 )) + &
837
- 0.5 * ((forces% tauy(i,J-1 )** 2 ) + (forces% tauy(i,J)** 2 )))/ CS% Rho0))
838
- enddo ; enddo ; endif
839
-
840
- ! > Set magnitude of the wind stress [R L Z T-2 ~> Pa]
841
- if (associated (forces% tau_mag)) then ; do j= js,je ; do i= is,ie
842
- forces% tau_mag(i,j) = G% mask2dT(i,j) * (CS% gustiness + &
843
- sqrt (0.5 * ((forces% taux(I-1 ,j)** 2 ) + (forces% taux(I,j)** 2 )) + &
844
- 0.5 * ((forces% tauy(i,J-1 )** 2 ) + (forces% tauy(i,J)** 2 ))))
845
- enddo ; enddo ; endif
846
-
847
- end subroutine SCM_idealized_hurricane_wind_forcing
848
-
849
655
! > This function returns the air-sea drag coefficient using a simple function of the air-sea velocity difference.
850
656
function simple_wind_scaled_Cd (u10 , du10 , CS ) result(Cd)
851
657
real , intent (in ) :: U10 ! < The 10 m wind speed [L T-1 ~> m s-1]
0 commit comments