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
Esempio n. 2
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