Exemple #1
0
    def get_error(wh, subdomains=subdomains, exact=exact):
        u1h, uh = wh

        sigma_exact, u_exact, p_exact, I_exact = exact

        V = uh.function_space()
        mesh = V.mesh()
        #
        # Recover the transmembrane potential by postprocessing
        #
        V = uh.function_space()
        mesh = V.mesh()
        interface_mesh = BoundaryMesh(mesh, 'exterior')

        V = FunctionSpace(interface_mesh, 'CG', 1)
        Tu1 = PETScMatrix(trace_mat_no_restrict(u1h.function_space(),
                                                V)) * u1h.vector()
        Tu = PETScMatrix(trace_mat_no_restrict(uh.function_space(),
                                               V)) * uh.vector()

        vh = Function(V, Tu1 - Tu)
        # On finer
        #V = FunctionSpace(interface_mesh, 'CG', 3)
        # Hs = matrix_fromHs(HsNorm(V, s=0.5))
        ## Use interpolate
        #vh = interpolate(vh, V)

        return (
            sqrt(H1_norm(u_exact[0], u1h)**2 + H1_norm(u_exact[1], uh)**2),
            sqrt(L2_norm(u_exact[0], u1h)**2 + L2_norm(u_exact[1], uh)**2),
            #Aerror(Hs, V, p_exact, vh))
            L2_norm(p_exact, vh))
Exemple #2
0
def get_diff(u_ext, u_int):
    V = u_int.function_space()
    mesh = V.mesh()
    interface_mesh = BoundaryMesh(mesh, 'exterior')
        
    V = FunctionSpace(interface_mesh, 'CG', 1)
    Tu_ext = PETScMatrix(trace_mat_no_restrict(u_ext.function_space(), V))*u_ext.vector()
    Tu_int = PETScMatrix(trace_mat_no_restrict(u_int.function_space(), V))*u_int.vector()
        
    vh = Function(V, Tu_ext - Tu_int)
    return vh
Exemple #3
0
def test_trace(n, f, true=None):
    '''Surface integral (for benchmark problem)'''
    omega = UnitCubeMesh(n, n, n)

    # 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)

    # What we want to extend
    f3 = interpolate(f, V3)

    T = PETScMatrix(trace_mat_no_restrict(V3, V2))
    x = T * f3.vector()
    f2 = Function(V2, x)

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

    return gamma.hmin(), error, f2
Exemple #4
0
def test_DLT():
    '''Injection of DLT dofs'''
    for n in (4, 8, 16, 32, 64):
        mesh = UnitSquareMesh(n, n)

        V = FunctionSpace(mesh, 'Discontinuous Lagrange Trace', 0)
        v = TestFunction(V)

        f = Expression('x[0]+2*x[1]', degree=1)

        fV = Function(V)
        assemble((1 / FacetArea(mesh)) * inner(f, v) * ds, tensor=fV.vector())

        facet_f = MeshFunction('size_t', mesh, 1, 0)
        DomainBoundary().mark(facet_f, 1)

        trace_mesh = EmbeddedMesh(facet_f, 1)
        TV = FunctionSpace(trace_mesh, 'DG', 0)

        T = PETScMatrix(trace_mat_no_restrict(V, TV, trace_mesh))

        gTV = Function(TV)
        gTV.vector()[:] = T * fV.vector()

        assert sqrt(abs(assemble(inner(gTV - f, gTV - f) * ds))) < 1E-13
Exemple #5
0
def test_vec_trace():
    mesh = UnitSquareMesh(10, 10)

    bdry = MeshFunction('size_t', mesh, 1, 0)
    DomainBoundary().mark(bdry, 1)
    bmesh = EmbeddedMesh(bdry, 1)

    V = FunctionSpace(mesh, 'CG', 2)
    TV = FunctionSpace(bmesh, 'CG', 2)

    Trace = PETScMatrix(trace_mat_no_restrict(V, TV, bmesh))

    f = Expression('sin(pi*(x[0]+x[1]))', degree=3)

    v = interpolate(f, V)
    Tv0 = interpolate(f, TV)

    Tv = Function(TV)
    Trace.mult(v.vector(), Tv.vector())

    Tv0.vector().axpy(-1, Tv.vector())
    assert Tv0.vector().norm('linf') < 1E-13
Exemple #6
0
def check(ncells, Qelm):
    mesh = UnitSquareMesh(*(ncells, ) * 2)
    bmesh = BoundaryMesh(mesh, 'exterior')

    V = FunctionSpace(mesh, 'CG', 1)
    Q = FunctionSpace(bmesh, Qelm(bmesh.ufl_cell()))

    u = TrialFunction(V)
    q = TestFunction(Q)

    n = FacetNormal(mesh)
    # Want grad(u).n * q
    v = TestFunction(V)

    a = inner(dot(grad(u), n), v) * ds
    A = assemble(a)
    # Now take it from testV to test Q

    T = PETScMatrix(trace_mat_no_restrict(V, Q, bmesh))

    B = ii_convert(T * A)

    # Now we should be able to integrate linear function exactly
    x, y = SpatialCoordinate(mesh)

    f = 2 * x + y
    g = x - 3 * y

    truth = assemble(inner(dot(grad(f), n), g) * ds)

    fV = interpolate(Expression('x[1] + 2*x[0]', degree=1), V)
    gQ = interpolate(Expression('x[0] - 3*x[1]', degree=1), Q)

    me = gQ.vector().inner(B * fV.vector())

    return abs(truth - me)
Exemple #7
0
    def get_error(wh,
                  subdomains=subdomains,
                  exact=exact,
                  mms=mms_data,
                  params=params):
        u1h, uh, ph = wh
        sigma_exact, u_exact, p_exact, I_exact = exact

        # Mutliplier error
        mesh = ph.function_space().mesh()
        Q = FunctionSpace(mesh, 'CG', 3)

        cell_f = MeshFunction('size_t', mesh, mesh.topology().dim(), 0)
        # Spaces on pieces
        for tag, subd in enumerate(subdomains, 1):
            CompiledSubDomain(subd, tol=1E-10).mark(cell_f, tag)
        dx = Measure('dx', domain=mesh, subdomain_data=cell_f)

        p, q = TrialFunction(Q), TestFunction(Q)
        a = inner(p, q) * dx
        L = sum(
            inner(I_exact_i, q) * dx(i)
            for i, I_exact_i in enumerate(I_exact, 1))
        I_exact = Function(Q)
        A, b = map(assemble, (a, L))
        solve(A, I_exact.vector(), b)

        V = uh.function_space()
        mesh = V.mesh()
        #
        # Recover the transmembrane potential by postprocessing
        #
        V = uh.function_space()
        mesh = V.mesh()
        interface_mesh = BoundaryMesh(mesh, 'exterior')

        V = FunctionSpace(interface_mesh, 'CG', 1)
        Tu1 = PETScMatrix(trace_mat_no_restrict(u1h.function_space(),
                                                V)) * u1h.vector()
        Tu = PETScMatrix(trace_mat_no_restrict(uh.function_space(),
                                               V)) * uh.vector()

        vh = Function(V, Tu1 - Tu)

        # Now using flux we have
        Q = ph.function_space()
        mesh = Q.mesh()

        cell_f = MeshFunction('size_t', mesh, mesh.topology().dim(), 0)
        # Spaces on pieces
        for tag, subd in enumerate(subdomains, 1):
            CompiledSubDomain(subd, tol=1E-10).mark(cell_f, tag)
        dx = Measure('dx', domain=mesh, subdomain_data=cell_f)

        p, q = TrialFunction(Q), TestFunction(Q)
        gGamma = mms.rhs[3]

        a = inner(p, q) * dx
        L = inner(params.eps * ph, q) * dx + sum(
            inner(gi, q) * dx(i) for i, gi in enumerate(gGamma, 1))
        A, b = map(assemble, (a, L))
        vh_P = Function(Q)  # Since we project
        solve(A, vh_P.vector(), b)

        vh_I = subdomain_interpolate(zip(gGamma, subdomains), Q)
        vh_I.vector().axpy(params.eps, ph.vector())

        # Simply by interpolation

        return (sqrt(H1_norm(u_exact[0], u1h)**2 + H1_norm(u_exact[1], uh)**2),
                L2_norm(p_exact, vh), L2_norm(p_exact,
                                              vh_P), L2_norm(p_exact, vh_I))
Exemple #8
0
def solve_problem(ncells, eps, solver_params):
    '''Optim problem on [0, 1]^2'''
    # Made up
    f = Expression('x[0] + x[1]', degree=1)

    mesh = UnitSquareMesh(*(ncells, ) * 2)
    bmesh = BoundaryMesh(mesh, 'exterior')

    Q = FunctionSpace(mesh, 'DG', 0)
    V = FunctionSpace(mesh, 'CG', 1)
    B = FunctionSpace(mesh, 'CG', 1)
    W = [Q, V, B]

    p, u, lmbda = list(map(TrialFunction, W))
    q, v, beta = list(map(TestFunction, W))
    Tu = Trace(u, bmesh)
    Tv = Trace(v, bmesh)

    # The line integral
    dxGamma = Measure('dx', domain=bmesh)

    a = [[0] * len(W) for _ in range(len(W))]

    a[0][0] = Constant(eps) * inner(p, q) * dx
    a[0][2] = inner(q, lmbda) * dx
    # We put zero on the diagonal temporarily and then replace by
    # the fractional laplacian
    a[1][1] = 0
    a[1][2] = inner(grad(v), grad(lmbda)) * dx + inner(v, lmbda) * dx

    a[2][0] = inner(p, beta) * dx
    a[2][1] = inner(grad(u), grad(beta)) * dx + inner(u, beta) * dx

    L = [
        inner(Constant(0), q) * dx,
        inner(Constant(0), v) * dx,  # Same replacement idea here
        inner(Constant(0), beta) * dx
    ]
    # All but (1, 1) and 1 are final
    AA, bb = list(map(ii_assemble, (a, L)))

    # Now I want and operator which corresponds to (Tv, (-Delta^{0.5} T_u))_bdry
    TV = FunctionSpace(bmesh, 'CG', 1)
    T = PETScMatrix(trace_mat_no_restrict(V, TV))
    # The fractional laplacian nodal->dual
    fDelta = HsNorm(TV, s=0.5)
    # This should be it
    A11 = block_transpose(T) * fDelta * T
    # Now, while here we can also comute the rhs contribution
    # (Tv, (-Delta^{0.5}, f))
    f_vec = interpolate(f, V).vector()
    b1 = A11 * f_vec
    bb[1] = b1
    AA[1][1] = A11

    wh = ii_Function(W)
    # Direct solve
    if not solver_params:
        AAm, bbm = list(map(ii_convert, (AA, bb)))
        LUSolver('umfpack').solve(AAm, wh.vector(), bbm)
        return wh, -1

    # Magne like precond
    if False:
        # Preconditioner like in the L2 case but with L2 bdry replaced
        b00 = Constant(eps) * inner(p, q) * dx
        B00 = LumpedInvDiag(ii_assemble(b00))

        H1 = ii_assemble(inner(grad(v), grad(u)) * dx + inner(v, u) * dx)
        # From dual to nodal
        R = LumpedInvDiag(ii_assemble(inner(u, v) * dx))
        # The whole matrix to be inverted is then (second term is H2 approx)
        B11 = collapse(A11 + eps * H1 * R * H1)
        # And the inverse
        B11 = AMG(B11, parameters={'pc_hypre_boomeramg_cycle_type': 'W'})

        b22 = Constant(1. / eps) * inner(lmbda, beta) * dx
        B22 = LumpedInvDiag(ii_assemble(b22))
    # A bit like SZ
    else:
        b00 = Constant(eps) * inner(p, q) * dx
        B00 = LumpedInvDiag(ii_assemble(b00))

        # L2 \cap eps H1
        H1 = assemble(
            Constant(eps) * (inner(grad(v), grad(u)) * dx + inner(v, u) * dx))
        B11 = AMG(collapse(A11 + H1))

        # (1./eps)*L2 \cap 1./sqrt(eps)H1
        a = Constant(1./eps)*inner(beta, lmbda)*dx + \
            Constant(1./sqrt(eps))*(inner(grad(beta), grad(lmbda))*dx + inner(beta, lmbda)*dx)
        B22 = AMG(assemble(a))

    BB = block_diag_mat([B00, B11, B22])

    # Want the iterations to start from random (iterative)
    wh.block_vec().randomize()

    # Default is minres
    if '-ksp_type' not in solver_params: solver_params['-ksp_type'] = 'minres'

    opts = PETSc.Options()
    for key, value in solver_params.items():
        opts.setValue(key, None if value == 'none' else value)

    ksp = PETSc.KSP().create()
    ksp.setOperators(ii_PETScOperator(AA))
    ksp.setPC(ii_PETScPreconditioner(BB, ksp))

    ksp.setNormType(PETSc.KSP.NormType.NORM_PRECONDITIONED)
    ksp.setFromOptions()

    ksp.solve(as_petsc_nest(bb), wh.petsc_vec())

    niters = ksp.getIterationNumber()

    return wh, niters
def solve_problem(ncells, eps, solver_params):
    '''Optim problem on [0, 1]^2'''
    # Made up
    f = Expression('x[0] + x[1]', degree=1)
    
    mesh = UnitSquareMesh(*(ncells, )*2)
    bmesh = BoundaryMesh(mesh, 'exterior')

    Q = FunctionSpace(mesh, 'DG', 0)
    V = FunctionSpace(mesh, 'CG', 1)
    B = FunctionSpace(mesh, 'CG', 1)
    W = [Q, V, B]

    p, u, lmbda = map(TrialFunction, W)
    q, v, beta = map(TestFunction, W)
    Tu = Trace(u, bmesh)
    Tv = Trace(v, bmesh)

    # The line integral
    dxGamma = Measure('dx', domain=bmesh)

    a = [[0]*len(W) for _ in range(len(W))]

    a[0][0] = Constant(eps)*inner(p, q)*dx
    a[0][2] = inner(q, lmbda)*dx
    # We put zero on the diagonal temporarily and then replace by
    # the fractional laplacian
    a[1][1] = 0
    a[1][2] = inner(grad(v), grad(lmbda))*dx + inner(v, lmbda)*dx

    a[2][0] = inner(p, beta)*dx
    a[2][1] = inner(grad(u), grad(beta))*dx + inner(u, beta)*dx

    L = [inner(Constant(0), q)*dx,
         inner(Constant(0), v)*dx,  # Same replacement idea here
         inner(Constant(0), beta)*dx]
    # All but (1, 1) and 1 are final
    AA, bb = map(ii_assemble, (a, L))

    # Now I want and operator which corresponds to (Tv, (-Delta^{0.5} T_u))_bdry
    TV = FunctionSpace(bmesh, 'CG', 1)
    T = PETScMatrix(trace_mat_no_restrict(V, TV))
    # The fractional laplacian nodal->dual
    fDelta = HsNorm(TV, s=0.5)
    # This should be it
    A11 = block_transpose(T)*fDelta*T
    # Now, while here we can also comute the rhs contribution
    # (Tv, (-Delta^{0.5}, f))
    f_vec = interpolate(f, V).vector()
    b1 = A11*f_vec
    bb[1] = b1
    AA[1][1] = A11

    wh = ii_Function(W)
    # Direct solve
    if not solver_params:
        AAm, bbm = map(ii_convert, (AA, bb))
        LUSolver('umfpack').solve(AAm, wh.vector(), bbm)
        return wh, -1


    # Magne like precond
    if False:
        # Preconditioner like in the L2 case but with L2 bdry replaced
        b00 = Constant(eps)*inner(p, q)*dx
        B00 = LumpedInvDiag(ii_assemble(b00))

        H1 = ii_assemble(inner(grad(v), grad(u))*dx + inner(v, u)*dx)
        # From dual to nodal
        R = LumpedInvDiag(ii_assemble(inner(u, v)*dx))
        # The whole matrix to be inverted is then (second term is H2 approx)
        B11 = collapse(A11 + eps*H1*R*H1)
        # And the inverse
        B11 = AMG(B11, parameters={'pc_hypre_boomeramg_cycle_type': 'W'})

        b22 = Constant(1./eps)*inner(lmbda, beta)*dx
        B22 = LumpedInvDiag(ii_assemble(b22))
    # A bit like SZ
    else:
        b00 = Constant(eps)*inner(p, q)*dx
        B00 = LumpedInvDiag(ii_assemble(b00))

        # L2 \cap eps H1
        H1 = assemble(Constant(eps)*(inner(grad(v), grad(u))*dx + inner(v, u)*dx))
        B11 = AMG(collapse(A11 + H1))

        # (1./eps)*L2 \cap 1./sqrt(eps)H1
        a = Constant(1./eps)*inner(beta, lmbda)*dx + \
            Constant(1./sqrt(eps))*(inner(grad(beta), grad(lmbda))*dx + inner(beta, lmbda)*dx)
        B22 = AMG(assemble(a))

    
    BB = block_diag_mat([B00, B11, B22])

    # Want the iterations to start from random (iterative)
    wh.block_vec().randomize()

    # Default is minres
    if '-ksp_type' not in solver_params: solver_params['-ksp_type'] = 'minres'
            
    opts = PETSc.Options()
    for key, value in solver_params.iteritems():
        opts.setValue(key, None if value == 'none' else value)
        
    ksp = PETSc.KSP().create()
    ksp.setOperators(ii_PETScOperator(AA))
    ksp.setPC(ii_PETScPreconditioner(BB, ksp))
    
    ksp.setNormType(PETSc.KSP.NormType.NORM_PRECONDITIONED)
    ksp.setFromOptions()
    
    ksp.solve(as_petsc_nest(bb), wh.petsc_vec())
    
    niters = ksp.getIterationNumber()

    return wh, niters