def test_separated_parametrized_forms_vector_5(): h = CellDiameter(mesh) a5 = inner((expr3 * h) * grad(u), grad(v)) * dx + inner( grad(u) * (expr2 * h), v) * dx + (expr1 * h) * inner(u, v) * dx a5_sep = SeparatedParametrizedForm(a5) log(PROGRESS, "*** ### FORM 5 ### ***") log( PROGRESS, "Starting from form 4, use parenthesis to make sure that the extracted coefficients retain the mesh size factor" ) a5_sep.separate() log( PROGRESS, "\tLen coefficients:\n" + "\t\t" + str(len(a5_sep.coefficients)) + "\n") assert 3 == len(a5_sep.coefficients) log( PROGRESS, "\tSublen coefficients:\n" + "\t\t" + str(len(a5_sep.coefficients[0])) + "\n" + "\t\t" + str(len(a5_sep.coefficients[1])) + "\n" + "\t\t" + str(len(a5_sep.coefficients[2])) + "\n") assert 1 == len(a5_sep.coefficients[0]) assert 1 == len(a5_sep.coefficients[1]) assert 1 == len(a5_sep.coefficients[2]) log( PROGRESS, "\tCoefficients:\n" + "\t\t" + str(a5_sep.coefficients[0][0]) + "\n" + "\t\t" + str(a5_sep.coefficients[1][0]) + "\n" + "\t\t" + str(a5_sep.coefficients[2][0]) + "\n") assert "{ A | A_{i_{54}, i_{55}} = diameter * f_7[i_{54}, i_{55}] }" == str( a5_sep.coefficients[0][0]) assert "{ A | A_{i_{59}} = diameter * f_6[i_{59}] }" == str( a5_sep.coefficients[1][0]) assert "diameter * f_5" == str(a5_sep.coefficients[2][0]) log( PROGRESS, "\tPlaceholders:\n" + "\t\t" + str(a5_sep._placeholders[0][0]) + "\n" + "\t\t" + str(a5_sep._placeholders[1][0]) + "\n" + "\t\t" + str(a5_sep._placeholders[2][0]) + "\n") assert "f_51" == str(a5_sep._placeholders[0][0]) assert "f_52" == str(a5_sep._placeholders[1][0]) assert "f_53" == str(a5_sep._placeholders[2][0]) log( PROGRESS, "\tForms with placeholders:\n" + "\t\t" + str(a5_sep._form_with_placeholders[0].integrals()[0].integrand()) + "\n" + "\t\t" + str(a5_sep._form_with_placeholders[1].integrals()[0].integrand()) + "\n" + "\t\t" + str(a5_sep._form_with_placeholders[2].integrals()[0].integrand()) + "\n") assert "sum_{i_{63}} sum_{i_{62}} ({ A | A_{i_{56}, i_{57}} = sum_{i_{58}} f_51[i_{56}, i_{58}] * (grad(v_1))[i_{58}, i_{57}] })[i_{62}, i_{63}] * (grad(v_0))[i_{62}, i_{63}] " == str( a5_sep._form_with_placeholders[0].integrals()[0].integrand()) assert "sum_{i_{64}} ({ A | A_{i_{60}} = sum_{i_{61}} f_52[i_{61}] * (grad(v_1))[i_{60}, i_{61}] })[i_{64}] * v_0[i_{64}] " == str( a5_sep._form_with_placeholders[1].integrals()[0].integrand()) assert "f_53 * (sum_{i_{65}} v_0[i_{65}] * v_1[i_{65}] )" == str( a5_sep._form_with_placeholders[2].integrals()[0].integrand()) log( PROGRESS, "\tLen unchanged forms:\n" + "\t\t" + str(len(a5_sep._form_unchanged)) + "\n") assert 0 == len(a5_sep._form_unchanged)
def test_separated_parametrized_forms_vector_4(): h = CellDiameter(mesh) a4 = inner(expr3 * h * grad(u), grad(v)) * dx + inner( grad(u) * expr2 * h, v) * dx + expr1 * h * inner(u, v) * dx a4_sep = SeparatedParametrizedForm(a4) log(PROGRESS, "*** ### FORM 4 ### ***") log( PROGRESS, "We add a term depending on the mesh size. The extracted coefficients may retain the mesh size factor depending on the UFL tree" ) a4_sep.separate() log( PROGRESS, "\tLen coefficients:\n" + "\t\t" + str(len(a4_sep.coefficients)) + "\n") assert 3 == len(a4_sep.coefficients) log( PROGRESS, "\tSublen coefficients:\n" + "\t\t" + str(len(a4_sep.coefficients[0])) + "\n" + "\t\t" + str(len(a4_sep.coefficients[1])) + "\n" + "\t\t" + str(len(a4_sep.coefficients[2])) + "\n") assert 1 == len(a4_sep.coefficients[0]) assert 1 == len(a4_sep.coefficients[1]) assert 1 == len(a4_sep.coefficients[2]) log( PROGRESS, "\tCoefficients:\n" + "\t\t" + str(a4_sep.coefficients[0][0]) + "\n" + "\t\t" + str(a4_sep.coefficients[1][0]) + "\n" + "\t\t" + str(a4_sep.coefficients[2][0]) + "\n") assert "{ A | A_{i_{42}, i_{43}} = diameter * f_7[i_{42}, i_{43}] }" == str( a4_sep.coefficients[0][0]) assert "f_6" == str(a4_sep.coefficients[1][0]) assert "diameter * f_5" == str(a4_sep.coefficients[2][0]) log( PROGRESS, "\tPlaceholders:\n" + "\t\t" + str(a4_sep._placeholders[0][0]) + "\n" + "\t\t" + str(a4_sep._placeholders[1][0]) + "\n" + "\t\t" + str(a4_sep._placeholders[2][0]) + "\n") assert "f_48" == str(a4_sep._placeholders[0][0]) assert "f_49" == str(a4_sep._placeholders[1][0]) assert "f_50" == str(a4_sep._placeholders[2][0]) log( PROGRESS, "\tForms with placeholders:\n" + "\t\t" + str(a4_sep._form_with_placeholders[0].integrals()[0].integrand()) + "\n" + "\t\t" + str(a4_sep._form_with_placeholders[1].integrals()[0].integrand()) + "\n" + "\t\t" + str(a4_sep._form_with_placeholders[2].integrals()[0].integrand()) + "\n") assert "sum_{i_{51}} sum_{i_{50}} ({ A | A_{i_{44}, i_{45}} = sum_{i_{46}} f_48[i_{44}, i_{46}] * (grad(v_1))[i_{46}, i_{45}] })[i_{50}, i_{51}] * (grad(v_0))[i_{50}, i_{51}] " == str( a4_sep._form_with_placeholders[0].integrals()[0].integrand()) assert "sum_{i_{52}} ({ A | A_{i_{49}} = diameter * ({ A | A_{i_{47}} = sum_{i_{48}} f_49[i_{48}] * (grad(v_1))[i_{47}, i_{48}] })[i_{49}] })[i_{52}] * v_0[i_{52}] " == str( a4_sep._form_with_placeholders[1].integrals()[0].integrand()) assert "f_50 * (sum_{i_{53}} v_0[i_{53}] * v_1[i_{53}] )" == str( a4_sep._form_with_placeholders[2].integrals()[0].integrand()) log( PROGRESS, "\tLen unchanged forms:\n" + "\t\t" + str(len(a4_sep._form_unchanged)) + "\n") assert 0 == len(a4_sep._form_unchanged)
def __init__(self, mesh, FuncSpaces_L, FuncSpaces_G, alpha, beta_stab=Constant(0.0), ds=ds): self.mixedL = FuncSpaces_L self.mixedG = FuncSpaces_G self.n = FacetNormal(mesh) self.beta_stab = beta_stab self.alpha = alpha self.he = CellDiameter(mesh) self.ds = ds self.gdim = mesh.geometry().dim()
def solve_timestep(u_, p_, r_, u_1, p_1, r_1, tau_SUPG, D, L1, a1, L2, A2, L3, A3, L4, a4, bcu, bcp, bcr): # Step 1: Tentative velocity step A1 = assemble(a1) # needs to be reassembled because density changed! [bc.apply(A1) for bc in bcu] b1 = assemble(L1) [bc.apply(b1) for bc in bcu] solve(A1, u_.vector(), b1, 'bicgstab', 'hypre_amg') # Step 2: Pressure correction step b2 = assemble(L2) [bc.apply(b2) for bc in bcp] solve(A2, p_.vector(), b2, 'bicgstab', 'hypre_amg') # Step 3: Velocity correction step b3 = assemble(L3) solve(A3, u_.vector(), b3, 'cg', 'sor') # Step 4: Transport of rho / Convection-diffusion and SUPG # wont work for DG if D > 0.0: mesh = tau_SUPG.function_space().mesh() magnitude = project((sqrt(inner(u_, u_))), mesh=mesh).vector().vec().array h = project(CellDiameter(mesh), mesh=mesh).vector().vec().array Pe = magnitude * h / (2.0 * D) tau_np = np.zeros_like(Pe) ll = Pe > 0. tau_np[ll] = h[ll] / (2.0 * magnitude[ll]) * (1.0 / np.tanh(Pe[ll]) - 1.0 / Pe[ll]) tau_SUPG.vector().vec().array = tau_np A4 = assemble(a4) b4 = assemble(L4) [bc.apply(A4) for bc in bcr] [bc.apply(b4) for bc in bcr] solve(A4, r_.vector(), b4, 'bicgstab', 'hypre_amg') # F = (div(D*grad(rho_1)) - div(u_*rho_1))*dt + rho_1 # rho_ = project(F, mesh=mesh) # Update previous solution u_1.assign(u_) p_1.assign(p_) r_1.assign(r_) return u_1, p_1, r_1
def __init__(self, mesh, FuncSpaces_L, FuncSpaces_G, alpha, h_d=[ Expression(('0.0', '0.0'), degree=3), Expression(('0.0', '0.0'), degree=3) ], beta_stab=Constant(0.), ds=ds): self.mixedL = FuncSpaces_L self.mixedG = FuncSpaces_G self.n = FacetNormal(mesh) self.beta_stab = beta_stab self.alpha = alpha self.he = CellDiameter(mesh) self.h_d = h_d self.ds = ds self.gdim = mesh.geometry().dim()
def transport_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, \ d_0, d_1, d_t, vel_c, p_con, A_0, Temp, c_extrapolate): # 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_cg = FiniteElement("CG", mesh.ufl_cell(), 1) C_dg = FiniteElement("DG", mesh.ufl_cell(), 0) mini = C_cg + C_dg C = FunctionSpace(mesh, mini) 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)) penalty1 = Constant(1.0) tau = Function(PM) tau = tau_cal(tau, phi, -0.5) tuning_para = 0.25 vel_norm = (dot(vel_c, n) + abs(dot(vel_c, n))) / 2.0 cell_size = CellDiameter(mesh) vnorm = sqrt(dot(vel_c, vel_c)) I = Identity(mesh.topology().dim()) d_eff = Function(TM) d_eff = diff_coeff_cal_rev(d_eff, d_0, tau, phi) + tuning_para * cell_size * vnorm * I monitor_dt = dt # Define variational problem dc, = BlockTrialFunction(C) dc_dot, = BlockTrialFunction(C) psic, = BlockTestFunction(C) block_c = BlockFunction(C) c, = block_split(block_c) block_c_dot = BlockFunction(C) c_dot, = block_split(block_c_dot) theta = -1.0 a_time = phi * rho * inner(c_dot, psic) * dx a_dif = dot(rho*d_eff*grad(c),grad(psic))*dx \ - dot(avg_w(rho*d_eff*grad(c),weight_e(rho*d_eff,n)), jump(psic, n))*dS \ + theta*dot(avg_w(rho*d_eff*grad(psic),weight_e(rho*d_eff,n)), jump(c, n))*dS \ + penalty1/h_avg*k_e(rho*d_eff,n)*dot(jump(c, n), jump(psic, n))*dS a_adv = -dot(rho*vel_c*c,grad(psic))*dx \ + dot(jump(psic), rho('+')*vel_norm('+')*c('+') - rho('-')*vel_norm('-')*c('-') )*dS \ + dot(psic, rho*vel_norm*c)*ds(3) R_c = R_c_cal(c_extrapolate, p_con, Temp) c_D1 = Constant(0.5) rhs_c = R_c * A_s_cal(phi, phi_0, A_0) * psic * dx - dot( rho * phi * vel_c, n) * c_D1 * psic * ds(1) r_u = [a_dif + a_adv] j_u = block_derivative(r_u, [c], [dc]) r_u_dot = [a_time] j_u_dot = block_derivative(r_u_dot, [c_dot], [dc_dot]) r = [r_u_dot[0] + r_u[0] - rhs_c] # this part is not applied. exact_solution_expression1 = Expression("1.0", t=0, element=C[0].ufl_element()) def bc(t): p5 = DirichletBC(C.sub(0), exact_solution_expression1, boundaries, 1, method="geometric") return BlockDirichletBC([p5]) # Define problem wrapper class ProblemWrapper(object): def set_time(self, t): pass # Residual and jacobian functions def residual_eval(self, t, solution, solution_dot): return r def jacobian_eval(self, t, solution, solution_dot, solution_dot_coefficient): return [[ Constant(solution_dot_coefficient) * j_u_dot[0, 0] + j_u[0, 0] ]] # Define boundary condition def bc_eval(self, t): pass # Define initial condition def ic_eval(self): return solution0 # Define custom monitor to plot the solution def monitor(self, t, solution, solution_dot): pass problem_wrapper = ProblemWrapper() (solution, solution_dot) = (block_c, block_c_dot) solver = TimeStepping(problem_wrapper, solution, solution_dot) solver.set_parameters({ "initial_time": t_start, "time_step_size": dt, "monitor": { "time_step_size": monitor_dt, }, "final_time": T, "exact_final_time": "stepover", "integrator_type": integrator_type, "problem_type": "linear", "linear_solver": "mumps", "report": True }) export_solution = solver.solve() return export_solution, T
def test_poisson(k): # Polynomial order and mesh resolution nx_list = [4, 8, 16] # Error list error_u_l2, error_u_h1 = [], [] for nx in nx_list: mesh = UnitSquareMesh(nx, nx) # Define FunctionSpaces and functions V = FunctionSpace(mesh, "DG", k) Vbar = FunctionSpace(mesh, FiniteElement("CG", mesh.ufl_cell(), k)["facet"]) u_soln = Expression("sin(pi*x[0])*sin(pi*x[1])", degree=k + 1, domain=mesh) f = Expression("2*pi*pi*sin(pi*x[0])*sin(pi*x[1])", degree=k + 1) u, v = Function(V), TestFunction(V) ubar, vbar = Function(Vbar), TestFunction(Vbar) n = FacetNormal(mesh) h = CellDiameter(mesh) alpha = Constant(6 * k * k) penalty = alpha / h def facet_integral(integrand): return integrand('-') * dS + integrand('+') * dS + integrand * ds u_flux = ubar F_v_flux = grad(u) + penalty * outer(u_flux - u, n) residual_local = inner(grad(u), grad(v)) * dx residual_local += facet_integral(inner(outer(u_flux - u, n), grad(v))) residual_local -= facet_integral(inner(F_v_flux, outer(v, n))) residual_local -= f * v * dx residual_global = facet_integral(inner(F_v_flux, outer(vbar, n))) a_ll = derivative(residual_local, u) a_lg = derivative(residual_local, ubar) a_gl = derivative(residual_global, u) a_gg = derivative(residual_global, ubar) l_l = -residual_local l_g = -residual_global bcs = [DirichletBC(Vbar, u_soln, "on_boundary")] # Initialize static condensation assembler assembler = AssemblerStaticCondensation(a_ll, a_lg, a_gl, a_gg, l_l, l_g, bcs) A_g, b_g = PETScMatrix(), PETScVector() assembler.assemble_global_lhs(A_g) assembler.assemble_global_rhs(b_g) for bc in bcs: bc.apply(A_g, b_g) solver = PETScKrylovSolver() solver.set_operator(A_g) PETScOptions.set("ksp_type", "preonly") PETScOptions.set("pc_type", "lu") PETScOptions.set("pc_factor_mat_solver_type", "mumps") solver.set_from_options() solver.solve(ubar.vector(), b_g) assembler.backsubstitute(ubar._cpp_object, u._cpp_object) # Compute L2 and H1 norms e_u_l2 = assemble((u - u_soln)**2 * dx)**0.5 e_u_h1 = assemble(grad(u - u_soln)**2 * dx)**0.5 if mesh.mpi_comm().rank == 0: error_u_l2.append(e_u_l2) error_u_h1.append(e_u_h1) if mesh.mpi_comm().rank == 0: iterator_list = [1.0 / float(nx) for nx in nx_list] conv_u_l2 = compute_convergence(iterator_list, error_u_l2) conv_u_h1 = compute_convergence(iterator_list, error_u_h1) # Optimal rate of k + 1 - tolerance assert np.all(conv_u_l2 >= (k + 1.0 - 0.15)) # Optimal rate of k - tolerance assert np.all(conv_u_h1 >= (k - 0.1))