From a33ecf3eda9dc116e0b0cd802a27ce22ebb43363 Mon Sep 17 00:00:00 2001
From: Lionel GUEZ <guez@lmd.ens.fr>
Date: Thu, 17 May 2018 16:32:24 +0200
Subject: [PATCH] Add procedure successive_overlap and corresponding test. The
 libraries GPC_F and GPC must be used.

---
 GNUmakefile                            | 10 +++-
 Tests/Stdin/successive_overlap_nml.txt |  5 ++
 Tests/read_snapshot.f                  | 10 +++-
 Tests/test_successive_overlap.f        | 57 ++++++++++++++++++
 Tests/tests.json                       | 36 ++++++++++++
 depend.mk                              |  2 +
 derived_types.f                        | 12 ++--
 successive_overlap.f                   | 81 ++++++++++++++++++++++++++
 8 files changed, 202 insertions(+), 11 deletions(-)
 create mode 100644 Tests/Stdin/successive_overlap_nml.txt
 create mode 100644 Tests/test_successive_overlap.f
 create mode 100644 successive_overlap.f

diff --git a/GNUmakefile b/GNUmakefile
index 2c198fef..5aae2083 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -23,9 +23,11 @@ src_test_read_eddy = test_read_eddy.f derived_types.f init_shapefiles.f read_edd
 
 src_test_read_snapshot = test_read_snapshot.f derived_types.f dispatch_snapshot.f init_shapefiles.f read_snapshot.f write_eddy.f send_snapshot.f read_eddy.f
 
-sources := $(sort ${src_test_local_extrema} ${src_test_get_1_outerm} ${src_test_set_max_speed} ${src_test_get_snapshot} ${src_test_set_all_outerm} ${src_test_weight} ${src_test_spherical_polygon_area} ${src_test_read_eddy} ${src_test_read_snapshot}) test_good_contour.f test_inside_4.f test_max_speed_contour_ssh.f test_mean_speed.f test_spherical_polyline_area.f
+src_test_successive_overlap = test_successive_overlap.f derived_types.f successive_overlap.f read_snapshot.f spherical_polygon_area.f spherical_polyline_area.f weight.f read_eddy.f
 
-lib_list = GPC_F contour_531 numer_rec_95 shapelib_03 netcdf95 geometry jumble netcdff fortrangis shp fortranc nr_util
+sources := $(sort ${src_test_local_extrema} ${src_test_get_1_outerm} ${src_test_set_max_speed} ${src_test_get_snapshot} ${src_test_set_all_outerm} ${src_test_weight} ${src_test_spherical_polygon_area} ${src_test_read_eddy} ${src_test_read_snapshot} ${src_test_successive_overlap}) test_good_contour.f test_inside_4.f test_max_speed_contour_ssh.f test_mean_speed.f test_spherical_polyline_area.f
+
+lib_list = GPC_F contour_531 numer_rec_95 GPC shapelib_03 netcdf95 geometry jumble netcdff fortrangis shp fortranc nr_util
 
 # 2. Objects and executable files
 
@@ -38,10 +40,11 @@ obj_test_weight := $(src_test_weight:.f=.o)
 obj_test_spherical_polygon_area := $(src_test_spherical_polygon_area:.f=.o)
 obj_test_read_eddy := $(src_test_read_eddy:.f=.o)
 obj_test_read_snapshot := $(src_test_read_snapshot:.f=.o)
+obj_test_successive_overlap := $(src_test_successive_overlap:.f=.o)
 
 objects := $(sources:.f=.o)
 
-execut = test_good_contour test_inside_4 test_get_1_outerm test_local_extrema test_max_speed_contour_ssh test_mean_speed test_set_max_speed test_get_snapshot test_set_all_outerm test_weight test_spherical_polyline_area test_spherical_polygon_area test_read_eddy test_read_snapshot
+execut = test_good_contour test_inside_4 test_get_1_outerm test_local_extrema test_max_speed_contour_ssh test_mean_speed test_set_max_speed test_get_snapshot test_set_all_outerm test_weight test_spherical_polyline_area test_spherical_polygon_area test_read_eddy test_read_snapshot test_successive_overlap
 
 # 3. Compiler-dependent part
 
@@ -80,6 +83,7 @@ test_spherical_polyline_area: spherical_polyline_area.o
 test_spherical_polygon_area: ${obj_test_spherical_polygon_area}
 test_read_eddy: ${obj_test_read_eddy}
 test_read_snapshot: ${obj_test_read_snapshot}
+test_successive_overlap: ${obj_test_successive_overlap}
 
 depend ${makefile_dir}/depend.mk:
 	makedepf90 -free -Wmissing -Wconfused $(addprefix -I, ${VPATH}) -nosrc $(addprefix -u , ${lib_list} shapelib netcdf intrinsic) ${sources} >${makefile_dir}/depend.mk
diff --git a/Tests/Stdin/successive_overlap_nml.txt b/Tests/Stdin/successive_overlap_nml.txt
new file mode 100644
index 00000000..f4f7c4fe
--- /dev/null
+++ b/Tests/Stdin/successive_overlap_nml.txt
@@ -0,0 +1,5 @@
+ &MAIN_NML
+ CORNER  = 16.12500       , -38.87500      ,
+ NLON    = 20,
+ NLAT    = 20
+ /
diff --git a/Tests/read_snapshot.f b/Tests/read_snapshot.f
index dfee0586..3ac2cd43 100644
--- a/Tests/read_snapshot.f
+++ b/Tests/read_snapshot.f
@@ -11,7 +11,7 @@ contains
 
     use contour_531, only: convert_to_ind
     use derived_types, only: snapshot, eddy
-    use nr_util, only: pi, assert, deg_to_rad
+    use nr_util, only: assert, deg_to_rad
     use read_eddy_m, only: read_eddy
     use shapelib, only: shpfileobject, shpgetinfo
 
@@ -30,7 +30,13 @@ contains
     integer, intent(in):: nlon, nlat
 
     ! Local:
-    integer ishape, k, i
+    integer ishape
+
+    integer k
+    ! Date index, not used. We could check that it has the same value
+    ! for all input shapes.
+
+    integer i ! eddy index
     integer shapetype, dbffieldcount, dbfrecordcount
     real(c_double) minbound(4), maxbound(4)
     type(eddy) e
diff --git a/Tests/test_successive_overlap.f b/Tests/test_successive_overlap.f
new file mode 100644
index 00000000..e30e359f
--- /dev/null
+++ b/Tests/test_successive_overlap.f
@@ -0,0 +1,57 @@
+program test_successive_overlap
+
+  use, intrinsic:: ISO_FORTRAN_ENV
+
+  use derived_types, only: snapshot
+  use jumble, only: new_unit
+  use nr_util, only: deg_to_rad
+  use read_snapshot_m, only: read_snapshot
+  use shapelib, only: shpfileobject, shpclose
+  use shapelib_03, only: shp_open_03
+  use successive_overlap_m, only: successive_overlap
+
+  implicit none
+
+  integer unit_graph, i
+  type(snapshot) flow(2)
+  TYPE(shpfileobject) hshp_extremum ! shapefile extremum_1
+  TYPE(shpfileobject) hshp_outermost ! shapefile outermost_contour_1
+  TYPE(shpfileobject) hshp_max_speed ! shapefile max_speed_contour_1
+
+  real:: corner(2) = [0.125, - 59.875]
+  ! longitude and latitude of the corner of the whole grid, in degrees
+
+  integer:: nlon = 120, nlat = 120
+  namelist /main_nml/ corner, nlon, nlat
+
+  !-------------------------------------------------------------------------
+
+  write(unit = error_unit, nml = main_nml)
+  write(unit = error_unit, fmt = *) "Enter namelist main_nml."
+  read(unit = *, nml = main_nml)
+  write(unit = *, nml = main_nml)
+
+  call shp_open_03("extremum_1", pszaccess = "rb", hshp = hshp_extremum)
+  call shp_open_03("outermost_contour_1", pszaccess = "rb", &
+       hshp = hshp_outermost)
+  call shp_open_03("max_speed_contour_1", pszaccess = "rb", &
+       hshp = hshp_max_speed)
+  call read_snapshot(flow(1), hshp_extremum, hshp_outermost, hshp_max_speed, &
+       corner * deg_to_rad, nlon, nlat)
+  CALL shpclose(hshp_extremum)
+  CALL shpclose(hshp_outermost)
+  CALL shpclose(hshp_max_speed)
+
+  flow(2) = flow(1)
+  call new_unit(unit_graph)
+  open(unit_graph, file = "graph_1.txt", status = "replace", action  = "write")
+  call successive_overlap(unit_graph, nlon, nlat, flow, j = 2, k = 2)
+  close(unit_graph)
+  print *, 'Created file "graph_1.txt".'
+
+  do i = 1, 2
+     print *, "flow(", i, ")%list_vis%delta_in:", flow(i)%list_vis%delta_in
+     print *, "flow(", i, ")%list_vis%delta_out:", flow(i)%list_vis%delta_out
+  end do
+
+end program test_successive_overlap
diff --git a/Tests/tests.json b/Tests/tests.json
index 792bf929..3cbc520e 100644
--- a/Tests/tests.json
+++ b/Tests/tests.json
@@ -219,5 +219,41 @@
 		  "$input_dir/2006_01/h_region_4.nc"],
 	"title" : "Local_extrema_missing",
 	"description": "test_local_extrema with input file containing missing values."
+    },
+    {
+	"args" : "$compil_prod_dir/test_successive_overlap",
+	"title" : "Successive_overlap",
+	"description": "Overlap of a snapshot with itself.",
+	"required":
+	[
+	    ["$input_dir/Test_read_eddy/extremum_1_old.dbf", "extremum_1.dbf"],
+	    ["$input_dir/Test_read_eddy/extremum_1_old.shp", "extremum_1.shp"],
+	    ["$input_dir/Test_read_eddy/extremum_1_old.shx", "extremum_1.shx"],
+	    [
+		"$input_dir/Test_read_eddy/max_speed_contour_1_old.dbf",
+		"max_speed_contour_1.dbf"
+	    ],
+	    [
+		"$input_dir/Test_read_eddy/max_speed_contour_1_old.shp",
+		"max_speed_contour_1.shp"
+	    ],
+	    [
+		"$input_dir/Test_read_eddy/max_speed_contour_1_old.shx",
+		"max_speed_contour_1.shx"
+	    ],
+	    [
+		"$input_dir/Test_read_eddy/outermost_contour_1_old.dbf",
+		"outermost_contour_1.dbf"
+	    ],
+	    [
+		"$input_dir/Test_read_eddy/outermost_contour_1_old.shp",
+		"outermost_contour_1.shp"
+	    ],
+	    [
+		"$input_dir/Test_read_eddy/outermost_contour_1_old.shx",
+		"outermost_contour_1.shx"
+	    ]
+	],
+	"stdin": "$stdin_dir/successive_overlap_nml.txt"
     }
 ]
diff --git a/depend.mk b/depend.mk
index 93ccfd2b..5fefc99a 100644
--- a/depend.mk
+++ b/depend.mk
@@ -8,6 +8,7 @@ send_snapshot.o : derived_types.o
 set_all_outerm.o : local_extrema.o get_1_outerm.o derived_types.o 
 set_max_speed.o : spherical_polyline_area.o mean_speed.o max_speed_contour_ssh.o inside_4.o good_contour.o derived_types.o 
 spherical_polygon_area.o : spherical_polyline_area.o 
+successive_overlap.o : weight.o spherical_polyline_area.o spherical_polygon_area.o derived_types.o 
 test_get_1_outerm.o : get_1_outerm.o derived_types.o 
 test_get_snapshot.o : init_shapefiles.o get_snapshot.o dispatch_snapshot.o derived_types.o 
 test_local_extrema.o : local_extrema.o 
@@ -16,6 +17,7 @@ test_read_snapshot.o : read_snapshot.o init_shapefiles.o dispatch_snapshot.o der
 test_set_all_outerm.o : set_all_outerm.o derived_types.o 
 test_set_max_speed.o : set_max_speed.o derived_types.o 
 test_spherical_polygon_area.o : spherical_polygon_area.o 
+test_successive_overlap.o : successive_overlap.o read_snapshot.o derived_types.o 
 test_weight.o : weight.o derived_types.o 
 weight.o : derived_types.o 
 write_eddy.o : init_shapefiles.o derived_types.o 
diff --git a/derived_types.f b/derived_types.f
index e5508d12..ae85197c 100644
--- a/derived_types.f
+++ b/derived_types.f
@@ -45,12 +45,12 @@ module derived_types
      
      integer number_vis_eddies ! number of visible eddies
 
-     integer, allocatable:: extr_map(:, :) ! (nlon, nlat) At a point
-     ! of extremum SSH with out_cont found, of sufficient amplitude:
-     ! identification number or this extremum. At a point of extremum
-     ! SSH with no out_cont or out_cont of insufficient amplitude: the
-     ! opposite of the identification number or this extremum. 0 at
-     ! other points.
+     integer, allocatable:: extr_map(:, :) ! (nlon, nlat)
+     ! At a point of extremum SSH with out_cont found, of sufficient
+     ! amplitude: identification number or this extremum. At a point
+     ! of extremum SSH with no out_cont or out_cont of insufficient
+     ! amplitude: the opposite of the identification number or this
+     ! extremum. 0 at other points.
 
      integer, allocatable:: ind_extr(:, :) ! (2, number_vis_eddies)
      ! indices in the global grid of ssh extrema
diff --git a/successive_overlap.f b/successive_overlap.f
new file mode 100644
index 00000000..78c1f44d
--- /dev/null
+++ b/successive_overlap.f
@@ -0,0 +1,81 @@
+module successive_overlap_m
+
+  implicit none
+
+contains
+
+  subroutine successive_overlap(unit_graph, nlon, nlat, flow, j, k)
+
+    ! Finds edges between flow(j - 1) and flow(j), corresponding to
+    ! dates k - 1 and k. Writes these edges to graph.txt. Updates
+    ! flow(j - 1)%list_vis%delta_out and flow(j)%list_vis%delta_in.
+
+    use contour_531, only: polyline
+    use derived_types, only: snapshot
+    use gpc_f, only: gpc_polygon_clip_f, GPC_INT, polygon
+    use spherical_polygon_area_m, only: spherical_polygon_area
+    use spherical_polyline_area_m, only: spherical_polyline_area
+    use weight_m, only: weight
+
+    integer, intent(in):: unit_graph ! logical unit for graph file
+    integer, intent(in):: nlon, nlat
+    type(snapshot), intent(inout):: flow(:) ! (max_delta + 1)
+    integer, intent(in):: j, k
+
+    ! Local:
+    integer i1, i1_lon, i1_lat, m, l, i2
+    type(polyline) polyline_1, polyline_2
+    type(polygon) res_pol
+
+    integer, parameter:: dist_lim = 12
+    ! We look for an overlapping eddy at dist_lim (in grid points) of
+    ! the first extremum.
+
+    !-----------------------------------------------------------------------
+
+    do i1 = 1, flow(j - 1)%number_vis_eddies
+       if (flow(j - 1)%list_vis(i1)%suff_amp) then
+          polyline_1 = merge(flow(j - 1)%list_vis(i1)%speed_cont%polyline, &
+               flow(j - 1)%list_vis(i1)%out_cont%polyline, &
+               flow(j - 1)%list_vis(i1)%speed_cont%n_points /= 0)
+          i1_lon = flow(j - 1)%ind_extr(1, i1)
+          i1_lat = flow(j - 1)%ind_extr(2, i1)
+
+          DO m = max(i1_lat - dist_lim, 1), min(i1_lat + dist_lim, nlat)
+             DO l = max(i1_lon - dist_lim, 1), min(i1_lon + dist_lim, nlon)
+                if (flow(j)%extr_map(l, m) > 0) then
+                   i2 = flow(j)%extr_map(l, m)
+
+                   if (flow(j)%list_vis(i2)%cyclone &
+                        .eqv. flow(j - 1)%list_vis(i1)%cyclone) then
+                      polyline_2 &
+                           = merge(flow(j)%list_vis(i2)%speed_cont%polyline, &
+                           flow(j)%list_vis(i2)%out_cont%polyline, &
+                           flow(j)%list_vis(i2)%speed_cont%n_points /= 0)
+                      call gpc_polygon_clip_f(GPC_INT, polygon(nparts = 1, &
+                           part = [polyline_1], hole = [.false.]), &
+                           polygon(nparts = 1, part = [polyline_2], &
+                           hole = [.false.]), res_pol)
+
+                      if (res_pol%nparts /= 0) then
+                         ! polyline_1 and polyline_2 overlap
+                         if (spherical_polygon_area(res_pol) >= 0.25 &
+                              * min(spherical_polyline_area(polyline_1), &
+                              spherical_polyline_area(polyline_2))) then
+                            write(unit_graph, fmt = *) k - 1, i1, k, i2, &
+                                 weight(flow(j - 1)%list_vis(i1), &
+                                 flow(j)%list_vis(i2))
+                            flow(j - 1)%list_vis(i1)%delta_out = 1
+                            flow(j)%list_vis(i2)%delta_in = 1
+                         end if
+                      end if
+                   end if
+                end if
+             end DO
+          end DO
+       end if
+    end do
+
+  end subroutine successive_overlap
+  
+end module successive_overlap_m
-- 
GitLab