Пример #1
0
        public void Solve(TypeOfFixation type, IBoundaryCondition conditions, ILoad load)
        {
            globalMatrix = solver.GlobalMatrix;
            results      = new double[length];

            SetLoads(load);
            SetBoundaryConditions(type, conditions);

            //List<double> nonZeroRows = globalMatrix.Storage.EnumerateNonZero().ToList();

            var iterationCountStopCriterion = new IterationCountStopCriterion <double>(length >> 1);
            var residualStopCriterion       = new ResidualStopCriterion <double>(ACCURACY);

            var monitor = new Iterator <double>(iterationCountStopCriterion, residualStopCriterion);

            var solverM = new TFQMR();

            //Vector<double> vectorResults = globalMatrix.LU().Solve(Vector.Build.DenseOfArray(loads));
            Vector <double> vectorResults = globalMatrix
                                            .SolveIterative(Vector.Build.DenseOfArray(loads), solverM, monitor);

            results = vectorResults.ToArray();
            for (int i = 0; i < results.Length; i++)
            {
                if (globalMatrix[i, i] == 1.0)
                {
                    results[i] = 0.0;
                }
            }
        }
        private void SetBoundaryConditions(TypeOfFixation type, IBoundaryCondition conditions)
        {
            foreach (var item in conditions.FixedNodes)
            {
                int ind = item.Key * DEGREES_OF_FREEDOM;
                switch (type)
                {
                case TypeOfFixation.RIGID:
                    MathOps.SetZerosRow(ref globalMatrix, ind);
                    MemoryMatrix.SetDoubleValue(ref globalMatrix, ind, ind, 1.0);
                    MathOps.SetZerosRow(ref globalMatrix, ind + 1);
                    MemoryMatrix.SetDoubleValue(ref globalMatrix, ind + 1, ind + 1, 1.0);
                    MathOps.SetZerosRow(ref globalMatrix, ind + 2);
                    MemoryMatrix.SetDoubleValue(ref globalMatrix, ind + 2, ind + 2, 1.0);

                    loads[ind]     = 0.0;
                    loads[ind + 1] = 0.0;
                    loads[ind + 2] = 0.0;
                    break;

                case TypeOfFixation.ARTICULATION_YZ: throw new NotImplementedException();

                case TypeOfFixation.ARTICULATION_XZ: throw new NotImplementedException();

                case TypeOfFixation.ARTICULATION_XY: throw new NotImplementedException();

                default: throw new ArgumentException("Wrong type of the fixation");
                }
            }
        }
Пример #3
0
        private void SetBoundaryConditions(TypeOfFixation type, IBoundaryCondition conditions)
        {
            foreach (var item in conditions.FixedNodes)
            {
                switch (type)
                {
                case TypeOfFixation.RIGID:
                    MathOps.SetZerosRow(ref globalMatrix, item.Key * DEGREES_OF_FREEDOM);
                    globalMatrix[item.Key * DEGREES_OF_FREEDOM, item.Key *DEGREES_OF_FREEDOM] = 1.0;
                    MathOps.SetZerosRow(ref globalMatrix, item.Key * DEGREES_OF_FREEDOM + 1);
                    globalMatrix[item.Key * DEGREES_OF_FREEDOM + 1, item.Key *DEGREES_OF_FREEDOM + 1] = 1.0;
                    MathOps.SetZerosRow(ref globalMatrix, item.Key * DEGREES_OF_FREEDOM + 2);
                    globalMatrix[item.Key * DEGREES_OF_FREEDOM + 2, item.Key *DEGREES_OF_FREEDOM + 2] = 1.0;

                    loads[item.Key * DEGREES_OF_FREEDOM]     = 0.0;
                    loads[item.Key * DEGREES_OF_FREEDOM + 1] = 0.0;
                    loads[item.Key * DEGREES_OF_FREEDOM + 2] = 0.0;
                    break;

                case TypeOfFixation.ARTICULATION_YZ: throw new NotImplementedException();

                case TypeOfFixation.ARTICULATION_XZ: throw new NotImplementedException();

                case TypeOfFixation.ARTICULATION_XY: throw new NotImplementedException();

                default: throw new ArgumentException("Wrong type of the fixation");
                }
            }
        }
Пример #4
0
        private void SetBoundaryConditions(TypeOfFixation type, IBoundaryCondition conditions)
        {
            foreach (var node in conditions.FixedNodes)
            {
                switch (type)
                {
                case TypeOfFixation.RIGID:
                    globalMatrix.ClearRow(node.Key * DEGREES_OF_FREEDOM);
                    //globalMatrix.ClearColumn(node.Key * DEGREES_OF_FREEDOM);
                    globalMatrix[node.Key * DEGREES_OF_FREEDOM, node.Key *DEGREES_OF_FREEDOM] = 1.0;

                    globalMatrix.ClearRow(node.Key * DEGREES_OF_FREEDOM + 1);
                    //globalMatrix.ClearColumn(node.Key * DEGREES_OF_FREEDOM + 1);
                    globalMatrix[node.Key * DEGREES_OF_FREEDOM + 1, node.Key *DEGREES_OF_FREEDOM + 1] = 1.0;

                    globalMatrix.ClearRow(node.Key * DEGREES_OF_FREEDOM + 2);
                    //globalMatrix.ClearColumn(node.Key * DEGREES_OF_FREEDOM + 2);
                    globalMatrix[node.Key * DEGREES_OF_FREEDOM + 2, node.Key *DEGREES_OF_FREEDOM + 2] = 1.0;

                    loads[node.Key * DEGREES_OF_FREEDOM]     = 0.0;
                    loads[node.Key * DEGREES_OF_FREEDOM + 1] = 0.0;
                    loads[node.Key * DEGREES_OF_FREEDOM + 2] = 0.0;
                    break;

                case TypeOfFixation.ARTICULATION_YZ: throw new NotImplementedException();

                case TypeOfFixation.ARTICULATION_XZ: throw new NotImplementedException();

                case TypeOfFixation.ARTICULATION_XY: throw new NotImplementedException();

                default: throw new ArgumentException("Wrong type of the fixation");
                }
            }
        }
        public void Solve(TypeOfFixation type, IBoundaryCondition conditions, ILoad load)
        {
            globalMatrix = solver.GlobalMatrix;
            results      = new double[length];


            SetLoads(load);
            SetBoundaryConditions(type, conditions, globalMatrix);

            var           storage     = globalMatrix.Storage as SparseCompressedRowMatrixStorage <double>;
            List <double> nonZeroRows = globalMatrix.Storage.EnumerateNonZero().ToList();

            //CudaSolveSparse sp = new CudaSolveSparse();
            //CudaSparseMatrixDescriptor matrixDescriptor = new CudaSparseMatrixDescriptor();
            //        sp.CsrlsvluHost(globalMatrix.RowCount, nonZeroRows.Count, matrixDescriptor, nonZeroRows.ToArray(),
            //storage.RowPointers, storage.ColumnIndices, loads, ACCURACY, 0, results);

            for (int i = 0; i < results.Length; i++)
            {
                if (globalMatrix[i, i] == 1.0)
                {
                    results[i] = 0.0;
                }
            }
        }
        /// <summary>
        /// Solves the problem of stress-strain state
        /// </summary>
        /// <param name="type">Type of fixation</param>
        /// <param name="conditions">Boundary conditions</param>
        /// <returns>Result vector</returns>
        public void Solve(TypeOfFixation type, IBoundaryCondition conditions, ILoad load)
        {
            globalMatrix = solver.GlobalMatrix;
            results      = new double[globalMatrix.Count];

            SetLoads(load);
            SetBoundaryConditions(type, conditions);

            results = MathOps.MethodOfGauss(ref globalMatrix, loads);
        }
Пример #7
0
        /// <summary>
        /// Solves the problem of stress-strain state
        /// </summary>
        /// <param name="type">Type of fixation</param>
        /// <param name="conditions">Boundary conditions</param>
        /// <returns>Result vector</returns>
        public void Solve(TypeOfFixation type, IBoundaryCondition conditions, ILoad load)
        {
            globalMatrix = solver.GlobalMatrix;
            results      = new double[globalMatrix.GetLength(1)];

            SetLoads(load);
            SetBoundaryConditions(type, conditions);

            results = MathOps.GausSlau(globalMatrix, loads);
        }
Пример #8
0
        /// <summary>
        /// Solves the problem of stress-strain state
        /// </summary>
        /// <param name="type">Type of fixation</param>
        /// <param name="conditions">Boundary conditions</param>
        /// <returns>Result vector</returns>
        public void Solve(TypeOfFixation type, IBoundaryCondition conditions, ILoad load)
        {
            results = new double[solver.GlobalMatrix.Length];

            SetLoads(load);
            SetBoundaryConditions(type, conditions);

            results = MathOps.MethodOfGauss(DIRECTORY_PATH, globalMatrix, loads);
            //results = MathOps.CGMethod(DIRECTORY_PATH, globalMatrix, loads, EPSILON);
        }
Пример #9
0
        /// <summary>
        /// Solves the problem of stress-strain state
        /// </summary>
        /// <param name="type">Type of fixation</param>
        /// <param name="conditions">Boundary conditions</param>
        /// <returns>Result vector</returns>
        public void Solve(TypeOfFixation type, IBoundaryCondition conditions, ILoad load)
        {
            //globalMatrix = solver.GlobalMatrix;
            results = new double[lengthMatrix];

            using (globalMatrix = MappedMatrix.Open("global.matrix", "globalMatrix"))
            {
                using (var accessor = globalMatrix.CreateViewAccessor())
                {
                    SetLoads(load);
                    SetBoundaryConditions(accessor, type, conditions);

                    results = MathOps.MethodOfGauss(accessor, loads);
                }
            }
        }
Пример #10
0
        public void Solve(TypeOfFixation type, IBoundaryCondition conditions, ILoad load)
        {
            globalMatrix = solver.GlobalMatrix;
            results      = new double[length];

            //MathOps.IncompleteCholeskyFactorization(ref globalMatrix);
            //DictionaryMatrix C = MathOps.Multiply(ref globalMatrix);

            AddZeros();
            SetLoads(load);
            //SetBoundaryConditions(type, conditions, C);
            SetBoundaryConditions(type, conditions, globalMatrix);

            results = MathOps.MethodOfGauss(globalMatrix, loads);
            //results = MathOps.CGMethod(globalMatrix, loads, EPSILON);
            //results = MathOps.CGMethod(C, loads, EPSILON);
        }
Пример #11
0
        private void SetBoundaryConditions(TypeOfFixation type, IBoundaryCondition conditions, DictionaryMatrix dictionaryMatrix)
        {
            int processCount = conditions.FixedNodes.Count;

            using (ManualResetEvent resetEvent = new ManualResetEvent(false))
            {
                foreach (var item in conditions.FixedNodes)
                {
                    ThreadPool.QueueUserWorkItem(thrItem =>
                    {
                        KeyValuePair <int, Node> node = (KeyValuePair <int, Node>)thrItem;

                        switch (type)
                        {
                        case TypeOfFixation.RIGID:
                            MathOps.SetZerosRowColumn(ref dictionaryMatrix, node.Key * DEGREES_OF_FREEDOM, length);
                            dictionaryMatrix.SetValue(node.Key * DEGREES_OF_FREEDOM, node.Key * DEGREES_OF_FREEDOM, 1.0);
                            MathOps.SetZerosRowColumn(ref dictionaryMatrix, node.Key * DEGREES_OF_FREEDOM + 1, length);
                            dictionaryMatrix.SetValue(node.Key * DEGREES_OF_FREEDOM + 1, node.Key * DEGREES_OF_FREEDOM + 1, 1.0);
                            MathOps.SetZerosRowColumn(ref dictionaryMatrix, node.Key * DEGREES_OF_FREEDOM + 2, length);
                            dictionaryMatrix.SetValue(node.Key * DEGREES_OF_FREEDOM + 2, node.Key * DEGREES_OF_FREEDOM + 2, 1.0);

                            loads[node.Key * DEGREES_OF_FREEDOM]     = 0.0;
                            loads[node.Key * DEGREES_OF_FREEDOM + 1] = 0.0;
                            loads[node.Key * DEGREES_OF_FREEDOM + 2] = 0.0;
                            break;

                        case TypeOfFixation.ARTICULATION_YZ: throw new NotImplementedException();

                        case TypeOfFixation.ARTICULATION_XZ: throw new NotImplementedException();

                        case TypeOfFixation.ARTICULATION_XY: throw new NotImplementedException();

                        default: throw new ArgumentException("Wrong type of the fixation");
                        }
                        if (Interlocked.Decrement(ref processCount) == 0)
                        {
                            resetEvent.Set();
                        }
                    }, item);
                }
                resetEvent.WaitOne();
            }
        }
Пример #12
0
        private void Button2_Click(object sender, EventArgs e)
        {
            //trnglRepository = new StlTriangularRepository<string>();
            tetrahedralRepository = new StlTetrahedralRepository <string>();
            trinagleRepository    = new StlTriangularRepository2 <string>();

            List <List <Triangle> > vertebras  = new List <List <Triangle> >();
            List <Triangle>         myvertebra = new List <Triangle>();

            myvertebra = ReadVertebra(1, "Vertebras/st1/");

            vertebras.Add(myvertebra);

            //vertebras.Add(ReadVertebra(1, "Vertebras/st2/"));
            //int countVertebras = 5;
            //for (int i = 2; i <= countVertebras; i++)
            //{
            //    vertebras.Add(ReadVertebra(i, "Vertebras/st2/"));
            //}

            List <Triangle> allVertebras = new List <Triangle>();

            vertebras.ForEach(trngls => allVertebras.AddRange(trngls));

            double shiftX = Math.Abs(allVertebras.Min(tngl => tngl.Center.X));
            double shiftY = Math.Abs(allVertebras.Min(tngl => tngl.Center.Y));
            double shiftZ = Math.Abs(allVertebras.Min(tngl => tngl.Center.Z));

            double minX   = allVertebras.Min(tngl => tngl.Center.X);
            double minY   = allVertebras.Min(tngl => tngl.Center.Y);
            double minZ   = allVertebras.Min(tngl => tngl.Center.Z);
            double maxX   = allVertebras.Max(tngl => tngl.Center.X);
            double maxY   = allVertebras.Max(tngl => tngl.Center.Y);
            double maxZ   = allVertebras.Max(tngl => tngl.Center.Z);
            double avX    = (minX + maxX) / 2.0;
            double avY    = (minY + maxY) / 2.0;
            double lenght = maxX - minX;
            double width  = maxY - minY;

            width = (lenght > width) ? lenght : width;
            double height = maxZ - minZ;

            ShiftModel(ref vertebras, shiftX, shiftY, shiftZ);
            //ShiftModel(ref disks, shiftX, shiftY, shiftZ);

            toolStripStatusLabel1.Text = $"Генерация конечно-элементной сетки...";
            this.Refresh();

            FeModel scene = GenerateTetrahedralModel(width, height + STEP_HEIGHT, STEP_WIDTH, STEP_HEIGHT, VERTEBRA_MATERIAL_ID);

            model = GetGeneralModelFromScene(scene, vertebras);
            var aaaaaa = model.Triangles;
            var bbbbbb = model.Tetrahedrons;

            //load = new Force(SelectedSide.TOP, new Node((int)avX, (int)avY, maxZ - 10), forceValue, true, model.Triangles);

            toolStripStatusLabel1.Text = $"Учет граничных условий и внешних нагрузок...";
            this.Refresh();

            //load = new Force(SelectedSide.TOP, new Node((int)avY, (int)avX, maxZ - 10), forceValue, true, model.Triangles);
            //load = new Pressure(SelectedSide.TOP, new Node((int)avX, (int)avY, maxZ - 10), forceValue, true, model.Triangles);
            //load = new ConcentratedForce(SelectedSide.TOP, forceValue, true, model.Nodes, height / 10.0);
            load       = new Force(SelectedSide.TOP, forceValue, true, model.Nodes, height / 18.0);
            conditions = new VolumeBoundaryCondition(SelectedSide.BOTTOM, model.Nodes, height / 20.0);
            //conditions = new VolumeBoundaryCondition(SelectedSide.BOTTOM, new Node((int)avX, (int)avY, minZ), model.Triangles);
            tetrahedralRepository.Create(model.Id + "in", model.Tetrahedrons);

            int         concentratedIndex = load.LoadVectors.FirstOrDefault().Key;
            int         step      = (int)(STEP_HEIGHT / 4.0);
            Node        tmpNode   = model.Nodes.FirstOrDefault(nd => nd.GlobalIndex == concentratedIndex);
            List <Node> nearNodes = new List <Node>(model.Nodes.Where(nd =>
                                                                      (nd.X > model.Nodes[concentratedIndex].X - step && nd.X < model.Nodes[concentratedIndex].X + step) &&
                                                                      (nd.Y > model.Nodes[concentratedIndex].Y - step && nd.Y < model.Nodes[concentratedIndex].Y + step) &&
                                                                      (nd.Z > model.Nodes[concentratedIndex].Z - step && nd.Z < model.Nodes[concentratedIndex].Z + step))
                                                    .ToList());

            nearNodes.Remove(tmpNode);

            concentratedIndex = TrueIndexOfCenter(concentratedIndex, nearNodes, 0);
            if (concentratedIndex != load.LoadVectors.FirstOrDefault().Key)
            {
                LoadVector vector = new LoadVector(load.LoadVectors.FirstOrDefault().Value.Value, VectorDirection.Z);
                load.LoadVectors.Clear();
                load.LoadVectors.Add(concentratedIndex, vector);
            }

            //trnglRepository.Create(model.Id + "in", model.Triangles);
            //trnglRepository.Create(model.Id + "load", ((Force)load).LoadedTriangles);
            //trnglRepository.Create(model.Id + "fix", ((VolumeBoundaryCondition)conditions).FixedTriangles);



            solver   = new StressStrainSparseMatrix(model);
            solution = new StaticMechanicSparseSolution(solver, model);

            var begin = DateTime.Now;

            solution.Solve(TypeOfFixation.RIGID, conditions, load);

            TimeSpan endSolve = DateTime.Now - begin;

            double[] results = solution.Results;

            toolStripStatusLabel1.Text = $"Расчет завершен.";
            this.Refresh();

            using (StreamWriter writer = new StreamWriter("results.txt"))
            {
                writer.WriteLine($"Total time solving SLAE: {endSolve.TotalSeconds} sec.");
                writer.WriteLine();
                double max = solution.Results[2];
                for (int i = 2; i < solution.Results.Length; i += 3)
                {
                    if (Math.Abs(solution.Results[i]) > Math.Abs(max))
                    {
                        max = solution.Results[i];
                    }
                }

                writer.WriteLine($"Max deformation: {max} mm.");
                writer.WriteLine();

                for (int i = 0; i < solution.Results.Length; i++)
                {
                    writer.WriteLine(solution.Results[i]);
                }
            }

            TotalEpure(model.Nodes, solution.Results, "TotalEpureSpine");

            List <Tetrahedron> outList = ApplyResultsToTetrahedrons(results);
            List <Node>        nodlist = ApplyResultsToGenList(results);

            tetrahedralRepository.Create(model.Id + "out", outList);
            tetrahedralRepository.Create2(model.Id + "out2", outList);
            trinagleRepository.Create2(model.Id + "out3", myvertebra, nodlist);

            lastname          = model.Id + "out3.stl";
            lastname_fullpath = Environment.CurrentDirectory + "\\" + lastname;

            MessageBox.Show($"Total time solving SLAE: {endSolve.TotalSeconds} sec.");

            //Process.Start("notepad.exe", "results.txt");
        }