Esempio n. 1
0
def coarsen_function_space(V, self, coefficient_mapping=None):
    if hasattr(V, "_coarse"):
        return V._coarse
    fine = V
    indices = []
    while True:
        if V.index is not None:
            indices.append(V.index)
        if V.component is not None:
            indices.append(V.component)
        if V.parent is not None:
            V = V.parent
        else:
            break

    mesh = self(V.mesh(), self)

    Vf = V
    V = firedrake.FunctionSpace(mesh, V.ufl_element())

    from firedrake.dmhooks import get_transfer_operators, push_transfer_operators
    transfer = get_transfer_operators(Vf.dm)
    push_transfer_operators(V.dm, *transfer)
    if len(V) > 1:
        for V_, Vc_ in zip(Vf, V):
            transfer = get_transfer_operators(V_.dm)
            push_transfer_operators(Vc_.dm, *transfer)

    for i in reversed(indices):
        V = V.sub(i)
    V._fine = fine
    fine._coarse = V

    return V
Esempio n. 2
0
def coarsen_function_space(V, self, coefficient_mapping=None):
    if hasattr(V, "_coarse"):
        return V._coarse
    fine = V
    indices = []
    while True:
        if V.index is not None:
            indices.append(V.index)
        if V.component is not None:
            indices.append(V.component)
        if V.parent is not None:
            V = V.parent
        else:
            break

    mesh = self(V.mesh(), self)

    Vf = V
    V = firedrake.FunctionSpace(mesh, V.ufl_element())

    from firedrake.dmhooks import get_transfer_operators, push_transfer_operators
    transfer = get_transfer_operators(Vf.dm)
    push_transfer_operators(V.dm, *transfer)
    if len(V) > 1:
        for V_, Vc_ in zip(Vf, V):
            transfer = get_transfer_operators(V_.dm)
            push_transfer_operators(Vc_.dm, *transfer)

    for i in reversed(indices):
        V = V.sub(i)
    V._fine = fine
    fine._coarse = V

    return V
Esempio n. 3
0
    def compute_operators(ksp, J, P):
        r"""Form the Jacobian for this problem

        :arg ksp: a PETSc KSP object
        :arg J: the Jacobian (a Mat)
        :arg P: the preconditioner matrix (a Mat)
        """
        dm = ksp.getDM()
        ctx = dmhooks.get_appctx(dm)
        problem = ctx._problem

        assert J.handle == ctx._jac.petscmat.handle
        if problem._constant_jacobian and ctx._jacobian_assembled:
            # Don't need to do any work with a constant jacobian
            # that's already assembled
            return
        ctx._jacobian_assembled = True

        fine = ctx._fine
        if fine is not None:
            _, _, inject = dmhooks.get_transfer_operators(fine._x.function_space().dm)
            inject(fine._x, ctx._x)
            for bc in ctx._problem.bcs:
                bc.apply(ctx._x)

        ctx._assemble_jac()
        ctx._jac.force_evaluation()
        if ctx.Jp is not None:
            assert P.handle == ctx._pjac.petscmat.handle
            ctx._assemble_pjac()
            ctx._pjac.force_evaluation()
Esempio n. 4
0
    def compute_operators(ksp, J, P):
        r"""Form the Jacobian for this problem

        :arg ksp: a PETSc KSP object
        :arg J: the Jacobian (a Mat)
        :arg P: the preconditioner matrix (a Mat)
        """
        from firedrake.bcs import DirichletBC

        dm = ksp.getDM()
        ctx = dmhooks.get_appctx(dm)
        problem = ctx._problem
        assert J.handle == ctx._jac.petscmat.handle
        # TODO: Check how to use constant jacobian properly for TS
        if problem._constant_jacobian and ctx._jacobian_assembled:
            # Don't need to do any work with a constant jacobian
            # that's already assembled
            return
        ctx._jacobian_assembled = True

        fine = ctx._fine
        if fine is not None:
            manager = dmhooks.get_transfer_operators(
                fine._x.function_space().dm)
            manager.inject(fine._x, ctx._x)

            for bc in itertools.chain(*ctx._problem.bcs):
                if isinstance(bc, DirichletBC):
                    bc.apply(ctx._x)

        ctx._assemble_jac()

        if ctx.Jp is not None:
            assert P.handle == ctx._pjac.petscmat.handle
            ctx._assemble_pjac()
Esempio n. 5
0
def coarsen_function_space(V, self, coefficient_mapping=None):
    if hasattr(V, "_coarse"):
        return V._coarse
    from firedrake.dmhooks import (get_transfer_operators, get_parent,
                                   push_transfer_operators,
                                   pop_transfer_operators, push_parent,
                                   pop_parent, add_hook)
    fine = V
    indices = []
    while True:
        if V.index is not None:
            indices.append(V.index)
        if V.component is not None:
            indices.append(V.component)
        if V.parent is not None:
            V = V.parent
        else:
            break

    mesh = self(V.mesh(), self)

    V = firedrake.FunctionSpace(mesh, V.ufl_element())

    for i in reversed(indices):
        V = V.sub(i)
    V._fine = fine
    fine._coarse = V

    # FIXME: This replicates some code from dmhooks.coarsen, but we
    # can't do things there because that code calls this code.

    # We need to move these operators over here because if we have
    # fieldsplits + MG with auxiliary coefficients on spaces other
    # than which we do the MG, dm.coarsen is never called, so the
    # hooks are not attached. Instead we just call (say) inject which
    # coarsens the functionspace.
    cdm = V.dm
    transfer = get_transfer_operators(fine.dm)
    parent = get_parent(fine.dm)
    try:
        add_hook(parent,
                 setup=partial(push_parent, cdm, parent),
                 teardown=partial(pop_parent, cdm, parent),
                 call_setup=True)
        add_hook(parent,
                 setup=partial(push_transfer_operators, cdm, transfer),
                 teardown=partial(pop_transfer_operators, cdm, transfer),
                 call_setup=True)
    except ValueError:
        # Not in an add_hooks context
        pass

    return V