Exemple #1
0
    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)
Exemple #4
0
    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()