コード例 #1
0
    def test_constructor(self):
        #
        # Define mesh, element, and dofhandler
        #
        mesh = QuadMesh(box=[0, 20, 0, 20],
                        resolution=(20, 20),
                        periodic={0, 1})
        dim = mesh.dim()
        element = QuadFE(dim, 'Q2')
        dofhandler = DofHandler(mesh, element)
        dofhandler.distribute_dofs()
        basis = Basis(dofhandler, 'u')

        alph = 2
        kppa = 1

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

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

        #plot.contour(f)

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

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

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

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

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

        tau = (h11, h12, h22)

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

        plot = Plot(20)
        plot.contour(v)
コード例 #2
0
def test03_dJdq():
    """
    Compute dJdq for a simple problem, check that it works
    """
    #
    # Mesh
    #
    mesh = Mesh1D(resolution=(20, ))
    mesh.mark_region('left', lambda x: np.abs(x) < 1e-10)
    mesh.mark_region('right', lambda x: np.abs(x - 1) < 1e-10)

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

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

    #
    # Parameters
    #

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

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

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

    #
    # Compute dJdq
    #

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

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

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

    # Check that the answers are close to -1
    assert np.allclose(Jp_per, -1)
    assert np.allclose(Jp_sen, -1)
    assert np.allclose(Jp_adj, -1)
コード例 #3
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
コード例 #4
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()))
コード例 #5
0
def test02a_sensitivity_gradient():
    """
    Test whether the sensitivity and adjoint calculations give the same gradient
    """
    # Mesh
    mesh = Mesh1D(resolution=(100, ))
    mesh.mark_region('left', lambda x: np.abs(x) < 1e-10)
    mesh.mark_region('right', lambda x: np.abs(1 - x) < 1e-10)

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

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

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

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

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

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

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

    # Compute gradient using adjoint method
    dJa = dJdq_adj(q0_fn, u0_fn)
    dJa_fn = Nodal(data=dJa, basis=phi)
    print(dJa)
    plot.line(dJa_fn)
コード例 #6
0
ファイル: test_assembler.py プロジェクト: hvanwyk/quadmesh
    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))
コード例 #7
0
ファイル: test_assembler.py プロジェクト: hvanwyk/quadmesh
    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()))
コード例 #8
0
ファイル: test_assembler.py プロジェクト: hvanwyk/quadmesh
    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)
コード例 #9
0
ファイル: test_assembler.py プロジェクト: hvanwyk/quadmesh
    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))
コード例 #10
0
    def test_constructor(self):
        #
        # Errors
        #

        # Nothing specified
        self.assertRaises(Exception, Nodal)

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

        data = np.arange(0, 4)

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

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

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

        kwargs = {'data': data, 'element': element}
        self.assertRaises(Exception, Nodal, **kwargs)
コード例 #11
0
 def get_solution(self, as_function=True):
     """
     Returns the solution of the linear system 
     """
     if not as_function:
         #
         # Return solution vector
         # 
         return self.__u
     else: 
         #
         # Return solution as nodal function
         # 
         u = Nodal(data=self.__u, basis=self.get_basis())
         return u
コード例 #12
0
    def test_n_samples(self):
        #
        # Sampled Case
        #
        meshes = {1: Mesh1D(), 2: QuadMesh()}
        elements = {1: QuadFE(1, 'Q2'), 2: QuadFE(2, 'Q2')}

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

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

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

                #
                # Sampled
                #
                f = Nodal(f=fn,
                          parameters=parm,
                          basis=basis,
                          mesh=mesh,
                          element=element,
                          dim=dim,
                          n_variables=n_variables)
                self.assertEqual(f.n_samples(), 2)
コード例 #13
0
ファイル: test_assembler.py プロジェクト: hvanwyk/quadmesh
    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)
コード例 #14
0
def set_diffusion(dQ, z):
    """
    Generate sample of diffusion coefficient
    
    Inputs:
    
        dQ: DofHandler, dofhandler object
    
        z: (n_samples, n_dim) array of sample points in [0,1]^2
    """
    x = dQ.get_dof_vertices()
    q_vals = 1 + 0.1  *np.outer(np.cos(1*np.pi*x[:,0]),z[:,0])+\
                 0.05 *np.outer(np.cos(2*np.pi*x[:,0]),z[:,1])+\
                 0.01 *np.outer(np.cos(3*np.pi*x[:,0]),z[:,2])+\
                 0.005*np.outer(np.cos(4*np.pi*x[:,0]),z[:,3])

    q_fn = Nodal(dofhandler=dQ, data=q_vals)
    return q_fn
コード例 #15
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
コード例 #16
0
ファイル: test_gmrf.py プロジェクト: hvanwyk/quadmesh
    def test_constructor(self):
        """
        GMRF
        """
        mesh = Mesh1D(resolution=(1000, ))
        element = QuadFE(1, 'Q1')
        dofhandler = DofHandler(mesh, element)
        cov_kernel = CovKernel(name='matern', dim=2, \
                                      parameters= {'sgm': 1, 'nu': 2,
                                                   'l': 0.1, 'M': None})

        print('assembling covariance')
        covariance = Covariance(cov_kernel, dofhandler)

        print('defining gmrf')
        X = GMRF(covariance=covariance)

        print('sampling')
        Xh = Nodal(data=X.chol_sample(), dofhandler=dofhandler)

        print('plotting')
        plot = Plot()
        plot.line(Xh)
        '''
コード例 #17
0
ファイル: ex06.py プロジェクト: hvanwyk/quadmesh
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
コード例 #18
0
ファイル: ex06.py プロジェクト: hvanwyk/quadmesh
z, w = hermite_rule(k, depth)
n_sg = len(w)

# 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, 
コード例 #19
0
ファイル: ex06.py プロジェクト: hvanwyk/quadmesh
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()
コード例 #20
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()))
コード例 #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
    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()))
コード例 #23
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()))
コード例 #24
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()))
コード例 #25
0
            # Assembler system
            #
            assembler = Assembler([problem], mesh)
            assembler.add_dirichlet(None, ue)
            assembler.assemble()

            #
            # Get solution
            #
            ua = assembler.solve()

            #
            # Compute the error
            #
            e_vec = ua[:, None] - ue.interpolant(dofhandler).data()
            efn = Nodal(data=e_vec, basis=u, dim=2)

            #
            # Record error
            #
            errors[resolution][eps][etype] = max(np.abs(e_vec))

headers = ('Resolution', 'Q1:1', 'Q1:1e-3', 'Q1:1e-6', 'Q2:1', 'Q2:1e-3',
           'Q2:1e-6')
print('{:<12} {:<10} {:<10} {:<10} {:<10} {:<10} {:<10}'.format(*headers))

for resolution in errors.keys():
    er = errors[resolution]

    row = [resolution[0],er[1]['Q1'][0], er[1e-3]['Q1'][0], er[1e-6]['Q1'][0], \
           er[1]['Q2'][0], er[1e-3]['Q2'][0], er[1e-6]['Q2'][0]]
コード例 #26
0
phiy_1 = Basis(dQ1, 'vy')

phi_2 = Basis(dQ2)
phix_2 = Basis(dQ2, 'vx')
phiy_2 = Basis(dQ2, 'vy')

#
# Define Random field
#
cov = Covariance(dQ0, name='gaussian', parameters={'l': 0.01})
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
コード例 #27
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)
コード例 #28
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))
コード例 #29
0
state = LS(phi)
state.add_dirichlet_constraint('left', 1)
state.add_dirichlet_constraint('right', 0)
state.set_constraint_relation()

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

# =============================================================================
# System Parameters
# =============================================================================
# Target
y_target = Nodal(f=lambda x: 3 - 4 * (x[:, 0] - 1)**2, dim=1, dofhandler=dh)
y_data = y_target.data()

# Regularization parameter
#gamma = 0.00001
gamma = 1e-5
# Inital guess
u = np.zeros((m, 1))

#
# Diffusion Parameter
#

# Initialize diffusion
q = Nodal(data=np.empty((m, 1)), dofhandler=dh)
コード例 #30
0
phi = Basis(dQ1)
phi_x = Basis(dQ1, derivative='vx')
phi_y = Basis(dQ1, derivative='vy')

#
# Diffusion Parameter
#

# Covariance Matrix
K = Covariance(dQ1, name='exponential', parameters={'sgm': 1, 'l': 0.1})

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