-
Notifications
You must be signed in to change notification settings - Fork 0
memmett/tfortran
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
tfortran: Simple pre-processor to help write multi-dimensional Fortran
codes.
Basic usage
===========
To transform ``input`` and write to ``output``::
$ tfortran [-d DIMENSION] [-i] [-r] [-c] input output
The default dimension is 3.
Known issues
============
#. Error reporting during the transformation process is non-existant.
#. I'm not sure I've settled on the notation... suggestions are welcome.
Transformations
===============
A few simple transforms, by example:
#. Basic indexing (order is preserved)::
With three indexes:
1d: <{ nx, ny, nz }> -> nx
2d: <{ nx, ny, nz }> -> nx, ny
3d: <{ nx, ny, nz }> -> nx, ny, nz
With components:
1d: <{ i, j, k; c }> -> i, c
2d: <{ i, j, k; c }> -> i, j, c
3d: <{ i, j, k; c }> -> i, j, k, c
Auto expansion:
1d: <{ n }> -> n1
2d: <{ n }> -> n1, n2
3d: <{ n }> -> n1, n2, n3
Auto expansion with components:
1d: <{ n; c }> -> n1, c
2d: <{ n; c }> -> n1, n2, c
3d: <{ n; c }> -> n1, n2, n3, c
One-dimensional compression (``compress``): if true, a ``1`` or
``.`` in the component slot is supressed when the dimension is 1::
1d: <{ i, j, k; 1 }> -> i
1d: <{ i, j, k; . }> -> i
1d: <{ i, j, k; c }> -> i, c
2d: <{ i, j, k; 1 }> -> i, j, 1
2d: <{ i, j, k; c }> -> i, j, c
This is enabled by default (disable with ``-c``).
#. Modified indexing (order depends on modifiers):
This is the same as basic indexing (above), except using ``{{`` and
``}}``. Modified indexing is subject to several modifiers:
#. Interleaved components (``interleave``): if true the component
piece is moved to the front::
2d: {{ i, j, k; c }} -> c, i, j
3d: {{ i, j, k; c }} -> c, i, j, k
The is disabled by default (enable with ``-i``).
#. C/row-major storage (``row_major``): if true the spatial indexes
are transposed::
2d: {{ i, j, k; c }} -> j, i, c
3d: {{ i, j, k; c }} -> k, j, i, c
This is disabled by default (enable with ``-r``).
Note that if both ``row_major`` and ``interleave`` are true, then::
2d: {{ i, j, k; c }} -> c, j, i
3d: {{ i, j, k; c }} -> c, k, j, i
#. Selecting appropriate statements::
1d: ({ cos(x); cos(x*y); cos(x*y*z) }) -> cos(x)
2d: ({ cos(x); cos(x*y); cos(x*y*z) }) -> cos(x*y)
3d: ({ cos(x); cos(x*y); cos(x*y*z) }) -> cos(x*y*z)
#. Concatenation::
1d: [{ x**2; + y**2; + z**2 }] -> x**2
2d: [{ x**2; + y**2; + z**2 }] -> x**2 + y**2
3d: [{ x**2; + y**2; + z**2 }] -> x**2 + y**2 + z**2
#. Multiple do loops::
do multi(i, j, k; nx, ny, nz)
! body
end do multi
transforms into
do i = 1, nx
do j = 1, ny
do k = 1, nz
! body
end do
end do
end do
You can optionally supply to/from ranges as well:
do multi(i, j, k; -L, -L, -L; L, L, L)
! body
end do multi
transforms into
do i = -L, L
do j = -L, L
do k = -L, L
! body
end do
end do
end do
Example
=======
Consider the following subroutine::
subroutine gradient(f, <{n}>, h, gradf) bind(c, name="divergence")
real(c_double), intent(in) :: f({{n}})
integer(c_int), intent(in), value :: <{n}>
real(c_double), intent(in), value :: h
real(c_double), intent(out) :: gradf({{n;.}})
integer :: {{ i, j, k }}
do multi(<{i, j, k}>; <{n}>)
{[
gradf({{i,j,k;1}}) = f({{i,j,k}});
gradf({{i,j,k;2}}) = f({{i,j,k}});
gradf({{i,j,k;3}}) = f({{i,j,k}})
]}
end do multi
end subroutine divergence
In two dimensions with interleaved, row-major storage, the above
becomes::
subroutine gradient(f, n1, n2, h, gradf) bind(c, name="divergence")
real(c_double), intent(in) :: f(n2, n1)
integer(c_int), intent(in), value :: n1, n2
real(c_double), intent(in), value :: h
real(c_double), intent(out) :: gradf(2, n2, n1)
integer :: j, i
do i = 1, n1
do j = 1, n2
gradf(1, j, i) = f(j, i)
gradf(2, j, i) = f(j, i)
end do
end do
end subroutine divergence
About
Templated Fortran
Resources
Stars
Watchers
Forks
Releases
No releases published
Packages 0
No packages published