1 module canopy_transfer_mod
5 subroutine canopy_transfer_init( im, km, nkc, nkt, & !in
6 massair_can, massair, & !out
9 frctr2c, frctc2r, & !out
25 use machine ,
only : kind_phys
31 integer,
intent(in) :: im, km, nkc, nkt
33 integer,
intent(out) :: &
34 nfrct (km+nkc, im) , &
37 real(kind=kind_phys),
intent(out) :: &
38 massair_can(im, km+nkc) , &
40 mmr_o3_can(im, km+nkc) , &
41 frctr2c(km+nkc, 2, im) , &
42 frctc2r(km+nkc, 2, im)
44 character(len=*),
intent(out) :: errmsg
45 integer,
intent(out) :: errflg
63 end subroutine canopy_transfer_init
67 subroutine canopy_transfer_run( im, km, nkc, nkt, &
71 Q1, DENS, & !in: kg kg-1
75 zmom_can, zmid_can, & !in
76 PRES_CAN, DENS_CAN, & !in
77 Q1_MOD, Q1_CAN, Q1_2M, & !inout kg kg-1
78 massair_can, massair, & !inout
80 nfrct, ifrct, & !inout
81 frctr2c, frctc2r, & !inout
113 use machine ,
only : kind_phys
119 integer,
intent(in) :: im, km, nkc, nkt, ntrac, ntoz
120 integer,
intent(in) :: flag
121 real(kind=kind_phys),
intent(in) :: zi(im, km+1), zl(im, km), zm(im, km)
122 real(kind=kind_phys),
intent(in) :: garea(im)
125 real(kind=kind_phys),
intent(in) :: q1(im, km, ntrac)
127 real(kind=kind_phys),
intent(in) :: dens(im, km)
129 integer,
intent(in) :: kmod (im, km), kcan3 (im, nkc)
131 real(kind=kind_phys),
intent(inout) :: zmom_can(im, nkt+1) , &
134 real(kind=kind_phys),
intent(in) :: frt_mask(im) , &
136 pres_can(im, nkt) , &
140 real(kind=kind_phys),
intent(inout) :: q1_mod(im, km, ntrac), &
141 q1_can(im, nkt, ntrac)
142 real(kind=kind_phys),
intent(inout) :: q1_2m(im, ntrac)
144 integer,
intent(inout) :: nfrct (km+nkc, im) , &
145 ifrct (km+nkc, 2, im)
147 real(kind=kind_phys),
intent(inout) :: massair_can(im, km+nkc), &
149 mmr_o3_can(im, km+nkc), &
150 frctr2c(km+nkc, 2, im), &
151 frctc2r(km+nkc, 2, im)
153 character(len=*),
intent(out) :: errmsg
154 integer,
intent(out) :: errflg
158 real(kind=kind_phys) :: zmid(km) , &
163 pres_can3(nkt), pres3(km) , &
164 dens_can3(nkt), dens3(km) , &
168 real(kind=kind_phys) :: &
172 mmr_resolved(km + 1), &
173 vmr_resolved(km + 1), &
187 real(kind=kind_phys),
parameter :: diag_hgt = 2.0
188 real(kind=kind_phys),
parameter :: epsilon = 1.e-10
199 REAL(kind=kind_phys),
PARAMETER :: forward_conv = 1.e-9
200 REAL(kind=kind_phys),
PARAMETER :: reverse_conv = 1.e+9
202 real(kind=kind_phys) :: mmr_diag
204 logical(kind=4) :: chm_error_l = .false.
206 integer(kind=4) :: k, kk, kc, k2, II, npass
208 logical(kind=4) :: local_dbg
222 mass_resolved(:) = 0.
229 IF (frt_mask(i) <= 0.)
THEN
238 dens3(ii) = dens(i,k)
248 massair(i, k) = dens3(k) * garea(i) * &
249 (zmom(k) - zmom(k + 1))
254 massair_can(i, k) = massair(i, k)
258 massair_can(i, km+kc) = massair(i, km)
263 ELSE IF (frt_mask(i) > 0.)
THEN
275 pres_can3(ii) = pres_can(i,k)
276 dens_can3(ii) = dens_can(i,k)
285 zmom_can(i, nkt+ 1) = 0.0
288 massair_can(i, k) = dens_can3(k) * garea(i) * &
289 (zmom_can(i, k) - zmom_can(i, k + 1))
298 dens3(ii) = dens(i,k)
307 massair(i, k) = dens3(k) * garea(i) * &
308 (zmom(k) - zmom(k + 1))
325 if (zmom_can(i, k) == zmom(k) .and. zmom_can(i, k+1) == zmom(k+1))
then
328 frctr2c(k, 1, i) = 1.0
329 frctc2r(k, 1, i) = 1.0
344 if ((zmom_can(i, k) == zmom(kk) .and. zmom_can(i, k+1) > zmom(kk+1)) .or. &
348 (zmom_can(i, k+1) == zmom(kk+1) .and. zmom_can(i, k) > zmom(kk)) .or. &
352 (zmom_can(i, k) < zmom(kk) .and. zmom_can(i, k+1) >= zmom(kk+1)))
then
356 frctr2c(k, 1, i) = (zmom_can(i, k) - zmom_can(i, k+1)) / (zmom(kk) - zmom(kk+1))
357 frctc2r(k, 1, i) = 1.0
365 if (zmom_can(i, k+1) < zmom(kk) .and. zmom_can(i, k) > zmom(kk))
then
368 ifrct(k, 2, i) = kk-1
372 frctr2c(k, 1, i) = (zmom(kk) - zmom_can(i, k+1)) / (zmom(kk) - zmom(kk+1))
373 frctr2c(k, 2, i) = (zmom_can(i, k) - zmom(kk)) / (zmom(kk-1) - zmom(kk) )
377 frctc2r(k, 1, i) = (zmom(kk) - zmom_can(i, k+1)) / (zmom_can(i, k) - zmom_can(i, k+1))
378 frctc2r(k, 2, i) = (zmom_can(i, k) - zmom(kk)) / (zmom_can(i, k) - zmom_can(i, k+1) )
405 IF (frt_mask(i) > 0.)
THEN
421 vmr_resolved(ii) = q1_mod(i, k, s)
430 vmr_canopy(ii) = q1_can(i, k, s)
438 conc_can3(kc) = vmr_canopy(k)
451 mmr_canopy(kk) = reverse_conv * vmr_resolved(k)
459 mmr_canopy(kc) = reverse_conv * conc_can3(k)
466 mass_resolved(:) = 0.
470 if(s == 11) mmr_o3_can(i,k) = mmr_canopy(k)
472 mass_canopy(k) = mmr_canopy(k) * massair_can(i, k)
473 do kk = 1, nfrct(k, i)
475 mass_resolved(kc) = mass_resolved(kc) + mass_canopy(k) * frctc2r(k,kk,i)
482 call canopy_mass_check(mass_canopy, mass_resolved, i, flag, nkc, nkt, errmsg, errflg)
483 if (errflg /= 0)
return
492 mmr_resolved(k) = mass_resolved(k) / (massair(i, k))
497 vmr_resolved(k) = forward_conv * mmr_resolved(k)
515 do k = nkt, nkt-8, -1
517 if (diag_hgt <= zmid_can(i, k-1) .and. &
518 diag_hgt > zmid_can(i, k))
then
525 mmr_diag = mmr_canopy(nkt)
526 vmr_resolved(km + 1) = forward_conv * mmr_canopy(nkt)
533 (mmr_canopy(kk) - mmr_canopy(kk + 1)) / &
535 (zmid_can(i, kk) - zmid_can(i, kk + 1)) * &
536 (diag_hgt - zmid_can(i, kk + 1))
537 vmr_resolved(km + 1) = forward_conv * mmr_diag
547 q1_mod(i, ii, s) = vmr_resolved(k)
551 q1_2m(i, s) = vmr_resolved(km+1)
579 IF (frt_mask(i) > 0.)
THEN
595 conc3(ii) = q1_mod(i, k, s)
596 vmr_resolved(ii) = q1_mod(i, k, s)
603 mmr_resolved(k) = reverse_conv * conc3(k)
609 mass_resolved(k) = mmr_resolved(k) * massair(i, k)
622 do kk = 1, nfrct(k, i)
624 mass_canopy(k) = mass_canopy(k) + mass_resolved(kc) * frctr2c(k, kk, i)
631 call canopy_mass_check(mass_canopy, mass_resolved, i, flag, nkc, nkt, errmsg, errflg)
632 if (errflg /= 0)
return
638 mmr_canopy(k) = mass_canopy(k) / (massair_can(i, k))
643 if(s == 11) mmr_o3_can(i,k) = frctr2c(k, 2, i)
654 vmr_resolved(kk) = forward_conv * mmr_canopy(k)
665 vmr_canopy(k) = vmr_resolved(kk)
672 conc_can3(kc) = forward_conv * mmr_canopy(k)
682 vmr_canopy(k) = conc_can3(kc)
694 q1_can(i, ii, s) = vmr_canopy(k)
713 subroutine canopy_mass_check(mass_canopy, mass_model, i, flag, nkc, nkt, errmsg, errflg)
715 integer(kind=4),
intent(in) :: flag, i, nkc, nkt
716 real(kind=kind_phys),
intent(in) :: mass_canopy(nkt), mass_model(km)
717 character(len=*),
intent(out) :: errmsg
718 integer,
intent(out) :: errflg
720 character(len=18) :: mode_transfer
721 real(kind=kind_phys) :: masstotcan, masstotres, massrat
722 real(kind=kind_phys) :: sum2can(nkt), sum2res(nkt)
727 masstotcan = masstotcan + mass_canopy(k)
730 masstotres = masstotres + mass_model(k)
734 mode_transfer =
"canopy_to_resolved"
736 mode_transfer =
"resolved_to_canopy"
740 if (masstotres > 0.0 )
then
741 massrat = masstotcan / masstotres
742 if (massrat > 1.001 .or. massrat < 0.999)
then
743 write(errmsg,fmt=
'(*(a,f10.4,a,f10.4))')
'Conversion of mass in ccpp_canopy_transfer not conserved ' // &
744 'during ' // mode_transfer //
' evaluation. masstotcan = ', masstotcan, &
745 ' and masstotres = ', masstotres
756 do kk = 1, nfrct(k, i)
758 sum2can(kc) = sum2can(kc) + frctr2c(k, kk, i)
759 sum2res(k) = sum2res(k) + frctc2r(k, kk, i)
764 if (sum2can(k) < 0.999 .or. sum2can(k) > 1.001)
then
765 write(errmsg,fmt=
'(*(a,i0,a,i0,a,f10.4))')
'layer mismatch in canopy level setup in resolved to canopy indexing: ' // &
766 'column ', i,
' layer ', k,
' sum=', sum2can(k)
772 if (sum2res(k) < 0.999 .or. sum2res(k) > 1.001)
then
773 write(errmsg,fmt=
'(*(a,i0,a,i0,a,f10.4))')
'layer mismatch in canopy level setup in canopy to resolved indexing: ' // &
774 'column ', i,
' layer ', k,
' sum=', sum2res(k)
782 end subroutine canopy_mass_check
784 end subroutine canopy_transfer_run
786 end module canopy_transfer_mod