LZN's Blog CodePlayer

【已解决】CESM Tibetan Plateau无PBL加热试验


wzq师兄希望做一个没有青藏高原PBL加热的试验,因为有之前改deep convection的经验,这个应该不复杂。

wzq tends to test an experiment without sensible heating from the TP. As I’ve got the experience from deep convection heating experiments,  this shouldn’t be very complex.

首先希望能用model自身读入netcdf格式的TP mask文件。grep到了 control目录下的cam_initfiles.F90文件,其中是读init数据和topo数据的,果断就follow格式加入如下语句:

First, we hope to get var from the netcdf file directly via the packeged method in the model. Using command ‘grep’, we located a source file called cam_initfiles.F90, which was programmed to read init data and topo data. Thus, we follow the style of this file to add the changes as follows:

< tpmask_file_get_id, &! returns filehandle for tp mask file
< type(file_desc_t), pointer :: fh_ini, fh_topo, fh_tpmask
> type(file_desc_t), pointer :: fh_ini, fh_topo
< function tpmask_file_get_id()
< type(file_desc_t), pointer :: tpmask_file_get_id
< tpmask_file_get_id => fh_tpmask
< end function tpmask_file_get_id
< character(len=256) :: bnd_tpmask_loc ! filepath of topo file on local disk
< bnd_tpmask_loc = "/users/yangsong3/wzq/TP_noPBL_HEAT/data/TPmask.nc"
< call getfil(bnd_topo, bnd_topo_loc) !getfil is check process
> call getfil(bnd_topo, bnd_topo_loc)
< ! 20150721 Add for TP mask
< allocate(fh_tpmask)
< call cam_pio_openfile(fh_tpmask, bnd_tpmask_loc, PIO_NOWRITE)
< call pio_closefile(fh_tpmask)
< deallocate(fh_tpmask)
< nullify(fh_tpmask)


We then put the TPmask.nc to a new foolder “data” in the case directory, and compile the model. Successed! We now go back to the code in cam_initfiles.F90 and find that there is no read data keyword for topo. However, a “readinitial” keyword operated to the initial data found in the file.

grep the keyword with “readinitial”, we found a file called readinitial.F90. Check it! To our disappointment, it is only for the validation check. Next, we change another keyword “topo” to grep, we found startup_initialconds.F90, in this file, we then locate a sentence

 call read_inidat(fh_ini, fh_topo, dyn_in)

Very interesting! we believe this could be the true method to read data from the topo file. Another grep!

In fact, we found keyword “dycore” appeared in a number of files. Then we locate $SRC/dynamic/fv, then we grep inidat.F90. In this file, we finally found how the model deal with the topo field

    fieldname = 'PHIS'
    readvar   = .false.
    if (ideal_phys .or. aqua_planet) then
       dyn_in%phis(:,:) = D0_0
       allocate(phis_tmp(im, jm))
       call infld(fieldname, ncid_topo, 'lon', 'lat', ifirstxy, ilastxy, jfirstxy, jlastxy, &
            dyn_in%phis, readvar, grid_map='dyn')
       if (.not. readvar) &
            call endrun(trim(subname)//' ERROR: PHIS not found on topo dataset.')
       call process_inidat(ncid_ini, ncid_topo, grid, dyn_in, 'PHIS')
    end if

Apparently, infld is a method that read a field from a specific file. grep “infld” and locate the file ./control/ncdio_cam.F90 to refer the usage. Since “infld” is a common usage in many source files, we try to search it in the main interface of the physics package physpkg.F90, bingo! We got it in subroutine phys_initdat(). We are familiar with this source file because we have changed the deep convection in this file. Phys_initdata() is a subroutine that only be called during the startup run. Therefore, we add a infld in phy_init(), which would be called during every run type.

Be careful with the “use module_name” statement, never leave a wild variable. Then we need to add another field to the surface field. Definition code is in comsrf.F90

<   public landm, sgh, tpmask, sgh30, fv, ram1, soilw, fsns, fsds
>   public landm, sgh, sgh30, fv, ram1, soilw, fsns, fsds
<   real(r8), allocatable:: tpmask(:,:)    ! Tibetan Platau Mask flag
<        allocate (tpmask  (pcols,begchunk:endchunk))
<        tpmask   (:,:) = nan

Try to build it again. Successful! Now we have read the TP mask in.

#Up to 20150722#

The final code has been uploaded to my github. So, no more update here.

#Up to 20150924#