diff --git a/src/OpenFOAM/primitives/MatrixSpace/MatrixSpace.H b/src/OpenFOAM/primitives/MatrixSpace/MatrixSpace.H
new file mode 100644
index 0000000000000000000000000000000000000000..1d7bcec20ddfa37c0ef5ba23fb8ad592712b3c25
--- /dev/null
+++ b/src/OpenFOAM/primitives/MatrixSpace/MatrixSpace.H
@@ -0,0 +1,322 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::MatrixSpace
+
+Description
+    Templated matrix space.
+
+    Template arguments are the Form the matrix space will be used to create,
+    the type of the elements and the number of rows and columns of the matrix.
+
+SourceFiles
+    MatrixSpaceI.H
+
+SeeAlso
+    Foam::VectorSpace
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef MatrixSpace_H
+#define MatrixSpace_H
+
+#include "VectorSpace.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                         Class MatrixSpace Declaration
+\*---------------------------------------------------------------------------*/
+
+template<class Form, class Cmpt, direction Nrows, direction Ncols>
+class MatrixSpace
+:
+    public VectorSpace<Form, Cmpt, Nrows*Ncols>
+{
+
+public:
+
+    //- MatrixSpace type
+    typedef MatrixSpace<Form, Cmpt, Nrows, Ncols> msType;
+
+
+    // Member constants
+
+        static const direction nRows = Nrows;
+        static const direction nCols = Ncols;
+
+
+    // Static member functions
+
+        //- Return the number of rows
+        static direction m()
+        {
+            return Nrows;
+        }
+
+        //- Return the number of columns
+        static direction n()
+        {
+            return Ncols;
+        }
+
+        //- Return the identity matrix for square matrix spaces
+        inline static msType identity();
+
+
+    // Sub-Block Classes
+
+        //- Const sub-block type
+        template<class SubTensor, direction BRowStart, direction BColStart>
+        class ConstBlock
+        {
+            //- Reference to parent matrix
+            const msType& matrix_;
+
+        public:
+
+            static const direction nRows = SubTensor::nRows;
+            static const direction nCols = SubTensor::nCols;
+
+            //- Return the number of rows in the block
+            static direction m()
+            {
+                return nRows;
+            }
+
+            //- Return the number of columns in the block
+            static direction n()
+            {
+                return nCols;
+            }
+
+            //- Construct for the given matrix
+            inline ConstBlock(const msType& matrix);
+
+            //- (i, j) const element access operator
+            inline const Cmpt& operator()
+            (
+                const direction i,
+                const direction j
+            ) const;
+        };
+
+
+        //- Sub-block type
+        template
+        <
+            class SubTensor,
+            direction BRowStart,
+            direction BColStart
+        >
+        class Block
+        {
+            //- Reference to parent matrix
+            msType& matrix_;
+
+        public:
+
+            static const direction nRows = SubTensor::nRows;
+            static const direction nCols = SubTensor::nCols;
+
+            //- Return the number of rows in the block
+            static direction m()
+            {
+                return nRows;
+            }
+
+            //- Return the number of columns in the block
+            static direction n()
+            {
+                return nCols;
+            }
+
+            //- Construct for the given matrix
+            inline Block(msType& matrix);
+
+            //- Assignment to a matrix
+            template<class Form2>
+            inline void operator=
+            (
+                const MatrixSpace
+                <
+                    Form2,
+                    Cmpt,
+                    SubTensor::nRows,
+                    SubTensor::nCols
+                >& matrix
+            );
+
+            //- Assignment to a column vector
+            template<class VSForm>
+            inline void operator=
+            (
+                const VectorSpace<VSForm, Cmpt, SubTensor::nRows>& v
+            );
+
+            //- (i, j) const element access operator
+            inline const Cmpt& operator()
+            (
+                const direction i,
+                const direction j
+            ) const;
+
+            //- (i, j) element access operator
+            inline Cmpt& operator()(const direction i, const direction j);
+        };
+
+
+    // Constructors
+
+        //- Construct null
+        inline MatrixSpace();
+
+        //- Construct initialized to zero
+        inline explicit MatrixSpace(const Foam::zero);
+
+        //- Construct as copy of a VectorSpace with the same size
+        template<class Form2, class Cmpt2>
+        inline explicit MatrixSpace
+        (
+            const VectorSpace<Form2, Cmpt2, Nrows*Ncols>&
+        );
+
+        //- Construct from a block of another matrix space
+        template
+        <
+            template<class, direction, direction> class Block2,
+            direction BRowStart,
+            direction BColStart
+        >
+        inline MatrixSpace
+        (
+            const Block2<Form, BRowStart, BColStart>& block
+        );
+
+        //- Construct from Istream
+        MatrixSpace(Istream&);
+
+
+    // Member Functions
+
+        //- Fast const element access using compile-time addressing
+        template<direction Row, direction Col>
+        inline const Cmpt& elmt() const;
+
+        //- Fast element access using compile-time addressing
+        template<direction Row, direction Col>
+        inline Cmpt& elmt();
+
+        // Const element access functions for a 3x3
+        // Compile-time errors are generated for inappropriate use
+
+            inline const Cmpt& xx() const;
+            inline const Cmpt& xy() const;
+            inline const Cmpt& xz() const;
+            inline const Cmpt& yx() const;
+            inline const Cmpt& yy() const;
+            inline const Cmpt& yz() const;
+            inline const Cmpt& zx() const;
+            inline const Cmpt& zy() const;
+            inline const Cmpt& zz() const;
+
+        // Element access functions for a 3x3
+        // Compile-time errors are generated for inappropriate use
+
+            inline Cmpt& xx();
+            inline Cmpt& xy();
+            inline Cmpt& xz();
+            inline Cmpt& yx();
+            inline Cmpt& yy();
+            inline Cmpt& yz();
+            inline Cmpt& zx();
+            inline Cmpt& zy();
+            inline Cmpt& zz();
+
+        //- Return the transpose of the matrix
+        inline typename typeOfTranspose<Cmpt, Form>::type T() const;
+
+        //- Return a const sub-block corresponding to the specified type
+        //  starting at the specified row and column
+        template<class SubTensor, direction BRowStart, direction BColStart>
+        inline ConstBlock<SubTensor, BRowStart, BColStart> block() const;
+
+        //- Return a sub-block corresponding to the specified type
+        //  starting at the specified row and column
+        template<class SubTensor, direction BRowStart, direction BColStart>
+        inline Block<SubTensor, BRowStart, BColStart> block();
+
+        //- (i, j) const element access operator
+        inline const Cmpt& operator()
+        (
+            const direction& row,
+            const direction& col
+        ) const;
+
+        //- (i, j) element access operator
+        inline Cmpt& operator()(const direction& row, const direction& col);
+
+
+    // Member Operators
+
+        //- Assignment to zero
+        inline void operator=(const Foam::zero);
+
+        //- Assignment to a block of another matrix space
+        template
+        <
+            template<class, direction, direction> class Block2,
+            direction BRowStart,
+            direction BColStart
+        >
+        inline void operator=
+        (
+            const Block2<Form, BRowStart, BColStart>& block
+        );
+
+        //- Inner product with a compatible square matrix
+        template<class Form2>
+        inline void operator&=
+        (
+            const MatrixSpace<Form, Cmpt, Ncols, Ncols>& matrix
+        );
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#include "MatrixSpaceI.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/primitives/MatrixSpace/MatrixSpaceI.H b/src/OpenFOAM/primitives/MatrixSpace/MatrixSpaceI.H
new file mode 100644
index 0000000000000000000000000000000000000000..e8df098a9489e14c7bfa2a579ad330ba60ad64c9
--- /dev/null
+++ b/src/OpenFOAM/primitives/MatrixSpace/MatrixSpaceI.H
@@ -0,0 +1,609 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "StaticAssert.H"
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
+inline Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::MatrixSpace()
+{}
+
+
+template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
+inline Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::MatrixSpace
+(
+    const Foam::zero z
+)
+:
+    MatrixSpace::vsType(z)
+{}
+
+
+template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
+template<class Form2, class Cmpt2>
+inline Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::MatrixSpace
+(
+    const VectorSpace<Form2, Cmpt2, Nrows*Ncols>& vs
+)
+:
+    MatrixSpace::vsType(vs)
+{}
+
+
+template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
+template
+<
+    template<class, Foam::direction, Foam::direction> class Block2,
+    Foam::direction BRowStart,
+    Foam::direction BColStart
+>
+inline Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::MatrixSpace
+(
+    const Block2<Form, BRowStart, BColStart>& block
+)
+{
+    for (direction i=0; i<Nrows; ++i)
+    {
+        for (direction j=0; j<Ncols; ++j)
+        {
+            operator()(i, j) = block(i, j);
+        }
+    }
+}
+
+
+template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
+inline Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::MatrixSpace(Istream& is)
+:
+    MatrixSpace::vsType(is)
+{}
+
+
+template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
+template<class SubTensor, Foam::direction BRowStart, Foam::direction BColStart>
+inline Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::
+ConstBlock<SubTensor, BRowStart, BColStart>::
+ConstBlock(const msType& matrix)
+:
+    matrix_(matrix)
+{
+    StaticAssert(msType::nRows >= BRowStart + nRows);
+    StaticAssert(msType::nCols >= BColStart + nCols);
+}
+
+
+template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
+template<class SubTensor, Foam::direction BRowStart, Foam::direction BColStart>
+inline Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::
+Block<SubTensor, BRowStart, BColStart>::
+Block(msType& matrix)
+:
+    matrix_(matrix)
+{
+    StaticAssert(msType::nRows >= BRowStart + nRows);
+    StaticAssert(msType::nCols >= BColStart + nCols);
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
+template<Foam::direction Row, Foam::direction Col>
+inline const Cmpt& Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::elmt() const
+{
+    StaticAssert(Row < Nrows && Col < Ncols);
+    return this->v_[Row*Ncols + Col];
+}
+
+
+template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
+template<Foam::direction Row, Foam::direction Col>
+inline Cmpt& Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::elmt()
+{
+    StaticAssert(Row < Nrows && Col < Ncols);
+    return this->v_[Row*Ncols + Col];
+}
+
+
+template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
+inline const Cmpt& Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::xx() const
+{
+    return elmt<0, 0>();
+}
+
+
+template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
+inline Cmpt& Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::xx()
+{
+    return elmt<0, 0>();
+}
+
+
+template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
+inline const Cmpt& Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::xy() const
+{
+    return elmt<0,1>();
+}
+
+
+template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
+inline Cmpt& Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::xy()
+{
+    return elmt<0,1>();
+}
+
+
+template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
+inline const Cmpt& Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::xz() const
+{
+    return elmt<0,2>();
+}
+
+
+template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
+inline Cmpt& Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::xz()
+{
+    return elmt<0,2>();
+}
+
+
+template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
+inline const Cmpt& Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::yx() const
+{
+    return elmt<1,0>();
+}
+
+
+template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
+inline Cmpt& Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::yx()
+{
+    return elmt<1,0>();
+}
+
+
+template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
+inline const Cmpt& Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::yy() const
+{
+    return elmt<1,1>();
+}
+
+
+template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
+inline Cmpt& Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::yy()
+{
+    return elmt<1,1>();
+}
+
+
+template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
+inline const Cmpt& Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::yz() const
+{
+    return elmt<1,2>();
+}
+
+
+template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
+inline Cmpt& Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::yz()
+{
+    return elmt<1,2>();
+}
+
+
+template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
+inline const Cmpt& Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::zx() const
+{
+    return elmt<2,0>();
+}
+
+
+template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
+inline Cmpt& Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::zx()
+{
+    return elmt<2,0>();
+}
+
+
+template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
+inline const Cmpt& Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::zy() const
+{
+    return elmt<2,1>();
+}
+
+
+template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
+inline Cmpt& Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::zy()
+{
+    return elmt<2,1>();
+}
+
+
+template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
+inline const Cmpt& Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::zz() const
+{
+    return elmt<2,2>();
+}
+
+template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
+inline Cmpt& Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::zz()
+{
+    return elmt<2,2>();
+}
+
+template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
+inline Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>
+Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::identity()
+{
+    StaticAssert(Nrows == Ncols);
+    msType result((Foam::zero()));
+
+    for (direction i=0; i<Ncols; ++i)
+    {
+        result(i, i) = 1;
+    }
+
+    return result;
+}
+
+
+template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
+inline typename Foam::typeOfTranspose<Cmpt, Form>::type
+Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::T() const
+{
+    typename typeOfTranspose<Cmpt, Form>::type result;
+
+    for (direction i=0; i<Nrows; ++i)
+    {
+        for (direction j=0; j<Ncols; ++j)
+        {
+            result(j,i) = operator()(i, j);
+        }
+    }
+
+    return result;
+}
+
+
+template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
+template
+<
+    class SubTensor,
+    Foam::direction BRowStart,
+    Foam::direction BColStart
+>
+inline typename Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::template
+    ConstBlock<SubTensor, BRowStart, BColStart>
+Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::block() const
+{
+    return *this;
+}
+
+
+template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
+template
+<
+    class SubTensor,
+    Foam::direction BRowStart,
+    Foam::direction BColStart
+>
+inline
+typename Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::template
+    Block<SubTensor, BRowStart, BColStart>
+Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::block()
+{
+    return *this;
+}
+
+
+// * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
+
+template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
+inline const Cmpt& Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::operator()
+(
+    const direction& row,
+    const direction& col
+) const
+{
+    #ifdef FULLDEBUG
+    if (row < 0 || row > Nrows-1 || col < 0 || col > Ncols-1)
+    {
+        FatalErrorInFunction
+            << "indices out of range"
+            << abort(FatalError);
+    }
+    #endif
+
+    return this->v_[row*Ncols + col];
+}
+
+
+template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
+inline Cmpt& Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::operator()
+(
+    const direction& row,
+    const direction& col
+)
+{
+    #ifdef FULLDEBUG
+    if (row < 0 || row > Nrows-1 || col < 0 || col > Ncols-1)
+    {
+        FatalErrorInFunction
+            << "indices out of range"
+            << abort(FatalError);
+    }
+    #endif
+
+    return this->v_[row*Ncols + col];
+}
+
+
+template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
+template<class SubTensor, Foam::direction BRowStart, Foam::direction BColStart>
+inline const Cmpt&
+Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::
+ConstBlock<SubTensor, BRowStart, BColStart>::
+operator()(const direction i, const direction j) const
+{
+    return matrix_(BRowStart + i, BColStart + j);
+}
+
+
+template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
+template<class SubTensor, Foam::direction BRowStart, Foam::direction BColStart>
+inline const Cmpt&
+Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::
+Block<SubTensor, BRowStart, BColStart>::
+operator()(const direction i, const direction j) const
+{
+    return matrix_(BRowStart + i, BColStart + j);
+}
+
+
+template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
+template<class SubTensor, Foam::direction BRowStart, Foam::direction BColStart>
+inline Cmpt&
+Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::
+Block<SubTensor, BRowStart, BColStart>::
+operator()(const direction i, const direction j)
+{
+    return matrix_(BRowStart + i, BColStart + j);
+}
+
+
+template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
+inline void Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::operator=
+(
+    const Foam::zero z
+)
+{
+    MatrixSpace::vsType::operator=(z);
+}
+
+
+template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
+template<class Form2>
+inline void Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::operator&=
+(
+    const MatrixSpace<Form, Cmpt, Ncols, Ncols>& matrix
+)
+{
+    *this = *this & matrix;
+}
+
+
+template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
+template
+<
+    template<class, Foam::direction, Foam::direction> class Block2,
+    Foam::direction BRowStart,
+    Foam::direction BColStart
+>
+inline void Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::operator=
+(
+    const Block2<Form, BRowStart, BColStart>& block
+)
+{
+    for (direction i = 0; i < Nrows; ++i)
+    {
+        for (direction j = 0; j < Ncols; ++j)
+        {
+            operator()(i, j) = block(i, j);
+        }
+    }
+}
+
+
+template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
+template<class SubTensor, Foam::direction BRowStart, Foam::direction BColStart>
+template<class Form2>
+inline void
+Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::
+Block<SubTensor, BRowStart, BColStart>::
+operator=
+(
+    const MatrixSpace<Form2, Cmpt, SubTensor::nRows, SubTensor::nCols>& matrix
+)
+{
+    for (direction i=0; i<nRows; ++i)
+    {
+        for (direction j=0; j<nCols; ++j)
+        {
+            operator()(i,j) = matrix(i,j);
+        }
+    }
+}
+
+
+template<class Form, class Cmpt, Foam::direction Nrows, Foam::direction Ncols>
+template<class SubTensor, Foam::direction BRowStart, Foam::direction BColStart>
+template<class VSForm>
+inline void
+Foam::MatrixSpace<Form, Cmpt, Nrows, Ncols>::
+Block<SubTensor, BRowStart, BColStart>::
+operator=
+(
+    const VectorSpace<VSForm, Cmpt, SubTensor::nRows>& v
+)
+{
+    StaticAssert(nCols == 1);
+
+    for (direction i=0; i<SubTensor::nRows; ++i)
+    {
+        operator()(i,0) = v[i];
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// * * * * * * * * * * * * * * * Friend Functions  * * * * * * * * * * * * * //
+
+template<class Form, class Cmpt, direction Nrows, direction Ncols>
+inline typename typeOfTranspose<Cmpt, Form>::type T
+(
+    const MatrixSpace<Form, Cmpt, Ncols, Nrows>& matrix
+)
+{
+    return matrix.T();
+}
+
+
+template<class Form, class Cmpt, direction Ncmpts>
+inline typename typeOfTranspose<Cmpt, Form>::type T
+(
+    const VectorSpace<Form, Cmpt, Ncmpts>& v
+)
+{
+    typename typeOfTranspose<Cmpt, Form>::type result;
+
+    for (direction i=0; i<Ncmpts; ++i)
+    {
+        result[i] = v[i];
+    }
+
+    return result;
+}
+
+
+// * * * * * * * * * * * * * * * Friend Operators  * * * * * * * * * * * * * //
+
+template
+<
+    class Form1,
+    class Form2,
+    class Cmpt,
+    direction Nrows1,
+    direction Ncols1,
+    direction Nrows2,
+    direction Ncols2
+>
+inline typename typeOfInnerProduct<Cmpt, Form1, Form2>::type operator&
+(
+    const MatrixSpace<Form1, Cmpt, Nrows1, Ncols1>& matrix1,
+    const MatrixSpace<Form2, Cmpt, Nrows2, Ncols2>& matrix2
+)
+{
+    StaticAssert(Ncols1 == Nrows2);
+
+    typename typeOfInnerProduct<Cmpt, Form1, Form2>::type result
+    (
+        (Foam::zero())
+    );
+
+    for (direction i=0; i<Nrows1; ++i)
+    {
+        for (direction j=0; j<Ncols2; ++j)
+        {
+            for (direction k=0; k<Nrows2; k++)
+            {
+                result(i, j) += matrix1(i, k)*matrix2(k, j);
+            }
+        }
+    }
+
+    return result;
+}
+
+
+template<class Form, class VSForm, class Cmpt, direction Nrows, direction Ncols>
+inline typename typeOfInnerProduct<Cmpt, Form, VSForm>::type operator&
+(
+    const MatrixSpace<Form, Cmpt, Nrows, Ncols>& matrix,
+    const VectorSpace<VSForm, Cmpt, Ncols>& v
+)
+{
+    typename typeOfInnerProduct<Cmpt, Form, VSForm>::type result
+    (
+        (Foam::zero())
+    );
+
+    for (direction i=0; i<Nrows; ++i)
+    {
+        for (direction j=0; j<Ncols; ++j)
+        {
+            result[i] += matrix(i, j)*v[j];
+        }
+    }
+
+    return result;
+}
+
+
+template
+<
+    class Form1,
+    class Form2,
+    class Cmpt,
+    direction Ncmpts1,
+    direction Ncmpts2
+>
+inline typename typeOfOuterProduct<Cmpt, Form1, Form2>::type operator*
+(
+    const VectorSpace<Form1, Cmpt, Ncmpts1>& v1,
+    const VectorSpace<Form2, Cmpt, Ncmpts2>& v2
+)
+{
+    typename typeOfOuterProduct<Cmpt, Form1, Form2>::type result;
+
+    for (direction i=0; i<Ncmpts1; ++i)
+    {
+        for (direction j=0; j<Ncmpts2; ++j)
+        {
+            result(i, j) = v1[i]*v2[j];
+        }
+    }
+
+    return result;
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/primitives/Tensor/Tensor.H b/src/OpenFOAM/primitives/Tensor/Tensor.H
index cf92644c16d2b667ac61ffe15b2effe9d258b5e8..ce5d305be7ff07446663c7f7779af31cc49f9cb6 100644
--- a/src/OpenFOAM/primitives/Tensor/Tensor.H
+++ b/src/OpenFOAM/primitives/Tensor/Tensor.H
@@ -25,7 +25,7 @@ Class
     Foam::Tensor
 
 Description
-    Templated 3D tensor derived from VectorSpace adding construction from
+    Templated 3D tensor derived from MatrixSpace adding construction from
     9 components, element access using xx(), xy() etc. member functions and
     the inner-product (dot-product) and outer-product of two Vectors
     (tensor-product) operators.
@@ -33,11 +33,16 @@ Description
 SourceFiles
     TensorI.H
 
+SeeAlso
+    Foam::MatrixSpace
+    Foam::Vector
+
 \*---------------------------------------------------------------------------*/
 
 #ifndef Tensor_H
 #define Tensor_H
 
+#include "MatrixSpace.H"
 #include "Vector.H"
 #include "SphericalTensor.H"
 
@@ -56,7 +61,7 @@ class SymmTensor;
 template<class Cmpt>
 class Tensor
 :
-    public VectorSpace<Tensor<Cmpt>, Cmpt, 9>
+    public MatrixSpace<Tensor<Cmpt>, Cmpt, 3, 3>
 {
 
 public:
@@ -85,6 +90,13 @@ public:
         //- Construct null
         inline Tensor();
 
+        //- Construct initialized to zero
+        inline explicit Tensor(const Foam::zero);
+
+        //- Construct given MatrixSpace of the same rank
+        template<class Cmpt2>
+        inline Tensor(const MatrixSpace<Tensor<Cmpt2>, Cmpt2, 3, 3>&);
+
         //- Construct given VectorSpace of the same rank
         template<class Cmpt2>
         inline Tensor(const VectorSpace<Tensor<Cmpt2>, Cmpt2, 9>&);
@@ -114,13 +126,25 @@ public:
             const Cmpt tzx, const Cmpt tzy, const Cmpt tzz
         );
 
+        //- Construct from a block of another matrix space
+        template
+        <
+            template<class, direction, direction> class Block2,
+            direction BRowStart,
+            direction BColStart
+        >
+        Tensor
+        (
+            const Block2<Tensor<Cmpt>, BRowStart, BColStart>& block
+        );
+
         //- Construct from Istream
-        Tensor(Istream&);
+        inline Tensor(Istream&);
 
 
     // Member Functions
 
-        // Access
+        // Component access
 
             inline const Cmpt& xx() const;
             inline const Cmpt& xy() const;
@@ -142,7 +166,7 @@ public:
             inline Cmpt& zy();
             inline Cmpt& zz();
 
-            // Access vector components.
+        // Row-vector access.
 
             inline Vector<Cmpt> x() const;
             inline Vector<Cmpt> y() const;
@@ -161,6 +185,10 @@ public:
         //- Inner-product with a Tensor
         inline void operator&=(const Tensor<Cmpt>&);
 
+        //- Assign to an equivalent vector space
+        template<class Cmpt2>
+        inline void operator=(const VectorSpace<Tensor<Cmpt2>, Cmpt2, 9>&);
+
         //- Assign to a SphericalTensor
         inline void operator=(const SphericalTensor<Cmpt>&);
 
@@ -181,6 +209,15 @@ public:
 };
 
 
+template<class Cmpt>
+class typeOfTranspose<Cmpt, Tensor<Cmpt>>
+{
+public:
+
+    typedef Tensor<Cmpt> type;
+};
+
+
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 } // End namespace Foam
diff --git a/src/OpenFOAM/primitives/Tensor/TensorI.H b/src/OpenFOAM/primitives/Tensor/TensorI.H
index 35bfdef0c469f823a546c9b796e9798f06f5daa6..56737032858015fcd5cc78bded6bf6d8ab516e07 100644
--- a/src/OpenFOAM/primitives/Tensor/TensorI.H
+++ b/src/OpenFOAM/primitives/Tensor/TensorI.H
@@ -32,6 +32,24 @@ inline Foam::Tensor<Cmpt>::Tensor()
 {}
 
 
+template<class Cmpt>
+inline Foam::Tensor<Cmpt>::Tensor(const Foam::zero z)
+:
+    Tensor::msType(z)
+{}
+
+
+template<class Cmpt>
+template<class Cmpt2>
+inline Foam::Tensor<Cmpt>::Tensor
+(
+    const MatrixSpace<Tensor<Cmpt2>, Cmpt2, 3, 3>& vs
+)
+:
+    Tensor::msType(vs)
+{}
+
+
 template<class Cmpt>
 template<class Cmpt2>
 inline Foam::Tensor<Cmpt>::Tensor
@@ -39,7 +57,7 @@ inline Foam::Tensor<Cmpt>::Tensor
     const VectorSpace<Tensor<Cmpt2>, Cmpt2, 9>& vs
 )
 :
-    VectorSpace<Tensor<Cmpt>, Cmpt, 9>(vs)
+    Tensor::msType(vs)
 {}
 
 
@@ -107,55 +125,29 @@ inline Foam::Tensor<Cmpt>::Tensor
 
 
 template<class Cmpt>
-inline Foam::Tensor<Cmpt>::Tensor(Istream& is)
+template
+<
+    template<class, Foam::direction, Foam::direction> class Block2,
+    Foam::direction BRowStart,
+    Foam::direction BColStart
+>
+inline Foam::Tensor<Cmpt>::Tensor
+(
+    const Block2<Tensor<Cmpt>, BRowStart, BColStart>& block
+)
 :
-    VectorSpace<Tensor<Cmpt>, Cmpt, 9>(is)
+    Tensor::msType(block)
 {}
 
 
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-template<class Cmpt>
-inline Foam::Vector<Cmpt> Foam::Tensor<Cmpt>::x() const
-{
-    return Vector<Cmpt>(this->v_[XX], this->v_[XY], this->v_[XZ]);
-}
-
-
 template<class Cmpt>
-inline Foam::Vector<Cmpt> Foam::Tensor<Cmpt>::y() const
-{
-    return Vector<Cmpt>(this->v_[YX], this->v_[YY], this->v_[YZ]);
-}
-
-
-template<class Cmpt>
-inline Foam::Vector<Cmpt> Foam::Tensor<Cmpt>::z() const
-{
-    return Vector<Cmpt>(this->v_[ZX], this->v_[ZY], this->v_[ZZ]);
-}
+inline Foam::Tensor<Cmpt>::Tensor(Istream& is)
+:
+    Tensor::msType(is)
+{}
 
 
-template<class Cmpt>
-inline Foam::Vector<Cmpt> Foam::Tensor<Cmpt>::vectorComponent
-(
-    const direction cmpt
-) const
-{
-    switch (cmpt)
-    {
-        case 0:
-            return x();
-        break;
-        case 1:
-            return y();
-        break;
-        case 2:
-            return z();
-        break;
-    }
-}
-
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
 template<class Cmpt>
 inline const Cmpt& Foam::Tensor<Cmpt>::xx() const
@@ -283,6 +275,48 @@ inline Cmpt& Foam::Tensor<Cmpt>::zz()
 }
 
 
+template<class Cmpt>
+inline Foam::Vector<Cmpt> Foam::Tensor<Cmpt>::x() const
+{
+    return Vector<Cmpt>(this->v_[XX], this->v_[XY], this->v_[XZ]);
+}
+
+
+template<class Cmpt>
+inline Foam::Vector<Cmpt> Foam::Tensor<Cmpt>::y() const
+{
+    return Vector<Cmpt>(this->v_[YX], this->v_[YY], this->v_[YZ]);
+}
+
+
+template<class Cmpt>
+inline Foam::Vector<Cmpt> Foam::Tensor<Cmpt>::z() const
+{
+    return Vector<Cmpt>(this->v_[ZX], this->v_[ZY], this->v_[ZZ]);
+}
+
+
+template<class Cmpt>
+inline Foam::Vector<Cmpt> Foam::Tensor<Cmpt>::vectorComponent
+(
+    const direction cmpt
+) const
+{
+    switch (cmpt)
+    {
+        case 0:
+            return x();
+            break;
+        case 1:
+            return y();
+            break;
+        case 2:
+            return z();
+            break;
+    }
+}
+
+
 template<class Cmpt>
 inline Foam::Tensor<Cmpt> Foam::Tensor<Cmpt>::T() const
 {
@@ -320,6 +354,17 @@ inline void Foam::Tensor<Cmpt>::operator&=(const Tensor<Cmpt>& t)
 }
 
 
+template<class Cmpt>
+template<class Cmpt2>
+inline void Foam::Tensor<Cmpt>::operator=
+(
+    const VectorSpace<Tensor<Cmpt2>, Cmpt2, 9>& vs
+)
+{
+    VectorSpace<Tensor<Cmpt>, Cmpt, 9>::operator=(vs);
+}
+
+
 template<class Cmpt>
 inline void Foam::Tensor<Cmpt>::operator=(const SphericalTensor<Cmpt>& st)
 {
diff --git a/src/OpenFOAM/primitives/VectorSpace/VectorSpace.H b/src/OpenFOAM/primitives/VectorSpace/VectorSpace.H
index 27c1bff3c1cd555208c932f146de793564a36007..1d47ae3a0788fa78a4ce1eacef24cd625b54c2cd 100644
--- a/src/OpenFOAM/primitives/VectorSpace/VectorSpace.H
+++ b/src/OpenFOAM/primitives/VectorSpace/VectorSpace.H
@@ -88,7 +88,7 @@ public:
     typedef Cmpt cmptType;
 
 
-    // Member constants
+    // Static constants
 
         //- Dimensionality of space
         static const direction dim = 3;
@@ -97,6 +97,13 @@ public:
         static const direction nComponents = Ncmpts;
 
 
+        // VectorSpace currently defaults to a column-vector
+        // This will be removed when column-vector is introduced
+        // as a specialization
+        static const direction nRows = Ncmpts;
+        static const direction nCols = 1;
+
+
     // Static data members
 
         static const char* const typeName;
@@ -109,6 +116,38 @@ public:
         static const Form rootMin;
 
 
+    // Sub-Block Classes
+
+        //- Const sub-block type
+        template
+        <
+            class SubVector,
+            direction BStart
+        >
+        class ConstBlock
+        {
+            const vsType& vs_;
+
+        public:
+
+            //- Number of components in this vector space
+            static const direction nComponents = SubVector::nComponents;
+
+            //- Construct for a given vector
+            inline ConstBlock(const vsType& vs);
+
+            //- [i] const element access operator
+            inline const Cmpt& operator[](const direction i) const;
+
+            //- (i, 0) const element access operator
+            inline const Cmpt& operator()
+            (
+                const direction i,
+                const direction
+            ) const;
+        };
+
+
     // Constructors
 
         //- Construct null
@@ -123,9 +162,9 @@ public:
         //- Construct as copy
         inline VectorSpace(const VectorSpace<Form, Cmpt, Ncmpts>&);
 
-        //- Construct as copy of another VectorSpace type of the same rank
+        //- Construct as copy of a VectorSpace with the same size
         template<class Form2, class Cmpt2>
-        inline VectorSpace(const VectorSpace<Form2, Cmpt2, Ncmpts>&);
+        inline explicit VectorSpace(const VectorSpace<Form2, Cmpt2, Ncmpts>&);
 
 
     // Member Functions
@@ -142,6 +181,9 @@ public:
         //- Return a VectorSpace with all elements = s
         inline static Form uniform(const Cmpt& s);
 
+        template<class SubVector, direction BStart>
+        inline const ConstBlock<SubVector, BStart> block() const;
+
 
     // Member Operators
 
diff --git a/src/OpenFOAM/primitives/VectorSpace/VectorSpaceI.H b/src/OpenFOAM/primitives/VectorSpace/VectorSpaceI.H
index fe4a47be48ebbf6e60d164c4bbdd358f7deceb80..10f6964e7b2ff8376b38dba56a6f4e65c9c52347 100644
--- a/src/OpenFOAM/primitives/VectorSpace/VectorSpaceI.H
+++ b/src/OpenFOAM/primitives/VectorSpace/VectorSpaceI.H
@@ -27,6 +27,7 @@ License
 #include "products.H"
 #include "VectorSpaceOps.H"
 #include "ops.H"
+#include "StaticAssert.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -68,6 +69,20 @@ inline VectorSpace<Form, Cmpt, Ncmpts>::VectorSpace
 }
 
 
+template<class Form, class Cmpt, direction Ncmpts>
+template<class SubVector, direction BStart>
+inline
+VectorSpace<Form, Cmpt, Ncmpts>::ConstBlock<SubVector, BStart>::ConstBlock
+(
+    const vsType& vs
+)
+:
+    vs_(vs)
+{
+    StaticAssert(vsType::nComponents >= BStart + nComponents);
+}
+
+
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
 template<class Form, class Cmpt, direction Ncmpts>
@@ -164,6 +179,16 @@ inline Form VectorSpace<Form, Cmpt, Ncmpts>::uniform(const Cmpt& s)
 }
 
 
+template<class Form, class Cmpt, direction Ncmpts>
+template<class SubVector, direction BStart>
+inline const typename VectorSpace<Form, Cmpt, Ncmpts>::template
+    ConstBlock<SubVector, BStart>
+VectorSpace<Form, Cmpt, Ncmpts>::block() const
+{
+    return *this;
+}
+
+
 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
 
 template<class Form, class Cmpt, direction Ncmpts>
@@ -204,6 +229,58 @@ inline Cmpt& VectorSpace<Form, Cmpt, Ncmpts>::operator[]
 }
 
 
+template<class Form, class Cmpt, direction Ncmpts>
+template<class SubVector, direction BStart>
+inline const Cmpt&
+VectorSpace<Form, Cmpt, Ncmpts>::
+ConstBlock<SubVector, BStart>::operator[]
+(
+    const direction i
+) const
+{
+    #ifdef FULLDEBUG
+    if (i >= Ncmpts)
+    {
+        FatalErrorInFunction
+            << "index out of range"
+            << abort(FatalError);
+    }
+    #endif
+
+    return vs_[BStart + i];
+}
+
+
+template<class Form, class Cmpt, direction Ncmpts>
+template<class SubVector, direction BStart>
+inline const Cmpt&
+VectorSpace<Form, Cmpt, Ncmpts>::
+ConstBlock<SubVector, BStart>::operator()
+(
+    const direction i,
+    const direction j
+) const
+{
+    #ifdef FULLDEBUG
+    if (i >= Ncmpts)
+    {
+        FatalErrorInFunction
+            << "index out of range"
+            << abort(FatalError);
+    }
+
+    if (j != 0)
+    {
+        FatalErrorInFunction
+            << "j != 0"
+            << abort(FatalError);
+    }
+    #endif
+
+    return vs_[BStart + i];
+}
+
+
 template<class Form, class Cmpt, direction Ncmpts>
 inline void VectorSpace<Form, Cmpt, Ncmpts>::operator=
 (
diff --git a/src/OpenFOAM/primitives/VectorSpace/products.H b/src/OpenFOAM/primitives/VectorSpace/products.H
index 4214f32f0f27dce8549764d7e1451fcdc2e81d06..5992444b8b5ac8d2054b8d3b1f074fa352d39408 100644
--- a/src/OpenFOAM/primitives/VectorSpace/products.H
+++ b/src/OpenFOAM/primitives/VectorSpace/products.H
@@ -41,6 +41,24 @@ namespace Foam
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
+//- Abstract template class to provide the form resulting from
+//  the inner-product of two forms
+template<class Cmpt, class Form1, class Form2>
+class typeOfInnerProduct
+{};
+
+//- Abstract template class to provide the form resulting from
+//  the outer-product of two forms
+template<class Cmpt, class Form1, class Form2>
+class typeOfOuterProduct
+{};
+
+//- Abstract template class to provide the transpose form of a form
+template<class Cmpt, class Form>
+class typeOfTranspose
+{};
+
+
 template<class Cmpt, direction rank>
 class typeOfRank
 {};