def test_closed_boundary(advection_scheme): # FIXME: rk3 scheme does not bounces off the wall properly xmin, xmax = 0., 1. ymin, ymax = 0., 1. mesh = RectangleMesh(Point(xmin, ymin), Point(xmax, ymax), 10, 10) # Particle x = np.array([[0.975, 0.475]]) # Given velocity field: vexpr = Constant((1., 0.)) # Given time do_step: dt = 0.05 # Then bounced position is x_bounced = np.array([[0.975, 0.475]]) p = particles(x, [x, x], mesh) V = VectorFunctionSpace(mesh, "CG", 1) v = Function(V) v.assign(vexpr) # Different boundary parts bound_left = UnitSquareLeft() bound_right = UnitSquareRight() bound_top = UnitSquareTop() bound_bottom = UnitSquareBottom() # Mark all facets facet_marker = MeshFunction('size_t', mesh, mesh.topology().dim() - 1) facet_marker.set_all(0) # Mark as closed bound_right.mark(facet_marker, 1) # Mark other boundaries as open bound_left.mark(facet_marker, 2) bound_top.mark(facet_marker, 2) bound_bottom.mark(facet_marker, 2) if advection_scheme == 'euler': ap = advect_particles(p, V, v, facet_marker) elif advection_scheme == 'rk2': ap = advect_rk2(p, V, v, facet_marker) elif advection_scheme == 'rk3': ap = advect_rk3(p, V, v, facet_marker) else: assert False # Do one timestep, particle must bounce from wall of ap.do_step(dt) xpE = p.positions() # Check if particle correctly bounced off from closed wall xpE_root = comm.gather(xpE, root=0) if comm.rank == 0: xpE_root = np.float64(np.vstack(xpE_root)) error = np.linalg.norm(x_bounced - xpE_root) assert(error < 1e-10)
def test_advect_periodic(advection_scheme): # FIXME: this unit test is sensitive to the ordering of the particle # array, i.e. xp0_root and xpE_root may contain exactly the same entries # but only in a different order. This will return an error right now xmin, xmax = 0., 1. ymin, ymax = 0., 1. pres = 3 mesh = RectangleMesh(Point(xmin, ymin), Point(xmax, ymax), 10, 10) lims = np.array([[xmin, xmin, ymin, ymax], [xmax, xmax, ymin, ymax], [xmin, xmax, ymin, ymin], [xmin, xmax, ymax, ymax]]) vexpr = Constant((1., 1.)) V = VectorFunctionSpace(mesh, "CG", 1) x = RandomRectangle(Point(0.05, 0.05), Point(0.15, 0.15)).generate([pres, pres]) x = comm.bcast(x, root=0) dt = 0.05 v = Function(V) v.assign(vexpr) p = particles(x, [x*0, x**2], mesh) if advection_scheme == 'euler': ap = advect_particles(p, V, v, 'periodic', lims.flatten()) elif advection_scheme == 'rk2': ap = advect_rk2(p, V, v, 'periodic', lims.flatten()) elif advection_scheme == 'rk3': ap = advect_rk3(p, V, v, 'periodic', lims.flatten()) else: assert False xp0 = p.positions() t = 0. while t < 1.-1e-12: ap.do_step(dt) t += dt xpE = p.positions() # Check if position correct xp0_root = comm.gather(xp0, root=0) xpE_root = comm.gather(xpE, root=0) num_particles = p.number_of_particles() if comm.Get_rank() == 0: xp0_root = np.float32(np.vstack(xp0_root)) xpE_root = np.float32(np.vstack(xpE_root)) # Sort on x positions xp0_root = xp0_root[xp0_root[:, 0].argsort(), :] xpE_root = xpE_root[xpE_root[:, 0].argsort(), :] error = np.linalg.norm(xp0_root - xpE_root) assert error < 1e-10 assert num_particles - pres**2 == 0
def test_advect_periodic(advection_scheme): xmin, ymin, zmin = 0., 0., 0. xmax, ymax, zmax = 1., 1., 1. pres = 10 mesh = UnitCubeMesh(10, 10, 10) lims = np.array([[xmin, xmin, ymin, ymax, zmin, zmax], [xmax, xmax, ymin, ymax, zmin, zmax], [xmin, xmax, ymin, ymin, zmin, zmax], [xmin, xmax, ymax, ymax, zmin, zmax], [xmin, xmax, ymin, ymax, zmin, zmin], [xmin, xmax, ymin, ymax, zmax, zmax]]) vexpr = Constant((1., 1., 1.)) V = VectorFunctionSpace(mesh, "CG", 1) v = Function(V) v.assign(vexpr) x = RandomBox(Point(0., 0., 0.), Point(1., 1., 1.)).generate([pres, pres, pres]) x = comm.bcast(x, root=0) dt = 0.05 p = particles(x, [x * 0, x**2], mesh) if advection_scheme == 'euler': ap = advect_particles(p, V, v, 'periodic', lims.flatten()) elif advection_scheme == 'rk2': ap = advect_rk2(p, V, v, 'periodic', lims.flatten()) elif advection_scheme == 'rk3': ap = advect_rk3(p, V, v, 'periodic', lims.flatten()) else: assert False xp0 = p.positions() t = 0. while t < 1. - 1e-12: ap.do_step(dt) t += dt xpE = p.positions() xp0_root = comm.gather(xp0, root=0) xpE_root = comm.gather(xpE, root=0) assert len(xp0) == len(xpE) num_particles = p.number_of_particles() if comm.Get_rank() == 0: xp0_root = np.float32(np.vstack(xp0_root)) xpE_root = np.float32(np.vstack(xpE_root)) # Sort on x positions xp0_root = xp0_root[xp0_root[:, 0].argsort(), :] xpE_root = xpE_root[xpE_root[:, 0].argsort(), :] error = np.linalg.norm(xp0_root - xpE_root) assert error < 1e-10 assert num_particles - pres**3 == 0
def test_open_boundary(advection_scheme): xmin, xmax = 0.0, 1.0 ymin, ymax = 0.0, 1.0 pres = 3 mesh = RectangleMesh(Point(xmin, ymin), Point(xmax, ymax), 10, 10) # Particle x = RandomRectangle(Point(0.955, 0.45), Point(1.0, 0.55)).generate([pres, pres]) x = comm.bcast(x, root=0) # Given velocity field: vexpr = Constant((1.0, 1.0)) # Given time do_step: dt = 0.05 p = particles(x, [x, x], mesh) V = VectorFunctionSpace(mesh, "CG", 1) v = Function(V) v.assign(vexpr) # Different boundary parts bound_left = UnitSquareLeft() bound_right = UnitSquareRight() bound_top = UnitSquareTop() bound_bottom = UnitSquareBottom() # Mark all facets facet_marker = MeshFunction("size_t", mesh, mesh.topology().dim() - 1) facet_marker.set_all(0) # Mark as open bound_right.mark(facet_marker, 2) # Mark other boundaries as closed bound_left.mark(facet_marker, 1) bound_top.mark(facet_marker, 1) bound_bottom.mark(facet_marker, 1) if advection_scheme == "euler": ap = advect_particles(p, V, v, facet_marker) elif advection_scheme == "rk2": ap = advect_rk2(p, V, v, facet_marker) elif advection_scheme == "rk3": ap = advect_rk3(p, V, v, facet_marker) else: assert False # Do one timestep, particle must bounce from wall of ap.do_step(dt) num_particles = p.number_of_particles() # Check if all particles left domain if comm.rank == 0: assert (num_particles == 0)
def test_advect_periodic_facet_marker(advection_scheme): xmin, xmax = 0.0, 1.0 ymin, ymax = 0.0, 1.0 mesh = RectangleMesh(Point(xmin, ymin), Point(xmax, ymax), 10, 10) facet_marker = MeshFunction("size_t", mesh, mesh.topology().dim() - 1) facet_marker.set_all(0) boundaries = Boundaries() boundaries.mark(facet_marker, 3) lims = np.array([ [xmin, xmin, ymin, ymax], [xmax, xmax, ymin, ymax], [xmin, xmax, ymin, ymin], [xmin, xmax, ymax, ymax], ]) vexpr = Constant((1.0, 1.0)) V = VectorFunctionSpace(mesh, "CG", 1) x = RandomRectangle(Point(0.05, 0.05), Point(0.15, 0.15)).generate([3, 3]) x = comm.bcast(x, root=0) dt = 0.05 v = Function(V) v.assign(vexpr) p = particles(x, [x * 0, x**2], mesh) if advection_scheme == "euler": ap = advect_particles(p, V, v, facet_marker, lims.flatten()) elif advection_scheme == "rk2": ap = advect_rk2(p, V, v, facet_marker, lims.flatten()) elif advection_scheme == "rk3": ap = advect_rk3(p, V, v, facet_marker, lims.flatten()) else: assert False xp0 = p.positions() t = 0.0 while t < 1.0 - 1e-12: ap.do_step(dt) t += dt xpE = p.positions() # Check if position correct xp0_root = comm.gather(xp0, root=0) xpE_root = comm.gather(xpE, root=0) if comm.Get_rank() == 0: xp0_root = np.float32(np.vstack(xp0_root)) xpE_root = np.float32(np.vstack(xpE_root)) error = np.linalg.norm(xp0_root - xpE_root) assert error < 1e-10
def test_bounded_domain_boundary(xlims, ylims, advection_scheme): xmin, xmax = xlims ymin, ymax = ylims pres = 1 mesh = RectangleMesh(Point(xmin, ymin), Point(xmax, ymax), 10, 10) ymin += 0.0025 lims = np.array([xmin, xmax, ymin, ymax]) v_arr = np.array([-1.0, -1.0]) vexpr = Constant(v_arr) V = VectorFunctionSpace(mesh, "CG", 1) x = RandomRectangle(Point(0.05, 0.05), Point(0.15, 0.15)).generate([pres, pres]) dt = 0.005 v = Function(V) v.assign(vexpr) p = particles(x, [x], mesh) if advection_scheme == 'euler': ap = advect_particles(p, V, v, 'bounded', lims.flatten()) elif advection_scheme == 'rk2': ap = advect_rk2(p, V, v, 'bounded', lims.flatten()) elif advection_scheme == 'rk3': ap = advect_rk3(p, V, v, 'bounded', lims.flatten()) else: assert False original_num_particles = p.number_of_particles() t = 0. while t < 3.0 - 1e-12: ap.do_step(dt) t += dt assert p.number_of_particles() == original_num_particles xpn = np.array(p.get_property(0)).reshape((-1, 2)) x0 = np.array(p.get_property(1)).reshape((-1, 2)) analytical_position = x0 + t * v_arr analytical_position[:, 0] = np.maximum( np.minimum(xmax, analytical_position[:, 0]), xmin) analytical_position[:, 1] = np.maximum( np.minimum(ymax, analytical_position[:, 1]), ymin) error = np.abs(xpn - analytical_position) assert np.all(np.abs(error) < 1e-12)
def test_advect_open(advection_scheme): pres = 3 mesh = UnitCubeMesh(10, 10, 10) # Particle x = RandomBox(Point(0.955, 0.45, 0.5), Point(0.99, 0.55, 0.6)).generate([pres, pres, pres]) x = comm.bcast(x, root=0) # Given velocity field: vexpr = Constant((1.0, 1.0, 1.0)) # Given time do_step: dt = 0.05 p = particles(x, [x, x], mesh) V = VectorFunctionSpace(mesh, "CG", 1) v = Function(V) v.assign(vexpr) # Different boundary parts bounds = Boundaries() bound_right = UnitCubeRight() # Mark all facets facet_marker = MeshFunction("size_t", mesh, mesh.topology().dim() - 1) facet_marker.set_all(0) bounds.mark(facet_marker, 1) bound_right.mark(facet_marker, 2) # Mark as open bound_right.mark(facet_marker, 2) if advection_scheme == "euler": ap = advect_particles(p, V, v, facet_marker) elif advection_scheme == "rk2": ap = advect_rk2(p, V, v, facet_marker) elif advection_scheme == "rk3": ap = advect_rk3(p, V, v, facet_marker) else: assert False # Do one timestep, particle must bounce from wall of ap.do_step(dt) num_particles = p.number_of_particles() # Check if all particles left domain if comm.rank == 0: assert num_particles == 0
def test_advect_particle(advection_scheme): if comm.rank == 0: print('Run advect_particle') # Rotate one particle, and compute the error mesh = UnitSquareMesh(10, 10) # Particle x = np.array([[0.25, 0.25]]) dt_list = [0.08, 0.04, 0.02, 0.01, 0.005] # Velocity field vexpr = Expression(('-pi*(x[1] - 0.5)', 'pi*(x[0]-0.5)'), degree=3) V = VectorFunctionSpace(mesh, "CG", 1) v = Function(V) v.assign(vexpr) error_list = [] for dt in dt_list: p = particles(x, [x, x], mesh) if advection_scheme == 'euler': ap = advect_particles(p, V, v, 'closed') elif advection_scheme == 'rk2': ap = advect_rk2(p, V, v, 'closed') elif advection_scheme == 'rk3': ap = advect_rk3(p, V, v, 'closed') else: assert False xp_0 = p.positions() t = 0. while t < 2.-1e-12: ap.do_step(dt) t += dt xp_end = p.positions() error_list.append(np.linalg.norm(xp_0 - xp_end)) if not all(eps == 0 for eps in error_list): rate = compute_convergence(dt_list, error_list) if advection_scheme == 'euler': # First order for euler assert any(i > 0.9 for i in rate) elif advection_scheme == 'rk2': # Second order for rk2 assert any(i > 1.95 for i in rate) elif advection_scheme == 'rk3': # Third order for rk3 assert any(i > 2.9 for i in rate)
# Function space and velocity field W = FunctionSpace(mesh, 'DG', k) psi_h = Function(W) 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:
rhop = assign_particle_values(x, initial_density) # Increment requires dup to be stored, init zero dup = up p = particles(x, [rhop, up, dup], mesh) # Init rho0 field lstsq_rho = l2projection(p, Q_Rho, 1) lstsq_rho.project(rho0, float(rho2), float(rho1)) # Initialize l2 projection for specific momentum lstsq_u = l2projection(p, W_2, 2) # Initialize advection class ap = advect_rk3(p, W_2, Udiv, "closed") # Set-up boundary conditions (free slip) boundaries = MeshFunction("size_t", mesh, mesh.topology().dim() - 1) boundaries.set_all(0) all_bounds = Boundaries() all_bounds.mark(boundaries, 98) ds = Measure("ds", domain=mesh, subdomain_data=boundaries) # Set-up density projection funcspaces_rho = { "FuncSpace_local": Q_Rho, "FuncSpace_lambda": T_1, "FuncSpace_bar": Qbar } forms_rho = FormsPDEMap(mesh, funcspaces_rho).forms_theta_linear(
x = RandomRectangle(Point(xmin, ymin), Point(xmax, ymax)).generate([pres, pres]) s = assign_particle_values(x, u_exact) lims = np.array([ [xmin, xmin, ymin, ymax], [xmax, xmax, ymin, ymax], [xmin, xmax, ymin, ymin], [xmin, xmax, ymax, ymax], ]) # Particle specific momentum is stored at slot 1 # the second slot will be to store old velocities at particle level property_idx = 1 p = particles(x, [s, s], mesh) ap = advect_rk3(p, W_2, Udiv, "periodic", lims.flatten()) # Particle management AD = AddDelete(p, 10, 20, [Udiv, duh0]) # Forms PDE map funcspace_dict = { "FuncSpace_local": W_2, "FuncSpace_lambda": T_2, "FuncSpace_bar": Wbar_2 } forms_adv = FormsPDEMap(mesh, funcspace_dict).forms_theta_nlinear( u0_a, ubar0_a, dt, theta_map=Constant(1.0),
if remesh_elastic == False: Vdg = FunctionSpace(model.mesh.mesh, 'DG', 1) Vcg = FunctionSpace(model.mesh.mesh, 'DG', 1) (xp, pstrain, ptemp, pepsII) = (p.return_property(mesh, 0), p.return_property(mesh, 1), p.return_property(mesh, 2), p.return_property(mesh, 3)) del p p = particles(xp, [pstrain, ptemp, pepsII], model.mesh.mesh) else: p.relocate() # Advect particles -- Turn this on to advect particles now that it is removed from Stokes script Vdg = FunctionSpace(model.mesh.mesh, 'DG', 1) ap = advect_rk3(p, model.vector2, model.u_k, "open") ap.do_step(time_step) AD = AddDelete(p, p_min, p_max, [ interpolate(model.strain, Vdg), interpolate(model.temp, Vdg), interpolate(model.epsII, Vdg) ]) # Sweep over mesh to delete/insert particles AD.do_sweep() # Plotting (xp, pstrain, ptemp, pepsII) = (p.return_property(mesh, 0), p.return_property(mesh, 1), p.return_property(mesh, 2), p.return_property(mesh, 3)) pstrain[xp[:, 0] < xyield_min] = 0.0 p.change_property(pstrain, 1)
sigma=float(sigma), U=[Uh, Uh], time=0.0, height=1.0, degree=3) # Generate particles x = RandomCircle(Point(x0, y0), r).generate([pres, pres]) s = np.zeros((len(x), 1), dtype=np.float_) # Initialize particles with position x and scalar property s at the mesh p = particles(x, [s], mesh) property_idx = 1 # Scalar quantity is stored at slot 1 # Initialize advection class, use RK3 scheme ap = advect_rk3(p, V, uh, "open") # Define the variational (projection problem) W_e = FiniteElement("DG", mesh.ufl_cell(), k) T_e = FiniteElement("DG", mesh.ufl_cell(), 0) Wbar_e = FiniteElement("DGT", mesh.ufl_cell(), k) W = FunctionSpace(mesh, W_e) T = FunctionSpace(mesh, T_e) Wbar = FunctionSpace(mesh, Wbar_e) psi_h, psi0_h = Function(W), Function(W) lambda_h = Function(T) psibar_h = Function(Wbar) # Boundary conditions
amplitude=1.0, degree=1)) 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, beta_map=Constant(1e-8)) forms_pde = FormsPDE.forms_theta_linear(phih0, uadvect, dt, Constant(1.0), zeta=Constant(0.), h=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) ap = advect_rk3(p, V, uh, 'open') # Initialize the initial condition at mesh by an l2 projection lstsq_rho = l2projection(p, Q_Rho, 1) lstsq_rho.project(phih0) outfile << phih0 for step in range(num_steps): u_expr.t = step * float(dt) u_expre_neg.t = step * float(dt) uh.assign(u_expr) # Compute area at old configuration old_area = assemble(phih0*dx)
rhop = assign_particle_values(x, initial_density) # Increment requires dup to be stored, init zero dup = up p = particles(x, [rhop, up, dup], mesh) # Init rho0 field lstsq_rho = l2projection(p, Q_Rho, 1) lstsq_rho.project(rho0, float(rho2), float(rho1)) # Initialize l2 projection for specific momentum lstsq_u = l2projection(p, W_2, 2) # Initialize advection class ap = advect_rk3(p, W_2, Udiv, 'closed') # Set-up boundary conditions (free slip) boundaries = MeshFunction("size_t", mesh, mesh.topology().dim() - 1) boundaries.set_all(0) all_bounds = Boundaries() all_bounds.mark(boundaries, 98) ds = Measure('ds', domain=mesh, subdomain_data=boundaries) # Set-up density projection funcspaces_rho = { 'FuncSpace_local': Q_Rho, 'FuncSpace_lambda': T_1, 'FuncSpace_bar': Qbar } forms_rho = FormsPDEMap(mesh, funcspaces_rho).forms_theta_linear(
ubar0_a.assign(u_exact) Udiv.assign(u_exact) # Initialize particles x = RandomRectangle(Point(xmin, ymin), Point(xmax, ymax)).generate([pres, pres]) s = assign_particle_values(x, u_exact) lims = np.array([[xmin, xmin, ymin, ymax], [xmax, xmax, ymin, ymax], [xmin, xmax, ymin, ymin], [xmin, xmax, ymax, ymax]]) # Particle specific momentum is stored at slot 1 # the second slot will be to store old velocities at particle level property_idx = 1 p = particles(x, [s, s], mesh) ap = advect_rk3(p, W_2, Udiv, 'periodic', lims.flatten()) # Particle management AD = AddDelete(p, 10, 20, [Udiv, duh0]) # Forms PDE map funcspace_dict = { 'FuncSpace_local': W_2, 'FuncSpace_lambda': T_2, 'FuncSpace_bar': Wbar_2 } forms_adv = FormsPDEMap(mesh, funcspace_dict).forms_theta_nlinear( u0_a, ubar0_a, dt, theta_map=Constant(1.0),
Rb = Constant(1.0) eta_top = Constant(1.0) eta_bottom = Constant(0.01) eta = eta_bottom + phi * (eta_top - eta_bottom) forms_stokes = FormsStokes(mesh, mixedL, mixedG, alpha) \ .forms_steady(eta, Rb * phi * Constant((0, -1, 0))) ssc = StokesStaticCondensation(mesh, forms_stokes['A_S'], forms_stokes['G_S'], forms_stokes['B_S'], forms_stokes['Q_S'], forms_stokes['S_S']) # Particle advector C_CFL = 0.5 hmin = MPI.min(comm, mesh.hmin()) ap = advect_rk3(ptcls, u_vec.function_space(), u_vec, "closed") # Write particles and their values to XDMF file particles_directory = "./particles/" points_list = list(Point(*pp) for pp in ptcls.positions()) particles_values = ptcls.get_property(property_idx) XDMFFile(os.path.join(particles_directory, "step%.4d.xdmf" % 0)) \ .write(points_list, particles_values) n_particles = MPI.sum(comm, len(points_list)) info("Solving with %d particles" % n_particles) # Write the intitial compostition field to XDMF file XDMFFile("composition.xdmf").write_checkpoint(phi, "composition", float(t), append=False) conservation0 = assemble(phi * dx)
# Function space and velocity field W = FunctionSpace(mesh, "DG", k) (psi_h0, psi_h) = (Function(W), Function(W)) 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 and get initial condition lstsq_psi = l2projection(p, W, 1) lstsq_psi.project(psi_h, lb, ub) assign(psi_h0, psi_h) step = 0 t = 0.0 area_0 = assemble(psi_h * dx) (psi_h_min, psi_h_max) = (0.0, 0.0) timer = Timer() timer.start() # Write initial field and dump initial particle field