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); passing a literal 0 from 157Fortran in this case will crash the code. For example, when no options prefix is desired 158in the routine `PetscOptionsGetInt()`, one must use the following 159command in Fortran: 160 161```fortran 162PetscCall(PetscOptionsGetInt(PETSC_NULL_OPTIONS, PETSC_NULL_CHARACTER, PETSC_NULL_CHARACTER, '-name', N, flg, ierr)) 163``` 164 165Where the code expects an array, then use `PETSC_NULL_XXX_ARRAY`. For example: 166 167```fortran 168PetscCall(MatCreateSeqDense(comm, m, n, PETSC_NULL_SCALAR_ARRAY, A)) 169``` 170 171When a PETSc function returns multiple arrays, such as `DMDAGetOwnershipRanges()` and the user does not need 172certain arrays they must pass `PETSC_NULL_XXX_POINTER` as the argument. For example, 173 174```fortran 175PetscInt, pointer :: lx(:), ly(:) 176PetscCallA(DMDAGetOwnershipRanges(da, lx, ly, PETSC_NULL_INTEGER_POINTER, ierr)) 177PetscCallA(DMDARestoreOwnershipRanges(da, lx, ly, PETSC_NULL_INTEGER_POINTER, ierr)) 178``` 179 180Finally when a subroutine returns a `PetscObject` through an argument, to check if it is `NULL` you must use: 181 182```fortran 183if (PetscObjectIsNull(dm)) then 184if (.not. PetscObjectIsNull(dm)) then 185``` 186 187you cannot use 188 189```fortran 190if (dm .eq. PETSC_NULL_DM) then 191``` 192 193Note that 194 195```fortran 196if (PetscObjectIsNull(PETSC_NULL_VEC)) then 197``` 198 199will always return true, for any PETSc object. 200 201These specializations with `NULL` types are required because of Fortran's strict type checking system and lack of a concept of `NULL`, 202the Fortran compiler will often warn you if the wrong `NULL` type is passed. 203 204(sec_fortranarrays)= 205 206### Output Arrays from PETSc functions 207 208For PETSc routine arguments that return an array of `PetscInt`, `PetscScalar`, `PetscReal` or of PETSc objects, 209one passes in a pointer to an array and the PETSc routine returns an array containing the values. For example, 210 211```c 212PetscScalar *a; 213Vec v; 214VecGetArray(v, &a); 215``` 216 217is in Fortran, 218 219```fortran 220PetscScalar, pointer :: a(:) 221Vec, v 222VecGetArray(v, a, ierr) 223``` 224 225For PETSc routine arguments that return a character string (array), e.g. `const char *str[]` pass a string long enough to hold the 226result. For example, 227 228```fortran 229character*(80) str 230PetscCall(KSPGetType(ksp,str,ierr)) 231``` 232 233The result is copied into `str`. 234 235Similarly, 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`. 236In Fortran pass a string long enough to hold the result, but not the separate length argument. For example, 237 238```fortran 239character*(80) str 240PetscCall(PetscGetHostName(name,ierr)) 241``` 242 243### Matrix, Vector and IS Indices 244 245All matrices, vectors and `IS` in PETSc use zero-based indexing in the PETSc API 246regardless of whether C or Fortran is being used. For example, 247`MatSetValues()` and `VecSetValues()` always use 248zero indexing. See {any}`sec_matoptions` for further 249details. 250 251Indexing into Fortran arrays, for example obtained with `VecGetArray()`, uses the Fortran 252convention and generally begin with 1 except for special routines such as `DMDAVecGetArray()` which uses the ranges 253provided by `DMDAGetCorners()`. 254 255### Setting Routines and Contexts 256 257Some PETSc functions take as arguments user-functions and contexts for the function. For example 258 259```fortran 260external func 261SNESSetFunction(snes, r, func, ctx, ierr) 262SNES snes 263Vec r 264PetscErrorCode ierr 265``` 266 267where `func` has the calling sequence 268 269```fortran 270subroutine func(snes, x, f, ctx, ierr) 271SNES snes 272Vec x,f 273PetscErrorCode ierr 274``` 275 276and `ctx` can be almost anything (represented as `void *` in C). 277 278It can be a Fortran derived type as in 279 280```fortran 281subroutine func(snes, x, f, ctx, ierr) 282SNES snes 283Vec x,f 284type (userctx) ctx 285PetscErrorCode ierr 286... 287 288external func 289SNESSetFunction(snes, r, func, ctx, ierr) 290SNES snes 291Vec r 292PetscErrorCode ierr 293type (userctx) ctx 294``` 295 296or a PETSc object 297 298```fortran 299subroutine func(snes, x, f, ctx, ierr) 300SNES snes 301Vec x,f 302Vec ctx 303PetscErrorCode ierr 304... 305 306external func 307SNESSetFunction(snes, r, func, ctx, ierr) 308SNES snes 309Vec r 310PetscErrorCode ierr 311Vec ctx 312``` 313 314or nothing 315 316```fortran 317subroutine func(snes, x, f, dummy, ierr) 318SNES snes 319Vec x,f 320integer dummy(*) 321PetscErrorCode ierr 322... 323 324external func 325SNESSetFunction(snes, r, func, 0, ierr) 326SNES snes 327Vec r 328PetscErrorCode ierr 329``` 330 331When a function pointer (declared as external in Fortran) is passed as an argument to a PETSc function, 332it is assumed that this 333function references a routine written in the same language as the PETSc 334interface function that was called. For instance, if 335`SNESSetFunction()` is called from C, the function must be a C function. Likewise, if it is called from Fortran, the 336function must be (a subroutine) written in Fortran. 337 338If you are using Fortran classes that have bound functions (methods) as in 339<a href="PETSC_DOC_OUT_ROOT_PLACEHOLDER/src/snes/tests/ex18f90.F90.html">src/snes/tests/ex18f90.F90</a>, the context cannot be passed 340to function pointer setting routines, such as `SNESSetFunction()`. Instead, one must use `SNESSetFunctionNoInterface()`, 341and define the interface directly in the user code, see 342<a href="PETSC_DOC_OUT_ROOT_PLACEHOLDER/src/snes/tests/ex18f90.F90.html">ex18f90.F90</a> 343for a full demonstration. 344 345(sec_fortcompile)= 346 347### Compiling and Linking Fortran Programs 348 349See {any}`sec_writing_application_codes`. 350 351### Duplicating Multiple Vectors 352 353The Fortran interface to `VecDuplicateVecs()` differs slightly from 354the C/C++ variant. To create `n` vectors of the same 355format as an existing vector, the user must declare a vector array, 356`v_new` of size `n`. Then, after `VecDuplicateVecs()` has been 357called, `v_new` will contain (pointers to) the new PETSc vector 358objects. When finished with the vectors, the user should destroy them by 359calling `VecDestroyVecs()`. For example, the following code fragment 360duplicates `v_old` to form two new vectors, `v_new(1)` and 361`v_new(2)`. 362 363```fortran 364Vec v_old, v_new(2) 365PetscInt ierr 366PetscScalar alpha 367.... 368PetscCall(VecDuplicateVecs(v_old, 2, v_new, ierr)) 369alpha = 4.3 370PetscCall(VecSet(v_new(1), alpha, ierr)) 371alpha = 6.0 372PetscCall(VecSet(v_new(2), alpha, ierr)) 373.... 374PetscCall(VecDestroyVecs(2, v_new, ierr)) 375``` 376 377(sec_fortran_examples)= 378 379## Sample Fortran Programs 380 381Sample programs that illustrate the PETSc interface for Fortran are 382given below, corresponding to 383<a href="PETSC_DOC_OUT_ROOT_PLACEHOLDER/src/vec/vec/tests/ex19f.F90.html">Vec Test ex19f</a>, 384<a href="PETSC_DOC_OUT_ROOT_PLACEHOLDER/src/vec/vec/tutorials/ex4f.F90.html">Vec Tutorial ex4f</a>, 385<a href="PETSC_DOC_OUT_ROOT_PLACEHOLDER/src/sys/classes/draw/tests/ex5f.F90.html">Draw Test ex5f</a>, 386and 387<a href="PETSC_DOC_OUT_ROOT_PLACEHOLDER/src/snes/tutorials/ex1f.F90.html">SNES Tutorial ex1f</a>, 388respectively. We also refer Fortran programmers to the C examples listed 389throughout the manual, since PETSc usage within the two languages 390differs only slightly. 391 392:::{admonition} Listing: `src/vec/vec/tests/ex19f.F90` 393:name: vec-test-ex19f 394 395```{literalinclude} /../src/vec/vec/tests/ex19f.F90 396:end-at: end 397:language: fortran 398``` 399::: 400 401(listing_vec_ex4f)= 402 403:::{admonition} Listing: `src/vec/vec/tutorials/ex4f.F90` 404:name: vec-ex4f 405 406```{literalinclude} /../src/vec/vec/tutorials/ex4f.F90 407:end-before: '!/*TEST' 408:language: fortran 409``` 410::: 411 412:::{admonition} Listing: `src/sys/classes/draw/tests/ex5f.F90` 413:name: draw-test-ex5f 414 415```{literalinclude} /../src/sys/classes/draw/tests/ex5f.F90 416:end-at: end 417:language: fortran 418``` 419::: 420 421:::{admonition} Listing: `src/snes/tutorials/ex1f.F90` 422:name: snes-ex1f 423 424```{literalinclude} /../src/snes/tutorials/ex1f.F90 425:end-before: '!/*TEST' 426:language: fortran 427``` 428::: 429 430### Calling Fortran Routines from C (and C Routines from Fortran) 431 432The information here applies only if you plan to call your **own** 433C functions from Fortran or Fortran functions from C. 434Different compilers have different methods of naming Fortran routines 435called from C (or C routines called from Fortran). Most Fortran 436compilers change the capital letters in Fortran routines to 437all lowercase. With some compilers, the Fortran compiler appends an underscore 438to the end of each Fortran routine name; for example, the Fortran 439routine `Dabsc()` would be called from C with `dabsc_()`. Other 440compilers change all the letters in Fortran routine names to capitals. 441 442PETSc provides two macros (defined in C/C++) to help write portable code 443that mixes C/C++ and Fortran. They are `PETSC_HAVE_FORTRAN_UNDERSCORE` 444and `PETSC_HAVE_FORTRAN_CAPS` , which will be defined in the file 445`$PETSC_DIR/$PETSC_ARCH/include/petscconf.h` based on the compilers 446conventions. The macros are used, 447for example, as follows: 448 449```fortran 450#if defined(PETSC_HAVE_FORTRAN_CAPS) 451#define dabsc_ DABSC 452#elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE) 453#define dabsc_ dabsc 454#endif 455..... 456dabsc_( &n,x,y); /* call the Fortran function */ 457``` 458