xref: /petsc/doc/manual/fortran.md (revision 4e8208cbcbc709572b8abe32f33c78b69c819375)
17f296bb3SBarry Smith(ch_fortran)=
27f296bb3SBarry Smith
37f296bb3SBarry Smith# PETSc for Fortran Users
47f296bb3SBarry Smith
57f296bb3SBarry SmithMake sure the suffix of your Fortran files is .F90, not .f or .f90.
67f296bb3SBarry Smith
7b06eb4cdSBarry Smith## Fortran and MPI
8b06eb4cdSBarry Smith
9b06eb4cdSBarry SmithBy default PETSc uses the MPI Fortran module `mpi`. To use `mpi_f08` run `./configure` with `--with-mpi-ftn-module=mpi_f08`.
10b06eb4cdSBarry Smith
11b06eb4cdSBarry SmithWe do not recommend it but it is possible to write Fortran code that works with both `use mpi` or `use mpi_f08`.
12b06eb4cdSBarry SmithYou must declare MPI objects using `MPIU_XXX` (for example `MPIU_Comm`, which the PETSc include files map to either `integer4` or `type(MPI_XXX)`.
13b06eb4cdSBarry SmithIn addition, you must handle `MPIU_Status` declarations and access to entries using the Fortran preprocessor. For example,
14b06eb4cdSBarry Smith
15b06eb4cdSBarry Smith```fortran
16b06eb4cdSBarry Smith#if defined(PETSC_USE_MPI_F08)
17b06eb4cdSBarry Smith  MPIU_Status status
18b06eb4cdSBarry Smith#else
19b06eb4cdSBarry Smith  MPIU_Status status(MPI_STATUS_SIZE)
20b06eb4cdSBarry Smith#endif
21b06eb4cdSBarry Smith```
22b06eb4cdSBarry Smith
23b06eb4cdSBarry Smithand then
24b06eb4cdSBarry Smith
25b06eb4cdSBarry Smith```fortran
26b06eb4cdSBarry Smith#if defined(PETSC_USE_MPI_F08)
27b06eb4cdSBarry Smith      tag = status%MPI_TAG
28b06eb4cdSBarry Smith#else
29b06eb4cdSBarry Smith      tag = status(MPI_TAG)
30b06eb4cdSBarry Smith#endif
31b06eb4cdSBarry Smith```
32b06eb4cdSBarry Smith
33b06eb4cdSBarry Smith## Numerical Constants
34b06eb4cdSBarry Smith
35b06eb4cdSBarry SmithSince 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.
36b06eb4cdSBarry Smith
37b06eb4cdSBarry Smith```fortran
38b06eb4cdSBarry Smith   interface
39b06eb4cdSBarry Smith     subroutine SampleSubroutine(real, complex, integer, MPIinteger)
40b06eb4cdSBarry Smith       PetscReal real         ! real(PETSC_REAL_KIND)
41b06eb4cdSBarry Smith       PetscComplex complex   ! real(PETSC_REAL_KIND) or complex(PETSC_REAL_KIND)
42b06eb4cdSBarry Smith       PetscInt integer       ! integer(PETSC_INT_KIND)
43b06eb4cdSBarry Smith       PetscMPIInt MPIinteger ! integer(PETSC_MPIINT_KIND)
44b06eb4cdSBarry Smith     end subroutine
45b06eb4cdSBarry Smith   end interface
46b06eb4cdSBarry Smith   ...
47b06eb4cdSBarry Smith   ! Fortran () automatically sets the complex KIND to correspond to the KIND of constant arguments
48b06eb4cdSBarry Smith   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)
49b06eb4cdSBarry Smith   ! For variable arguments one must set the complex kind explicitly or it defaults to single precision
50b06eb4cdSBarry Smith   PetscReal a = 0.1, b = 0.0
51b06eb4cdSBarry Smith   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)
52b06eb4cdSBarry Smith```
53b06eb4cdSBarry Smith
547f296bb3SBarry Smith## Basic Fortran API Differences
557f296bb3SBarry Smith
567f296bb3SBarry Smith(sec_fortran_includes)=
577f296bb3SBarry Smith
587f296bb3SBarry Smith### Modules and Include Files
597f296bb3SBarry Smith
607f296bb3SBarry SmithYou must use both PETSc include files and modules.
617f296bb3SBarry SmithAt the beginning of every function and module definition you need something like
627f296bb3SBarry Smith
637f296bb3SBarry Smith```fortran
647f296bb3SBarry Smith#include "petsc/finclude/petscXXX.h"
657f296bb3SBarry Smith   use petscXXX
667f296bb3SBarry Smith```
677f296bb3SBarry Smith
687f296bb3SBarry SmithThe Fortran include files for PETSc are located in the directory
69b06eb4cdSBarry Smith`$PETSC_DIR/$PETSC_ARCH/include/petsc/finclude` and the module files are located in `$PETSC_DIR/$PETSC_ARCH/include`
707f296bb3SBarry Smith
717f296bb3SBarry SmithThe include files are nested, that is, for example, `petsc/finclude/petscmat.h` automatically includes
72b06eb4cdSBarry Smith`petsc/finclude/petscvec.h` and so on. The modules are also nested. One can use
737f296bb3SBarry Smith
747f296bb3SBarry Smith```c
757f296bb3SBarry Smithuse petsc
767f296bb3SBarry Smith```
777f296bb3SBarry Smith
78b06eb4cdSBarry Smithto include all of them.
797f296bb3SBarry Smith
807f296bb3SBarry Smith### Declaring PETSc Object Variables
817f296bb3SBarry Smith
827f296bb3SBarry SmithYou can declare PETSc object variables using either of the following:
837f296bb3SBarry Smith
847f296bb3SBarry Smith```fortran
857f296bb3SBarry SmithXXX variablename
867f296bb3SBarry Smith```
877f296bb3SBarry Smith
887f296bb3SBarry Smith```fortran
897f296bb3SBarry Smithtype(tXXX) variablename
907f296bb3SBarry Smith```
917f296bb3SBarry Smith
927f296bb3SBarry SmithFor example,
937f296bb3SBarry Smith
947f296bb3SBarry Smith```fortran
957f296bb3SBarry Smith#include "petsc/finclude/petscvec.h"
967f296bb3SBarry Smith  use petscvec
977f296bb3SBarry Smith
987f296bb3SBarry Smith  Vec b
997f296bb3SBarry Smith  type(tVec) x
1007f296bb3SBarry Smith```
1017f296bb3SBarry Smith
1027f296bb3SBarry SmithPETSc types like `PetscInt` and `PetscReal` are simply aliases for basic Fortran types and cannot be written as `type(tPetscInt)`
1037f296bb3SBarry Smith
1047f296bb3SBarry SmithPETSc objects are always automatically initialized when declared so you do not need to (and should not) do
1057f296bb3SBarry Smith
1067f296bb3SBarry Smith```fortran
1077f296bb3SBarry Smithtype(tXXX) x = PETSC_NULL_XXX
1087f296bb3SBarry SmithXXX x = PETSC_NULL_XXX
1097f296bb3SBarry Smith```
1107f296bb3SBarry Smith
111a7a02aaeSBarry SmithTo make a variable no longer point to its previously assigned PETSc object use, for example,
112a7a02aaeSBarry Smith
113a7a02aaeSBarry Smith```fortran
114a7a02aaeSBarry Smith   Vec x, y
115a7a02aaeSBarry Smith   PetscInt one = 1
116a7a02aaeSBarry Smith   PetscCallA(VecCreateMPI(PETSC_COMM_WORLD, one, PETSC_DETERMINE, x, ierr))
117a7a02aaeSBarry Smith   y = x
118a7a02aaeSBarry Smith   PetscCallA(VecDestroy(x, ierr))
119a7a02aaeSBarry Smith   PetscObjectNullify(y)
120a7a02aaeSBarry Smith```
121a7a02aaeSBarry Smith
122a7a02aaeSBarry SmithOtherwise `y` will be a dangling pointer whose access will cause a crash.
123a7a02aaeSBarry Smith
124a7a02aaeSBarry Smith
1257f296bb3SBarry Smith### Calling Sequences
1267f296bb3SBarry Smith
1277f296bb3SBarry SmithThe calling sequences for the Fortran version are in most cases
1287f296bb3SBarry Smithidentical to the C version, except for the error checking variable
1297f296bb3SBarry Smithdiscussed in {any}`sec_fortran_errors`.
1307f296bb3SBarry Smith
1317f296bb3SBarry SmithThe key differences in handling arguments when calling PETSc functions from Fortran are
1327f296bb3SBarry Smith
1337f296bb3SBarry Smith- One cannot pass a scalar variable to a function expecting an array, {any}`sec_passarray`.
1347f296bb3SBarry Smith- One must use type specific `PETSC_NULL` arguments, such as `PETSC_NULL_INTEGER`, {any}`sec_nullptr`.
1357f296bb3SBarry Smith- One must pass pointers to arrays for arguments that output an array, for example `PetscScalar, pointer \:\: a(\:)`,
1367f296bb3SBarry Smith  {any}`sec_fortranarrays`.
1377f296bb3SBarry Smith- `PETSC_DECIDE` and friends need to match the argument type, for example `PETSC_DECIDE_INTEGER`.
1387f296bb3SBarry Smith
1397f296bb3SBarry SmithWhen passing floating point numbers into PETSc Fortran subroutines, always
1407f296bb3SBarry Smithmake sure you have them marked as double precision (e.g., pass in `10.d0`
1417f296bb3SBarry Smithinstead of `10.0` or declare them as PETSc variables, e.g.
1427f296bb3SBarry Smith`PetscScalar one = 1.0`). Otherwise, the compiler interprets the input as a single
1437f296bb3SBarry Smithprecision number, which can cause crashes or other mysterious problems.
1447f296bb3SBarry SmithWe **highly** recommend using the `implicit none`
1457f296bb3SBarry Smithoption at the beginning of each Fortran subroutine and declaring all variables.
1467f296bb3SBarry Smith
1477f296bb3SBarry Smith(sec_fortran_errors)=
1487f296bb3SBarry Smith
1497f296bb3SBarry Smith### Error Checking
1507f296bb3SBarry Smith
1517f296bb3SBarry SmithIn the Fortran version, each PETSc routine has as its final argument an
1527f296bb3SBarry Smithinteger error variable. The error code is
1537f296bb3SBarry Smithnonzero if an error has been detected; otherwise, it is zero. For
1547f296bb3SBarry Smithexample, the Fortran and C variants of `KSPSolve()` are given,
1557f296bb3SBarry Smithrespectively, below, where `ierr` denotes the `PetscErrorCode` error variable:
1567f296bb3SBarry Smith
1577f296bb3SBarry Smith```fortran
1587f296bb3SBarry Smithcall KSPSolve(ksp, b, x, ierr) ! Fortran
1597f296bb3SBarry Smithierr = KSPSolve(ksp, b, x);    // C
1607f296bb3SBarry Smith```
1617f296bb3SBarry Smith
1627f296bb3SBarry SmithFor proper error handling one should not use the above syntax instead one should use
1637f296bb3SBarry Smith
1647f296bb3SBarry Smith```fortran
1657f296bb3SBarry SmithPetscCall(KSPSolve(ksp, b, x, ierr))   ! Fortran subroutines
1667f296bb3SBarry SmithPetscCallA(KSPSolve(ksp, b, x, ierr))  ! Fortran main program
1677f296bb3SBarry SmithPetscCall(KSPSolve(ksp, b, x))         // C
1687f296bb3SBarry Smith```
1697f296bb3SBarry Smith
1707f296bb3SBarry Smith(sec_passarray)=
1717f296bb3SBarry Smith
1727f296bb3SBarry Smith### Passing Arrays To PETSc Functions
1737f296bb3SBarry Smith
1747f296bb3SBarry SmithMany PETSc functions take arrays as arguments; in Fortran they must be passed as arrays even if the "array"
1757f296bb3SBarry Smithis of length one (unlike Fortran 77 where one can pass scalars to functions expecting arrays). When passing
1767f296bb3SBarry Smitha single value one can use the Fortran [] notation to pass the scalar as an array, for example
1777f296bb3SBarry Smith
1787f296bb3SBarry Smith```fortran
1797f296bb3SBarry SmithPetscCall(VecSetValues(v, one, [i], [val], ierr))
1807f296bb3SBarry Smith```
1817f296bb3SBarry Smith
1827f296bb3SBarry SmithThis trick can only be used for arrays used to pass data into a PETSc routine, it cannot be used
1837f296bb3SBarry Smithfor arrays used to receive data from a PETSc routine. For example,
1847f296bb3SBarry Smith
1857f296bb3SBarry Smith```fortran
1867f296bb3SBarry SmithPetscCall(VecGetValues(v, one, idx, [val], ierr))
1877f296bb3SBarry Smith```
1887f296bb3SBarry Smith
1897f296bb3SBarry Smithis invalid and will not set `val` with the correct value.
1907f296bb3SBarry Smith
1917f296bb3SBarry Smith(sec_nullptr)=
1927f296bb3SBarry Smith
1937f296bb3SBarry Smith### Passing null pointers to PETSc functions
1947f296bb3SBarry Smith
1957f296bb3SBarry SmithMany PETSc C functions have the option of passing a `NULL`
1967f296bb3SBarry Smithargument (for example, the fifth argument of `MatCreateSeqAIJ()`).
1977f296bb3SBarry SmithFrom Fortran, users *must* pass `PETSC_NULL_XXX` to indicate a null
1987f296bb3SBarry Smithargument (where `XXX` is `INTEGER`, `DOUBLE`, `CHARACTER`,
1997c884152SBarry Smith`SCALAR`, `VEC`, `MAT`, etc depending on the argument type). For example, when no options prefix is desired
2007f296bb3SBarry Smithin the routine `PetscOptionsGetInt()`, one must use the following
2017f296bb3SBarry Smithcommand in Fortran:
2027f296bb3SBarry Smith
2037f296bb3SBarry Smith```fortran
2047f296bb3SBarry SmithPetscCall(PetscOptionsGetInt(PETSC_NULL_OPTIONS, PETSC_NULL_CHARACTER, PETSC_NULL_CHARACTER, '-name', N, flg, ierr))
2057f296bb3SBarry Smith```
2067f296bb3SBarry Smith
2077f296bb3SBarry SmithWhere the code expects an array, then use `PETSC_NULL_XXX_ARRAY`. For example:
2087f296bb3SBarry Smith
2097f296bb3SBarry Smith```fortran
2107f296bb3SBarry SmithPetscCall(MatCreateSeqDense(comm, m, n, PETSC_NULL_SCALAR_ARRAY, A))
2117f296bb3SBarry Smith```
2127f296bb3SBarry Smith
2137f296bb3SBarry SmithWhen a PETSc function returns multiple arrays, such as `DMDAGetOwnershipRanges()` and the user does not need
2147f296bb3SBarry Smithcertain arrays they must pass `PETSC_NULL_XXX_POINTER` as the argument. For example,
2157f296bb3SBarry Smith
2167f296bb3SBarry Smith```fortran
2177f296bb3SBarry SmithPetscInt, pointer :: lx(:), ly(:)
218b5ef2b50SBarry SmithPetscCallA(DMDAGetOwnershipRanges(dm, lx, ly, PETSC_NULL_INTEGER_POINTER, ierr))
219b5ef2b50SBarry SmithPetscCallA(DMDARestoreOwnershipRanges(dm, lx, ly, PETSC_NULL_INTEGER_POINTER, ierr))
2207f296bb3SBarry Smith```
2217f296bb3SBarry Smith
2227c884152SBarry SmithArguments that are fully defined Fortran derived types (C structs), such as `MatFactorInfo` or `PetscSFNode`,
2237c884152SBarry Smithcannot be passed as null from Fortran. A properly defined variable must be passed in for those arguments.
2247c884152SBarry Smith
2257f296bb3SBarry SmithFinally when a subroutine returns a `PetscObject` through an argument, to check if it is `NULL` you must use:
2267f296bb3SBarry Smith
2277f296bb3SBarry Smith```fortran
2287f296bb3SBarry Smithif (PetscObjectIsNull(dm)) then
2297f296bb3SBarry Smithif (.not. PetscObjectIsNull(dm)) then
2307f296bb3SBarry Smith```
2317f296bb3SBarry Smith
2327f296bb3SBarry Smithyou cannot use
2337f296bb3SBarry Smith
2347f296bb3SBarry Smith```fortran
2357f296bb3SBarry Smithif (dm .eq. PETSC_NULL_DM) then
2367f296bb3SBarry Smith```
2377f296bb3SBarry Smith
2387f296bb3SBarry SmithNote that
2397f296bb3SBarry Smith
2407f296bb3SBarry Smith```fortran
2417f296bb3SBarry Smithif (PetscObjectIsNull(PETSC_NULL_VEC)) then
2427f296bb3SBarry Smith```
2437f296bb3SBarry Smith
2447f296bb3SBarry Smithwill always return true, for any PETSc object.
2457f296bb3SBarry Smith
2467f296bb3SBarry SmithThese specializations with `NULL` types are required because of Fortran's strict type checking system and lack of a concept of `NULL`,
2477f296bb3SBarry Smiththe Fortran compiler will often warn you if the wrong `NULL` type is passed.
2487f296bb3SBarry Smith
2497f296bb3SBarry Smith(sec_fortranarrays)=
2507f296bb3SBarry Smith
2517f296bb3SBarry Smith### Output Arrays from PETSc functions
2527f296bb3SBarry Smith
2537f296bb3SBarry SmithFor PETSc routine arguments that return an array of `PetscInt`, `PetscScalar`, `PetscReal` or of PETSc objects,
2547f296bb3SBarry Smithone passes in a pointer to an array and the PETSc routine returns an array containing the values. For example,
2557f296bb3SBarry Smith
2567f296bb3SBarry Smith```c
2577f296bb3SBarry SmithPetscScalar *a;
2587f296bb3SBarry SmithVec         v;
2597f296bb3SBarry SmithVecGetArray(v, &a);
2607f296bb3SBarry Smith```
2617f296bb3SBarry Smith
2627f296bb3SBarry Smithis in Fortran,
2637f296bb3SBarry Smith
2647f296bb3SBarry Smith```fortran
2657f296bb3SBarry SmithPetscScalar, pointer :: a(:)
2667f296bb3SBarry SmithVec,         v
2677f296bb3SBarry SmithVecGetArray(v, a, ierr)
2687f296bb3SBarry Smith```
2697f296bb3SBarry Smith
2707f296bb3SBarry SmithFor PETSc routine arguments that return a character string (array), e.g. `const char *str[]` pass a string long enough to hold the
2717f296bb3SBarry Smithresult. For example,
2727f296bb3SBarry Smith
2737f296bb3SBarry Smith```fortran
2747f296bb3SBarry Smithcharacter*(80)  str
2757f296bb3SBarry SmithPetscCall(KSPGetType(ksp,str,ierr))
2767f296bb3SBarry Smith```
2777f296bb3SBarry Smith
2787f296bb3SBarry SmithThe result is copied into `str`.
2797f296bb3SBarry Smith
2807f296bb3SBarry SmithSimilarly, 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`.
2817f296bb3SBarry SmithIn Fortran pass a string long enough to hold the result, but not the separate length argument. For example,
2827f296bb3SBarry Smith
2837f296bb3SBarry Smith```fortran
2847f296bb3SBarry Smithcharacter*(80)  str
2857f296bb3SBarry SmithPetscCall(PetscGetHostName(name,ierr))
2867f296bb3SBarry Smith```
2877f296bb3SBarry Smith
2887f296bb3SBarry Smith### Matrix, Vector and IS Indices
2897f296bb3SBarry Smith
2907f296bb3SBarry SmithAll matrices, vectors and `IS` in PETSc use zero-based indexing in the PETSc API
2917f296bb3SBarry Smithregardless of whether C or Fortran is being used. For example,
2927f296bb3SBarry Smith`MatSetValues()` and `VecSetValues()` always use
2937f296bb3SBarry Smithzero indexing. See {any}`sec_matoptions` for further
2947f296bb3SBarry Smithdetails.
2957f296bb3SBarry Smith
2967f296bb3SBarry SmithIndexing into Fortran arrays, for example obtained with `VecGetArray()`, uses the Fortran
2977f296bb3SBarry Smithconvention and generally begin with 1 except for special routines such as `DMDAVecGetArray()` which uses the ranges
2987f296bb3SBarry Smithprovided by `DMDAGetCorners()`.
2997f296bb3SBarry Smith
300*2a8381b2SBarry Smith(sec_fortran_context)=
301*2a8381b2SBarry Smith
3027f296bb3SBarry Smith### Setting Routines and Contexts
3037f296bb3SBarry Smith
3047f296bb3SBarry SmithSome PETSc functions take as arguments user-functions and contexts for the function. For example
3057f296bb3SBarry Smith
3067f296bb3SBarry Smith```fortran
3077f296bb3SBarry Smithexternal func
3087f296bb3SBarry SmithSNESSetFunction(snes, r, func, ctx, ierr)
3097f296bb3SBarry SmithSNES snes
3107f296bb3SBarry SmithVec r
3117f296bb3SBarry SmithPetscErrorCode ierr
3127f296bb3SBarry Smith```
3137f296bb3SBarry Smith
3147f296bb3SBarry Smithwhere `func` has the calling sequence
3157f296bb3SBarry Smith
3167f296bb3SBarry Smith```fortran
3177f296bb3SBarry Smithsubroutine func(snes, x, f, ctx, ierr)
3187f296bb3SBarry SmithSNES snes
3197f296bb3SBarry SmithVec x,f
3207f296bb3SBarry SmithPetscErrorCode ierr
3217f296bb3SBarry Smith```
3227f296bb3SBarry Smith
3237f296bb3SBarry Smithand `ctx` can be almost anything (represented as `void *` in C).
3247f296bb3SBarry Smith
325*2a8381b2SBarry SmithIn Fortran, it has to be a derived type as in
3267f296bb3SBarry Smith
3277f296bb3SBarry Smith```fortran
3287f296bb3SBarry Smithsubroutine func(snes, x, f, ctx, ierr)
3297f296bb3SBarry SmithSNES snes
3307f296bb3SBarry SmithVec x,f
331*2a8381b2SBarry Smithtype (AppCtx)   ctx
3327f296bb3SBarry SmithPetscErrorCode ierr
3337f296bb3SBarry Smith...
3347f296bb3SBarry Smith
3357f296bb3SBarry Smithexternal func
3367f296bb3SBarry SmithSNESSetFunction(snes, r, func, ctx, ierr)
3377f296bb3SBarry SmithSNES snes
3387f296bb3SBarry SmithVec r
3397f296bb3SBarry SmithPetscErrorCode ierr
340*2a8381b2SBarry Smithtype (AppCtx)   ctx
3417f296bb3SBarry Smith```
3427f296bb3SBarry Smith
3437f296bb3SBarry Smithor a PETSc object
3447f296bb3SBarry Smith
3457f296bb3SBarry Smith```fortran
3467f296bb3SBarry Smithsubroutine func(snes, x, f, ctx, ierr)
3477f296bb3SBarry SmithSNES snes
3487f296bb3SBarry SmithVec x,f
3497f296bb3SBarry SmithVec ctx
3507f296bb3SBarry SmithPetscErrorCode ierr
3517f296bb3SBarry Smith...
3527f296bb3SBarry Smith
3537f296bb3SBarry Smithexternal func
3547f296bb3SBarry SmithSNESSetFunction(snes, r, func, ctx, ierr)
3557f296bb3SBarry SmithSNES snes
3567f296bb3SBarry SmithVec r
3577f296bb3SBarry SmithPetscErrorCode ierr
3587f296bb3SBarry SmithVec ctx
3597f296bb3SBarry Smith```
3607f296bb3SBarry Smith
3617f296bb3SBarry Smithor nothing
3627f296bb3SBarry Smith
3637f296bb3SBarry Smith```fortran
3647f296bb3SBarry Smithsubroutine func(snes, x, f, dummy, ierr)
3657f296bb3SBarry SmithSNES snes
3667f296bb3SBarry SmithVec x,f
3677f296bb3SBarry Smithinteger dummy(*)
3687f296bb3SBarry SmithPetscErrorCode ierr
3697f296bb3SBarry Smith...
3707f296bb3SBarry Smith
3717f296bb3SBarry Smithexternal func
3727f296bb3SBarry SmithSNESSetFunction(snes, r, func, 0, ierr)
3737f296bb3SBarry SmithSNES snes
3747f296bb3SBarry SmithVec r
3757f296bb3SBarry SmithPetscErrorCode ierr
3767f296bb3SBarry Smith```
3777f296bb3SBarry Smith
378*2a8381b2SBarry SmithCertain 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
379*2a8381b2SBarry Smithsuch as
380*2a8381b2SBarry Smith
381*2a8381b2SBarry Smith```c
382*2a8381b2SBarry SmithAppCtx *ctx;
383*2a8381b2SBarry SmithSNESGetApplicationContext(snes, &ctx);
384*2a8381b2SBarry Smith```
385*2a8381b2SBarry Smith
386*2a8381b2SBarry SmithIn Fortran, they must be declared as a pointer with, for example,
387*2a8381b2SBarry Smith```fortran
388*2a8381b2SBarry Smithtype(AppCtx), pointer :: ctx
389*2a8381b2SBarry Smithcall SNESGetApplicationContext(snes, ctx)
390*2a8381b2SBarry Smith```
391*2a8381b2SBarry Smith
392*2a8381b2SBarry SmithBut sadly, this alone will not work. One must also specifically tell the Fortran compiler in an interface definition
393*2a8381b2SBarry Smiththat `SNESGetApplicationContext()` expects the `ctx` argument to be a pointer to `type(AppCtx)` since
394*2a8381b2SBarry SmithFortran forbids pointers to unknown types. PETSc provides macros to provide this information easily using, for example,
395*2a8381b2SBarry Smith
396*2a8381b2SBarry Smith```fortran
397*2a8381b2SBarry SmithInterface_SNESGetApplicationContext(AppCtx)
398*2a8381b2SBarry Smithend interface
399*2a8381b2SBarry Smith```
400*2a8381b2SBarry Smith
401*2a8381b2SBarry SmithOne must insert these lines into the Fortran source code where one inserts interface definitions, see, for example,
402*2a8381b2SBarry Smith<a href="PETSC_DOC_OUT_ROOT_PLACEHOLDER/src/snes/tutorials/ex5f90.F90.html">src/snes/tests/ex590.F90</a>. For those interested,
403*2a8381b2SBarry Smiththe 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*2a8381b2SBarry Smith
405*2a8381b2SBarry Smith
4067f296bb3SBarry SmithWhen a function pointer (declared as external in Fortran) is passed as an argument to a PETSc function,
4077f296bb3SBarry Smithit is assumed that this
4087f296bb3SBarry Smithfunction references a routine written in the same language as the PETSc
4097f296bb3SBarry Smithinterface function that was called. For instance, if
4107f296bb3SBarry Smith`SNESSetFunction()` is called from C, the function must be a C function. Likewise, if it is called from Fortran, the
4117f296bb3SBarry Smithfunction must be (a subroutine) written in Fortran.
4127f296bb3SBarry Smith
4137f296bb3SBarry SmithIf you are using Fortran classes that have bound functions (methods) as in
4147f296bb3SBarry Smith<a href="PETSC_DOC_OUT_ROOT_PLACEHOLDER/src/snes/tests/ex18f90.F90.html">src/snes/tests/ex18f90.F90</a>, the context cannot be passed
4157f296bb3SBarry Smithto function pointer setting routines, such as `SNESSetFunction()`. Instead, one must use `SNESSetFunctionNoInterface()`,
4167f296bb3SBarry Smithand define the interface directly in the user code, see
4177f296bb3SBarry Smith<a href="PETSC_DOC_OUT_ROOT_PLACEHOLDER/src/snes/tests/ex18f90.F90.html">ex18f90.F90</a>
4187f296bb3SBarry Smithfor a full demonstration.
4197f296bb3SBarry Smith
4207f296bb3SBarry Smith(sec_fortcompile)=
4217f296bb3SBarry Smith
4227f296bb3SBarry Smith### Compiling and Linking Fortran Programs
4237f296bb3SBarry Smith
4247f296bb3SBarry SmithSee {any}`sec_writing_application_codes`.
4257f296bb3SBarry Smith
4267f296bb3SBarry Smith
4277f296bb3SBarry Smith(sec_fortran_examples)=
4287f296bb3SBarry Smith
4297f296bb3SBarry Smith## Sample Fortran Programs
4307f296bb3SBarry Smith
4317f296bb3SBarry SmithSample programs that illustrate the PETSc interface for Fortran are
4327f296bb3SBarry Smithgiven below, corresponding to
4337f296bb3SBarry Smith<a href="PETSC_DOC_OUT_ROOT_PLACEHOLDER/src/vec/vec/tests/ex19f.F90.html">Vec Test ex19f</a>,
4347f296bb3SBarry Smith<a href="PETSC_DOC_OUT_ROOT_PLACEHOLDER/src/vec/vec/tutorials/ex4f.F90.html">Vec Tutorial ex4f</a>,
4357f296bb3SBarry Smith<a href="PETSC_DOC_OUT_ROOT_PLACEHOLDER/src/sys/classes/draw/tests/ex5f.F90.html">Draw Test ex5f</a>,
4367f296bb3SBarry Smithand
4377f296bb3SBarry Smith<a href="PETSC_DOC_OUT_ROOT_PLACEHOLDER/src/snes/tutorials/ex1f.F90.html">SNES Tutorial ex1f</a>,
4387f296bb3SBarry Smithrespectively. We also refer Fortran programmers to the C examples listed
4397f296bb3SBarry Smiththroughout the manual, since PETSc usage within the two languages
4407f296bb3SBarry Smithdiffers only slightly.
4417f296bb3SBarry Smith
4427f296bb3SBarry Smith:::{admonition} Listing: `src/vec/vec/tests/ex19f.F90`
4437f296bb3SBarry Smith:name: vec-test-ex19f
4447f296bb3SBarry Smith
4457f296bb3SBarry Smith```{literalinclude} /../src/vec/vec/tests/ex19f.F90
4467f296bb3SBarry Smith:end-at: end
4477f296bb3SBarry Smith:language: fortran
4487f296bb3SBarry Smith```
4497f296bb3SBarry Smith:::
4507f296bb3SBarry Smith
4517f296bb3SBarry Smith(listing_vec_ex4f)=
4527f296bb3SBarry Smith
4537f296bb3SBarry Smith:::{admonition} Listing: `src/vec/vec/tutorials/ex4f.F90`
4547f296bb3SBarry Smith:name: vec-ex4f
4557f296bb3SBarry Smith
4567f296bb3SBarry Smith```{literalinclude} /../src/vec/vec/tutorials/ex4f.F90
4577f296bb3SBarry Smith:end-before: '!/*TEST'
4587f296bb3SBarry Smith:language: fortran
4597f296bb3SBarry Smith```
4607f296bb3SBarry Smith:::
4617f296bb3SBarry Smith
4627f296bb3SBarry Smith:::{admonition} Listing: `src/sys/classes/draw/tests/ex5f.F90`
4637f296bb3SBarry Smith:name: draw-test-ex5f
4647f296bb3SBarry Smith
4657f296bb3SBarry Smith```{literalinclude} /../src/sys/classes/draw/tests/ex5f.F90
4667f296bb3SBarry Smith:end-at: end
4677f296bb3SBarry Smith:language: fortran
4687f296bb3SBarry Smith```
4697f296bb3SBarry Smith:::
4707f296bb3SBarry Smith
4717f296bb3SBarry Smith:::{admonition} Listing: `src/snes/tutorials/ex1f.F90`
4727f296bb3SBarry Smith:name: snes-ex1f
4737f296bb3SBarry Smith
4747f296bb3SBarry Smith```{literalinclude} /../src/snes/tutorials/ex1f.F90
4757f296bb3SBarry Smith:end-before: '!/*TEST'
4767f296bb3SBarry Smith:language: fortran
4777f296bb3SBarry Smith```
4787f296bb3SBarry Smith:::
4797f296bb3SBarry Smith
4807f296bb3SBarry Smith### Calling Fortran Routines from C (and C Routines from Fortran)
4817f296bb3SBarry Smith
4827f296bb3SBarry SmithThe information here applies only if you plan to call your **own**
4837f296bb3SBarry SmithC functions from Fortran or Fortran functions from C.
4847f296bb3SBarry SmithDifferent compilers have different methods of naming Fortran routines
4857f296bb3SBarry Smithcalled from C (or C routines called from Fortran). Most Fortran
4867f296bb3SBarry Smithcompilers change the capital letters in Fortran routines to
4877f296bb3SBarry Smithall lowercase. With some compilers, the Fortran compiler appends an underscore
4887f296bb3SBarry Smithto the end of each Fortran routine name; for example, the Fortran
4897f296bb3SBarry Smithroutine `Dabsc()` would be called from C with `dabsc_()`. Other
4907f296bb3SBarry Smithcompilers change all the letters in Fortran routine names to capitals.
4917f296bb3SBarry Smith
4927f296bb3SBarry SmithPETSc provides two macros (defined in C/C++) to help write portable code
4937f296bb3SBarry Smiththat mixes C/C++ and Fortran. They are `PETSC_HAVE_FORTRAN_UNDERSCORE`
4947f296bb3SBarry Smithand `PETSC_HAVE_FORTRAN_CAPS` , which will be defined in the file
4957f296bb3SBarry Smith`$PETSC_DIR/$PETSC_ARCH/include/petscconf.h` based on the compilers
4967f296bb3SBarry Smithconventions. The macros are used,
4977f296bb3SBarry Smithfor example, as follows:
4987f296bb3SBarry Smith
4997f296bb3SBarry Smith```fortran
5007f296bb3SBarry Smith#if defined(PETSC_HAVE_FORTRAN_CAPS)
5017f296bb3SBarry Smith#define dabsc_ DABSC
5027f296bb3SBarry Smith#elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
5037f296bb3SBarry Smith#define dabsc_ dabsc
5047f296bb3SBarry Smith#endif
5057f296bb3SBarry Smith.....
5067f296bb3SBarry Smithdabsc_( &n,x,y); /* call the Fortran function */
5077f296bb3SBarry Smith```
508