funit-12 0.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/bin/funit-12 ADDED
@@ -0,0 +1,72 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ # Main fUnit routine
4
+
5
+ begin require 'rubygems'; rescue LoadError; end
6
+
7
+ $:.push "#{File.dirname $0}/../lib"
8
+ require 'funit'
9
+ require 'optparse'
10
+ require 'ostruct'
11
+
12
+ include Funit
13
+
14
+ funit_data = OpenStruct.new
15
+ funit_data.prog_source_dirs = ['.']
16
+ funit_data.c_code = Funit::C_compile.new
17
+
18
+ OptionParser.new do |opts|
19
+ opts.banner = <<-END_OF_HELP
20
+ To use fUnit, type:
21
+ funit [-options] [test_file_name(s)]
22
+ The argument(s) is optional. If no argument is given, then all the .fun files inside the working directory will be used.
23
+ END_OF_HELP
24
+
25
+ opts.separator ""
26
+ opts.separator "Specific options:"
27
+
28
+ opts.on("-s","--source <dir>",String,"Specify a directory for the non-test source") do |dir|
29
+ funit_data.prog_source_dirs << dir.chomp("/")
30
+ end
31
+
32
+ opts.on("-l","--link_c_code <dir>",String,"Specify a directory of C/C++ code that must be compiled/linked") do |dir|
33
+ funit_data.c_code.compile_library(dir)
34
+ end
35
+
36
+ opts.on_tail("--clean","To remove the files generated by funit") do
37
+ funit_data.c_code.clean_c_code
38
+ Funit::clean_genFiles
39
+ exit
40
+ end
41
+
42
+ opts.separator ""
43
+ opts.separator "Common options:"
44
+
45
+ opts.on_tail("-v","--version","Print version") do
46
+ puts "funit version #{Funit::VERSION}"
47
+ exit
48
+ end
49
+
50
+ opts.on_tail("-h", "--help", "Detailed overview of funit options") do
51
+ puts opts
52
+ exit
53
+ end
54
+
55
+ end.parse!
56
+
57
+ funit_data.prog_source_dirs.flatten!
58
+ funit_data.prog_source_dirs.uniq!
59
+
60
+ Funit::check_for_FSFLAG
61
+
62
+ Funit::run_tests(funit_data)
63
+
64
+ #--
65
+ # Copyright 2006-2007 United States Government as represented by
66
+ # NASA Langley Research Center. No copyright is claimed in
67
+ # the United States under Title 17, U.S. Code. All Other Rights
68
+ # Reserved.
69
+ #
70
+ # This file is governed by the NASA Open Source Agreement.
71
+ # See License.txt for details.
72
+ #++
@@ -0,0 +1,34 @@
1
+ module FluxFunctions
2
+
3
+ implicit none
4
+
5
+ contains
6
+
7
+ subroutine CentralFlux( LeftState, RightState, InterfaceFlux )
8
+ real, intent(in) :: leftState
9
+ real, intent(in) :: rightState
10
+ real, intent(out) :: interfaceFlux
11
+ interfaceFlux = 0.5*(Flux(leftState)+Flux(rightState))
12
+ end subroutine CentralFlux
13
+
14
+ subroutine RoeFlux( LeftState, RightState, InterfaceFlux )
15
+ real, intent(in) :: leftState
16
+ real, intent(in) :: rightState
17
+ real, intent(out) :: interfaceFlux
18
+ interfaceFlux = 0.5*(Flux(leftState)+Flux(rightState)) &
19
+ - 0.5*RoeAvg(leftState,rightState)*(rightState-leftState)
20
+ end subroutine RoeFlux
21
+
22
+ function Flux( state )
23
+ real :: Flux
24
+ real, intent(in) :: state
25
+ Flux = 0.5*state**2
26
+ end function Flux
27
+
28
+ function RoeAvg( leftState, rightState )
29
+ real :: RoeAvg
30
+ real, intent(in) :: leftState, rightState
31
+ RoeAvg = 0.5*(leftState+rightState)
32
+ end function RoeAvg
33
+
34
+ end module FluxFunctions
@@ -0,0 +1,51 @@
1
+ test_suite FluxFunctions
2
+
3
+ real :: leftState, rightState, interfaceFlux
4
+
5
+ setup
6
+ leftState = 0
7
+ rightState = 1
8
+ end setup
9
+
10
+ test FluxZero
11
+ real :: state
12
+ state = 0
13
+ Assert_Equal_Within( 0, Flux(state), 0.00001 )
14
+ end test
15
+
16
+ test FluxOne
17
+ real :: state = 1
18
+ Assert_Equal_Within( 0.5, Flux(state), 0.00001 )
19
+ end test
20
+
21
+ test RoeAvgZero
22
+ Assert_Real_Equal( 0, RoeAvg(0.0,0.0) )
23
+ Assert_False( RoeAvg(0.0,0.0)==1 )
24
+ end test
25
+
26
+ test RoeAvgKnown
27
+ Assert_Real_Equal( 0.5, RoeAvg(leftState,rightState) )
28
+ Assert_True( RoeAvg(leftState,rightState) > 0 )
29
+ end test
30
+
31
+ test CentralFluxKnown
32
+ call CentralFlux( leftState, rightState, interfaceFlux )
33
+ Assert_Equal_Within( 0.25, interfaceFlux, 0.001 )
34
+ Assert_Equal_Within( 0.25, interfaceFlux, 0.00000001 )
35
+ Assert_Equal( 0.25, interfaceFlux )
36
+ end test
37
+
38
+ test RoeFluxExpansionShock
39
+ leftState = -1
40
+ call RoeFlux( leftState, rightState, interfaceFlux )
41
+ Assert_Equal( 0.5, interfaceFlux )
42
+ end test
43
+
44
+ test RoeFluxZero
45
+ rightState = 0
46
+ call RoeFlux( leftState, rightState, interfaceFlux )
47
+ Assert_Real_Equal( 0, interfaceFlux )
48
+ Assert_Equal( 0, interfaceFlux )
49
+ end test
50
+
51
+ end test_suite
@@ -0,0 +1,7 @@
1
+ module Gammas
2
+
3
+ implicit none
4
+
5
+ real, parameter :: Gamma = 1.4
6
+
7
+ end module Gammas
@@ -0,0 +1,16 @@
1
+ module GasModel
2
+
3
+ use Gammas
4
+
5
+ implicit none
6
+
7
+ contains
8
+
9
+ subroutine PerfectP (Density, Energy, Pressure)
10
+ real, intent(in) :: Density
11
+ real, intent(in) :: Energy
12
+ real, intent(out) :: Pressure
13
+ Pressure = Density * Energy * ( Gamma - 1.0 )
14
+ end subroutine PerfectP
15
+
16
+ end module GasModel
@@ -0,0 +1,24 @@
1
+ test_suite GasModel
2
+
3
+ real :: Pressure, Density, Energy
4
+
5
+ test PerfectPZeroed
6
+ real, parameter :: zero = 0
7
+ call PerfectP (zero, zero, Pressure)
8
+ Assert_Real_Equal( 0, Pressure )
9
+ Assert_Equal_within( 0, Pressure, 0.0000000001 )
10
+ end test
11
+
12
+ test Warbler
13
+ end test
14
+
15
+ test PerfectPKnown
16
+ real :: Density = 1
17
+ Energy = 1
18
+ call PerfectP( Density, Energy, Pressure )
19
+ Assert_Real_Equal( 0.4, Pressure )
20
+ Assert_True( Pressure > 0 )
21
+ Assert_False( Pressure < 0 )
22
+ end test
23
+
24
+ end test_suite
@@ -0,0 +1,27 @@
1
+ module time_series_data
2
+ implicit none
3
+ integer, parameter :: MAX_POINTS = 100000 ! or use allocate
4
+ type date_time
5
+ integer :: year, month, day, hour, minute
6
+ end type date_time
7
+ type time_series
8
+ type(date_time) :: date_time
9
+ real :: value = 0.0
10
+ end type time_series
11
+ type(time_series), dimension(MAX_POINTS), save :: ts_data
12
+ contains
13
+ subroutine read_time_series( filename )
14
+ character(len=*), intent(in) :: filename
15
+ integer :: i, ios
16
+ open(10, file=filename, iostat=ios)
17
+ if (ios/=0) then
18
+ print *, 'failed to open file: >>', filename, '<<'
19
+ else
20
+ do i = 1, MAX_POINTS
21
+ read( 10, fmt='(i4,i2,i2,i2,i2,e20.12)', end=20 ) ts_data(i)
22
+ end do
23
+ print *, 'quit reading data after ', MAX_POINTS, ' points'
24
+ 20 continue
25
+ end if
26
+ end subroutine read_time_series
27
+ end module time_series_data
@@ -0,0 +1,33 @@
1
+ test_suite time_series_data
2
+
3
+ character(len=10), parameter :: FILE = 'values.txt'
4
+
5
+ setup
6
+ open(8, file=FILE)
7
+ write(8,'(a)'), '200609300000 0.223200546265E+003'
8
+ write(8,'(a)'), '200609300132 0.226001495361E+003'
9
+ close(8)
10
+ end setup
11
+
12
+ test load_time_series_data_from_file
13
+ call read_time_series( FILE )
14
+ Assert_Equal( 2006, ts_data(1)%date_time%year )
15
+ Assert_Equal( 9, ts_data(1)%date_time%month )
16
+ Assert_Equal( 30, ts_data(1)%date_time%day )
17
+ Assert_Equal( 0, ts_data(1)%date_time%hour )
18
+ Assert_Equal( 0, ts_data(1)%date_time%minute )
19
+ Assert_Equal_Within( 223.2, ts_data(1)%value, 0.1 )
20
+ Assert_Equal( 2006, ts_data(2)%date_time%year )
21
+ Assert_Equal( 9, ts_data(2)%date_time%month )
22
+ Assert_Equal( 30, ts_data(2)%date_time%day )
23
+ Assert_Equal( 1, ts_data(2)%date_time%hour )
24
+ Assert_Equal( 32, ts_data(2)%date_time%minute )
25
+ Assert_Equal_Within( 226.0, ts_data(2)%value, 0.1 )
26
+ end test
27
+
28
+ teardown
29
+ call system('/bin/rm '//FILE)
30
+ end teardown
31
+
32
+ end test_suite
33
+
@@ -0,0 +1,50 @@
1
+ module StopWatch
2
+
3
+ implicit none
4
+
5
+ public
6
+
7
+ logical :: notInitialized = .TRUE.
8
+
9
+ integer, dimension(8) :: last
10
+
11
+ contains
12
+
13
+ real function SecBetween(beginDnT, endDnT)
14
+ integer, dimension(8), intent(in) :: beginDnT, endDnT
15
+ real :: days, hours, minutes, seconds
16
+ integer, parameter :: yr=1, mo=2, day=3, utc=4, hr=5, mn=6, s=7, ms=8
17
+
18
+ continue
19
+
20
+ if ( endDnT(day) == beginDnT(day) ) then
21
+ days = 0
22
+ else
23
+ days = 1 ! note: assuming one day
24
+ endif
25
+
26
+ hours = endDnT(hr) - beginDnT(hr) + 24*days
27
+ minutes = endDnT(mn) - beginDnT(mn) + 60*hours
28
+ seconds = endDnT(s) - beginDnT(s) + 60*minutes
29
+
30
+ SecBetween = seconds + ( endDnT(ms) - beginDnT(ms) ) / 1000.
31
+
32
+ end function SecBetween
33
+
34
+ real function secSinceLast()
35
+
36
+ integer, dimension(8) :: now
37
+
38
+ if (notInitialized) then
39
+ notInitialized = .FALSE.
40
+ secSinceLast = 0.0
41
+ call date_and_time(values=last)
42
+ else
43
+ call date_and_time(values=now)
44
+ secSinceLast = secBetween(last, now)
45
+ last = now
46
+ endif
47
+
48
+ end function secSinceLast
49
+
50
+ end module StopWatch
@@ -0,0 +1,77 @@
1
+ test_suite StopWatch
2
+
3
+ integer, dimension(8) :: dateAndTime1, dateAndTime2
4
+ real :: seconds
5
+
6
+ setup
7
+ NotInitialized = .TRUE.
8
+ last = 0
9
+ seconds = HUGE(0.0)
10
+ end setup
11
+
12
+ test SystemDateAndTimeWorks
13
+ call date_and_time(values=dateAndTime1)
14
+ Assert_True( dateAndTime1(1) /= -huge(0) )
15
+ Assert_True( size(dateAndTime1,1) == 8 )
16
+ end test
17
+
18
+ ! test secBetween
19
+ test OneMSecDifference
20
+ dateAndTime1 = (/ 2000, 1, 1, 0, 0, 0, 0, 0 /)
21
+ dateAndTime2 = (/ 2000, 1, 1, 0, 0, 0, 0, 1 /)
22
+ seconds = SecBetween(dateAndTime1, dateAndTime2)
23
+ Assert_Real_Equal( 0.001, seconds)
24
+ end test
25
+
26
+ test MinuteRollover
27
+ dateAndTime1 = (/ 2000, 1, 1, 0, 0, 0,59, 0 /)
28
+ dateAndTime2 = (/ 2000, 1, 1, 0, 0, 1, 0, 0 /)
29
+ seconds = SecBetween(dateAndTime1, dateAndTime2)
30
+ Assert_Real_Equal( 1.0, seconds )
31
+ end test
32
+
33
+ ! test secSinceLast
34
+ test InitializationState
35
+ Assert_True(notInitialized)
36
+ seconds = secSinceLast()
37
+ Assert_False(notInitialized)
38
+ seconds = secSinceLast()
39
+ Assert_False(notInitialized)
40
+ end test
41
+
42
+ test InitiallyReturnsZero
43
+ seconds = secSinceLast()
44
+ Assert_Real_Equal( 0.0, seconds )
45
+ call timeDelay(seconds)
46
+ seconds = secSinceLast()
47
+ Assert_True( seconds /= 0.0 )
48
+ end test
49
+
50
+ subroutine timeDelay (sum)
51
+ integer :: i
52
+ real :: sum
53
+ do i = 1, 1000000
54
+ sum = sum + i
55
+ enddo
56
+ end subroutine timeDelay
57
+
58
+ test ComputesSeconds
59
+ seconds = secSinceLast()
60
+ call timeDelay (seconds)
61
+ seconds = secSinceLast()
62
+ Assert_True( seconds > 0.0 )
63
+ end test
64
+
65
+ test ComputesSecondsSpecial
66
+ real :: expectedSeconds
67
+
68
+ seconds = secSinceLast()
69
+ dateAndTime1 = last
70
+ call timeDelay (seconds)
71
+ seconds = secSinceLast()
72
+ dateAndTime2 = last
73
+ expectedSeconds = secBetween(dateAndTime1,dateAndTime2)
74
+ Assert_Real_Equal( expectedSeconds, seconds )
75
+ end test
76
+
77
+ end test_suite
data/lib/funit.rb ADDED
@@ -0,0 +1,87 @@
1
+ begin
2
+ require 'rubygems'
3
+ require 'fortran_dependencies'
4
+ rescue LoadError
5
+ STDERR.puts "gem install fortran"
6
+ exit 1
7
+ end
8
+
9
+ require 'funit/compiler'
10
+ require 'funit/functions'
11
+ require 'funit/assertions'
12
+ require 'funit/testsuite'
13
+ require 'funit/c_tools'
14
+ require 'fileutils'
15
+
16
+ module Funit
17
+
18
+ VERSION = '0.12.1'
19
+
20
+ ##
21
+ # run all tests
22
+
23
+ def run_tests(funit_data)
24
+ Compiler.new# a test for compiler env set (FIXME: remove this later)
25
+ write_test_runner( test_files = parse_command_line )
26
+ test_suites = []
27
+ test_files.each{ |test_file|
28
+ tf_content = IO.read(test_file+'.fun')
29
+ tf_content.scan(/test_suite\s+(\w+)(.*?)end\s+test_suite/m).each{|ts|
30
+ ts_name = $1
31
+ ts_content = $2
32
+ if((!File.exist?(ts_name+"_fun.f90")) || File.mtime(ts_name+"_fun.f90") < File.mtime(test_file+".fun")) then
33
+ if ( File.read(ts_name+'.f90').match(/\s*module\s+#{ts_name}/i) ) then
34
+ TestSuite.new(ts_name, ts_content, false)
35
+ else
36
+ TestSuite.new(ts_name, ts_content, true)
37
+ end
38
+ end
39
+ test_suites.push(ts_name)
40
+ }
41
+ }
42
+ compile_tests(test_suites,funit_data)
43
+ exit 1 unless system "env PATH='.' TestRunner"
44
+ end
45
+
46
+ ##
47
+ # remove files generated by fUnit
48
+
49
+ def clean_genFiles
50
+ module_names = Dir["**/*.fun"].map{|mn| mn.chomp(".fun")}
51
+ tbCancelled = module_names.map{|mn| mn+"_fun."} + ["TestRunner."]
52
+ tbCancelled = tbCancelled.map{|tbc| [tbc+"f90",tbc+"o",tbc+"MOD"]}.flatten
53
+ tbCancelled += Dir["**/TestRunner"]
54
+ tbCancelled += Dir["**/makeTestRunner"]
55
+ tbCancelled = (tbCancelled+tbCancelled.map{|tbc| tbc.downcase}).uniq
56
+ FileUtils.rm_f(tbCancelled)
57
+ end
58
+
59
+ def check_for_FSFLAG
60
+ if(ENV['FSFLAG'].nil?) then
61
+ puts <<-EOF
62
+ No environment variable FSFLAG set.
63
+
64
+ For example for most compilers such as gfortran you will need: -I
65
+ sh: export FSFLAG=-I
66
+ csh: setenv FSFLAG -I
67
+ windows: set FSFLAG=-I
68
+
69
+ but for some such as Sun's f95 compiler you will need: -M
70
+ sh: export FSFLAG=-M
71
+ csh: setenv FSFLAG -M
72
+ windows: set FSFLAG=-M
73
+ EOF
74
+ exit
75
+ end
76
+ end
77
+ end
78
+
79
+ #--
80
+ # Copyright 2006-2007 United States Government as represented by
81
+ # NASA Langley Research Center. No copyright is claimed in
82
+ # the United States under Title 17, U.S. Code. All Other Rights
83
+ # Reserved.
84
+ #
85
+ # This file is governed by the NASA Open Source Agreement.
86
+ # See License.txt for details.
87
+ #++