예제 #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 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))
예제 #3
0
    def test_constructor(self):
        """
        Test initialization
        """
        f = Explicit(lambda x, a: a * x**2,
                     parameters={'a': 1},
                     dim=1,
                     n_variables=1)
        f.eval(1)
        self.assertAlmostEqual(f.eval(1), 1)

        #
        # Errors
        #
        self.assertRaises(Exception, Explicit)
예제 #4
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()))
예제 #5
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)
예제 #6
0
    def test_add_rules(self):
        # Define explicit function
        rule = lambda x, a: a * x**2
        parameters = [{'a': 1}, {'a': 2}]
        f = Explicit(rule, parameters=parameters, dim=1)

        # Raises an error attempt to add multiple functions
        self.assertRaises(Exception, f.add_rule, *(lambda x: x, ),
                          **{'parameters': [{}, {}]})

        # Add a single rule and evaluate at a point
        f.add_rule(lambda x: x)
        x = 2
        vals = [4, 8, 2]

        for i in range(3):

            #(*(x,),**{'a':1}))
            self.assertEqual(f.eval(x)[0, i], vals[i])
예제 #7
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))
예제 #8
0
    def test_set_rules(self):

        #
        # Errors
        #

        # Number of parameter dicts differs from number of rules
        flist = [lambda x, a: a * x**2, lambda x: x]
        plist = [{}, {}, {}]
        self.assertRaises(Exception, Explicit, *(flist, ), **{
            'parameters': plist,
            'dim': 1
        })

        # Specify that function is symmetric, but n_variables=1
        f = lambda x: x
        self.assertRaises(Exception, Explicit, *(f, ), **{'symmetric': True})

        #
        # Expected
        #

        # Only one set of parameters multiple functions
        f = Explicit(flist, parameters={}, dim=1)
        self.assertEqual(len(f.parameters()), 2)

        # Only one function multiple parameters
        rule = lambda x, a: a * x**2
        parameters = [{'a': 1}, {'a': 2}]
        f = Explicit(rule, parameters=parameters, dim=1)
        self.assertEqual(len(f.rules()), 2)
예제 #9
0
    def test_set_parameters(self):
        # Define explicit function
        rule = lambda x, a: a * x[:, 0] - x[:, 1]
        parms = [{'a': 1}, {'a': 2}]
        f = Explicit(rule, parameters=parms, dim=2)

        x = (1, 2)
        self.assertTrue(np.allclose(f.eval(x), np.array([-1, 0])))

        # Modify parameter
        f.set_parameters({'a': 2}, pos=0)
        self.assertTrue(np.allclose(f.eval(x), np.array([0, 0])))
예제 #10
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))
예제 #11
0
    def test_subsample_deterministic(self):
        """
        When evaluating a deterministic function while specifying a subsample,
        n_subsample copies of the function output should be returned.        
        """
        #
        # Deterministic functions
        #

        # Functions
        fns = {
            1: {
                1: lambda x: x[:, 0]**2,
                2: lambda x, y: x[:, 0] + y[:, 0]
            },
            2: {
                1: lambda x: x[:, 0]**2 + x[:, 1]**2,
                2: lambda x, y: x[:, 0] * y[:, 0] + x[:, 1] * y[:, 1]
            }
        }

        # Singletons
        x = {1: {1: 2, 2: (3, 4)}, 2: {1: (1, 2), 2: ((1, 2), (3, 4))}}

        xv = {
            1: {
                1: [(2, ), (2, )],
                2: ([(3, ), (3, )], [(4, ), (4, )])
            },
            2: {
                1: [(1, 2), (1, 2)],
                2: ([(1, 2), (1, 2)], [(3, 4), (3, 4)])
            }
        }

        vals = {1: {1: 4, 2: 7}, 2: {1: 5, 2: 11}}
        subsample = np.array([2, 3], dtype=np.int)

        for dim in [1, 2]:
            #
            # Iterate over dimension
            #

            # DofHandler
            if dim == 1:
                mesh = Mesh1D(box=[0, 5], resolution=(1, ))
            elif dim == 2:
                mesh = QuadMesh(box=[0, 5, 0, 5])
            element = QuadFE(dim, 'Q2')
            dofhandler = DofHandler(mesh, element)
            dofhandler.distribute_dofs()
            basis = Basis(dofhandler)
            for n_variables in [1, 2]:
                #
                # Iterate over number of variables
                #

                #
                # Explicit
                #
                f = fns[dim][n_variables]

                # Explicit
                fe = Explicit(f, n_variables=n_variables, dim=dim, \
                             subsample=subsample)

                # Nodal
                fn = Nodal(f, n_variables=n_variables, basis=basis, dim=dim, \
                           dofhandler=dofhandler, subsample=subsample)

                # Constant
                fc = Constant(1, n_variables=n_variables, \
                              subsample=subsample)

                # Singleton input
                xn = x[dim][n_variables]

                # Explicit
                self.assertEqual(fe.eval(xn).shape[1], len(subsample))
                self.assertEqual(fe.eval(xn)[0, 0], vals[dim][n_variables])
                self.assertEqual(fe.eval(xn)[0, 1], vals[dim][n_variables])

                # Nodal
                self.assertEqual(fn.eval(xn).shape[1], len(subsample))
                self.assertAlmostEqual(
                    fn.eval(xn)[0, 0], vals[dim][n_variables])
                self.assertAlmostEqual(
                    fn.eval(xn)[0, 1], vals[dim][n_variables])

                # Constant
                self.assertEqual(fc.eval(xn).shape[1], len(subsample))
                self.assertAlmostEqual(fc.eval(xn)[0, 0], 1)
                self.assertAlmostEqual(fc.eval(xn)[0, 1], 1)

                # Vector input
                xn = xv[dim][n_variables]
                n_points = 2

                # Explicit
                self.assertEqual(fe.eval(xn).shape, (2, 2))
                for i in range(fe.n_subsample()):
                    for j in range(n_points):
                        self.assertEqual(
                            fe.eval(xn)[i][j], vals[dim][n_variables])

                # Nodal
                self.assertEqual(fn.eval(xn).shape, (2, 2))
                for i in range(fe.n_subsample()):
                    for j in range(n_points):
                        self.assertAlmostEqual(
                            fn.eval(xn)[i][j], vals[dim][n_variables])

                # Constant
                self.assertEqual(fc.eval(xn).shape, (2, 2))
                for i in range(fe.n_subsample()):
                    for j in range(n_points):
                        self.assertEqual(fc.eval(xn)[i][j], 1)
예제 #12
0
    def test_eval(self):

        #
        # Evaluate single univariate/bivariate functions in 1 or 2 dimensions
        #
        fns = {
            1: {
                1: lambda x: x**2,
                2: lambda x, y: x + y
            },
            2: {
                1: lambda x: x[:, 0]**2 + x[:, 1]**2,
                2: lambda x, y: x[:, 0] * y[:, 0] + x[:, 1] * y[:, 1]
            }
        }

        # Singletons
        x = {1: {1: 2, 2: (3, 4)}, 2: {1: (1, 2), 2: ((1, 2), (3, 4))}}

        vals = {1: {1: 4, 2: 7}, 2: {1: 5, 2: 11}}

        for dim in [1, 2]:
            #
            # Iterate over dimension
            #
            for n_variables in [1, 2]:
                #
                # Iterate over number of variables
                #
                fn = fns[dim][n_variables]
                f = Explicit(fn, n_variables=n_variables, dim=dim)

                xn = x[dim][n_variables]
                self.assertEqual(f.eval(xn), vals[dim][n_variables])

        #
        # Evaluate sampled functions
        #
        fns = {
            1: {
                1: lambda x, a: a * x**2,
                2: lambda x, y, a: a * (x + y)
            },
            2: {
                1: lambda x, a: a * (x[:, 0]**2 + x[:, 1]**2),
                2: lambda x, y, a: a * (x[:, 0] * y[:, 0] + x[:, 1] * y[:, 1])
            }
        }

        pars = [{'a': 1}, {'a': 2}]

        #
        # Singletons
        #
        x = {1: {1: 2, 2: (3, 4)}, 2: {1: (1, 2), 2: ((1, 2), (3, 4))}}

        vals = {1: {1: 4, 2: 7}, 2: {1: 5, 2: 11}}

        for dim in [1, 2]:
            #
            # Iterate over dimension
            #
            for n_variables in [1, 2]:
                #
                # Iterate over number of variables
                #
                fn = fns[dim][n_variables]
                f = Explicit(fn,
                             parameters=pars,
                             n_variables=n_variables,
                             dim=dim)

                xn = x[dim][n_variables]
                self.assertEqual(f.eval(xn)[0][0], vals[dim][n_variables])
                self.assertEqual(f.eval(xn)[0][1], 2 * vals[dim][n_variables])

        #
        # 2 points
        #
        n_points = 2
        x = {
            1: {
                1: [(2, ), (2, )],
                2: ([(3, ), (3, )], [(4, ), (4, )])
            },
            2: {
                1: [(1, 2), (1, 2)],
                2: ([(1, 2), (1, 2)], [(3, 4), (3, 4)])
            }
        }
        for dim in [1, 2]:
            #
            # Iterate over dimension
            #
            for n_variables in [1, 2]:
                #
                # Iterate over number of variables
                #
                fn = fns[dim][n_variables]
                f = Explicit(fn,
                             parameters=pars,
                             n_variables=n_variables,
                             dim=dim)

                xn = x[dim][n_variables]
                self.assertEqual(f.eval(xn).shape[0], n_points)
                self.assertEqual(f.eval(xn).shape[1], f.n_samples())

                for i in range(f.n_samples()):
                    for j in range(2):
                        val = pars[i]['a'] * vals[dim][n_variables]
                        self.assertEqual(f.eval(xn)[j, i], val)
예제 #13
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)
예제 #14
0
from mesh import QuadMesh, Mesh1D
from plot import Plot
from fem import QuadFE, DofHandler
from function import Explicit
import numpy as np

plot = Plot()
mesh = Mesh1D()
Q0 = QuadFE(1, 'DQ0')
dh0 = DofHandler(mesh, Q0)
n_levels = 10

for l in range(n_levels):
    mesh.cells.refine(new_label=l)
    dh0.distribute_dofs(subforest_flag=l)

f = Explicit(lambda x: np.abs(x - 0.5), dim=1)
fQ = f.interpolant(dh0, subforest_flag=3)

plot.line(fQ, mesh)
plot.mesh(mesh, dofhandler=dh0, subforest_flag=0)

mesh = QuadMesh(resolution=(10, 10))
plot.mesh(mesh)
예제 #15
0
파일: timing.py 프로젝트: hvanwyk/quadmesh
dofhandler = DofHandler(mesh, element)

comment.tic('distribute dofs')
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 = [
예제 #16
0
        he.mark('B')
mesh.tear_region('B')

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

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

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

uB = Explicit(f=lambda x: np.cos(2 * np.pi * (x[:, 1] + 0.25)), dim=2)
problem = [
    Form(epsilon, trial=ux, test=ux),
    Form(epsilon, trial=uy, test=uy),
    Form(vx, trial=ux, test=u),
    Form(vy, trial=uy, test=u),
    Form(0, test=u)
]

print('assembling', end=' ')
assembler = Assembler(problem, mesh)
assembler.assemble()
print('done')
예제 #17
0
    def test_integrals_1d(self):
        """
        Test system assembly
        """
        #
        # Constant form
        #

        # Mesh
        mesh = Mesh1D(box=[1, 2], resolution=(1, ))

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

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

        #
        # Linear forms (x,x) and (x,x') over [1,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)

            # 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,x)
            b0 = assembler.get_vector(0)
            self.assertAlmostEqual(np.sum(b0 * xfn.data()[:, 0]), 7 / 3)

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

        #
        # Bilinear forms
        #
        # Compute (1,x,x) = 7/3, or (x^2, 1, 1) = 7/3

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

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

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

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

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

        # ======================================================================
        # Test 1: Assemble simple bilinear form (u,v) on Mesh1D
        # ======================================================================
        # Mesh
        mesh = Mesh1D(resolution=(1, ))
        Q1 = QuadFE(mesh.dim(), 'Q1')
        Q2 = QuadFE(mesh.dim(), 'Q2')
        Q3 = QuadFE(mesh.dim(), 'Q3')

        # Test and trial functions
        dhQ1 = DofHandler(mesh, QuadFE(1, 'Q1'))
        dhQ1.distribute_dofs()

        u = Basis(dhQ1, 'u')
        v = Basis(dhQ1, 'v')

        # Form
        form = Form(trial=u, test=v)

        # Define system
        system = Assembler(form, mesh)

        # Get local information
        cell = mesh.cells.get_child(0)
        si = system.shape_info(cell)

        # Compute local Gauss nodes
        xg, wg, phi, dofs = system.shape_eval(cell)
        self.assertTrue(cell in xg)
        self.assertTrue(cell in wg)

        # Compute local shape functions
        self.assertTrue(cell in phi)
        self.assertTrue(u in phi[cell])
        self.assertTrue(v in phi[cell])
        self.assertTrue(u in dofs[cell])

        # Assemble system
        system.assemble()

        # Extract system bilinear form
        A = system.get_matrix()

        # Use bilinear form to integrate x^2 over [0,1]
        f = Nodal(lambda x: x, basis=u)
        fv = f.data()[:, 0]
        self.assertAlmostEqual(np.sum(fv * A.dot(fv)), 1 / 3)

        # ======================================================================
        # Test 3: Constant form (x^2,.,.) over 1D mesh
        # ======================================================================

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

        # Nodal kernel function
        Q2 = QuadFE(1, 'Q2')
        dhQ2 = DofHandler(mesh, Q2)
        dhQ2.distribute_dofs()
        phiQ2 = Basis(dhQ2)

        f = Nodal(lambda x: x**2, basis=phiQ2)
        kernel = Kernel(f=f)

        # Form
        form = Form(kernel=kernel)

        # Generate and assemble the system
        system = Assembler(form, mesh)
        system.assemble()

        # Check
        self.assertAlmostEqual(system.get_scalar(), 1 / 3)

        # =====================================================================
        # Test 4: Periodic Mesh
        # =====================================================================
        #
        # TODO: NO checks yet
        #

        mesh = Mesh1D(resolution=(2, ), periodic=True)

        #
        Q1 = QuadFE(1, 'Q1')
        dhQ1 = DofHandler(mesh, Q1)
        dhQ1.distribute_dofs()
        u = Basis(dhQ1, 'u')

        form = Form(trial=u, test=u)

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

        # =====================================================================
        # Test 5: Assemble simple sampled form
        # ======================================================================
        mesh = Mesh1D(resolution=(3, ))

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

        xv = dofhandler.get_dof_vertices()
        n_points = dofhandler.n_dofs()

        n_samples = 6
        a = np.arange(n_samples)

        f = lambda x, a: a * x

        fdata = np.zeros((n_points, n_samples))
        for i in range(n_samples):
            fdata[:, i] = f(xv, a[i]).ravel()

        # Define sampled function
        fn = Nodal(data=fdata, basis=phi)
        kernel = Kernel(fn)
        #
        # Integrate I[0,1] ax^2 dx by using the linear form (ax,x)
        #
        v = Basis(dofhandler, 'v')
        form = Form(kernel=kernel, test=v)
        system = Assembler(form, mesh)
        system.assemble()

        one = np.ones(n_points)
        for i in range(n_samples):
            b = system.get_vector(i_sample=i)
            self.assertAlmostEqual(one.dot(b), 0.5 * a[i])

        #
        # Integrate I[0,1] ax^4 dx using bilinear form (ax, x^2, x)
        #
        Q2 = QuadFE(1, 'Q2')
        dhQ2 = DofHandler(mesh, Q2)
        dhQ2.distribute_dofs()
        u = Basis(dhQ2, 'u')

        # Define form
        form = Form(kernel=kernel, test=v, trial=u)

        # Define and assemble system
        system = Assembler(form, mesh)
        system.assemble()

        # Express x^2 in terms of trial function basis
        dhQ2.distribute_dofs()
        xvQ2 = dhQ2.get_dof_vertices()
        xv_squared = xvQ2**2

        for i in range(n_samples):
            #
            # Iterate over samples
            #

            # Form sparse matrix
            A = system.get_matrix(i_sample=i)

            # Evaluate the integral
            I = np.sum(xv * A.dot(xv_squared))

            # Compare with expected result
            self.assertAlmostEqual(I, 0.2 * a[i])

        # =====================================================================
        # Test 6: Working with submeshes
        # =====================================================================
        mesh = Mesh1D(resolution=(2, ))
예제 #18
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)
예제 #19
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
예제 #20
0
# -----------------------------------------------------------------------------
# Observations
# ----------------------------------------------------------------------------- 
# Determine vertices corresponding to production wells
n_prod = 4
h = (x_max-x_min)/(n_prod+2)
x_prod = np.array([(i+1)*h for i in range(n_prod)])
v = dh_y.get_dof_vertices()
dofs_prod = []
for x in x_prod:
    dofs_prod.append(np.argmin(abs(v-x)))
#   
# Target pressure at production wells
#
z_fn = Explicit(f=lambda x: 3-4*(x[:,0]-1)**2, dim=1, mesh=mesh)
z_data = z_fn.eval(v[dofs_prod])

# -----------------------------------------------------------------------------
# Control
# -----------------------------------------------------------------------------
# Determine the vertices corresponding to the injection wells
n_inj = 6
h = (x_max-x_min)/(n_inj+2)
x_inj = np.array([(i+1)*h for i in range(n_inj)])
dofs_inj = []
for x in x_inj:
    dofs_inj.append(np.argmin(abs(v-x)))
 
u_data = np.zeros((ny,1))
u_data[dofs_inj] = 1
예제 #21
0
xy = np.array([X.ravel(), Y.ravel()]).T
cells_production = mesh.bin_points(xy)

# Mark vertices
for cell, dummy in cells_production:
    cell.get_vertex(2).mark('production')

# Extract degrees of freedom
production_dofs = dh_Q1.get_region_dofs(entity_type='vertex',
                                        entity_flag='production')

v_production = dh_Q1.get_dof_vertices(dofs=production_dofs)

# Target pressure at production wells
z_fn = Explicit(f=lambda x: 3 - 4 * (x[:, 0] - 1)**2 - 8 * (x[:, 1] - 0.5)**2,
                dim=2,
                mesh=mesh)
y_target = z_fn.eval(v_production)

#
# Locations of injection wells
#
n_injection = (5, 4)  # resolution
x_injection = np.linspace(0.5, 1.5, n_injection[0])
y_injection = np.linspace(0.25, 0.75, n_injection[1])
X, Y = np.meshgrid(x_injection, y_injection)
xy = np.array([X.ravel(), Y.ravel()]).T
cells_injection = mesh.bin_points(xy)

# Mark vertices
for cell, dummy in cells_injection:
예제 #22
0
nt = np.int((t1 - t0) / dt)

# Initial condition
u0 = Constant(0)


# Left Dirichlet condition
def u_left(x):
    n_points = x.shape[0]
    u = np.zeros((n_points, 1))
    left_strip = (x[:, 0] >= 4) * (x[:, 0] <= 6) * (abs(x[:, 1]) < 1e-9)
    u[left_strip, 0] = 1
    return u


u_left = Explicit(f=u_left, mesh=mesh)

# Define problems
Dx = 1
Dy = 0.1 * Dx

Form(1, trial=v, test=v)

k_max = 1
up = Nodal(f=lambda x: x[:, 1]**2, dofhandler=V1)
um = Nodal(f=lambda x: x[:, 0], dofhandler=V1)
residual = [Form(1, test=v)]
"""
residual = [Form(Kernel(f=up),test=v),
            Form(Kernel(f=um), test=v),
            Form(Kernel(f=up),test=v_x)]
예제 #23
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()))
예제 #24
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())
예제 #25
0
import numpy as np
import matplotlib.pyplot as plt
"""
Error analysis for advection diffusion equation

 -epsilon*(d^2u_dx^2 + d^2u_dy^2) + vx*du_dx + vy*du_dy = f 

subject to dirichlet boundary conditions.
"""
#
# Define functions
#

# Exact solution
ue = Explicit(f=lambda x: np.sin(x[:, 0]) * np.sin(x[:, 1]),
              n_variables=1,
              dim=2)

# Forcing function
ffn = lambda x: 2*eps*np.sin(x[:,0])*np.sin(x[:,1]) + \
                    x[:,0]*np.cos(x[:,0])*np.sin(x[:,1]) + \
                    x[:,1]*np.sin(x[:,0])*np.cos(x[:,1])
f = Explicit(ffn, dim=2)

# Velocity function
vx = Explicit(lambda x: x[:, 0], dim=2)
vy = Explicit(lambda x: x[:, 1], dim=2)

errors = {}
for resolution in [(5, 5), (10, 10), (20, 20), (40, 40)]:
    #
예제 #26
0
파일: bc_ex01.py 프로젝트: hvanwyk/quadmesh
Q1 = QuadFE(2,'Q1')  # element for pressure
Q2 = QuadFE(2,'Q2')  # element for velocity

# Dofhandler
DQ1 = DofHandler(mesh, Q1)
DQ2 = DofHandler(mesh, Q2)

# Time discretization
T = 1
nt = 101
t = np.linspace(0,T,nt)


# Problem Parameters
g = 10
gma = 0.1
U = 0.1
tht = 1
nu = Explicit(f=lambda x: np.sin(x[:,0])**2+1, dim=2)

# Explicit solution 
u1 = Explicit(f=lambda x,t: t[:,0]**3*np.sin(np.pi*x[:,0])*np.sin(np.pi*x[:,1]),\
              dim=2, n_variables=2)

#
# Iterate over time ss
#
u = np.empty()
for i in range(nt):
    
    pass