Skip to content
Snippets Groups Projects
Commit 0e1f9399 authored by Lionel GUEZ's avatar Lionel GUEZ
Browse files

Keep the good contours

Keep the good contours found when looking for the outermost contour,
subject to a maximum of `n_max_cont` contours. The idea is to use them
later when looking for the maximum-speed contour. Inside function
`get_1_outerm`, we temporarily store the good contours in a local
explicit-shape array, `cont_list`.
parent cf540bfd
No related branches found
No related tags found
No related merge requests found
...@@ -9,10 +9,20 @@ contains ...@@ -9,10 +9,20 @@ contains
! This procedure gets one outermost contour, if it can find ! This procedure gets one outermost contour, if it can find
! one. If the procedure cannot find an outermost contour, it ! one. If the procedure cannot find an outermost contour, it
! returns a null ssh_contour. An outermost contour is not found ! returns a null ssh_contour. The procedure also finds some inner
! if, and only if, there is no good contour at innermost level. If ! contours. The number of contours stored, including the outermost
! a contour is found then its level is farther from the extremum ! contour, is lower than or equal to n_max_cont. If we find more
! than innermost level. ! than n_max_cont -1 good contours excluding the outermost
! contour, then we store only the first n_max_cont -1 found,
! because they provide a better sample of the ssh range. If the
! procedure cannot find an outermost contour, it does not store
! inner contours. An outermost contour is not found if, and only
! if, there is no good contour at innermost level. If an outermost
! contour is found then its level is farther from the extremum
! than innermost level. In the array of stored contours, the
! contours are in monotonic order of ssh: ascending if the
! extremum is a minimum, descending if the extremum is a
! maximum. The area is only computed for the outermost contour.
! Method: dichotomy on level of ssh. ! Method: dichotomy on level of ssh.
...@@ -29,7 +39,7 @@ contains ...@@ -29,7 +39,7 @@ contains
use jumble, only: assert use jumble, only: assert
use ccw_orient_m, only: ccw_orient use ccw_orient_m, only: ccw_orient
use derived_types, only: ssh_contour, missing_ssh use derived_types, only: ssh_contour, null_ssh_contour
use good_contour_m, only: good_contour use good_contour_m, only: good_contour
use spher_polyline_area_m, only: spher_polyline_area use spher_polyline_area_m, only: spher_polyline_area
...@@ -55,60 +65,74 @@ contains ...@@ -55,60 +65,74 @@ contains
! Local: ! Local:
real level_try, level_good, level_bad ! in m real level_try, level_good, level_bad ! in m
type(polyline) tentative_contour
real, parameter:: precision = 5e-4 ! in m real, parameter:: precision = 5e-4 ! in m
logical mask(size(ssh, 1), size(ssh, 2)) logical mask(size(ssh, 1), size(ssh, 2))
integer, parameter:: n_max_cont = 31
type(ssh_contour) cont_list(n_max_cont + 1)
! Contour list. The outermost contour is element n_cont. The
! contours are in monotonic order of ssh.
integer n_cont ! number of good contours found and stored
!----------------------------------------------------------------- !-----------------------------------------------------------------
get_1_outerm%polyline = good_contour(corner, step, ssh, innermost_level_2, & n_cont = 0
cont_list(1)%polyline = good_contour(corner, step, ssh, innermost_level_2, &
coord_extr, outside_points) coord_extr, outside_points)
if (get_1_outerm%n_points == 0) then if (cont_list(1)%n_points == 0) then
! null ssh contour get_1_outerm = null_ssh_contour()
get_1_outerm%ssh = missing_ssh
get_1_outerm%area = - 1e6
else else
n_cont = 1
cont_list(1)%ssh = innermost_level_2
level_good = innermost_level_2 level_good = innermost_level_2
mask = ssh /= huge(0.) mask = ssh /= huge(0.)
level_try = merge(maxval(ssh, mask), minval(ssh, mask), cyclone) level_try = merge(maxval(ssh, mask), minval(ssh, mask), cyclone)
call assert(merge(level_try > level_good, level_try < level_good, & call assert(merge(level_try > level_good, level_try < level_good, &
cyclone), "get_1_outerm level_try") cyclone), "get_1_outerm level_try")
tentative_contour = good_contour(corner, step, ssh, level_try, & cont_list(2)%polyline = good_contour(corner, step, ssh, level_try, &
coord_extr, outside_points) coord_extr, outside_points)
if (tentative_contour%n_points /= 0) then if (cont_list(2)%n_points /= 0) then
! This can only happen if there are degenerate extrema ! This can only happen if there are degenerate extrema
! everywhere around the path of contour. So it should ! everywhere around the path of contour. So it should
! probably never happen. ! probably never happen.
get_1_outerm%polyline = tentative_contour n_cont = 2
get_1_outerm%ssh = level_try cont_list(2)%ssh = level_try
else else
! Assertion: {no good contour at maxval or minval} ! Assertion: {no good contour at maxval or minval}
level_bad = level_try level_bad = level_try
do while (abs(level_bad - level_good) > precision) do while (abs(level_bad - level_good) > precision)
level_try = (level_good + level_bad) / 2. level_try = (level_good + level_bad) / 2.
tentative_contour = good_contour(corner, step, ssh, level_try, & cont_list(n_cont + 1)%polyline = good_contour(corner, step, ssh, &
coord_extr, outside_points) level_try, coord_extr, outside_points)
if (cont_list(n_cont + 1)%n_points /= 0) then
cont_list(n_cont + 1)%ssh = level_try
if (n_cont == n_max_cont) then
! Replace the previous good contour found
cont_list(n_cont) = cont_list(n_cont + 1)
else
n_cont = n_cont + 1
end if
if (tentative_contour%n_points /= 0) then
level_good = level_try level_good = level_try
get_1_outerm%polyline = tentative_contour
else else
level_bad = level_try level_bad = level_try
end if end if
! Assertion: get_1_outerm%polyline == good_contour(. . ., ! Assertion: cont_list(n_cont)%polyline == good_contour(. . .,
! level_good) and get_1_outerm%%n_points /= 0 and ! level_good) and cont_list(n_cont)%%n_points /= 0 and
! no good contour at level_bad ! no good contour at level_bad
end do end do
get_1_outerm%ssh = level_good
end if end if
get_1_outerm%area = spher_polyline_area(get_1_outerm%polyline) cont_list(n_cont)%area = spher_polyline_area(cont_list(n_cont)%polyline)
call ccw_orient(get_1_outerm) call ccw_orient(cont_list(n_cont))
get_1_outerm = cont_list(n_cont)
end if end if
end function get_1_outerm end function get_1_outerm
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment