Right at the beginning of the file there is a keyword
PRIVATEwhich means that everything in this module is
PRIVATE
, i.e.,
invisible to programs using this module, unless specified otherwise.
The otherwise specifications can then be seen below:
PUBLIC init_diffusion, init_temp, diff_coef REAL, PUBLIC :: dif_ly_ratio INTEGER, PUBLIC :: dif_nx, dif_ny, dif_npts, dif_ntemps INTEGER, PUBLIC :: dif_numx, dif_numy REAL(long), PUBLIC :: dif_delta_tThis means that functions
init_diffusion
, init_temp
,
and diff_coef
are visible to calling programs, as are
variables dif_ly_ratio
(aka l_{r}), dif_nx
(aka n_{x},
i.e., the number of harmonics in the x direction),
dif_ny
(n_{y}, the number of harmonics in the y direction),
dif_npts
(n_{p}, the total number of grid points),
dif_ntemps
(the total number of time snapshots),
dif_numx
(number of grid points in the x direction),
dif_numy
(number of grid points in the y direction),
and dif_delta_t
(the
that separates time snapshots).
However, the following two variables:
INTEGER :: init_f=1, diff_f=1are private to module
diffusion
. They are used only
by functions init_temp
, and diff_coef
and
don't have to be accessible to any callers.
Observe that although init_f
and diff_f
are private
to this module, they are also global within this module,
i.e., all functions and subroutines
of the module have access to these two variables.
NAMELIST
and its use. This is how it is
declared and then used:
NAMELIST /input/ ly_ratio, delta_t, numx, numy, nx, ny, numt, init_f, diff_f ... INQUIRE ( file='diffus.naml', exist=ex) IF( ex ) THEN OPEN( 10, file='diffus.naml', action='read') READ( 10, input) CLOSE(10) ENDIF ...The declaration of
NAMELIST
specifies certain input
format
that is quite unique to Fortran. It is also very convenient,
although not always portable.
The way you would have to input your data on file diffus.naml
is as follows:
&input ly_ratio = 1.0d0, delta_t = 0.05, numx = 5, numy = 6, nx = 14, ny = 14, numt = 40, init_f = 3, diff_f = 3 /
You can always check easily, if your data has been read in correctly. To do so simply insert:
WRITE( 6, input )immediately after the
READ( 10, input )
statement.
What you will get, when the program runs, should look
as follows:
&INPUT LY_RATIO=1.00000000000000000, DELTA_T=0.500000000000000028E-01, NUMX=5, NUMY=6, NX=14, NY=14, NUMT=40, INIT_F=3, DIFF_F=3 /
The subroutine works as follows. All variables to be read from the namelist are pre-initialised to default values in the declaration part:
INTEGER :: numx=5, numy=5, nx=7, ny=7, numt=20 REAL(long) :: ly_ratio=1.d0, delta_t=0.1Then the subroutine checks if the input file
diffus.naml
exists. The answer to that question is returned on
a logical variable:
LOGICAL :: exIf the file exists then values of
ly_ratio
, delta_t
, numx
, numy
,
nx
, ny
, numt
, init_f
, and
diff_f
are read from the namelist. If the file
does not exist then we stay with the defaults.
All the variables listed above are PRIVATE
.
Before the subroutine exits, the data is transferred from
PRIVATE
to PUBLIC
variables:
dif_ly_ratio = ly_ratio dif_npts = numx*numy dif_delta_t = delta_t dif_ntemps = numt dif_nx = nx dif_ny = ny dif_numx = numx dif_numy = numy
Here is how this is accomplished:
isign = 1 x1 = x IF( x .GT. pi ) THEN isign = -isign x1 = twopi - x ENDIF y1 = y IF( y .GT. pi ) THEN isign = -isign y1 = twopi - y ENDIF
Now we have the definitions of eight models of T_{0}(x, y) (in truth only 7, because model 5 is the same as model 1)
implemented using the SELECT CASE
statement (which
is much the same as SWITCH
in C):
CASE (1) init_temp = isign*(x1*(pi-x1))*y1*(pi-y1)
CASE (2) init_temp = isign*(x1*(pi-x1))*y1*(pi-y1)*y1
CASE (3) init_temp = isign*(x1*(pi-x1))*y1*(pi-y1)*x1
CASE (4) init_temp = isign*(x1*(pi-x1))*y1*(pi-y1)*x1*y1
CASE (5) init_temp = isign*(x1*(pi-x1))*y1*(pi-y1)This model is really the same as model 1.
CASE (6) init_temp = isign*(x1*(pi-x1))**2 *y1*(pi-y1)
CASE (7) init_temp = isign*(x1*(pi-x1))*(y1*(pi-y1))**2
init_f
is not in
then
the default distribution is assumed, which is
CASE default init_temp = isign*SIN(x1)*SIN(y1)
diff_coef
defines D(x,y). The diffusion
coefficient is defined to be even about .
The reason for this is that we are really considering
the following integral:
So, here is how D(x,y) is made even about :
x1 = x IF( x .GT. pi ) x1 = twopi - x y1 = y IF( y .GT. pi ) y1 = twopi - yThe three models and a default model for D(x,y) are as follows:
CASE (1) diff_coef = .5d0 + (x1 + y1) / (2 * twopi)
CASE (2) diff_coef = ((1.d0 + x1)*(pi - x1 + 1.d0)*(y1 + pi))/ 3*pi
CASE (3) diff_coef = (y1 + pi) * pi/((pi + x1) * (2* pi - x1))
CASE default diff_coef = 1.d0