Beispiel #1
0
        /// <summary>
        /// The resultant "B" matrix when the interpolation function is derived
        /// du/dx = 1/|A| * [y2 - y3    0   y3 - y1 0   y1 - y2 0] * [u1 v1 u2 v2 u3 v3] -> du/dx = B * [u1 v1 u2 v2 u3 v3]
        /// dv/dy = 1/|A| * [0      -(x2 - x3)    0   -(x3 - x1)    0   -(x1 -x2)] * [u1 v1 u2 v2 u3 v3] -> dv/dy = B * [u1 v1 u2 v2 u3 v3]
        /// (du/dy + dv/dx) = 1/|A| * [-(x2 - x3)    y2-y3   -(x3 - x1)    y3 - y1   -(x1 -x2)    y1 - y2] * [u1 v1 u2 v2 u3 v3] -> dv/dy = B * [u1 v1 u2 v2 u3 v3]
        /// </summary>
        /// <returns></returns>
        public override double[][] GetBMatrix()
        {
            var    matrix      = MatrixOperations.MatrixCreate(3, 6);
            double determinant = GetInterpolationMatrixDeterminant();

            matrix[0][0] = (Vertex2.Y - Vertex3.Y) / determinant;
            matrix[0][1] = 0.0;
            matrix[0][2] = (Vertex3.Y - Vertex1.Y) / determinant;
            matrix[0][3] = 0.0;
            matrix[0][4] = (Vertex1.Y - Vertex2.Y) / determinant;
            matrix[0][5] = 0.0;

            matrix[1][0] = 0.0;
            matrix[1][1] = -(Vertex2.X - Vertex3.X) / determinant;
            matrix[1][2] = 0.0;
            matrix[1][3] = -(Vertex3.X - Vertex1.X) / determinant;
            matrix[1][4] = 0.0;
            matrix[1][5] = -(Vertex1.X - Vertex2.X) / determinant;

            matrix[2][0] = -(Vertex2.X - Vertex3.X) / determinant;
            matrix[2][1] = (Vertex2.Y - Vertex3.Y) / determinant;
            matrix[2][2] = -(Vertex3.X - Vertex1.X) / determinant;
            matrix[2][3] = (Vertex3.Y - Vertex1.Y) / determinant;
            matrix[2][4] = -(Vertex1.X - Vertex2.X) / determinant;
            matrix[2][5] = (Vertex1.Y - Vertex2.Y) / determinant;

            return(matrix);
        }
Beispiel #2
0
        public void MatrixOrder4AnotherTest()
        {
            double[][] matrix = MatrixOperations.MatrixCreate(4, 4);
            matrix[0][0] = 4.0;
            matrix[0][1] = 3.0;
            matrix[0][2] = 2.0;
            matrix[0][3] = 2.0;

            matrix[1][0] = 0.0;
            matrix[1][1] = 1.0;
            matrix[1][2] = -3.0;
            matrix[1][3] = 3.0;

            matrix[2][0] = 0.0;
            matrix[2][1] = -1.0;
            matrix[2][2] = 3.0;
            matrix[2][3] = 3.0;

            matrix[3][0] = 0.0;
            matrix[3][1] = 3.0;
            matrix[3][2] = 1.0;
            matrix[3][3] = 1.0;

            double det = matrix.MatrixDeterminant();

            Assert.AreEqual(-240.0, det);
        }
Beispiel #3
0
        public void MatrixInverseTest()
        {
            double[][] matrix = MatrixOperations.MatrixCreate(3, 3);
            matrix[0][0] = 1.0;
            matrix[0][1] = -1.0;
            matrix[0][2] = 0.0;

            matrix[1][0] = 0.0;
            matrix[1][1] = 1.0;
            matrix[1][2] = 0.0;

            matrix[2][0] = 2.0;
            matrix[2][1] = 0.0;
            matrix[2][2] = 1.0;

            double[][] inv = matrix.MatrixInverse();

            var identity = MatrixOperations.MatrixIdentity(3);

            double[][] result = inv.MatrixProduct(matrix);

            Assert.AreEqual(identity[0][0], result[0][0]);
            Assert.AreEqual(identity[0][1], result[0][1]);
            Assert.AreEqual(identity[0][2], result[0][2]);

            Assert.AreEqual(identity[1][0], result[1][0]);
            Assert.AreEqual(identity[1][1], result[1][1]);
            Assert.AreEqual(identity[1][2], result[1][2]);

            Assert.AreEqual(identity[2][0], result[2][0]);
            Assert.AreEqual(identity[2][1], result[2][1]);
            Assert.AreEqual(identity[2][2], result[2][2]);
        }
Beispiel #4
0
        /// <summary>
        /// The resultant "B" matrix when the interpolation function is derived
        /// du/dx = 1/|A| * [1  1] * [u1    u2] -> du/dx = B * [u1 u2]
        /// </summary>
        /// <returns></returns>
        public override double[][] GetBMatrix()
        {
            var    matrix      = MatrixOperations.MatrixCreate(1, 2);
            double determinant = GetInterpolationMatrixDeterminant();

            matrix[0][0] = -1.0 / determinant;
            matrix[0][1] = 1.0 / determinant;

            return(matrix);
        }
Beispiel #5
0
        /// <summary>
        /// Matrix "A" for a linear interpolation of the desired solution
        /// [1  x1]
        /// [1  x2]
        /// </summary>
        /// <returns></returns>
        public override double[][] GetInterpolationMatrix()
        {
            var matrix = MatrixOperations.MatrixCreate(2, 2);

            matrix[0][0] = 1;
            matrix[0][1] = Vertex1.X;

            matrix[1][0] = 1;
            matrix[1][1] = Vertex2.X;

            return(matrix);
        }
Beispiel #6
0
        public void MatrixOrder2Test()
        {
            double[][] matrix = MatrixOperations.MatrixCreate(2, 2);
            matrix[0][0] = 1.0;
            matrix[0][1] = 2.0;
            matrix[1][0] = -1.0;
            matrix[1][1] = 2.0;

            double det = matrix.MatrixDeterminant();

            Assert.AreEqual(matrix[0][0] * matrix[1][1] - matrix[1][0] * matrix[0][1], det);
        }
Beispiel #7
0
        public void MatrixInverse2Test()
        {
            double error = 0.000000000000001;

            double[][] matrix = MatrixOperations.MatrixCreate(4, 4);
            matrix[0][0] = 4.0;
            matrix[0][1] = 3.0;
            matrix[0][2] = 2.0;
            matrix[0][3] = 2.0;

            matrix[1][0] = 0.0;
            matrix[1][1] = 1.0;
            matrix[1][2] = -3.0;
            matrix[1][3] = 3.0;

            matrix[2][0] = 0.0;
            matrix[2][1] = -1.0;
            matrix[2][2] = 3.0;
            matrix[2][3] = 3.0;

            matrix[3][0] = 0.0;
            matrix[3][1] = 3.0;
            matrix[3][2] = 1.0;
            matrix[3][3] = 1.0;

            double[][] inv = matrix.MatrixInverse();

            var identity = MatrixOperations.MatrixIdentity(4);

            double[][] result = inv.MatrixProduct(matrix);

            Assert.IsTrue(Math.Abs(identity[0][0] - result[0][0]) < error);
            Assert.IsTrue(Math.Abs(identity[0][1] - result[0][1]) < error);
            Assert.IsTrue(Math.Abs(identity[0][2] - result[0][2]) < error);
            Assert.IsTrue(Math.Abs(identity[0][3] - result[0][3]) < error);

            Assert.IsTrue(Math.Abs(identity[1][0] - result[1][0]) < error);
            Assert.IsTrue(Math.Abs(identity[1][1] - result[1][1]) < error);
            Assert.IsTrue(Math.Abs(identity[1][2] - result[1][2]) < error);
            Assert.IsTrue(Math.Abs(identity[1][3] - result[1][3]) < error);

            Assert.IsTrue(Math.Abs(identity[2][0] - result[2][0]) < error);
            Assert.IsTrue(Math.Abs(identity[2][1] - result[2][1]) < error);
            Assert.IsTrue(Math.Abs(identity[2][2] - result[2][2]) < error);
            Assert.IsTrue(Math.Abs(identity[2][3] - result[2][3]) < error);

            Assert.IsTrue(Math.Abs(identity[3][0] - result[3][0]) < error);
            Assert.IsTrue(Math.Abs(identity[3][1] - result[3][1]) < error);
            Assert.IsTrue(Math.Abs(identity[3][2] - result[3][2]) < error);
            Assert.IsTrue(Math.Abs(identity[3][3] - result[3][3]) < error);
        }
        public void GetKMatrixLinearElementTest()
        {
            //  ElasticCoefficient = E / (1 - v^2)
            double elasticCoefficient = 2.31E+06;

            Node node1 = new Node(0.0, 0.0);
            Node node2 = new Node(1.0, 0.0);

            LinearElement element1 = new LinearElement(node1, node2);

            double[][] dMatrix = MatrixOperations.MatrixCreate(1, 1);
            dMatrix[0][0] = elasticCoefficient;

            element1.SetDMatrix(dMatrix);

            #region Kglobal

            FiniteElementMethodModel model = new FiniteElementMethodModel();

            model.Nodes.Add(node1);
            model.Nodes.Add(node2);
            model.Elements.Add(element1);

            var kGlobal = model.BuildGlobalKMatrix();

            Console.Write(kGlobal.DisplayMatrixToString());

            //  Setting displacements
            double[][] uMatrix = MatrixOperations.MatrixCreate(2, 1);

            uMatrix[0][0] = 0.0;
            uMatrix[1][0] = 0.001;

            //  todo improve matrix inverse and determinant
            double[][] fMatrix = kGlobal.MatrixProduct(uMatrix);

            //  With those strains, this is equivalent to a force of 2310 N applying on the free side
            Assert.AreEqual(-2310, fMatrix[0][0]);
            Assert.AreEqual(2310, fMatrix[1][0]);
            #endregion
        }
Beispiel #9
0
        public void MatrixOrder3Test()
        {
            double[][] matrix = MatrixOperations.MatrixCreate(3, 3);
            matrix[0][0] = 1.0;
            matrix[0][1] = 2.0;
            matrix[0][2] = -2.0;

            matrix[1][0] = 1.0;
            matrix[1][1] = -2.0;
            matrix[1][2] = 5.0;

            matrix[2][0] = -8.0;
            matrix[2][1] = 5.0;
            matrix[2][2] = 4.0;

            double det = matrix.MatrixDeterminant();

            Assert.AreEqual((matrix[0][0] * matrix[1][1] * matrix[2][2] + matrix[0][1] * matrix[1][2] * matrix[2][0] +
                             matrix[1][0] * matrix[2][1] * matrix[0][2]) -
                            (matrix[0][2] * matrix[1][1] * matrix[2][0] + matrix[1][0] * matrix[0][1] * matrix[2][2] +
                             matrix[2][1] * matrix[1][2] * matrix[0][0]), det);
        }
        public double[][] BuildGlobalKMatrix()
        {
            double[][] globalKMatrix = null;

            if (Elements.Any(el => el is TriangularElement))
            {
                globalKMatrix = MatrixOperations.MatrixCreate(Nodes.Count * 2, Nodes.Count * 2);
            }
            else if (Elements.Any(el => el is LinearElement))
            {
                globalKMatrix = MatrixOperations.MatrixCreate(Nodes.Count, Nodes.Count);
            }

            foreach (IInterpolationElement element in Elements)
            {
                //  2D simulation: {u1, v1, u2, v2, ..., un, vn}
                if (element is TriangularElement triangularElement)
                {
                    //  {u1, v1, u2, v2, u3, v3}
                    double[][] localKmatrix = triangularElement.GetKMatrix();

                    int indexVertex1 = Nodes.IndexOf(triangularElement.Vertex1);
                    int indexVertex2 = Nodes.IndexOf(triangularElement.Vertex2);
                    int indexVertex3 = Nodes.IndexOf(triangularElement.Vertex3);

                    //  Element local F1H
                    globalKMatrix[indexVertex1 * 2][indexVertex1 * 2]     = globalKMatrix[indexVertex1 * 2][indexVertex1 * 2] + localKmatrix[0][0];
                    globalKMatrix[indexVertex1 * 2][indexVertex1 * 2 + 1] = globalKMatrix[indexVertex1 * 2][indexVertex1 * 2 + 1] + localKmatrix[0][1];
                    globalKMatrix[indexVertex1 * 2][indexVertex2 * 2]     = globalKMatrix[indexVertex1 * 2][indexVertex2 * 2] + localKmatrix[0][2];
                    globalKMatrix[indexVertex1 * 2][indexVertex2 * 2 + 1] = globalKMatrix[indexVertex1 * 2][indexVertex2 * 2 + 1] + localKmatrix[0][3];
                    globalKMatrix[indexVertex1 * 2][indexVertex3 * 2]     = globalKMatrix[indexVertex1 * 2][indexVertex3 * 2] + localKmatrix[0][4];
                    globalKMatrix[indexVertex1 * 2][indexVertex3 * 2 + 1] = globalKMatrix[indexVertex1 * 2][indexVertex3 * 2 + 1] + localKmatrix[0][5];

                    //  Element local F1V
                    globalKMatrix[indexVertex1 * 2 + 1][indexVertex1 * 2]     = globalKMatrix[indexVertex1 * 2 + 1][indexVertex1 * 2] + localKmatrix[1][0];
                    globalKMatrix[indexVertex1 * 2 + 1][indexVertex1 * 2 + 1] = globalKMatrix[indexVertex1 * 2 + 1][indexVertex1 * 2 + 1] + localKmatrix[1][1];
                    globalKMatrix[indexVertex1 * 2 + 1][indexVertex2 * 2]     = globalKMatrix[indexVertex1 * 2 + 1][indexVertex2 * 2] + localKmatrix[1][2];
                    globalKMatrix[indexVertex1 * 2 + 1][indexVertex2 * 2 + 1] = globalKMatrix[indexVertex1 * 2 + 1][indexVertex2 * 2 + 1] + localKmatrix[1][3];
                    globalKMatrix[indexVertex1 * 2 + 1][indexVertex3 * 2]     = globalKMatrix[indexVertex1 * 2 + 1][indexVertex3 * 2] + localKmatrix[1][4];
                    globalKMatrix[indexVertex1 * 2 + 1][indexVertex3 * 2 + 1] = globalKMatrix[indexVertex1 * 2 + 1][indexVertex3 * 2 + 1] + localKmatrix[1][5];

                    //  Element local F2H
                    globalKMatrix[indexVertex2 * 2][indexVertex1 * 2]     = globalKMatrix[indexVertex2 * 2][indexVertex1 * 2] + localKmatrix[2][0];
                    globalKMatrix[indexVertex2 * 2][indexVertex1 * 2 + 1] = globalKMatrix[indexVertex2 * 2][indexVertex1 * 2 + 1] + localKmatrix[2][1];
                    globalKMatrix[indexVertex2 * 2][indexVertex2 * 2]     = globalKMatrix[indexVertex2 * 2][indexVertex2 * 2] + localKmatrix[2][2];
                    globalKMatrix[indexVertex2 * 2][indexVertex2 * 2 + 1] = globalKMatrix[indexVertex2 * 2][indexVertex2 * 2 + 1] + localKmatrix[2][3];
                    globalKMatrix[indexVertex2 * 2][indexVertex3 * 2]     = globalKMatrix[indexVertex2 * 2][indexVertex3 * 2] + localKmatrix[2][4];
                    globalKMatrix[indexVertex2 * 2][indexVertex3 * 2 + 1] = globalKMatrix[indexVertex2 * 2][indexVertex3 * 2 + 1] + localKmatrix[2][5];

                    //  Element local F2V
                    globalKMatrix[indexVertex2 * 2 + 1][indexVertex1 * 2]     = globalKMatrix[indexVertex2 * 2 + 1][indexVertex1 * 2] + localKmatrix[3][0];
                    globalKMatrix[indexVertex2 * 2 + 1][indexVertex1 * 2 + 1] = globalKMatrix[indexVertex2 * 2 + 1][indexVertex1 * 2 + 1] + localKmatrix[3][1];
                    globalKMatrix[indexVertex2 * 2 + 1][indexVertex2 * 2]     = globalKMatrix[indexVertex2 * 2 + 1][indexVertex2 * 2] + localKmatrix[3][2];
                    globalKMatrix[indexVertex2 * 2 + 1][indexVertex2 * 2 + 1] = globalKMatrix[indexVertex2 * 2 + 1][indexVertex2 * 2 + 1] + localKmatrix[3][3];
                    globalKMatrix[indexVertex2 * 2 + 1][indexVertex3 * 2]     = globalKMatrix[indexVertex2 * 2 + 1][indexVertex3 * 2] + localKmatrix[3][4];
                    globalKMatrix[indexVertex2 * 2 + 1][indexVertex3 * 2 + 1] = globalKMatrix[indexVertex2 * 2 + 1][indexVertex3 * 2 + 1] + localKmatrix[3][5];

                    //  Element local F3H
                    globalKMatrix[indexVertex3 * 2][indexVertex1 * 2]     = globalKMatrix[indexVertex3 * 2][indexVertex1 * 2] + localKmatrix[4][0];
                    globalKMatrix[indexVertex3 * 2][indexVertex1 * 2 + 1] = globalKMatrix[indexVertex3 * 2][indexVertex1 * 2 + 1] + localKmatrix[4][1];
                    globalKMatrix[indexVertex3 * 2][indexVertex2 * 2]     = globalKMatrix[indexVertex3 * 2][indexVertex2 * 2] + localKmatrix[4][2];
                    globalKMatrix[indexVertex3 * 2][indexVertex2 * 2 + 1] = globalKMatrix[indexVertex3 * 2][indexVertex2 * 2 + 1] + localKmatrix[4][3];
                    globalKMatrix[indexVertex3 * 2][indexVertex3 * 2]     = globalKMatrix[indexVertex3 * 2][indexVertex3 * 2] + localKmatrix[4][4];
                    globalKMatrix[indexVertex3 * 2][indexVertex3 * 2 + 1] = globalKMatrix[indexVertex3 * 2][indexVertex3 * 2 + 1] + localKmatrix[4][5];

                    //  Element local F3V
                    globalKMatrix[indexVertex3 * 2 + 1][indexVertex1 * 2]     = globalKMatrix[indexVertex3 * 2 + 1][indexVertex1 * 2] + localKmatrix[5][0];
                    globalKMatrix[indexVertex3 * 2 + 1][indexVertex1 * 2 + 1] = globalKMatrix[indexVertex3 * 2 + 1][indexVertex1 * 2 + 1] + localKmatrix[5][1];
                    globalKMatrix[indexVertex3 * 2 + 1][indexVertex2 * 2]     = globalKMatrix[indexVertex3 * 2 + 1][indexVertex2 * 2] + localKmatrix[5][2];
                    globalKMatrix[indexVertex3 * 2 + 1][indexVertex2 * 2 + 1] = globalKMatrix[indexVertex3 * 2 + 1][indexVertex2 * 2 + 1] + localKmatrix[5][3];
                    globalKMatrix[indexVertex3 * 2 + 1][indexVertex3 * 2]     = globalKMatrix[indexVertex3 * 2 + 1][indexVertex3 * 2] + localKmatrix[5][4];
                    globalKMatrix[indexVertex3 * 2 + 1][indexVertex3 * 2 + 1] = globalKMatrix[indexVertex3 * 2 + 1][indexVertex3 * 2 + 1] + localKmatrix[5][5];
                }
                //  1D simulation: {u1, u2}
                else if (element is LinearElement linearElement)
                {
                    //  {u1, u2}
                    double[][] localKmatrix = linearElement.GetKMatrix();

                    int indexVertex1 = Nodes.IndexOf(linearElement.Vertex1);
                    int indexVertex2 = Nodes.IndexOf(linearElement.Vertex2);


                    //  Element local F1H
                    globalKMatrix[indexVertex1][indexVertex1] = globalKMatrix[indexVertex1][indexVertex1] + localKmatrix[0][0];
                    globalKMatrix[indexVertex1][indexVertex2] = globalKMatrix[indexVertex1][indexVertex2] + localKmatrix[0][1];

                    //  Element local F2H
                    globalKMatrix[indexVertex2][indexVertex1] = globalKMatrix[indexVertex2][indexVertex1] + localKmatrix[1][0];
                    globalKMatrix[indexVertex2][indexVertex2] = globalKMatrix[indexVertex2][indexVertex2] + localKmatrix[1][1];
                }
            }

            return(globalKMatrix);
        }
        public void GetKMatrixLinearNElementTest()
        {
            //  ElasticCoefficient = E / (1 - v^2)
            double elasticCoefficient = 2.31E+06;

            Node node1 = new Node(0.0, 0.0);
            Node node2 = new Node(0.25, 0.0);
            Node node3 = new Node(0.5, 0.0);
            Node node4 = new Node(0.75, 0.0);
            Node node5 = new Node(1.0, 0.0);

            LinearElement element1 = new LinearElement(node1, node2);
            LinearElement element2 = new LinearElement(node2, node3);
            LinearElement element3 = new LinearElement(node3, node4);
            LinearElement element4 = new LinearElement(node4, node5);

            double[][] dMatrix = MatrixOperations.MatrixCreate(1, 1);
            dMatrix[0][0] = elasticCoefficient;

            element1.SetDMatrix(dMatrix);
            element2.SetDMatrix(dMatrix);
            element3.SetDMatrix(dMatrix);
            element4.SetDMatrix(dMatrix);

            #region Kglobal

            FiniteElementMethodModel model = new FiniteElementMethodModel();

            model.Nodes.Add(node1);
            model.Nodes.Add(node2);
            model.Nodes.Add(node3);
            model.Nodes.Add(node4);
            model.Nodes.Add(node5);
            model.Elements.Add(element1);
            model.Elements.Add(element2);
            model.Elements.Add(element3);
            model.Elements.Add(element4);

            var kGlobal = model.BuildGlobalKMatrix();

            Console.Write(kGlobal.DisplayMatrixToString());

            //  Setting displacements
            double[][] uMatrix = MatrixOperations.MatrixCreate(5, 1);

            uMatrix[0][0] = 0.0;
            uMatrix[1][0] = 0.00025;
            uMatrix[2][0] = 0.0005;
            uMatrix[3][0] = 0.00075;
            uMatrix[4][0] = 0.001;

            //  todo improve matrix inverse and determinant
            double[][] fMatrix = kGlobal.MatrixProduct(uMatrix);

            //  With those strains, this is equivalent to a force of 2310 N applying on the free side
            Assert.AreEqual(-2310, fMatrix[0][0]);
            Assert.AreEqual(0, fMatrix[1][0]);
            Assert.AreEqual(0, fMatrix[2][0]);
            Assert.AreEqual(0, fMatrix[3][0]);
            Assert.AreEqual(2310, fMatrix[4][0]);

            //  Let's get the submatrix and get its inverse to solve the problem automatically and compare its results

            double[][] subKMatrix = MatrixOperations.MatrixCreate(4, 4);
            double[][] subFMatrix = MatrixOperations.MatrixCreate(4, 1);
            int        i2         = 0;

            for (int i1 = 1; i1 < kGlobal.Length; i1++)
            {
                int j2 = 0;
                for (int j1 = 1; j1 < kGlobal[0].Length; j1++)
                {
                    subKMatrix[i2][j2] = kGlobal[i1][j1];

                    j2++;
                }

                subFMatrix[i2] = fMatrix[i1];
                i2++;
            }

            double[][] subKInverse = subKMatrix.MatrixInverse();
            double[][] newUMatrix  = subKInverse.MatrixProduct(subFMatrix);

            Assert.IsTrue(Math.Abs(uMatrix[1][0] - newUMatrix[0][0]) < 0.001);
            Assert.IsTrue(Math.Abs(uMatrix[2][0] - newUMatrix[1][0]) < 0.001);
            Assert.IsTrue(Math.Abs(uMatrix[3][0] - newUMatrix[2][0]) < 0.001);
            Assert.IsTrue(Math.Abs(uMatrix[4][0] - newUMatrix[3][0]) < 0.001);
            #endregion
        }
        public void GetKMatrixTest()
        {
            //  E/(1-v^2) = E / ((1-v)*(1+v) =	2,31E+06
            //  Modulo elastico acero: E = 2,10E+06
            //  Coeficiente de Poisson Acero: v = E/2G - 1 = 0.3
            //  Modulo de elasticidad transversal acero: G = E/(2*(1 + v)), este cálculo asume que Tension_tangencial = G * (2 * Deformacion_tangencial)
            //  La fórmula de arriba es la que aplicaremos para simplificar calculos en la matriz de derivadas, aunque en realidad: G = E /(1 + v)

            //  ElasticCoefficient = E / (1 - v^2)
            double elasticCoefficient = 2.31E+06;

            // D matrix: {Stress} = [D] * {Strain}
            //                        | 1   v      0    |   |   Strain_X    |
            //  [D] = E / (1 - v^2) * | v   1      0    | * |   Strain_Y    |
            //                        | 0   0   (1-v)/2 |   |   Strain_XY   |, Strain_XY = 2 * Actual_Strain_XY (That's why there is a 2 dividing (1-v).

            double[][] cMatrix = MatrixOperations.MatrixCreate(3, 3);
            cMatrix[0][0] = 1.0;
            cMatrix[0][1] = 0.3;
            cMatrix[0][2] = 0.0;

            cMatrix[1][0] = 0.3;
            cMatrix[1][1] = 1.0;
            cMatrix[1][2] = 0.0;

            cMatrix[2][0] = 0.0;
            cMatrix[2][1] = 0.0;
            cMatrix[2][2] = 0.35;

            Node node1 = new Node(0.0, 0.0);

            Node node2 = new Node(15.0, 0.0);

            Node node3 = new Node(0.0, 15.0);

            Node node4 = new Node(15.0, 15.0);

            //  It looks it is important that all elements are set up with the same spin direction

            //  Check what happens in 3D how does it work

            //  node1 => node4 => node3
            TriangularElement element1 = new TriangularElement(node1, node4, node3);

            //  node1 => node2 => node4
            TriangularElement element2 = new TriangularElement(node1, node2, node4);

            var dMatrix = cMatrix.MatrixProductByConstant(elasticCoefficient);

            #region Element 1

            element1.SetDMatrix(dMatrix);

            #endregion

            #region Element 2

            element2.SetDMatrix(dMatrix);

            #endregion

            #region Kglobal

            FiniteElementMethodModel model = new FiniteElementMethodModel();

            model.Nodes.Add(node1);
            model.Nodes.Add(node2);
            model.Nodes.Add(node3);
            model.Nodes.Add(node4);

            model.Elements.Add(element1);
            model.Elements.Add(element2);

            var kGlobal = model.BuildGlobalKMatrix();

            //  Setting displacements
            double[][] uMatrix = MatrixOperations.MatrixCreate(8, 1);

            uMatrix[0][0] = 0.0;
            uMatrix[1][0] = 0.0;
            uMatrix[2][0] = 0.364E-2;
            uMatrix[3][0] = 0.742E-3;
            uMatrix[4][0] = 0.0;
            uMatrix[5][0] = 0.0;
            uMatrix[6][0] = 0.316E-2;
            uMatrix[7][0] = -0.259E-3;

            //  Obtaining global matrix
            double[][] fMatrix = kGlobal.MatrixProduct(uMatrix);

            Console.Write(kGlobal.DisplayMatrixToString());

            //  Checking for absolute errors
            var absErrorF1X = Math.Abs(fMatrix[0][0] - (-3750.0));
            var absErrorF1Y = Math.Abs(fMatrix[1][0] - (-1198.0));
            var absErrorF2X = Math.Abs(fMatrix[2][0] - (3750));
            var absErrorF2Y = Math.Abs(fMatrix[3][0] - (0));
            var absErrorF3X = Math.Abs(fMatrix[4][0] - (-3750.0));
            var absErrorF3Y = Math.Abs(fMatrix[5][0] - (1198));
            var absErrorF4X = Math.Abs(fMatrix[6][0] - (3750.0));
            var absErrorF4Y = Math.Abs(fMatrix[7][0] - (0));

            //  Making sure absolute errors are less than 1%
            Assert.IsTrue(absErrorF1X < Math.Abs(fMatrix[0][0] * 0.01));
            Assert.IsTrue(absErrorF1Y < Math.Abs(fMatrix[1][0] * 0.01));
            Assert.IsTrue(absErrorF2X < Math.Abs(fMatrix[2][0] * 0.01));
            Assert.IsTrue(absErrorF2Y < 1.0);
            Assert.IsTrue(absErrorF3X < Math.Abs(fMatrix[4][0] * 0.01));
            Assert.IsTrue(absErrorF3Y < Math.Abs(fMatrix[5][0] * 0.01));
            Assert.IsTrue(absErrorF4X < Math.Abs(fMatrix[6][0] * 0.01));
            Assert.IsTrue(absErrorF4Y < 1.0);

            #endregion
        }
        public void GetKMatrix2Test()
        {
            Node node1 = new Node(0.0, 0.0);
            Node node2 = new Node(1.0, 0.0);
            Node node3 = new Node(2.0, 0.0);
            Node node4 = new Node(2.0, 1.0);
            Node node5 = new Node(1.0, 1.0);
            Node node6 = new Node(0.0, 1.0);

            TriangularElement element1 = new TriangularElement(node1, node2, node5);
            TriangularElement element2 = new TriangularElement(node2, node3, node4);
            TriangularElement element3 = new TriangularElement(node2, node4, node5);
            TriangularElement element4 = new TriangularElement(node1, node5, node6);

            double[][] dMatrix = MatrixOperations.MatrixCreate(3, 3);
            dMatrix[0][0] = 1.0;
            dMatrix[0][1] = 0.5;
            dMatrix[0][2] = 0.0;

            dMatrix[1][0] = 0.5;
            dMatrix[1][1] = 1.0;
            dMatrix[1][2] = 0.0;

            dMatrix[2][0] = 0.0;
            dMatrix[2][1] = 0.0;
            dMatrix[2][2] = 1.0;

            element1.SetDMatrix(dMatrix);
            element2.SetDMatrix(dMatrix);
            element3.SetDMatrix(dMatrix);
            element4.SetDMatrix(dMatrix);

            #region Kglobal

            FiniteElementMethodModel model = new FiniteElementMethodModel();

            model.Nodes.Add(node1);
            model.Nodes.Add(node2);
            model.Nodes.Add(node3);
            model.Nodes.Add(node4);
            model.Nodes.Add(node5);
            model.Nodes.Add(node6);

            model.Elements.Add(element1);
            model.Elements.Add(element2);
            model.Elements.Add(element3);
            model.Elements.Add(element4);

            var kGlobal = model.BuildGlobalKMatrix();

            Console.Write(kGlobal.DisplayMatrixToString());

            Assert.AreEqual(1.0, kGlobal[0][0]);
            Assert.AreEqual(-0.75, kGlobal[0][9]);
            Assert.AreEqual(-0.5, kGlobal[0][10]);

            Assert.AreEqual(-0.5, kGlobal[1][3]);
            Assert.AreEqual(-0.0, kGlobal[1][6]);
            Assert.AreEqual(-0.5, kGlobal[1][11]);

            Assert.AreEqual(2.0, kGlobal[2][2]);
            Assert.AreEqual(0.25, kGlobal[2][5]);
            Assert.AreEqual(-0.75, kGlobal[2][7]);

            Assert.AreEqual(0.25, kGlobal[3][0]);
            Assert.AreEqual(2.0, kGlobal[3][3]);
            Assert.AreEqual(-0.0, kGlobal[3][7]);

            Assert.AreEqual(0.0, kGlobal[8][0]);
            Assert.AreEqual(2.0, kGlobal[8][8]);
            Assert.AreEqual(-0.75, kGlobal[8][9]);

            #endregion
        }