140 #include <fms_platform.h> 145 use block_control_mod,
only: block_control_type
146 use constants_mod,
only: cp_air, rdgas, grav, rvgas, kappa, pstd_mks
147 use time_manager_mod,
only: time_type, get_time, set_time,
operator(+), &
148 operator(-),
operator(/), time_type_to_real
149 use fms_mod,
only: file_exist, open_namelist_file, &
150 close_file, error_mesg, fatal, &
151 check_nml_error, stdlog, &
152 write_version_number, &
155 mpp_clock_id, mpp_clock_begin, &
156 mpp_clock_end, clock_subcomponent, &
157 clock_flag_default, nullify_domain
158 use mpp_mod,
only: mpp_error, stdout, fatal, note, &
159 input_nml_file, mpp_root_pe, &
160 mpp_npes, mpp_pe, mpp_chksum, &
161 mpp_get_current_pelist, &
162 mpp_set_current_pelist
163 use mpp_parameter_mod,
only: eupdate, wupdate, supdate, nupdate
164 use mpp_domains_mod,
only: domain2d, mpp_update_domains
165 use xgrid_mod,
only: grid_box_type
166 use field_manager_mod,
only: model_atmos
167 use tracer_manager_mod,
only: get_tracer_index, get_number_tracers, &
170 use ipd_typedefs,
only: ipd_data_type, kind_phys => ipd_kind_phys
196 use mpp_domains_mod,
only: mpp_get_data_domain, mpp_get_compute_domain
224 #include<file_version.h> 225 character(len=20) ::
mod_name =
'fvGFS/atmosphere_mod' 270 subroutine atmosphere_init (Time_init, Time, Time_step, Grid_box, area)
276 use ccpp_api,
only: ccpp_init
277 use ccpp_static_api,
only: ccpp_physics_init
279 use iso_c_binding,
only: c_loc
280 use ccpp_api,
only: ccpp_init, &
285 use ccpp_data,
only: ccpp_suite, &
286 cdata => cdata_tile, &
293 #include "ccpp_modules_fast_physics.inc" 297 type(time_type),
intent(in) :: time_init, time, time_step
298 type(grid_box_type),
intent(inout) :: grid_box
299 real(kind=kind_phys),
pointer,
dimension(:,:),
intent(inout) :: area
303 logical :: do_atmos_nudge
304 character(len=32) :: tracer_name, tracer_units
315 allocate(
pelist(mpp_npes()))
316 call mpp_get_current_pelist(
pelist)
318 zvir = rvgas/rdgas - 1.
328 cold_start = (.not.file_exist(
'INPUT/fv_core.res.nc') .and. .not.file_exist(
'INPUT/fv_core.res.tile1.nc'))
339 if(
atm(
mytile)%flagstruct%warm_start)
then 344 call write_version_number (
'fvGFS/ATMOSPHERE_MOD', version )
365 sphum = get_tracer_index(model_atmos,
'sphum' )
366 liq_wat = get_tracer_index(model_atmos,
'liq_wat' )
367 ice_wat = get_tracer_index(model_atmos,
'ice_wat' )
368 rainwat = get_tracer_index(model_atmos,
'rainwat' )
369 snowwat = get_tracer_index(model_atmos,
'snowwat' )
370 graupel = get_tracer_index(model_atmos,
'graupel' )
372 cld_amt = get_tracer_index(model_atmos,
'cld_amt')
376 call mpp_error (fatal,
' atmosphere_init: condensate species are not first in the list of & 377 &tracers defined in the field_table')
387 allocate(grid_box%edge_w(
jsc:
jec+1))
388 allocate(grid_box%edge_e(
jsc:
jec+1))
389 allocate(grid_box%edge_s(
isc:
iec+1 ))
390 allocate(grid_box%edge_n(
isc:
iec+1 ))
436 id_dynam = mpp_clock_id(
'FV dy-core', flags = clock_flag_default, grain=clock_subcomponent )
437 id_subgridz = mpp_clock_id(
'FV subgrid_z',flags = clock_flag_default, grain=clock_subcomponent )
438 id_fv_diag = mpp_clock_id(
'FV Diag', flags = clock_flag_default, grain=clock_subcomponent )
446 call ccpp_init(trim(ccpp_suite), cdata, ierr)
448 cdata%errmsg =
' atmosphere_dynamics: error in ccpp_init: ' // trim(cdata%errmsg)
449 call mpp_error (fatal, cdata%errmsg)
459 nthreads = omp_get_max_threads()
470 cld_amt>0, kappa,
atm(
mytile)%flagstruct%hydrostatic, &
487 mpirank=mpp_pe(), mpiroot=mpp_root_pe())
491 #include "ccpp_fields_fast_physics.inc" 494 if (
atm(
mytile)%flagstruct%do_sat_adj)
then 497 call ccpp_physics_init(cdata, suite_name=trim(ccpp_suite), group_name=
"fast_physics", ierr=ierr)
499 call ccpp_physics_init(cdata, group_name=
"fast_physics", ierr=ierr)
502 cdata%errmsg =
' atmosphere_dynamics: error in ccpp_physics_init for group fast_physics: ' // trim(cdata%errmsg)
503 call mpp_error (fatal, cdata%errmsg)
516 if (
atm(
mytile)%flagstruct%na_init>0 )
then 517 call nullify_domain ( )
518 if ( .not.
atm(
mytile)%flagstruct%hydrostatic )
then 522 if ( .not.
atm(
mytile)%flagstruct%hydrostatic )
then 525 call prt_height(
'na_ini Z500',
isc,
iec,
jsc,
jec, 3,
npz, 500.e2,
atm(
mytile)%phis,
atm(
mytile)%delz, &
529 call mpp_error(note,
'No adiabatic initialization correction in use')
533 call nullify_domain()
538 call switch_current_atm(
atm(n))
545 subroutine p_adi(km, ng, ifirst, ilast, jfirst, jlast, ptop, &
546 delp, pt, ps, pe, peln, pk, pkz, hydrostatic)
549 integer,
intent(in):: km, ng
550 integer,
intent(in):: ifirst, ilast
551 integer,
intent(in):: jfirst, jlast
552 logical,
intent(in):: hydrostatic
553 real,
intent(in):: ptop
554 real,
intent(in):: pt(ifirst-ng:ilast+ng,jfirst-ng:jlast+ng, km)
555 real,
intent(in):: delp(ifirst-ng:ilast+ng,jfirst-ng:jlast+ng, km)
557 real,
intent(out) :: ps(ifirst-ng:ilast+ng, jfirst-ng:jlast+ng)
558 real,
intent(out) :: pk(ifirst:ilast, jfirst:jlast, km+1)
559 real,
intent(out) :: pe(ifirst-1:ilast+1,km+1,jfirst-1:jlast+1)
560 real,
intent(out) :: peln(ifirst:ilast, km+1, jfirst:jlast)
561 real,
intent(out) :: pkz(ifirst:ilast, jfirst:jlast, km)
579 pe(i,k,j) = pe(i,k-1,j) + delp(i,j,k-1)
580 peln(i,k,j) = log(pe(i,k,j))
581 pk(i,j,k) = exp( kappa*peln(i,k,j) )
586 ps(i,j) = pe(i,km+1,j)
589 if ( hydrostatic )
then 592 pkz(i,j,k) = (pk(i,j,k+1)-pk(i,j,k))/(kappa*(peln(i,k+1,j)-peln(i,k,j)))
604 type(time_type),
intent(in) :: time
605 integer :: n, psc, atmos_time_step
606 integer :: k, w_diff, nt_dyn, n_split_loc,
seconds,
days 608 type(time_type) :: atmos_time
619 if (
seconds < nint(3600*
atm(n)%flagstruct%fhouri) .and.
atm(n)%flagstruct%fac_n_spl > 1.0)
then 620 n_split_loc = nint(
atm(n)%flagstruct%n_split *
atm(n)%flagstruct%fac_n_spl)
622 n_split_loc =
atm(n)%flagstruct%n_split
632 if(
atm(n)%flagstruct%regional)
then 643 atm(n)%flagstruct%consv_te,
atm(n)%flagstruct%fill, &
644 atm(n)%flagstruct%reproduce_sum, kappa, cp_air,
zvir, &
646 n_split_loc,
atm(n)%flagstruct%q_split, &
649 atm(n)%flagstruct%hydrostatic, &
656 atm(n)%flagstruct%hybrid_z, &
657 atm(n)%gridstruct,
atm(n)%flagstruct, &
658 atm(n)%neststruct,
atm(n)%idiag,
atm(n)%bd, &
659 atm(n)%parent_grid,
atm(n)%domain,
atm(n)%diss_est)
681 w_diff = get_tracer_index(model_atmos,
'w_diff' )
682 if (
atm(n)%flagstruct%fv_sg_adj > 0 )
then 684 if ( w_diff /= no_tracer )
then 689 atm(n)%flagstruct%nwat,
atm(n)%delp,
atm(n)%pe, &
691 atm(n)%ua,
atm(n)%va,
atm(n)%flagstruct%hydrostatic,&
693 atm(n)%flagstruct%n_sponge)
697 if ( .not.
atm(n)%flagstruct%hydrostatic .and. w_diff /= no_tracer )
then 703 q_dt(:,:,k,w_diff) = 0.
721 use ccpp_static_api,
only: ccpp_physics_finalize
722 use ccpp_data,
only: ccpp_suite
724 use ccpp_api,
only: ccpp_physics_finalize
726 use ccpp_data,
only: cdata => cdata_tile
728 type(time_type),
intent(in) :: time
729 type(grid_box_type),
intent(inout) :: grid_box
734 if (
atm(
mytile)%flagstruct%do_sat_adj)
then 737 call ccpp_physics_finalize(cdata, suite_name=trim(ccpp_suite), group_name=
"fast_physics", ierr=ierr)
739 call ccpp_physics_finalize(cdata, group_name=
"fast_physics", ierr=ierr)
742 cdata%errmsg =
' atmosphere_dynamics: error in ccpp_physics_finalize for group fast_physics: ' // trim(cdata%errmsg)
743 call mpp_error (fatal, cdata%errmsg)
748 call nullify_domain ( )
770 character(len=*),
intent(in) :: timestamp
781 integer,
intent(out) :: i_size, j_size
782 logical,
intent(in),
optional :: global
786 if(
PRESENT(global) ) local = .NOT.global
801 real,
dimension(:,:),
intent(inout) :: p_ref
809 integer,
intent(out) :: i1, i2, j1, j2, kt
810 logical,
intent(out),
optional :: p_hydro, hydro
811 integer,
intent(out),
optional :: tile_num
818 if (
present(tile_num)) tile_num =
atm(
mytile)%tile
819 if (
present(p_hydro)) p_hydro =
atm(
mytile)%flagstruct%phys_hydrostatic
820 if (
present( hydro)) hydro =
atm(
mytile)%flagstruct%hydrostatic
828 real(kind=kind_phys),
intent(out) :: lon(:,:), lat(:,:)
845 real,
intent(out) :: blon(:,:), blat(:,:)
846 logical,
intent(in),
optional :: global
850 if(
PRESENT(global) )
then 851 if (global)
call mpp_error(fatal,
'==> global grid is no longer available & 852 & in the Cubed Sphere')
866 call mpp_set_current_pelist(
atm(
mytile)%pelist, no_sync=.true.)
875 type(domain2d),
intent(out) :: fv_domain
876 integer,
intent(out) :: layout(2)
877 logical,
intent(out) :: regional
878 logical,
intent(out) :: nested
879 integer,
pointer,
intent(out) ::
pelist(:)
883 fv_domain =
atm(
mytile)%domain_for_coupler
885 regional =
atm(
mytile)%flagstruct%regional
896 integer,
intent(out) :: axes (:)
899 if (
size(axes(:)) < 0 .or.
size(axes(:)) > 4 )
call error_mesg ( &
900 'get_atmosphere_axes in atmosphere_mod', &
901 'size of argument is incorrect', fatal )
903 axes(1:
size(axes(:))) =
atm(
mytile)%atmos_axes (1:
size(axes(:)))
913 real(kind=kind_phys),
pointer,
dimension(:),
intent(inout) :: ak, bk
914 logical,
intent(in) :: flip
935 real(kind=kind_phys),
pointer,
dimension(:,:,:),
intent(inout) :: hgt
936 character(len=5),
intent(in) :: position
937 logical,
intent(in) :: relative
938 logical,
intent(in) :: flip
940 integer:: lev, k, j, i,
npx,
npy 941 real(kind=kind_phys),
dimension(isc:iec,jsc:jec,1:npz+1) :: z
942 real(kind=kind_phys),
dimension(isc:iec,jsc:jec,1:npz) :: dz
944 if ((position .ne.
"layer") .and. (position .ne.
"level"))
then 945 call mpp_error (fatal,
'atmosphere_hgt:: incorrect position specification')
953 if (
atm(
mytile)%flagstruct%hydrostatic)
then 978 if (position ==
"level")
then 981 elseif (position ==
"layer")
then 1006 real(kind=kind_phys),
dimension(1:isize,1:jsize,ksize),
intent(inout) :: data
1009 integer,
intent(in) :: halo
1010 integer,
intent(in) :: isize
1011 integer,
intent(in) :: jsize
1012 integer,
intent(in) :: ksize
1013 real(kind=kind_phys),
dimension(:,:),
optional,
intent(in) :: data_p
1017 character(len=44) :: modname =
'atmosphere_mod::atmosphere_scalar_field_halo' 1018 integer :: mpp_flags
1021 if (halo .gt. 3)
call mpp_error(fatal, modname//.gt.
' - halo3 requires extending the MPP domain to support')
1022 ic = isize - 2 * halo
1023 jc = jsize - 2 * halo
1026 if (
present(data_p))
then 1027 if (ic*jc .ne.
size(data_p,1))
call mpp_error(fatal, modname//
' - incorrect sizes for incoming & 1028 &variables data and data_p')
1036 data(i+halo, j+halo, k) = data_p(i + (j-1)*ic, k)
1042 mpp_flags = eupdate + wupdate + supdate + nupdate
1044 call mpp_update_domains(
data,
atm(
mytile)%domain_for_coupler, flags=mpp_flags, complete=.true.)
1045 elseif (halo == 3)
then 1046 call mpp_update_domains(
data,
atm(
mytile)%domain, flags=mpp_flags, complete=.true.)
1048 call mpp_error(fatal, modname//
' - unsupported halo size')
1057 if ((
isc== 1) .and. (
jsc== 1))
data(halo+1-j ,halo+1-i ,k) =
data(halo+i ,halo+1-j ,k)
1058 if ((
isc== 1) .and. (
jec==
npy-1))
data(halo+1-j ,halo+jc+i,k) =
data(halo+i ,halo+jc+j,k)
1059 if ((
iec==
npx-1) .and. (
jsc== 1))
data(halo+ic+j,halo+1-i ,k) =
data(halo+ic-i+1,halo+1-j ,k)
1060 if ((
iec==
npx-1) .and. (
jec==
npy-1))
data(halo+ic+j,halo+jc+i,k) =
data(halo+ic-i+1,halo+jc+j,k)
1073 integer,
intent(in) :: npass
1079 do k = 1,min(3,npass)
1101 type(time_type),
intent(in) :: time
1102 logical,
optional,
intent(in) :: init, ltavg
1103 real,
optional,
intent(in) :: avg_max_length
1104 if (
PRESENT(init))
then 1109 call mpp_error(fatal,
'atmosphere_nggps_diag - calling with init present, but set to .false.')
1112 if (
PRESENT(ltavg))
then 1162 subroutine get_bottom_mass ( t_bot, tr_bot, p_bot, z_bot, p_surf, slp )
1168 real,
intent(out),
dimension(isc:iec,jsc:jec):: t_bot, p_bot, z_bot, p_surf
1169 real,
intent(out),
optional,
dimension(isc:iec,jsc:jec):: slp
1170 real,
intent(out),
dimension(isc:iec,jsc:jec,nq):: tr_bot
1172 integer :: i, j, m, k, kr
1173 real :: rrg, sigtop, sigbot
1174 real,
dimension(isc:iec,jsc:jec) :: tref
1175 real,
parameter :: tlaps = 6.5e-3
1184 z_bot(i,j) = rrg*t_bot(i,j)*(1. -
atm(
mytile)%pe(i,
npz,j)/p_bot(i,j))
1193 if (
present(slp) )
then 1198 if (sigbot+sigtop > 1.6)
then 1209 slp(i,j) =
atm(
mytile)%ps(i,j)*(1.+tlaps*
atm(
mytile)%phis(i,j)/(tref(i,j)*grav))**(1./(rrg*tlaps))
1231 real,
intent(out),
dimension(isc:iec,jsc:jec):: u_bot, v_bot
1256 type(block_control_type),
intent(in) :: atm_block
1259 integer :: ix, i, j, nt, k, nb
1260 real :: rrg, sigtop, sigbot, tref
1262 real,
parameter :: tlaps = 6.5e-3
1265 logical,
save :: first_time = .true.
1269 if (first_time)
then 1270 print *,
'calculating slp kr value' 1275 if (sigbot+sigtop > 1.6)
then 1282 do nb = 1,atm_block%nblks
1283 call dycore_data(nb)%Coupling%create (atm_block%blksz(nb),
nq)
1285 first_time = .false.
1291 do nb = 1,atm_block%nblks
1292 do ix = 1,atm_block%blksz(nb)
1293 i = atm_block%index(nb)%ii(ix)
1294 j = atm_block%index(nb)%jj(ix)
1296 dycore_data(nb)%Coupling%p_srf(ix) =
atm(
mytile)%ps(i,j)
1298 dycore_data(nb)%Coupling%t_bot(ix) =
atm(
mytile)%pt(i,j,
npz)
1300 dycore_data(nb)%Coupling%u_bot(ix) =
atm(
mytile)%u_srf(i,j)
1301 dycore_data(nb)%Coupling%v_bot(ix) =
atm(
mytile)%v_srf(i,j)
1303 dycore_data(nb)%Coupling%z_bot(ix) = rrg*dycore_data(nb)%Coupling%t_bot(ix) * &
1304 (1. -
atm(
mytile)%pe(i,
npz,j)/dycore_data(nb)%Coupling%p_bot(ix))
1306 dycore_data(nb)%Coupling%z_bot(ix) = dycore_data(nb)%Coupling%z_bot(ix)*
virq(
atm(
mytile)%q(i,j,
npz,:))
1308 dycore_data(nb)%Coupling%z_bot(ix) = dycore_data(nb)%Coupling%z_bot(ix)*(1.+
zvir*
atm(
mytile)%q(i,j,
npz,1))
1313 dycore_data(nb)%Coupling%slp(ix) =
atm(
mytile)%ps(i,j)*(1.+tlaps*
atm(
mytile)%phis(i,j)/(tref*grav))**(1./(rrg*tlaps))
1318 do ix = 1,atm_block%blksz(nb)
1319 i = atm_block%index(nb)%ii(ix)
1320 j = atm_block%index(nb)%jj(ix)
1321 dycore_data(nb)%Coupling%tr_bot(ix,nt) =
atm(
mytile)%q(i,j,
npz,nt)
1330 integer,
intent(in) :: index
1331 real,
intent(out) :: value
1337 real wm(isc:iec,jsc:jec)
1339 real,
pointer :: area(:,:)
1372 value =
value + wm(i,j)*area(i,j)
1387 type(time_type),
intent(in) :: time
1388 type(ipd_data_type),
intent(in) :: ipd_data(:)
1390 type(block_control_type),
intent(in) :: atm_block
1391 logical,
intent(in) :: flip_vc
1393 type(time_type) :: time_prev, time_next
1394 integer :: i, j, ix, k, k1, n, w_diff, nt_dyn, iq
1395 integer :: nb, blen, nwat, dnats, nq_adv
1396 real(kind=kind_phys):: rcp, q0, qwat(
nq), qt, rdt
1402 nwat =
atm(n)%flagstruct%nwat
1406 if(
nq<3 )
call mpp_error(fatal,
'GFS phys must have 3 interactive tracers')
1408 if (iau_data%in_interval)
then 1416 u_dt(i,j,k) =
u_dt(i,j,k) + iau_data%ua_inc(i,j,k)
1417 v_dt(i,j,k) =
v_dt(i,j,k) + iau_data%va_inc(i,j,k)
1418 t_dt(i,j,k) =
t_dt(i,j,k) + iau_data%temp_inc(i,j,k)
1419 atm(n)%delp(i,j,k) =
atm(n)%delp(i,j,k) + iau_data%delp_inc(i,j,k)*
dt_atmos 1423 if (.not.
atm(
mytile)%flagstruct%hydrostatic)
then 1427 atm(n)%delz(i,j,k) =
atm(n)%delz(i,j,k) + iau_data%delz_inc(i,j,k)*
dt_atmos 1433 do nb = 1,atm_block%nblks
1435 blen = atm_block%blksz(nb)
1443 i = atm_block%index(nb)%ii(ix)
1444 j = atm_block%index(nb)%jj(ix)
1445 ipd_data(nb)%Stateout%gq0(ix,k,:) = ipd_data(nb)%Stateout%gq0(ix,k,:) + iau_data%tracer_inc(i,j,k1,:)*
dt_atmos 1463 do nb = 1,atm_block%nblks
1467 blen = atm_block%blksz(nb)
1468 call fill_gfs(blen,
npz, ipd_data(nb)%Statein%prsi, ipd_data(nb)%Stateout%gq0, 1.e-9_kind_phys)
1477 i = atm_block%index(nb)%ii(ix)
1478 j = atm_block%index(nb)%jj(ix)
1479 u_dt(i,j,k1) =
u_dt(i,j,k1) + (ipd_data(nb)%Stateout%gu0(ix,k) - ipd_data(nb)%Statein%ugrs(ix,k)) * rdt
1480 v_dt(i,j,k1) =
v_dt(i,j,k1) + (ipd_data(nb)%Stateout%gv0(ix,k) - ipd_data(nb)%Statein%vgrs(ix,k)) * rdt
1482 t_dt(i,j,k1) =
t_dt(i,j,k1) + (ipd_data(nb)%Stateout%gt0(ix,k) - ipd_data(nb)%Statein%tgrs(ix,k)) * rdt
1490 q0 = ipd_data(nb)%Statein%prsi(ix,k) - ipd_data(nb)%Statein%prsi(ix,k+1)
1492 q0 = ipd_data(nb)%Statein%prsi(ix,k+1) - ipd_data(nb)%Statein%prsi(ix,k)
1494 qwat(1:nq_adv) = q0*ipd_data(nb)%Stateout%gq0(ix,k,1:nq_adv)
1501 q0 =
atm(n)%delp(i,j,k1)*(1.-sum(
atm(n)%q(i,j,k1,1:max(nwat,
num_gas)))) + sum(qwat(1:max(nwat,
num_gas)))
1503 qt = sum(qwat(1:nwat))
1504 q0 =
atm(n)%delp(i,j,k1)*(1.-sum(
atm(n)%q(i,j,k1,1:nwat))) + qt
1506 atm(n)%delp(i,j,k1) = q0
1507 atm(n)%q(i,j,k1,1:nq_adv) = qwat(1:nq_adv) / q0
1523 i = atm_block%index(nb)%ii(ix)
1524 j = atm_block%index(nb)%jj(ix)
1525 atm(
mytile)%qdiag(i,j,k1,iq) = ipd_data(nb)%Stateout%gq0(ix,k,iq)
1534 w_diff = get_tracer_index(model_atmos,
'w_diff' )
1536 if ( w_diff /= no_tracer )
then 1542 if ( .not.
atm(n)%flagstruct%hydrostatic .and. w_diff /= no_tracer )
then 1550 atm(n)%q(i,j,k,w_diff) = q_dt(i,j,k,w_diff)
1552 t_dt(i,j,k) =
t_dt(i,j,k) - q_dt(i,j,k,w_diff)*rcp*&
1563 call fv_update_phys(
dt_atmos,
isc,
iec,
jsc,
jec,
isd,
ied,
jsd,
jed,
atm(n)%ng, nt_dyn, &
1565 atm(n)%q,
atm(n)%qdiag, &
1570 .true., time_next,
atm(n)%flagstruct%nudge,
atm(n)%gridstruct, &
1571 atm(n)%gridstruct%agrid(:,:,1),
atm(n)%gridstruct%agrid(:,:,2), &
1572 atm(n)%npx,
atm(n)%npy,
atm(n)%npz,
atm(n)%flagstruct, &
1573 atm(n)%neststruct,
atm(n)%bd,
atm(n)%domain,
atm(n)%ptop)
1584 call nullify_domain()
1587 if (
atm(
mytile)%flagstruct%print_freq /= -99)
then 1593 call nullify_domain()
1609 type(time_type),
intent(in) :: time
1610 real,
allocatable,
dimension(:,:,:):: u0, v0, t0, dz0, dp0
1611 real,
intent(in) :: zvir
1612 logical,
intent(inout):: nudge_dz
1614 real,
parameter:: wt = 2.
1618 real,
parameter:: q1_h2o = 2.2e-6
1619 real,
parameter:: q7_h2o = 3.8e-6
1620 real,
parameter:: q100_h2o = 3.8e-6
1621 real,
parameter:: q1000_h2o = 3.1e-6
1622 real,
parameter:: q2000_h2o = 2.8e-6
1623 real,
parameter:: q3000_h2o = 3.0e-6
1625 integer:: isc, iec, jsc, jec, npz
1626 integer:: m, n, i,j,k, ngc, n_split_loc, days
1628 character(len=80) :: errstr
1632 write(errstr,
'(A, I4, A)')
'Performing adiabatic init',
atm(
mytile)%flagstruct%na_init,
' times' 1633 call mpp_error(note, errstr)
1634 sphum = get_tracer_index(model_atmos,
'sphum' )
1652 allocate ( u0(isc:iec, jsc:jec+1, npz) )
1653 allocate ( v0(isc:iec+1,jsc:jec, npz) )
1654 allocate (dp0(isc:iec,jsc:jec, npz) )
1656 if (
atm(
mytile)%flagstruct%hydrostatic ) nudge_dz = .false.
1658 if ( nudge_dz )
then 1659 allocate (dz0(isc:iec,jsc:jec, npz) )
1661 allocate ( t0(isc:iec,jsc:jec, npz) )
1678 if ( nudge_dz )
then 1699 call get_time (time,
seconds, days)
1701 n_split_loc = nint(
atm(
mytile)%flagstruct%n_split *
atm(
mytile)%flagstruct%fac_n_spl)
1703 n_split_loc =
atm(
mytile)%flagstruct%n_split
1712 atm(
mytile)%flagstruct%fill,
atm(
mytile)%flagstruct%reproduce_sum, kappa, cp_air, zvir, &
1727 atm(
mytile)%flagstruct%fill,
atm(
mytile)%flagstruct%reproduce_sum, kappa, cp_air, zvir, &
1755 if(
atm(
mytile)%flagstruct%nudge_qv )
then 1759 if ( p00 < 30.e2 )
then 1760 if ( p00 < 1. )
then 1762 elseif ( p00 <= 7. .and. p00 >= 1. )
then 1763 q00 = q1_h2o + (q7_h2o-q1_h2o)*log(
pref(k,1)/1.)/log(7.)
1764 elseif ( p00 < 100. .and. p00 >= 7. )
then 1765 q00 = q7_h2o + (q100_h2o-q7_h2o)*log(
pref(k,1)/7.)/log(100./7.)
1766 elseif ( p00 < 1000. .and. p00 >= 100. )
then 1767 q00 = q100_h2o + (q1000_h2o-q100_h2o)*log(
pref(k,1)/1.e2)/log(10.)
1768 elseif ( p00 < 2000. .and. p00 >= 1000. )
then 1769 q00 = q1000_h2o + (q2000_h2o-q1000_h2o)*log(
pref(k,1)/1.e3)/log(2.)
1771 q00 = q2000_h2o + (q3000_h2o-q2000_h2o)*log(
pref(k,1)/2.e3)/log(1.5)
1780 if ( nudge_dz )
then 1804 atm(
mytile)%flagstruct%fill,
atm(
mytile)%flagstruct%reproduce_sum, kappa, cp_air, zvir, &
1819 atm(
mytile)%flagstruct%fill,
atm(
mytile)%flagstruct%reproduce_sum, kappa, cp_air, zvir, &
1847 if ( nudge_dz )
then 1873 if (
allocated(t0) )
deallocate ( t0 )
1874 if (
allocated(dz0) )
deallocate ( dz0 )
1889 #if defined(OVERLOAD_R4) 1890 #define _DBL_(X) DBLE(X) 1891 #define _RL_(X) REAL(X,KIND=4) 1897 type(ipd_data_type),
intent(inout) :: ipd_data(:)
1898 type(block_control_type),
intent(in) :: atm_block
1899 logical,
intent(in) :: flip_vc
1903 real(kind=kind_phys),
parameter :: p00 = 1.e5
1904 real(kind=kind_phys),
parameter :: qmin = 1.0e-10
1905 real(kind=kind_phys) :: pk0inv, ptop, pktop
1906 real(kind=kind_phys) :: rtv, dm, qgrs_rad
1907 integer :: nb, blen,
npz, i, j, k, ix, k1, kz, dnats, nq_adv
1914 pktop = (ptop/p00)**kappa
1915 pk0inv = (1.0_kind_phys/p00)**kappa
1930 do nb = 1,atm_block%nblks
1934 blen = atm_block%blksz(nb)
1938 ipd_data(nb)%Statein%phii(:,1) = 0.0_kind_phys
1940 ipd_data(nb)%Statein%phii(:,
npz+1) = 0.0_kind_phys
1942 ipd_data(nb)%Statein%prsik(:,:) = 1.e25_kind_phys
1955 i = atm_block%index(nb)%ii(ix)
1956 j = atm_block%index(nb)%jj(ix)
1958 ipd_data(nb)%Statein%tgrs(ix,k) = _dbl_(_rl_(
atm(
mytile)%pt(i,j,k1)))
1959 ipd_data(nb)%Statein%ugrs(ix,k) = _dbl_(_rl_(
atm(
mytile)%ua(i,j,k1)))
1960 ipd_data(nb)%Statein%vgrs(ix,k) = _dbl_(_rl_(
atm(
mytile)%va(i,j,k1)))
1961 ipd_data(nb)%Statein%vvl(ix,k) = _dbl_(_rl_(
atm(
mytile)%omga(i,j,k1)))
1962 ipd_data(nb)%Statein%prsl(ix,k) = _dbl_(_rl_(
atm(
mytile)%delp(i,j,k1)))
1963 if (
atm(
mytile)%flagstruct%do_skeb)ipd_data(nb)%Statein%diss_est(ix,k) = _dbl_(_rl_(
atm(
mytile)%diss_est(i,j,k1)))
1966 if (.not.
atm(
mytile)%flagstruct%hydrostatic .and. (.not.
atm(
mytile)%flagstruct%use_hydro_pressure)) &
1967 ipd_data(nb)%Statein%phii(ix,k+1) = ipd_data(nb)%Statein%phii(ix,k) - _dbl_(_rl_(
atm(
mytile)%delz(i,j,k1)*grav))
1969 if (.not.
atm(
mytile)%flagstruct%hydrostatic .and. (.not.
atm(
mytile)%flagstruct%use_hydro_pressure)) &
1970 ipd_data(nb)%Statein%phii(ix,kz) = ipd_data(nb)%Statein%phii(ix,kz+1) - _dbl_(_rl_(
atm(
mytile)%delz(i,j,kz)*grav))
1974 ipd_data(nb)%Statein%qgrs(ix,k,1:nq_adv) = _dbl_(_rl_(
atm(
mytile)%q(i,j,k1,1:nq_adv))) &
1975 * ipd_data(nb)%Statein%prsl(ix,k)
1977 ipd_data(nb)%Statein%qgrs(ix,k,nq_adv+1:
nq) = _dbl_(_rl_(
atm(
mytile)%q(i,j,k1,nq_adv+1:
nq)))
1983 if (
atm(
mytile)%flagstruct%nwat == 6 )
then 1984 ipd_data(nb)%Statein%prsl(ix,k) = ipd_data(nb)%Statein%prsl(ix,k) &
1985 - ipd_data(nb)%Statein%qgrs(ix,k,
liq_wat) &
1986 - ipd_data(nb)%Statein%qgrs(ix,k,
ice_wat) &
1987 - ipd_data(nb)%Statein%qgrs(ix,k,
rainwat) &
1988 - ipd_data(nb)%Statein%qgrs(ix,k,
snowwat) &
1989 - ipd_data(nb)%Statein%qgrs(ix,k,
graupel)
1991 ipd_data(nb)%Statein%prsl(ix,k) = ipd_data(nb)%Statein%prsl(ix,k) &
1992 - sum(ipd_data(nb)%Statein%qgrs(ix,k,2:
atm(
mytile)%flagstruct%nwat))
2000 ipd_data(nb)%Statein%prsi(i,
npz+1) = ptop
2004 ipd_data(nb)%Statein%prsi(i,k) = ipd_data(nb)%Statein%prsi(i,k+1) + ipd_data(nb)%Statein%prsl(i,k)
2005 ipd_data(nb)%Statein%prsik(i,k) = log( ipd_data(nb)%Statein%prsi(i,k) )
2007 ipd_data(nb)%Statein%qgrs(i,k,1:nq_adv) = ipd_data(nb)%Statein%qgrs(i,k,1:nq_adv) &
2008 / ipd_data(nb)%Statein%prsl(i,k)
2013 ipd_data(nb)%Statein%prsi(i, 1) = ptop
2017 ipd_data(nb)%Statein%prsi(i,k+1) = ipd_data(nb)%Statein%prsi(i,k) + ipd_data(nb)%Statein%prsl(i,k)
2018 ipd_data(nb)%Statein%prsik(i,k) = log( ipd_data(nb)%Statein%prsi(i,k) )
2020 ipd_data(nb)%Statein%qgrs(i,k,1:nq_adv) = ipd_data(nb)%Statein%qgrs(i,k,1:nq_adv) &
2021 / ipd_data(nb)%Statein%prsl(i,k)
2027 ipd_data(nb)%Statein%pgr(i) = ipd_data(nb)%Statein%prsi(i,1)
2028 ipd_data(nb)%Statein%prsik(i,
npz+1) = log(ptop)
2035 rtv = rdgas*ipd_data(nb)%Statein%tgrs(i,k)*
virq_max(ipd_data(nb)%Statein%qgrs(i,k,:),qmin)
2037 qgrs_rad = max(qmin,ipd_data(nb)%Statein%qgrs(i,k,
sphum))
2038 rtv = rdgas*ipd_data(nb)%Statein%tgrs(i,k)*(1.+
zvir*qgrs_rad)
2040 if (
atm(
mytile)%flagstruct%hydrostatic .or.
atm(
mytile)%flagstruct%use_hydro_pressure ) &
2041 ipd_data(nb)%Statein%phii(i,k+1) = ipd_data(nb)%Statein%phii(i,k) &
2042 + rtv*(ipd_data(nb)%Statein%prsik(i,k) &
2043 - ipd_data(nb)%Statein%prsik(i,k+1))
2045 dm = ipd_data(nb)%Statein%prsl(i,k)
2046 ipd_data(nb)%Statein%prsl(i,k) = dm*rtv/(ipd_data(nb)%Statein%phii(i,k+1) &
2047 - ipd_data(nb)%Statein%phii(i,k))
2050 if ( .not.
atm(
mytile)%flagstruct%hydrostatic )
then 2052 ipd_data(nb)%Statein%prsl(i,k) = min(ipd_data(nb)%Statein%prsl(i,k), &
2053 ipd_data(nb)%Statein%prsi(i,k) - 0.01*dm)
2054 ipd_data(nb)%Statein%prsl(i,k) = max(ipd_data(nb)%Statein%prsl(i,k), &
2055 ipd_data(nb)%Statein%prsi(i,k+1) + 0.01*dm)
2063 ipd_data(nb)%Statein%prslk(i,k) = exp( kappa*log(ipd_data(nb)%Statein%prsl(i,k)/p00) )
2065 ipd_data(nb)%Statein%phil(i,k) = 0.5_kind_phys*(ipd_data(nb)%Statein%phii(i,k) &
2066 + ipd_data(nb)%Statein%phii(i,k+1))
2073 ipd_data(nb)%Statein%prsik(i, 1) = exp( kappa*ipd_data(nb)%Statein%prsik(i,1) )*pk0inv
2074 ipd_data(nb)%Statein%prsik(i,
npz+1) = pktop
2077 if (
atm(
mytile)%flagstruct%hydrostatic .or.
atm(
mytile)%flagstruct%use_hydro_pressure )
then 2080 ipd_data(nb)%Statein%prsik(i,k) = exp( kappa*ipd_data(nb)%Statein%prsik(i,k) )*pk0inv
subroutine, public atmosphere_end(Time, Grid_box)
The subroutine 'atmosphere_end' is an API for the termination of the FV3 dynamical core responsible f...
subroutine, public prt_height(qname, is, ie, js, je, ng, km, press, phis, delz, peln, area, lat)
subroutine, public fv_restart(fv_domain, Atm, dt_atmos, seconds, days, cold_start, grid_type, grids_on_this_pe)
The subroutine 'fv_restart' initializes the model state, including prognaostic variables and several ...
subroutine, public fv_update_phys(dt, is, ie, js, je, isd, ied, jsd, jed, ng, nq, u, v, w, delp, pt, q, qdiag, ua, va, ps, pe, peln, pk, pkz, ak, bk, phis, u_srf, v_srf, ts, delz, hydrostatic, u_dt, v_dt, t_dt, moist_phys, Time, nudge, gridstruct, lona, lata, npx, npy, npz, flagstruct, neststruct, bd, domain, ptop, q_dt)
subroutine, public atmosphere_dynamics(Time)
The subroutine 'atmosphere_dynamics' is an API for the main driver of the FV3 dynamical core responsi...
subroutine, public atmosphere_hgt(hgt, position, relative, flip)
The subroutine 'atmosphere_hgt' is an API to return the height coordinate. By default, the vertical dimension assumes the standard FV3 convention of TOA (k=1) to Surface (k=npz). There are options to choose location [level (interface) or layer] and absolute vs. relative height (zero-based).
logical, public do_adiabatic_init
subroutine get_stock_pe(index, value)
real, public current_time_in_seconds
The module 'fv_mp_mod' is a single program multiple data (SPMD) parallel decompostion/communication m...
subroutine timing_off(blk_name)
The subroutine 'timing_off' stops a timer.
subroutine, public fv_write_restart(Atm, grids_on_this_pe, timestamp)
The subroutine 'fv_write_restart' writes restart files to disk.
subroutine, public fv_init(Atm, dt_atmos, grids_on_this_pe, p_split)
The subroutine 'fv_init' initializes FV3.
subroutine, public atmosphere_get_bottom_layer(Atm_block, DYCORE_Data)
The subroutine 'atmosphere_get_bottom_layer' is an API to provide the bottom layer quantities needed ...
subroutine, public fv_nggps_tavg(Atm, Time_step_atmos, avg_max_length, zvir)
The module 'multi_gases' peforms multi constitutents computations.
pure real function, public virq_max(q, qmin)
subroutine, public atmosphere_diss_est(npass)
subroutine adiabatic_init(zvir, nudge_dz, time)
The subroutine 'adiabatic_init' is an optional step during initialization to pre-condition a solution...
subroutine, public get_eta_level(npz, p_s, pf, ph, ak, bk, pscale)
The subroutine 'get_eta_level' returns the interface and layer-mean pressures for reference...
subroutine, public atmosphere_control_data(i1, i2, j1, j2, kt, p_hydro, hydro, tile_num)
subroutine, public atmos_phys_driver_statein(IPD_Data, Atm_block, flip_vc)
The subroutine 'atmos_phys_driver_statein' is an API to populate the IPD_DataStatein container with t...
logical, dimension(:), allocatable grids_on_this_pe
The module 'fv_update_phys' applies physics tendencies consistent with the FV3 discretization and def...
integer, parameter, public r_grid
The module 'fv_dynamics' is the top-level routine for the dynamical core.
real, dimension(:), allocatable ri
The module 'fv_sg' performs FV sub-grid mixing.
The module fv_nwp_nudge contains routines for nudging to input analyses. note This module is currentl...
integer, dimension(:), allocatable id_tracerdt_dyn
type(time_type) time_step_atmos
real, dimension(:,:,:), allocatable u_dt
subroutine get_bottom_mass(t_bot, tr_bot, p_bot, z_bot, p_surf, slp)
The module 'fv_timing' contains FV3 timers.
pure real function, public virq(q)
real, dimension(:), allocatable dum1d
subroutine, public fv_diag_init(Atm, axes, Time, npx, npy, npz, p_ref)
subroutine, public fv_dynamics(npx, npy, npz, nq_tot, ng, bdt, consv_te, fill, reproduce_sum, kappa, cp_air, zvir, ptop, ks, ncnst, n_split, q_split, u, v, w, delz, hydrostatic, pt, delp, q, ps, pe, pk, peln, pkz, phis, q_con, omga, ua, va, uc, vc, ak, bk, mfx, mfy, cx, cy, ze0, hybrid_z, gridstruct, flagstruct, neststruct, idiag, bd, parent_grid, domain, diss_est, time_total)
The module 'fv_nggps_diags' computes output diagnostics entirely on 3D pressure levels.
incremental analysis update module
subroutine, public fv_nggps_diag(Atm, zvir, Time)
subroutine get_bottom_wind(u_bot, v_bot)
subroutine, public fv_nggps_diag_init(Atm, axes, Time)
subroutine, public atmosphere_diag_axes(axes)
The subroutine 'atmosphere_diag_axes' is an API to return the axis indices for the atmospheric (mass)...
subroutine, public fv_nwp_nudge_end
The subroutine 'fv_nwp_nudge_end' terminates the nudging module.
The module 'fv_arrays' contains the 'fv_atmos_type' and associated datatypes.
subroutine, public set_atmosphere_pelist()
real, dimension(:,:,:), allocatable v_dt
The module 'fv_eta' contains routine to set up the reference (Eulerian) pressure coordinate.
subroutine, public twoway_nesting(Atm, ngrids, grids_on_this_pe, zvir)
The subroutine'twoway_nesting' performs a two-way update of nested-grid data onto the parent grid...
subroutine, public fv_diag(Atm, zvir, Time, print_freq)
The module 'atmosphere' provides the interface for the Cubed-Sphere FV dynamical core.
subroutine, public atmosphere_resolution(i_size, j_size, global)
The subroutine 'atmospehre_resolution' is an API to return the local extents of the current MPI-rank ...
subroutine, public atmosphere_etalvls(ak, bk, flip)
The subroutine 'atmosphere_etalvls' is an API to return the ak/bk pairs used to compute the eta or pr...
subroutine, public atmosphere_init(Time_init, Time, Time_step, Grid_box, area)
The subroutine 'atmosphere_init' is an API to initialize the FV3 dynamical core, including the grid s...
subroutine, public del2_cubed(q, cd, gridstruct, domain, npx, npy, km, nmax, bd)
The subroutine 'del2-cubed' filters the omega field for the physics.
type(fv_atmos_type), dimension(:), allocatable, target, public atm
subroutine, public fill_gfs(im, km, pe2, q, q_min)
The subroutine 'fill_gfs' is for mass-conservative filling of nonphysical negative values in the trac...
integer, dimension(:), allocatable pelist
subroutine p_adi(km, ng, ifirst, ilast, jfirst, jlast, ptop, delp, pt, ps, pe, peln, pk, pkz, hydrostatic)
The subroutine 'p_adi' computes (ps, pk, pe, peln, pkz) given (ptop, delp).
type(time_type), public fv_time
real, dimension(:), allocatable cpi
subroutine, public atmosphere_pref(p_ref)
The subroutine 'atmosphere_pref' is an API to return the reference pressure.
subroutine timing_on(blk_name)
The subroutine 'timing_on' starts a timer.
@ The module 'fv_diagnostics' contains routines to compute diagnosic fields.
subroutine, public atmosphere_restart(timestamp)
The subroutine 'atmosphere_restart' is an API to save restart information at a given timestamp...
The module 'dyn_core' peforms the Lagrangian acoustic dynamics described by .
subroutine, public prt_maxmin(qname, q, is, ie, js, je, n_g, km, fac)
character(len=20) mod_name
subroutine, public start_regional_restart(Atm, isc, iec, jsc, jec, isd, ied, jsd, jed)
subroutine, public fv_subgrid_z(isd, ied, jsd, jed, is, ie, js, je, km, nq, dt, tau, nwat, delp, pe, peln, pkz, ta, qa, ua, va, hydrostatic, w, delz, u_dt, v_dt, t_dt, q_dt, k_bot)
real, dimension(:,:), allocatable pref
subroutine, public atmosphere_scalar_field_halo(data, halo, isize, jsize, ksize, data_p)
The subroutine 'atmosphere_scalar_field_halo' is an API to return halo information of the current MPI...
subroutine, public fv_nwp_nudge_init(time, axes, npz, zvir, ak, bk, ts, phis, gridstruct, ks, npx, neststruct, bd)
The subroutine 'fv_nwp_nudge_init' initializes the nudging module.
subroutine, public atmosphere_nggps_diag(Time, init, ltavg, avg_max_length)
The subroutine 'atmosphere_nggps_diag' is an API to trigger output of diagnostics in NCEP/EMC format...
subroutine, public atmosphere_state_update(Time, IPD_Data, IAU_Data, Atm_block, flip_vc)
The subroutine 'atmosphere_state_update' is an API to apply tendencies and compute a consistent progn...
The module 'FV3_control' is for initialization and termination of the model, and controls namelist pa...
subroutine, public atmosphere_grid_bdry(blon, blat, global)
The subroutine 'atmosphere_grid_bdry' is an API to returns the longitude and latitude finite volume e...
subroutine, public atmosphere_grid_ctr(lon, lat)
The subroutine 'atmosphere_grid_ctr' is an API that returns the longitude and latitude cell centers o...
subroutine, public fv_end(Atm, grids_on_this_pe)
The subroutine 'fv_end' terminates FV3, deallocates memory, saves restart files, and stops I/O...
subroutine, public read_new_bc_data(Atm, Time, Time_step_atmos, p_split, isd, ied, jsd, jed)
subroutine, public atmosphere_domain(fv_domain, layout, regional, nested, pelist)
The subroutine 'atmosphere_domain' is an API to return the "domain2d" variable associated with the co...
The module 'fv_nesting' is a collection of routines pertaining to grid nesting .
real, dimension(:,:,:), allocatable t_dt