def demo64(self, permeability, obs_case=1): mesh = UnitSquareMesh(63, 63) ak_values = permeability flux_order = 3 s = scenarios.darcy_problem_1() DRT = fenics.FiniteElement("DRT", mesh.ufl_cell(), flux_order) # Lagrange CG = fenics.FiniteElement("CG", mesh.ufl_cell(), flux_order + 1) if s.integral_constraint: # From https://fenicsproject.org/qa/14184/how-to-solve-linear-system-with-constaint R = fenics.FiniteElement("R", mesh.ufl_cell(), 0) W = fenics.FunctionSpace(mesh, fenics.MixedElement([DRT, CG, R])) # Define trial and test functions (sigma, u, r) = fenics.TrialFunctions(W) (tau, v, r_) = fenics.TestFunctions(W) else: W = fenics.FunctionSpace(mesh, DRT * CG) # Define trial and test functions (sigma, u) = fenics.TrialFunctions(W) (tau, v) = fenics.TestFunctions(W) f = s.source_function g = s.g # Define property field function W_CG = fenics.FunctionSpace(mesh, "Lagrange", 1) if s.ak is None: ak = property_field.get_conductivity(W_CG, ak_values) else: ak = s.ak # Define variational form a = (fenics.dot(sigma, tau) + fenics.dot(ak * fenics.grad(u), tau) + fenics.dot(sigma, fenics.grad(v))) * fenics.dx L = -f * v * fenics.dx + g * v * fenics.ds # L = 0 if s.integral_constraint: # Lagrange multiplier? See above link. a += r_ * u * fenics.dx + v * r * fenics.dx # Define Dirichlet BC bc = fenics.DirichletBC(W.sub(1), s.dirichlet_bc, s.gamma_dirichlet) # Compute solution w = fenics.Function(W) fenics.solve(a == L, w, bc) # fenics.solve(a == L, w) if s.integral_constraint: (sigma, u, r) = w.split() else: (sigma, u) = w.split() x = u.compute_vertex_values(mesh) x2 = sigma.compute_vertex_values(mesh) p = x pre = p.reshape((64, 64)) vx = x2[:4096].reshape((64, 64)) vy = x2[4096:].reshape((64, 64)) if obs_case == 1: dd = np.zeros([8, 8]) pos = np.full((8 * 8, 2), 0) col = [4, 12, 20, 28, 36, 44, 52, 60] position = [4, 12, 20, 28, 36, 44, 52, 60] for i in range(8): for j in range(8): row = position pos[8 * i + j, :] = [col[i], row[j]] dd[i, j] = pre[col[i], row[j]] like = dd.reshape(8 * 8, ) return like, pre, vx, vy, ak_values, pos
def demo16(self, permeability, obs_case=1): """This demo program solves the mixed formulation of Poisson's equation: sigma + grad(u) = 0 in Omega div(sigma) = f in Omega du/dn = g on Gamma_N u = u_D on Gamma_D The corresponding weak (variational problem) <sigma, tau> + <grad(u), tau> = 0 for all tau - <sigma, grad(v)> = <f, v> + <g, v> for all v is solved using DRT (Discontinuous Raviart-Thomas) elements of degree k for (sigma, tau) and CG (Lagrange) elements of degree k + 1 for (u, v) for k >= 1. """ mesh = UnitSquareMesh(15, 15) ak_values = permeability flux_order = 3 s = scenarios.darcy_problem_1() DRT = fenics.FiniteElement("DRT", mesh.ufl_cell(), flux_order) # Lagrange CG = fenics.FiniteElement("CG", mesh.ufl_cell(), flux_order + 1) if s.integral_constraint: # From https://fenicsproject.org/qa/14184/how-to-solve-linear-system-with-constaint R = fenics.FiniteElement("R", mesh.ufl_cell(), 0) W = fenics.FunctionSpace(mesh, fenics.MixedElement([DRT, CG, R])) # Define trial and test functions (sigma, u, r) = fenics.TrialFunctions(W) (tau, v, r_) = fenics.TestFunctions(W) else: W = fenics.FunctionSpace(mesh, DRT * CG) # Define trial and test functions (sigma, u) = fenics.TrialFunctions(W) (tau, v) = fenics.TestFunctions(W) f = s.source_function g = s.g # Define property field function W_CG = fenics.FunctionSpace(mesh, "Lagrange", 1) if s.ak is None: ak = property_field.get_conductivity(W_CG, ak_values) else: ak = s.ak # Define variational form a = (fenics.dot(sigma, tau) + fenics.dot(ak * fenics.grad(u), tau) + fenics.dot(sigma, fenics.grad(v))) * fenics.dx L = -f * v * fenics.dx + g * v * fenics.ds # L = 0 if s.integral_constraint: # Lagrange multiplier? See above link. a += r_ * u * fenics.dx + v * r * fenics.dx # Define Dirichlet BC bc = fenics.DirichletBC(W.sub(1), s.dirichlet_bc, s.gamma_dirichlet) # Compute solution w = fenics.Function(W) fenics.solve(a == L, w, bc) # fenics.solve(a == L, w) if s.integral_constraint: (sigma, u, r) = w.split() else: (sigma, u) = w.split() x = u.compute_vertex_values(mesh) x2 = sigma.compute_vertex_values(mesh) p = x pre = p.reshape((16, 16)) vx = x2[:256].reshape((16, 16)) vy = x2[256:].reshape((16, 16)) if obs_case == 1: dd = np.zeros([8, 8]) pos = np.full((8 * 8, 2), 0) col = [1, 3, 5, 7, 9, 11, 13, 15] position = [1, 3, 5, 7, 9, 11, 13, 15] for i in range(8): for j in range(8): row = position pos[8 * i + j, :] = [col[i], row[j]] dd[i, j] = pre[col[i], row[j]] like = dd.reshape(8 * 8, ) return like, pre, vx, vy, ak_values, pos