public SymmetricMatrix <DoubleContainerElement> build(ElementsMap elementsMap)
        {
            InputData input = elementsMap.input;

            SymmetricMatrix <MatrixDimension3> result = new SymmetricMatrix <MatrixDimension3>((input.Nx + 1) * (input.Ny + 1) * (input.Nz + 1), new MatrixDimension3());

            Matrix resultSegerlind = new Matrix(result.Dimension * 3, result.Dimension * 3);

            Matrix matrixD = new Matrix(6, 6);

            matrixD[0, 0] = 1;
            matrixD[0, 1] = input.poissonRatio / (1 - input.poissonRatio);
            matrixD[1, 0] = matrixD[0, 1];
            matrixD[0, 2] = input.poissonRatio / (1 - input.poissonRatio);
            matrixD[2, 0] = matrixD[0, 2];
            matrixD[1, 1] = 1;
            matrixD[1, 2] = input.poissonRatio / (1 - input.poissonRatio);
            matrixD[2, 1] = matrixD[1, 2];
            matrixD[2, 2] = 1;
            matrixD[3, 3] = (1 - 2 * input.poissonRatio) / (2 * (1 - input.poissonRatio));
            matrixD[4, 4] = (1 - 2 * input.poissonRatio) / (2 * (1 - input.poissonRatio));
            matrixD[5, 5] = (1 - 2 * input.poissonRatio) / (2 * (1 - input.poissonRatio));

            matrixD = matrixD * (input.elasticityModulus * (1 - input.poissonRatio) / ((1 + input.poissonRatio) * (1 - 2 * input.poissonRatio)));

            //StreamWriter sw = new StreamWriter("C:\\Data\\university\\master_1_year\\NM\\nm-lab-mag\\files\\log.txt");
            //sw.Close();

            foreach (var element in elementsMap.elements)
            {
                createMatrKESegerlind(element, resultSegerlind, matrixD);
                createMatrKE(element, result, matrixD);
            }
            //resultSegerlind.printToFile("C:\\Data\\university\\master_1_year\\NM\\nm-lab-mag\\files\\GeneralMatrixSegerlind.txt");
            //var sum = resultSegerlind.SumByRow();

            //var tempRes = SymmetricMatrix<MatrixDimension3>.ToMatrix(result);
            //var sumByRowTempRes = tempRes.SumByRow();
            return(SymmetricMatrix <DoubleContainerElement> .fromMatrix(resultSegerlind));
        }
        public IList <IList <Vector3D> > buildSolution(InputData inputData)
        {
            // Список перемещений на каждой итерации. Внутренний список - перемещения каждого узла внутри итерации.
            IList <IList <Vector3D> > solutions = new List <IList <Vector3D> >();

            // Весовой коэффициент (для итеративного процесса)
            double weightCoef = 0;

            // Последнее перемещения узлов
            IList <Vector3D> lastTransition = new List <Vector3D>();

            // Формируем реестр элементов
            ElementsMap elementsRegistry = new ElementsMap(inputData);

            for (int iterIndex = 0; iterIndex < inputData.iterationsCount; iterIndex++)
            {
                weightCoef += 1 / (double)inputData.iterationsCount;

                // Генерируем правую часть
                IList <Vector3D> rightSide = new List <Vector3D>();

                foreach (double proportionCoef in elementsRegistry.nodeProportions)
                {
                    rightSide.Add(new Vector3D(0, 0, -proportionCoef * weightCoef));
                }

                // Формируем обобщенную матрицу
                //SymmetricMatrix<MatrixDimension3> generalMatrix = _generalMatrixBuilder.build(elementsRegistry);
                SymmetricMatrix <DoubleContainerElement> generalMatrix = _generalMatrixBuilder.build(elementsRegistry);

                // Применяем граничные условия
                applyBoundaryConditions(generalMatrix, rightSide, inputData.boundaryConditions);

                // Решаем систему
                IList <Vector3D> solution = _choleskySolver.solve(generalMatrix, rightSide);

                // Считаем перемещение на текущей итерации и добавляем в результат
                if (lastTransition.Count > 0)
                {
                    if (lastTransition.Count != solution.Count)
                    {
                        throw new ArgumentException("Size of lastTransition and solution list must be the same!");
                    }
                    List <Vector3D> buffer = new List <Vector3D>();
                    for (int nodeIndex = 0; nodeIndex < lastTransition.Count; nodeIndex++)
                    {
                        buffer.Add(solution[nodeIndex] - lastTransition[nodeIndex]);
                    }
                    solutions.Add(buffer);
                }
                else
                {
                    solutions.Add(solution);
                }

                lastTransition = solution;
            }


            return(solutions);
        }