Changeset 1020
- Timestamp:
- Mar 7, 2005, 9:38:36 AM (20 years ago)
- Location:
- inundation/ga/storm_surge/pyvolution
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
inundation/ga/storm_surge/pyvolution/domain.py
r991 r1020 20 20 Mesh.__init__(self, coordinates, vertices, boundary, tagged_elements) 21 21 22 from Numeric import zeros, Float 22 from Numeric import zeros, Float 23 23 from quantity import Quantity, Conserved_quantity 24 24 … … 26 26 #the conservation equations 27 27 #(Must be a subset of quantities) 28 if conserved_quantities is None: 28 if conserved_quantities is None: 29 29 self.conserved_quantities = [] 30 30 else: 31 self.conserved_quantities = conserved_quantities 31 self.conserved_quantities = conserved_quantities 32 32 33 33 if other_quantities is None: 34 34 self.other_quantities = [] 35 35 else: 36 self.other_quantities = other_quantities 37 36 self.other_quantities = other_quantities 37 38 38 39 39 #Build dictionary of Quantity instances keyed by quantity names … … 53 53 from config import max_smallsteps, beta_w, beta_h, epsilon, CFL 54 54 self.beta_w = beta_w 55 self.beta_h = beta_h 55 self.beta_h = beta_h 56 56 self.epsilon = epsilon 57 57 … … 61 61 self.order = self.default_order 62 62 self.smallsteps = 0 63 self.max_smallsteps = max_smallsteps 63 self.max_smallsteps = max_smallsteps 64 64 self.number_of_steps = 0 65 self.number_of_first_order_steps = 0 65 self.number_of_first_order_steps = 0 66 66 self.CFL = CFL 67 68 #Model time 67 68 #Model time 69 69 self.time = 0.0 70 70 self.finaltime = None … … 74 74 self.zone = zone 75 75 self.xllcorner = xllcorner 76 self.yllcorner = yllcorner 77 78 79 #Checkpointing and storage 76 self.yllcorner = yllcorner 77 78 79 #Checkpointing and storage 80 80 from config import default_datadir 81 self.datadir = default_datadir 81 self.datadir = default_datadir 82 82 self.filename = 'domain' 83 83 self.checkpoint = False 84 85 86 #Public interface to Domain 84 85 86 #Public interface to Domain 87 87 def get_conserved_quantities(self, vol_id, vertex=None, edge=None): 88 88 """Get conserved quantities at volume vol_id … … 93 93 If both are specified an exeception is raised 94 94 95 Return value: Vector of length == number_of_conserved quantities 96 95 Return value: Vector of length == number_of_conserved quantities 96 97 97 """ 98 98 99 99 from Numeric import zeros, Float 100 100 101 101 if not (vertex is None or edge is None): 102 102 msg = 'Values for both vertex and edge was specified.' 103 msg += 'Only one (or none) is allowed.' 103 msg += 'Only one (or none) is allowed.' 104 104 raise msg 105 105 106 106 q = zeros( len(self.conserved_quantities), Float) 107 107 108 108 for i, name in enumerate(self.conserved_quantities): 109 109 Q = self.quantities[name] … … 113 113 q[i] = Q.edge_values[vol_id, edge] 114 114 else: 115 q[i] = Q.centroid_values[vol_id] 116 117 return q 115 q[i] = Q.centroid_values[vol_id] 116 117 return q 118 118 119 119 … … 121 121 """Set values for named quantities. 122 122 The index is the quantity 123 123 124 124 name: Name of quantity 125 125 X: Compatible list, Numeric array, const or function (see below) 126 126 127 127 The values will be stored in elements following their 128 128 internal ordering. … … 131 131 for key in quantity_dict.keys(): 132 132 self.set_quantity(key, quantity_dict[key], location='vertices') 133 133 134 134 135 135 def set_quantity(self, name, X, location='vertices', indexes = None): 136 136 """Set values for named quantity 137 137 138 138 name: Name of quantity 139 139 X: Compatible list, Numeric array, const or function (see below) … … 144 144 be a list of a Numerical array of length N, N being the number 145 145 of elements. Otherwise it must be of dimension Nx3. 146 146 147 147 Indexes is the set of element ids that the operation applies to 148 148 149 149 The values will be stored in elements following their 150 150 internal ordering. 151 151 152 152 #FIXME (Ole): I suggest the following interface 153 153 set_quantity(name, X, location, region) 154 154 where 155 155 name: Name of quantity 156 X: 157 -Compatible list, 158 -Numeric array, 156 X: 157 -Compatible list, 158 -Numeric array, 159 159 -const or function (see below) 160 160 -another quantity Q or an expression of the form … … 168 168 - indices (refers to specific triangles) 169 169 - polygon (identifies region) 170 170 171 171 This should work for all values of X 172 172 173 173 174 174 … … 176 176 177 177 #from quantity import Quantity, Conserved_quantity 178 178 179 179 #Create appropriate quantity object 180 180 ##if name in self.conserved_quantities: 181 181 ## self.quantities[name] = Conserved_quantity(self) 182 182 ##else: 183 ## self.quantities[name] = Quantity(self) 183 ## self.quantities[name] = Quantity(self) 184 184 185 185 #Set value 186 186 self.quantities[name].set_values(X, location, indexes = indexes) 187 187 188 188 189 189 def get_quantity(self, name, location='vertices', indexes = None): 190 190 """Get values for named quantity 191 191 192 192 name: Name of quantity 193 193 194 194 In case of location == 'centroid' the dimension values must 195 195 be a list of a Numerical array of length N, N being the number … … 197 197 198 198 Indexes is the set of element ids that the operation applies to. 199 199 200 200 The values will be stored in elements following their 201 201 internal ordering. … … 203 203 204 204 return self.quantities[name].get_values( location, indexes = indexes) 205 205 206 206 207 207 def set_boundary(self, boundary_map): … … 215 215 in the list self.boundary_objects. 216 216 More entries may point to the same boundary object 217 217 218 218 Schematically the mapping is from two dictionaries to one list 219 219 where the index is used as pointer to the boundary_values arrays … … 224 224 ---------------------------------------------- 225 225 self.boundary_objects: ((vol_id, edge_id), boundary_object) 226 226 227 227 228 228 Pre-condition: … … 236 236 However, if a tag is not used to the domain, no error is thrown. 237 237 FIXME: This would lead to implementation of a 238 default boundary condition 238 default boundary condition 239 239 240 240 Note: If a segment is listed in the boundary dictionary and if it is … … 242 242 even if there is a neighbouring triangle. 243 243 This would be the case for internal boundaries 244 244 245 245 Boundary objects that are None will be skipped. 246 246 … … 248 248 object is changed into None, the neighbour structure will not be 249 249 restored!!! 250 250 251 251 252 252 """ … … 269 269 pass 270 270 #FIXME: Check and perhaps fix neighbour structure 271 271 272 272 273 273 else: … … 279 279 raise msg 280 280 281 281 282 282 def set_region(self, functions): 283 283 # The order of functions in the list is used. … … 290 290 #Do we need to do this sort of thing? 291 291 #self = function(tag, self.tagged_elements[tag], self) 292 293 #MISC 292 293 #MISC 294 294 def check_integrity(self): 295 295 Mesh.check_integrity(self) … … 299 299 assert quantity in self.quantities, msg 300 300 301 ##assert hasattr(self, 'boundary_objects') 302 301 ##assert hasattr(self, 'boundary_objects') 302 303 303 def write_time(self): 304 304 if self.min_timestep == self.max_timestep: … … 309 309 print 'Time = %.4f, steps=%d (%d)'\ 310 310 %(self.time, self.number_of_steps, 311 self.number_of_first_order_steps) 311 self.number_of_first_order_steps) 312 312 else: 313 313 print 'Time = %.4f, delta t in [%.8f, %.8f], steps=%d (%d)'\ … … 318 318 319 319 def get_name(self): 320 return self.filename 321 320 return self.filename 321 322 322 def set_name(self, name): 323 self.filename = name 323 self.filename = name 324 324 325 325 def get_datadir(self): 326 return self.datadir 327 326 return self.datadir 327 328 328 def set_datadir(self, name): 329 self.datadir = name 330 331 329 self.datadir = name 330 331 332 332 333 333 #def set_defaults(self): … … 337 337 # 338 338 # for name in self.conserved_quantities + self.other_quantities: 339 # self.set_quantity(name, 0.0) 340 339 # self.set_quantity(name, 0.0) 340 341 341 342 342 ########################### … … 346 346 """Evolve model from time=0.0 to finaltime yielding results 347 347 every yieldstep. 348 348 349 349 Internally, smaller timesteps may be taken. 350 350 351 351 Evolve is implemented as a generator and is to be called as such, e.g. 352 352 353 353 for t in domain.evolve(timestep, yieldstep, finaltime): 354 354 <Do something with domain and t> 355 355 356 356 """ 357 357 … … 360 360 #FIXME: Maybe lump into a larger check prior to evolving 361 361 msg = 'Boundary tags must be bound to boundary objects before evolving system, ' 362 msg += 'e.g. using the method set_boundary.\n' 362 msg += 'e.g. using the method set_boundary.\n' 363 363 msg += 'This system has the boundary tags %s ' %self.get_boundary_tags() 364 364 assert hasattr(self, 'boundary_objects'), msg 365 365 366 366 ##self.set_defaults() 367 367 … … 370 370 371 371 self.order = self.default_order 372 373 372 373 374 374 self.yieldtime = 0.0 #Time between 'yields' 375 375 … … 379 379 self.finaltime = finaltime 380 380 self.number_of_steps = 0 381 self.number_of_first_order_steps = 0 381 self.number_of_first_order_steps = 0 382 382 383 383 #Initial update of vertex and edge values 384 384 self.distribute_to_vertices_and_edges() 385 386 385 386 387 387 #Or maybe restore from latest checkpoint 388 388 if self.checkpoint is True: 389 389 self.goto_latest_checkpoint() 390 390 391 391 392 392 yield(self.time) #Yield initial values 393 393 394 394 while True: 395 395 #Update boundary values 396 self.update_boundary() 397 398 #Compute fluxes across each element edge 396 self.update_boundary() 397 398 #Compute fluxes across each element edge 399 399 self.compute_fluxes() 400 400 … … 403 403 404 404 #Update conserved quantities 405 self.update_conserved_quantities() 405 self.update_conserved_quantities() 406 406 407 407 #Update vertex and edge values 408 408 self.distribute_to_vertices_and_edges() 409 410 #Update time 409 410 #Update time 411 411 self.time += self.timestep 412 412 self.yieldtime += self.timestep 413 413 self.number_of_steps += 1 414 414 if self.order == 1: 415 self.number_of_first_order_steps += 1 415 self.number_of_first_order_steps += 1 416 416 417 417 #Yield results … … 421 421 break 422 422 423 424 if abs(self.yieldtime - yieldstep) < epsilon: 423 424 if abs(self.yieldtime - yieldstep) < epsilon: 425 425 # Yield (intermediate) time and allow inspection of domain 426 426 … … 428 428 self.store_checkpoint() 429 429 self.delete_old_checkpoints() 430 431 #Pass control on to outer loop for more specific actions 432 yield(self.time) 430 431 #Pass control on to outer loop for more specific actions 432 yield(self.time) 433 433 434 434 # Reinitialise 435 self.yieldtime = 0.0 435 self.yieldtime = 0.0 436 436 self.min_timestep = max_timestep 437 437 self.max_timestep = min_timestep 438 438 self.number_of_steps = 0 439 self.number_of_first_order_steps = 0 440 441 439 self.number_of_first_order_steps = 0 440 441 442 442 def evolve_to_end(self, finaltime = 1.0): 443 443 """Iterate evolve all the way to the end 444 444 """ 445 445 446 for _ in self.evolve(yieldstep=None, finaltime=finaltime): 446 for _ in self.evolve(yieldstep=None, finaltime=finaltime): 447 447 pass 448 449 450 448 449 450 451 451 def update_boundary(self): 452 452 """Go through list of boundary objects and update boundary values … … 471 471 472 472 from config import min_timestep 473 473 474 474 timestep = self.timestep 475 476 #Record maximal and minimal values of timestep for reporting 475 476 #Record maximal and minimal values of timestep for reporting 477 477 self.max_timestep = max(timestep, self.max_timestep) 478 478 self.min_timestep = min(timestep, self.min_timestep) 479 479 480 480 #Protect against degenerate time steps 481 481 if timestep < min_timestep: 482 482 483 483 #Number of consecutive small steps taken b4 taking action 484 self.smallsteps += 1 484 self.smallsteps += 1 485 485 486 486 if self.smallsteps > self.max_smallsteps: 487 487 self.smallsteps = 0 #Reset 488 488 489 489 if self.order == 1: 490 490 msg = 'Too small timestep %.16f reached ' %timestep … … 501 501 if self.order == 1 and self.default_order == 2: 502 502 self.order = 2 503 503 504 504 505 505 #Ensure that final time is not exceeded … … 515 515 516 516 517 def compute_forcing_terms(self): 517 def compute_forcing_terms(self): 518 518 """If there are any forcing functions driving the system 519 519 they should be defined in Domain subclass and appended to … … 524 524 f(self) 525 525 526 526 527 527 528 528 def update_conserved_quantities(self): … … 532 532 533 533 from Numeric import ones, sum, equal, Float 534 534 535 535 N = self.number_of_elements 536 536 d = len(self.conserved_quantities) 537 537 538 538 timestep = self.timestep 539 539 540 #Compute forcing terms 541 self.compute_forcing_terms() 540 #Compute forcing terms 541 self.compute_forcing_terms() 542 542 543 543 #Update conserved_quantities … … 547 547 548 548 #Clean up 549 #Note that Q.explicit_update is reset by compute_fluxes 549 #Note that Q.explicit_update is reset by compute_fluxes 550 550 Q.semi_implicit_update[:] = 0.0 551 551 552 552 553 553 554 554 def distribute_to_vertices_and_edges(self): … … 567 567 elif self.order == 2: 568 568 Q.extrapolate_second_order() 569 Q.limit() 569 Q.limit() 570 570 else: 571 571 raise 'Unknown order' 572 Q.interpolate_from_vertices_to_edges() 573 574 575 572 Q.interpolate_from_vertices_to_edges() 573 574 575 576 576 ############################################## 577 577 #Initialise module … … 587 587 print msg 588 588 else: 589 psyco.bind(Domain.update_boundary) 589 psyco.bind(Domain.update_boundary) 590 590 #psyco.bind(Domain.update_timestep) #Not worth it 591 591 psyco.bind(Domain.update_conserved_quantities) 592 592 psyco.bind(Domain.distribute_to_vertices_and_edges) 593 593 594 594 595 595 if __name__ == "__main__": -
inundation/ga/storm_surge/pyvolution/util_ext.c
r999 r1020 2 2 // 3 3 // To compile (Python2.3): 4 // gcc -c util_ext.c -I/usr/include/python2.3 -o util_ext.o -Wall -O 5 // gcc -shared util_ext.o -o util_ext.so 4 // gcc -c util_ext.c -I/usr/include/python2.3 -o util_ext.o -Wall -O 5 // gcc -shared util_ext.o -o util_ext.so 6 6 // 7 7 // See the module util.py … … 9 9 // 10 10 // Ole Nielsen, GA 2004 11 11 12 12 #include "Python.h" 13 13 #include "Numeric/arrayobject.h" … … 19 19 20 20 21 int _point_on_line(double x, double y, 22 double x0, double y0, 21 int _point_on_line(double x, double y, 22 double x0, double y0, 23 23 double x1, double y1) { 24 /*Determine whether a point is on a line segment 25 24 /*Determine whether a point is on a line segment 25 26 26 Input: x, y, x0, x0, x1, y1: where 27 27 point is given by x, y 28 28 line is given by (x0, y0) and (x1, y1) 29 29 30 30 */ 31 31 32 32 double a0, a1, a_normal0, a_normal1, b0, b1, len_a, len_b; 33 33 34 34 a0 = x - x0; 35 a1 = y - y0; 36 35 a1 = y - y0; 36 37 37 a_normal0 = a1; 38 38 a_normal1 = -a0; 39 39 40 40 b0 = x1 - x0; 41 41 b1 = y1 - y0; 42 43 if ( a_normal0*b0 + a_normal1*b1 == 0 ) { 42 43 if ( a_normal0*b0 + a_normal1*b1 == 0 ) { 44 44 //Point is somewhere on the infinite extension of the line 45 45 46 len_a = sqrt(a0*a0 + a1*a1); 46 len_a = sqrt(a0*a0 + a1*a1); 47 47 len_b = sqrt(b0*b0 + b1*b1); 48 48 49 49 if (a0*b0 + a1*b1 >= 0 && len_a <= len_b) { 50 50 return 1; … … 63 63 double* points, 64 64 double* polygon, 65 int* indices, // M-Array for storage indices 66 int closed, 65 int* indices, // M-Array for storage indices 66 int closed, 67 67 int verbose) { 68 68 69 69 double minpx, maxpx, minpy, maxpy, x, y, px_i, py_i, px_j, py_j; 70 70 int i, j, k, count, inside; 71 72 //Find min and max of poly used for optimisation when points 73 //are far away from polygon 74 75 71 72 //Find min and max of poly used for optimisation when points 73 //are far away from polygon 74 75 76 76 minpx = polygon[0]; maxpx = minpx; 77 minpy = polygon[1]; maxpy = minpy; 78 77 minpy = polygon[1]; maxpy = minpy; 78 79 79 for (i=0; i<N; i++) { 80 80 px_i = polygon[2*i]; 81 81 py_i = polygon[2*i + 1]; 82 82 83 83 if (px_i < minpx) minpx = px_i; 84 if (px_i > maxpx) maxpx = px_i; 84 if (px_i > maxpx) maxpx = px_i; 85 85 if (py_i < minpy) minpy = py_i; 86 if (py_i > maxpy) maxpy = py_i; 86 if (py_i > maxpy) maxpy = py_i; 87 87 } 88 88 89 89 //Begin main loop (for each point) 90 90 count = 0; … … 93 93 //if (verbose){ 94 94 // if (k %((M+10)/10)==0: print 'Doing %d of %d' %(k, M) 95 95 96 96 x = points[2*k]; 97 y = points[2*k + 1]; 97 y = points[2*k + 1]; 98 98 99 99 inside = 0; … … 101 101 //Optimisation 102 102 if ((x > maxpx) || (x < minpx)) continue; 103 if ((y > maxpy) || (y < minpy)) continue; 104 105 //Check polygon 103 if ((y > maxpy) || (y < minpy)) continue; 104 105 //Check polygon 106 106 for (i=0; i<N; i++) { 107 107 //printf("k,i=%d,%d\n", k, i); 108 108 j = (i+1)%N; 109 109 110 110 px_i = polygon[2*i]; 111 111 py_i = polygon[2*i+1]; 112 112 px_j = polygon[2*j]; 113 py_j = polygon[2*j+1]; 114 115 //Check for case where point is contained in line segment 113 py_j = polygon[2*j+1]; 114 115 //Check for case where point is contained in line segment 116 116 if (_point_on_line(x, y, px_i, py_i, px_j, py_j)) { 117 117 if (closed == 1) { … … 120 120 inside = 0; 121 121 } 122 break; 123 } else { 124 //Check if truly inside polygon 122 break; 123 } else { 124 //Check if truly inside polygon 125 125 if ( ((py_i < y) && (py_j >= y)) || 126 126 ((py_j < y) && (py_i >= y)) ) { … … 133 133 indices[count] = k; 134 134 count++; 135 } 135 } 136 136 } // End k 137 137 138 138 return count; 139 139 } … … 146 146 // point_on_line(x, y, x0, y0, x1, y1) 147 147 // 148 148 149 149 double x, y, x0, y0, x1, y1; 150 150 int res; 151 151 PyObject *result; 152 153 // Convert Python arguments to C 154 if (!PyArg_ParseTuple(args, "dddddd", &x, &y, &x0, &y0, &x1, &y1)) 152 153 // Convert Python arguments to C 154 if (!PyArg_ParseTuple(args, "dddddd", &x, &y, &x0, &y0, &x1, &y1)) 155 155 return NULL; 156 156 157 157 158 158 // Call underlying routine 159 159 res = _point_on_line(x, y, x0, y0, x1, y1); … … 167 167 168 168 PyObject *inside_polygon(PyObject *self, PyObject *args) { 169 //def inside_polygon(point, polygon, closed, verbose, one_point): 169 //def inside_polygon(point, polygon, closed, verbose, one_point): 170 170 // """Determine whether points are inside or outside a polygon 171 // 171 // 172 172 // Input: 173 173 // point - Tuple of (x, y) coordinates, or list of tuples 174 174 // polygon - list of vertices of polygon 175 // one_poin - If True Boolean value should be returned 175 // one_poin - If True Boolean value should be returned 176 176 // If False, indices of points inside returned 177 // closed - (optional) determine whether points on boundary should be 178 // regarded as belonging to the polygon (closed = True) 179 // or not (closed = False) 180 181 // 177 // closed - (optional) determine whether points on boundary should be 178 // regarded as belonging to the polygon (closed = True) 179 // or not (closed = False) 180 181 // 182 182 // Output: 183 183 // If one point is considered, True or False is returned. 184 // If multiple points are passed in, the function returns indices 185 // of those points that fall inside the polygon 186 // 184 // If multiple points are passed in, the function returns indices 185 // of those points that fall inside the polygon 186 // 187 187 // Examples: 188 188 // inside_polygon( [0.5, 0.5], [[0,0], [1,0], [1,1], [0,1]] ) 189 // will evaluate to True as the point 0.5, 0.5 is inside the unit square 190 // 189 // will evaluate to True as the point 0.5, 0.5 is inside the unit square 190 // 191 191 // inside_polygon( [[0.5, 0.5], [1, -0.5], [0.3, 0.2]] ) 192 // will return the indices [0, 2] as only the first and the last point 192 // will return the indices [0, 2] as only the first and the last point 193 193 // is inside the unit square 194 // 194 // 195 195 // Remarks: 196 196 // The vertices may be listed clockwise or counterclockwise and 197 // the first point may optionally be repeated. 197 // the first point may optionally be repeated. 198 198 // Polygons do not need to be convex. 199 // Polygons can have holes in them and points inside a hole is 200 // regarded as being outside the polygon. 201 // 202 // 203 // Algorithm is based on work by Darel Finley, 204 // http://www.alienryderflex.com/polygon/ 205 // 206 // 207 208 PyArrayObject 209 *point, 210 *polygon, 199 // Polygons can have holes in them and points inside a hole is 200 // regarded as being outside the polygon. 201 // 202 // 203 // Algorithm is based on work by Darel Finley, 204 // http://www.alienryderflex.com/polygon/ 205 // 206 // 207 208 PyArrayObject 209 *point, 210 *polygon, 211 211 *indices; 212 213 int closed, verbose; //Flags 212 213 int closed, verbose; //Flags 214 214 int count, M, N; 215 216 // Convert Python arguments to C 217 if (!PyArg_ParseTuple(args, "OOOii", 218 &point, 219 &polygon, 220 &indices, 221 &closed, 222 &verbose)) 215 216 // Convert Python arguments to C 217 if (!PyArg_ParseTuple(args, "OOOii", 218 &point, 219 &polygon, 220 &indices, 221 &closed, 222 &verbose)) 223 223 return NULL; 224 224 225 M = point -> dimensions[0]; //Number of points 226 N = polygon -> dimensions[0]; //Number of vertices in polygon 225 M = point -> dimensions[0]; //Number of points 226 N = polygon -> dimensions[0]; //Number of vertices in polygon 227 227 228 228 //printf("M=%d, N=%d\n", M, N); 229 229 // Call underlying routine 230 count = _inside_polygon(M, N, 230 count = _inside_polygon(M, N, 231 231 (double*) point -> data, 232 232 (double*) polygon -> data, 233 233 (int*) indices -> data, 234 closed, verbose); 235 234 closed, verbose); 235 236 236 //NOTE: return number of points inside.. 237 237 //printf("COunt=%d\n", count); … … 245 245 // a,b = gradient(x0, y0, x1, y1, x2, y2, q0, q1, q2) 246 246 // 247 247 248 248 double x0, y0, x1, y1, x2, y2, q0, q1, q2, a, b; 249 249 PyObject *result; 250 251 // Convert Python arguments to C 250 251 // Convert Python arguments to C 252 252 if (!PyArg_ParseTuple(args, "ddddddddd", &x0, &y0, &x1, &y1, &x2, &y2, 253 &q0, &q1, &q2)) 253 &q0, &q1, &q2)) 254 254 return NULL; 255 255 256 256 257 257 // Call underlying routine 258 _gradient(x0, y0, x1, y1, x2, y2, 258 _gradient(x0, y0, x1, y1, x2, y2, 259 259 q0, q1, q2, &a, &b); 260 260 … … 271 271 * three. 272 272 */ 273 274 //{"rotate", (PyCFunction)rotate, METH_VARARGS | METH_KEYWORDS, "Print out"}, 275 {"gradient", gradient, METH_VARARGS, "Print out"}, 276 {"point_on_line", point_on_line, METH_VARARGS, "Print out"}, 277 {"inside_polygon", inside_polygon, METH_VARARGS, "Print out"}, 273 274 //{"rotate", (PyCFunction)rotate, METH_VARARGS | METH_KEYWORDS, "Print out"}, 275 {"gradient", gradient, METH_VARARGS, "Print out"}, 276 {"point_on_line", point_on_line, METH_VARARGS, "Print out"}, 277 {"inside_polygon", inside_polygon, METH_VARARGS, "Print out"}, 278 278 {NULL, NULL, 0, NULL} /* sentinel */ 279 279 }; … … 281 281 282 282 283 // Module initialisation 283 // Module initialisation 284 284 void initutil_ext(void){ 285 285 Py_InitModule("util_ext", MethodTable); 286 287 import_array(); //Necessary for handling of NumPY structures 288 } 289 286 287 import_array(); //Necessary for handling of NumPY structures 288 }
Note: See TracChangeset
for help on using the changeset viewer.