Changeset 566


Ignore:
Timestamp:
Nov 16, 2004, 4:52:21 PM (19 years ago)
Author:
ole
Message:

First stab at wind stress from file

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

Legend:

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

    r449 r566  
    4040
    4141
     42eta_w = 3.0e-3 #Wind stress coefficient
     43rho_a = 1.2e-3 #Atmospheric density
     44rho_w = 1023   #Fluid density [kg/m^3] (rho_w = 1023 for salt water)
     45
     46       
     47
     48
     49
    4250
    4351beta = 0.9  #]0;1] (e.g. 0.9). 1 allows the steepest gradients,
  • inundation/ga/storm_surge/pyvolution/domain.py

    r546 r566  
    6464        self.time = 0.0
    6565        self.finaltime = None
    66         self.min_timestep = self.max_timestep = 0.0       
     66        self.min_timestep = self.max_timestep = 0.0
     67        self.starttime = None
    6768       
    6869        #Checkpointing         
  • inundation/ga/storm_surge/pyvolution/generic_boundary_conditions.py

    r527 r566  
    143143        fid.close()
    144144        fields = line.split(',')
    145         msg = 'Boundary file %s must have the format date, values'
     145        msg = 'File %s must have the format date, values'
    146146        assert len(fields) == 2, msg
    147147
    148148        try:
    149             start_time = time.mktime(time.strptime(fields[0], time_format))
     149            starttime = time.mktime(time.strptime(fields[0], time_format))
    150150        except ValueError:   
    151             msg = 'First field in boundary file %s must be' %filename
     151            msg = 'First field in file %s must be' %filename
    152152            msg += ' date-time with format %s.\n' %time_format
    153153            msg += 'I got %s instead.' %fields[0]
     
    170170        self.filename = filename
    171171        self.domain = domain
    172         self.start_time = start_time
    173 
     172        self.starttime = starttime
     173
     174        if domain.starttime is None:
     175            domain.starttime = starttime
     176        else:
     177            msg = 'Start time as specified in domain (%s) is earlier '
     178            'than the starttime of file %s: %s'\
     179                  %(domain.starttime, self.filename, self.starttime)
     180            if self.starttime > domain.starttime:
     181                raise msg
     182       
    174183        self.read_time_boundary() #Now read all times in.
    175184       
     
    195204            real_time = time.mktime(time.strptime(fields[0], time_format))
    196205
    197             T[i] = real_time - self.start_time
     206            T[i] = real_time - self.starttime
    198207
    199208           
     
    201210                Q[i, j] = float(value)
    202211
    203         msg = 'Time boundary must list time as a monotonuosly increasing sequence'         
     212        msg = 'Time boundary must list time as a monotonuosly '
     213        msg += 'increasing sequence'
     214       
    204215        assert alltrue( T[1:] - T[:-1] > 0 ), msg
    205216
     
    233244       
    234245        #t is now between index and index+1
    235         ratio = (t - self.T[self.index])/(self.T[self.index+1] - self.T[self.index])
    236 
    237         return self.Q[self.index,:] + ratio*(self.Q[self.index+1,:] - self.Q[self.index,:])
     246        ratio = (t - self.T[self.index])/\
     247                (self.T[self.index+1] - self.T[self.index])
     248
     249        return self.Q[self.index,:] +\
     250               ratio*(self.Q[self.index+1,:] - self.Q[self.index,:])
    238251
    239252
  • inundation/ga/storm_surge/pyvolution/pressure_force.py

    r552 r566  
    4848
    4949def cyclone(domain):
    50     rho = 1023  #Fluid density [kg/m^3] #FIXME: Move to config object
     50    from config import rho_w
    5151    from util import gradient
    5252
     
    7272
    7373        #Update momentum
    74         xmom[k] += -px*avg_h/rho
    75         ymom[k] += -py*avg_h/rho       
     74        xmom[k] += -px*avg_h/rho_w
     75        ymom[k] += -py*avg_h/rho_w       
    7676
    7777
  • inundation/ga/storm_surge/pyvolution/shallow_water.py

    r558 r566  
    937937        """
    938938
     939        from config import rho_a, rho_w, eta_w
     940       
    939941        self.s = s
    940942        self.phi = phi
    941943
    942         #FIXME: Maybe move to config or read from domain
    943         Cw = 3.0e-3 #Wind stress coefficient
    944         rho_a = 1.2e-3 #Atmospheric density
    945         rho = 1023 #Density of water
    946        
    947         self.const = Cw*rho_a/rho
     944        self.const = eta_w*rho_a/rho_w
    948945       
    949946
     
    10071004       
    10081005       
     1006
     1007class Wind_stress_from_file:
     1008    """Apply wind stress read from a file to water momentum
     1009
     1010    At this stage the wind field is assumed to depend on time only, i.e
     1011    no spatial dependency.
     1012   
     1013    FIXME: This class may be incorporated in the generic Wind_stress class
     1014    """
     1015
     1016    def __init__(self, filename):
     1017        """Initialise windfield from a file with the following format
     1018
     1019        time [DD/MM/YY hh:mm:ss], speed [m/s] direction [degrees]
     1020       
     1021        e.g.
     1022       
     1023        03/09/04 19:15:00, 9.53 39
     1024       
     1025        domain.forcing_terms.append(W)
     1026       
     1027        """
     1028
     1029        import time
     1030        from Numeric import array
     1031        from config import time_format
     1032
     1033
     1034        from config import rho_a, rho_w, eta_w
     1035        self.const = eta_w*rho_a/rho_w
     1036       
     1037
     1038        try:
     1039            fid = open(filename)
     1040        except Exception, e:
     1041            msg = 'Wind stress file %s could not be opened: %s\n'\
     1042                  %(filename, e)
     1043            raise msg
     1044
     1045
     1046        line = fid.readline()
     1047        fid.close()
     1048        fields = line.split(',')
     1049        msg = 'File %s must have the format date, values'
     1050        assert len(fields) == 2, msg
     1051
     1052        try:
     1053            starttime = time.mktime(time.strptime(fields[0], time_format))
     1054        except ValueError:   
     1055            msg = 'First field in file %s must be' %filename
     1056            msg += ' date-time with format %s.\n' %time_format
     1057            msg += 'I got %s instead.' %fields[0]
     1058            raise msg
     1059
     1060        #Split values
     1061        values = []
     1062        for value in fields[1].split():
     1063            values.append(float(value))
     1064
     1065        q = array(values)
     1066       
     1067        msg = 'ERROR: File function must return a 1d list or array '
     1068        assert len(q.shape) == 1, msg
     1069           
     1070
     1071        msg = 'Values specified in file must convert to an array of length 2'
     1072        assert len(q) == 2, msg
     1073
     1074        self.filename = filename
     1075        self.domain = domain
     1076        self.starttime = starttime
     1077
     1078
     1079        if domain.starttime is None:
     1080            domain.starttime = starttime
     1081        else:
     1082            msg = 'Start time as specified in domain (%s) is earlier '
     1083            'than the starttime of file %s: %s'\
     1084                  %(domain.starttime, self.filename, self.starttime)
     1085            if self.starttime > domain.starttime:
     1086                raise msg
     1087
     1088
     1089        self.read_times() #Now read all times in.
     1090
     1091       
     1092    def read_times(self):
     1093        from Numeric import zeros, Float, alltrue
     1094        from config import time_format
     1095        import time
     1096       
     1097        fid = open(self.filename)       
     1098        lines = fid.readlines()
     1099        fid.close()
     1100       
     1101        N = len(lines)
     1102
     1103        T = zeros(N, Float)       #Time
     1104        Q = zeros((N, 2), Float)  #Wind field (s, phi)
     1105       
     1106        for i, line in enumerate(lines):
     1107            fields = line.split(',')
     1108            real_time = time.mktime(time.strptime(fields[0], time_format))
     1109
     1110            T[i] = real_time - self.start_time
     1111
     1112            for j, value in enumerate(fields[1].split()):
     1113                Q[i, j] = float(value)
     1114
     1115        msg = 'File %s must list time as a monotonuosly ' %self.filename
     1116        msg += 'increasing sequence'
     1117        assert alltrue( T[1:] - T[:-1] > 0 ), msg
     1118
     1119        self.T = T     #Time
     1120        self.Q = Q     #Windfied
     1121        self.index = 0 #Initial index
     1122
     1123       
     1124    def __repr__(self):
     1125        return 'Wind field from file'
     1126
     1127       
     1128
     1129    def __call__(self, domain):
     1130        """Evaluate windfield based on values found in domain
     1131        """
     1132
     1133        from math import pi, cos, sin, sqrt
     1134       
     1135        xmom_update = domain.quantities['xmomentum'].explicit_update
     1136        ymom_update = domain.quantities['ymomentum'].explicit_update   
     1137       
     1138        N = domain.number_of_elements
     1139        t = self.domain.time
     1140       
     1141        msg = 'Time given in File %s does not match model time'\
     1142              %self.filename
     1143       
     1144        if t < self.T[0]: raise msg
     1145        if t > self.T[-1]: raise msg       
     1146
     1147        oldindex = self.index
     1148
     1149        #Find slot
     1150        while t > self.T[self.index]: self.index += 1
     1151        while t < self.T[self.index]: self.index -= 1
     1152
     1153        #t is now between index and index+1
     1154        ratio = (t - self.T[self.index])/\
     1155                (self.T[self.index+1] - self.T[self.index])
     1156
     1157        #Compute interpolated values for s and phi
     1158        q = self.Q[self.index,:] +\
     1159            ratio*(self.Q[self.index+1,:] - self.Q[self.index,:])
     1160
     1161        s = q[0]
     1162       
     1163        #Convert to radians
     1164        phi = q[1]*pi/180
     1165       
     1166        #Compute velocity vector (u, v)
     1167        u = s*cos(phi)
     1168        v = s*sin(phi)
     1169
     1170        #Compute wind stress for this time step
     1171        S = self.const * sqrt(u**2 + v**2)
     1172        xmom_update += S*u
     1173        ymom_update += S*v       
     1174       
     1175
     1176
    10091177
    10101178
Note: See TracChangeset for help on using the changeset viewer.