*/
PreconditionShell(const MPI_Comm &communicator);
-
/**
- * The callback for the application of the preconditioner. Defaults to
- * a copy operation if not provided.
+ * The callback for the application of the preconditioner.
*/
- std::function<int(VectorBase &dst, const VectorBase &src)> apply;
+ std::function<int(VectorBase &dst, const VectorBase &src)> vmult;
/**
* The callback for the application of the transposed preconditioner.
- * Defaults to the non-transpose operation if not provided.
*/
- std::function<int(VectorBase &dst, const VectorBase &src)> applyT;
+ std::function<int(VectorBase &dst, const VectorBase &src)> vmultT;
protected:
/**
{
AssertThrow(pc != nullptr, StandardExceptions::ExcInvalidState());
- const PetscErrorCode ierr = PCApply(pc, src, dst);
+ PetscErrorCode ierr = PCApply(pc, src, dst);
AssertThrow(ierr == 0, ExcPETScError(ierr));
}
{
AssertThrow(pc != nullptr, StandardExceptions::ExcInvalidState());
- const PetscErrorCode ierr = PCApplyTranspose(pc, src, dst);
+ PetscErrorCode ierr = PCApplyTranspose(pc, src, dst);
AssertThrow(ierr == 0, ExcPETScError(ierr));
}
PetscErrorCode ierr = PCShellGetContext(ppc, &ctx);
AssertThrow(ierr == 0, ExcPETScError(ierr));
+ auto user = static_cast<PreconditionShell *>(ctx);
+ AssertThrow(user->vmult,
+ StandardExceptions::ExcFunctionNotProvided(
+ "std::function vmult"));
+
VectorBase src(x);
VectorBase dst(y);
- auto user = static_cast<PreconditionShell *>(ctx);
- if (user->apply)
- user->apply(dst, src);
- else
- dst.sadd(0, src);
+ user->vmult(dst, src);
PetscFunctionReturn(0);
}
PetscErrorCode ierr = PCShellGetContext(ppc, &ctx);
AssertThrow(ierr == 0, ExcPETScError(ierr));
- auto user = static_cast<PreconditionShell *>(ctx);
+ auto user = static_cast<PreconditionShell *>(ctx);
+ AssertThrow(user->vmultT,
+ StandardExceptions::ExcFunctionNotProvided(
+ "std::function vmultT"));
+
VectorBase src(x);
VectorBase dst(y);
- if (user->applyT)
- user->applyT(dst, src);
- else if (user->apply)
- user->apply(dst, src);
- else
- dst.sadd(0, src);
+ user->vmult(dst, src);
PetscFunctionReturn(0);
}
u = 0.;
PETScWrappers::PreconditionShell preconditioner_user(A);
+
+ // Identity preconditioner
+ preconditioner_user.vmult =
+ [](PETScWrappers::VectorBase & dst,
+ const PETScWrappers::VectorBase &src) -> int {
+ dst = src;
+ return 0;
+ };
+
check_solver_within_range(solver.solve(A, u, f, preconditioner_user),
control.last_step(),
42,