Example #1
0
    def initialize(self, pc):
        # Make a new DM.
        # Hook up a (new) coarsen routine on that DM.
        # Make a new PC, of type MG.
        # Assign the DM to that PC.

        odm = pc.getDM()
        ctx = get_appctx(odm)

        test, trial = ctx.J.arguments()
        if test.function_space() != trial.function_space():
            raise NotImplementedError("test and trial spaces must be the same")

        prefix = pc.getOptionsPrefix()
        options_prefix = prefix + "pmg_"
        pdm = PETSc.DMShell().create(comm=pc.comm)
        pdm.setOptionsPrefix(options_prefix)

        # Get the coarse degree from PETSc options
        self.coarse_degree = PETSc.Options(options_prefix).getInt("mg_coarse_degree", default=1)

        # Construct a list with the elements we'll be using
        V = test.function_space()
        ele = V.ufl_element()
        elements = [ele]
        while True:
            try:
                ele_ = self.coarsen_element(ele)
                assert ele_.value_shape() == ele.value_shape()
                ele = ele_
            except ValueError:
                break
            elements.append(ele)

        sf = odm.getPointSF()
        section = odm.getDefaultSection()
        attach_hooks(pdm, level=len(elements)-1, sf=sf, section=section)
        # Now overwrite some routines on the DM
        pdm.setRefine(None)
        pdm.setCoarsen(self.coarsen)
        pdm.setCreateInterpolation(self.create_interpolation)
        # We need this for p-FAS
        pdm.setCreateInjection(self.create_injection)
        pdm.setSNESJacobian(_SNESContext.form_jacobian)
        pdm.setSNESFunction(_SNESContext.form_function)
        pdm.setKSPComputeOperators(_SNESContext.compute_operators)

        set_function_space(pdm, get_function_space(odm))

        parent = get_parent(odm)
        assert parent is not None
        add_hook(parent, setup=partial(push_parent, pdm, parent), teardown=partial(pop_parent, pdm, parent), call_setup=True)
        add_hook(parent, setup=partial(push_appctx, pdm, ctx), teardown=partial(pop_appctx, pdm, ctx), call_setup=True)

        self.ppc = self.configure_pmg(pc, pdm)
        self.ppc.setFromOptions()
        self.ppc.setUp()
Example #2
0
 def _dm(self):
     from firedrake.mg.utils import get_level
     dm = self.dof_dset.dm
     _, level = get_level(self.mesh())
     dmhooks.attach_hooks(dm, level=level,
                          sf=self.mesh()._plex.getPointSF(),
                          section=None)
     # Remember the function space so we can get from DM back to FunctionSpace.
     dmhooks.set_function_space(dm, self)
     return dm
 def _dm(self):
     from firedrake.mg.utils import get_level
     dm = self.dof_dset.dm
     _, level = get_level(self.mesh())
     dmhooks.attach_hooks(dm, level=level,
                          sf=self.mesh()._plex.getPointSF(),
                          section=self._shared_data.global_numbering)
     # Remember the function space so we can get from DM back to FunctionSpace.
     dmhooks.set_function_space(dm, self)
     return dm
Example #4
0
 def _dm(self):
     from firedrake.mg.utils import get_level
     dm = self.dof_dset.dm
     _, level = get_level(self.mesh())
     dmhooks.attach_hooks(dm, level=level,
                          sf=self.mesh().topology_dm.getPointSF(),
                          section=self._shared_data.global_numbering)
     # Remember the function space so we can get from DM back to FunctionSpace.
     dmhooks.set_function_space(dm, self)
     return dm
Example #5
0
 def _dm(self):
     from firedrake.mg.utils import get_level
     dm = self.dof_dset.dm
     _, level = get_level(self.mesh())
     dmhooks.attach_hooks(dm, level=level)
     return dm
Example #6
0
    def initialize(self, pc):
        # Make a new DM.
        # Hook up a (new) coarsen routine on that DM.
        # Make a new PC, of type MG.
        # Assign the DM to that PC.

        odm = pc.getDM()
        ctx = get_appctx(odm)

        test, trial = ctx.J.arguments()
        if test.function_space() != trial.function_space():
            raise NotImplementedError("test and trial spaces must be the same")

        # Construct a list with the elements we'll be using
        V = test.function_space()
        ele = V.ufl_element()
        elements = [ele]
        while True:
            try:
                ele_ = self.coarsen_element(ele)
                assert ele_.value_shape() == ele.value_shape()
                ele = ele_
            except ValueError:
                break
            elements.append(ele)

        pdm = PETSc.DMShell().create(comm=pc.comm)
        sf = odm.getPointSF()
        section = odm.getDefaultSection()
        attach_hooks(pdm, level=len(elements) - 1, sf=sf, section=section)
        # Now overwrite some routines on the DM
        pdm.setRefine(None)
        pdm.setCoarsen(self.coarsen)
        pdm.setCreateInterpolation(self.create_interpolation)
        pdm.setOptionsPrefix(pc.getOptionsPrefix() + "pmg_")
        set_function_space(pdm, get_function_space(odm))

        parent = get_parent(odm)
        assert parent is not None
        add_hook(parent,
                 setup=partial(push_parent, pdm, parent),
                 teardown=partial(pop_parent, pdm, parent),
                 call_setup=True)
        add_hook(parent,
                 setup=partial(push_appctx, pdm, ctx),
                 teardown=partial(pop_appctx, pdm, ctx),
                 call_setup=True)

        ppc = PETSc.PC().create(comm=pc.comm)
        ppc.setOptionsPrefix(pc.getOptionsPrefix() + "pmg_")
        ppc.setType("mg")
        ppc.setOperators(*pc.getOperators())
        ppc.setDM(pdm)
        ppc.incrementTabLevel(1, parent=pc)

        # PETSc unfortunately requires us to make an ugly hack.
        # We would like to use GMG for the coarse solve, at least
        # sometimes. But PETSc will use this p-DM's getRefineLevels()
        # instead of the getRefineLevels() of the MeshHierarchy to
        # decide how many levels it should use for PCMG applied to
        # the p-MG's coarse problem. So we need to set an option
        # for the user, if they haven't already; I don't know any
        # other way to get PETSc to know this at the right time.
        opts = PETSc.Options(pc.getOptionsPrefix() + "pmg_")
        if "mg_coarse_pc_mg_levels" not in opts:
            opts["mg_coarse_pc_mg_levels"] = odm.getRefineLevel() + 1

        ppc.setFromOptions()
        ppc.setUp()
        self.ppc = ppc
 def _dm(self):
     from firedrake.mg.utils import get_level
     dm = self.dof_dset.dm
     _, level = get_level(self.mesh())
     dmhooks.attach_hooks(dm, level=level)
     return dm