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

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

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

        self.assertTrue(phi0.same_mesh(phi0_x))
        self.assertFalse(phi0.same_mesh(phi1))
Esempio n. 3
0
    def test01_solve_2d(self):
        """
        Solve a simple 2D problem with no hanging nodes
        """
        mesh = QuadMesh(resolution=(5, 5))

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

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

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

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

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

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

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

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

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

        ue_fn = Nodal(f=lambda x: x[:, 0], basis=phi)
        ue = ue_fn.data()
        self.assertTrue(np.allclose(ue, ua))
        self.assertTrue(np.allclose(x0 + A.dot(ua[int_dofs, 0]), b))
Esempio n. 4
0
mesh.mark_region('bnd', bnd_fn, entity_type='half_edge', on_boundary=True)

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

#
# Elements
#
Q0 = QuadFE(mesh.dim(), 'DQ0')  # Constants for parameter
Q1 = QuadFE(mesh.dim(), 'Q1')  # Linear for output
Q2 = QuadFE(mesh.dim(), 'Q2')  # Quadratic for adjoint

#
# DofHandlers
#
dQ0 = DofHandler(mesh, Q0)
dQ1 = DofHandler(mesh, Q1)
dQ2 = DofHandler(mesh, Q2)

# Distribute DOFs
dQ0.distribute_dofs()
dQ1.distribute_dofs()
dQ2.distribute_dofs()
Esempio n. 5
0
mesh = QuadMesh(resolution=(50, 50))

# Mark Dirichlet boundary regions
out_fn = lambda x, y: abs(x - 1) < 1e-8 and 0.8 <= y and y <= 1
mesh.mark_region('out', out_fn, entity_type='half_edge', on_boundary=True)

in_fn = lambda x, y: abs(x) < 1e-8 and 0 <= y and y <= 0.2
mesh.mark_region('in', in_fn, entity_type='half_edge', on_boundary=True)

x_min, x_max = 0.7, 0.8
y_min, y_max = 0.4, 0.5
reg_fn = lambda x, y: x >= x_min and x <= x_max and y >= y_min and y <= y_max
mesh.mark_region('reg', reg_fn, entity_type='cell')

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

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 θ
Esempio n. 6
0
    def test_eval_phi(self):
        """
        Check that the shapes are correct
        """
        #
        # Mesh
        #
        mesh = QuadMesh()
        dim = mesh.dim()

        #
        # element information
        #
        element = QuadFE(dim, 'Q2')
        dofhandler = DofHandler(mesh, element)
        dofhandler.distribute_dofs()

        # Basis
        basis = Basis(dofhandler)

        # Define phi
        n_points = 5
        phi = np.random.rand(n_points, 2)
        dofs = [0, 1]

        #
        # Deterministic Data
        #
        n_dofs = dofhandler.n_dofs()
        data = np.random.rand(n_dofs)

        # Define deterministic function
        f = Nodal(data=data, basis=basis)

        # Evaluate and check dimensions
        fx = f.eval(phi=phi, dofs=dofs)
        self.assertEqual(fx.shape, (n_points, 1))

        #
        # Sampled Data
        #
        n_samples = 4
        data = np.random.rand(n_dofs, n_samples)

        # Define stochastic function
        f = Nodal(data=data, basis=basis, dofhandler=dofhandler)

        # Evaluate and check dimensions
        fx = f.eval(phi=phi, dofs=dofs)
        self.assertEqual(fx.shape, (n_points, n_samples))

        #
        # Bivariate deterministic
        #
        data = np.random.rand(n_dofs, n_dofs, 1)

        # Define deterministic function
        f = Nodal(data=data, basis=basis, dofhandler=dofhandler, n_variables=2)
        fx = f.eval(phi=(phi, phi), dofs=(dofs, dofs))
        self.assertEqual(fx.shape, (n_points, 1))

        #
        # Bivariate sampled
        #
        data = np.random.rand(n_dofs, n_dofs, n_samples)

        # Define stochastic function
        f = Nodal(data=data, basis=basis, dofhandler=dofhandler, n_variables=2)
        fx = f.eval(phi=(phi, phi), dofs=(dofs, dofs))
        self.assertEqual(fx.shape, (n_points, n_samples))

        #
        # Trivariate deterministic
        #
        data = np.random.rand(n_dofs, n_dofs, n_dofs, 1)
        f = Nodal(data=data, basis=basis, dofhandler=dofhandler, n_variables=3)
Esempio n. 7
0
bnd_fn = lambda x, y: abs(x) < 1e-6 or abs(1 - x) < 1e-6 or abs(
    y) < 1e-6 or abs(1 - y) < 1e-6
mesh.mark_region('bnd', bnd_fn, entity_type='half_edge', on_boundary=True)

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

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

phi = Basis(dQ0)

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

problem = Form(q)

mesh.cells.refine(new_label='fine_mesh')
assembler = Assembler(problem, mesh, subforest_flag='fine_mesh')
assembler.assemble()
Esempio n. 8
0
def reference_solution():
    """
    Use sparse grid method to compute a benchmark solution
    """
    
    mesh = QuadMesh(resolution=(10,10))
    mesh.mark_region('boundary', lambda x,y:True, 
                     entity_type='half_edge', on_boundary=True)
    element = QuadFE(mesh.dim(), 'Q1')
    dofhandler = DofHandler(mesh, element)
    dofhandler.distribute_dofs()
    n = dofhandler.n_dofs()
    phi = Basis(dofhandler, 'u')
    phi_x = Basis(dofhandler, 'ux')
    phi_y = Basis(dofhandler, 'uy')
    yd_fn = Explicit(lambda x: np.sin(2*np.pi*x[:,0])*np.sin(2*np.pi*x[:,1]),dim=2)
    g = np.ones((n,1))
    
    #
    # Random diffusion coefficient
    # 
    
    # Sparse grid
    tasmanian_library="/home/hans-werner/bin/TASMANIAN-6.0/libtasmaniansparsegrid.so"
    grid = TasmanianSG.TasmanianSparseGrid(tasmanian_library=tasmanian_library)
    dimensions = 4
    outputs = 1
    depth = 4
    type = 'tensor'
    rule = 'gauss-legendre'
    grid.makeGlobalGrid(dimensions, outputs, depth, type, rule)
    Y = grid.getPoints()
    w = grid.getQuadratureWeights()
    n_samples = grid.getNumPoints()
    
    
    x = dofhandler.get_dof_vertices()
    a_nodal = 1 + 0.1*(np.outer(np.cos(np.pi*x[:,1]),Y[:,0])+\
                       np.outer(np.cos(np.pi*x[:,0]),Y[:,1])+\
                       np.outer(np.sin(2*np.pi*x[:,1]),Y[:,2])+\
                       np.outer(np.sin(2*np.pi*x[:,0]),Y[:,3]))
    a = Nodal(data=a_nodal, dofhandler=dofhandler)
    yd_vec = yd_fn.eval(x)
    
    problems = [[Form(a, test=phi_x, trial=phi_x), 
                Form(a, test=phi_y, trial=phi_y)],
                [Form(1, test=phi, trial=phi)]]
    
    assembler = Assembler(problems, mesh)
    assembler.assemble()
    
    A = assembler.af[0]['bilinear'].get_matrix()
    M = assembler.af[1]['bilinear'].get_matrix()
    
    state = LS(phi)
    state.add_dirichlet_constraint('boundary')
    
    adjoint = LS(phi)
    adjoint.add_dirichlet_constraint('boundary')
    
    tau = 10
    k_max = 20
    alpha = 0.1
    u = np.zeros((n,1))
    norm_dJ_iter = []
    J_iter = []
    u_iter = []
    for k in range(k_max):
        print('iteration', k)
        # 
        # Compute average cost and gradient
        # 
        dJ = np.zeros((n,1))
        J = 0
        print('sampling')
        for n in range(n_samples):
            print(n)
            yn, pn, Jn, dJn = cost_gradient(state,adjoint,A[n],M,
                                            g,u,yd_vec,alpha)
            
            J += w[n]*Jn
            dJ += w[n]*dJn
        print('')
        norm_dJ = np.sqrt(dJ.T.dot(M.dot(dJ)))
        
        #
        # Store current iterates
        # 
        norm_dJ_iter.append(norm_dJ)
        J_iter.append(J)
        u_iter.append(u)
        
        #
        # Check for convergence
        # 
        if norm_dJ<1e-8:
            break
        #
        # Update iterate
        # 
        u -= tau*dJ
Esempio n. 9
0
    u_t - div*(D*grad(u)) + div(v*u) + R(u) = 0
    
subject to the appropriate initial and boundary conditions, using
SUPG and 
 
"""
comment = Verbose()
# Computational mesh
mesh = QuadMesh(box=[0, 10, 0, 10], resolution=(100, 100))
left = mesh.mark_region('left', lambda x, y: abs(x) < 1e-10)

# Finite elements

# Piecewise constants
E0 = QuadFE(mesh.dim(), 'DQ0')
V0 = DofHandler(mesh, E0)
V0.distribute_dofs()

# Piecewise linears
E1 = QuadFE(mesh.dim(), 'Q1')
V1 = DofHandler(mesh, E1)
V1.distribute_dofs()

v = Basis(V1, 'v')
v_x = Basis(V1, 'vx')
v_y = Basis(V1, 'vy')

V1.distribute_dofs()
print(V1.n_dofs())
Esempio n. 10
0
x_max = 2
y_min = 0
y_max = 1

mesh = QuadMesh(box=[x_min, x_max, y_min, y_max], resolution=(20, 10))

# Mark Dirichlet Edges
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 - 2) < 1e-9,
                 entity_type='half_edge')

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

dh_Q0 = DofHandler(mesh, element_Q0)
dh_Q0.distribute_dofs()
n_Q0 = dh_Q0.n_dofs()

dh_Q1 = DofHandler(mesh, element_Q1)
dh_Q1.distribute_dofs()
n_Q1 = dh_Q1.n_dofs()

# Basis functions
phi = Basis(dh_Q1, 'v')
phi_x = Basis(dh_Q1, 'vx')
phi_y = Basis(dh_Q1, 'vy')
Esempio n. 11
0
    def test_integrals_2d(self):
        """
        Test Assembly of some 2D systems
        """
        mesh = QuadMesh(box=[1, 2, 1, 2], resolution=(2, 2))
        mesh.cells.get_leaves()[0].mark(0)
        mesh.cells.refine(refinement_flag=0)

        # Kernel
        kernel = Kernel(Explicit(f=lambda x: x[:, 0] * x[:, 1], dim=2))

        problem = Form(kernel)
        assembler = Assembler(problem, mesh=mesh)
        assembler.assemble()
        self.assertAlmostEqual(assembler.get_scalar(), 9 / 4)

        #
        # Linear forms (x,x) and (x,x') over [1,2]^2 = 7/3, 3/2
        #

        # Elements
        Q1 = QuadFE(mesh.dim(), 'Q1')
        Q2 = QuadFE(mesh.dim(), 'Q2')
        Q3 = QuadFE(mesh.dim(), 'Q3')

        # Dofhandlers
        dQ1 = DofHandler(mesh, Q1)
        dQ2 = DofHandler(mesh, Q2)
        dQ3 = DofHandler(mesh, Q3)

        # Distribute dofs
        [d.distribute_dofs() for d in [dQ1, dQ2, dQ3]]

        for dQ in [dQ1, dQ2, dQ3]:
            # Basis
            phi = Basis(dQ, 'u')
            phi_x = Basis(dQ, 'ux')

            # Kernel function
            xfn = Nodal(f=lambda x: x[:, 0], basis=phi)
            yfn = Nodal(f=lambda x: x[:, 1], basis=phi)

            # Kernel
            kernel = Kernel(xfn)

            # Form
            problem = [[Form(kernel, test=phi)], [Form(kernel, test=phi_x)]]

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

            # Check b^Tx = (x,y)
            b0 = assembler.get_vector(0)
            self.assertAlmostEqual(np.sum(b0 * yfn.data()[:, 0]), 9 / 4)

            b1 = assembler.get_vector(1)
            self.assertAlmostEqual(np.sum(b1 * xfn.data()[:, 0]), 3 / 2)
            self.assertAlmostEqual(np.sum(b1 * yfn.data()[:, 0]), 0)

        #
        # Bilinear forms
        #
        # Compute (1,x,y) = 9/4, or (xy, 1, 1) = 9/4

        for dQ in [dQ1, dQ2, dQ3]:
            # Basis
            phi = Basis(dQ, 'u')
            phi_x = Basis(dQ, 'ux')
            phi_y = Basis(dQ, 'uy')

            # Kernel function
            xyfn = Explicit(f=lambda x: x[:, 0] * x[:, 1], dim=2)
            xfn = Nodal(f=lambda x: x[:, 0], basis=phi)
            yfn = Nodal(f=lambda x: x[:, 1], basis=phi)

            # Form
            problems = [[Form(1, test=phi, trial=phi)],
                        [Form(Kernel(xfn), test=phi, trial=phi_x)],
                        [Form(Kernel(xyfn), test=phi_y, trial=phi_x)]]

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

            x = xfn.data()[:, 0]
            y = yfn.data()[:, 0]
            for i_problem in range(3):
                A = assembler.get_matrix(i_problem)
                self.assertAlmostEqual(y.T.dot(A.dot(x)), 9 / 4)