From a0afdef1daa9f932fbee853e65906fee0f7fc900 Mon Sep 17 00:00:00 2001
From: Christoph Lehmann <christoph.lehmann@ufz.de>
Date: Sun, 21 Nov 2021 14:55:59 +0100
Subject: [PATCH] [PL] Unified createLocalAssemblers for Taylor-Hood elements

---
 .../HydroMechanics/CreateLocalAssemblers.h    |  81 ------------
 .../HydroMechanics/HydroMechanicsProcess.cpp  |   9 +-
 .../RichardsMechanics/CreateLocalAssemblers.h |  84 ------------
 .../RichardsMechanicsProcess.cpp              |   8 +-
 ProcessLib/StokesFlow/CreateLocalAssemblers.h |  82 ------------
 ProcessLib/StokesFlow/StokesFlowProcess.cpp   |  10 +-
 ProcessLib/TH2M/CreateLocalAssemblers.h       |  84 ------------
 ProcessLib/TH2M/TH2MProcess.cpp               |   7 +-
 .../CreateLocalAssemblers.h                   |  84 ------------
 .../ThermoHydroMechanicsProcess.cpp           |   8 +-
 .../CreateLocalAssemblers.h                   |  80 ------------
 .../ThermoRichardsMechanicsProcess.cpp        |   8 +-
 .../Utils/CreateLocalAssemblersTaylorHood.h   | 120 ++++++++++++++++++
 13 files changed, 143 insertions(+), 522 deletions(-)
 delete mode 100644 ProcessLib/HydroMechanics/CreateLocalAssemblers.h
 delete mode 100644 ProcessLib/RichardsMechanics/CreateLocalAssemblers.h
 delete mode 100644 ProcessLib/StokesFlow/CreateLocalAssemblers.h
 delete mode 100644 ProcessLib/TH2M/CreateLocalAssemblers.h
 delete mode 100644 ProcessLib/ThermoHydroMechanics/CreateLocalAssemblers.h
 delete mode 100644 ProcessLib/ThermoRichardsMechanics/CreateLocalAssemblers.h
 create mode 100644 ProcessLib/Utils/CreateLocalAssemblersTaylorHood.h

diff --git a/ProcessLib/HydroMechanics/CreateLocalAssemblers.h b/ProcessLib/HydroMechanics/CreateLocalAssemblers.h
deleted file mode 100644
index 44131a53884..00000000000
--- a/ProcessLib/HydroMechanics/CreateLocalAssemblers.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/**
- * \file
- * \copyright
- * Copyright (c) 2012-2021, OpenGeoSys Community (http://www.opengeosys.org)
- *            Distributed under a Modified BSD License.
- *              See accompanying file LICENSE.txt or
- *              http://www.opengeosys.org/project/license
- */
-
-#pragma once
-
-#include <vector>
-
-#include "BaseLib/Logging.h"
-#include "NumLib/DOF/LocalToGlobalIndexMap.h"
-#include "ProcessLib/Utils/LocalAssemblerFactoryTaylorHoodForOrderGeN.h"
-
-namespace ProcessLib
-{
-namespace HydroMechanics
-{
-namespace detail
-{
-template <int GlobalDim,
-          template <typename, typename, typename, int>
-          class LocalAssemblerImplementation,
-          typename LocalAssemblerInterface, typename... ExtraCtorArgs>
-void createLocalAssemblers(
-    NumLib::LocalToGlobalIndexMap const& dof_table,
-    std::vector<MeshLib::Element*> const& mesh_elements,
-    std::vector<std::unique_ptr<LocalAssemblerInterface>>& local_assemblers,
-    ExtraCtorArgs&&... extra_ctor_args)
-{
-    using LocAsmFactory = LocalAssemblerFactoryHM<LocalAssemblerInterface,
-                                                  LocalAssemblerImplementation,
-                                                  GlobalDim, ExtraCtorArgs...>;
-
-    DBUG("Create local assemblers.");
-
-    LocAsmFactory factory(dof_table);
-    local_assemblers.resize(mesh_elements.size());
-
-    DBUG("Calling local assembler builder for all mesh elements.");
-    GlobalExecutor::transformDereferenced(
-        factory, mesh_elements, local_assemblers,
-        std::forward<ExtraCtorArgs>(extra_ctor_args)...);
-}
-
-}  // namespace detail
-
-/*! Creates local assemblers for each element of the given \c mesh.
- *
- * \tparam LocalAssemblerImplementation the individual local assembler type
- * \tparam LocalAssemblerInterface the general local assembler interface
- * \tparam ExtraCtorArgs types of additional constructor arguments.
- *         Those arguments will be passed to the constructor of
- *         \c LocalAssemblerImplementation.
- *
- * The first two template parameters cannot be deduced from the arguments.
- * Therefore they always have to be provided manually.
- */
-template <int GlobalDim,
-          template <typename, typename, typename, int>
-          class LocalAssemblerImplementation,
-          typename LocalAssemblerInterface, typename... ExtraCtorArgs>
-void createLocalAssemblers(
-    const unsigned /*dimension*/,
-    std::vector<MeshLib::Element*> const& mesh_elements,
-    NumLib::LocalToGlobalIndexMap const& dof_table,
-    std::vector<std::unique_ptr<LocalAssemblerInterface>>& local_assemblers,
-    ExtraCtorArgs&&... extra_ctor_args)
-{
-    DBUG("Create local assemblers.");
-
-    detail::createLocalAssemblers<GlobalDim, LocalAssemblerImplementation>(
-        dof_table, mesh_elements, local_assemblers,
-        std::forward<ExtraCtorArgs>(extra_ctor_args)...);
-}
-}  // namespace HydroMechanics
-
-}  // namespace ProcessLib
diff --git a/ProcessLib/HydroMechanics/HydroMechanicsProcess.cpp b/ProcessLib/HydroMechanics/HydroMechanicsProcess.cpp
index c49de80bcf9..751c390c02c 100644
--- a/ProcessLib/HydroMechanics/HydroMechanicsProcess.cpp
+++ b/ProcessLib/HydroMechanics/HydroMechanicsProcess.cpp
@@ -17,8 +17,9 @@
 #include "MeshLib/Elements/Utils.h"
 #include "NumLib/DOF/ComputeSparsityPattern.h"
 #include "ProcessLib/Deformation/SolidMaterialInternalToSecondaryVariables.h"
-#include "ProcessLib/HydroMechanics/CreateLocalAssemblers.h"
 #include "ProcessLib/Process.h"
+#include "ProcessLib/Utils/CreateLocalAssemblersTaylorHood.h"
+
 namespace ProcessLib
 {
 namespace HydroMechanics
@@ -170,9 +171,9 @@ void HydroMechanicsProcess<DisplacementDim>::initializeConcreteProcess(
     MeshLib::Mesh const& mesh,
     unsigned const integration_order)
 {
-    ProcessLib::HydroMechanics::createLocalAssemblers<
-        DisplacementDim, HydroMechanicsLocalAssembler>(
-        mesh.getDimension(), mesh.getElements(), dof_table, _local_assemblers,
+    ProcessLib::createLocalAssemblersHM<DisplacementDim,
+                                        HydroMechanicsLocalAssembler>(
+        mesh.getElements(), dof_table, _local_assemblers,
         mesh.isAxiallySymmetric(), integration_order, _process_data);
 
     auto add_secondary_variable = [&](std::string const& name,
diff --git a/ProcessLib/RichardsMechanics/CreateLocalAssemblers.h b/ProcessLib/RichardsMechanics/CreateLocalAssemblers.h
deleted file mode 100644
index a2d563ee488..00000000000
--- a/ProcessLib/RichardsMechanics/CreateLocalAssemblers.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/**
- * \file
- * \copyright
- * Copyright (c) 2012-2021, OpenGeoSys Community (http://www.opengeosys.org)
- *            Distributed under a Modified BSD License.
- *              See accompanying file LICENSE.txt or
- *              http://www.opengeosys.org/project/license
- */
-
-#pragma once
-
-#include <vector>
-
-#include "BaseLib/Logging.h"
-#include "NumLib/DOF/LocalToGlobalIndexMap.h"
-#include "ProcessLib/Utils/LocalDataInitializerHM.h"
-
-namespace ProcessLib
-{
-namespace RichardsMechanics
-{
-namespace detail
-{
-template <int GlobalDim,
-          template <typename, typename, typename, int>
-          class LocalAssemblerImplementation,
-          typename LocalAssemblerInterface, typename... ExtraCtorArgs>
-void createLocalAssemblers(
-    NumLib::LocalToGlobalIndexMap const& dof_table,
-    std::vector<MeshLib::Element*> const& mesh_elements,
-    std::vector<std::unique_ptr<LocalAssemblerInterface>>& local_assemblers,
-    ExtraCtorArgs&&... extra_ctor_args)
-{
-    // Shape matrices initializer
-    using LocalDataInitializer =
-        LocalDataInitializerHM<LocalAssemblerInterface,
-                               LocalAssemblerImplementation, GlobalDim,
-                               ExtraCtorArgs...>;
-
-    DBUG("Create local assemblers.");
-    // Populate the vector of local assemblers.
-    local_assemblers.resize(mesh_elements.size());
-
-    LocalDataInitializer initializer(dof_table);
-
-    DBUG("Calling local assembler builder for all mesh elements.");
-    GlobalExecutor::transformDereferenced(
-        initializer, mesh_elements, local_assemblers,
-        std::forward<ExtraCtorArgs>(extra_ctor_args)...);
-}
-
-}  // namespace detail
-
-/*! Creates local assemblers for each element of the given \c mesh.
- *
- * \tparam LocalAssemblerImplementation the individual local assembler type
- * \tparam LocalAssemblerInterface the general local assembler interface
- * \tparam ExtraCtorArgs types of additional constructor arguments.
- *         Those arguments will be passed to the constructor of
- *         \c LocalAssemblerImplementation.
- *
- * The first two template parameters cannot be deduced from the arguments.
- * Therefore they always have to be provided manually.
- */
-template <int GlobalDim,
-          template <typename, typename, typename, int>
-          class LocalAssemblerImplementation,
-          typename LocalAssemblerInterface, typename... ExtraCtorArgs>
-void createLocalAssemblers(
-    const unsigned /*dimension*/,
-    std::vector<MeshLib::Element*> const& mesh_elements,
-    NumLib::LocalToGlobalIndexMap const& dof_table,
-    std::vector<std::unique_ptr<LocalAssemblerInterface>>& local_assemblers,
-    ExtraCtorArgs&&... extra_ctor_args)
-{
-    DBUG("Create local assemblers.");
-
-    detail::createLocalAssemblers<GlobalDim, LocalAssemblerImplementation>(
-        dof_table, mesh_elements, local_assemblers,
-        std::forward<ExtraCtorArgs>(extra_ctor_args)...);
-}
-}  // namespace RichardsMechanics
-
-}  // namespace ProcessLib
diff --git a/ProcessLib/RichardsMechanics/RichardsMechanicsProcess.cpp b/ProcessLib/RichardsMechanics/RichardsMechanicsProcess.cpp
index cd46be913bf..5fa79b9ad85 100644
--- a/ProcessLib/RichardsMechanics/RichardsMechanicsProcess.cpp
+++ b/ProcessLib/RichardsMechanics/RichardsMechanicsProcess.cpp
@@ -15,7 +15,7 @@
 #include "MeshLib/Elements/Utils.h"
 #include "NumLib/DOF/ComputeSparsityPattern.h"
 #include "ProcessLib/Deformation/SolidMaterialInternalToSecondaryVariables.h"
-#include "ProcessLib/RichardsMechanics/CreateLocalAssemblers.h"
+#include "ProcessLib/Utils/CreateLocalAssemblersTaylorHood.h"
 #include "RichardsMechanicsFEM.h"
 #include "RichardsMechanicsProcessData.h"
 
@@ -196,9 +196,9 @@ void RichardsMechanicsProcess<DisplacementDim>::initializeConcreteProcess(
 {
     using nlohmann::json;
 
-    ProcessLib::RichardsMechanics::createLocalAssemblers<
-        DisplacementDim, RichardsMechanicsLocalAssembler>(
-        mesh.getDimension(), mesh.getElements(), dof_table, _local_assemblers,
+    ProcessLib::createLocalAssemblersHM<DisplacementDim,
+                                        RichardsMechanicsLocalAssembler>(
+        mesh.getElements(), dof_table, _local_assemblers,
         mesh.isAxiallySymmetric(), integration_order, _process_data);
 
     auto add_secondary_variable = [&](std::string const& name,
diff --git a/ProcessLib/StokesFlow/CreateLocalAssemblers.h b/ProcessLib/StokesFlow/CreateLocalAssemblers.h
deleted file mode 100644
index e4261afda20..00000000000
--- a/ProcessLib/StokesFlow/CreateLocalAssemblers.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/**
- * \file
- * \copyright
- * Copyright (c) 2012-2021, OpenGeoSys Community (http://www.opengeosys.org)
- *            Distributed under a Modified BSD License.
- *              See accompanying file LICENSE.txt or
- *              http://www.opengeosys.org/project/license
- */
-
-#pragma once
-
-#include <vector>
-
-#include "BaseLib/Logging.h"
-#include "NumLib/DOF/LocalToGlobalIndexMap.h"
-#include "ProcessLib/Utils/LocalAssemblerFactoryTaylorHoodForOrderGeN.h"
-
-namespace ProcessLib
-{
-namespace StokesFlow
-{
-namespace detail
-{
-template <int GlobalDim,
-          template <typename, typename, typename, int>
-          class LocalAssemblerImplementation,
-          typename LocalAssemblerInterface, typename... ExtraCtorArgs>
-void createLocalAssemblers(
-    NumLib::LocalToGlobalIndexMap const& dof_table,
-    std::vector<MeshLib::Element*> const& mesh_elements,
-    std::vector<std::unique_ptr<LocalAssemblerInterface>>& local_assemblers,
-    ExtraCtorArgs&&... extra_ctor_args)
-{
-    using LocAsmFactory =
-        LocalAssemblerFactoryStokes<LocalAssemblerInterface,
-                                    LocalAssemblerImplementation, GlobalDim,
-                                    ExtraCtorArgs...>;
-
-    DBUG("Create local assemblers.");
-
-    LocAsmFactory factory(dof_table);
-    local_assemblers.resize(mesh_elements.size());
-
-    DBUG("Calling local assembler builder for all mesh elements.");
-    GlobalExecutor::transformDereferenced(
-        factory, mesh_elements, local_assemblers,
-        std::forward<ExtraCtorArgs>(extra_ctor_args)...);
-}
-
-}  // namespace detail
-
-/*! Creates local assemblers for each element of the given \c mesh.
- *
- * \tparam LocalAssemblerImplementation the individual local assembler type
- * \tparam LocalAssemblerInterface the general local assembler interface
- * \tparam ExtraCtorArgs types of additional constructor arguments.
- *         Those arguments will be passed to the constructor of
- *         \c LocalAssemblerImplementation.
- *
- * The first two template parameters cannot be deduced from the arguments.
- * Therefore they always have to be provided manually.
- */
-template <int GlobalDim,
-          template <typename, typename, typename, int>
-          class LocalAssemblerImplementation,
-          typename LocalAssemblerInterface, typename... ExtraCtorArgs>
-void createLocalAssemblers(
-    const unsigned /*dimension*/,
-    std::vector<MeshLib::Element*> const& mesh_elements,
-    NumLib::LocalToGlobalIndexMap const& dof_table,
-    std::vector<std::unique_ptr<LocalAssemblerInterface>>& local_assemblers,
-    ExtraCtorArgs&&... extra_ctor_args)
-{
-    DBUG("Create local assemblers.");
-
-    detail::createLocalAssemblers<GlobalDim, LocalAssemblerImplementation>(
-        dof_table, mesh_elements, local_assemblers,
-        std::forward<ExtraCtorArgs>(extra_ctor_args)...);
-}
-}  // namespace StokesFlow
-
-}  // namespace ProcessLib
diff --git a/ProcessLib/StokesFlow/StokesFlowProcess.cpp b/ProcessLib/StokesFlow/StokesFlowProcess.cpp
index 49b65f9474d..21060f27bb5 100644
--- a/ProcessLib/StokesFlow/StokesFlowProcess.cpp
+++ b/ProcessLib/StokesFlow/StokesFlowProcess.cpp
@@ -12,8 +12,8 @@
 
 #include <cassert>
 
-#include "CreateLocalAssemblers.h"
 #include "MeshLib/Elements/Utils.h"
+#include "ProcessLib/Utils/CreateLocalAssemblersTaylorHood.h"
 
 namespace ProcessLib
 {
@@ -88,12 +88,8 @@ void StokesFlowProcess<GlobalDim>::initializeConcreteProcess(
     MeshLib::Mesh const& mesh,
     unsigned const integration_order)
 {
-    // Todo: may move LocalDataInitializer.h and CreateLocalAssemblers.h which
-    // are identical to those in such processes as HydroMechanics,
-    // RichardsMechanics, and etc, into a common place.
-    ProcessLib::StokesFlow::createLocalAssemblers<GlobalDim,
-                                                  LocalAssemblerData>(
-        mesh.getDimension(), mesh.getElements(), dof_table, _local_assemblers,
+    ProcessLib::createLocalAssemblersStokes<GlobalDim, LocalAssemblerData>(
+        mesh.getElements(), dof_table, _local_assemblers,
         mesh.isAxiallySymmetric(), integration_order, _process_data);
 
     _process_data.pressure_interpolated =
diff --git a/ProcessLib/TH2M/CreateLocalAssemblers.h b/ProcessLib/TH2M/CreateLocalAssemblers.h
deleted file mode 100644
index 508d863d2dc..00000000000
--- a/ProcessLib/TH2M/CreateLocalAssemblers.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/**
- * \file
- * \copyright
- * Copyright (c) 2012-2021, OpenGeoSys Community (http://www.opengeosys.org)
- *            Distributed under a Modified BSD License.
- *              See accompanying file LICENSE.txt or
- *              http://www.opengeosys.org/project/license
- */
-
-#pragma once
-
-#include <vector>
-
-#include "BaseLib/Logging.h"
-#include "NumLib/DOF/LocalToGlobalIndexMap.h"
-#include "ProcessLib/Utils/LocalDataInitializerHM.h"
-
-namespace ProcessLib
-{
-namespace TH2M
-{
-namespace detail
-{
-template <int GlobalDim,
-          template <typename, typename, typename, int>
-          class LocalAssemblerImplementation,
-          typename LocalAssemblerInterface, typename... ExtraCtorArgs>
-void createLocalAssemblers(
-    NumLib::LocalToGlobalIndexMap const& dof_table,
-    std::vector<MeshLib::Element*> const& mesh_elements,
-    std::vector<std::unique_ptr<LocalAssemblerInterface>>& local_assemblers,
-    ExtraCtorArgs&&... extra_ctor_args)
-{
-    // Shape matrices initializer
-    using LocalDataInitializer =
-        LocalDataInitializerHM<LocalAssemblerInterface,
-                               LocalAssemblerImplementation, GlobalDim,
-                               ExtraCtorArgs...>;
-
-    DBUG("Create local assemblers.");
-    // Populate the vector of local assemblers.
-    local_assemblers.resize(mesh_elements.size());
-
-    LocalDataInitializer initializer(dof_table);
-
-    DBUG("Calling local assembler builder for all mesh elements.");
-    GlobalExecutor::transformDereferenced(
-        initializer, mesh_elements, local_assemblers,
-        std::forward<ExtraCtorArgs>(extra_ctor_args)...);
-}
-
-}  // namespace detail
-
-/*! Creates local assemblers for each element of the given \c mesh.
- *
- * \tparam LocalAssemblerImplementation the individual local assembler type
- * \tparam LocalAssemblerInterface the general local assembler interface
- * \tparam ExtraCtorArgs types of additional constructor arguments.
- *         Those arguments will be passed to the constructor of
- *         \c LocalAssemblerImplementation.
- *
- * The first two template parameters cannot be deduced from the arguments.
- * Therefore they always have to be provided manually.
- */
-template <int GlobalDim,
-          template <typename, typename, typename, int>
-          class LocalAssemblerImplementation,
-          typename LocalAssemblerInterface, typename... ExtraCtorArgs>
-void createLocalAssemblers(
-    const unsigned /*dimension*/,
-    std::vector<MeshLib::Element*> const& mesh_elements,
-    NumLib::LocalToGlobalIndexMap const& dof_table,
-    std::vector<std::unique_ptr<LocalAssemblerInterface>>& local_assemblers,
-    ExtraCtorArgs&&... extra_ctor_args)
-{
-    DBUG("Create local assemblers.");
-
-    detail::createLocalAssemblers<GlobalDim, LocalAssemblerImplementation>(
-        dof_table, mesh_elements, local_assemblers,
-        std::forward<ExtraCtorArgs>(extra_ctor_args)...);
-}
-}  // namespace TH2M
-
-}  // namespace ProcessLib
diff --git a/ProcessLib/TH2M/TH2MProcess.cpp b/ProcessLib/TH2M/TH2MProcess.cpp
index c174567ce32..8d74851ae4e 100644
--- a/ProcessLib/TH2M/TH2MProcess.cpp
+++ b/ProcessLib/TH2M/TH2MProcess.cpp
@@ -15,7 +15,7 @@
 #include "MeshLib/Elements/Utils.h"
 #include "NumLib/DOF/ComputeSparsityPattern.h"
 #include "ProcessLib/Process.h"
-#include "ProcessLib/TH2M/CreateLocalAssemblers.h"
+#include "ProcessLib/Utils/CreateLocalAssemblersTaylorHood.h"
 #include "TH2MFEM.h"
 #include "TH2MProcessData.h"
 
@@ -158,9 +158,8 @@ void TH2MProcess<DisplacementDim>::initializeConcreteProcess(
     MeshLib::Mesh const& mesh,
     unsigned const integration_order)
 {
-    ProcessLib::TH2M::createLocalAssemblers<DisplacementDim,
-                                            TH2MLocalAssembler>(
-        mesh.getDimension(), mesh.getElements(), dof_table, _local_assemblers,
+    ProcessLib::createLocalAssemblersHM<DisplacementDim, TH2MLocalAssembler>(
+        mesh.getElements(), dof_table, _local_assemblers,
         mesh.isAxiallySymmetric(), integration_order, _process_data);
 
     auto add_secondary_variable = [&](std::string const& name,
diff --git a/ProcessLib/ThermoHydroMechanics/CreateLocalAssemblers.h b/ProcessLib/ThermoHydroMechanics/CreateLocalAssemblers.h
deleted file mode 100644
index d512d6de635..00000000000
--- a/ProcessLib/ThermoHydroMechanics/CreateLocalAssemblers.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/**
- * \file
- * \copyright
- * Copyright (c) 2012-2021, OpenGeoSys Community (http://www.opengeosys.org)
- *            Distributed under a Modified BSD License.
- *              See accompanying file LICENSE.txt or
- *              http://www.opengeosys.org/project/license
- */
-
-#pragma once
-
-#include <vector>
-
-#include "BaseLib/Logging.h"
-#include "NumLib/DOF/LocalToGlobalIndexMap.h"
-#include "ProcessLib/Utils/LocalDataInitializerHM.h"
-
-namespace ProcessLib
-{
-namespace ThermoHydroMechanics
-{
-namespace detail
-{
-template <int GlobalDim,
-          template <typename, typename, typename, int>
-          class LocalAssemblerImplementation,
-          typename LocalAssemblerInterface, typename... ExtraCtorArgs>
-void createLocalAssemblers(
-    NumLib::LocalToGlobalIndexMap const& dof_table,
-    std::vector<MeshLib::Element*> const& mesh_elements,
-    std::vector<std::unique_ptr<LocalAssemblerInterface>>& local_assemblers,
-    ExtraCtorArgs&&... extra_ctor_args)
-{
-    // Shape matrices initializer
-    using LocalDataInitializer =
-        LocalDataInitializerHM<LocalAssemblerInterface,
-                               LocalAssemblerImplementation, GlobalDim,
-                               ExtraCtorArgs...>;
-
-    DBUG("Create local assemblers.");
-    // Populate the vector of local assemblers.
-    local_assemblers.resize(mesh_elements.size());
-
-    LocalDataInitializer initializer(dof_table);
-
-    DBUG("Calling local assembler builder for all mesh elements.");
-    GlobalExecutor::transformDereferenced(
-        initializer, mesh_elements, local_assemblers,
-        std::forward<ExtraCtorArgs>(extra_ctor_args)...);
-}
-
-}  // namespace detail
-
-/*! Creates local assemblers for each element of the given \c mesh.
- *
- * \tparam LocalAssemblerImplementation the individual local assembler type
- * \tparam LocalAssemblerInterface the general local assembler interface
- * \tparam ExtraCtorArgs types of additional constructor arguments.
- *         Those arguments will be passed to the constructor of
- *         \c LocalAssemblerImplementation.
- *
- * The first two template parameters cannot be deduced from the arguments.
- * Therefore they always have to be provided manually.
- */
-template <int GlobalDim,
-          template <typename, typename, typename, int>
-          class LocalAssemblerImplementation,
-          typename LocalAssemblerInterface, typename... ExtraCtorArgs>
-void createLocalAssemblers(
-    const unsigned /*dimension*/,
-    std::vector<MeshLib::Element*> const& mesh_elements,
-    NumLib::LocalToGlobalIndexMap const& dof_table,
-    std::vector<std::unique_ptr<LocalAssemblerInterface>>& local_assemblers,
-    ExtraCtorArgs&&... extra_ctor_args)
-{
-    DBUG("Create local assemblers.");
-
-    detail::createLocalAssemblers<GlobalDim, LocalAssemblerImplementation>(
-        dof_table, mesh_elements, local_assemblers,
-        std::forward<ExtraCtorArgs>(extra_ctor_args)...);
-}
-}  // namespace ThermoHydroMechanics
-
-}  // namespace ProcessLib
diff --git a/ProcessLib/ThermoHydroMechanics/ThermoHydroMechanicsProcess.cpp b/ProcessLib/ThermoHydroMechanics/ThermoHydroMechanicsProcess.cpp
index cc7a4869250..d1fd8f1fded 100644
--- a/ProcessLib/ThermoHydroMechanics/ThermoHydroMechanicsProcess.cpp
+++ b/ProcessLib/ThermoHydroMechanics/ThermoHydroMechanicsProcess.cpp
@@ -15,7 +15,7 @@
 #include "MeshLib/Elements/Utils.h"
 #include "NumLib/DOF/ComputeSparsityPattern.h"
 #include "ProcessLib/Process.h"
-#include "ProcessLib/ThermoHydroMechanics/CreateLocalAssemblers.h"
+#include "ProcessLib/Utils/CreateLocalAssemblersTaylorHood.h"
 #include "ThermoHydroMechanicsFEM.h"
 #include "ThermoHydroMechanicsProcessData.h"
 
@@ -176,9 +176,9 @@ void ThermoHydroMechanicsProcess<DisplacementDim>::initializeConcreteProcess(
     MeshLib::Mesh const& mesh,
     unsigned const integration_order)
 {
-    ProcessLib::ThermoHydroMechanics::createLocalAssemblers<
-        DisplacementDim, ThermoHydroMechanicsLocalAssembler>(
-        mesh.getDimension(), mesh.getElements(), dof_table, _local_assemblers,
+    ProcessLib::createLocalAssemblersHM<DisplacementDim,
+                                        ThermoHydroMechanicsLocalAssembler>(
+        mesh.getElements(), dof_table, _local_assemblers,
         mesh.isAxiallySymmetric(), integration_order, _process_data);
 
     _secondary_variables.addSecondaryVariable(
diff --git a/ProcessLib/ThermoRichardsMechanics/CreateLocalAssemblers.h b/ProcessLib/ThermoRichardsMechanics/CreateLocalAssemblers.h
deleted file mode 100644
index ab62ac3bd7f..00000000000
--- a/ProcessLib/ThermoRichardsMechanics/CreateLocalAssemblers.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/**
- * \file
- * \copyright
- * Copyright (c) 2012-2021, OpenGeoSys Community (http://www.opengeosys.org)
- *            Distributed under a Modified BSD License.
- *              See accompanying file LICENSE.txt or
- *              http://www.opengeosys.org/project/license
- */
-
-#pragma once
-
-#include <vector>
-
-#include "BaseLib/Logging.h"
-#include "NumLib/DOF/LocalToGlobalIndexMap.h"
-#include "ProcessLib/Utils/LocalDataInitializerHM.h"
-
-namespace ProcessLib::ThermoRichardsMechanics
-{
-namespace detail
-{
-template <int GlobalDim,
-          template <typename, typename, typename, int>
-          class LocalAssemblerImplementation,
-          typename LocalAssemblerInterface, typename... ExtraCtorArgs>
-void createLocalAssemblers(
-    NumLib::LocalToGlobalIndexMap const& dof_table,
-    std::vector<MeshLib::Element*> const& mesh_elements,
-    std::vector<std::unique_ptr<LocalAssemblerInterface>>& local_assemblers,
-    ExtraCtorArgs&&... extra_ctor_args)
-{
-    // Shape matrices initializer
-    using LocalDataInitializer =
-        LocalDataInitializerHM<LocalAssemblerInterface,
-                               LocalAssemblerImplementation, GlobalDim,
-                               ExtraCtorArgs...>;
-
-    DBUG("Create local assemblers.");
-    // Populate the vector of local assemblers.
-    local_assemblers.resize(mesh_elements.size());
-
-    LocalDataInitializer initializer(dof_table);
-
-    DBUG("Calling local assembler builder for all mesh elements.");
-    GlobalExecutor::transformDereferenced(
-        initializer, mesh_elements, local_assemblers,
-        std::forward<ExtraCtorArgs>(extra_ctor_args)...);
-}
-
-}  // namespace detail
-
-/*! Creates local assemblers for each element of the given \c mesh.
- *
- * \tparam LocalAssemblerImplementation the individual local assembler type
- * \tparam LocalAssemblerInterface the general local assembler interface
- * \tparam ExtraCtorArgs types of additional constructor arguments.
- *         Those arguments will be passed to the constructor of
- *         \c LocalAssemblerImplementation.
- *
- * The first two template parameters cannot be deduced from the arguments.
- * Therefore they always have to be provided manually.
- */
-template <int GlobalDim,
-          template <typename, typename, typename, int>
-          class LocalAssemblerImplementation,
-          typename LocalAssemblerInterface, typename... ExtraCtorArgs>
-void createLocalAssemblers(
-    const unsigned /*dimension*/,
-    std::vector<MeshLib::Element*> const& mesh_elements,
-    NumLib::LocalToGlobalIndexMap const& dof_table,
-    std::vector<std::unique_ptr<LocalAssemblerInterface>>& local_assemblers,
-    ExtraCtorArgs&&... extra_ctor_args)
-{
-    DBUG("Create local assemblers.");
-
-    detail::createLocalAssemblers<GlobalDim, LocalAssemblerImplementation>(
-        dof_table, mesh_elements, local_assemblers,
-        std::forward<ExtraCtorArgs>(extra_ctor_args)...);
-}
-}  // namespace ProcessLib::ThermoRichardsMechanics
diff --git a/ProcessLib/ThermoRichardsMechanics/ThermoRichardsMechanicsProcess.cpp b/ProcessLib/ThermoRichardsMechanics/ThermoRichardsMechanicsProcess.cpp
index cedca58f259..1bc652a2c02 100644
--- a/ProcessLib/ThermoRichardsMechanics/ThermoRichardsMechanicsProcess.cpp
+++ b/ProcessLib/ThermoRichardsMechanics/ThermoRichardsMechanicsProcess.cpp
@@ -13,11 +13,11 @@
 #include <cassert>
 
 #include "BaseLib/Error.h"
-#include "CreateLocalAssemblers.h"
 #include "MeshLib/Elements/Utils.h"
 #include "NumLib/DOF/ComputeSparsityPattern.h"
 #include "ProcessLib/Deformation/SolidMaterialInternalToSecondaryVariables.h"
 #include "ProcessLib/Process.h"
+#include "ProcessLib/Utils/CreateLocalAssemblersTaylorHood.h"
 #include "ThermoRichardsMechanicsFEM.h"
 
 namespace ProcessLib
@@ -154,9 +154,9 @@ void ThermoRichardsMechanicsProcess<DisplacementDim>::initializeConcreteProcess(
     MeshLib::Mesh const& mesh,
     unsigned const integration_order)
 {
-    createLocalAssemblers<DisplacementDim,
-                          ThermoRichardsMechanicsLocalAssembler>(
-        mesh.getDimension(), mesh.getElements(), dof_table, local_assemblers_,
+    createLocalAssemblersHM<DisplacementDim,
+                            ThermoRichardsMechanicsLocalAssembler>(
+        mesh.getElements(), dof_table, local_assemblers_,
         mesh.isAxiallySymmetric(), integration_order, process_data_);
 
     auto add_secondary_variable = [&](std::string const& name,
diff --git a/ProcessLib/Utils/CreateLocalAssemblersTaylorHood.h b/ProcessLib/Utils/CreateLocalAssemblersTaylorHood.h
new file mode 100644
index 00000000000..e20b7535449
--- /dev/null
+++ b/ProcessLib/Utils/CreateLocalAssemblersTaylorHood.h
@@ -0,0 +1,120 @@
+/**
+ * \file
+ * \copyright
+ * Copyright (c) 2012-2021, OpenGeoSys Community (http://www.opengeosys.org)
+ *            Distributed under a Modified BSD License.
+ *              See accompanying file LICENSE.txt or
+ *              http://www.opengeosys.org/project/license
+ *
+ */
+
+#pragma once
+
+#include <vector>
+
+#include "BaseLib/Logging.h"
+#include "LocalAssemblerFactoryTaylorHoodForOrderGeN.h"
+#include "NumLib/DOF/LocalToGlobalIndexMap.h"
+
+namespace ProcessLib
+{
+namespace detail
+{
+template <typename LocalAssemblerFactory, int GlobalDim,
+          template <typename, typename, typename, int>
+          class LocalAssemblerImplementation,
+          typename LocalAssemblerInterface, typename... ExtraCtorArgs>
+void createLocalAssemblersTaylorHood(
+    std::vector<MeshLib::Element*> const& mesh_elements,
+    NumLib::LocalToGlobalIndexMap const& dof_table,
+    std::vector<std::unique_ptr<LocalAssemblerInterface>>& local_assemblers,
+    ExtraCtorArgs&&... extra_ctor_args)
+{
+    DBUG("Create local assemblers.");
+
+    LocalAssemblerFactory factory(dof_table);
+    local_assemblers.resize(mesh_elements.size());
+
+    DBUG("Calling local assembler builder for all mesh elements.");
+    GlobalExecutor::transformDereferenced(
+        factory, mesh_elements, local_assemblers,
+        std::forward<ExtraCtorArgs>(extra_ctor_args)...);
+}
+
+/*! Creates local assemblers for each element of the given \c mesh.
+ *
+ * \tparam LocalAssemblerFactory the factory that will instantiate the local
+ *         assemblers
+ * \tparam LocalAssemblerImplementation the individual local assembler type
+ * \tparam LocalAssemblerInterface the general local assembler interface
+ * \tparam ExtraCtorArgs types of additional constructor arguments.
+ *         Those arguments will be passed to the constructor of
+ *         \c LocalAssemblerImplementation.
+ */
+template <template <typename /*LocalAssemblerInterface*/,
+                    template <typename /* shp fct */,
+                              typename /* lower order shp fct */,
+                              typename /* int meth */, int /* global dim */>
+                    class /*LocalAssemblerImplementation*/,
+                    int /* global dim */, typename... /*ConstructorArgs*/>
+          class LocalAssemblerFactory,
+          int GlobalDim,
+          template <typename /* shp fct */, typename /* lower order shp fct */,
+                    typename /* int meth */, int /* global dim */>
+          class LocalAssemblerImplementation,
+          typename LocalAssemblerInterface, typename... ExtraCtorArgs>
+void createLocalAssemblersTaylorHood(
+    std::vector<MeshLib::Element*> const& mesh_elements,
+    NumLib::LocalToGlobalIndexMap const& dof_table,
+    std::vector<std::unique_ptr<LocalAssemblerInterface>>& local_assemblers,
+    ExtraCtorArgs&&... extra_ctor_args)
+{
+    DBUG("Create local assemblers.");
+
+    createLocalAssemblersTaylorHood<
+        LocalAssemblerFactory<LocalAssemblerInterface,
+                              LocalAssemblerImplementation, GlobalDim,
+                              ExtraCtorArgs...>,
+        GlobalDim, LocalAssemblerImplementation>(
+        mesh_elements, dof_table, local_assemblers,
+        std::forward<ExtraCtorArgs>(extra_ctor_args)...);
+}
+}  // namespace detail
+
+template <int GlobalDim,
+          template <typename /* shp fct */, typename /* lower order shp fct */,
+                    typename /* int meth */, int /* global dim */>
+          class LocalAssemblerImplementation,
+          typename LocalAssemblerInterface, typename... ExtraCtorArgs>
+void createLocalAssemblersHM(
+    std::vector<MeshLib::Element*> const& mesh_elements,
+    NumLib::LocalToGlobalIndexMap const& dof_table,
+    std::vector<std::unique_ptr<LocalAssemblerInterface>>& local_assemblers,
+    ExtraCtorArgs&&... extra_ctor_args)
+{
+    detail::createLocalAssemblersTaylorHood<LocalAssemblerFactoryHM, GlobalDim,
+                                            LocalAssemblerImplementation,
+                                            LocalAssemblerInterface>(
+        mesh_elements, dof_table, local_assemblers,
+        std::forward<ExtraCtorArgs>(extra_ctor_args)...);
+}
+
+template <int GlobalDim,
+          template <typename /* shp fct */, typename /* lower order shp fct */,
+                    typename /* int meth */, int /* global dim */>
+          class LocalAssemblerImplementation,
+          typename LocalAssemblerInterface, typename... ExtraCtorArgs>
+void createLocalAssemblersStokes(
+    std::vector<MeshLib::Element*> const& mesh_elements,
+    NumLib::LocalToGlobalIndexMap const& dof_table,
+    std::vector<std::unique_ptr<LocalAssemblerInterface>>& local_assemblers,
+    ExtraCtorArgs&&... extra_ctor_args)
+{
+    detail::createLocalAssemblersTaylorHood<
+        LocalAssemblerFactoryStokes, GlobalDim, LocalAssemblerImplementation,
+        LocalAssemblerInterface>(
+        mesh_elements, dof_table, local_assemblers,
+        std::forward<ExtraCtorArgs>(extra_ctor_args)...);
+}
+
+}  // namespace ProcessLib
-- 
GitLab