wingosoft

reference information

brief introduction to modules

if you're not to familiar with modules, this page might be of interest

tips & tricks

some things I keep forgetting. I wrote them down for me but they might be useful for you.

fortran 90 references

contact

I also have modules to perform matrix operations using sor, gauss-seidel, point-jacobi, and thomas algorithms. this is useful in finite-difference modeling of differential equations. email me if you want these.

just the modules, thanks

everything [ browse directory | tarball ]

everything listed below.

datafile type [ source ]

automates the loading of data files from disk. instead of having to write custom list-based IO routines for every program that you write, you can just write two lines of code with this module that automatically reads in the file to a dynamically-sized array. current capabilities include interpolation, and I plan to add output to latex tables (no, the other kind) at some time in the future.

use datafile_type

type(datafile) :: d
integer        :: i = 1

! datafiles can contain one-line headers, where any number of spaces 
! separate the column names. this allows you to later retrieve the
! data by header name and row number. datafile_type detects the
! presence of a header line if the first non-space character is not
! a valid numeric character ([0-9],+,-). when open() is called, the
! entire datafile is read in and stored. The upper limit to array
! size depends on how much memory you have.

call open(d, 'datafile.txt');

do while (i<numrows(d))    ! numrows() is a datafile_type function
   write(*,*) get(d, i, 1) ! get() accesses the element from the 
                           ! 'i'th row and the first column
end do

! you don't need to call close() on a datafile
      

other methods include:

steam tables [ tarball ]

uses the datafile_type module to load steam tables from disk and interpolate within them for water in the subcooled, saturated, and supercooled regions. quite handy. data obtained from NIST's Chemistry Web book site.

use steamtables

call init() ! loads the steam tables into memory

write(*,*) P_sat(500.)  ! saturation pressure at 500 F
write(*,*) T_sat(1000.) ! saturation temperature at 1000 psia

! enthalpy of saturated steam with a quality of 0.5
! you may name any two of 'T=', 'P=', or 'x='
write(*,*) h_sat(T=500.,x=0.5)

! we can do superheated steam too
write(*,*) u_sup(T=700.,P=1000.)

! or subcooled water
write(*,*) u_sub(T=100.,P=14.7.)
      

The available properties are T_sat, P_sat, u, h, v, Cv, Cp, and s for saturated steam and just u, h, v, and s for subcooled and superheated water. For T_sat and P_sat you have to specify the corresponding property (P and T, respectively). The other values require two parameters, T and P for subcooled and superheated states and any two of T, P, or x for saturation properties.

math [ source ]

a few math routines, everyone's got their own toolkit. this particular one includes routines for numerical integration of functions and discrete data, differentiation, root finding, and calculation of error in trapezoidal integration.

use math

! data sets of some length
real, dimension(:) :: x, y

! this block is necessary for the routines that operate on functions
! if f(x) is not defined in a module
interface f
   real function f(x)
      real :: x
   end function f
end interface

write(*,*) derivative(f, 0.0) ! df/dx at x=0
write(*,*) newton(f,0.0)      ! finds root of f(x) using newton's
                              ! method, starting with a guess of x=0
write(*,*) bisection(f,-2.,2.)! finds root of f(x) using bisection.
                              ! inefficient but always works.
write(*,*) integral(f,0.,2.)  ! integral of f from 0 to 2 using
                              ! trapezoid summation
write(*,*) trapz(x,y)	      ! integral of data set (x,y) using
                              ! trapezoidal summation
write(*,*) trapz_poisson_error(x,y)
                              ! error associated with the summation
			      ! (not with the data points themselves)
write(*,*) sd(x)	      ! standard deviation of a data set
      

the trapezoidal functions also take arbitrary lower and upper bounds as third and fourth arguments. the set_epsilon subroutine sets the precision of many of the routines, and calling set_maxloop to something larger might help if you are getting 'maximum loops exceeded' errors.

linear least squares [ tarball ]

a package to determine fit coefficients for a linear least-squares correlation on a set of data, along with error calculation. thanks to Dr. J. M. Doster for starting this project along.

use linear_least_squares

! x and y arrays of some length. yfit will hold values of the
! fit for each x. y_sd is the standard deviation of the y points.
real, dimension(:) :: x, y, y_sd, yfit
real, dimension(2) :: a, a_sd

! fit function of form y=a(2)*x+a(1) to (x,y). standard deviation of
! y values in y_sd, resulting standard deviations of fitting
! parameters a in a_sd.
call lsq_linear(x,y,y_sd,yfit,a,a_sd)

! if you don't want all of that information, there are a couple of
! other ways to call it:

! no standard deviations
call lsq_linear(x,y,yfit,a) 

! no coefficient vector
call lsq_linear(x,y,yfit)

! to fit a function of form y=a(1)*x, first make sure that
! a is an array of dimension 1 and:
call lsq_linear_no_b(x,y,y_sd,yfit,a,a_sd)
! some arguments may be eliminated as above.
      

matrix type [ source ]

I went a little crazy on this one. this module defines vector and matrix types and overloads the '+', '-', '*', and '**' operators for matrices. it also does inversion, transposition, and gauss-jordan elimination.

use vector_type

type(vector) :: v1, v2 

! make v1 and v2 of length 5
call init(v1,5)
call init(v2,5)

v1%vData(1) = 4. ! v1(1) = 4
[...]

! add v1 and v2, take the dot product of the resulant vector and v1
write(*,*) (v1+v2)*v1

! unfortunately, I did not overload the equals operator. don't know why,
! I must not have needed it.
    
use matrix_type

type(matrix) :: m1, m2

! set m1 and m2 to be of dimension 3x3
call init(m1,3,3)
call init(m2,3,3)

m1%mData(1,2)=3. ! m1(1,2)=3.
      

these modules aren't as accessible as the others, but they come in handy if you have to do a lot of matrix operations. you access data elements directly by their associated arrays, vData in the case of vectors and mData for matrices. the defined routines are: