diff --git a/Applications/ApplicationsLib/ProjectData.cpp b/Applications/ApplicationsLib/ProjectData.cpp
index 58c6ff0169443a8a9eceece6b25d7dee7db5017d..ad78dd94513b33841626e7f1ac5ee906af3dd2d2 100644
--- a/Applications/ApplicationsLib/ProjectData.cpp
+++ b/Applications/ApplicationsLib/ProjectData.cpp
@@ -330,8 +330,7 @@ void ProjectData::parseTimeStepping(BaseLib::ConfigTree const& timestepping_conf
 {
     DBUG("Reading time loop configuration.");
 
-    _time_loop = ApplicationsLib::createUncoupledProcessesTimeLoop<
-        GlobalMatrix, GlobalVector>(timestepping_config);
+    _time_loop = ApplicationsLib::createUncoupledProcessesTimeLoop(timestepping_config);
 
     if (!_time_loop)
     {
@@ -372,7 +371,7 @@ void ProjectData::parseNonlinearSolvers(BaseLib::ConfigTree const& config)
         auto const name = conf.getConfigParameter<std::string>("name");
         BaseLib::insertIfKeyUniqueElseError(_nonlinear_solvers,
             name,
-            NumLib::createNonlinearSolver<GlobalMatrix, GlobalVector>(
+            NumLib::createNonlinearSolver(
                 *linear_solver, conf).first,
             "The nonlinear solver name is not unique");
     }
diff --git a/Applications/ApplicationsLib/ProjectData.h b/Applications/ApplicationsLib/ProjectData.h
index 9d5abda1704d66154d445d199698f6fbe3ab79b9..9397f5a75e6d918fa4fad2eeb22af6e0006b35ce 100644
--- a/Applications/ApplicationsLib/ProjectData.h
+++ b/Applications/ApplicationsLib/ProjectData.h
@@ -44,7 +44,6 @@ class NonlinearSolverBase;
 
 namespace ApplicationsLib
 {
-template<typename Matrix, typename Vector>
 class UncoupledProcessesTimeLoop;
 }
 
@@ -57,8 +56,7 @@ class ProjectData final
 {
 public:
     /// The time loop type used to solve this project's processes.
-    using TimeLoop = ApplicationsLib::UncoupledProcessesTimeLoop<
-        GlobalMatrix, GlobalVector>;
+    using TimeLoop = ApplicationsLib::UncoupledProcessesTimeLoop;
 
     /// The empty constructor used in the gui, for example, when the project's
     /// configuration is not loaded yet.
diff --git a/Applications/ApplicationsLib/UncoupledProcessesTimeLoop.h b/Applications/ApplicationsLib/UncoupledProcessesTimeLoop.h
index 2ce2b8a2c37dbc30ad6293408b8bf1ddd0fa5db3..dfa7cf00d44c425d6c79b9dc4a86b453f6d1d6f7 100644
--- a/Applications/ApplicationsLib/UncoupledProcessesTimeLoop.h
+++ b/Applications/ApplicationsLib/UncoupledProcessesTimeLoop.h
@@ -26,7 +26,6 @@ namespace ApplicationsLib
 {
 
 //! Time loop capable of time-integrating several uncoupled processes at once.
-template<typename Matrix, typename Vector>
 class UncoupledProcessesTimeLoop
 {
 public:
@@ -41,28 +40,28 @@ public:
 
 private:
     //! An abstract nonlinear solver
-    using AbstractNLSolver = NumLib::NonlinearSolverBase<Matrix, Vector>;
+    using AbstractNLSolver = NumLib::NonlinearSolverBase<GlobalMatrix, GlobalVector>;
     //! An abstract equations system
-    using EquationSystem   = NumLib::EquationSystem<Vector>;
+    using EquationSystem   = NumLib::EquationSystem<GlobalVector>;
     //! An abstract process
     using Process          = ProcessLib::Process;
     //! An abstract time discretization
-    using TimeDisc         = NumLib::TimeDiscretization<Vector>;
+    using TimeDisc         = NumLib::TimeDiscretization<GlobalVector>;
 
-    std::vector<Vector*> _process_solutions;
+    std::vector<GlobalVector*> _process_solutions;
     std::unique_ptr<NumLib::ITimeStepAlgorithm> _timestepper;
 
     struct SingleProcessData
     {
         template<NumLib::ODESystemTag ODETag, NumLib::NonlinearSolverTag NLTag>
         SingleProcessData(
-                NumLib::NonlinearSolver<Matrix, Vector, NLTag>& nonlinear_solver,
+                NumLib::NonlinearSolver<GlobalMatrix, GlobalVector, NLTag>& nonlinear_solver,
                 TimeDisc& time_disc,
-                NumLib::ODESystem<Matrix, Vector, ODETag, NLTag>& ode_sys)
+                NumLib::ODESystem<GlobalMatrix, GlobalVector, ODETag, NLTag>& ode_sys)
             : nonlinear_solver_tag(NLTag)
             , nonlinear_solver(nonlinear_solver)
             , tdisc_ode_sys(
-                  new NumLib::TimeDiscretizedODESystem<Matrix, Vector, ODETag, NLTag>(
+                  new NumLib::TimeDiscretizedODESystem<GlobalMatrix, GlobalVector, ODETag, NLTag>(
                                 ode_sys, time_disc))
             , mat_strg(dynamic_cast<NumLib::InternalMatrixStorage&>(*tdisc_ode_sys))
         {}
@@ -94,7 +93,7 @@ private:
      *
      * \note Currently the \c ODETag is automatically inferred from the given
      *       \c ody_sys. This works as long as \c Process derives from
-     *       \c ODESystem<Matrix, Vector, ODETag>, i.e. as long we only deal with
+     *       \c ODESystem<Matrix, GlobalVector, ODETag>, i.e. as long we only deal with
      *       one type of ODE. When we introduce more types, this method will have
      *       to be extended slightly.
      */
@@ -102,17 +101,17 @@ private:
     SingleProcessData
     makeSingleProcessData(
             AbstractNLSolver& nonlinear_solver,
-            NumLib::ODESystem<Matrix, Vector, ODETag,
+            NumLib::ODESystem<GlobalMatrix, GlobalVector, ODETag,
                 NumLib::NonlinearSolverTag::Picard>& ode_sys,
             TimeDisc& time_disc)
     {
         using Tag = NumLib::NonlinearSolverTag;
         // A concrete Picard solver
         using NonlinearSolverPicard =
-            NumLib::NonlinearSolver<Matrix, Vector, Tag::Picard>;
+            NumLib::NonlinearSolver<GlobalMatrix, GlobalVector, Tag::Picard>;
         // A concrete Newton solver
         using NonlinearSolverNewton =
-            NumLib::NonlinearSolver<Matrix, Vector, Tag::Newton>;
+            NumLib::NonlinearSolver<GlobalMatrix, GlobalVector, Tag::Newton>;
 
         if (auto* nonlinear_solver_picard =
             dynamic_cast<NonlinearSolverPicard*>(&nonlinear_solver))
@@ -129,7 +128,7 @@ private:
         {
             // The Newton-Raphson method needs a Newton-ready ODE.
 
-            using ODENewton = NumLib::ODESystem<Matrix, Vector, ODETag, Tag::Newton>;
+            using ODENewton = NumLib::ODESystem<GlobalMatrix, GlobalVector, ODETag, Tag::Newton>;
             if (auto* ode_newton = dynamic_cast<ODENewton*>(&ode_sys))
             {
                 return SingleProcessData{
@@ -156,7 +155,7 @@ private:
 
     //! Solves one timestep for the given \c process.
     bool solveOneTimeStepOneProcess(
-            Vector& x, double const t, double const delta_t,
+            GlobalVector& x, double const t, double const delta_t,
             SingleProcessData& process_data,
             Process& process);
 
@@ -166,8 +165,8 @@ private:
     static void setEquationSystem(AbstractNLSolver& nonlinear_solver,
                                   EquationSystem& eq_sys)
     {
-        using Solver = NumLib::NonlinearSolver<Matrix, Vector, NLTag>;
-        using EqSys  = NumLib::NonlinearSystem<Matrix, Vector, NLTag>;
+        using Solver = NumLib::NonlinearSolver<GlobalMatrix, GlobalVector, NLTag>;
+        using EqSys  = NumLib::NonlinearSystem<GlobalMatrix, GlobalVector, NLTag>;
 
         assert(dynamic_cast<Solver*>(&nonlinear_solver) != nullptr);
         assert(dynamic_cast<EqSys*> (&eq_sys) != nullptr);
@@ -200,9 +199,9 @@ private:
     //! for equation systems linearized with either the Picard or Newton method.
     template<NumLib::NonlinearSolverTag NLTag>
     static void applyKnownSolutions(
-            EquationSystem const& eq_sys, Vector& x)
+            EquationSystem const& eq_sys, GlobalVector& x)
     {
-        using EqSys = NumLib::NonlinearSystem<Matrix, Vector, NLTag>;
+        using EqSys = NumLib::NonlinearSystem<GlobalMatrix, GlobalVector, NLTag>;
         assert(dynamic_cast<EqSys const*> (&eq_sys) != nullptr);
         auto& eq_sys_ = static_cast<EqSys const&> (eq_sys);
 
@@ -213,7 +212,7 @@ private:
     //! for equation systems linearized with either the Picard or Newton method.
     static void applyKnownSolutions(
             EquationSystem const& eq_sys,
-            NumLib::NonlinearSolverTag const nl_tag, Vector& x)
+            NumLib::NonlinearSolverTag const nl_tag, GlobalVector& x)
     {
         using Tag = NumLib::NonlinearSolverTag;
         switch (nl_tag)
@@ -225,8 +224,7 @@ private:
 };
 
 //! Builds an UncoupledProcessesTimeLoop from the given configuration.
-template<typename Matrix, typename Vector>
-std::unique_ptr<UncoupledProcessesTimeLoop<Matrix, Vector> >
+inline std::unique_ptr<UncoupledProcessesTimeLoop>
 createUncoupledProcessesTimeLoop(BaseLib::ConfigTree const& conf)
 {
     //! \ogs_file_param{prj__time_stepping__type}
@@ -243,14 +241,13 @@ createUncoupledProcessesTimeLoop(BaseLib::ConfigTree const& conf)
             OGS_FATAL("Unknown timestepper type: `%s'.", type.c_str());
     }
 
-    using TimeLoop = UncoupledProcessesTimeLoop<Matrix, Vector>;
+    using TimeLoop = UncoupledProcessesTimeLoop;
     return std::unique_ptr<TimeLoop>{new TimeLoop{std::move(timestepper)}};
 }
 
 
-template<typename Matrix, typename Vector>
-std::vector<typename UncoupledProcessesTimeLoop<Matrix, Vector>::SingleProcessData>
-UncoupledProcessesTimeLoop<Matrix, Vector>::
+inline std::vector<typename UncoupledProcessesTimeLoop::SingleProcessData>
+UncoupledProcessesTimeLoop::
 initInternalData(ProjectData& project)
 {
     auto const num_processes = std::distance(project.processesBegin(),
@@ -274,9 +271,8 @@ initInternalData(ProjectData& project)
 }
 
 
-template<typename Matrix, typename Vector>
-void
-UncoupledProcessesTimeLoop<Matrix, Vector>::
+inline void
+UncoupledProcessesTimeLoop::
 setInitialConditions(ProjectData& project,
                      double const t0,
                      std::vector<SingleProcessData>& per_process_data)
@@ -299,7 +295,7 @@ setInitialConditions(ProjectData& project,
 
         // append a solution vector of suitable size
         _process_solutions.emplace_back(
-                    &MathLib::GlobalVectorProvider<Vector>::provider.getVector(
+                    &MathLib::GlobalVectorProvider<GlobalVector>::provider.getVector(
                         ode_sys.getMatrixSpecifications()));
 
         auto& x0 = *_process_solutions[pcs_idx];
@@ -321,13 +317,12 @@ setInitialConditions(ProjectData& project,
 }
 
 
-template<typename Matrix, typename Vector>
-bool
-UncoupledProcessesTimeLoop<Matrix, Vector>::
+inline bool
+UncoupledProcessesTimeLoop::
 solveOneTimeStepOneProcess(
-        Vector& x, double const t, double const delta_t,
+        GlobalVector& x, double const t, double const delta_t,
         SingleProcessData& process_data,
-        typename UncoupledProcessesTimeLoop<Matrix, Vector>::Process& process)
+        typename UncoupledProcessesTimeLoop::Process& process)
 {
     auto& time_disc        =  process.getTimeDiscretization();
     auto& ode_sys          = *process_data.tdisc_ode_sys;
@@ -358,9 +353,8 @@ solveOneTimeStepOneProcess(
 }
 
 
-template<typename Matrix, typename Vector>
-bool
-UncoupledProcessesTimeLoop<Matrix, Vector>::
+inline bool
+UncoupledProcessesTimeLoop::
 loop(ProjectData& project)
 {
     auto per_process_data = initInternalData(project);
@@ -440,12 +434,11 @@ loop(ProjectData& project)
 }
 
 
-template<typename Matrix, typename Vector>
-UncoupledProcessesTimeLoop<Matrix, Vector>::
+inline UncoupledProcessesTimeLoop::
 ~UncoupledProcessesTimeLoop()
 {
     for (auto * x : _process_solutions)
-        MathLib::GlobalVectorProvider<Vector>::provider.releaseVector(*x);
+        MathLib::GlobalVectorProvider<GlobalVector>::provider.releaseVector(*x);
 }
 
 } // namespace ApplicationsLib
diff --git a/NumLib/Assembler/VectorMatrixAssembler.h b/NumLib/Assembler/VectorMatrixAssembler.h
index 1a0433a8985f674a5250f6b0645844a97883453b..99e682e32c1b47f02cb0287c172b13a02fd839f0 100644
--- a/NumLib/Assembler/VectorMatrixAssembler.h
+++ b/NumLib/Assembler/VectorMatrixAssembler.h
@@ -37,8 +37,7 @@ getIndices(std::size_t const id,
     return indices;
 }
 
-template <typename GlobalVector>
-std::vector<double>
+inline std::vector<double>
 getLocalNodalDOFs(GlobalVector const& x,
                   std::vector<GlobalIndexType> const& dof_indices)
 {
@@ -64,15 +63,14 @@ getLocalNodalDOFs(GlobalVector const& x,
  * Each type of equation as flagged by the \c ODETag will have a different
  * VectorMatrixAssembler type.
  */
-template<typename GlobalMatrix, typename GlobalVector,
-         typename LocalAssembler,
+template<typename LocalAssembler,
          NumLib::ODESystemTag ODETag>
 class VectorMatrixAssembler;
 
 
 //! Specialization for first-order implicit quasi-linear systems.
-template<typename GlobalMatrix, typename GlobalVector, typename LocalAssembler>
-class VectorMatrixAssembler<GlobalMatrix, GlobalVector, LocalAssembler,
+template<typename LocalAssembler>
+class VectorMatrixAssembler<LocalAssembler,
         NumLib::ODESystemTag::FirstOrderImplicitQuasilinear> final
 {
 public:
@@ -167,8 +165,8 @@ private:
 
 
 //! Specialization used to add Neumann boundary conditions.
-template<typename GlobalMatrix, typename GlobalVector, typename LocalAssembler>
-class VectorMatrixAssembler<GlobalMatrix, GlobalVector, LocalAssembler,
+template<typename LocalAssembler>
+class VectorMatrixAssembler<LocalAssembler,
         NumLib::ODESystemTag::NeumannBC> final
 {
 public:
diff --git a/NumLib/Extrapolation/Extrapolator.h b/NumLib/Extrapolation/Extrapolator.h
index 797012aab204eaf33e53bc226da1eaf4d03dcd7e..da8ebe315085e29f0cc6d9c21df9284d0efcc714 100644
--- a/NumLib/Extrapolation/Extrapolator.h
+++ b/NumLib/Extrapolation/Extrapolator.h
@@ -21,11 +21,10 @@ namespace NumLib
  * Local assemblers that want to have some integration point values extrapolated
  * using Extrapolator have to implement this interface.
  *
- * \tparam GlobalVector type of the global vector
  * \tparam PropertyTag  type of the property used to query a specific kind of
  *                      integration point value, usually an enum.
  */
-template <typename GlobalVector, typename PropertyTag>
+template <typename PropertyTag>
 class Extrapolatable
 {
 public:
@@ -55,13 +54,12 @@ public:
 /*! Interface for classes that extrapolate integration point values to nodal
  *  values.
  *
- * \tparam GlobalVector   type of the global vector
  * \tparam PropertyTag    type of the property used to query a specific kind of
  *                        integration point value, usually an enum.
  * \tparam LocalAssembler type of the local assembler being queried for
  *                        integration point values.
  */
-template<typename GlobalVector, typename PropertyTag, typename LocalAssembler>
+template<typename PropertyTag, typename LocalAssembler>
 class Extrapolator
 {
 public:
diff --git a/NumLib/Extrapolation/LocalLinearLeastSquaresExtrapolator-impl.h b/NumLib/Extrapolation/LocalLinearLeastSquaresExtrapolator-impl.h
index 9215984c16f18c4b77dea9e879bdc4287b16537b..b95f39cb29127f7ebb503293b209ea1ce25a664a 100644
--- a/NumLib/Extrapolation/LocalLinearLeastSquaresExtrapolator-impl.h
+++ b/NumLib/Extrapolation/LocalLinearLeastSquaresExtrapolator-impl.h
@@ -21,9 +21,9 @@
 namespace NumLib
 {
 
-template<typename GlobalVector, typename PropertyTag, typename LocalAssembler>
+template<typename PropertyTag, typename LocalAssembler>
 void
-LocalLinearLeastSquaresExtrapolator<GlobalVector, PropertyTag, LocalAssembler>::
+LocalLinearLeastSquaresExtrapolator<PropertyTag, LocalAssembler>::
 extrapolate(LocalAssemblers const& local_assemblers, PropertyTag const property)
 {
     _nodal_values.setZero();
@@ -35,7 +35,7 @@ extrapolate(LocalAssemblers const& local_assemblers, PropertyTag const property)
     counts->setZero(); // TODO BLAS?
 
     using Self = LocalLinearLeastSquaresExtrapolator<
-        GlobalVector, PropertyTag, LocalAssembler>;
+        PropertyTag, LocalAssembler>;
 
     NumLib::SerialExecutor::executeMemberDereferenced(
         *this, &Self::extrapolateElement, local_assemblers, property, *counts);
@@ -43,24 +43,24 @@ extrapolate(LocalAssemblers const& local_assemblers, PropertyTag const property)
     MathLib::BLAS::componentwiseDivide(_nodal_values, _nodal_values, *counts);
 }
 
-template<typename GlobalVector, typename PropertyTag, typename LocalAssembler>
+template<typename PropertyTag, typename LocalAssembler>
 void
-LocalLinearLeastSquaresExtrapolator<GlobalVector, PropertyTag, LocalAssembler>::
+LocalLinearLeastSquaresExtrapolator<PropertyTag, LocalAssembler>::
 calculateResiduals(LocalAssemblers const& local_assemblers,
                    PropertyTag const property)
 {
     assert(static_cast<std::size_t>(_residuals.size()) == local_assemblers.size());
 
     using Self = LocalLinearLeastSquaresExtrapolator<
-        GlobalVector, PropertyTag, LocalAssembler>;
+        PropertyTag, LocalAssembler>;
 
     NumLib::SerialExecutor::executeMemberDereferenced(
         *this, &Self::calculateResiudalElement, local_assemblers, property);
 }
 
-template<typename GlobalVector, typename PropertyTag, typename LocalAssembler>
+template<typename PropertyTag, typename LocalAssembler>
 void
-LocalLinearLeastSquaresExtrapolator<GlobalVector, PropertyTag, LocalAssembler>::
+LocalLinearLeastSquaresExtrapolator<PropertyTag, LocalAssembler>::
 extrapolateElement(std::size_t const element_index,
                    LocalAssembler const& loc_asm, PropertyTag const property,
                    GlobalVector& counts)
@@ -115,9 +115,9 @@ extrapolateElement(std::size_t const element_index,
     counts.add(global_indices, std::vector<double>(global_indices.size(), 1.0));
 }
 
-template<typename GlobalVector, typename PropertyTag, typename LocalAssembler>
+template<typename PropertyTag, typename LocalAssembler>
 void
-LocalLinearLeastSquaresExtrapolator<GlobalVector, PropertyTag, LocalAssembler>::
+LocalLinearLeastSquaresExtrapolator<PropertyTag, LocalAssembler>::
 calculateResiudalElement(std::size_t const element_index,
                          LocalAssembler const& loc_asm, PropertyTag const property)
 {
diff --git a/NumLib/Extrapolation/LocalLinearLeastSquaresExtrapolator.h b/NumLib/Extrapolation/LocalLinearLeastSquaresExtrapolator.h
index a2f2e363b96c17a7475dc600324c4670195d1701..cfa1a4f54eeb4c8d4abfd32817b2e19c6e915508 100644
--- a/NumLib/Extrapolation/LocalLinearLeastSquaresExtrapolator.h
+++ b/NumLib/Extrapolation/LocalLinearLeastSquaresExtrapolator.h
@@ -34,13 +34,13 @@ namespace NumLib
  * use of the least squares which requires an exact or overdetermined equation system.
  * \endparblock
  */
-template<typename GlobalVector, typename PropertyTag, typename LocalAssembler>
+template<typename PropertyTag, typename LocalAssembler>
 class LocalLinearLeastSquaresExtrapolator
-        : public Extrapolator<GlobalVector, PropertyTag, LocalAssembler>
+        : public Extrapolator<PropertyTag, LocalAssembler>
 {
 public:
     using LocalAssemblers = typename Extrapolator<
-        GlobalVector, PropertyTag, LocalAssembler>::LocalAssemblers;
+        PropertyTag, LocalAssembler>::LocalAssemblers;
 
     /*! Constructs a new instance
      *
diff --git a/ProcessLib/GroundwaterFlow/GroundwaterFlowFEM.h b/ProcessLib/GroundwaterFlow/GroundwaterFlowFEM.h
index aa2d57f99cf2967f93304e4a91d65b7bc125b578..4f21fdc34310f2970b1c79d8c58258f09c26c35a 100644
--- a/ProcessLib/GroundwaterFlow/GroundwaterFlowFEM.h
+++ b/ProcessLib/GroundwaterFlow/GroundwaterFlowFEM.h
@@ -34,19 +34,16 @@ enum class IntegrationPointValue {
 
 const unsigned NUM_NODAL_DOF = 1;
 
-template <typename GlobalMatrix, typename GlobalVector>
 class GroundwaterFlowLocalAssemblerInterface
-        : public ProcessLib::LocalAssemblerInterface<GlobalMatrix, GlobalVector>
-        , public NumLib::Extrapolatable<GlobalVector, IntegrationPointValue>
+        : public ProcessLib::LocalAssemblerInterface
+        , public NumLib::Extrapolatable<IntegrationPointValue>
 {};
 
 template <typename ShapeFunction,
          typename IntegrationMethod,
-         typename GlobalMatrix,
-         typename GlobalVector,
          unsigned GlobalDim>
 class LocalAssemblerData
-        : public GroundwaterFlowLocalAssemblerInterface<GlobalMatrix, GlobalVector>
+        : public GroundwaterFlowLocalAssemblerInterface
 {
     using ShapeMatricesType = ShapeMatrixPolicyType<ShapeFunction, GlobalDim>;
     using ShapeMatrices = typename ShapeMatricesType::ShapeMatrices;
diff --git a/ProcessLib/GroundwaterFlow/GroundwaterFlowProcess.h b/ProcessLib/GroundwaterFlow/GroundwaterFlowProcess.h
index d5d2610ba9c27fee1d990ba4478231ea5aa9c9a3..9e87b15f72b576bb1add50dc069e934dbec4b89f 100644
--- a/ProcessLib/GroundwaterFlow/GroundwaterFlowProcess.h
+++ b/ProcessLib/GroundwaterFlow/GroundwaterFlowProcess.h
@@ -38,8 +38,8 @@ public:
         std::unique_ptr<Base::TimeDiscretization>&& time_discretization,
         std::vector<std::reference_wrapper<ProcessVariable>>&& process_variables,
         GroundwaterFlowProcessData&& process_data,
-        SecondaryVariableCollection<GlobalVector>&& secondary_variables,
-        ProcessOutput<GlobalVector>&& process_output
+        SecondaryVariableCollection&& secondary_variables,
+        ProcessOutput&& process_output
         )
         : Process(mesh, nonlinear_solver, std::move(time_discretization),
                                std::move(process_variables),
@@ -72,16 +72,16 @@ public:
 
 private:
     using LocalAssemblerInterface =
-        GroundwaterFlowLocalAssemblerInterface<GlobalMatrix, GlobalVector>;
+        GroundwaterFlowLocalAssemblerInterface;
 
     using GlobalAssembler = NumLib::VectorMatrixAssembler<
-            GlobalMatrix, GlobalVector, LocalAssemblerInterface,
+            LocalAssemblerInterface,
             NumLib::ODESystemTag::FirstOrderImplicitQuasilinear>;
 
     using ExtrapolatorInterface = NumLib::Extrapolator<
-        GlobalVector, IntegrationPointValue, LocalAssemblerInterface>;
+        IntegrationPointValue, LocalAssemblerInterface>;
     using ExtrapolatorImplementation = NumLib::LocalLinearLeastSquaresExtrapolator<
-        GlobalVector, IntegrationPointValue, LocalAssemblerInterface>;
+        IntegrationPointValue, LocalAssemblerInterface>;
 
     void initializeConcreteProcess(
             NumLib::LocalToGlobalIndexMap const& dof_table,
@@ -175,7 +175,7 @@ createGroundwaterFlowProcess(
         hydraulic_conductivity
     };
 
-    SecondaryVariableCollection<GlobalVector> secondary_variables {
+    SecondaryVariableCollection secondary_variables {
         //! \ogs_file_param{process__secondary_variables}
         config.getConfigSubtreeOptional("secondary_variables"),
         {
@@ -188,7 +188,7 @@ createGroundwaterFlowProcess(
         }
     };
 
-    ProcessOutput<GlobalVector>
+    ProcessOutput
         //! \ogs_file_param{process__output}
         process_output{config.getConfigSubtree("output"),
                 process_variables, secondary_variables};
diff --git a/ProcessLib/LocalAssemblerInterface.h b/ProcessLib/LocalAssemblerInterface.h
index 338faa9376d3a32c70a3d5a8bd299b05496c3c37..8c43b50380a754a2b0c2c9befe8ee103ae8494b0 100644
--- a/ProcessLib/LocalAssemblerInterface.h
+++ b/ProcessLib/LocalAssemblerInterface.h
@@ -18,7 +18,6 @@ namespace ProcessLib
  *
  * \todo Generalize to other NumLib::ODESystemTag's.
  */
-template <typename GlobalMatrix, typename GlobalVector>
 class LocalAssemblerInterface
 {
 public:
diff --git a/ProcessLib/NeumannBc.h b/ProcessLib/NeumannBc.h
index c666ec4787b65e53d09b3a21da5afcf56290ff5f..f034a3d99a50dd0982ad6e81ffa818904c2cd99b 100644
--- a/ProcessLib/NeumannBc.h
+++ b/ProcessLib/NeumannBc.h
@@ -138,12 +138,11 @@ private:
     /// the #_function.
     unsigned const _integration_order;
 
-    using LocalAssembler = LocalNeumannBcAsmDataInterface<
-        GlobalMatrix, GlobalVector>;
+    using LocalAssembler = LocalNeumannBcAsmDataInterface;
 
     using GlobalAssembler =
         NumLib::VectorMatrixAssembler<
-            GlobalMatrix, GlobalVector, LocalAssembler,
+            LocalAssembler,
             NumLib::ODESystemTag::NeumannBC>;
 
     std::unique_ptr<GlobalAssembler> _global_assembler;
diff --git a/ProcessLib/NeumannBcAssembler.h b/ProcessLib/NeumannBcAssembler.h
index 9da05d9453cb0553ee3b87651ef6a405b20fb035..1e13a3996f075c5180bd3052f2637954620006f3 100644
--- a/ProcessLib/NeumannBcAssembler.h
+++ b/ProcessLib/NeumannBcAssembler.h
@@ -19,7 +19,6 @@
 namespace ProcessLib
 {
 
-template <typename GlobalMatrix, typename GlobalVector>
 class LocalNeumannBcAsmDataInterface
 {
 public:
@@ -33,10 +32,8 @@ public:
 
 template <typename ShapeFunction_,
          typename IntegrationMethod_,
-         typename GlobalMatrix,
-         typename GlobalVector,
          unsigned GlobalDim>
-class LocalNeumannBcAsmData : public LocalNeumannBcAsmDataInterface<GlobalMatrix, GlobalVector>
+class LocalNeumannBcAsmData : public LocalNeumannBcAsmDataInterface
 {
 public:
     using ShapeFunction = ShapeFunction_;
diff --git a/ProcessLib/Process.h b/ProcessLib/Process.h
index a8d8e065f2dd3681bea130919c2da134cb4e2792..c762f9085d576b40b65cb31ae1e7a873cb8cddc5 100644
--- a/ProcessLib/Process.h
+++ b/ProcessLib/Process.h
@@ -49,8 +49,8 @@ public:
         NonlinearSolver& nonlinear_solver,
         std::unique_ptr<TimeDiscretization>&& time_discretization,
         std::vector<std::reference_wrapper<ProcessVariable>>&& process_variables,
-        SecondaryVariableCollection<GlobalVector>&& secondary_variables,
-        ProcessOutput<GlobalVector>&& process_output
+        SecondaryVariableCollection&& secondary_variables,
+        ProcessOutput&& process_output
         )
         : _mesh(mesh)
         , _secondary_variables(std::move(secondary_variables))
@@ -317,8 +317,8 @@ protected:
     std::unique_ptr<NumLib::LocalToGlobalIndexMap>
         _local_to_global_index_map;
 
-    SecondaryVariableCollection<GlobalVector> _secondary_variables;
-    ProcessOutput<GlobalVector> _process_output;
+    SecondaryVariableCollection _secondary_variables;
+    ProcessOutput _process_output;
 
 private:
     unsigned const _integration_order = 2;
diff --git a/ProcessLib/ProcessOutput.h b/ProcessLib/ProcessOutput.h
index 96017e01b722c35149c564d9d52d6d87787fa5e6..283a554c402a28f501300350e446eb287db184d4 100644
--- a/ProcessLib/ProcessOutput.h
+++ b/ProcessLib/ProcessOutput.h
@@ -18,14 +18,13 @@ namespace ProcessLib
 {
 
 //! Holds information about which variables to write to output files.
-template <typename GlobalVector>
 struct ProcessOutput final
 {
     //! Constructs a new instance.
     ProcessOutput(BaseLib::ConfigTree const& output_config,
                   std::vector<std::reference_wrapper<ProcessVariable>> const&
                   process_variables,
-                  SecondaryVariableCollection<GlobalVector> const& secondary_variables)
+                  SecondaryVariableCollection const& secondary_variables)
     {
         //! \ogs_file_param{process__output__variables}
         auto const out_vars = output_config.getConfigSubtree("variables");
@@ -84,16 +83,15 @@ struct ProcessOutput final
 
 
 //! Writes output to the given \c file_name using the VTU file format.
-template <typename GlobalVector>
-void doProcessOutput(
+inline void doProcessOutput(
         std::string const& file_name,
         GlobalVector const& x,
         MeshLib::Mesh& mesh,
         NumLib::LocalToGlobalIndexMap const& dof_table,
         std::vector<std::reference_wrapper<ProcessVariable>> const&
         process_variables,
-        SecondaryVariableCollection<GlobalVector> secondary_variables,
-        ProcessOutput<GlobalVector> const& process_output)
+        SecondaryVariableCollection secondary_variables,
+        ProcessOutput const& process_output)
 {
     DBUG("Process output.");
 
@@ -186,7 +184,7 @@ void doProcessOutput(
         return result;
     };
 
-    auto add_secondary_var = [&](SecondaryVariable<GlobalVector> const& var,
+    auto add_secondary_var = [&](SecondaryVariable const& var,
                              std::string const& output_name)
     {
         assert(var.n_components == 1); // TODO implement other cases
diff --git a/ProcessLib/SecondaryVariable.h b/ProcessLib/SecondaryVariable.h
index 480a9feedd2e780d6f7081e98ab279502daa989f..453363184040504d8529497602dff6329708b2b5 100644
--- a/ProcessLib/SecondaryVariable.h
+++ b/ProcessLib/SecondaryVariable.h
@@ -21,7 +21,6 @@ namespace ProcessLib
 
 //! Holder for function objects that compute secondary variables,
 //! and (optionally) also the residuals (e.g., in case of extrapolation)
-template<typename GlobalVector>
 struct SecondaryVariableFunctions final
 {
     /*! Type of functions used.
@@ -83,18 +82,16 @@ struct SecondaryVariableFunctions final
 };
 
 //! Stores information about a specific secondary variable
-template<typename GlobalVector>
 struct SecondaryVariable final
 {
     std::string const name;      //!< Name of the variable; used, e.g., for output.
     const unsigned n_components; //!< Number of components of the variable.
 
     //! Functions used for computing the secondary variable.
-    SecondaryVariableFunctions<GlobalVector> fcts;
+    SecondaryVariableFunctions fcts;
 };
 
 //! Handles configuration of several secondary variables from the project file.
-template<typename GlobalVector>
 class SecondaryVariableCollection final
 {
 public:
@@ -161,7 +158,7 @@ public:
      */
     void addSecondaryVariable(std::string const& tag_name,
                               const unsigned num_components,
-                              SecondaryVariableFunctions<GlobalVector>&& fcts)
+                              SecondaryVariableFunctions&& fcts)
     {
         auto it = _map_tagname_to_varname.find(tag_name);
 
@@ -173,7 +170,7 @@ public:
             if (!_configured_secondary_variables
                      .emplace(std::make_pair(
                          var_name,
-                         SecondaryVariable<GlobalVector>{
+                         SecondaryVariable{
                              var_name, num_components, std::move(fcts)}))
                      .second)
             {
@@ -193,7 +190,7 @@ public:
 
     //! Returns an iterator to the first secondary variable.
     typename std::map<std::string,
-                      SecondaryVariable<GlobalVector>>::const_iterator
+                      SecondaryVariable>::const_iterator
     begin() const
     {
         return _configured_secondary_variables.begin();
@@ -201,7 +198,7 @@ public:
 
     //! Returns an iterator past the last secondary variable.
     typename std::map<std::string,
-                      SecondaryVariable<GlobalVector>>::const_iterator
+                      SecondaryVariable>::const_iterator
     end() const
     {
         return _configured_secondary_variables.end();
@@ -213,7 +210,7 @@ private:
 
     //! Collection of all configured secondary variables.
     //! Maps the variable name to the corresponding SecondaryVariable.
-    std::map<std::string, SecondaryVariable<GlobalVector>> _configured_secondary_variables;
+    std::map<std::string, SecondaryVariable> _configured_secondary_variables;
 
     //! Set of all tags available as a secondary variable.
     std::set<std::string> _all_secondary_variables;
@@ -222,16 +219,16 @@ private:
 
 //! Creates an object that computes a secondary variable via extrapolation
 //! of integration point values.
-template<typename GlobalVector, typename PropertyEnum, typename LocalAssembler>
-SecondaryVariableFunctions<GlobalVector>
+template<typename PropertyEnum, typename LocalAssembler>
+SecondaryVariableFunctions
 makeExtrapolator(PropertyEnum const property,
-                 NumLib::Extrapolator<GlobalVector, PropertyEnum, LocalAssembler>&
+                 NumLib::Extrapolator<PropertyEnum, LocalAssembler>&
                  extrapolator,
-                 typename NumLib::Extrapolator<GlobalVector, PropertyEnum,
+                 typename NumLib::Extrapolator<PropertyEnum,
                      LocalAssembler>::LocalAssemblers const& local_assemblers)
 {
     static_assert(std::is_base_of<
-         NumLib::Extrapolatable<GlobalVector, PropertyEnum>, LocalAssembler>::value,
+         NumLib::Extrapolatable<PropertyEnum>, LocalAssembler>::value,
         "The passed local assembler type (i.e. the local assembler interface) must"
         " derive from NumLib::Extrapolatable<>.");
 
diff --git a/ProcessLib/TES/TESLocalAssembler-impl.h b/ProcessLib/TES/TESLocalAssembler-impl.h
index 4d4aa2ed9712869369ea2fdd6b1d656e6f2a24b4..524089b91208ad2f263fe0cf220e1bd4d5c7eac8 100644
--- a/ProcessLib/TES/TESLocalAssembler-impl.h
+++ b/ProcessLib/TES/TESLocalAssembler-impl.h
@@ -105,9 +105,9 @@ namespace ProcessLib
 namespace TES
 {
 template <typename ShapeFunction_, typename IntegrationMethod_,
-          typename GlobalMatrix, typename GlobalVector, unsigned GlobalDim>
+          unsigned GlobalDim>
 TESLocalAssembler<
-    ShapeFunction_, IntegrationMethod_, GlobalMatrix, GlobalVector,
+    ShapeFunction_, IntegrationMethod_,
     GlobalDim>::TESLocalAssembler(MeshLib::Element const& e,
                                   std::size_t const /*local_matrix_size*/,
                                   unsigned const integration_order,
@@ -131,9 +131,8 @@ TESLocalAssembler<
 }
 
 template <typename ShapeFunction_, typename IntegrationMethod_,
-          typename GlobalMatrix, typename GlobalVector, unsigned GlobalDim>
-void TESLocalAssembler<ShapeFunction_, IntegrationMethod_, GlobalMatrix,
-                       GlobalVector,
+          unsigned GlobalDim>
+void TESLocalAssembler<ShapeFunction_, IntegrationMethod_,
                        GlobalDim>::assemble(const double /*t*/,
                                             std::vector<double> const& local_x)
 {
@@ -186,9 +185,8 @@ void TESLocalAssembler<ShapeFunction_, IntegrationMethod_, GlobalMatrix,
 }
 
 template <typename ShapeFunction_, typename IntegrationMethod_,
-          typename GlobalMatrix, typename GlobalVector, unsigned GlobalDim>
-void TESLocalAssembler<ShapeFunction_, IntegrationMethod_, GlobalMatrix,
-                       GlobalVector, GlobalDim>::
+          unsigned GlobalDim>
+void TESLocalAssembler<ShapeFunction_, IntegrationMethod_, GlobalDim>::
     addToGlobal(
         NumLib::LocalToGlobalIndexMap::RowColumnIndices const& indices,
         GlobalMatrix& M, GlobalMatrix& K, GlobalVector& b) const
@@ -199,9 +197,9 @@ void TESLocalAssembler<ShapeFunction_, IntegrationMethod_, GlobalMatrix,
 }
 
 template <typename ShapeFunction_, typename IntegrationMethod_,
-          typename GlobalMatrix, typename GlobalVector, unsigned GlobalDim>
+          unsigned GlobalDim>
 std::vector<double> const& TESLocalAssembler<
-    ShapeFunction_, IntegrationMethod_, GlobalMatrix, GlobalVector,
+    ShapeFunction_, IntegrationMethod_,
     GlobalDim>::getIntegrationPointValues(TESIntPtVariables const var,
                                           std::vector<double>& cache) const
 {
@@ -209,9 +207,9 @@ std::vector<double> const& TESLocalAssembler<
 }
 
 template <typename ShapeFunction_, typename IntegrationMethod_,
-          typename GlobalMatrix, typename GlobalVector, unsigned GlobalDim>
+          unsigned GlobalDim>
 bool TESLocalAssembler<
-    ShapeFunction_, IntegrationMethod_, GlobalMatrix, GlobalVector,
+    ShapeFunction_, IntegrationMethod_,
     GlobalDim>::checkBounds(std::vector<double> const& local_x,
                             std::vector<double> const& local_x_prev_ts)
 {
diff --git a/ProcessLib/TES/TESLocalAssembler.h b/ProcessLib/TES/TESLocalAssembler.h
index cc80fc33e7fce097d3e79eef1e7db13b97b2e54c..d3e12d37e7addf6d3c01486198206959891e1384 100644
--- a/ProcessLib/TES/TESLocalAssembler.h
+++ b/ProcessLib/TES/TESLocalAssembler.h
@@ -22,9 +22,8 @@ namespace ProcessLib
 {
 namespace TES
 {
-template <typename GlobalMatrix, typename GlobalVector>
 class TESLocalAssemblerInterface
-    : public NumLib::Extrapolatable<GlobalVector, TESIntPtVariables>
+    : public NumLib::Extrapolatable<TESIntPtVariables>
 {
 public:
     virtual ~TESLocalAssemblerInterface() = default;
@@ -41,9 +40,9 @@ public:
 };
 
 template <typename ShapeFunction_, typename IntegrationMethod_,
-          typename GlobalMatrix, typename GlobalVector, unsigned GlobalDim>
+          unsigned GlobalDim>
 class TESLocalAssembler final
-    : public TESLocalAssemblerInterface<GlobalMatrix, GlobalVector>
+    : public TESLocalAssemblerInterface
 {
 public:
     using ShapeFunction = ShapeFunction_;
diff --git a/ProcessLib/TES/TESProcess.cpp b/ProcessLib/TES/TESProcess.cpp
index 0d91e6a7c4db4dc2737080825e250fc59ac8b100..85b9b4cc62de691c67cff4d84f8d716f6aead990 100644
--- a/ProcessLib/TES/TESProcess.cpp
+++ b/ProcessLib/TES/TESProcess.cpp
@@ -31,7 +31,6 @@ getRowColumnIndices_(std::size_t const id,
                                                                  indices);
 }
 
-template <typename GlobalVector>
 void getVectorValues(
     GlobalVector const& x,
     NumLib::LocalToGlobalIndexMap::RowColumnIndices const& r_c_indices,
@@ -48,7 +47,6 @@ void getVectorValues(
 }
 
 // TODO that essentially duplicates code which is also present in ProcessOutput.
-template <typename GlobalVector>
 double getNodalValue(GlobalVector const& x, MeshLib::Mesh const& mesh,
                      NumLib::LocalToGlobalIndexMap const& dof_table,
                      std::size_t const node_id,
@@ -73,8 +71,8 @@ TESProcess::TESProcess(
     std::unique_ptr<Process::TimeDiscretization>&&
         time_discretization,
     std::vector<std::reference_wrapper<ProcessVariable>>&& process_variables,
-    SecondaryVariableCollection<GlobalVector>&& secondary_variables,
-    ProcessOutput<GlobalVector>&& process_output,
+    SecondaryVariableCollection&& secondary_variables,
+    ProcessOutput&& process_output,
     const BaseLib::ConfigTree& config)
     : Process(
           mesh, nonlinear_solver, std::move(time_discretization),
@@ -202,12 +200,12 @@ void TESProcess::initializeConcreteProcess(
 
     // secondary variables
     auto add2nd = [&](std::string const& var_name, unsigned const n_components,
-                      SecondaryVariableFunctions<GlobalVector>&& fcts) {
+                      SecondaryVariableFunctions&& fcts) {
         this->_secondary_variables.addSecondaryVariable(var_name, n_components,
                                                         std::move(fcts));
     };
     auto makeEx =
-        [&](TESIntPtVariables var) -> SecondaryVariableFunctions<GlobalVector> {
+        [&](TESIntPtVariables var) -> SecondaryVariableFunctions {
         return ProcessLib::makeExtrapolator(var, *_extrapolator,
                                             _local_assemblers);
     };
diff --git a/ProcessLib/TES/TESProcess.h b/ProcessLib/TES/TESProcess.h
index 0570def18bf786b6f773f019fca58419284d845c..bd78483c0f6ea3ac7211390afdc5b6c47e0ce55c 100644
--- a/ProcessLib/TES/TESProcess.h
+++ b/ProcessLib/TES/TESProcess.h
@@ -41,8 +41,8 @@ public:
             time_discretization,
         std::vector<std::reference_wrapper<ProcessVariable>>&&
             process_variables,
-        SecondaryVariableCollection<GlobalVector>&& secondary_variables,
-        ProcessOutput<GlobalVector>&& process_output,
+        SecondaryVariableCollection&& secondary_variables,
+        ProcessOutput&& process_output,
         BaseLib::ConfigTree const& config);
 
     void preTimestep(GlobalVector const& x, const double t,
@@ -53,17 +53,17 @@ public:
     bool isLinear() const override { return false; }
 private:
     using LocalAssembler =
-        TESLocalAssemblerInterface<GlobalMatrix, GlobalVector>;
+        TESLocalAssemblerInterface;
 
     using GlobalAssembler = NumLib::VectorMatrixAssembler<
-        GlobalMatrix, GlobalVector, LocalAssembler,
+        LocalAssembler,
         NumLib::ODESystemTag::FirstOrderImplicitQuasilinear>;
 
     using ExtrapolatorInterface =
-        NumLib::Extrapolator<GlobalVector, TESIntPtVariables, LocalAssembler>;
+        NumLib::Extrapolator<TESIntPtVariables, LocalAssembler>;
     using ExtrapolatorImplementation =
         NumLib::LocalLinearLeastSquaresExtrapolator<
-            GlobalVector, TESIntPtVariables, LocalAssembler>;
+            TESIntPtVariables, LocalAssembler>;
 
     void initializeConcreteProcess(
         NumLib::LocalToGlobalIndexMap const& dof_table,
@@ -119,7 +119,7 @@ inline std::unique_ptr<TESProcess> createTESProcess(
         variables, config,
         {"fluid_pressure", "temperature", "vapour_mass_fraction"});
 
-    SecondaryVariableCollection<GlobalVector>
+    SecondaryVariableCollection
         secondary_variables{
             config.getConfigSubtreeOptional("secondary_variables"),
             {"solid_density", "reaction_rate", "velocity_x", "velocity_y",
@@ -127,7 +127,7 @@ inline std::unique_ptr<TESProcess> createTESProcess(
              "vapour_partial_pressure", "relative_humidity",
              "equilibrium_loading"}};
 
-    ProcessOutput<GlobalVector> process_output{
+    ProcessOutput process_output{
         config.getConfigSubtree("output"), process_variables,
         secondary_variables};
 
diff --git a/ProcessLib/Utils/CreateLocalAssemblers.h b/ProcessLib/Utils/CreateLocalAssemblers.h
index f4fae98b4582ab010a9b8c62674b6bf626c96fa3..e14aae36025f633d0d71cc71af825c0a23d45408 100644
--- a/ProcessLib/Utils/CreateLocalAssemblers.h
+++ b/ProcessLib/Utils/CreateLocalAssemblers.h
@@ -24,7 +24,7 @@ namespace detail
 {
 
 template<unsigned GlobalDim,
-         template <typename, typename, typename, typename, unsigned> class
+         template <typename, typename, unsigned> class
          LocalAssemblerImplementation,
          typename LocalAssemblerInterface,
          typename... ExtraCtorArgs>
@@ -40,8 +40,6 @@ void createLocalAssemblers(
     using LocalDataInitializer = LocalDataInitializer<
         LocalAssemblerInterface,
         LocalAssemblerImplementation,
-        GlobalMatrix,
-        GlobalVector,
         GlobalDim,
         ExtraCtorArgs...>;
 
@@ -74,7 +72,7 @@ void createLocalAssemblers(
  * The first two template parameters cannot be deduced from the arguments.
  * Therefore they always have to be provided manually.
  */
-template<template <typename, typename, typename, typename, unsigned> class
+template<template <typename, typename, unsigned> class
          LocalAssemblerImplementation,
          typename LocalAssemblerInterface,
          typename... ExtraCtorArgs>
diff --git a/ProcessLib/Utils/LocalDataInitializer.h b/ProcessLib/Utils/LocalDataInitializer.h
index 3f644c31556085363cf65783cded9febd83377f9..5a2ecba8b801110c3728c579553e8bcd19d31bc1 100644
--- a/ProcessLib/Utils/LocalDataInitializer.h
+++ b/ProcessLib/Utils/LocalDataInitializer.h
@@ -122,9 +122,7 @@ namespace ProcessLib
 /// NumLib::ShapeLine2 is created.
 template <
     typename LocalAssemblerInterface,
-    template <typename, typename, typename, typename, unsigned> class LocalAssemblerData,
-    typename GlobalMatrix,
-    typename GlobalVector,
+    template <typename, typename, unsigned> class LocalAssemblerData,
     unsigned GlobalDim,
     typename... ConstructorArgs>
 class LocalDataInitializer final
@@ -285,7 +283,7 @@ private:
     using LAData = LocalAssemblerData<
             ShapeFunction,
             IntegrationMethod<ShapeFunction>,
-            GlobalMatrix, GlobalVector, GlobalDim>;
+            GlobalDim>;
 
     /// Generates a function that creates a new LocalAssembler of type LAData<SHAPE_FCT>
     template<typename ShapeFct>
diff --git a/Tests/NumLib/SteadyDiffusion2DExample1.h b/Tests/NumLib/SteadyDiffusion2DExample1.h
index 5e72dce9b35b50b7e7ca6ed638feb91127c9ba19..213aed5fac92b35d56953fc3305f164de1195281 100644
--- a/Tests/NumLib/SteadyDiffusion2DExample1.h
+++ b/Tests/NumLib/SteadyDiffusion2DExample1.h
@@ -29,7 +29,6 @@ template<typename IndexType>struct SteadyDiffusion2DExample1
         Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
     using LocalVectorType = Eigen::VectorXd;
 
-    template <typename GlobalMatrix, typename GlobalVector>
     class LocalAssemblerData
     {
     public:
@@ -72,14 +71,13 @@ template<typename IndexType>struct SteadyDiffusion2DExample1
         LocalVectorType const* _localRhs = nullptr;
     };
 
-    template <typename GlobalMatrix, typename GlobalVector>
     static
     void initializeLocalData(const MeshLib::Element& e,
-            LocalAssemblerData<GlobalMatrix, GlobalVector>*& data_ptr,
+            LocalAssemblerData*& data_ptr,
             std::size_t const local_matrix_size,
             SteadyDiffusion2DExample1 const& example)
     {
-        data_ptr = new LocalAssemblerData<GlobalMatrix, GlobalVector>;
+        data_ptr = new LocalAssemblerData;
         data_ptr->init(e, local_matrix_size, example._localA, example._localRhs);
     }
 
diff --git a/Tests/NumLib/TestExtrapolation.cpp b/Tests/NumLib/TestExtrapolation.cpp
index 341debb750b564c6dfe9842a0270158b7aa3ea2d..c90703474115a09700d57039e5c9c749e9e68a12 100644
--- a/Tests/NumLib/TestExtrapolation.cpp
+++ b/Tests/NumLib/TestExtrapolation.cpp
@@ -70,9 +70,8 @@ enum class IntegrationPointValue
     DerivedQuantity // a quantity computed for each integration point on-the-fly
 };
 
-template<typename GlobalMatrix, typename GlobalVector>
 class LocalAssemblerDataInterface
-        : public NumLib::Extrapolatable<GlobalVector, IntegrationPointValue>
+        : public NumLib::Extrapolatable<IntegrationPointValue>
 {
 public:
     virtual void interpolateNodalValuesToIntegrationPoints(
@@ -82,11 +81,9 @@ public:
 
 template<typename ShapeFunction,
          typename IntegrationMethod,
-         typename GlobalMatrix,
-         typename GlobalVector,
          unsigned GlobalDim>
 class LocalAssemblerData
-        : public LocalAssemblerDataInterface<GlobalMatrix, GlobalVector>
+        : public LocalAssemblerDataInterface
 {
     using ShapeMatricesType = ShapeMatrixPolicyType<ShapeFunction, GlobalDim>;
     using ShapeMatrices = typename ShapeMatricesType::ShapeMatrices;
@@ -151,17 +148,17 @@ private:
 class TestProcess
 {
 public:
-    using LocalAssembler = LocalAssemblerDataInterface<GlobalMatrix, GlobalVector>;
+    using LocalAssembler = LocalAssemblerDataInterface;
     using GlobalAssembler = NumLib::VectorMatrixAssembler<
-        GlobalMatrix, GlobalVector, LocalAssembler,
+        LocalAssembler,
         // The exact tag does not matter here.
         NumLib::ODESystemTag::FirstOrderImplicitQuasilinear>;
 
     using ExtrapolatorInterface =
-        NumLib::Extrapolator<GlobalVector, IntegrationPointValue, LocalAssembler>;
+        NumLib::Extrapolator<IntegrationPointValue, LocalAssembler>;
     using ExtrapolatorImplementation =
         NumLib::LocalLinearLeastSquaresExtrapolator<
-            GlobalVector, IntegrationPointValue, LocalAssembler>;
+            IntegrationPointValue, LocalAssembler>;
 
     TestProcess(MeshLib::Mesh const& mesh, unsigned const integration_order)
         : _integration_order(integration_order)
@@ -236,7 +233,7 @@ private:
     {
         using LocalDataInitializer = ProcessLib::LocalDataInitializer<
             LocalAssembler, LocalAssemblerData,
-            GlobalMatrix, GlobalVector, GlobalDim>;
+            GlobalDim>;
 
         _local_assemblers.resize(mesh.getNumberOfElements());
 
diff --git a/Tests/NumLib/TestSerialLinearSolver.cpp b/Tests/NumLib/TestSerialLinearSolver.cpp
index cc495b12b777ed9d9bf9140e6ae805529e3db696..14fac011b9f7f0800a952c516d8609fa443e9551 100644
--- a/Tests/NumLib/TestSerialLinearSolver.cpp
+++ b/Tests/NumLib/TestSerialLinearSolver.cpp
@@ -73,7 +73,7 @@ TEST(NumLibSerialLinearSolver, Steady2DdiffusionQuadElem)
     auto x = MathLib::MatrixVectorTraits<GlobalVector>::newInstance(ms);
     // TODO no setZero() for rhs, x?
 
-    using LocalAssembler = Example::LocalAssemblerData<GlobalMatrix, GlobalVector>;
+    using LocalAssembler = Example::LocalAssemblerData;
     // Initializer of the local assembler data.
     std::vector<LocalAssembler*> local_assembler_data;
     local_assembler_data.resize(ex1.msh->getNumberOfElements());
@@ -87,7 +87,7 @@ TEST(NumLibSerialLinearSolver, Steady2DdiffusionQuadElem)
 
         auto const num_local_dof = local_to_global_index_map.getNumElementDOF(id);
 
-        Example::initializeLocalData<GlobalMatrix, GlobalVector>(
+        Example::initializeLocalData(
                     item, item_data, num_local_dof, ex1);
     };
 
@@ -100,7 +100,7 @@ TEST(NumLibSerialLinearSolver, Steady2DdiffusionQuadElem)
     // TODO in the future use simpler NumLib::ODESystemTag
     // Local and global assemblers.
     typedef NumLib::VectorMatrixAssembler<
-            GlobalMatrix, GlobalVector, LocalAssembler,
+            LocalAssembler,
             NumLib::ODESystemTag::FirstOrderImplicitQuasilinear> GlobalAssembler;
 
     GlobalAssembler assembler(local_to_global_index_map);