def WindStressParams(type=99, # "no wind" \ tau0=0, rho=0, alpha=0, xm=0, Rc=0, \ x0=0, y0=0, \ u0=0, v0=0, \ wind_speed=0, wind_direction=0): """ Backward compatibility function to avoid rewriting old code and notebooks. SHOULD NOT BE USED IN NEW CODE! Make WindStress object directly instead. """ type_ = np.int32(type) tau0_ = np.float32(tau0) rho_ = np.float32(rho) rho_air_ = np.float32(1.3) # new parameter alpha_ = np.float32(alpha) xm_ = np.float32(xm) Rc_ = np.float32(Rc) x0_ = np.float32(x0) y0_ = np.float32(y0) u0_ = np.float32(u0) v0_ = np.float32(v0) wind_speed_ = np.float32(wind_speed) wind_direction_ = np.float32(wind_direction) if type == 0: wind_stress = WindStress.UniformAlongShoreWindStress( \ tau0=tau0_, rho=rho_, alpha=alpha_) elif type == 1: wind_stress = WindStress.BellShapedAlongShoreWindStress( \ xm=xm_, tau0=tau0_, rho=rho_, alpha=alpha_) elif type == 2: wind_stress = WindStress.MovingCycloneWindStress( \ Rc=Rc_, x0=x0_, y0=y0_, u0=u0_, v0=v0_) elif type == 50: wind_stress = WindStress.GenericUniformWindStress( \ rho_air=rho_air_, wind_speed=wind_speed_, wind_direction=wind_direction_) elif type == 99: wind_stress = WindStress.NoWindStress() else: raise RuntimeError('Invalid wind stress type!') return wind_stress
def step(self, t_end=0.0, apply_stochastic_term=True, write_now=True, update_dt=False): """ Function which steps n timesteps. apply_stochastic_term: Boolean value for whether the stochastic perturbation (if any) should be applied. """ if self.t == 0: self.bc_kernel.update_bc_values(self.gpu_stream, self.t) self.bc_kernel.boundaryCondition(self.gpu_stream, \ self.gpu_data.h0, self.gpu_data.hu0, self.gpu_data.hv0) t_now = 0.0 while (t_now < t_end): #for i in range(0, n): # Get new random wind direction (emulationg large-scale model error) if(self.max_wind_direction_perturbation > 0.0 and self.wind_stress.type() == 1): # max perturbation +/- max_wind_direction_perturbation deg within original wind direction (at t=0) perturbation = 2.0*(np.random.rand()-0.5) * self.max_wind_direction_perturbation; new_wind_stress = WindStress.GenericUniformWindStress( \ rho_air=self.wind_stress.rho_air, \ wind_speed=self.wind_stress.wind_speed, \ wind_direction=self.wind_stress.wind_direction + perturbation) # Upload new wind stress params to device cuda.memcpy_htod_async(int(self.wind_stress_dev), new_wind_stress.tostruct(), stream=self.gpu_stream) # Calculate dt if using automatic dt if (self.dt <= 0 or update_dt): self.updateDt() local_dt = np.float32(min(self.dt, np.float32(t_end - t_now))) wind_stress_t = np.float32(self.update_wind_stress(self.kernel, self.cdklm_swe_2D)) self.bc_kernel.update_bc_values(self.gpu_stream, self.t) #self.bc_kernel.boundaryCondition(self.cl_queue, \ # self.gpu_data.h1, self.gpu_data.hu1, self.gpu_data.hv1) # 2nd order Runge Kutta if (self.rk_order == 2): self.callKernel(self.gpu_data.h0, self.gpu_data.hu0, self.gpu_data.hv0, \ self.gpu_data.h1, self.gpu_data.hu1, self.gpu_data.hv1, \ local_dt, wind_stress_t, 0) self.bc_kernel.boundaryCondition(self.gpu_stream, \ self.gpu_data.h1, self.gpu_data.hu1, self.gpu_data.hv1) self.callKernel(self.gpu_data.h1, self.gpu_data.hu1, self.gpu_data.hv1, \ self.gpu_data.h0, self.gpu_data.hu0, self.gpu_data.hv0, \ local_dt, wind_stress_t, 1) # Applying final boundary conditions after perturbation (if applicable) elif (self.rk_order == 1): self.callKernel(self.gpu_data.h0, self.gpu_data.hu0, self.gpu_data.hv0, \ self.gpu_data.h1, self.gpu_data.hu1, self.gpu_data.hv1, \ local_dt, wind_stress_t, 0) self.gpu_data.swap() # Applying boundary conditions after perturbation (if applicable) # 3rd order RK method: elif (self.rk_order == 3): self.callKernel(self.gpu_data.h0, self.gpu_data.hu0, self.gpu_data.hv0, \ self.gpu_data.h1, self.gpu_data.hu1, self.gpu_data.hv1, \ local_dt, wind_stress_t, 0) self.bc_kernel.boundaryCondition(self.gpu_stream, \ self.gpu_data.h1, self.gpu_data.hu1, self.gpu_data.hv1) self.callKernel(self.gpu_data.h1, self.gpu_data.hu1, self.gpu_data.hv1, \ self.gpu_data.h0, self.gpu_data.hu0, self.gpu_data.hv0, \ local_dt, wind_stress_t, 1) self.bc_kernel.boundaryCondition(self.gpu_stream, \ self.gpu_data.h1, self.gpu_data.hu1, self.gpu_data.hv1) self.callKernel(self.gpu_data.h1, self.gpu_data.hu1, self.gpu_data.hv1, \ self.gpu_data.h0, self.gpu_data.hu0, self.gpu_data.hv0, \ local_dt, wind_stress_t, 2) # Applying final boundary conditions after perturbation (if applicable) # Perturb ocean state with model error if self.small_scale_perturbation and apply_stochastic_term: self.small_scale_model_error.perturbSim(self) # Apply boundary conditions self.bc_kernel.boundaryCondition(self.gpu_stream, \ self.gpu_data.h0, self.gpu_data.hu0, self.gpu_data.hv0) # Evolve drifters if self.hasDrifters: self.drifters.drift(self.gpu_data.h0, self.gpu_data.hu0, \ self.gpu_data.hv0, \ np.float32(self.constant_equilibrium_depth), \ self.nx, self.ny, self.dx, self.dy, \ local_dt, \ np.int32(2), np.int32(2)) self.t += np.float64(local_dt) t_now += np.float64(local_dt) self.num_iterations += 1 if self.write_netcdf and write_now: self.sim_writer.writeTimestep(self) return self.t