8 use fckit_configuration_module, 
only: fckit_configuration
 
   17 use fckit_configuration_module, 
only: fckit_configuration
 
   18 use fckit_mpi_module, 
only: fckit_mpi_comm
 
   21 use mpp_domains_mod, 
only: center
 
   28 use type_gaugrid, 
only: gaussian_grid
 
   54  integer :: isc,iec,jsc,jec,npz
 
   64  real(kind=
kind_real), 
allocatable :: qsattraj(:,:,:) 
 
   69  type(gaussian_grid) :: glb 
 
   70  type(gaussian_grid) :: gg  
 
   71  integer :: nx,ny,nz,nv 
 
   75  integer,
allocatable :: istrx(:),jstry(:) 
 
   76  integer :: ngrid_ggh, ngrid_gg 
 
   78  character(len=256) :: path_to_nmcbalance_coeffs  
 
   79  integer :: read_latlon_from_nc                   
 
   86  real(kind=
kind_real), 
pointer :: psi(:,:,:) => null() 
 
   87  real(kind=
kind_real), 
pointer :: chi(:,:,:) => null() 
 
   88  real(kind=
kind_real), 
pointer :: tv(:,:,:) => null() 
 
  105 subroutine create(self, geom, bg, fg, conf)
 
  112 type(fckit_configuration),      
intent(in)    :: conf
 
  114 real(kind=
kind_real), 
pointer :: t(:,:,:)
 
  115 real(kind=
kind_real), 
pointer :: q(:,:,:)
 
  116 real(kind=
kind_real), 
pointer :: delp(:,:,:)
 
  118 integer :: hx,hy,layoutx,layouty,read_latlon_from_nc
 
  119 character(len=:),
allocatable :: str
 
  122 call self%geom_cs%clone(geom,geom%fields)
 
  123 self%npe = geom%f_comm%size()
 
  124 self%mype = geom%f_comm%rank()
 
  128 call bg%get_field(
't'   , t)
 
  129 call bg%get_field(
'sphum'   , q)
 
  130 call bg%get_field(
'delp', delp)
 
  133 allocate(self%tvtraj   (geom%isc:geom%iec,geom%jsc:geom%jec,1:geom%npz))
 
  134 call t_to_tv(geom,t,q,self%tvtraj)
 
  137 allocate(self%ttraj   (geom%isc:geom%iec,geom%jsc:geom%jec,1:geom%npz))
 
  141 allocate(self%qtraj   (geom%isc:geom%iec,geom%jsc:geom%jec,1:geom%npz))
 
  145 allocate(self%qsattraj(geom%isc:geom%iec,geom%jsc:geom%jec,1:geom%npz))
 
  148 call get_qsat(geom,delp,t,q,self%qsattraj)
 
  151 self%isc = geom%isc; self%iec = geom%iec
 
  152 self%jsc = geom%jsc; self%jec = geom%jec
 
  155 allocate(self%fld(self%isc:self%iec,self%jsc:self%jec,self%npz,4))
 
  156 self%fld = 0.0_kind_real
 
  159 if (conf%has(
"path_to_nmcbalance_coeffs")) 
then 
  160   call conf%get_or_die(
"path_to_nmcbalance_coeffs",str)
 
  161   self%path_to_nmcbalance_coeffs = str
 
  164   call abor1_ftn(
"fv3jedi_linvarcha_nmcbal_mod.create:& 
  165 & path_to_nmcbalance_coeffs must be set in configuration file")
 
  170 self%hx = 1; self%hy = 1 
 
  171 if(conf%has(
"hx")) 
then 
  172   call conf%get_or_die(
"hx",hx); self%hx = hx
 
  174 if(conf%has(
"hy")) 
then 
  175   call conf%get_or_die(
"hy",hy); self%hy = hy
 
  178 allocate(self%istrx(self%npe))
 
  179 allocate(self%jstry(self%npe))
 
  183 if(conf%has(
"layoutx").and.conf%has(
"layouty")) 
then 
  184   call conf%get_or_die(
"layoutx",layoutx)
 
  185   call conf%get_or_die(
"layouty",layouty)
 
  186   if(layoutx*layouty/=self%npe) 
then 
  187     call abor1_ftn(
"fv3jedi_linvarcha_nmcbal_mod.create:& 
  188 & invalid layout values")
 
  190   self%layout(1) = layoutx
 
  191   self%layout(2) = layouty
 
  196   else if(self%npe==18)
then 
  199   else if(self%npe==12)
then 
  202   else if(self%npe==6)
then 
  206     self%layout(1)=self%npe
 
  217 self%glb%nlat = self%ny; self%gg%nlat = self%y2
 
  218 self%glb%nlon = self%nx; self%gg%nlon = self%x2
 
  219 self%glb%nlev = self%nz; self%gg%nlev = self%z2
 
  220 self%glb%nvar = self%nv; self%gg%nvar = self%nv
 
  223 call self%glb%create(); 
call self%gg%create()
 
  226 call self%gg%fld3d_pointer(1,
'psi',self%psi)
 
  227 call self%gg%fld3d_pointer(2,
'chi',self%chi)
 
  228 call self%gg%fld3d_pointer(3,
'tv' ,self%tv)
 
  229 call self%gg%fld2d_pointer(4,
'ps' ,self%ps)
 
  232 self%read_latlon_from_nc = 0
 
  233 if(conf%has(
"read_latlon_from_nc")) 
then 
  234   call conf%get_or_die(
"read_latlon_from_nc",read_latlon_from_nc)
 
  235   self%read_latlon_from_nc = read_latlon_from_nc
 
  237 if(self%read_latlon_from_nc==1) 
then 
  240   call self%glb%calc_glb_latlon()
 
  248 allocate(self%agvz(self%gg%nlat,self%gg%nlev,self%gg%nlev))
 
  249 allocate(self%wgvz(self%gg%nlat,self%gg%nlev))
 
  250 allocate(self%bvz (self%gg%nlat,self%gg%nlev))
 
  263 if (
allocated(self%tvtraj))   
deallocate(self%tvtraj)
 
  264 if (
allocated(self%ttraj))    
deallocate(self%ttraj)
 
  265 if (
allocated(self%qtraj))    
deallocate(self%qtraj)
 
  266 if (
allocated(self%qsattraj)) 
deallocate(self%qsattraj)
 
  268 if (
allocated(self%istrx))    
deallocate(self%istrx)
 
  269 if (
allocated(self%jstry))    
deallocate(self%jstry)
 
  270 if (
allocated(self%agvz))     
deallocate(self%agvz)
 
  271 if (
allocated(self%wgvz))     
deallocate(self%wgvz)
 
  272 if (
allocated(self%bvz))      
deallocate(self%bvz)
 
  274 if (
allocated(self%fld))     
deallocate(self%fld)
 
  277 if (
associated(self%psi))     
nullify(self%psi)
 
  278 if (
associated(self%chi))     
nullify(self%chi)
 
  279 if (
associated(self%tv))      
nullify(self%tv)
 
  280 if (
associated(self%ps))      
nullify(self%ps)
 
  282 call self%glb%delete()
 
  283 call self%gg%delete()
 
  285 call self%c2g%delete()
 
  286 call self%g2c%delete()
 
  300 real(kind=
kind_real), 
pointer, 
dimension(:,:,:) :: xuba_psi
 
  301 real(kind=
kind_real), 
pointer, 
dimension(:,:,:) :: xuba_chi
 
  302 real(kind=
kind_real), 
pointer, 
dimension(:,:,:) :: xuba_tv
 
  303 real(kind=
kind_real), 
pointer, 
dimension(:,:,:) :: xuba_rh
 
  304 real(kind=
kind_real), 
pointer, 
dimension(:,:,:) :: xuba_ps
 
  306 real(kind=
kind_real), 
pointer, 
dimension(:,:,:) :: xbal_ua
 
  307 real(kind=
kind_real), 
pointer, 
dimension(:,:,:) :: xbal_va
 
  308 real(kind=
kind_real), 
pointer, 
dimension(:,:,:) :: xbal_t
 
  309 real(kind=
kind_real), 
pointer, 
dimension(:,:,:) :: xbal_q
 
  310 real(kind=
kind_real), 
pointer, 
dimension(:,:,:) :: xbal_ps
 
  312 real(
kind_real), 
allocatable :: psi_d(:,:,:), chi_d(:,:,:) 
 
  319 call xuba%get_field(
'psi', xuba_psi)
 
  320 call xuba%get_field(
'chi', xuba_chi)
 
  321 call xuba%get_field(
'tv' , xuba_tv)
 
  322 call xuba%get_field(
'rh' , xuba_rh)
 
  323 call xuba%get_field(
'ps' , xuba_ps)
 
  324 call xbal%get_field(
'ua' , xbal_ua)
 
  325 call xbal%get_field(
'va' , xbal_va)
 
  326 call xbal%get_field(
't'  , xbal_t)
 
  327 call xbal%get_field(
'sphum'  , xbal_q)
 
  328 call xbal%get_field(
'ps' , xbal_ps)
 
  333 self%fld(:,:,:,1) = xuba_psi
 
  334 self%fld(:,:,:,2) = xuba_chi
 
  335 self%fld(:,:,:,3) = xuba_tv
 
  336 self%fld(:,:,1:1,4) = xuba_ps
 
  349 allocate(psi_d(geom%isd:geom%ied,geom%jsd:geom%jed,1:geom%npz))
 
  350 allocate(chi_d(geom%isd:geom%ied,geom%jsd:geom%jed,1:geom%npz))
 
  351 psi_d = 0.0_kind_real; chi_d = 0.0_kind_real
 
  352 psi_d(geom%isc:geom%iec,geom%jsc:geom%jec,:) = self%fld(:,:,:,1)
 
  353 chi_d(geom%isc:geom%iec,geom%jsc:geom%jec,:) = self%fld(:,:,:,2)
 
  355 deallocate(psi_d,chi_d)
 
  358 call rh_to_q_tl(geom,self%qsattraj,xuba_rh,xbal_q)
 
  361 call tv_to_t_tl(geom,self%tvtraj,self%fld(:,:,:,3),self%qtraj,xbal_q,xbal_t)
 
  364 xbal_ps = self%fld(:,:,1:1,4)
 
  367 xbal%calendar_type = xuba%calendar_type
 
  368 xbal%date_init = xuba%date_init
 
  382 real(kind=
kind_real), 
pointer, 
dimension(:,:,:) :: xbal_ua
 
  383 real(kind=
kind_real), 
pointer, 
dimension(:,:,:) :: xbal_va
 
  384 real(kind=
kind_real), 
pointer, 
dimension(:,:,:) :: xbal_t
 
  385 real(kind=
kind_real), 
pointer, 
dimension(:,:,:) :: xbal_q
 
  386 real(kind=
kind_real), 
pointer, 
dimension(:,:,:) :: xbal_ps
 
  388 real(kind=
kind_real), 
pointer, 
dimension(:,:,:) :: xuba_psi
 
  389 real(kind=
kind_real), 
pointer, 
dimension(:,:,:) :: xuba_chi
 
  390 real(kind=
kind_real), 
pointer, 
dimension(:,:,:) :: xuba_tv
 
  391 real(kind=
kind_real), 
pointer, 
dimension(:,:,:) :: xuba_rh
 
  392 real(kind=
kind_real), 
pointer, 
dimension(:,:,:) :: xuba_ps
 
  394 real(
kind_real), 
allocatable :: psi_d(:,:,:), chi_d(:,:,:) 
 
  395 real(
kind_real), 
allocatable :: ps_not_copied(:,:,:)
 
  399 allocate(ps_not_copied(geom%isc:geom%iec,geom%jsc:geom%jec,1))
 
  400 call xuba%get_field(
'ps', ps_not_copied) 
 
  404 call xbal%get_field(
'ua' , xbal_ua)
 
  405 call xbal%get_field(
'va' , xbal_va)
 
  406 call xbal%get_field(
't'  , xbal_t)
 
  407 call xbal%get_field(
'sphum'  , xbal_q)
 
  408 call xbal%get_field(
'ps' , xbal_ps)
 
  409 call xuba%get_field(
'psi', xuba_psi)
 
  410 call xuba%get_field(
'chi', xuba_chi)
 
  411 call xuba%get_field(
'tv' , xuba_tv)
 
  412 call xuba%get_field(
'rh' , xuba_rh)
 
  413 call xuba%get_field(
'ps' , xuba_ps)
 
  415 xuba_ps(:,:,1) = ps_not_copied(:,:,1)
 
  416 deallocate(ps_not_copied)
 
  418 self%fld = 0.0_kind_real
 
  422 self%fld(:,:,1:1,4) = xbal_ps; xbal_ps = 0.0_kind_real
 
  425 call tv_to_t_ad(geom,self%tvtraj,self%fld(:,:,:,3),self%qtraj,xbal_q,xbal_t)
 
  428 call rh_to_q_ad(geom,self%qsattraj,xuba_rh,xbal_q)
 
  431 allocate(psi_d(geom%isd:geom%ied,geom%jsd:geom%jed,1:geom%npz))
 
  432 allocate(chi_d(geom%isd:geom%ied,geom%jsd:geom%jed,1:geom%npz))
 
  433 psi_d = 0.0_kind_real; chi_d = 0.0_kind_real
 
  435 self%fld(:,:,:,1) = psi_d(geom%isc:geom%iec,geom%jsc:geom%jec,:)
 
  436 self%fld(:,:,:,2) = chi_d(geom%isc:geom%iec,geom%jsc:geom%jec,:)
 
  437 deallocate(psi_d,chi_d)
 
  448 xuba_ps   = xuba_ps  + self%fld(:,:,1:1,4)
 
  449 xuba_tv   = xuba_tv  + self%fld(:,:,:,3)
 
  450 xuba_psi  = xuba_psi + self%fld(:,:,:,1)
 
  451 xuba_chi  = xuba_chi + self%fld(:,:,:,2)
 
  452 self%fld = 0.0_kind_real
 
  455 xuba%calendar_type = xbal%calendar_type
 
  456 xuba%date_init = xbal%date_init
 
  470 real(kind=
kind_real), 
pointer, 
dimension(:,:,:) :: xbal_ua
 
  471 real(kind=
kind_real), 
pointer, 
dimension(:,:,:) :: xbal_va
 
  472 real(kind=
kind_real), 
pointer, 
dimension(:,:,:) :: xbal_t
 
  473 real(kind=
kind_real), 
pointer, 
dimension(:,:,:) :: xbal_q
 
  475 real(kind=
kind_real), 
pointer, 
dimension(:,:,:) :: xuba_psi
 
  476 real(kind=
kind_real), 
pointer, 
dimension(:,:,:) :: xuba_chi
 
  477 real(kind=
kind_real), 
pointer, 
dimension(:,:,:) :: xuba_tv
 
  478 real(kind=
kind_real), 
pointer, 
dimension(:,:,:) :: xuba_rh
 
  486 call xbal%get_field(
'ua' , xbal_ua)
 
  487 call xbal%get_field(
'va' , xbal_va)
 
  488 call xbal%get_field(
't'  , xbal_t)
 
  489 call xbal%get_field(
'sphum'  , xbal_q)
 
  490 call xuba%get_field(
'psi', xuba_psi)
 
  491 call xuba%get_field(
'chi', xuba_chi)
 
  492 call xuba%get_field(
'tv' , xuba_tv)
 
  493 call xuba%get_field(
'rh' , xuba_rh)
 
  501 xuba%calendar_type = xbal%calendar_type
 
  502 xuba%date_init = xbal%date_init
 
  516 real(kind=
kind_real), 
pointer, 
dimension(:,:,:) :: xuba_psi
 
  517 real(kind=
kind_real), 
pointer, 
dimension(:,:,:) :: xuba_chi
 
  518 real(kind=
kind_real), 
pointer, 
dimension(:,:,:) :: xuba_tv
 
  519 real(kind=
kind_real), 
pointer, 
dimension(:,:,:) :: xuba_rh
 
  521 real(kind=
kind_real), 
pointer, 
dimension(:,:,:) :: xbal_ua
 
  522 real(kind=
kind_real), 
pointer, 
dimension(:,:,:) :: xbal_va
 
  523 real(kind=
kind_real), 
pointer, 
dimension(:,:,:) :: xbal_t
 
  524 real(kind=
kind_real), 
pointer, 
dimension(:,:,:) :: xbal_q
 
  531 call xuba%get_field(
'psi', xuba_psi)
 
  532 call xuba%get_field(
'chi', xuba_chi)
 
  533 call xuba%get_field(
'tv' , xuba_tv)
 
  534 call xuba%get_field(
'rh' , xuba_rh)
 
  535 call xbal%get_field(
'ua' , xbal_ua)
 
  536 call xbal%get_field(
'va' , xbal_va)
 
  537 call xbal%get_field(
't'  , xbal_t)
 
  538 call xbal%get_field(
'sphum'  , xbal_q)
 
  546 xbal%calendar_type = xuba%calendar_type
 
  547 xbal%date_init = xuba%date_init
 
  559 if(self%layout(2)==1)
then 
  575 integer,
allocatable:: imxy(:), jmxy(:)
 
  576 integer:: i,j,k,istart0, jstart0
 
  579 integer,
allocatable,
dimension(:) :: jlon1,ilat1
 
  593 allocate(jlon1(self%npe))
 
  594 allocate(ilat1(self%npe))
 
  607     jstart0 = jstart0 + jmxy(j-1)
 
  612     self%jstry(k) = jstart0
 
  615       istart0 = istart0 + imxy(i-1)
 
  617     self%istrx(k) = istart0
 
  623 self%y2=ilat1(mm1)+self%hy*2
 
  624 self%x2=jlon1(mm1)+self%hx*2
 
  625 deallocate(ilat1,jlon1)
 
  626 deallocate(imxy,jmxy)
 
  637 integer :: npts,nrnc,iinum,iileft,jrows,jleft,k,i,jjnum
 
  638 integer :: j,mm1,iicnt,ipts,jjleft
 
  639 integer,
allocatable,
dimension(:) :: jlon1,ilat1
 
  640 integer,
allocatable,
dimension(:) :: iiend,jjend,iistart
 
  641 real(kind_real) :: anperpe
 
  647   call abor1_ftn(
"fv3jedi_linvarcha_nmcbal_mod.deter_subdomain_nolayout:& 
  648 & npe has invalid value")
 
  650 anperpe=float(npts)/float(self%npe)
 
  653 nrnc=int(sqrt(anperpe))
 
  657 iileft=self%nx-iicnt*iinum
 
  659 jleft=self%npe-jrows*iinum
 
  665 allocate(iistart(self%npe+1))
 
  666 allocate(iiend(self%npe+1))
 
  667 allocate(jjend(self%npe+1))
 
  668 allocate(jlon1(self%npe))
 
  669 allocate(ilat1(self%npe))
 
  673   if(i <= iileft)ipts=ipts+1
 
  674   iiend(i)=iistart(i)+ipts-1
 
  675   iistart(i+1)=iiend(i)+1
 
  677   if(i <= jleft)jjnum=jrows+1
 
  681     self%istrx(k)= iistart(i)
 
  682     ilat1(k)=self%ny/jjnum
 
  683     jjleft=self%ny-ilat1(k)*jjnum
 
  684     if(j <= jjleft)ilat1(k)=ilat1(k)+1
 
  685     if(j > 1)self%jstry(k)=jjend(j-1)+1
 
  686     jjend(j)=self%jstry(k)+ilat1(k)-1
 
  689 deallocate(iistart,iiend,jjend)
 
  693 self%y2=ilat1(mm1)+self%hy*2
 
  694 self%x2=jlon1(mm1)+self%hx*2
 
  695 deallocate(ilat1,jlon1)
 
  704 integer,
intent(in   ) :: dim_world, ndes
 
  705 integer,
intent(inout) :: dim(0:ndes-1)
 
  709 rm = dim_world-ndes*im
 
  712   if( n<=rm-1 ) dim(n) = im+1
 
  726 jy=self%jstry(self%mype+1)-self%hy
 
  729   if(jy>=self%glb%nlat+1) jy=self%glb%nlat
 
  730   self%gg%rlats(j)=self%glb%rlats(jy)
 
  731   jy = self%jstry(self%mype+1)-self%hy+j
 
  735 ix=self%istrx(self%mype+1)-self%hx
 
  737   if(ix<=0) ix=ix+self%glb%nlon
 
  738   if(ix>self%glb%nlon) ix=ix-self%glb%nlon
 
  739   self%gg%rlons(i) = self%glb%rlons(ix)
 
  740   ix=self%istrx(self%mype+1)-self%hx+i
 
  753 integer :: jx,jy,jnode
 
  754 real(kind=
kind_real), 
pointer :: real_ptr(:,:)
 
  755 real(kind=
kind_real), 
allocatable :: lon_cs(:)  
 
  756 real(kind=
kind_real), 
allocatable :: lat_cs(:)  
 
  757 real(kind=
kind_real), 
allocatable :: lon_ggh(:) 
 
  758 real(kind=
kind_real), 
allocatable :: lat_ggh(:) 
 
  759 real(kind=
kind_real), 
allocatable :: lon_gg(:,:)  
 
  760 real(kind=
kind_real), 
allocatable :: lat_gg(:,:)  
 
  763 if(  (geom%isc/=self%isc).or.(geom%iec/=self%iec) &
 
  764 &.or.(geom%jsc/=self%jsc).or.(geom%jec/=self%jec)) 
then 
  765   call abor1_ftn(
"fv3jedi_linvarcha_nmcbal_mod.bump_init_gaugrid:& 
  766 & grid does not match that in the geometry")
 
  770 self%ngrid_cs = (geom%iec-geom%isc+1)*(geom%jec-geom%jsc+1)
 
  771 allocate(lon_cs(self%ngrid_cs))
 
  772 allocate(lat_cs(self%ngrid_cs))
 
  774 do jy=geom%jsc,geom%jec
 
  775   do jx=geom%isc,geom%iec
 
  777     lon_cs(jnode) = geom%grid_lon(jx,jy)*
rad2deg 
  778     lat_cs(jnode) = geom%grid_lat(jx,jy)*
rad2deg 
  783 self%ngrid_ggh = self%gg%nlat*self%gg%nlon
 
  784 self%ngrid_gg = (self%gg%nlat-self%hy*2)*(self%gg%nlon-self%hx*2)
 
  785 allocate(lon_ggh(self%ngrid_ggh))
 
  786 allocate(lat_ggh(self%ngrid_ggh))
 
  787 allocate(lon_gg(1+self%hx:self%gg%nlon-self%hx,1+self%hy:self%gg%nlat-self%hy))
 
  788 allocate(lat_gg(1+self%hx:self%gg%nlon-self%hx,1+self%hy:self%gg%nlat-self%hy))
 
  793     lon_ggh(jnode) = self%gg%rlons(jx)*
rad2deg 
  794     lat_ggh(jnode) = self%gg%rlats(jy)*
rad2deg 
  797 do jy=1+self%hy,self%gg%nlat-self%hy
 
  798   do jx=1+self%hx,self%gg%nlon-self%hx
 
  799     lon_gg(jx,jy) = self%gg%rlons(jx)
 
  800     lat_gg(jx,jy) = self%gg%rlats(jy)
 
  805 call self%c2g%setup(geom%f_comm,                                        &
 
  806 &                   geom%isc,geom%iec,geom%jsc,geom%jec,geom%npz,       &
 
  807 &                   geom%grid_lon(geom%isc:geom%iec,geom%jsc:geom%jec), &
 
  808 &                   geom%grid_lat(geom%isc:geom%iec,geom%jsc:geom%jec), &
 
  809 &                   self%ngrid_ggh,lon_ggh,lat_ggh)
 
  810 call self%g2c%setup(geom%f_comm,                                                            &
 
  811 &                   1+self%hx,self%gg%nlon-self%hx,1+self%hy,self%gg%nlat-self%hy,geom%npz, &
 
  812 &                   lon_gg(1+self%hx:self%gg%nlon-self%hx,1+self%hy:self%gg%nlat-self%hy),  &
 
  813 &                   lat_gg(1+self%hx:self%gg%nlon-self%hx,1+self%hy:self%gg%nlat-self%hy),  &
 
  814 &                   self%ngrid_cs,lon_cs,lat_cs)
 
  817 deallocate(lon_cs,lat_cs)
 
  818 deallocate(lon_ggh,lat_ggh)
 
  819 deallocate(lon_gg,lat_gg)
 
  830 integer :: iunit,ierr,ncid,dimid
 
  832 character(len=128) :: log_grid
 
  833 character(len=16)  :: nlat_c,nlon_c,nlev_c
 
  835 if(self%mype==0) 
then 
  837   call nccheck(nf90_open(trim(self%path_to_nmcbalance_coeffs),nf90_nowrite,ncid), &
 
  838  &                       
"nf90_open "//trim(self%path_to_nmcbalance_coeffs))
 
  840   call nccheck(nf90_inq_dimid(ncid,
"nlat",dimid), 
"nf90_inq_dimid nlat")
 
  841   call nccheck(nf90_inquire_dimension(ncid,dimid,len=grid(1)), &
 
  842  &            
"nf90_inquire_dimension nlat" )
 
  843   call nccheck(nf90_inq_dimid(ncid,
"nlon",dimid), 
"nf90_inq_dimid nlon")
 
  844   call nccheck(nf90_inquire_dimension(ncid,dimid,len=grid(2)), &
 
  845  &            
"nf90_inquire_dimension nlon" )
 
  846   call nccheck(nf90_inq_dimid(ncid,
"nlev",dimid), 
"nf90_inq_dimid nlev")
 
  847   call nccheck(nf90_inquire_dimension(ncid,dimid,len=grid(3)), &
 
  848 &            
"nf90_inquire_dimension nlev" )
 
  851   call nccheck(nf90_close(ncid),
"nf90_close")
 
  853 call self%geom_cs%f_comm%broadcast(grid,0)
 
  854 if(grid(3)/=self%npz) 
then 
  855   call abor1_ftn(
"fv3jedi_linvarcha_nmcbal_mod.read_nmcbalance_grid:& 
  856 & nlev must be the same as npz on FV3 geometry")
 
  861 if(self%mype==0) 
then 
  862   write(nlat_c,*) grid(1); 
write(nlon_c,*) grid(2); 
write(nlev_c,*) grid(3);
 
  863   write(log_grid,*) 
"NMC balance operalor grid size : nx=",&
 
  864  &                          trim(adjustl(nlon_c)), &
 
  865  &                   
",ny=",trim(adjustl(nlat_c)), &
 
  866  &                   
",nz=",trim(adjustl(nlev_c))
 
  867   write(6,
'(A)') log_grid
 
  879 integer :: iunit,ierr,ncid,varid
 
  880 integer :: mm1,jx,i,j,k
 
  882 real(kind=
kind_real),
allocatable :: rlats(:)
 
  883 real(kind=
kind_real),
allocatable :: rlons(:)
 
  885 allocate(rlats(self%glb%nlat))
 
  886 allocate(rlons(self%glb%nlon))
 
  888 if(self%mype==0) 
then 
  890   call nccheck(nf90_open(trim(self%path_to_nmcbalance_coeffs),nf90_nowrite,ncid), &
 
  891   &                      
"nf90_open "//trim(self%path_to_nmcbalance_coeffs))
 
  894   call nccheck(nf90_inq_varid(ncid,
"lats",varid), 
"nf90_inq_varid lats")
 
  895   call nccheck(nf90_get_var(ncid,varid,rlats),
"nf90_get_var lats" )
 
  896   call nccheck(nf90_inq_varid(ncid,
"lons",varid), 
"nf90_inq_varid lons")
 
  897   call nccheck(nf90_get_var(ncid,varid,rlons),
"nf90_get_var lons" )
 
  900   call nccheck(nf90_close(ncid),
"nf90_close")
 
  902 call self%geom_cs%f_comm%broadcast(rlats,0)
 
  903 call self%geom_cs%f_comm%broadcast(rlons,0)
 
  906   self%glb%rlons(i) = rlons(i)*
deg2rad 
  909   self%glb%rlats(i) = rlats(i)*
deg2rad 
  921 integer :: iunit,ierr,ncid,varid
 
  922 integer :: mm1,jx,i,j,k
 
  924 real(kind=
r_single),
allocatable :: agvin(:,:,:,:)
 
  925 real(kind=
r_single),
allocatable :: wgvin(:,:,:)
 
  926 real(kind=
r_single),
allocatable :: bvin(:,:,:)
 
  928 allocate(agvin(self%glb%nlat,self%glb%nlev,self%glb%nlev,1))
 
  929 allocate(wgvin(self%glb%nlat,self%glb%nlev,1))
 
  930 allocate(bvin(self%glb%nlat,self%glb%nlev,1))
 
  932 if(self%mype==0) 
then 
  934   call nccheck(nf90_open(trim(self%path_to_nmcbalance_coeffs),nf90_nowrite,ncid), &
 
  935  &                       
"nf90_open"//trim(self%path_to_nmcbalance_coeffs))
 
  937   call nccheck(nf90_inq_varid(ncid,
"agvz",varid), 
"nf90_inq_varid agvz")
 
  938   call nccheck(nf90_get_var(ncid,varid,agvin),
"nf90_get_var agvz" )
 
  939   call nccheck(nf90_inq_varid(ncid,
"wgvz",varid), 
"nf90_inq_varid wgvz")
 
  940   call nccheck(nf90_get_var(ncid,varid,wgvin),
"nf90_get_var wgvz" )
 
  941   call nccheck(nf90_inq_varid(ncid,
"bvz",varid), 
"nf90_inq_varid bvz")
 
  942   call nccheck(nf90_get_var(ncid,varid,bvin),
"nf90_get_var bvz" )
 
  945   call nccheck(nf90_close(ncid),
"nf90_close")
 
  947 call self%geom_cs%f_comm%broadcast(agvin,0)
 
  948 call self%geom_cs%f_comm%broadcast(wgvin,0)
 
  949 call self%geom_cs%f_comm%broadcast(bvin,0)
 
  950 self%agvz = 0.0_kind_real
 
  951 self%bvz  = 0.0_kind_real
 
  952 self%wgvz = 0.0_kind_real
 
  957       jx=self%jstry(mm1)+i-2
 
  959       jx=min(self%glb%nlat-1,jx)
 
  960       self%agvz(i,j,k)=agvin(jx,j,k,1)
 
  964     jx=self%jstry(mm1)+i-2
 
  966     jx=min(self%glb%nlat-1,jx)
 
  967     self%wgvz(i,k)=wgvin(jx,k,1)
 
  968     self%bvz(i,k)=bvin(jx,k,1)
 
  971 deallocate(agvin,wgvin,bvin)
 
  982 integer :: jvar,jnode,jx,jy,jz
 
  986 allocate(vec(self%ngrid_ggh,self%gg%nlev))
 
  993   call self%c2g%apply(self%npz,                                                      &
 
  994  &                    self%fld(self%isc:self%iec,self%jsc:self%jec,1:self%npz,jvar), &
 
  995  &                    self%ngrid_ggh,vec)
 
 1000     do jy=1,self%gg%nlat
 
 1001       do jx=1,self%gg%nlon
 
 1003         self%gg%fld(jy,jx,jz,jvar) = vec(jnode,jz)
 
 1021 integer :: jvar,jx,jy,jz,jnode
 
 1022 real(kind_real),
allocatable :: fld(:,:,:),vec(:,:)
 
 1025 allocate(fld(self%gg%nlon,self%gg%nlat,self%gg%nlev))
 
 1026 allocate(vec(self%ngrid_cs,self%npz))
 
 1031   do jz=1,self%gg%nlev
 
 1032     do jy=1+self%hy,self%gg%nlat-self%hy
 
 1033       do jx=1+self%hx,self%gg%nlon-self%hx
 
 1034         fld(jx,jy,jz) = self%gg%fld(jy,jx,jz,jvar)
 
 1041   call self%g2c%apply(self%gg%nlev,                                                                      &
 
 1042  &                    fld(1+self%hx:self%gg%nlon-self%hx,1+self%hy:self%gg%nlat-self%hy,1:self%gg%nlev), &
 
 1043  &                    self%ngrid_cs,vec)
 
 1048     do jy=self%jsc,self%jec
 
 1049        do jx=self%isc,self%iec
 
 1051          self%fld(jx,jy,jz,jvar) = vec(jnode,jz)
 
 1070 integer :: jvar,jnode,jx,jy,jz
 
 1071 real(kind_real),
allocatable :: vec(:,:)
 
 1074 allocate(vec(self%ngrid_ggh,self%gg%nlev))
 
 1081   do jz=1,self%gg%nlev
 
 1083     do jy=1,self%gg%nlat
 
 1084       do jx=1,self%gg%nlon
 
 1086         vec(jnode,jz) = self%gg%fld(jy,jx,jz,jvar)
 
 1092   call self%c2g%apply_ad(self%npz,                                                      &
 
 1093  &                       self%fld(self%isc:self%iec,self%jsc:self%jec,1:self%npz,jvar), &
 
 1094  &                       self%ngrid_ggh,vec)
 
 1099 self%gg%fld = 0.0_kind_real
 
 1114 integer :: jvar,jx,jy,jz,jnode
 
 1115 real(kind_real),
allocatable :: fld(:,:,:),vec(:,:)
 
 1118 allocate(fld(self%gg%nlon,self%gg%nlat,self%gg%nlev))
 
 1119 allocate(vec(self%ngrid_cs,self%npz))
 
 1122 self%gg%fld = 0.0_kind_real
 
 1128     do jy=self%jsc,self%jec
 
 1129        do jx=self%isc,self%iec
 
 1131          vec(jnode,jz) = self%fld(jx,jy,jz,jvar)
 
 1137   call self%g2c%apply_ad(self%gg%nlev,                                                                      &
 
 1138  &                       fld(1+self%hx:self%gg%nlon-self%hx,1+self%hy:self%gg%nlat-self%hy,1:self%gg%nlev), &
 
 1139  &                       self%ngrid_cs,vec)
 
 1142   do jz=1,self%gg%nlev
 
 1143     do jy=1+self%hy,self%gg%nlat-self%hy
 
 1144       do jx=1+self%hx,self%gg%nlon-self%hx
 
 1145         self%gg%fld(jy,jx,jz,jvar) = self%gg%fld(jy,jx,jz,jvar)+fld(jx,jy,jz)
 
 1153 self%fld = 0.0_kind_real
 
 1175       self%ps(j,i)=self%ps(j,i)+self%wgvz(j,k)*self%psi(j,i,k)
 
 1184       self%chi(j,i,k)=self%chi(j,i,k)+self%bvz(j,k)*self%psi(j,i,k)
 
 1192         self%tv(j,i,k)=self%tv(j,i,k)+self%agvz(j,k,l)*self%psi(j,i,l)
 
 1213         self%psi(j,i,k)=self%psi(j,i,k)+self%agvz(j,l,k)*self%tv(j,i,l)
 
 1221       self%psi(j,i,k)=self%psi(j,i,k)+self%bvz(j,k)*self%chi(j,i,k)
 
 1231       self%psi(j,i,k)=self%psi(j,i,k)+self%wgvz(j,k)*self%ps(j,i)
 
 1240 subroutine bi2nc(path_to_gsi_bal_coeffs)
 
 1243 character(len=*),               
intent(in   ) :: path_to_gsi_bal_coeffs
 
 1245 integer :: iunit,ierr
 
 1246 integer :: nlev,nlat,nlon
 
 1247 integer :: fileopts, ncid, vc, varid(10)
 
 1248 integer :: x_dimid,y_dimid,z_dimid,t_dimid
 
 1249 integer,
allocatable :: v_dimids(:)
 
 1250 real(kind=
kind_real),
allocatable :: lats(:),lons(:)
 
 1251 integer,
allocatable :: zk(:)
 
 1254 character(len=64)  :: nlat_c,nlev_c
 
 1255 character(len=128) :: ncname
 
 1256 real(kind=
r_single),
allocatable :: agvin(:,:,:,:)
 
 1257 real(kind=
r_single),
allocatable :: wgvin(:,:,:)
 
 1258 real(kind=
r_single),
allocatable :: bvin(:,:,:)
 
 1259 type(gaussian_grid) :: gauss
 
 1262 open(iunit,file=trim(path_to_gsi_bal_coeffs),form=
'unformatted', &
 
 1263 &     convert=
'big_endian',status=
'old',iostat=ierr)
 
 1266 read(iunit,iostat=ierr) nlev,nlat,nlon
 
 1273 call gauss%calc_glb_latlon()
 
 1275 allocate(lats(nlat))
 
 1277   lats(j)=gauss%rlats(j)*
rad2deg 
 1279 allocate(lons(nlon))
 
 1281   lons(i)=gauss%rlons(i)*
rad2deg 
 1288 allocate(agvin(nlat,nlev,nlev,1))
 
 1289 allocate(wgvin(nlat,nlev,1))
 
 1290 allocate(bvin(nlat,nlev,1))
 
 1291 read(iunit,iostat=ierr) agvin,bvin,wgvin
 
 1294 fileopts = ior(nf90_netcdf4, nf90_mpiio)
 
 1297 write(nlev_c,*) nlev; 
write(nlat_c,*) nlat
 
 1298 write(ncname,*) 
"global_berror.l",trim(adjustl(nlev_c)),
"y",trim(adjustl(nlat_c)),
".nc" 
 1299 call nccheck(nf90_create(trim(adjustl(ncname)),fileopts,ncid),
'nf90_create')
 
 1301 call nccheck(nf90_def_dim(ncid,
'nlat',nlat,y_dimid),
'nf90_def_dim nlat')
 
 1302 call nccheck(nf90_def_dim(ncid,
'nlon',nlon,x_dimid),
'nf90_def_dim nlon')
 
 1303 call nccheck(nf90_def_dim(ncid,
'nlev',nlev,z_dimid),
'nf90_def_dim nlev')
 
 1304 call nccheck(nf90_def_dim(ncid,
'time',   1,t_dimid),
'nf90_def_dim time')
 
 1307 call nccheck(nf90_def_var(ncid,
"lats",nf90_double,y_dimid,varid(vc)),
"nf90_def_var lats")
 
 1308 call nccheck(nf90_put_att(ncid,varid(vc),
"long_name",
"latitude"))
 
 1309 call nccheck(nf90_put_att(ncid,varid(vc),
"units",
"degrees_north"))
 
 1311 call nccheck(nf90_def_var(ncid,
"lons",nf90_double,x_dimid,varid(vc)),
"nf90_def_var lons")
 
 1312 call nccheck(nf90_put_att(ncid,varid(vc),
"long_name",
"longitude"))
 
 1313 call nccheck(nf90_put_att(ncid,varid(vc),
"units",
"degrees_west"))
 
 1315 call nccheck(nf90_def_var(ncid,
"level",nf90_int,z_dimid,varid(vc)),
"nf90_def_var level")
 
 1316 call nccheck(nf90_put_att(ncid,varid(vc),
"long_name",
"vertical level"))
 
 1317 call nccheck(nf90_put_att(ncid,varid(vc),
"units",
"none"))
 
 1319 call nccheck(nf90_def_var(ncid,
"time",nf90_int,t_dimid,varid(vc)),
"nf90_def_var time")
 
 1320 call nccheck(nf90_put_att(ncid,varid(vc),
"long_name",
"time"),
"nf90_def_var time long_name")
 
 1323 allocate(v_dimids(4))
 
 1324 v_dimids(:) = (/y_dimid,z_dimid,z_dimid,t_dimid/)
 
 1325 call nccheck(nf90_def_var(ncid,
'agvz',nf90_float,v_dimids,varid(vc)),
'nf90_def_var agvz')
 
 1326 call nccheck(nf90_put_att(ncid,varid(vc), &
 
 1327 & 
"long_name",
"projection_of_streamfunction_onto_balanced_temperature"))
 
 1328 call nccheck(nf90_put_att(ncid,varid(vc),
"units",
"K s m-2"))
 
 1329 deallocate(v_dimids)
 
 1331 allocate(v_dimids(3))
 
 1332 v_dimids(:) = (/y_dimid,z_dimid,t_dimid/)
 
 1333 call nccheck(nf90_def_var(ncid,
'bvz',nf90_float,v_dimids,varid(vc)),
'nf90_def_var bvz')
 
 1334 call nccheck(nf90_put_att(ncid,varid(vc), &
 
 1335 & 
"long_name",
"projection_of_streamfunction_onto_balanced_velocity_potential"))
 
 1336 call nccheck(nf90_put_att(ncid,varid(vc),
"units",
"none"))
 
 1338 call nccheck(nf90_def_var(ncid,
'wgvz',nf90_float,v_dimids,varid(vc)),
'nf90_def_var wgvz')
 
 1339 call nccheck(nf90_put_att(ncid,varid(vc), &
 
 1340 & 
"long_name",
"projection_of_streamfunction_onto_balanced_surface_pressure"))
 
 1341 call nccheck(nf90_put_att(ncid,varid(vc),
"units",
"Pa s m-2"))
 
 1342 deallocate(v_dimids)
 
 1344 call nccheck(nf90_enddef(ncid),
"nf90_enddef")
 
 1347 call nccheck(nf90_put_var(ncid,varid(vc),lats),
"nf90_put_var lats")
 
 1349 call nccheck(nf90_put_var(ncid,varid(vc),lons),
"nf90_put_var lons")
 
 1351 call nccheck(nf90_put_var(ncid,varid(vc),zk),
"nf90_put_var level")
 
 1353 call nccheck(nf90_put_var(ncid,varid(vc),1),
"nf90_put_var time")
 
 1356 call nccheck(nf90_put_var(ncid,varid(vc),agvin),
"nf90_put_var agvz")
 
 1358 call nccheck(nf90_put_var(ncid,varid(vc),bvin),
"nf90_put_var bvz")
 
 1360 call nccheck(nf90_put_var(ncid,varid(vc),wgvin),
"nf90_put_var wgvz")
 
 1362 call nccheck(nf90_close(ncid),
'nf90_close')
 
 1366 deallocate(agvin,wgvin,bvin)
 
 1368 end subroutine bi2nc 
 1375 integer,
intent(in),
optional :: iunit_in
 
 1377 logical :: lopened, lexist
 
 1378 integer,
parameter :: iunit_str=11, iunit_end=99
 
 1381 if(
present(iunit_in)) 
then 
 1382   inquire(unit=iunit_in,opened=lopened,exist=lexist)
 
 1383   if(lexist.and.(.not.lopened)) iunit=iunit_in
 
 1387 do i=iunit_str,iunit_end
 
 1388   inquire(unit=i,opened=lopened,exist=lexist)
 
 1389   if(lexist.and.(.not.lopened)) 
then 
 1402 integer,
intent(in) :: ierr
 
 1403 character(len=*),
intent(in) :: mess
 
 1405 character(len=256) :: abort_log
 
 1407 write(abort_log,
'(3A,I3)') 
"IO Error : ",trim(mess),
" : iostat=",ierr
 
 1409   call abor1_ftn(trim(adjustl(abort_log)))