xref: /petsc/doc/manual/fortran.md (revision 51ece73c09ceeb024bb01a3716d2d4b0ee62fef2)
1(ch_fortran)=
2
3# PETSc for Fortran Users
4
5Make sure the suffix of your Fortran files is .F90, not .f or .f90.
6
7## Basic Fortran API Differences
8
9(sec_fortran_includes)=
10
11### Modules and Include Files
12
13You must use both PETSc include files and modules.
14At the beginning of every function and module definition you need something like
15
16```fortran
17#include "petsc/finclude/petscXXX.h"
18   use petscXXX
19```
20
21The Fortran include files for PETSc are located in the directory
22`$PETSC_DIR/include/petsc/finclude` and the module files are located in `$PETSC_DIR/$PETSC_ARCH/include`
23
24The include files are nested, that is, for example, `petsc/finclude/petscmat.h` automatically includes
25`petsc/finclude/petscvec.h` and so on. Except for `petscsys` which is nested in the other modules,
26modules are **not** nested. Thus if your routine uses, for example, both
27`Mat` and `Vec` operations you need
28
29```c
30use petscvec
31use petscmat
32```
33
34The reason they are not nested is that they are very large and including all of them slows down the compile time.
35One can use
36
37```c
38use petsc
39```
40
41to include all of them. In addition, if you have a routine that does not have function calls for an object, but has
42the object as an argument you can use, for example,
43
44```c
45subroutine FormFunction(snes,x,f,dummy,ierr)
46  use petscvec
47  use petscsnesdef
48  implicit none
49```
50
51### Declaring PETSc Object Variables
52
53You can declare PETSc object variables using either of the following:
54
55```fortran
56XXX variablename
57```
58
59```fortran
60type(tXXX) variablename
61```
62
63For example,
64
65```fortran
66#include "petsc/finclude/petscvec.h"
67  use petscvec
68
69  Vec b
70  type(tVec) x
71```
72
73PETSc types like `PetscInt` and `PetscReal` are simply aliases for basic Fortran types and cannot be written as `type(tPetscInt)`
74
75PETSc objects are always automatically initialized when declared so you do not need to (and should not) do
76
77```fortran
78type(tXXX) x = PETSC_NULL_XXX
79XXX x = PETSC_NULL_XXX
80```
81
82### Calling Sequences
83
84The calling sequences for the Fortran version are in most cases
85identical to the C version, except for the error checking variable
86discussed in {any}`sec_fortran_errors`.
87
88The key differences in handling arguments when calling PETSc functions from Fortran are
89
90- One cannot pass a scalar variable to a function expecting an array, {any}`sec_passarray`.
91- One must use type specific `PETSC_NULL` arguments, such as `PETSC_NULL_INTEGER`, {any}`sec_nullptr`.
92- One must pass pointers to arrays for arguments that output an array, for example `PetscScalar, pointer \:\: a(\:)`,
93  {any}`sec_fortranarrays`.
94- `PETSC_DECIDE` and friends need to match the argument type, for example `PETSC_DECIDE_INTEGER`.
95
96When passing floating point numbers into PETSc Fortran subroutines, always
97make sure you have them marked as double precision (e.g., pass in `10.d0`
98instead of `10.0` or declare them as PETSc variables, e.g.
99`PetscScalar one = 1.0`). Otherwise, the compiler interprets the input as a single
100precision number, which can cause crashes or other mysterious problems.
101We **highly** recommend using the `implicit none`
102option at the beginning of each Fortran subroutine and declaring all variables.
103
104(sec_fortran_errors)=
105
106### Error Checking
107
108In the Fortran version, each PETSc routine has as its final argument an
109integer error variable. The error code is
110nonzero if an error has been detected; otherwise, it is zero. For
111example, the Fortran and C variants of `KSPSolve()` are given,
112respectively, below, where `ierr` denotes the `PetscErrorCode` error variable:
113
114```fortran
115call KSPSolve(ksp, b, x, ierr) ! Fortran
116ierr = KSPSolve(ksp, b, x);    // C
117```
118
119For proper error handling one should not use the above syntax instead one should use
120
121```fortran
122PetscCall(KSPSolve(ksp, b, x, ierr))   ! Fortran subroutines
123PetscCallA(KSPSolve(ksp, b, x, ierr))  ! Fortran main program
124PetscCall(KSPSolve(ksp, b, x))         // C
125```
126
127(sec_passarray)=
128
129### Passing Arrays To PETSc Functions
130
131Many PETSc functions take arrays as arguments; in Fortran they must be passed as arrays even if the "array"
132is of length one (unlike Fortran 77 where one can pass scalars to functions expecting arrays). When passing
133a single value one can use the Fortran [] notation to pass the scalar as an array, for example
134
135```fortran
136PetscCall(VecSetValues(v, one, [i], [val], ierr))
137```
138
139This trick can only be used for arrays used to pass data into a PETSc routine, it cannot be used
140for arrays used to receive data from a PETSc routine. For example,
141
142```fortran
143PetscCall(VecGetValues(v, one, idx, [val], ierr))
144```
145
146is invalid and will not set `val` with the correct value.
147
148(sec_nullptr)=
149
150### Passing null pointers to PETSc functions
151
152Many PETSc C functions have the option of passing a `NULL`
153argument (for example, the fifth argument of `MatCreateSeqAIJ()`).
154From Fortran, users *must* pass `PETSC_NULL_XXX` to indicate a null
155argument (where `XXX` is `INTEGER`, `DOUBLE`, `CHARACTER`,
156`SCALAR`, `VEC`, `MAT`, etc depending on the argument type). For example, when no options prefix is desired
157in the routine `PetscOptionsGetInt()`, one must use the following
158command in Fortran:
159
160```fortran
161PetscCall(PetscOptionsGetInt(PETSC_NULL_OPTIONS, PETSC_NULL_CHARACTER, PETSC_NULL_CHARACTER, '-name', N, flg, ierr))
162```
163
164Where the code expects an array, then use `PETSC_NULL_XXX_ARRAY`. For example:
165
166```fortran
167PetscCall(MatCreateSeqDense(comm, m, n, PETSC_NULL_SCALAR_ARRAY, A))
168```
169
170When a PETSc function returns multiple arrays, such as `DMDAGetOwnershipRanges()` and the user does not need
171certain arrays they must pass `PETSC_NULL_XXX_POINTER` as the argument. For example,
172
173```fortran
174PetscInt, pointer :: lx(:), ly(:)
175PetscCallA(DMDAGetOwnershipRanges(da, lx, ly, PETSC_NULL_INTEGER_POINTER, ierr))
176PetscCallA(DMDARestoreOwnershipRanges(da, lx, ly, PETSC_NULL_INTEGER_POINTER, ierr))
177```
178
179Arguments that are fully defined Fortran derived types (C structs), such as `MatFactorInfo` or `PetscSFNode`,
180cannot be passed as null from Fortran. A properly defined variable must be passed in for those arguments.
181
182Finally when a subroutine returns a `PetscObject` through an argument, to check if it is `NULL` you must use:
183
184```fortran
185if (PetscObjectIsNull(dm)) then
186if (.not. PetscObjectIsNull(dm)) then
187```
188
189you cannot use
190
191```fortran
192if (dm .eq. PETSC_NULL_DM) then
193```
194
195Note that
196
197```fortran
198if (PetscObjectIsNull(PETSC_NULL_VEC)) then
199```
200
201will always return true, for any PETSc object.
202
203These specializations with `NULL` types are required because of Fortran's strict type checking system and lack of a concept of `NULL`,
204the Fortran compiler will often warn you if the wrong `NULL` type is passed.
205
206(sec_fortranarrays)=
207
208### Output Arrays from PETSc functions
209
210For PETSc routine arguments that return an array of `PetscInt`, `PetscScalar`, `PetscReal` or of PETSc objects,
211one passes in a pointer to an array and the PETSc routine returns an array containing the values. For example,
212
213```c
214PetscScalar *a;
215Vec         v;
216VecGetArray(v, &a);
217```
218
219is in Fortran,
220
221```fortran
222PetscScalar, pointer :: a(:)
223Vec,         v
224VecGetArray(v, a, ierr)
225```
226
227For PETSc routine arguments that return a character string (array), e.g. `const char *str[]` pass a string long enough to hold the
228result. For example,
229
230```fortran
231character*(80)  str
232PetscCall(KSPGetType(ksp,str,ierr))
233```
234
235The result is copied into `str`.
236
237Similarly, for PETSc routines where the user provides a character array (to be filled) followed by the array's length, e.g. `char name[], size_t nlen`.
238In Fortran pass a string long enough to hold the result, but not the separate length argument. For example,
239
240```fortran
241character*(80)  str
242PetscCall(PetscGetHostName(name,ierr))
243```
244
245### Matrix, Vector and IS Indices
246
247All matrices, vectors and `IS` in PETSc use zero-based indexing in the PETSc API
248regardless of whether C or Fortran is being used. For example,
249`MatSetValues()` and `VecSetValues()` always use
250zero indexing. See {any}`sec_matoptions` for further
251details.
252
253Indexing into Fortran arrays, for example obtained with `VecGetArray()`, uses the Fortran
254convention and generally begin with 1 except for special routines such as `DMDAVecGetArray()` which uses the ranges
255provided by `DMDAGetCorners()`.
256
257### Setting Routines and Contexts
258
259Some PETSc functions take as arguments user-functions and contexts for the function. For example
260
261```fortran
262external func
263SNESSetFunction(snes, r, func, ctx, ierr)
264SNES snes
265Vec r
266PetscErrorCode ierr
267```
268
269where `func` has the calling sequence
270
271```fortran
272subroutine func(snes, x, f, ctx, ierr)
273SNES snes
274Vec x,f
275PetscErrorCode ierr
276```
277
278and `ctx` can be almost anything (represented as `void *` in C).
279
280It can be a Fortran derived type as in
281
282```fortran
283subroutine func(snes, x, f, ctx, ierr)
284SNES snes
285Vec x,f
286type (userctx)   ctx
287PetscErrorCode ierr
288...
289
290external func
291SNESSetFunction(snes, r, func, ctx, ierr)
292SNES snes
293Vec r
294PetscErrorCode ierr
295type (userctx)   ctx
296```
297
298or a PETSc object
299
300```fortran
301subroutine func(snes, x, f, ctx, ierr)
302SNES snes
303Vec x,f
304Vec ctx
305PetscErrorCode ierr
306...
307
308external func
309SNESSetFunction(snes, r, func, ctx, ierr)
310SNES snes
311Vec r
312PetscErrorCode ierr
313Vec ctx
314```
315
316or nothing
317
318```fortran
319subroutine func(snes, x, f, dummy, ierr)
320SNES snes
321Vec x,f
322integer dummy(*)
323PetscErrorCode ierr
324...
325
326external func
327SNESSetFunction(snes, r, func, 0, ierr)
328SNES snes
329Vec r
330PetscErrorCode ierr
331```
332
333When a function pointer (declared as external in Fortran) is passed as an argument to a PETSc function,
334it is assumed that this
335function references a routine written in the same language as the PETSc
336interface function that was called. For instance, if
337`SNESSetFunction()` is called from C, the function must be a C function. Likewise, if it is called from Fortran, the
338function must be (a subroutine) written in Fortran.
339
340If you are using Fortran classes that have bound functions (methods) as in
341<a href="PETSC_DOC_OUT_ROOT_PLACEHOLDER/src/snes/tests/ex18f90.F90.html">src/snes/tests/ex18f90.F90</a>, the context cannot be passed
342to function pointer setting routines, such as `SNESSetFunction()`. Instead, one must use `SNESSetFunctionNoInterface()`,
343and define the interface directly in the user code, see
344<a href="PETSC_DOC_OUT_ROOT_PLACEHOLDER/src/snes/tests/ex18f90.F90.html">ex18f90.F90</a>
345for a full demonstration.
346
347(sec_fortcompile)=
348
349### Compiling and Linking Fortran Programs
350
351See {any}`sec_writing_application_codes`.
352
353### Duplicating Multiple Vectors
354
355The Fortran interface to `VecDuplicateVecs()` differs slightly from
356the C/C++ variant. To create `n` vectors of the same
357format as an existing vector, the user must declare a vector array,
358`v_new` of size `n`. Then, after `VecDuplicateVecs()` has been
359called, `v_new` will contain (pointers to) the new PETSc vector
360objects. When finished with the vectors, the user should destroy them by
361calling `VecDestroyVecs()`. For example, the following code fragment
362duplicates `v_old` to form two new vectors, `v_new(1)` and
363`v_new(2)`.
364
365```fortran
366Vec          v_old, v_new(2)
367PetscInt     ierr
368PetscScalar  alpha
369....
370PetscCall(VecDuplicateVecs(v_old, 2, v_new, ierr))
371alpha = 4.3
372PetscCall(VecSet(v_new(1), alpha, ierr))
373alpha = 6.0
374PetscCall(VecSet(v_new(2), alpha, ierr))
375....
376PetscCall(VecDestroyVecs(2, v_new, ierr))
377```
378
379(sec_fortran_examples)=
380
381## Sample Fortran Programs
382
383Sample programs that illustrate the PETSc interface for Fortran are
384given below, corresponding to
385<a href="PETSC_DOC_OUT_ROOT_PLACEHOLDER/src/vec/vec/tests/ex19f.F90.html">Vec Test ex19f</a>,
386<a href="PETSC_DOC_OUT_ROOT_PLACEHOLDER/src/vec/vec/tutorials/ex4f.F90.html">Vec Tutorial ex4f</a>,
387<a href="PETSC_DOC_OUT_ROOT_PLACEHOLDER/src/sys/classes/draw/tests/ex5f.F90.html">Draw Test ex5f</a>,
388and
389<a href="PETSC_DOC_OUT_ROOT_PLACEHOLDER/src/snes/tutorials/ex1f.F90.html">SNES Tutorial ex1f</a>,
390respectively. We also refer Fortran programmers to the C examples listed
391throughout the manual, since PETSc usage within the two languages
392differs only slightly.
393
394:::{admonition} Listing: `src/vec/vec/tests/ex19f.F90`
395:name: vec-test-ex19f
396
397```{literalinclude} /../src/vec/vec/tests/ex19f.F90
398:end-at: end
399:language: fortran
400```
401:::
402
403(listing_vec_ex4f)=
404
405:::{admonition} Listing: `src/vec/vec/tutorials/ex4f.F90`
406:name: vec-ex4f
407
408```{literalinclude} /../src/vec/vec/tutorials/ex4f.F90
409:end-before: '!/*TEST'
410:language: fortran
411```
412:::
413
414:::{admonition} Listing: `src/sys/classes/draw/tests/ex5f.F90`
415:name: draw-test-ex5f
416
417```{literalinclude} /../src/sys/classes/draw/tests/ex5f.F90
418:end-at: end
419:language: fortran
420```
421:::
422
423:::{admonition} Listing: `src/snes/tutorials/ex1f.F90`
424:name: snes-ex1f
425
426```{literalinclude} /../src/snes/tutorials/ex1f.F90
427:end-before: '!/*TEST'
428:language: fortran
429```
430:::
431
432### Calling Fortran Routines from C (and C Routines from Fortran)
433
434The information here applies only if you plan to call your **own**
435C functions from Fortran or Fortran functions from C.
436Different compilers have different methods of naming Fortran routines
437called from C (or C routines called from Fortran). Most Fortran
438compilers change the capital letters in Fortran routines to
439all lowercase. With some compilers, the Fortran compiler appends an underscore
440to the end of each Fortran routine name; for example, the Fortran
441routine `Dabsc()` would be called from C with `dabsc_()`. Other
442compilers change all the letters in Fortran routine names to capitals.
443
444PETSc provides two macros (defined in C/C++) to help write portable code
445that mixes C/C++ and Fortran. They are `PETSC_HAVE_FORTRAN_UNDERSCORE`
446and `PETSC_HAVE_FORTRAN_CAPS` , which will be defined in the file
447`$PETSC_DIR/$PETSC_ARCH/include/petscconf.h` based on the compilers
448conventions. The macros are used,
449for example, as follows:
450
451```fortran
452#if defined(PETSC_HAVE_FORTRAN_CAPS)
453#define dabsc_ DABSC
454#elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
455#define dabsc_ dabsc
456#endif
457.....
458dabsc_( &n,x,y); /* call the Fortran function */
459```
460