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_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_l2projection_bounded(polynomial_order, lb, ub): # Test l2 projection if it stays within bounds given by lb and ub interpolate_expression = SlottedDisk(radius=0.15, center=[0.5, 0.5], width=0.05, depth=0., degree=3, lb=lb, ub=ub) xmin, xmax = 0., 1. ymin, ymax = 0., 1. property_idx = 5 mesh = RectangleMesh(Point(xmin, ymin), Point(xmax, ymax), 40, 40) V = FunctionSpace(mesh, "DG", polynomial_order) x = RandomRectangle(Point(xmin, ymin), Point(xmax, ymax)).generate([500, 500]) s = assign_particle_values(x, interpolate_expression) # Just make a complicated particle, possibly with scalars and vectors mixed p = particles(x, [x, s, x, x, s], mesh) vh = Function(V) lstsq_rho = l2projection(p, V, property_idx) lstsq_rho.project(vh, lb, ub) # Assert if it stays within bounds assert np.all(vh.vector().get_local() < ub + 1e-12) assert np.all(vh.vector().get_local() > lb - 1e-12)
def test_l2projection(polynomial_order, in_expression): # Test l2 projection for scalar and vector valued expression interpolate_expression = Expression(in_expression, degree=3) xmin, xmax = 0., 1. ymin, ymax = 0., 1. property_idx = 5 mesh = RectangleMesh(Point(xmin, ymin), Point(xmax, ymax), 40, 40) 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.interpolate(interpolate_expression) x = RandomRectangle(Point(xmin, ymin), Point(xmax, ymax)).generate([500, 500]) s = assign_particle_values(x, interpolate_expression) # Just make a complicated particle, possibly with scalars and vectors mixed p = particles(x, [x, s, x, x, s], mesh) vh = Function(V) lstsq_rho = l2projection(p, V, property_idx) lstsq_rho.project(vh) error_sq = abs(assemble(dot(v_exact - vh, v_exact - vh) * dx)) assert error_sq < 1e-15
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
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_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)
def test_mesh_generator_2d(): """Basic functionality test.""" mesh = RectangleMesh(Point(0.0, 0.0), Point(1.0, 1.0), 5, 5) for x in mesh.coordinates(): x[0] += 0.5 * x[1] w = RandomCell(mesh) pts = w.generate(3) assert len(pts) == mesh.num_cells() * 3 interpolate_expression = Expression("x[0] + x[1]", degree=1) s = assign_particle_values(pts, interpolate_expression, on_root=False) p = particles(pts, [s], mesh) assert np.linalg.norm(np.sum(pts, axis=1) - s) <= 1e-15 assert np.linalg.norm(pts - p.positions()) <= 1e-15
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
def test_mesh_generator_3d(): """Basic functionality test.""" mesh = BoxMesh(Point(0.0, 0.0, 0.0), Point(1.0, 1.0, 1.0), 5, 5, 5) for x in mesh.coordinates(): x[0] += 0.5 * x[1] + 0.2 * x[2] w = RandomCell(mesh) pts = w.generate(3) assert len(pts) == mesh.num_cells() * 3 interpolate_expression = Expression("x[0] + x[1] + x[2]", degree=1) s = assign_particle_values(pts, interpolate_expression, on_root=False) assert np.linalg.norm(np.sum(pts, axis=1) - s) <= 1e-15 p = particles(pts, [s], mesh) assert pts.shape == p.positions().shape for i in range(10000): s, t, u, v = w._random_bary(4) assert s >= 0 and s <= 1 assert t >= 0 and t <= 1 assert u >= 0 and u <= 1 assert v >= 0 and v <= 1
def read_calving_front_sim(fname_base): fname_ext = '.npz' fname = fname_base + fname_ext print(fname) # Load particle data if path.exists(fname): tracer_data = np.load(fname) else: print('Cannot read file') t = tracer_data['t'].item() # Load mesh mesh_file = fname_base + '.xml' mesh = Mesh(mesh_file) # Make particle class n = len(tracer_data['xm']) xp = np.vstack( (tracer_data['xm'], tracer_data['zm'])).transpose().reshape(n, 2) pstrain = tracer_data['strain'] pepsII = tracer_data['epsII'] ptemp = tracer_data['temp'] p = particles(xp, [pstrain, ptemp, pepsII], mesh) # Interpolate particles to mesh Vdg = FunctionSpace(mesh, 'DG', 1) strain = Function(Vdg) lstsq_strain = l2projection(p, Vdg, 1) # First variable??? lstsq_strain.project_mpm(strain) # Projection is stored in phih0 # Boundary mesh with portion above sea level marked bmesh = BoundaryMesh(mesh, 'exterior', order=True) x = bmesh.coordinates() #ymax = np.max(x[x[:,0]==0,1]) filter = (x[:, 0] > 1e-4) & (x[:, 1] > 0) xm = np.min(x[filter, 0]) id = np.argwhere(x[:, 0] == xm).item() # Check if nodes increasing or decreasing if (x[id - 1, 0] > x[id, 0]): # Decrease nodes inc = -1 stop = 0 else: # Increase nodes inc = 1 stop = len(x) iold = id for i in range(id, stop, inc): if x[i, 1] > 0.0: slope = (x[i, 1] - x[iold, 1]) / (x[i, 0] - x[iold, 0]) #print(x[i,0],strain(x[i]),strain(x[i])>0.99,slope,slope<-pi/3) #print(-slope*180/pi) if strain(x[i]) > 0.1: L = x[iold, 0] break elif np.abs(slope) > pi / 6: L = x[iold, 0] break iold = i print('Terminus position', L) # Extract profile centered on terminus filter = (x[:, 1] > 0.0) & (x[:, 0] > 10) & (x[:, 0] < L + 5 * 800) xp = x[filter, 0] - L zp = x[filter, 1] idx = np.argsort(xp) xp = xp[idx] zp = zp[idx] zp = gaussian_filter(zp, 1.5) #fname = fname_base + 'term_pos.npz' #print(fname) return xp, zp
def read_files(fname_base): L = [] t = [] for step in range(0, 1000000, 10): fname_ext = str(step).zfill(3) + '.npz' fname = fname_base + fname_ext print(fname) # Load particle data if path.exists(fname): tracer_data = np.load(fname) else: print('Cannot read file') break t.append(tracer_data['t'].item()) # Load mesh mesh_file = fname_base + str(step).zfill(3) + '.xml' mesh = Mesh(mesh_file) # Make particle class n = len(tracer_data['xm']) xp = np.vstack( (tracer_data['xm'], tracer_data['zm'])).transpose().reshape(n, 2) pstrain = tracer_data['strain'] pepsII = tracer_data['epsII'] ptemp = tracer_data['temp'] p = particles(xp, [pstrain, ptemp, pepsII], mesh) # Interpolate particles to mesh Vdg = FunctionSpace(mesh, 'DG', 1) strain = Function(Vdg) lstsq_strain = l2projection(p, Vdg, 1) # First variable??? lstsq_strain.project_mpm(strain) # Projection is stored in phih0 # Boundary mesh with portion above sea level marked bmesh = BoundaryMesh(mesh, 'exterior', order=True) x = bmesh.coordinates() #ymax = np.max(x[x[:,0]==0,1]) filter = (x[:, 0] > 1e-4) & (x[:, 1] > 0) xm = np.min(x[filter, 0]) id = np.argwhere(x[:, 0] == xm).item() # Check if nodes increasing or decreasing if (x[id - 1, 0] > x[id, 0]): # Decrease nodes inc = -1 stop = 0 else: # Increase nodes inc = 1 stop = len(x) iold = id for i in range(id, stop, inc): if x[i, 1] > 0.0: slope = (x[i, 1] - x[iold, 1]) / (x[i, 0] - x[iold, 0]) #print(x[i,0],strain(x[i]),strain(x[i])>0.99,slope,slope<-pi/3) #print(-slope*180/pi) if strain(x[i]) > 0.99: L.append(x[iold, 0]) break elif np.abs(slope) > pi / 6: L.append(x[iold, 0]) break iold = i print('Terminus position', L[-1]) if i == stop - inc: print('No terminus identified') L.append(np.Nan) fname = fname_base + 'term_pos.npz' print(fname) # Least squares fit to data #if len(t)>len(L): # print('Not equal') # t =t[0:-1] print(len(t), len(L)) t = np.array(t) L = np.array(L) filter = (t > 2 / 12) # t, L = np.array(t), np.array(L) dLdt, b, rvalue, pvalue1, err = linregress(t[filter], L[filter]) print('Rate of terminus advance', dLdt, 'Errror', err) np.savez(fname, t=t, L=L, dLdt=dLdt, err=err, pvalue=pvalue1, rvalue=rvalue) return None
uh = Function(V) uh.assign(Expression(("-Uh*x[1]", "Uh*x[0]"), Uh=Uh, degree=3)) psi0_expression = GaussianPulse(center=(xc, yc), 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)
temp_fun = temp_init(Ts, Tb, surf_fun, bed_fun, degree=1) # Create functions defined on mesh with initial values strain_mesh.assign(strain_init) temp_mesh.assign(interpolate(temp_fun, Vdg)) epsII_mesh.assign(strain_init) # Particle values at nodes pstrain = assign_particle_values(xp, strain_fun) pepsII = assign_particle_values(xp, strain_fun) ptemp = assign_particle_values(xp, temp_fun) print('Done initializing function spaces') # Now we initialize the particle class print('Creating particles') p = particles(xp, [pstrain, ptemp, pepsII], mesh.mesh) print('Done particles') # Make sure we have enough particles per cell #AD = AddDelete(p, p_min, p_max, [strain_mesh, temp_mesh,epsII_mesh]) # Sweep over mesh to delete/insert particles #AD.do_sweep() (xp, pstrain, ptemp, pepsII) = (p.return_property(mesh, 0), p.return_property(mesh, 1), p.return_property(mesh, 2), p.return_property(mesh, 3)) #_____________________________________________ # Initialize temperature model print('Initializing temperature') Tmodel = tempModel(mesh.mesh, Tb=Tb, Ts=Ts) x = SpatialCoordinate(mesh.mesh) zb = bot_fun(x[0])
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
Uhbar0 = Function(mixedG) # Set initial density field initial_density = BinaryBlock(geometry, float(rho1), float(rho2), degree=1) zero_expression = Expression(("0.", "0."), degree=1) # Initialize particles x = RandomRectangle(Point(xmin, ymin), Point(xmax, ymax)).generate( [pres, int(pres * (ymax - ymin) / (xmax - xmin))]) up = assign_particle_values(x, zero_expression) 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()
ALE.move(mesh, displacement) # Entrainment functional measures de = 1 cf = MeshFunction("size_t", mesh, mesh.topology().dim(), 0) CompiledSubDomain("x[1] > db - DOLFIN_EPS", db=db).mark(cf, de) dx = Measure("dx", subdomain_data=cf) # Setup particles pres = 25 x = RandomBox(Point(xmin, ymin, zmin), Point(xmax, ymax, zmax)).generate([pres, pres, pres]) s = np.zeros((len(x), 1), dtype=np.float_) # Interpolate initial function onto particles, index slot 1 property_idx = 1 ptcls = particles(x, [s], mesh) # Define the variational (projection problem) k = 1 W_e = FiniteElement("DG", mesh.ufl_cell(), k) T_e = FiniteElement("DG", mesh.ufl_cell(), 0) Wbar_e = FiniteElement("DGT", mesh.ufl_cell(), k) # Composition field space Wh = FunctionSpace(mesh, W_e) Th = FunctionSpace(mesh, T_e) Wbarh = FunctionSpace(mesh, Wbar_e) phi = interpolate(StepFunction(), Wh) gamma0 = interpolate(StepFunction(), Wh)