Exemplo n.º 1
0
 def _set_atol(self,atol):
     
     self.options["atol"] = set_type_shape_array(atol) 
     if len(self.options["atol"]) == 1:
         self.options["atol"] = self.options["atol"]*np.ones(self._leny)
     elif len(self.options["atol"]) != self._leny:
         raise ODASSL_Exception("atol must be of length one or same as the dimension of the problem.")
Exemplo n.º 2
0
    def integrate(self, t, y, yprime, tf, opts):
        ny = self.problem_info["dim"]

        neq = len(set_type_shape_array(self.problem.res(t, y, yprime)))
        #neq = self.problem_info["neq"]
        lrw = 40 + 8 * ny + neq**2 + 3 * neq
        rwork = np.zeros((lrw, ))
        liw = 22 + neq
        iwork = np.zeros((liw, ), np.int)
        jac_dummy = lambda t, x, xp: x
        info = np.zeros((15, ), np.int)
        info[1] = 1  # Tolerances are vectors
        info[2] = normal_mode = 1 if opts["output_list"] is None or opts[
            "report_continuously"] else 0  # intermediate output mode
        info[6] = 1 if self.options["maxh"] > 0.0 else 0
        rwork[1] = self.options["maxh"]
        info[7] = 1 if self.options["inith"] > 0.0 else 0
        rwork[2] = self.options["inith"]
        info[8] = 1 if self.options["maxord"] > 0 else 0
        iwork[2] = self.options["maxord"]
        #info[11] will be set later (see Ticket #230)
        #iwork[0] = ML
        #iwork[1] = MU

        atol = self.options["atol"]
        rtol = set_type_shape_array(self.options["rtol"])

        if len(rtol) == 1:
            rtol = rtol * np.ones(self._leny)

        if hasattr(self.problem, "algvar"):
            for i in range(ny):
                if self.problem.algvar[i] == 0:
                    rtol[i] = 1.e7
                    atol[i] = 1.e7
        tlist = []
        ylist = []
        ydlist = []

        #Store the opts
        self._opts = opts

        #THIS IS NOT SUPPOSE TO BE NECCESSARY, BUT DUE TO A PROBLEM
        #REPORTED IN TICKET:244 THIS IS HOWEVER NECCESSARY AS A
        #WORKAROUND FOR NOW...
        def py_residual(t, y, yd):
            return self.problem.res(t, y, yd)

        callback_residual = py_residual
        #----
        if opts["report_continuously"]:
            idid = 1
            while idid == 1:
                t,y,yprime,tf,info,idid,rwork,iwork = \
                   odassl.odassl(callback_residual,neq,ny,t,y,yprime,
                        tf,info,rtol,atol,rwork,iwork,jac_dummy)

                initialize_flag = self.report_solution(t, y, yprime, opts)
                if initialize_flag:
                    flag = ID_PY_EVENT
                    break
                if idid == 2 or idid == 3:
                    flag = ID_PY_COMPLETE
                elif idid < 0:
                    raise ODASSL_Exception(
                        "ODASSL failed with flag IDID {IDID}".format(
                            IDID=idid))
        else:
            if normal_mode == 1:  # intermediate output mode
                idid = 1
                while idid == 1:
                    t,y,yprime,tf,info,idid,rwork,iwork = \
                       odassl.odassl(callback_residual,neq,ny,t,y,yprime,
                             tf,info,rtol,atol,rwork,iwork,jac_dummy)

                    tlist.append(t)
                    ylist.append(y.copy())
                    ydlist.append(yprime.copy())
                    if idid == 2 or idid == 3:
                        flag = ID_PY_COMPLETE
                    elif idid < 0:
                        raise ODASSL_Exception(
                            "ODASSL failed with flag IDID {IDID}".format(
                                IDID=idid))

            else:  # mode with output_list
                output_list = opts["output_list"]
                for tout in output_list:
                    t,y,yprime,tout,info,idid,rwork,iwork = \
                      odassl.odassl(callback_residual,neq,ny,t,y,yprime, \
                             tout,info,rtol,atol,rwork,iwork,jac_dummy)
                    tlist.append(t)
                    ylist.append(y.copy())
                    ydlist.append(yprime.copy())
                    if idid > 0 and t >= tf:
                        flag = ID_PY_COMPLETE
                    elif idid < 0:
                        raise ODASSL_Exception(
                            "ODASSL failed with flag IDID {IDID}".format(
                                IDID=idid))

        #Retrieving statistics
        self.statistics["nsteps"] += iwork[10]
        self.statistics["nfcns"] += iwork[11]
        self.statistics["njacs"] += iwork[12]
        self.statistics["nerrfails"] += iwork[13]
        self.statistics["nnfails"] += iwork[14]

        return flag, tlist, ylist, ydlist