def is_linear(L, u): '''Is L linear in u''' # Compute the deriative dL = ii_convert(ii_assemble(ii_derivative(L, u))) if dL == 0: info('dL/du is zero') return None # Random guy w = Function(u.function_space()).vector() w.set_local(np.random.rand(w.local_size())) # Where we evaluate the direction dw = PETScVector(as_backend_type(dL).mat().getVecLeft()) dL.mult(w, dw) # Now L(u) + dw Lu_dw = ii_assemble(L) + dw # And if the thing is linear then L(u+dw) should be the same u.vector().axpy(1, w) Lu_dw0 = ii_assemble(L) return (Lu_dw - Lu_dw0).norm('linf'), Lu_dw0.norm( 'linf') #, dw.norm('linf')
def test_2d_incomplete(n=32, tol=1E-10): '''[|]''' mesh = UnitSquareMesh(n, n) cell_f = MeshFunction('size_t', mesh, 2, 2) CompiledSubDomain('x[0] < 0.5+DOLFIN_EPS').mark(cell_f, 1) left = EmbeddedMesh(cell_f, 1) right = EmbeddedMesh(cell_f, 2) facet_f = MeshFunction('size_t', left, 1, 0) CompiledSubDomain('near(x[0], 0.0)').mark(facet_f, 1) CompiledSubDomain('near(x[0], 0.5)').mark(facet_f, 2) CompiledSubDomain('near(x[1], 0.0)').mark(facet_f, 3) CompiledSubDomain('near(x[1], 1.0)').mark(facet_f, 4) # More complicated iface iface = EmbeddedMesh(facet_f, (1, 2, 3, 4)) # Right will interact with it in a simpler way facet_f = MeshFunction('size_t', right, 1, 0) CompiledSubDomain('near(x[0], 0.5)').mark(facet_f, 2) # We want to embed mappings = iface.compute_embedding(facet_f, 2) # Is it correct? xi, x = iface.coordinates(), right.coordinates() assert min(np.linalg.norm(xi[list(mappings[0].keys())]-x[list(mappings[0].values())], 2, 1)) < tol tdim = right.topology().dim()-1 right.init(tdim, 0) f2v = right.topology()(tdim, 0) icells = iface.cells() vertex_match = lambda xs, ys: all(min(np.linalg.norm(ys - x, 2, 1)) < tol for x in xs) assert all([vertex_match(xi[icells[key]], x[f2v(val)]) for key, val in list(mappings[tdim].items())]) try: iface.compute_embedding(facet_f, 2) except ValueError: pass V = FunctionSpace(right, 'CG', 2) u = interpolate(Expression('x[1]*x[1]', degree=1), V) # FIXME: this passes but looks weird dx_ = Measure('dx', domain=iface, subdomain_data=iface.marking_function) assert abs(ii_assemble(Trace(u, iface, tag=2)*dx_(2)) - 1./3) < tol
def test_2d(n=32, tol=1E-10): '''[|]''' mesh = UnitSquareMesh(n, n) cell_f = MeshFunction('size_t', mesh, 2, 2) CompiledSubDomain('x[0] < 0.5+DOLFIN_EPS').mark(cell_f, 1) left = EmbeddedMesh(cell_f, 1) right = EmbeddedMesh(cell_f, 2) facet_f = MeshFunction('size_t', left, 1, 0) CompiledSubDomain('near(x[0], 0.5)').mark(facet_f, 1) iface = EmbeddedMesh(facet_f, 1) # Now suppose facet_f = MeshFunction('size_t', right, 1, 0) CompiledSubDomain('near(x[0], 0.5)').mark(facet_f, 2) # We want to embed mappings = iface.compute_embedding(facet_f, 2) # Is it correct? xi, x = iface.coordinates(), right.coordinates() assert min(np.linalg.norm(xi[list(mappings[0].keys())]-x[list(mappings[0].values())], 2, 1)) < tol tdim = right.topology().dim()-1 right.init(tdim, 0) f2v = right.topology()(tdim, 0) icells = iface.cells() vertex_match = lambda xs, ys: all(min(np.linalg.norm(ys - x, 2, 1)) < tol for x in xs) assert all([vertex_match(xi[icells[key]], x[f2v(val)]) for key, val in list(mappings[tdim].items())]) try: iface.compute_embedding(facet_f, 2) except ValueError: pass V = FunctionSpace(right, 'CG', 1) u = interpolate(Expression('x[1]', degree=1), V) dx_ = Measure('dx', domain=iface) assert abs(ii_assemble(Trace(u, iface)*dx_) - 0.5) < tol
def test_3d(n=4, tol=1E-10): '''[|]''' mesh = UnitCubeMesh(n, n, n) cell_f = MeshFunction('size_t', mesh, 3, 2) CompiledSubDomain('x[0] < 0.5+DOLFIN_EPS').mark(cell_f, 1) left = EmbeddedMesh(cell_f, 1) facet_f = MeshFunction('size_t', left, 2, 0) CompiledSubDomain('near(x[0], 0.5)').mark(facet_f, 1) iface = EmbeddedMesh(facet_f, 1) # We want to embed mappings = iface.parent_entity_map[left.id()] # Is it correct? xi, x = iface.coordinates(), left.coordinates() assert min( np.linalg.norm( xi[list(mappings[0].keys())] - x[list(mappings[0].values())], 2, 1)) < tol tdim = left.topology().dim() - 1 left.init(tdim, 0) f2v = left.topology()(tdim, 0) icells = iface.cells() vertex_match = lambda xs, ys: all( min(np.linalg.norm(ys - x, 2, 1)) < tol for x in xs) assert all([ vertex_match(xi[icells[key]], x[f2v(val)]) for key, val in list(mappings[tdim].items()) ]) V = FunctionSpace(left, 'CG', 1) u = interpolate(Expression('x[0] + x[1]', degree=1), V) dx_ = Measure('dx', domain=iface) assert abs(ii_assemble(Trace(u, iface) * dx_) - 1.0) < tol
mesh = UnitSquareMesh(16, 16) V = VectorFunctionSpace(mesh, 'CG', 1) Vb = VectorFunctionSpace(mesh, 'Bubble', 3) u, v = TrialFunction(V), TestFunction(V) ub, vb = TrialFunction(Vb), TestFunction(Vb) b = [[0, 0], [0, 0]] b[0][0] = inner(grad(u), grad(v)) * dx + inner(u, v) * dx b[0][1] = inner(grad(ub), grad(v)) * dx + inner(ub, v) * dx b[1][0] = inner(grad(u), grad(vb)) * dx + inner(u, vb) * dx b[1][1] = inner(grad(ub), grad(vb)) * dx + inner(ub, vb) * dx BB = ii_assemble(b) x = Function(V).vector() x.set_local(np.random.rand(x.local_size())) y = Function(Vb).vector() y.set_local(np.random.rand(y.local_size())) bb = block_vec([x, y]) z_block = BB * bb # Make into a monolithic matrix BB_m = ii_convert(BB) R = ReductionOperator([2], W=[V, Vb]) z = (R.T) * BB_m * (R * bb)
def test(dt, ncells, w_exact): '''Want to solve a heat equation''' # Rest for f in w_exact: f.t = 0. # On a unit square left = CompiledSubDomain('near(x[0], 0)') rest = CompiledSubDomain('near(x[0], 1) || near(x[1]*(1-x[1]), 0)') mesh = UnitSquareMesh(ncells, ncells) boundaries = MeshFunction('size_t', mesh, 1, 0) left.mark(boundaries, 1) rest.mark(boundaries, 2) bmesh = EmbeddedMesh(boundaries, 1) V = FunctionSpace(mesh, 'CG', 1) Q = FunctionSpace(bmesh, 'CG', 1) W = [V, Q] u, p = list(map(TrialFunction, W)) v, q = list(map(TestFunction, W)) Tu, Tv = Trace(u, bmesh), Trace(v, bmesh) dx_ = Measure('dx', domain=bmesh) wh = ii_Function(W) a = block_form(W, 2) a[0][0] = inner(u, v) * dx + dt * inner(grad(u), grad(v)) * dx a[0][1] = inner(p, Tv) * dx_ a[1][0] = inner(q, Tu) * dx_ # Unpack data u_exact, p_exact, f_exact = w_exact p_exact.k = dt(0) L = block_form(W, 2) L[0] = inner(wh[0], v) * dx + dt * inner(f_exact, v) * dx L[1] = inner(u_exact, q) * dx_ bcs = [[DirichletBC(V, u_exact, boundaries, 2)], [DirichletBC(Q, Constant(0), 'on_boundary')]] A, b = list(map(ii_assemble, (a, L))) b_bc = block_rhs_bc(bcs, A) # Apply bcs to the system A_bc, _ = apply_bc(A, b, bcs) # Solver is setup based on monolithic A_mono = ii_convert(A_bc) print(('Setting up solver %d' % sum(Wi.dim() for Wi in W))) time_Ainv = Timer('Ainv') A_inv = PETScLUSolver(A_mono, 'umfpack') # Setup once print(('Done in %g s' % time_Ainv.stop())) time = 0 while time < 0.5: time += dt(0) f_exact.t = time u_exact.t = time # We don't need to reasamble the system #aux, b = map(ii_assemble, (a, L)) #_, b = apply_bc(aux, b, bcs) b = ii_assemble(L) b_bc.apply(b) b_ = ii_convert(b) x = wh.vector() A_inv.solve(x, b_) uh, ph = wh eu = errornorm(u_exact, uh, 'H1') ep = errornorm(p_exact, ph, 'L2') return mesh.hmin(), eu, ep
def test_2d_enclosed(n=32, tol=1E-10): ''' |----| | [] | |----| ''' mesh = UnitSquareMesh(n, n) # Lets get the outer part cell_f = MeshFunction('size_t', mesh, 2, 1) inside = '(x[0] > 0.25-DOLFIN_EPS) && (x[0] < 0.75+DOLFIN_EPS) && (x[1] > 0.25-DOLFIN_EPS) && (x[1] < 0.75+DOLFIN_EPS)' CompiledSubDomain(inside).mark(cell_f, 2) # Stokes --- mesh1 = EmbeddedMesh(cell_f, 1) bdries1 = MeshFunction('size_t', mesh1, mesh1.topology().dim()-1, 0) CompiledSubDomain('near(x[0], 0)').mark(bdries1, 10) CompiledSubDomain('near(x[0], 1)').mark(bdries1, 20) CompiledSubDomain('near(x[1], 0)').mark(bdries1, 30) CompiledSubDomain('near(x[1], 1)').mark(bdries1, 40) CompiledSubDomain('near(x[0], 0.25) && ((x[1] > 0.25-DOLFIN_EPS) && (x[1] < 0.75+DOLFIN_EPS))').mark(bdries1, 1) CompiledSubDomain('near(x[0], 0.75) && ((x[1] > 0.25-DOLFIN_EPS) && (x[1] < 0.75+DOLFIN_EPS))').mark(bdries1, 2) CompiledSubDomain('near(x[1], 0.25) && ((x[0] > 0.25-DOLFIN_EPS) && (x[0] < 0.75+DOLFIN_EPS))').mark(bdries1, 3) CompiledSubDomain('near(x[1], 0.75) && ((x[0] > 0.25-DOLFIN_EPS) && (x[0] < 0.75+DOLFIN_EPS))').mark(bdries1, 4) # Darcy --- mesh2 = EmbeddedMesh(cell_f, 2) bdries2 = MeshFunction('size_t', mesh2, mesh2.topology().dim()-1, 0) CompiledSubDomain('near(x[0], 0.25) && ((x[1] > 0.25-DOLFIN_EPS) && (x[1] < 0.75+DOLFIN_EPS))').mark(bdries2, 1) CompiledSubDomain('near(x[0], 0.75) && ((x[1] > 0.25-DOLFIN_EPS) && (x[1] < 0.75+DOLFIN_EPS))').mark(bdries2, 2) CompiledSubDomain('near(x[1], 0.25) && ((x[0] > 0.25-DOLFIN_EPS) && (x[0] < 0.75+DOLFIN_EPS))').mark(bdries2, 3) CompiledSubDomain('near(x[1], 0.75) && ((x[0] > 0.25-DOLFIN_EPS) && (x[0] < 0.75+DOLFIN_EPS))').mark(bdries2, 4) # ----------------- # And interface bmesh = EmbeddedMesh(bdries2, (1, 2, 3, 4)) # Embedded it viewwed from stokes mappings = bmesh.compute_embedding(bdries1, (1, 2, 3, 4)) xi, x = bmesh.coordinates(), mesh1.coordinates() assert min(np.linalg.norm(xi[list(mappings[0].keys())]-x[list(mappings[0].values())], 2, 1)) < tol tdim = mesh1.topology().dim()-1 mesh1.init(tdim, 0) f2v = mesh1.topology()(tdim, 0) icells = bmesh.cells() vertex_match = lambda xs, ys: all(min(np.linalg.norm(ys - x, 2, 1)) < tol for x in xs) assert all([vertex_match(xi[icells[key]], x[f2v(val)]) for key, val in list(mappings[tdim].items())]) try: bmesh.compute_embedding(bdries1, 2) except ValueError: pass V = VectorFunctionSpace(mesh1, 'CG', 1) u = interpolate(Expression(('x[1]', 'x[0]'), degree=1), V) dx_ = Measure('dx', domain=bmesh) n_ = OuterNormal(bmesh, [0.5, 0.5]) # Because it is divergence free assert abs(ii_assemble(dot(n_, Trace(u, bmesh))*dx_)) < tol
# These should be linear L = inner(Tu, q) * dxGamma assert is_linear(L, Function(V)) == None test(*is_linear(L, u)) # --------------------------------------------------------------- L = inner(Tu + Tu, q) * dxGamma test(*is_linear(L, u)) # --------------------------------------------------------------- # # Some simple nonlinearity where I can check things L = inner(Tu**2, q) * dxGamma dL0 = inner(2 * Tu * Trace(TrialFunction(V), bmesh), q) * dxGamma A0 = ii_convert(ii_assemble(dL0)).array() dL = ii_derivative(L, u) A = ii_convert(ii_assemble(dL)).array() test(np.linalg.norm(A - A0, np.inf), np.linalg.norm(A0, np.inf)) # --------------------------------------------------------------- L = inner(2 * Tu**3 - sin(Tu), q) * dxGamma dL0 = inner( (6 * Tu**2 - cos(Tu)) * Trace(TrialFunction(V), bmesh), q) * dxGamma A0 = ii_convert(ii_assemble(dL0)).array() dL = ii_derivative(L, u) A = ii_convert(ii_assemble(dL)).array()
V1d = FunctionSpace(Vmesh, 'CG', 1) Q = FunctionSpace(Emesh, 'CG', 1) W = [V3d, V1d, Q] u3d, u1d, p = list(map(TrialFunction, W)) v3d, v1d, q = list(map(TestFunction, W)) Tu3d, Tv3d = (Trace(f, Emesh) for f in (u3d, v3d)) Eu1d, Ev1d = (Extension(f, Emesh, type='uniform') for f in (u1d, v1d)) # Cell integral of Qspace dxLM = Measure('dx', domain=Emesh) a = inner(Ev1d, p) * dxLM A = ii_assemble(a) # Let's use the matrix to perform the following integral p_expr = Expression('x[0]-2*x[1]+3*x[2]', degree=1) # Something which can be extended exactly v_expr = Expression('2*x[2]', degree=1) true = assemble(inner(p_expr, v_expr) * dxLM) p_func = interpolate(p_expr, Q) v_func = interpolate(v_expr, V1d) # Quadrature num = v_func.vector().inner(A * p_func.vector()) print('>', abs(num - true), (true, num)) # Check the transpose as well a = inner(Eu1d, q) * dxLM
# And thhe multiplier one mesh_lm = EmbeddedMesh(facet_f, 2) V_2d = FunctionSpace(mesh, 'CG', 1) V_1d = FunctionSpace(mesh_1d, 'CG', 1) Q = FunctionSpace(mesh_lm, 'CG', 1) # We are after (Trace(V_2d) - Ext(V_1d), Q) q = TestFunction(Q) u2d, u1d = TrialFunction(V_2d), TrialFunction(V_1d) Tu2d = Trace(u2d, mesh_lm) Eu1d = Extension(u1d, mesh_lm, type='uniform') dxLM = Measure('dx', domain=mesh_lm) T = ii_assemble(inner(Tu2d, q) * dxLM) E = ii_assemble(inner(q, Eu1d) * dxLM) f2d = Expression('1+x[0]+2*x[1]', degree=1) # The extended function will practically be shifted so I want invariance # in that case f1d = Expression('2-x[1]', degree=1) # LM is free fLM = Expression('4-2*x[1]+x[0]', degree=1) # What we are after true = assemble(inner(f2d - f1d, fLM) * dxLM) # How do we get it? f2d_ = interpolate(f2d, V_2d) f1d_ = interpolate(f1d, V_1d)
def __init__(self, mesh, orientation): if orientation is None: # We assume convex domain and take center as ... orientation = mesh.coordinates().mean(axis=0) if isinstance(orientation, df.Mesh): # We set surface normal as outer with respect to orientation mesh assert orientation.id() in mesh.parent_entity_map n = df.FacetNormal(orientation) hA = df.FacetArea(orientation) # Project normal, we have a function on mesh DLT = df.VectorFunctionSpace(orientation, 'Discontinuous Lagrange Trace', 0) n_ = df.Function(DLT) df.assemble((1 / hA) * df.inner(n, df.TestFunction(DLT)) * df.ds, tensor=n_.vector()) # Now we get it to manifold dx_ = df.Measure('dx', domain=mesh) V = df.VectorFunctionSpace(mesh, 'DG', 0) df.Function.__init__(self, V) hK = df.CellVolume(mesh) n_vec = xii.ii_convert( xii.ii_assemble( (1 / hK) * df.inner(xii.Trace(n_, mesh), df.TestFunction(V)) * dx_)) self.vector()[:] = n_vec return None # Manifold assumption assert 1 <= mesh.topology().dim() < mesh.geometry().dim() gdim = mesh.geometry().dim() # Orientation from inside point if isinstance(orientation, (list, np.ndarray, tuple)): assert len(orientation) == gdim kwargs = {'x0%d' % i: val for i, val in enumerate(orientation)} orientation = ['x[%d] - x0%d' % (i, i) for i in range(gdim)] orientation = df.Expression(orientation, degree=1, **kwargs) assert orientation.ufl_shape == (gdim, ) V = df.VectorFunctionSpace(mesh, 'DG', 0, gdim) df.Function.__init__(self, V) n_values = self.vector().get_local() X = mesh.coordinates() dd = X[np.argmin(X[:, 0])] - X[np.argmax(X[:, 0])] values = [] R = np.array([[0, -1], [1, 0]]) for cell in df.cells(mesh): n = cell.cell_normal().array()[:gdim] x = cell.midpoint().array()[:gdim] # Disagree? if np.inner(orientation(x), n) < 0: n *= -1. values.append(n / np.linalg.norm(n)) values = np.array(values) for sub in range(gdim): dofs = V.sub(sub).dofmap().dofs() n_values[dofs] = values[:, sub] self.vector().set_local(n_values) self.vector().apply('insert')