xref: /petsc/doc/manual/fortran.md (revision 7f296bb328fcd4c99f2da7bfe8ba7ed8a4ebceee)
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