def get_algorithm_data(self): """ Returns the order and step size used in the last successful step. """ hu, nqu, nq, nyh, nqnyh = get_lsod_common() return hu, nqu
def interpolate(self, t): """ Helper method to interpolate the solution at time t using the Nordsieck history array. Wrapper to ODEPACK's subroutine DINTDY. """ #print 'interpolate at t={} and nyh={}'.format(t,self._nyh) if self._update_nordsieck: #Nordsieck start index nordsieck_start_index = 21+3*self.problem_info["dimRoot"] - 1 hu, nqu ,nq ,nyh, nqnyh = get_lsod_common() self._nordsieck_array = \ self._RWORK[nordsieck_start_index:nordsieck_start_index+(nq+1)*nyh].reshape((nyh,-1),order='F') self._nyh = nyh self._update_nordsieck = False dky, iflag = dintdy(t, 0, self._nordsieck_array, self._nyh) if iflag!= 0 and iflag!=-2: raise ODEPACK_Exception("DINTDY returned with iflag={} (see ODEPACK documentation).".format(iflag)) elif iflag==-2: dky=self.y.copy() return dky
def integrate_start(self, t, y): """ Helper program for the initialization of LSODAR """ #print ' We have rkstarter {} and rkstarter_active {}'.format(self.rkstarter, self._rkstarter_active) if not (self.rkstarter > 1 and self._rkstarter_active): # first call or classical restart after a discontinuity ISTATE = 1 # reset work arrays RWORK = 0.0 * self._RWORK IWORK = 0.0 * self._IWORK else: #self.rkstarter and self._rkstarter_active # RK restart RWORK = self._RWORK.copy() IWORK = self._IWORK.copy() ISTATE = 2 # should be 2 dls001 = common_like() dlsr01 = common_like() # invoke rkstarter # a) get previous stepsize if any hu, nqu, nq, nyh, nqnyh = get_lsod_common() #H = hu if hu != 0. else 1.e-4 # this needs some reflections #H =(abs(RWORK[0]-t)*((self.options["rtol"])**(1/(self.rkstarter+1))))/(100*Sc.norm(self.problem.rhs(t,y,self.sw))+10)#if hu != 0. else 1.e-4 H = 1e-2 #H=self.autostart(t,y) #H=3*H # b) compute the Nordsieck array and put it into RWORK rkNordsieck = RKStarterNordsieck(self.problem.rhs, H, number_of_steps=self.rkstarter) t, nordsieck = rkNordsieck(t, y, self.sw) nordsieck = nordsieck.T nordsieck_start_index = 21 + 3 * self.problem_info["dimRoot"] - 1 RWORK[nordsieck_start_index:nordsieck_start_index+nordsieck.size] = \ nordsieck.flatten(order='F') # c) compute method coefficients and update the common blocks dls001.init = 1 #dls001.jstart = -1.0 #take the next step with a new value of H,n,meth,.. mf = 20 nq = self.rkstarter dls001.meth = meth = mf // 10 dls001.miter = mf % 10 elco, tesco = dcfode(meth) # dls001.maxord = 5 #max order dls001.nq = self.rkstarter #Next step order dls001.nqu = self.rkstarter #Method order last used (check if this is needed) dls001.meo = meth #meth dls001.nqnyh = nq * self.problem_info["dim"] #nqnyh dls001.conit = 0.5 / (nq + 2) #conit dls001.el = elco[:, nq - 1] # el0 is set internally dls001.hu = H # this sets also hold and h internally dls001.jstart = 1 # IWORK[...] = #IWORK[13]=dls001.nqu IWORK[14] = dls001.nq #IWORK[18]=dls001.meth #IWORK[7]=dlsa01.mxordn #max allowed order for Adams methods #IWORK[8]=dlsa01.mxords #max allowed order for BDF IWORK[19] = meth #the current method indicator #RWORK[...] dls001.tn = t RWORK[12] = t RWORK[10] = hu #step-size used successfully RWORK[11] = H #step-size to be attempted for the next step #RWORK[6]=dls001.hmin #RWORK[5]=dls001.hmxi number_of_fevals = N.array([1, 2, 4, 7, 11]) # d) Reset statistics IWORK[9:13] = [0] * 4 dls001.nst = 1 dls001.nfe = number_of_fevals[self.rkstarter - 1] # from the starter dls001.nje = 0 dlsr01.nge = 0 # set common block commonblocks = {} commonblocks.update(dls001()) commonblocks.update(dlsr01()) set_lsod_common(**commonblocks) return ISTATE, RWORK, IWORK