Ignore:
Timestamp:
Aug 9, 2005, 5:44:21 PM (20 years ago)
Author:
steve
Message:

Found problem with File_Boundary as used in validation test LWRU2. Have setup new BC Transmissive_Momentum_Set _Stage

Location:
inundation/ga/storm_surge/pyvolution
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • inundation/ga/storm_surge/pyvolution/config.py

    r1690 r1697  
    8787if sys.platform == 'win32':
    8888    #default_datadir = 'C:\grohm_output'
    89     default_datadir = '.' 
     89    default_datadir = '.'
    9090else:
    9191    #default_datadir = os.path.expanduser('~'+os.sep+'grohm_output')
    92     default_datadir = '.' 
     92    default_datadir = '.'
    9393
    9494
  • inundation/ga/storm_surge/pyvolution/domain.py

    r1681 r1697  
    545545        from config import min_timestep
    546546
    547         timestep = self.timestep
     547        # self.timestep is calculated from speed of characteristics
     548        # Apply CFL condition here
     549        timestep = self.CFL*self.timestep
    548550
    549551        #Record maximal and minimal values of timestep for reporting
     
    635637    def update_ghosts(self):
    636638        pass
    637 
    638639
    639640    def distribute_to_vertices_and_edges(self):
  • inundation/ga/storm_surge/pyvolution/generic_boundary_conditions.py

    r1657 r1697  
    1010       A boundary object has one neighbour; the one it
    1111       serves.
    12     """   
     12    """
    1313
    1414    def __init__(self):
    1515        pass
    16        
     16
    1717    def evaluate(self, vol_id=None, edge_id=None):
    1818        msg = 'Generic class Boundary must be subclassed'
     
    2626    Underlying domain must be specified when boundary is instantiated
    2727    """
    28    
     28
    2929    def __init__(self, domain = None):
    3030        Boundary.__init__(self)
     
    3333            msg = 'Domain must be specified for transmissive boundary'
    3434            raise msg
    35        
    36         self.domain = domain
    37        
     35
     36        self.domain = domain
     37
    3838    def __repr__(self):
    3939        return 'Transmissive_boundary(%s)' %self.domain
     
    4343        of the volume they serve.
    4444        """
    45        
     45
    4646        q = self.domain.get_conserved_quantities(vol_id, edge = edge_id)
    47         return q       
     47        return q
    4848
    4949
     
    6666    def __repr__(self):
    6767        return 'Dirichlet boundary (%s)' %self.conserved_quantities
    68    
     68
    6969    def evaluate(self, vol_id=None, edge_id=None):
    7070        return self.conserved_quantities
     
    8888            msg = 'Function for time boundary could not be executed:\n%s' %e
    8989            raise msg
    90        
    91 
    92         from Numeric import array, Float       
     90
     91
     92        from Numeric import array, Float
    9393        try:
    9494            q = array(q).astype(Float)
     
    9696            msg = 'Return value from time boundary function could '
    9797            msg += 'not be converted into a Numeric array of floats.\n'
    98             msg += 'Specified function should return either list or array.' 
     98            msg += 'Specified function should return either list or array.'
    9999            raise msg
    100100
    101101        msg = 'ERROR: Time boundary function must return a 1d list or array '
    102102        assert len(q.shape) == 1, msg
    103            
     103
    104104        d = len(domain.conserved_quantities)
    105105        msg = 'Return value for f must be a list or an array of length %d' %d
     
    132132        from config import time_format
    133133        from util import File_function
    134        
     134
    135135        Boundary.__init__(self)
    136136
     
    145145        assert len(q) == d, msg
    146146
    147        
     147
    148148    def __repr__(self):
    149149        return 'File boundary'
     
    174174    File boundary must read and interpolate from *smoothed* version
    175175    as stored in sww and cannot work with the discontinuos triangles.
    176    
     176
    177177    """
    178178
     
    182182        from config import time_format
    183183        from util import file_function
    184        
     184
    185185        Boundary.__init__(self)
    186186
    187187        #Get x,y vertex coordinates for all triangles
    188188        V = domain.vertex_coordinates
    189        
     189
    190190        #Compute midpoint coordinates for all boundary elements
    191         #Only a subset may be invoked when boundary is evaluated but
    192         #we don't know which ones at this stage since this object can be attached to
    193         #any tagged boundary later on.
     191        #Only a subset may be invoked when boundary is evaluated but
     192        #we don't know which ones at this stage since this object can be attached to
     193        #any tagged boundary later on.
    194194
    195195        if verbose: print 'Find midpoint coordinates of entire boundary'
    196196        self.midpoint_coordinates = zeros( (len(domain.boundary), 2), Float)
    197         boundary_keys = domain.boundary.keys()
    198        
    199         #Record ordering #FIXME: should this happen in domain.py
    200         self.boundary_indices = {} 
    201        
     197        boundary_keys = domain.boundary.keys()
     198
     199        #Record ordering #FIXME: should this happen in domain.py
     200        self.boundary_indices = {}
     201
    202202        for i, (vol_id, edge_id) in enumerate(boundary_keys):
    203            
     203
    204204            x0 = V[vol_id, 0]; y0 = V[vol_id, 1]
    205205            x1 = V[vol_id, 2]; y1 = V[vol_id, 3]
    206             x2 = V[vol_id, 4]; y2 = V[vol_id, 5]           
    207 
    208             #Midpoints       
     206            x2 = V[vol_id, 4]; y2 = V[vol_id, 5]
     207
     208            #Midpoints
    209209            if edge_id == 0: m = array([(x1 + x2)/2, (y1 + y2)/2])
    210210            if edge_id == 1: m = array([(x0 + x2)/2, (y0 + y2)/2])
    211             if edge_id == 2: m = array([(x1 + x0)/2, (y1 + y0)/2])           
     211            if edge_id == 2: m = array([(x1 + x0)/2, (y1 + y0)/2])
    212212            self.midpoint_coordinates[i,:] = m
    213            
    214             self.boundary_indices[(vol_id, edge_id)] = i
    215        
    216 
    217         if verbose: print 'Initialise file_function'
    218         self.F = file_function(filename, domain, 
     213
     214            self.boundary_indices[(vol_id, edge_id)] = i
     215
     216
     217        if verbose: print 'Initialise file_function'
     218        self.F = file_function(filename, domain,
    219219                               interpolation_points=self.midpoint_coordinates,
    220220                               verbose = verbose)
     
    225225
    226226        d = len(domain.conserved_quantities)
    227         msg = 'Values specified in file %s must be ' %filename 
    228         msg += ' a list or an array of length %d' %d
     227        msg = 'Values specified in file %s must be ' %filename
     228        msg += ' a list or an array of length %d' %d
    229229        assert len(q) == d, msg
    230230
    231        
     231
    232232    def __repr__(self):
    233233        return 'File boundary'
     
    247247        else:
    248248            #raise 'Boundary call without point_id not implemented'
    249             #FIXME: What should the semantics be?       
     249            #FIXME: What should the semantics be?
    250250            return self.F(t)
    251251
     
    262262    conserved quantities from a volume as defined by a connection table
    263263    mapping between tuples of (volume id, face id) for volumes that
    264     have their boundaries connected. 
     264    have their boundaries connected.
    265265
    266266    FIXME: Perhaps include possibility of mapping between
     
    274274    def __init__(self, table):
    275275        from domain import Volume
    276        
     276
    277277        Boundary.__init__(self)
    278278
     
    281281
    282282    def __repr__(self):
    283         return 'Connective boundary'       
     283        return 'Connective boundary'
    284284
    285285    #FIXME: IF we ever need to get field_values from connected volume,
     
    287287    #get_conserved_quantities
    288288    #def get_field_values()
    289    
     289
    290290    def get_conserved_quantities(self, volume, face=0):
    291291
    292292        id = volume.id
    293293        if self.connection_table.has_key((id, face)):
    294             other_id, other_face = self.connection_table[(id, face)] 
    295            
     294            other_id, other_face = self.connection_table[(id, face)]
     295
    296296            other_volume = self.Volume.instances[other_id]
    297297            cmd = 'q = other_volume.conserved_quantities_face%d' %face;
    298             exec(cmd)       
     298            exec(cmd)
    299299            return q
    300300        else:
     
    302302                  %(id, face)
    303303            raise msg
    304            
    305        
    306 
    307 
    308 
    309 #FIXME: Add a boundary with a general function of x,y, and t 
     304
     305
     306
     307
     308
     309#FIXME: Add a boundary with a general function of x,y, and t
    310310
    311311#FIXME: Add periodic boundaries e.g.:
     
    317317#
    318318#    print i,k
    319 #   
     319#
    320320#    domain[i].faces[2].neighbour = domain[k].faces[1]
    321 #    domain[k].faces[1].neighbour = domain[i].faces[2]   
    322    
     321#    domain[k].faces[1].neighbour = domain[i].faces[2]
     322
    323323
    324324
     
    329329    Must specify initial conserved quantities,
    330330    neighbour,
    331     domain to get access to model time 
     331    domain to get access to model time
    332332    a function f(q_old, neighbours_q, t) which must return
    333333    new conserved quantities q as a function time
     
    366366        from Numeric import array
    367367        from config import time_format
    368        
     368
    369369        Boundary.__init__(self)
    370370
     
    385385        try:
    386386            starttime = time.mktime(time.strptime(fields[0], time_format))
    387         except ValueError:   
     387        except ValueError:
    388388            msg = 'First field in file %s must be' %filename
    389389            msg += ' date-time with format %s.\n' %time_format
    390             msg += 'I got %s instead.' %fields[0] 
     390            msg += 'I got %s instead.' %fields[0]
    391391            raise msg
    392392
     
    397397
    398398        q = array(values)
    399        
     399
    400400        msg = 'ERROR: File boundary function must return a 1d list or array '
    401401        assert len(q.shape) == 1, msg
    402            
     402
    403403        d = len(domain.conserved_quantities)
    404404        msg = 'Values specified in file must be a list or an array of length %d' %d
     
    414414            msg = 'Start time as specified in domain (%s) is earlier '
    415415            'than the starttime of file %s: %s'\
    416                   %(domain.starttime, self.filename, self.starttime) 
     416                  %(domain.starttime, self.filename, self.starttime)
    417417            if self.starttime > domain.starttime:
    418418                raise msg
    419        
     419
    420420        self.read_time_boundary() #Now read all times in.
    421        
    422        
     421
     422
    423423    def read_time_boundary(self):
    424424        from Numeric import zeros, Float, alltrue
    425425        from config import time_format
    426426        import time
    427        
    428         fid = open(self.filename)       
     427
     428        fid = open(self.filename)
    429429        lines = fid.readlines()
    430430        fid.close()
    431        
     431
    432432        N = len(lines)
    433433        d = len(self.domain.conserved_quantities)
     
    436436        Q = zeros((N, d), Float)
    437437
    438        
     438
    439439        for i, line in enumerate(lines):
    440440            fields = line.split(',')
     
    443443            T[i] = real_time - self.starttime
    444444
    445            
     445
    446446            for j, value in enumerate(fields[1].split()):
    447447                Q[i, j] = float(value)
     
    449449        msg = 'Time boundary must list time as a monotonuosly '
    450450        msg += 'increasing sequence'
    451        
     451
    452452        assert alltrue( T[1:] - T[:-1] > 0 ), msg
    453453
     
    456456        self.index = 0 #Initial index
    457457
    458        
     458
    459459    def __repr__(self):
    460460        return 'File boundary'
     
    465465
    466466        t = self.domain.time
    467        
     467
    468468        msg = 'Time given in File boundary does not match model time'
    469469        if t < self.T[0]: raise msg
    470         if t > self.T[-1]: raise msg       
     470        if t > self.T[-1]: raise msg
    471471
    472472        oldindex = self.index
     
    478478        #if oldindex != self.index:
    479479        #    print 'Changing from %d to %d' %(oldindex, self.index)
    480        
    481        
     480
     481
    482482        #t is now between index and index+1
    483483        ratio = (t - self.T[self.index])/\
     
    485485
    486486        return self.Q[self.index,:] +\
    487                ratio*(self.Q[self.index+1,:] - self.Q[self.index,:])
    488 
    489 
    490    
    491    
    492        
     487               ratio*(self.Q[self.index+1,:] - self.Q[self.index,:])
     488
     489
     490
     491
  • inundation/ga/storm_surge/pyvolution/netherlands.py

    r1688 r1697  
    8383N = 130 #size = 33800
    8484N = 600 #Size = 720000
    85 N = 100
     85N = 50
    8686
    8787
     
    154154#
    155155print 'Initial condition'
    156 domain.set_quantity('stage', Constant_height(Z, 0.0))
    157 #domain.set_quantity('stage', Constant_stage(-1.0))
     156#domain.set_quantity('stage', Constant_height(Z, 0.0))
     157domain.set_quantity('stage', Constant_stage(inflow_stage/2.0))
    158158
    159159#Evolve
     
    169169for t in domain.evolve(yieldstep = 0.02, finaltime = 15.0):
    170170    domain.write_time()
     171    print domain.quantities['stage'].get_values(location='centroids',indexes=[0])
    171172    #V.update_quantity('stage')
    172173    #rpdb.set_active()
  • inundation/ga/storm_surge/pyvolution/quantity.py

    r1681 r1697  
    182182            self.set_values_from_file(X) #FIXME: More parameters
    183183
    184        
     184
    185185        if location == 'vertices' or location == 'unique vertices':
    186186            #Intialise centroid and edge_values
     
    199199                  Default is "vertices"
    200200
    201         In case of location == 'centroid' the dimension values must
     201        In case of location == 'centroids' the dimension values must
    202202        be a list of a Numerical array of length N, N being the number
    203203        of elements. Otherwise it must be of dimension Nx3
     
    266266        #FIXME: Should check that function returns something sensible and
    267267        #raise a meaningfol exception if it returns None for example
    268        
     268
    269269        from Numeric import take
    270270
     
    404404        #FIXME location, indices
    405405
    406        
     406
    407407        import util, least_squares
    408408
     
    413413            attribute_name = names[0]
    414414
    415            
     415
    416416        if verbose:
    417417            print 'Using attribute %s from file %s' %(attribute_name, filename)
    418             print 'Available attributes: %s' %(names) 
    419            
     418            print 'Available attributes: %s' %(names)
     419
    420420
    421421        try:
     
    425425                  %(attribute_name, filename)
    426426            raise msg
    427        
     427
    428428
    429429        #Fit attributes to mesh
     
    438438        #Recursively set value using fitted array
    439439        print 'shape', X.shape
    440         self.set_values(X, location='vertices')  #FIXME, indexes = None):       
    441        
     440        self.set_values(X, location='vertices')  #FIXME, indexes = None):
     441
    442442
    443443
     
    470470            assert A.shape[0] == len(indexes)
    471471            vertex_list = indexes
    472            
     472
    473473        #Go through list of unique vertices
    474474        for i_index, unique_vert_id in enumerate(vertex_list):
     
    606606            #M = 3*m        #Total number of unique vertices
    607607            #V = reshape(array(range(M)).astype(Int), (m,3))
    608            
     608
    609609            V = self.domain.get_triangles(obj=True)
    610610            #FIXME use get_vertices, when ready
     
    861861
    862862            #Gradient
    863             a[k], b[k] = gradient2(x0, y0, x1, y1, q0, q1)         
     863            a[k], b[k] = gradient2(x0, y0, x1, y1, q0, q1)
    864864        else:
    865865            #No true neighbours -
  • inundation/ga/storm_surge/pyvolution/realtime_visualisation_new.py

    r1688 r1697  
    206206        #print 'update bed image'
    207207        if qname=='elevation':
    208             self.vpython_z_models[qname].pos    = self.pos+1.0e-3
    209         else:
    210             self.vpython_z_models[qname].pos    = self.pos
    211 
     208            self.pos[:,2] = self.pos[:,2]+1.0e-3
     209
     210        self.vpython_z_models[qname].pos    = self.pos
    212211        self.vpython_z_models[qname].color  = self.colour
    213212        self.vpython_z_models[qname].normal = self.normals
  • inundation/ga/storm_surge/pyvolution/shallow_water.py

    r1688 r1697  
    113113            from realtime_visualisation_new import Visualiser
    114114            self.visualiser = Visualiser(self,scale_z,rect)
    115             self.visualiser.updating['elevation']=True
     115            self.visualiser.setup['elevation']=True
    116116        self.visualise = True
    117117
     
    181181
    182182#         #self.quantities['stage'].interpolate()
    183 
    184183
    185184
     
    964963
    965964
     965
     966class Transmissive_Momentum_Set_Stage_boundary(Boundary):
     967    """Returns same momentum conserved quantities as
     968    those present in its neighbour volume. Sets stage
     969
     970    Underlying domain must be specified when boundary is instantiated
     971    """
     972
     973    def __init__(self, domain = None, function=None):
     974        Boundary.__init__(self)
     975
     976        if domain is None:
     977            msg = 'Domain must be specified for this type boundary'
     978            raise msg
     979
     980        if function is None:
     981            msg = 'Function must be specified for this type boundary'
     982            raise msg
     983
     984        self.domain   = domain
     985        self.function = function
     986
     987    def __repr__(self):
     988        return 'Transmissive_Momentum_Set_Stage_boundary(%s)' %self.domain
     989
     990    def evaluate(self, vol_id, edge_id):
     991        """Transmissive Momentum Set Stage boundaries return the edge momentum
     992        values of the volume they serve.
     993        """
     994
     995        q = self.domain.get_conserved_quantities(vol_id, edge = edge_id)
     996        value = self.function(self.domain.time)
     997        q[0] = value[0]
     998        return q
     999
     1000
     1001
     1002
     1003
    9661004#class Spatio_temporal_boundary(Boundary):
    9671005#    """The spatio-temporal boundary, reads values for the conserved
Note: See TracChangeset for help on using the changeset viewer.