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); }