Changeset 8928
- Timestamp:
- Jun 25, 2013, 7:34:21 PM (12 years ago)
- Location:
- trunk/anuga_core/source/anuga/operators
- Files:
-
- 1 edited
- 4 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/anuga_core/source/anuga/operators/run_set_elevation.py
r8873 r8928 36 36 """Complex topography defined by a function of vectors x and y.""" 37 37 38 38 39 z = -x/100 39 40 40 N = len(x)41 for i in range(N):42 # Step43 if 2 < x[i] < 4:44 z[i] += 0.4 - 0.05*y[i]45 41 46 # Permanent pole 47 if (x[i] - 8)**2 + (y[i] - 2)**2 < 0.4**2: 48 z[i] += 1 42 # Step 43 id_s = (2 < x) & (x < 4) 44 45 z[id_s] += 0.4 - 0.05*y[id_s] 46 47 # Permanent pole 48 id_p = (x - 8)**2 + (y - 2)**2 < 0.4**2 49 50 z[id_p] += 1 51 52 49 53 return z 50 54 … … 81 85 if t<10: 82 86 return 0.0 83 elif t>1 5:87 elif t>12: 84 88 return 0.0 85 89 else: … … 105 109 106 110 from anuga.operators.set_elevation_operators import Set_elevation_operator 107 108 111 op1 = Set_elevation_operator(domain, elevation=pole, radius=0.5, center = (12.0,3.0)) 109 112 110 from anuga.operators.set_elevation _operatorsimport Set_elevation111 op2 = Set_elevation(domain, elevation = topography , radius = 1.0, center = (12.0,3.0))113 from anuga.operators.set_elevation import Set_elevation 114 op2 = Set_elevation(domain, elevation = topography) 112 115 113 116 growing = False … … 119 122 domain.print_operator_timestepping_statistics() 120 123 121 if num.allclose(17.0, t): 124 if num.allclose(15.0, t): 125 op1.set_elevation(None) 122 126 op2() 123 127 -
trunk/anuga_core/source/anuga/operators/set_elevation_oprator.py
r8926 r8928 17 17 18 18 from anuga.operators.base_operator import Operator 19 from anuga.operators.set_elevation import Set_elevation 19 20 20 21 from anuga import indent 21 22 class Set_elevation(object):23 """24 Helper class to setup calculation of elevation25 associated with a region (defined by indices, polygon or center/radius26 """27 28 def __init__(self,29 domain,30 elevation=None,31 indices=None,32 polygon=None,33 center=None,34 radius=None):35 36 #------------------------------------------37 # Local variables38 #------------------------------------------39 self.elevation = elevation40 self.indices = indices41 self.center = center42 self.radius = radius43 self.polygon = polygon44 45 46 #------------------------------------------47 # Useful aliases48 #------------------------------------------49 self.domain = domain50 self.stage_c = self.domain.quantities['stage'].centroid_values51 self.xmom_c = self.domain.quantities['xmomentum'].centroid_values52 self.ymom_c = self.domain.quantities['ymomentum'].centroid_values53 self.elev_c = self.domain.quantities['elevation'].centroid_values54 self.coord_c = self.domain.centroid_coordinates55 self.areas = self.domain.areas56 57 58 #------------------------------------------59 # Extra aliases for changing elevation at60 # vertices and edges61 #------------------------------------------62 self.elev_v = self.domain.quantities['elevation'].vertex_values63 self.elev_e = self.domain.quantities['elevation'].edge_values64 65 #------------------------------------------66 # Need to turn off this optimization as it67 # doesn't fixup the relationship between68 # bed and stage vertex values in dry region69 #------------------------------------------70 self.domain.optimise_dry_cells = 071 72 73 #-------------------------------------------74 # Work out region:75 #-------------------------------------------76 if self.indices is not None:77 # This overrides polygon, center and radius78 pass79 elif (self.center is not None) and (self.radius is not None):80 81 assert self.indices is None82 assert self.polygon is None83 84 self.setup_indices_circle()85 86 elif (self.polygon is not None):87 88 assert self.indices is None89 90 self.setup_indices_polygon()91 else:92 assert self.indices is None or self.indices is []93 94 95 #-----------------------------------------96 # Extra structures to support maintaining97 # continuity of elevation98 #-----------------------------------------99 self.setup_node_structures()100 101 102 def __call__(self):103 """104 Apply rate to those triangles defined in indices105 106 indices == [], then don't apply anywhere107 indices == None, then apply everywhere108 otherwise apply for the specific indices109 """110 111 if self.indices is []:112 return113 114 #------------------------------------------115 # Apply changes to elevation vertex values116 # via the update_quantites routine117 #------------------------------------------118 if not self.update_quantities():119 return120 121 122 #------------------------------------------123 # Cleanup elevation and stage quantity values124 #-----------------------------------------125 if self.indices is None:126 127 #--------------------------------------128 # Make elevation continuous and clean up129 # stage values to ensure conservation130 #--------------------------------------131 height_c = self.stage_c - self.elev_c132 self.domain.quantities['elevation'].smooth_vertex_values()133 self.domain.quantities['elevation'].interpolate()134 self.stage_c[:] = self.elev_c + height_c135 136 137 else:138 139 #--------------------------------------140 # Make elevation continuous and clean up141 # stage values to ensure conservation142 #--------------------------------------143 height_c = self.stage_c[self.vols] - self.elev_c[self.vols]144 for nid in self.node_ids:145 non = self.domain.number_of_triangles_per_node[nid]146 147 vid = num.arange(self.node_index[nid], self.node_index[nid+1],dtype=num.int)148 vidd = self.domain.vertex_value_indices[vid]149 150 self.elev_v[vidd/3,vidd%3] = num.sum(self.elev_v[vidd/3,vidd%3])/non151 152 153 #--------------------------------------154 # clean up the centroid values and edge values155 #--------------------------------------156 self.elev_c[self.vols] = num.mean(self.elev_v[self.vols],axis=1)157 158 self.elev_e[self.vols,0] = 0.5*(self.elev_v[self.vols,1]+ self.elev_v[self.vols,2])159 self.elev_e[self.vols,1] = 0.5*(self.elev_v[self.vols,2]+ self.elev_v[self.vols,0])160 self.elev_e[self.vols,2] = 0.5*(self.elev_v[self.vols,0]+ self.elev_v[self.vols,1])161 162 self.stage_c[self.vols] = self.elev_c[self.vols] + height_c163 164 165 166 def update_quantities(self):167 """Update the vertex values of the quantities to model erosion168 """169 170 171 elevation = self.get_elevation()172 173 if elevation is None:174 return False175 176 updated = True177 178 if self.indices is None:179 180 #--------------------------------------181 # Update all three vertices for each cell182 #--------------------------------------183 self.elev_v[:] = elevation184 185 else:186 187 #--------------------------------------188 # Update all three vertices for each cell189 #--------------------------------------190 self.elev_v[self.indices] = elevation191 192 193 return updated194 195 def get_elevation(self, t=None):196 """Get value of elevation at time t.197 If t not specified, return elevation at current domain time198 """199 200 from anuga.fit_interpolate.interpolate import Modeltime_too_early, \201 Modeltime_too_late202 203 if t is None:204 t = self.domain.get_time()205 206 if callable(self.elevation):207 try:208 elevation = self.elevation(t)209 except Modeltime_too_early, e:210 raise Modeltime_too_early(e)211 except Modeltime_too_late, e:212 msg = '%s: ANUGA is trying to run longer than specified data.\n' %str(e)213 msg += 'You can specify keyword argument default_rate in the '214 msg += 'rate operator to tell it what to do in the absence of time data.'215 raise Modeltime_too_late(msg)216 else:217 elevation = self.elevation218 219 220 # if elevation is None:221 # msg = 'Attribute elevation must be specified'222 # raise Exception(msg)223 224 return elevation225 226 227 228 def setup_indices_circle(self):229 230 # Determine indices in circular region231 N = self.domain.get_number_of_triangles()232 points = self.domain.get_centroid_coordinates(absolute=True)233 234 indices = []235 236 c = self.center237 r = self.radius238 239 240 intersect = False241 for k in range(N):242 x, y = points[k,:] # Centroid243 244 if ((x-c[0])**2+(y-c[1])**2) < r**2:245 intersect = True246 indices.append(k)247 248 self.indices = indices249 250 msg = 'No centroids intersect circle center'+str(c)+' radius '+str(r)251 assert intersect, msg252 253 254 def setup_indices_polygon(self):255 256 # Determine indices for polygonal region257 points = self.domain.get_centroid_coordinates(absolute=True)258 259 260 self.indices = inside_polygon(points, self.polygon)261 262 263 264 265 def setup_node_structures(self):266 """ For setting elevation we need to267 ensure that the elevation quantity remains268 continuous (at least for version 1.3 of anuga)269 270 So we need to find all the vertices that need to271 update within each timestep.272 """273 274 275 276 if self.indices is None or self.indices is []:277 self.vol_ids = None278 self.vols = None279 self.vert_ids = None280 return281 282 283 284 node_ids = set()285 286 for ind in self.indices:287 for k in [0,1,2]:288 node_ids.add(self.domain.triangles[ind,k])289 290 self.node_ids = [ id for id in node_ids ]291 292 293 294 node_index = num.zeros((self.domain.number_of_nodes)+1, dtype = num.int)295 296 # FIXME: SR Don't we calculate this for the domain already!297 k = 0298 node_index[0] = 0299 for i in range(self.domain.number_of_nodes):300 node_index[i+1] = node_index[i] + self.domain.number_of_triangles_per_node[i]301 302 self.node_index = node_index303 304 vertex_ids =[]305 for nid in self.node_ids:306 #print nid,self.domain.number_of_triangles_per_node[nid]307 for vid in range(node_index[nid], node_index[nid+1]):308 vidd = self.domain.vertex_value_indices[vid]309 vertex_ids.append(vidd)310 #print ' ',nid, vid, vidd, vidd/3, vidd%3311 312 self.vol_ids = num.array(vertex_ids,dtype=num.int)/3313 self.vols = num.array(list(set(self.vol_ids)), dtype=num.int)314 self.vert_ids = num.array(vertex_ids,dtype=num.int)%3315 316 317 318 319 22 320 23 … … 376 79 #message = indent + self.label + ': Set_elevation = ' + str('') 377 80 #message += ' at center '+str(self.center) 378 return 'test' 81 82 return 'Set_elevation_operator active at time '+str(self.domain.get_time()) 379 83 380 84 -
trunk/anuga_core/source/anuga/operators/test_set_elevation_operator.py
r8926 r8928 13 13 from anuga.config import time_format 14 14 15 from set_elevation_operator simport *15 from set_elevation_operator import * 16 16 17 17 import numpy as num … … 21 21 22 22 23 class Test_set_elevation_operator s(unittest.TestCase):23 class Test_set_elevation_operator(unittest.TestCase): 24 24 def setUp(self): 25 25 pass
Note: See TracChangeset
for help on using the changeset viewer.