示例#1
0
    def _solve_cvode(f, t, y0, args, console=False, max_steps=1000, terminate=False):
        """Wrapper for Assimulo's CVODE-Sundials routine
        """
        def rhs(t, u):
            return f(u, t, *args)

        prob = Explicit_Problem(rhs, y0)
        sim = CVode(prob)
        sim.rtol = 1e-15
        sim.atol = 1e-12
        sim.discr = 'BDF'
        sim.maxord = 5 
        sim.maxsteps = max_steps

        if not console:
            sim.verbosity = 50
        else:
            sim.report_continuously = True


        t_end = t[-1]
        steps = len(t)

        try:
            print t_end, steps
            t, x = sim.simulate(t_end, steps)
        except CVodeError, e:
            raise ValueError("Something broke in CVode: %r" % e)
            return None, False
示例#2
0
    def _setup_sim(self, **kwargs):
        """ Create a simulation interface to Assimulo using CVODE, given
        a problem definition

        """

        # Create Assimulo interface
        sim = CVode(self.prob)
        sim.discr = 'BDF'
        sim.maxord = 5

        # Setup some default arguments for the ODE solver, or override
        # if available. This is very hackish, but it's fine for now while
        # the number of anticipated tuning knobs is small.
        if 'maxh' in kwargs:
            sim.maxh = kwargs['maxh']
        else:
            sim.maxh = np.min([0.1, self.output_dt])

        if 'minh' in kwargs:
            sim.minh = kwargs['minh']
        # else: sim.minh = 0.001

        if "iter" in kwargs:
            sim.iter = kwargs['iter']
        else:
            sim.iter = 'Newton'

        if "linear_solver" in kwargs:
            sim.linear_solver = kwargs['linear_solver']

        if "max_steps" in kwargs:  # DIFFERENT NAME!!!!
            sim.maxsteps = kwargs['max_steps']
        else:
            sim.maxsteps = 1000

        if "time_limit" in kwargs:
            sim.time_limit = kwargs['time_limit']
            sim.report_continuously = True
        else:
            sim.time_limit = 0.0

        # Don't save the [t_-, t_+] around events
        sim.store_event_points = False

        # Setup tolerances
        nr = self.args[0]
        sim.rtol = state_rtol
        sim.atol = state_atol + [1e-12] * nr

        if not self.console:
            sim.verbosity = 50
        else:
            sim.verbosity = 40
        # sim.report_continuously = False

        # Save the Assimulo interface
        return sim
示例#3
0
    def _setup_sim(self, **kwargs):
        """ Create a simulation interface to Assimulo using CVODE, given
        a problem definition

        """

        # Create Assimulo interface
        sim = CVode(self.prob)
        sim.discr = 'BDF'
        sim.maxord = 5

        # Setup some default arguments for the ODE solver, or override
        # if available. This is very hackish, but it's fine for now while
        # the number of anticipated tuning knobs is small.
        if 'maxh' in kwargs:
            sim.maxh = kwargs['maxh']
        else:
            sim.maxh = np.min([0.1, self.output_dt])

        if 'minh' in kwargs:
            sim.minh = kwargs['minh']
        # else: sim.minh = 0.001

        if "iter" in kwargs:
            sim.iter = kwargs['iter']
        else:
            sim.iter = 'Newton'

        if "linear_solver" in kwargs:
            sim.linear_solver = kwargs['linear_solver']

        if "max_steps" in kwargs:  # DIFFERENT NAME!!!!
            sim.maxsteps = kwargs['max_steps']
        else:
            sim.maxsteps = 1000

        if "time_limit" in kwargs:
            sim.time_limit = kwargs['time_limit']
            sim.report_continuously = True
        else:
            sim.time_limit = 0.0

        # Don't save the [t_-, t_+] around events
        sim.store_event_points = False

        # Setup tolerances
        nr = self.args[0]
        sim.rtol = state_rtol
        sim.atol = state_atol + [1e-12]*nr

        if not self.console:
            sim.verbosity = 50
        else:
            sim.verbosity = 40
        # sim.report_continuously = False

        # Save the Assimulo interface
        return sim
示例#4
0
def run_example(with_plots=True):
    def curl(v):
        return array([[0, v[2], -v[1]], [-v[2], 0, v[0]], [v[1], -v[0], 0]])

    #Defines the rhs
    def f(t, u):
        """
        Simulations for the Gyro (Heavy Top) example in Celledoni/Safstrom: 
        Journal of Physics A, Vol 39, 5463-5478, 2006
        """
        I1 = 1000.
        I2 = 5000.
        I3 = 6000.
        u0 = [0, 0, 1.]
        pi = u[0:3]
        Q = (u[3:12]).reshape((3, 3))
        Qu0 = dot(Q, u0)
        f = array([Qu0[1], -Qu0[0], 0.])
        f = 0
        omega = array([pi[0] / I1, pi[1] / I2, pi[2] / I3])
        pid = dot(curl(omega), pi) + f
        Qd = dot(curl(omega), Q)
        return hstack([pid, Qd.reshape((9, ))])

    def energi(state):
        energi = []
        for st in state:
            Q = (st[3:12]).reshape((3, 3))
            pi = st[0:3]
            u0 = [0, 0, 1.]
            Qu0 = dot(Q, u0)
            V = Qu0[2]  # potential energy
            T = 0.5 * (pi[0]**2 / 1000. + pi[1]**2 / 5000. + pi[2]**2 / 6000.)
            energi.append([T])
        return energi

    #Initial conditions
    y0 = hstack([[1000. * 10, 5000. * 10, 6000 * 10], eye(3).reshape((9, ))])

    #Create an Assimulo explicit problem
    gyro_mod = Explicit_Problem(f, y0)

    #Create an Assimulo explicit solver (CVode)
    gyro_sim = CVode(gyro_mod)

    #Sets the parameters
    gyro_sim.discr = 'BDF'
    gyro_sim.iter = 'Newton'
    gyro_sim.maxord = 2  #Sets the maxorder
    gyro_sim.atol = 1.e-10
    gyro_sim.rtol = 1.e-10

    #Simulate
    t, y = gyro_sim.simulate(0.1)

    #Basic tests
    nose.tools.assert_almost_equal(y[-1][0], 692.800241862)
    nose.tools.assert_almost_equal(y[-1][8], 7.08468221e-1)

    #Plot
    if with_plots:
        P.plot(t, y)
        P.show()
示例#5
0
    def integration_assimulo(self, **kwargs):
        """
        Perform time integration for ODEs with the assimulo package
        """
        assert self.set_time_setting == 1, 'Time discretization must be specified first'
        
        if self.tclose > 0:
            close    = True
        else: 
            close    = False

        # Control vector
        self.U = interpolate(self.boundary_cntrl_space, self.Vb).vector()[self.bndr_i_b]
        if self.discontinous_boundary_values == 1:
            self.U[self.Corner_indices] = self.U[self.Corner_indices]/2

        # Definition of the sparse solver for the ODE rhs function to
        # be defined next
        #my_solver = factorized(csc_matrix(self.M))
        my_solver = factorized(self.M)
        #my_jac_o  = csr_matrix(my_solver(self.J @ self.Q))
        #my_jac_c  = csr_matrix(my_solver((self.J - self.R) @ self.Q))
                
        # Definition of the rhs function required in assimulo
        def rhs(t,y):
            """
            Definition of the rhs function required in the ODE part of assimulo
            """   
            if close:
                if t < self.tclose:
                    z = self.my_mult(self.J, self.my_mult(self.Q,y)) + self.my_mult(self.Bext,self.U* self.boundary_cntrl_time(t,self.tclose))
                else:
                    z = self.my_mult((self.J - self.R), self.my_mult(self.Q,y))
            else:
                z = self.my_mult(self.J, self.my_mult(self.Q,y)) + self.my_mult(self.Bext,self.U* self.boundary_cntrl_time(t,self.tclose)) 
            
            return my_solver(z)
 
        def jacobian(t,y):
            """
            Jacobian related to the ODE formulation
            """
            if close:
                if t < self.tclose:
                    my_jac = my_jac_o
                else:
                    my_jac = my_jac_c
            else:
                my_jac = my_jac_o
            
            return my_jac
        
        def jacv(t,y,fy,v):
            """
            Jacobian matrix-vector product related to the ODE formulation
            """
            if close:
                if t < self.tclose:
                    z = self.my_mult(self.J, self.my_mult(self.Q,v) )
                else:
                    z = self.my_mult((self.J - self.R), self.my_mult(self.Q,v))
            else:
                z = self.my_mult(self.J, self.my_mult(self.Q,v))
            
            return my_solver(z)
           
        print('ODE Integration using assimulo built-in functions:')

#
# https://jmodelica.org/assimulo/_modules/assimulo/examples/cvode_with_preconditioning.html#run_example
#
        
        model                     = Explicit_Problem(rhs,self.A0,self.tinit)
        #model.jac                 = jacobian
        model.jacv                = jacv
        sim                       = CVode(model,**kwargs)
        sim.atol                  = 1e-3 
        sim.rtol                  = 1e-3 
        sim.linear_solver         = 'SPGMR' 
        sim.maxord                = 3
        #sim.usejac                = True
        #sim                       = RungeKutta34(model,**kwargs)
        time_span, ODE_solution   = sim.simulate(self.tfinal)
        
        A_ode = ODE_solution.transpose()
        
        # Hamiltonian
        self.Nt    = A_ode.shape[1]
        self.tspan = np.array(time_span)
        
        Ham_ode = np.zeros(self.Nt)
        
        for k in range(self.Nt):
            #Ham_ode[k] = 1/2 * A_ode[:,k] @ self.M @ self.Q @ A_ode[:,k]
            Ham_ode[k] = 1/2 * self.my_mult(A_ode[:,k].T, \
                               self.my_mult(self.M, self.my_mult(self.Q, A_ode[:,k])))
      
        # Get q variables
        Aq_ode = A_ode[:self.Nq,:] 
        
        # Get p variables
        Ap_ode = A_ode[self.Nq:,:]

        # Get Deformation
        Rho = np.zeros(self.Np)
        for i in range(self.Np):
            Rho[i] = self.rho(self.coord_p[i])
            
        W_ode = np.zeros((self.Np,self.Nt))
        theta = .5
        for k in range(self.Nt-1):
            W_ode[:,k+1] = W_ode[:,k] + self.dt * 1/Rho[:] * ( theta * Ap_ode[:,k+1] + (1-theta) * Ap_ode[:,k] ) 

        self.Ham_ode = Ham_ode
    
        return Aq_ode, Ap_ode, Ham_ode, W_ode, np.array(time_span)
示例#6
0
def run_example(with_plots=True):
    
    def curl(v):
        return array([[0,v[2],-v[1]],[-v[2],0,v[0]],[v[1],-v[0],0]])

    #Defines the rhs
    def f(t,u):
        """
        Simulations for the Gyro (Heavy Top) example in Celledoni/Safstrom: 
        Journal of Physics A, Vol 39, 5463-5478, 2006
        """
        I1=1000.
        I2=5000.
        I3=6000.
        u0=[0,0,1.]
        pi=u[0:3]
        Q=(u[3:12]).reshape((3,3))
        Qu0=dot(Q,u0)
        f=array([Qu0[1],-Qu0[0],0.])
        f=0
        omega=array([pi[0]/I1,pi[1]/I2,pi[2]/I3])
        pid=dot(curl(omega),pi)+f
        Qd=dot(curl(omega),Q)
        return hstack([pid,Qd.reshape((9,))])

    def energi(state):
        energi=[]
        for st in state:
            Q=(st[3:12]).reshape((3,3))
            pi=st[0:3]
            u0=[0,0,1.]
            Qu0=dot(Q,u0)
            V=Qu0[2]  # potential energy
            T=0.5*(pi[0]**2/1000.+pi[1]**2/5000.+pi[2]**2/6000.)
            energi.append([T])
        return energi

    #Initial conditions
    y0=hstack([[1000.*10,5000.*10,6000*10],eye(3).reshape((9,))])
    
    #Create an Assimulo explicit problem
    gyro_mod = Explicit_Problem(f,y0)
    
    #Create an Assimulo explicit solver (CVode)
    gyro_sim=CVode(gyro_mod)
    
    #Sets the parameters
    gyro_sim.discr='BDF'
    gyro_sim.iter='Newton'
    gyro_sim.maxord=2 #Sets the maxorder
    gyro_sim.atol=1.e-10
    gyro_sim.rtol=1.e-10
    
    #Simulate
    t, y = gyro_sim.simulate(0.1)
    
    #Basic tests
    nose.tools.assert_almost_equal(y[-1][0],692.800241862)
    nose.tools.assert_almost_equal(y[-1][8],7.08468221e-1)
    
    #Plot
    if with_plots:
        P.plot(t,y)
        P.show()
示例#7
0
    def integration_assimulo(self, **kwargs):
        """
        Perform time integration for ODEs with the assimulo package
        """
        assert self.set_time_setting == 1, 'Time discretization must be specified first'
        
        if self.tclose > 0:
            close    = True
        else: 
            close    = False

        # Control vector
        self.U = interpolate(self.boundary_cntrl_space, self.Vb).vector()[self.bndr_i_b]
        
        if self.discontinous_boundary_values == 1:
            self.U[self.Corner_indices] = self.U[self.Corner_indices]/2

        # Definition of the sparse solver for the ODE rhs function to
        # be defined next
        
        my_solver = factorized(csc_matrix(self.Mp_rho_Cv))
        C         = self.A
        
        if self.sparse == 1:
            my_jac_o  = csr_matrix(my_solver(C.toarray()))
        else:
            my_jac_o  = my_solver(C)
                
        # Definition of the rhs function required in assimulo
        def rhs(t,y):
            """
            Definition of the rhs function required in the ODE part of assimulo
            """   
            
            z = self.my_mult(self.A, y) + self.my_mult(self.Bext,self.U* self.boundary_cntrl_time(t,self.tclose)) 
            
            return my_solver(z)
            
            
            #z                                    = np.zeros(shape=y.shape[:])        
            #z[0:self.Np]                         = self.my_mult(self.Mp, yd[0:self.Np])              - self.my_mult(D, y[self.Np+self.Nq:self.Np+2*self.Nq]) 
            #z[self.Np:self.Np+self.Nq]           = self.my_mult(self.Mq, y[self.Np:self.Np+self.Nq]) + self.my_mult(D.T, y[0:self.Np]) - self.my_mult(self.Bp, self.U* self.boundary_cntrl_time(t,self.tclose))
            #z[self.Np+self.Nq:self.Np+2*self.Nq] = self.my_mult(self.Mq, y[self.Np+self.Nq:self.Np+2*self.Nq]) - self.my_mult(self.L,y[self.Np:self.Np+self.Nq])
            #return z
 
        def jacobian(t,y):
            """
            Jacobian related to the ODE formulation
            """
            my_jac = my_jac_o 
            
            return my_jac
        
        def jacv(t,y,fy,v):
            """
            Jacobian matrix-vector product related to the ODE formulation
            """
            return None
           
        print('ODE Integration using assimulo built-in functions:')

#
# https://jmodelica.org/assimulo/_modules/assimulo/examples/cvode_with_preconditioning.html#run_example
#
        
        model                     = Explicit_Problem(rhs,self.Tp0,self.tinit)
        sim                       = CVode(model,**kwargs)
        sim.atol                  = 1e-3 
        sim.rtol                  = 1e-3 
        sim.linear_solver         = 'SPGMR' 
        sim.maxord                = 3
        #sim.usejac                = True
        #sim                       = RungeKutta34(model,**kwargs)
        time_span, ODE_solution   = sim.simulate(self.tfinal)
        
        A_ode = ODE_solution.transpose()
        
        # Hamiltonian
        self.Nt    = A_ode.shape[1]
        self.tspan = np.array(time_span)
        
        Ham_ode = np.zeros(self.Nt)
        
        for k in range(self.Nt):
            Ham_ode[k] = 1/2 * self.my_mult(A_ode[:,k].T, \
                               self.my_mult(self.Mp_rho_Cv,  A_ode[:,k]))
      
        self.Ham_ode = Ham_ode
    
        return Ham_ode, np.array(time_span)