From 6e0c6f856b4262dce933090dee96c7545c378568 Mon Sep 17 00:00:00 2001
From: Dmitri Naumov <dmitri.naumov@ufz.de>
Date: Fri, 19 Jan 2024 13:06:26 +0100
Subject: [PATCH] [PL/DS] Rewrite using ranges. Early return.

Small optimization for first variable, no need to make a set_union
with empty _ids_of_active_elements.
---
 ProcessLib/Process.cpp | 50 ++++++++++++++++++++++++++++--------------
 1 file changed, 33 insertions(+), 17 deletions(-)

diff --git a/ProcessLib/Process.cpp b/ProcessLib/Process.cpp
index e45d6511274..e0a8ee0c38c 100644
--- a/ProcessLib/Process.cpp
+++ b/ProcessLib/Process.cpp
@@ -10,6 +10,11 @@
 
 #include "Process.h"
 
+#include <range/v3/algorithm/any_of.hpp>
+#include <range/v3/algorithm/set_algorithm.hpp>
+#include <range/v3/view/drop.hpp>
+#include <range/v3/view/transform.hpp>
+
 #include "NumLib/DOF/ComputeSparsityPattern.h"
 #include "NumLib/Extrapolation/LocalLinearLeastSquaresExtrapolator.h"
 #include "NumLib/ODESolver/ConvergenceCriterionPerComponent.h"
@@ -202,25 +207,36 @@ void Process::updateDeactivatedSubdomains(double const time,
     {
         variable.get().updateDeactivatedSubdomains(time);
     }
+
     _ids_of_active_elements.clear();
-    for (ProcessLib::ProcessVariable const& pv :
-         getProcessVariables(process_id))
+
+    auto active_elements_ids = ranges::views::transform(
+        [](auto const& variable)
+        { return variable.get().getActiveElementIDs(); });
+
+    // Early return if there's any process variable with all elements active.
+    if (ranges::any_of(variables_per_process | active_elements_ids,
+                       [](auto const& vector) { return vector.empty(); }))
     {
-        auto const pv_active_element_ids = pv.getActiveElementIDs();
-        // empty if no deactivated_subdomains exist in process variable
-        // executeSelectedMemberDereferenced with empty active_element_ids
-        // will run executeMemberDereferenced (i.e. on all elements)
-        if (pv_active_element_ids.empty())
-        {
-            _ids_of_active_elements.clear();
-            return;
-        }
-        std::vector<std::size_t> tempResult;
-        std::set_union(
-            _ids_of_active_elements.begin(), _ids_of_active_elements.end(),
-            pv_active_element_ids.begin(), pv_active_element_ids.end(),
-            std::back_inserter(tempResult));
-        _ids_of_active_elements = std::move(tempResult);
+        return;
+    }
+
+    // Some process variable has deactivated elements. Create union of active
+    // ids.
+
+    _ids_of_active_elements =  // there is at least one process variable.
+        variables_per_process[0].get().getActiveElementIDs();
+
+    for (auto const& pv_active_element_ids :
+         variables_per_process | ranges::views::drop(1) | active_elements_ids)
+    {
+        std::vector<std::size_t> new_active_elements;
+        new_active_elements.reserve(_ids_of_active_elements.size() +
+                                    pv_active_element_ids.size());
+        ranges::set_union(_ids_of_active_elements, pv_active_element_ids,
+                          std::back_inserter(new_active_elements));
+
+        _ids_of_active_elements = std::move(new_active_elements);
     }
 }
 
-- 
GitLab