示例#1
0
    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
示例#2
0
 def test_setcoefficients(self):
     elco, tesco = dcfode(1)
     nose.tools.assert_almost_equal(elco[0, 2], 5. / 12., 9)  # AM-2
     nose.tools.assert_almost_equal(tesco[0, 2], 2., 9)  # AM-2 error coeff