示例#1
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))
示例#2
0
 def test_is_balanced(self):
     
     mesh_1 = QuadMesh(resolution=(2,2))
     mesh_2 = QuadMesh(resolution=(2,2), periodic={1})
     mesh_3 = QuadMesh(resolution=(2,2), periodic={0,1})
     
     count = 0
     for mesh in [mesh_1, mesh_2, mesh_3]:
         # Initial Meshes should be balanced
         self.assertTrue(mesh.is_balanced())
         
         # Refine mesh and label it
         mesh.cells.get_child(0).mark(1)
         mesh.cells.refine(refinement_flag=1, new_label='b1')
         
         # Check if refined mesh is balanced
         mesh.is_balanced(subforest_flag='b1')
         
         # Now refine again - unbalanced
         mesh.cells.get_child(0).get_child(0).mark(1)
         mesh.cells.refine(refinement_flag=1, subforest_flag='b1', new_label='ub1')
         
         # New mesh should not be balanced
         if count in [0]:
             self.assertTrue(mesh.is_balanced())
             self.assertTrue(mesh.is_balanced(subforest_flag='ub1'))
         else:
             self.assertFalse(mesh.is_balanced(subforest_flag='ub1'))
             self.assertFalse(mesh.is_balanced())
         
         # Old mesh should still be balanced
         self.assertTrue(mesh.is_balanced(subforest_flag='b1'))
         
         count += 1
示例#3
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)
示例#4
0
    def test_set(self):
        mesh = QuadMesh(resolution=(1, 1))
        element = QuadFE(2, 'Q1')
        dofhandler = DofHandler(mesh, element)
        dofhandler.distribute_dofs()
        px = Basis(dofhandler, 'ux')
        p = Basis(dofhandler, 'ux')

        self.assertNotEqual(px, p)
示例#5
0
 def test_get_boundary_segments(self):
     """
     Test 
     """
     #
     # Define Mesh
     # 
     mesh = QuadMesh(resolution=(2,2))
     mesh.record('mesh_1')
     mesh.cells.get_child(2).mark('1')
     mesh.cells.refine(refinement_flag='1') 
     
     #
     # 
     # 
     for segment in mesh.get_boundary_segments(subforest_flag=None):
         for he in segment:
             pass
示例#6
0
 def test_n_dofs(self):
     """
     Check that the total number of dofs is correct
     
     NOTE: A mesh with multiple levels has dofs on coarser levels that may not appear in leaves
     """    
     etypes = ['DQ0', 'DQ1', 'DQ2', 'DQ3', 'Q1', 'Q2', 'Q3']
     #
     # Single cell
     #
     n_dofs = dict.fromkeys([0,1])
     n_dofs[0] = {'DQ0': 1, 'DQ1': 2, 'DQ2': 3, 'DQ3': 4, 'Q1': 2, 'Q2': 3, 'Q3': 4}
     n_dofs[1] = {'DQ0': 1, 'DQ1': 4, 'DQ2': 9, 'DQ3': 16, 'Q1': 4, 'Q2': 9, 'Q3':16}
     for dim in range(2):
         if dim==0:
             mesh = Mesh1D()
         elif dim==1:
             mesh = QuadMesh()
     
         for etype in etypes:
             element = QuadFE(dim+1, etype)
             dofhandler = DofHandler(mesh, element)
             dofhandler.distribute_dofs()
             self.assertEqual(n_dofs[dim][etype], dofhandler.n_dofs())
         
     #
     # Mesh with multiple cells
     #     
     n_dofs = dict.fromkeys([0,1])
     n_dofs[0] = {'DQ0': 2, 'DQ1': 4, 'DQ2': 6, 'DQ3': 8, 'Q1': 3, 'Q2': 5, 'Q3': 7}
     n_dofs[1] = {'DQ0': 4, 'DQ1': 16, 'DQ2': 36, 'DQ3': 64, 'Q1': 9, 'Q2': 25, 'Q3': 49}
     for dim in range(2):
         if dim==0:
             mesh = Mesh1D(resolution=(2,))
         elif dim==1:
             mesh = QuadMesh(resolution=(2,2))
         
         for etype in etypes:
             element = QuadFE(dim+1, etype)
             dofhandler = DofHandler(mesh, element)                
             dofhandler.distribute_dofs()
             self.assertEqual(n_dofs[dim][etype], dofhandler.n_dofs())
示例#7
0
 def test_mark_region(self):
     """
     This is a method in Mesh2D, but 
     """
     #
     # Define Mesh
     # 
     mesh = QuadMesh(resolution=(2,2))
     mesh.cells.get_child(2).mark('1')
     mesh.cells.refine(refinement_flag='1')
     
     #
     # Mark left boundary vertices 
     #  
     f_left = lambda x,dummy: np.abs(x)<1e-9
     mesh.mark_region('left', f_left, on_boundary=True)
     
     #
     # Check that left boundary vertices are the only  
     # 
     count = 0
     for segment in mesh.get_boundary_segments():
         for he in segment:
             # Half-edge should not be marked 
             self.assertFalse(he.is_marked('left'))
             
             # Cell should not be marked
             self.assertFalse(he.cell().is_marked('left'))
             
             for v in he.get_vertices():
                 if f_left(*v.coordinates()):
                     #
                     # Left boundary vertices should be marked
                     # 
                     self.assertTrue(v.is_marked('left'))
                     count += 1
                 else:
                     #
                     # No other boundary vertices should be marked
                     # 
                     self.assertFalse(v.is_marked('left'))
     self.assertEqual(count, 8)
示例#8
0
 def test_get_region(self):
     #
     # Define Mesh
     # 
     mesh = QuadMesh(resolution=(2,2))
     mesh.cells.get_child(2).mark('1')
     mesh.cells.refine(refinement_flag='1')
     
     #
     # Mark left boundary vertices 
     #  
     f_left = lambda x,dummy: np.abs(x)<1e-9
     mesh.mark_region('left', f_left, on_boundary=True)
     
     
     
     
     for v,cell in mesh.get_region('left', entity_type='vertex', 
                                   return_cells=True, on_boundary=True):
         self.assertTrue(v.is_marked('left'))
示例#9
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)
示例#10
0
 def test_balance(self):
     mesh_1 = QuadMesh(resolution=(2,2))
     mesh_2 = QuadMesh(resolution=(2,2), periodic={1})
     mesh_3 = QuadMesh(resolution=(2,2), periodic={0,1})
     
     plot = Plot()
     for mesh in [mesh_1, mesh_2, mesh_3]:
         
         # Refine mesh and label it
         mesh.cells.get_child(0).mark(1)
         mesh.cells.refine(refinement_flag=1, new_label='b1')
         
         # Check if refined mesh is balanced
         mesh.is_balanced(subforest_flag='b1')
         
         # Now refine again - unbalanced
         mesh.cells.get_child(0).get_child(0).mark(1)
         mesh.cells.refine(refinement_flag=1, subforest_flag='b1', new_label='ub1')
         
         #plot.mesh(mesh, mesh_flag='ub1')        
         mesh.balance(subforest_flag='ub1')
示例#11
0
 def test_timings(self):
     """
     """
     comment = Verbose()
     mesh = QuadMesh()
     element = QuadFE(2,'Q1')
     dofhandler = DofHandler(mesh, element)
     for dummy in range(7):
         mesh.cells.refine()
         comment.tic()
         dofhandler.distribute_dofs()
         comment.toc()
         print(dofhandler.n_dofs())
示例#12
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))
示例#13
0
    def test_edge_integrals(self):
        """
        Test computing
        """
        mesh = QuadMesh(resolution=(1, 1))
        Q = QuadFE(2, 'Q1')
        dQ = DofHandler(mesh, Q)
        dQ.distribute_dofs()

        phi = Basis(dQ, 'u')
        f = Nodal(data=np.ones((phi.n_dofs(), 1)), basis=phi)
        kernel = Kernel(f)
        form = Form(kernel, dmu='ds')
        assembler = Assembler(form, mesh)

        cell = mesh.cells.get_leaves()[0]
        shape_info = assembler.shape_info(cell)
        xg, wg, phi, dofs = assembler.shape_eval(cell)
示例#14
0
 def test_distribute_dofs(self):
     show_plots = False
     if show_plots:
         plot = Plot()
        
         #
         # Define QuadMesh with hanging node
         # 
         mesh = QuadMesh(resolution=(1,1), periodic={0,1})        
         mesh.cells.refine()
         mesh.cells.get_child(0).get_child(0).mark(flag=0)                
         mesh.cells.refine(refinement_flag=0) 
         etypes = ['DQ0','DQ1', 'DQ2', 'DQ3', 'Q1', 'Q2', 'Q3'] 
         for etype in etypes:
             # Define new element
             element = QuadFE(2,etype)
     
             # Distribute dofs
             dofhandler = DofHandler(mesh, element)
             dofhandler.distribute_dofs()
 
             plot.mesh(mesh, dofhandler=dofhandler, dofs=True)
示例#15
0
 def test_get_local_dofs(self):
     """
     Extract local dofs from a corner vertex, halfEdge or cell
     """      
     local_dofs = {1: {'DQ0': [[0], [], [0]], 
                       'DQ1': [[0,1], [1], []], 
                       'DQ2': [[0,1,2], [1], [2]],
                       'DQ3': [[0,1,2,3], [1], [2,3]]
                       }, 
                   2: {'DQ0': [[0], [], [], [0]],
                       'DQ1': [[0,1,2,3], [1], [], []],
                       'DQ2': [[0,1,2,3,4,5,6,7,8], [1], [6], [8]],
                       'DQ3': [[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15], [1], [8,9], [12,13,14,15]]
                       }
                   } 
     etypes = ['DQ' + i for i in '0123']        
     for dim in range(1,3):
         if dim==1:
             mesh = Mesh1D(box=[2,4], resolution=(1,))
             cell = mesh.cells.get_child(0)
             vertex  = cell.get_vertex(1)
             entities = [None, vertex, cell]
         elif dim==2:
             mesh = QuadMesh(box = [0,2,0,2], resolution=(2,2))
             cell = mesh.cells.get_child(1)
             vertex = cell.get_vertex(1)
             half_edge = cell.get_half_edge(2)
             entities = [None, vertex, half_edge, cell]
             
         for etype in etypes:
             element = QuadFE(dim, etype)
             dofhandler = DofHandler(mesh, element)
             for i_entity in range(len(entities)):
                 entity = entities[i_entity]
                 dofs = dofhandler.get_cell_dofs(cell, entity=entity,
                                                 doftype='local', interior=True)
                 self.assertEqual(local_dofs[dim][etype][i_entity], dofs)
示例#16
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)
示例#17
0
 def test_bin_points(self):
     # Construct mesh
     mesh = QuadMesh(resolution=(2,2))
     mesh.record(1)
     mesh.cells.get_child(0).mark('refine')
     mesh.cells.refine(refinement_flag='refine')
     
     #
     # Bin random points using the coarsest mesh
     #
     x = np.random.rand(5,2)
     bins = mesh.bin_points(x,subforest_flag=1)
     for cell, dummy in bins:
         self.assertEqual(cell.get_depth(),0)
     
     #
     # x
     # 
     x = np.array([[0.125,0.125]])
     bins = mesh.bin_points(x, subforest_flag=1)
     self.assertEqual(len(bins),1)
     for cell, dummy in bins:
         # Cell should be on level 0
         self.assertEqual(cell.get_depth(),0)
         
     # Bin over all cells
     bins = mesh.bin_points(x)
     self.assertEqual(len(bins),1)
     for cell, dummy in bins:
         # Cell should now be on level  1
         self.assertEqual(cell.get_depth(),1)
     
     # 
     # Out of bounds x
     # 
     x = np.array([[-1,-1]])
     self.assertRaises(Exception, mesh.bin_points, *(x,))
示例#18
0
    def test_set_hanging_nodes(self):
        """
        Check that functions in the finite element space can be interpolated
        by linear combinations of shape functions at supporting nodes.
        
        TODO: Move this test to tests for system
        """        
        #
        # Define QuadMesh with hanging node
        # 
        mesh = QuadMesh(resolution=(1,1))        
        mesh.cells.refine()
        mesh.cells.get_child(0).get_child(0).mark(flag=0)                
        mesh.cells.refine(refinement_flag=0)
        
        c_00 = mesh.cells.get_child(0).get_child(0)
        #
        # Define test functions to interpolate
        # 
        test_functions = {'Q1': lambda x,y: x + y, \
                          'Q2': lambda x,y: x**2 + y**2,\
                          'Q3': lambda x,y: x**3*y + y**2*x**2}
        etypes = ['Q1', 'Q2', 'Q3']
        plot = Plot()
        for etype in etypes:
            #print(etype)
            # Define new element
            element = QuadFE(2,etype)
        
            # Distribute dofs and set vertices
            dofhandler = DofHandler(mesh, element)
            dofhandler.distribute_dofs()
            dofhandler.set_dof_vertices()
            
            # Determine hanging nodes
            dofhandler.set_hanging_nodes()
            hanging_nodes = dofhandler.get_hanging_nodes()
            for dof, support in hanging_nodes.items():
                # Get hanging node vertex
                x_hgnd = dofhandler.get_dof_vertices(dof)

                # Extract support indices and weights
                js, ws = support 
                
                # Extract
                dofs_glb = dofhandler.get_cell_dofs(c_00)
                
                #print(dof, js)
                
                # Local dof numbers for supporting nodes
                dofs_loc_supp = [i for i in range(element.n_dofs()) if dofs_glb[i] in js]
                #x_dofs = c_00.reference_map(element.reference_nodes())
                
                #phi_supp = element.shape(x_hgnd, cell=c_00, local_dofs=dofs_loc_supp)
                #print(phi_supp, js)
                
                # Evaluate test function at hanging node 
                #f_hgnd = test_functions[etype](x_hgnd[0],x_hgnd[1])

                #print('Weighted sum of support function', np.dot(phi_supp,ws))
                
                #print(f_hgnd - np.dot(phi_supp, ws))
                #phi_hgnd = element.shape(x_dofs, cell=c_00, local_dofs=dofs_loc_hgnd)
                
                #print(phi_supp)
                #print(phi_hgnd)
            #plot.mesh(mesh, dofhandler=dofhandler, dofs=True)
            
            # Evaluate 
            c_01 = mesh.cells.get_child(0).get_child(1)
            c_022 = mesh.cells.get_child(0).get_child(2).get_child(2)
            #print(dofhandler.get_global_dofs(c_022))
            x_ref = element.reference_nodes()
            #print(dofhandler.get_global_dofs(c_01))
            #print(dofhandler.get_hanging_nodes())
            x = c_01.reference_map(x_ref)
示例#19
0
 def test_share_dofs_with_children(self):
     #
     # 1D Test
     # 
     mesh = Mesh1D(resolution=(1,))
     mesh.cells.refine()
     for etype in ['DQ0','DQ1', 'DQ2', 'DQ3', 'Q1', 'Q2', 'Q3']:
         # New DofHandler
         element = QuadFE(1, etype)
         dh = DofHandler(mesh, element)
         
         # Fill in parent dofs and share with children
         cell = mesh.cells.get_child(0)
         dh.fill_dofs(cell)
         dh.share_dofs_with_children(cell)
         
         # Expected dofs for children
         left_child_dofs = {'DQ0': [None], 
                            'DQ1': [0, None], 
                            'DQ2': [0, 2, None], 
                            'DQ3': [0, None, None, 2], 
                            'Q1': [0, None], 
                            'Q2': [0, 2, None], 
                            'Q3': [0, None, None, 2]}
         right_child_dofs = {'DQ0': [None],
                             'DQ1': [None, 1],
                             'DQ2': [None, 1, None],
                             'DQ3': [None, 1, 3, None], 
                             'Q1':[None, 1], 
                             'Q2': [2, 1, None],
                             'Q3': [None, 1, 3, None]}
         left_child = cell.get_child(0)
         right_child = cell.get_child(1)
         #
         # Check whether shared dofs are as expected.
         # 
         self.assertEqual(dh.get_cell_dofs(left_child), left_child_dofs[etype])
         self.assertEqual(dh.get_cell_dofs(right_child), right_child_dofs[etype])
     #
     # 2D Test
     # 
     mesh = QuadMesh(resolution=(1,1))
     mesh.cells.refine()
     for etype in ['DQ0','DQ1', 'DQ2', 'DQ3', 'Q1', 'Q2', 'Q3']:
         
         # New dofhandler
         element = QuadFE(2, etype)
         dh = DofHandler(mesh, element)
         
         # Fill in parent dofs and share with children
         cell = mesh.cells.get_child(0)
         dh.fill_dofs(cell)
         dh.share_dofs_with_children(cell)
         
         # Expected dofs for children
         child_dofs = {0: {'DQ0': [None], 
                            'DQ1': [0, None, None, None], 
                            'DQ2': [0, 4, 8, 7, None, None, None, None, None], 
                            'DQ3': [0, None, None, None, None, 4, None, None, 
                                    None, None, 11, None, None, None, None, 12], 
                            'Q1': [0, None, None, None], 
                            'Q2': [0, 4, 8, 7, None, None, None, None, None], 
                            'Q3': [0, None, None, None, None, 4, None, None, 
                                   None, None, 11, None, None, None, None, 12]}, 
                       1: {'DQ0': [None], 
                            'DQ1': [None, 1, None, None], 
                            'DQ2': [None, 1, 5, None, None, None, None, None, None], 
                            'DQ3': [None, 1, None, None, 5, None, None, 6, 
                                    None, None, None, None, None, None, 13, None], 
                            'Q1': [None, 1, None, None], 
                            'Q2': [4, 1, 5, 8, None, None, None, None, None], 
                            'Q3': [None, 1, None, None, 5, None, None, 6, 
                                   None, None, None, None, None, None, 13, None]},
                       2: {'DQ0': [None], 
                            'DQ1': [None, None, 2, None], 
                            'DQ2': [None, None, 2, 6, None, None, None, None, None], 
                            'DQ3': [None, None, 2, None, None, None, 7, None, 
                                    None, 8, None, None, 15, None, None, None], 
                            'Q1': [None, None, 2, None], 
                            'Q2': [8, 5, 2, 6, None, None, None, None, None], 
                            'Q3': [None, None, 2, None, None, None, 7, None, 
                                    None, 8, None, None, 15, None, None, None]},
                       3: {'DQ0': [None], 
                            'DQ1': [None, None, None, 3], 
                            'DQ2': [None, None, None, 3, None, None, None, None, None], 
                            'DQ3': [None, None, None, 3, None, None, None, 
                                    None, 9, None, None, 10, None, 14, None, None], 
                            'Q1': [None, None, None, 3], 
                            'Q2': [7, 8, 6, 3, None, None, None, None, None], 
                            'Q3': [None, None, None, 3, None, None, None, 
                                    None, 9, None, None, 10, None, 14, None, None]}}
         for i in range(4):
             child = cell.get_child(i)
             #
             # Check whether shared dofs are as expected
             # 
             self.assertEqual(dh.get_cell_dofs(child), child_dofs[i][etype])
示例#20
0
# 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)]:
    #
    # Define new mesh
    #
    mesh = QuadMesh(resolution=resolution)

    errors[resolution] = {}
    for eps in [1, 1e-3, 1e-6]:

        errors[resolution][eps] = {}

        for etype in ['Q1', 'Q2']:
            #
            # Define element
            #
            element = QuadFE(2, etype)
            dofhandler = DofHandler(mesh, element)
            dofhandler.distribute_dofs()
            #
            # Define Basis Functions
示例#21
0
    def test_eval_x(self):
        #
        # Evaluate Nodal function at a given set of x-values
        #

        # Meshes and elements
        meshes = {1: Mesh1D(resolution=(2, )), 2: QuadMesh(resolution=(2, 1))}
        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: [{}, {}]}}

        n_points = 1
        for dim in [1, 2]:
            mesh = meshes[dim]
            element = elements[dim]
            dofhandler = DofHandler(mesh, element)
            dofhandler.distribute_dofs()
            #dofhandler.get_region_dofs()
            basis = Basis(dofhandler)
            #
            # Define random points in domain
            #
            if dim == 1:
                x_min, x_max = mesh.bounding_box()

                x = x_min + 0.5 * (x_max - x_min) * np.random.rand(n_points)
                x = x[:, np.newaxis]

                y = x_min + (x_max - x_min) * np.random.rand(n_points)
                y = y[:, np.newaxis]
            elif dim == 2:
                x_min, x_max, y_min, y_max = mesh.bounding_box()

                x = np.zeros((n_points, 2))
                x[:, 0] = x_min + (x_max - x_min) * np.random.rand(n_points)
                x[:, 1] = y_min + (y_max - y_min) * np.random.rand(n_points)

                y = np.zeros((n_points, 2))
                y[:, 0] = x_min + (x_max - x_min) * np.random.rand(n_points)
                y[:, 1] = y_min + (y_max - y_min) * np.random.rand(n_points)

            for n_variables in [1, 2]:
                fn = fns[dim][n_variables]
                parm = parms[dim][n_variables]
                #
                # Deterministic
                #
                f = Nodal(f=fn,
                          basis=basis,
                          mesh=mesh,
                          element=element,
                          dim=dim,
                          n_variables=n_variables)

                if n_variables == 1:
                    xx = x
                    fe = fn(x)
                elif n_variables == 2:
                    xx = (x, y)
                    fe = fn(*xx)
                fx = f.eval(x=xx)
                self.assertTrue(np.allclose(fx, fe))

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

                fx = f.eval(x=xx)
                self.assertTrue(np.allclose(fx[:, 0], fe))
                self.assertTrue(np.allclose(fx[:, 1], fe))
示例#22
0
from fem import DofHandler
from fem import QuadFE
from fem import Basis
from function import Explicit
from mesh import Mesh1D
from mesh import QuadMesh
from mesh import Vertex
from mesh import HalfEdge
from solver import LinearSystem as LS
from plot import Plot
import numpy as np

# =============================================================================
# Computational mesh
# =============================================================================
mesh = QuadMesh(box=[-0.5, 0.5, -0.5, 0.5], resolution=(20, 20))

# Mark slit region
slit = HalfEdge(Vertex((0, 0)), Vertex((0, -0.5)))
sf = lambda x, y: slit.contains_points(np.array([x, y]))[0]
mesh.mark_region('slit', sf, entity_type='half_edge')

# Mark perimeter
tol = 1e-9
pf = lambda x,y: np.abs(x+0.5)<tol or np.abs(x-0.5)<tol or \
                 np.abs(y+0.5)<tol or np.abs(y-0.5)<tol
mesh.mark_region('perimeter', pf, entity_type='half_edge')

# Get rid of neighbors of half-edges on slit
for he in mesh.half_edges.get_leaves('slit'):
    if he.unit_normal()[0] < 0:
示例#23
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)
示例#24
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()))
示例#25
0
from diagnostics import Verbose

# Built-in modules
import numpy as np
import scipy.linalg as la
import matplotlib.pyplot as plt
"""
Investigate local error estimates on the resolution of a random field
"""

plot = Plot()

#
# Computational mesh
#
mesh = QuadMesh(resolution=(4, 4))

# Mark boundary
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')])
示例#26
0
    def test_derivative(self):
        """
        Compute the derivatives of a Nodal Map
        """
        # Define meshes for each dimension
        meshes = {1: Mesh1D(resolution=(2, )), 2: QuadMesh(resolution=(2, 2))}

        # Define elements for each dimension
        elements = {1: QuadFE(1, 'Q2'), 2: QuadFE(2, 'Q2')}

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

        derivatives = {1: [(1, 0), (2, 0)], 2: [(1, 0), (1, 1), (2, 0, 0)]}

        dfdx_exact = {
            1:
            [lambda x: 4 * x[:, 0][:, None], lambda x: 4 * np.ones(x.shape)],
            2: [
                lambda x: 2 * x[:, 0][:, None], lambda x: np.ones(x.shape),
                lambda x: 2 * np.ones(x.shape)
            ]
        }

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

        for dim in [1, 2]:
            mesh = meshes[dim]

            # Random points in domain
            n_points = 5
            if dim == 1:
                x_min, x_max = mesh.bounding_box()
                x = x_min + 0.5 * (x_max - x_min) * np.random.rand(n_points)
                x = x[:, np.newaxis]
            elif dim == 2:
                x_min, x_max, y_min, y_max = mesh.bounding_box()
                x = np.zeros((n_points, 2))
                x[:, 0] = x_min + (x_max - x_min) * np.random.rand(n_points)
                x[:, 1] = y_min + (y_max - y_min) * np.random.rand(n_points)

            element = elements[dim]
            fn = fns[dim]
            dofhandler = DofHandler(mesh, element)
            dofhandler.distribute_dofs()
            basis = Basis(dofhandler)
            #
            # Deterministic
            #
            f = Nodal(f=fn,
                      basis=basis,
                      mesh=mesh,
                      element=element,
                      dim=dim,
                      n_variables=1)

            count = 0
            for derivative in derivatives[dim]:
                # Evaluate the derivative
                dfdx = f.differentiate(derivative)
                self.assertTrue(
                    np.allclose(dfdx.eval(x=x), dfdx_exact[dim][count](x)))
                count += 1
            #
            # Sampled
            #
            parm = parms[dim]
            f = Nodal(f=fn,
                      parameters=parm,
                      basis=basis,
                      mesh=mesh,
                      element=element,
                      dim=dim)
            count = 0
            for derivative in derivatives[dim]:
                # Evaluate the derivative
                dfdx = f.differentiate(derivative)

                self.assertTrue(
                    np.allclose(
                        dfdx.eval(x=x)[:, 0], dfdx_exact[dim][count](x)[:, 0]))
                self.assertTrue(
                    np.allclose(
                        dfdx.eval(x=x)[:, 1], dfdx_exact[dim][count](x)[:, 0]))
                count += 1
示例#27
0
 def test_get_region_dofs(self):
     """
     Test the function for returning the dofs associated with a region.
     """   
     # 
     # 2D
     #
     mesh = QuadMesh()
     for etype in ['Q1','Q2','Q3']:
         element = QuadFE(2, etype)
         dofhandler = DofHandler(mesh, element)
         dofhandler.distribute_dofs()
         
         # 
         # Mark half-edges 
         #  
         bnd_right = lambda x,dummy: np.abs(x-1)<1e-9
         mesh.mark_region('right', bnd_right, \
                          entity_type='half_edge', \
                          on_boundary=True)
         
         # Check that mesh.mark_region is doing the right thing. 
         cell = mesh.cells.get_child(0)
         marked_edge = False
         for he in cell.get_half_edges():
             if he.is_marked('right'):
                 #
                 # All vertices should be on the boundary
                 # 
                 marked_edge = True
                 for v in he.get_vertices():
                     x,y = v.coordinates()
                 self.assertTrue(bnd_right(x,y))
             else:
                 #
                 # Not all vertices on should be on the boundary
                 # 
                 on_right = True
                 for v in he.get_vertices():
                     x,y = v.coordinates()
                     if not bnd_right(x,y):
                         on_right = False
                 self.assertFalse(on_right)
         #
         # Some half-edge should be marked
         # 
         self.assertTrue(marked_edge)
         
         #
         # Check that we get the right number of dofs
         #
         n_dofs = {True: {'Q1': 0, 'Q2': 1, 'Q3': 2}, 
                   False: {'Q1': 2, 'Q2': 3, 'Q3': 4}}
         for interior in [True, False]:
             dofs = dofhandler.get_region_dofs(entity_type='half_edge', \
                                               entity_flag='right', \
                                               interior=interior, \
                                               on_boundary=True)
             #
             # Check that we get the right number of dofs
             # 
             self.assertEqual(len(dofs), n_dofs[interior][etype])
示例#28
0
from fem import QuadFE
from fem import DofHandler
from fem import Form
from fem import Basis
from fem import Kernel
from fem import GaussRule
from fem import Assembler
from fem import Function
from plot import Plot
from scipy import sparse as sp
import numpy as np

#
# Define Mesh
# 
mesh = QuadMesh(resolution=(2,1))
mesh.cells.get_child(1).mark('1')
mesh.cells.refine(refinement_flag='1')


#
# Define element
# 
Q1 = QuadFE(2,'Q1')

#
# Basis Functions 
#
u = Basis(Q1, 'u')
ux = Basis(Q1, 'ux')
uy = Basis(Q1, 'uy')
示例#29
0
Created on Mon Apr  4 16:17:45 2022

@author: hans-werner
"""

from mesh import QuadMesh
from fem import DofHandler, Basis, QuadFE
from function import Nodal
from gmrf import GaussianField, SPDMatrix, Covariance
from plot import Plot
from assembler import Assembler, Form, Kernel
import numpy as np

# Computational mesh
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')
示例#30
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)