Issues unique to Fortran - that
we will encounter in class - are discussed here.
Compiling
- We will generally use a Makefile when
compiling. But in general, to compile a file
with the Intel compiler ifort:
ifort name-of-your-program.f90
(.f90 is the
typical suffix for free-format Fortran 90 code)
- As we'll discuss in class, there are times when you
need to employ additional checking of your code while
it executes, to help track down possible errors
(bugs). In such cases, we will change the
OPTIONS in our Makefile to enable additional
code-checking when compiling; some of those compiler
options are described here.
For example, we could do this:
ifort -g -traceback -check all -ftrapuv
-zero name-of-your-program.f90
- The Portland Group (PGI) compiler, pgf90, is
available on Stampede via the module command.
- There is also
the GNU Fortran compiler, gfortran, which is free and usable
on all platforms and which is also available on
Stampede. It may prove helpful if you want to
download it onto your home/work/laptop personal
computer and do testing of code there. For more
information on gfortran,
check this
page, where you will find binary downloads for
Windows, Linux and Mac. For Mac use, consider
also taking a look at this sourceforge
page (sourceforge is a safe
site for software).
Boundary conditions and
array layout
In Fortran,
1-D arrays are usually
defined/declared with statements like
real s(nx), which is
the same as
real
s(1:nx).
This means that there are
nx array elements, and we address them
as
s(1), s(2), ...,
s(nx).
In some cases this is fine. However, for arrays used
in our
integration,
we will
encounter issues connected to boundary conditions.
Imagine we have a domain that is
nx grid points in
size. And, assume we use an array named
s1
to hold the conditions at the present time, and array
s2 to hold conditions
in the future - at the next time step. For some
array index
j,
determining
s2(j) - the
future value of array
s2 at index point
j - requires knowing
s1(j),
the
current
value at point
j.
However,
most integration methods also require knowing the
neighboring grid values:
s1(j-1) and
s1(j+1),
for example - the grid points to the left and right of
point
j.
Why do we care? Well -
- away from the boundaries - far from j=1 or j=nx - we can
examine points s1(j-1)
and s1(j+1)
without problems.
- at the left boundary, s1(j=1), though, we would need the j-1 point:
s1(0).
- at the right boundary, s1(j=nx), we would need the j+1 point: s1(nx+1).
- but: s1(0) and
s1(nx+1)
don't exist in an array defined s1(nx).
Most codes deal with this one of two ways.
- One approach breaks down the integration procedure with
checks
to see if we are near a boundary. For
example,
do j = 1,nx
if (j.eq.1)
then
do something special
for integration at the left-boundary to get s2(j)
else
if (j.eq.nx) then
do something special
for integration at the right-boundary to get s2(j)
else
this is an
"interior" grid point: do the usual integration,
e.g. s2(j) = some function of s1(j-1), s1(j), and
s1(j+1)
endif
enddo
This gets pretty messy, particularly in 2-D and 3-D;
there are boundaries and corner points to consider.
- Another approach, which
we will follow: deal with the
boundaries before
you do the integration. So it looks
like:
call bc( this subroutine sets the boundary points
s1(0) and s1(nx+1) )
do j = 1,nx
do the same procedure
for all j = 1,...,nx
enddo
In other words, we
set the grid points we need "off the
ends" of our arrays before we do the integration.
We call those 'extra' grid points "
ghost zones" or "ghost
grid points" - they are there to help us solve things
quickly and neatly (there are also some considerations for
ghost
or "halo" points for parallel computing we can talk
about in class). So,
our arrays are defined s1(0:nx+1) instead of
s1(1:nx). The declaration at the top of
your program would look like
"real s1(0:nx+1)".
So you will see plenty of places in Fortran codes where
extra array points are used, more than the simple (nx).
In the demo code,
we define arrays
s1(0:nx+1)
and
s2(0:nx+1).
Only
1,...,nx
are physical; the others are 'helper' points.
Click on the following icon to see an image
summarizing the above: |
|