示例#1
0
    public static double[] diffusivity_2d_elman(double a, double cl, double dc0, int m_1d,
                                                double[] omega, int n1, int n2, double[] x, double[] y)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    DIFFUSIVITY_2D_ELMAN evaluates a 2D stochastic diffusivity function.
    //
    //  Discussion:
    //
    //    The 2D diffusion equation has the form
    //
    //      - Del ( DC(X,Y) Del U(X,Y) ) = F(X,Y)
    //
    //    where DC(X,Y) is a function called the diffusivity.
    //
    //    In the stochastic version of the problem, the diffusivity function
    //    includes the influence of stochastic parameters:
    //
    //      - Del ( DC(X,Y;OMEGA) Del U(X,Y;OMEGA) ) = F(X,Y).
    //
    //    In this function, the domain is assumed to be the square [-A,+A]x[-A,+A].
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    07 August 2013
    //
    //  Author:
    //
    //    John Burkardt
    //
    //  Reference:
    //
    //    Howard Elman, Darran Furnaval,
    //    Solving the stochastic steady-state diffusion problem using multigrid,
    //    IMA Journal on Numerical Analysis,
    //    Volume 27, Number 4, 2007, pages 675-688.
    //
    //    Roger Ghanem, Pol Spanos,
    //    Stochastic Finite Elements: A Spectral Approach,
    //    Revised Edition,
    //    Dover, 2003,
    //    ISBN: 0486428184,
    //    LC: TA347.F5.G56.
    //
    //  Parameters:
    //
    //    Input, double A, the "radius" of the square region.  The region
    //    is assumed to be [-A,+A]x[-A,+A].
    //    0 < A.
    //
    //    Input, double CL, the correlation length.
    //    0 < CL.
    //
    //    Input, double DC0, the constant term in the expansion of the
    //    diffusion coefficient.  Take DC0 = 10.
    //
    //    Input, int M_1D, the first and second dimensions of the
    //    stochastic parameter array.
    //
    //    Input, double OMEGA[M_1D*M_1D], the stochastic parameters.
    //
    //    Input, int N1, N2, the dimensions of the X and Y arrays.
    //
    //    Input, double X[N1*N2], Y[N1*N2], the points where the diffusion
    //    coefficient is to be evaluated.
    //
    //    Output, double DIFFUSIVITY_2D_ELMAN[N1*N2], the value of the diffusion
    //    coefficient at X.
    //
    {
        int i;
        int j;
        int k;

        //
        //  Compute THETA.
        //
        double[] theta_1d = Theta.theta_solve(a, cl, m_1d);
        //
        //  Compute LAMBDA_1D.
        //
        double[] lambda_1d = new double[m_1d];

        for (i = 0; i < m_1d; i++)
        {
            lambda_1d[i] = 2.0 * cl / (1.0 + cl * cl * theta_1d[i] * theta_1d[i]);
        }

        //
        //  Compute C_1DX(1:M1D) and C_1DY(1:M1D) at (X,Y).
        //
        double[] c_1dx = new double[m_1d * n1 * n2];
        double[] c_1dy = new double[m_1d * n1 * n2];

        for (k = 0; k < n2; k++)
        {
            for (j = 0; j < n1; j++)
            {
                for (i = 0; i < m_1d; i++)
                {
                    c_1dx[i + j * m_1d + k * m_1d * n1] = 0.0;
                    c_1dy[i + j * m_1d + k * m_1d * n1] = 0.0;
                }
            }
        }

        i = 0;

        for (;;)
        {
            if (m_1d <= i)
            {
                break;
            }

            for (k = 0; k < n2; k++)
            {
                for (j = 0; j < n1; j++)
                {
                    c_1dx[i + j * m_1d + k * m_1d * n1] = Math.Cos(theta_1d[i] * a * x[j + k * n1])
                                                          / Math.Sqrt(a + Math.Sin(2.0 * theta_1d[i] * a)
                                                                      / (2.0 * theta_1d[i]));

                    c_1dy[i + j * m_1d + k * m_1d * n1] = Math.Cos(theta_1d[i] * a * y[j + k * n1])
                                                          / Math.Sqrt(a + Math.Sin(2.0 * theta_1d[i] * a)
                                                                      / (2.0 * theta_1d[i]));
                }
            }

            i += 1;

            if (m_1d <= i)
            {
                break;
            }

            for (k = 0; k < n2; k++)
            {
                for (j = 0; j < n1; j++)
                {
                    c_1dx[i + j * m_1d + k * m_1d * n1] = Math.Sin(theta_1d[i] * a * x[j + k * n1])
                                                          / Math.Sqrt(a - Math.Sin(2.0 * theta_1d[i] * a)
                                                                      / (2.0 * theta_1d[i]));

                    c_1dy[i + j * m_1d + k * m_1d * n1] = Math.Sin(theta_1d[i] * a * y[j + k * n1])
                                                          / Math.Sqrt(a - Math.Sin(2.0 * theta_1d[i] * a)
                                                                      / (2.0 * theta_1d[i]));
                }
            }

            i += 1;
        }

        //
        //  Evaluate the diffusion coefficient DC at (X,Y).
        //
        double[] dc = new double[n1 * n2];

        for (k = 0; k < n2; k++)
        {
            for (j = 0; j < n1; j++)
            {
                dc[j + k * n1] = dc0;
                int i2;
                for (i2 = 0; i2 < m_1d; i2++)
                {
                    int i1;
                    for (i1 = 0; i1 < m_1d; i1++)
                    {
                        dc[j + k * n1] += Math.Sqrt(lambda_1d[i1] * lambda_1d[i2])
                                          * c_1dx[i1 + j * m_1d + k * m_1d * n1] * c_1dy[i2 + j * m_1d + k * m_1d * n1]
                                          * omega[i1 + i2 * m_1d];
                    }
                }
            }
        }

        return(dc);
    }