private double GetValue(int i, int j, TwoDLayer layer)
 {
     double ro = hr * (j + 1);
     return layer[i, j] + tau/(ro*hr)*(layer[i, j] - layer[i, j - 1]) +
            tau/(hr*hr)*(layer[i, j + 1] - 2*layer[i, j] + layer[i, j - 1]) +
            tau/(ro*ro*hal*hal)*(layer[i + 1, j] - 2*layer[i, j] + layer[i - 1, j]);
 }
        protected TwoDLayer PrepareLayer()
        {
            var layer = new TwoDLayer(I + 1, J + 1);
            for (int i = 0; i <= I; i++)
            {
                for (int j = 0; j <= J; j++)
                {
                    layer[i, j] = problem.Fi(j * hr, i * hal);
                }
            }

            layer.Number = 0;

            return layer;
        }
        private TwoDLayer Next(TwoDLayer firstLayer)
        {
            var secondLayer = new TwoDLayer(I + 1, J + 1);

            var n = firstLayer.Number + 1;

            // передняя грань
            for (int i = 0; i <= I; i++)
            {
                //secondLayer[i, 0] = problem.Psi();
                secondLayer[i, 0] = problem.Psi(0 * hr, i * hal, (n) * tau);
            }

            // задняя грань
            for (int i = 0; i <= I; i++)
            {
               // secondLayer[i, J] = problem.Psi(GetX(i, n), GetY(J), GetT(i, n));
                secondLayer[i, J] = problem.Psi(J * hr, i * hal , (n) * tau);
            }

            // левая грань
            for (int i = 0; i <= J; i++)
            {
                //secondLayer[0, i] = problem.Psi(GetX(0, n), GetY(i), GetT(i, n));
                secondLayer[0, i] = problem.Psi(i * hr, 0 * hal, (n) * tau);
            }

            // правая грань
            for (int i = 0; i <= J; i++)
            {
                //secondLayer[I, i] = problem.Psi(GetX(I, n), GetY(i), GetT(i, n));
                secondLayer[I, i] = problem.Psi(i * hr, I * hal, (n) * tau);
            }

            for (int i = 1; i < I; i++)
            {
                for (int j = 1; j < J; j++)
                {
                    secondLayer[i, j] = GetValue(i, j, firstLayer);
                }
            }

            secondLayer.Number = ++firstLayer.Number;

            return secondLayer;
        }
        private TwoDLayer Next(TwoDLayer firstLayer)
        {
            var newLayer = new TwoDLayer(I + 1, J + 1);
            var A = new double[(I + 1) * (J + 1), (I + 1) * (J + 1)];
            var B = new double[(I + 1) * (J + 1)];
            //var A = new SparseMatrix((I + 1) * (J + 1), (I + 1) * (J + 1));
            //var B = new SparseVector((I + 1) * (J + 1));
            for (int i = 0; i <= I; ++i)
            {
                for (int j = 0; j <= J; ++j)
                {
                    if (i == 0 || i == I || j == 0 || j == J)
                    {
                        A[i*(J + 1) + j, i*(J + 1) + j] = 1;
                        B[i * (J + 1) + j] = problem.Psi(hr * j, hal * i, (firstLayer.Number + 1) * tau);
                    }
                    else
                    {
                        B[i * (J + 1) + j] = firstLayer[i,j];
                        double ro = hr*(j + 1);
                        A[i * (J + 1) + j, i * (J + 1) + j] = 1 - (tau) / (ro * hr) + 2 * tau / (hr * hr) + 2 * tau / (ro * ro * hal * hal);
                        A[i * (J + 1) + j, (i + 1) * (J + 1) + j] = -tau / (ro * ro * hal * hal);
                        A[i * (J + 1) + j, (i - 1) * (J + 1) + j] = -tau / (ro * ro * hal * hal);
                        A[i * (J + 1) + j, (i) * (J + 1) + (j - 1)] = tau / (hr * ro) -tau  / (hr * hr);
                        A[i * (J + 1) + j, (i) * (J + 1) + (j + 1)] = -tau / (hr * hr);
                    }
                }
            }

            var seidel = systemSolver.SolveSystem(new DefaultSystemEquations(A, B), IterativeMethod.Seidel);
            var X = seidel.X;
            for (int i = 0; i <= I; ++i)
            {
                for (int j = 0; j <= J; ++j)
                {
                    newLayer[i, j] = X[i * (J + 1) + j];
                }
            }

            newLayer.Number = firstLayer.Number + 1;

            return newLayer;
        }
 double GetValue(int i, int j, TwoDLayer flayer, TwoDLayer slayer)
 {
     double ro = hr * (j + 1);
     return flayer[i, j] + tau / (ro * ro * hal * hal) * (slayer[i + 1, j] - 2 * slayer[i, j] + slayer[i - 1, j]);
 }
 double GetValue(int i, int j, TwoDLayer flayer)
 {
     double ro = hr*(j + 1);
     return flayer[i, j] + tau/(ro*hr)*(flayer[i, j] - flayer[i, j - 1]) +
            tau/(hr*hr)*(flayer[i, j + 1] - 2*flayer[i, j] + flayer[i, j - 1]);
 }
        private TwoDLayer PrepareLayer()
        {
            var layer = new TwoDLayer(I + 1, J + 1);
            for (int i = 0; i <= I; i++)
            {
                for (int j = 0; j <= J; j++)
                {
                    layer[i, j] = problem.Fi(i * h, j * h);
                }
            }

            layer.Number = 0;

            return layer;
        }