source: trunk/anuga_core/source/anuga_parallel/parallel_shallow_water.py @ 8272

Last change on this file since 8272 was 8272, checked in by steve, 12 years ago

added sww_merge to parallel_domain functions

File size: 7.0 KB
Line 
1"""Class Parallel_shallow_water_domain -
22D triangular domains for finite-volume computations of
3the shallow water equation, with extra structures to allow
4communication between other Parallel_domains and itself
5
6This module contains a specialisation of class Domain
7from module shallow_water.py
8
9Ole Nielsen, Stephen Roberts, Duncan Gray, Christopher Zoppou
10Geoscience Australia, 2004-2005
11
12"""
13
14from anuga import Domain
15
16from anuga_parallel.parallel_generic_communications import *
17from anuga.abstract_2d_finite_volumes.neighbour_mesh import Mesh
18
19import numpy as num
20
21
22#Import matplotlib
23
24
25
26class Parallel_domain(Domain):
27
28    def __init__(self, coordinates, vertices,
29                 boundary=None,
30                 full_send_dict=None,
31                 ghost_recv_dict=None,
32                 number_of_full_nodes=None,
33                 number_of_full_triangles=None,
34                 geo_reference=None,
35                 tri_map=None,
36                 inv_tri_map=None): #jj added this
37
38        Domain.__init__(self,
39                        coordinates,
40                        vertices,
41                        boundary,
42                        full_send_dict=full_send_dict,
43                        ghost_recv_dict=ghost_recv_dict,
44                        processor=pypar.rank(),
45                        numproc=pypar.size(),
46                        number_of_full_nodes=number_of_full_nodes,
47                        number_of_full_triangles=number_of_full_triangles,
48                        geo_reference=geo_reference) #jj added this
49       
50        # PETE: Find the number of full nodes and full triangles, this is a temporary fix
51        # until the bug with get_number_of_full_[nodes|triangles]() is fixed.
52
53        if number_of_full_nodes is not None:
54            self.number_of_full_nodes_tmp = number_of_full_nodes
55        else:
56            self.number_of_full_nodes_tmp = get_number_of_nodes()
57
58        if number_of_full_triangles is not None:
59            self.number_of_full_triangles_tmp = number_of_full_triangles
60        else:
61            self.number_of_full_triangles_tmp = get_number_of_triangles()
62
63        setup_buffers(self)
64
65        self.global_name = 'domain'
66        self.tri_map = tri_map
67        self.inv_tri_map = inv_tri_map
68
69
70    def set_name(self, name):
71        """Assign name based on processor number
72        """
73
74        if name.endswith('.sww'):
75            name = name[:-4]
76
77        self.global_name = name
78
79        # Call parents method with processor number attached.
80        Domain.set_name(self, name + '_P%d_%d' %(self.processor, self.numproc))
81
82
83    def get_global_name(self):
84
85        return self.global_name
86
87
88    def update_timestep(self, yieldstep, finaltime):
89        """Calculate local timestep
90        """
91
92        communicate_flux_timestep(self, yieldstep, finaltime)
93
94        Domain.update_timestep(self, yieldstep, finaltime)
95
96
97
98    def update_ghosts(self):
99
100        # We must send the information from the full cells and
101        # receive the information for the ghost cells
102
103
104        communicate_ghosts(self)
105
106    def apply_fractional_steps(self):
107
108        for operator in self.fractional_step_operators:
109            operator()
110
111        # PETE: Make sure that there are no deadlocks here
112
113        self.update_ghosts()
114
115
116
117    def sww_merge(self, verbose=False):
118
119        if self.processor == 0 and self.numproc > 1:
120            import anuga.utilities.sww_merge as merge
121           
122            merge.sww_merge(self.get_global_name(),self.numproc,verbose)
123
124
125# =======================================================================
126# PETE: NEW METHODS FOR FOR PARALLEL STRUCTURES. Note that we assume the
127# first "number_of_full_[nodes|triangles]" are full [nodes|triangles]
128# For full triangles it is possible to enquire self.tri_full_flag == True
129# =======================================================================
130
131    def get_number_of_full_triangles(self, *args, **kwargs):
132        return self.number_of_full_triangles_tmp
133
134    def get_full_centroid_coordinates(self, *args, **kwargs):
135        C = self.mesh.get_centroid_coordinates(*args, **kwargs)
136        return C[:self.number_of_full_triangles_tmp, :]
137
138    def get_full_vertex_coordinates(self, *args, **kwargs):
139        V = self.mesh.get_vertex_coordinates(*args, **kwargs)
140        return V[:3*self.number_of_full_triangles_tmp,:]
141
142    def get_full_triangles(self, *args, **kwargs):
143        T = self.mesh.get_triangles(*args, **kwargs)
144        return T[:self.number_of_full_triangles_tmp,:]
145
146    def get_full_nodes(self, *args, **kwargs):
147        N = self.mesh.get_nodes(*args, **kwargs)
148        return N[:self.number_of_full_nodes_tmp,:]
149
150    def get_tri_map(self):
151        return self.tri_map
152
153    def get_inv_tri_map(self):
154        return self.inv_tri_map
155
156    '''
157    Outputs domain triangulation, full triangles are shown in green while ghost triangles are shown in blue.
158    The default filename is "domain.png"
159    '''
160    def dump_triangulation(self, filename="domain.png"):
161        # Get vertex coordinates, partition full and ghost triangles based on self.tri_full_flag
162
163        try:
164            import matplotlib
165            matplotlib.use('Agg')
166            import matplotlib.pyplot as plt
167            import matplotlib.tri as tri
168        except:
169            print "Couldn't import module from matplotlib, probably you need to update matplotlib"
170            raise
171
172        vertices = self.get_vertex_coordinates()
173        full_mask = num.repeat(self.tri_full_flag == 1, 3)
174        ghost_mask = num.repeat(self.tri_full_flag == 0, 3)
175       
176        myid = pypar.rank()
177        numprocs = pypar.size()
178
179        if myid == 0:
180            fx = {}
181            fy = {}
182            gx = {}
183            gy = {}
184
185            # Proc 0 gathers full and ghost nodes from self and other processors
186            fx[0] = vertices[full_mask,0]
187            fy[0] = vertices[full_mask,1]
188            gx[0] = vertices[ghost_mask,0]
189            gy[0] = vertices[ghost_mask,1]
190           
191            for i in range(1,numprocs):
192                fx[i] = pypar.receive(i)
193                fy[i] = pypar.receive(i)
194                gx[i] = pypar.receive(i)
195                gy[i] = pypar.receive(i)
196
197            # Plot full triangles
198            for i in range(0, numprocs):
199                n = int(len(fx[i])/3)
200                           
201                triang = num.array(range(0,3*n))
202                triang.shape = (n, 3)
203                plt.triplot(fx[i], fy[i], triang, 'g-')
204
205            # Plot ghost triangles
206            for i in range(0, numprocs):
207                n = int(len(gx[i])/3)
208                           
209                triang = num.array(range(0,3*n))
210                triang.shape = (n, 3)
211                plt.triplot(gx[i], gy[i], triang, 'b--')
212
213            # Save triangulation to location pointed by filename
214            plt.savefig(filename)
215
216        else:
217            # Proc 1..numprocs send full and ghost triangles to Proc 0
218            pypar.send(vertices[full_mask,0], 0)
219            pypar.send(vertices[full_mask,1], 0)
220            pypar.send(vertices[ghost_mask,0], 0)
221            pypar.send(vertices[ghost_mask,1], 0)
222           
223
Note: See TracBrowser for help on using the repository browser.