Changeset 8154
- Timestamp:
- Mar 17, 2011, 5:51:42 PM (14 years ago)
- Location:
- trunk/anuga_core/source/anuga
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/anuga_core/source/anuga/__init__.py
r8133 r8154 29 29 30 30 from anuga.shallow_water.shallow_water_domain import Domain 31 32 from anuga.abstract_2d_finite_volumes.quantity import Quantity 31 33 32 34 from anuga.abstract_2d_finite_volumes.util import file_function, \ … … 132 134 133 135 #--------------------------- 134 # Structure s136 # Structure Operators 135 137 #--------------------------- 136 138 from anuga.structures.structure_operator import Structure_operator -
trunk/anuga_core/source/anuga/abstract_2d_finite_volumes/generic_domain.py
r8148 r8154 100 100 self.vertex_coordinates = self.mesh.vertex_coordinates 101 101 self.boundary = self.mesh.boundary 102 self.boundary_enumeration = self.mesh.boundary_enumeration 102 103 self.neighbours = self.mesh.neighbours 103 104 self.surrogate_neighbours = self.mesh.surrogate_neighbours … … 708 709 if B is not None: 709 710 self.boundary_objects.append(((vol_id, edge_id), B)) 710 self.neighbours[vol_id, edge_id] = \711 -len(self.boundary_objects)711 #self.neighbours[vol_id, edge_id] = \ 712 #-len(self.boundary_objects) 712 713 else: 713 714 pass … … 721 722 raise Exception(msg) 722 723 724 ## 725 # @brief Set quantities based on a regional tag. 726 # @param args 727 # @param kwargs 723 728 def set_region(self, *args, **kwargs): 724 729 """Set quantities based on a regional tag. -
trunk/anuga_core/source/anuga/abstract_2d_finite_volumes/neighbour_mesh.py
r8124 r8154 178 178 if verbose: log.critical('Mesh: Building boundary dictionary') 179 179 self.build_boundary_dictionary(boundary) 180 181 #Update boundary_enumeration 182 self.build_boundary_neighbours() 180 183 181 184 #Build tagged element dictionary mapping (tag) to array of elements … … 441 444 442 445 self.neighbours[id, edge] = index 446 447 self.boundary_enumeration[id,edge] = index 448 443 449 index -= 1 450 451 def build_boundary_neighbours(self): 452 """Traverse boundary and 453 enumerate neighbour indices from -1 and 454 counting down. 455 456 Precondition: 457 self.boundary is defined. 458 Post condition: 459 neighbours array has unique negative indices for boundary 460 boundary_segments array imposes an ordering on segments 461 (not otherwise available from the dictionary) 462 463 """ 464 465 if self.boundary is None: 466 msg = 'Boundary dictionary must be defined before ' 467 msg += 'building boundary structure' 468 raise Exception(msg) 469 470 self.boundary_enumeration = {} 471 472 X = self.boundary.keys() 473 X.sort() 474 475 index = -1 476 for id, edge in X: 477 self.neighbours[id, edge] = index 478 479 self.boundary_enumeration[id,edge] = -index -1 480 481 index -= 1 482 444 483 445 484 -
trunk/anuga_core/source/anuga/abstract_2d_finite_volumes/quantity.py
r8149 r8154 234 234 self.beta = beta 235 235 236 ## 237 # @brief Get the current beta value. 238 # @return The current beta value. 236 239 def get_beta(self): 237 240 """Get default beta value for limiting""" … … 239 242 return self.beta 240 243 244 245 246 ## 247 # @brief Set boundary values using a function or array or scalar 248 # @param numeric: function or array or scalar 249 def set_boundary_values(self, numeric = 0.0): 250 """Set boundary values """ 251 252 if isinstance(numeric, (list, num.ndarray)): 253 self._set_boundary_values_from_array(numeric) 254 elif callable(numeric): 255 self._set_boundary_values_from_function(numeric) 256 else: # see if it's coercible to a float (float, int or long, etc) 257 try: 258 numeric = float(numeric) 259 except ValueError: 260 msg = ("Illegal type for variable 'numeric': %s" 261 % type(numeric)) 262 raise Exception(msg) 263 self._set_boundary_values_from_constant(numeric) 264 265 266 ## 267 # @brief Set boundary values using a function 268 # @param numeric: function 269 def _set_boundary_values_from_function(self, function): 270 """Set boundary values from function of x,y """ 271 272 for (vol_id, edge_id) , j in self.domain.boundary_enumeration.items(): 273 [x,y] = self.domain.get_edge_midpoint_coordinates(vol_id)[edge_id] 274 self.boundary_values[j] = function(x,y) 275 276 ## 277 # @brief Set boundary values using a scalar 278 # @param numeric: scalar 279 def _set_boundary_values_from_constant(self, scalar): 280 """Set boundary values from scalar """ 281 282 for (vol_id, edge_id) , j in self.domain.boundary_enumeration.items(): 283 [x,y] = self.domain.get_edge_midpoint_coordinates(vol_id)[edge_id] 284 self.boundary_values[j] = scalar 285 286 ## 287 # @brief Set boundary values using a scalar 288 # @param numeric: scalar 289 def _set_boundary_values_from_array(self, array): 290 """Set boundary values from array """ 291 292 assert len(array) == len(self.domain.boundary_enumeration) 293 294 for (vol_id, edge_id) , j in self.domain.boundary_enumeration.items(): 295 [x,y] = self.domain.get_edge_midpoint_coordinates(vol_id)[edge_id] 296 self.boundary_values[j] = array[j] 297 298 ## 299 # @brief Compute interpolated values at edges and centroid. 300 # @note vertex_values must be set before calling this. 241 301 def interpolate(self): 242 302 """Compute interpolated values at edges and centroid … … 583 643 assert values.shape[0] == N, msg 584 644 585 self.centroid_values = values645 self.centroid_values[:] = values 586 646 else: 587 647 msg = 'Number of values must match number of indices' … … 610 670 611 671 if indices is None: 612 self.vertex_values = values672 self.vertex_values[:] = values 613 673 else: 614 674 for element_index, value in map(None, indices, values): -
trunk/anuga_core/source/anuga/abstract_2d_finite_volumes/test_neighbour_mesh.py
r8124 r8154 1233 1233 1234 1234 neighbours = mesh.get_triangle_neighbours(0) 1235 assert num.allclose(neighbours, [-1,1,- 1])1235 assert num.allclose(neighbours, [-1,1,-2]) 1236 1236 neighbours = mesh.get_triangle_neighbours(-10) 1237 1237 assert neighbours == [] -
trunk/anuga_core/source/anuga/abstract_2d_finite_volumes/test_quantity.py
r8124 r8154 97 97 [0.,0.,0.], [0.,0.,0.]]) 98 98 99 def test_set_boundary_values(self): 100 101 quantity = Quantity(self.mesh1) 102 103 quantity.set_boundary_values() 104 105 assert num.allclose(quantity.boundary_values, [0.0, 0.0, 0.0]) 106 107 108 def test_set_boundary_values_with_function(self): 109 110 quantity = Quantity(self.mesh1) 111 #assert num.allclose(quantity.vertex_values, [[0.,0.,0.]]) 112 113 def simple(x,y): 114 return x+3*y 115 116 quantity.set_boundary_values(simple) 117 118 assert num.allclose(quantity.boundary_values, [1.0, 4.0, 3.0]) 119 120 def test_set_boundary_values_with_constant(self): 121 122 quantity = Quantity(self.mesh1) 123 #assert num.allclose(quantity.vertex_values, [[0.,0.,0.]]) 124 125 quantity.set_boundary_values(10.0) 126 127 assert num.allclose(quantity.boundary_values, [10.0, 10.0, 10.0]) 128 129 130 def test_set_boundary_values_with_array(self): 131 132 quantity = Quantity(self.mesh1) 133 #assert num.allclose(quantity.vertex_values, [[0.,0.,0.]]) 134 135 136 quantity.set_boundary_values([10.0, 4.0, 5.0]) 137 138 assert num.allclose(quantity.boundary_values, [10.0, 4.0, 5.0]) 139 140 def test_set_boundary_values_with_wrong_sized_array(self): 141 142 quantity = Quantity(self.mesh1) 143 #assert num.allclose(quantity.vertex_values, [[0.,0.,0.]]) 144 145 try: 146 quantity.set_boundary_values([10.0, 4.0, 5.0, 8.0]) 147 except: 148 pass 149 else: 150 msg = 'Should have caught this' 151 raise Exception(msg) 99 152 100 153 def test_interpolation(self): … … 247 300 quantity = Quantity(self.mesh4) 248 301 302 # get referece to data arrays 303 centroid_values = quantity.centroid_values 304 vertex_values = quantity.vertex_values 249 305 250 306 quantity.set_values([[1,2,3], [5,5,5], [0,0,9], [-6, 3, 3]], … … 252 308 assert num.allclose(quantity.vertex_values, 253 309 [[1,2,3], [5,5,5], [0,0,9], [-6, 3, 3]]) 310 311 assert id(vertex_values) == id(quantity.vertex_values) 254 312 assert num.allclose(quantity.centroid_values, [2., 5., 3., 0.]) #Centroid 255 313 assert num.allclose(quantity.edge_values, [[2.5, 2.0, 1.5], … … 281 339 282 340 341 283 342 try: 284 343 quantity.set_values([[1,2,3], [0,0,9]]) 285 except AssertionError:344 except ValueError: 286 345 pass 287 346 except: 288 raise Exception('should have raised Assertionerror')347 raise Exception('should have raised ValueeError') 289 348 290 349 … … 2368 2427 2369 2428 if __name__ == "__main__": 2370 suite = unittest.makeSuite(Test_Quantity, 'test') 2429 suite = unittest.makeSuite(Test_Quantity, 'test') 2371 2430 runner = unittest.TextTestRunner() 2372 2431 runner.run(suite) -
trunk/anuga_core/source/anuga/operators/kinematic_viscosity.py
r8152 r8154 9 9 import anuga.utilities.log as log 10 10 11 12 11 13 class Kinematic_Viscosity: 12 14 """ … … 35 37 """ 36 38 37 def __init__(self, domain, diffusivity = None,use_triangle_areas=True, verbose=False):39 def __init__(self, domain, use_triangle_areas=True, verbose=False): 38 40 if verbose: log.critical('Kinematic Viscosity: Beginning Initialisation') 39 41 #Expose the domain attributes … … 44 46 self.boundary_enumeration = domain.boundary_enumeration 45 47 46 # Setup diffusivity quantity 47 if diffusivity is None: 48 diffusivity = Quantity(domain) 49 diffusivity.set_values(1.0) 50 diffusivity.set_boundary_values(1.0) 51 #check that diffusivity is a quantity associated with domain 52 assert diffusivity.domain == domain 53 54 self.diffusivity = diffusivity 55 #self.diffusivity_bdry_data = self.diffusivity.boundary_values 56 #self.diffusivity_cell_data = self.diffusivity.centroid_values 57 48 # Dummy diffusivity quantity 49 diffusivity = Quantity(domain) 50 diffusivity.set_values(1.0) 51 diffusivity.set_boundary_values(1.0) 58 52 59 53 self.n = len(self.domain) 60 self.dt = 1 e-6#Need to set to domain.timestep54 self.dt = 1.0 #Need to set to domain.timestep 61 55 self.boundary_len = len(domain.boundary) 62 56 self.tot_len = self.n + self.boundary_len … … 95 89 96 90 # Build matrix self.elliptic_matrix [A B] 97 self.build_elliptic_matrix() 98 99 # Build self.boundary_term 100 #self.build_elliptic_boundary_term() 101 102 self.parabolic_solve = False #Are we doing a parabolic solve at the moment? 91 self.build_elliptic_matrix(diffusivity) 92 93 self.boundary_term = num.zeros((self.n, ), num.float) 94 95 self.parabolic = False #Are we doing a parabolic solve at the moment? 103 96 104 97 if verbose: log.critical('Kinematic Viscosity: Initialisation Done') … … 109 102 110 103 111 def set_qty_considered(self, qty): 112 # FIXME SR: Probably should just be set by quantity to which operation is applied 113 if qty == 1 or qty == 'u': 114 self.qty_considered = 1 115 elif qty == 2 or qty == 'v': 116 self.qty_considered = 2 117 else: #Raise an exception 118 msg = "Incorrect input qty" 119 assert 0 == 1, msg 120 121 def build_elliptic_matrix(self): 104 def set_parabolic_solve(self,flag): 105 106 self.parabolic = flag 107 108 109 def build_elliptic_matrix(self, a): 122 110 """ 123 111 Builds matrix representing 124 112 125 div ( diffusivitygrad )113 div ( a grad ) 126 114 127 115 which has the form [ A B ] … … 131 119 # are setup via this call 132 120 kinematic_viscosity_ext.build_elliptic_matrix(self, \ 133 self.diffusivity.centroid_values, \134 self.diffusivity.boundary_values)121 a.centroid_values, \ 122 a.boundary_values) 135 123 136 124 self.elliptic_matrix = Sparse_CSR(None, \ … … 138 126 self.n, self.tot_len) 139 127 140 #print 'elliptic_matrix' 141 #print self.elliptic_matrix 142 143 # #Set up the scaling matrix 144 # data = h 145 # num.putmask(data, data != 0, 1 / data) #take the reciprocal of each entry unless it is zero 146 # self.stage_heights_scaling = \ 147 # Sparse_CSR(None, self.diffusivity_data, num.arange(self.n), num.arange(self.n +1), self.n, self.n) 148 149 def update_elliptic_matrix(self): 128 129 def update_elliptic_matrix(self, a=None): 150 130 """ 151 131 Updates the data values of matrix representing 152 132 153 div ( diffusivitygrad )154 155 (as when diffusivitiy has changed)133 div ( a grad ) 134 135 If a == None then we set a = quantity which is set to 1 156 136 """ 157 137 … … 159 139 # through to the Sparse_CSR matrix. 160 140 141 if a == None: 142 a = Quantity(self.domain) 143 a.set_values(1.0) 144 a.set_boundary_values(1.0) 145 161 146 kinematic_viscosity_ext.update_elliptic_matrix(self, \ 162 self.diffusivity.centroid_values, \ 163 self.diffusivity.boundary_values) 164 165 166 def build_elliptic_boundary_term(self,quantity): 167 """ 168 Operator has form [A B] and U = [ u ; b] 169 170 This procedure calculates B b which can be calculated as 147 a.centroid_values, \ 148 a.boundary_values) 149 150 151 152 153 154 def update_elliptic_boundary_term(self, boundary): 155 156 157 if isinstance(boundary, Quantity): 158 159 self._update_elliptic_boundary_term(boundary.boundary_values) 160 161 elif isinstance(boundary, num.ndarray): 162 163 self._update_elliptic_boundary_term(boundary.boundary_values) 164 165 else: 166 167 raise TypeError('expecting quantity or numpy array') 168 169 170 def _update_elliptic_boundary_term(self, b): 171 """ 172 Operator has form [A B] and u = [ u_1 ; b] 173 174 u_1 associated with centroid values of u 175 u_2 associated with boundary_values of u 176 177 This procedure calculates B u_2 which can be calculated as 171 178 172 179 [A B] [ 0 ; b] 180 181 Assumes that update_elliptic_matrix has just been run. 173 182 """ 174 183 … … 176 185 tot_len = self.tot_len 177 186 178 self.boundary_term = num.zeros((n, ), num.float)179 180 187 X = num.zeros((tot_len,), num.float) 181 188 182 X[n:] = quantity.boundary_values189 X[n:] = b 183 190 self.boundary_term[:] = self.elliptic_matrix * X 184 191 … … 188 195 189 196 190 def elliptic_multiply(self, quantity_in, quantity_out=None, include_boundary=True): 197 198 def elliptic_multiply(self, input, output=None): 199 200 201 if isinstance(input, Quantity): 202 203 assert isinstance(output, Quantity) or output is None 204 205 output = self._elliptic_multiply_quantity(input, output) 206 207 elif isinstance(input, num.ndarray): 208 209 assert isinstance(output, num.ndarray) or output is None 210 211 output = self._elliptic_multiply_array(input, output) 212 213 else: 214 215 raise TypeError('expecting quantity or numpy array') 216 217 return output 218 219 220 def _elliptic_multiply_quantity(self, quantity_in, quantity_out): 221 """ 222 Assumes that update_elliptic_matrix has been run 223 """ 224 225 if quantity_out is None: 226 quantity_out = Quantity(self.domain) 227 228 array_in = quantity_in.centroid_values 229 array_out = quantity_out.centroid_values 230 231 X = self._elliptic_multiply_array(array_in, array_out) 232 233 quantity_out.set_values(X, location = 'centroids') 234 235 return quantity_out 236 237 def _elliptic_multiply_array(self, array_in, array_out): 238 """ 239 calculates [A B] [array_in ; 0] 240 """ 191 241 192 242 n = self.n … … 194 244 195 245 V = num.zeros((tot_len,), num.float) 196 X = num.zeros((n,), num.float) 246 247 assert len(array_in) == n 248 249 if array_out is None: 250 array_out = num.zeros_like(array_in) 251 252 V[0:n] = array_in 253 V[n:] = 0.0 254 255 256 if self.apply_triangle_areas: 257 V[0:n] = self.triangle_areas * V[0:n] 258 259 260 array_out[:] = self.elliptic_matrix * V 261 262 263 return array_out 264 265 266 267 268 269 def parabolic_multiply(self, input, output=None): 270 271 272 if isinstance(input, Quantity): 273 274 assert isinstance(output, Quantity) or output is None 275 276 output = self._parabolic_multiply_quantity(input, output) 277 278 elif isinstance(input, num.ndarray): 279 280 assert isinstance(output, num.ndarray) or output is None 281 282 output = self._parabolic_multiply_array(input, output) 283 284 else: 285 286 raise TypeError('expecting quantity or numpy array') 287 288 return output 289 290 291 def _parabolic_multiply_quantity(self, quantity_in, quantity_out): 292 """ 293 Assumes that update_elliptic_matrix has been run 294 """ 197 295 198 296 if quantity_out is None: 199 297 quantity_out = Quantity(self.domain) 200 298 201 V[0:n] = quantity_in.centroid_values 299 array_in = quantity_in.centroid_values 300 array_out = quantity_out.centroid_values 301 302 X = self._parabolic_multiply_array(array_in, array_out) 303 304 quantity_out.set_values(X, location = 'centroids') 305 306 return quantity_out 307 308 def _parabolic_multiply_array(self, array_in, array_out): 309 """ 310 calculates ( [ I 0 ; 0 0] + dt [A B] ) [array_in ; 0] 311 """ 312 313 n = self.n 314 tot_len = self.tot_len 315 316 V = num.zeros((tot_len,), num.float) 317 318 assert len(array_in) == n 319 320 if array_out is None: 321 array_out = num.zeros_like(array_in) 322 323 V[0:n] = array_in 202 324 V[n:] = 0.0 203 204 205 # FIXME SR: These sparse matrix vector multiplications206 # should be done in such a way to reuse memory, ie207 # should have a procedure208 # matrix.multiply(vector_in, vector_out)209 325 210 326 … … 213 329 214 330 215 X[:] = self.elliptic_matrix * V 216 217 if include_boundary: 218 self.build_elliptic_boundary_term(quantity_in) 219 X[:] += self.boundary_term 220 221 222 quantity_out.set_values(X, location = 'centroids') 223 return quantity_out 224 225 #parabolic_multiply(V) = identity - dt*elliptic_multiply(V) 226 #We do not need include boundary, as we will only use this 227 #method for solving (include_boundary = False) 228 #Here V is already either (u) or (v), not (uh) or (vh) 229 def parabolic_multiply(self, V): 230 msg = "(KV_Operator.parabolic_multiply) V vector has incorrect dimensions" 231 assert V.shape == (self.n, ) or V.shape == (self.n, 1), msg 232 233 D = V #The return value 234 X = V #a temporary array 235 236 #Apply triangle areas 237 if self.apply_triangle_areas: 238 X = self.triangle_areas * X 239 240 #Multiply out 241 X = num.append(X, num.zeros((self.boundary_len, )), axis=0) 242 D = D - self.dt * (self.elliptic_matrix * X) 243 244 return num.array(D).reshape(self.n, ) 245 246 def __mul__(self, other): 247 try: 248 B = num.array(other) 249 except: 250 msg = "Trying to multiply the Kinematic Viscosity Operator against a non-numeric type" 251 raise msg 252 253 if len(B.shape) == 0: 254 #Scalar 255 R = B * self 256 elif len(B.shape) == 1 or (len(B.shape) == 2 and B.shape[1] == 1): 257 #Vector 258 if self.parabolic_solve: 259 R = self.parabolic_multiply(other) 260 else: 261 #include_boundary=False is this is *only* used for cg_solve() 262 R = self.elliptic_multiply(other, include_boundary=False) 331 array_out[:] = array_in - self.dt * (self.elliptic_matrix * V) 332 333 return array_out 334 335 336 337 338 def __mul__(self, vector): 339 340 #Vector 341 if self.parabolic: 342 R = self.parabolic_multiply(vector) 263 343 else: 264 raise ValueError, 'Dimension too high: d=%d' % len(B.shape) 344 #include_boundary=False is this is *only* used for cg_solve() 345 R = self.elliptic_multiply(vector) 346 265 347 return R 266 348 … … 271 353 except: 272 354 msg = 'Sparse matrix can only "right-multiply" onto a scalar' 273 raise TypeError , msg355 raise TypeError(msg) 274 356 else: 275 357 new = self.elliptic_matrix * new 276 358 return new 277 359 278 def cg_solve(self, B, qty_to_consider=None):279 if len(B.shape) == 1:280 return self.cg_solve_vector(B, qty_to_consider)281 elif len(B.shape) == 2:282 return self.cg_solve_matrix(B)283 else:284 raise ValueError, 'Dimension too high: d=%d' % len(B.shape)285 286 def cg_solve_matrix(self, B):287 assert B.shape[1] < 3, "Input matrix has too many columns (max 2)"288 289 X = num.zeros(B.shape, num.float)290 for i in range(B.shape[1]):291 X[:, i] = self.cg_solve_vector(B[:, i], i + 1) #assuming B columns are (uh) and (vh)292 return X293 360 294 def cg_solve_vector(self, b, qty_to_consider=None): 295 if not qty_to_consider == None: 296 self.set_qty_considered(qty_to_consider) 297 #Call the ANUGA conjugate gradient utility 298 x = conjugate_gradient(self, b - self.boundary_vector[:, self.qty_considered-1]) 299 return x 300 301 #Solve the parabolic equation to find u^(n+1), where u = u^n 302 #Here B = [uh vh] where uh,vh = n*1 column vectors 303 def parabolic_solver(self, B): 304 assert B.shape == (self.n, 2), "Input matrix has incorrect dimensions" 305 306 next_B = num.zeros((self.n, 2), num.float) 307 #The equation is self.parabolic_multiply*u^(n+1) = u^n + (dt)*self.boundary_vector 308 self.parabolic_solve = True 309 #Change (uh) and (vh) to (u) and (v) 310 b = self.stage_heights_scaling * B 311 312 next_B = conjugate_gradient(self, b + (self.dt * self.boundary_vector), iprint=1) 313 314 #Return (u) and (v) back to (uh) and (vh) 315 next_B = self.stage_heights_scaling * next_B 316 317 self.parabolic_solve = False 318 319 return next_B 361 def elliptic_solve(self, u_in, b, a = None, u_out = None, \ 362 imax=10000, tol=1.0e-8, atol=1.0e-8, iprint=None): 363 """ Solving div ( a grad u ) = b 364 u | boundary = g 365 366 u_in, u_out, f anf g are Quantity objects 367 368 Dirichlet BC g encoded into u_in boundary_values 369 370 Initial guess for iterative scheme is given by 371 centroid values of u_in 372 373 Centroid values of a and b provide diffusivity and rhs 374 375 Solution u is retruned in u_out 376 """ 377 378 if u_out == None: 379 u_out = Quantity(self.domain) 380 381 382 self.update_elliptic_matrix(a) 383 self.update_elliptic_boundary_term(u_in) 384 385 # Pull out arrays and a matrix operator 386 A = self 387 rhs = b.centroid_values - self.boundary_term 388 x0 = u_in.centroid_values 389 390 x = conjugate_gradient(A,rhs,x0,imax=imax, tol=tol, atol=atol, iprint=iprint) 391 392 u_out.set_values(x, location='centroids') 393 u_out.set_boundary_values(u_in.boundary_values) 394 395 return u_out 396 397 398 def parabolic_solve(self, u_in, b, a = None, u_out = None, \ 399 imax=10000, tol=1.0e-8, atol=1.0e-8, iprint=None): 400 """ 401 Solve for u in the equation 402 403 ( I + dt div a grad ) u = b 404 405 u | boundary = g 406 407 408 u_in, u_out, f anf g are Quantity objects 409 410 Dirichlet BC g encoded into u_in boundary_values 411 412 Initial guess for iterative scheme is given by 413 centroid values of u_in 414 415 Centroid values of a and b provide diffusivity and rhs 416 417 Solution u is retruned in u_out 418 419 """ 420 421 if u_out == None: 422 u_out = Quantity(self.domain) 423 424 425 self.update_elliptic_matrix(a) 426 self.update_elliptic_boundary_term(u_in) 427 428 self.set_parabolic_solve(True) 429 430 431 # Pull out arrays and a matrix operator 432 IdtA = self 433 rhs = b.centroid_values + (self.dt * self.boundary_term) 434 x0 = u_in.centroid_values 435 436 x = conjugate_gradient(IdtA,rhs,x0,imax=imax, tol=tol, atol=atol, iprint=iprint) 437 438 self.set_parabolic_solve(False) 439 440 u_out.set_values(x, location='centroids') 441 u_out.set_boundary_values(u_in.boundary_values) 442 443 return u_out 444 445 -
trunk/anuga_core/source/anuga/operators/test_kinematic_viscosity.py
r8152 r8154 1 import operator 1 2 from anuga import Domain 2 3 from anuga import Quantity … … 104 105 operator = self.operator1() 105 106 domain = operator.domain 106 107 operator.update_elliptic_matrix() 107 108 a = Quantity(operator.domain) 109 a.set_values(1.0) 110 a.set_boundary_values(1.0) 111 112 operator.update_elliptic_matrix(a) 108 113 109 114 A = operator.elliptic_matrix … … 111 116 assert num.allclose(A.todense(), num.array([-6.0-12.0/sqrt(5), 6.0, 6.0/sqrt(5), 6.0/sqrt(5)])) 112 117 113 diffusivity = operator.diffusivity 114 diffusivity.set_values(10.0) 115 diffusivity.set_boundary_values(10.0) 116 117 operator.update_elliptic_matrix() 118 a.set_values(10.0) 119 a.set_boundary_values(10.0) 120 121 operator.update_elliptic_matrix(a) 118 122 119 123 assert num.allclose(A.todense(), 10*num.array([-6.0-12.0/sqrt(5), 6.0, 6.0/sqrt(5), 6.0/sqrt(5)])) … … 126 130 127 131 domain = operator.domain 128 diffusivity = operator.diffusivity 132 133 a = Quantity(operator.domain) 134 a.set_values(1.0) 135 a.set_boundary_values(1.0) 136 operator.update_elliptic_matrix(a) 129 137 130 138 A = operator.elliptic_matrix 131 139 132 diffusivity.set_values(1.0) 133 diffusivity.set_boundary_values(1.0) 134 operator.update_elliptic_matrix() 135 140 136 141 A0 = num.array([[-3.0,3.0,0.0,0.0,0.0,0.0], 137 142 [0.0,-6.0/sqrt(5.0),0.0,0.0,6.0/sqrt(5.0),0.0]]) … … 144 149 assert num.allclose(A.todense(), A0+A1+A2) 145 150 146 diffusivity.set_values([2.0, 1.0], location = 'centroids')147 diffusivity.set_boundary_values(1.0)148 operator.update_elliptic_matrix( )151 a.set_values([2.0, 1.0], location = 'centroids') 152 a.set_boundary_values(1.0) 153 operator.update_elliptic_matrix(a) 149 154 150 155 A = operator.elliptic_matrix … … 154 159 assert num.allclose(A.todense()[1,:], A0[1,:]+1.5*A1[1,:]+A2[1,:]) 155 160 156 diffusivity.set_values([-2.0, -2.0], location = 'centroids')157 diffusivity.set_boundary_values(1.0)158 operator.update_elliptic_matrix( )161 a.set_values([-2.0, -2.0], location = 'centroids') 162 a.set_boundary_values(1.0) 163 operator.update_elliptic_matrix(a) 159 164 160 165 assert num.allclose(A.todense()[0,:], -2*A0[0,:]-0.5*A1[0,:]-0.5*A2[0,:]) … … 166 171 167 172 print operator.apply_triangle_areas 168 169 n = operator.n 173 174 a = Quantity(operator.domain) 175 a.set_values(1.0) 176 a.set_boundary_values(1.0) 177 178 operator.update_elliptic_matrix() 179 180 181 182 q_in = Quantity(operator.domain) 183 q_in.set_values(1.0) 184 q_in.set_boundary_values(1.0) 185 186 n = operator.n 187 188 A = num.array([-6.0-12.0/sqrt(5), 6.0, 6.0/sqrt(5), 6.0/sqrt(5)]) 189 190 191 q_1 = operator.elliptic_multiply(q_in) 192 193 q_2 = operator.elliptic_multiply(q_in, quantity_out = q_in) 194 195 assert id(q_in) == id(q_2) 196 197 assert num.allclose(q_1.centroid_values,q_2.centroid_values) 198 199 assert num.allclose( num.zeros((n,), num.float), q_1.centroid_values ) 200 201 #Now have different boundary values 202 203 q_in.set_values(1.0) 204 q_in.set_boundary_values(0.0) 205 operator.update_elliptic_matrix(a) 206 207 208 A = num.array([-6.0-12.0/sqrt(5), 6.0, 6.0/sqrt(5), 6.0/sqrt(5)]) 209 210 211 q_1 = operator.elliptic_multiply(q_in) 212 213 assert num.allclose( [-6.0-12.0/sqrt(5)], q_1.centroid_values ) 214 215 def test_elliptic_multiply_exclude_boundary_one_triangle(self): 216 operator = self.operator1() 217 operator.set_triangle_areas(False) 218 219 print operator.apply_triangle_areas 220 #n = operator.n 170 221 171 222 q_in = Quantity(operator.domain) … … 174 225 operator.update_elliptic_matrix() 175 226 176 227 228 A = num.array([-6.0-12.0/sqrt(5), 6.0, 6.0/sqrt(5), 6.0/sqrt(5)]) 229 230 231 q_1 = operator.elliptic_multiply(q_in, include_boundary=False) 232 233 234 assert num.allclose( [-6.0-12.0/sqrt(5)], q_1.centroid_values ) 235 236 def test_elliptic_multiply_include_boundary_one_triangle(self): 237 operator = self.operator1() 238 operator.set_triangle_areas(True) 239 240 n = operator.n 241 242 q_in = Quantity(operator.domain) 243 q_in.set_values(1.0) 244 q_in.set_boundary_values(1.0) 245 246 operator.update_elliptic_matrix() 247 248 177 249 A = num.array([-6.0-12.0/sqrt(5), 6.0, 6.0/sqrt(5), 6.0/sqrt(5)]) 178 250 … … 180 252 q_1 = operator.elliptic_multiply(q_in) 181 253 182 q_2 = operator.elliptic_multiply(q_in, quantity_out = q_in)254 q_2 = operator.elliptic_multiply(q_in, output = q_in) 183 255 184 256 assert id(q_in) == id(q_2) … … 186 258 assert num.allclose(q_1.centroid_values,q_2.centroid_values) 187 259 188 assert num.allclose( num.zeros((n,), num.float), q_1.centroid_values )260 assert num.allclose( [-12.0-24.0/sqrt(5)], q_1.centroid_values ) 189 261 190 262 #Now have different boundary values … … 200 272 q_1 = operator.elliptic_multiply(q_in) 201 273 202 assert num.allclose( [- 6.0-12.0/sqrt(5)], q_1.centroid_values )203 274 assert num.allclose( [-12.0-24.0/sqrt(5)], q_1.centroid_values ) 275 204 276 def test_elliptic_multiply_exclude_boundary_one_triangle(self): 205 277 operator = self.operator1() 206 operator.set_triangle_areas(False) 207 208 print operator.apply_triangle_areas 209 #n = operator.n 278 operator.set_triangle_areas(True) 210 279 211 280 q_in = Quantity(operator.domain) … … 218 287 219 288 220 q_1 = operator.elliptic_multiply(q_in, include_boundary=False) 221 222 223 assert num.allclose( [-6.0-12.0/sqrt(5)], q_1.centroid_values ) 224 225 def test_elliptic_multiply_include_boundary_one_triangle(self): 226 operator = self.operator1() 227 operator.set_triangle_areas(True) 228 229 n = operator.n 230 231 q_in = Quantity(operator.domain) 232 q_in.set_values(1.0) 233 q_in.set_boundary_values(1.0) 289 q_1 = operator.elliptic_multiply(q_in) 290 291 292 assert num.allclose( [-12.0-24.0/sqrt(5)], q_1.centroid_values ) 293 294 def test_mul_arg(self): 295 operator = self.operator1() 296 297 u = Quantity(operator.domain) 298 u.set_values(2.0) 299 #q boundary_values should equal 0.0 300 301 302 303 operator.update_elliptic_boundary_term(u) 304 305 r = 2.0 306 307 try: 308 q_out = operator * 2.0 309 except TypeError: 310 pass 311 else: 312 raise Exception('Should have caught an TypeError') 313 314 315 def test_mul(self): 316 operator = self.operator1() 317 318 u = Quantity(operator.domain) 319 u.set_values(2.0) 320 #q boundary_values should equal 0.0 321 234 322 operator.update_elliptic_matrix() 235 323 236 237 A = num.array([-6.0-12.0/sqrt(5), 6.0, 6.0/sqrt(5), 6.0/sqrt(5)]) 238 239 240 q_1 = operator.elliptic_multiply(q_in) 241 242 q_2 = operator.elliptic_multiply(q_in, quantity_out = q_in) 243 244 assert id(q_in) == id(q_2) 245 246 assert num.allclose(q_1.centroid_values,q_2.centroid_values) 247 248 assert num.allclose( num.zeros((n,), num.float), q_1.centroid_values ) 249 250 #Now have different boundary values 251 252 q_in.set_values(1.0) 253 q_in.set_boundary_values(0.0) 254 operator.update_elliptic_matrix() 255 256 257 A = num.array([-6.0-12.0/sqrt(5), 6.0, 6.0/sqrt(5), 6.0/sqrt(5)]) 258 259 260 q_1 = operator.elliptic_multiply(q_in) 261 262 assert num.allclose( [-12.0-24.0/sqrt(5)], q_1.centroid_values ) 263 264 def test_elliptic_multiply_exclude_boundary_one_triangle(self): 265 operator = self.operator1() 266 operator.set_triangle_areas(True) 267 268 q_in = Quantity(operator.domain) 269 q_in.set_values(1.0) 270 q_in.set_boundary_values(1.0) 271 operator.update_elliptic_matrix() 272 273 274 A = num.array([-6.0-12.0/sqrt(5), 6.0, 6.0/sqrt(5), 6.0/sqrt(5)]) 275 276 277 q_1 = operator.elliptic_multiply(q_in, include_boundary=False) 278 279 280 assert num.allclose( [-12.0-24.0/sqrt(5)], q_1.centroid_values ) 281 282 283 284 def test_mul(self): 285 operator = self.operator1() 286 287 q = Quantity(operator.domain) 288 q.set_values(2.0) 289 #q boundary_values should equal 0.0 290 291 operator.build_elliptic_boundary_term() 292 A = num.array([-6.0-12.0/sqrt(5), 6.0, 6.0/sqrt(5), 6.0/sqrt(5)]) 293 V1 = num.array([2.0]) #(uh)=2 324 operator.update_elliptic_boundary_term(u) 325 326 A = num.array([-6.0-12.0/sqrt(5), 6.0, 6.0/sqrt(5), 6.0/sqrt(5)]) 327 V1 = num.array([2.0]) #u=2 294 328 U1 = num.array([[2.0],[0.0],[0.0],[0.0]]) 295 assert num.allclose(operator * q, 2*num.array(num.mat(A)*num.mat(U1)).reshape(1,)) 296 297 def test_cg_solve(self): 298 #cf self.test_mul() 299 operator1 = self.operator1() 300 operator1.apply_stage_heights(num.array([[1.0]])) #h=1 301 operator1.set_qty_considered('u') 302 V = num.array([2.0]) #h=1, (uh)=2 303 A = num.array([-6.0-12.0/sqrt(5), 6.0, 6.0/sqrt(5), 6.0/sqrt(5)]) 304 U = num.array([[2.0,2.0],[2.0,1.0],[1.0,2.0],[1.0,0.0]]) 305 test = 2*num.mat(A)*num.mat(U[:,0].reshape(4,1)) 306 X = operator1.cg_solve(num.array(test).reshape(1,)) 307 assert num.allclose(V, X) 308 309 def test_parabolic_solve(self): 310 operator1 = self.operator1() 311 operator1.apply_stage_heights(num.array([[1.0]])) #h=1 312 A = num.array([-6.0-12.0/sqrt(5), 6.0, 6.0/sqrt(5), 6.0/sqrt(5)]) 313 U = num.array([[2.0,1.0],[2.0,1.0],[1.0,2.0],[1.0,0.0]]) 314 u = num.array([[2.0,1.0]]) 315 U_new = operator1.parabolic_solver(u) 316 U_mod = num.array([[0.0,0.0],[2.0,1.0],[1.0,2.0],[1.0,0.0]]) 317 U_mod[0,:] = U_new 318 assert num.allclose(U_new - operator1.dt * 2 * num.mat(A)*num.mat(U_mod), U[0,:]) 329 330 q_out = operator * u 331 332 assert num.allclose(q_out.centroid_values, 2*num.array(num.mat(A)*num.mat(U1)).reshape(1,)) 333 334 def test_elliptic_solve_one_triangle(self): 335 336 operator = self.operator1() 337 n = operator.n 338 339 U = num.array([2.0,2.0,1.0,1.0]) 340 341 u_in = Quantity(operator.domain) 342 u_in.set_values(U[:1], location='centroids') 343 u_in.set_boundary_values(U[1:]) 344 345 a = Quantity(operator.domain) 346 a.set_values(1.0) 347 a.set_boundary_values(1.0) 348 349 # Do this to get access to the matrix 350 # This is also called inside elliptic_solve 351 operator.update_elliptic_matrix(a) 352 353 V = num.array([2.0]) #h=1, u=2 354 A = num.array([-6.0-12.0/sqrt(5), 6.0, 6.0/sqrt(5), 6.0/sqrt(5)]) 355 #U = num.array([[2.0,2.0],[2.0,1.0],[1.0,2.0],[1.0,0.0]]) 356 357 #Setup up rhs as b = A u 358 X = num.array(2*num.mat(A)*num.mat(U.reshape(4,1))).reshape(1,) 359 b = Quantity(operator.domain) 360 b.set_values(X, location='centroids') 361 362 u_in.set_values(0.0) 363 364 u_out = operator.elliptic_solve(u_in, b, a, iprint=1) 365 366 assert num.allclose(u_out.centroid_values, U[:n]) 367 368 369 def test_elliptic_solve_two_triangle(self): 370 371 operator = self.operator2() 372 n = operator.n 373 374 U = num.array([2.0,3.0,1.0,1.0,4.0,3.0]) 375 376 u_in = Quantity(operator.domain) 377 u_in.set_values(U[:2], location='centroids') 378 u_in.set_boundary_values(U[2:]) 379 380 a = Quantity(operator.domain) 381 a.set_values(1.0) 382 a.set_boundary_values(1.0) 383 384 # Do this to get access to the matrix 385 # This is also called inside elliptic_solve 386 operator.update_elliptic_matrix(a) 387 388 V1 = U[:n] 389 V2 = U[n:] 390 391 A = num.mat(operator.elliptic_matrix.todense()) 392 U = num.mat(U.reshape(6,1)) 393 394 #Setup up rhs as b = A u 395 X = num.array(2*A*U).reshape(2,) 396 397 b = Quantity(operator.domain) 398 b.set_values(X, location='centroids') 399 400 u_in.set_values(0.0) 401 402 u_out = operator.elliptic_solve(u_in, b, a, iprint=1) 403 404 assert num.allclose(u_out.centroid_values, V1) 405 assert num.allclose(u_out.boundary_values, V2) 406 407 def test_elliptic_solve_rectangular_cross(self): 408 409 from anuga import rectangular_cross_domain 410 411 m1 = 10 412 n1 = 10 413 domain = rectangular_cross_domain(m1,n1) 414 415 # Diffusivity 416 a = Quantity(domain) 417 a.set_values(1.0) 418 a.set_boundary_values(1.0) 419 420 # Quantity to solve 421 u = Quantity(domain) 422 u.set_values(0.0) 423 u.set_boundary_values(1.0) 424 425 # Quantity for rhs 426 b = Quantity(domain) 427 b.set_values(0.0) 428 b.set_boundary_values(0.0) 429 430 operator = Kinematic_Viscosity(domain) 431 432 n = operator.n 433 tot_len = operator.tot_len 434 435 u_out = operator.elliptic_solve(u, b, a, iprint=1) 436 437 assert num.allclose(u_out.centroid_values, num.ones_like(u_out.centroid_values)) 438 assert num.allclose(u_out.boundary_values, num.ones_like(u_out.boundary_values)) 439 440 441 442 def test_parabolic_solve_one_triangle(self): 443 operator = self.operator1() 444 n = operator.n 445 dt = operator.dt 446 447 U = num.array([2.0,2.0,1.0,1.0]) 448 U_mod = num.array([10.0, 2.0, 1.0, 1.0]) 449 450 u_in = Quantity(operator.domain) 451 u_in.set_values(U[:n], location='centroids') 452 u_in.set_boundary_values(U_mod[n:]) 453 454 a = Quantity(operator.domain) 455 a.set_values(1.0) 456 a.set_boundary_values(1.0) 457 458 459 V = num.array([2.0]) 460 A = num.array([-6.0-12.0/sqrt(5), 6.0, 6.0/sqrt(5), 6.0/sqrt(5)]) 461 462 #Setup up rhs 463 X = U_mod[:n] - dt*2*num.array(num.mat(A)*num.mat(U_mod.reshape(4,1))).reshape(n,) 464 b = Quantity(operator.domain) 465 b.set_values(X, location='centroids') 466 467 468 u_out = operator.parabolic_solve(u_in, b, a, iprint=1) 469 470 471 assert num.allclose(u_out.centroid_values, U_mod[:n]) 472 473 474 def test_parabolic_solve_two_triangles(self): 475 operator = self.operator2() 476 n = operator.n 477 nt = operator.tot_len 478 479 dt = operator.dt 480 481 U = num.array([2.0,3.0,1.0,1.0,4.0,3.0]) 482 U_mod = num.array([4.0,2.0,1.0,1.0,4.0,3.0]) 483 484 485 u_in = Quantity(operator.domain) 486 u_in.set_values(U[:n], location='centroids') 487 u_in.set_boundary_values(U_mod[n:]) 488 489 a = Quantity(operator.domain) 490 a.set_values(1.0) 491 a.set_boundary_values(1.0) 492 493 operator.update_elliptic_matrix(a) 494 495 496 A = num.array([[-8.36656315, 3., 2.68328157, 2.68328157, 0., 0. ], 497 [ 3., -8.36656315 , 0. , 0. , 2.68328157, 2.68328157]]) 498 499 assert num.allclose(A,operator.elliptic_matrix.todense()) 500 501 502 503 #Setup up rhs 504 X = U_mod[:n] - dt*2*num.array(num.mat(A)*num.mat(U_mod.reshape(nt,1))).reshape(n,) 505 b = Quantity(operator.domain) 506 b.set_values(X, location='centroids') 507 508 509 u_out = operator.parabolic_solve(u_in, b, a, iprint=1) 510 511 512 assert num.allclose(u_out.centroid_values, U_mod[:n]) 513 514 def test_parabolic_solve_rectangular_cross(self): 515 516 from anuga import rectangular_cross_domain 517 518 m1 = 10 519 n1 = 10 520 domain = rectangular_cross_domain(m1,n1) 521 522 # Diffusivity 523 a = Quantity(domain) 524 a.set_values(1.0) 525 a.set_boundary_values(1.0) 526 527 # Quantity initial condition 528 u_in = Quantity(domain) 529 #u_in.set_values( 0.0 ) 530 u_in.set_values(lambda x,y : 16.0*x*(1-x)*y*(1-y)) 531 u_in.set_boundary_values(0.0) 532 533 # Quantity to solve 534 u_mod = Quantity(domain) 535 u_mod.set_values(lambda x,y : 15.9*x*(1-x)*y*(1-y) ) 536 u_mod.set_boundary_values(0.0) 537 538 # Quantity for rhs 539 b = Quantity(domain) 540 b.set_values(0.0) 541 b.set_boundary_values(0.0) 542 543 operator = Kinematic_Viscosity(domain) 544 545 dt = 0.01 546 operator.dt = dt 547 n = operator.n 548 nt = operator.tot_len 549 550 operator.update_elliptic_matrix(a) 551 552 A = num.mat(operator.elliptic_matrix.todense()) 553 D = num.mat(operator.triangle_areas.todense()) 554 U_mod = num.concatenate( (u_mod.centroid_values, u_mod.boundary_values) ) 555 556 557 #Setup up rhs 558 X = U_mod[:n] - dt*num.array(D*A*num.mat(U_mod.reshape(nt,1))).reshape(n,) 559 b = Quantity(operator.domain) 560 b.set_values(X, location='centroids') 561 562 563 u_out = operator.parabolic_solve(u_in, b, a, iprint=1) 564 565 assert num.allclose(u_out.centroid_values, U_mod[:n]) 566 319 567 320 568 ################################################################################ -
trunk/anuga_core/source/anuga/shallow_water/test_shallow_water_domain.py
r8124 r8154 512 512 (3, 1): 'Second', 513 513 (3, 2): 'Third', 514 (0, 1): 'Internal'} 514 (0, 1): 'Internal', 515 (1, 2): 'Internal'} 515 516 516 517 domain = Domain(points, vertices, boundary) … … 532 533 domain.update_boundary() 533 534 domain.check_integrity() 535 536 def test_boundary_conditions_inconsistent_internal(self): 537 a = [0.0, 0.0] 538 b = [0.0, 2.0] 539 c = [2.0, 0.0] 540 d = [0.0, 4.0] 541 e = [2.0, 2.0] 542 f = [4.0, 0.0] 543 544 points = [a, b, c, d, e, f] 545 # bac, bce, ecf, dbe 546 vertices = [[1,0,2], [1,2,4], [4,2,5], [3,1,4]] 547 boundary = {(0, 0): 'Third', 548 (0, 2): 'First', 549 (2, 0): 'Second', 550 (2, 1): 'Second', 551 (3, 1): 'Second', 552 (3, 2): 'Third', 553 (0, 1): 'Internal'} 554 555 domain = Domain(points, vertices, boundary) 556 557 try: 558 domain.check_integrity() 559 except AssertionError: 560 pass 561 else: 562 msg = 'should have thrown assertion exception' 563 raise Exception(msg) 564 565 566 567 534 568 535 569 def test_boundary_conditionsIII(self): … … 678 712 679 713 assert num.allclose(domain.neighbours, 680 [[-1,1,- 1], [2,3,0], [-1,-1,1],[1,-1,-1]])714 [[-1,1,-2], [2,3,0], [-3,-4,1],[1,-5,-6]]) 681 715 assert num.allclose(domain.neighbour_edges, 682 716 [[-1,2,-1], [2,0,1], [-1,-1,0],[1,-1,-1]]) -
trunk/anuga_core/source/anuga/utilities/cg_solve.py
r8025 r8154 8 8 9 9 10 def conjugate_gradient(A, b,x0=None,imax=10000,tol=1.0e-8,atol=1.0e-14,iprint=None):10 def conjugate_gradient(A, b, x0=None, imax=10000, tol=1.0e-8, atol=1.0e-14, iprint=None): 11 11 """ 12 12 Try to solve linear equation Ax = b using … … 23 23 24 24 b = num.array(b, dtype=num.float) 25 if len(b.shape) != 1 25 if len(b.shape) != 1: 26 26 27 27 for i in range(b.shape[1]): 28 x0[:, i] = _conjugate_gradient(A, b[:,i], x0[:,i],29 imax, tol, atol, iprint)28 x0[:, i] = _conjugate_gradient(A, b[:, i], x0[:, i], 29 imax, tol, atol, iprint) 30 30 else: 31 31 x0 = _conjugate_gradient(A, b, x0, imax, tol, atol, iprint) … … 34 34 35 35 def _conjugate_gradient(A, b, x0, 36 imax=10000, tol=1.0e-8, atol=1.0e-1 4, iprint=None):37 """36 imax=10000, tol=1.0e-8, atol=1.0e-10, iprint=None): 37 """ 38 38 Try to solve linear equation Ax = b using 39 39 conjugate gradient method … … 51 51 """ 52 52 53 b = num.array(b, dtype=num.float) 54 if len(b.shape) != 1: 55 raise VectorShapeError, 'input vector should consist of only one column' 53 56 54 b = num.array(b, dtype=num.float) 55 if len(b.shape) != 1 : 56 raise VectorShapeError, 'input vector should consist of only one column' 57 58 if x0 is None: 59 x0 = num.zeros(b.shape, dtype=num.float) 60 else: 61 x0 = num.array(x0, dtype=num.float) 57 if x0 is None: 58 x0 = num.zeros(b.shape, dtype=num.float) 59 else: 60 x0 = num.array(x0, dtype=num.float) 62 61 63 62 64 #FIXME: Should test using None 65 if iprint == None or iprint == 0: 66 iprint = imax 63 if iprint == None or iprint == 0: 64 iprint = imax 67 65 68 i=169 x = x070 r = b - A*x71 d = r72 rTr = num.dot(r,r)73 rTr0 = rTr66 i = 1 67 x = x0 68 r = b - A * x 69 d = r 70 rTr = num.dot(r, r) 71 rTr0 = rTr 74 72 75 #FIXME Let the iterations stop if starting with a small residual76 while (i<imax and rTr>tol**2*rTr0 and rTr>atol**2 ):77 q = A*d78 alpha = rTr/num.dot(d,q)79 x = x + alpha*d80 if i%50 :81 r = b - A*x82 else:83 r = r - alpha*q84 rTrOld = rTr85 rTr = num.dot(r,r)86 bt = rTr/rTrOld87 73 88 d = r + bt*d 89 i = i+1 90 if i%iprint == 0 : 91 log.info('i = %g rTr = %20.15e' %(i,rTr)) 74 75 #FIXME Let the iterations stop if starting with a small residual 76 while (i < imax and rTr > tol ** 2 * rTr0 and rTr > atol ** 2): 77 q = A * d 78 alpha = rTr / num.dot(d, q) 79 xold = x 80 x = x + alpha * d 92 81 93 if i==imax: 82 dx = num.linalg.norm(x-xold) 83 if dx < atol : 84 break 85 86 if i % 50: 87 r = b - A * x 88 else: 89 r = r - alpha * q 90 rTrOld = rTr 91 rTr = num.dot(r, r) 92 bt = rTr / rTrOld 93 94 d = r + bt * d 95 i = i + 1 96 if i % iprint == 0: 97 log.info('i = %g rTr = %15.8e dx = %15.8e' % (i, rTr, dx)) 98 99 if i == imax: 94 100 log.warning('max number of iterations attained') 95 msg = 'Conjugate gradient solver did not converge: rTr==%20.15e' % rTr101 msg = 'Conjugate gradient solver did not converge: rTr==%20.15e' % rTr 96 102 raise ConvergenceError, msg 97 103 98 return x 104 #print x 105 return x 99 106 -
trunk/anuga_core/source/anuga/utilities/sparse.py
r8127 r8154 291 291 292 292 def __repr__(self): 293 return '%d X %d sparse matrix:\n' %(self.M, self.N) + `self.data` 293 return '%d X %d sparse matrix:\n' %(self.M, self.N) + 'data '+ `self.data` + '\ncolind ' + \ 294 `self.colind` + '\nrow_ptr ' + `self.row_ptr` 294 295 295 296 def __len__(self):
Note: See TracChangeset
for help on using the changeset viewer.