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