def F(self, x): if self._F is None: self._F = assemble_vector(self.L) else: with self._F.localForm() as f_local: f_local.set(0.0) self._F = assemble_vector(self._F, self.L) self._F.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE) return self._F
def _(b: PETSc.Vec, L: typing.List[FormMetaClass], constants=None, coeffs=None) -> PETSc.Vec: """Assemble linear forms into a nested PETSc (VecNest) vector. The vector is not zeroed before assembly and it is not finalised, i.e. ghost values are not accumulated on the owning processes. """ constants = [None] * len(L) if constants is None else constants coeffs = [None] * len(L) if coeffs is None else coeffs for b_sub, L_sub, const, coeff in zip(b.getNestSubVecs(), L, constants, coeffs): with b_sub.localForm() as b_local: assemble.assemble_vector(b_local.array_w, L_sub, const, coeff) return b
def F(self, x: PETSc.Vec, b: PETSc.Vec): """Assemble the residual F into the vector b. Parameters ---------- x The vector containing the latest solution b Vector to assemble the residual into """ # Reset the residual vector with b.localForm() as b_local: b_local.set(0.0) assemble_vector(b, self._L) # Apply boundary condition apply_lifting(b, [self._a], bcs=[self.bcs], x0=[x], scale=-1.0) b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE) set_bc(b, self.bcs, x, -1.0)
def assemble_vector(L: FormMetaClass, constants=None, coeffs=None) -> PETSc.Vec: """Assemble linear form into a new PETSc vector. Note: The returned vector is not finalised, i.e. ghost values are not accumulated on the owning processes. Args: L: A linear form. Returns: An assembled vector. """ b = la.create_petsc_vector(L.function_spaces[0].dofmap.index_map, L.function_spaces[0].dofmap.index_map_bs) with b.localForm() as b_local: assemble.assemble_vector(b_local.array_w, L, constants, coeffs) return b
def _(b: PETSc.Vec, L: FormMetaClass, constants=None, coeffs=None) -> PETSc.Vec: """Assemble linear form into an existing PETSc vector. Note: The vector is not zeroed before assembly and it is not finalised, i.e. ghost values are not accumulated on the owning processes. Args: b: Vector to assemble the contribution of the linear form into. L: A linear form to assemble into `b`. Returns: An assembled vector. """ with b.localForm() as b_local: assemble.assemble_vector(b_local.array_w, L, constants, coeffs) return b
def solve(self) -> Function: """Solve the problem.""" # Assemble lhs self._A.zeroEntries() assemble_matrix(self._A, self._a, bcs=self.bcs) self._A.assemble() # Assemble rhs with self._b.localForm() as b_loc: b_loc.set(0) assemble_vector(self._b, self._L) # Apply boundary conditions to the rhs apply_lifting(self._b, [self._a], bcs=[self.bcs]) self._b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE) set_bc(self._b, self.bcs) # Solve linear system and update ghost values in the solution self._solver.solve(self._b, self._x) self.u.x.scatter_forward() return self.u
def F(self, x, b): with b.localForm() as f_local: f_local.set(0.0) assemble_vector(b, self.L) b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)