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