afivo-streamer 1.1
1D/2D/3D streamer simulations with AMR
Loading...
Searching...
No Matches
test_correctness.f90
Go to the documentation of this file.
3
4 implicit none
5 integer, parameter :: dp = kind(0.0d0)
6 integer, parameter :: table_size = 99
7 integer, parameter :: test_size = 100*1000
8
9 call test_linear_data(table_size, test_size)
10 call test_linear_extrapolation(table_size, test_size)
11 call test_valid_location(table_size, test_size)
12
13contains
14
15 subroutine test_linear_data(table_size, n_samples)
16 integer, intent(in) :: table_size, n_samples
17 type(lt_t) :: my_lt
18 real(dp) :: x(2) = [-1.0_dp, 1.0_dp]
19 real(dp) :: x_sample(2) = [-2.0_dp, 2.0_dp]
20 real(dp), allocatable :: x_test(:), y(:)
21 real(dp) :: max_deviation
22 real(dp), parameter :: tolerance = 5e-14_dp
23
24 print *, "test_linear_data"
25
26 my_lt = lt_create(x(1), x(2), n_points=table_size, n_cols=1, &
27 xspacing=lt_xspacing_linear)
28
29 call lt_set_col(my_lt, 1, x, f_linear(x))
30
31 allocate(x_test(n_samples))
32 allocate(y(n_samples))
33
34 call random_number(x_test)
35 x_test = x_sample(1) + (x_sample(2) - x_sample(1)) * x_test
36
37 where (x_test < x(1))
38 y = f_linear(x(1))
39 elsewhere (x_test > x(2))
40 y = f_linear(x(2))
41 elsewhere
42 y = f_linear(x_test)
43 end where
44
45 max_deviation = maxval(abs(lt_get_col(my_lt, 1, x_test) - y))
46
47 if (max_deviation > tolerance) then
48 print *, "FAILED: too large deviation from solution", max_deviation
49 else
50 print *, "PASSED"
51 end if
52
53 end subroutine test_linear_data
54
55 subroutine test_linear_extrapolation(table_size, n_samples)
56 integer, intent(in) :: table_size, n_samples
57 type(lt_t) :: my_lt
58 real(dp) :: x(2) = [-1.0_dp, 1.0_dp]
59 real(dp) :: x_sample(2) = [-2.0_dp, 2.0_dp]
60 real(dp), allocatable :: x_test(:), y(:)
61 real(dp) :: max_deviation
62 real(dp), parameter :: tolerance = 5e-14_dp
63
64 print *, "test_linear_extrapolation"
65
66 my_lt = lt_create(x(1), x(2), n_points=table_size, n_cols=1, &
67 xspacing=lt_xspacing_linear, extrapolate_above=.true.)
68
69 call lt_set_col(my_lt, 1, x, f_linear(x))
70
71 allocate(x_test(n_samples))
72 allocate(y(n_samples))
73
74 call random_number(x_test)
75 x_test = x_sample(1) + (x_sample(2) - x_sample(1)) * x_test
76
77 where (x_test < x(1))
78 y = f_linear(x(1))
79 elsewhere
80 y = f_linear(x_test)
81 end where
82
83 max_deviation = maxval(abs(lt_get_col(my_lt, 1, x_test) - y))
84
85 if (max_deviation > tolerance) then
86 print *, "FAILED: too large deviation from solution", max_deviation
87 else
88 print *, "PASSED"
89 end if
90
91 end subroutine test_linear_extrapolation
92
93 subroutine test_valid_location(table_size, n_samples)
94 integer, intent(in) :: table_size, n_samples
95 type(lt_t) :: my_lt
96 real(dp) :: x(2) = [-1.0_dp, 1.0_dp]
97 real(dp) :: x_sample(2) = [-2.0_dp, 2.0_dp]
98 real(dp), allocatable :: x_test(:)
99 type(lt_loc_t), allocatable :: locs(:)
100 integer :: n
101 logical :: success
102
103 print *, "test_valid_location"
104
105 my_lt = lt_create(x(1), x(2), n_points=table_size, n_cols=0, &
106 xspacing=lt_xspacing_linear)
107
108 allocate(x_test(n_samples))
109 call random_number(x_test)
110 x_test = x_sample(1) + (x_sample(2) - x_sample(1)) * x_test
111
112 allocate(locs(n_samples))
113 locs = lt_get_loc(my_lt, x_test)
114
115 success = .true.
116 if (maxval(locs(:)%low_ix) > table_size - 1) then
117 print *, "FAILED: too high low_ix in location"
118 success = .false.
119 end if
120
121 if (minval(locs(:)%low_ix) < 1) then
122 print *, "FAILED: too low low_ix in location"
123 success = .false.
124 end if
125
126 do n = 1, n_samples
127 if (x_test(n) < x(1)) then
128 if (locs(n)%low_ix /= 1) then
129 print *, "FAILED: low_ix /= 1 for x < x_min"
130 exit
131 end if
132 else if (x_test(n) > x(2)) then
133 if (locs(n)%low_ix /= table_size-1) then
134 print *, "FAILED: low_ix /= table_size-1 for x > x_max"
135 exit
136 end if
137 else if (my_lt%x(locs(n)%low_ix) > x_test(n) .or. &
138 my_lt%x(locs(n)%low_ix+1) < x_test(n)) then
139 print *, "FAILED: x not between x(low_ix) and x(low_ix+1)"
140 exit
141 end if
142 end do
143
144 if (n /= n_samples + 1) success = .false.
145 if (success) print *, "PASSED"
146
147 end subroutine test_valid_location
148
149 real(dp) elemental function f_linear(x)
150 real(dp), intent(in) :: x
151 f_linear = -1.5_dp * x + 0.5_dp
152 end function f_linear
153
154end program
A Fortran 90 module for creating lookup tables. These tables can be used to efficiently interpolate o...
subroutine, public lt_set_col(my_lt, col_ix, x, y)
Fill the column with index col_ix after linearly interpolating.
type(lt_t) function, public lt_create(x_min, x_max, n_points, n_cols, xspacing, extrapolate_above)
This function returns a new lookup table.
elemental real(dp) function, public lt_get_col(my_lt, col_ix, x)
Get the value of a single column at x.
integer, parameter, public lt_xspacing_linear
elemental type(lt_loc_t) function, public lt_get_loc(my_lt, x)
Get a location in the lookup table.
Type to indicate a location in the lookup table, which can be used to speed up multiple lookups of di...
The lookup table type. There can be one or more columns, for which values can be looked up for a give...
program usage_example
subroutine test_linear_data(table_size, n_samples)