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"); } } }
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"); } } }
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); }
/// <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); }
/// <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); }
/// <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); } } }
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); }
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(); } }
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"); }