123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- ! Bilinear coeffisients are calculated witin this program for all the
- ! observation points.
- ! Only wet points are stored in the observation.uf file
- module m_get_def_wet_point
- implicit none
- integer, parameter, private :: STRLEN = 512
- character(STRLEN), parameter, private :: MEANSSHFNAME = "meanssh.uf"
-
- private read_mean_ssh
- private land_nearby
- contains
- subroutine get_def_wet_point(obs, data, gr, depths, modlat, modlon, nrobs, nx, ny)
- ! Program converts to a general format readable by ENKF (observations.uf)
- use mod_measurement
- use mod_grid
- ! Functions to be used
- use m_oldtonew
- use m_bilincoeff
- use m_pivotp
- use m_confmap
- use m_spherdist
- integer, intent(in) :: nx, ny
- type (measurement), intent(in) :: data(:)
- type (measurement), intent(inout) :: obs(:)
- type (grid), intent(in) :: gr ! observations grid
- real, dimension(nx, ny), intent(in) :: depths, modlat, modlon
- integer, intent(out) :: nrobs
- integer, parameter :: maxobs = 1441 * 722 !2*400*600 ! maximum number of observations
- real, dimension(nx, ny) :: mean_ssh
- integer k, imin, imax, jmin, jmax
- integer ipiv, jpiv, nsupport, nsmin, nsmax
- real :: x0, y0
- real wetsill, griddiag, mingridsize, minobssize
- logical wet
- ! gr = default_grid
- nrobs = 0;
- nsmin = maxobs;
- nsmax = 0
- mingridsize = 1.E+10;
- minobssize = 1.E+10 ! in meters
- call confmap_init(nx,ny) ! Initialize conformal mapping before calling
- !Calculate pivot points
- !Find wet points (all neigbours in water)
- !Find the points with defined data value
- !Put the data into the obs data structture
- !Compute bilinear coefficients
- call read_mean_ssh(mean_ssh, nx, ny)
- do k = 1, gridpoints(gr)
- if (data(k) % id .eq. 'SLA' .or. data(k) % id .eq. 'sla' .or. &
- data(k) % id.eq. 'SSH' .or. data(k)%id .eq. 'ssh' .or.&
- data(k)%id.eq.'TSLA') then
- wetsill = 200. ! Discarding data in shallow waters
- else
- wetsill=10.
- endif
- call oldtonew(data(k) % lat, data(k) % lon, y0, x0)
- call pivotp(x0, y0, ipiv, jpiv)
- ! Discard obs on model boundaries (TODO: cyclic domains)
- ! Also valid if ns=0
- imin = ipiv - data(k) % ns
- imax = ipiv + data(k) % ns + 1
- jmin = jpiv - data(k) % ns
- jmax = jpiv + data(k) % ns + 1
- if ((imin .le. 0) .or. (jmin .le. 0) .or. (imax .ge. nx) .or. &
- (jmax .ge. ny)) cycle
- ! Is observation surrounded by wet grid points?
- if (any(depths(imin:imax, jmin:jmax) < wetsill .or. depths(imin:imax, jmin:jmax) == depths(imin:imax, jmin:jmax) + 1.0)) cycle
- wet = data(k) % status ! Discards inconsistent/Fill values
- if (data(k) % id .eq. 'SLA' .or. data(k) % id .eq. 'sla' .or.&
- data(k) % id .eq. 'TSLA') then
- wet = wet .and. (mean_ssh(ipiv, jpiv) < 990)
- wet = wet .and. .not. land_nearby(nx, ny, mean_ssh, modlon, modlat,&
- ipiv, jpiv, data(k) % lon, data(k) % lat)
- endif
- if(.not. undefined(data(k) % d, gr) .and. wet) then
- nrobs = nrobs + 1
- obs(nrobs) = data(k)
- obs(nrobs) % ipiv = ipiv
- obs(nrobs) % jpiv= jpiv
- obs(nrobs) % status = .true. ! Wet obs
- if (data(k) % ns > 0) then ! large support data: a1 is the obs support(m)
- griddiag = spherdist(modlon(ipiv, jpiv), modlat(ipiv, jpiv), &
- modlon(ipiv + 1, jpiv + 1), modlat(ipiv + 1, jpiv + 1))
- !FC: 0.5 because m_Generate_element_Si runs from -ns to +ns
- nsupport = floor(0.5 * data(k) % a1 / griddiag) ! both in meters
- obs(nrobs)%ns = nsupport ! number of grid cells in the diagonal
- nsmin = min(nsmin, nsupport)
- nsmax = max(nsmax, nsupport)
- mingridsize = min(mingridsize, griddiag)
- minobssize = min(minobssize, data(k) % a1)
- else
- obs(nrobs) % ns = 0 ! point measurements have zero support
- endif
- call bilincoeff(modlon, modlat, nx, ny, obs(nrobs)%lon, &
- obs(nrobs) % lat, obs(nrobs) % ipiv, obs(nrobs) % jpiv, &
- obs(nrobs) % a1, obs(nrobs) % a2, obs(nrobs) % a3, &
- obs(nrobs) % a4)
- endif
- end do
- print*, 'Number of defined and wet observations: nrobs ', nrobs
- print*, 'Support (in nb of cells) between: ', nsmin, ' and ', nsmax
- print '(2(a,f8.3),a)', ' Minimum obs support: ', 0.001 * minobssize, &
- 'km, min grid diagonal: ', 0.001 * mingridsize, ' km'
- end subroutine get_def_wet_point
- subroutine read_mean_ssh(mean_ssh, nx, ny)
- integer, intent(in) :: nx, ny
- real, intent(out):: mean_ssh(nx, ny)
- logical :: exists
- inquire(file = trim(MEANSSHFNAME), exist = exists)
- if (.not. exists) then
- print *,'ERROR: read_mean_ssh(): file "', trim(MEANSSHFNAME), '" not found'
- stop
- end if
-
- open (10, file = trim(MEANSSHFNAME), status = 'unknown',form = 'unformatted')
- read (10) mean_ssh
- close (10)
- end subroutine read_mean_ssh
- logical function land_nearby(nx, ny, mean_ssh, modlon, modlat, ipiv, jpiv, obslon, obslat)
- use m_spherdist
- implicit none
- real, parameter :: Dis0 = 50.0d0
- integer, intent (in) :: nx, ny, ipiv, jpiv
- real, dimension(nx,ny), intent(in) :: mean_ssh, modlon, modlat
- real, intent (in) :: obslon,obslat
- integer :: ii, jj, ncells
- real :: griddist
- land_nearby = .false.
- ncells = ceiling(Dis0 / spherdist(modlon(ipiv, jpiv), modlat(ipiv, jpiv),&
- modlon(ipiv, jpiv + 1), modlat(ipiv, jpiv + 1)))
- do jj = max(jpiv - ncells, 1), min(jpiv + ncells, ny)
- do ii = max(ipiv - ncells, 1), min(ipiv + ncells, nx)
- griddist = spherdist(modlon(ii, jj), modlat(ii, jj), obslon, obslat)
- if (mean_ssh(ipiv,jpiv) < 990 .and. griddist < Dis0) then
- land_nearby = .true.
- return
- end if
- enddo
- enddo
- end function land_nearby
- end module m_get_def_wet_point
|