diff --git a/test/averagedistanceassemblertest.cc b/test/averagedistanceassemblertest.cc
index 983b9707daf25fcac5cef1a211b83decdb4ea79c..03f97eac08b6ed3f0d99d94295ff3feb636123ea 100644
--- a/test/averagedistanceassemblertest.cc
+++ b/test/averagedistanceassemblertest.cc
@@ -9,6 +9,7 @@
 #include <dune/gfe/rotation.hh>
 #include <dune/gfe/realtuple.hh>
 #include <dune/gfe/unitvector.hh>
+#include <dune/gfe/productmanifold.hh>
 
 #include <dune/gfe/localgeodesicfefunction.hh>
 
@@ -229,9 +230,29 @@ void testRotations()
 }
 
 
+void testProductManifold()
+{
+    typedef Dune::GFE::ProductManifold<RealTuple<double,5>,UnitVector<double,3>, Rotation<double,3>> TargetSpace;
+
+    std::vector<TargetSpace> corners(dim+1);
+
+    std::generate(corners.begin(), corners.end(), []()  {
+        return Dune::GFE::randomFieldVector<typename TargetSpace::field_type,TargetSpace::CoordinateType::dimension>(0.9,1.1);
+    });
+
+    TargetSpace argument = corners[0];
+    testWeightSet(corners, argument);
+    argument = corners[1];
+    testWeightSet(corners, argument);
+    argument = corners[2];
+    testWeightSet(corners, argument);
+}
+
+
 int main()
 {
     testRealTuples();
     testUnitVectors();
     testRotations();
+    testProductManifold();
 }
diff --git a/test/localgeodesicfefunctiontest.cc b/test/localgeodesicfefunctiontest.cc
index a2fa30ba11d9fd40d18180f39a36141ee3fef364..613fbda902bda20a398d7e7b313e40990108f89a 100644
--- a/test/localgeodesicfefunctiontest.cc
+++ b/test/localgeodesicfefunctiontest.cc
@@ -14,6 +14,7 @@
 #include <dune/gfe/rotation.hh>
 #include <dune/gfe/realtuple.hh>
 #include <dune/gfe/unitvector.hh>
+#include <dune/gfe/productmanifold.hh>
 
 #include <dune/gfe/localgeodesicfefunction.hh>
 #include "multiindex.hh"
@@ -303,6 +304,8 @@ int main()
     test<UnitVector<double,3>,1>(GeometryTypes::simplex(1));
     test<Rotation<double,3>,1>(GeometryTypes::simplex(1));
     test<RigidBodyMotion<double,3>,1>(GeometryTypes::simplex(1));
+    typedef Dune::GFE::ProductManifold<RealTuple<double,1>,Rotation<double,3>,UnitVector<double,2>> CrazyManifold;
+    test<CrazyManifold,1>(GeometryTypes::simplex(1));
     
     ////////////////////////////////////////////////////////////////
     //  Test functions on 2d simplex elements
@@ -313,6 +316,8 @@ int main()
     test<UnitVector<double,3>,2>(GeometryTypes::simplex(2));
     test<Rotation<double,3>,2>(GeometryTypes::simplex(2));
     test<RigidBodyMotion<double,3>,2>(GeometryTypes::simplex(2));
+    typedef Dune::GFE::ProductManifold<RealTuple<double,1>,Rotation<double,3>,UnitVector<double,2>> CrazyManifold;
+    test<CrazyManifold,2>(GeometryTypes::simplex(2));
 
     ////////////////////////////////////////////////////////////////
     //  Test functions on 2d quadrilateral elements
@@ -323,5 +328,7 @@ int main()
     test<UnitVector<double,3>,2>(GeometryTypes::cube(2));
     test<Rotation<double,3>,2>(GeometryTypes::cube(2));
     test<RigidBodyMotion<double,3>,2>(GeometryTypes::cube(2));
+    typedef Dune::GFE::ProductManifold<RealTuple<double,1>,Rotation<double,3>,UnitVector<double,2>> CrazyManifold;
+    test<CrazyManifold,2>(GeometryTypes::cube(2));
 
 }
diff --git a/test/localgfetestfunctiontest.cc b/test/localgfetestfunctiontest.cc
index 4b9769c95f7348e66363ed16f9eaa88d8ec5ae38..2890f50e383039173b7d4581a44368bd93525866 100644
--- a/test/localgfetestfunctiontest.cc
+++ b/test/localgfetestfunctiontest.cc
@@ -10,6 +10,7 @@
 #include <dune/gfe/rotation.hh>
 #include <dune/gfe/realtuple.hh>
 #include <dune/gfe/unitvector.hh>
+#include <dune/gfe/productmanifold.hh>
 
 #include <dune/gfe/localgeodesicfefunction.hh>
 #include <dune/gfe/localgfetestfunctionbasis.hh>
@@ -79,6 +80,8 @@ int main() try
         
     test<Rotation<double,3>, 1>();
     test<Rotation<double,3>, 2>();
+    typedef Dune::GFE::ProductManifold<RealTuple<double,1>,Rotation<double,3>,UnitVector<double,2>> CrazyManifold;
+    test<CrazyManifold, 2>();
 
 } catch (Exception& e) {
     std::cout << e << std::endl;
diff --git a/test/localprojectedfefunctiontest.cc b/test/localprojectedfefunctiontest.cc
index d2f6829398d13b3c60ba4052988e38ad8f701a7d..ec6164f4f3315f536ba722654b37de9c6338e1dd 100644
--- a/test/localprojectedfefunctiontest.cc
+++ b/test/localprojectedfefunctiontest.cc
@@ -15,6 +15,7 @@
 #include <dune/gfe/rotation.hh>
 #include <dune/gfe/realtuple.hh>
 #include <dune/gfe/unitvector.hh>
+#include <dune/gfe/productmanifold.hh>
 
 #include <dune/gfe/localprojectedfefunction.hh>
 #include "multiindex.hh"
@@ -105,6 +106,20 @@ void testDerivativeTangentiality(const RigidBodyMotion<double,3>& x,
 {
 }
 
+// the columns of the derivative must be tangential to the manifold
+template <int domainDim, int vectorDim,typename ...TargetSpaces>
+void testDerivativeTangentiality(const Dune::GFE::ProductManifold<TargetSpaces...>& x,
+                                 const FieldMatrix<double,vectorDim,domainDim>& derivative)
+{
+    size_t posHelper=0;
+    using namespace Dune::Hybrid;
+    forEach(integralRange(Dune::Hybrid::size(x)), [&](auto&& i) {
+        using Manifold = std::remove_reference_t<decltype(x[i])>;
+        testDerivativeTangentiality(x[i],Dune::GFE::blockAt<Manifold::embeddedDim,domainDim>( derivative,posHelper,0));
+        posHelper +=Manifold::embeddedDim;
+    });
+}
+
 /** \brief Test whether interpolation is invariant under permutation of the simplex vertices
  * \todo Implement this for all dimensions
  */
@@ -255,6 +270,8 @@ int main()
     test<UnitVector<double,3>,1>(GeometryTypes::line);
     test<Rotation<double,3>,1>(GeometryTypes::line);
     test<RigidBodyMotion<double,3>,1>(GeometryTypes::line);
+    typedef Dune::GFE::ProductManifold<RealTuple<double,1>,Rotation<double,3>,UnitVector<double,2>> CrazyManifold;
+    test<CrazyManifold, 1>(GeometryTypes::line);
 
     ////////////////////////////////////////////////////////////////
     //  Test functions on 2d simplex elements
@@ -265,6 +282,8 @@ int main()
     test<UnitVector<double,3>,2>(GeometryTypes::triangle);
     test<Rotation<double,3>,2>(GeometryTypes::triangle);
     test<RigidBodyMotion<double,3>,2>(GeometryTypes::triangle);
+    typedef Dune::GFE::ProductManifold<RealTuple<double,1>,Rotation<double,3>,UnitVector<double,2>> CrazyManifold;
+    test<CrazyManifold, 2>(GeometryTypes::triangle);
 
     ////////////////////////////////////////////////////////////////
     //  Test functions on 2d quadrilateral elements
@@ -275,5 +294,7 @@ int main()
     test<UnitVector<double,3>,2>(GeometryTypes::quadrilateral);
     test<Rotation<double,3>,2>(GeometryTypes::quadrilateral);
     test<RigidBodyMotion<double,3>,2>(GeometryTypes::quadrilateral);
+    typedef Dune::GFE::ProductManifold<RealTuple<double,1>,Rotation<double,3>,UnitVector<double,2>> CrazyManifold;
+    test<CrazyManifold, 2>(GeometryTypes::quadrilateral);
 
 }
diff --git a/test/targetspacetest.cc b/test/targetspacetest.cc
index cadfe4818e3f3c0c8bfce2ff69c7b0e22acaa9cb..b5e1c650bf1e91361fb1bf8fd7111ac40414bff8 100644
--- a/test/targetspacetest.cc
+++ b/test/targetspacetest.cc
@@ -3,6 +3,7 @@
 #include <dune/gfe/unitvector.hh>
 #include <dune/gfe/realtuple.hh>
 #include <dune/gfe/rotation.hh>
+#include <dune/gfe/productmanifold.hh>
 #include <dune/gfe/hyperbolichalfspacepoint.hh>
 
 #include "valuefactory.hh"
@@ -138,8 +139,8 @@ void testDerivativeOfSquaredDistance(const TargetSpace& a, const TargetSpace& b)
     // transform into embedded coordinates
     typename TargetSpace::EmbeddedTangentVector d2_fd_embedded;
     B.mtv(d2_fd,d2_fd_embedded);
-    
-    if ( (d2 - d2_fd_embedded).infinity_norm() > 100*eps ) {
+
+    if ( (d2 - d2_fd_embedded).infinity_norm() > 200*eps ) {
         std::cout << className(a) << ": Analytical gradient does not match fd approximation." << std::endl;
         std::cout << "d2 Analytical: " << d2 << std::endl;
         std::cout << "d2 FD        : " << d2_fd << std::endl;
@@ -156,14 +157,14 @@ void testHessianOfSquaredDistance(const TargetSpace& a, const TargetSpace& b)
     ///////////////////////////////////////////////////////////////////
     //  Test second derivative with respect to second argument
     ///////////////////////////////////////////////////////////////////
-    FieldMatrix<double,embeddedDim,embeddedDim> d2d2 = TargetSpace::secondDerivativeOfDistanceSquaredWRTSecondArgument(a, b);
-    
+    FieldMatrix<double,embeddedDim,embeddedDim> d2d2 = (TargetSpace::secondDerivativeOfDistanceSquaredWRTSecondArgument(a, b)).matrix();
+
     // finite-difference approximation
     FieldMatrix<double,embeddedDim,embeddedDim> d2d2_fd = getSecondDerivativeOfSecondArgumentFD<TargetSpace,embeddedDim>(a,b);
     
     FieldMatrix<double,embeddedDim,embeddedDim> d2d2_diff = d2d2;
     d2d2_diff -= d2d2_fd;
-    if ( (d2d2_diff).infinity_norm() > 100*eps) {
+    if ( (d2d2_diff).infinity_norm() > 200*eps) {
         std::cout << className(a) << ": Analytical second derivative does not match fd approximation." << std::endl;
         std::cout << "d2d2 Analytical:" << std::endl << d2d2 << std::endl;
         std::cout << "d2d2 FD        :" << std::endl << d2d2_fd << std::endl;
@@ -207,7 +208,8 @@ void testMixedDerivativesOfSquaredDistance(const TargetSpace& a, const TargetSpa
     
     FieldMatrix<double,embeddedDim,embeddedDim> d1d2_diff = d1d2;
     d1d2_diff -= d1d2_fd;
-    if ( (d1d2_diff).infinity_norm() > 100*eps ) {
+
+    if ( (d1d2_diff).infinity_norm() > 200*eps ) {
         std::cout << className(a) << ": Analytical mixed second derivative does not match fd approximation." << std::endl;
         std::cout << "d1d2 Analytical:" << std::endl << d1d2 << std::endl;
         std::cout << "d1d2 FD        :" << std::endl << d1d2_fd << std::endl;
@@ -245,8 +247,8 @@ void testDerivativeOfHessianOfSquaredDistance(const TargetSpace& a, const Target
         d2d2d2_fd[i] /= 2*eps;
         
     }
-    
-    if ( (d2d2d2 - d2d2d2_fd).infinity_norm() > 100*eps) {
+
+    if ( (d2d2d2 - d2d2d2_fd).infinity_norm() > 200*eps) {
         std::cout << className(a) << ": Analytical third derivative does not match fd approximation." << std::endl;
         std::cout << "d2d2d2 Analytical:" << std::endl << d2d2d2 << std::endl;
         std::cout << "d2d2d2 FD        :" << std::endl << d2d2d2_fd << std::endl;
@@ -284,8 +286,8 @@ void testMixedDerivativeOfHessianOfSquaredDistance(const TargetSpace& a, const T
         d1d2d2_fd[i] /= 2*eps;
         
     }
-    
-    if ( (d1d2d2 - d1d2d2_fd).infinity_norm() > 100*eps ) {
+
+    if ( (d1d2d2 - d1d2d2_fd).infinity_norm() > 200*eps ) {
         std::cout << className(a) << ": Analytical mixed third derivative does not match fd approximation." << std::endl;
         std::cout << "d1d2d2 Analytical:" << std::endl << d1d2d2 << std::endl;
         std::cout << "d1d2d2 FD        :" << std::endl << d1d2d2_fd << std::endl;
@@ -360,7 +362,7 @@ void test()
             std::cout << "p: " << testPointPair[0] << ",   q: " << testPointPair[1] << std::endl;
             std::cout << TargetSpace::exp(p, TargetSpace::log(p,q)) << std::endl;
             
-            //testDerivativesOfSquaredDistance<TargetSpace>(testPoints[i], testPoints[j]);
+            testDerivativesOfSquaredDistance<TargetSpace>(testPoints[i], testPoints[j]);
             
         }
         
@@ -378,6 +380,9 @@ int main() try
     test<UnitVector<double,3> >();
     test<UnitVector<double,4> >();
 
+    test<Dune::GFE::ProductManifold<RealTuple<double,1>,Rotation<double,3>,UnitVector<double,2>>>();
+    test<Dune::GFE::ProductManifold<Rotation<double,3>,UnitVector<double,5>>>();
+
 //     test<Rotation<double,3> >();
 //
 //     test<RigidBodyMotion<double,3> >();
diff --git a/test/valuefactory.hh b/test/valuefactory.hh
index 5a1a795696a85a38d6edaf2d3df1968416dcebb1..9d23579177b486e56e17bb168efda579c454c7bf 100644
--- a/test/valuefactory.hh
+++ b/test/valuefactory.hh
@@ -6,6 +6,7 @@
 #include <dune/gfe/unitvector.hh>
 #include <dune/gfe/rotation.hh>
 #include <dune/gfe/rigidbodymotion.hh>
+#include <dune/gfe/productmanifold.hh>
 #include <dune/gfe/orthogonalmatrix.hh>
 #include <dune/gfe/hyperbolichalfspacepoint.hh>
 
@@ -328,4 +329,30 @@ public:
 
 
 
+
+
+/** \brief A class that creates sets of values of various types, to be used in unit tests
+*
+* This is the specialization for ProducManifold<...>
+*/
+template <typename ...TargetSpaces>
+class ValueFactory<Dune::GFE::ProductManifold<TargetSpaces...> >
+{
+using TargetSpace = Dune::GFE::ProductManifold<TargetSpaces...>;
+
+public:
+    static void get(std::vector<TargetSpace >& values) {
+
+        std::vector<typename TargetSpace::CoordinateType > testPoints(10);
+
+        std::generate(testPoints.begin(), testPoints.end(), [](){
+            return Dune::GFE::randomFieldVector<typename TargetSpace::field_type,TargetSpace::CoordinateType::dimension>(0.9,1.1) ; });
+
+        values.resize(testPoints.size());
+
+        std::transform(testPoints.cbegin(),testPoints.cend(),values.begin(),[](const auto& testPoint){return TargetSpace(testPoint);});
+    }
+};
+
+
 #endif
\ No newline at end of file