示例#1
0
    private static void Main()
    //****************************************************************************80
    //
    //  Purpose:
    //
    //    MAIN is the main program for FD1D_HEAT_IMPLICIT.
    //
    //  Discussion:
    //
    //    FD1D_HEAT_IMPLICIT solves the 1D heat equation with an implicit method.
    //
    //    This program solves
    //
    //      dUdT - k * d2UdX2 = F(X,T)
    //
    //    over the interval [A,B] with boundary conditions
    //
    //      U(A,T) = UA(T),
    //      U(B,T) = UB(T),
    //
    //    over the time interval [T0,T1] with initial conditions
    //
    //      U(X,T0) = U0(X)
    //
    //    The code uses the finite difference method to approximate the
    //    second derivative in space, and an implicit backward Euler approximation
    //    to the first derivative in time.
    //
    //    The finite difference form can be written as
    //
    //      U(X,T+dt) - U(X,T)                  ( U(X-dx,T) - 2 U(X,T) + U(X+dx,T) )
    //      ------------------  = F(X,T) + k *  ------------------------------------
    //               dt                                   dx * dx
    //
    //    so that we have the following linear system for the values of U at time T+dt:
    //
    //            -     k * dt / dx / dx   * U(X-dt,T+dt)
    //      + ( 1 + 2 * k * dt / dx / dx ) * U(X,   T+dt)
    //            -     k * dt / dx / dx   * U(X+dt,T+dt)
    //      =               dt             * F(X,   T+dt)
    //      +                                U(X,   T)
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    31 May 2009
    //
    //  Author:
    //
    //    John Burkardt
    //
    {
        int i;
        int j;

        Console.WriteLine("");
        Console.WriteLine("FD1D_HEAT_IMPLICIT");
        Console.WriteLine("");
        Console.WriteLine("  Finite difference solution of");
        Console.WriteLine("  the time dependent 1D heat equation");
        Console.WriteLine("");
        Console.WriteLine("    Ut - k * Uxx = F(x,t)");
        Console.WriteLine("");
        Console.WriteLine("  for space interval A <= X <= B with boundary conditions");
        Console.WriteLine("");
        Console.WriteLine("    U(A,t) = UA(t)");
        Console.WriteLine("    U(B,t) = UB(t)");
        Console.WriteLine("");
        Console.WriteLine("  and time interval T0 <= T <= T1 with initial condition");
        Console.WriteLine("");
        Console.WriteLine("    U(X,T0) = U0(X).");
        Console.WriteLine("");
        Console.WriteLine("  A second order difference approximation is used for Uxx.");
        Console.WriteLine("");
        Console.WriteLine("  A first order backward Euler difference approximation");
        Console.WriteLine("  is used for Ut.");

        const double k = 5.0E-07;
        //
        //  Set X values.
        //
        const double x_min  = 0.0;
        const double x_max  = 0.3;
        const int    x_num  = 11;
        const double x_delt = (x_max - x_min) / (x_num - 1);

        double[] x = new double[x_num];

        for (i = 0; i < x_num; i++)
        {
            x[i] = ((x_num - i - 1) * x_min
                    + i * x_max)
                   / (x_num - 1);
        }

        //
        //  Set T values.
        //
        const double t_min  = 0.0;
        const double t_max  = 22000.0;
        const int    t_num  = 51;
        const double t_delt = (t_max - t_min) / (t_num - 1);

        double[] t = new double[t_num];

        for (j = 0; j < t_num; j++)
        {
            t[j] = ((t_num - j - 1) * t_min
                    + j * t_max)
                   / (t_num - 1);
        }

        //
        //  Set the initial data, for time T_MIN.
        //
        double[] u = new double[x_num * t_num];

        u0(x_min, x_max, t_min, x_num, x, ref u);
        //
        //  The matrix A does not change with time.  We can set it once,
        //  factor it once, and solve repeatedly.
        //
        double w = k * t_delt / x_delt / x_delt;

        double[] a = new double[3 * x_num];

        a[0 + 0 * 3] = 0.0;

        a[1 + 0 * 3] = 1.0;
        a[0 + 1 * 3] = 0.0;

        for (i = 1; i < x_num - 1; i++)
        {
            a[2 + (i - 1) * 3] = -w;
            a[1 + i * 3]       = 1.0 + 2.0 * w;
            a[0 + (i + 1) * 3] = -w;
        }

        a[2 + (x_num - 2) * 3] = 0.0;
        a[1 + (x_num - 1) * 3] = 1.0;

        a[2 + (x_num - 1) * 3] = 0.0;
        //
        //  Factor the matrix.
        //
        typeMethods.r83_np_fa(x_num, ref a);

        double[] b    = new double[x_num];
        double[] fvec = new double[x_num];

        for (j = 1; j < t_num; j++)
        {
            //
            //  Set the right hand side B.
            //
            b[0] = ua(x_min, x_max, t_min, t[j]);

            f(x_min, x_max, t_min, t[j - 1], x_num, x, ref fvec);

            for (i = 1; i < x_num - 1; i++)
            {
                b[i] = u[i + (j - 1) * x_num] + t_delt * fvec[i];
            }

            b[x_num - 1] = ub(x_min, x_max, t_min, t[j]);

            int job = 0;
            fvec = typeMethods.r83_np_sl(x_num, a, b, job);

            for (i = 0; i < x_num; i++)
            {
                u[i + j * x_num] = fvec[i];
            }
        }

        const string x_file = "x.txt";

        DTable.dtable_write(x_file, 1, x_num, x, false);

        Console.WriteLine("");
        Console.WriteLine("  X data written to \"" + x_file + "\".");

        const string t_file = "t.txt";

        DTable.dtable_write(t_file, 1, t_num, t, false);

        Console.WriteLine("  T data written to \"" + t_file + "\".");

        const string u_file = "u.txt";

        DTable.dtable_write(u_file, x_num, t_num, u, false);

        Console.WriteLine("  U data written to \"" + u_file + "\".");

        Console.WriteLine("");
        Console.WriteLine("FD1D_HEAT_IMPLICIT");
        Console.WriteLine("  Normal end of execution.");
        Console.WriteLine("");
    }