17.4: Module Example Program
- Page ID
- 54376
\( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)
\( \newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\)
( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\)
\( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)
\( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\)
\( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)
\( \newcommand{\Span}{\mathrm{span}}\)
\( \newcommand{\id}{\mathrm{id}}\)
\( \newcommand{\Span}{\mathrm{span}}\)
\( \newcommand{\kernel}{\mathrm{null}\,}\)
\( \newcommand{\range}{\mathrm{range}\,}\)
\( \newcommand{\RealPart}{\mathrm{Re}}\)
\( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)
\( \newcommand{\Argument}{\mathrm{Arg}}\)
\( \newcommand{\norm}[1]{\| #1 \|}\)
\( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)
\( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\AA}{\unicode[.8,0]{x212B}}\)
\( \newcommand{\vectorA}[1]{\vec{#1}} % arrow\)
\( \newcommand{\vectorAt}[1]{\vec{\text{#1}}} % arrow\)
\( \newcommand{\vectorB}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vectorC}[1]{\textbf{#1}} \)
\( \newcommand{\vectorD}[1]{\overrightarrow{#1}} \)
\( \newcommand{\vectorDt}[1]{\overrightarrow{\text{#1}}} \)
\( \newcommand{\vectE}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash{\mathbf {#1}}}} \)
\( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)
\(\newcommand{\avec}{\mathbf a}\) \(\newcommand{\bvec}{\mathbf b}\) \(\newcommand{\cvec}{\mathbf c}\) \(\newcommand{\dvec}{\mathbf d}\) \(\newcommand{\dtil}{\widetilde{\mathbf d}}\) \(\newcommand{\evec}{\mathbf e}\) \(\newcommand{\fvec}{\mathbf f}\) \(\newcommand{\nvec}{\mathbf n}\) \(\newcommand{\pvec}{\mathbf p}\) \(\newcommand{\qvec}{\mathbf q}\) \(\newcommand{\svec}{\mathbf s}\) \(\newcommand{\tvec}{\mathbf t}\) \(\newcommand{\uvec}{\mathbf u}\) \(\newcommand{\vvec}{\mathbf v}\) \(\newcommand{\wvec}{\mathbf w}\) \(\newcommand{\xvec}{\mathbf x}\) \(\newcommand{\yvec}{\mathbf y}\) \(\newcommand{\zvec}{\mathbf z}\) \(\newcommand{\rvec}{\mathbf r}\) \(\newcommand{\mvec}{\mathbf m}\) \(\newcommand{\zerovec}{\mathbf 0}\) \(\newcommand{\onevec}{\mathbf 1}\) \(\newcommand{\real}{\mathbb R}\) \(\newcommand{\twovec}[2]{\left[\begin{array}{r}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\ctwovec}[2]{\left[\begin{array}{c}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\threevec}[3]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\cthreevec}[3]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\fourvec}[4]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\cfourvec}[4]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\fivevec}[5]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\cfivevec}[5]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\mattwo}[4]{\left[\begin{array}{rr}#1 \amp #2 \\ #3 \amp #4 \\ \end{array}\right]}\) \(\newcommand{\laspan}[1]{\text{Span}\{#1\}}\) \(\newcommand{\bcal}{\cal B}\) \(\newcommand{\ccal}{\cal C}\) \(\newcommand{\scal}{\cal S}\) \(\newcommand{\wcal}{\cal W}\) \(\newcommand{\ecal}{\cal E}\) \(\newcommand{\coords}[2]{\left\{#1\right\}_{#2}}\) \(\newcommand{\gray}[1]{\color{gray}{#1}}\) \(\newcommand{\lgray}[1]{\color{lightgray}{#1}}\) \(\newcommand{\rank}{\operatorname{rank}}\) \(\newcommand{\row}{\text{Row}}\) \(\newcommand{\col}{\text{Col}}\) \(\renewcommand{\row}{\text{Row}}\) \(\newcommand{\nul}{\text{Nul}}\) \(\newcommand{\var}{\text{Var}}\) \(\newcommand{\corr}{\text{corr}}\) \(\newcommand{\len}[1]{\left|#1\right|}\) \(\newcommand{\bbar}{\overline{\bvec}}\) \(\newcommand{\bhat}{\widehat{\bvec}}\) \(\newcommand{\bperp}{\bvec^\perp}\) \(\newcommand{\xhat}{\widehat{\xvec}}\) \(\newcommand{\vhat}{\widehat{\vvec}}\) \(\newcommand{\uhat}{\widehat{\uvec}}\) \(\newcommand{\what}{\widehat{\wvec}}\) \(\newcommand{\Sighat}{\widehat{\Sigma}}\) \(\newcommand{\lt}{<}\) \(\newcommand{\gt}{>}\) \(\newcommand{\amp}{&}\) \(\definecolor{fillinmathshade}{gray}{0.9}\)The following is an example program to compute the surface area and volume of a sphere. This is a fairly straightforward problem focusing more on the creation and use of a module for some routines.
Understand the Problem
This problem will be divided into two parts, the main program source file and a secondary source file containing the subroutines and functions. While this problem is not large enough to require splitting into multiple files, it is split to provide an example of how to use modules.
The formulas for the surface area and volume of a sphere are as follows:

\[ \textit{surfaceArea} = 4.0 \cdot \pi \cdot \textit{radius}^2 \nonumber \]
\[ \textit{volume} = \frac{4.0 \cdot \pi}{3.0} \cdot \textit{radius}^3 \nonumber \]
The value of \(\pi\) will be defined as a constant and set to 3.14159.
For this example, the main program will display some initial headers and read the radius from the user. Once the radius is read, the main program will call functions for the surface area and the volume, and a subroutine to display the results.
Create the Algorithm
Based on the problem definition, the steps for the main are:
! display header and read radius ! call functions for sphere volume and surface area ! call routine to display formatted results
The module will contain the functions and subroutine. The first function will compute the sphere volume. The single step is:
! compute the volume of a sphere with given radius. ! sphere volume = [ (4.0 * pi) / 3.0 ] * radius^3
The second function will compute the sphere surface area. The single step is:
! compute the volume of a sphere with given radius ! sphere volume = 4.0 * pi * radius^2
The subroutine will display the formatted results.
Implement the Program
The program is presented in two parts corresponding to the main program and the secondary module routines. While this example is not really long or complex enough to require multiple files, the program is split in order to provide an example using a separate module file.
Main Program
Based on the algorithm, the below program could be created.
program sphere use sphereRoutines implicit none real :: radius, spVolume, spSurfaceArea ! ----- ! Display header and read radius write (*,'(a/)') "Sphere Example Program" write (*,'(a)', advance="no") "Radius: " read (*,*) radius ! ----- ! Call functions for sphere volume and surface area spVolume = sphereVolume(radius) spSurfaceArea = sphereSurfaceArea(radius) ! ----- ! Call routine to display formatted results. call displayResults(radius, spVolume, spSurfaceArea) end program sphere
The name of the module, sphereRoutines
in this example, must be the name of the secondary source file.
Module Routines
Based on the algorithms for the two functions and subroutine, the below module program could be developed. In this example, the declaration for π is defined as a global variable. This shares the variable between all the subroutines and functions in the module. Use of global variables is typically limited. This provides an example of an appropriate use of a global variable.
! Example secondary source file. module sphereRoutines implicit none ! needed in every module ! Global declarations, if any, go here. real, parameter :: pi = 3.14159 ! ******************************************************** ! Subroutines and functions are included after ! the 'contains'. contains ! ******************************************************** ! Compute the volume of a sphere with given radius. ! sphere volume = [ (4.0 * pi) / 3.0 ] * radius^3 real function sphereVolume (radius) real, intent(in) :: radius sphereVolume = ( ( 4.0 * pi ) / 3.0 ) * radius ** 3 return end function sphereVolume ! ******************************************************** ! Compute the volume of a sphere with given radius. ! sphere volume = 4.0 * pi * radius^2 real function sphereSurfaceArea (radius) real, intent(in) :: radius sphereSurfaceArea = 4.0 * pi * radius ** 2 return end function sphereSurfaceArea ! ******************************************************** ! Simple routine to display results. subroutine displayResults(rad, vol, area) real, intent(in) :: rad, vol, area write (*,'(/, a)') "-------------------------------" write (*, '(a)' ) "Results:" write (*,'(3x, a, f10.2)') "Sphere Radius = ", rad write (*,'(3x, a, f10.2)') "Sphere Volume = ", vol write (*,'(3x, a, f10.2, /)') & "Sphere Surface Area = ", area return end subroutine displayResults ! ******************************************************** end module sphereRoutines
In a more complex program, multiple module files might be used. The grouping should be based on the logical relationship of the routines. A more complicated program would require a more comprehensive design effort.
Compile the Program
The commands to compile the module file and then the main file are as follows:
gfortran -c sphereroutines.f95 gfortran -o modmain modmain.f95 sphereroutine.o
The first will create files sphereroutines.o
and sphereroutines.mod
. The second will read the files modmain.f95
and sphereroutines.o
then create the executable modmain.exe
file.
Test/Debug the Program
For this problem, testing would involve executing the program and entering a series of radius values and to ensure that the results are correct. If the program does not provide the correct results, each of the functions and the subroutines could be verified individually. Each can be checked by displaying the intermediate results to the screen. In this manner, the subroutine or function that is not working correctly can be quickly identified. Once identified, some additional write statements inside the subprogram can be used to help identify the specific problem.