# Applying a modified preconditioner matrix in PETSc

**URL:** <https://community.freefem.org/t/applying-a-modified-preconditioner-matrix-in-petsc/1142>\
**Category:** General Discussion\
**Created:** [August 6, 2021, 10:37am UTC](https://community.freefem.org/t/applying-a-modified-preconditioner-matrix-in-petsc/1142 "2021-08-06T10:37:18Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![gbwalton](https://yyz2.discourse-cdn.com/flex030/user_avatar/community.freefem.org/gbwalton/32/617_2.png) [@gbwalton](https://community.freefem.org/u/gbwalton)\
**Post date:** [August 6, 2021, 10:37am UTC](https://community.freefem.org/t/applying-a-modified-preconditioner-matrix-in-petsc/1142/1 "2021-08-06T10:37:19Z")

</div>

Hi all,

Is it possible to specific a modified preconditioner matrix when using PETSc in FreeFEM?

In PETSc a different Amat and Pmat can be specified using `KSPSetOperators(KSP ksp,Mat Amat,Mat Pmat)`. Is this possible using FreeFEM?

Thanks in advance,  
Greg

---

<div class="post-metadata">

**Author:** ![prj](https://avatars.discourse-cdn.com/v4/letter/p/ecae2f/32.png) [@prj](https://community.freefem.org/u/prj)\
**Post date:** [August 6, 2021, 10:47am UTC](https://community.freefem.org/t/applying-a-modified-preconditioner-matrix-in-petsc/1142/2 "2021-08-06T10:47:46Z")

</div>

It is possible, but I had to make design choices that made the API “easy” for beginners, and slightly less “easy” for power users. I’d consider this a power user feature, thus the API is not very “easy”.

Here goes. `KSPSetOperators()` is always called by `Amat` in both slots. However, you can trick FreeFEM (or PETSc, whatever you prefer), by using a `PCSHELL` with your `KSP`. To do that, you have to define a `func PetscScalar[int] Pmat(PetscScalar[int]& in) { PetscScalar[int] out; KSPSolve(P, in, out); return out; }` and then call `set(Amat, precon = Pmat, sparams = "-pc_type shell");`.  
Of course, you may want to adjust the `Pmat` function to your needs, see, e.g., [FreeFem-sources/oseen-2d-PETSc.edp at develop · FreeFem/FreeFem-sources · GitHub](https://github.com/FreeFem/FreeFem-sources/blob/develop/examples/hpddm/oseen-2d-PETSc.edp#L120).

If this does not fits your needs, please let me know.

---

<div class="post-metadata">

**Author:** ![gbwalton](https://yyz2.discourse-cdn.com/flex030/user_avatar/community.freefem.org/gbwalton/32/617_2.png) [@gbwalton](https://community.freefem.org/u/gbwalton)\
**Post date:** [August 6, 2021, 11:02am UTC](https://community.freefem.org/t/applying-a-modified-preconditioner-matrix-in-petsc/1142/3 "2021-08-06T11:02:15Z")

</div>

Thanks for the quick response. I’ll give that a go.

---

<div class="post-metadata">

**Author:** ![gbwalton](https://yyz2.discourse-cdn.com/flex030/user_avatar/community.freefem.org/gbwalton/32/617_2.png) [@gbwalton](https://community.freefem.org/u/gbwalton)\
**Post date:** [August 6, 2021, 12:27pm UTC](https://community.freefem.org/t/applying-a-modified-preconditioner-matrix-in-petsc/1142/4 "2021-08-06T12:27:50Z")

</div>

Is `PetscScalar[int]` definitely a permitted output type to a `func`? It looks like `PetscScalar` isn’t a valid identifier.

---

<div class="post-metadata">

**Author:** ![prj](https://avatars.discourse-cdn.com/v4/letter/p/ecae2f/32.png) [@prj](https://community.freefem.org/u/prj)\
**Post date:** [August 6, 2021, 2:58pm UTC](https://community.freefem.org/t/applying-a-modified-preconditioner-matrix-in-petsc/1142/5 "2021-08-06T14:58:06Z")

</div>

> Is `PetscScalar[int]` definitely a permitted output type to a `func` ?

Yes.

```auto
$ git diff --unified=1 oseen-2d-PETSc.edp
diff --git a/examples/hpddm/oseen-2d-PETSc.edp b/examples/hpddm/oseen-2d-PETSc.edp
index db7774a3..d79f2595 100644
--- a/examples/hpddm/oseen-2d-PETSc.edp
+++ b/examples/hpddm/oseen-2d-PETSc.edp
@@ -109,3 +109,3 @@ set(dAp, sparams="-prefix_push stiffness_ -ksp_constant_null_space -pc_type gamg
 set(dMp, sparams="-prefix_push mass_ -pc_type jacobi -ksp_type cg -ksp_max_it 5 -prefix_pop", prefix="mass_");
-func real[int] PCD(real[int]& in) {
+func PetscScalar[int] PCD(PetscScalar[int]& in) {
     real[int] out(in.n);
$ ff-mpirun -n 4 oseen-2d-PETSc.edp -v 0
'mpiexec' -n 4 /Users/jolivet/repo/FreeFem-sources-opt/src/mpi/FreeFem++-mpi -nw 'oseen-2d-PETSc.edp' -v 0
  0 KSP Residual norm 1.126942766958e+01
  1 KSP Residual norm 1.211704042327e+00
  2 KSP Residual norm 1.196774444376e+00
  3 KSP Residual norm 9.349518221811e-01
  4 KSP Residual norm 6.165076499177e-01
  5 KSP Residual norm 5.160899777308e-01
  6 KSP Residual norm 4.258461730310e-01
  7 KSP Residual norm 3.233845833153e-01
  8 KSP Residual norm 2.549468207077e-01
  9 KSP Residual norm 2.082486066860e-01
 10 KSP Residual norm 1.658173156505e-01
 11 KSP Residual norm 1.265213502966e-01
 12 KSP Residual norm 9.290575051382e-02
 13 KSP Residual norm 6.324474572261e-02
 14 KSP Residual norm 3.979519396695e-02
 15 KSP Residual norm 2.400455372980e-02
 16 KSP Residual norm 1.467199804593e-02
 17 KSP Residual norm 9.934514655560e-03
 18 KSP Residual norm 7.109634777396e-03
 19 KSP Residual norm 5.471649973749e-03
 20 KSP Residual norm 4.547054280958e-03
 21 KSP Residual norm 4.178684030727e-03
 22 KSP Residual norm 3.924235944687e-03
 23 KSP Residual norm 3.406191499661e-03
 24 KSP Residual norm 2.343458788730e-03
 25 KSP Residual norm 1.199118692965e-03
 26 KSP Residual norm 6.228083971918e-04
 27 KSP Residual norm 3.377254147466e-04
 28 KSP Residual norm 1.996655242067e-04
 29 KSP Residual norm 1.108701321233e-04
Linear solve converged due to CONVERGED_RTOL iterations 29

```

By just saying “It looks like `PetscScalar` isn’t a valid identifier”, I can’t really help you further. My guess is that you have an old FreeFEM version which doesn’t have this commit [https://github.com/FreeFem/FreeFem-sources/commit/723520e75ec36eb7f3802d30ec67319c249af51d#diff-6dd6dd51051ada00b3d8fa1b5e233cecd08ffe961add4f9fbdadf0805b73db1d](https://github.com/FreeFem/FreeFem-sources/commit/723520e75ec36eb7f3802d30ec67319c249af51d#diff-6dd6dd51051ada00b3d8fa1b5e233cecd08ffe961add4f9fbdadf0805b73db1d).
