xref: /petsc/doc/manual/fortran.md (revision bcd4bb4a4158aa96f212e9537e87b40407faf83e)
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### Setting Routines and Contexts
301
302Some PETSc functions take as arguments user-functions and contexts for the function. For example
303
304```fortran
305external func
306SNESSetFunction(snes, r, func, ctx, ierr)
307SNES snes
308Vec r
309PetscErrorCode ierr
310```
311
312where `func` has the calling sequence
313
314```fortran
315subroutine func(snes, x, f, ctx, ierr)
316SNES snes
317Vec x,f
318PetscErrorCode ierr
319```
320
321and `ctx` can be almost anything (represented as `void *` in C).
322
323It can be a Fortran derived type as in
324
325```fortran
326subroutine func(snes, x, f, ctx, ierr)
327SNES snes
328Vec x,f
329type (userctx)   ctx
330PetscErrorCode ierr
331...
332
333external func
334SNESSetFunction(snes, r, func, ctx, ierr)
335SNES snes
336Vec r
337PetscErrorCode ierr
338type (userctx)   ctx
339```
340
341or a PETSc object
342
343```fortran
344subroutine func(snes, x, f, ctx, ierr)
345SNES snes
346Vec x,f
347Vec ctx
348PetscErrorCode ierr
349...
350
351external func
352SNESSetFunction(snes, r, func, ctx, ierr)
353SNES snes
354Vec r
355PetscErrorCode ierr
356Vec ctx
357```
358
359or nothing
360
361```fortran
362subroutine func(snes, x, f, dummy, ierr)
363SNES snes
364Vec x,f
365integer dummy(*)
366PetscErrorCode ierr
367...
368
369external func
370SNESSetFunction(snes, r, func, 0, ierr)
371SNES snes
372Vec r
373PetscErrorCode ierr
374```
375
376When a function pointer (declared as external in Fortran) is passed as an argument to a PETSc function,
377it is assumed that this
378function references a routine written in the same language as the PETSc
379interface function that was called. For instance, if
380`SNESSetFunction()` is called from C, the function must be a C function. Likewise, if it is called from Fortran, the
381function must be (a subroutine) written in Fortran.
382
383If you are using Fortran classes that have bound functions (methods) as in
384<a href="PETSC_DOC_OUT_ROOT_PLACEHOLDER/src/snes/tests/ex18f90.F90.html">src/snes/tests/ex18f90.F90</a>, the context cannot be passed
385to function pointer setting routines, such as `SNESSetFunction()`. Instead, one must use `SNESSetFunctionNoInterface()`,
386and define the interface directly in the user code, see
387<a href="PETSC_DOC_OUT_ROOT_PLACEHOLDER/src/snes/tests/ex18f90.F90.html">ex18f90.F90</a>
388for a full demonstration.
389
390(sec_fortcompile)=
391
392### Compiling and Linking Fortran Programs
393
394See {any}`sec_writing_application_codes`.
395
396
397(sec_fortran_examples)=
398
399## Sample Fortran Programs
400
401Sample programs that illustrate the PETSc interface for Fortran are
402given below, corresponding to
403<a href="PETSC_DOC_OUT_ROOT_PLACEHOLDER/src/vec/vec/tests/ex19f.F90.html">Vec Test ex19f</a>,
404<a href="PETSC_DOC_OUT_ROOT_PLACEHOLDER/src/vec/vec/tutorials/ex4f.F90.html">Vec Tutorial ex4f</a>,
405<a href="PETSC_DOC_OUT_ROOT_PLACEHOLDER/src/sys/classes/draw/tests/ex5f.F90.html">Draw Test ex5f</a>,
406and
407<a href="PETSC_DOC_OUT_ROOT_PLACEHOLDER/src/snes/tutorials/ex1f.F90.html">SNES Tutorial ex1f</a>,
408respectively. We also refer Fortran programmers to the C examples listed
409throughout the manual, since PETSc usage within the two languages
410differs only slightly.
411
412:::{admonition} Listing: `src/vec/vec/tests/ex19f.F90`
413:name: vec-test-ex19f
414
415```{literalinclude} /../src/vec/vec/tests/ex19f.F90
416:end-at: end
417:language: fortran
418```
419:::
420
421(listing_vec_ex4f)=
422
423:::{admonition} Listing: `src/vec/vec/tutorials/ex4f.F90`
424:name: vec-ex4f
425
426```{literalinclude} /../src/vec/vec/tutorials/ex4f.F90
427:end-before: '!/*TEST'
428:language: fortran
429```
430:::
431
432:::{admonition} Listing: `src/sys/classes/draw/tests/ex5f.F90`
433:name: draw-test-ex5f
434
435```{literalinclude} /../src/sys/classes/draw/tests/ex5f.F90
436:end-at: end
437:language: fortran
438```
439:::
440
441:::{admonition} Listing: `src/snes/tutorials/ex1f.F90`
442:name: snes-ex1f
443
444```{literalinclude} /../src/snes/tutorials/ex1f.F90
445:end-before: '!/*TEST'
446:language: fortran
447```
448:::
449
450### Calling Fortran Routines from C (and C Routines from Fortran)
451
452The information here applies only if you plan to call your **own**
453C functions from Fortran or Fortran functions from C.
454Different compilers have different methods of naming Fortran routines
455called from C (or C routines called from Fortran). Most Fortran
456compilers change the capital letters in Fortran routines to
457all lowercase. With some compilers, the Fortran compiler appends an underscore
458to the end of each Fortran routine name; for example, the Fortran
459routine `Dabsc()` would be called from C with `dabsc_()`. Other
460compilers change all the letters in Fortran routine names to capitals.
461
462PETSc provides two macros (defined in C/C++) to help write portable code
463that mixes C/C++ and Fortran. They are `PETSC_HAVE_FORTRAN_UNDERSCORE`
464and `PETSC_HAVE_FORTRAN_CAPS` , which will be defined in the file
465`$PETSC_DIR/$PETSC_ARCH/include/petscconf.h` based on the compilers
466conventions. The macros are used,
467for example, as follows:
468
469```fortran
470#if defined(PETSC_HAVE_FORTRAN_CAPS)
471#define dabsc_ DABSC
472#elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
473#define dabsc_ dabsc
474#endif
475.....
476dabsc_( &n,x,y); /* call the Fortran function */
477```
478