Exemplo n.º 1
0
    def F(self, snes: PETSc.SNES, x: PETSc.Vec, b: PETSc.Vec):
        """Assemble the residual F into the vector b.

        Parameters
        ==========
        snes: the snes object
        x: Vector containing the latest solution.
        b: Vector to assemble the residual into.
        """
        # We need to assign the vector to the function

        x.ghostUpdate(addv=PETSc.InsertMode.INSERT,
                      mode=PETSc.ScatterMode.FORWARD)
        x.copy(self.u.vector)
        self.u.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT,
                                  mode=PETSc.ScatterMode.FORWARD)

        # Zero the residual vector
        # import pdb; pdb.set_trace()
        with b.localForm() as b_local:
            b_local.set(0.0)
        assemble_vector(b, self.F_form)

        # Apply boundary conditions
        apply_lifting(b, [self.J_form], [self.bcs], [x], -1.0)
        b.ghostUpdate(addv=PETSc.InsertMode.ADD,
                      mode=PETSc.ScatterMode.REVERSE)
        set_bc(b, self.bcs, x, -1.0)
    def f1(self, t: float, u: PETSc.Vec, v: PETSc.Vec, result: PETSc.Vec) -> PETSc.Vec:
        """For dv/dt = f(t, u, v), compute and return f"""
        # # Update boundary condition
        # with self.g.vector.localForm() as g_local:
        #     g_local.set(-2 * self.omega / self.c * np.cos(self.omega * t))

        # Set up plane wave incident field - it's made of two parts, a cosine
        # and a sine, which are multiplied by cos(omega*t) and sin(omega*t)
        # later on
        with self.g1.vector.localForm() as g1_local:
            g1_local.set(np.cos(self.omega * t))

        with self.g2.vector.localForm() as g2_local:
            g2_local.set(np.sin(self.omega * t))

        # Update fields that f depends on
        u.copy(result=self.u.vector)
        self.u.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT,
                                  mode=PETSc.ScatterMode.FORWARD)
        v.copy(result=self.v.vector)
        self.v.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT,
                                  mode=PETSc.ScatterMode.FORWARD)
        # Assemble b
        if self.b is None:
            self.b = dolfinx.fem.assemble_vector(self.L1)
        else:
            with self.b.localForm() as b_local:
                b_local.set(0.0)
            dolfinx.fem.assemble_vector(self.b, self.L1)
        self.b.ghostUpdate(addv=PETSc.InsertMode.ADD,
                           mode=PETSc.ScatterMode.REVERSE)

        if result is None:
            result = v.duplicate()

        # Solve
        if self.lumped:
            result.pointwiseDivide(self.b, self.M)
        else:
            self.solver.solve(self.b, result)

        return result
Exemplo n.º 3
0
    def f1(self, t: float, u: PETSc.Vec, v: PETSc.Vec,
           result: PETSc.Vec) -> PETSc.Vec:
        """For dv/dt = f(t, u, v), return f"""

        # Plane wave
        with self.g.vector.localForm() as g_local:
            g_local.set(-2 * self.omega / self.c * self.a *
                        np.cos(self.omega * t))

        with self.g_deriv.vector.localForm() as g_deriv_local:
            g_deriv_local.set(2 * self.omega**2 / self.c * self.a *
                              np.sin(self.omega * t))

        # Update fields that f depends on
        u.copy(result=self.u.vector)
        self.u.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT,
                                  mode=PETSc.ScatterMode.FORWARD)
        v.copy(result=self.v.vector)
        self.v.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT,
                                  mode=PETSc.ScatterMode.FORWARD)

        # Assemble
        if self.b is None:
            self.b = dolfinx.fem.assemble_vector(self.L1)
        else:
            with self.b.localForm() as b_local:
                b_local.set(0.0)
            dolfinx.fem.assemble_vector(self.b, self.L1)
        self.b.ghostUpdate(addv=PETSc.InsertMode.ADD,
                           mode=PETSc.ScatterMode.REVERSE)

        # Solve
        if result is None:
            result = v.duplicate()
        if self.lumped:
            result.pointwiseDivide(self.b, self.M)
        else:
            self.solver.solve(self.b, result)

        return result
Exemplo n.º 4
0
 def f0(self, t: float, u: PETSc.Vec, v: PETSc.Vec,
        result: PETSc.Vec) -> PETSc.Vec:
     """For du/dt = f(t, u, v), return f"""
     return v.copy(result=result)