# # Locations of production wells (measurements) # n_production = (4, 3) # resolution x_production = np.linspace(0.5, 1.5, n_production[0]) y_production = np.linspace(0.2, 0.8, n_production[1]) X, Y = np.meshgrid(x_production, y_production) 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])
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])
# ============================================================================= M = assembler.af[1]['bilinear'].get_matrix() y_train = y_data[:, i_train] y_test = y_data[:, i_test] U, S, Vt = la.svd(y_train) x = dofhandler.get_dof_vertices() m = 8 d = 7 Um = U[:, :m] plt.plot(x, Um, 'k') # Test functions i_left = dofhandler.get_region_dofs(entity_flag='left', entity_type='vertex') B = Um[i_left, :].T plt.plot(np.tile(x[i_left], B.shape), B, 'r.') plt.show() Q, R = la.qr(B, mode='full') psi = Um.dot(Q[:, 1:]) plt.plot(x, psi) plt.show() rom_tol = 1e-10 rom_error = 1 - np.cumsum(S) / np.sum(S) n_rom = np.sum(rom_error >= rom_tol) print(n_rom) Ur = U[:, :n_rom]