def solve(self, T = None, tol = None): 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 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): q = sw_io.map_to_arrays(model.w[0], model.map_dict)[0] self.L_k = self.k_tf*self.dX/(self.L*q.max())*self.cfl*dx solve(self.a_k == self.L_k, self.k) self.timestep = self.k.vector().array()[0] print self.timestep solve(self.F == 0, self.w[0], J=self.J, solver_parameters=solver_parameters) if self.slope_limiter: self.slope_limit() if tol: delta = 0.0 delta = errornorm(w[0], w[1], norm_type="L2", degree_rise=1)/self.timestep 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 print model.t, T, self.w[0].vector().array().min(), self.w[0].vector().array().max() if self.plot: self.plotter.clean_up()
def __call__(self, value): try: print "\n* * * Adjoint and optimiser time taken = {}".format(toc()) list_timings(True) except: pass #### initial condition dump hack #### phi_ic = value[0].vector().array() phi = phi_ic.copy() for i in range(len(model.mesh.cells())): j = i*2 phi[j] = phi_ic[-(j+2)] phi[j+1] = phi_ic[-(j+1)] phi_ic = phi sw_io.write_array_to_file('phi_ic_adj{}_latest.json'.format(job),phi_ic,'w') sw_io.write_array_to_file('phi_ic_adj{}.json'.format(job),phi_ic,'a') try: h_ic = value[1].vector().array() sw_io.write_array_to_file('h_ic_adj{}_latest.json'.format(job),h_ic,'w') sw_io.write_array_to_file('h_ic_adj{}.json'.format(job),h_ic,'a') except: pass try: q_a_ = value[2]((0,0)); q_pa_ = value[3]((0,0)); q_pb_ = value[4]((0,0)) sw_io.write_q_vals_to_file('q_ic_adj{}_latest.json'.format(job),q_a_,q_pa_,q_pb_,'w') sw_io.write_q_vals_to_file('q_ic_adj{}.json'.format(job),q_a_,q_pa_,q_pb_,'a') except: pass tic() print "\n* * * Computing forward model" func_value = (super(MyReducedFunctional, self)).__call__(value) # model.setup(h_ic = value[1], phi_ic = value[0], q_a = value[2], q_pa = value[3], q_pb = value[4]) # model.solve(T = options.T) # func_value = adjointer.evaluate_functional(self.functional, 0) print "* * * Forward model: time taken = {}".format(toc()) list_timings(True) # sys.exit() j = self.scale * func_value j_log.append(j) sw_io.write_array_to_file('j_log{}.json'.format(job), j_log, 'w') (fwd_var, output) = adjointer.get_forward_solution(adjointer.equation_count - 1) var = adjointer.get_variable_value(fwd_var) y, q, h, phi, phi_d, x_N, u_N = sw_io.map_to_arrays(var.data, model.y, model.mesh) sw_io.write_array_to_file('phi_d_adj{}_latest.json'.format(job),phi_d,'w') sw_io.write_array_to_file('phi_d_adj{}.json'.format(job),phi_d,'a') # from IPython import embed; embed() plotter.update_plot(phi_ic, phi_d, y, x_N, j) print "* * * J = {}".format(j) tic() return func_value
model.setup(zero_q = True) T = 75.0 if (options.T): T = options.T model.solve(T) elif job == 1: adjoint_setup(model) model.initialise_function_spaces() phi_ic = project(Expression('1.0 - 0.1*cos(pi*x[0])'), model.phi_FS) model.setup(phi_ic = phi_ic) y, q, h, phi, phi_d, x_N, u_N = sw_io.map_to_arrays(model.w[0], model.y, model.mesh) sw_io.write_array_to_file('phi_ic.json', phi, 'w') model.solve(T = options.T) y, q, h, phi, phi_d, x_N, u_N = sw_io.map_to_arrays(model.w[0], model.y, model.mesh) sw_io.write_array_to_file('deposit_data.json', phi_d, 'w') sw_io.write_array_to_file('runout_data.json', [x_N], 'w') elif job == 4: adjoint_setup(model) model.initialise_function_spaces() # phi_ic = project(Expression('1.0 - (0.8*cos(pow(x[0] +0.1,4.0)*pi))'), model.phi_FS) phi_ic = project(Expression('1.0'), model.phi_FS)
def slope_limit(self): # get array for variable arr = self.w[0].vector().array() q0, h0, phi0, phi_d0 = sw_io.map_to_arrays(self.w[0], self.map_dict) # solve(self.F_wb_0==0, self.wb_0) # solve(self.F_wb_1==0, self.wb_1) for i_eq in range(4): if self.disc[i_eq] == 'DG': # create storage arrays for max, min and mean values ele_dof = 2 # only for P1 DG elements (self.W.sub(i_eq).dofmap().cell_dofs(0).shape[0]) n_dof = ele_dof * len(self.mesh.cells()) u_i_max = np.ones([n_dof]) * 1e-200 u_i_min = np.ones([n_dof]) * 1e200 u_c = np.empty([len(self.mesh.cells())]) # for each vertex in the mesh store the min and max and mean values for b in range(len(self.mesh.cells())): # obtain u_c, u_min and u_max u_i = np.array([arr[index] for index in self.W.sub(i_eq).dofmap().cell_dofs(b)]) u_c[b] = u_i.mean() n1 = b*ele_dof u_i_max[n1:n1+ele_dof] = u_c[b] u_i_min[n1:n1+ele_dof] = u_c[b] if b > 0: u_j = np.array([arr[index] for index in self.W.sub(i_eq).dofmap().cell_dofs(b - 1)]) if self.slope_limiter == 'vb': u_i_max[n1] = max(u_i_max[n1], u_j.max()) u_i_min[n1] = min(u_i_min[n1], u_j.min()) elif self.slope_limiter == 'bj': u_i_max[n1] = max(u_i_max[n1], u_j.mean()) u_i_min[n1] = min(u_i_min[n1], u_j.mean()) else: sys.exit('Can only do vertex-based (vb) or Barth-Jesperson (bj) slope limiting') # elif self.E[i_eq].weak_b[0] != None: # wb = sw_io.map_to_arrays(self.wb_0, self.map_dict)[i_eq] # u_i_max[n1] = max(u_i_max[n1], wb[0]) # u_i_min[n1] = min(u_i_min[n1], wb[0]) if b + 1 < len(self.mesh.cells()): u_j = np.array([arr[index] for index in self.W.sub(i_eq).dofmap().cell_dofs(b + 1)]) if self.slope_limiter == 'vb': u_i_max[n1+1] = max(u_i_max[n1+1], u_j.max()) u_i_min[n1+1] = min(u_i_min[n1+1], u_j.min()) elif self.slope_limiter == 'bj': u_i_max[n1+1] = max(u_i_max[n1+1], u_j.mean()) u_i_min[n1+1] = min(u_i_min[n1+1], u_j.mean()) else: sys.exit('Can only do vertex-based (vb) or Barth-Jesperson (bj) slope limiting') # elif self.E[i_eq].weak_b[1] != None: # wb = sw_io.map_to_arrays(self.wb_1, self.map_dict)[i_eq] # u_i_max[n1+1] = max(u_i_max[n1], wb[0]) # u_i_min[n1+1] = min(u_i_min[n1], wb[0]) # print u_i_max # print u_i_min # print wb[0] for b in range(len(self.mesh.cells())): # calculate alpha u_i = np.array([arr[index] for index in self.W.sub(i_eq).dofmap().cell_dofs(b)]) alpha = 1.0 n1 = b*ele_dof for c in range(ele_dof): if u_i[c] - u_c[b] > 0: alpha = min(alpha, (u_i_max[n1+c] - u_c[b])/(u_i[c] - u_c[b])) if u_i[c] - u_c[b] < 0: alpha = min(alpha, (u_i_min[n1+c] - u_c[b])/(u_i[c] - u_c[b])) # apply slope limiting slope = u_i - u_c[b] indices = self.W.sub(i_eq).dofmap().cell_dofs(b) for c in range(ele_dof): arr[indices[c]] = u_c[b] + alpha*slope[c] # put array back into w[0] self.w[0].vector()[:] = arr q1, h1, phi1, phi_d1 = sw_io.map_to_arrays(self.w[0], self.map_dict)[:4] print np.abs((q1-q0)).max(), np.abs((h1-h0)).max(), np.abs((phi1-phi0)).max(), np.abs((phi_d1-phi_d0)).max()