def test_l2projection_bounded_3D(polynomial_order, lb, ub): xmin, ymin, zmin = 0., 0., 0. xmax, ymax, zmax = 1., 1., 1. nx = 10 interpolate_expression = Ball(0.15, [0.5, 0.5, 0.5], degree=3, lb=lb, ub=ub) property_idx = 1 mesh = BoxMesh(Point(xmin, ymin, zmin), Point(xmax, ymax, zmax), nx, nx, nx) V = FunctionSpace(mesh, "DG", polynomial_order) x = RegularBox(Point(0., 0., 0.), Point(1., 1., 1.)).generate([100, 100, 100]) s = assign_particle_values(x, interpolate_expression) # Just make a complicated particle, possibly with scalars and vectors mixed p = particles(x, [s], mesh) vh = Function(V) lstsq_rho = l2projection(p, V, property_idx) lstsq_rho.project(vh.cpp_object(), lb, ub) # Assert if it stays within bounds assert np.any(vh.vector().get_local() < ub + 1e-12) assert np.any(vh.vector().get_local() > lb - 1e-12)
def test_failsafe_sweep(): interpolate_expression = Expression('x[0]', degree=1) mesh = UnitSquareMesh(5, 5) V = FunctionSpace(mesh, "DG", 1) v = Function(V) v.assign(interpolate_expression) np_min, np_max = 1, 2 np_failsafe = 4 # Initialize particles x = RandomRectangle(Point(0.0, 0.0), Point(1., 1.)).generate([100, 100]) s = assign_particle_values(x, interpolate_expression) # Broadcast to other procs x = comm.bcast(x, root=0) s = comm.bcast(s, root=0) property_idx = 1 p = particles(x, [s], mesh) AD = AddDelete(p, np_min, np_max, [v]) AD.do_sweep_failsafe(np_failsafe) # Must recover linear lstsq_rho = l2projection(p, V, property_idx) lstsq_rho.project(v.cpp_object()) error = sqrt( assemble( (v - interpolate_expression) * (v - interpolate_expression) * dx)) assert len(p.positions() == mesh.num_cells() * np_failsafe) assert error < 1e-12
def test_l2_projection_3D(polynomial_order, in_expression): xmin, ymin, zmin = 0.0, 0.0, 0.0 xmax, ymax, zmax = 1.0, 1.0, 1.0 nx = 25 property_idx = 1 mesh = BoxMesh(Point(xmin, ymin, zmin), Point(xmax, ymax, zmax), nx, nx, nx) interpolate_expression = Expression(in_expression, degree=3) if len(interpolate_expression.ufl_shape) == 0: V = FunctionSpace(mesh, "DG", polynomial_order) elif len(interpolate_expression.ufl_shape) == 1: V = VectorFunctionSpace(mesh, "DG", polynomial_order) v_exact = Function(V) v_exact.assign(interpolate_expression) x = RandomBox(Point(0.0, 0.0, 0.0), Point(1.0, 1.0, 1.0)).generate([4, 4, 4]) s = assign_particle_values(x, interpolate_expression) # Just make a complicated particle, possibly with scalars and vectors mixed p = particles(x, [s], mesh) # Do AddDelete sweep AD = AddDelete(p, 13, 15, [v_exact]) AD.do_sweep() vh = Function(V) lstsq_vh = l2projection(p, V, property_idx) lstsq_vh.project(vh.cpp_object()) error_sq = abs(assemble(dot(v_exact - vh, v_exact - vh) * dx)) if comm.Get_rank() == 0: assert error_sq < 1e-13
step = 0 area_0 = assemble(psi0_h * dx) timer = Timer() timer.start() while step < num_steps: step += 1 # Add/delete particles, must be done before advection! AD.do_sweep() # Advect particle, assemble and solve pde projection ap.do_step(float(dt)) pde_projection.assemble(True, True) pde_projection.solve_problem(psibar_h.cpp_object(), psi_h.cpp_object(), "gmres", "hypre_amg") # Update old solution assign(psi0_h, psi_h) # Store # if step % store_step is 0 or step is 1: output_field << psi_h timer.stop() # Compute error (we should accurately recover initial condition) l2_error = sqrt( abs( assemble(
V = VectorFunctionSpace(mesh, 'DG', 3) uh = Function(V) uh.assign(Expression(('-Uh*x[1]', 'Uh*x[0]'), Uh=Uh, degree=3)) # Generate particles x = RandomCircle(Point(x0, y0), r).generate([pres, pres]) s = assign_particle_values(x, psi0_expr) p = particles(x, [s], mesh) # Initialize advection class, use RK3 scheme ap = advect_rk3(p, V, uh, 'closed') # Init projection lstsq_psi = l2projection(p, W, 1) # Do projection to get initial field lstsq_psi.project(psi_h.cpp_object(), lb, ub) AD = AddDelete(p, 10, 20, [psi_h], [1], [lb, ub]) step = 0 t = 0. area_0 = assemble(psi_h * dx) timer = Timer() timer.start() outfile.write(psi_h, t) while step < num_steps: step += 1 t += float(dt) if comm.Get_rank() == 0: print("Step " + str(step))
def output_data_step(append=False): urms = (1.0 / (lmbdax*lmbdaz) * assemble(dot(u_vec, u_vec) * dx)) ** 0.5 conservation = abs(assemble(phi * dx) - conservation0) entrainment = assemble(1.0 / (lmbdax * lmbdaz * Constant(db)) * phi * dx(de)) output_functionals(data_filename, [float(t), float(dt), urms, conservation, entrainment], append=append) # Initial Stokes solve time = Timer("ZZZ Stokes assemble") ssc.assemble_global_system(True) del time time = Timer("ZZZ Stokes solve") for bc in bcs: ssc.apply_boundary(bc) ssc.solve_problem(Uhbar.cpp_object(), Uh.cpp_object(), "mumps", "default") del time # Transfer the computed velocity function and compute functionals velocity_assigner.assign(u_vec, Uh.sub(0)) output_data_step(append=False) time_snap_shot_interval = 5.0 next_snap_shot_time = time_snap_shot_interval for j in range(50000): max_u_vec = u_vec.vector().norm("linf") dt.assign(C_CFL * hmin / max_u_vec) t.assign(float(t) + float(dt)) if float(t) > 2000.0:
print("Step " + str(step)) # Advect particle, assemble and solve pde projection t1 = Timer("[P] Advect particles step") AD.do_sweep() ap.do_step(float(dt)) AD.do_sweep_failsafe(4) del (t1) t1 = Timer("[P] Assemble PDE system") pde_projection.assemble(True, True) # pde_projection.apply_boundary(bc) del (t1) t1 = Timer("[P] Solve PDE constrained projection") pde_projection.solve_problem(psibar_h.cpp_object(), psi_h.cpp_object(), 'mumps', 'default') del (t1) t1 = Timer("[P] Update and store") # Update old solution assign(psi0_h, psi_h) # Store field if step % store_step == 0 or step == 1: output_field.write(psi_h, t) # Avoid getting accused of cheating, compute # L2 error and mass error at half rotation if int(np.floor(2 * step - num_steps)) == 0:
# Limit number of particles AD.do_sweep() # Advect particles ap.do_step(float(dt)) # Do failsafe sweep AD.do_sweep_failsafe(7) del t1 # Do constrained projection t1 = Timer("[P] Assemble") pde_projection.assemble(True, True) del t1 t1 = Timer("[P] Solve") pde_projection.solve_problem(ubar_a.cpp_object(), ustar.cpp_object(), "bicgstab", "hypre_amg") del t1 # Solve Stokes t1 = Timer("[P] Stokes assemble") ssc.assemble_global_system(True) del t1 t1 = Timer("[P] Stokes solve") for bc in bcs: ssc.apply_boundary(bc) ssc.solve_problem(Uhbar.cpp_object(), Uh.cpp_object(), "mumps", "default") del t1 t1 = Timer("[P] Assign and output") # Needed for particle advection
def test_moving_mesh(): t = 0. dt = 0.025 num_steps = 20 xmin, ymin = 0., 0. xmax, ymax = 2., 2. xc, yc = 1., 1. nx, ny = 20, 20 pres = 150 k = 1 mesh = RectangleMesh(Point(xmin, ymin), Point(xmax, ymax), nx, ny) n = FacetNormal(mesh) # Class for mesh motion dU = PeriodicVelocity(xmin, xmax, dt, t, degree=1) Qcg = VectorFunctionSpace(mesh, 'CG', 1) boundaries = MeshFunction("size_t", mesh, mesh.topology().dim()-1) boundaries.set_all(0) leftbound = Left(xmin) leftbound.mark(boundaries, 99) ds = Measure('ds', domain=mesh, subdomain_data=boundaries) # Create function spaces Q_E_Rho = FiniteElement("DG", mesh.ufl_cell(), k) T_1 = FunctionSpace(mesh, 'DG', 0) Qbar_E = FiniteElement("DGT", mesh.ufl_cell(), k) Q_Rho = FunctionSpace(mesh, Q_E_Rho) Qbar = FunctionSpace(mesh, Qbar_E) phih, phih0 = Function(Q_Rho), Function(Q_Rho) phibar = Function(Qbar) # Advective velocity uh = Function(Qcg) uh.assign(Constant((0., 0.))) # Mesh velocity umesh = Function(Qcg) # Total velocity uadvect = uh-umesh # Now throw in the particles x = RandomRectangle(Point(xmin, ymin), Point(xmax, ymax)).generate([pres, pres]) s = assign_particle_values(x, GaussianPulse(center=(xc, yc), sigma=float(0.25), U=[0, 0], time=0., height=1., degree=3)) x = comm.bcast(x, root=0) s = comm.bcast(s, root=0) p = particles(x, [s], mesh) # Define projections problem FuncSpace_adv = {'FuncSpace_local': Q_Rho, 'FuncSpace_lambda': T_1, 'FuncSpace_bar': Qbar} FormsPDE = FormsPDEMap(mesh, FuncSpace_adv, ds=ds) forms_pde = FormsPDE.forms_theta_linear(phih0, uadvect, dt, Constant(1.0), zeta=Constant(0.)) pde_projection = PDEStaticCondensation(mesh, p, forms_pde['N_a'], forms_pde['G_a'], forms_pde['L_a'], forms_pde['H_a'], forms_pde['B_a'], forms_pde['Q_a'], forms_pde['R_a'], forms_pde['S_a'], [], 1) # Initialize the initial condition at mesh by an l2 projection lstsq_rho = l2projection(p, Q_Rho, 1) lstsq_rho.project(phih0.cpp_object()) for step in range(num_steps): # Compute old area at old configuration old_area = assemble(phih0*dx) # Pre-assemble rhs pde_projection.assemble_state_rhs() # Move mesh dU.compute_ubc() umesh.assign(project(dU, Qcg)) ALE.move(mesh, project(dU * dt, Qcg)) dU.update() # Relocate particles as a result of mesh motion # NOTE: if particles were advected themselve, # we had to run update_facets_info() here as well p.relocate() # Assemble left-hand side on new config, but not the right-hand side pde_projection.assemble(True, False) pde_projection.solve_problem(phibar.cpp_object(), phih.cpp_object(), 'mumps', 'none') # Needed to compute conservation, note that there # is an outgoing flux at left boundary new_area = assemble(phih*dx) gamma = conditional(ge(dot(uadvect, n), 0), 0, 1) bflux = assemble((1-gamma) * dot(uadvect, n) * phih * ds) # Update solution assign(phih0, phih) # Put assertion on (global) mass balance, local mass balance is # too time consuming but should pass also assert new_area - old_area + bflux * dt < 1e-12 # Assert that max value of phih stays close to 2 and # min value close to 0. This typically will fail if # we do not do a correct relocate of particles assert np.amin(phih.vector().get_local()) > -0.015 assert np.amax(phih.vector().get_local()) < 1.04
step = 0 area_0 = assemble(psi0_h * dx) timer = Timer('[P] Advection loop') timer.start() while step < num_steps: step += 1 # Advect particle, assemble and solve pde projection t2 = Timer('[P] Do step') ap.do_step(float(dt)) del (t2) t2 = Timer('[P] Assemble particles') pde_projection.assemble(True, True) del (t2) t3 = Timer('[P] Projection particles') pde_projection.solve_problem(psibar_h.cpp_object(), psi_h.cpp_object(), lambda_h.cpp_object(), 'gmres', 'hypre_amg') del (t3) t2 = Timer('[P] Assign & output') # Update old solution assign(psi0_h, psi_h) # Store if step % store_step == 0 or step == 1: output_field << psi_h del (t2) timer.stop()
# Limit number of particles t1 = Timer("[P] advect particles") AD.do_sweep() # Advect particles ap.do_step(float(dt)) # Do failsafe sweep AD.do_sweep_failsafe(5) del(t1) # Do constrained projection t1 = Timer("[P] assemble projection") pde_projection.assemble(True, True) del(t1) t1 = Timer("[P] solve projection") pde_projection.solve_problem(ubar_a.cpp_object(), ustar.cpp_object(), lamb.cpp_object(), 'mumps', 'default') del(t1) # Solve Stokes t1 = Timer("[P] Stokes assemble ") ssc.assemble_global_system(True) for bc in bcs: ssc.apply_boundary(bc) del(t1) t1 = Timer("[P] Stokes solve") ssc.solve_problem(Uhbar.cpp_object(), Uh.cpp_object(), "mumps", "none") del(t1) # Needed for particle advection assign(Udiv, Uh.sub(0))