Changeset 623 for inundation/ga/storm_surge/pyvolution/shallow_water.py
- Timestamp:
- Nov 24, 2004, 4:43:40 PM (20 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
inundation/ga/storm_surge/pyvolution/shallow_water.py
r620 r623 518 518 """ 519 519 520 #FIXME: Experimental 520 #FIXME: Experimental (from old version). Not in use at the moment 521 521 522 522 #Shortcuts … … 560 560 xmomc[k] = ymomc[k] = 0.0 561 561 562 #FIXME: Delete 562 563 #From 'newstyle 563 564 #if hc[k] < domain.minimum_allowed_height: … … 901 902 def check_forcefield(f): 902 903 """Check that f is either 903 1: a callable object of x,y,t, where x and y are vectors904 1: a callable object f(t,x,y), where x and y are vectors 904 905 and that it returns an array or a list of same length 905 906 as x and y … … 915 916 y = ones(3, Float) 916 917 try: 917 q = f( x, y, 1.0)918 q = f(1.0, x, y) 918 919 except Exception, e: 919 920 msg = 'Function %s could not be executed:\n%s' %(f, e) … … 943 944 944 945 class 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] 946 948 """ 947 949 … … 959 961 map from True north to grid north. 960 962 961 Arguments can also be Python functions of x,y,tas in962 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): 964 966 ... 965 967 return s 966 968 967 def angle( x,y,t):969 def angle(t,x,y): 968 970 ... 969 971 return phi … … 978 980 forcing_terms as in 979 981 982 Alternatively, one vector valued function for (speed, angle) 983 can be applied, providing both quantities simultaneously. 984 FIXME: Not yet implemented 985 980 986 domain.forcing_terms.append(W) 981 982 987 """ 983 988 … … 1006 1011 if callable(self.speed): 1007 1012 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]) 1009 1014 else: 1010 1015 #Assume s is a scalar … … 1019 1024 if callable(self.phi): 1020 1025 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]) 1022 1027 else: 1023 1028 #Assume phi is a scalar … … 1057 1062 ymom_update[k] += S*v 1058 1063 1059 1060 class Wind_stress_from_file:1061 """Apply wind stress read from a file to water momentum1062 1063 At this stage the wind field is assumed to depend on time only, i.e1064 no spatial dependency.1065 1066 FIXME: This class may be incorporated in the generic Wind_stress class1067 Superseded1068 """1069 1070 1071 def __init__(self, filename):1072 """Initialise windfield from a file with the following format1073 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 391079 1080 domain.forcing_terms.append(W)1081 1082 """1083 1084 import time1085 from Numeric import array1086 from config import time_format1087 1088 1089 from config import rho_a, rho_w, eta_w1090 self.const = eta_w*rho_a/rho_w1091 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 msg1099 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, msg1106 1107 try:1108 starttime = time.mktime(time.strptime(fields[0], time_format))1109 except ValueError:1110 msg = 'First field in file %s must be' %filename1111 msg += ' date-time with format %s.\n' %time_format1112 msg += 'I got %s instead.' %fields[0]1113 raise msg1114 1115 #Split values1116 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, msg1124 1125 1126 msg = 'Values specified in file must convert to an array of length 2'1127 assert len(q) == 2, msg1128 1129 self.filename = filename1130 self.domain = domain1131 self.starttime = starttime1132 1133 1134 if domain.starttime is None:1135 domain.starttime = starttime1136 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 msg1142 1143 1144 self.read_times() #Now read all times in.1145 1146 1147 def read_times(self):1148 from Numeric import zeros, Float, alltrue1149 from config import time_format1150 import time1151 1152 fid = open(self.filename)1153 lines = fid.readlines()1154 fid.close()1155 1156 N = len(lines)1157 1158 T = zeros(N, Float) #Time1159 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_time1166 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.filename1171 msg += 'increasing sequence'1172 assert alltrue( T[1:] - T[:-1] > 0 ), msg1173 1174 self.T = T #Time1175 self.Q = Q #Windfied1176 self.index = 0 #Initial index1177 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 domain1186 """1187 1188 from math import pi, cos, sin, sqrt1189 1190 xmom_update = domain.quantities['xmomentum'].explicit_update1191 ymom_update = domain.quantities['ymomentum'].explicit_update1192 1193 N = domain.number_of_elements1194 t = self.domain.time1195 1196 msg = 'Time given in File %s does not match model time'\1197 %self.filename1198 1199 if t < self.T[0]: raise msg1200 if t > self.T[-1]: raise msg1201 1202 oldindex = self.index1203 1204 #Find slot1205 while t > self.T[self.index]: self.index += 11206 while t < self.T[self.index]: self.index -= 11207 1208 #t is now between index and index+11209 ratio = (t - self.T[self.index])/\1210 (self.T[self.index+1] - self.T[self.index])1211 1212 #Compute interpolated values for s and phi1213 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 radians1219 phi = q[1]*pi/1801220 1221 #Compute velocity vector (u, v)1222 u = s*cos(phi)1223 v = s*sin(phi)1224 1225 #Compute wind stress for this time step1226 S = self.const * sqrt(u**2 + v**2)1227 xmom_update += S*u1228 ymom_update += S*v1229 1230 1231 1232 1064 1233 1065
Note: See TracChangeset
for help on using the changeset viewer.