Ejemplo n.º 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)
Ejemplo n.º 2
0
def sensitivity_sample_qoi(exp_q, dofhandler):
    """
    Sample QoI by means of Taylor expansion
    
        J(q+dq) ~= J(q) + dJdq(q)dq
    """
    # Basis
    phi = Basis(dofhandler, 'v')
    phi_x = Basis(dofhandler, 'vx')

    # Define problem
    exp_q_fn = Nodal(data=exp_q, basis=phi)

    primal = [Form(exp_q_fn, test=phi_x, trial=phi_x), Form(1, test=phi)]
    adjoint = [Form(exp_q_fn, test=phi_x, trial=phi_x), Form(0, test=phi)]
    qoi = [Form(exp_q_fn, test=phi_x)]
    problems = [primal, adjoint, qoi]

    # Define assembler
    assembler = Assembler(problems)

    #
    # Dirichlet conditions for primal problem
    #
    assembler.add_dirichlet('left', 0, i_problem=0)
    assembler.add_dirichlet('right', 1, i_problem=0)

    # Dirichlet conditions for adjoint problem
    assembler.add_dirichlet('left', 0, i_problem=1)
    assembler.add_dirichlet('right', -1, i_problem=1)

    # Assemble system
    assembler.assemble()

    # Compute solution and qoi at q (primal)
    u = assembler.solve(i_problem=0)

    # Compute solution of the adjoint problem
    v = assembler.solve(i_problem=1)

    # Evaluate J
    J = u.dot(assembler.get_vector(2))

    #
    # Assemble gradient
    #
    ux_fn = Nodal(data=u, basis=phi_x)
    vx_fn = Nodal(data=v, basis=phi_x)

    k_int = Kernel(f=[exp_q_fn, ux_fn, vx_fn],
                   F=lambda exp_q, ux, vx: exp_q * ux * vx)

    problem = [Form(k_int, test=phi)]

    assembler = Assembler(problem)
    assembler.assemble()
    dJ = -assembler.get_vector()
    return dJ
Ejemplo n.º 3
0
    def test_set(self):
        mesh = QuadMesh(resolution=(1, 1))
        element = QuadFE(2, 'Q1')
        dofhandler = DofHandler(mesh, element)
        dofhandler.distribute_dofs()
        px = Basis(dofhandler, 'ux')
        p = Basis(dofhandler, 'ux')

        self.assertNotEqual(px, p)
Ejemplo n.º 4
0
def sample_qoi(q, dofhandler):
    """
    Sample total energy of output for a given sample of q's 
    """
    # 
    # Set up weak form 
    # 
    
    # Basis 
    phi   = Basis(dofhandler, 'v')
    phi_x = Basis(dofhandler, 'vx')
       
    # Elliptic problem
    problems = [[Form(q, test=phi_x, trial=phi_x), Form(1, test=phi)],
                [Form(1, test=phi, trial=phi)]]
    
    # Assemble
    assembler = Assembler(problems, mesh)
    assembler.assemble()
    
    # System matrices
    A = assembler.af[0]['bilinear'].get_matrix()
    b = assembler.af[0]['linear'].get_matrix()
    M = assembler.af[1]['bilinear'].get_matrix()
    
    # Define linear system
    system = LS(phi)
    system.add_dirichlet_constraint('left',1)
    system.add_dirichlet_constraint('right',0)
    
    n_samples = q.n_samples()
    y_smpl = []
    QoI_smpl = []
    for i in range(n_samples):
        # Sample system 
        if n_samples > 1:
            Ai = A[i]
        else:
            Ai = A
        system.set_matrix(Ai)
        system.set_rhs(b.copy())
        
        # Solve system
        system.solve_system()
        
        # Record solution and qoi
        y = system.get_solution(as_function=False)
        y_smpl.append(y)
        QoI_smpl.append(y.T.dot(M.dot(y)))
    
    # Convert to numpy array    
    y_smpl = np.concatenate(y_smpl,axis=1)
    QoI = np.concatenate(QoI_smpl, axis=1).ravel()
    
    return y_smpl, QoI
Ejemplo n.º 5
0
    def test02_1d_dirichlet_higher_order(self):
        mesh = Mesh1D()
        for etype in ['Q2', 'Q3']:
            element = QuadFE(1, etype)
            dofhandler = DofHandler(mesh, element)
            dofhandler.distribute_dofs()

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

            # Exact solution
            ue = Nodal(f=lambda x: x * (1 - x), basis=u)

            # Define coefficient functions
            one = Constant(1)
            two = Constant(2)

            # Define forms
            a = Form(kernel=Kernel(one), trial=ux, test=ux)
            L = Form(kernel=Kernel(two), test=u)
            problem = [a, L]

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

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

            # Set up linear system
            system = LinearSystem(u, A=A, b=b)

            # Boundary functions
            bnd_left = lambda x: np.abs(x) < 1e-9
            bnd_right = lambda x: np.abs(1 - x) < 1e-9

            # Mark mesh
            mesh.mark_region('left', bnd_left, entity_type='vertex')
            mesh.mark_region('right', bnd_right, entity_type='vertex')

            # Add Dirichlet constraints to system
            system.add_dirichlet_constraint('left', 0)
            system.add_dirichlet_constraint('right', 0)

            # Solve system
            system.solve_system()
            system.resolve_constraints()

            # Compare solution with the exact solution
            ua = system.get_solution(as_function=True)
            self.assertTrue(np.allclose(ua.data(), ue.data()))
Ejemplo n.º 6
0
    def test01_solve_2d(self):
        """
        Solve a simple 2D problem with no hanging nodes
        """
        mesh = QuadMesh(resolution=(5, 5))

        # Mark dirichlet boundaries
        mesh.mark_region('left',
                         lambda x, dummy: np.abs(x) < 1e-9,
                         entity_type='half_edge')

        mesh.mark_region('right',
                         lambda x, dummy: np.abs(x - 1) < 1e-9,
                         entity_type='half_edge')

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

        phi = Basis(dQ1, 'u')
        phi_x = Basis(dQ1, 'ux')
        phi_y = Basis(dQ1, 'uy')

        problem = [
            Form(1, test=phi_x, trial=phi_x),
            Form(1, test=phi_y, trial=phi_y),
            Form(0, test=phi)
        ]

        assembler = Assembler(problem, mesh)
        assembler.add_dirichlet('left', dir_fn=0)
        assembler.add_dirichlet('right', dir_fn=1)
        assembler.assemble()

        # Get matrix dirichlet correction and right hand side
        A = assembler.get_matrix().toarray()
        x0 = assembler.assembled_bnd()
        b = assembler.get_vector()

        ua = np.zeros((phi.n_dofs(), 1))
        int_dofs = assembler.get_dofs('interior')
        ua[int_dofs, 0] = np.linalg.solve(A, b - x0)

        dir_bc = assembler.get_dirichlet()
        dir_vals = np.array([dir_bc[dof] for dof in dir_bc])
        dir_dofs = [dof for dof in dir_bc]
        ua[dir_dofs] = dir_vals

        ue_fn = Nodal(f=lambda x: x[:, 0], basis=phi)
        ue = ue_fn.data()
        self.assertTrue(np.allclose(ue, ua))
        self.assertTrue(np.allclose(x0 + A.dot(ua[int_dofs, 0]), b))
Ejemplo n.º 7
0
    def test_constructor(self):
        #
        # Define mesh, element, and dofhandler
        #
        mesh = QuadMesh(box=[0, 20, 0, 20],
                        resolution=(20, 20),
                        periodic={0, 1})
        dim = mesh.dim()
        element = QuadFE(dim, 'Q2')
        dofhandler = DofHandler(mesh, element)
        dofhandler.distribute_dofs()
        basis = Basis(dofhandler, 'u')

        alph = 2
        kppa = 1

        # Symmetric tensor gma T + bta* vv^T
        gma = 0.1
        bta = 25

        p = lambda x: 10/np.pi*(0.75*np.sin(np.pi*x[:,0]/10)+\
                                0.25*np.sin(np.pi*x[:,1]/10))
        f = Nodal(f=p, basis=basis)
        fx = f.differentiate((1, 0))
        fy = f.differentiate((1, 1))

        #plot.contour(f)

        x = np.linspace(0, 20, 12)
        X, Y = np.meshgrid(x, x)
        xy = np.array([X.ravel(), Y.ravel()]).T
        U = fx.eval(xy).reshape(X.shape)
        V = fy.eval(xy).reshape(X.shape)

        v1 = lambda x: -0.25 * np.cos(np.pi * x[:, 1] / 10)
        v2 = lambda x: 0.75 * np.cos(np.pi * x[:, 0] / 10)

        U = v1(xy).reshape(X.shape)
        V = v2(xy).reshape(X.shape)

        #plt.quiver(X,Y, U, V)
        #plt.show()

        h11 = Explicit(lambda x: gma + bta * v1(x) * v1(x), dim=2)
        h12 = Explicit(lambda x: bta * v1(x) * v2(x), dim=2)
        h22 = Explicit(lambda x: gma + bta * v2(x) * v2(x), dim=2)

        tau = (h11, h12, h22)

        #tau = (Constant(2), Constant(1), Constant(1))
        #
        # Define default elliptic field
        #
        u = EllipticField(dofhandler, kappa=1, tau=tau, gamma=2)
        Q = u.precision()
        v = Nodal(data=u.sample(mode='precision', decomposition='chol'),
                  basis=basis)

        plot = Plot(20)
        plot.contour(v)
Ejemplo n.º 8
0
def experiment01():
    """
    Compute the quantity of interest, it's expectation and variance
    """
    #
    # FE Discretization
    #

    # Computational mesh
    mesh = Mesh1D(resolution=(64, ))

    # Element
    element = QuadFE(mesh.dim(), 'DQ0')
    dofhandler = DofHandler(mesh, element)
    dofhandler.distribute_dofs()

    # Linear Functional
    mesh.mark_region('integrate',
                     lambda x: x > 0.75,
                     entity_type='cell',
                     strict_containment=False)
    phi = Basis(dofhandler)
    assembler = Assembler(Form(1, test=phi, flag='integrate'))
    assembler.assemble()
    L = assembler.get_vector()
Ejemplo n.º 9
0
    def test_assemble_iiform(self):

        mesh = Mesh1D(resolution=(1, ))

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

        phi = Basis(dofhandler, 'u')

        k = Explicit(lambda x, y: x * y, n_variables=2, dim=1)
        kernel = Kernel(k)

        form = IIForm(kernel, test=phi, trial=phi)

        assembler = Assembler(form, mesh)
        assembler.assemble()
        Ku = Nodal(lambda x: 1 / 3 * x, basis=phi)

        #af = assembler.af[0]['bilinear']
        M = assembler.get_matrix().toarray()

        u = Nodal(lambda x: x, basis=phi)
        u_vec = u.data()
        self.assertTrue(np.allclose(M.dot(u_vec), Ku.data()))
Ejemplo n.º 10
0
    def test_assemble_ipform(self):
        # =====================================================================
        # Test 7: Assemble Kernel
        # =====================================================================
        mesh = Mesh1D(resolution=(10, ))

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

        phi = Basis(dofhandler, 'u')

        k = Explicit(lambda x, y: x * y, n_variables=2, dim=1)
        kernel = Kernel(k)
        form = IPForm(kernel, test=phi, trial=phi)

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

        #af = assembler.af[0]['bilinear']
        M = assembler.get_matrix().toarray()

        u = Nodal(lambda x: x, basis=phi)
        v = Nodal(lambda x: 1 - x, basis=phi)

        u_vec = u.data()
        v_vec = v.data()

        I = v_vec.T.dot(M.dot(u_vec))
        self.assertAlmostEqual(I[0, 0], 1 / 18)
Ejemplo n.º 11
0
def sampling_error():
    """
    Test the sampling error by comparing the accuracy of the quantities of 
    interest q1 = E[|y|] and q2 = E[y(0.5)]
        
    """
    c = Verbose()
    mesh = Mesh1D(resolution=(1026,))
    mesh.mark_region('left', lambda x:np.abs(x)<1e-10)
    mesh.mark_region('right', lambda x:np.abs(x-1)<1e-10)
    
    element = QuadFE(1,'Q1')
    dofhandler = DofHandler(mesh, element)
    dofhandler.distribute_dofs()
    dofhandler.set_dof_vertices()
    
    phi = Basis(dofhandler,'u')
    phi_x = Basis(dofhandler,'ux')
    
    ns_ref = 10000
    z = get_points(n_samples=ns_ref)
    q = set_diffusion(dofhandler,z)
    
    problems = [[Form(q, test=phi_x, trial=phi_x), Form(1, test=phi)],
                [Form(1, test=phi, trial=phi)]]
    
    c.tic('assembling')
    assembler = Assembler(problems, mesh)
    assembler.assemble()
    c.toc()
    
    A = assembler.af[0]['bilinear'].get_matrix()
    b = assembler.af[0]['linear'].get_matrix()
    M = assembler.af[0]['bilinear'].get_matrix()
    
    system = LS(phi)
    system.add_dirichlet_constraint('left')
    system.add_dirichlet_constraint('right')
    
    c.tic('solving')
    for n in range(ns_ref):
        system.set_matrix(A[n])
        system.set_rhs(b.copy())    
        system.solve_system()
        
    c.toc()    
Ejemplo n.º 12
0
    def test_edge_integrals(self):
        """
        Test computing
        """
        mesh = QuadMesh(resolution=(1, 1))
        Q = QuadFE(2, 'Q1')
        dQ = DofHandler(mesh, Q)
        dQ.distribute_dofs()

        phi = Basis(dQ, 'u')
        f = Nodal(data=np.ones((phi.n_dofs(), 1)), basis=phi)
        kernel = Kernel(f)
        form = Form(kernel, dmu='ds')
        assembler = Assembler(form, mesh)

        cell = mesh.cells.get_leaves()[0]
        shape_info = assembler.shape_info(cell)
        xg, wg, phi, dofs = assembler.shape_eval(cell)
Ejemplo n.º 13
0
def sample_state(mesh,dQ,z,mflag,reference=False):
    """
    Compute the sample output corresponding to a given input
    """
    n_samples = z.shape[0]
    q = set_diffusion(dQ,z)
    
    phi = Basis(dQ,'u', mflag)
    phi_x = Basis(dQ, 'ux', mflag)
    
    if reference:
        problems = [[Form(q,test=phi_x,trial=phi_x), Form(1,test=phi)], 
                    [Form(1,test=phi, trial=phi)],
                    [Form(1,test=phi_x, trial=phi_x)]]
    else:
        problems = [[Form(q,test=phi_x,trial=phi_x), Form(1,test=phi)]]
    
    assembler = Assembler(problems, mesh, subforest_flag=mflag)
    assembler.assemble()
    
    A = assembler.af[0]['bilinear'].get_matrix()
    b = assembler.af[0]['linear'].get_matrix()
    if reference:
        M = assembler.af[1]['bilinear'].get_matrix()
        K = assembler.af[2]['bilinear'].get_matrix()
        
    system = LS(phi)
    system.add_dirichlet_constraint('left')
    system.add_dirichlet_constraint('right')
    
    n_dofs = dQ.n_dofs(subforest_flag=mflag)
    y = np.empty((n_dofs,n_samples))
    for n in range(n_samples):
        system.set_matrix(A[n])
        system.set_rhs(b.copy())
        system.solve_system()
        y[:,n] = system.get_solution(as_function=False)[:,0]
    y_fn = Nodal(dofhandler=dQ,subforest_flag=mflag,data=y)
    
    if reference:
        return y_fn, M, K
    else:
        return y_fn
Ejemplo n.º 14
0
    def test_n_samples(self):
        #
        # Sampled Case
        #
        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]
            }
        }

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

        for dim in [1, 2]:
            mesh = meshes[dim]
            element = elements[dim]
            dofhandler = DofHandler(mesh, element)
            dofhandler.distribute_dofs()
            basis = Basis(dofhandler)
            for n_variables in [1, 2]:
                fn = fns[dim][n_variables]
                parm = parms[dim][n_variables]
                #
                # Deterministic
                #
                f = Nodal(f=fn,
                          mesh=mesh,
                          basis=basis,
                          element=element,
                          dim=dim,
                          n_variables=n_variables)
                self.assertEqual(f.n_samples(), 1)

                #
                # 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)
Ejemplo n.º 15
0
    def test_same_dofs(self):
        #
        # Construct nested mesh
        #
        mesh = QuadMesh()
        mesh.record(0)

        for dummy in range(2):
            mesh.cells.refine()
        #
        # Define dofhandler
        #
        element = QuadFE(mesh.dim(), 'Q1')
        dofhandler = DofHandler(mesh, element)
        dofhandler.distribute_dofs()

        #
        # Define basis functions
        #
        phi0 = Basis(dofhandler, 'u', subforest_flag=0)
        phi0_x = Basis(dofhandler, 'ux', subforest_flag=0)
        phi1 = Basis(dofhandler, 'u')

        self.assertTrue(phi0.same_mesh(phi0_x))
        self.assertFalse(phi0.same_mesh(phi1))
Ejemplo n.º 16
0
def test02a_sensitivity_gradient():
    """
    Test whether the sensitivity and adjoint calculations give the same gradient
    """
    # Mesh
    mesh = Mesh1D(resolution=(100, ))
    mesh.mark_region('left', lambda x: np.abs(x) < 1e-10)
    mesh.mark_region('right', lambda x: np.abs(1 - x) < 1e-10)

    # Element
    Q = QuadFE(mesh.dim(), 'Q2')
    dh = DofHandler(mesh, Q)
    dh.distribute_dofs()
    n_dofs = dh.n_dofs()
    phi = Basis(dh, 'u')

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

    # Coarse field (single sample)
    d0 = 2
    z0 = np.random.randn(d0, 1)
    q0 = sample_q0(V, lmd, d0, z0)
    q0_fn = Nodal(data=q0, basis=phi)

    # State
    J0, u0 = sample_qoi(q0, dh, return_state=True)
    u0_fn = Nodal(data=u0, basis=phi)

    # Compute gradient using sensitivity
    dJs = np.zeros(n_dofs)
    for i in range(n_dofs):
        # Define perturbation
        dq = np.zeros(n_dofs)
        dq[i] = 1
        dq_fn = Nodal(data=dq, basis=phi)

        # Compute gradient using sensitivity
        dJs[i] = dJdq_sen(q0_fn, u0_fn, dq_fn)

    dJs_fn = Nodal(data=dJs, basis=phi)
    plot = Plot()
    plot.line(dJs_fn)

    # Compute gradient using adjoint method
    dJa = dJdq_adj(q0_fn, u0_fn)
    dJa_fn = Nodal(data=dJa, basis=phi)
    print(dJa)
    plot.line(dJa_fn)
Ejemplo n.º 17
0
    def test01_solve_1d(self):
        """
        Test solving 1D systems
        """
        mesh = Mesh1D(resolution=(20, ))
        mesh.mark_region('left', lambda x: np.abs(x) < 1e-9)
        mesh.mark_region('right', lambda x: np.abs(x - 1) < 1e-9)

        Q1 = QuadFE(1, 'Q1')
        dQ1 = DofHandler(mesh, Q1)
        dQ1.distribute_dofs()

        phi = Basis(dQ1, 'u')
        phi_x = Basis(dQ1, 'ux')

        problem = [Form(1, test=phi_x, trial=phi_x), Form(0, test=phi)]
        assembler = Assembler(problem, mesh)
        assembler.add_dirichlet('left', dir_fn=0)
        assembler.add_dirichlet('right', dir_fn=1)
        assembler.assemble()

        # Get matrix dirichlet correction and right hand side
        A = assembler.get_matrix().toarray()
        x0 = assembler.assembled_bnd()
        b = assembler.get_vector()

        ua = np.zeros((phi.n_dofs(), 1))
        int_dofs = assembler.get_dofs('interior')
        ua[int_dofs, 0] = np.linalg.solve(A, b - x0)

        dir_bc = assembler.get_dirichlet()
        dir_vals = np.array([dir_bc[dof] for dof in dir_bc])
        dir_dofs = [dof for dof in dir_bc]
        ua[dir_dofs] = dir_vals

        ue_fn = Nodal(f=lambda x: x[:, 0], basis=phi)
        ue = ue_fn.data()
        self.assertTrue(np.allclose(ue, ua))
        self.assertTrue(np.allclose(x0 + A.dot(ua[int_dofs, 0]), b))
Ejemplo n.º 18
0
def test02_variance():
    """
    Compute the variance of J(q) for different mesh refinement levels
    and compare with MC estimates. 
    """
    l_max = 8
    for i_res in np.arange(2, l_max):

        # Computational mesh
        mesh = Mesh1D(resolution=(2**i_res, ))

        # Element
        element = QuadFE(mesh.dim(), 'DQ0')
        dofhandler = DofHandler(mesh, element)
        dofhandler.distribute_dofs()

        # Linear Functional
        mesh.mark_region('integrate',
                         lambda x: x >= 0.75,
                         entity_type='cell',
                         strict_containment=False)
        phi = Basis(dofhandler)
        assembler = Assembler(Form(4, test=phi, flag='integrate'))
        assembler.assemble()
        L = assembler.get_vector()

        # Define Gaussian random field
        C = Covariance(dofhandler, name='gaussian', parameters={'l': 0.05})
        C.compute_eig_decomp()

        eta = GaussianField(dofhandler.n_dofs(), K=C)
        eta.update_support()

        n_samples = 100000
        J_paths = L.dot(eta.sample(n_samples=n_samples))
        var_mc = np.var(J_paths)
        lmd, V = C.get_eig_decomp()
        LV = L.dot(V)
        var_an = LV.dot(np.diag(lmd).dot(LV.transpose()))

        print(var_mc, var_an)
Ejemplo n.º 19
0
    def test_constructor(self):
        #
        # Errors
        #

        # Nothing specified
        self.assertRaises(Exception, Nodal)

        # Nominal case
        mesh = QuadMesh()
        element = QuadFE(2, 'Q1')
        dofhandler = DofHandler(mesh, element)
        dofhandler.distribute_dofs()
        basis = Basis(dofhandler)

        data = np.arange(0, 4)

        f = Nodal(data=data, basis=basis, mesh=mesh, element=element)
        self.assertEqual(f.dim(), 2)
        self.assertTrue(np.allclose(f.data().ravel(), data))

        # Now change the data -> Error
        false_data = np.arange(0, 6)
        self.assertRaises(
            Exception, Nodal, **{
                'data': false_data,
                'mesh': mesh,
                'element': element
            })

        # Now omit mesh or element
        kwargs = {'data': data, 'mesh': mesh}
        self.assertRaises(Exception, Nodal, **kwargs)

        kwargs = {'data': data, 'element': element}
        self.assertRaises(Exception, Nodal, **kwargs)
Ejemplo n.º 20
0
Q0 = QuadFE(1, 'DQ0')
Q1 = QuadFE(1, 'Q1')

#
# Exact diffusion coefficient
# 
qe = Function(qfn, 'explicit', dim=1)
one  = Function(1, 'constant')
k1 = 1e-9
k2 = 1000


#
# Basis functions 
# 
u  = Basis(Q1, 'u')
ux = Basis(Q1, 'ux')
q  = Basis(Q1, 'q')

#
# Forms
# 
a_qe  = Form(kernel=Kernel(qe), trial=ux, test=ux)
a_one = Form(kernel=Kernel(one), trial=ux, test=ux)

L = Form(kernel=Kernel(one), test=u)

# 
# Problems
# 
problems = [[a_qe,L], [a_one]]
Ejemplo n.º 21
0
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()

# =============================================================================
# System Parameters
# =============================================================================
Ejemplo n.º 22
0
    errors[resolution] = {}
    for eps in [1, 1e-3, 1e-6]:

        errors[resolution][eps] = {}

        for etype in ['Q1', 'Q2']:
            #
            # Define element
            #
            element = QuadFE(2, etype)
            dofhandler = DofHandler(mesh, element)
            dofhandler.distribute_dofs()
            #
            # Define Basis Functions
            #
            u = Basis(dofhandler, 'u')
            ux = Basis(dofhandler, 'ux')
            uy = Basis(dofhandler, 'uy')

            #
            # Define weak form
            #
            a_diff_x = Form(eps, trial=ux, test=ux)
            a_diff_y = Form(eps, trial=uy, test=uy)
            a_adv_x = Form(vx, trial=ux, test=u)
            a_adv_y = Form(vy, trial=uy, test=u)
            b = Form(f, test=u)

            problem = [a_diff_x, a_diff_y, a_adv_x, a_adv_y, b]

            #
Ejemplo n.º 23
0
# Define Mesh
# 
mesh = QuadMesh(resolution=(2,1))
mesh.cells.get_child(1).mark('1')
mesh.cells.refine(refinement_flag='1')


#
# Define element
# 
Q1 = QuadFE(2,'Q1')

#
# Basis Functions 
#
u = Basis(Q1, 'u')
ux = Basis(Q1, 'ux')
uy = Basis(Q1, 'uy')

rule = GaussRule(9, Q1)

ue = Function(lambda x,dummy: x, 'nodal', mesh=mesh, element=Q1)
zero = Function(0, 'constant')

ax = Form(trial=ux, test=ux)
ay = Form(trial=uy, test=uy)
L = Form(kernel=Kernel(zero), test=u)
assembler = Assembler([ax,ay,L], mesh)
for dofhandler in assembler.dofhandlers.values():
    dofhandler.set_hanging_nodes()
Ejemplo n.º 24
0
mesh.mark_region('perimeter', pf, entity_type='half_edge')

# Get rid of neighbors of half-edges on slit
for he in mesh.half_edges.get_leaves('slit'):
    if he.unit_normal()[0] < 0:
        he.mark('B')
mesh.tear_region('B')

# =============================================================================
# Functions
# =============================================================================
Q1 = QuadFE(2, 'Q1')
dofhandler = DofHandler(mesh, Q1)
dofhandler.distribute_dofs()

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

epsilon = 1e-6
vx = Explicit(f=lambda x: -x[:, 1], dim=2)
vy = Explicit(f=lambda x: x[:, 0], dim=2)

uB = Explicit(f=lambda x: np.cos(2 * np.pi * (x[:, 1] + 0.25)), dim=2)
problem = [
    Form(epsilon, trial=ux, test=ux),
    Form(epsilon, trial=uy, test=uy),
    Form(vx, trial=ux, test=u),
    Form(vy, trial=uy, test=u),
    Form(0, test=u)
]
Ejemplo n.º 25
0
f_int_region = lambda x: x >= x_min and x <= x_max
f_cnd_region = lambda x: x >= xx_min and x <= xx_max

mesh.mark_region('integration', f_int_region, entity_type='cell')
mesh.mark_region('condition', f_cnd_region, entity_type='cell')

#
# Finite Elements
#

# Piecewise Constant
Q0 = QuadFE(mesh.dim(), 'DQ0')
dQ0 = DofHandler(mesh, Q0)
dQ0.distribute_dofs()
phi_0 = Basis(dQ0)

# Piecewise Linear
Q1 = QuadFE(mesh.dim(), 'Q1')
dQ1 = DofHandler(mesh, Q1)
dQ1.distribute_dofs()
phi_1 = Basis(dQ1)

# -----------------------------------------------------------------------------
# Stochastic Approximation
# -----------------------------------------------------------------------------
#
# Random Field
#
# Covariance kernel
K = Covariance(dQ1, name='gaussian', parameters={'sgm': 1, 'l': 0.1})
Ejemplo n.º 26
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()))
Ejemplo n.º 27
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()))
Ejemplo n.º 28
0
    def test05_2d_dirichlet(self):
        """
        Two dimensional Dirichlet problem with hanging nodes
        """
        #
        # Define mesh
        #
        mesh = QuadMesh(resolution=(1, 2))
        mesh.cells.get_child(1).mark(1)
        mesh.cells.refine(refinement_flag=1)
        mesh.cells.refine()

        #
        # Mark left and right boundaries
        #
        bm_left = lambda x, dummy: np.abs(x) < 1e-9
        bm_right = lambda x, dummy: np.abs(1 - x) < 1e-9
        mesh.mark_region('left', bm_left, entity_type='half_edge')
        mesh.mark_region('right', bm_right, entity_type='half_edge')

        for etype in ['Q1', 'Q2', 'Q3']:
            #
            # Element
            #
            element = QuadFE(2, etype)
            dofhandler = DofHandler(mesh, element)
            dofhandler.distribute_dofs()

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

            #
            # Construct forms
            #
            ue = Nodal(f=lambda x: x[:, 0], basis=u)
            ax = Form(kernel=Kernel(Constant(1)), trial=ux, test=ux)
            ay = Form(kernel=Kernel(Constant(1)), trial=uy, test=uy)
            L = Form(kernel=Kernel(Constant(0)), test=u)
            problem = [ax, ay, L]

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

            #
            # Get system matrices
            #
            A = assembler.get_matrix()
            b = assembler.get_vector()

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

            #
            # Constraints
            #
            # Add dirichlet conditions
            system.add_dirichlet_constraint('left', ue)
            system.add_dirichlet_constraint('right', ue)

            #
            # Solve
            #
            system.solve_system()
            #system.resolve_constraints()

            #
            # Check solution
            #
            ua = system.get_solution(as_function=True)
            self.assertTrue(np.allclose(ua.data(), ue.data()))
Ejemplo n.º 29
0
    def test01_1d_dirichlet_linear(self):
        """
        Solve one dimensional boundary value problem with dirichlet 
        conditions on left and right
        """
        #
        # Define mesh
        #
        mesh = Mesh1D(resolution=(10, ))

        for etype in ['Q1', 'Q2', 'Q3']:
            element = QuadFE(1, etype)
            dofhandler = DofHandler(mesh, element)
            dofhandler.distribute_dofs()
            phi = Basis(dofhandler)
            #
            # Exact solution
            #
            ue = Nodal(f=lambda x: x, basis=phi)

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

            #
            # Define bilinear form
            #
            one = Constant(1)
            zero = Constant(0)
            a = Form(kernel=Kernel(one), trial=ux, test=ux)
            L = Form(kernel=Kernel(zero), test=u)
            problem = [a, L]

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

            #
            # Form linear system
            #

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

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

            #
            # Dirichlet conditions
            #

            # Boundary functions
            bm_left = lambda x: np.abs(x) < 1e-9
            bm_rght = lambda x: np.abs(x - 1) < 1e-9

            # Mark boundary regions
            mesh.mark_region('left', bm_left, on_boundary=True)
            mesh.mark_region('right', bm_rght, on_boundary=True)

            # Add Dirichlet constraints
            system.add_dirichlet_constraint('left', ue)
            system.add_dirichlet_constraint('right', ue)

            #
            # Solve system
            #
            #system.solve_system()
            system.solve_system()

            #
            # Get solution
            #
            #ua = system.get_solution(as_function=True)
            uaa = system.get_solution(as_function=True)
            #uaa = uaa.data().ravel()

            # Compare with exact solution
            #self.assertTrue(np.allclose(ua.data(), ue.data()))
            self.assertTrue(np.allclose(uaa.data(), ue.data()))
Ejemplo n.º 30
0
    def test04_1d_periodic(self):
        #
        # Dirichlet Problem on a Periodic Mesh
        #

        # Define mesh, element
        mesh = Mesh1D(resolution=(100, ), periodic=True)
        element = QuadFE(1, 'Q3')
        dofhandler = DofHandler(mesh, element)
        dofhandler.distribute_dofs()

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

        # Exact solution
        ue = Nodal(f=lambda x: np.sin(2 * np.pi * x), basis=u)

        #
        # Mark dirichlet regions
        #
        bnd_left = lambda x: np.abs(x) < 1e-9
        mesh.mark_region('left', bnd_left, entity_type='vertex')

        #
        # Set up forms
        #

        # Bilinear form
        a = Form(kernel=Kernel(Constant(1)), trial=ux, test=ux)

        # Linear form
        f = Explicit(lambda x: 4 * np.pi**2 * np.sin(2 * np.pi * x), dim=1)
        L = Form(kernel=Kernel(f), test=u)

        #
        # Assemble
        #
        problem = [a, L]
        assembler = Assembler(problem, mesh)
        assembler.assemble()
        A = assembler.get_matrix()
        b = assembler.get_vector()

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

        # Add dirichlet constraint
        system.add_dirichlet_constraint('left', 0, on_boundary=False)

        # Assemble constraints
        #system.set_constraint_relation()
        #system.incorporate_constraints()
        system.solve_system()
        #system.resolve_constraints()

        # Compare with interpolant of exact solution
        ua = system.get_solution(as_function=True)

        #plot = Plot(2)
        #plot.line(ua)
        #plot.line(ue)
        self.assertTrue(np.allclose(ua.data(), ue.data()))