public void Compute_Success()
        {
            //Arrange
            //Устанавливаем сетку 3x3 с единичными начальными и граничными условиями
            //1 0 1
            //1 0 1
            //1 1 1
            var net = new MathNet2(2, 2, 1, 1);

            //Начальные и граничные условия условия
            for (var i = 0; i <= net.Width; i++)
            {
                net.Set(i, 0, 1);
                net.Set(0, i, 1);
                net.Set(net.Width, i, 1);
            }

            double Func(double x, double t) => x + t * 10;

            var method = new ExplicitMethod(Func);

            //Act
            method.Compute(net);

            //Assert
            Assert.Equal(2, net.Get(1, 1));
            Assert.Equal(11, net.Get(1, 2));
        }
 public void Compute(MathNet2 net)
 {
     //Вычисляем по слоям по времени
     for (var j = 0; j < net.Height; j++)
     {
         var approximation    = net.GetRow(j);
         var newtonIsComplete = false;
         while (!newtonIsComplete)
         {
             //Получаем новое преближение с помощью метода ньютона
             var nextAproximation = GetNextApproximation(net, approximation, j);
             //Вычисление ошибки
             var error = nextAproximation
                         .Zip(approximation, (e1, e2) => Math.Abs(e1 - e2))
                         .Max();
             newtonIsComplete = error < NewtonEpsilon;
             approximation    = nextAproximation;
         }
         //Подставляем преближение в сетку с результатом
         for (var i = 1; i < net.Width; i++)
         {
             net.Set(i, j + 1, approximation[i]);
         }
     }
 }
        public void Ctor_Success_TestCases(MathNetTestCase @case)
        {
            //Arrange and Act
            var net = new MathNet2(@case.MaxX, @case.MaxT, @case.H, @case.D);

            Assert.Equal(@case.Widht, net.Width);
            Assert.Equal(@case.Height, net.Height);
        }
Beispiel #4
0
 public override void Compute(MathNet2 net)
 {
     for (var j = 1; j <= net.Height; j++)
     {
         var tdmaResult = ComputeTriagonalMatrix(net, j);
         for (var i = 1; i < net.Width; i++)
         {
             net.Set(i, j, tdmaResult[i]);
         }
     }
 }
        public double[] GetNextApproximation(MathNet2 net, double[] approximation, int j)
        {
            //Коэфиценты для построения матрицы
            double a, b;

            a = b = -net.D / (2 * net.H * net.H);
            var t = net.D * j;

            //Подготавливаем трехдиагональную матрицу c правыми частями
            var n      = net.Width - 1;
            var matrix = new double[n, n];
            var values = new double[n];


            for (var i = 0; i < n; i++)
            {
                //Заполняем матрицу
                if (i > 0)
                {
                    matrix[i - 1, i] = a;
                }
                matrix[i, i] = _differenceFunctionDerivative(approximation[i]) + net.D / (net.H * net.H);
                if (i < n - 1)
                {
                    matrix[i + 1, i] = b;
                }

                //Заполняем правую часть
                var x = i * net.H;
                values[i] = -(_differenceFunction(approximation[i])
                              - _differenceFunction(net.Get(i, j))
                              - _differenceFunctionDerivative(approximation[i]) * approximation[i]
                              - net.D * _heterogeniousFunction(x, t))
                            + net.D / (2 * net.H * net.H) * (approximation[i + 2] - 2 * approximation[i + 1] + approximation[i]);
            }

            //Коректируем с помощью граничных условий
            values[0]     -= net.Get(0, j);
            values[n - 1] -= net.Get(net.Width, j);
            var tdma = AlgoritmContext.Current.TridiagonalMatrixAlgoritm(matrix, values);
            //Заполняем граничные условия
            var result = new double[net.Width + 1];

            result[0] = net.Get(0, j);
            for (var i = 1; i < tdma.Length; i++)
            {
                result[i] = tdma[i];
            }
            result[net.Width] = net.Get(net.Width, j);
            return(result);
        }
        protected double[] ComputeTriagonalMatrix(MathNet2 net, int j)
        {
            //Коэфиценты для построения матрицы
            double a, b, c;
            var    dh2 = net.D / (2 * net.H * net.H);

            a = b = -dh2;
            c = 1 + 2 * dh2;
            var t = net.D * (j - 1);

            //Подготавливаем трехдиагональную матрицу c правыми частями
            var n      = net.Width - 1;
            var matrix = new double[n, n];
            var values = new double[n];

            for (var i = 0; i < n; i++)
            {
                //Заполняем матрицу
                if (i > 0)
                {
                    matrix[i - 1, i] = a;
                }
                matrix[i, i] = c;
                if (i < n - 1)
                {
                    matrix[i + 1, i] = b;
                }

                //Заполняем правую часть
                var x = (i + 1) * net.H;
                values[i] = Function(x, t) * net.D +
                            net.Get(i + 1, j - 1) +
                            dh2 * (net.Get(i, j - 1) - 2 * net.Get(i + 1, j - 1) + net.Get(i + 2, j - 1));
            }

            //Коректируем с помощью граничных условий
            values[0]     -= net.Get(0, j) * a;
            values[n - 1] -= net.Get(net.Width, j) * a;
            var tdma = AlgoritmContext.Current.TridiagonalMatrixAlgoritm(matrix, values);
            //Заполняем граничные условия
            var result = new double[net.Width + 1];

            result[0] = net.Get(0, j);
            for (var i = 0; i < tdma.Length; i++)
            {
                result[i + 1] = tdma[i];
            }
            result[net.Width] = net.Get(net.Width, j);
            return(result);
        }
        public override void Compute(MathNet2 net)
        {
            for (var j = 1; j <= net.Height; j++)
            {
                for (var i = 1; i < net.Width; i++)
                {
                    var x     = net.H * i;
                    var t     = net.D * (j - 1);
                    var value = net.Get(i, j - 1) + net.D *
                                ((net.Get(i + 1, j - 1) - 2 * net.Get(i, j - 1) + net.Get(i - 1, j - 1))
                                 / (net.H * net.H) + Function(x, t));

                    net.Set(i, j, value);
                }
            }
        }
Beispiel #8
0
 public abstract void Compute(MathNet2 net);