69 use mom_cpu_clock, only : cpu_clock_id, cpu_clock_begin, cpu_clock_end
84 use mom_io, only : east_face, north_face
87 use mom_time_manager, only : time_type,
operator(+),
operator(/), get_time, set_time
107 use data_override_mod
, only : data_override_init, data_override
109 implicit none ;
private 111 #include <MOM_memory.h> 121 logical :: use_temperature
122 logical :: restorebuoy
124 logical :: variable_winds
125 logical :: variable_buoyforce
132 real :: latent_heat_fusion
133 real :: latent_heat_vapor
134 real :: tau_x0, tau_y0
137 logical :: read_gust_2d
138 real,
pointer :: gust(:,:) => null()
141 real,
pointer :: t_restore(:,:) => null()
142 real,
pointer :: s_restore(:,:) => null()
143 real,
pointer :: dens_restore(:,:) => null()
145 integer :: buoy_last_lev_read = -1
147 real :: gyres_taux_const, gyres_taux_sin_amp, gyres_taux_cos_amp, gyres_taux_n_pis
152 real :: t_north, t_south
154 real :: s_north, s_south
157 logical :: first_call_set_forcing = .true.
158 logical :: archaic_omip_file = .true.
159 logical :: dataoverrideisinitialized = .false.
162 real :: constantheatforcing
164 character(len=8) :: wind_stagger
171 character(len=200) :: inputdir
172 character(len=200) :: wind_config
173 character(len=200) :: wind_file
174 character(len=200) :: buoy_config
176 character(len=200) :: longwave_file =
'' 177 character(len=200) :: shortwave_file =
'' 178 character(len=200) :: evaporation_file =
'' 179 character(len=200) :: sensibleheat_file =
'' 180 character(len=200) :: latentheat_file =
'' 182 character(len=200) :: rain_file =
'' 183 character(len=200) :: snow_file =
'' 184 character(len=200) :: runoff_file =
'' 186 character(len=200) :: longwaveup_file =
'' 187 character(len=200) :: shortwaveup_file =
'' 189 character(len=200) :: sstrestore_file =
'' 190 character(len=200) :: salinityrestore_file =
'' 192 character(len=80) :: &
193 stress_x_var =
'', stress_y_var =
'', ustar_var =
'', &
194 lw_var =
'', sw_var =
'', latent_var =
'', sens_var =
'', evap_var =
'', &
195 rain_var =
'', snow_var =
'', lrunoff_var =
'', frunoff_var =
'', &
196 sst_restore_var =
'', sss_restore_var =
'' 199 integer :: sw_nlev = -1, lw_nlev = -1, latent_nlev = -1, sens_nlev = -1
200 integer :: wind_nlev = -1, evap_nlev = -1, precip_nlev = -1, runoff_nlev = -1
201 integer :: sst_nlev = -1, sss_nlev = -1
204 integer :: wind_last_lev = -1
205 integer :: sw_last_lev = -1, lw_last_lev = -1, latent_last_lev = -1
206 integer :: sens_last_lev = -1
207 integer :: evap_last_lev = -1, precip_last_lev = -1, runoff_last_lev = -1
208 integer :: sst_last_lev = -1, sss_last_lev = -1
227 subroutine set_forcing(state, fluxes, day_start, day_interval, G, CS)
229 type(
forcing),
intent(inout) :: fluxes
230 type(time_type),
intent(in) :: day_start
231 type(time_type),
intent(in) :: day_interval
247 type(time_type) :: day_center
253 day_center = day_start + day_interval/2
254 call get_time(day_interval, intdt)
258 if (cs%variable_winds .or. cs%first_call_set_forcing)
then 260 if (trim(cs%wind_config) ==
"file")
then 262 elseif (trim(cs%wind_config) ==
"data_override")
then 264 elseif (trim(cs%wind_config) ==
"2gyre")
then 266 elseif (trim(cs%wind_config) ==
"1gyre")
then 268 elseif (trim(cs%wind_config) ==
"gyres")
then 270 elseif (trim(cs%wind_config) ==
"zero")
then 272 elseif (trim(cs%wind_config) ==
"const")
then 274 elseif (trim(cs%wind_config) ==
"MESO")
then 275 call meso_wind_forcing(state, fluxes, day_center, g, cs%MESO_forcing_CSp)
276 elseif (trim(cs%wind_config) ==
"SCM_ideal_hurr")
then 277 call scm_idealized_hurricane_wind_forcing(state, fluxes, day_center, g, cs%SCM_idealized_hurricane_CSp)
278 elseif (trim(cs%wind_config) ==
"SCM_CVmix_tests")
then 279 call scm_cvmix_tests_wind_forcing(state, fluxes, day_center, g, cs%SCM_CVmix_tests_CSp)
280 elseif (trim(cs%wind_config) ==
"USER")
then 281 call user_wind_forcing(state, fluxes, day_center, g, cs%user_forcing_CSp)
282 elseif (cs%variable_winds .and. .not.cs%first_call_set_forcing)
then 283 call mom_error(fatal, &
284 "MOM_surface_forcing: Variable winds defined with no wind config")
286 call mom_error(fatal, &
287 "MOM_surface_forcing:Unrecognized wind config "//trim(cs%wind_config))
312 if ((cs%variable_buoyforce .or. cs%first_call_set_forcing) .and. &
313 (.not.cs%adiabatic))
then 314 if (trim(cs%buoy_config) ==
"file")
then 317 elseif (trim(cs%buoy_config) ==
"data_override")
then 320 elseif (trim(cs%buoy_config) ==
"zero")
then 323 elseif (trim(cs%buoy_config) ==
"const")
then 326 elseif (trim(cs%buoy_config) ==
"linear")
then 329 elseif (trim(cs%buoy_config) ==
"MESO")
then 330 call meso_buoyancy_forcing(state, fluxes, day_center, dt, g, cs%MESO_forcing_CSp)
331 elseif (trim(cs%buoy_config) ==
"SCM_CVmix_tests")
then 332 call scm_cvmix_tests_buoyancy_forcing(state, fluxes, day_center, g, cs%SCM_CVmix_tests_CSp)
333 elseif (trim(cs%buoy_config) ==
"USER")
then 334 call user_buoyancy_forcing(state, fluxes, day_center, dt, g, cs%user_forcing_CSp)
335 elseif (trim(cs%buoy_config) ==
"BFB")
then 336 call bfb_buoyancy_forcing(state, fluxes, day_center, dt, g, cs%BFB_forcing_CSp)
337 elseif (trim(cs%buoy_config) ==
"NONE")
then 338 call mom_mesg(
"MOM_surface_forcing: buoyancy forcing has been set to omitted.")
339 elseif (cs%variable_buoyforce .and. .not.cs%first_call_set_forcing)
then 340 call mom_error(fatal, &
341 "MOM_surface_forcing: Variable buoy defined with no buoy config.")
343 call mom_error(fatal, &
344 "MOM_surface_forcing: Unrecognized buoy config "//trim(cs%buoy_config))
348 if (
associated(cs%tracer_flow_CSp))
then 349 if (.not.
associated(fluxes%tr_fluxes))
allocate(fluxes%tr_fluxes)
350 call call_tracer_set_forcing(state, fluxes, day_start, day_interval, g, cs%tracer_flow_CSp)
354 call user_alter_forcing(state, fluxes, day_center, g, cs%urf_CS)
356 cs%first_call_set_forcing = .false.
375 integer :: isd, ied, jsd, jed
376 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
380 if (
associated(fluxes%p_surf))
then 381 fluxes%p_surf(:,:) = 0.0
384 if ( cs%use_temperature )
then 393 if (cs%restorebuoy)
then 394 call safe_alloc_ptr(cs%T_Restore,isd,ied,jsd,jed)
395 call safe_alloc_ptr(fluxes%heat_added,isd,ied,jsd,jed)
396 call safe_alloc_ptr(cs%S_Restore,isd,ied,jsd,jed)
401 call safe_alloc_ptr(fluxes%buoy,isd,ied,jsd,jed)
402 if (cs%restorebuoy)
call safe_alloc_ptr(cs%Dens_Restore,isd,ied,jsd,jed)
411 type(
forcing),
intent(inout) :: fluxes
412 real,
intent(in) :: tau_x0
413 real,
intent(in) :: tau_y0
414 type(time_type),
intent(in) :: day
428 integer :: i, j, is, ie, js, je, Isq, Ieq, Jsq, Jeq
429 integer :: isd, ied, jsd, jed, IsdB, IedB, JsdB, JedB
431 call calltree_enter(
"wind_forcing_const, MOM_surface_forcing.F90")
432 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
433 isq = g%IscB ; ieq = g%IecB ; jsq = g%JscB ; jeq = g%JecB
434 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
435 isdb = g%IsdB ; iedb = g%IedB ; jsdb = g%JsdB ; jedb = g%JedB
438 mag_tau = sqrt( tau_x0**2 + tau_y0**2)
440 do j=js,je ;
do i=is-1,ieq
441 fluxes%taux(i,j) = tau_x0
444 do j=js-1,jeq ;
do i=is,ie
445 fluxes%tauy(i,j) = tau_y0
448 if (cs%read_gust_2d)
then 449 if (
associated(fluxes%ustar))
then ;
do j=js,je ;
do i=is,ie
450 fluxes%ustar(i,j) = sqrt( ( mag_tau + cs%gust(i,j) ) / cs%Rho0 )
451 enddo ;
enddo ;
endif 453 if (
associated(fluxes%ustar))
then ;
do j=js,je ;
do i=is,ie
454 fluxes%ustar(i,j) = sqrt( ( mag_tau + cs%gust_const ) / cs%Rho0 )
455 enddo ;
enddo ;
endif 464 type(
forcing),
intent(inout) :: fluxes
465 type(time_type),
intent(in) :: day
479 integer :: i, j, is, ie, js, je, Isq, Ieq, Jsq, Jeq
480 integer :: isd, ied, jsd, jed, IsdB, IedB, JsdB, JedB
482 call calltree_enter(
"wind_forcing_2gyre, MOM_surface_forcing.F90")
483 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
484 isq = g%IscB ; ieq = g%IecB ; jsq = g%JscB ; jeq = g%JecB
485 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
486 isdb = g%IsdB ; iedb = g%IedB ; jsdb = g%JsdB ; jedb = g%JedB
491 do j=js,je ;
do i=is-1,ieq
492 fluxes%taux(i,j) = 0.1*(1.0 - cos(2.0*pi*(g%geoLatCu(i,j)-cs%South_lat) / &
496 do j=js-1,jeq ;
do i=is,ie
497 fluxes%tauy(i,j) = 0.0
506 type(
forcing),
intent(inout) :: fluxes
507 type(time_type),
intent(in) :: day
521 integer :: i, j, is, ie, js, je, Isq, Ieq, Jsq, Jeq
522 integer :: isd, ied, jsd, jed, IsdB, IedB, JsdB, JedB
524 call calltree_enter(
"wind_forcing_1gyre, MOM_surface_forcing.F90")
525 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
526 isq = g%IscB ; ieq = g%IecB ; jsq = g%JscB ; jeq = g%JecB
527 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
528 isdb = g%IsdB ; iedb = g%IedB ; jsdb = g%JsdB ; jedb = g%JedB
533 do j=js,je ;
do i=is-1,ieq
534 fluxes%taux(i,j) =-0.2*cos(pi*(g%geoLatCu(i,j)-cs%South_lat)/cs%len_lat)
537 do j=js-1,jeq ;
do i=is,ie
538 fluxes%tauy(i,j) = 0.0
547 type(
forcing),
intent(inout) :: fluxes
548 type(time_type),
intent(in) :: day
562 integer :: i, j, is, ie, js, je, Isq, Ieq, Jsq, Jeq
563 integer :: isd, ied, jsd, jed, IsdB, IedB, JsdB, JedB
565 call calltree_enter(
"wind_forcing_gyres, MOM_surface_forcing.F90")
566 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
567 isq = g%IscB ; ieq = g%IecB ; jsq = g%JscB ; jeq = g%JecB
568 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
569 isdb = g%IsdB ; iedb = g%IedB ; jsdb = g%JsdB ; jedb = g%JedB
574 do j=jsd,jed ;
do i=is-1,iedb
575 y = (g%geoLatCu(i,j)-cs%South_lat)/cs%len_lat
576 fluxes%taux(i,j) = cs%gyres_taux_const + &
577 ( cs%gyres_taux_sin_amp*sin(cs%gyres_taux_n_pis*pi*y) &
578 + cs%gyres_taux_cos_amp*cos(cs%gyres_taux_n_pis*pi*y) )
581 do j=js-1,jedb ;
do i=isd,ied
582 fluxes%tauy(i,j) = 0.0
586 do j=js,je ;
do i=is,ie
587 fluxes%ustar(i,j) = sqrt(sqrt(0.5*(fluxes%tauy(i,j-1)*fluxes%tauy(i,j-1) + &
588 fluxes%tauy(i,j)*fluxes%tauy(i,j) + fluxes%taux(i-1,j)*fluxes%taux(i-1,j) + &
589 fluxes%taux(i,j)*fluxes%taux(i,j)))/cs%Rho0 + (cs%gust_const/cs%Rho0))
598 type(
forcing),
intent(inout) :: fluxes
599 type(time_type),
intent(in) :: day
612 character(len=200) :: filename
613 real :: temp_x(szi_(g),szj_(g))
614 real :: temp_y(szi_(g),szj_(g))
615 integer :: time_lev_daily
616 integer :: time_lev_monthly
618 integer :: days, seconds
619 integer :: i, j, is, ie, js, je, Isq, Ieq, Jsq, Jeq
620 integer :: isd, ied, jsd, jed, IsdB, IedB, JsdB, JedB
621 logical :: read_Ustar
623 call calltree_enter(
"wind_forcing_from_file, MOM_surface_forcing.F90")
624 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
625 isq = g%IscB ; ieq = g%IecB ; jsq = g%JscB ; jeq = g%JecB
626 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
627 isdb = g%IsdB ; iedb = g%IedB ; jsdb = g%JsdB ; jedb = g%JedB
629 call get_time(day,seconds,days)
630 time_lev_daily = days - 365*floor(
real(days) / 365.0)
632 if (time_lev_daily < 31)
then ; time_lev_monthly = 0
633 else if (time_lev_daily < 59)
then ; time_lev_monthly = 1
634 else if (time_lev_daily < 90)
then ; time_lev_monthly = 2
635 else if (time_lev_daily < 120)
then ; time_lev_monthly = 3
636 else if (time_lev_daily < 151)
then ; time_lev_monthly = 4
637 else if (time_lev_daily < 181)
then ; time_lev_monthly = 5
638 else if (time_lev_daily < 212)
then ; time_lev_monthly = 6
639 else if (time_lev_daily < 243)
then ; time_lev_monthly = 7
640 else if (time_lev_daily < 273)
then ; time_lev_monthly = 8
641 else if (time_lev_daily < 304)
then ; time_lev_monthly = 9
642 else if (time_lev_daily < 334)
then ; time_lev_monthly = 10
643 else ; time_lev_monthly = 11
646 time_lev_daily = time_lev_daily+1
647 time_lev_monthly = time_lev_monthly+1
649 select case (cs%wind_nlev)
650 case (12) ; time_lev = time_lev_monthly
651 case (365) ; time_lev = time_lev_daily
652 case default ; time_lev = 1
655 if (time_lev /= cs%wind_last_lev)
then 656 filename = trim(cs%wind_file)
657 read_ustar = (len_trim(cs%ustar_var) > 0)
661 select case (
uppercase(cs%wind_stagger(1:1)) )
663 temp_x(:,:) = 0.0 ; temp_y(:,:) = 0.0
664 call read_data(filename,cs%stress_x_var,temp_x(:,:), &
665 domain=g%Domain%mpp_domain,timelevel=time_lev)
666 call read_data(filename,cs%stress_y_var,temp_y(:,:), &
667 domain=g%Domain%mpp_domain,timelevel=time_lev)
669 call pass_vector(temp_x, temp_y, g%Domain, to_all, agrid)
670 do j=js,je ;
do i=is-1,ieq
671 fluxes%taux(i,j) = 0.5 * cs%wind_scale * (temp_x(i,j) + temp_x(i+1,j))
673 do j=js-1,jeq ;
do i=is,ie
674 fluxes%tauy(i,j) = 0.5 * cs%wind_scale * (temp_y(i,j) + temp_y(i,j+1))
677 if (.not.read_ustar)
then 678 if (cs%read_gust_2d)
then 679 do j=js,je ;
do i=is,ie
680 fluxes%ustar(i,j) = sqrt((sqrt(temp_x(i,j)*temp_x(i,j) + &
681 temp_y(i,j)*temp_y(i,j)) + cs%gust(i,j)) / cs%Rho0)
684 do j=js,je ;
do i=is,ie
685 fluxes%ustar(i,j) = sqrt(sqrt(temp_x(i,j)*temp_x(i,j) + &
686 temp_y(i,j)*temp_y(i,j))/cs%Rho0 + (cs%gust_const/cs%Rho0))
691 if (g%symmetric)
then 692 if (.not.
associated(g%Domain_aux))
call mom_error(fatal, &
693 " wind_forcing_from_file with C-grid input and symmetric memory "//&
694 " called with a non-associated auxiliary domain in the grid type.")
697 temp_x(:,:) = 0.0 ; temp_y(:,:) = 0.0
698 call read_data(filename, cs%stress_x_var, temp_x(:,:), position=east_face, &
699 domain=g%Domain_aux%mpp_domain, timelevel=time_lev)
700 call read_data(filename, cs%stress_y_var, temp_y(:,:), position=north_face, &
701 domain=g%Domain_aux%mpp_domain, timelevel=time_lev)
703 do j=js,je ;
do i=is,ie
704 fluxes%taux(i,j) = cs%wind_scale * temp_x(i,j)
705 fluxes%tauy(i,j) = cs%wind_scale * temp_y(i,j)
709 call read_data(filename, cs%stress_x_var, fluxes%taux(:,:), &
710 domain=g%Domain%mpp_domain, position=east_face, &
712 call read_data(filename, cs%stress_y_var, fluxes%tauy(:,:), &
713 domain=g%Domain%mpp_domain, position=north_face, &
716 if (cs%wind_scale /= 1.0)
then 717 do j=js,je ;
do i=isq,ieq
718 fluxes%taux(i,j) = cs%wind_scale * fluxes%taux(i,j)
720 do j=jsq,jeq ;
do i=is,ie
721 fluxes%tauy(i,j) = cs%wind_scale * fluxes%tauy(i,j)
726 call pass_vector(fluxes%taux, fluxes%tauy, g%Domain, to_all)
727 if (.not.read_ustar)
then 728 if (cs%read_gust_2d)
then 729 do j=js, je ;
do i=is, ie
730 fluxes%ustar(i,j) = sqrt((sqrt(0.5*((fluxes%tauy(i,j-1)**2 + &
731 fluxes%tauy(i,j)**2) + (fluxes%taux(i-1,j)**2 + &
732 fluxes%taux(i,j)**2))) + cs%gust(i,j)) / cs%Rho0 )
735 do j=js, je ;
do i=is, ie
736 fluxes%ustar(i,j) = sqrt(sqrt(0.5*((fluxes%tauy(i,j-1)**2 + &
737 fluxes%tauy(i,j)**2) + (fluxes%taux(i-1,j)**2 + &
738 fluxes%taux(i,j)**2)))/cs%Rho0 + (cs%gust_const/cs%Rho0))
743 call mom_error(fatal,
"wind_forcing_from_file: Unrecognized stagger "//&
744 trim(cs%wind_stagger)//
" is not 'A' or 'C'.")
748 call read_data(filename, cs%Ustar_var, fluxes%ustar(:,:), &
749 domain=g%Domain%mpp_domain, timelevel=time_lev)
752 cs%wind_last_lev = time_lev
762 type(
forcing),
intent(inout) :: fluxes
763 type(time_type),
intent(in) :: day
775 real :: temp_x(szi_(g),szj_(g))
776 real :: temp_y(szi_(g),szj_(g))
777 integer :: i, j, is_in, ie_in, js_in, je_in
778 logical :: read_uStar
780 call calltree_enter(
"wind_forcing_by_data_override, MOM_surface_forcing.F90")
782 if (.not.cs%dataOverrideIsInitialized)
then 784 call data_override_init(ocean_domain_in=g%Domain%mpp_domain)
785 cs%dataOverrideIsInitialized = .true.
788 is_in = g%isc - g%isd + 1
789 ie_in = g%iec - g%isd + 1
790 js_in = g%jsc - g%jsd + 1
791 je_in = g%jec - g%jsd + 1
793 temp_x(:,:) = 0.0 ; temp_y(:,:) = 0.0
794 call data_override(
'OCN',
'taux', temp_x, day, is_in=is_in, ie_in=ie_in, js_in=js_in, je_in=je_in)
795 call data_override(
'OCN',
'tauy', temp_y, day, is_in=is_in, ie_in=ie_in, js_in=js_in, je_in=je_in)
796 call pass_vector(temp_x, temp_y, g%Domain, to_all, agrid)
798 do j=g%jsc,g%jec ;
do i=g%isc-1,g%IecB
799 fluxes%taux(i,j) = 0.5 * (temp_x(i,j) + temp_x(i+1,j))
801 do j=g%jsc-1,g%JecB ;
do i=g%isc,g%iec
802 fluxes%tauy(i,j) = 0.5 * (temp_y(i,j) + temp_y(i,j+1))
805 read_ustar = (len_trim(cs%ustar_var) > 0)
807 call data_override(
'OCN',
'ustar', fluxes%ustar, day, is_in=is_in, ie_in=ie_in, js_in=js_in, je_in=je_in)
809 if (cs%read_gust_2d)
then 810 call data_override(
'OCN',
'gust', cs%gust, day, is_in=is_in, ie_in=ie_in, js_in=js_in, je_in=je_in)
811 do j=g%jsc,g%jec ;
do i=g%isc,g%iec
812 fluxes%ustar(i,j) = sqrt((sqrt(temp_x(i,j)*temp_x(i,j) + &
813 temp_y(i,j)*temp_y(i,j)) + cs%gust(i,j)) / cs%Rho0)
816 do j=g%jsc,g%jec ;
do i=g%isc,g%iec
817 fluxes%ustar(i,j) = sqrt(sqrt(temp_x(i,j)*temp_x(i,j) + &
818 temp_y(i,j)*temp_y(i,j))/cs%Rho0 + (cs%gust_const/cs%Rho0))
823 call pass_vector(fluxes%taux, fluxes%tauy, g%Domain, to_all)
832 type(
forcing),
intent(inout) :: fluxes
833 type(time_type),
intent(in) :: day
834 real,
intent(in) :: dt
852 real,
dimension(SZI_(G),SZJ_(G)) :: &
865 integer :: time_lev_daily
866 integer :: time_lev_monthly
869 integer :: days, seconds
870 integer :: i, j, is, ie, js, je
872 call calltree_enter(
"buoyancy_forcing_from_files, MOM_surface_forcing.F90")
874 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
876 if (cs%use_temperature) rhoxcp = cs%Rho0 * fluxes%C_p
880 call get_time(day,seconds,days)
882 time_lev_daily = days - 365*floor(
real(days) / 365.0)
884 if (time_lev_daily < 31)
then ; time_lev_monthly = 0
885 else if (time_lev_daily < 59)
then ; time_lev_monthly = 1
886 else if (time_lev_daily < 90)
then ; time_lev_monthly = 2
887 else if (time_lev_daily < 120)
then ; time_lev_monthly = 3
888 else if (time_lev_daily < 151)
then ; time_lev_monthly = 4
889 else if (time_lev_daily < 181)
then ; time_lev_monthly = 5
890 else if (time_lev_daily < 212)
then ; time_lev_monthly = 6
891 else if (time_lev_daily < 243)
then ; time_lev_monthly = 7
892 else if (time_lev_daily < 273)
then ; time_lev_monthly = 8
893 else if (time_lev_daily < 304)
then ; time_lev_monthly = 9
894 else if (time_lev_daily < 334)
then ; time_lev_monthly = 10
895 else ; time_lev_monthly = 11
898 time_lev_daily = time_lev_daily +1
899 time_lev_monthly = time_lev_monthly+1
901 if (time_lev_daily /= cs%buoy_last_lev_read)
then 904 select case (cs%LW_nlev)
905 case (12) ; time_lev = time_lev_monthly
906 case (365) ; time_lev = time_lev_daily
907 case default ; time_lev = 1
909 call read_data(cs%longwave_file, cs%LW_var, fluxes%LW(:,:), &
910 domain=g%Domain%mpp_domain, timelevel=time_lev)
911 if (cs%archaic_OMIP_file)
then 912 call read_data(cs%longwaveup_file, &
913 "lwup_sfc",temp(:,:), domain=g%Domain%mpp_domain, timelevel=time_lev)
914 do j=js,je ;
do i=is,ie ; fluxes%LW(i,j) = fluxes%LW(i,j) - temp(i,j) ;
enddo ;
enddo 916 cs%LW_last_lev = time_lev
919 select case (cs%evap_nlev)
920 case (12) ; time_lev = time_lev_monthly
921 case (365) ; time_lev = time_lev_daily
922 case default ; time_lev = 1
924 if (cs%archaic_OMIP_file)
then 925 call read_data(cs%evaporation_file, cs%evap_var, temp(:,:), &
926 domain=g%Domain%mpp_domain, timelevel=time_lev)
927 do j=js,je ;
do i=is,ie
928 fluxes%latent(i,j) = -cs%latent_heat_vapor*temp(i,j)
929 fluxes%evap(i,j) = -temp(i,j)
930 fluxes%latent_evap_diag(i,j) = fluxes%latent(i,j)
933 call read_data(cs%evaporation_file, cs%evap_var, fluxes%evap(:,:), &
934 domain=g%Domain%mpp_domain, timelevel=time_lev)
936 cs%evap_last_lev = time_lev
938 select case (cs%latent_nlev)
939 case (12) ; time_lev = time_lev_monthly
940 case (365) ; time_lev = time_lev_daily
941 case default ; time_lev = 1
943 if (.not.cs%archaic_OMIP_file)
then 944 call read_data(cs%latentheat_file, cs%latent_var, fluxes%latent(:,:), &
945 domain=g%Domain%mpp_domain, timelevel=time_lev)
946 do j=js,je ;
do i=is,ie
947 fluxes%latent_evap_diag(i,j) = fluxes%latent(i,j)
950 cs%latent_last_lev = time_lev
952 select case (cs%sens_nlev)
953 case (12) ; time_lev = time_lev_monthly
954 case (365) ; time_lev = time_lev_daily
955 case default ; time_lev = 1
957 if (cs%archaic_OMIP_file)
then 958 call read_data(cs%sensibleheat_file, cs%sens_var, temp(:,:), &
959 domain=g%Domain%mpp_domain, timelevel=time_lev)
960 do j=js,je ;
do i=is,ie ; fluxes%sens(i,j) = -temp(i,j) ;
enddo ;
enddo 962 call read_data(cs%sensibleheat_file, cs%sens_var, fluxes%sens(:,:), &
963 domain=g%Domain%mpp_domain, timelevel=time_lev)
965 cs%sens_last_lev = time_lev
967 select case (cs%SW_nlev)
968 case (12) ; time_lev = time_lev_monthly
969 case (365) ; time_lev = time_lev_daily
970 case default ; time_lev = 1
972 call read_data(cs%shortwave_file, cs%SW_var, fluxes%sw(:,:), &
973 domain=g%Domain%mpp_domain, timelevel=time_lev)
974 if (cs%archaic_OMIP_file)
then 975 call read_data(cs%shortwaveup_file,
"swup_sfc", temp(:,:), &
976 domain=g%Domain%mpp_domain, timelevel=time_lev)
977 do j=js,je ;
do i=is,ie
978 fluxes%sw(i,j) = fluxes%sw(i,j) - temp(i,j)
981 cs%SW_last_lev = time_lev
983 select case (cs%precip_nlev)
984 case (12) ; time_lev = time_lev_monthly
985 case (365) ; time_lev = time_lev_daily
986 case default ; time_lev = 1
988 call read_data(cs%snow_file, cs%snow_var, &
989 fluxes%fprec(:,:), domain=g%Domain%mpp_domain, timelevel=time_lev)
990 call read_data(cs%rain_file, cs%rain_var, &
991 fluxes%lprec(:,:), domain=g%Domain%mpp_domain, timelevel=time_lev)
992 if (cs%archaic_OMIP_file)
then 993 do j=js,je ;
do i=is,ie
994 fluxes%lprec(i,j) = fluxes%lprec(i,j) - fluxes%fprec(i,j)
997 cs%precip_last_lev = time_lev
999 select case (cs%runoff_nlev)
1000 case (12) ; time_lev = time_lev_monthly
1001 case (365) ; time_lev = time_lev_daily
1002 case default ; time_lev = 1
1004 if (cs%archaic_OMIP_file)
then 1005 call read_data(cs%runoff_file, cs%lrunoff_var, temp(:,:), &
1006 domain=g%Domain%mpp_domain, timelevel=time_lev)
1007 do j=js,je ;
do i=is,ie
1008 fluxes%lrunoff(i,j) = temp(i,j)*g%IareaT(i,j)
1010 call read_data(cs%runoff_file, cs%frunoff_var, temp(:,:), &
1011 domain=g%Domain%mpp_domain, timelevel=time_lev)
1012 do j=js,je ;
do i=is,ie
1013 fluxes%frunoff(i,j) = temp(i,j)*g%IareaT(i,j)
1016 call read_data(cs%runoff_file, cs%lrunoff_var, fluxes%lrunoff(:,:), &
1017 domain=g%Domain%mpp_domain, timelevel=time_lev)
1018 call read_data(cs%runoff_file, cs%frunoff_var, fluxes%frunoff(:,:), &
1019 domain=g%Domain%mpp_domain, timelevel=time_lev)
1021 cs%runoff_last_lev = time_lev
1024 if (cs%restorebuoy)
then 1025 select case (cs%SST_nlev)
1026 case (12) ; time_lev = time_lev_monthly
1027 case (365) ; time_lev = time_lev_daily
1028 case default ; time_lev = 1
1030 call read_data(cs%SSTrestore_file, cs%SST_restore_var, &
1031 cs%T_Restore(:,:), domain=g%Domain%mpp_domain, timelevel=time_lev)
1032 cs%SST_last_lev = time_lev
1034 select case (cs%SSS_nlev)
1035 case (12) ; time_lev = time_lev_monthly
1036 case (365) ; time_lev = time_lev_daily
1037 case default ; time_lev = 1
1039 call read_data(cs%salinityrestore_file, cs%SSS_restore_var, &
1040 cs%S_Restore(:,:), domain=g%Domain%mpp_domain, timelevel=time_lev)
1041 cs%SSS_last_lev = time_lev
1043 cs%buoy_last_lev_read = time_lev_daily
1051 do j=js,je ;
do i=is,ie
1052 fluxes%evap(i,j) = fluxes%evap(i,j) * g%mask2dT(i,j)
1053 fluxes%lprec(i,j) = fluxes%lprec(i,j) * g%mask2dT(i,j)
1054 fluxes%fprec(i,j) = fluxes%fprec(i,j) * g%mask2dT(i,j)
1055 fluxes%lrunoff(i,j) = fluxes%lrunoff(i,j) * g%mask2dT(i,j)
1056 fluxes%frunoff(i,j) = fluxes%frunoff(i,j) * g%mask2dT(i,j)
1057 fluxes%LW(i,j) = fluxes%LW(i,j) * g%mask2dT(i,j)
1058 fluxes%sens(i,j) = fluxes%sens(i,j) * g%mask2dT(i,j)
1059 fluxes%sw(i,j) = fluxes%sw(i,j) * g%mask2dT(i,j)
1060 fluxes%latent(i,j) = fluxes%latent(i,j) * g%mask2dT(i,j)
1062 fluxes%latent_evap_diag(i,j) = fluxes%latent_evap_diag(i,j) * g%mask2dT(i,j)
1063 fluxes%latent_fprec_diag(i,j) = -fluxes%fprec(i,j)*cs%latent_heat_fusion
1064 fluxes%latent_frunoff_diag(i,j) = -fluxes%frunoff(i,j)*cs%latent_heat_fusion
1071 if (cs%restorebuoy)
then 1073 if (cs%use_temperature)
then 1074 do j=js,je ;
do i=is,ie
1075 if (g%mask2dT(i,j) > 0)
then 1076 fluxes%heat_added(i,j) = g%mask2dT(i,j) * &
1077 ((cs%T_Restore(i,j) - state%SST(i,j)) * rhoxcp * cs%Flux_const)
1078 fluxes%vprec(i,j) = - (cs%Rho0*cs%Flux_const) * &
1079 (cs%S_Restore(i,j) - state%SSS(i,j)) / &
1080 (0.5*(state%SSS(i,j) + cs%S_Restore(i,j)))
1082 fluxes%heat_added(i,j) = 0.0
1083 fluxes%vprec(i,j) = 0.0
1087 do j=js,je ;
do i=is,ie
1088 if (g%mask2dT(i,j) > 0)
then 1089 fluxes%buoy(i,j) = (cs%Dens_Restore(i,j) - state%sfc_density(i,j)) * &
1090 (cs%G_Earth*cs%Flux_const/cs%Rho0)
1092 fluxes%buoy(i,j) = 0.0
1098 if (.not.cs%use_temperature)
then 1099 call mom_error(fatal,
"buoyancy_forcing in MOM_surface_forcing: "// &
1100 "The fluxes need to be defined without RESTOREBUOY.")
1121 type(
forcing),
intent(inout) :: fluxes
1122 type(time_type),
intent(in) :: day
1123 real,
intent(in) :: dt
1141 real,
dimension(SZI_(G),SZJ_(G)) :: &
1153 integer :: time_lev_daily
1154 integer :: time_lev_monthly
1155 integer :: itime_lev
1157 integer :: days, seconds
1158 integer :: i, j, is, ie, js, je, isd, ied, jsd, jed
1159 integer :: is_in, ie_in, js_in, je_in
1161 call calltree_enter(
"buoyancy_forcing_from_data_override, MOM_surface_forcing.F90")
1163 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
1164 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
1166 if (cs%use_temperature) rhoxcp = cs%Rho0 * fluxes%C_p
1169 if (.not.cs%dataOverrideIsInitialized)
then 1170 call data_override_init(ocean_domain_in=g%Domain%mpp_domain)
1171 cs%dataOverrideIsInitialized = .true.
1174 is_in = g%isc - g%isd + 1
1175 ie_in = g%iec - g%isd + 1
1176 js_in = g%jsc - g%jsd + 1
1177 je_in = g%jec - g%jsd + 1
1179 call data_override(
'OCN',
'lw', fluxes%LW(:,:), day, &
1180 is_in=is_in, ie_in=ie_in, js_in=js_in, je_in=je_in)
1181 call data_override(
'OCN',
'evap', fluxes%evap(:,:), day, &
1182 is_in=is_in, ie_in=ie_in, js_in=js_in, je_in=je_in)
1185 do j=js,je ;
do i=is,ie
1186 fluxes%evap(i,j) = -fluxes%evap(i,j)
1188 fluxes%latent(i,j) = cs%latent_heat_vapor*fluxes%evap(i,j)
1189 fluxes%latent_evap_diag(i,j) = fluxes%latent(i,j)
1192 call data_override(
'OCN',
'sens', fluxes%sens(:,:), day, &
1193 is_in=is_in, ie_in=ie_in, js_in=js_in, je_in=je_in)
1196 do j=js,je ;
do i=is,ie
1197 fluxes%sens(i,j) = -fluxes%sens(i,j)
1201 call data_override(
'OCN',
'sw', fluxes%sw(:,:), day, &
1202 is_in=is_in, ie_in=ie_in, js_in=js_in, je_in=je_in)
1204 call data_override(
'OCN',
'snow', fluxes%fprec(:,:), day, &
1205 is_in=is_in, ie_in=ie_in, js_in=js_in, je_in=je_in)
1207 call data_override(
'OCN',
'rain', fluxes%lprec(:,:), day, &
1208 is_in=is_in, ie_in=ie_in, js_in=js_in, je_in=je_in)
1210 call data_override(
'OCN',
'runoff', fluxes%lrunoff(:,:), day, &
1211 is_in=is_in, ie_in=ie_in, js_in=js_in, je_in=je_in)
1213 call data_override(
'OCN',
'calving', fluxes%frunoff(:,:), day, &
1214 is_in=is_in, ie_in=ie_in, js_in=js_in, je_in=je_in)
1217 if (cs%restorebuoy)
then 1218 call data_override(
'OCN',
'SST_restore', cs%T_restore(:,:), day, &
1219 is_in=is_in, ie_in=ie_in, js_in=js_in, je_in=je_in)
1221 call data_override(
'OCN',
'SSS_restore', cs%S_restore(:,:), day, &
1222 is_in=is_in, ie_in=ie_in, js_in=js_in, je_in=je_in)
1227 if (cs%restorebuoy)
then 1228 if (cs%use_temperature)
then 1229 do j=js,je ;
do i=is,ie
1230 if (g%mask2dT(i,j) > 0)
then 1231 fluxes%heat_added(i,j) = g%mask2dT(i,j) * &
1232 ((cs%T_Restore(i,j) - state%SST(i,j)) * rhoxcp * cs%Flux_const)
1233 fluxes%vprec(i,j) = - (cs%Rho0*cs%Flux_const) * &
1234 (cs%S_Restore(i,j) - state%SSS(i,j)) / &
1235 (0.5*(state%SSS(i,j) + cs%S_Restore(i,j)))
1237 fluxes%heat_added(i,j) = 0.0
1238 fluxes%vprec(i,j) = 0.0
1242 do j=js,je ;
do i=is,ie
1243 if (g%mask2dT(i,j) > 0)
then 1244 fluxes%buoy(i,j) = (cs%Dens_Restore(i,j) - state%sfc_density(i,j)) * &
1245 (cs%G_Earth*cs%Flux_const/cs%Rho0)
1247 fluxes%buoy(i,j) = 0.0
1252 if (.not.cs%use_temperature)
then 1253 call mom_error(fatal,
"buoyancy_forcing in MOM_surface_forcing: "// &
1254 "The fluxes need to be defined without RESTOREBUOY.")
1265 do j=js,je ;
do i=is,ie
1266 fluxes%evap(i,j) = fluxes%evap(i,j) * g%mask2dT(i,j)
1267 fluxes%lprec(i,j) = fluxes%lprec(i,j) * g%mask2dT(i,j)
1268 fluxes%fprec(i,j) = fluxes%fprec(i,j) * g%mask2dT(i,j)
1269 fluxes%lrunoff(i,j) = fluxes%lrunoff(i,j) * g%mask2dT(i,j)
1270 fluxes%frunoff(i,j) = fluxes%frunoff(i,j) * g%mask2dT(i,j)
1271 fluxes%LW(i,j) = fluxes%LW(i,j) * g%mask2dT(i,j)
1272 fluxes%latent(i,j) = fluxes%latent(i,j) * g%mask2dT(i,j)
1273 fluxes%sens(i,j) = fluxes%sens(i,j) * g%mask2dT(i,j)
1274 fluxes%sw(i,j) = fluxes%sw(i,j) * g%mask2dT(i,j)
1276 fluxes%latent_evap_diag(i,j) = fluxes%latent_evap_diag(i,j) * g%mask2dT(i,j)
1277 fluxes%latent_fprec_diag(i,j) = -fluxes%fprec(i,j)*cs%latent_heat_fusion
1278 fluxes%latent_frunoff_diag(i,j) = -fluxes%frunoff(i,j)*cs%latent_heat_fusion
1292 call calltree_leave(
"buoyancy_forcing_from_data_override")
1297 type(surface),
intent(inout) :: state
1298 type(forcing),
intent(inout) :: fluxes
1299 type(time_type),
intent(in) :: day
1300 real,
intent(in) :: dt
1302 type(ocean_grid_type),
intent(in) :: G
1318 integer :: i, j, is, ie, js, je
1320 call calltree_enter(
"buoyancy_forcing_zero, MOM_surface_forcing.F90")
1321 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
1323 if (cs%use_temperature)
then 1324 do j=js,je ;
do i=is,ie
1325 fluxes%evap(i,j) = 0.0
1326 fluxes%lprec(i,j) = 0.0
1327 fluxes%fprec(i,j) = 0.0
1328 fluxes%vprec(i,j) = 0.0
1329 fluxes%lrunoff(i,j) = 0.0
1330 fluxes%frunoff(i,j) = 0.0
1331 fluxes%lw(i,j) = 0.0
1332 fluxes%latent(i,j) = 0.0
1333 fluxes%sens(i,j) = 0.0
1334 fluxes%sw(i,j) = 0.0
1335 fluxes%latent_evap_diag(i,j) = 0.0
1336 fluxes%latent_fprec_diag(i,j) = 0.0
1337 fluxes%latent_frunoff_diag(i,j) = 0.0
1340 do j=js,je ;
do i=is,ie
1341 fluxes%buoy(i,j) = 0.0
1345 call calltree_leave(
"buoyancy_forcing_zero")
1350 type(surface),
intent(inout) :: state
1351 type(forcing),
intent(inout) :: fluxes
1352 type(time_type),
intent(in) :: day
1353 real,
intent(in) :: dt
1355 type(ocean_grid_type),
intent(in) :: G
1371 integer :: i, j, is, ie, js, je
1372 call calltree_enter(
"buoyancy_forcing_const, MOM_surface_forcing.F90")
1373 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
1375 if (cs%use_temperature)
then 1376 do j=js,je ;
do i=is,ie
1377 fluxes%evap(i,j) = 0.0
1378 fluxes%lprec(i,j) = 0.0
1379 fluxes%fprec(i,j) = 0.0
1380 fluxes%vprec(i,j) = 0.0
1381 fluxes%lrunoff(i,j) = 0.0
1382 fluxes%frunoff(i,j) = 0.0
1383 fluxes%lw(i,j) = 0.0
1384 fluxes%latent(i,j) = 0.0
1385 fluxes%sens(i,j) = cs%constantHeatForcing * g%mask2dT(i,j)
1386 fluxes%sw(i,j) = 0.0
1387 fluxes%latent_evap_diag(i,j) = 0.0
1388 fluxes%latent_fprec_diag(i,j) = 0.0
1389 fluxes%latent_frunoff_diag(i,j) = 0.0
1392 do j=js,je ;
do i=is,ie
1393 fluxes%buoy(i,j) = 0.0
1397 call calltree_leave(
"buoyancy_forcing_const")
1402 type(surface),
intent(inout) :: state
1403 type(forcing),
intent(inout) :: fluxes
1404 type(time_type),
intent(in) :: day
1405 real,
intent(in) :: dt
1407 type(ocean_grid_type),
intent(in) :: G
1422 real :: y, T_restore, S_restore
1423 integer :: i, j, is, ie, js, je
1425 call calltree_enter(
"buoyancy_forcing_linear, MOM_surface_forcing.F90")
1426 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
1429 if (cs%use_temperature)
then 1430 do j=js,je ;
do i=is,ie
1431 fluxes%evap(i,j) = 0.0
1432 fluxes%lprec(i,j) = 0.0
1433 fluxes%fprec(i,j) = 0.0
1434 fluxes%vprec(i,j) = 0.0
1435 fluxes%lrunoff(i,j) = 0.0
1436 fluxes%frunoff(i,j) = 0.0
1437 fluxes%lw(i,j) = 0.0
1438 fluxes%latent(i,j) = 0.0
1439 fluxes%sens(i,j) = 0.0
1440 fluxes%sw(i,j) = 0.0
1441 fluxes%latent_evap_diag(i,j) = 0.0
1442 fluxes%latent_fprec_diag(i,j) = 0.0
1443 fluxes%latent_frunoff_diag(i,j) = 0.0
1446 do j=js,je ;
do i=is,ie
1447 fluxes%buoy(i,j) = 0.0
1451 if (cs%restorebuoy)
then 1452 if (cs%use_temperature)
then 1453 do j=js,je ;
do i=is,ie
1454 y = (g%geoLatCu(i,j)-cs%South_lat)/cs%len_lat
1455 t_restore = cs%T_south + (cs%T_north-cs%T_south)*y
1456 s_restore = cs%S_south + (cs%S_north-cs%S_south)*y
1457 if (g%mask2dT(i,j) > 0)
then 1458 fluxes%heat_added(i,j) = g%mask2dT(i,j) * &
1459 ((t_restore - state%SST(i,j)) * ((cs%Rho0 * fluxes%C_p) * cs%Flux_const))
1460 fluxes%vprec(i,j) = - (cs%Rho0*cs%Flux_const) * &
1461 (s_restore - state%SSS(i,j)) / &
1462 (0.5*(state%SSS(i,j) + s_restore))
1464 fluxes%heat_added(i,j) = 0.0
1465 fluxes%vprec(i,j) = 0.0
1469 call mom_error(fatal,
"buoyancy_forcing_linear in MOM_surface_forcing: "// &
1470 "RESTOREBUOY to linear not written yet.")
1481 if (.not.cs%use_temperature)
then 1482 call mom_error(fatal,
"buoyancy_forcing_linear in MOM_surface_forcing: "// &
1483 "The fluxes need to be defined without RESTOREBUOY.")
1487 call calltree_leave(
"buoyancy_forcing_linear")
1494 type(ocean_grid_type),
intent(inout) :: G
1495 type(time_type),
intent(in) :: Time
1496 character(len=*),
intent(in) :: directory
1497 logical,
optional,
intent(in) :: time_stamped
1498 character(len=*),
optional,
intent(in) :: filename_suffix
1509 if (.not.
associated(cs))
return 1510 if (.not.
associated(cs%restart_CSp))
return 1512 call save_restart(directory, time, g, cs%restart_CSp, time_stamped)
1518 type(time_type),
intent(in) :: Time
1519 type(ocean_grid_type),
intent(in) :: G
1520 type(param_file_type),
intent(in) :: param_file
1521 type(diag_ctrl),
target,
intent(inout) :: diag
1523 type(tracer_flow_control_cs),
pointer :: tracer_flow_CSp
1533 type(directories) :: dirs
1535 type(time_type) :: Time_frc
1537 #include "version_variable.h" 1538 character(len=40) :: mdl =
"MOM_surface_forcing" 1539 character(len=200) :: filename, gust_file
1541 if (
associated(cs))
then 1542 call mom_error(warning,
"surface_forcing_init called with an associated "// &
1543 "control structure.")
1548 id_clock_forcing=cpu_clock_id(
'(Ocean surface forcing)', grain=clock_module)
1552 if (
associated(tracer_flow_csp)) cs%tracer_flow_CSp => tracer_flow_csp
1555 call log_version(param_file, mdl, version,
'')
1556 call get_param(param_file, mdl,
"ENABLE_THERMODYNAMICS", cs%use_temperature, &
1557 "If true, Temperature and salinity are used as state \n"//&
1558 "variables.", default=.true.)
1559 call get_param(param_file, mdl,
"INPUTDIR", cs%inputdir, &
1560 "The directory in which all input files are found.", &
1562 cs%inputdir = slasher(cs%inputdir)
1564 call get_param(param_file, mdl,
"ADIABATIC", cs%adiabatic, &
1565 "There are no diapycnal mass fluxes if ADIABATIC is \n"//&
1566 "true. This assumes that KD = KDML = 0.0 and that \n"//&
1567 "there is no buoyancy forcing, but makes the model \n"//&
1568 "faster by eliminating subroutine calls.", default=.false.)
1569 call get_param(param_file, mdl,
"VARIABLE_WINDS", cs%variable_winds, &
1570 "If true, the winds vary in time after the initialization.", &
1572 call get_param(param_file, mdl,
"VARIABLE_BUOYFORCE", cs%variable_buoyforce, &
1573 "If true, the buoyancy forcing varies in time after the \n"//&
1574 "initialization of the model.", default=.true.)
1576 call get_param(param_file, mdl,
"BUOY_CONFIG", cs%buoy_config, &
1577 "The character string that indicates how buoyancy forcing \n"//&
1578 "is specified. Valid options include (file), (zero), \n"//&
1579 "(linear), (USER), (BFB) and (NONE).", fail_if_missing=.true.)
1580 if (trim(cs%buoy_config) ==
"file")
then 1581 call get_param(param_file, mdl,
"ARCHAIC_OMIP_FORCING_FILE", cs%archaic_OMIP_file, &
1582 "If true, use the forcing variable decomposition from \n"//&
1583 "the old German OMIP prescription that predated CORE. If \n"//&
1584 "false, use the variable groupings available from MOM \n"//&
1585 "output diagnostics of forcing variables.", default=.true.)
1586 if (cs%archaic_OMIP_file)
then 1587 call get_param(param_file, mdl,
"LONGWAVEDOWN_FILE", cs%longwave_file, &
1588 "The file with the downward longwave heat flux, in \n"//&
1589 "variable lwdn_sfc.", fail_if_missing=.true.)
1590 call get_param(param_file, mdl,
"LONGWAVEUP_FILE", cs%longwaveup_file, &
1591 "The file with the upward longwave heat flux, in \n"//&
1592 "variable lwup_sfc.", fail_if_missing=.true.)
1593 call get_param(param_file, mdl,
"EVAPORATION_FILE", cs%evaporation_file, &
1594 "The file with the evaporative moisture flux, in \n"//&
1595 "variable evap.", fail_if_missing=.true.)
1596 call get_param(param_file, mdl,
"SENSIBLEHEAT_FILE", cs%sensibleheat_file, &
1597 "The file with the sensible heat flux, in \n"//&
1598 "variable shflx.", fail_if_missing=.true.)
1599 call get_param(param_file, mdl,
"SHORTWAVEUP_FILE", cs%shortwaveup_file, &
1600 "The file with the upward shortwave heat flux.", &
1601 fail_if_missing=.true.)
1602 call get_param(param_file, mdl,
"SHORTWAVEDOWN_FILE", cs%shortwave_file, &
1603 "The file with the downward shortwave heat flux.", &
1604 fail_if_missing=.true.)
1605 call get_param(param_file, mdl,
"SNOW_FILE", cs%snow_file, &
1606 "The file with the downward frozen precip flux, in \n"//&
1607 "variable snow.", fail_if_missing=.true.)
1608 call get_param(param_file, mdl,
"PRECIP_FILE", cs%rain_file, &
1609 "The file with the downward total precip flux, in \n"//&
1610 "variable precip.", fail_if_missing=.true.)
1611 call get_param(param_file, mdl,
"FRESHDISCHARGE_FILE", cs%runoff_file, &
1612 "The file with the fresh and frozen runoff/calving fluxes, \n"//&
1613 "invariables disch_w and disch_s.", fail_if_missing=.true.)
1616 cs%latentheat_file = cs%evaporation_file ; cs%latent_var =
"evap" 1617 cs%LW_var =
"lwdn_sfc"; cs%SW_var =
"swdn_sfc"; cs%sens_var =
"shflx" 1618 cs%evap_var =
"evap"; cs%rain_var =
"precip"; cs%snow_var =
"snow" 1619 cs%lrunoff_var =
"disch_w"; cs%frunoff_var =
"disch_s" 1622 call get_param(param_file, mdl,
"LONGWAVE_FILE", cs%longwave_file, &
1623 "The file with the longwave heat flux, in the variable \n"//&
1624 "given by LONGWAVE_FORCING_VAR.", fail_if_missing=.true.)
1625 call get_param(param_file, mdl,
"LONGWAVE_FORCING_VAR", cs%LW_var, &
1626 "The variable with the longwave forcing field.", default=
"LW")
1628 call get_param(param_file, mdl,
"SHORTWAVE_FILE", cs%shortwave_file, &
1629 "The file with the shortwave heat flux, in the variable \n"//&
1630 "given by SHORTWAVE_FORCING_VAR.", fail_if_missing=.true.)
1631 call get_param(param_file, mdl,
"SHORTWAVE_FORCING_VAR", cs%SW_var, &
1632 "The variable with the shortwave forcing field.", default=
"SW")
1634 call get_param(param_file, mdl,
"EVAPORATION_FILE", cs%evaporation_file, &
1635 "The file with the evaporative moisture flux, in the \n"//&
1636 "variable given by EVAP_FORCING_VAR.", fail_if_missing=.true.)
1637 call get_param(param_file, mdl,
"EVAP_FORCING_VAR", cs%evap_var, &
1638 "The variable with the evaporative moisture flux.", &
1641 call get_param(param_file, mdl,
"LATENTHEAT_FILE", cs%latentheat_file, &
1642 "The file with the latent heat flux, in the variable \n"//&
1643 "given by LATENT_FORCING_VAR.", fail_if_missing=.true.)
1644 call get_param(param_file, mdl,
"LATENT_FORCING_VAR", cs%latent_var, &
1645 "The variable with the latent heat flux.", default=
"latent")
1647 call get_param(param_file, mdl,
"SENSIBLEHEAT_FILE", cs%sensibleheat_file, &
1648 "The file with the sensible heat flux, in the variable \n"//&
1649 "given by SENSIBLE_FORCING_VAR.", fail_if_missing=.true.)
1650 call get_param(param_file, mdl,
"SENSIBLE_FORCING_VAR", cs%sens_var, &
1651 "The variable with the sensible heat flux.", default=
"sensible")
1653 call get_param(param_file, mdl,
"RAIN_FILE", cs%rain_file, &
1654 "The file with the liquid precipitation flux, in the \n"//&
1655 "variable given by RAIN_FORCING_VAR.", fail_if_missing=.true.)
1656 call get_param(param_file, mdl,
"RAIN_FORCING_VAR", cs%rain_var, &
1657 "The variable with the liquid precipitation flux.", &
1658 default=
"liq_precip")
1659 call get_param(param_file, mdl,
"SNOW_FILE", cs%snow_file, &
1660 "The file with the frozen precipitation flux, in the \n"//&
1661 "variable given by SNOW_FORCING_VAR.", fail_if_missing=.true.)
1662 call get_param(param_file, mdl,
"SNOW_FORCING_VAR", cs%snow_var, &
1663 "The variable with the frozen precipitation flux.", &
1664 default=
"froz_precip")
1666 call get_param(param_file, mdl,
"RUNOFF_FILE", cs%runoff_file, &
1667 "The file with the fresh and frozen runoff/calving \n"//&
1668 "fluxes, in variables given by LIQ_RUNOFF_FORCING_VAR \n"//&
1669 "and FROZ_RUNOFF_FORCING_VAR.", fail_if_missing=.true.)
1670 call get_param(param_file, mdl,
"LIQ_RUNOFF_FORCING_VAR", cs%lrunoff_var, &
1671 "The variable with the liquid runoff flux.", &
1672 default=
"liq_runoff")
1673 call get_param(param_file, mdl,
"FROZ_RUNOFF_FORCING_VAR", cs%frunoff_var, &
1674 "The variable with the frozen runoff flux.", &
1675 default=
"froz_runoff")
1678 call get_param(param_file, mdl,
"SSTRESTORE_FILE", cs%SSTrestore_file, &
1679 "The file with the SST toward which to restore in the \n"//&
1680 "variable given by SST_RESTORE_VAR.", fail_if_missing=.true.)
1681 call get_param(param_file, mdl,
"SALINITYRESTORE_FILE", cs%salinityrestore_file, &
1682 "The file with the surface salinity toward which to \n"//&
1683 "restore in the variable given by SSS_RESTORE_VAR.", &
1684 fail_if_missing=.true.)
1686 if (cs%archaic_OMIP_file)
then 1687 cs%SST_restore_var =
"TEMP" ; cs%SSS_restore_var =
"SALT" 1689 call get_param(param_file, mdl,
"SST_RESTORE_VAR", cs%SST_restore_var, &
1690 "The variable with the SST toward which to restore.", &
1692 call get_param(param_file, mdl,
"SSS_RESTORE_VAR", cs%SSS_restore_var, &
1693 "The variable with the SSS toward which to restore.", &
1698 cs%shortwave_file = trim(cs%inputdir)//trim(cs%shortwave_file)
1699 cs%longwave_file = trim(cs%inputdir)//trim(cs%longwave_file)
1700 cs%sensibleheat_file = trim(cs%inputdir)//trim(cs%sensibleheat_file)
1701 cs%latentheat_file = trim(cs%inputdir)//trim(cs%latentheat_file)
1702 cs%evaporation_file = trim(cs%inputdir)//trim(cs%evaporation_file)
1703 cs%snow_file = trim(cs%inputdir)//trim(cs%snow_file)
1704 cs%rain_file = trim(cs%inputdir)//trim(cs%rain_file)
1705 cs%runoff_file = trim(cs%inputdir)//trim(cs%runoff_file)
1707 cs%shortwaveup_file = trim(cs%inputdir)//trim(cs%shortwaveup_file)
1708 cs%longwaveup_file = trim(cs%inputdir)//trim(cs%longwaveup_file)
1710 cs%SSTrestore_file = trim(cs%inputdir)//trim(cs%SSTrestore_file)
1711 cs%salinityrestore_file = trim(cs%inputdir)//trim(cs%salinityrestore_file)
1712 elseif (trim(cs%buoy_config) ==
"const")
then 1713 call get_param(param_file, mdl,
"SENSIBLE_HEAT_FLUX", cs%constantHeatForcing, &
1714 "A constant heat forcing (positive into ocean) applied \n"//&
1715 "through the sensible heat flux field. ", &
1716 units=
'W/m2', fail_if_missing=.true.)
1718 call get_param(param_file, mdl,
"WIND_CONFIG", cs%wind_config, &
1719 "The character string that indicates how wind forcing \n"//&
1720 "is specified. Valid options include (file), (2gyre), \n"//&
1721 "(1gyre), (gyres), (zero), and (USER).", fail_if_missing=.true.)
1722 if (trim(cs%wind_config) ==
"file")
then 1723 call get_param(param_file, mdl,
"WIND_FILE", cs%wind_file, &
1724 "The file in which the wind stresses are found in \n"//&
1725 "variables STRESS_X and STRESS_Y.", fail_if_missing=.true.)
1726 call get_param(param_file, mdl,
"WINDSTRESS_X_VAR",cs%stress_x_var, &
1727 "The name of the x-wind stress variable in WIND_FILE.", &
1729 call get_param(param_file, mdl,
"WINDSTRESS_Y_VAR", cs%stress_y_var, &
1730 "The name of the y-wind stress variable in WIND_FILE.", &
1732 call get_param(param_file, mdl,
"WINDSTRESS_STAGGER",cs%wind_stagger, &
1733 "A character indicating how the wind stress components \n"//&
1734 "are staggered in WIND_FILE. This may be A or C for now.", &
1736 call get_param(param_file, mdl,
"WINDSTRESS_SCALE", cs%wind_scale, &
1737 "A value by which the wind stresses in WIND_FILE are rescaled.", &
1738 default=1.0, units=
"nondim")
1739 call get_param(param_file, mdl,
"USTAR_FORCING_VAR", cs%ustar_var, &
1740 "The name of the friction velocity variable in WIND_FILE \n"//&
1741 "or blank to get ustar from the wind stresses plus the \n"//&
1742 "gustiness.", default=
" ", units=
"nondim")
1743 cs%wind_file = trim(cs%inputdir) // trim(cs%wind_file)
1745 if (trim(cs%wind_config) ==
"gyres")
then 1746 call get_param(param_file, mdl,
"TAUX_CONST", cs%gyres_taux_const, &
1747 "With the gyres wind_config, the constant offset in the \n"//&
1748 "zonal wind stress profile: \n"//&
1749 " A in taux = A + B*sin(n*pi*y/L) + C*cos(n*pi*y/L).", &
1750 units=
"Pa", default=0.0)
1751 call get_param(param_file, mdl,
"TAUX_SIN_AMP",cs%gyres_taux_sin_amp, &
1752 "With the gyres wind_config, the sine amplitude in the \n"//&
1753 "zonal wind stress profile: \n"//&
1754 " B in taux = A + B*sin(n*pi*y/L) + C*cos(n*pi*y/L).", &
1755 units=
"Pa", default=0.0)
1756 call get_param(param_file, mdl,
"TAUX_COS_AMP",cs%gyres_taux_cos_amp, &
1757 "With the gyres wind_config, the cosine amplitude in \n"//&
1758 "the zonal wind stress profile: \n"//&
1759 " C in taux = A + B*sin(n*pi*y/L) + C*cos(n*pi*y/L).", &
1760 units=
"Pa", default=0.0)
1761 call get_param(param_file, mdl,
"TAUX_N_PIS",cs%gyres_taux_n_pis, &
1762 "With the gyres wind_config, the number of gyres in \n"//&
1763 "the zonal wind stress profile: \n"//&
1764 " n in taux = A + B*sin(n*pi*y/L) + C*cos(n*pi*y/L).", &
1765 units=
"nondim", default=0.0)
1767 if ((trim(cs%wind_config) ==
"2gyre") .or. &
1768 (trim(cs%wind_config) ==
"1gyre") .or. &
1769 (trim(cs%wind_config) ==
"gyres") .or. &
1770 (trim(cs%buoy_config) ==
"linear"))
then 1771 cs%south_lat = g%south_lat
1772 cs%len_lat = g%len_lat
1774 call get_param(param_file, mdl,
"RHO_0", cs%Rho0, &
1775 "The mean ocean density used with BOUSSINESQ true to \n"//&
1776 "calculate accelerations and the mass for conservation \n"//&
1777 "properties, or with BOUSSINSEQ false to convert some \n"//&
1778 "parameters from vertical units of m to kg m-2.", &
1779 units=
"kg m-3", default=1035.0)
1780 call get_param(param_file, mdl,
"RESTOREBUOY", cs%restorebuoy, &
1781 "If true, the buoyancy fluxes drive the model back \n"//&
1782 "toward some specified surface state with a rate \n"//&
1783 "given by FLUXCONST.", default= .false.)
1784 call get_param(param_file, mdl,
"LATENT_HEAT_FUSION", cs%latent_heat_fusion, &
1785 "The latent heat of fusion.", units=
"J/kg", default=hlf)
1786 call get_param(param_file, mdl,
"LATENT_HEAT_VAPORIZATION", cs%latent_heat_vapor, &
1787 "The latent heat of fusion.", units=
"J/kg", default=hlv)
1788 if (cs%restorebuoy)
then 1789 call get_param(param_file, mdl,
"FLUXCONST", cs%Flux_const, &
1790 "The constant that relates the restoring surface fluxes \n"//&
1791 "to the relative surface anomalies (akin to a piston \n"//&
1792 "velocity). Note the non-MKS units.", units=
"m day-1", &
1793 fail_if_missing=.true.)
1795 cs%Flux_const = cs%Flux_const / 86400.0
1796 if (trim(cs%buoy_config) ==
"linear")
then 1797 call get_param(param_file, mdl,
"SST_NORTH", cs%T_north, &
1798 "With buoy_config linear, the sea surface temperature \n"//&
1799 "at the northern end of the domain toward which to \n"//&
1800 "to restore.", units=
"deg C", default=0.0)
1801 call get_param(param_file, mdl,
"SST_SOUTH", cs%T_south, &
1802 "With buoy_config linear, the sea surface temperature \n"//&
1803 "at the southern end of the domain toward which to \n"//&
1804 "to restore.", units=
"deg C", default=0.0)
1805 call get_param(param_file, mdl,
"SSS_NORTH", cs%S_north, &
1806 "With buoy_config linear, the sea surface salinity \n"//&
1807 "at the northern end of the domain toward which to \n"//&
1808 "to restore.", units=
"PSU", default=35.0)
1809 call get_param(param_file, mdl,
"SSS_SOUTH", cs%S_south, &
1810 "With buoy_config linear, the sea surface salinity \n"//&
1811 "at the southern end of the domain toward which to \n"//&
1812 "to restore.", units=
"PSU", default=35.0)
1815 call get_param(param_file, mdl,
"G_EARTH", cs%G_Earth, &
1816 "The gravitational acceleration of the Earth.", &
1817 units=
"m s-2", default = 9.80)
1819 call get_param(param_file, mdl,
"GUST_CONST", cs%gust_const, &
1820 "The background gustiness in the winds.", units=
"Pa", &
1822 call get_param(param_file, mdl,
"READ_GUST_2D", cs%read_gust_2d, &
1823 "If true, use a 2-dimensional gustiness supplied from \n"//&
1824 "an input file", default=.false.)
1825 if (cs%read_gust_2d)
then 1826 call get_param(param_file, mdl,
"GUST_2D_FILE", gust_file, &
1827 "The file in which the wind gustiness is found in \n"//&
1828 "variable gustiness.", fail_if_missing=.true.)
1829 call safe_alloc_ptr(cs%gust,g%isd,g%ied,g%jsd,g%jed)
1830 filename = trim(cs%inputdir) // trim(gust_file)
1831 call read_data(filename,
'gustiness',cs%gust,domain=g%domain%mpp_domain, &
1837 if (trim(cs%wind_config) ==
"USER" .or. trim(cs%buoy_config) ==
"USER" )
then 1838 call user_surface_forcing_init(time, g, param_file, diag, cs%user_forcing_CSp)
1839 elseif (trim(cs%buoy_config) ==
"BFB" )
then 1840 call bfb_surface_forcing_init(time, g, param_file, diag, cs%BFB_forcing_CSp)
1841 elseif (trim(cs%wind_config) ==
"MESO" .or. trim(cs%buoy_config) ==
"MESO" )
then 1842 call meso_surface_forcing_init(time, g, param_file, diag, cs%MESO_forcing_CSp)
1843 elseif (trim(cs%wind_config) ==
"SCM_ideal_hurr")
then 1844 call scm_idealized_hurricane_wind_init(time, g, param_file, cs%SCM_idealized_hurricane_CSp)
1845 elseif (trim(cs%wind_config) ==
"const")
then 1846 call get_param(param_file, mdl,
"CONST_WIND_TAUX", cs%tau_x0, &
1847 "With wind_config const, this is the constant zonal\n"//&
1848 "wind-stress", units=
"Pa", fail_if_missing=.true.)
1849 call get_param(param_file, mdl,
"CONST_WIND_TAUY", cs%tau_y0, &
1850 "With wind_config const, this is the constant zonal\n"//&
1851 "wind-stress", units=
"Pa", fail_if_missing=.true.)
1852 elseif (trim(cs%wind_config) ==
"SCM_CVmix_tests" .or. &
1853 trim(cs%buoy_config) ==
"SCM_CVmix_tests")
then 1854 call scm_cvmix_tests_surface_forcing_init(time, g, param_file, cs%SCM_CVmix_tests_CSp)
1855 cs%SCM_CVmix_tests_CSp%Rho0 = cs%Rho0
1858 call register_forcing_type_diags(time, diag, cs%use_temperature, cs%handles)
1861 call restart_init(param_file, cs%restart_CSp,
"MOM_forcing.res")
1864 call restart_init_end(cs%restart_CSp)
1866 if (
associated(cs%restart_CSp))
then 1867 call get_mom_input(dirs=dirs)
1870 if ((dirs%input_filename(1:1) ==
'n') .and. &
1871 (len_trim(dirs%input_filename) == 1)) new_sim = .true.
1872 if (.not.new_sim)
then 1873 call restore_state(dirs%input_filename, dirs%restart_input_dir, time_frc, &
1879 if (trim(cs%buoy_config) ==
"file")
then 1880 cs%SW_nlev = num_timelevels(cs%shortwave_file, cs%SW_var, min_dims=3)
1881 cs%LW_nlev = num_timelevels(cs%longwave_file, cs%LW_var, min_dims=3)
1882 cs%latent_nlev = num_timelevels(cs%latentheat_file, cs%latent_var, 3)
1883 cs%sens_nlev = num_timelevels(cs%sensibleheat_file, cs%sens_var, min_dims=3)
1885 cs%evap_nlev = num_timelevels(cs%evaporation_file, cs%evap_var, min_dims=3)
1886 cs%precip_nlev = num_timelevels(cs%rain_file, cs%rain_var, min_dims=3)
1887 cs%runoff_nlev = num_timelevels(cs%runoff_file, cs%lrunoff_var, 3)
1889 cs%SST_nlev = num_timelevels(cs%SSTrestore_file, cs%SST_restore_var, 3)
1890 cs%SSS_nlev = num_timelevels(cs%salinityrestore_file, cs%SSS_restore_var, 3)
1893 if (trim(cs%wind_config) ==
"file") &
1894 cs%wind_nlev = num_timelevels(cs%wind_file, cs%stress_x_var, min_dims=3)
1898 call user_revise_forcing_init(param_file, cs%urf_CS)
1906 type(forcing),
optional,
intent(inout) :: fluxes
1912 if (
present(fluxes))
call deallocate_forcing_type(fluxes)
1916 if (
associated(cs))
deallocate(cs)
subroutine, public set_forcing(state, fluxes, day_start, day_interval, G, CS)
subroutine wind_forcing_2gyre(state, fluxes, day, G, CS)
The following structure contains pointers to various fields which may be used describe the surface st...
subroutine, public scm_idealized_hurricane_wind_init(Time, G, param_file, CS)
Initializes wind profile for the SCM idealized hurricane example.
subroutine, public bfb_buoyancy_forcing(state, fluxes, day, dt, G, CS)
subroutine wind_forcing_by_data_override(state, fluxes, day, G, CS)
This module implements boundary forcing for MOM6.
integer, parameter, public to_all
Ocean grid type. See mom_grid for details.
subroutine, public meso_buoyancy_forcing(state, fluxes, day, dt, G, CS)
subroutine, public scm_cvmix_tests_wind_forcing(state, fluxes, day, G, CS)
Provides the ocean grid type.
Container for parameters describing idealized wind structure.
subroutine, public allocate_forcing_type(G, fluxes, stress, ustar, water, heat, shelf, press, iceberg)
Conditionally allocate fields within the forcing type.
subroutine, public calltree_leave(mesg)
Writes a message about leaving a subroutine if call tree reporting is active.
This module contains I/O framework code.
subroutine buoyancy_forcing_from_files(state, fluxes, day, dt, G, CS)
subroutine wind_forcing_from_file(state, fluxes, day, G, CS)
subroutine, public user_alter_forcing(state, fluxes, day, G, CS)
This subroutine sets the surface wind stresses.
subroutine buoyancy_forcing_from_data_override(state, fluxes, day, dt, G, CS)
subroutine wind_forcing_1gyre(state, fluxes, day, G, CS)
subroutine, public bfb_surface_forcing_init(Time, G, param_file, diag, CS)
character(len=len(input_string)) function, public uppercase(input_string)
subroutine, public scm_cvmix_tests_surface_forcing_init(Time, G, param_file, CS)
Initializes surface forcing for the CVmix test case suite.
subroutine, public register_forcing_type_diags(Time, diag, use_temperature, handles, use_berg_fluxes)
Register members of the forcing type for diagnostics.
subroutine, public user_revise_forcing_init(param_file, CS)
subroutine, public call_tracer_set_forcing(state, fluxes, day_start, day_interval, G, CS)
This subroutine calls the individual tracer modules' subroutines to specify or read quantities relate...
logical function, public is_root_pe()
subroutine, public forcing_save_restart(CS, G, Time, directory, time_stamped, filename_suffix)
subroutine, public scm_cvmix_tests_buoyancy_forcing(state, fluxes, day, G, CS)
Structure that contains pointers to the boundary forcing used to drive the liquid ocean simulated by ...
subroutine, public user_surface_forcing_init(Time, G, param_file, diag, CS)
subroutine, public meso_surface_forcing_init(Time, G, param_file, diag, CS)
subroutine buoyancy_forcing_zero(state, fluxes, day, dt, G, CS)
subroutine, public mom_mesg(message, verb, all_print)
subroutine, public meso_wind_forcing(state, fluxes, day, G, CS)
subroutine surface_forcing_end(CS, fluxes)
subroutine, public user_buoyancy_forcing(state, fluxes, day, dt, G, CS)
subroutine, public save_restart(directory, time, G, CS, time_stamped, filename, GV)
Initial conditions and forcing for the single column model (SCM) CVmix test set.
subroutine, public restart_init_end(CS)
subroutine buoyancy_forcing_allocate(fluxes, G, CS)
subroutine, public user_wind_forcing(state, fluxes, day, G, CS)
subroutine buoyancy_forcing_linear(state, fluxes, day, dt, G, CS)
subroutine, public scm_idealized_hurricane_wind_forcing(state, fluxes, day, G, CS)
subroutine buoyancy_forcing_const(state, fluxes, day, dt, G, CS)
subroutine wind_forcing_gyres(state, fluxes, day, G, CS)
subroutine wind_forcing_const(state, fluxes, tau_x0, tau_y0, day, G, CS)
subroutine, public surface_forcing_init(Time, G, param_file, diag, CS, tracer_flow_CSp)
subroutine, public deallocate_forcing_type(fluxes)
Deallocate the forcing type.
subroutine, public restart_init(param_file, CS, restart_root)
Structure that defines the id handles for the forcing type.
subroutine, public mom_error(level, message, all_print)
Initial conditions and forcing for the single column model (SCM) idealized hurricane example...
integer function, public num_timelevels(filename, varname, min_dims)
This function determines how many time levels a variable has.
Container for surface forcing parameters.
subroutine, public restore_state(filename, directory, day, G, CS)
subroutine, public calltree_enter(mesg, n)
Writes a message about entering a subroutine if call tree reporting is active.