private Matrix CalculateConstitutiveMatrix(TSplineKirchhoffLoveShellElement element, Vector surfaceBasisVector1, Vector surfaceBasisVector2)
        {
            var auxMatrix1 = Matrix.CreateZero(2, 2);

            auxMatrix1[0, 0]             = surfaceBasisVector1.DotProduct(surfaceBasisVector1);
            auxMatrix1[0, 1]             = surfaceBasisVector1.DotProduct(surfaceBasisVector2);
            auxMatrix1[1, 0]             = surfaceBasisVector2.DotProduct(surfaceBasisVector1);
            auxMatrix1[1, 1]             = surfaceBasisVector2.DotProduct(surfaceBasisVector2);
            (Matrix inverse, double det) = auxMatrix1.InvertAndDeterminant();

            var material           = ((IContinuumMaterial2D)element.Patch.Material);
            var constitutiveMatrix = Matrix.CreateFromArray(new double[3, 3]
            {
                {
                    inverse[0, 0] * inverse[0, 0],
                    material.PoissonRatio * inverse[0, 0] * inverse[1, 1] + (1 - material.PoissonRatio) * inverse[1, 0] * inverse[1, 0],
                    inverse[0, 0] * inverse[1, 0]
                },
                {
                    material.PoissonRatio *inverse[0, 0] * inverse[1, 1] + (1 - material.PoissonRatio) * inverse[1, 0] * inverse[1, 0],
                    inverse[1, 1] * inverse[1, 1],
                    inverse[1, 1] * inverse[1, 0]
                },
                {
                    inverse[0, 0] * inverse[1, 0],
                    inverse[1, 1] * inverse[1, 0],
                    0.5 * (1 - material.PoissonRatio) * inverse[0, 0] * inverse[1, 1] + (1 + material.PoissonRatio) * inverse[1, 0] * inverse[1, 0]
                },
            });

            return(constitutiveMatrix);
        }
        /// <summary>
        /// Calculates knots physical coordinates for post-processing with Paraview.
        /// </summary>
        /// <param name="element">An <see cref="Element"/> of type <see cref="TSplineKirchhoffLoveShellElement"/>.</param>
        /// <returns>A <see cref="double"/> array calculating the coordinates of the element Knots'.
        /// The rows of the matrix denote the knot numbering while the columns the displacements for each degree of freedom.</returns>
        public double[,] CalculatePointsForPostProcessing(TSplineKirchhoffLoveShellElement element)
        {
            var localCoordinates = new double[4, 2]
            {
                { -1, -1 },
                { -1, 1 },
                { 1, -1 },
                { 1, 1 }
            };

            var knotParametricCoordinatesKsi  = Vector.CreateFromArray(new double[] { -1, 1 });
            var knotParametricCoordinatesHeta = Vector.CreateFromArray(new double[] { -1, 1 });
            var elementControlPoints          = element.ControlPoints.ToArray();
            var tsplines = new ShapeTSplines2DFromBezierExtraction(element, elementControlPoints, knotParametricCoordinatesKsi, knotParametricCoordinatesHeta);

            var knotDisplacements       = new double[4, 3];
            var paraviewKnotRenumbering = new int[] { 0, 3, 1, 2 };

            for (int j = 0; j < localCoordinates.GetLength(0); j++)
            {
                for (int i = 0; i < elementControlPoints.Length; i++)
                {
                    knotDisplacements[paraviewKnotRenumbering[j], 0] += tsplines.TSplineValues[i, j] * elementControlPoints[i].X;
                    knotDisplacements[paraviewKnotRenumbering[j], 1] += tsplines.TSplineValues[i, j] * elementControlPoints[i].Y;
                    knotDisplacements[paraviewKnotRenumbering[j], 2] += tsplines.TSplineValues[i, j] * elementControlPoints[i].Z;
                }
            }

            return(knotDisplacements);
        }
        private IList <GaussLegendrePoint3D> CreateElementGaussPoints(TSplineKirchhoffLoveShellElement element)
        {
            GaussQuadrature gauss = new GaussQuadrature();

            return(gauss.CalculateElementGaussPoints(element.DegreeKsi, element.DegreeHeta, new List <Knot>
            {
                new Knot()
                {
                    ID = 0, Ksi = -1, Heta = -1, Zeta = 0
                },
                new Knot()
                {
                    ID = 1, Ksi = -1, Heta = 1, Zeta = 0
                },
                new Knot()
                {
                    ID = 2, Ksi = 1, Heta = -1, Zeta = 0
                },
                new Knot()
                {
                    ID = 3, Ksi = 1, Heta = 1, Zeta = 0
                }
            }));
        }