5 close_file, stdlog, mpp_pe, mpp_root_pe, &
7 fatal, warning, note, file_exist
17 operator(<),
operator(+)
30 integer :: is, ie, js, je, npz
32 real(FVPRC),
pointer,
dimension(:,:) :: ps
33 real(FVPRC),
pointer,
dimension(:,:,:) :: u, v, t
34 real(FVPRC),
pointer,
dimension(:,:,:,:) :: q
37 interface assignment(=)
47 integer,
allocatable ::
id1(:,:),
id2(:,:),
jdc(:,:)
48 real(FVPRC),
allocatable ::
s2c(:,:,:)
98 integer,
dimension(3),
intent(in) :: axes
99 logical,
optional,
intent(out) :: flag
100 integer :: n, ierr, io, unit
101 character(len=128) :: units, calendar, desc
103 real(4),
allocatable :: tlevels(:)
105 real(8),
allocatable :: tlevels(:)
107 real(FVPRC) :: eps = 1.e-10
108 real(FVPRC) :: missing_value = -1.e10
113 #ifdef INTERNAL_FILE_NML 114 read (input_nml_file, nml=fv_climate_nudge_nml, iostat=io)
117 if (file_exist(
'input.nml') )
then 118 unit = open_namelist_file()
121 read (unit, nml=fv_climate_nudge_nml, iostat=io, end=10)
124 10
call close_file (unit)
131 call write_version_number (
'0.0',
'fv3-jedi-lm')
132 if (mpp_pe() == mpp_root_pe())
write (unit, nml=fv_climate_nudge_nml)
146 call error_mesg (
'fv_climate_nudge_nlm_mod',
'no variables specified '//&
147 'for override', warning)
151 call error_mesg (
'fv_climate_nudge_nlm_mod',
'variables specified '//&
152 'for override when freq = 0', fatal)
158 if (
present(flag))
then 168 desc =
' tendency due to data insertion' 171 'zonal wind'//trim(desc),
'm/s2', missing_value=missing_value)
173 'meridional wind'//trim(desc),
'm/s2',missing_value=missing_value)
175 'temperature'//trim(desc),
'degK/s',missing_value=missing_value)
177 'specific humidity'//trim(desc),
'kg/kg/s',missing_value=missing_value)
179 'surface pressure'//trim(desc),
'Pa/s',missing_value=missing_value)
184 'zonal wind'//trim(desc),
'm/s2', missing_value=missing_value)
186 'meridional wind'//trim(desc),
'm/s2',missing_value=missing_value)
188 'temperature'//trim(desc),
'degK/s',missing_value=missing_value)
190 'specific humidity'//trim(desc),
'kg/kg/s',missing_value=missing_value)
192 'surface pressure'//trim(desc),
'Pa/s',missing_value=missing_value)
194 desc =
' observation used for nudging' 197 'zonal wind'//trim(desc),
'm/s2', missing_value=missing_value)
199 'meridional wind'//trim(desc),
'm/s2',missing_value=missing_value)
201 'temperature'//trim(desc),
'degK/s',missing_value=missing_value)
203 'specific humidity'//trim(desc),
'kg/kg/s',missing_value=missing_value)
205 'surface pressure'//trim(desc),
'Pa/s',missing_value=missing_value)
219 call error_mesg (
'fv_climate_nudge_nlm_mod',
'initializing nudging', note)
221 if (
verbose .gt. 1 .and. mpp_pe() .eq. mpp_root_pe())
then 222 print
'(a,4i10)',
'fv_climate_nudge: nlon_obs, nlat_obs, nlev_obs, ntime_obs = ', &
229 call read_time ( tlevels, units, calendar )
232 permit_calendar_conversion=.true. )
234 deallocate ( tlevels )
240 if (mpp_pe() .eq. mpp_root_pe())
then 242 print *,
'fv_climate_nudge: ak_obs=',
ak_obs 243 print *,
'fv_climate_nudge: bk_obs=',
bk_obs 258 lon, lat, phis, ptop, ak, bk, &
259 ps, u, v, t, q, psdt, udt, vdt, tdt, qdt )
261 real(FVPRC),
intent(in) :: dt
262 integer,
intent(in) :: is, ie, js, je, npz
263 real(FVPRC),
intent(IN) :: ptop
265 real(FVPRC),
intent(in) :: phis(is:ie,js:je)
266 real(FVPRC),
intent(in) :: lon (is:ie,js:je)
267 real(FVPRC),
intent(in) :: lat (is:ie,js:je)
268 real(FVPRC),
intent(in) :: ak (npz+1)
269 real(FVPRC),
intent(in) :: bk (npz+1)
270 real(FVPRC),
intent(in) :: pfull (npz)
272 real(FVPRC),
intent(inout) :: ps (is:ie,js:je)
273 real(FVPRC),
intent(inout) :: psdt(is:ie,js:je)
275 real(FVPRC),
intent(inout) :: u(is:ie,js:je,npz)
276 real(FVPRC),
intent(inout) :: v(is:ie,js:je,npz)
277 real(FVPRC),
intent(inout) :: t(is:ie,js:je,npz)
278 real(FVPRC),
intent(inout) :: q(is:ie,js:je,npz,1)
280 real(FVPRC),
intent(inout) :: udt(is:ie,js:je,npz)
281 real(FVPRC),
intent(inout) :: vdt(is:ie,js:je,npz)
282 real(FVPRC),
intent(inout) :: tdt(is:ie,js:je,npz)
283 real(FVPRC),
intent(inout) :: qdt(is:ie,js:je,npz,1)
286 real(FVPRC),
dimension(is:ie,js:je,nlev_obs) :: u_obs, v_obs, t_obs
287 real(FVPRC),
dimension(is:ie,js:je,nlev_obs) :: q_obs
288 real(FVPRC),
dimension(is:ie,js:je) :: ps_obs, phis_obs
290 real(FVPRC),
dimension(is:ie,js:je,nlev_obs+1) :: phaf_obs, lphaf_obs
291 real(FVPRC),
dimension(is:ie,js:je,npz+1) :: phaf, lphaf
294 real(FVPRC),
allocatable :: dat3(:,:,:)
296 real(FVPRC),
dimension(is:ie,js:je,npz) :: obs, tend
297 real(FVPRC) :: factor(npz,3), wght(2)
299 integer :: itime(2), k, n
300 character(len=128) :: str
301 character(len=8) :: rstr(2)
302 character(len=256) :: err_msg
306 logical :: virtual_temp_obs = .false.
309 call error_mesg (
'fv_climate_nudge_nlm_mod',
'module not initialized', fatal)
338 allocate (
id1(is:ie,js:je),
id2(is:ie,js:je),
jdc(is:ie,js:je),
s2c(is:ie,js:je,4) )
350 if(err_msg /=
'')
then 351 call error_mesg(
'fv_climate_nudge_nlm_mod',trim(err_msg), fatal)
354 wght(1) = 1. - wght(2)
355 if (
verbose .gt. 1 .and. mpp_pe() .eq. mpp_root_pe())
then 356 write (rstr(1),
'(f8.6)') wght(1)
357 write (rstr(2),
'(f8.6)') wght(2)
358 str =
'Data Nudging: itime='//trim(
string(itime(1)))//
','//trim(
string(itime(2)))// &
359 '; wght='//rstr(1)//
','//rstr(2)//
'; Date: ' 365 if (itime(n) .ne.
state(n)%time_level)
then 367 if (itime(1) .eq.
state(2)%time_level)
then 378 call remap_xy (1,
nlon_obs,
jsd,
jed, dat3(:,:,1), is, ie, js, je,
id1,
id2,
jdc,
s2c, phis_obs)
382 call remap_xy (1,
nlon_obs,
jsd,
jed, dat3(:,:,1), is, ie, js, je,
id1,
id2,
jdc,
s2c, ps_obs)
390 lphaf_obs(:,:,k) = log(phaf_obs(:,:,k))
392 where (phaf_obs(:,:,1) .gt. 0.0)
393 lphaf_obs(:,:,1) = log(phaf_obs(:,:,1))
395 lphaf_obs(:,:,1) = lphaf_obs(:,:,2)-2.
397 lphaf_obs(:,:,1) =
max(lphaf_obs(:,:,1),0.0)
403 call remap_xy (1,
nlon_obs,
jsd,
jed,
nlev_obs, dat3, is, ie, js, je,
id1,
id2,
jdc,
s2c, u_obs)
406 call remap_xy (1,
nlon_obs,
jsd,
jed,
nlev_obs, dat3, is, ie, js, je,
id1,
id2,
jdc,
s2c, v_obs)
412 call remap_xy (1,
nlon_obs,
jsd,
jed,
nlev_obs, dat3, is, ie, js, je,
id1,
id2,
jdc,
s2c, q_obs)
418 call remap_xy (1,
nlon_obs,
jsd,
jed,
nlev_obs, dat3, is, ie, js, je,
id1,
id2,
jdc,
s2c, t_obs)
419 if (.not.virtual_temp_obs)
then 420 t_obs = t_obs*(1.+
zvir*q_obs)
426 call remap_ps (is, ie, js, je,
nlev_obs, phis_obs, phaf_obs, lphaf_obs, t_obs, phis,
state(n)%ps)
430 phaf(:,:,k) = ak(k) + bk(k)*
state(n)%ps
431 lphaf(:,:,k) = log(phaf(:,:,k))
435 call remap_3d (is, ie, js, je,
nlev_obs, npz, phaf_obs, u_obs, phaf,
state(n)%u, -1, ptop)
436 call remap_3d (is, ie, js, je,
nlev_obs, npz, phaf_obs, v_obs, phaf,
state(n)%v, -1, ptop)
439 call remap_3d (is, ie, js, je,
nlev_obs, npz, phaf_obs, q_obs, phaf,
state(n)%q(:,:,:,1), 0, ptop)
443 call remap_3d (is, ie, js, je,
nlev_obs, npz, lphaf_obs, t_obs, lphaf,
state(n)%t, 1, ptop)
447 state(n)%time_level = itime(n)
458 if (
allocated(dat3))
deallocate (dat3)
467 tend(:,:,k) = (obs(:,:,k) - u(:,:,k)) / (
u_tau + dt) * factor(k,1)
468 u(:,:,k) = u(:,:,k) + dt*tend(:,:,k)
469 udt(:,:,k) = udt(:,:,k) + tend(:,:,k)
487 tend(:,:,k) = (obs(:,:,k) - v(:,:,k)) / (
v_tau + dt) * factor(k,1)
488 v(:,:,k) = v(:,:,k) + dt*tend(:,:,k)
489 vdt(:,:,k) = vdt(:,:,k) + tend(:,:,k)
507 tend(:,:,k) = (obs(:,:,k) - t(:,:,k)) / (
t_tau + dt) * factor(k,2)
508 t(:,:,k) = t(:,:,k) + dt*tend(:,:,k)
509 tdt(:,:,k) = tdt(:,:,k) + tend(:,:,k)
524 obs =
state(1)%q(:,:,:,1)*wght(1) +
state(2)%q(:,:,:,1)*wght(2)
527 tend(:,:,k) = (obs(:,:,k) - q(:,:,k,1)) / (
q_tau + dt) * factor(k,2)
528 q(:,:,k,1) = q(:,:,k,1) + dt*tend(:,:,k)
529 qdt(:,:,k,1) = qdt(:,:,k,1) + tend(:,:,k)
536 tend = q(:,:,:,1) - obs
544 obs(:,:,1) =
state(1)%ps*wght(1) +
state(2)%ps*wght(2)
546 tend(:,:,1) = (obs(:,:,1) - ps) / (
ps_tau + dt)
547 ps = ps + dt*tend(:,:,1)
548 psdt = psdt + tend(:,:,1)
554 tend(:,:,1) = ps - obs(:,:,1)
565 integer,
intent(in) :: nlev
566 real(FVPRC),
intent(in) :: pfull(nlev)
567 real(FVPRC),
intent(out) :: factor(nlev,3)
593 factor(k,1) = factor(k+1,1) + 1./
real(skip_bot_v)
630 factor(k,3) = factor(k+1,3) + 1./
real(skip_bot_q)
639 factor(k,:) = factor(k,:)*(pfull(k)/psurf)
653 type(var_state_type),
intent(inout) :: State
654 integer,
intent(in) :: is, ie, js, je, npz
661 state%time_level = -1
662 allocate (state%ps(is:ie,js:je))
664 allocate (state%u(is:ie,js:je,1:npz))
665 allocate (state%v(is:ie,js:je,1:npz))
668 allocate (state%t(is:ie,js:je,1:npz))
671 allocate (state%q(is:ie,js:je,1:npz,1:1))
679 type(var_state_type),
intent(inout) :: State1
680 type(var_state_type),
intent(in) :: State2
683 if (state1%is /= state2%is .or. state1%ie /= state2%ie .or. &
684 state1%js /= state2%js .or. state1%je /= state2%je .or. &
685 state1%npz /= state2%npz)
then 686 call error_mesg (
'fv_climate_nudge_nlm_mod',
'invalid var_state assignment: '// &
687 'dimensions must match', fatal)
691 state1%time_level = state2%time_level
692 state1%ps = state2%ps
693 if (
associated(state1%u)) state1%u = state2%u
694 if (
associated(state1%v)) state1%v = state2%v
695 if (
associated(state1%t)) state1%t = state2%t
696 if (
associated(state1%q)) state1%q = state2%q
703 type(var_state_type),
intent(inout) :: State
710 state%time_level = -1
711 deallocate (state%ps)
713 if (
associated(state%u))
deallocate (state%u)
714 if (
associated(state%v))
deallocate (state%v)
717 if (
associated(state%t))
deallocate (state%t)
720 if (
associated(state%q))
deallocate (state%q)
749 character(len=*),
intent(in) :: str
750 real(FVPRC),
intent(in) :: a(:,:)
751 real(FVPRC) :: local_min, local_max
753 local_min = minval(a)
754 local_max = maxval(a)
757 if (mpp_pe()==mpp_root_pe())
then 758 print *, trim(str),local_min,local_max
766 character(len=*),
intent(in) :: str
767 real(FVPRC),
intent(in) :: a(:,:,:)
768 real(FVPRC) :: local_min, local_max
770 local_min = minval(a)
771 local_max = maxval(a)
774 if (mpp_pe()==mpp_root_pe())
then 775 print *, trim(str),local_min,local_max
785 subroutine remap_coef( isd, ied, jsd, jed, lon_in, lat_in, &
786 is, ie, js, je, lon_out, lat_out, &
792 integer,
intent(in):: isd, ied
793 integer,
intent(in):: jsd, jed
794 real(FVPRC),
intent(in):: lon_in(isd:ied)
795 real(FVPRC),
intent(in):: lat_in(jsd:jed)
798 integer,
intent(in):: is, ie, js, je
799 real(FVPRC),
intent(in):: lon_out(is:ie,js:je)
800 real(FVPRC),
intent(in):: lat_out(is:ie,js:je)
806 integer,
intent(out),
dimension(is:ie,js:je ):: id1, id2, jdc
807 real(FVPRC),
intent(out),
dimension(is:ie,js:je,4):: s2c
812 real(FVPRC):: rdlon(isd:ied)
813 real(FVPRC):: rdlat(jsd:jed)
815 integer i, j, i1, i2, jc, i0, j0
821 rdlon(i) = 1. / (lon_in(i+1) - lon_in(i))
823 rdlon(ied) = 1. / (lon_in(isd) + 2.*
pi - lon_in(ied))
826 rdlat(j) = 1. / (lat_in(j+1) - lat_in(j))
834 if ( lon_out(i,j) .gt. lon_in(ied) )
then 836 a1 = (lon_out(i,j)-lon_in(ied)) * rdlon(ied)
837 elseif ( lon_out(i,j) .lt. lon_in(1) )
then 839 a1 = (lon_out(i,j)+2.*
pi-lon_in(ied)) * rdlon(ied)
842 if ( lon_out(i,j) .ge. lon_in(i0) .and. lon_out(i,j) .le. lon_in(i0+1) )
then 844 a1 = (lon_out(i,j)-lon_in(i1)) * rdlon(i0)
852 if ( lat_out(i,j) .lt. lat_in(jsd) )
then 855 elseif ( lat_out(i,j) .gt. lat_in(jed) )
then 860 if ( lat_out(i,j) .ge. lat_in(j0) .and. lat_out(i,j) .le. lat_in(j0+1) )
then 862 b1 = (lat_out(i,j)-lat_in(jc)) * rdlat(jc)
874 s2c(i,j,1) = (1.-a1) * (1.-b1)
875 s2c(i,j,2) = a1 * (1.-b1)
877 s2c(i,j,4) = (1.-a1) * b1
889 subroutine remap_xy_3d( isd, ied, jsd, jed, km, q_in, &
890 is, ie, js, je, id1, id2, jdc, s2c, &
896 integer,
intent(in):: isd, ied
897 integer,
intent(in):: jsd, jed
898 integer,
intent(in):: km
899 real(FVPRC),
intent(in),
dimension(isd:ied,jsd:jed,km) :: q_in
902 integer,
intent(in):: is, ie, js, je
905 integer,
intent(in),
dimension(is:ie,js:je ):: id1, id2, jdc
906 real(FVPRC),
intent(in),
dimension(is:ie,js:je,4):: s2c
912 real(FVPRC),
intent(out),
dimension(is:ie,js:je,km):: q_out
919 q_out(i,j,k) = s2c(i,j,1)*q_in(id1(i,j),jdc(i,j), k) + s2c(i,j,2)*q_in(id2(i,j),jdc(i,j), k) + &
920 s2c(i,j,3)*q_in(id2(i,j),jdc(i,j)+1,k) + s2c(i,j,4)*q_in(id1(i,j),jdc(i,j)+1,k)
929 subroutine remap_xy_2d( isd, ied, jsd, jed, q_in, &
930 is, ie, js, je, id1, id2, jdc, s2c, &
935 integer,
intent(in):: isd, ied
936 integer,
intent(in):: jsd, jed
937 real(FVPRC),
intent(in),
dimension(isd:ied,jsd:jed) :: q_in
938 integer,
intent(in):: is, ie, js, je
939 integer,
intent(in),
dimension(is:ie,js:je ):: id1, id2, jdc
940 real(FVPRC),
intent(in),
dimension(is:ie,js:je,4):: s2c
944 real(FVPRC),
intent(out),
dimension(is:ie,js:je):: q_out
947 real(FVPRC),
dimension(isd:ied,jsd:jed,1) :: q3d_in
948 real(FVPRC),
dimension(is:ie,js:je,1) :: q3d_out
952 is, ie, js, je, id1, id2, jdc, s2c, &
954 q_out = q3d_out(:,:,1)
960 subroutine remap_ps( is, ie, js, je, km, &
961 gz_dat, ph_dat, pn_dat, tp_dat, phis, ps )
966 integer,
intent(in):: is, ie, js, je
967 integer,
intent(in):: km
968 real(FVPRC),
intent(in):: gz_dat(is:ie,js:je)
969 real(FVPRC),
intent(in):: ph_dat(is:ie,js:je,km+1)
970 real(FVPRC),
intent(in):: pn_dat(is:ie,js:je,km+1)
971 real(FVPRC),
intent(in):: tp_dat(is:ie,js:je,km)
972 real(FVPRC),
intent(in):: phis (is:ie,js:je)
977 real(FVPRC),
intent(out):: ps (is:ie,js:je)
981 real(FVPRC) :: pk0(km+1), gz(km+1), pt0, pst
988 gz(km+1) = gz_dat(i,j)
989 pk0(km+1) = ph_dat(i,j,km+1)**
kappa 991 gz(k) = gz(k+1) +
rdgas*tp_dat(i,j,k)*(pn_dat(i,j,k+1)-pn_dat(i,j,k))
992 pk0(k) = ph_dat(i,j,k)**
kappa 994 if ( phis(i,j) .gt. gz_dat(i,j) )
then 996 if( phis(i,j) < gz(k) .and. &
997 phis(i,j) >= gz(k+1) )
then 998 pst = pk0(k) + (pk0(k+1)-pk0(k))*(gz(k)-phis(i,j))/(gz(k)-gz(k+1))
1005 pt0= tp_dat(i,j,km)/(pk0(km+1)-pk0(km))*(
kappa*(pn_dat(i,j,km+1)-pn_dat(i,j,km)))
1006 pst = pk0(km+1) + (gz_dat(i,j)-phis(i,j))/(
cp_air*pt0)
1008 123 ps(i,j) = pst**(1./
kappa)
1018 subroutine remap_3d( is, ie, js, je, km, npz, &
1019 pe0, qn0, pe1, qn1, n, ptop )
1024 integer,
intent(in):: is, ie, js, je
1025 integer,
intent(in):: km
1026 integer,
intent(in):: npz
1027 real(FVPRC),
intent(in):: pe0(is:ie,js:je,km+1)
1028 real(FVPRC),
intent(in):: qn0(is:ie,js:je,km)
1029 real(FVPRC),
intent(in):: pe1(is:ie,js:je,npz+1)
1030 integer,
intent(in):: n
1031 real(FVPRC),
intent(IN):: ptop
1036 real(FVPRC),
intent(out):: qn1(is:ie,js:je,npz)
1042 call mappm(km, pe0(is:ie,j,:), qn0(is:ie,j,:), npz, pe1(is:ie,j,:), qn1(is:ie,j,:), is,ie, n, 8, ptop)
real(fvprc), dimension(:), allocatable lat_obs
real(fvprc), dimension(:), allocatable lon_obs
subroutine remap_3d(is, ie, js, je, km, npz, pe0, qn0, pe1, qn1, n, ptop)
subroutine, public fv_climate_nudge_init(Time, axes, flag)
subroutine var_state_init(is, ie, js, je, npz, State)
integer, dimension(:,:), allocatable jdc
integer function, public register_static_field(module_name, field_name, axes, long_name, units, missing_value, range, mask_variant, standard_name, DYNAMIC, do_not_log, interp_method, tile_count, area, volume, realm)
subroutine, public fv_climate_nudge(Time, dt, is, ie, js, je, npz, pfull, lon, lat, phis, ptop, ak, bk, ps, u, v, t, q, psdt, udt, vdt, tdt, qdt)
real, parameter, public rdgas
Gas constant for dry air [J/kg/deg].
type(time_type) function, public get_cal_time(time_increment, units, calendar, permit_calendar_conversion)
integer function, public check_nml_error(IOSTAT, NML_NAME)
subroutine get_factor(nlev, pfull, factor)
subroutine remap_coef(isd, ied, jsd, jed, lon_in, lat_in, is, ie, js, je, lon_out, lat_out, id1, id2, jdc, s2c)
subroutine var_state_assignment(State1, State2)
character(len=input_str_length), dimension(:), allocatable, target, public input_nml_file
real(fvprc), dimension(:,:,:), allocatable s2c
subroutine prt_minmax_2d(str, a)
integer, dimension(:,:), allocatable id2
subroutine var_state_del(State)
real(fvprc), parameter zvir
real(fvprc), dimension(:), allocatable ak_obs
real, parameter, public rvgas
Gas constant for water vapor [J/kg/deg].
type(time_type) time_next
subroutine, public fv_climate_nudge_end
real, parameter, public cp_air
Specific heat capacity of dry air at constant pressure [J/kg/deg].
subroutine remap_ps(is, ie, js, je, km, gz_dat, ph_dat, pn_dat, tp_dat, phis, ps)
real(fvprc), dimension(:), allocatable bk_obs
subroutine remap_xy_3d(isd, ied, jsd, jed, km, q_in, is, ie, js, je, id1, id2, jdc, s2c, q_out)
subroutine prt_minmax_3d(str, a)
integer, dimension(:,:), allocatable id1
subroutine, public mappm(km, pe1, q1, kn, pe2, q2, i1, i2, iv, kord, ptop)
subroutine, public read_grid(lon, lat, ak, bk)
subroutine, public read_sub_domain_init(ylo, yhi, ydat, js, je)
subroutine, public read_time(times, units, calendar)
subroutine, public error_mesg(routine, message, level)
subroutine, public read_climate_nudge_data_init(nlon, nlat, nlev, ntime)
subroutine, public read_climate_nudge_data_end
logical module_is_initialized
real, parameter, public kappa
RDGAS / CP_AIR [dimensionless].
type(time_type), dimension(:), allocatable timelist
type(var_state_type), dimension(2) state
subroutine, public print_date(Time, str, unit)
real(fp), parameter, public pi
subroutine remap_xy_2d(isd, ied, jsd, jed, q_in, is, ie, js, je, id1, id2, jdc, s2c, q_out)