Exemplo n.º 1
0
    def DAE_integration_assimulo(self, **kwargs):
        """
        Perform time integration for DAEs 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 DAE res function to
        # be defined next M should be invertible !! 
        my_solver = factorized(csc_matrix(self.M))
        rhs       = self.my_mult(self.J, self.my_mult(self.Q,self.A0)) + self.my_mult(self.Bext,self.U* self.boundary_cntrl_time(0.,self.tclose))
        self.AD0  = my_solver(rhs) 
        
        # Definition of the rhs function required in assimulo
        def res(t,y,yd):
            """
            Definition of the residual function required in the DAE part of assimulo
            """   
            if close:
                if t < self.tclose:
                    z = self.my_mult(self.M,yd) - 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.M,yd) - self.my_mult((self.J - self.R), self.my_mult(self.Q,y))
            else:
                z = self.my_mult(self.M,yd) - 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 z
  

        # Definition of the jacobian function required in assimulo
        def jac(c,t,y,yd):
            """
            Definition of the Jacobian matrix required in the DAE part of assimulo
            """  
            Matrix = csr_matrix(self.my_mult(self.J,self.Q))
            
            if close and t > self.tclose:
                    Matrix = csr_matrix(self.my_mult(self.J - self.R, self.Q))
            
            return c*csr_matrix(self.M) - Matrix
        
        # Definition of the jacobian matrix vector function required in assimulo
        def jacv(t,y,yd,res,v,c):
            """
            Jacobian matrix-vector product required in the DAE part of assimulo
            """  
            w = self.my_mult(self.Q, v)
            z = self.my_mult(self.J, w)
            
            if close and t > self.tclose:
                z -= self.my_mult(self.R, w)
                
            return c*self.my_mult(self.M,v) - z
        
        print('DAE Integration using assimulo built-in functions:')

        
        model                     = Implicit_Problem(res,self.A0,self.AD0,self.tinit)
        model.jacv                = jacv
        #sim                       = Radau5DAE(model,**kwargs)
        #
        # IDA method from Assimulo
        #
        sim                       = IDA(model,**kwargs)
        sim.algvar                = [1 for i in range(self.M.shape[0])]
        sim.atol                  = 1.e-6
        sim.rtol                  = 1.e-6
        sim.report_continuously   = True
        ncp                       = self.Nt
        sim.usejac                = True
        sim.suppress_alg          = True
        sim.inith                 = self.dt
        sim.maxord                = 5
        #sim.linear_solver         = 'SPGMR'
        time_span, DAE_y, DAE_yd  = sim.simulate(self.tfinal,ncp)
        
        #print(sim.get_options())
        print(sim.print_statistics())
        
        A_dae = DAE_y.transpose()
        
        # Hamiltonian
        self.Nt    = A_dae.shape[1]
        self.tspan = np.array(time_span)
        
        Ham_dae = np.zeros(self.Nt)
        
        for k in range(self.Nt):
            #Ham_dae[k] = 1/2 * A_dae[:,k] @ self.M @ self.Q @ A_dae[:,k]
            Ham_dae[k] = 1/2 * self.my_mult(A_dae[:,k].T, \
                               self.my_mult(self.M, self.my_mult(self.Q, A_dae[:,k])))
      
        # Get q variables
        Aq_dae = A_dae[:self.Nq,:] 
        
        # Get p variables
        Ap_dae = A_dae[self.Nq:,:]

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

        self.Ham_dae = Ham_dae
    
        return Aq_dae, Ap_dae, Ham_dae, W_dae, np.array(time_span)    
Exemplo n.º 2
0
    def DAE_integration_assimulo_lagrangian(self, **kwargs):
        """
        Perform time integration for DAEs with the assimulo package
        Lagrangian variant
        """
        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.Vl).vector()[self.bndr_i_l]
        if self.discontinous_boundary_values == 1:
            self.U[self.Corner_indices] = self.U[self.Corner_indices]/2
            
        self.UU = np.zeros(self.Nb)
        for i in range(self.Nb):
            self.UU[i] = self.boundary_cntrl_space(self.coord_b[i])
        

        # Definition of the sparse solver for the DAE res function to
        # be defined next M should be invertible !! 
        #my_solver = factorized(csc_matrix(self.M))
        #rhs       = self.my_mult(self.J, self.my_mult(self.Q,self.A0)) + self.my_mult(self.Bext,self.U* self.boundary_cntrl_time(0.,self.tclose))
        #self.AD0  = my_solver(rhs) 
        
        # Definition of the rhs function required in assimulo
        def res(t,y,yd):
            """
            Definition of the residual function required in the DAE part of assimulo
            """   
            z                                    = np.zeros(self.Np+self.Nl)        
            z[0:self.Np]                         = self.my_mult(self.M_class, yd[0:self.Np])  + self.my_mult(self.D_class, y[0:self.Np]) - self.my_mult(self.C_class, y[self.Np:])
            z[self.Np:self.Np+self.Nl]           = self.my_mult(self.C_class.T, y[0:self.Np]) - self.L_class * self.boundary_cntrl_time(t,self.tclose)
            
            return z
  
        # Definition of the jacobian function required in assimulo
        def jac(c,t,y,yd):
            """
            Definition of the Jacobian matrix required in the DAE part of assimulo
            """  
            #Matrix = csr_matrix(self.my_mult(self.J,self.Q))
            
            #if close and t > self.tclose:
            #        Matrix = csr_matrix(self.my_mult(self.J - self.R, self.Q))
            
            #return c*csr_matrix(self.M) - Matrix
            
            return None
        
        # Definition of the jacobian matrix vector function required in assimulo
        def jacv(t,y,yd,res,v,c):
            """
            Jacobian matrix-vector product required in the DAE part of assimulo
            """  
            #w = self.my_mult(self.Q, v)
            #z = self.my_mult(self.J, w)
            
            #if close and t > self.tclose:
            #    z -= self.my_mult(self.R, w)
                
            #return c*self.my_mult(self.M,v) - z
            
            return None
        
        print('DAE Integration using assimulo built-in functions:')

        #def handle_result(solver, t ,y, yd):
        #    global order
        #    order.append(solver.get_last_order())
        # 
        #     solver.t_sol.extend([t])
        #    solver.y_sol.extend([y])
        #    solver.yd_sol.extend([yd]) 
            
        # The initial conditons
        y0  =  np.concatenate(( self.Tp0, np.zeros(self.Nl) )) 
        yd0 =  np.zeros(self.Np + self.Nl)     
        
        model                     = Implicit_Problem(res,y0,yd0,self.tinit)
        #model.handle_result       = handle_result
        #model.jacv                = jacv
        #sim                       = Radau5DAE(model,**kwargs)
        #
        # IDA method from Assimulo
        #
        sim                       = IDA(model,**kwargs)
        sim.algvar                = list(np.concatenate((np.ones(self.Np), np.zeros(self.Nl) )) )
        sim.atol                  = 1.e-6
        sim.rtol                  = 1.e-6
        sim.report_continuously   = True
        ncp                       = self.Nt
        #sim.usejac                = True
        sim.suppress_alg          = True
        sim.inith                 = self.dt
        sim.maxord                = 5
        #sim.linear_solver         = 'SPGMR'
        sim.make_consistent('IDA_YA_YDP_INIT')
        
        #time_span, DAE_y, DAE_yd  = sim.simulate(self.tfinal,ncp, self.tspan)
        time_span, DAE_y, DAE_yd  = sim.simulate(self.tfinal, 0, self.tspan)
        
        #print(sim.get_options())
        print(sim.print_statistics())
        
        A_dae = DAE_y[:,0:self.Np].transpose()
                
        # Hamiltonian
        self.Nt    = A_dae.shape[1]
        self.tspan = np.array(time_span)
        
        Ham_dae = np.zeros(self.Nt)
        
        for k in range(self.Nt):
            Ham_dae[k] = 1/2 * self.my_mult(A_dae[:,k].T, \
                               self.my_mult(self.Mp_rho_Cv, A_dae[:,k]))
      
        self.Ham_dae = Ham_dae
    
        return Ham_dae, np.array(time_span)