source: anuga_validation/automated_validation_tests/okushiri_tank_validation/compare_timeseries_with_measures.py @ 4339

Last change on this file since 4339 was 4339, checked in by ole, 16 years ago

Inspected visual validation output and settled for tolerances. Automated validation now passes on Windows.

File size: 6.4 KB
Line 
1"""Verify that simulation produced by ANUGA compares to published
2validation timeseries ch5, ch7 and ch9 as well as the boundary timeseries.
3
4RMS norm is printed and plots are produced.
5"""
6
7from Numeric import allclose, argmin, argmax
8from Scientific.IO.NetCDF import NetCDFFile
9
10from anuga.abstract_2d_finite_volumes.util import file_function
11from anuga.utilities.numerical_tools import\
12     ensure_numeric, cov, get_machine_precision
13
14import project
15
16try:
17    from pylab import ion, hold, plot, title, legend, xlabel, ylabel, savefig
18except:
19    print 'Could not import pylab'
20    plotting = False
21else:
22    plotting = True
23
24# No plotting for automated unittest (unless one wishes to run
25# this manually and look at the outputs)
26plotting = False
27
28
29#-------------------------
30# Basic data
31#-------------------------
32
33finaltime = 22.5
34timestep = 0.05
35
36gauge_locations = [[0.000, 1.696]] # Boundary gauge
37gauge_locations += [[4.521, 1.196],  [4.521, 1.696],  [4.521, 2.196]] #Ch 5-7-9
38gauge_names = ['Boundary', 'ch5', 'ch7', 'ch9']
39
40validation_data = {}
41for key in gauge_names:
42    validation_data[key] = []
43
44
45# Expected values
46expected_covariance = {'Boundary': 5.269569575007607815e-05, 
47                       'ch5': 1.166277999581819919e-04,
48                       'ch7': 1.127136457890861503e-04,
49                       'ch9': 1.250659477418482129e-04}
50
51expected_difference = {'Boundary': 8.350712673810733924e-04,
52                       'ch5': 3.405426180525532483e-03,
53                       'ch7': 2.852870417368218517e-03,
54                       'ch9': 3.248778982037564891e-03}
55
56expected_maximum = {'Boundary': 1.611749508386188523e-02, 
57                    'ch5': 3.551308418158714147e-02,
58                    'ch7': 3.858418457126511908e-02,
59                    'ch9': 4.317962986578308127e-02}
60
61expected_minimum = {'Boundary': -1.164547474575844919e-02, 
62                    'ch5': -8.664439185502026408e-03,
63                    'ch7': -2.726335488279797541e-03,
64                    'ch9': -5.977581218447349659e-03}
65
66expected_argmax = {'Boundary': 1.255000000000000071e+01, 
67                   'ch5': 1.839999999999999858e+01,
68                   'ch7': 1.700000000000000000e+01,
69                   'ch9': 1.685000000000000142e+01}
70
71expected_argmin = {'Boundary': 2.064999999999999858e+01, 
72                   'ch5': 1.459999999999999964e+01,
73                   'ch7': 1.230000000000000071e+01,
74                   'ch9': 1.315000000000000036e+01}
75
76#-------------------------
77# Read validation dataa
78#-------------------------
79
80print 'Reading', project.boundary_filename
81fid = NetCDFFile(project.boundary_filename, 'r')
82input_time = fid.variables['time'][:]
83validation_data['Boundary'] = fid.variables['stage'][:]
84
85reference_time = []
86fid = open(project.validation_filename)
87lines = fid.readlines()
88fid.close()
89
90for i, line in enumerate(lines[1:]):
91    if i == len(input_time): break
92   
93    fields = line.split()
94
95    reference_time.append(float(fields[0]))    # Record reference time
96    for j, key in enumerate(gauge_names[1:]):  # Omit boundary gauge
97        value = float(fields[1:][j])           # Omit time
98        validation_data[key].append(value/100) # Convert cm2m
99
100
101# Checks
102assert reference_time[0] == 0.0
103assert reference_time[-1] == finaltime
104assert allclose(reference_time, input_time)
105
106for key in gauge_names:
107    validation_data[key] = ensure_numeric(validation_data[key])
108
109#--------------------------------------------------
110# Read and interpolate model output
111#--------------------------------------------------
112
113import sys
114if len(sys.argv) > 1:
115    sww_filename = sys.argv[1]
116else:   
117    sww_filename = project.output_filename
118   
119f = file_function(sww_filename,
120                  quantities='stage',
121                  interpolation_points=gauge_locations,
122                  use_cache=True,
123                  verbose=True)
124
125
126def report_difference(name, computed_value, reference_value, rtol, atol):
127
128    if abs(reference_value) > 0:
129        msg = '%s (expected, computed):\n  (%.18e, %.18e):\n  Relative error=%.18e'\
130              %(name, reference_value, computed_value,
131                abs(reference_value-computed_value)/reference_value)
132        print msg
133       
134
135    msg = '  Absolute error=%.18e'\
136          %(abs(reference_value-computed_value))       
137    print msg
138
139   
140    #print 'Allclose:', allclose(reference_value, computed_value,
141    #                            rtol=rtol, atol=atol)
142    assert allclose(reference_value, computed_value, rtol=rtol, atol=atol), msg
143   
144
145
146#--------------------------------------------------
147# Compare model output to validation data
148#--------------------------------------------------
149
150
151#eps = get_machine_precision()
152
153# Windows tolerances
154rtol = 1.0e-2
155atol = 1.0e-3
156print 'Precisions used: rtol=%e, atol=%e' %(rtol, atol)
157
158for k, name in enumerate(gauge_names):
159
160    sqsum = 0
161    denom = 0
162    model = []
163    print 
164    print 'Validating ' + name
165    observed_timeseries = validation_data[name]
166    for i, t in enumerate(reference_time):
167        model.append(f(t, point_id=k)[0])
168
169    # Covariance measure   
170    res = cov(observed_timeseries, model)
171    report_difference('Covariance', res, expected_covariance[name], rtol, atol)
172     
173    # Difference measures   
174    res = sum(abs(observed_timeseries-model))/len(model)
175    report_difference('Accumulated difference', res,
176                      expected_difference[name], rtol, atol)   
177
178    # Extrema
179    res = max(model)
180    report_difference('Maximum', res, expected_maximum[name], rtol, atol)
181   
182    res = min(model)
183    report_difference('Minimum', res, expected_minimum[name], rtol, atol)   
184
185    # Locations of extrema
186    #i0 = argmax(observed_timeseries)
187    i1 = argmax(model)
188    res = reference_time[i1]
189    report_difference('Location of maximum', res, expected_argmax[name], rtol, atol)   
190   
191
192    if name <> 'ch9':
193        # Minimum of ch9 is very flat and hard to pinpoint
194        i1 = argmin(model)
195        res = reference_time[i1]
196        report_difference('Location of minimum', res, expected_argmin[name],
197                          rtol, atol)       
198
199
200    if plotting is True:
201        ion()
202        hold(False)
203   
204        plot(reference_time, validation_data[name], 'r-',
205             reference_time, model, 'k-')
206        title('Gauge %s' %name)
207        xlabel('time(s)')
208        ylabel('stage (m)')   
209        legend(('Observed', 'Modelled'), shadow=True, loc='upper left')
210        savefig(name, dpi = 300)       
211
212        raw_input('Next')
213
214
215
Note: See TracBrowser for help on using the repository browser.