def solve(self, T = None, tol = None, nl_tol = 1e-5): def time_finish(t): if T: if t >= T: return True return False def converged(du): if tol: if du < tol: return True return False tic() delta = 1e10 while not (time_finish(self.t) or converged(delta)): # ADAPTIVE TIMESTEP if self.adapt_timestep and (self.t > 0.0 or self.adapt_initial_timestep): solve(self.a_k == self.L_k, self.k) self.timestep = self.k.vector().array()[0] # SOLVE COUPLED EQUATIONS # solve(self.F == 0, self.w[0], bcs=self.bc, solver_parameters=solver_parameters) solve(self.F == 0, self.w[0], bcs=self.bc, J=self.J, solver_parameters=solver_parameters) if tol: delta = 0.0 f_list = [[self.w[0].split()[i], self.w[1].split()[i]] for i in range(len(self.w[0].split()))] for f_0, f_1 in f_list: delta = max(errornorm(f_0, f_1, norm_type="L2", degree_rise=1)/self.timestep, delta) self.w[1].assign(self.w[0]) self.t += self.timestep # display results if self.plot: if self.t > self.plot_t: self.plotter.update_plot(self) self.plot_t += self.plot # save data if self.write: if self.t > self.write_t: sw_io.write_model_to_files(self, 'a', file=self.save_loc) self.write_t += self.write # write timestep info sw_io.print_timestep_info(self, delta) print "\n* * * Initial forward run finished: time taken = {}".format(toc()) list_timings(True) if self.plot: self.plotter.clean_up()
def solve(self, T = None, tol = None, nl_tol = 1e-5): def time_finish(t): if T: if t >= T: return True return False def converged(du): if tol: if du < tol: return True return False tic() delta = 1e10 while not (time_finish(self.t) or converged(delta)): # ADAPTIVE TIMESTEP if self.adapt_timestep and (self.t > 0.0 or self.adapt_initial_timestep): solve(self.a_k == self.L_k, self.k) self.timestep = self.k.vector().array()[0] # M = assemble(self.J) # U, s, Vh = scipy.linalg.svd(M.array()) # cond = s.max()/s.min() # print cond, s.min(), s.max() # SOLVE COUPLED EQUATIONS if self.time_discretise.im_func == runge_kutta: # store previous solution self.w[2].assign(self.w[1]) # runge kutta timestep solve(self.F == 0, self.w[0], bcs=self.bc, J=self.J, solver_parameters=solver_parameters) if self.slope_limiter: self.slope_limit() # # 2nd order # self.w[1].assign(self.w[0]) # solve(self.F_RK == 0, self.w[0], bcs=self.bc, J=self.J_RK, # solver_parameters=solver_parameters) # 3rd order self.w[1].assign(self.w[0]) solve(self.F_RK1 == 0, self.w[0], bcs=self.bc, J=self.J_RK1, solver_parameters=solver_parameters) if self.slope_limiter: self.slope_limit() self.w[1].assign(self.w[0]) solve(self.F_RK2 == 0, self.w[0], bcs=self.bc, J=self.J_RK2, solver_parameters=solver_parameters) # replace previous solution self.w[1].assign(self.w[2]) else: solve(self.F == 0, self.w[0], bcs=self.bc, J=self.J, solver_parameters=solver_parameters) if self.slope_limiter: self.slope_limit() if tol: delta = 0.0 f_list = [[self.w[0].split()[i], self.w[1].split()[i]] for i in range(len(self.w[0].split()))] for f_0, f_1 in f_list: delta = max(errornorm(f_0, f_1, norm_type="L2", degree_rise=1)/self.timestep, delta) self.w[1].assign(self.w[0]) self.t += self.timestep # display results if self.plot: if self.t > self.plot_t: self.plotter.update_plot(self) self.plot_t += self.plot # save data if self.write: if self.t > self.write_t: sw_io.write_model_to_files(self, 'a', file=self.save_loc) self.write_t += self.write # write timestep info sw_io.print_timestep_info(self, delta) print "\n* * * Initial forward run finished: time taken = {}".format(toc()) list_timings(True) if self.plot: self.plotter.clean_up() # error calc callback if self.error_callback: return self.error_callback(self)
def setup(self, h_ic = None, phi_ic = None, q_a = Constant(0.0), q_pa = Constant(0.0), q_pb = Constant(1.0), w_ic = None, zero_q = False, similarity = False, dam_break = False): # q_a between 0.0 and 1.0 # q_pa between 0.2 and 0.99 # q_pb between 1.0 and # define constants self.Fr = Constant(self.Fr_, name="Fr") self.beta = Constant(self.beta_, name="beta") if type(w_ic) == type(None): # define initial conditions if type(h_ic) == type(None): h_ic = 1.0 h_N = 1.0 # h_ic = Function(self.h_FS, name='h_ic') # trial = TrialFunction(self.h_FS) # test = TestFunction(self.h_FS) # a = inner(test, trial)*dx # q_b = Constant(1.0) - q_a # f = (1.0 - (q_a*cos(((self.X/self.L)**q_pa)*np.pi) + q_b*cos(((self.X/self.L)**q_pb)*np.pi)))/2.0 # L = inner(test, f + Constant(1e-1))*dx # solve(a == L, h_ic) # h_N = h_ic.vector().array()[-1] else: h_N = h_ic.vector().array()[-1] if type(phi_ic) == type(None): # phi_ic = 1.0 # phi_N = 1.0 phi_ic = Function(self.phi_FS, name='phi_ic') trial = TrialFunction(self.phi_FS) test = TestFunction(self.phi_FS) a = inner(test, trial)*dx q_b = Constant(1.0) - q_a f = (1.0 - (q_a*cos(((self.X/self.L)**q_pa)*np.pi) + q_b*cos(((self.X/self.L)**q_pb)*np.pi)))/2.0 L = inner(test, f + Constant(1e-3))*dx solve(a == L, phi_ic) phi_N = phi_ic.vector().array()[-1] else: phi_N = phi_ic.vector().array()[-1] # calculate u_N component trial = TrialFunction(self.var_N_FS) test = TestFunction(self.var_N_FS) u_N_ic = Function(self.var_N_FS, name='u_N_ic') a = inner(test, trial)*self.ds(1) L = inner(test, self.Fr*phi_ic**0.5)*self.ds(1) solve(a == L, u_N_ic) # define q q_N_ic = Function(self.var_N_FS, name='q_N_ic') q_ic = Function(self.q_FS, name='q_ic') # cosine initial condition for u if not zero_q: a = inner(test, trial)*self.ds(1) L = inner(test, u_N_ic*h_ic)*self.ds(1) solve(a == L, q_N_ic) trial = TrialFunction(self.q_FS) test = TestFunction(self.q_FS) a = inner(test, trial)*dx q_b = Constant(1.0) - q_a f = (1.0 - (q_a*cos(((self.X/self.L)**q_pa)*np.pi) + q_b*cos(((self.X/self.L)**q_pb)*np.pi)))/2.0 L = inner(test, f*q_N_ic)*dx solve(a == L, q_ic) # create ic array self.w_ic = [ q_ic, h_ic, phi_ic, Function(self.phi_d_FS, name='phi_d_ic'), self.x_N_, u_N_ic ] else: # whole of w_ic defined externally self.w_ic = w_ic # define bc's bcphi_d = DirichletBC(self.W.sub(3), '0.0', "near(x[0], 1.0) && on_boundary") bcq = DirichletBC(self.W.sub(0), '0.0', "near(x[0], 0.0) && on_boundary") self.bc = [bcq, bcphi_d] self.generate_form() # initialise plotting if self.plot: self.plotter = sw_io.Plotter(self, rescale=True, file=self.save_loc, similarity = similarity, dam_break = dam_break) self.plot_t = self.plot # write ic's if self.write: sw_io.clear_model_files(file=self.save_loc) sw_io.write_model_to_files(self, 'a', file=self.save_loc) self.write_t = self.write