Example #1
0
def test_surf_approx(n, f, true=None):
    '''Surface integral (for benchmark problem)'''
    omega = UnitCubeMesh(n, n, 2 * n)

    A = np.array([0.5, 0.5, 0.0])
    B = np.array([0.5, 0.5, 1.0])
    gamma = StraightLineMesh(A, B, 2 * n)

    V3 = FunctionSpace(omega, 'CG', 1)
    V1 = FunctionSpace(gamma, 'CG', 1)

    f3 = interpolate(f, V3)

    shape = SquareRim(P=lambda x: np.array([0.25, 0.25, x[2]]), degree=10)

    Pi = average_matrix(V3, V1, shape=shape)
    x = Pi * f3.vector()

    f1 = Function(V1, x)

    if true is None:
        true = f
    error = sqrt(abs(assemble(inner(true - f1, true - f1) * dx)))

    return gamma.hmin(), error, f1
Example #2
0
def test_id(n, f, align=True):
    '''Surface integral (for benchmark problem)'''
    omega = UnitCubeMesh(n, n, 2 * n)

    A = np.array([0.5, 0.5, 0.0])
    B = np.array([0.5, 0.5, 1.0])

    lmbda = StraightLineMesh(A, B, 2 * n if align else n)  # The curve

    # Coupling surface
    walls = [
        'near((x[0]-0.25)*(x[0]-0.75), 0) && ((0.25-tol) < x[1]) && ((0.75+tol) > x[1])',
        'near((x[1]-0.25)*(x[1]-0.75), 0) && ((0.25-tol) < x[0]) && ((0.75+tol) > x[0])'
    ]
    walls = ['( %s )' % w for w in walls]

    chi = CompiledSubDomain(' || '.join(walls), tol=1E-10)
    surfaces = MeshFunction('size_t', omega, 2, 0)
    chi.mark(surfaces, 1)

    gamma = EmbeddedMesh(surfaces, 1)

    V3 = FunctionSpace(omega, 'CG', 1)
    V2 = FunctionSpace(gamma, 'CG', 1)
    V1 = FunctionSpace(lmbda, 'CG', 1)

    # What we want to extend
    f1 = interpolate(f, V1)
    # To 2d
    E = uniform_extension_matrix(V1, V2)
    x = E * f1.vector()
    f2 = Function(V2, x)
    # Extend to 3d by harmonic extension
    u, v = TrialFunction(V3), TestFunction(V3)
    a, L = inner(grad(u), grad(v)) * dx, inner(Constant(0), v) * dx
    bcs = [DirichletBC(V3, f, 'on_boundary'), DirichletBC(V3, f, surfaces, 1)]

    A, b = assemble_system(a, L, bcs)
    f3 = Function(V3)

    solver = KrylovSolver('cg', 'hypre_amg')
    solver.parameters['relative_tolerance'] = 1E-13

    solver.solve(A, f3.vector(), b)

    # Come back
    shape = SquareRim(P=lambda x: np.array([0.25, 0.25, x[2]]), degree=10)

    Pi = average_matrix(V3, V1, shape=shape)
    x = Pi * f3.vector()

    f10 = Function(V1, x)

    error = sqrt(abs(assemble(inner(f10 - f, f10 - f) * dx)))

    return gamma.hmin(), error, f10
Example #3
0
def worker_(f, n, radius=radius, degree=8):
    '''Check integrals due to averaging operator'''
    from weak_bcs.paper_daq.utils import circle_3d1d_conform

    mesh, entity_fs = circle_3d1d_conform(n=n, rad=radius)

    line_mesh = EmbeddedMesh(entity_fs[1], 1)

    V = FunctionSpace(mesh, 'CG', 1)
    TV = FunctionSpace(line_mesh, 'DG', 1)

    f = interpolate(f, V)

    cylinder = Circle(radius, degree)

    Pi = PETScMatrix(average_matrix(V, TV, cylinder))
    # print('\t', Pi.norm('linf'), max(len(Pi.getrow(i)[0]) for i in range(TV.dim())))

    Pi_f = Function(TV)
    Pi.mult(f.vector(), Pi_f.vector())

    return Pi_f
Example #4
0
def worker(f, n, radius=0.3, degree=8):
    '''Check integrals due to averaging operator'''
    mesh = BoxMesh(Point(-1, -1, -1), Point(1, 1, 1), n, n, n)

    mf = MeshFunction('size_t', mesh, 1, 0)
    CompiledSubDomain('near(x[0], 0.0) && near(x[1], 0.0)').mark(mf, 1)
    line_mesh = EmbeddedMesh(mf, 1)

    V = FunctionSpace(mesh, 'CG', 1)
    TV = FunctionSpace(line_mesh, 'DG', 1)

    f = interpolate(f, V)

    cylinder = Circle(radius, degree)

    Pi = PETScMatrix(average_matrix(V, TV, cylinder))
    # print('\t', Pi.norm('linf'), max(len(Pi.getrow(i)[0]) for i in range(TV.dim())))

    Pi_f = Function(TV)
    Pi.mult(f.vector(), Pi_f.vector())

    return Pi_f
Example #5
0
# We assemble now into block_mat objects (not necessarily matrices)
A, b = map(ii_assemble, (a, L))

# After the assembler pass; the block of A that involve coupling are not
# represented as matrices. Instead they are matrix expressions. For example
# the a[1][0] block is a product of M * Pi where Pi is the matrix representation
# of the averaging operator from V to PiV space and M is the mass matrix
# between PiV and Q
_, PiMat = A[1][0].chain
# Check that Pi really goes from V
assert PiMat.size(1) == V.dim()
# The PiV space is inferred by the assembler. If you are not happy with
# it you can always get the matrix representation your self
from xii.assembler.average_matrix import average_matrix
# Here we get it map to DG0 on the line
MyPiMat = average_matrix(V, FunctionSpace(mesh1d, 'DG', 0), shape=shape)
# Whily before DG1 was used
print 'inferred', PiMat.size(0), 'manual', MyPiMat.size(0)

# Suppose now that there are also boundary conditions; we specify them
# as a list for every subspace
V_bcs = [DirichletBC(V, Constant(0), 'near(x[2], 0)')]
Q_bcs = []
W_bcs = [V_bcs, Q_bcs]
# Apply
A, b = apply_bc(A, b, W_bcs)

# Just checking if the off-diagonal block sane
print '|A01| and |A10|', A[0][1].norm('linf'), A[1][0].norm('linf')
print '# Unknowns', sum(Wi.dim() for Wi in W)