예제 #1
0
        public void AddBoundary(IMatrix A, double[] b, FirstBoundary boundary)
        {
            Func <double, double>[] basis = new Func <double, double>[4]
            {
                (double x) => 0.5 * (1 - x) * (3 * (1 - x) - 1) * (3 * (1 - x) - 2),
                (double x) => 4.5 * (1 - x) * x * (3 * (1 - x) - 1),
                (double x) => 4.5 * (1 - x) * x * (3 * x - 1),
                (double x) => 0.5 * x * (3 * x - 1) * (3 * x - 2)
            };

            foreach (Edge edge in boundary.Edges)
            {
                double[][] M = new double[4][]
                {
                    new double[4] {
                        8.0 / 105, 33.0 / 560, -3.0 / 140, 19.0 / 1680
                    },
                    new double[4] {
                        33.0 / 560, 27.0 / 70, -27.0 / 560, -3.0 / 140
                    },
                    new double[4] {
                        -3.0 / 140, -27.0 / 560, 27.0 / 70, 33.0 / 560
                    },
                    new double[4] {
                        19.0 / 1680, -3.0 / 140, 33.0 / 560, 8.0 / 105
                    }
                };

                double[] f = new double[4];

                double r0 = Info.Points[edge.V1].R;
                double r1 = Info.Points[edge.V4].R;
                double z0 = Info.Points[edge.V1].Z;
                double z1 = Info.Points[edge.V4].Z;

                for (int i = 0; i < 4; i++)
                {
                    f[i] = Utilities.NewtonCotes(0.0, 1.0, (double t) => edge.Function(r0 + t * (r1 - r0), z0 + t * (z1 - z0)) * basis[i](t));
                }

                double[] q = Utilities.Gauss(M, f);

                if (!(Math.Abs(r0 - Info.R0) < 1.0e-15 && Math.Abs(z0 - Info.Z0) < 1.0e-15))
                {
                    A.DI[edge.V1] = 1.0E+50;
                    b[edge.V1]    = 1.0E+50 * q[0];
                }
                A.DI[edge.V2] = 1.0E+50;
                b[edge.V2]    = 1.0E+50 * q[1];
                A.DI[edge.V3] = 1.0E+50;
                b[edge.V3]    = 1.0E+50 * q[2];

                if (!(Math.Abs(r1 - Info.R0) < 1.0e-15 && Math.Abs(z1 - Info.Z0) < 1.0e-15))
                {
                    A.DI[edge.V4] = 1.0E+50;
                    b[edge.V4]    = 1.0E+50 * q[3];
                }
            }
        }
        public void BuildBoundary(FirstBoundary boundary)
        {
            foreach (Edge edge in boundary.Edges)
            {
                int  a = edge.V1;
                int  b = edge.V4;
                bool f = a > b;
                if (f)
                {
                    (a, b) = (b, a);
                }

                edge.V2 = EdgeMatrix[a][b] + (f ? 1 : 0);
                edge.V3 = EdgeMatrix[a][b] + (f ? 0 : 1);
            }
        }