CAM Component  1.2.2
 All Classes Files Functions Variables
camsrfexch.F90
Go to the documentation of this file.
1 !> \file
2 !! \brief Data types for exchange between CAM and coupler components.
3 !!
4 !! Module to handle data that is exchanged between the CAM atmosphere
5 !! model and the surface models (land, sea-ice, and ocean).
6 
7 module camsrfexch
8 
9 use shr_kind_mod, only: r8 => shr_kind_r8, r4 => shr_kind_r4
10 use constituents, only: pcnst
11 use ppgrid, only: pcols, begchunk, endchunk
12 use phys_grid, only: get_ncols_p, phys_grid_initialized
13 use infnan, only: posinf, assignment(=)
14 use abortutils, only: endrun
15 use cam_logfile, only: iulog
16 
17 implicit none
18 private
19 
20 ! Public interfaces
21 
22 public atm2hub_alloc ! Atmosphere to surface data allocation method
23 public hub2atm_alloc ! Merged hub surface to atmosphere data allocation method
24 public hub2atm_setopts ! Set options to allocate optional parts of data type
25 public atm2hub_deallocate
26 public hub2atm_deallocate
27 public cam_export
28 
29 !> \struct cam_out_t
30 !! \brief CAM export state
31 !!
32 !! Container for the data sent from the atmosphere to the coupler component
33 
34 type, public :: cam_out_t
35  integer :: lchnk !< chunk index
36  integer :: ncol !< number of columns in chunk
37  real(r8) :: tbot(pcols) !< bot level temperature
38  real(r8) :: zbot(pcols) !< bot level height above surface
39  real(r8) :: ubot(pcols) !< bot level u wind
40  real(r8) :: vbot(pcols) !< bot level v wind
41  real(r8) :: qbot(pcols,pcnst) !< bot level specific humidity
42  real(r8) :: pbot(pcols) !< bot level pressure
43  real(r8) :: rho(pcols) !< bot level density
44  real(r8) :: netsw(pcols) !
45  real(r8) :: flwds(pcols) !
46  real(r8) :: precsc(pcols) !
47  real(r8) :: precsl(pcols) !
48  real(r8) :: precc(pcols) !
49  real(r8) :: precl(pcols) !
50  real(r8) :: soll(pcols) !
51  real(r8) :: sols(pcols) !
52  real(r8) :: solld(pcols) !
53  real(r8) :: solsd(pcols) !
54  real(r8) :: thbot(pcols) !
55  real(r8) :: co2prog(pcols) !< prognostic co2
56  real(r8) :: co2diag(pcols) !< diagnostic co2
57  real(r8) :: psl(pcols)
58  real(r8) :: bcphiwet(pcols) !< wet deposition of hydrophilic black carbon
59  real(r8) :: bcphidry(pcols) !< dry deposition of hydrophilic black carbon
60  real(r8) :: bcphodry(pcols) !< dry deposition of hydrophobic black carbon
61  real(r8) :: ocphiwet(pcols) !< wet deposition of hydrophilic organic carbon
62  real(r8) :: ocphidry(pcols) !< dry deposition of hydrophilic organic carbon
63  real(r8) :: ocphodry(pcols) !< dry deposition of hydrophobic organic carbon
64  real(r8) :: dstwet1(pcols) !< wet deposition of dust (bin1)
65  real(r8) :: dstdry1(pcols) !< dry deposition of dust (bin1)
66  real(r8) :: dstwet2(pcols) !< wet deposition of dust (bin2)
67  real(r8) :: dstdry2(pcols) !< dry deposition of dust (bin2)
68  real(r8) :: dstwet3(pcols) !< wet deposition of dust (bin3)
69  real(r8) :: dstdry3(pcols) !< dry deposition of dust (bin3)
70  real(r8) :: dstwet4(pcols) !< wet deposition of dust (bin4)
71  real(r8) :: dstdry4(pcols) !< dry deposition of dust (bin4)
72 end type cam_out_t
73 
74 !> \struct cam_in_t
75 !! \brief CAM import state
76 !!
77 !! Container for the data sent to the atmosphere from the coupler component.
78 !! This is the merged state of sea-ice, land and ocean.
79 
80 type, public :: cam_in_t
81  integer :: lchnk !< chunk index
82  integer :: ncol !< number of active columns
83  real(r8) :: asdir(pcols) !< albedo: shortwave, direct
84  real(r8) :: asdif(pcols) !< albedo: shortwave, diffuse
85  real(r8) :: aldir(pcols) !< albedo: longwave, direct
86  real(r8) :: aldif(pcols) !< albedo: longwave, diffuse
87  real(r8) :: lwup(pcols) !< longwave up radiative flux
88  real(r8) :: lhf(pcols) !< latent heat flux
89  real(r8) :: shf(pcols) !< sensible heat flux
90  real(r8) :: wsx(pcols) !< surface u-stress (N)
91  real(r8) :: wsy(pcols) !< surface v-stress (N)
92  real(r8) :: tref(pcols) !< ref height surface air temp
93  real(r8) :: qref(pcols) !< ref height specific humidity
94  real(r8) :: u10(pcols) !< 10m wind speed
95  real(r8) :: ts(pcols) !< merged surface temp
96  real(r8) :: sst(pcols) !< sea surface temp
97  real(r8) :: snowhland(pcols) !< snow depth (liquid water equivalent) over land
98  real(r8) :: snowhice(pcols) !< snow depth over ice
99  real(r8) :: fco2_lnd(pcols) !< co2 flux from lnd
100  real(r8) :: fco2_ocn(pcols) !< co2 flux from ocn
101  real(r8) :: fdms(pcols) !< dms flux
102  real(r8) :: landfrac(pcols) !< land area fraction
103  real(r8) :: icefrac(pcols) !< sea-ice areal fraction
104  real(r8) :: ocnfrac(pcols) !< ocean areal fraction
105  real(r8), pointer, dimension(:) :: ram1 !< aerodynamical resistance (s/m) (pcols)
106  real(r8), pointer, dimension(:) :: fv !< friction velocity (m/s) (pcols)
107  real(r8), pointer, dimension(:) :: soilw !< volumetric soil water (m3/m3)
108  real(r8) :: cflx(pcols,pcnst) !< constituent flux (evap)
109  real(r8) :: ustar(pcols) !< atm/ocn saved version of ustar
110  real(r8) :: re(pcols) !< atm/ocn saved version of re
111  real(r8) :: ssq(pcols) !< atm/ocn saved version of ssq
112  real(r8), pointer, dimension(:,:) :: depvel !< deposition velocities
113 end type cam_in_t
114 
115 logical :: dust = .false. !< .true. => aerosol dust package is being used
116 
117 !===============================================================================
118 CONTAINS
119 !===============================================================================
120 
121 !> \brief Initialize objects of type cam_in_t
122 !! \param cam_in object of type cam_in_t
123 
124 subroutine hub2atm_alloc( cam_in )
125  use seq_drydep_mod, only : lnd_drydep, n_drydep
126  use cam_cpl_indices, only: index_x2a_sl_soilw
127 
128  ! ARGUMENTS:
129  type(cam_in_t), pointer :: cam_in(:) ! Merged surface state
130 
131  ! LOCAL VARIABLES:
132  integer :: c ! chunk index
133  integer :: ierror ! Error code
134  !-----------------------------------------------------------------------
135 
136  if ( .not. phys_grid_initialized() ) call endrun( "HUB2ATM_ALLOC error: phys_grid not called yet" )
137  allocate (cam_in(begchunk:endchunk), stat=ierror)
138  if ( ierror /= 0 )then
139  write(iulog,*) 'Allocation error: ', ierror
140  call endrun('HUB2ATM_ALLOC error: allocation error')
141  end if
142 
143  do c = begchunk,endchunk
144  nullify(cam_in(c)%ram1)
145  nullify(cam_in(c)%fv)
146  nullify(cam_in(c)%soilw)
147  nullify(cam_in(c)%depvel)
148  enddo
149  if ( dust ) then
150  do c = begchunk,endchunk
151  allocate (cam_in(c)%ram1(pcols), stat=ierror)
152  if ( ierror /= 0 ) call endrun('HUB2ATM_ALLOC error: allocation error ram1')
153  allocate (cam_in(c)%fv(pcols), stat=ierror)
154  if ( ierror /= 0 ) call endrun('HUB2ATM_ALLOC error: allocation error fv')
155  if (index_x2a_sl_soilw /= 0) then
156  allocate (cam_in(c)%soilw(pcols), stat=ierror)
157  if ( ierror /= 0 ) call endrun('HUB2ATM_ALLOC error: allocation error soilw')
158  end if
159  end do
160  endif !dust
161 
162  if (lnd_drydep .and. n_drydep>0) then
163  do c = begchunk,endchunk
164  allocate (cam_in(c)%depvel(pcols,n_drydep), stat=ierror)
165  if ( ierror /= 0 ) call endrun('HUB2ATM_ALLOC error: allocation error depvel')
166  end do
167  endif
168 
169  do c = begchunk,endchunk
170  cam_in(c)%lchnk = c
171  cam_in(c)%ncol = get_ncols_p(c)
172  cam_in(c)%asdir (:) = 0._r8
173  cam_in(c)%asdif (:) = 0._r8
174  cam_in(c)%aldir (:) = 0._r8
175  cam_in(c)%aldif (:) = 0._r8
176  cam_in(c)%lwup (:) = 0._r8
177  cam_in(c)%lhf (:) = 0._r8
178  cam_in(c)%shf (:) = 0._r8
179  cam_in(c)%wsx (:) = 0._r8
180  cam_in(c)%wsy (:) = 0._r8
181  cam_in(c)%tref (:) = 0._r8
182  cam_in(c)%qref (:) = 0._r8
183  cam_in(c)%u10 (:) = 0._r8
184  cam_in(c)%ts (:) = 0._r8
185  cam_in(c)%sst (:) = 0._r8
186  cam_in(c)%snowhland(:) = 0._r8
187  cam_in(c)%snowhice (:) = 0._r8
188  cam_in(c)%fco2_lnd (:) = 0._r8
189  cam_in(c)%fco2_ocn (:) = 0._r8
190  cam_in(c)%fdms (:) = 0._r8
191  cam_in(c)%landfrac (:) = posinf
192  cam_in(c)%icefrac (:) = posinf
193  cam_in(c)%ocnfrac (:) = posinf
194  if ( dust ) then
195  cam_in(c)%ram1 (:) = 0.1_r8
196  cam_in(c)%fv (:) = 0.1_r8
197  if (associated(cam_in(c)%soilw)) &
198  cam_in(c)%soilw (:) = 0.0_r8
199  endif
200  cam_in(c)%cflx (:,:) = 0._r8
201  cam_in(c)%ustar (:) = 0._r8
202  cam_in(c)%re (:) = 0._r8
203  cam_in(c)%ssq (:) = 0._r8
204  if (lnd_drydep .and. n_drydep>0) then
205  cam_in(c)%depvel (:,:) = 0._r8
206  endif
207  end do
208 
209 end subroutine hub2atm_alloc
210 
211 !===============================================================================
212 
213 !> \brief Initialize objects of type cam_out_t
214 !! \param cam_out object of type cam_out_t
215 
216 subroutine atm2hub_alloc( cam_out )
217 
218  ! ARGUMENTS:
219  type(cam_out_t), pointer :: cam_out(:) ! Atmosphere to surface input
220 
221  ! LOCAL VARIABLES:
222  integer :: c ! chunk index
223  integer :: ierror ! Error code
224  !-----------------------------------------------------------------------
225 
226  if ( .not. phys_grid_initialized() ) call endrun( "ATM2HUB_ALLOC error: phys_grid not called yet" )
227  allocate (cam_out(begchunk:endchunk), stat=ierror)
228  if ( ierror /= 0 )then
229  write(iulog,*) 'Allocation error: ', ierror
230  call endrun('ATM2HUB_ALLOC error: allocation error')
231  end if
232 
233  do c = begchunk,endchunk
234  cam_out(c)%lchnk = c
235  cam_out(c)%ncol = get_ncols_p(c)
236  cam_out(c)%tbot(:) = 0._r8
237  cam_out(c)%zbot(:) = 0._r8
238  cam_out(c)%ubot(:) = 0._r8
239  cam_out(c)%vbot(:) = 0._r8
240  cam_out(c)%qbot(:,:) = 0._r8
241  cam_out(c)%pbot(:) = 0._r8
242  cam_out(c)%rho(:) = 0._r8
243  cam_out(c)%netsw(:) = 0._r8
244  cam_out(c)%flwds(:) = 0._r8
245  cam_out(c)%precsc(:) = 0._r8
246  cam_out(c)%precsl(:) = 0._r8
247  cam_out(c)%precc(:) = 0._r8
248  cam_out(c)%precl(:) = 0._r8
249  cam_out(c)%soll(:) = 0._r8
250  cam_out(c)%sols(:) = 0._r8
251  cam_out(c)%solld(:) = 0._r8
252  cam_out(c)%solsd(:) = 0._r8
253  cam_out(c)%thbot(:) = 0._r8
254  cam_out(c)%co2prog(:) = 0._r8
255  cam_out(c)%co2diag(:) = 0._r8
256  cam_out(c)%psl(:) = 0._r8
257  cam_out(c)%bcphidry(:) = 0._r8
258  cam_out(c)%bcphodry(:) = 0._r8
259  cam_out(c)%bcphiwet(:) = 0._r8
260  cam_out(c)%ocphidry(:) = 0._r8
261  cam_out(c)%ocphodry(:) = 0._r8
262  cam_out(c)%ocphiwet(:) = 0._r8
263  cam_out(c)%dstdry1(:) = 0._r8
264  cam_out(c)%dstwet1(:) = 0._r8
265  cam_out(c)%dstdry2(:) = 0._r8
266  cam_out(c)%dstwet2(:) = 0._r8
267  cam_out(c)%dstdry3(:) = 0._r8
268  cam_out(c)%dstwet3(:) = 0._r8
269  cam_out(c)%dstdry4(:) = 0._r8
270  cam_out(c)%dstwet4(:) = 0._r8
271  end do
272 
273 end subroutine atm2hub_alloc
274 
275 !> \brief Destroy objects of type cam_out_t
276 !! \param cam_out object of type cam_out_t
277 
278 subroutine atm2hub_deallocate(cam_out)
279  type(cam_out_t), pointer :: cam_out(:) ! Atmosphere to surface input
280  if(associated(cam_out)) then
281  deallocate(cam_out)
282  end if
283  nullify(cam_out)
284 end subroutine atm2hub_deallocate
285 
286 !> \brief Destroy objects of type cam_in_t
287 !! \param cam_in object of type cam_in_t
288 
289 subroutine hub2atm_deallocate(cam_in)
290  type(cam_in_t), pointer :: cam_in(:) ! Atmosphere to surface input
291  integer :: c
292 
293  if(associated(cam_in)) then
294  do c=begchunk,endchunk
295  if(associated(cam_in(c)%ram1)) then
296  deallocate(cam_in(c)%ram1)
297  nullify(cam_in(c)%ram1)
298  end if
299  if(associated(cam_in(c)%fv)) then
300  deallocate(cam_in(c)%fv)
301  nullify(cam_in(c)%fv)
302  end if
303  if(associated(cam_in(c)%soilw)) then
304  deallocate(cam_in(c)%soilw)
305  nullify(cam_in(c)%soilw)
306  end if
307  if(associated(cam_in(c)%depvel)) then
308  deallocate(cam_in(c)%depvel)
309  nullify(cam_in(c)%depvel)
310  end if
311 
312  enddo
313 
314  deallocate(cam_in)
315  end if
316  nullify(cam_in)
317 
318 end subroutine hub2atm_deallocate
319 
320 !======================================================================
321 
322 !> \brief Set options used to initialize cam_in_t objects.
323 !!
324 !! Method for outside packages to influence what is allocated
325 !! (For now, just aerosol dust controls if fv, ram1, and soilw
326 !! arrays are allocated.)
327 !!
328 !! \param[in] aero_dust_in set value of the camsrfexch::dust attribute
329 
330 subroutine hub2atm_setopts( aero_dust_in )
331 
332  ! ARGUMENTS:
333  logical, intent(in),optional :: aero_dust_in
334 
335  !-----------------------------------------------------------------------
336  if ( present(aero_dust_in ) ) then
337  dust = aero_dust_in
338  endif
339 
340 end subroutine hub2atm_setopts
341 
342 !> \brief Set components of cam_out_t objects.
343 !!
344 !! Set components of cam_out_t objects from fields in the state
345 !! and physics buffer. Also sets fields in the comsrf module.
346 !!
347 !! \param[in] state physics state object
348 !! \param[in] pbuf physics buffer
349 !! \param[inout] cam_out export object
350 
351 subroutine cam_export(state,cam_out,pbuf)
352 
353  use physics_types, only: physics_state
354  use ppgrid, only: pver
355  use comsrf, only: psm1, srfrpdel, prcsnw
356  use chem_surfvals, only: chem_surfvals_get
357  use co2_cycle, only: co2_transport, c_i
358  use physconst, only: mwdry, mwco2
359  use constituents, only: pcnst
360  use cam_control_mod, only: rair
361  use physics_buffer, only: pbuf_get_index, pbuf_get_field, physics_buffer_desc
362 
363  ! Input arguments
364  type(physics_state), intent(in) :: state
365  type (cam_out_t), intent(inout) :: cam_out
366  type(physics_buffer_desc), pointer :: pbuf(:)
367 
368  ! Local variables
369  integer :: i ! Longitude index
370  integer :: m ! constituent index
371  integer :: lchnk ! Chunk index
372  integer :: ncol
373  integer :: prec_dp_idx, snow_dp_idx, prec_sh_idx, snow_sh_idx
374  integer :: prec_sed_idx,snow_sed_idx,prec_pcw_idx,snow_pcw_idx
375 
376  real(r8), pointer :: prec_dp(:) ! total precipitation from ZM convection
377  real(r8), pointer :: snow_dp(:) ! snow from ZM convection
378  real(r8), pointer :: prec_sh(:) ! total precipitation from Hack convection
379  real(r8), pointer :: snow_sh(:) ! snow from Hack convection
380  real(r8), pointer :: prec_sed(:) ! total precipitation from ZM convection
381  real(r8), pointer :: snow_sed(:) ! snow from ZM convection
382  real(r8), pointer :: prec_pcw(:) ! total precipitation from Hack convection
383  real(r8), pointer :: snow_pcw(:) ! snow from Hack convection
384  !-----------------------------------------------------------------------
385 
386  lchnk = state%lchnk
387  ncol = state%ncol
388 
389  prec_dp_idx = pbuf_get_index('PREC_DP')
390  snow_dp_idx = pbuf_get_index('SNOW_DP')
391  prec_sh_idx = pbuf_get_index('PREC_SH')
392  snow_sh_idx = pbuf_get_index('SNOW_SH')
393  prec_sed_idx = pbuf_get_index('PREC_SED')
394  snow_sed_idx = pbuf_get_index('SNOW_SED')
395  prec_pcw_idx = pbuf_get_index('PREC_PCW')
396  snow_pcw_idx = pbuf_get_index('SNOW_PCW')
397 
398  call pbuf_get_field(pbuf, prec_dp_idx, prec_dp)
399  call pbuf_get_field(pbuf, snow_dp_idx, snow_dp)
400  call pbuf_get_field(pbuf, prec_sh_idx, prec_sh)
401  call pbuf_get_field(pbuf, snow_sh_idx, snow_sh)
402  call pbuf_get_field(pbuf, prec_sed_idx, prec_sed)
403  call pbuf_get_field(pbuf, snow_sed_idx, snow_sed)
404  call pbuf_get_field(pbuf, prec_pcw_idx, prec_pcw)
405  call pbuf_get_field(pbuf, snow_pcw_idx, snow_pcw)
406 
407  do i=1,ncol
408  cam_out%tbot(i) = state%t(i,pver)
409  cam_out%thbot(i) = state%t(i,pver) * state%exner(i,pver)
410  cam_out%zbot(i) = state%zm(i,pver)
411  cam_out%ubot(i) = state%u(i,pver)
412  cam_out%vbot(i) = state%v(i,pver)
413  cam_out%pbot(i) = state%pmid(i,pver)
414  cam_out%rho(i) = cam_out%pbot(i)/(rair*cam_out%tbot(i))
415  psm1(i,lchnk) = state%ps(i)
416  srfrpdel(i,lchnk)= state%rpdel(i,pver)
417  end do
418  do m = 1, pcnst
419  do i = 1, ncol
420  cam_out%qbot(i,m) = state%q(i,pver,m)
421  end do
422  end do
423 
424  cam_out%co2diag(:ncol) = chem_surfvals_get('CO2VMR') * 1.0e+6_r8
425  if (co2_transport()) then
426  do i=1,ncol
427  cam_out%co2prog(i) = state%q(i,pver,c_i(4)) * 1.0e+6_r8 *mwdry/mwco2
428  end do
429  end if
430 
431  ! Precipation and snow rates from shallow convection, deep convection and stratiform processes.
432  ! Compute total convective and stratiform precipitation and snow rates
433 
434  do i=1,ncol
435  cam_out%precc (i) = prec_dp(i) + prec_sh(i)
436  cam_out%precl (i) = prec_sed(i) + prec_pcw(i)
437  cam_out%precsc(i) = snow_dp(i) + snow_sh(i)
438  cam_out%precsl(i) = snow_sed(i) + snow_pcw(i)
439 
440  ! These checks should not be necessary if they exist in the parameterizations
441  if (cam_out%precc(i) .lt.0._r8) cam_out%precc(i)=0._r8
442  if (cam_out%precl(i) .lt.0._r8) cam_out%precl(i)=0._r8
443  if (cam_out%precsc(i).lt.0._r8) cam_out%precsc(i)=0._r8
444  if (cam_out%precsl(i).lt.0._r8) cam_out%precsl(i)=0._r8
445  if (cam_out%precsc(i).gt.cam_out%precc(i)) cam_out%precsc(i)=cam_out%precc(i)
446  if (cam_out%precsl(i).gt.cam_out%precl(i)) cam_out%precsl(i)=cam_out%precl(i)
447  end do
448 
449  ! total snowfall rate: needed by slab ocean model
450  prcsnw(:ncol,lchnk) = cam_out%precsc(:ncol) + cam_out%precsl(:ncol)
451 
452 end subroutine cam_export
453 
454 end module camsrfexch
subroutine, public cam_export(state, cam_out, pbuf)
Set components of cam_out_t objects.
Definition: camsrfexch.F90:351
subroutine, public hub2atm_setopts(aero_dust_in)
Set options used to initialize cam_in_t objects.
Definition: camsrfexch.F90:330
subroutine, public atm2hub_alloc(cam_out)
Initialize objects of type cam_out_t.
Definition: camsrfexch.F90:216
subroutine, public atm2hub_deallocate(cam_out)
Destroy objects of type cam_out_t.
Definition: camsrfexch.F90:278
CAM export state.
Definition: camsrfexch.F90:34
CAM import state.
Definition: camsrfexch.F90:80
subroutine, public hub2atm_alloc(cam_in)
Initialize objects of type cam_in_t.
Definition: camsrfexch.F90:124
subroutine, public hub2atm_deallocate(cam_in)
Destroy objects of type cam_in_t.
Definition: camsrfexch.F90:289