From c987fbf0950b466ee816eb4bfabc83e67ebccdaf Mon Sep 17 00:00:00 2001
From: Dmitri Naumov <dmitri.naumov@ufz.de>
Date: Tue, 27 Aug 2013 23:40:37 +0200
Subject: [PATCH] Compose vector/matrix builder in GlobalSetup structure.

Also add a typical setup using GlobalDense matrix and SerialExecutor.
---
 AssemblerLib/GlobalSetup.h                    | 49 +++++++++++++++++++
 AssemblerLib/SerialDenseSetup.h               | 31 ++++++++++++
 AssemblerLib/SerialExecutor.h                 | 35 +++++++------
 Tests/AssemblerLib/TestSerialExecutor.cpp     |  2 +-
 Tests/AssemblerLib/TestSerialLinearSolver.cpp | 19 ++++---
 5 files changed, 109 insertions(+), 27 deletions(-)
 create mode 100644 AssemblerLib/GlobalSetup.h
 create mode 100644 AssemblerLib/SerialDenseSetup.h

diff --git a/AssemblerLib/GlobalSetup.h b/AssemblerLib/GlobalSetup.h
new file mode 100644
index 00000000000..8aa545bb6a8
--- /dev/null
+++ b/AssemblerLib/GlobalSetup.h
@@ -0,0 +1,49 @@
+/**
+ * \copyright
+ * Copyright (c) 2013, OpenGeoSys Community (http://www.opengeosys.org)
+ *            Distributed under a Modified BSD License.
+ *              See accompanying file LICENSE.txt or
+ *              http://www.opengeosys.org/project/license
+ *
+ */
+
+#ifndef ASSEMBLERLIB_GLOBALSETUP_H_
+#define ASSEMBLERLIB_GLOBALSETUP_H_
+
+#include <functional>
+
+#include "MeshComponentMap.h"
+
+namespace AssemblerLib
+{
+
+/// The GlobalSetup collects vector and matrix builder and corresponding global
+/// loop executor.
+template <typename VectorMatrixBuilder, typename Executor>
+struct GlobalSetup
+{
+    typedef typename VectorMatrixBuilder::VectorType VectorType;
+    typedef typename VectorMatrixBuilder::MatrixType MatrixType;
+
+    template <typename... Args>
+    VectorType* createVector(Args&& ... args) const
+    {
+        return VectorMatrixBuilder::createVector(std::forward<Args>(args)...);
+    }
+
+    template <typename... Args>
+    MatrixType* createMatrix(Args&& ... args) const
+    {
+        return VectorMatrixBuilder::createMatrix(std::forward<Args>(args)...);
+    }
+
+    template <typename... Args>
+    void execute(Args&& ... args) const
+    {
+        return Executor::execute(std::forward<Args>(args)...);
+    }
+};
+
+}   // namespace AssemblerLib
+
+#endif  // ASSEMBLERLIB_GLOBALSETUP_H_
diff --git a/AssemblerLib/SerialDenseSetup.h b/AssemblerLib/SerialDenseSetup.h
new file mode 100644
index 00000000000..fbac129d4c4
--- /dev/null
+++ b/AssemblerLib/SerialDenseSetup.h
@@ -0,0 +1,31 @@
+/**
+ * \copyright
+ * Copyright (c) 2013, OpenGeoSys Community (http://www.opengeosys.org)
+ *            Distributed under a Modified BSD License.
+ *              See accompanying file LICENSE.txt or
+ *              http://www.opengeosys.org/project/license
+ *
+ */
+
+#ifndef ASSEMBLERLIB_SERIALDENSESETUP_H_
+#define ASSEMBLERLIB_SERIALDENSESETUP_H_
+
+
+#include "AssemblerLib/GlobalSetup.h"
+
+#include "AssemblerLib/SerialDenseVectorMatrixBuilder.h"
+#include "AssemblerLib/SerialExecutor.h"
+
+namespace AssemblerLib
+{
+
+/// Using GlobalDenseMatrix and DenseVector for global entities and serial
+/// global assembly loop.
+typedef GlobalSetup<
+        AssemblerLib::SerialDenseVectorMatrixBuilder,
+        AssemblerLib::SerialExecutor>
+    SerialDenseSetup;
+
+}   // namespace AssemblerLib
+
+#endif  // ASSEMBLERLIB_SERIALDENSESETUP_H_
diff --git a/AssemblerLib/SerialExecutor.h b/AssemblerLib/SerialExecutor.h
index 770314d359d..edfac6e973e 100644
--- a/AssemblerLib/SerialExecutor.h
+++ b/AssemblerLib/SerialExecutor.h
@@ -13,26 +13,29 @@
 #ifndef ASSEMBLERLIB_SERIALEXECUTOR_H_H
 #define ASSEMBLERLIB_SERIALEXECUTOR_H_H
 
-#include <vector>
-
 namespace AssemblerLib
 {
 
-/// Executes a \c f for each element from the input container.
-/// Return values of the function call are ignored.
-///
-/// \tparam F   \c f type.
-/// \tparam C   input container type.
-///
-/// \param f    a function that accepts a pointer to container's elements and
-///             an index as arguments.
-/// \param c    a container supporting access over operator[].
-template <typename F, typename C>
-void
-serialExecute(F const& f, C const& c)
+struct SerialExecutor
 {
-    for (std::size_t i = 0; i < c.size(); i++)
-        f(c[i], i);
+    /// Executes a \c f for each element from the input container.
+    /// Return values of the function call are ignored.
+    ///
+    /// \tparam F   \c f type.
+    /// \tparam C   input container type.
+    ///
+    /// \param f    a function that accepts a pointer to container's elements and
+    ///             an index as arguments.
+    /// \param c    a container supporting access over operator[].
+    template <typename F, typename C>
+    static
+    void
+    execute(F const& f, C const& c)
+    {
+        for (std::size_t i = 0; i < c.size(); i++)
+            f(c[i], i);
+    };
+
 };
 
 }   // namespace AssemblerLib
diff --git a/Tests/AssemblerLib/TestSerialExecutor.cpp b/Tests/AssemblerLib/TestSerialExecutor.cpp
index 2850c539202..433398c7d36 100644
--- a/Tests/AssemblerLib/TestSerialExecutor.cpp
+++ b/Tests/AssemblerLib/TestSerialExecutor.cpp
@@ -53,7 +53,7 @@ using namespace std::placeholders;
 
 TYPED_TEST_P(AssemblerLibSerialExecutor, ContainerArgument)
 {
-    AssemblerLib::serialExecute(
+    AssemblerLib::SerialExecutor::execute(
         std::bind(&TestFixture::subtractFromReference, this, _1, _2),
         this->container);
     ASSERT_TRUE(this->referenceIsZero());
diff --git a/Tests/AssemblerLib/TestSerialLinearSolver.cpp b/Tests/AssemblerLib/TestSerialLinearSolver.cpp
index 94d89c6d7a5..4d91893d464 100644
--- a/Tests/AssemblerLib/TestSerialLinearSolver.cpp
+++ b/Tests/AssemblerLib/TestSerialLinearSolver.cpp
@@ -18,8 +18,7 @@
 
 #include "AssemblerLib/LinearSystemAssembler.h"
 #include "AssemblerLib/MeshComponentMap.h"
-#include "AssemblerLib/SerialDenseVectorMatrixBuilder.h"
-#include "AssemblerLib/SerialExecutor.h"
+#include "AssemblerLib/SerialDenseSetup.h"
 
 
 #include "MathLib/LinAlg/Dense/DenseTools.h"
@@ -45,8 +44,8 @@ TEST(AssemblerLibSerialLinearSolver, Steady2DdiffusionQuadElem)
 	//--------------------------------------------------------------------------
 	// Choose implementation type
 	//--------------------------------------------------------------------------
-	typedef AssemblerLib::SerialDenseVectorMatrixBuilder SerialBuilder;
-	SerialBuilder vecMatOnMesh;
+    typedef AssemblerLib::SerialDenseSetup GlobalSetup;
+    const GlobalSetup globalSetup;
 
 	//--------------------------------------------------------------------------
 	// Prepare mesh items where data are assigned
@@ -65,12 +64,12 @@ TEST(AssemblerLibSerialLinearSolver, Steady2DdiffusionQuadElem)
 	    vec_comp_dis, AssemblerLib::ComponentOrder::BY_COMPONENT);
 
 	// allocate a vector and matrix
-	typedef SerialBuilder::VectorType GlobalVector;
-	typedef SerialBuilder::MatrixType GlobalMatrix;
-	std::unique_ptr<GlobalMatrix> A(vecMatOnMesh.createMatrix(vec1_composition));
+	typedef GlobalSetup::VectorType GlobalVector;
+	typedef GlobalSetup::MatrixType GlobalMatrix;
+	std::unique_ptr<GlobalMatrix> A(globalSetup.createMatrix(vec1_composition));
 	A->setZero();
-	std::unique_ptr<GlobalVector> rhs(vecMatOnMesh.createVector(vec1_composition));
-	std::unique_ptr<GlobalVector> x(vecMatOnMesh.createVector(vec1_composition));
+	std::unique_ptr<GlobalVector> rhs(globalSetup.createVector(vec1_composition));
+	std::unique_ptr<GlobalVector> x(globalSetup.createVector(vec1_composition));
 
 	//--------------------------------------------------------------------------
 	// Construct a linear system
@@ -111,7 +110,7 @@ TEST(AssemblerLibSerialLinearSolver, Steady2DdiffusionQuadElem)
         AssemblerLib::LocalToGlobalIndexMap(map_ele_nodes2vec_entries));
 
 	// Call global assembler for each mesh element.
-	AssemblerLib::serialExecute(assembler, ex1.msh->getElements());
+    globalSetup.execute(assembler, ex1.msh->getElements());
 
 	//std::cout << "A=\n";
 	//A->write(std::cout);
-- 
GitLab