Beispiel #1
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()))
Beispiel #2
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()))
Beispiel #3
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)
Beispiel #4
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
Beispiel #5
0
 def __init__(self, f, u, eps, upwind_type='classical'):
     """
     Constructor
     
     Inputs:
     
         f: Map, explicit kernel function
         
         u: Map, velocity function
         
         eps: double >0, diffusivity
         
         upwind_scheme: str, type of upwind scheme used 
     """
     Kernel.__init__(self, f)
     self.__upwind_type = upwind_type
     self.__vel = u
     self.__eps = eps
Beispiel #6
0
 def test_n_samples(self):
     # 
     # 1D
     #
     
     # Define mesh
     mesh = Mesh1D(resolution=(10,))
     
     # Define function  
     f = Explicit([lambda x: x, lambda x: -2+2*x**2], dim=1)
     n_samples = f.n_samples()
     
     k = Kernel(f)
     
     n_points = 101
     x0, x1 = mesh.bounding_box()
     x = np.linspace(x0,x1,n_points)
     
     self.assertEqual(k.eval(x).shape, (n_points, n_samples))
     self.assertTrue(np.allclose(k.eval(x)[:,0],x))
     self.assertTrue(np.allclose(k.eval(x)[:,1], -2+2*x**2))
Beispiel #7
0
 def test_eval(self):
     #
     # 1D 
     # 
     
     # Define Kernel function
     def k_fn(x,y,c = 2):
         return x*y + c
     
     k = Explicit(f=lambda x,y,c: x*y+c, parameters={'c':1}, 
                  n_variables=2, dim=1)
     
     # Construct kernel, specifying parameter c
     kernel = Kernel(k)
     
     # Evaluation points
     x = np.ones((11,1))
     y = np.linspace(0,1,11)[:,None]
     
     # Check accuracy
     self.assertTrue(np.allclose(kernel.eval((x,y)), x*y+1))
     
     # Define kernel with default parameters
     k.set_parameters({'c':2})
     
     kernel = Kernel(k)
     
     # Check accuracy
     self.assertTrue(np.allclose(kernel.eval((x,y)), x*y+2))
Beispiel #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)
Beispiel #9
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()))
Beispiel #10
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()))
Beispiel #11
0
    def test_eval_projection(self):
        """
        Test validity of the local projection-based kernel. 
        
        Choose 
        
            u, v in V 
            k(x,y) in VxV (symmetric/non-symm)
            cell01, cell02
            
        Compare
        
            v^T*Kloc*u ?= Icell01 Icell02 k(x,y)u(y)dy dx
        """
        #
        # 1D
        #

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

        # Finite element space
        etype = 'Q1'
        element = QuadFE(1, etype)

        # Dofhandler
        dofhandler = DofHandler(mesh, element)
        dofhandler.distribute_dofs()

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

        # Symmetric kernel function
        kfns = {
            'symmetric': lambda x, y: x * y,
            'non_symmetric': lambda x, y: x - y
        }

        vals = {
            'symmetric':
            (1 / 2 * 1 / 9 - 1 / 3 * 1 / 27) * (1 / 3 - 1 / 3 * 8 / 27),
            'non_symmetric': (1 / 18 - 1 / 3 * 1 / 27) * (1 / 2 - 2 / 9) +
            (1 / 18 - 1 / 3) * (1 / 3 - 1 / 3 * 8 / 27)
        }

        for ktype in ['symmetric', 'non_symmetric']:

            # Get kernel function
            kfn = kfns[ktype]

            # Define integral kernel
            kernel = Kernel(Explicit(kfn, dim=1, n_variables=2))

            # Define Bilinear Form
            form = IPForm(kernel, trial=phi, test=phi)

            #
            # Compute inputs required for evaluating form_loc
            #

            # Assembler
            assembler = Assembler(form, mesh)

            # Cells
            ci = mesh.cells.get_child(0)
            cj = mesh.cells.get_child(2)

            # Shape function info on cells
            ci_sinfo = assembler.shape_info(ci)
            cj_sinfo = assembler.shape_info(cj)

            # Gauss nodes and weights on cell
            xi_g, wi_g, phii, dofsi = assembler.shape_eval(ci)
            xj_g, wj_g, phij, dofsj = assembler.shape_eval(cj)

            #
            # Evaluate form
            #
            form_loc = form.eval((ci,cj), (xi_g,xj_g), \
                                 (wi_g,wj_g), (phii,phij), (dofsi,dofsj))
            #
            # Define functions
            #
            u = Nodal(f=lambda x: x, basis=phi)
            v = Nodal(f=lambda x: 1 - x, basis=phi)

            #
            # Get local node values
            #
            # Degrees of freedom
            ci_dofs = phi.dofs(ci)
            cj_dofs = phi.dofs(cj)
            uj = u.data()[np.array(cj_dofs)]
            vi = v.data()[np.array(ci_dofs)]

            if ktype == 'symmetric':
                # Local form by hand
                c10 = 1 / 54
                c11 = 1 / 27
                c20 = 3 / 2 - 1 - 3 / 2 * 4 / 9 + 8 / 27
                c21 = 4 / 27
                fl = np.array([[c10 * c20, c10 * c21], [c11 * c20, c11 * c21]])

                # Compare computed and explicit local forms
                self.assertTrue(np.allclose(fl, form_loc))

            # Evaluate Ici Icj k(x,y) y dy (1-x)dx
            fa = np.dot(vi.T, form_loc.dot(uj))
            fe = vals[ktype]
            self.assertAlmostEqual(fa, fe)
Beispiel #12
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()
Beispiel #13
0
    def test_eval_interpolation(self):
        #
        # 1D
        #

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

        # Finite element space
        etype = 'Q1'
        element = QuadFE(1, etype)

        # Dofhandler
        dofhandler = DofHandler(mesh, element)
        dofhandler.distribute_dofs()

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

        # Symmetric kernel function
        kfns = {
            'symmetric': lambda x, y: x * y,
            'non_symmetric': lambda x, y: x - y
        }

        vals = {
            'symmetric':
            np.array([0, 1 / 9 * (1 - 8 / 27)]),
            'non_symmetric':
            np.array([1 / 3 * (-1 + 8 / 27), 1 / 6 * 5 / 9 - 1 / 3 * 19 / 27])
        }

        for ktype in ['symmetric', 'non_symmetric']:

            # Get kernel function
            kfn = kfns[ktype]

            # Define integral kernel
            kernel = Kernel(Explicit(kfn, dim=1, n_variables=2))

            # Define Bilinear Form
            form = IIForm(kernel, trial=phi, test=phi)

            #
            # Compute inputs required for evaluating form_loc
            #

            # Assembler
            assembler = Assembler(form, mesh)

            # Cells
            cj = mesh.cells.get_child(2)
            ci = mesh.cells.get_child(0)

            # Gauss nodes and weights on cell
            xj_g, wj_g, phij, dofsj = assembler.shape_eval(cj)

            #
            # Evaluate form
            #
            form_loc = form.eval(cj, xj_g, wj_g, phij, dofsj)
            #
            # Define functions
            #
            u = Nodal(lambda x: x, basis=phi)

            #
            # Get local node values
            #

            # Degrees of freedom
            cj_dofs = phi.dofs(cj)
            ci_dofs = phi.dofs(ci)

            uj = u.data()[np.array(cj_dofs)]

            # Evaluate Ici Icj k(x,y) y dy (1-x)dx
            fa = form_loc[ci_dofs].dot(uj)
            fe = vals[ktype][:, None]

            self.assertTrue(np.allclose(fa, fe))
Beispiel #14
0
# Monte Carlo Sample
# =============================================================================

n_batches = 1
n_samples_per_batch = 10
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)
Beispiel #15
0
def test_ft():
    plot = Plot()
    vb = Verbose()

    # =============================================================================
    # Parameters
    # =============================================================================
    #
    # Flow
    #

    # permeability field
    phi = Constant(1)  # porosity
    D = Constant(0.0252)  # dispersivity
    K = Constant(1)  # permeability

    # =============================================================================
    # Mesh and Elements
    # =============================================================================
    # Mesh
    mesh = QuadMesh(resolution=(30, 30))

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

    # Elements
    p_element = QuadFE(2, 'Q1')  # element for pressure
    c_element = QuadFE(2, 'Q1')  # element for concentration

    # Dofhandlers
    p_dofhandler = DofHandler(mesh, p_element)
    c_dofhandler = DofHandler(mesh, c_element)

    p_dofhandler.distribute_dofs()
    c_dofhandler.distribute_dofs()

    # Basis functions
    p_ux = Basis(p_dofhandler, 'ux')
    p_uy = Basis(p_dofhandler, 'uy')
    p_u = Basis(p_dofhandler, 'u')

    p_inflow = lambda x, y: np.ones(shape=x.shape)
    p_outflow = lambda x, y: np.zeros(shape=x.shape)
    c_inflow = lambda x, y: np.zeros(shape=x.shape)

    # =============================================================================
    # Solve the steady state flow equations
    # =============================================================================
    vb.comment('Solving flow equations')

    # Define problem
    flow_problem = [
        Form(1, test=p_ux, trial=p_ux),
        Form(1, test=p_uy, trial=p_uy),
        Form(0, test=p_u)
    ]

    # Assemble
    vb.tic('assembly')
    assembler = Assembler(flow_problem)
    assembler.add_dirichlet('left', 1)
    assembler.add_dirichlet('right', 0)
    assembler.assemble()
    vb.toc()

    # Solve linear system
    vb.tic('solve')
    A = assembler.get_matrix().tocsr()
    b = assembler.get_vector()
    x0 = assembler.assembled_bnd()

    # Interior nodes
    pa = np.zeros((p_u.n_dofs(), 1))
    int_dofs = assembler.get_dofs('interior')
    pa[int_dofs, 0] = spla.spsolve(A, b - x0)

    # Resolve Dirichlet conditions
    dir_dofs, dir_vals = assembler.get_dirichlet(asdict=False)
    pa[dir_dofs] = dir_vals
    vb.toc()

    # Pressure function
    pfn = Nodal(data=pa, basis=p_u)

    px = pfn.differentiate((1, 0))
    py = pfn.differentiate((1, 1))

    #plot.contour(px)
    #plt.show()

    # =============================================================================
    # Transport Equations
    # =============================================================================
    # Specify initial condition
    c0 = Constant(1)
    dt = 1e-1
    T = 6
    N = int(np.ceil(T / dt))

    c = Basis(c_dofhandler, 'c')
    cx = Basis(c_dofhandler, 'cx')
    cy = Basis(c_dofhandler, 'cy')

    print('assembling transport equations')
    k_phi = Kernel(f=phi)
    k_advx = Kernel(f=[K, px], F=lambda K, px: -K * px)
    k_advy = Kernel(f=[K, py], F=lambda K, py: -K * py)
    tht = 1
    m = [Form(kernel=k_phi, test=c, trial=c)]
    s = [
        Form(kernel=k_advx, test=c, trial=cx),
        Form(kernel=k_advy, test=c, trial=cy),
        Form(kernel=Kernel(D), test=cx, trial=cx),
        Form(kernel=Kernel(D), test=cy, trial=cy)
    ]

    problems = [m, s]
    assembler = Assembler(problems)
    assembler.add_dirichlet('left', 0, i_problem=0)
    assembler.add_dirichlet('left', 0, i_problem=1)
    assembler.assemble()

    x0 = assembler.assembled_bnd()

    # Interior nodes
    int_dofs = assembler.get_dofs('interior')

    # Dirichlet conditions
    dir_dofs, dir_vals = assembler.get_dirichlet(asdict=False)

    # System matrices
    M = assembler.get_matrix(i_problem=0)
    S = assembler.get_matrix(i_problem=1)

    # Initialize c0 and cp
    c0 = np.ones((c.n_dofs(), 1))
    cp = np.zeros((c.n_dofs(), 1))
    c_fn = Nodal(data=c0, basis=c)

    #
    # Compute solution
    #
    print('time stepping')
    for i in range(N):

        # Build system
        A = M + tht * dt * S
        b = M.dot(c0[int_dofs]) - (1 - tht) * dt * S.dot(c0[int_dofs])

        # Solve linear system
        cp[int_dofs, 0] = spla.spsolve(A, b)

        # Add Dirichlet conditions
        cp[dir_dofs] = dir_vals

        # Record current iterate
        c_fn.add_samples(data=cp)

        # Update c0
        c0 = cp.copy()

        #plot.contour(c_fn, n_sample=i)

    #
    # Quantity of interest
    #
    def F(c, px, py, entity=None):
        """
        Compute c(x,y,t)*(grad p * n)
        """
        n = entity.unit_normal()
        return c * (px * n[0] + py * n[1])

    px.set_subsample(i=np.arange(41))
    py.set_subsample(i=np.arange(41))

    #kernel = Kernel(f=[c_fn,px,py], F=F)
    kernel = Kernel(c_fn)

    #print(kernel.n_subsample())
    form = Form(kernel, flag='right', dmu='ds')
    assembler = Assembler(form, mesh=mesh)
    assembler.assemble()
    QQ = assembler.assembled_forms()[0].aggregate_data()['array']

    Q = np.array([assembler.get_scalar(i_sample=i) for i in np.arange(N + 1)])
    t = np.linspace(0, T, N + 1)
    plt.plot(t, Q)
    plt.show()
    print(Q)
Beispiel #16
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()))
Beispiel #17
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()
Beispiel #18
0
def dJdq_sen(q, u, dq):
    """
    Compute the directional derivative dJ(q,dq) by means of the sensitivity 
    equation.

        -(exp(q)*s')' = (exp(q)*dq*u')'
        s(0) = s(1) = 0
        
    and computing 
    
        dJ(q,dq) = -exp(q(1))*dq(1)*u'(1) - exp(q(1))*s'(1)
        
    """
    #
    # Finite Element Specification
    #

    # Reference state
    u_dh = u.basis().dofhandler()
    mesh = u_dh.mesh
    phi = Basis(u_dh, 'u')
    phi_x = Basis(u_dh, 'ux')
    ux_fn = Nodal(data=u.data(), basis=phi_x)

    # Reference diffusivitity
    q_dh = q.basis().dofhandler()
    psi = q.basis()
    exp_q = Nodal(data=np.exp(q.data()), basis=phi)

    # Define sensitivity equation
    ker_sen = Kernel(f=[exp_q, dq, ux_fn], F=lambda eq, dq, ux: -eq * dq * ux)
    sensitivity_eqn = [
        Form(exp_q, test=phi_x, trial=phi_x),
        Form(ker_sen, test=phi_x)
    ]

    # Assembler
    assembler = Assembler(sensitivity_eqn, u_dh.mesh, n_gauss=(6, 36))

    # Apply Dirichlet Boundary conditions
    assembler.add_dirichlet('left', 0)
    assembler.add_dirichlet('right', 0)

    # Assemble system
    assembler.assemble()

    # Solve for sensitivity
    s_fn = Nodal(basis=phi)
    for i in range(dq.n_samples()):
        # Solve for ith sensitivity
        s = assembler.solve(i_vector=i)
        s_fn.add_samples(s)

    # Derivative of sensitivity
    sx_fn = Nodal(data=s_fn.data(), basis=phi_x)

    # Sensitivity
    k_sens = Kernel(f=[exp_q, dq, ux_fn, sx_fn],
                    F=lambda eq, dq, ux, sx: -eq * dq * ux - eq * sx)
    sens_qoi = Form(k_sens, dmu='dv', flag='right')

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

    # Differential
    dJ = np.array([assembler.get_scalar(i_sample=i) \
                   for i in range(dq.n_samples())])

    return dJ
Beispiel #19
0
gamma = 0.1

#
# 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)
Beispiel #20
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)
Beispiel #21
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()))
Beispiel #22
0
def dJdq_adj(q, u, dq=None):
    """
    Compute the directional derivative dJ(q,dq) by solving the adjoint equation 
    
        -(exp(q)v')' = 0, 
        v(0)=0, v(1)=1 
        
    and computing
    
        ( v, (exp(q)*dq(1)*u')' ) + exp(q(1))*dq(1)*u'(1) = -(exp(q)*dq u', v')
        
        
    Inputs: 
    
        q: Nodal, single reference log diffusitivity 
        
        u: Nodal, single reference system response
        
        dq: Nodal/None, sampled perturbation vector (or None) 
        
    
    Output:
    
        dJdq: Derivative of J wrt q
        
            If dq = Nodal, return directional derivative in direction dq
            
            If dq = None, return gradient
    """
    #
    # Finite Element Specification
    #

    # Reference solution
    u_dh = u.basis().dofhandler()
    phi = Basis(u_dh, 'u')
    phi_x = Basis(u_dh, 'ux')
    ux = Nodal(data=u.data(), basis=phi_x)

    # Reference diffusivity
    q_dh = q.basis().dofhandler()
    psi = Basis(q_dh, 'q')
    exp_q = Nodal(data=np.exp(q.data()), basis=psi)

    # Define adjoint equations
    adjoint_eqn = [Form(exp_q, test=phi_x, trial=phi_x), Form(0, test=phi)]

    # Assembler
    assembler = Assembler(adjoint_eqn)

    # Apply Dirichlet BC
    assembler.add_dirichlet('left', 0)
    assembler.add_dirichlet('right', 1)

    # Assemble
    assembler.assemble()

    # Solve for adjoint
    v = assembler.solve()

    # Get derivative
    vx = Nodal(data=v, basis=phi_x)

    # Assemble

    if dq is None:
        #
        # Compute the gradient
        #

        # Kernel
        k_adj = Kernel(f=[exp_q, ux, vx], F=lambda eq, ux, vx: -eq * ux * vx)

        # Linear form
        adj_qoi = [Form(k_adj, test=psi)]

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

        # Get gradient vector
        dJdq = assembler.get_vector()
    else:
        #
        # Compute the directional derivative
        #

        # Kernel
        k_adj = Kernel(f=[exp_q, dq, ux, vx],
                       F=lambda eq, dq, ux, vx: -eq * dq * ux * vx)

        # Constant form
        adj_qoi = [Form(k_adj)]

        # Assemble
        assembler = Assembler(adj_qoi, mesh=u_dh.mesh)
        assembler.assemble()

        # Get directional derivatives for each direction
        dJdq = np.array(
            [assembler.get_scalar(i_sample=i) for i in range(dq.n_samples())])
    # Return
    return dJdq
Beispiel #23
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()))
Beispiel #24
0
dofhandler.distribute_dofs()
comment.toc()

print('number of dofs:', dofhandler.n_dofs())

# Basis functions
p_u = Basis(dofhandler, 'u')
p_ux = Basis(dofhandler, 'ux')
p_uy = Basis(dofhandler, 'uy')
pp_u = Basis(dofhandler, 'u')

f = lambda x: x[:, 0] * (1 - x[:, 0]) * x[:, 1] * (1 - x[:, 1])
qq = Explicit(f=f, dim=2)
fNodal = Nodal(f=f, basis=p_u)

qk = Kernel(f=[qq], F=lambda qq, mu=3: 3 * qq)

p_inflow = lambda x, y: np.ones(shape=x.shape)
p_outflow = lambda x, y: np.zeros(shape=x.shape)
c_inflow = lambda x, y: np.zeros(shape=x.shape)

# =============================================================================
# Solve the steady state flow equations
# =============================================================================

# Define problem

flow_problem = [
    Form(fNodal),
    Form(1, test=p_uy, trial=p_uy),
    Form(1, test=p_u)
Beispiel #25
0
# Generate truncated field at the sparse grid points
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()
Beispiel #26
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())
Beispiel #27
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
Beispiel #28
0
 def __init__(self, u, dfdx=None, samples='all'):
     """
     Constructor 
     """
     Kernel.__init__(self, u, dfdx=dfdx, F=None, samples=samples)
Beispiel #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()
Beispiel #30
0
# Gaussian random field θ
tht = GaussianField(dQ1.n_dofs(), K=K)

# 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()