def identity_test(n, shape, subd=I_curve): '''Averaging over indep coords of f''' true = df.Expression('x[2]*x[2]', degree=2) mesh = df.UnitCubeMesh(n, n, n) V = df.FunctionSpace(mesh, 'CG', 2) v = df.interpolate(true, V) f = df.MeshFunction('size_t', mesh, 1, 0) subd.mark(f, 1) line_mesh = EmbeddedMesh(f, 1) Q = average_space(V, line_mesh) q = df.Function(Q) Pi = avg_mat(V, Q, line_mesh, {'shape': shape}) Pi.mult(v.vector(), q.vector()) q0 = true # Error L = df.inner(q0 - q, q0 - q) * df.dx e = q.vector().copy() e.axpy(-1, df.interpolate(q0, Q).vector()) return df.sqrt(abs(df.assemble(L)))
def square_test(n, subd=I_curve): '''Averaging over indep coords of f''' size = 0.1 shape = Square(P=lambda x0: x0 - np.array( [size + size * x0[2], size + size * x0[2], 0]), degree=10) foo = df.Expression('x[2]*((x[0]-0.5)*(x[0]-0.5) + (x[1]-0.5)*(x[1]-0.5))', degree=3) mesh = df.UnitCubeMesh(n, n, n) V = df.FunctionSpace(mesh, 'CG', 3) v = df.interpolate(foo, V) f = df.MeshFunction('size_t', mesh, 1, 0) subd.mark(f, 1) true = df.Expression('x[2]*2./3*(size+size*x[2])*(size+size*x[2])', degree=4, size=size) line_mesh = EmbeddedMesh(f, 1) Q = average_space(V, line_mesh) q = df.Function(Q) Pi = avg_mat(V, Q, line_mesh, {'shape': shape}) Pi.mult(v.vector(), q.vector()) q0 = true # Error L = df.inner(q0 - q, q0 - q) * df.dx e = q.vector().copy() e.axpy(-1, df.interpolate(q0, Q).vector()) return df.sqrt(abs(df.assemble(L)))
def disk_test(n, subd=I_curve): '''Averaging over indep coords of f''' shape = Disk(radius=lambda x0: 0.1 + 0.0 * x0[2] / 2, degree=10) foo = df.Expression('x[2]*((x[0]-0.5)*(x[0]-0.5) + (x[1]-0.5)*(x[1]-0.5))', degree=3) mesh = df.UnitCubeMesh(n, n, n) V = df.FunctionSpace(mesh, 'CG', 3) v = df.interpolate(foo, V) f = df.MeshFunction('size_t', mesh, 1, 0) subd.mark(f, 1) true = df.Expression('x[2]*(0.1+0.0*x[2]/2)*(0.1+0.0*x[2]/2)/2', degree=4) line_mesh = EmbeddedMesh(f, 1) Q = average_space(V, line_mesh) q = df.Function(Q) Pi = avg_mat(V, Q, line_mesh, {'shape': shape}) Pi.mult(v.vector(), q.vector()) q0 = true # Error L = df.inner(q0 - q, q0 - q) * df.dx e = q.vector().copy() e.axpy(-1, df.interpolate(q0, Q).vector()) return df.sqrt(abs(df.assemble(L)))
def MeasureFunction(averaged): '''Get measure of the averaging shape as a function on the 1d surface''' # Get space on 1d mesh for the measure V = averaged.function_space() # 3d one # Want the measure in scalar space if V.ufl_element().value_shape(): V = V.sub(0).collapse() mesh_1d = averaged.average_['mesh'] # Finally TV = average_space(V, mesh_1d) TV_coordinates = TV.tabulate_dof_coordinates().reshape((TV.dim(), -1)) TV_dm = TV.dofmap() visited = np.zeros(TV.dim(), dtype=bool) mesh_x = mesh_1d.coordinates() shape = averaged.average_['shape'] values = np.empty(TV.dim(), dtype=float) for cell in cells(mesh_1d): # Get the tangent (normal of the plane which cuts the virtual # surface to yield the bdry curve v0, v1 = mesh_x[cell.entities(0)] n = v0 - v1 # Where to dofs = TV_dm.cell_dofs(cell.index()) for seen, dof in zip(visited[dofs], dofs): if not seen: x = TV_coordinates[dof] # Values sum up to the measure of the hypersurface values[dof] = sum(shape.quadrature(x, n).weights) visited[dof] = True assert np.all(visited) # Wrap as a function m = Function(TV) m.vector().set_local(values) return m
def render_avg_surface(Pi): '''Plot the averaging surface via looking at the quadrature points used''' V = Pi.function_space() line_mesh = Pi.average_['mesh'] shape = Pi.average_['shape'] # Where the average will be represented Pi_V = average_space(V, line_mesh) # We produce a curve of quardrature points for each dof surface = [] dm = Pi_V.dofmap() dofs_x = Pi_V.tabulate_dof_coordinates().reshape((Pi_V.dim(), -1)) for cell in df.cells(line_mesh): v0, v1 = cell.get_vertex_coordinates().reshape((2, 3)) n = v1 - v0 for dof_x in dofs_x[dm.cell_dofs(cell.index())]: x = np.row_stack(shape.quadrature(dof_x, n).points) surface.append(x) return surface
def sanity_test(n, subd, shape): '''Constant is preserved''' mesh = df.UnitCubeMesh(n, n, n) V = df.FunctionSpace(mesh, 'CG', 2) v = df.interpolate(df.Constant(1), V) f = df.MeshFunction('size_t', mesh, 1, 0) subd.mark(f, 1) line_mesh = EmbeddedMesh(f, 1) Q = average_space(V, line_mesh) q = df.Function(Q) Pi = avg_mat(V, Q, line_mesh, {'shape': shape}) Pi.mult(v.vector(), q.vector()) q0 = df.Constant(1) # Error L = df.inner(q0 - q, q0 - q) * df.dx e = q.vector().copy() e.axpy(-1, df.interpolate(q0, Q).vector()) return df.sqrt(abs(df.assemble(L)))