Changeset 4685


Ignore:
Timestamp:
Aug 28, 2007, 2:23:35 PM (17 years ago)
Author:
ole
Message:

Implemented optimisation excluding dry cells from flux calculation.
All tests pass and the script run_okushiri_profile.py reports an improvement
in compute_fluxes from 11.25s to 8.58s or 24% faster.
The overall computation was about 40s, so this optimisation improved the
total running time for the problem in question by 7%.

This partially addresses ticket:135

Files:
5 edited

Legend:

Unmodified
Added
Removed
  • anuga_core/source/anuga/config.py

    r4677 r4685  
    130130
    131131
    132 optimised_gradient_limiter = True #Use hardwired gradient limiter
     132optimise_dry_cells = True # Exclude dry and still cells from flux computation
     133
     134optimised_gradient_limiter = True # Use hardwired gradient limiter
    133135
    134136#Specific to shallow water W.E.
     
    140142
    141143
    142 minimum_storable_height = 1.0e-5 #Water depth below which it is *stored* as 0
     144minimum_storable_height = 1.0e-5 # Water depth below which it is *stored* as 0
    143145
    144146points_file_block_line_size = 500 # Number of lines read in from a points file
     
    146148
    147149umask = 002  # used to set file and directory permission created by anuga
     150
  • anuga_core/source/anuga/shallow_water/shallow_water_domain.py

    r4631 r4685  
    102102     beta_uh, beta_uh_dry, beta_vh, beta_vh_dry, tight_slope_limiters
    103103from anuga.config import alpha_balance
     104from anuga.config import optimise_dry_cells
    104105
    105106
     
    164165
    165166        self.tight_slope_limiters = tight_slope_limiters
     167        self.optimise_dry_cells = optimise_dry_cells
    166168
    167169        self.flux_function = flux_function_central
     
    889891                                         Ymom.explicit_update,
    890892                                         domain.already_computed_flux,
    891                                          domain.max_speed)
     893                                         domain.max_speed,
     894                                         int(domain.optimise_dry_cells))
    892895
    893896
  • anuga_core/source/anuga/shallow_water/shallow_water_ext.c

    r4682 r4685  
    245245  soundspeed_right = sqrt(g*h_right);
    246246
    247  
    248247  s_max = max(u_left+soundspeed_left, u_right+soundspeed_right);
    249248  if (s_max < 0.0) s_max = 0.0;
    250249
    251250  s_min = min(u_left-soundspeed_left, u_right-soundspeed_right);
    252   if (s_min > 0.0) s_min = 0.0;
    253 
     251   if (s_min > 0.0) s_min = 0.0;
     252
     253 
    254254  //Flux formulas
    255255  flux_left[0] = u_left*h_left;
     
    261261  flux_right[2] = u_right*vh_right;
    262262
    263 
     263 
     264 
    264265  //Flux computation
    265266  denom = s_max-s_min;
     
    12811282                                     Xmom.explicit_update,
    12821283                                     Ymom.explicit_update,
    1283                                      already_computed_flux)
     1284                                     already_computed_flux,
     1285                                     optimise_dry_cells)                                     
    12841286
    12851287
     
    13081310    *max_speed_array; //Keeps track of max speeds for each triangle
    13091311
     1312
    13101313  // Local variables
    13111314  double timestep, max_speed, epsilon, g, H0, length, area;
     1315  int optimise_dry_cells=0; // Optimisation flag 
    13121316  double normal[2], ql[3], qr[3], zl, zr;
    13131317  double edgeflux[3]; // Work array for summing up fluxes
    13141318
    1315   int number_of_elements, k, i, j, m, n, computation_needed;
     1319  int number_of_elements, k, i, m, n; //, j, computation_needed;
     1320
    13161321  int ki, nm=0, ki2; // Index shorthands
    13171322  static long call=1; // Static local variable flagging already computed flux
     
    13191324
    13201325  // Convert Python arguments to C
    1321   if (!PyArg_ParseTuple(args, "ddddOOOOOOOOOOOOOOOOOOO",
     1326  if (!PyArg_ParseTuple(args, "ddddOOOOOOOOOOOOOOOOOOOi",
    13221327                        &timestep,
    13231328                        &epsilon,
     
    13401345                        &ymom_explicit_update,
    13411346                        &already_computed_flux,
    1342                         &max_speed_array)) {
     1347                        &max_speed_array,
     1348                        &optimise_dry_cells)) {
    13431349    PyErr_SetString(PyExc_RuntimeError, "Input arguments failed");
    13441350    return NULL;
    13451351  }
     1352 
    13461353 
    13471354  number_of_elements = stage_edge_values -> dimensions[0];
     
    13671374        // We've already computed the flux across this edge
    13681375        continue;
     1376       
    13691377       
    13701378      ql[0] = ((double *) stage_edge_values -> data)[ki];
     
    13931401     
    13941402     
    1395       // Check if flux calculation is necessary across this edge
    1396       // FIXME (Ole): Work in progress!
    1397       computation_needed = 0;
    1398       //for (j=0; j<3; j++) {     
    1399       //if (ql[j] != qr[j]) computation_needed = 1;
    1400       //}
    1401      
    1402       //if (computation_needed == 0) {
    1403         //printf("flux exemption identified\n");
     1403      if (optimise_dry_cells) {     
     1404        // Check if flux calculation is necessary across this edge
     1405        // This check will exclude dry cells.
     1406        // This will also optimise cases where zl != zr as
     1407        // long as both are dry
     1408
     1409        if ( fabs(ql[0] - zl) < epsilon &&
     1410             fabs(qr[0] - zr) < epsilon ) {
     1411          // Cell boundary is dry
     1412         
     1413          ((long *) already_computed_flux -> data)[ki] = call; // #k Done       
     1414          if (n>=0)
     1415            ((long *) already_computed_flux -> data)[nm] = call; // #n Done
    14041416       
    1405         //((long *) already_computed_flux -> data)[ki] = call; // #k Done       
    1406         //if (n>=0)
    1407         //  ((long *) already_computed_flux -> data)[nm] = call; // #n Done
    1408        
    1409         //max_speed = 0.0;
    1410         //continue;
    1411       //}
     1417          max_speed = 0.0;
     1418          continue;
     1419        }
     1420      }
    14121421     
    14131422
     
    14591468        }
    14601469      }
     1470     
    14611471    } // End edge i
    14621472   
  • anuga_core/source/anuga/shallow_water/test_shallow_water_domain.py

    r4684 r4685  
    229229        domain.compute_fluxes()
    230230       
    231         print domain.get_quantity('stage').explicit_update
     231        #print domain.get_quantity('stage').explicit_update
    232232        # FIXME (Ole): TODO the general case
    233233        #assert allclose(domain.get_quantity('stage').explicit_update[1], ........??)
     
    13061306
    13071307    #####################################################
    1308     def test_initial_condition(self):
    1309         """Test that initial condition is output at time == 0
     1308
     1309    def test_flux_optimisation(self):
     1310        """test_flux_optimisation
     1311        Test that fluxes are correctly computed using
     1312        dry and still cell exclusions
    13101313        """
    13111314
     
    13441347        domain.set_boundary({'exterior': Reflective_boundary(domain)})
    13451348
     1349
     1350        #  Check that update arrays are initialised to zero
     1351        assert allclose(domain.get_quantity('stage').explicit_update, 0)
     1352        assert allclose(domain.get_quantity('xmomentum').explicit_update, 0)
     1353        assert allclose(domain.get_quantity('ymomentum').explicit_update, 0)               
     1354
     1355
     1356        # Get true values
     1357        domain.optimise_dry_cells = False
     1358        domain.compute_fluxes()
     1359        stage_ref = copy.copy(domain.get_quantity('stage').explicit_update)
     1360        xmom_ref = copy.copy(domain.get_quantity('xmomentum').explicit_update)
     1361        ymom_ref = copy.copy(domain.get_quantity('ymomentum').explicit_update)       
     1362
     1363        # Try with flux optimisation
     1364        domain.optimise_dry_cells = True
     1365        domain.compute_fluxes()
     1366
     1367        assert allclose(stage_ref, domain.get_quantity('stage').explicit_update)
     1368        assert allclose(xmom_ref, domain.get_quantity('xmomentum').explicit_update)
     1369        assert allclose(ymom_ref, domain.get_quantity('ymomentum').explicit_update)
     1370       
     1371   
     1372       
     1373    def test_initial_condition(self):
     1374        """test_initial_condition
     1375        Test that initial condition is output at time == 0 and that
     1376        computed values change as system evolves
     1377        """
     1378
     1379        from anuga.config import g
     1380        import copy
     1381
     1382        a = [0.0, 0.0]
     1383        b = [0.0, 2.0]
     1384        c = [2.0, 0.0]
     1385        d = [0.0, 4.0]
     1386        e = [2.0, 2.0]
     1387        f = [4.0, 0.0]
     1388
     1389        points = [a, b, c, d, e, f]
     1390        #bac, bce, ecf, dbe
     1391        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
     1392
     1393        domain = Domain(points, vertices)
     1394
     1395        #Set up for a gradient of (3,0) at mid triangle (bce)
     1396        def slope(x, y):
     1397            return 3*x
     1398
     1399        h = 0.1
     1400        def stage(x,y):
     1401            return slope(x,y)+h
     1402
     1403        domain.set_quantity('elevation', slope)
     1404        domain.set_quantity('stage', stage)
     1405
     1406        # Allow slope limiters to work (FIXME (Ole): Shouldn't this be automatic in ANUGA?)     
     1407        domain.distribute_to_vertices_and_edges()       
     1408
     1409        initial_stage = copy.copy(domain.quantities['stage'].vertex_values)
     1410
     1411        domain.set_boundary({'exterior': Reflective_boundary(domain)})
     1412
     1413        domain.optimise_dry_cells = True
    13461414        #Evolution
    1347         for t in domain.evolve(yieldstep = 1.0, finaltime = 2.0):
     1415        for t in domain.evolve(yieldstep = 0.5, finaltime = 2.0):
    13481416            stage = domain.quantities['stage'].vertex_values
    13491417
     
    13521420            else:
    13531421                assert not allclose(stage, initial_stage)
     1422
    13541423
    13551424        os.remove(domain.get_name() + '.sww')
     
    47994868       
    48004869if __name__ == "__main__":
    4801     suite = unittest.makeSuite(Test_Shallow_Water,'test_flux_computation')   
     4870
     4871    suite = unittest.makeSuite(Test_Shallow_Water,'test')   
    48024872    #suite = unittest.makeSuite(Test_Shallow_Water,'test_tight_slope_limiters')
    48034873    #suite = unittest.makeSuite(Test_Shallow_Water,'test_get_maximum_inundation_from_sww')
  • anuga_validation/performance_tests/okushiri/run_okushiri_profile.py

    r4631 r4685  
    7878domain.set_boundary({'wave': Bts, 'wall': Br})
    7979
     80# Select optimisation
     81domain.optimise_dry_cells = True
    8082
    8183#-------------------------
Note: See TracChangeset for help on using the changeset viewer.