module grib2_module !------------------------------------------------------------------------ ! ! This module generates grib2 messages and writes out the messages in ! parallel. ! ! program log: ! March, 2010 Jun Wang Initial code ! Jan, 2012 Jun Wang post available fields with grib2 description ! are defined in xml file ! March, 2015 Lin Gan Replace XML file with flat file implementation ! with parameter marshalling !------------------------------------------------------------------------ use xml_perl_data, only: param_t,paramset_t ! implicit none private ! ------------------------------------------------------------------------ ! !--- general grib2 info provided by post control file ! type param_t ! integer :: post_avblfldidx=-9999 ! character(len=80) :: shortname='' ! character(len=300) :: longname='' ! character(len=30) :: pdstmpl='' ! integer :: mass_windpoint=1 ! character(len=30) :: pname='' ! character(len=10) :: table_info='' ! character(len=20) :: stats_proc='' ! character(len=80) :: fixed_sfc1_type='' ! integer, dimension(:), pointer :: scale_fact_fixed_sfc1 => null() ! real, dimension(:), pointer :: level => null() ! character(len=80) :: fixed_sfc2_type='' ! integer, dimension(:), pointer :: scale_fact_fixed_sfc2 => null() ! real, dimension(:), pointer :: level2 => null() ! character(len=80) :: aerosol_type='' ! character(len=80) :: typ_intvl_size='' ! integer :: scale_fact_1st_size=0 ! real :: scale_val_1st_size=0. ! integer :: scale_fact_2nd_size=0 ! real :: scale_val_2nd_size=0. ! character(len=80) :: typ_intvl_wvlen='' ! integer :: scale_fact_1st_wvlen=0 ! real :: scale_val_1st_wvlen=0. ! integer :: scale_fact_2nd_wvlen=0 ! real :: scale_val_2nd_wvlen=0. ! real, dimension(:), pointer :: scale => null() ! integer :: stat_miss_val=0 ! integer :: leng_time_range_prev=0 ! integer :: time_inc_betwn_succ_fld=0 ! character(len=80) :: type_of_time_inc='' ! character(len=20) :: stat_unit_time_key_succ='' ! character(len=20) :: bit_map_flag='' ! integer :: perturb_num=0 ! integer :: num_ens_fcst=10 ! end type param_t ! ! type paramset_t ! character(len=6) :: datset='' ! integer :: grid_num=255 ! character(len=20) :: sub_center='' ! character(len=20) :: version_no='' ! character(len=20) :: local_table_vers_no='' ! character(len=20) :: sigreftime='' ! character(len=20) :: prod_status='' ! character(len=20) :: data_type='' ! character(len=20) :: gen_proc_type='' ! character(len=30) :: time_range_unit='' ! character(len=50) :: orig_center='' ! character(len=30) :: gen_proc='' ! character(len=20) :: packing_method='' ! character(len=20) :: field_datatype='' ! character(len=20) :: comprs_type='' ! character(len=50) :: type_ens_fcst='' ! character(len=50) :: type_derived_fcst='' ! type(param_t), dimension(:), pointer :: param => null() ! end type paramset_t type(paramset_t),save :: pset ! !--- grib2 info related to a specific data file integer nrecout integer num_pset integer isec,hrs_obs_cutoff,min_obs_cutoff integer sec_intvl,stat_miss_val,time_inc_betwn_succ_fld integer perturb_num,num_ens_fcst character*80 type_of_time_inc,stat_unit_time_key_succ logical*1,allocatable :: bmap(:) integer ibm integer,allocatable :: mg(:) ! integer,parameter :: max_bytes=1000*1300000 integer,parameter :: MAX_NUMBIT=16 integer,parameter :: lugi=650 character*255 fl_nametbl,fl_gdss3 real(8) :: stime,stime1,stime2,etime,etime1 logical :: first_grbtbl ! public num_pset,pset,nrecout,gribit2,grib_info_init,first_grbtbl,grib_info_finalize real(8), EXTERNAL :: timef !------------------------------------------------------------------------------------- ! contains ! !------------------------------------------------------------------------------------- subroutine grib_info_init() ! !--- initialize general grib2 information and ! implicit none ! ! logical,intent(in) :: first_grbtbl ! !-- local variables integer ierr character(len=80) outfile character(len=10) envvar ! !-- set up pset ! !-- 1. pset is set up at READCNTRL_xml.f !-- initialize items of pset that are not set in xml file ! if(pset%grid_num==0) & pset%grid_num=218 if(trim(pset%sub_center)=='') & pset%sub_center="ncep_emc" if(trim(pset%version_no)=='') & pset%version_no="v2003" if(trim(pset%local_table_vers_no)=='') & pset%local_table_vers_no="local_table_no" if(trim(pset%sigreftime)=='') & pset%sigreftime="fcst" if(trim(pset%prod_status)=='') & pset%prod_status="oper_test" if(trim(pset%data_type)=='') & pset%data_type="fcst" if(trim(pset%orig_center)=='') & pset%orig_center="nws_ncep" if(trim(pset%time_range_unit)=='') & pset%time_range_unit="hour" if(trim(pset%gen_proc_type)=='') & pset%gen_proc_type="fcst" if(trim(pset%gen_proc)=='') & pset%gen_proc="gfs_avn" if(trim(pset%packing_method)=='') & pset%packing_method="jpeg" if(trim(pset%field_datatype)=='') & pset%field_datatype="flting_pnt" if(trim(pset%comprs_type)=='') & pset%comprs_type="lossless" if(trim(pset%type_ens_fcst)=='') & pset%type_ens_fcst="pos_pert_fcst" if(trim(pset%type_derived_fcst)=='') & pset%type_derived_fcst="unweighted_mean_all_mem" ! !-- set up other grib2_info ! isec=0 hrs_obs_cutoff=0 ! applies to only obs min_obs_cutoff=0 ! applies to only obs sec_intvl=0 stat_miss_val=0 type_of_time_inc='same_start_time_fcst_fcst_time_inc' stat_unit_time_key_succ='missing' time_inc_betwn_succ_fld=0 ! !-- open fld name tble ! if(first_grbtbl) then fl_nametbl='params_grib2_tbl_new' call open_and_read_4dot2( fl_nametbl, ierr ) if ( ierr .ne. 0 ) then print*, 'Couldnt open table file - return code was ',ierr call mpi_abort() endif first_grbtbl=.false. endif ! !-- ! end subroutine grib_info_init !------------------------------------------------------------------------------------- !------------------------------------------------------------------------------------- ! subroutine grib_info_finalize ! !--- finalize grib2 information and close file ! implicit none ! !--- integer ierr call close_4dot2(ierr) ! end subroutine grib_info_finalize !------------------------------------------------------------------------------------- !------------------------------------------------------------------------------------- subroutine gribit2(post_fname) ! !------- use ctlblk_mod, only : im,jm,im_jm,num_procs,me,jsta,jend,ifhr,sdat,ihrst,imin, & mpi_comm_comp,ntlfld,fld_info,datapd,icnt,idsp implicit none ! include 'mpif.h' ! ! real,intent(in) :: data(im,1:jend-jsta+1,ntlfld) character(255),intent(in) :: post_fname ! !------- local variables integer i,j,k,n,nm,nprm,nlvl,fldlvl1,fldlvl2,cstart,cgrblen,ierr integer nf,nfpe,nmod integer fh, clength,lunout integer idisc,icatg,iparm,itblinfo,ntrange,leng_time_range_stat integer,allocatable :: nfld_pe(:),snfld_pe(:),enfld_pe(:) integer(4),allocatable :: isdsp(:),iscnt(:),ircnt(:),irdsp(:) integer status(MPI_STATUS_SIZE) integer(kind=MPI_OFFSET_KIND) idisp integer,allocatable :: jsta_pe(:),jend_pe(:) integer,allocatable :: grbmsglen(:) real,allocatable :: datafld(:,:) real,allocatable :: datafldtmp(:) ! character(1) cgrib(max_bytes) ! ! !---------------- code starts here -------------------------- ! ! !******* part 1 resitribute data ******** ! !--- calculate # of fields on each processor ! nf=ntlfld/num_procs nfpe=nf+1 nmod=mod(ntlfld,num_procs) ! print *,'ntlfld=',ntlfld,'nf=',nf,'nmod=',nmod allocate(snfld_pe(num_procs),enfld_pe(num_procs),nfld_pe(num_procs)) do n=1,num_procs if(n-1