Exemple #1
0
        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);
        }
Exemple #2
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];
                    }
                }
            }
        }
Exemple #3
0
        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;
            }
        }
Exemple #4
0
        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;
                }
            }
        }
Exemple #5
0
        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;
                }
            }
        }
Exemple #6
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();
        }