def apply_bc_and_block_bc_vector_non_linear(rhs, block_rhs, block_bcs, block_V): if block_bcs is None: return (None, None) N = len(block_bcs) assert N in (1, 2) if N == 1: function = Function(block_V[0]) [bc.apply(rhs, function.vector()) for bc in block_bcs[0]] block_function = BlockFunction(block_V) block_bcs.apply(block_rhs, block_function.block_vector()) return (function, block_function) else: function1 = Function(block_V[0]) [bc1.apply(rhs[0], function1.vector()) for bc1 in block_bcs[0]] function2 = Function(block_V[1]) [bc2.apply(rhs[1], function2.vector()) for bc2 in block_bcs[1]] block_function = BlockFunction(block_V) block_bcs.apply(block_rhs, block_function.block_vector()) return ((function1, function2), block_function)
def assert_functions_manipulations(functions, block_V): n_blocks = len(functions) assert n_blocks in (1, 2) # a) Convert from a list of Functions to a BlockFunction block_function_a = BlockFunction(block_V) for (index, function) in enumerate(functions): assign(block_function_a.sub(index), function) # Block vector should have received the data stored in the list of Functions if n_blocks == 1: assert_block_functions_equal(functions[0], block_function_a, block_V) else: assert_block_functions_equal((functions[0], functions[1]), block_function_a, block_V) # b) Test block_assign block_function_b = BlockFunction(block_V) block_assign(block_function_b, block_function_a) # Each sub function should now contain the same data as the original block function for index in range(n_blocks): assert array_equal(block_function_b.sub(index).vector().get_local(), block_function_a.sub(index).vector().get_local()) # The two block vectors should store the same data assert array_equal(block_function_b.block_vector().get_local(), block_function_a.block_vector().get_local())
def m_linear(integrator_type, mesh, subdomains, boundaries, t_start, dt, T, solution0, \ alpha_0, K_0, mu_l_0, lmbda_l_0, Ks_0, \ alpha_1, K_1, mu_l_1, lmbda_l_1, Ks_1, \ alpha, K, mu_l, lmbda_l, Ks, \ cf_0, phi_0, rho_0, mu_0, k_0,\ cf_1, phi_1, rho_1, mu_1, k_1,\ cf, phi, rho, mu, k, \ pressure_freeze): # Create mesh and define function space parameters["ghost_mode"] = "shared_facet" # required by dS dx = Measure('dx', domain=mesh, subdomain_data=subdomains) ds = Measure('ds', domain=mesh, subdomain_data=boundaries) dS = Measure('dS', domain=mesh, subdomain_data=boundaries) C = VectorFunctionSpace(mesh, "CG", 2) C = BlockFunctionSpace([C]) TM = TensorFunctionSpace(mesh, 'DG', 0) PM = FunctionSpace(mesh, 'DG', 0) n = FacetNormal(mesh) vc = CellVolume(mesh) fc = FacetArea(mesh) h = vc/fc h_avg = (vc('+') + vc('-'))/(2*avg(fc)) monitor_dt = dt f_stress_x = Constant(-1.e3) f_stress_y = Constant(-20.0e6) f = Constant((0.0, 0.0)) #sink/source for displacement I = Identity(mesh.topology().dim()) # Define variational problem psiu, = BlockTestFunction(C) block_u = BlockTrialFunction(C) u, = block_split(block_u) w = BlockFunction(C) theta = -1.0 a_time = inner(-alpha*pressure_freeze*I,sym(grad(psiu)))*dx #quasi static a = inner(2*mu_l*strain(u)+lmbda_l*div(u)*I, sym(grad(psiu)))*dx rhs_a = inner(f,psiu)*dx \ + dot(f_stress_y*n,psiu)*ds(2) r_u = [a] #DirichletBC bcd1 = DirichletBC(C.sub(0).sub(0), 0.0, boundaries, 1) # No normal displacement for solid on left side bcd3 = DirichletBC(C.sub(0).sub(0), 0.0, boundaries, 3) # No normal displacement for solid on right side bcd4 = DirichletBC(C.sub(0).sub(1), 0.0, boundaries, 4) # No normal displacement for solid on bottom side bcs = BlockDirichletBC([bcd1,bcd3,bcd4]) AA = block_assemble([r_u]) FF = block_assemble([rhs_a - a_time]) bcs.apply(AA) bcs.apply(FF) block_solve(AA, w.block_vector(), FF, "mumps") export_solution = w return export_solution, T
penalty2 / h * rho / vis * dot(dot(n, k), n) * (p_con - p_D1) * con * ds(2)) if MPI.size(MPI.comm_world) == 1: xdmu = XDMFFile("biot_" + discretization + "_u.xdmf") xdmp = XDMFFile("biot_" + discretization + "_p.xdmf") print("Discretization:", discretization) while t < T: t += dt print("\tsolving at time", t) AA = block_assemble(lhs) FF = block_assemble(rhs) bcs.apply(AA) bcs.apply(FF) block_solve(AA, w.block_vector(), FF, "mumps") block_assign(w0, w) xdmu.write(w[0], t) xdmp.write(w[1], t) u_con.assign(w[0]) p_con.assign(w[1]) mass = assemble(mass_con) print("\taverage mass residual: ", np.average(np.abs(mass[:]))) if discretization == "DG": assert np.isclose(w[0].vector().norm("l2"), 0.019389822) assert np.isclose(w[1].vector().norm("l2"), 11778.77487) elif discretization == "EG": assert np.isclose(w[0].vector().norm("l2"), 0.019391447) # The assert on the norm of w[1] is missing because its value is not consistent across