# Porting a problem from Clawpack 4.6.x to PyClaw¶

The script pyclaw/development/clawdata2pyclaw.py is intended to aid in converting a Clawpack 4.6 problem setup to PyClaw. However, some manual conversion is necessary, especially if the problem includes custom fortran routines.

In PyClaw, the high-level portions of the Fortran routines are reorganized in an object-oriented Python framework, while the low-level ones are bound through the Fortran to Python interface generator f2py. Therefore, for simple problems you won’t need to call f2py directly. However, if you want to reutilize some problem-specific fortran routines that were set up and tested in a Clawpack problem, you can easily do it. Indeed, if those routines are complicated and/or computationally intensive, you should consider directly using the f2py interface in the initialization script (see Setting up your own problem). The example in clawpack/pyclaw/examples/shallow_sphere, which solves the shallow water equations on the surface of a sphere, is a complete example that relies heavily on the use of problem-specific Fortran routines. In that problem setup, a few Fortran routines have been used to provide the following functionality:

- Initialize the solution
`state.q[:,:,:]`

- Provide the mapping from a uniform Cartesian domain to the desired physical domain, i.e. the mapc2p function
- Setup the auxiliary variables
`state.aux[:,:,:]`

- Compute the (non-hyperbolic) contribution of a source term
- Impose custom boundary conditions to both solution and auxiliary variables

The first step to succesfully interface the Fortran functions with PyClaw is to automate the extension module generation of these routines through f2py. You can use clawpack/pyclaw/examples/shallow_sphere/Makefile as a template:

```
# Problem's source Fortran files
INITIALIZE_SOURCE = mapc2p.f setaux.f qinit.f src2.f
problem.so: $(INITIALIZE_SOURCE)
$(F2PY) -m problem -c $^
```

The code above, calls f2py to compile a set of Fortran routines
and build a module
(`problem.so`

) which can then be imported as a function in Python.
The argument following the ‘’-m’’ flag is the name the python module should have (i.e.
the name of the target). f2py uses the `numpy.distutils`

module from NumPy
that supports a number of major Fortran compilers. For more information
see http://www.scipy.org/F2py.

After compilation, it is useful to check the signature of each
function contained in `problem.so`

, which may be different than
that of the original Fortran function, since f2py eliminates dummy variables.
One can easily achieve that by using the following commands:

```
$ ipython
>>> import problem
>>> problem?
```

The last command queries the content of the module and outputs the functions’ signature that must be used in the initialization script to correctly call the fortran functions. In the shallow water equations on a sphere example, we get the following output:

```
>>> Type: module
>>> Base Class: <type 'module'>
>>> String Form: <module 'problem' from 'problem.so'>
>>> Namespace: Interactive
>>> File: /Users/../../../clawpack/pyclaw/examples/shallow-sphere/problem.so
>>> Docstring:
This module 'problem' is auto-generated with f2py (version:1).
Functions:
mapc2p(x1,y1,xp,yp,zp,rsphere)
aux = setaux(maxmx,maxmy,num_ghost,mx,my,xlower,ylower,dxc,dyc,aux,rsphere,num_aux=shape(aux,0))
q = qinit(maxmx,maxmy,num_ghost,mx,my,xlower,ylower,dx,dy,q,aux,rsphere,num_eqn=shape(q,0),num_aux=shape(aux,0))
q = src2(maxmx,maxmy,num_ghost,xlower,ylower,dx,dy,q,aux,t,dt,rsphere,num_eqn=shape(q,0),mx=shape(q,1),my=shape(q,2),num_aux=shape(aux,0))
```

For instance, the function `src2`

, which computes the contribution of the
(non-hyperbolic) source term, has the following intent variables:

```
>>> cf2py integer intent(in) maxmx
>>> cf2py integer intent(in) maxmy
>>> cf2py integer optional, intent(in) num_eqn
>>> cf2py integer intent(in) num_ghost
>>> cf2py integer intent(in) mx
>>> cf2py integer intent(in) my
>>> cf2py double precision intent(in) xlower
>>> cf2py double precision intent(in) ylower
>>> cf2py double precision intent(in) dx
>>> cf2py double precision intent(in) dy
>>> cf2py intent(in,out) q
>>> cf2py integer optional, intent(in) num_aux
>>> cf2py intent(in) aux
>>> cf2py double precision intent(in) t
>>> cf2py double precision intent(in) dt
>>> cf2py double precision intent(in) Rsphere
```

Note that `num_eqn`

, `mx`

, `my`

`num_aux`

are identified by f2py as optional
arguments since their values can be retrieved by looking at the dimensions of
other multidimensional arrays, i.e. `q`

and `aux`

.

We are now ready to call and use the Fortran functions in the initialization
script. For instance, the `src2`

function is called in the
script by using a fortran_src_wrapper function whose main part reads:

```
>>> # Call src2 function
>>> import problem
>>> state.q = problem.src2(mx,my,num_ghost,xlowerg,ylowerg,dx,dy,q,aux,t,dt,Rsphere)
```

A similar approach is used to call other wrapped Fortran functions like
`qinit`

, `setaux`

, etc.

An important feature that makes PyClaw more flexible is the
capability to replace the standard low-level Fortran routines whith some
problem-specific routines. Binding new low-level functions and replacing the
standard ones is very easy; the user just needs to modify the problem-specific
Makefile. The shallow water equations on a sphere is again a
typical example that uses this nice feature. Indeed, to run correctly the problem an
ad-hoc `step2`

function (i.e. the `step2qcor`

) is required. For that problem
the interesting part of the Makefile
reads:

```
# Override step2.f with a new function that contains a call to an additional
# function, i.e. qcor.f
# ==========================================================================
override TWO_D_CLASSIC_SOURCES = step2qcor.f qcor.o flux2.o limiter.o philim.o
qcor.o: qcor.f
$(FC) $(FFLAGS) -o qcor.o -c qcor.f
```

The user has just to override `step2.f`

with the new function `step2qcor.f`

and provide new:

```
output_filenames : input_filenames
actions
```

rules to create the targets required by the new Fortran routine. Similar changes to the problem-specific Makefile can be used to replace other low-level Fortran routines.