Пример #1
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
Пример #2
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()))
Пример #3
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))
Пример #4
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()
Пример #5
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()    
Пример #6
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))
Пример #7
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
Пример #8
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)
Пример #9
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)
Пример #10
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
Пример #11
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()))
Пример #12
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()))
Пример #13
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()))
Пример #14
0
#
# Random diffusion coefficient
# 
n_samples = 200
cov = Covariance(dh_y, name='gaussian', parameters={'l':0.1})
k = GaussianField(ny, K=cov)
k.update_support()
kfn = Nodal(dofhandler=dh_y, data=k.sample(n_samples=n_samples))

    
# =============================================================================
# Assembly
# =============================================================================
K = Kernel(kfn, F=lambda f:np.exp(f))  # diffusivity

problems = [[Form(K, test=phi_x, trial=phi_x)], 
            [Form(test=phi, trial=phi)]]

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

# Mass matrix (for control)
M = assembler.af[1]['bilinear'].get_matrix()


# =============================================================================
# Define State and Adjoint Systems
# =============================================================================
state = LS(phi)
adjoint = LS(phi) 
Пример #15
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()))
Пример #16
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
Пример #17
0
cov.compute_eig_decomp()
q = GaussianField(dQ0.n_dofs(), K=cov)

# Sample Random field
n_samples = 100
eq = Nodal(basis=phi_0, data=np.exp(q.sample(n_samples)))

plot.contour(eq, n_sample=25)

#
# Compute state
#

# Define weak form
state = [[
    Form(eq, test=phix_1, trial=phix_1),
    Form(eq, test=phiy_1, trial=phiy_1),
    Form(1, test=phi_1)
], [Form(1, test=phi_1, flag='dmn')]]

# Assemble system
assembler = Assembler(state)
assembler.add_dirichlet('bnd')
assembler.assemble()

J = assembler.get_vector(1)

# Solve system
u_vec = assembler.solve()
u = Nodal(basis=phi_1, data=u_vec)
Пример #18
0
n_samples = n_batches * n_samples_per_batch
f_mc = []
g_mc = []
for n_batch in tqdm(range(n_batches)):
    #
    # Generate random sample
    #
    z = np.random.normal(size=(r, n_samples_per_batch))
    q_smpl = Vr.dot(np.diag(np.sqrt(lr)).dot(z))
    q.set_data(q_smpl)
    expq = Kernel(q, F=lambda f: np.exp(f))

    #
    # Assemble system
    #
    problems = [[Form(expq, test=phi_x, trial=phi_x)],
                [Form(test=phi, trial=phi)]]
    assembler = Assembler(problems, mesh)
    assembler.assemble()

    M = assembler.af[0]['bilinear'].get_matrix()[0]
    for n in range(n_samples_per_batch):
        A = assembler.af[0]['bilinear'].get_matrix()[n]
        fn, gn, yn, pn = sample_cost_gradient(state, adjoint, A, M, u, y_data,
                                              gamma)
        f_mc.append(fn)
        g_mc.append(gn)

f_mc = np.concatenate(f_mc, axis=1)
g_mc = np.concatenate(g_mc, axis=1)
np.save('f_mc', f_mc)
Пример #19
0
# =============================================================================
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)
]

print('assembling', end=' ')
assembler = Assembler(problem, mesh)
assembler.assemble()
print('done')

print('solving', end=' ')
A = assembler.get_matrix()
b = np.zeros(u.n_dofs())
system = LS(u, A=A, b=b)
Пример #20
0
def plot_heuristics(f, tht, basis, region, condition):
    """
    Parameters
    ----------
    f : lambda, 
        Function of θ to be integrated.
        
    n : int, 
        Sample size for Monte Carlo sample
    
    """
    tht.update_support()
    #
    # Plot samples of the random field
    #
    n = 10000
    tht_sample = tht.sample(n)
    tht_fn = Nodal(data=tht_sample, basis=basis)

    #
    # Compute the quantity of interest
    #

    # Define the kernel
    kf = Kernel(tht_fn, F=f)

    # Assemble over the mesh
    problems = [[Form(kernel=kf, flag=region)], [Form(flag=region)]]
    assembler = Assembler(problems, basis.mesh())
    assembler.assemble()

    # Extract sample
    dx = assembler.get_scalar(i_problem=1)
    q_sample = assembler.get_scalar(i_sample=None) / dx

    #
    # Compute correlation coefficients of q with spatial data
    #

    plot = Plot(quickview=False)
    fig, ax = plt.subplots()
    plt_args = {'linewidth': 0.5, 'color': 'k'}
    ax = plot.line(tht_fn,
                   axis=ax,
                   i_sample=list(range(100)),
                   plot_kwargs=plt_args)
    fig.savefig('ex01_sample_paths.eps')

    fig, ax = plt.subplots()
    ftht = Nodal(data=f(tht_sample), basis=basis)
    ax = plot.line(ftht,
                   axis=ax,
                   i_sample=list(range(100)),
                   plot_kwargs=plt_args)
    fig.savefig('ex01_integrand.eps')

    fig, ax = plt.subplots(1, 1)
    plt.hist(q_sample, bins=50, density=True)
    ax.set_title(r'Histogram $Q(\theta)$')
    fig.savefig('ex01_histogram.eps')
    plt.close('all')

    dh = basis.dofhandler()
    n_dofs = dh.n_dofs()

    # Extract the region on which we condition
    cnd_dofs = dh.get_region_dofs(entity_flag=condition)
    I = np.eye(n_dofs)
    I = I[cnd_dofs, :]

    # Measured tht
    tht_msr = tht_sample[cnd_dofs, 0][:, None]

    n_cnd = 30
    cnd_tht = tht.condition(I, tht_msr, n_samples=n_cnd)

    #cnd_tht_data = np.array([tht_sample[:,0] for dummy in range(n_cnd)])
    #cnd_tht_data[cnd_dofs,:] = cnd_tht

    cnd_tht_fn = Nodal(data=f(cnd_tht), basis=basis)
    fig, ax = plt.subplots()
    ax = plot.line(cnd_tht_fn,
                   axis=ax,
                   i_sample=np.arange(n_cnd),
                   plot_kwargs=plt_args)
    fig.tight_layout()
    plt.show()
Пример #21
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()))
Пример #22
0
"""
Task: 

Modify the kernel class to allow for the computation of forms involving

(i) normal derivatives or
(ii) jumps 

across cell edges. 

i.e. I n.A*grad(u) ds or 
"""

#
# Define mesh
#
mesh = QuadMesh(resolution=(20, 20))
element = QuadFE(2, 'DQ1')

u = Nodal(f=lambda x: -1 + x[:, 0]**5 + x[:, 1]**8, mesh=mesh, element=element)
print(u.data())
plot = Plot(3)
plot.wire(u)

kernel = JumpKernel(u, dfdx='fx')
form = Form(kernel=kernel, dmu='ds')
assembler = Assembler(form, mesh)
assembler.assemble()
cf = assembler.af[0]['constant']
print(cf.get_matrix())
Пример #23
0
eta_trunc_sg = V[:, :k].dot(np.diag(np.sqrt(D[:k])).dot(z.T))

# Generate a Monte Carlo sample on top of sparse grid
n_mc = 20
zz = np.random.randn(n_dofs - k, n_mc)
eta_tail_mc = V[:, k:].dot(np.diag(np.sqrt(D[k:]))).dot(zz)

# -----------------------------------------------------------------------------
# Sample and Integrate
# -----------------------------------------------------------------------------
# Samples of random field
theta_trunc = Nodal(data=eta_trunc_sg[:, [50]] + eta_tail_mc, basis=phi_1)

# Assembler
k = Kernel(theta_trunc, F=lambda tht: tht**2)
problem = Form(flag='integration', kernel=k)
assembler = Assembler(problem, mesh)
assembler.assemble()
v = assembler.get_scalar(i_sample=3)

#plot = Plot(quickview=False)
#fig, ax = plt.subplots()

#plot.mesh(mesh,regions=[('region','cell')])
"""
ax = plot.line(theta_trunc, axis=ax, i_sample=np.arange(n_mc), 
               plot_kwargs={'linewidth':0.2, 
                            'color':'k'})
"""
#plt.show()
Пример #24
0
    y) < 1e-6 or abs(1 - y) < 1e-6
mesh.mark_region('bnd', bnd_fn, entity_type='half_edge', on_boundary=True)

# Mark averaging region
dmn_fn = lambda x, y: x >= 0.75 and x <= 1 and y >= 0.75 and y <= 1
mesh.mark_region('dmn',
                 dmn_fn,
                 entity_type='cell',
                 strict_containment=True,
                 on_boundary=False)
#cells = mesh.get_region(flag='dmn', entity_type='cell', on_boundary=False, subforest_flag=None)
#plot.mesh(mesh, regions=[('bnd','edge'),('dmn','cell')])

# Define Elements
Q0 = QuadFE(mesh.dim(), 'DQ0')
dQ0 = DofHandler(mesh, Q0)
dQ0.distribute_dofs()

phi = Basis(dQ0)

q = Nodal(
    f=lambda x: np.sin(2 * np.pi * x[:, 0]) * np.sin(2 * np.pi * x[:, 1]),
    dim=2,
    basis=phi)

problem = Form(q)

mesh.cells.refine(new_label='fine_mesh')
assembler = Assembler(problem, mesh, subforest_flag='fine_mesh')
assembler.assemble()
Пример #25
0
def reference_qoi(f, tht, basis, region, n=1000000, verbose=True):
    """
    Parameters
    ----------
    f : lambda function,
        Function of θ to be integrated.
        
    tht : GaussianField, 
        Random field θ defined on mesh in terms of its mean and covariance
        
    basis : Basis, 
        Basis function defining the nodal interpolant. It incorporates the
        mesh, the dofhandler, and the derivative.
        
    region : meshflag, 
        Flag indicating the region of integration
    
    n : int, default=1000000 
        Sample size
    
    Returns
    -------
    Q_ref : double, 
        Reference quantity of interest
        
    err : double, 
        Expected RMSE given by var(Q)/n. 
    """

    #
    # Assemble integral
    #
    batch_size = 100000
    n_batches = n // batch_size + (0 if (n % batch_size) == 0 else 1)

    if verbose:
        print('Computing Reference Quantity of Interest')
        print('========================================')
        print('Sample size: ', n)
        print('Batch size: ', batch_size)
        print('Number of batches: ', n_batches)

    Q_smpl = np.empty(n)
    for k in range(n_batches):

        # Determine sample sizes for each batch
        if k < n_batches - 1:
            n_sample = batch_size
        else:
            # Last sample may be smaller than batch_size
            n_sample = n - k * batch_size

        if verbose:
            print(' - Batch Number ', k)
            print(' - Sample Size: ', n_sample)
            print(' - Sampling random field')

        # Sample from field
        tht_smpl = tht.sample(n_sample)

        # Define kernel
        tht_n = Nodal(data=tht_smpl, basis=basis)
        kf = Kernel(tht_n, F=f)

        # Define forms
        if k == 0:
            problems = [[Form(kernel=kf, flag=region)], [Form(flag=region)]]
        else:
            problems = [Form(kernel=kf, flag=region)]

        if verbose:
            print(' - Assembling.')

        # Compute the integral
        assembler = Assembler(problems, basis.mesh())
        assembler.assemble()

        #
        # Compute statistic
        #

        # Get samples
        if k == 0:
            dx = assembler.get_scalar(i_problem=1)

        if verbose:
            print(' - Updating samples \n')

        batch_sample = assembler.get_scalar(i_problem=0, i_sample=None)
        Q_smpl[k * batch_size:k * batch_size + n_sample] = batch_sample / dx

    # Compute mean and MSE
    Q_ref = np.mean(Q_smpl)
    err = np.var(Q_smpl) / n

    # Return reference
    return Q_ref, err
Пример #26
0
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)

print('A before constraint', A.toarray())

system = LS(phi_x)
system.add_dirichlet_constraint('left', 1)
system.add_dirichlet_constraint('right', 0)
Пример #27
0
            # 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]

            #
            # Assembler system
            #
            assembler = Assembler([problem], mesh)
            assembler.add_dirichlet(None, ue)
            assembler.assemble()

            #
Пример #28
0
# Sample from field
tht_fn = Nodal(data=tht.sample(n_samples=3), basis=phi)
plot = Plot()
plot.contour(tht_fn)

#
# Advection
#
v = [0.1, -0.1]

plot.mesh(mesh, regions=[('in', 'edge'), ('out', 'edge'), ('reg', 'cell')])

k = Kernel(tht_fn, F=lambda tht: np.exp(tht))
adv_diff = [
    Form(k, trial=phi_x, test=phi_x),
    Form(k, trial=phi_y, test=phi_y),
    Form(0, test=phi),
    Form(v[0], trial=phi_x, test=phi),
    Form(v[1], trial=phi_y, test=phi)
]

average = [Form(1, test=phi, flag='reg'), Form(1, flag='reg')]
assembler = Assembler([adv_diff, average], mesh)
assembler.add_dirichlet('out', dir_fn=0)
assembler.add_dirichlet('in', dir_fn=10)

assembler.assemble()

u_vec = assembler.solve(i_problem=0, i_matrix=0, i_vector=0)
plot.contour(Nodal(data=u_vec, basis=phi))
Пример #29
0
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]]

#
# Assembly
# 
assembler = Assembler(problems, mesh)
assembler.assemble()
Пример #30
0
Q1 = QuadFE(1, 'Q1')


qe = Function(qfn, 'explicit', dim=1)
one  = Function(1, 'constant')
#
# Basis functions 
# 
u  = Basis(Q1, 'u')
ux = Basis(Q1, 'ux')
q  = Basis(Q0, 'q')

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

# 
# Problems
# 
problems = [[a_qe,L], [a_one], [m]]

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