From 47fda163f5fc5c4dacf7badede0858b24f511134 Mon Sep 17 00:00:00 2001
From: David Wells <drwells@email.unc.edu>
Date: Thu, 3 Nov 2022 14:21:18 -0400
Subject: [PATCH] AffineConstraints: de-template add_entries_local_to_global()
 part 2

---
 cmake/config/template-arguments.in            | 10 ----
 include/deal.II/lac/affine_constraints.h      |  6 +--
 .../lac/affine_constraints.templates.h        | 50 +++++++++++++------
 source/lac/affine_constraints.inst.in         | 44 ----------------
 4 files changed, 37 insertions(+), 73 deletions(-)

diff --git a/cmake/config/template-arguments.in b/cmake/config/template-arguments.in
index a4231884ba..d5d0f84093 100644
--- a/cmake/config/template-arguments.in
+++ b/cmake/config/template-arguments.in
@@ -248,16 +248,6 @@ SPARSITY_PATTERNS := { SparsityPattern;
                        BlockDynamicSparsityPattern;
                        @DEAL_II_EXPAND_TRILINOS_BLOCK_SPARSITY_PATTERN@; }
 
-// Special lists for AffineConstraints:
-AFFINE_CONSTRAINTS_SP := { SparsityPattern;
-                           DynamicSparsityPattern;
-                           @DEAL_II_EXPAND_TRILINOS_SPARSITY_PATTERN@;
-                         }
-AFFINE_CONSTRAINTS_SP_BLOCK := { BlockSparsityPattern;
-                                 BlockDynamicSparsityPattern;
-                                 @DEAL_II_EXPAND_TRILINOS_BLOCK_SPARSITY_PATTERN@;
-                               }
-
 // all supported logical dimensions
 DIMENSIONS := { 1; 2; 3 }
 
diff --git a/include/deal.II/lac/affine_constraints.h b/include/deal.II/lac/affine_constraints.h
index ba263cd24c..cb640ff5cf 100644
--- a/include/deal.II/lac/affine_constraints.h
+++ b/include/deal.II/lac/affine_constraints.h
@@ -1533,12 +1533,11 @@ public:
   /**
    * Similar to the other function, but for non-quadratic sparsity patterns.
    */
-  template <typename SparsityPatternType>
   void
   add_entries_local_to_global(
     const std::vector<size_type> &row_indices,
     const std::vector<size_type> &col_indices,
-    SparsityPatternType &         sparsity_pattern,
+    SparsityPatternBase &         sparsity_pattern,
     const bool                    keep_constrained_entries = true,
     const Table<2, bool> &        dof_mask = Table<2, bool>()) const;
 
@@ -1546,13 +1545,12 @@ public:
    * Similar to the other function, but for non-quadratic sparsity patterns, and
    * for different constraints in the column space.
    */
-  template <typename SparsityPatternType>
   void
   add_entries_local_to_global(
     const std::vector<size_type> &   row_indices,
     const AffineConstraints<number> &col_constraints,
     const std::vector<size_type> &   col_indices,
-    SparsityPatternType &            sparsity_pattern,
+    SparsityPatternBase &            sparsity_pattern,
     const bool                       keep_constrained_entries = true,
     const Table<2, bool> &           dof_mask = Table<2, bool>()) const;
 
diff --git a/include/deal.II/lac/affine_constraints.templates.h b/include/deal.II/lac/affine_constraints.templates.h
index b34dcb3fc2..babfd8ef06 100644
--- a/include/deal.II/lac/affine_constraints.templates.h
+++ b/include/deal.II/lac/affine_constraints.templates.h
@@ -4400,19 +4400,27 @@ AffineConstraints<number>::add_entries_local_to_global(
 
 
 template <typename number>
-template <typename SparsityPatternType>
 void
 AffineConstraints<number>::add_entries_local_to_global(
   const std::vector<size_type> &   row_indices,
   const AffineConstraints<number> &col_constraints,
   const std::vector<size_type> &   col_indices,
-  SparsityPatternType &            sparsity_pattern,
+  SparsityPatternBase &            sparsity_pattern,
   const bool                       keep_constrained_entries,
   const Table<2, bool> &           dof_mask) const
 {
   const size_type n_local_rows = row_indices.size();
   const size_type n_local_cols = col_indices.size();
 
+  typename internal::AffineConstraints::ScratchDataAccessor<number>
+                          scratch_data(this->scratch_data);
+  std::vector<size_type> &rows = scratch_data->rows;
+  std::vector<size_type> &cols = scratch_data->columns;
+  rows.resize(0);
+  rows.reserve(row_indices.size() * col_indices.size());
+  cols.resize(0);
+  cols.reserve(row_indices.size() * col_indices.size());
+
   // if constrained entries should be kept, need to add rows and columns of
   // those to the sparsity pattern
   if (keep_constrained_entries == true)
@@ -4420,11 +4428,19 @@ AffineConstraints<number>::add_entries_local_to_global(
       for (const size_type row_index : row_indices)
         if (is_constrained(row_index))
           for (const size_type col_index : col_indices)
-            sparsity_pattern.add(row_index, col_index);
+            {
+              rows.push_back(row_index);
+              cols.push_back(col_index);
+            }
       for (const size_type col_index : col_indices)
         if (col_constraints.is_constrained(col_index))
           for (const size_type row_index : row_indices)
-            sparsity_pattern.add(row_index, col_index);
+            {
+              rows.push_back(row_index);
+              cols.push_back(col_index);
+            }
+      sparsity_pattern.add_entries(make_array_view(rows),
+                                   make_array_view(cols));
     }
 
   // if the dof mask is not active, all we have to do is to add some indices
@@ -4435,19 +4451,24 @@ AffineConstraints<number>::add_entries_local_to_global(
     dof_mask.n_rows() == n_local_rows && dof_mask.n_cols() == n_local_cols;
   if (dof_mask_is_active == false)
     {
-      std::vector<size_type> actual_row_indices(n_local_rows);
-      std::vector<size_type> actual_col_indices(n_local_cols);
-      make_sorted_row_list(row_indices, actual_row_indices);
-      col_constraints.make_sorted_row_list(col_indices, actual_col_indices);
-      const size_type n_actual_rows = actual_row_indices.size();
+      rows.resize(n_local_rows);
+      cols.resize(n_local_cols);
+      // TODO these fills may not be necessary: previously we assumed all zeros
+      // which seems incorrect. At least this way things will crash
+      std::fill(rows.begin(),
+                rows.end(),
+                std::numeric_limits<size_type>::max());
+      std::fill(cols.begin(),
+                cols.end(),
+                std::numeric_limits<size_type>::max());
+      make_sorted_row_list(row_indices, rows);
+      col_constraints.make_sorted_row_list(col_indices, cols);
+      const size_type n_actual_rows = rows.size();
 
       // now add the indices we collected above to the sparsity pattern. Very
       // easy here - just add the same array to all the rows...
       for (size_type i = 0; i < n_actual_rows; ++i)
-        sparsity_pattern.add_entries(actual_row_indices[i],
-                                     actual_col_indices.begin(),
-                                     actual_col_indices.end(),
-                                     true);
+        sparsity_pattern.add_row_entries(rows[i], make_array_view(cols), true);
       return;
     }
 
@@ -4458,12 +4479,11 @@ AffineConstraints<number>::add_entries_local_to_global(
 
 
 template <typename number>
-template <typename SparsityPatternType>
 void
 AffineConstraints<number>::add_entries_local_to_global(
   const std::vector<size_type> &row_indices,
   const std::vector<size_type> &col_indices,
-  SparsityPatternType &         sparsity_pattern,
+  SparsityPatternBase &         sparsity_pattern,
   const bool                    keep_constrained_entries,
   const Table<2, bool> &        dof_mask) const
 {
diff --git a/source/lac/affine_constraints.inst.in b/source/lac/affine_constraints.inst.in
index 7456d909c6..68112ff9dd 100644
--- a/source/lac/affine_constraints.inst.in
+++ b/source/lac/affine_constraints.inst.in
@@ -250,50 +250,6 @@ for (S : REAL_AND_COMPLEX_SCALARS)
   }
 
 
-// ---------------------------------------------------------------------
-//
-// Instantiate AffineConstraints<S>::add_entries_local_to_global variants
-//
-// ---------------------------------------------------------------------
-
-
-for (S : REAL_AND_COMPLEX_SCALARS; SP : AFFINE_CONSTRAINTS_SP)
-  {
-    template void AffineConstraints<S>::add_entries_local_to_global<SP>(
-      const std::vector<AffineConstraints<S>::size_type> &,
-      const std::vector<AffineConstraints<S>::size_type> &,
-      SP &,
-      const bool,
-      const Table<2, bool> &) const;
-
-    template void AffineConstraints<S>::add_entries_local_to_global<SP>(
-      const std::vector<AffineConstraints<S>::size_type> &,
-      const AffineConstraints<S> &,
-      const std::vector<AffineConstraints<S>::size_type> &,
-      SP &,
-      const bool,
-      const Table<2, bool> &) const;
-  }
-
-for (S : REAL_AND_COMPLEX_SCALARS; SP : AFFINE_CONSTRAINTS_SP_BLOCK)
-  {
-    template void AffineConstraints<S>::add_entries_local_to_global<SP>(
-      const std::vector<AffineConstraints<S>::size_type> &,
-      const std::vector<AffineConstraints<S>::size_type> &,
-      SP &,
-      const bool,
-      const Table<2, bool> &) const;
-
-    template void AffineConstraints<S>::add_entries_local_to_global<SP>(
-      const std::vector<AffineConstraints<S>::size_type> &,
-      const AffineConstraints<S> &,
-      const std::vector<AffineConstraints<S>::size_type> &,
-      SP &,
-      const bool,
-      const Table<2, bool> &) const;
-  }
-
-
 // ---------------------------------------------------------------------
 //
 // Rest:
-- 
2.39.5