def max_mesh_dimension(mesh: fd.Mesh): coords = mesh.coordinates MAXSP = fd.FunctionSpace(mesh, "R", 0) max_y = fd.Function(MAXSP) min_y = fd.Function(MAXSP) max_x = fd.Function(MAXSP) min_x = fd.Function(MAXSP) domain = "{[i, j] : 0 <= i < u.dofs}" def extract_comp(mode, comp, result): instruction = f""" component[0] = abs(u[i, {comp}]) """ fd.par_loop( (domain, instruction), fd.dx, { "u": (coords, fd.READ), "component": (result, mode) }, is_loopy_kernel=True, ) return result max_y_comp = extract_comp(fd.MAX, 1, max_y).dat.data[0] min_y_comp = extract_comp(fd.MIN, 1, min_y).dat.data[0] max_x_comp = extract_comp(fd.MAX, 0, max_x).dat.data[0] min_x_comp = extract_comp(fd.MIN, 0, min_x).dat.data[0] max_dim_x = abs(max_x_comp - min_x_comp) max_dim_y = abs(max_y_comp - min_y_comp) max_dim = max(max_dim_x, max_dim_y) if mesh.geometric_dimension() == 3: max_z = fd.Function(MAXSP) min_z = fd.Function(MAXSP) max_z_comp = extract_comp(fd.MAX, 2, max_z).dat.data[0] min_z_comp = extract_comp(fd.MIN, 2, min_z).dat.data[0] max_dim_z = abs(max_z_comp - min_z_comp) max_dim = max(max_dim, max_dim_z) return max_dim
def test_2D_dirichlet_regions(): # Can't do mesh refinement because MeshHierarchy ruins the domain tags mesh = Mesh("./2D_mesh.msh") dim = mesh.geometric_dimension() x = SpatialCoordinate(mesh) S = VectorFunctionSpace(mesh, "CG", 1) beta = 1.0 reg_solver = RegularizationSolver( S, mesh, beta=beta, gamma=0.0, dx=dx, design_domain=0 ) # Exact solution with free Neumann boundary conditions for this domain u_exact = Function(S) u_exact_component = (-cos(x[0] * pi * 2) + 1) * (-cos(x[1] * pi * 2) + 1) u_exact.interpolate( as_vector(tuple(u_exact_component for _ in range(dim))) ) f = Function(S) f_component = ( -beta * ( 4.0 * pi * pi * cos(2 * pi * x[0]) * (-cos(2 * pi * x[1]) + 1) + 4.0 * pi * pi * cos(2 * pi * x[1]) * (-cos(2 * pi * x[0]) + 1) ) + u_exact_component ) f.interpolate(as_vector(tuple(f_component for _ in range(dim)))) theta = TestFunction(S) rhs_form = inner(f, theta) * dx velocity = Function(S) rhs = assemble(rhs_form) reg_solver.solve(velocity, rhs) assert norm(project(domainify(u_exact, x) - velocity, S)) < 1e-3
def test_3D_dirichlet_regions(): # Can't do mesh refinement because MeshHierarchy ruins the domain tags mesh = Mesh("./3D_mesh.msh") dim = mesh.geometric_dimension() x = SpatialCoordinate(mesh) solver_parameters_amg = { "ksp_type": "cg", "ksp_converged_reason": None, "ksp_rtol": 1e-7, "pc_type": "hypre", "pc_hypre_type": "boomeramg", "pc_hypre_boomeramg_max_iter": 5, "pc_hypre_boomeramg_coarsen_type": "PMIS", "pc_hypre_boomeramg_agg_nl": 2, "pc_hypre_boomeramg_strong_threshold": 0.95, "pc_hypre_boomeramg_interp_type": "ext+i", "pc_hypre_boomeramg_P_max": 2, "pc_hypre_boomeramg_relax_type_all": "sequential-Gauss-Seidel", "pc_hypre_boomeramg_grid_sweeps_all": 1, "pc_hypre_boomeramg_truncfactor": 0.3, "pc_hypre_boomeramg_max_levels": 6, } S = VectorFunctionSpace(mesh, "CG", 1) beta = 1.0 reg_solver = RegularizationSolver( S, mesh, beta=beta, gamma=0.0, dx=dx, design_domain=0, solver_parameters=solver_parameters_amg, ) # Exact solution with free Neumann boundary conditions for this domain u_exact = Function(S) u_exact_component = ( (-cos(x[0] * pi * 2) + 1) * (-cos(x[1] * pi * 2) + 1) * (-cos(x[2] * pi * 2) + 1) ) u_exact.interpolate( as_vector(tuple(u_exact_component for _ in range(dim))) ) f = Function(S) f_component = ( -beta * ( 4.0 * pi * pi * cos(2 * pi * x[0]) * (-cos(2 * pi * x[1]) + 1) * (-cos(2 * pi * x[2]) + 1) + 4.0 * pi * pi * cos(2 * pi * x[1]) * (-cos(2 * pi * x[0]) + 1) * (-cos(2 * pi * x[2]) + 1) + 4.0 * pi * pi * cos(2 * pi * x[2]) * (-cos(2 * pi * x[1]) + 1) * (-cos(2 * pi * x[0]) + 1) ) + u_exact_component ) f.interpolate(as_vector(tuple(f_component for _ in range(dim)))) theta = TestFunction(S) rhs_form = inner(f, theta) * dx velocity = Function(S) rhs = assemble(rhs_form) reg_solver.solve(velocity, rhs) error = norm( project( domainify(u_exact, x) - velocity, S, solver_parameters=solver_parameters_amg, ) ) assert error < 5e-2
x, y, z = spatial_coord norm = sqrt(x**2 + y**2 + z**2) return Constant(1j / (4 * pi)) / norm * exp(1j * wave_number * norm) elif mesh_dim == 2: x, y = spatial_coord return Constant(1j / 4) * hankel_function( wave_number * sqrt(x**2 + y**2), n=80) raise ValueError("Only meshes of dimension 2, 3 supported") # Get the mesh and appropriate boundary tags mesh_file_name = 'meshes/circle_in_square/max0%25.msh' h = mesh_file_name[mesh_file_name.find('%') - 1:mesh_file_name.find('.')] mesh = Mesh(mesh_file_name) if mesh.geometric_dimension() == 2: scatterer_bdy_id = 1 outer_bdy_id = 2 else: scatterer_bdy_id = 1 outer_bdy_id = 3 # build fspace and bilinear forms fspace = FunctionSpace(mesh, 'CG', 1) u = TrialFunction(fspace) v = TestFunction(fspace) wave_number = 0.1 # one of [0.1, 1.0, 5.0, 10.0] true_sol = get_true_sol_expr(SpatialCoordinate(mesh), wave_number)