1 | """Class Parallel_shallow_water_domain - |
---|
2 | 2D triangular domains for finite-volume computations of |
---|
3 | the shallow water equation, with extra structures to allow |
---|
4 | communication between other Parallel_domains and itself |
---|
5 | |
---|
6 | This module contains a specialisation of class Domain |
---|
7 | from module shallow_water.py |
---|
8 | |
---|
9 | Ole Nielsen, Stephen Roberts, Duncan Gray, Christopher Zoppou |
---|
10 | Geoscience Australia, 2004-2005 |
---|
11 | |
---|
12 | """ |
---|
13 | |
---|
14 | from anuga import Domain |
---|
15 | |
---|
16 | from anuga_parallel.parallel_generic_communications import * |
---|
17 | from anuga.abstract_2d_finite_volumes.neighbour_mesh import Mesh |
---|
18 | |
---|
19 | import numpy as num |
---|
20 | |
---|
21 | |
---|
22 | |
---|
23 | class Parallel_domain(Domain): |
---|
24 | |
---|
25 | def __init__(self, coordinates, vertices, |
---|
26 | boundary=None, |
---|
27 | full_send_dict=None, |
---|
28 | ghost_recv_dict=None, |
---|
29 | number_of_full_nodes=None, |
---|
30 | number_of_full_triangles=None, |
---|
31 | geo_reference=None): #jj added this |
---|
32 | |
---|
33 | Domain.__init__(self, |
---|
34 | coordinates, |
---|
35 | vertices, |
---|
36 | boundary, |
---|
37 | full_send_dict=full_send_dict, |
---|
38 | ghost_recv_dict=ghost_recv_dict, |
---|
39 | processor=pypar.rank(), |
---|
40 | numproc=pypar.size(), |
---|
41 | number_of_full_nodes=number_of_full_nodes, |
---|
42 | number_of_full_triangles=number_of_full_triangles, |
---|
43 | geo_reference=geo_reference) #jj added this |
---|
44 | |
---|
45 | # PETE: Find the number of full nodes and full triangles, this is a temporary fix |
---|
46 | # until the bug with get_number_of_full_[nodes|triangles]() is fixed. |
---|
47 | |
---|
48 | if number_of_full_nodes is not None: |
---|
49 | self.number_of_full_nodes_tmp = number_of_full_nodes |
---|
50 | else: |
---|
51 | self.number_of_full_nodes_tmp = get_number_of_nodes() |
---|
52 | |
---|
53 | if number_of_full_triangles is not None: |
---|
54 | self.number_of_full_triangles_tmp = number_of_full_triangles |
---|
55 | else: |
---|
56 | self.number_of_full_triangles_tmp = get_number_of_triangles() |
---|
57 | |
---|
58 | setup_buffers(self) |
---|
59 | |
---|
60 | |
---|
61 | def set_name(self, name): |
---|
62 | """Assign name based on processor number |
---|
63 | """ |
---|
64 | |
---|
65 | if name.endswith('.sww'): |
---|
66 | name = name[:-4] |
---|
67 | |
---|
68 | # Call parents method with processor number attached. |
---|
69 | Domain.set_name(self, name + '_P%d_%d' %(self.processor, self.numproc)) |
---|
70 | |
---|
71 | |
---|
72 | def update_timestep(self, yieldstep, finaltime): |
---|
73 | """Calculate local timestep |
---|
74 | """ |
---|
75 | |
---|
76 | communicate_flux_timestep(self, yieldstep, finaltime) |
---|
77 | |
---|
78 | Domain.update_timestep(self, yieldstep, finaltime) |
---|
79 | |
---|
80 | |
---|
81 | |
---|
82 | def update_ghosts(self): |
---|
83 | |
---|
84 | # We must send the information from the full cells and |
---|
85 | # receive the information for the ghost cells |
---|
86 | |
---|
87 | |
---|
88 | communicate_ghosts(self) |
---|
89 | |
---|
90 | def apply_fractional_steps(self): |
---|
91 | |
---|
92 | for operator in self.fractional_step_operators: |
---|
93 | operator() |
---|
94 | |
---|
95 | # PETE: Make sure that there are no deadlocks here |
---|
96 | |
---|
97 | self.update_ghosts() |
---|
98 | |
---|
99 | # ======================================================================= |
---|
100 | # PETE: NEW METHODS FOR FOR PARALLEL STRUCTURES. Note that we assume the |
---|
101 | # first "number_of_full_[nodes|triangles]" are full [nodes|triangles] |
---|
102 | # For full triangles it is possible to enquire self.tri_full_flag == True |
---|
103 | # ======================================================================= |
---|
104 | |
---|
105 | def get_number_of_full_triangles(self, *args, **kwargs): |
---|
106 | return self.number_of_full_triangles_tmp |
---|
107 | |
---|
108 | def get_full_centroid_coordinates(self, *args, **kwargs): |
---|
109 | C = self.mesh.get_centroid_coordinates(*args, **kwargs) |
---|
110 | return C[:self.number_of_full_triangles_tmp, :] |
---|
111 | |
---|
112 | def get_full_vertex_coordinates(self, *args, **kwargs): |
---|
113 | V = self.mesh.get_vertex_coordinates(*args, **kwargs) |
---|
114 | return V[:3*self.number_of_full_triangles_tmp,:] |
---|
115 | |
---|
116 | def get_full_triangles(self, *args, **kwargs): |
---|
117 | T = self.mesh.get_triangles(*args, **kwargs) |
---|
118 | return T[:self.number_of_full_triangles_tmp,:] |
---|
119 | |
---|
120 | def get_full_nodes(self, *args, **kwargs): |
---|
121 | N = self.mesh.get_nodes(*args, **kwargs) |
---|
122 | return N[:self.number_of_full_nodes_tmp,:] |
---|
123 | |
---|