public double U(Point p) { FiniteElement element = null; foreach (FiniteElement e in Info.Mesh) { if (Utilities.PointInsideTriangle(Info.Points[e.V1], Info.Points[e.V2], Info.Points[e.V3], p)) { element = e; break; } } if (element != null) { (double L1, double L2, double L3) = Utilities.GetL(Info.Points[element.V1], Info.Points[element.V2], Info.Points[element.V3], p); double result = 0.0; for (int i = 0; i < FEMInfo.BasisSize; i++) { result += Weights[element.Vertices[i]] * FEMInfo.LBasis[i](L1, L2, L3); } return(result); } return(0.0); }
void AddLocalToGlobal(IMatrix A, double[] B, FiniteElement e) { for (int i = 0; i < FEMInfo.BasisSize; i++) { A.DI[e.Vertices[i]] += local[i, i]; B[e.Vertices[i]] += localb[i]; for (int j = 0; j < i; j++) { int a = e.Vertices[i]; int b = e.Vertices[j]; if (a < b) { (a, b) = (b, a); } if (A.IA[a + 1] > A.IA[a]) { Span <int> span = new Span <int>(A.JA, A.IA[a], A.IA[a + 1] - A.IA[a]); int k; for (k = 0; k < A.IA[a + 1] - A.IA[a]; k++) { if (span[k] == b) { break; } } int index = A.IA[a] + k; A.AL[index] += local[i, j]; } } } }
void BuildLocalB(FiniteElement e) { Point a = Info.Points[e.V1]; Point b = Info.Points[e.V2]; Point c = Info.Points[e.V3]; Point[] coords = Utilities.TriangleCubicPoints(a, b, c); double D = Math.Abs(Utilities.Det(a, b, c)); double[] temp = new double[FEMInfo.BasisSize]; for (int i = 0; i < FEMInfo.BasisSize; i++) { temp[i] = Info.F(coords[i].R, coords[i].Z); } for (int i = 0; i < FEMInfo.BasisSize; i++) { localb[i] = temp[0] * M[i][0]; for (int j = 1; j < FEMInfo.BasisSize; j++) { localb[i] += temp[j] * M[i][j]; } localb[i] *= D; } }
void BuildLocalMatrix(FiniteElement e) { Point a = Info.Points[e.V1]; Point b = Info.Points[e.V2]; Point c = Info.Points[e.V3]; double D = Math.Abs(Utilities.Det(a, b, c)); double[] alpha = Utilities.Alpha(a, b, c); Grad[] grads = new Grad[3] { new Grad(alpha[0], alpha[1]), new Grad(alpha[2], alpha[3]), new Grad(alpha[4], alpha[5]) }; for (int i = 0; i < FEMInfo.BasisSize; i++) { Array.Fill(M[i], 0.0); } for (int i = 0; i < FEMInfo.BasisSize; i++) { for (int j = 0; j < FEMInfo.BasisSize; j++) { double G = 0; foreach (FEMInfo.LocalCompG comp in gPattern[i, j]) { double scalGrad = grads[comp.Grad1].R * grads[comp.Grad2].R + grads[comp.Grad1].Z * grads[comp.Grad2].Z; G += comp.Coefficient * scalGrad * Info.Points[e.Vertices[comp.Rnum]].R; } foreach (FEMInfo.LocalCompM comp in mPattern[i, j]) { M[i][j] += comp.Coefficient * Info.Points[e.Vertices[comp.Rnum]].R; } local[i, j] = (e.Material.Gamma * M[i][j] + e.Material.Sigma * G) * D; } } }
void BuildLocalB(FiniteElement e) { Point a = Info.Points[e.V1]; Point b = Info.Points[e.V2]; Point c = Info.Points[e.V3]; Point[] coords = Utilities.TriangleCubicPoints(a, b, c); for (int i = 0; i < FEMInfo.BasisSize; i++) { if (Math.Abs(coords[i].R - Info.R0) < 1.0e-15 && Math.Abs(coords[i].Z - Info.Z0) < 1.0e-15) { localb[i] = 1.0 * Info.DeltaCoefficient; } else { localb[i] = 0.0; } } }
public void Analys(List <Node> nodes, List <Triangle> triangles, int nx, int ny) { // Собственно метод МКЭ: сборка и решение СЛАУ K = new DenseMatrix(nodes.Count); F = new DenseVector(nodes.Count); FiniteElement element = new FiniteElement(); // Ансамблирование // Цикл по всем КЭ for (int k = 0; k < triangles.Count; k++) { Triangle tr = triangles[k]; // Локальная матрица жетскости КЭ DenseMatrix Ke = element.ElementMatrix(nodes[tr.nodes[0]], nodes[tr.nodes[1]], nodes[tr.nodes[2]]); // Локальный вектор нагрузок КЭ DenseVector Fe = element.GetVector(); // Добавление локальной матрицы к глобальной for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { K[tr.nodes[i], tr.nodes[j]] += Ke[i, j]; } // Добавление локального вектора к глобальному if (nodes[tr.nodes[i]].isload) { F[tr.nodes[i]] += nodes[tr.nodes[i]].load * Fe[i]; } } } // Внесение в систему граничных условий for (int i = 0; i < nodes.Count; i++) { if (!nodes[i].boundary) { continue; } for (int j = 0; j < nodes.Count; j++) { F[j] -= nodes[i].value * K[j, i]; K[i, j] = 0; K[j, i] = 0; } K[i, i] = 1; F[i] = nodes[i].value; } // Решение системы DenseVector x = (DenseVector)K.LU().Solve(F); // Вывод результатов в файл FileStream fs = File.Create("all.txt"); StreamWriter sw = new StreamWriter(fs); for (int i = 0; i < nx + 1; i++) { for (int j = 0; j < ny + 1; j++) { int k = i * (ny + 1) + j; double err = Math.Abs(1 - x[k] / Fan(nodes[k].x, nodes[k].y)); String s = String.Format(CultureInfo.CreateSpecificCulture("en-US"), "{0,14:E} {1,14:E} {2,14:E} {3,14:E}", nodes[k].x, nodes[k].y, x[k], err); sw.WriteLine(s); } sw.WriteLine(); } sw.Close(); fs.Close(); }