Skip navigation links
(Wind-US Documentation Home Page) (Wind-US User's Guide) (GMAN User's Guide) (MADCAP User's Guide) (CFPOST User's Guide) (Wind-US Utilities) (Common File User's Guide) (Wind-US Installation Guide) (Wind-US Developer's Reference) (Guidelines Documents)

(Programming Guidelines) (Documentation Guidelines) (Testing Guidelines)

Programming Guidelines for
NPARC Alliance Software Development

Introduction

This document describes the programming guidelines to be used during NPARC Alliance software development projects. [Since much of the NPARC Alliance software has been developed over several years, some of the programming guidelines described in this document will not necessarily be followed throughout the final product. They should, however, be followed for any new code that is written.] It deals exclusively with Fortran 90, since most new NPARC Alliance software is written in that language. [Throughout this document, the term "Fortran" should be understood to mean Fortran 90.]

The guidelines are intended to enhance the following aspects of the final product, listed in decreasing order of importance:

Much of this material has been taken, sometimes verbatim, from the following documents:

Program Development and Design

Items in this section are fairly general and fundamental in nature. They impact all three of the items listed above - maintainability, portability, and efficiency.

Language

Use ANSI standard Fortran 90 exclusively, with the following exceptions:

Organization

Common Blocks

Data Types

Dynamic Memory

Compilation

Coding Style

Items in this section are fairly specific, and primarily impact the readability, and thus the maintainability, of the final product. It is recognized that rules for "good coding style" are somewhat subjective. [The guidelines in this document no doubt reflect some of my own biases.] Some flexibility for personal preference should be acceptable. However, these guidelines should be followed at least in spirit throughout the program.

Program Units

Statement Form

Statement Labels

Upper/Lower Case

Spacing

Variable Names

Arrays

Common Blocks

Fortran Parameters

Control Statements

Comments

Input/Output

Obsolete/Forbidden Features

The following Fortran features are either formally declared as obsolete, or widely considered to be poor programming practice, and should not be used:

Appendix - Standard Subprogram Format

The following is an example illustrating the use of the guidelines in this document for one of the subprograms in Wind-US. First, here's an include file named mxdim.par that's needed:

   Integer MXDIM   ! Max grid points in any direction
   Parameter (MXDIM = 1023)
And here's another named test.inc:
   Common /test/ itest
   Integer itest(200)   ! Test options
   Save /test/

And here's the subprogram itself, named blomax.f90:

         Subroutine blomax (jedge,re,yy,rh,uu,vo,vi,tauw,tv)
   !
   !-----Purpose:  This subroutine computes the turbulent viscosity
   !               coefficient using the Baldwin-Lomax model.
   !
   
   !-----Use modules
         Use data_types   ! kind parameters
   
   !-----Require explicit typing of variables
         Implicit none
   
   !-----Parameter statements
         Include 'mxdim.par'
   
   !-----Common blocks
         Include 'test.inc'
   
   !-----Input arguments
         Integer(kindInt), intent(in) :: jedge       ! Index of bl edge
   
         Real(kindSingle), intent(in) :: re          ! Reference Reynolds number
         Real(kindSingle), intent(in) :: yy(MXDIM)   ! Distance from wall
         Real(kindSingle), intent(in) :: rh(MXDIM)   ! Static density
         Real(kindSingle), intent(in) :: uu(jedge)   ! Velocity
         Real(kindSingle), intent(in) :: vo(MXDIM)   ! Vorticity
         Real(kindSingle), intent(in) :: vi(MXDIM)   ! Laminar viscosity coeff
         Real(kindSingle), intent(in) :: tauw        ! Shear stress at the wall
   
   !-----Output arguments
         Real(kindSingle), intent(out) :: tv(jedge)  ! Turbulent viscosity coeff
   
   !-----Local variables
         Integer(kindInt) icross   ! Flag for inner/outer region
         Integer(kindInt) j        ! Do loop index
         Integer(kindInt) jedg     ! Index limit for Fmax search
   
         Real(kindSingle) al       ! Mixing length
         Real(kindSingle) aplus    ! Van Driest damping constant
         Real(kindSingle) bigk     ! Clauser constant
         Real(kindSingle) ccp      ! Constant in outer region model
         Real(kindSingle) ckleb    ! Constant in Klebanoff intermittency factor
         Real(kindSingle) cwk      ! Constant in outer region model
         Real(kindSingle) fkleb    ! Klebanoff intermittency factor
         Real(kindSingle) fl       ! Baldwin-Lomax F parameter
         Real(kindSingle) fmax     ! Baldwin-Lomax Fmax parameter
         Real(kindSingle) frac     ! Fractional decrease in F req'd for peak
         Real(kindSingle) fwake    ! Baldwin-Lomax Fwake parameter
         Real(kindSingle) rdum     ! Ratio of distance from wall to ymax
         Real(kindSingle) smlk     ! Von Karman constant
         Real(kindSingle) tvi      ! Inner region turbulent viscosity coeff
         Real(kindSingle) tvo      ! Outer region turbulent viscosity coeff
         Real(kindSingle) udif     ! Max velocity difference
         Real(kindSingle) umax     ! Max velocity
         Real(kindSingle) umin     ! Min velocity
         Real(kindSingle) ymax     ! Distance from wall to location of Fmax
         Real(kindSingle) yp       ! y+
         Real(kindSingle) ypcon    ! Coeff term for y+, based on wall values
         Real(kindSingle) ypconl   ! Coeff term for y+
         Real(kindSingle) yyj      ! Distance from wall
   
   !-----Set constants
   
         aplus = 26.
         ccp   = 1.6
         ckleb = 0.3
         cwk   = 0.25
         smlk  = 0.4
         bigk  = 0.0168
         If (itest(126) == 1) bigk = 0.0180   ! Comp. correction (cfl3de)
   
   !-----Compute stuff needed in model
   
   !-----Get coefficient term for y+
         If (itest(25) == 1) then     ! Using wall vorticity as in cfl3de
            ypcon = Sqrt(re*rh(1)*vo(1)/vi(1))
         Else                         ! Using wall shear stress
            If (tauw <= 1.e-9) tauw = 1.e-9
            ypcon = Sqrt(re*rh(1)*tauw)/vi(1)
         End if
   
   !-----Set index limit for Fmax search, and fractional decrease needed to
   !-----   qualify as first peak
         jedg = jedge
         frac = .70
         If (itest(163) > 0) then           ! User-spec. frac. decrease
            frac = Real(itest(163))/1000.
         Else if (itest(163) < 0) then      ! Reset search range, use max
            jedg = Min(jedge,-itest(163))   !    value, not first peak
            frac = 0.0
         Endif
   
   !-----Get max velocity and max velocity difference
         umin = 0.
         umax = 0.
         Do j = 2,jedge
            umax = Max(umax,uu(j))
            umin = Min(umin,uu(j))
         End do
         udif = umax - umin
   
   !-----Get Fmax by searching for first peak in F
   
         ymax = 0.
         fmax = 0.
         ypconl = ypcon
         Do j = 2,jedg
            yyj = yy(j)
            If (itest(26) == 1) then   ! Use local values in y+
               ypconl = ypcon*Sqrt(rh(j)/rh(1))*vi(1)/vi(j)
            End if
            yp = ypconl*yyj   ! y+
            fl = yyj*vo(j)*(1. - Exp(-yp/aplus))   ! B-L F parameter
            If (fl > fmax) then             ! Set new Fmax
               fmax = fl
               ymax = yyj
            Else if (fl > frac*fmax) then   ! Keep searching
               Cycle
            Else                            ! Found Fmax, so get out
               Exit
            End if
         End do
   
   !-----Reset ymax and Fmax if necessary, to avoid overflows
         If (ymax < 1.e-6) ymax = 5.e-5
         If (fmax < 1.e-6) fmax = 5.e-5
   
   !-----Compute turbulent viscosity
   
         icross = 0
         ypconl = ypcon
         Do j = 2,jedge
            yyj = yy(j)
            tvi = 1.e10
   
   !--------Inner region value, if we're still there
            If (icross == 0) then
               If (itest(26) == 1) then   ! Use local values in y+
                  ypconl = ypcon*Sqrt(rh(j)/rh(1))*vi(1)/vi(j)
               End if
               yp = ypconl*yyj   ! y+
               al = smlk*yyj*(1. - Exp(-yp/aplus))   ! Mixing length
               tvi = rh(j)*al*al*vo(j)
            End if
   
   !--------Outer region value
            rdum = yyj/ymax
            If (rdum >= 1.e5) then     ! Prevent overflow
              fkleb = 0.0
            Else                       ! Klebanoff intermittency factor
              fkleb = 1./(1. + 5.5*(ckleb*rdum)**6)
            End if
            fwake = Min(ymax*fmax,cwk*ymax*udif*udif/fmax)
            tvo = bigk*ccp*rh(j)*fwake*fkleb
   
   !--------Set turbulent viscosity, plus flag if we're in outer region
            tv(j) = tvi
            If (tvo < tvi) then
               icross = 1
               tv(j) = tvo
            End if
   
   !--------Non-dimensionalize
            tv(j) = re*tv(j)
         End do   ! Do j = 2,jedge
   
   !-----Zero out turbulent viscosity at wall
         tv(1) = 0.0
   
         Return
         End


Last updated 22 Apr 2004