From 087cfc251f509746552dcee195fdcff628d6e72b Mon Sep 17 00:00:00 2001
From: Daniel Arndt <daniel.arndt@iwr.uni-heidelberg.de>
Date: Thu, 7 Dec 2017 00:43:12 +0100
Subject: [PATCH] Make the SUNDIALS solvers usuable for serial vector types

---
 source/sundials/arkode.cc             | 10 ++++--
 source/sundials/ida.cc                | 10 ++++--
 source/sundials/kinsol.cc             | 10 ++++--
 tests/sundials/serial_sundials.cc     | 44 +++++++++++++++++++++++++++
 tests/sundials/serial_sundials.output |  4 +++
 5 files changed, 72 insertions(+), 6 deletions(-)
 create mode 100644 tests/sundials/serial_sundials.cc
 create mode 100644 tests/sundials/serial_sundials.output

diff --git a/source/sundials/arkode.cc b/source/sundials/arkode.cc
index 33d62dbf70..68ebed5cb8 100644
--- a/source/sundials/arkode.cc
+++ b/source/sundials/arkode.cc
@@ -221,7 +221,9 @@ namespace SUNDIALS
                              const MPI_Comm mpi_comm) :
     data(data),
     arkode_mem(nullptr),
-    communicator(Utilities::MPI::duplicate_communicator(mpi_comm))
+    communicator(is_serial_vector<VectorType>::value ?
+                 MPI_COMM_SELF :
+                 Utilities::MPI::duplicate_communicator(mpi_comm))
   {
     set_functions_to_trigger_an_assert();
   }
@@ -232,7 +234,11 @@ namespace SUNDIALS
     if (arkode_mem)
       ARKodeFree(&arkode_mem);
 #ifdef DEAL_II_WITH_MPI
-    MPI_Comm_free(&communicator);
+    if (is_serial_vector<VectorType>::value == false)
+      {
+        const int ierr = MPI_Comm_free(&communicator);
+        AssertThrowMPI(ierr);
+      }
 #endif
   }
 
diff --git a/source/sundials/ida.cc b/source/sundials/ida.cc
index 3bbc1eada6..cd887d4ed7 100644
--- a/source/sundials/ida.cc
+++ b/source/sundials/ida.cc
@@ -142,7 +142,9 @@ namespace SUNDIALS
                        const MPI_Comm mpi_comm) :
     data(data),
     ida_mem(nullptr),
-    communicator(Utilities::MPI::duplicate_communicator(mpi_comm))
+    communicator(is_serial_vector<VectorType>::value ?
+                 MPI_COMM_SELF :
+                 Utilities::MPI::duplicate_communicator(mpi_comm))
   {
     set_functions_to_trigger_an_assert();
   }
@@ -153,7 +155,11 @@ namespace SUNDIALS
     if (ida_mem)
       IDAFree(&ida_mem);
 #ifdef DEAL_II_WITH_MPI
-    MPI_Comm_free(&communicator);
+    if (is_serial_vector<VectorType>::value == false)
+      {
+        const int ierr = MPI_Comm_free(&communicator);
+        AssertThrowMPI(ierr);
+      }
 #endif
   }
 
diff --git a/source/sundials/kinsol.cc b/source/sundials/kinsol.cc
index d807fbfda0..fe00b17db2 100644
--- a/source/sundials/kinsol.cc
+++ b/source/sundials/kinsol.cc
@@ -148,7 +148,9 @@ namespace SUNDIALS
   KINSOL<VectorType>::KINSOL(const AdditionalData &data, const MPI_Comm mpi_comm) :
     data(data),
     kinsol_mem(nullptr),
-    communicator(Utilities::MPI::duplicate_communicator(mpi_comm))
+    communicator(is_serial_vector<VectorType>::value ?
+                 MPI_COMM_SELF :
+                 Utilities::MPI::duplicate_communicator(mpi_comm))
   {
     set_functions_to_trigger_an_assert();
   }
@@ -161,7 +163,11 @@ namespace SUNDIALS
     if (kinsol_mem)
       KINFree(&kinsol_mem);
 #ifdef DEAL_II_WITH_MPI
-    MPI_Comm_free(&communicator);
+    if (is_serial_vector<VectorType>::value == false)
+      {
+        const int ierr = MPI_Comm_free(&communicator);
+        AssertThrowMPI(ierr);
+      }
 #endif
   }
 
diff --git a/tests/sundials/serial_sundials.cc b/tests/sundials/serial_sundials.cc
new file mode 100644
index 0000000000..9dd8b897b1
--- /dev/null
+++ b/tests/sundials/serial_sundials.cc
@@ -0,0 +1,44 @@
+//-----------------------------------------------------------
+//
+//    Copyright (C) 2017 by the deal.II authors
+//
+//    This file is part of the deal.II library.
+//
+//    The deal.II library is free software; you can use it, redistribute
+//    it, and/or modify it under the terms of the GNU Lesser General
+//    Public License as published by the Free Software Foundation; either
+//    version 2.1 of the License, or (at your option) any later version.
+//    The full text of the license can be found in the file LICENSE at
+//    the top level of the deal.II distribution.
+//
+//-----------------------------------------------------------
+
+// Make sure that we can initialize the SUNDIALS solvers
+// for serial vector types without initializing MPI
+
+#include "../tests.h"
+#include <deal.II/lac/vector.h>
+#include <deal.II/sundials/arkode.h>
+#include <deal.II/sundials/ida.h>
+#include <deal.II/sundials/kinsol.h>
+
+
+int main()
+{
+  initlog();
+
+  SUNDIALS::IDA<Vector<double>> ida_solver;
+  (void) ida_solver;
+  deallog << "IDA OK" << std::endl;
+
+  SUNDIALS::KINSOL<Vector<double>> kinsol_solver;
+  (void) kinsol_solver;
+  deallog << "KINSOL OK" << std::endl;
+
+  SUNDIALS::ARKode<Vector<double>> arkode_solver;
+  (void) arkode_solver;
+  deallog << "ARKODE OK" << std::endl;
+
+  return 0;
+}
+
diff --git a/tests/sundials/serial_sundials.output b/tests/sundials/serial_sundials.output
new file mode 100644
index 0000000000..779a52b94b
--- /dev/null
+++ b/tests/sundials/serial_sundials.output
@@ -0,0 +1,4 @@
+
+DEAL::IDA OK
+DEAL::KINSOL OK
+DEAL::ARKODE OK
-- 
2.39.5