示例#1
0
def test03_dJdq():
    """
    Compute dJdq for a simple problem, check that it works
    """
    #
    # 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')
    dh = DofHandler(mesh, Q)
    dh.distribute_dofs()
    nx = dh.n_dofs()
    x = dh.get_dof_vertices()

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

    #
    # Parameters
    #

    # Reference q
    q_ref = Nodal(data=np.zeros(nx), basis=phi)

    # Perturbation
    dq = Nodal(data=np.ones(nx), basis=phi)

    #
    # Sample Reference QoI
    #
    J, u_ref = sample_qoi(q_ref.data(), dh, return_state=True)
    u_ref = Nodal(data=u_ref, basis=phi)

    #
    # Compute dJdq
    #

    # Perturbation method
    Jp_per = dJdq_per(q_ref, dq, dh)

    # Sensitivity method
    Jp_sen = dJdq_sen(q_ref, u_ref, dq)

    # Adjoint method
    Jp_adj = dJdq_adj(q_ref, u_ref, dq)

    # Check that the answers are close to -1
    assert np.allclose(Jp_per, -1)
    assert np.allclose(Jp_sen, -1)
    assert np.allclose(Jp_adj, -1)
示例#2
0
    def test09_1d_inverse(self):
        """
        Compute the inverse of a matrix and apply it to a vector/matrix.
        """
        #
        # Mesh
        #
        mesh = Mesh1D(resolution=(1, ))
        mesh.mark_region('left', lambda x: np.abs(x) < 1e-9, on_boundary=True)
        mesh.mark_region('right',
                         lambda x: np.abs(1 - x) < 1e-9,
                         on_boundary=True)

        #
        # Elements
        #
        Q3 = QuadFE(1, 'Q3')
        dofhandler = DofHandler(mesh, Q3)
        dofhandler.distribute_dofs()

        #
        # Basis
        #
        u = Basis(dofhandler, 'u')
        ux = Basis(dofhandler, 'ux')

        #
        # Define sampled right hand side and exact solution
        #
        xv = dofhandler.get_dof_vertices()
        n_points = dofhandler.n_dofs()

        n_samples = 6
        a = np.arange(n_samples)

        ffn = lambda x, a: a * x
        ufn = lambda x, a: a / 6 * (x - x**3) + x
        fdata = np.zeros((n_points, n_samples))
        udata = np.zeros((n_points, n_samples))
        for i in range(n_samples):
            fdata[:, i] = ffn(xv, a[i]).ravel()
            udata[:, i] = ufn(xv, a[i]).ravel()

        # Define sampled function
        fn = Nodal(data=fdata, basis=u)
        ue = Nodal(data=udata, basis=u)

        #
        # Forms
        #
        one = Constant(1)
        a = Form(Kernel(one), test=ux, trial=ux)
        L = Form(Kernel(fn), test=u)
        problem = [[a], [L]]

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

        A = assembler.get_matrix()
        b = assembler.get_vector(i_problem=1)

        #
        # Linear System
        #
        system = LinearSystem(u, A=A)

        # Set constraints
        system.add_dirichlet_constraint('left', 0)
        system.add_dirichlet_constraint('right', 1)
        system.solve_system(b)

        # Extract finite element solution
        ua = system.get_solution(as_function=True)

        system2 = LinearSystem(u, A=A, b=b)

        # Set constraints
        system2.add_dirichlet_constraint('left', 0)
        system2.add_dirichlet_constraint('right', 1)
        system2.solve_system()
        u2 = system2.get_solution(as_function=True)

        # Check that the solution is close
        self.assertTrue(np.allclose(ue.data()[:, 0], ua.data()[:, 0]))
        self.assertTrue(np.allclose(ue.data()[:, [0]], u2.data()))
示例#3
0
    def test08_1d_sampled_rhs(self):
        #
        # Mesh
        #
        mesh = Mesh1D(resolution=(1, ))
        mesh.mark_region('left', lambda x: np.abs(x) < 1e-9, on_boundary=True)
        mesh.mark_region('right',
                         lambda x: np.abs(1 - x) < 1e-9,
                         on_boundary=True)

        #
        # Elements
        #
        Q3 = QuadFE(1, 'Q3')
        dofhandler = DofHandler(mesh, Q3)
        dofhandler.distribute_dofs()

        #
        # Basis
        #
        v = Basis(dofhandler, 'u')
        vx = Basis(dofhandler, 'ux')

        #
        # Define sampled right hand side and exact solution
        #
        xv = dofhandler.get_dof_vertices()
        n_points = dofhandler.n_dofs()

        n_samples = 6
        a = np.arange(n_samples)

        f = lambda x, a: a * x
        u = lambda x, a: a / 6 * (x - x**3) + x
        fdata = np.zeros((n_points, n_samples))
        udata = np.zeros((n_points, n_samples))
        for i in range(n_samples):
            fdata[:, i] = f(xv, a[i]).ravel()
            udata[:, i] = u(xv, a[i]).ravel()

        # Define sampled function
        fn = Nodal(data=fdata, basis=v)
        ue = Nodal(data=udata, basis=v)

        #
        # Forms
        #
        one = Constant(1)
        a = Form(Kernel(one), test=vx, trial=vx)
        L = Form(Kernel(fn), test=v)
        problem = [a, L]

        #
        # Assembler
        #
        assembler = Assembler(problem, mesh)
        assembler.assemble()
        A = assembler.get_matrix()
        b = assembler.get_vector()
        #
        # Linear System
        #
        system = LinearSystem(v, A=A, b=b)

        # Set constraints
        system.add_dirichlet_constraint('left', 0)
        system.add_dirichlet_constraint('right', 1)
        #system.set_constraint_relation()
        #system.incorporate_constraints()

        # Solve and resolve constraints
        system.solve_system()
        #system.resolve_constraints()

        # Extract finite element solution
        ua = system.get_solution(as_function=True)

        # Check that the solution is close
        print(ue.data()[:, [0]])
        print(ua.data())
        self.assertTrue(np.allclose(ue.data()[:, [0]], ua.data()))
示例#4
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]))
示例#5
0
文件: ex01.py 项目: hvanwyk/quadmesh
#
mesh = Mesh1D(resolution=(20,))

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

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

# Dofhandler
dofhandler = DofHandler(mesh, Q1)
dofhandler.distribute_dofs()
x = dofhandler.get_dof_vertices()
n = dofhandler.n_dofs()

# -----------------------------------------------------------------------------
# Sample full dimensional parameter space
# -----------------------------------------------------------------------------
#
# Set up sparse grid on coarse parameter space 
#
tasmanian_library="/home/hans-werner/bin/TASMANIAN-6.0/libtasmaniansparsegrid.so"
grid = TasmanianSG.TasmanianSparseGrid(tasmanian_library=tasmanian_library)
dimensions = 4
outputs = 1
max_depth = 8
type = 'level'
rule = 'gauss-legendre'
示例#6
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())
示例#7
0
def reference_solution():
    """
    Use sparse grid method to compute a benchmark solution
    """
    
    mesh = QuadMesh(resolution=(10,10))
    mesh.mark_region('boundary', lambda x,y:True, 
                     entity_type='half_edge', on_boundary=True)
    element = QuadFE(mesh.dim(), 'Q1')
    dofhandler = DofHandler(mesh, element)
    dofhandler.distribute_dofs()
    n = dofhandler.n_dofs()
    phi = Basis(dofhandler, 'u')
    phi_x = Basis(dofhandler, 'ux')
    phi_y = Basis(dofhandler, 'uy')
    yd_fn = Explicit(lambda x: np.sin(2*np.pi*x[:,0])*np.sin(2*np.pi*x[:,1]),dim=2)
    g = np.ones((n,1))
    
    #
    # Random diffusion coefficient
    # 
    
    # Sparse grid
    tasmanian_library="/home/hans-werner/bin/TASMANIAN-6.0/libtasmaniansparsegrid.so"
    grid = TasmanianSG.TasmanianSparseGrid(tasmanian_library=tasmanian_library)
    dimensions = 4
    outputs = 1
    depth = 4
    type = 'tensor'
    rule = 'gauss-legendre'
    grid.makeGlobalGrid(dimensions, outputs, depth, type, rule)
    Y = grid.getPoints()
    w = grid.getQuadratureWeights()
    n_samples = grid.getNumPoints()
    
    
    x = dofhandler.get_dof_vertices()
    a_nodal = 1 + 0.1*(np.outer(np.cos(np.pi*x[:,1]),Y[:,0])+\
                       np.outer(np.cos(np.pi*x[:,0]),Y[:,1])+\
                       np.outer(np.sin(2*np.pi*x[:,1]),Y[:,2])+\
                       np.outer(np.sin(2*np.pi*x[:,0]),Y[:,3]))
    a = Nodal(data=a_nodal, dofhandler=dofhandler)
    yd_vec = yd_fn.eval(x)
    
    problems = [[Form(a, test=phi_x, trial=phi_x), 
                Form(a, test=phi_y, trial=phi_y)],
                [Form(1, test=phi, trial=phi)]]
    
    assembler = Assembler(problems, mesh)
    assembler.assemble()
    
    A = assembler.af[0]['bilinear'].get_matrix()
    M = assembler.af[1]['bilinear'].get_matrix()
    
    state = LS(phi)
    state.add_dirichlet_constraint('boundary')
    
    adjoint = LS(phi)
    adjoint.add_dirichlet_constraint('boundary')
    
    tau = 10
    k_max = 20
    alpha = 0.1
    u = np.zeros((n,1))
    norm_dJ_iter = []
    J_iter = []
    u_iter = []
    for k in range(k_max):
        print('iteration', k)
        # 
        # Compute average cost and gradient
        # 
        dJ = np.zeros((n,1))
        J = 0
        print('sampling')
        for n in range(n_samples):
            print(n)
            yn, pn, Jn, dJn = cost_gradient(state,adjoint,A[n],M,
                                            g,u,yd_vec,alpha)
            
            J += w[n]*Jn
            dJ += w[n]*dJn
        print('')
        norm_dJ = np.sqrt(dJ.T.dot(M.dot(dJ)))
        
        #
        # Store current iterates
        # 
        norm_dJ_iter.append(norm_dJ)
        J_iter.append(J)
        u_iter.append(u)
        
        #
        # Check for convergence
        # 
        if norm_dJ<1e-8:
            break
        #
        # Update iterate
        # 
        u -= tau*dJ
示例#8
0
phi_0 = Basis(dhQ1)
print(phi_0.subforest_flag())
phi_1 = Basis(dhQ1, subforest_flag='coarse')
cell = mesh.cells.get_leaves(subforest_flag='coarse')[0]
cell.info()

print(mesh.cells.is_contained_in('fine', 'coarse'))
# Evaluate phi_1 on cell
sub_dofs = []
for child in cell.get_leaves(flag='fine'):
    sub_dofs.extend(dhQ1.get_cell_dofs(child))

sub_dofs = list(set(sub_dofs))
print(sub_dofs)
x = dhQ1.get_dof_vertices(dofs=sub_dofs)
x_ref = cell.reference_map(x, mapsto='reference')
print(x_ref)

data = phi_1.eval(x_ref, cell)

fig = plt.figure()
ax = plt.axes(projection='3d')

print(data.shape, x.shape)
ax.scatter3D(x[:, 0], x[:, 1], data[:, 0])
plt.show()
print(data)

phi_2 = Basis(dhQ1, subforest_flag='fine')
phi_0 = Basis(dhQ0)
示例#9
0
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()

dofs = dofhandler.get_global_dofs(subforest_flag=flag)
print(dofs)

dofs = dofhandler.get_global_dofs(subforest_flag=new_flag)
print(dofs)

dv = dofhandler.get_dof_vertices(dofs)
print(dv)
示例#10
0
n_production = (4, 3)  # resolution
x_production = np.linspace(0.5, 1.5, n_production[0])
y_production = np.linspace(0.2, 0.8, n_production[1])
X, Y = np.meshgrid(x_production, y_production)
xy = np.array([X.ravel(), Y.ravel()]).T
cells_production = mesh.bin_points(xy)

# Mark vertices
for cell, dummy in cells_production:
    cell.get_vertex(2).mark('production')

# Extract degrees of freedom
production_dofs = dh_Q1.get_region_dofs(entity_type='vertex',
                                        entity_flag='production')

v_production = dh_Q1.get_dof_vertices(dofs=production_dofs)

# Target pressure at production wells
z_fn = Explicit(f=lambda x: 3 - 4 * (x[:, 0] - 1)**2 - 8 * (x[:, 1] - 0.5)**2,
                dim=2,
                mesh=mesh)
y_target = z_fn.eval(v_production)

#
# Locations of injection wells
#
n_injection = (5, 4)  # resolution
x_injection = np.linspace(0.5, 1.5, n_injection[0])
y_injection = np.linspace(0.25, 0.75, n_injection[1])
X, Y = np.meshgrid(x_injection, y_injection)
xy = np.array([X.ravel(), Y.ravel()]).T
示例#11
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)
示例#12
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)
    """
示例#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, ))
示例#14
0
    def test_set_hanging_nodes(self):
        """
        Check that functions in the finite element space can be interpolated
        by linear combinations of shape functions at supporting nodes.
        
        TODO: Move this test to tests for system
        """        
        #
        # Define QuadMesh with hanging node
        # 
        mesh = QuadMesh(resolution=(1,1))        
        mesh.cells.refine()
        mesh.cells.get_child(0).get_child(0).mark(flag=0)                
        mesh.cells.refine(refinement_flag=0)
        
        c_00 = mesh.cells.get_child(0).get_child(0)
        #
        # Define test functions to interpolate
        # 
        test_functions = {'Q1': lambda x,y: x + y, \
                          'Q2': lambda x,y: x**2 + y**2,\
                          'Q3': lambda x,y: x**3*y + y**2*x**2}
        etypes = ['Q1', 'Q2', 'Q3']
        plot = Plot()
        for etype in etypes:
            #print(etype)
            # Define new element
            element = QuadFE(2,etype)
        
            # Distribute dofs and set vertices
            dofhandler = DofHandler(mesh, element)
            dofhandler.distribute_dofs()
            dofhandler.set_dof_vertices()
            
            # Determine hanging nodes
            dofhandler.set_hanging_nodes()
            hanging_nodes = dofhandler.get_hanging_nodes()
            for dof, support in hanging_nodes.items():
                # Get hanging node vertex
                x_hgnd = dofhandler.get_dof_vertices(dof)

                # Extract support indices and weights
                js, ws = support 
                
                # Extract
                dofs_glb = dofhandler.get_cell_dofs(c_00)
                
                #print(dof, js)
                
                # Local dof numbers for supporting nodes
                dofs_loc_supp = [i for i in range(element.n_dofs()) if dofs_glb[i] in js]
                #x_dofs = c_00.reference_map(element.reference_nodes())
                
                #phi_supp = element.shape(x_hgnd, cell=c_00, local_dofs=dofs_loc_supp)
                #print(phi_supp, js)
                
                # Evaluate test function at hanging node 
                #f_hgnd = test_functions[etype](x_hgnd[0],x_hgnd[1])

                #print('Weighted sum of support function', np.dot(phi_supp,ws))
                
                #print(f_hgnd - np.dot(phi_supp, ws))
                #phi_hgnd = element.shape(x_dofs, cell=c_00, local_dofs=dofs_loc_hgnd)
                
                #print(phi_supp)
                #print(phi_hgnd)
            #plot.mesh(mesh, dofhandler=dofhandler, dofs=True)
            
            # Evaluate 
            c_01 = mesh.cells.get_child(0).get_child(1)
            c_022 = mesh.cells.get_child(0).get_child(2).get_child(2)
            #print(dofhandler.get_global_dofs(c_022))
            x_ref = element.reference_nodes()
            #print(dofhandler.get_global_dofs(c_01))
            #print(dofhandler.get_hanging_nodes())
            x = c_01.reference_map(x_ref)
示例#15
0
dh_y = DofHandler(mesh, Q1)
dh_y.distribute_dofs()
ny = dh_y.n_dofs()

# Basis functions
phi   = Basis(dh_y, 'v')
phi_x = Basis(dh_y, 'vx')

# -----------------------------------------------------------------------------
# Observations
# ----------------------------------------------------------------------------- 
# Determine vertices corresponding to production wells
n_prod = 4
h = (x_max-x_min)/(n_prod+2)
x_prod = np.array([(i+1)*h for i in range(n_prod)])
v = dh_y.get_dof_vertices()
dofs_prod = []
for x in x_prod:
    dofs_prod.append(np.argmin(abs(v-x)))
#   
# Target pressure at production wells
#
z_fn = Explicit(f=lambda x: 3-4*(x[:,0]-1)**2, dim=1, mesh=mesh)
z_data = z_fn.eval(v[dofs_prod])

# -----------------------------------------------------------------------------
# Control
# -----------------------------------------------------------------------------
# Determine the vertices corresponding to the injection wells
n_inj = 6
h = (x_max-x_min)/(n_inj+2)
示例#16
0
# 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()
x = dh.get_dof_vertices()

# Basis functions
phi = Basis(dh, 'v')
phi_x = Basis(dh, 'vx')

state = LS(phi)
state.add_dirichlet_constraint('left', 1)
state.add_dirichlet_constraint('right', 0)
state.set_constraint_relation()

adjoint = LS(phi)
adjoint.add_dirichlet_constraint('left', 0)
adjoint.add_dirichlet_constraint('right', 0)
adjoint.set_constraint_relation()
示例#17
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')