source: trunk/anuga_core/source/anuga/error_api.py @ 8361

Last change on this file since 8361 was 8260, checked in by janes, 13 years ago

Adding anuga.error_api.py

File size: 4.5 KB
Line 
1import matplotlib
2import matplotlib.pyplot as plt
3import matplotlib.tri as tri
4from pylab import *
5
6# The abstract Python-MPI interface
7from anuga_parallel.parallel_abstraction import size, rank, get_processor_name
8from anuga_parallel.parallel_abstraction import finalize, send, receive
9from anuga_parallel.parallel_abstraction import pypar_available, barrier
10
11import random
12
13import numpy as num
14
15'''
16Adds random noise to stage quantities (centroid) in the domain.
17domain - domain where noise is to be added
18samples - number of centroids to add noise to
19dthr - minimum depth threshold, stages corresponding to depths less than this value are not modified
20mag - (relative) magnitude of the noise, uniformly distributed in [-mag, mag]
21'''
22def addRandomNoiseToStage(domain, samples = 50, dthr = 0.1, mag = 1E-15):
23
24    # Calculate depth
25    depth = domain.get_quantity('stage').centroid_values[domain.tri_full_flag == 1] \
26        - domain.get_quantity('elevation').centroid_values[domain.tri_full_flag == 1]
27
28    stage = domain.get_quantity('stage')
29
30    # Sample centroid values with depth greater than dthr
31    n_tri = int(num.sum(domain.tri_full_flag))
32    tri_index = num.array(range(0,n_tri))
33    submerged = tri_index[depth > dthr]
34    submerged = random.sample(submerged, min(samples, len(submerged)))
35
36    # Add random noise to sampled centroid values
37    if len(submerged) > 0:
38        for i in range(len(submerged)):
39            new_val = (1.0 + random.uniform(-1.0, 1.0)*mag)*stage.centroid_values[submerged[i]]
40            domain.get_quantity('stage').centroid_values.put(submerged[i], new_val)
41
42'''
43Plot errors in centroid quantities, triangles with errors are denoted in blue, while
44triangles without errors are denoted in green.
45
46domain - domain for which the error plots will be displayed
47control_data - control data to compare quantity values against (must have serial indexing)
48rthr - relative error threshold
49athr - absolute error threshold
50quantity - quantity e.g stage
51filename - output filename
52'''
53
54def plotCentroidError(domain, control_data, rthr = 1E-7, athr = 1E-12, 
55                      quantity = 'stage', filename = 'centroid_error.png'):
56
57    n_triangles = num.sum(domain.tri_full_flag)
58   
59    if size() > 1:
60        # If parallel, translate control data to parallel indexing
61        local_control_data = num.zeros(n_triangles)
62        inv_tri_map = domain.get_inv_tri_map()
63       
64        for i in range(n_triangles):
65            local_control_data[i] = control_data[inv_tri_map[(rank(), i)]]
66    else:
67        local_control_data = control_data
68
69    # Evaluate absolute and relative difference between control and actual values
70    stage = domain.get_quantity(quantity)
71    actual_data = stage.centroid_values[:n_triangles]
72    adiff = num.fabs((actual_data - local_control_data))
73    rdiff = adiff/num.fabs(local_control_data)
74
75    # Compute masks for error (err_mask) and non-error (acc_mask) vertex indices based on thresholds
76    vertices = domain.get_vertex_coordinates()
77    err_mask = rdiff > rthr
78    err_mask[adiff <= athr] = False   
79    err_mask = num.repeat(err_mask, 3)
80
81    acc_mask = ~err_mask
82    inv_tri_map = domain.get_inv_tri_map()
83
84    # Plot error and non-error triangle
85    if rank() == 0:
86        fx = {}
87        fy = {}
88        gx = {}
89        gy = {}
90
91        fx[0] = vertices[acc_mask,0]
92        fy[0] = vertices[acc_mask,1]
93        gx[0] = vertices[err_mask,0]
94        gy[0] = vertices[err_mask,1]
95
96        # Receive vertex indices of non-error triangles (fx, fy) and error triangles (gx, gy)
97        for i in range(1,size()):
98            fx[i] = receive(i)
99            fy[i] = receive(i)
100            gx[i] = receive(i)
101            gy[i] = receive(i)
102
103        # Plot non-error triangles in green
104        for i in range(0,size()):
105            n = int(len(fx[i])/3)
106            triang = num.array(range(0,3*n))
107            triang.shape = (n, 3)
108
109            if len(fx[i]) > 0:
110                plt.triplot(fx[i], fy[i], triang, 'g-')
111
112        # Plot error triangles in blue
113        for i in range(0,size()):
114            n = int(len(gx[i])/3)
115                           
116            triang = num.array(range(0,3*n))
117            triang.shape = (n, 3)
118
119            if len(gx[i]) > 0: 
120                plt.triplot(gx[i], gy[i], triang, 'b--')
121               
122        # Save plot
123        plt.savefig(filename)
124       
125    else:
126        # Send error and non-error vertex indices to Proc 0
127        send(vertices[acc_mask,0], 0)
128        send(vertices[acc_mask,1], 0)
129        send(vertices[err_mask,0], 0)
130        send(vertices[err_mask,1], 0)     
Note: See TracBrowser for help on using the repository browser.