Ignore:
Timestamp:
Oct 30, 2007, 5:13:17 PM (17 years ago)
Author:
ole
Message:

Retired all Python code which is superseded by C implementations.
This has made the code base much smaller and there is less confusion when people try to understand the algorithms.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • anuga_core/source/anuga/abstract_2d_finite_volumes/quantity.py

    r4768 r4769  
    332332
    333333
    334         #General input checks
     334        # General input checks
    335335        L = [numeric, quantity, function, geospatial_data, points, filename]
    336336        msg = 'Exactly one of the arguments '+\
     
    360360
    361361
    362         #Determine which 'set_values_from_...' to use
     362        # Determine which 'set_values_from_...' to use
    363363
    364364        if numeric is not None:
     
    13371337   
    13381338
    1339 def update(quantity, timestep):
    1340     """Update centroid values based on values stored in
    1341     explicit_update and semi_implicit_update as well as given timestep
    1342 
    1343     Function implementing forcing terms must take on argument
    1344     which is the domain and they must update either explicit
    1345     or implicit updates, e,g,:
    1346 
    1347     def gravity(domain):
    1348         ....
    1349         domain.quantities['xmomentum'].explicit_update = ...
    1350         domain.quantities['ymomentum'].explicit_update = ...
    1351 
    1352 
    1353 
    1354     Explicit terms must have the form
    1355 
    1356         G(q, t)
    1357 
    1358     and explicit scheme is
    1359 
    1360        q^{(n+1}) = q^{(n)} + delta_t G(q^{n}, n delta_t)
    1361 
    1362 
    1363     Semi implicit forcing terms are assumed to have the form
    1364 
    1365        G(q, t) = H(q, t) q
    1366 
    1367     and the semi implicit scheme will then be
    1368 
    1369       q^{(n+1}) = q^{(n)} + delta_t H(q^{n}, n delta_t) q^{(n+1})
    1370 
    1371 
    1372     """
    1373 
    1374     from Numeric import sum, equal, ones, exp, Float
    1375 
    1376     N = quantity.centroid_values.shape[0]
    1377 
    1378 
    1379     # Divide H by conserved quantity to obtain G (see docstring above)
    1380 
    1381 
    1382     for k in range(N):
    1383         x = quantity.centroid_values[k]
    1384         if x == 0.0:
    1385             #FIXME: Is this right
    1386             quantity.semi_implicit_update[k] = 0.0
    1387         else:
    1388             quantity.semi_implicit_update[k] /= x
    1389 
    1390 
    1391     # Semi implicit updates
    1392     denominator = ones(N, Float)-timestep*quantity.semi_implicit_update
    1393 
    1394     if sum(less(denominator, 1.0)) > 0.0:
    1395         msg = 'denominator < 1.0 in semi implicit update. Call Stephen :-)'
    1396         raise msg
    1397 
    1398     if sum(equal(denominator, 0.0)) > 0.0:
    1399         msg = 'Zero division in semi implicit update. Call Stephen :-)'
    1400         raise msg
    1401     else:
    1402         #Update conserved_quantities from semi implicit updates
    1403         quantity.centroid_values /= denominator
    1404 
    1405 #    quantity.centroid_values = exp(timestep*quantity.semi_implicit_update)*quantity.centroid_values
    1406 
    1407     #Explicit updates
    1408     quantity.centroid_values += timestep*quantity.explicit_update
    1409 
    1410 def interpolate_from_vertices_to_edges(quantity):
    1411     """Compute edge values from vertex values using linear interpolation
    1412     """
    1413 
    1414     for k in range(quantity.vertex_values.shape[0]):
    1415         q0 = quantity.vertex_values[k, 0]
    1416         q1 = quantity.vertex_values[k, 1]
    1417         q2 = quantity.vertex_values[k, 2]
    1418 
    1419         quantity.edge_values[k, 0] = 0.5*(q1+q2)
    1420         quantity.edge_values[k, 1] = 0.5*(q0+q2)
    1421         quantity.edge_values[k, 2] = 0.5*(q0+q1)
    1422 
    1423 
    1424 
    1425 def backup_centroid_values(quantity):
    1426     """Copy centroid values to backup array"""
    1427 
    1428     qc = quantity.centroid_values
    1429     qb = quantity.centroid_backup_values
    1430 
    1431     #Check each triangle
    1432     for k in range(len(quantity.domain)):
    1433         qb[k] = qc[k]
    1434 
    1435 
    1436 def saxpy_centroid_values(quantity,a,b):
    1437     """saxpy operation between centroid value and backup"""
    1438 
    1439     qc = quantity.centroid_values
    1440     qb = quantity.centroid_backup_values
    1441 
    1442     #Check each triangle
    1443     for k in range(len(quantity.domain)):
    1444         qc[k] = a*qc[k]+b*qb[k]       
    1445 
    1446 
    1447 def compute_gradients(quantity):
    1448     """Compute gradients of triangle surfaces defined by centroids of
    1449     neighbouring volumes.
    1450     If one edge is on the boundary, use own centroid as neighbour centroid.
    1451     If two or more are on the boundary, fall back to first order scheme.
    1452     """
    1453 
    1454     from Numeric import zeros, Float
    1455     from utilitites.numerical_tools import gradient
    1456 
    1457     centroid_coordinates = quantity.domain.centroid_coordinates
    1458     surrogate_neighbours = quantity.domain.surrogate_neighbours
    1459     centroid_values = quantity.centroid_values
    1460     number_of_boundaries = quantity.domain.number_of_boundaries
    1461 
    1462     N = centroid_values.shape[0]
    1463 
    1464     a = zeros(N, Float)
    1465     b = zeros(N, Float)
    1466 
    1467     for k in range(N):
    1468         if number_of_boundaries[k] < 2:
    1469             #Two or three true neighbours
    1470 
    1471             #Get indices of neighbours (or self when used as surrogate)
    1472             k0, k1, k2 = surrogate_neighbours[k,:]
    1473 
    1474             #Get data
    1475             q0 = centroid_values[k0]
    1476             q1 = centroid_values[k1]
    1477             q2 = centroid_values[k2]
    1478 
    1479             x0, y0 = centroid_coordinates[k0] #V0 centroid
    1480             x1, y1 = centroid_coordinates[k1] #V1 centroid
    1481             x2, y2 = centroid_coordinates[k2] #V2 centroid
    1482 
    1483             #Gradient
    1484             a[k], b[k] = gradient(x0, y0, x1, y1, x2, y2, q0, q1, q2)
    1485 
    1486         elif number_of_boundaries[k] == 2:
    1487             #One true neighbour
    1488 
    1489             #Get index of the one neighbour
    1490             for k0 in surrogate_neighbours[k,:]:
    1491                 if k0 != k: break
    1492             assert k0 != k
    1493 
    1494             k1 = k  #self
    1495 
    1496             #Get data
    1497             q0 = centroid_values[k0]
    1498             q1 = centroid_values[k1]
    1499 
    1500             x0, y0 = centroid_coordinates[k0] #V0 centroid
    1501             x1, y1 = centroid_coordinates[k1] #V1 centroid
    1502 
    1503             #Gradient
    1504             a[k], b[k] = gradient2(x0, y0, x1, y1, q0, q1)
    1505         else:
    1506             #No true neighbours -
    1507             #Fall back to first order scheme
    1508             pass
    1509 
    1510 
    1511     return a, b
    1512 
    1513 
    1514 
    1515 def limit(quantity):
    1516     """Limit slopes for each volume to eliminate artificial variance
    1517     introduced by e.g. second order extrapolator
    1518 
    1519     This is an unsophisticated limiter as it does not take into
    1520     account dependencies among quantities.
    1521 
    1522     precondition:
    1523     vertex values are estimated from gradient
    1524     postcondition:
    1525     vertex values are updated
    1526     """
    1527 
    1528     from Numeric import zeros, Float
    1529 
    1530     N = quantity.domain.number_of_nodes
    1531 
    1532     beta_w = quantity.domain.beta_w
    1533 
    1534     qc = quantity.centroid_values
    1535     qv = quantity.vertex_values
    1536 
    1537     #Find min and max of this and neighbour's centroid values
    1538     qmax = zeros(qc.shape, Float)
    1539     qmin = zeros(qc.shape, Float)
    1540 
    1541     for k in range(N):
    1542         qmax[k] = qc[k]
    1543         qmin[k] = qc[k]
    1544         for i in range(3):
    1545             n = quantity.domain.neighbours[k,i]
    1546             if n >= 0:
    1547                 qn = qc[n] #Neighbour's centroid value
    1548 
    1549                 qmin[k] = min(qmin[k], qn)
    1550                 qmax[k] = max(qmax[k], qn)
    1551         qmax[k] = min(qmax[k], 2.0*qc[k])
    1552         qmin[k] = max(qmin[k], 0.5*qc[k])
    1553 
    1554 
    1555     #Diffences between centroids and maxima/minima
    1556     dqmax = qmax - qc
    1557     dqmin = qmin - qc
    1558 
    1559     #Deltas between vertex and centroid values
    1560     dq = zeros(qv.shape, Float)
    1561     for i in range(3):
    1562         dq[:,i] = qv[:,i] - qc
    1563 
    1564     #Phi limiter
    1565     for k in range(N):
    1566 
    1567         #Find the gradient limiter (phi) across vertices
    1568         phi = 1.0
    1569         for i in range(3):
    1570             r = 1.0
    1571             if (dq[k,i] > 0): r = dqmax[k]/dq[k,i]
    1572             if (dq[k,i] < 0): r = dqmin[k]/dq[k,i]
    1573 
    1574             phi = min( min(r*beta_w, 1), phi )
    1575 
    1576         #Then update using phi limiter
    1577         for i in range(3):
    1578             qv[k,i] = qc[k] + phi*dq[k,i]
    1579 
    1580 
    15811339
    15821340from anuga.utilities import compile
    1583 if compile.can_use_C_extension('quantity_ext.c'):
    1584     #Replace python version with c implementations
     1341if compile.can_use_C_extension('quantity_ext.c'):   
     1342    # Underlying C implementations can be accessed
    15851343
    15861344    from quantity_ext import average_vertex_values, backup_centroid_values, \
     
    15881346
    15891347    from quantity_ext import compute_gradients, limit,\
    1590     extrapolate_second_order, interpolate_from_vertices_to_edges, update
     1348    extrapolate_second_order, interpolate_from_vertices_to_edges, update   
     1349else:
     1350    msg = 'C implementations could not be accessed by %s.\n ' %__file__
     1351    msg += 'Make sure compile_all.py has been run as described in '
     1352    msg += 'the ANUGA installation guide.'
     1353    raise Exception, msg
     1354
     1355
     1356
Note: See TracChangeset for help on using the changeset viewer.