Ignore:
Timestamp:
Nov 24, 2004, 4:43:40 PM (20 years ago)
Author:
ole
Message:

Created and tested general File_function (reading and interpolating time series from file) and used it to refactor and simplify File_boundary

File:
1 edited

Legend:

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

    r620 r623  
    518518    """
    519519
    520     #FIXME: Experimental
     520    #FIXME: Experimental (from old version). Not in use at the moment
    521521   
    522522    #Shortcuts
     
    560560            xmomc[k] = ymomc[k] = 0.0
    561561       
     562        #FIXME: Delete   
    562563        #From 'newstyle
    563564        #if hc[k] < domain.minimum_allowed_height:       
     
    901902def check_forcefield(f):
    902903    """Check that f is either
    903     1: a callable object of x,y,t, where x and y are vectors
     904    1: a callable object f(t,x,y), where x and y are vectors
    904905       and that it returns an array or a list of same length
    905906       as x and y
     
    915916        y = ones(3, Float)           
    916917        try:
    917             q = f(x, y, 1.0)
     918            q = f(1.0, x, y)
    918919        except Exception, e:
    919920            msg = 'Function %s could not be executed:\n%s' %(f, e)
     
    943944
    944945class Wind_stress:
    945     """Apply wind stress to water momentum
     946    """Apply wind stress to water momentum in terms of
     947    wind speed [m/s] and wind direction [degrees]   
    946948    """
    947949
     
    959961        map from True north to grid north.
    960962
    961         Arguments can also be Python functions of x,y,t as in
    962 
    963         def speed(x,y,t):
     963        Arguments can also be Python functions of t,x,y as in
     964
     965        def speed(t,x,y):
    964966            ...
    965967            return s
    966968       
    967         def angle(x,y,t):
     969        def angle(t,x,y):
    968970            ...
    969971            return phi
     
    978980        forcing_terms as in
    979981
     982        Alternatively, one vector valued function for (speed, angle)
     983        can be applied, providing both quantities simultaneously.
     984        FIXME: Not yet implemented
     985
    980986        domain.forcing_terms.append(W)
    981        
    982987        """
    983988
     
    10061011        if callable(self.speed):
    10071012            xc = domain.get_centroid_coordinates()           
    1008             s_vec = self.speed(xc[:,0], xc[:,1], t)
     1013            s_vec = self.speed(t, xc[:,0], xc[:,1])
    10091014        else:
    10101015            #Assume s is a scalar
     
    10191024        if callable(self.phi):
    10201025            xc = domain.get_centroid_coordinates()           
    1021             phi_vec = self.phi(xc[:,0], xc[:,1], t)
     1026            phi_vec = self.phi(t, xc[:,0], xc[:,1])
    10221027        else:
    10231028            #Assume phi is a scalar
     
    10571062        ymom_update[k] += S*v       
    10581063           
    1059 
    1060 class Wind_stress_from_file:
    1061     """Apply wind stress read from a file to water momentum
    1062 
    1063     At this stage the wind field is assumed to depend on time only, i.e
    1064     no spatial dependency.
    1065    
    1066     FIXME: This class may be incorporated in the generic Wind_stress class
    1067     Superseded
    1068     """
    1069 
    1070    
    1071     def __init__(self, filename):
    1072         """Initialise windfield from a file with the following format
    1073 
    1074         time [DD/MM/YY hh:mm:ss], speed [m/s] direction [degrees]
    1075        
    1076         e.g.
    1077        
    1078         03/09/04 19:15:00, 9.53 39
    1079        
    1080         domain.forcing_terms.append(W)
    1081        
    1082         """
    1083 
    1084         import time
    1085         from Numeric import array
    1086         from config import time_format
    1087 
    1088 
    1089         from config import rho_a, rho_w, eta_w
    1090         self.const = eta_w*rho_a/rho_w
    1091        
    1092 
    1093         try:
    1094             fid = open(filename)
    1095         except Exception, e:
    1096             msg = 'Wind stress file %s could not be opened: %s\n'\
    1097                   %(filename, e)
    1098             raise msg
    1099 
    1100 
    1101         line = fid.readline()
    1102         fid.close()
    1103         fields = line.split(',')
    1104         msg = 'File %s must have the format date, values'
    1105         assert len(fields) == 2, msg
    1106 
    1107         try:
    1108             starttime = time.mktime(time.strptime(fields[0], time_format))
    1109         except ValueError:   
    1110             msg = 'First field in file %s must be' %filename
    1111             msg += ' date-time with format %s.\n' %time_format
    1112             msg += 'I got %s instead.' %fields[0]
    1113             raise msg
    1114 
    1115         #Split values
    1116         values = []
    1117         for value in fields[1].split():
    1118             values.append(float(value))
    1119 
    1120         q = array(values)
    1121        
    1122         msg = 'ERROR: File function must return a 1d list or array '
    1123         assert len(q.shape) == 1, msg
    1124            
    1125 
    1126         msg = 'Values specified in file must convert to an array of length 2'
    1127         assert len(q) == 2, msg
    1128 
    1129         self.filename = filename
    1130         self.domain = domain
    1131         self.starttime = starttime
    1132 
    1133 
    1134         if domain.starttime is None:
    1135             domain.starttime = starttime
    1136         else:
    1137             msg = 'Start time as specified in domain (%s) is earlier '
    1138             'than the starttime of file %s: %s'\
    1139                   %(domain.starttime, self.filename, self.starttime)
    1140             if self.starttime > domain.starttime:
    1141                 raise msg
    1142 
    1143 
    1144         self.read_times() #Now read all times in.
    1145 
    1146        
    1147     def read_times(self):
    1148         from Numeric import zeros, Float, alltrue
    1149         from config import time_format
    1150         import time
    1151        
    1152         fid = open(self.filename)       
    1153         lines = fid.readlines()
    1154         fid.close()
    1155        
    1156         N = len(lines)
    1157 
    1158         T = zeros(N, Float)       #Time
    1159         Q = zeros((N, 2), Float)  #Wind field (s, phi)
    1160        
    1161         for i, line in enumerate(lines):
    1162             fields = line.split(',')
    1163             real_time = time.mktime(time.strptime(fields[0], time_format))
    1164 
    1165             T[i] = real_time - self.start_time
    1166 
    1167             for j, value in enumerate(fields[1].split()):
    1168                 Q[i, j] = float(value)
    1169 
    1170         msg = 'File %s must list time as a monotonuosly ' %self.filename
    1171         msg += 'increasing sequence'
    1172         assert alltrue( T[1:] - T[:-1] > 0 ), msg
    1173 
    1174         self.T = T     #Time
    1175         self.Q = Q     #Windfied
    1176         self.index = 0 #Initial index
    1177 
    1178        
    1179     def __repr__(self):
    1180         return 'Wind field from file'
    1181 
    1182        
    1183 
    1184     def __call__(self, domain):
    1185         """Evaluate windfield based on values found in domain
    1186         """
    1187 
    1188         from math import pi, cos, sin, sqrt
    1189        
    1190         xmom_update = domain.quantities['xmomentum'].explicit_update
    1191         ymom_update = domain.quantities['ymomentum'].explicit_update   
    1192        
    1193         N = domain.number_of_elements
    1194         t = self.domain.time
    1195        
    1196         msg = 'Time given in File %s does not match model time'\
    1197               %self.filename
    1198        
    1199         if t < self.T[0]: raise msg
    1200         if t > self.T[-1]: raise msg       
    1201 
    1202         oldindex = self.index
    1203 
    1204         #Find slot
    1205         while t > self.T[self.index]: self.index += 1
    1206         while t < self.T[self.index]: self.index -= 1
    1207 
    1208         #t is now between index and index+1
    1209         ratio = (t - self.T[self.index])/\
    1210                 (self.T[self.index+1] - self.T[self.index])
    1211 
    1212         #Compute interpolated values for s and phi
    1213         q = self.Q[self.index,:] +\
    1214             ratio*(self.Q[self.index+1,:] - self.Q[self.index,:])
    1215 
    1216         s = q[0]
    1217        
    1218         #Convert to radians
    1219         phi = q[1]*pi/180
    1220        
    1221         #Compute velocity vector (u, v)
    1222         u = s*cos(phi)
    1223         v = s*sin(phi)
    1224 
    1225         #Compute wind stress for this time step
    1226         S = self.const * sqrt(u**2 + v**2)
    1227         xmom_update += S*u
    1228         ymom_update += S*v       
    1229        
    1230 
    1231 
    12321064
    12331065
Note: See TracChangeset for help on using the changeset viewer.