Exemple #1
0
from mesh import QuadMesh, Vertex, HalfEdge, QuadCell, Mesh1D, Interval, Tree
from fem import DofHandler, QuadFE, GaussRule, Function
from mesh import convert_to_array
from plot import Plot
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np

mtags = Tree(regular=False)
mesh = Mesh1D(resolution=(1, ))

flag = tuple(mtags.get_node_address())
mesh.cells.record(flag)

mtags.add_child()
new_flag = tuple(mtags.get_child(0).get_node_address())
mesh.cells.refine(subforest_flag=flag, \
                  new_label=new_flag)

for leaf in mesh.cells.get_leaves(subforest_flag=flag):
    leaf.info()

print('==' * 20)

for leaf in mesh.cells.get_leaves(subforest_flag=new_flag):
    leaf.info()

element = QuadFE(1, 'Q2')
dofhandler = DofHandler(mesh, element)
dofhandler.distribute_dofs()
dofhandler.set_dof_vertices()
Exemple #2
0
def experiment01_problem():
    """
    Illustrate the problem:  Plot sample paths of the input q, of the output, 
        and histogram of the QoI.
    """

    #
    # Computational Mesh
    #
    mesh = Mesh1D(resolution=(100, ))
    mesh.mark_region('left', lambda x: np.abs(x) < 1e-10)
    mesh.mark_region('right', lambda x: np.abs(x - 1) < 1e-10)

    #
    # Element
    #
    Q1 = QuadFE(mesh.dim(), 'Q1')
    dQ1 = DofHandler(mesh, Q1)
    dQ1.distribute_dofs()

    #
    # Basis
    #
    phi = Basis(dQ1, 'v')
    phi_x = Basis(dQ1, 'vx')

    #
    # Covariance
    #
    cov = Covariance(dQ1, name='gaussian', parameters={'l': 0.05})
    cov.compute_eig_decomp()
    lmd, V = cov.get_eig_decomp()
    d = len(lmd)

    #
    # Sample and plot full dimensional parameter and solution
    #
    n_samples = 20000
    z = np.random.randn(d, n_samples)
    q = sample_q0(V, lmd, d, z)

    # Define finite element function
    qfn = Nodal(data=q, basis=phi)
    problem = [[Form(qfn, test=phi_x, trial=phi_x),
                Form(1, test=phi)],
               [Form(qfn, test=phi_x, dmu='dv', flag='right')]]

    # Define assembler
    assembler = Assembler(problem)

    # Incorporate Dirichlet conditions
    assembler.add_dirichlet('left', 0)
    assembler.add_dirichlet('right', 1)

    comment.tic('assembly')
    # Assemble system
    assembler.assemble()
    comment.toc()

    comment.tic('solver')
    ufn = Nodal(basis=phi, data=None)
    J = np.zeros(n_samples)
    for i in range(n_samples):
        # Solve system
        u = assembler.solve(i_problem=0, i_matrix=i, i_vector=0)

        # Compute quantity of interest
        J[i] = u.dot(assembler.get_vector(1, i))

        # Update sample paths
        ufn.add_samples(u)
    comment.toc()

    #
    # Plots
    #
    """
    # Formatting
    plt.rc('text', usetex=True)
    
    # Figure sizes
    fs2 = (3,2)
    fs1 = (4,3)
    
    plot = Plot(quickview=False)
    plot_kwargs = {'color':'k', 'linewidth':0.05}
    
    #
    # Plot qfn
    # 
    
    # Figure 
    fig = plt.figure(figsize=fs2)
    ax = fig.add_subplot(111)
    ax = plot.line(qfn, axis=ax, 
                   i_sample=np.arange(100), 
                   plot_kwargs=plot_kwargs)
    ax.set_xlabel(r'$x$')
    ax.set_ylabel(r'$q$')
    plt.tight_layout()
    fig.savefig('fig/ex02_gauss_qfn.eps')
    plt.close()
    
    #
    # Plot ufn
    # 
    fig = plt.figure(figsize=fs2)
    ax = fig.add_subplot(111)
    ax = plot.line(ufn, axis=ax, 
                   i_sample=np.arange(100), 
                   plot_kwargs=plot_kwargs)
    ax.set_xlabel(r'$x$')
    ax.set_ylabel(r'$u$')
    plt.tight_layout()
    fig.savefig('fig/ex02_gauss_ufn.eps')
    plt.close()
    """

    # Formatting
    plt.rc('text', usetex=True)

    # Figure sizes
    fs2 = (3, 2)
    fs1 = (4, 3)

    fig = plt.figure(figsize=fs2)
    ax = fig.add_subplot(111)
    plt.hist(J, bins=100, density=True)
    ax.set_xlabel(r'$J(u)$')
    plt.tight_layout()
    fig.savefig('fig/ex02_gauss_jhist.eps')
Exemple #3
0
    L = assembler.get_vector()

    # Gaussian field


if __name__ == '__main__':
    #%% Test 2: Variance

    test02_variance()

    #%% Simple projection Matrix

    #
    # Define and record coarse mesh
    #
    mesh = Mesh1D(resolution=(16, ))
    mesh.record(0)

    #
    # Refine mesh and record
    #
    """
    # One level of refinement
    mesh.cells.find_node([0]).mark('r')
    mesh.cells.refine(refinement_flag='r')
    
    mesh.cells.find_node([0,0]).mark('r')
    mesh.cells.refine(refinement_flag='r')
    """
    l_max = 4
    for i in range(l_max):
Exemple #4
0
    def test_derivative(self):
        """
        Compute the derivatives of a Nodal Map
        """
        # Define meshes for each dimension
        meshes = {1: Mesh1D(resolution=(2, )), 2: QuadMesh(resolution=(2, 2))}

        # Define elements for each dimension
        elements = {1: QuadFE(1, 'Q2'), 2: QuadFE(2, 'Q2')}

        # Use function to set data
        fns = {1: lambda x: 2 * x[:, 0]**2, 2: lambda x: x[:, 0]**2 + x[:, 1]}

        derivatives = {1: [(1, 0), (2, 0)], 2: [(1, 0), (1, 1), (2, 0, 0)]}

        dfdx_exact = {
            1:
            [lambda x: 4 * x[:, 0][:, None], lambda x: 4 * np.ones(x.shape)],
            2: [
                lambda x: 2 * x[:, 0][:, None], lambda x: np.ones(x.shape),
                lambda x: 2 * np.ones(x.shape)
            ]
        }

        # n_samples = 2
        parms = {1: [{}, {}], 2: [{}, {}]}

        for dim in [1, 2]:
            mesh = meshes[dim]

            # Random points in domain
            n_points = 5
            if dim == 1:
                x_min, x_max = mesh.bounding_box()
                x = x_min + 0.5 * (x_max - x_min) * np.random.rand(n_points)
                x = x[:, np.newaxis]
            elif dim == 2:
                x_min, x_max, y_min, y_max = mesh.bounding_box()
                x = np.zeros((n_points, 2))
                x[:, 0] = x_min + (x_max - x_min) * np.random.rand(n_points)
                x[:, 1] = y_min + (y_max - y_min) * np.random.rand(n_points)

            element = elements[dim]
            fn = fns[dim]
            dofhandler = DofHandler(mesh, element)
            dofhandler.distribute_dofs()
            basis = Basis(dofhandler)
            #
            # Deterministic
            #
            f = Nodal(f=fn,
                      basis=basis,
                      mesh=mesh,
                      element=element,
                      dim=dim,
                      n_variables=1)

            count = 0
            for derivative in derivatives[dim]:
                # Evaluate the derivative
                dfdx = f.differentiate(derivative)
                self.assertTrue(
                    np.allclose(dfdx.eval(x=x), dfdx_exact[dim][count](x)))
                count += 1
            #
            # Sampled
            #
            parm = parms[dim]
            f = Nodal(f=fn,
                      parameters=parm,
                      basis=basis,
                      mesh=mesh,
                      element=element,
                      dim=dim)
            count = 0
            for derivative in derivatives[dim]:
                # Evaluate the derivative
                dfdx = f.differentiate(derivative)

                self.assertTrue(
                    np.allclose(
                        dfdx.eval(x=x)[:, 0], dfdx_exact[dim][count](x)[:, 0]))
                self.assertTrue(
                    np.allclose(
                        dfdx.eval(x=x)[:, 1], dfdx_exact[dim][count](x)[:, 0]))
                count += 1
Exemple #5
0
    def test_eval(self):
        #
        # Out of the box covariance kernels
        #
        fig, ax = plt.subplots(6, 4, figsize=(5, 7))

        cov_names = [
            'constant', 'linear', 'gaussian', 'exponential', 'matern',
            'rational'
        ]

        anisotropies = {1: [None, 2], 2: [None, np.diag([2, 1])]}
        m_count = 0
        for mesh in [Mesh1D(resolution=(10, )), QuadMesh(resolution=(10, 10))]:
            # Dimension
            dim = mesh.dim()

            #
            # Construct computational mesh
            #
            # Piecewise constant elements
            element = QuadFE(dim, 'DQ0')

            # Define dofhandler -> get vertices
            dofhandler = DofHandler(mesh, element)
            dofhandler.distribute_dofs()
            dofhandler.set_dof_vertices()
            v = dofhandler.get_dof_vertices()

            # Define meshgrid for 1 and 2 dimensions
            n_dofs = dofhandler.n_dofs()
            M1, M2 = np.mgrid[0:n_dofs, 0:n_dofs]
            if dim == 1:
                X = v[:, 0][M1].ravel()
                Y = v[:, 0][M2].ravel()
            elif dim == 2:
                X = np.array([v[:, 0][M1].ravel(), v[:, 1][M1].ravel()]).T
                Y = np.array([v[:, 0][M2].ravel(), v[:, 1][M2].ravel()]).T

            x = convert_to_array(X, dim=dim)
            y = convert_to_array(Y, dim=dim)
            a_count = 0
            isotropic_label = ['isotropic', 'anisotropic']
            for M in anisotropies[dim]:
                # Cycle through anisotropies

                # Define covariance parameters
                cov_pars = {
                    'constant': {
                        'sgm': 1
                    },
                    'linear': {
                        'sgm': 1,
                        'M': M
                    },
                    'gaussian': {
                        'sgm': 1,
                        'l': 0.1,
                        'M': M
                    },
                    'exponential': {
                        'l': 0.1,
                        'M': M
                    },
                    'matern': {
                        'sgm': 1,
                        'nu': 2,
                        'l': 0.5,
                        'M': M
                    },
                    'rational': {
                        'a': 3,
                        'M': M
                    }
                }

                c_count = 0
                for cov_name in cov_names:

                    C = CovKernel(cov_name, cov_pars[cov_name])
                    Z = C.eval((x, y)).reshape(M1.shape)

                    col = int(m_count * 2**1 + a_count * 2**0)
                    row = c_count
                    ax[row, col].imshow(Z)
                    if col == 0:
                        ax[row, col].set_ylabel(cov_name)

                    if row == 0:
                        ax[row, col].set_title('%dD mesh\n %s' %
                                               (dim, isotropic_label[a_count]))

                    ax[row, col].set_xticks([], [])
                    ax[row, col].set_yticks([], [])

                    c_count += 1
                a_count += 1
            m_count += 1
        fig.savefig('test_covkernel_eval.eps')
Exemple #6
0
from mesh import QuadMesh, Mesh1D
from plot import Plot
from fem import QuadFE, DofHandler
from function import Explicit
import numpy as np

plot = Plot()
mesh = Mesh1D()
Q0 = QuadFE(1, 'DQ0')
dh0 = DofHandler(mesh, Q0)
n_levels = 10

for l in range(n_levels):
    mesh.cells.refine(new_label=l)
    dh0.distribute_dofs(subforest_flag=l)

f = Explicit(lambda x: np.abs(x - 0.5), dim=1)
fQ = f.interpolant(dh0, subforest_flag=3)

plot.line(fQ, mesh)
plot.mesh(mesh, dofhandler=dh0, subforest_flag=0)

mesh = QuadMesh(resolution=(10, 10))
plot.mesh(mesh)
Exemple #7
0
    def test_set_data(self):
        meshes = {1: Mesh1D(), 2: QuadMesh()}
        elements = {1: QuadFE(1, 'Q2'), 2: QuadFE(2, 'Q2')}

        #
        # Use function to set data
        #
        fns = {
            1: {
                1: lambda x: 2 * x[:, 0]**2,
                2: lambda x, y: 2 * x[:, 0] + 2 * y[:, 0]
            },
            2: {
                1: lambda x: x[:, 0]**2 + x[:, 1],
                2: lambda x, y: x[:, 0] * y[:, 0] + x[:, 1] * y[:, 1]
            }
        }

        parms = {1: {1: [{}, {}], 2: [{}, {}]}, 2: {1: [{}, {}], 2: [{}, {}]}}

        for dim in [1, 2]:
            # Get mesh and element
            mesh = meshes[dim]
            element = elements[dim]

            # Set dofhandler
            dofhandler = DofHandler(mesh, element)
            dofhandler.distribute_dofs()
            n_dofs = dofhandler.n_dofs()

            # Set basis
            basis = Basis(dofhandler)

            # Determine the shapes of the data
            det_shapes = {1: (n_dofs, 1), 2: (n_dofs, n_dofs, 1)}
            smp_shapes = {1: (n_dofs, 2), 2: (n_dofs, n_dofs, 2)}

            # Get a vertex
            i = np.random.randint(n_dofs)
            j = np.random.randint(n_dofs)
            dofhandler.set_dof_vertices()
            x = dofhandler.get_dof_vertices()

            x1 = np.array([x[i, :]])
            x2 = np.array([x[j, :]])

            for n_variables in [1, 2]:
                fn = fns[dim][n_variables]
                parm = parms[dim][n_variables]
                #
                # Deterministic
                #
                f = Nodal(f=fn, basis=basis, n_variables=n_variables)

                # Check shape
                self.assertEqual(f.data().shape, det_shapes[n_variables])

                # Check value
                if n_variables == 1:
                    val = fn(x1)[0]
                    self.assertEqual(val, f.data()[i])
                else:
                    val = fn(x1, x2)
                    self.assertEqual(val[0], f.data()[i, j])

                #
                # Sampled
                #
                f = Nodal(f=fn,
                          parameters=parm,
                          basis=basis,
                          n_variables=n_variables)

                # Check shape
                self.assertEqual(f.data().shape, smp_shapes[n_variables])

                # Check that samples are stored in the right place
                if n_variables == 1:
                    self.assertTrue(np.allclose(f.data()[:, 0],
                                                f.data()[:, 1]))
                elif n_variables == 2:
                    self.assertTrue(
                        np.allclose(f.data()[:, :, 0],
                                    f.data()[:, :, 1]))
Exemple #8
0
def experiment04_sparse_grid():
    """
    Test sparse grid
    """
    #
    # Computational mesh
    #
    mesh = Mesh1D(resolution=(100, ))
    mesh.mark_region('left', lambda x: np.abs(x) < 1e-10)
    mesh.mark_region('right', lambda x: np.abs(x - 1) < 1e-10)

    #
    # Element
    #
    Q1 = QuadFE(mesh.dim(), 'Q1')
    dQ1 = DofHandler(mesh, Q1)
    dQ1.distribute_dofs()

    #
    # Covariance
    #
    cov = Covariance(dQ1, name='gaussian', parameters={'l': 0.05})
    cov.compute_eig_decomp()
    lmd, V = cov.get_eig_decomp()

    # Truncation levels
    truncation_levels = [1, 5, 10, 20]

    # Formatting
    plt.rc('text', usetex=True)

    # Set figure and axis
    fs2 = (3, 2)
    fs1 = (4, 3)

    # For mean
    fig1 = plt.figure(figsize=fs1)
    ax1 = fig1.add_subplot(111)

    # For variance
    fig2 = plt.figure(figsize=fs1)
    ax2 = fig2.add_subplot(111)

    for d0 in truncation_levels:
        J = []
        mean = []
        var = []
        n = []
        for depth in range(5):
            #
            # Construct Sparse Grid
            #
            grid = TasmanianSG.TasmanianSparseGrid()
            dimensions = d0
            outputs = 1
            type = 'level'
            rule = 'gauss-hermite'
            grid.makeGlobalGrid(dimensions, outputs, depth, type, rule)

            # Get Sample Points
            zzSG = grid.getPoints()
            zSG = np.sqrt(2) * zzSG  # transform to N(0,1)

            wSG = grid.getQuadratureWeights()
            wSG /= np.sqrt(np.pi)**d0  # normalize weights

            n0 = grid.getNumPoints()
            n.append(n0)

            #
            # Sample input parameter
            #
            q0 = sample_q0(V, lmd, d0, zSG.T)
            J = sample_qoi(q0, dQ1)

            EJ = np.sum(wSG * J)
            VJ = np.sum(wSG * (J**2)) - EJ**2
            mean.append(EJ)
            var.append(VJ)

        J_mc = np.load('data/j_%d_mc.npy' % (d0))

        # Compute mean and variance
        mean_mc = np.mean(J_mc)
        var_mc = np.var(J_mc)

        # Plot mean error
        mean_err = [np.abs(mean[i] - mean_mc) for i in range(5)]
        ax1.loglog(n, mean_err, '.-.', label=r'$k=%d$' % (d0))
        ax1.set_xlabel(r'$n$')
        ax1.set_ylabel(r'$\mathrm{Error}$')
        ax1.legend()
        fig1.tight_layout()

        # Plot variance error
        var_err = [np.abs(var[i] - var_mc) for i in range(5)]
        ax2.loglog(n, var_err, '.-.', label=r'k=%d' % (d0))
        ax2.set_xlabel(r'$n$')
        ax2.set_ylabel(r'$\mathrm{Error}$')
        ax2.legend()
        fig2.tight_layout()

    fig1.savefig('fig/ex02_gauss_sg_mean_error.eps')
    fig2.savefig('fig/ex02_gauss_sg_var_error.eps')
Exemple #9
0
def experiment05_conditioning():
    """
    Obtain an estimate of J using sparse grids on the coarse scale and MC as a
    correction. 
    
    REMARKS: This takes very long, especially since the convergence rate of the 
    conditional samples is low. 
    """
    #
    # Computational mesh
    #
    mesh = Mesh1D(resolution=(100, ))
    mesh.mark_region('left', lambda x: np.abs(x) < 1e-10)
    mesh.mark_region('right', lambda x: np.abs(x - 1) < 1e-10)

    #
    # Element
    #
    Q1 = QuadFE(mesh.dim(), 'Q1')
    dQ1 = DofHandler(mesh, Q1)
    dQ1.distribute_dofs()

    #
    # Covariance
    #
    cov = Covariance(dQ1, name='gaussian', parameters={'l': 0.05})
    cov.compute_eig_decomp()
    lmd, V = cov.get_eig_decomp()
    d = len(lmd)

    # Fix coarse truncation level
    d0 = 10

    #
    # Build Sparse Grid
    #
    grid = TasmanianSG.TasmanianSparseGrid()
    dimensions = d0
    outputs = 1
    depth = 2
    type = 'level'
    rule = 'gauss-hermite'
    grid.makeGlobalGrid(dimensions, outputs, depth, type, rule)

    # Sample Points
    zzSG = grid.getPoints()
    zSG = np.sqrt(2) * zzSG  # transform to N(0,1)

    # Quadrature Weights
    wSG = grid.getQuadratureWeights()
    wSG /= np.sqrt(np.pi)**d0  # normalize weights

    # Number of grid points
    n0 = grid.getNumPoints()

    #
    # Sample low dimensional input parameter
    #
    q0 = sample_q0(V, lmd, d0, zSG.T)
    J0 = sample_qoi(q0, dQ1)

    # Compute sparse grid mean and variance
    EJ0 = np.sum(wSG * J0)
    VJ0 = np.sum(wSG * (J0**2)) - EJ0**2

    J = np.load('data/j_mc.npy')
    mean_ref = np.mean(J)
    var_ref = np.var(J)

    # Record errors
    mean_err = [np.abs(EJ0 - mean_ref)]
    var_err = [np.abs(VJ0 - var_ref)]

    for n_samples in [10, 100, 1000]:
        mean_Jg0 = 0
        var_Jg0 = 0
        for i in range(n0):
            z = np.random.randn(d - d0, n_samples)
            qg0 = sample_q_given_q0(q0[:, i], V, lmd, d0, z)
            Jg0 = sample_qoi(qg0, dQ1)

            mean_Jg0 += wSG[i] * np.mean(Jg0)

        mean_err.append(np.abs(mean_Jg0 - mean_ref))

    # Formatting
    plt.rc('text', usetex=True)

    # Figure sizes
    fs2 = (3, 2)
    fs1 = (4, 3)

    fig = plt.figure(figsize=fs2)
    ax = fig.add_subplot(111)
    ax.semilogy([0, 10, 100, 1000], mean_err, '.-')
    ax.set_xlabel(r'$n$')
    ax.set_ylabel(r'$\mathrm{Error}$')

    fig.tight_layout()
    fig.savefig('fig/ex02_gauss_hyb_mean_err.eps')
    """
    #
    # Plot conditional variances
    #
    fig = plt.figure(figsize=fs2)
    ax = fig.add_subplot(111)
    ax.hist(varJg,bins=30, density=True)
    ax.set_xlabel(r'$\sigma_{J|q_0}^2$')
    fig.tight_layout()
    fig.savefig('fig/ex02_gauss_cond_var.eps')
    """
    """     
Exemple #10
0
def experiment02_reference():
    """
    Convergence rate of MC
    """
    generate = False
    #
    # Computational Mesh
    #
    mesh = Mesh1D(resolution=(100, ))
    mesh.mark_region('left', lambda x: np.abs(x) < 1e-10)
    mesh.mark_region('right', lambda x: np.abs(x - 1) < 1e-10)

    #
    # Element
    #
    Q1 = QuadFE(mesh.dim(), 'Q1')
    dQ1 = DofHandler(mesh, Q1)
    dQ1.distribute_dofs()

    #
    # Covariance
    #
    cov = Covariance(dQ1, name='gaussian', parameters={'l': 0.05})
    cov.compute_eig_decomp()
    lmd, V = cov.get_eig_decomp()
    d = len(lmd)

    #
    # Generate random sample for J
    #

    n_samples = 1000000

    if generate:
        n_batches = 1000
        batch_size = n_samples // n_batches
        J = np.empty(n_samples)
        for i in range(n_batches):

            # Sample diffusion coefficient
            z = np.random.randn(d, n_samples // n_batches)
            q = sample_q0(V, lmd, d, z)

            # Evaluate quantity of interest
            J[(i) * batch_size:(i + 1) * batch_size] = sample_qoi(q, dQ1)

            # Save current update to file
            np.save('./data/j_mc.npy', J)

    #
    # Process data
    #

    # Load MC samples
    J = np.load('data/j_mc.npy')

    # Compute sample mean and variance of J
    EX = np.mean(J)
    VarX = np.var(J)

    print(EX, VarX)
Exemple #11
0
def experiment03_truncation():
    """
    Investigate the error in truncation level
    """
    generate = False

    mesh = Mesh1D(resolution=(100, ))
    mesh.mark_region('left', lambda x: np.abs(x) < 1e-10)
    mesh.mark_region('right', lambda x: np.abs(x - 1) < 1e-10)

    #
    # Element
    #
    Q1 = QuadFE(mesh.dim(), 'Q1')
    dQ1 = DofHandler(mesh, Q1)
    dQ1.distribute_dofs()

    #
    # Basis
    #
    phi = Basis(dQ1, 'v')
    phi_x = Basis(dQ1, 'vx')

    #
    # Covariance
    #
    cov = Covariance(dQ1, name='gaussian', parameters={'l': 0.05})
    cov.compute_eig_decomp()
    lmd, V = cov.get_eig_decomp()
    d = len(lmd)

    # Truncation levels
    truncation_levels = [1, 5, 10, 20, 50]

    n_samples = 1000000
    if generate:
        n_batches = 1000
        batch_size = n_samples // n_batches

        for d0 in truncation_levels:
            comment.tic('d = %d' % (d0))
            J = np.empty(n_samples)
            for i in range(n_batches):
                # Print progress
                #print('.',end='')

                # Sample diffusion coefficient
                z = np.random.randn(d0, batch_size)
                q = sample_q0(V, lmd, d0, z)

                # Evaluate quantity of interest
                J[(i) * batch_size:(i + 1) * batch_size] = sample_qoi(q, dQ1)

                # Save current update to file
                np.save('./data/j_%d_mc.npy' % (d0), J)
            comment.toc()

    #
    # Compute estimates and errors
    #
    n_levels = len(truncation_levels)
    mean = []
    var = []
    for d0 in truncation_levels:
        J = np.load('data/j_%d_mc.npy' % (d0))

        # Compute mean and variance
        mean.append(np.mean(J))
        var.append(np.var(J))

    # Load reference
    J = np.load('data/j_mc.npy')
    mean_ref = np.mean(J)
    var_ref = np.var(J)

    #truncation_levels.append(101)
    err_mean = [np.abs(mean[i] - mean_ref) for i in range(n_levels)]
    err_var = [np.abs(var[i] - var_ref) for i in range(n_levels)]

    #
    # Plots
    #
    # Formatting
    plt.rc('text', usetex=True)

    # Figure sizes
    fs2 = (3, 2)
    fs1 = (4, 3)

    #
    # Plot truncation error for mean and variance of J
    #

    fig = plt.figure(figsize=fs2)
    ax = fig.add_subplot(111)

    plt.semilogy(truncation_levels, err_mean, '.-', label='mean')
    plt.semilogy(truncation_levels, err_var, '.--', label='variance')
    plt.legend()

    ax.set_xlabel(r'$k$')
    ax.set_ylabel(r'$\mathrm{Error}$')
    plt.tight_layout()
    fig.savefig('fig/ex02_gauss_trunc_error.eps')

    #
    # Plot estimated mean and variance
    #

    fig = plt.figure(figsize=fs2)
    ax = fig.add_subplot(111)

    truncation_levels.append(101)
    mean.append(mean_ref)
    var.append(var_ref)
    plt.plot(truncation_levels, mean, 'k.-', label='mean')
    plt.plot(truncation_levels, var, 'k.--', label='variance')
    plt.legend()

    ax.set_xlabel(r'$k$')
    plt.tight_layout()
    fig.savefig('fig/ex02_gauss_trunc_stats.eps')
Exemple #12
0
    # -------------------------------------------------------------------------
    g = M.dot(p + gamma * u_data)[dofs_inj]

    print(np.linalg.norm(g))

    return f, g.ravel()


# =============================================================================
# Mesh
# =============================================================================
# Computational domain
x_min = 0
x_max = 2

mesh = Mesh1D(box=[x_min, x_max], resolution=(512, ))

# Mark Dirichlet Vertices
mesh.mark_region('left', lambda x: np.abs(x) < 1e-9)
mesh.mark_region('right', lambda x: np.abs(x - 2) < 1e-9)

#
# Finite element spaces
#
Q1 = QuadFE(mesh.dim(), 'Q1')

# Dofhandler for state
dh_y = DofHandler(mesh, Q1)
dh_y.distribute_dofs()
ny = dh_y.n_dofs()
Exemple #13
0
    def test_integrals_1d(self):
        """
        Test system assembly
        """
        #
        # Constant form
        #

        # Mesh
        mesh = Mesh1D(box=[1, 2], resolution=(1, ))

        # Kernel
        kernel = Kernel(Explicit(f=lambda x: x[:, 0], dim=1))

        problem = Form(kernel)
        assembler = Assembler(problem, mesh=mesh)
        assembler.assemble()
        self.assertAlmostEqual(assembler.get_scalar(), 3 / 2)

        #
        # Linear forms (x,x) and (x,x') over [1,2] = 7/3, 3/2
        #

        # Elements
        Q1 = QuadFE(mesh.dim(), 'Q1')
        Q2 = QuadFE(mesh.dim(), 'Q2')
        Q3 = QuadFE(mesh.dim(), 'Q3')

        # Dofhandlers
        dQ1 = DofHandler(mesh, Q1)
        dQ2 = DofHandler(mesh, Q2)
        dQ3 = DofHandler(mesh, Q3)

        # Distribute dofs
        [d.distribute_dofs() for d in [dQ1, dQ2, dQ3]]

        for dQ in [dQ1, dQ2, dQ3]:
            # Basis
            phi = Basis(dQ, 'u')
            phi_x = Basis(dQ, 'ux')

            # Kernel function
            xfn = Nodal(f=lambda x: x[:, 0], basis=phi)

            # Kernel
            kernel = Kernel(xfn)

            # Form
            problem = [[Form(kernel, test=phi)], [Form(kernel, test=phi_x)]]

            # Assembly
            assembler = Assembler(problem, mesh)
            assembler.assemble()

            # Check b^Tx = (x,x)
            b0 = assembler.get_vector(0)
            self.assertAlmostEqual(np.sum(b0 * xfn.data()[:, 0]), 7 / 3)

            b1 = assembler.get_vector(1)
            self.assertAlmostEqual(np.sum(b1 * xfn.data()[:, 0]), 3 / 2)

        #
        # Bilinear forms
        #
        # Compute (1,x,x) = 7/3, or (x^2, 1, 1) = 7/3

        for dQ in [dQ1, dQ2, dQ3]:
            # Basis
            phi = Basis(dQ, 'u')
            phi_x = Basis(dQ, 'ux')

            # Kernel function
            x2fn = Explicit(f=lambda x: x[:, 0]**2, dim=1)
            xfn = Nodal(f=lambda x: x[:, 0], basis=phi)

            # Form
            problems = [[Form(1, test=phi, trial=phi)],
                        [Form(Kernel(xfn), test=phi, trial=phi_x)],
                        [Form(Kernel(x2fn), test=phi_x, trial=phi_x)]]

            # Assemble
            assembler = Assembler(problems, mesh)
            assembler.assemble()

            x = xfn.data()[:, 0]
            for i_problem in range(3):
                A = assembler.get_matrix(i_problem)
                self.assertAlmostEqual(x.T.dot(A.dot(x)), 7 / 3)

        # ======================================================================
        # Test 1: Assemble simple bilinear form (u,v) on Mesh1D
        # ======================================================================
        # Mesh
        mesh = Mesh1D(resolution=(1, ))
        Q1 = QuadFE(mesh.dim(), 'Q1')
        Q2 = QuadFE(mesh.dim(), 'Q2')
        Q3 = QuadFE(mesh.dim(), 'Q3')

        # Test and trial functions
        dhQ1 = DofHandler(mesh, QuadFE(1, 'Q1'))
        dhQ1.distribute_dofs()

        u = Basis(dhQ1, 'u')
        v = Basis(dhQ1, 'v')

        # Form
        form = Form(trial=u, test=v)

        # Define system
        system = Assembler(form, mesh)

        # Get local information
        cell = mesh.cells.get_child(0)
        si = system.shape_info(cell)

        # Compute local Gauss nodes
        xg, wg, phi, dofs = system.shape_eval(cell)
        self.assertTrue(cell in xg)
        self.assertTrue(cell in wg)

        # Compute local shape functions
        self.assertTrue(cell in phi)
        self.assertTrue(u in phi[cell])
        self.assertTrue(v in phi[cell])
        self.assertTrue(u in dofs[cell])

        # Assemble system
        system.assemble()

        # Extract system bilinear form
        A = system.get_matrix()

        # Use bilinear form to integrate x^2 over [0,1]
        f = Nodal(lambda x: x, basis=u)
        fv = f.data()[:, 0]
        self.assertAlmostEqual(np.sum(fv * A.dot(fv)), 1 / 3)

        # ======================================================================
        # Test 3: Constant form (x^2,.,.) over 1D mesh
        # ======================================================================

        # Mesh
        mesh = Mesh1D(resolution=(10, ))

        # Nodal kernel function
        Q2 = QuadFE(1, 'Q2')
        dhQ2 = DofHandler(mesh, Q2)
        dhQ2.distribute_dofs()
        phiQ2 = Basis(dhQ2)

        f = Nodal(lambda x: x**2, basis=phiQ2)
        kernel = Kernel(f=f)

        # Form
        form = Form(kernel=kernel)

        # Generate and assemble the system
        system = Assembler(form, mesh)
        system.assemble()

        # Check
        self.assertAlmostEqual(system.get_scalar(), 1 / 3)

        # =====================================================================
        # Test 4: Periodic Mesh
        # =====================================================================
        #
        # TODO: NO checks yet
        #

        mesh = Mesh1D(resolution=(2, ), periodic=True)

        #
        Q1 = QuadFE(1, 'Q1')
        dhQ1 = DofHandler(mesh, Q1)
        dhQ1.distribute_dofs()
        u = Basis(dhQ1, 'u')

        form = Form(trial=u, test=u)

        system = Assembler(form, mesh)
        system.assemble()

        # =====================================================================
        # Test 5: Assemble simple sampled form
        # ======================================================================
        mesh = Mesh1D(resolution=(3, ))

        Q1 = QuadFE(1, 'Q1')
        dofhandler = DofHandler(mesh, Q1)
        dofhandler.distribute_dofs()
        phi = Basis(dofhandler)

        xv = dofhandler.get_dof_vertices()
        n_points = dofhandler.n_dofs()

        n_samples = 6
        a = np.arange(n_samples)

        f = lambda x, a: a * x

        fdata = np.zeros((n_points, n_samples))
        for i in range(n_samples):
            fdata[:, i] = f(xv, a[i]).ravel()

        # Define sampled function
        fn = Nodal(data=fdata, basis=phi)
        kernel = Kernel(fn)
        #
        # Integrate I[0,1] ax^2 dx by using the linear form (ax,x)
        #
        v = Basis(dofhandler, 'v')
        form = Form(kernel=kernel, test=v)
        system = Assembler(form, mesh)
        system.assemble()

        one = np.ones(n_points)
        for i in range(n_samples):
            b = system.get_vector(i_sample=i)
            self.assertAlmostEqual(one.dot(b), 0.5 * a[i])

        #
        # Integrate I[0,1] ax^4 dx using bilinear form (ax, x^2, x)
        #
        Q2 = QuadFE(1, 'Q2')
        dhQ2 = DofHandler(mesh, Q2)
        dhQ2.distribute_dofs()
        u = Basis(dhQ2, 'u')

        # Define form
        form = Form(kernel=kernel, test=v, trial=u)

        # Define and assemble system
        system = Assembler(form, mesh)
        system.assemble()

        # Express x^2 in terms of trial function basis
        dhQ2.distribute_dofs()
        xvQ2 = dhQ2.get_dof_vertices()
        xv_squared = xvQ2**2

        for i in range(n_samples):
            #
            # Iterate over samples
            #

            # Form sparse matrix
            A = system.get_matrix(i_sample=i)

            # Evaluate the integral
            I = np.sum(xv * A.dot(xv_squared))

            # Compare with expected result
            self.assertAlmostEqual(I, 0.2 * a[i])

        # =====================================================================
        # Test 6: Working with submeshes
        # =====================================================================
        mesh = Mesh1D(resolution=(2, ))
Exemple #14
0
    def test_shape_info(self):
        """
        Test whether system extracts the correct information
        """
        #
        # 1D
        #
        mesh = Mesh1D(resolution=(1, ))
        Q1 = QuadFE(1, 'Q1')
        dhQ1 = DofHandler(mesh, Q1)
        dhQ1.distribute_dofs()

        ux = Basis(dhQ1, 'ux')
        v = Basis(dhQ1, 'v')
        system = Assembler(Form(trial=ux, test=v), mesh)

        cell = mesh.cells.get_child(0)

        si = system.shape_info(cell)
        self.assertTrue(cell in si)
        self.assertTrue(ux in si[cell])
        self.assertTrue(v in si[cell])

        #
        # 2D
        #
        mesh = QuadMesh(resolution=(1, 1))
        Q1 = QuadFE(2, 'Q1')
        Q2 = QuadFE(2, 'Q2')

        dhQ1 = DofHandler(mesh, Q1)
        dhQ1.distribute_dofs()

        dhQ2 = DofHandler(mesh, Q2)
        dhQ2.distribute_dofs()

        phiQ1 = Basis(dhQ1)
        phiQ2 = Basis(dhQ2)

        # Kernel
        f = Nodal(lambda x: x[:, 0] * x[:, 1], basis=phiQ2)
        g = Nodal(lambda x: x[:, 0] + x[:, 1], basis=phiQ1)
        F = lambda f, g: f - g
        kernel = Kernel([f, g], derivatives=['fx', 'g'], F=F)

        # Form defined over HalfEdge with flag 1
        u = Basis(dhQ1, 'u')
        vx = Basis(dhQ2, 'vx')
        v = Basis(dhQ2, 'v')

        form_1 = Form(kernel, trial=u, test=vx, dmu='ds', flag=1)
        form_2 = Form(trial=u, test=v, dmu='dx', flag=2)

        problem = [form_1, form_2]

        # Assembler
        system = Assembler(problem, mesh)

        # Shape info on cell
        cell = mesh.cells.get_child(0)
        si = system.shape_info(cell)

        # Empty info dictionary (Cell hasn't been marked)
        self.assertEqual(si, {})

        # Mark HalfEdge and cell and do it again
        he = cell.get_half_edge(0)
        he.mark(1)
        cell.mark(2)
        si = system.shape_info(cell)

        # Check that shape info contains the right stuff
        for region in [he, cell]:
            self.assertTrue(region in si)

        for basis in [u, vx]:
            self.assertTrue(basis in si[he])

        for basis in [u, v]:
            self.assertTrue(basis in si[cell])
Exemple #15
0
            return np.sign(a)
    elif name == 'critical_approximation':
        if a <= -1:
            return -1 - 1 / a
        elif np.abs(a) <= 1:
            return 0
        elif a >= 1:
            return 1 - 1 / a


# Parameters
eps = 1e-3
a = 1

# Computational mesh
mesh = Mesh1D(resolution=(200, ))
mesh.mark_region('left', lambda x: np.abs(x) < 1e-9, entity_type='vertex')
mesh.mark_region('right', lambda x: np.abs(x - 1) < 1e-9, entity_type='vertex')

# Element
element = QuadFE(1, 'Q1')
dofhandler = DofHandler(mesh, element)
dofhandler.distribute_dofs()

# Kernels
k_eps = SUPGKernel(Constant(-eps), Constant(a), eps)
k_a = SUPGKernel(Constant(a), Constant(a), eps)

# Forms
u = Basis(dofhandler, 'u')
ux = Basis(dofhandler, 'ux')
Exemple #16
0
def experiment06_sensitivity_stats():
    """
    Compute the sensitivities
    """
    comment = Verbose()
    comment.comment('Computing statistics for the sensitivity dJ_dq')

    #
    # Computational mesh
    #
    mesh = Mesh1D(resolution=(100, ))
    mesh.mark_region('left', lambda x: np.abs(x) < 1e-10)
    mesh.mark_region('right', lambda x: np.abs(x - 1) < 1e-10)

    #
    # Element
    #
    Q1 = QuadFE(mesh.dim(), 'Q1')
    dQ1 = DofHandler(mesh, Q1)
    dQ1.distribute_dofs()
    n_dofs = dQ1.n_dofs()
    phi = Basis(dQ1, 'u')

    #
    # Covariance
    #
    cov = Covariance(dQ1, name='gaussian', parameters={'l': 0.05})
    cov.compute_eig_decomp()
    lmd, V = cov.get_eig_decomp()
    d = len(lmd)

    # Fix coarse truncation level
    d0 = 10

    #
    # Build Sparse Grid
    #
    grid = TasmanianSG.TasmanianSparseGrid()
    dimensions = d0
    outputs = 1
    depth = 4
    type = 'level'
    rule = 'gauss-hermite'
    grid.makeGlobalGrid(dimensions, outputs, depth, type, rule)

    # Sample Points
    zzSG = grid.getPoints()
    zSG = np.sqrt(2) * zzSG  # transform to N(0,1)

    # Quadrature Weights
    wSG = grid.getQuadratureWeights()
    wSG /= np.sqrt(np.pi)**d0  # normalize weights

    # Number of grid points
    n0 = grid.getNumPoints()

    comment.comment('Element DOFs: {0}'.format(n_dofs))
    comment.comment('Sparse Grid Size: {0}'.format(n0))

    #
    # Sample low dimensional input parameter
    #
    comment.tic('Sampling reference')
    q0 = sample_q0(V, lmd, d0, zSG.T)
    J0, u0 = sample_qoi(q0, dQ1, return_state=True)
    comment.toc()

    comment.tic('Sampling gradient')
    dJdq = np.zeros((n_dofs, n0))
    for i in range(n0):
        # Sample input and state
        q = Nodal(data=q0[:, i], basis=phi)
        u = Nodal(data=u0[:, i], basis=phi)

        # Compute gradient using adjoint approach
        dJdq[:, i] = dJdq_adj(q, u)
    comment.toc()

    # Compute sparse grid mean and variance
    E_dJ = np.dot(dJdq, wSG)
    V_dJ = np.dot(dJdq**2, wSG) - E_dJ**2

    E_dJ = Nodal(data=E_dJ, basis=phi)
    V_dJ = Nodal(data=V_dJ, basis=phi)

    fig, ax = plt.subplots(nrows=1, ncols=2)

    plot = Plot(quickview=False)
    ax[0] = plot.line(E_dJ, axis=ax[0])
    ax[1] = plot.line(V_dJ, axis=ax[1])
    plt.show()
Exemple #17
0
    def test_constructor(self):
        # =====================================================================
        # Test 1D 
        # ===================================================================== 
        
        #
        # Kernel consists of a single explicit Function: 
        # 
        f1 = lambda x: x+2
        f = Explicit(f1, dim=1)
        k = Kernel(f)
        x = np.linspace(0,1,100)
        n_points = len(x)
        
        # Check that it evaluates correctly.
        self.assertTrue(np.allclose(f1(x), k.eval(x).ravel()))
        
        # Check shape of kernel
        self.assertEqual(k.eval(x).shape, (n_points,1))
        
        #
        # Kernel consists of a combination of two explicit functions
        # 
        f1 = Explicit(lambda x: x+2, dim=1)
        f2 = Explicit(lambda x: x**2 + 1, dim=1)
        F = lambda f1, f2: f1**2 + f2
        f_t = lambda x: (x+2)**2 + x**2 + 1
        k = Kernel([f1,f2], F=F)
        
        # Check evaluation
        self.assertTrue(np.allclose(f_t(x), k.eval(x).ravel()))
        
        # Check shape 
        self.assertEqual(k.eval(x).shape, (n_points,1))
        

        #
        # Same thing as above, but with nodal functions
        # 
        mesh = Mesh1D(resolution=(1,))
        Q1 = QuadFE(1,'Q1')
        Q2 = QuadFE(1,'Q2')
        
        dQ1 = DofHandler(mesh,Q1)
        dQ2 = DofHandler(mesh,Q2)
        
        # Distribute dofs
        [dQ.distribute_dofs() for dQ in [dQ1,dQ2]]
        
        # Basis functions
        phi1 = Basis(dQ1,'u')
        phi2 = Basis(dQ2,'u')
        
        f1 = Nodal(lambda x: x+2, basis=phi1)
        f2 = Nodal(lambda x: x**2 + 1, basis=phi2)
        k = Kernel([f1,f2], F=F)
        
        # Check evaluation
        self.assertTrue(np.allclose(f_t(x), k.eval(x).ravel()))
        
        #
        # Replace f2 above with its derivative
        # 
        k = Kernel([f1,f2], derivatives=['f', 'fx'], F=F)
        f_t = lambda x: (x+2)**2 + 2*x
                
        # Check derivative evaluation F = F(f1, df2_dx)
        self.assertTrue(np.allclose(f_t(x), k.eval(x).ravel()))
        
        
        # 
        # Sampling 
        #
        one = Constant(1)
        f1 = Explicit(lambda x: x**2 + 1, dim=1)
        
        # Sampled function
        a = np.linspace(0,1,11)
        n_samples = len(a)
        
        # Define Dofhandler
        dh = DofHandler(mesh, Q2)
        dh.distribute_dofs()
        dh.set_dof_vertices()
        xv = dh.get_dof_vertices()
        n_dofs = dh.n_dofs()
        
        phi = Basis(dh, 'u')
        
        # Evaluate parameterized function at mesh dof vertices
        f2_m  = np.empty((n_dofs, n_samples))
        for i in range(n_samples):
            f2_m[:,i] = xv.ravel() + a[i]*xv.ravel()**2
        f2 = Nodal(data=f2_m, basis=phi)
        
        # Define kernel
        F = lambda f1, f2, one: f1 + f2 + one
        k = Kernel([f1,f2,one], F=F)
        
        # Evaluate on a fine mesh
        x = np.linspace(0,1,100)
        n_points = len(x)
        self.assertEqual(k.eval(x).shape, (n_points, n_samples))    
        for i in range(n_samples):
            # Check evaluation            
            self.assertTrue(np.allclose(k.eval(x)[:,i], f1.eval(x)[:,i] + x + a[i]*x**2+ 1))
            
        
        #
        # Sample multiple constant functions
        # 
        f1 = Constant(data=a)
        f2 = Explicit(lambda x: 1 + x**2, dim=1)
        f3 = Nodal(data=f2_m[:,-1], basis=phi)
        
        F = lambda f1, f2, f3: f1 + f2 + f3
        k = Kernel([f1,f2,f3], F=F)
        
        x = np.linspace(0,1,100)
        for i in range(n_samples):
            self.assertTrue(np.allclose(k.eval(x)[:,i], \
                                        a[i] + f2.eval(x)[:,i] + f3.eval(x)[:,i]))
        
        #
        # Submeshes
        # 
        mesh = Mesh1D(resolution=(1,))
        mesh_labels = Tree(regular=False)
        
        mesh = Mesh1D(resolution=(1,))
        Q1 = QuadFE(1,'Q1')
        Q2 = QuadFE(1,'Q2')
        
        dQ1 = DofHandler(mesh,Q1)
        dQ2 = DofHandler(mesh,Q2)
        
        # Distribute dofs
        [dQ.distribute_dofs() for dQ in [dQ1,dQ2]]
        
        # Basis
        p1 = Basis(dQ1)
        p2 = Basis(dQ2) 
        
        
        f1 = Nodal(lambda x: x, basis=p1)
        f2 = Nodal(lambda x: -2+2*x**2, basis=p2)
        one = Constant(np.array([1,2]))
    
        F = lambda f1, f2, one: 2*f1**2 + f2 + one
        
        I = mesh.cells.get_child(0)
        
        kernel = Kernel([f1,f2, one], F=F)
        
        rule1D = GaussRule(5,shape='interval')
        x = I.reference_map(rule1D.nodes())
Exemple #18
0
def test06_linearization():
    """
    Compute samples on fine grid via the linearization
    """
    plot = Plot()
    #
    # Computational mesh
    #
    mesh = Mesh1D(resolution=(100, ))
    mesh.mark_region('left', lambda x: np.abs(x) < 1e-10)
    mesh.mark_region('right', lambda x: np.abs(x - 1) < 1e-10)

    #
    # Element
    #
    Q1 = QuadFE(mesh.dim(), 'Q1')
    dQ1 = DofHandler(mesh, Q1)
    dQ1.distribute_dofs()
    nx = dQ1.n_dofs()
    x = dQ1.get_dof_vertices()

    Q3 = QuadFE(mesh.dim(), 'Q3')
    dQ3 = DofHandler(mesh, Q3)
    dQ3.distribute_dofs()

    #
    # Basis
    #
    phi = Basis(dQ1, 'u')
    phi_x = Basis(dQ1, 'ux')
    psi = Basis(dQ3, 'u')
    psi_x = Basis(dQ3, 'ux')

    #
    # Covariance
    #
    cov = Covariance(dQ1, name='gaussian', parameters={'l': 0.05})
    cov.compute_eig_decomp()
    lmd, V = cov.get_eig_decomp()
    d = len(lmd)

    # Fix coarse truncation level
    d0 = 10

    #
    # Build Sparse Grid
    #
    grid = TasmanianSG.TasmanianSparseGrid()
    dimensions = d0
    outputs = 1
    depth = 2
    type = 'level'
    rule = 'gauss-hermite'
    grid.makeGlobalGrid(dimensions, outputs, depth, type, rule)

    # Sample Points
    zzSG = grid.getPoints()
    zSG = np.sqrt(2) * zzSG  # transform to N(0,1)

    # Quadrature Weights
    wSG = grid.getQuadratureWeights()
    wSG /= np.sqrt(np.pi)**d0  # normalize weights

    # Number of grid points
    n0 = grid.getNumPoints()

    #
    # Sample low dimensional input parameter
    #
    q0 = sample_q0(V, lmd, d0, zSG.T)
    J0 = sample_qoi(q0, dQ1)

    #
    # Sample conditional expectation
    #

    # Pick a single coarse sample to check
    i0 = np.random.randint(0, high=n0)

    # Sample fine, conditional on coarse
    n_samples = 1
    z1 = np.random.randn(d - d0, n_samples)
    q = sample_q_given_q0(q0[:, i0], V, lmd, d0, z1)

    # Perturbation
    log_qref = np.log(q0[:, i0])
    dlog_q = np.log(q.ravel()) - log_qref
    dlog_qfn = Nodal(data=dlog_q, basis=phi)

    # Perturbed q
    n_eps = 12  # Number of refinements
    epsilons = [10**(-l) for l in range(n_eps)]
    log_qper = np.empty((nx, n_eps))
    for i in range(n_eps):
        log_qper[:, i] = log_qref + epsilons[i] * dlog_q
    """
    plt.plot(x, log_qref, label='ref')
    for i in range(n_eps):
        plt.plot(x, log_qper[:,i],label='%d'%(i))
    """

    assert np.allclose(log_qper[:, 0], np.log(q.ravel()))

    plt.legend()
    plt.show()

    # Define finite element function
    exp_qref = Nodal(data=q0[:, i0], basis=phi)
    exp_qper = Nodal(data=np.exp(log_qper), basis=phi)

    #
    # PDEs
    #

    # 1. State Equation
    state_eqn = [Form(exp_qref, test=phi_x, trial=phi_x), Form(1, test=phi)]
    state_dbc = {'left': 0, 'right': 1}

    # 2. Perturbed Equation
    perturbed_eqn = [
        Form(exp_qper, test=phi_x, trial=phi_x),
        Form(1, test=phi)
    ]
    perturbed_dbc = {'left': 0, 'right': 1}

    # 3. Adjoint Equation
    adjoint_eqn = [Form(exp_qref, test=psi_x, trial=psi_x), Form(0, test=psi)]
    adjoint_dbc = {'left': 0, 'right': -1}

    # Combine
    eqns = [state_eqn, perturbed_eqn, adjoint_eqn]
    bcs = [state_dbc, perturbed_dbc, adjoint_dbc]

    #
    # Assembly
    #
    assembler = Assembler(eqns, n_gauss=(6, 36))

    # Boundary conditions
    for i, bc in zip(range(3), bcs):
        for loc, val in bc.items():
            assembler.add_dirichlet(loc, val, i_problem=i)

    # Assemble
    assembler.assemble()

    #
    # Solve
    #

    # Solve state
    ur = assembler.solve(i_problem=0)
    u_ref = Nodal(data=ur, basis=phi)
    ux_ref = Nodal(data=ur, basis=phi_x)

    # Solve perturbed state
    u_per = Nodal(basis=phi)
    for i in range(n_eps):
        # FEM solution
        up = assembler.solve(i_problem=1, i_matrix=i)
        u_per.add_samples(up)

        plt.plot(x, up - ur)
    plt.show()
    ux_per = Nodal(data=u_per.data(), basis=phi_x)

    # Solve adjoint equation
    v = assembler.solve(i_problem=2)
    v_adj = Nodal(data=v, basis=psi)
    vx_adj = Nodal(data=v, basis=psi_x)

    #
    # Sensitivity
    #

    # Sensitivity Equation
    ker_sen = Kernel(f=[exp_qref, dlog_qfn, ux_ref],
                     F=lambda eq, dq, ux: -eq * dq * ux)
    sensitivity_eqn = [
        Form(exp_qref, test=phi_x, trial=phi_x),
        Form(ker_sen, test=phi_x)
    ]

    sensitivity_dbc = {'left': 0, 'right': 0}
    assembler = Assembler(sensitivity_eqn, n_gauss=(6, 36))
    for loc in sensitivity_dbc:
        assembler.add_dirichlet(loc, sensitivity_dbc[loc])
    assembler.assemble()
    s = assembler.solve()
    sx = Nodal(data=s, basis=phi_x)

    plt.plot(x, s)
    plt.show()

    #
    # Quantities of Interest
    #

    # Reference
    k_ref = Kernel(f=[exp_qref, ux_ref], F=lambda eq, ux: eq * ux)
    ref_qoi = [Form(k_ref, dmu='dv', flag='right')]

    # Perturbed
    k_per = Kernel(f=[exp_qper, ux_per], F=lambda eq, ux: eq * ux)
    per_qoi = [Form(k_per, dmu='dv', flag='right')]

    # Adjoint
    k_adj = Kernel(f=[exp_qref, dlog_qfn, ux_ref, vx_adj],
                   F=lambda eq, dq, ux, vx: -eq * dq * ux * vx)
    adj_qoi = [Form(k_adj)]

    # Sensitivity
    k_sens = Kernel(f=[exp_qref, dlog_qfn, ux_ref, sx],
                    F=lambda eq, dq, ux, sx: eq * dq * ux + eq * sx)
    sens_qoi = Form(k_sens, dmu='dv', flag='right')

    qois = [ref_qoi, per_qoi, adj_qoi, sens_qoi]

    # Assemble
    assembler = Assembler(qois, mesh=mesh)
    assembler.assemble()

    # Evaluate
    J_ref = assembler.get_scalar(0)
    J_per = []
    for i in range(n_eps):
        J_per.append(assembler.get_scalar(1, i))

    # Finite difference approximation
    dJ = []
    for eps, J_p in zip(epsilons, J_per):
        dJ.append((J_p - J_ref) / eps)

    # Adjoint differential
    dJ_adj = assembler.get_scalar(2)

    # Sensitivity differential
    dJ_sen = assembler.get_scalar(3)

    print(dJ_adj)
    print(dJ_sen)
    print(dJ)
    """
Exemple #19
0
pp = A[1,:] - Q.dot(Q.T.dot(A[1,:]))

print(pp)
print('R\n',R)

print(A.dot(V))
Q,R = linalg.qr(A, mode='economic')
r = np.diag(R)
print(len(r[np.abs(r)>1e-13]))
print(Q,'\n',R)

'''
print("TasmanianSG version: {0:s}".format(TasmanianSG.__version__))
print("TasmanianSG license: {0:s}".format(TasmanianSG.__license__))

mesh = Mesh1D(resolution=(2, ))
element = QuadFE(mesh.dim(), 'Q1')
dofhandler = DofHandler(mesh, element)

phi_x = Basis(dofhandler, 'ux')

problems = [Form(1, test=phi_x, trial=phi_x)]
assembler = Assembler(problems, mesh)
assembler.assemble()

A = assembler.af[0]['bilinear'].get_matrix()
n = dofhandler.n_dofs()
b = np.ones((n, 1))

mesh.mark_region('left', lambda x: np.abs(x) < 1e-9)
mesh.mark_region('right', lambda x: np.abs(1 - x) < 1e-9)
Exemple #20
0
def test01_finite_elements():
    """
    Test accuracy of the finite element approximation
    """
    #
    # Construct reference solution
    #
    plot = Plot(quickview=False)

    # Mesh
    mesh = Mesh1D(resolution=(2**11, ))
    mesh.mark_region('left', lambda x: np.abs(x) < 1e-10)
    mesh.mark_region('right', lambda x: np.abs(x - 1) < 1e-10)

    # Element
    Q1 = QuadFE(mesh.dim(), 'Q1')
    dQ1 = DofHandler(mesh, Q1)
    dQ1.distribute_dofs()

    # Basis
    phi = Basis(dQ1, 'v')
    phi_x = Basis(dQ1, 'vx')

    #
    # Covariance
    #
    cov = Covariance(dQ1, name='gaussian', parameters={'l': 0.05})
    cov.compute_eig_decomp()
    lmd, V = cov.get_eig_decomp()
    d = len(lmd)

    #
    # Sample and plot full dimensional parameter and solution
    #
    n_samples = 1
    z = np.random.randn(d, n_samples)
    q_ref = sample_q0(V, lmd, d, z)

    print(q_ref.shape)

    # Define finite element function
    q_ref_fn = Nodal(data=q_ref, basis=phi)
    problem = [[Form(q_ref_fn, test=phi_x, trial=phi_x),
                Form(1, test=phi)],
               [Form(q_ref_fn, test=phi_x, dmu='dv', flag='right')]]

    # Define assembler
    assembler = Assembler(problem)

    # Incorporate Dirichlet conditions
    assembler.add_dirichlet('left', 0)
    assembler.add_dirichlet('right', 1)

    # Assemble system
    assembler.assemble()

    # Solve system
    u_ref = assembler.solve()

    # Compute quantity of interest
    J_ref = u_ref.dot(assembler.get_vector(1))

    # Plot
    fig = plt.figure(figsize=(6, 4))
    ax = fig.add_subplot(111)
    u_ref_fn = Nodal(basis=phi, data=u_ref)

    ax = plot.line(u_ref_fn, axis=ax)

    n_levels = 10
    J = np.zeros(n_levels)
    for l in range(10):
        comment.comment('level: %d' % (l))

        #
        # Mesh
        #
        mesh = Mesh1D(resolution=(2**l, ))
        mesh.mark_region('left', lambda x: np.abs(x) < 1e-10)
        mesh.mark_region('right', lambda x: np.abs(x - 1) < 1e-10)

        #
        # Element
        #
        Q1 = QuadFE(mesh.dim(), 'Q1')
        dQ1 = DofHandler(mesh, Q1)
        dQ1.distribute_dofs()

        #
        # Basis
        #
        phi = Basis(dQ1, 'v')
        phi_x = Basis(dQ1, 'vx')

        # Define problem
        problem = [[
            Form(q_ref_fn, test=phi_x, trial=phi_x),
            Form(1, test=phi)
        ], [Form(q_ref_fn, test=phi_x, dmu='dv', flag='right')]]

        assembler = Assembler(problem)

        # Incorporate Dirichlet conditions
        assembler.add_dirichlet('left', 0)
        assembler.add_dirichlet('right', 1)

        assembler.assemble()
        A = assembler.get_matrix()
        print('A shape', A.shape)

        u = assembler.solve()
        J[l] = u.dot(assembler.get_vector(1))

        print(u.shape)
        print(phi.n_dofs())
        ufn = Nodal(basis=phi, data=u)
        ax = plot.line(ufn, axis=ax)

    plt.show()
    #
    # Plots
    #
    # Formatting
    plt.rc('text', usetex=True)

    # Figure sizes
    fs2 = (3, 2)
    fs1 = (4, 3)

    print(J_ref)
    print(J)

    #
    # Plot truncation error for mean and variance of J
    #

    fig = plt.figure(figsize=fs2)
    ax = fig.add_subplot(111)

    err = np.array([np.abs(J[i] - J_ref) for i in range(n_levels)])
    h = np.array([2**(-l) for l in range(n_levels)])
    plt.loglog(h, err, '.-')

    ax.set_xlabel(r'$h$')
    ax.set_ylabel(r'$|J-J^h|$')
    plt.tight_layout()
    fig.savefig('fig/ex02_gauss_fem_error.eps')
Exemple #21
0
    def test_subsample_deterministic(self):
        """
        When evaluating a deterministic function while specifying a subsample,
        n_subsample copies of the function output should be returned.        
        """
        #
        # Deterministic functions
        #

        # Functions
        fns = {
            1: {
                1: lambda x: x[:, 0]**2,
                2: lambda x, y: x[:, 0] + y[:, 0]
            },
            2: {
                1: lambda x: x[:, 0]**2 + x[:, 1]**2,
                2: lambda x, y: x[:, 0] * y[:, 0] + x[:, 1] * y[:, 1]
            }
        }

        # Singletons
        x = {1: {1: 2, 2: (3, 4)}, 2: {1: (1, 2), 2: ((1, 2), (3, 4))}}

        xv = {
            1: {
                1: [(2, ), (2, )],
                2: ([(3, ), (3, )], [(4, ), (4, )])
            },
            2: {
                1: [(1, 2), (1, 2)],
                2: ([(1, 2), (1, 2)], [(3, 4), (3, 4)])
            }
        }

        vals = {1: {1: 4, 2: 7}, 2: {1: 5, 2: 11}}
        subsample = np.array([2, 3], dtype=np.int)

        for dim in [1, 2]:
            #
            # Iterate over dimension
            #

            # DofHandler
            if dim == 1:
                mesh = Mesh1D(box=[0, 5], resolution=(1, ))
            elif dim == 2:
                mesh = QuadMesh(box=[0, 5, 0, 5])
            element = QuadFE(dim, 'Q2')
            dofhandler = DofHandler(mesh, element)
            dofhandler.distribute_dofs()
            basis = Basis(dofhandler)
            for n_variables in [1, 2]:
                #
                # Iterate over number of variables
                #

                #
                # Explicit
                #
                f = fns[dim][n_variables]

                # Explicit
                fe = Explicit(f, n_variables=n_variables, dim=dim, \
                             subsample=subsample)

                # Nodal
                fn = Nodal(f, n_variables=n_variables, basis=basis, dim=dim, \
                           dofhandler=dofhandler, subsample=subsample)

                # Constant
                fc = Constant(1, n_variables=n_variables, \
                              subsample=subsample)

                # Singleton input
                xn = x[dim][n_variables]

                # Explicit
                self.assertEqual(fe.eval(xn).shape[1], len(subsample))
                self.assertEqual(fe.eval(xn)[0, 0], vals[dim][n_variables])
                self.assertEqual(fe.eval(xn)[0, 1], vals[dim][n_variables])

                # Nodal
                self.assertEqual(fn.eval(xn).shape[1], len(subsample))
                self.assertAlmostEqual(
                    fn.eval(xn)[0, 0], vals[dim][n_variables])
                self.assertAlmostEqual(
                    fn.eval(xn)[0, 1], vals[dim][n_variables])

                # Constant
                self.assertEqual(fc.eval(xn).shape[1], len(subsample))
                self.assertAlmostEqual(fc.eval(xn)[0, 0], 1)
                self.assertAlmostEqual(fc.eval(xn)[0, 1], 1)

                # Vector input
                xn = xv[dim][n_variables]
                n_points = 2

                # Explicit
                self.assertEqual(fe.eval(xn).shape, (2, 2))
                for i in range(fe.n_subsample()):
                    for j in range(n_points):
                        self.assertEqual(
                            fe.eval(xn)[i][j], vals[dim][n_variables])

                # Nodal
                self.assertEqual(fn.eval(xn).shape, (2, 2))
                for i in range(fe.n_subsample()):
                    for j in range(n_points):
                        self.assertAlmostEqual(
                            fn.eval(xn)[i][j], vals[dim][n_variables])

                # Constant
                self.assertEqual(fc.eval(xn).shape, (2, 2))
                for i in range(fe.n_subsample()):
                    for j in range(n_points):
                        self.assertEqual(fc.eval(xn)[i][j], 1)
Exemple #22
0
def test02_sensitivity():
    """
    Check that the sensitivity calculation works. Compare 
    
        J(q+eps*dq) - J(q) ~= eps*dJ^T dq
    """
    #
    # Mesh
    #
    mesh = Mesh1D(resolution=(20, ))
    mesh.mark_region('left', lambda x: np.abs(x) < 1e-10)
    mesh.mark_region('right', lambda x: np.abs(x - 1) < 1e-10)

    #
    # Element
    #
    Q = QuadFE(mesh.dim(), 'Q3')
    dQ = DofHandler(mesh, Q)
    dQ.distribute_dofs()
    nx = dQ.n_dofs()
    x = dQ.get_dof_vertices()

    #
    # Basis
    #
    phi = Basis(dQ, 'v')
    phi_x = Basis(dQ, 'vx')

    #
    # Parameters
    #

    # Reference q
    q_ref = np.zeros(nx)

    # Perturbation
    dq = np.ones(nx)

    # Perturbed q
    n_eps = 10  # Number of refinements
    epsilons = [10**(-l) for l in range(n_eps)]
    q_per = np.empty((nx, n_eps))
    for i in range(n_eps):
        q_per[:, i] = q_ref + epsilons[i] * dq

    # Define finite element function
    exp_qref = Nodal(data=np.exp(q_ref), basis=phi)
    exp_qper = Nodal(data=np.exp(q_per), basis=phi)

    #
    # PDEs
    #

    # 1. State Equation
    state_eqn = [Form(exp_qref, test=phi_x, trial=phi_x), Form(1, test=phi)]
    state_dbc = {'left': 0, 'right': 1}

    # 2. Perturbed Equation
    perturbed_eqn = [
        Form(exp_qper, test=phi_x, trial=phi_x),
        Form(1, test=phi)
    ]
    perturbed_dbc = {'left': 0, 'right': 1}

    # 3. Adjoint Equation
    adjoint_eqn = [Form(exp_qref, test=phi_x, trial=phi_x), Form(0, test=phi)]
    adjoint_dbc = {'left': 0, 'right': -1}

    # Combine
    eqns = [state_eqn, perturbed_eqn, adjoint_eqn]
    bcs = [state_dbc, perturbed_dbc, adjoint_dbc]

    #
    # Assembly
    #
    assembler = Assembler(eqns)

    # Boundary conditions
    for i, bc in zip(range(3), bcs):
        for loc, val in bc.items():
            assembler.add_dirichlet(loc, val, i_problem=i)

    # Assemble
    assembler.assemble()

    #
    # Solve
    #

    # Solve state
    ur = assembler.solve(i_problem=0)
    u_ref = Nodal(data=ur, basis=phi)
    ux_ref = Nodal(data=ur, basis=phi_x)

    # Solve perturbed state
    u_per = Nodal(basis=phi)
    ue_per = Nodal(basis=phi)
    for i in range(n_eps):
        # FEM solution
        up = assembler.solve(i_problem=1, i_matrix=i)
        u_per.add_samples(up)

        # Exact perturbed solution
        eps = epsilons[i]
        ue_per.add_samples(0.5 * np.exp(-eps) * (x - x**2) + x)

    ux_per = Nodal(data=u_per.data(), basis=phi_x)

    # Solve adjoint equation
    v = assembler.solve(i_problem=2)
    v_adj = Nodal(data=v, basis=phi)
    vx_adj = Nodal(data=v, basis=phi_x)

    #
    # Check against exact solution
    #
    ue = -0.5 * x**2 + 1.5 * x
    ve = -x

    assert np.allclose(ue, u_ref.data())
    assert np.allclose(ve, v_adj.data())
    assert np.allclose(ue_per.data(), u_per.data())

    #
    # Quantities of Interest
    #

    # Reference
    k_ref = Kernel(f=[exp_qref, ux_ref], F=lambda eq, ux: eq * ux)
    ref_qoi = [Form(k_ref, dmu='dv', flag='right')]

    # Perturbed
    k_per = Kernel(f=[exp_qper, ux_per], F=lambda eq, ux: eq * ux)
    per_qoi = [Form(k_per, dmu='dv', flag='right')]

    # Adjoint
    k_adj = Kernel(f=[exp_qref, ux_ref, vx_adj],
                   F=lambda eq, ux, vx: -eq * ux * vx)
    adj_qoi = [Form(k_adj, test=phi)]

    qois = [ref_qoi, per_qoi, adj_qoi]

    # Assemble
    assembler = Assembler(qois)
    assembler.assemble()

    # Evaluate
    J_ref = assembler.get_scalar(0)
    J_per = []
    for i in range(n_eps):
        J_per.append(assembler.get_scalar(1, i))

    # Finite difference approximation
    dJ = []
    for eps, J_p in zip(epsilons, J_per):
        dJ.append((J_p - J_ref) / eps)

    # Adjoint differential
    dJ_adj = assembler.get_vector(2).dot(dq)

    #
    # Check against exact qois
    #

    # Check reference sol
    Je_ref = 0.5
    assert np.allclose(Je_ref, J_ref)

    # Check perturbed cost
    Je_per = -0.5 + np.exp(np.array(epsilons))
    assert np.allclose(Je_per, J_per)

    # Check derivative by the adjoint equation
    dJdq = 1
    assert np.allclose(dJ_adj, dJdq)
Exemple #23
0
    def test_eval_x(self):
        #
        # Evaluate Nodal function at a given set of x-values
        #

        # Meshes and elements
        meshes = {1: Mesh1D(resolution=(2, )), 2: QuadMesh(resolution=(2, 1))}
        elements = {1: QuadFE(1, 'Q2'), 2: QuadFE(2, 'Q2')}

        # Use function to set data
        fns = {
            1: {
                1: lambda x: 2 * x[:, 0]**2,
                2: lambda x, y: 2 * x[:, 0] + 2 * y[:, 0]
            },
            2: {
                1: lambda x: x[:, 0]**2 + x[:, 1],
                2: lambda x, y: x[:, 0] * y[:, 0] + x[:, 1] * y[:, 1]
            }
        }

        # n_samples = 2
        parms = {1: {1: [{}, {}], 2: [{}, {}]}, 2: {1: [{}, {}], 2: [{}, {}]}}

        n_points = 1
        for dim in [1, 2]:
            mesh = meshes[dim]
            element = elements[dim]
            dofhandler = DofHandler(mesh, element)
            dofhandler.distribute_dofs()
            #dofhandler.get_region_dofs()
            basis = Basis(dofhandler)
            #
            # Define random points in domain
            #
            if dim == 1:
                x_min, x_max = mesh.bounding_box()

                x = x_min + 0.5 * (x_max - x_min) * np.random.rand(n_points)
                x = x[:, np.newaxis]

                y = x_min + (x_max - x_min) * np.random.rand(n_points)
                y = y[:, np.newaxis]
            elif dim == 2:
                x_min, x_max, y_min, y_max = mesh.bounding_box()

                x = np.zeros((n_points, 2))
                x[:, 0] = x_min + (x_max - x_min) * np.random.rand(n_points)
                x[:, 1] = y_min + (y_max - y_min) * np.random.rand(n_points)

                y = np.zeros((n_points, 2))
                y[:, 0] = x_min + (x_max - x_min) * np.random.rand(n_points)
                y[:, 1] = y_min + (y_max - y_min) * np.random.rand(n_points)

            for n_variables in [1, 2]:
                fn = fns[dim][n_variables]
                parm = parms[dim][n_variables]
                #
                # Deterministic
                #
                f = Nodal(f=fn,
                          basis=basis,
                          mesh=mesh,
                          element=element,
                          dim=dim,
                          n_variables=n_variables)

                if n_variables == 1:
                    xx = x
                    fe = fn(x)
                elif n_variables == 2:
                    xx = (x, y)
                    fe = fn(*xx)
                fx = f.eval(x=xx)
                self.assertTrue(np.allclose(fx, fe))

                #
                # Sampled
                #
                f = Nodal(f=fn,
                          parameters=parm,
                          basis=basis,
                          mesh=mesh,
                          element=element,
                          dim=dim,
                          n_variables=n_variables)
                self.assertEqual(f.n_samples(), 2)

                fx = f.eval(x=xx)
                self.assertTrue(np.allclose(fx[:, 0], fe))
                self.assertTrue(np.allclose(fx[:, 1], fe))
    return f, g, y, p


# =============================================================================
# Variational Form
# =============================================================================
comment = Verbose()
#
# Mesh
#
# Computational domain
x_min = 0
x_max = 2

mesh = Mesh1D(box=[x_min, x_max], resolution=(100, ))

# Mark Dirichlet Vertices
mesh.mark_region('left', lambda x: np.abs(x) < 1e-9)
mesh.mark_region('right', lambda x: np.abs(x - 2) < 1e-9)

#
# Finite element spaces
#
Q1 = QuadFE(mesh.dim(), 'Q1')

# Dofhandler for state
dh = DofHandler(mesh, Q1)
dh.distribute_dofs()
m = dh.n_dofs()
dh.set_dof_vertices()