From b5df36d7a9bb646ca79227bb10a98b40d903589b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Johann-Tobias=20Sch=C3=A4g?= <joto@l014.fem.tu-ilmenau.de>
Date: Mon, 25 May 2020 18:19:55 +0200
Subject: [PATCH 1/6] Add field for support of pooling events.

---
 src/callbacks.jl | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/src/callbacks.jl b/src/callbacks.jl
index 9f0999c83..fcf955732 100644
--- a/src/callbacks.jl
+++ b/src/callbacks.jl
@@ -175,15 +175,16 @@ struct VectorContinuousCallback{F1,F2,F3,F4,T,T2,I,R} <: AbstractContinuousCallb
   dtrelax::R
   abstol::T
   reltol::T2
+  pool_events::Bool
   VectorContinuousCallback(condition::F1,affect!::F2,affect_neg!::F3,len::Int,
                            initialize::F4,idxs::I,rootfind,
                            interp_points,save_positions,dtrelax::R,
-                           abstol::T,reltol::T2) where {F1,F2,F3,F4,T,T2,I,R} =
+                           abstol::T,reltol::T2, pool_events) where {F1,F2,F3,F4,T,T2,I,R} =
                        new{F1,F2,F3,F4,T,T2,I,R}(condition,
                                                affect!,affect_neg!,len,
                                                initialize,idxs,rootfind,interp_points,
                                                BitArray(collect(save_positions)),
-                                               dtrelax,abstol,reltol)
+                                               dtrelax,abstol,reltol,pool_events)
 end
 
 VectorContinuousCallback(condition,affect!,affect_neg!,len;
@@ -193,13 +194,13 @@ VectorContinuousCallback(condition,affect!,affect_neg!,len;
                          save_positions=(true,true),
                          interp_points=10,
                          dtrelax=1,
-                         abstol=10eps(),reltol=0) = VectorContinuousCallback(
+                         abstol=10eps(),reltol=0, pool_events=false) = VectorContinuousCallback(
                               condition,affect!,affect_neg!,len,
                               initialize,
                               idxs,
                               rootfind,interp_points,
                               save_positions,dtrelax,
-                              abstol,reltol)
+                              abstol,reltol, pool_events)
 
 function VectorContinuousCallback(condition,affect!,len;
                    initialize = INITIALIZE_DEFAULT,
@@ -209,13 +210,13 @@ function VectorContinuousCallback(condition,affect!,len;
                    affect_neg! = affect!,
                    interp_points=10,
                    dtrelax=1,
-                   abstol=10eps(),reltol=0)
+                   abstol=10eps(),reltol=0, pool_events=false)
 
  VectorContinuousCallback(
             condition,affect!,affect_neg!,len,initialize,idxs,
             rootfind,interp_points,
             collect(save_positions),
-            dtrelax,abstol,reltol)
+            dtrelax,abstol,reltol,pool_events)
 
 end
 

From 3c85f2ed049720b4ea081e563799d03e834ec534 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Johann-Tobias=20Sch=C3=A4g?=
 <joto@wlan-l2065.fem.tu-ilmenau.de>
Date: Mon, 25 May 2020 23:17:29 +0200
Subject: [PATCH 2/6] Add pooltol field, handle pooling not sure how to test.

---
 src/callbacks.jl | 45 ++++++++++++++++++++++++++++-----------------
 1 file changed, 28 insertions(+), 17 deletions(-)

diff --git a/src/callbacks.jl b/src/callbacks.jl
index fcf955732..f565e4dcd 100644
--- a/src/callbacks.jl
+++ b/src/callbacks.jl
@@ -122,18 +122,17 @@ function ContinuousCallback(condition,affect!;
             rootfind,interp_points,
             collect(save_positions),
             dtrelax,abstol,reltol)
-
 end
 
 """
 ```julia
 VectorContinuousCallback(condition,affect!,affect_neg!,len;
-                         initialize = INITIALIZE_DEFAULT,
-                         idxs = nothing,
-                         rootfind=true,
-                         save_positions=(true,true),
-                         interp_points=10,
-                         abstol=10eps(),reltol=0)
+                   initialize = INITIALIZE_DEFAULT,
+                   idxs = nothing,
+                   rootfind=true,
+                   save_positions=(true,true),
+                   interp_points=10,
+                   abstol=10eps(),reltol=0,pooltol=nothing,pool_events=false)
 ```
 
 ```julia
@@ -144,7 +143,7 @@ VectorContinuousCallback(condition,affect!,len;
                    save_positions=(true,true),
                    affect_neg! = affect!,
                    interp_points=10,
-                   abstol=10eps(),reltol=0)
+                   abstol=10eps(),reltol=0,pooltol=nothing,pool_events=false)
 ```
 
 This is also a subtype of `AbstractContinuousCallback`. `CallbackSet` is not feasible when you have a large number of callbacks,
@@ -159,10 +158,13 @@ multiple events.
 - `affect!`: This is a function `affect!(integrator, event_index)` which lets you modify `integrator` and it tells you about
    which event occured using `event_idx` i.e. gives you index `i` for which `out[i]` came out to be zero.
 - `len`: Number of callbacks chained. This is compulsory to be specified.
+- `pool_events`: Whether multiple concurrent events should be passed as one array of indexs instead of the indexes on a time.
+- `pooltol`: Custom limit which values get grouped. Callback accepted if it's absolute value is smaller than pooltol at callback time.
+   The default value is `eps(integrator.t) + eps(callback_return_type)`.
 
 Rest of the arguments have the same meaning as in [`ContinuousCallback`](@ref).
 """
-struct VectorContinuousCallback{F1,F2,F3,F4,T,T2,I,R} <: AbstractContinuousCallback
+struct VectorContinuousCallback{F1,F2,F3,F4,T,T2,T3,I,R} <: AbstractContinuousCallback
   condition::F1
   affect!::F2
   affect_neg!::F3
@@ -175,16 +177,17 @@ struct VectorContinuousCallback{F1,F2,F3,F4,T,T2,I,R} <: AbstractContinuousCallb
   dtrelax::R
   abstol::T
   reltol::T2
+  pooltol::T3
   pool_events::Bool
   VectorContinuousCallback(condition::F1,affect!::F2,affect_neg!::F3,len::Int,
                            initialize::F4,idxs::I,rootfind,
                            interp_points,save_positions,dtrelax::R,
-                           abstol::T,reltol::T2, pool_events) where {F1,F2,F3,F4,T,T2,I,R} =
-                       new{F1,F2,F3,F4,T,T2,I,R}(condition,
+                           abstol::T,reltol::T2, pooltol::T3, pool_events) where {F1,F2,F3,F4,T,T2,T3,I,R} =
+                       new{F1,F2,F3,F4,T,T2,T3,I,R}(condition,
                                                affect!,affect_neg!,len,
                                                initialize,idxs,rootfind,interp_points,
                                                BitArray(collect(save_positions)),
-                                               dtrelax,abstol,reltol,pool_events)
+                                               dtrelax,abstol,reltol,pooltol,pool_events)
 end
 
 VectorContinuousCallback(condition,affect!,affect_neg!,len;
@@ -194,13 +197,13 @@ VectorContinuousCallback(condition,affect!,affect_neg!,len;
                          save_positions=(true,true),
                          interp_points=10,
                          dtrelax=1,
-                         abstol=10eps(),reltol=0, pool_events=false) = VectorContinuousCallback(
+                         abstol=10eps(),reltol=0, pooltol=missing, pool_events=false) = VectorContinuousCallback(
                               condition,affect!,affect_neg!,len,
                               initialize,
                               idxs,
                               rootfind,interp_points,
                               save_positions,dtrelax,
-                              abstol,reltol, pool_events)
+                              abstol,reltol, pooltol, pool_events)
 
 function VectorContinuousCallback(condition,affect!,len;
                    initialize = INITIALIZE_DEFAULT,
@@ -210,14 +213,13 @@ function VectorContinuousCallback(condition,affect!,len;
                    affect_neg! = affect!,
                    interp_points=10,
                    dtrelax=1,
-                   abstol=10eps(),reltol=0, pool_events=false)
+                   abstol=10eps(),reltol=0, pooltol=missing, pool_events=false)
 
  VectorContinuousCallback(
             condition,affect!,affect_neg!,len,initialize,idxs,
             rootfind,interp_points,
             collect(save_positions),
-            dtrelax,abstol,reltol,pool_events)
-
+            dtrelax,abstol,reltol,pooltol,pool_events)
 end
 
 """
@@ -761,6 +763,15 @@ function find_callback_time(integrator,callback::VectorContinuousCallback,counte
     min_event_idx = 1
   end
 
+  if callback.pool_event
+    if callback.pooltol isa Missing
+      pool_tol = eps(integrator.t) + eps(zero_func(Θ))
+    else
+      pool_tol = callback.pooltol
+    end
+    min_event_idx = findall(x->abs(ArrayInterface.allowed_getindex(get_condition(integrator, callback, abst),x)) < pool_tol, get_condition(integrator, callback, pool_tol))
+  end
+
   new_t,ArrayInterface.allowed_getindex(prev_sign,min_event_idx),event_occurred,min_event_idx
 end
 

From 24add267fcf4faea72180ce68721066644ad724d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Johann-Tobias=20Sch=C3=A4g?=
 <joto@wlan-l2065.fem.tu-ilmenau.de>
Date: Mon, 25 May 2020 23:44:51 +0200
Subject: [PATCH 3/6] Fix spelling error

---
 src/callbacks.jl | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/callbacks.jl b/src/callbacks.jl
index f565e4dcd..96819c035 100644
--- a/src/callbacks.jl
+++ b/src/callbacks.jl
@@ -763,7 +763,7 @@ function find_callback_time(integrator,callback::VectorContinuousCallback,counte
     min_event_idx = 1
   end
 
-  if callback.pool_event
+  if callback.pool_events
     if callback.pooltol isa Missing
       pool_tol = eps(integrator.t) + eps(zero_func(Θ))
     else

From 09bb173da468f3d5ed9cf425c1823f85c2d4d76e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Johann-Tobias=20Sch=C3=A4g?=
 <joto@wlan-l2065.fem.tu-ilmenau.de>
Date: Tue, 26 May 2020 00:14:47 +0200
Subject: [PATCH 4/6] Fix spelling error

---
 src/callbacks.jl | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/callbacks.jl b/src/callbacks.jl
index 96819c035..19392d56e 100644
--- a/src/callbacks.jl
+++ b/src/callbacks.jl
@@ -769,7 +769,7 @@ function find_callback_time(integrator,callback::VectorContinuousCallback,counte
     else
       pool_tol = callback.pooltol
     end
-    min_event_idx = findall(x->abs(ArrayInterface.allowed_getindex(get_condition(integrator, callback, abst),x)) < pool_tol, get_condition(integrator, callback, pool_tol))
+    min_event_idx = findall(x->abs(ArrayInterface.allowed_getindex(get_condition(integrator, callback, min_t),x)) < pool_tol, get_condition(integrator, callback, pool_tol))
   end
 
   new_t,ArrayInterface.allowed_getindex(prev_sign,min_event_idx),event_occurred,min_event_idx

From 706f61fde114e13300d9adf9773d0b8bf1e9572a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Johann-Tobias=20Sch=C3=A4g?=
 <joto@wlan-l2065.fem.tu-ilmenau.de>
Date: Sun, 31 May 2020 16:15:27 +0200
Subject: [PATCH 5/6] Move pool_events to right place not to trigger on "no
 callback (necessary)" branches

---
 src/callbacks.jl | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/src/callbacks.jl b/src/callbacks.jl
index 19392d56e..e2953fd42 100644
--- a/src/callbacks.jl
+++ b/src/callbacks.jl
@@ -757,21 +757,21 @@ function find_callback_time(integrator,callback::VectorContinuousCallback,counte
         new_t = integrator.dt
         min_event_idx = event_idx[1]
       end
+      if callback.pool_events
+        tmp = get_condition(integrator, callback, integrator.dt + new_t)
+        if callback.pooltol isa Missing
+          pool_tol = eps(integrator.t + new_t) + eps(typeof(tmp[end]))
+        else
+          pool_tol = callback.pooltol
+        end
+        min_event_idx = findall(x-> x < pool_tol, tmp)
+      end
     end
   else
     new_t = zero(typeof(integrator.t))
     min_event_idx = 1
   end
 
-  if callback.pool_events
-    if callback.pooltol isa Missing
-      pool_tol = eps(integrator.t) + eps(zero_func(Θ))
-    else
-      pool_tol = callback.pooltol
-    end
-    min_event_idx = findall(x->abs(ArrayInterface.allowed_getindex(get_condition(integrator, callback, min_t),x)) < pool_tol, get_condition(integrator, callback, pool_tol))
-  end
-
   new_t,ArrayInterface.allowed_getindex(prev_sign,min_event_idx),event_occurred,min_event_idx
 end
 

From b9ae0ca13881b8638fc3f36597f6765e0ea5a5fe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Johann-Tobias=20Sch=C3=A4g?=
 <joto@wlan-l2065.fem.tu-ilmenau.de>
Date: Sun, 31 May 2020 16:18:58 +0200
Subject: [PATCH 6/6] Add comment, use abs

---
 src/callbacks.jl | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/callbacks.jl b/src/callbacks.jl
index e2953fd42..cc8a0a002 100644
--- a/src/callbacks.jl
+++ b/src/callbacks.jl
@@ -760,11 +760,12 @@ function find_callback_time(integrator,callback::VectorContinuousCallback,counte
       if callback.pool_events
         tmp = get_condition(integrator, callback, integrator.dt + new_t)
         if callback.pooltol isa Missing
+          # This is still dubious
           pool_tol = eps(integrator.t + new_t) + eps(typeof(tmp[end]))
         else
           pool_tol = callback.pooltol
         end
-        min_event_idx = findall(x-> x < pool_tol, tmp)
+        min_event_idx = findall(x-> abs(x) < pool_tol, tmp)
       end
     end
   else