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.")
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