Scheduled Downtime
On Tuesday 24 October 2023 @ 5pm MT the forums will be in read only mode in preparation for the downtime. On Wednesday 25 October 2023 @ 5am MT, this website will be down for maintenance and expected to return online later in the morning.
Normal Operations
The forums are back online with normal operations. If you notice any issues or errors related to the forums, please reach out to help@ucar.edu

“Chunk” data structure in physics driver in CAM5

Hi there,

I have problem understanding the "Chunk" data structure, and hopefully someone could explain it to me.
OK, what I want to do is to read a couple of variables (i.e x1(time,lat,lon,lev), x2(time, lat, lon), x3(lat,lon), etc) from a netcdf file, then broadcast to the slave SMP processes. According to Eaton and Boville (Interface to column physics and chemistry packages, Sep 2002), these variables should be converted to the "chunk" structure, where chunk is an arbitrary collection of vertical columns. My present question is, how do I convert x1,x2,x3 to the chunk structure? Especially, how do I relate lat,lon with columns? Thank you!
 

eaton

CSEG and Liaisons
The best approach for reading data from global grids into arrays using the chunk data structure is to use the utility code that has already been constructed for this purpose. For the simplest case of reading data that does not need any time or space interpolation look in physpkg.F90 at the phys_inidat subroutine for examples of how this is done for both 2D and 3D fields. Also look at the CAM initial file which is being read by this code and imitate the metadata and dimension ordering of that file in the netcdf file that contains the data you want to read. For the case where time and/or spatial interpolation is needed look at this post which described using other CAM utility code designed for that purpose:

http://forum.cgd.ucar.edu/showthread.php?1688-adding-heating-in-CAM4-fv-dynamical-core
 
Thank you for your reply! I've looked at the phys_inidat subroutine in physpkg.F90 in detail.
But I still encountered some problems.
I was trying to test reading the data by adding a variable "cldfct" (pointer, similar to cldptr) in the phys_inidat subroutine to access the CLDICE(time, lev, lat, lon) in the initial file.

1. My first question would be where to register the new variable "cldfct" by the following code?
My understanding is that, this can be done in physpkg.F90 or stratiform.F90 (many variables used in physpky.F90 are defined there).
But I tried both, neither works. I don't know why is that.
#####################
real(r8), pointer :: cldfct(:,:,:,:)
integer :: cldfct_idx
call pbuf_add('CLDFCT', 'global', 1, pver, pbuf_times, cldfct_idx)
#####################

2. I used the following code, which is essentially the same as physpky.F90 does to read the 3-D fields, except that
I changed the variable names. But errors like "ENDRUN:PBUF_GET_FLD_IDX: index not found for CLDICE" always exists.

fieldname='CLDICE'
m = pbuf_get_fld_idx('CLDICE')
if(associated(pbuf(m)%fld_ptr)) then
cldfct => pbuf(m)%fld_ptr(1,:,:,begchunk:endchunk,:)
else
call endrun('pbuf not allocated in phys_inidat')
end if
call infld(fieldname,ncid_ini,dim1name, 'lev', 'lat', 1, pcols, 1, pver, begchunk, endchunk, &
cldfct(:,:,:,1), found, grid_map='PHYS')

3. I have no idea of why "if(associated(pbuf(m)%fld_ptr)) then" is needed, before pointing cldfct to pbuf(m)?
But I also tested that if this statement is removed, model will terminate in error like:

forrtl: severe (174): SIGSEGV, segmentation fault occurred
Image PC Routine Line Source
. 0000000000F0CE55 Unknown Unknown Unknown
. 0000000000E0EA34 Unknown Unknown Unknown
. 0000000000EA7000 Unknown Unknown Unknown

Hopefully, someone could point out what's wrong in here ... Thanks!
 

eaton

CSEG and Liaisons
1. Physics buffer fields are registered early in the initialization process. In cesm1_0_4 the initindx subroutine calls other subroutines that register pbuf fields. If you added the pbuf_add call to stratiform_register and that had no effect, I'm guessing it's because you're using cam5 physics which doesn't use the stratiform module.

2. CLDICE is not in the physics buffer (unless you added it). What the code you're looking at is doing using the CLDICE field from the initial file (if it's there) to initialize the pbuf field LCWAT.

3. I'm not sure the if(associated conditional is really needed. The pbuf_get_fld_idx call should fail if the field is not in the pbuf. Otherwise the pbuf field should be allocated so that a pointer can be associated with it.
 
Top