def test_pde_constrained(polynomial_order, in_expression): interpolate_expression = Expression(in_expression, degree=3) xmin, xmax = 0., 1. ymin, ymax = 0., 1. property_idx = 1 dt = 1. k = polynomial_order # Make mesh mesh = RectangleMesh(Point(xmin, ymin), Point(xmax, ymax), 40, 40) # Make function spaces and functions 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) uadvect = Constant((0, 0)) # Define particles x = RandomRectangle(Point(xmin, ymin), Point(xmax, ymax)).generate([500, 500]) s = assign_particle_values(x, interpolate_expression) psi0_h.assign(interpolate_expression) # Just make a complicated particle, possibly with scalars and vectors mixed p = particles(x, [s], mesh) p.interpolate(psi0_h, 1) # Initialize forms FuncSpace_adv = { 'FuncSpace_local': W, 'FuncSpace_lambda': T, 'FuncSpace_bar': Wbar } forms_pde = FormsPDEMap(mesh, FuncSpace_adv).forms_theta_linear( psi0_h, uadvect, dt, Constant(1.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'], [], property_idx) # Assemble and solve pde_projection.assemble(True, True) pde_projection.solve_problem(psibar_h, psi_h, lambda_h, 'none', 'default') error_psih = abs(assemble((psi_h - psi0_h) * (psi_h - psi0_h) * dx)) error_lamb = abs(assemble(lambda_h * lambda_h * dx)) assert error_psih < 1e-15 assert error_lamb < 1e-15
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( dot(psi_h - psi0_expression, psi_h - psi0_expression) *
t.assign(float(t) + float(dt)) if float(t) > 2000.0: break info("Timestep %d, dt = %.3e, t = %.3e" % (j, float(dt), float(t))) time = Timer("ZZZ Do_step") ap.do_step(float(dt)) del time time = Timer("ZZZ PDE project assemble") pde_projection.assemble(True, True) del time time = Timer("ZZZ PDE project solve") pde_projection.solve_problem(psibar_h.cpp_object(), phi.cpp_object(), lambda_h.cpp_object(), 'mumps', 'default') del time gamma_assigner.assign(gamma0, phi) # Solve Stokes 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 velocity_assigner.assign(u_vec, Uh.sub(0))
t.assign(float(t) + float(dt)) if float(t) > 2000.0: break info("Timestep %d, dt = %.3e, t = %.3e" % (j, float(dt), float(t))) time = Timer("ZZZ Do_step") ap.do_step(float(dt)) del time time = Timer("ZZZ PDE project assemble") pde_projection.assemble(True, True) del time time = Timer("ZZZ PDE project solve") pde_projection.solve_problem(psibar_h.cpp_object(), phi.cpp_object(), lambda_h.cpp_object(), "mumps", "default") del time gamma_assigner.assign(gamma0, phi) # Solve Stokes 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 velocity_assigner.assign(u_vec, Uh.sub(0))
step += 1 t += float(dt) if comm.Get_rank() == 0: print("Step " + str(step) + ", time = " + str(t)) # Advect t1 = Timer("[P] advect particles") ap.do_step(float(dt)) del t1 # Project density and specific momentum t1 = Timer("[P] density projection") if projection_type == "PDE": pde_rho.assemble(True, True) pde_rho.solve_problem(rhobar, rho, "gmres", "hypre_amg") else: lstsq_rho.project(rho, float(rho2), float(rho1)) del t1 t1 = Timer("[P] momentum projection") if projection_type == "PDE": pde_u.assemble(True, True) pde_u.solve_problem(ustar_bar, ustar, "gmres", "hypre_amg") else: lstsq_u.project(ustar) del t1 t1 = Timer("[P] Computing conservation statements, just output!") # total_mass = assemble(rho * dx)
if comm.rank == 0: print("Step " + str(step)) # Advect particle, assemble and solve pde projection t1 = Timer("[P] Advect particles step") ap.do_step(float(dt)) AD.do_sweep_failsafe(4 * k) 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, psi_h, '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: psi0_expression.t = step * float(dt) l2_error_half = sqrt(
# 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))
old_area = assemble(phih0*dx) # Pre-assemble rhs pde_projection.assemble_state_rhs() # Advect the particles ap.do_step(float(dt)) # Move mesh umesh.assign(u_expre_neg) ALE.move(mesh, project(umesh * dt, Vcg)) # Relocate particles as a result of mesh motion ap.update_facets_info() 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, phih, 'mumps', 'none') # Area on new configuration new_area = assemble(phih*dx) # Update solution assign(phih0, phih) # Global mass error, should be machine precision print("Mass error "+str(new_area - old_area)) outfile << phih0
# 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 assign(Udiv, Uh.sub(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 assign(Udiv, Uh.sub(0))
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( dot(psi_h - psi0_expression, psi_h - psi0_expression) *
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
# 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))
timer = Timer("[P] Advection loop") timer.start() while step < num_steps: step += 1 # Advect particle, assemble and solve pde projection t1 = Timer("[P] Advect particles step") ap.do_step(float(dt)) del t1 if projection_type == "PDE": t1 = Timer("[P] Assemble PDE system") pde_projection.assemble(True, True) del t1 t1 = Timer("[P] Solve projection") pde_projection.solve_problem(psibar_h, psi_h, "superlu_dist", "default") del t1 else: t1 = Timer("[P] Solve projection") lstsq_psi.project(psi_h) del t1 t1 = 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 t1 timer.stop()
while step < num_steps: step += 1 if comm.rank == 0: print("Step number" + str(step)) # Advect particle, assemble and solve pde projection t1 = Timer("[P] Advect particles step") ap.do_step(float(dt)) del t1 if projection_type == "PDE": t1 = Timer("[P] Assemble PDE system") pde_projection.assemble(True, True) del t1 t1 = Timer("[P] Solve projection") pde_projection.solve_problem(psibar_h, psi_h, solver, "default") del t1 else: t1 = Timer("[P] Solve projection") lstsq_psi.project(psi_h) del t1 # The global mass conservation error should be zero area_n = assemble(psi_h * dx) t1 = Timer("[P] Assign & output") # Update old solution assign(psi0_h, psi_h) # Store some results if step % store_step == 0 or step == 1:
step += 1 t += float(dt) if comm.Get_rank() == 0: print("Step " + str(step) + ', time = ' + str(t)) # Advect t1 = Timer("[P] advect particles") ap.do_step(float(dt)) del (t1) # Project density and specific momentum t1 = Timer("[P] density projection") if projection_type == 'PDE': pde_rho.assemble(True, True) pde_rho.solve_problem(rhobar, rho, solver, "default") else: lstsq_rho.project(rho, float(rho2), float(rho1)) del (t1) t1 = Timer("[P] momentum projection") if projection_type == 'PDE': pde_u.assemble(True, True) pde_u.solve_problem(ustar_bar, ustar, solver, "default") else: lstsq_u.project(ustar) del (t1) t1 = Timer("[P] Computing conservation statements, just output!") # total_mass = assemble(rho * dx)
while step < num_steps: step += 1 t += float(dt) if comm.Get_rank() == 0: print("Step " + str(step) + ', time = ' + str(t)) # Advect t1 = Timer("[P] advect particles") ap.do_step(float(dt)) del (t1) # Project density and specific momentum t1 = Timer("[P] density projection") pde_rho.assemble(True, True) pde_rho.solve_problem(rhobar, rho, "mumps", "default") del (t1) t1 = Timer("[P] momentum projection") pde_u.assemble(True, True) try: pde_u.solve_problem(ustar_bar, ustar, "mumps", "default") except Exception: # FIXME: work-around lstsq_u.project(ustar) del (t1) # Solve Stokes t1 = Timer("[P] Stokes assemble ") ssc.assemble_global()
if comm.rank == 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 if projection_type == "PDE": t1 = Timer("[P] Assemble PDE system") pde_projection.assemble(True, True) del t1 t1 = Timer("[P] Solve projection") pde_projection.solve_problem(psibar_h, psi_h, "mumps", "default") del t1 else: t1 = Timer("[P] Solve projection") lstsq_psi.project(psi_h) 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
old_area = assemble(phih0 * dx) # Pre-assemble rhs pde_projection.assemble_state_rhs() # Advect the particles ap.do_step(float(dt)) # Move mesh umesh.assign(u_expre_neg) ALE.move(mesh, project(umesh * dt, Vcg)) # Relocate particles as a result of mesh motion ap.update_facets_info() 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, phih, "mumps", "none") # Area on new configuration new_area = assemble(phih * dx) # Update solution assign(phih0, phih) # Global mass error, should be machine precision print("Mass error " + str(new_area - old_area)) outfile << phih0