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)))