Changeset 566 for inundation/ga/storm_surge/pyvolution/shallow_water.py
- Timestamp:
- Nov 16, 2004, 4:52:21 PM (20 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
inundation/ga/storm_surge/pyvolution/shallow_water.py
r558 r566 937 937 """ 938 938 939 from config import rho_a, rho_w, eta_w 940 939 941 self.s = s 940 942 self.phi = phi 941 943 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 948 945 949 946 … … 1007 1004 1008 1005 1006 1007 class 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 1009 1177 1010 1178
Note: See TracChangeset
for help on using the changeset viewer.