Changeset 566
- Timestamp:
- Nov 16, 2004, 4:52:21 PM (20 years ago)
- Location:
- inundation/ga/storm_surge/pyvolution
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
inundation/ga/storm_surge/pyvolution/config.py
r449 r566 40 40 41 41 42 eta_w = 3.0e-3 #Wind stress coefficient 43 rho_a = 1.2e-3 #Atmospheric density 44 rho_w = 1023 #Fluid density [kg/m^3] (rho_w = 1023 for salt water) 45 46 47 48 49 42 50 43 51 beta = 0.9 #]0;1] (e.g. 0.9). 1 allows the steepest gradients, -
inundation/ga/storm_surge/pyvolution/domain.py
r546 r566 64 64 self.time = 0.0 65 65 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 67 68 68 69 #Checkpointing -
inundation/ga/storm_surge/pyvolution/generic_boundary_conditions.py
r527 r566 143 143 fid.close() 144 144 fields = line.split(',') 145 msg = ' Boundary file %s must have the format date, values'145 msg = 'File %s must have the format date, values' 146 146 assert len(fields) == 2, msg 147 147 148 148 try: 149 start _time = time.mktime(time.strptime(fields[0], time_format))149 starttime = time.mktime(time.strptime(fields[0], time_format)) 150 150 except ValueError: 151 msg = 'First field in boundaryfile %s must be' %filename151 msg = 'First field in file %s must be' %filename 152 152 msg += ' date-time with format %s.\n' %time_format 153 153 msg += 'I got %s instead.' %fields[0] … … 170 170 self.filename = filename 171 171 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 174 183 self.read_time_boundary() #Now read all times in. 175 184 … … 195 204 real_time = time.mktime(time.strptime(fields[0], time_format)) 196 205 197 T[i] = real_time - self.start _time206 T[i] = real_time - self.starttime 198 207 199 208 … … 201 210 Q[i, j] = float(value) 202 211 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 204 215 assert alltrue( T[1:] - T[:-1] > 0 ), msg 205 216 … … 233 244 234 245 #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,:]) 238 251 239 252 -
inundation/ga/storm_surge/pyvolution/pressure_force.py
r552 r566 48 48 49 49 def cyclone(domain): 50 rho = 1023 #Fluid density [kg/m^3] #FIXME: Move to config object50 from config import rho_w 51 51 from util import gradient 52 52 … … 72 72 73 73 #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 76 76 77 77 -
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.