def parallel_ODE_penalty_solver(self,u,N,m): """ Solving the state equation with partitioning Arguments: * u: the control * N: Number of discritization points """ rank = self.rank T = self.T dt = float(T)/N y = interval_partition(N+1,m,rank) if rank == 0: y[0] = self.y0 j_help = 0 u = u.local_vec.copy() else: y[0] = u[-1] #### OBS!!!! #### j_help = -1 u = u.local_vec.copy() u_h = np.zeros(len(u)+1) u_h[1:]=u[:] u=u_h y_len = len(y) for j in range(y_len-1): y[j+1] = self.ODE_update(y,u,j,j,dt)#self.ODE_update(y,u,j,j+j_help,dt) self.local_end = y[-1] return y
def partition_control(self, u, N, m): new_u = [] ss, sl, _, _ = v_comm_numbers(N + 1, m) for i in range(m): ui = interval_partition(N + 1, m, i) ui[:] = u.copy()[ss[i]:ss[i] + sl[i]] new_u.append(ui) return new_u
def decompose_time(self, N, m): t = np.linspace(0, self.T, N + 1) T_z = [] for i in range(m): ti = interval_partition(N + 1, m, i) s = u_part(N + 1, m, i) for j in range(len(ti)): ti[j] = t[s + j] T_z.append(ti.copy()) return t, T_z
def p_adjoint_solver(self, variables): i = variables[0] y = variables[1] N = variables[2] m = variables[3] mu = variables[4] u = variables[5] dt = float(self.T) / N l = interval_partition(N + 1, m, i) if i == m - 1: l[-1] = self.initial_adjoint(y[-1][-1]) else: l[-1] = self.initial_penalty(y, u, mu, N, i) for j in range(len(l) - 1): l[-(j + 2)] = self.adjoint_update(l, y[i], j, dt) return l
def parallel_adjoint_penalty_solver(self,u,N,m,mu): """ Solving the adjoint equation using finite difference, and partitioning the time interval. Arguments: * u: the control * N: Number of discritization points * m: Number of intervals we partition time in """ comm = self.comm T = self.T y0 = self.y0 dt = float(T)/N yT = self.yT rank = self.rank l = interval_partition(N+1,m,rank)#partition_func(N+1,m) y= self.parallel_ODE_penalty_solver(u,N,m) if rank == m-1: comm.send(y[0],dest=rank-1) lam = None elif rank!=0: lam = comm.recv(source=rank+1) comm.send(y[0],dest=rank-1) else: lam = comm.recv(source=rank+1) if rank == m-1: l[-1] = self.initial_adjoint(y[-1]) else: l[-1]=self.initial_penalty(y,lam,mu,N,rank) #my*(y[i][-1]-u[N+1+i]) for j in range(len(l)-1): l[-(j+2)] = self.adjoint_update(l,y,j,dt) return l
def p_ode_solver(self, variables): i = variables[0] u = variables[1] N = variables[2] m = variables[3] dt = float(self.T) / N y = interval_partition(N + 1, m, i) if i == 0: y[0] = self.y0 else: y[0] = u[N + i] start = u_part(N + 1, m, i) for j in range(len(y) - 1): y[j + 1] = self.ODE_update(y, u, j, start + j, dt) return y