Example #1
0
    def restrict(self, gf, gc):
        """Restrict a dual function.

        :arg gf: The source (fine grid) dual function.
        :arg gc: The target (coarse grid) dual function.
        """
        Vc = gc.function_space()
        Vf = gf.function_space()

        dgf = self.DG_work(Vf)
        dgc = self.DG_work(Vc)
        VDGf = dgf.function_space()
        VDGc = dgc.function_space()
        work = self.work_vec(Vf)
        dgwork = self.work_vec(VDGc)

        # g \in Vf^* -> g \in VDGf^*
        with gf.dat.vec_ro as gfv, dgf.dat.vec_wo as dgscratch:
            if self.use_fortin_interpolation:
                work.pointwiseDivide(gfv, self.V_dof_weights(Vf))
                self.V_approx_inv_mass(Vf, VDGf).multTranspose(work, dgscratch)
            else:
                self.V_inv_mass_ksp(Vf).solve(gfv, work)
                self.V_DG_mass(Vf, VDGf).mult(work, dgscratch)

        # g \in VDGf^* -> g \in VDGc^*
        firedrake.restrict(dgf, dgc)

        # g \in VDGc^* -> g \in Vc^*
        with dgc.dat.vec_ro as dgscratch, gc.dat.vec_wo as gcv:
            self.DG_inv_mass(VDGc).mult(dgscratch, dgwork)
            self.V_DG_mass(Vc, VDGc).multTranspose(dgwork, gcv)
Example #2
0
    def restrict(self, gf, gc):
        """Restrict a dual function.

        :arg gf: The source (fine grid) dual function.
        :arg gc: The target (coarse grid) dual function.
        """
        Vc = gc.function_space()
        Vf = gf.function_space()

        dgf = self.DG_work(Vf)
        dgc = self.DG_work(Vc)
        VDGf = dgf.function_space()
        VDGc = dgc.function_space()
        work = self.work_vec(Vf)
        dgwork = self.work_vec(VDGc)

        # g \in Vf^* -> g \in VDGf^*
        with gf.dat.vec_ro as gfv, dgf.dat.vec_wo as dgscratch:
            if self.use_fortin_interpolation:
                work.pointwiseDivide(gfv, self.V_dof_weights(Vf))
                self.V_approx_inv_mass(Vf, VDGf).multTranspose(work, dgscratch)
            else:
                self.V_inv_mass_ksp(Vf).solve(gfv, work)
                self.V_DG_mass(Vf, VDGf).mult(work, dgscratch)

        # g \in VDGf^* -> g \in VDGc^*
        firedrake.restrict(dgf, dgc)

        # g \in VDGc^* -> g \in Vc^*
        with dgc.dat.vec_ro as dgscratch, gc.dat.vec_wo as gcv:
            self.DG_inv_mass(VDGc).mult(dgscratch, dgwork)
            self.V_DG_mass(Vc, VDGc).multTranspose(dgwork, gcv)
Example #3
0
 def multTranspose(self, mat, x, y, inc=False):
     with self.ffn.dat.vec as v:
         x.copy(v)
     firedrake.restrict(self.ffn, self.cfn)
     for bc in self.cbcs:
         bc.zero(self.cfn)
     with self.cfn.dat.vec_ro as v:
         if inc:
             y.axpy(1.0, v)
         else:
             v.copy(y)
Example #4
0
 def multTranspose(self, mat, x, y, inc=False):
     with self.ffn.dat.vec as v:
         x.copy(v)
     firedrake.restrict(self.ffn, self.cfn)
     for bc in self.cbcs:
         bc.zero(self.cfn)
     with self.cfn.dat.vec_ro as v:
         if inc:
             y.axpy(1.0, v)
         else:
             v.copy(y)
Example #5
0
 def restrict(f, c):
     return firedrake.restrict(f, c)
Example #6
0
 def restrict(self, residual, out):
     Tf = residual
     for Tinter in reversed(self.intermediate_Ts):
         fd.restrict(Tf, Tinter)
         Tf = Tinter
     fd.restrict(Tf, out.fun)
Example #7
0
 def restrict(f, c):
     return firedrake.restrict(f, c)