Main menu


Questions on physics_buffer

8 posts / 0 new
Last post
Questions on physics_buffer

Dear all:

In CAM5, there are a lot of physics buffers in modle physics. These buffers are added by pbuf_add('xxx'.....)

Since they can only be inquired by pointers, so how are they initiated?

Is there a uniform initialization of phys_buf that are added? Or they are initiated respectively in different schemes?


The default initialization of the physics buffer (pbuf) fields is to set
them to the nan value accessed from the infnan module (this is done in the
pbuf_allocate subroutine in phys_buffer.F90).

Below is sample code that illustrates the basics of how physics buffer
fields are set. The sample shows how to initialize a pbuf field, although
this is unnecessary if the parameterization that sets the values is called
before any parameterization that accesses the values.

module mod1

use shr_kind_mod, only: r8=>shr_kind_r8
use ppgrid, only: pcols, pver, begchunk, endchunk
use phys_buffer, only: pbuf_add, pbuf_fld
use physics_types, only: physics_state, physics_ptend
use time_manager, only: is_first_step

implicit none

public :: mod1_register, mod1_init, mod1_tend

integer :: fld1_idx ! save the index into the pbuf


subroutine mod1_register

! Add 3D pbuf field with global scope. This field will
! persist across timesteps, and automatically be written
! to the restart file.

call pbuf_add('FLD1', 'global', 1, pver, 1, fld1_idx)

end subroutine mod1_register

subroutine mod1_init(pbuf)

! Example of initializing a field in the physics buffer. Note that this
! is not necessary if the 'run' subroutine which computes the field values
! is called before any other subroutines which need to access the values.
! Note that init routines are called outside the loop over chunks (the
! data structure used by the physics grid decompostion), and so all the
! chunks, begchunk:endchunk, need to be dealt with.

type(pbuf_fld) :: pbuf(:)

real(r8), pointer :: fld1(:,:,:) ! all the chunks

! associate the pointer with the physics buffer field
fld1 => pbuf(fld1_idx)%fld_ptr(1,1:pcols,1:pver,begchunk:endchunk,1)

! Initialize field values
! Note -- init subroutines are typically called on the first step of a
! restart as well as during the first step of an initial run.
! For 'global' fields, to avoid having the values that are
! restored from the restart file from being overwritten, an
! initialization done in an init method needs to happen inside
! an is_first_step conditional.

if (is_first_step) then
fld1 = 0._r8
end if


end subroutine mod1_init

subroutine mod1_tend(state, ptend, pbuf)

! Example of setting a field in the physics buffer.
! Note that 'tend' routines are called inside the loop over chunks (the
! data structure used by the physics grid decompostion), and so only
! the chunk corresponding to the state variables, state%lchnk, is set.

type(physics_state), intent(in) :: state ! State variables
type(physics_ptend), intent(out) :: ptend ! physics tendencies
type(pbuf_fld) :: pbuf(:)

real(r8), pointer :: fld1(:,:) ! just one chunk
integer :: i, k, lchnk, ncol

lchnk = state%lchnk
ncol = state%ncol ! number of active columns in this chunk

! associate the pointer with the physics buffer field
fld1 => pbuf(fld1_idx)%fld_ptr(1,1:pcols,1:pver,lchnk,1)

! set the field
do k = 1, plev
do i = 1, ncol
fld1(i,k) = ...
end do
end do


end subroutine mod1_tend

end module mod1


I would like to copy a physics_state and a physics_tend type before some physics happens and to restore it/part of it later.

Rosa, D. LBNL


What model version are you using?




I am running pure mpi, state_save and tend_save are defined at the module level

then in one routine I have:

nstep = get_nstep()
write(0, *) 'crm_save_state_tend: nstep: ', nstep
write(0, *) 'crm_save_state_tend: allocating tend_save'
call physics_tend_alloc(tend_save, pcols)
end if
call physics_tend_init(tend_save)
tend_save = tend

The output is:

crm_save_state_tend: nstep: 0
crm_save_state_tend: allocating tend_save
(shr_sys_abort) ERROR: physics_tend_alloc error: allocation error for tend%dtdt


I am suspecting the problem is when the second time it passes by to do another chunck of grid (and it still is the first step)

it complains that tend_save is already allocated ...



Rosa, D. LBNL


In the physics_types module there are subroutines physics_state_copy and physics_ptend_copy to make local copies of state and ptend objects.

You probably want to be working with a physics_ptend object and not a physics_tend object.  The ptend objects are what the individual parameterizations return to the driver layer.  The tend objects are updated with the information from a ptend object by physics_update.  There is no physics_tend_copy subroutine because we've not yet come across a need for one.




Thanks for the answer.

1, How about the subroutines named: pbuf_add_field, pbuf_get_field ?

It seems both two are used in a easy way in crm_physics.f90 (SPCAM) as following:

 call pbuf_add_field('CRM_U',     'global', dtype_r8, (/pcols,crm_nx, crm_ny, crm_nz/),                crm_u_idx)
call pbuf_get_field (pbuf, crm_u_idx,         crm_u).

It seems these variables are not assigned to all the chunks but still working.

2, And whats the different between "global" and "physpkg"? Is there any limitation about the size of fields put into the physics puffer?


Thank you, Brian. What I am doing is not the best practice.

Rosa, D. LBNL

Log in or register to post comments

Who's new

  • jwolff
  • tinna.gunnarsdo...
  • sarthak2235@...
  • eolivares@...
  • shubham.gandhi@...