tools_sub.f90 Source File


Source Code

module tools_sub
!! Module for rearrangement of the radial grid and some operations for undef data in tools/ programs

  ! under construction
  type file_ord_3d  !! Setting variable order in read/write file
     integer :: VT
     integer :: VR
     integer :: VTs
     integer :: VTc
     integer :: VRs
     integer :: VRc
     integer :: phi
     integer :: phis
     integer :: phic
     integer :: zeta
     integer :: zetas
     integer :: zetac
  end type file_ord_3d

contains

!--------------------------------------------------
!--------------------------------------------------

subroutine replace_val_2d( ival2d, orgval, repval )
!! replace orgval with repval in ival2d array
  implicit none
  double precision, intent(inout) :: ival2d(:,:)  !! base
  double precision, intent(in) :: orgval  !! replace from this
  double precision, intent(in) :: repval  !! replace to this
  integer :: ii, jj, ix, jy  !! internal variables

  ix=size(ival2d,1)
  jy=size(ival2d,2)

  do jj=1,jy
     do ii=1,ix
        if(ival2d(ii,jj)==orgval)then
           ival2d(ii,jj)=repval
        end if
     end do
  end do

end subroutine replace_val_2d

!--------------------------------------------------
!--------------------------------------------------

subroutine replace_undef( ioval2d, undeflag, undefv )
!! replace ioval2d with undefv at the point undeflag == .true.
  implicit none
  double precision, intent(inout) :: ioval2d(:,:)  !! base
  logical, intent(in) :: undeflag(size(ioval2d,1),size(ioval2d,2))  !! flag for undefined point
  double precision, intent(in) :: undefv  !! undefined value
  integer :: ii, jj, ix, jy  !! internal variables

  ix=size(ioval2d,1)
  jy=size(ioval2d,2)

  do jj=1,jy
     do ii=1,ix
        if(undeflag(ii,jj).eqv..true.)then
           ioval2d(ii,jj)=undefv
        end if
     end do
  end do

end subroutine replace_undef

!--------------------------------------------------
!--------------------------------------------------

subroutine proj_Vs( xcent, ycent, xx, yy, ux, vy, projV, undef )
!! projection of a uniform wind [(ux,vy) on Cartesian grids] to the line-of-sight component along the radar beam
  implicit none
  double precision, intent(in) :: xcent  !! Radar location (x or lon)
  double precision, intent(in) :: ycent  !! Radar location (y or lat)
  double precision, intent(in) :: xx(:,:)  !! x coordinate (x or lon)
  double precision, intent(in) :: yy(size(xx,1),size(xx,2))  !! y coordinate (y or lat)
  double precision, intent(in) :: ux  !! X component of the uniform wind (m/s)
  double precision, intent(in) :: vy  !! Y component of the uniform wind (m/s)
  double precision, intent(out) :: projV(size(xx,1),size(xx,2))  !! line-of-sight component on (xx,yy)
  double precision, intent(in) :: undef  !! undefined value
  integer :: ii, jj, ix, jy
  double precision :: r_inv, rpx, rpy

  ix=size(xx,1)
  jy=size(xx,2)
  projV=undef

!$omp parallel default(shared)
!$omp do schedule(runtime) private(ii,jj,r_inv,rpx,rpy)

  do jj=1,jy
     do ii=1,ix
        rpx=xx(ii,jj)-xcent
        rpy=yy(ii,jj)-ycent
        if(rpx/=0.0d0.or.rpy/=0.0d0)then
           r_inv=1.0d0/dsqrt(rpx**2+rpy**2)
           projV(ii,jj)=rpx*r_inv*ux+rpy*r_inv*vy
        end if
     end do
  end do

!$omp end do
!$omp end parallel

end subroutine proj_Vs

!--------------------------------------------------
!--------------------------------------------------

subroutine proj_rtVs( radi, thet, ux, vy, projVR, projVT, undef )
!! projection of a uniform wind [(ux,vy) on Cartesian grids] to the radial and tangential components on the polar coordinate
  implicit none
  double precision, intent(in) :: radi(:)  !! radial grid (m)
  double precision, intent(in) :: thet(:)  !! azimuthal grid (rad)
  double precision, intent(in) :: ux       !! X-component of a uniform wind (m/s)
  double precision, intent(in) :: vy       !! Y-component of a uniform wind (m/s)
  double precision, intent(out) :: projVR(size(radi),size(thet))  !! radial wind
  double precision, intent(out) :: projVT(size(radi),size(thet))  !! tangential wind
  double precision, intent(in) :: undef  !! undefined value
  integer :: ii, jj, ix, jy

  ix=size(radi)
  jy=size(thet)
  projVR=undef
  projVT=undef

!$omp parallel default(shared)
!$omp do schedule(runtime) private(ii,jj)

  do jj=1,jy
     do ii=1,ix
        projVR(ii,jj)=ux*dcos(thet(jj))+vy*dsin(thet(jj))
        projVT(ii,jj)=-ux*dsin(thet(jj))+vy*dcos(thet(jj))
     end do
  end do

!$omp end do
!$omp end parallel

end subroutine proj_rtVs

!--------------------------------------------------
!--------------------------------------------------

subroutine decomp_Vd2rdpn( Vd, thetad, u_decomp, v_decomp, undef )
!! decomposition of VD to the components parallel and normal 
!!  to the direction of thetad = 0
  implicit none
  double precision, intent(in) :: Vd(:,:)  !! Doppler velocity (m/s)
  double precision, intent(in) :: thetad(size(Vd,1),size(Vd,2))  !! azimuthal angle from the line of radar to TC center (rad)
  double precision, intent(out) :: u_decomp(size(Vd,1),size(Vd,2))  !! parallel component 
  double precision, intent(out) :: v_decomp(size(Vd,1),size(Vd,2))  !! normal component
  double precision, intent(in) :: undef  !! undefined value
  integer :: ii, jj, ix, jy

  ix=size(Vd,1)
  jy=size(Vd,2)
  u_decomp=undef
  v_decomp=undef

!$omp parallel default(shared)
!$omp do schedule(runtime) private(ii,jj)

  do jj=1,jy
     do ii=1,ix
        if(Vd(ii,jj)/=undef)then
           u_decomp(ii,jj)=Vd(ii,jj)*dcos(thetad(ii,jj))
           v_decomp(ii,jj)=Vd(ii,jj)*dsin(thetad(ii,jj))
        end if
     end do
  end do

!$omp end do
!$omp end parallel

end subroutine decomp_Vd2rdpn

!--------------------------------------------------
!--------------------------------------------------

integer function check_data_fulfill( val, undef, nt_count, dir, ncount )
!! Check the innermost radius of data with no undef
!! If the innermost radius has not been found, 
!! the value of zero is returned.
  implicit none
  double precision, intent(in) :: val(:,:)  !! original data
  double precision, intent(in) :: undef     !! missing value
  integer, intent(in), optional :: nt_count !! minimum of data gridpoints
                                            !! default = size(val,2)
  character(3), intent(in), optional :: dir !! direction for searching
                                            !! 'i2o': inner to outer radii
                                            !!        (default)
                                            !! 'o2i': outer to inner radii
  integer, intent(out), optional :: ncount  !! available sampling number
  integer :: ifirst, ntc, ntcmax
  integer :: ii, jj, ix, jy, ixs, ixe, ixi
  logical :: i2o_flag

  ix=size(val,1)
  jy=size(val,2)
  ifirst=0

  if(present(nt_count))then
     ntcmax=nt_count
  else
     ntcmax=jy
  end if

  if(present(dir))then
     if(dir(1:3)=="i2o")then
        i2o_flag=.true.
     else if(dir(1:3)=="o2i")then
        i2o_flag=.false.
     else
        write(*,*) "*** ERROR (main:check_data_fulfill) ***: dir is invalid."
        stop
     end if
  else
     i2o_flag=.true.
  end if

  if(i2o_flag.eqv..true.)then  ! inner to outer
     ixs=1
     ixe=ix
     ixi=1
  else  ! outer to inner
     ixs=ix
     ixe=1
     ixi=-1
  end if

  do ii=ixs,ixe,ixi
     ntc=0
     do jj=1,jy
        if(val(ii,jj)/=undef)then
           ntc=ntc+1
        end if
     end do
     if(ntc>=ntcmax)then
        ifirst=ii
        if(present(ncount))then
           ncount=ntc
        end if
        exit
     end if
write(*,*) "ntcheck", ntc, ntcmax
  end do

  check_data_fulfill=ifirst

  return

end function check_data_fulfill

subroutine rearrange_undef_rad( skip_thres, nr_in, nr_out_org, nt, undef_grid,  &
  &                             r_org, rh_org, thetad_org, Vra_org,  &
  &                             nr_out, nn_grid, r, rh, thetad, Vra )
!! rearrange the radial grids:
!! 1. skip radii with few azimuthal sampling (less than "skip_thres")
!! 2. rearrange the radial coordinate.
!! [Note1]: r, rh, thetad, and Vra must be given by the same as
!!          the array number in the original.
!!          (that is, size(r_org) == size(r).)
!! [Note2]: nr_out_org >= nr_out. 
!!          Undef value is given in r, rh, thetad, and Vra outside nr_out. 
  implicit none
  integer, intent(in) :: skip_thres  !! threshold for unused radius
  integer, intent(in) :: nr_in       !! innermost array number in radius
  integer, intent(in) :: nr_out_org  !! outermost array number in radius (orig)
  integer, intent(in) :: nt          !! azimuthal array number
  logical, dimension(nr_in:nr_out_org,1:nt), intent(in) :: undef_grid
                                     !! flag of undefined grid (.true. is undef)
  double precision, dimension(nr_in:nr_out_org), intent(in) :: r_org
                                     !! velocity radius (original) [m]
  double precision, dimension(nr_in:nr_out_org+1), intent(in) :: rh_org
                                     !! potential radius (original) [m]
  double precision, dimension(nr_in:nr_out_org,1:nt), intent(in) :: thetad_org
                                     !! azimuthal angle from radar (original) [rad]
  double precision, dimension(nr_in:nr_out_org,1:nt), intent(in) :: Vra_org
                                     !! Doppler velocity (original) [m/s]
  integer, intent(out) :: nr_out     !! outermost array number in radius (skip)
  integer, dimension(nr_in:nr_out_org), intent(out) :: nn_grid
                                     !! grid number in rearranged each radius
  double precision, dimension(nr_in:nr_out_org), intent(out) :: r
                                     !! velocity radius (skip) [m]
  double precision, dimension(nr_in:nr_out_org+1), intent(out) :: rh
                                     !! potential radius (skip) [m]
  double precision, dimension(nr_in:nr_out_org,1:nt), intent(out) :: thetad
                                     !! azimuthal angle from radar (skip) [rad]
  double precision, dimension(nr_in:nr_out_org,1:nt), intent(out) :: Vra
                                     !! Doppler velocity (skip) [m/s]

  integer :: rcounter, tcounter, ii, jj

  rcounter=nr_in

  r(nr_in)=r_org(nr_in)
  rh(nr_in)=rh_org(nr_in)
  thetad(nr_in,1:nt)=thetad_org(nr_in,1:nt)
  Vra(nr_in,1:nt)=Vra_org(nr_in,1:nt)
  nn_grid=0
  nn_grid(nr_in)=nr_in

  do jj=nr_in+1,nr_out_org
     tcounter=0
     do ii=1,nt
        if(undef_grid(jj,ii).eqv..false.)then
           tcounter=tcounter+1
           if(tcounter>=skip_thres)then
              rcounter=rcounter+1
              nn_grid(rcounter)=jj
              exit
           end if
        end if
     end do

     r(rcounter)=r_org(nn_grid(rcounter))
     thetad(rcounter,1:nt)=thetad_org(nn_grid(rcounter),1:nt)
     Vra(rcounter,1:nt)=Vra_org(nn_grid(rcounter),1:nt)
  end do

  nr_out=rcounter

  do jj=nr_in+1,nr_out
     !-- [Note]: r is rearranged.
     rh(jj)=0.5d0*(r(jj)+r(jj-1))
  end do
  rh(nr_out+1)=rh_org(nn_grid(nr_out)+1)

end subroutine rearrange_undef_rad

!--------------------------------------------------
!--------------------------------------------------

subroutine recover_undef_rad( nrotmin, nrot, ndivmin, ndiv,  &
  &                           nr_in, nr_out, nr_out_org, nt,  &
  &                           undef, undef_grid, nn_grid,  &
  &                           VTtot_rt_t, VRtot_rt_t, VRT0_rt_t, VDR0_rt_t,  &
  &                           VRTn_rt_t, VRRn_rt_t, VDTm_rt_t, VDRm_rt_t,  &
  &                           VRT0_GVTD_rt_t, VDR0_GVTD_rt_t,  &
  &                           VRTns_r, VRTnc_r, VRRns_r, VRRnc_r,  &
  &                           Vn_0_rt_t, phin_rt_t, zetan_rt_t,  &
  &                           zetans_r, zetanc_r )
!! recover the retrieved values from the rearranged to original radii.
  implicit none
  integer, intent(in) :: nrotmin     !! minimum wavenumber for rotational components
  integer, intent(in) :: nrot        !! maximum wavenumber for rotational components
  integer, intent(in) :: ndivmin     !! minimum wavenumber for divergent components
  integer, intent(in) :: ndiv        !! maximum wavenumber for divergent components
  integer, intent(in) :: nr_in       !! innermost array number in radius
  integer, intent(in) :: nr_out      !! outermost array number in radius (skip)
  integer, intent(in) :: nr_out_org  !! outermost array number in radius (orig)
  integer, intent(in) :: nt          !! azimuthal array number
  double precision, intent(in) :: undef  !! undefined value
  logical, dimension(nr_in:nr_out_org,1:nt), intent(in) :: undef_grid
                                     !! flag of undefined grid (.true. is undef)
  integer, dimension(nr_in:nr_out_org), intent(in) :: nn_grid
                                     !! grid number in rearranged each radius
  double precision, dimension(nr_in:nr_out_org,1:nt), intent(inout) :: VTtot_rt_t
  double precision, dimension(nr_in:nr_out_org,1:nt), intent(inout) :: VRtot_rt_t
  double precision, dimension(nr_in:nr_out_org,1:nt), intent(inout) :: VRT0_rt_t
  double precision, dimension(nr_in:nr_out_org,1:nt), intent(inout) :: VDR0_rt_t
  double precision, dimension(nrotmin:nrot,nr_in:nr_out_org,1:nt), intent(inout) :: VRTn_rt_t
  double precision, dimension(nrotmin:nrot,nr_in:nr_out_org,1:nt), intent(inout) :: VRRn_rt_t
  double precision, dimension(ndivmin:ndiv,nr_in:nr_out_org,1:nt), intent(inout) :: VDTm_rt_t
  double precision, dimension(ndivmin:ndiv,nr_in:nr_out_org,1:nt), intent(inout) :: VDRm_rt_t
  double precision, dimension(nr_in:nr_out_org,1:nt), intent(inout) :: VRT0_GVTD_rt_t
  double precision, dimension(nr_in:nr_out_org,1:nt), intent(inout) :: VDR0_GVTD_rt_t
  double precision, dimension(nrotmin:nrot,nr_in:nr_out_org), intent(inout) :: VRTns_r
  double precision, dimension(nrotmin:nrot,nr_in:nr_out_org), intent(inout) :: VRTnc_r
  double precision, dimension(nrotmin:nrot,nr_in:nr_out_org), intent(inout) :: VRRns_r
  double precision, dimension(nrotmin:nrot,nr_in:nr_out_org), intent(inout) :: VRRnc_r
  double precision, dimension(nr_in:nr_out_org,1:nt), intent(inout) :: Vn_0_rt_t
  double precision, dimension(nrotmin:nrot,nr_in:nr_out_org,1:nt), intent(inout) :: phin_rt_t
  double precision, dimension(nrotmin:nrot,nr_in:nr_out_org,1:nt), intent(inout) :: zetan_rt_t
  double precision, dimension(nrotmin:nrot,nr_in:nr_out_org), intent(inout) :: zetans_r
  double precision, dimension(nrotmin:nrot,nr_in:nr_out_org), intent(inout) :: zetanc_r

  integer :: rcounter, tcounter, ii, jj
  double precision, dimension(nr_in:nr_out_org,1:nt) :: VTtot_skp_rt_t, VRtot_skp_rt_t, VRT0_skp_rt_t, VDR0_skp_rt_t, VRT0_GVTD_skp_rt_t, VDR0_GVTD_skp_rt_t, Vn_0_skp_rt_t
  double precision, dimension(nrotmin:nrot,nr_in:nr_out_org,1:nt) :: VRTn_skp_rt_t, VRRn_skp_rt_t
  double precision, dimension(nrotmin:nrot,nr_in:nr_out_org) :: VRTns_skp_r, VRTnc_skp_r, VRRns_skp_r, VRRnc_skp_r
  double precision, dimension(nrotmin:nrot,nr_in:nr_out_org,1:nt) :: phin_skp_rt_t, zetan_skp_rt_t
  double precision, dimension(nrotmin:nrot,nr_in:nr_out_org) :: zetans_skp_r, zetanc_skp_r
  double precision, dimension(ndivmin:ndiv,nr_in:nr_out_org,1:nt) :: VDTm_skp_rt_t, VDRm_skp_rt_t

  VTtot_skp_rt_t(nr_in:nr_out_org,1:nt)=VTtot_rt_t(nr_in:nr_out_org,1:nt)
  VRtot_skp_rt_t(nr_in:nr_out_org,1:nt)=VRtot_rt_t(nr_in:nr_out_org,1:nt)
  VRT0_skp_rt_t(nr_in:nr_out_org,1:nt)=VRT0_rt_t(nr_in:nr_out_org,1:nt)
  VDR0_skp_rt_t(nr_in:nr_out_org,1:nt)=VDR0_rt_t(nr_in:nr_out_org,1:nt)
  VRTn_skp_rt_t(nrotmin:nrot,nr_in:nr_out_org,1:nt)=VRTn_rt_t(nrotmin:nrot,nr_in:nr_out_org,1:nt)
  VRRn_skp_rt_t(nrotmin:nrot,nr_in:nr_out_org,1:nt)=VRRn_rt_t(nrotmin:nrot,nr_in:nr_out_org,1:nt)
  VDTm_skp_rt_t(ndivmin:ndiv,nr_in:nr_out_org,1:nt)=VDTm_rt_t(ndivmin:ndiv,nr_in:nr_out_org,1:nt)
  VDRm_skp_rt_t(ndivmin:ndiv,nr_in:nr_out_org,1:nt)=VDRm_rt_t(ndivmin:ndiv,nr_in:nr_out_org,1:nt)
  VRT0_GVTD_skp_rt_t(nr_in:nr_out_org,1:nt)=VRT0_GVTD_rt_t(nr_in:nr_out_org,1:nt)
  VDR0_GVTD_skp_rt_t(nr_in:nr_out_org,1:nt)=VDR0_GVTD_rt_t(nr_in:nr_out_org,1:nt)
  VRTns_skp_r(nrotmin:nrot,nr_in:nr_out_org)=VRTns_r(nrotmin:nrot,nr_in:nr_out_org)
  VRTnc_skp_r(nrotmin:nrot,nr_in:nr_out_org)=VRTnc_r(nrotmin:nrot,nr_in:nr_out_org)
  VRRns_skp_r(nrotmin:nrot,nr_in:nr_out_org)=VRRns_r(nrotmin:nrot,nr_in:nr_out_org)
  VRRnc_skp_r(nrotmin:nrot,nr_in:nr_out_org)=VRRnc_r(nrotmin:nrot,nr_in:nr_out_org)
  Vn_0_skp_rt_t(nr_in:nr_out_org,1:nt)=Vn_0_rt_t(nr_in:nr_out_org,1:nt)
  phin_skp_rt_t(nrotmin:nrot,nr_in:nr_out_org,1:nt)=phin_rt_t(nrotmin:nrot,nr_in:nr_out_org,1:nt)
  zetan_skp_rt_t(nrotmin:nrot,nr_in:nr_out_org,1:nt)=zetan_rt_t(nrotmin:nrot,nr_in:nr_out_org,1:nt)
  zetans_skp_r(nrotmin:nrot,nr_in:nr_out_org)=zetans_r(nrotmin:nrot,nr_in:nr_out_org)
  zetanc_skp_r(nrotmin:nrot,nr_in:nr_out_org)=zetanc_r(nrotmin:nrot,nr_in:nr_out_org)

  VTtot_rt_t(nr_in:nr_out_org,1:nt)=undef
  VRtot_rt_t(nr_in:nr_out_org,1:nt)=undef
  VRT0_rt_t(nr_in:nr_out_org,1:nt)=undef
  VDR0_rt_t(nr_in:nr_out_org,1:nt)=undef
  VRTn_rt_t(nrotmin:nrot,nr_in:nr_out_org,1:nt)=undef
  VRRn_rt_t(nrotmin:nrot,nr_in:nr_out_org,1:nt)=undef
  VDTm_rt_t(ndivmin:ndiv,nr_in:nr_out_org,1:nt)=undef
  VDRm_rt_t(ndivmin:ndiv,nr_in:nr_out_org,1:nt)=undef
  VRT0_GVTD_rt_t(nr_in:nr_out_org,1:nt)=undef
  VDR0_GVTD_rt_t(nr_in:nr_out_org,1:nt)=undef
  VRTns_r(nrotmin:nrot,nr_in:nr_out_org)=undef
  VRTnc_r(nrotmin:nrot,nr_in:nr_out_org)=undef
  VRRns_r(nrotmin:nrot,nr_in:nr_out_org)=undef
  VRRnc_r(nrotmin:nrot,nr_in:nr_out_org)=undef
  Vn_0_rt_t(nr_in:nr_out_org,1:nt)=undef
  phin_rt_t(nrotmin:nrot,nr_in:nr_out_org,1:nt)=undef
  zetan_rt_t(nrotmin:nrot,nr_in:nr_out_org,1:nt)=undef
  zetans_r(nrotmin:nrot,nr_in:nr_out_org)=undef
  zetanc_r(nrotmin:nrot,nr_in:nr_out_org)=undef

  do jj=nr_out,nr_in,-1
     VRT0_rt_t(nn_grid(jj),1:nt)=VRT0_skp_rt_t(jj,1:nt)
     VDR0_rt_t(nn_grid(jj),1:nt)=VDR0_skp_rt_t(jj,1:nt)
     VRT0_GVTD_rt_t(nn_grid(jj),1:nt)=VRT0_GVTD_skp_rt_t(jj,1:nt)
     VDR0_GVTD_rt_t(nn_grid(jj),1:nt)=VDR0_GVTD_skp_rt_t(jj,1:nt)
     do ii=1,nt
        if(undef_grid(nn_grid(jj),ii).eqv..false.)then
           VTtot_rt_t(nn_grid(jj),ii)=VTtot_skp_rt_t(jj,ii)
           VRtot_rt_t(nn_grid(jj),ii)=VRtot_skp_rt_t(jj,ii)
        end if
     end do
  end do

  if(nrotmin==1)then
     do jj=nr_out,nr_in,-1
        do ii=1,nt
           if(undef_grid(nn_grid(jj),ii).eqv..false.)then
              VRTn_rt_t(nrotmin:nrot,nn_grid(jj),ii)=VRTn_skp_rt_t(nrotmin:nrot,jj,ii)
              VRRn_rt_t(nrotmin:nrot,nn_grid(jj),ii)=VRRn_skp_rt_t(nrotmin:nrot,jj,ii)
           end if
        end do
        VRTns_r(nrotmin:nrot,nn_grid(jj))=VRTns_skp_r(nrotmin:nrot,jj)
        VRTnc_r(nrotmin:nrot,nn_grid(jj))=VRTnc_skp_r(nrotmin:nrot,jj)
        VRRns_r(nrotmin:nrot,nn_grid(jj))=VRRns_skp_r(nrotmin:nrot,jj)
        VRRnc_r(nrotmin:nrot,nn_grid(jj))=VRRnc_skp_r(nrotmin:nrot,jj)
        Vn_0_rt_t(nn_grid(jj),1:nt)=Vn_0_skp_rt_t(jj,1:nt)
        phin_rt_t(nrotmin:nrot,nn_grid(jj),1:nt)=phin_skp_rt_t(nrotmin:nrot,jj,1:nt)
        zetan_rt_t(nrotmin:nrot,nn_grid(jj),1:nt)=zetan_skp_rt_t(nrotmin:nrot,jj,1:nt)
        zetans_r(nrotmin:nrot,nn_grid(jj))=zetans_skp_r(nrotmin:nrot,jj)
        zetanc_r(nrotmin:nrot,nn_grid(jj))=zetanc_skp_r(nrotmin:nrot,jj)
     end do
  end if

  if(ndivmin==1)then
     do jj=nr_out,nr_in,-1
        do ii=1,nt
           if(undef_grid(nn_grid(jj),ii).eqv..false.)then
              VDTm_rt_t(ndivmin:ndiv,nn_grid(jj),ii)=VDTm_skp_rt_t(ndivmin:ndiv,jj,ii)
              VDRm_rt_t(ndivmin:ndiv,nn_grid(jj),ii)=VDRm_skp_rt_t(ndivmin:ndiv,jj,ii)
           end if
        end do
     end do
  end if

end subroutine recover_undef_rad

!--------------------------------------------------
!--------------------------------------------------

subroutine check_undef_grid( vval, undefv, undeflag )
!! check missing grids
  implicit none
  double precision, intent(in) :: vval(:,:)  !! input data
  double precision, intent(in) :: undefv  !! undefined value
  logical, intent(out) :: undeflag(size(vval,1),size(vval,2))  !! undefined flag (.true.)
  integer :: ii, jj, nni, nnj

  nni=size(vval,1)
  nnj=size(vval,2)
  undeflag=.false.

  do jj=1,nnj
     do ii=1,nni
        if(vval(ii,jj)==undefv)then
           undeflag(ii,jj)=.true.
        end if
     end do
  end do

end subroutine check_undef_grid

!--------------------------------------------------
!--------------------------------------------------

integer function inner_radius_check( nrin, nrout, radi )
!! Check positive value of the innermost radius. 
!! If the innermost radius is negative, 
!! the element number located at the innermost positive radius is returned.
  implicit none
  integer, intent(in) :: nrin     !! A given element of the innermost radius
  integer, intent(in) :: nrout    !! A given element of the outermost radius
  double precision, intent(in) :: radi(nrin:nrout)   !! Original radial grids
  integer :: ii

  if(radi(nrin)<=0.0d0)then
     do ii=nrin+1,nrout
        if(radi(ii)>0.0d0)then
           inner_radius_check=ii
           exit
        end if
     end do
  else
     inner_radius_check=nrin
  end if

  return

end function inner_radius_check

!--------------------------------------------------
! 
!--------------------------------------------------

end module tools_sub