Ejemplo n.º 1
0
class BsplineParameters(ExplicitComponent):
    """
    Creates a Bspline interpolant for several CADRE variables
    so that their time histories can be shaped with m control points
    instead of n time points.
    """
    def __init__(self, n, m):
        super(BsplineParameters, self).__init__()

        self.n = n
        self.m = m

        self.deriv_cached = False

    def setup(self):
        m = self.m
        n = self.n

        # Inputs
        self.add_input('t1', 0., units='s', desc='Start time')

        self.add_input('t2', 43200., units='s', desc='End time')

        self.add_input('CP_P_comm',
                       np.zeros((m, )),
                       units='W',
                       desc='Communication power at the control points')

        self.add_input('CP_gamma',
                       np.zeros((m, )),
                       units='rad',
                       desc='Satellite roll angle at control points')

        self.add_input(
            'CP_Isetpt',
            np.zeros((m, 12)),
            units='A',
            desc='Currents of the solar panels at the control points')

        # Outputs
        self.add_output('P_comm',
                        np.ones((n, )),
                        units='W',
                        desc='Communication power over time')

        self.add_output('Gamma',
                        0.1 * np.ones((n, )),
                        units='rad',
                        desc='Satellite roll angle over time')

        self.add_output('Isetpt',
                        0.2 * np.ones((n, 12)),
                        units='A',
                        desc='Currents of the solar panels over time')

        self.declare_partials('P_comm', 'CP_P_comm')
        self.declare_partials('Gamma', 'CP_gamma')

        rowm = np.repeat(0, m)
        colm = 12 * np.arange(m)
        rown = np.tile(rowm, n) + np.repeat(12 * np.arange(n), m)
        coln = np.tile(colm, n)
        rows = np.tile(rown, 12) + np.repeat(np.arange(12), n * m)
        cols = np.tile(coln, 12) + np.repeat(np.arange(12), n * m)

        self.declare_partials('Isetpt', 'CP_Isetpt', rows=rows, cols=cols)

    def compute(self, inputs, outputs):
        """
        Calculate outputs.
        """
        # Only need to do this once.
        if self.deriv_cached is False:
            t1 = inputs['t1']
            t2 = inputs['t2']
            n = self.n

            self.B = MBI(np.zeros(n), [np.linspace(t1, t2, n)], [self.m],
                         [4]).getJacobian(0, 0)
            self.Bdot = MBI(np.zeros(n), [np.linspace(t1, t2, n)], [self.m],
                            [4]).getJacobian(1, 0)

            self.BT = self.B.transpose()
            self.BdotT = self.Bdot.transpose()

            self.deriv_cached = True

        outputs['P_comm'] = self.B.dot(inputs['CP_P_comm'])
        outputs['Gamma'] = self.B.dot(inputs['CP_gamma'])
        for k in range(12):
            outputs['Isetpt'][:, k] = self.B.dot(inputs['CP_Isetpt'][:, k])

    def compute_partials(self, inputs, partials):
        """
        Calculate and save derivatives. (i.e., Jacobian)
        """
        B = self.B
        partials['P_comm', 'CP_P_comm'] = B
        partials['Gamma', 'CP_gamma'] = B

        # TODO : need to fix the time issue so that we can declare very sparse derivatives.
        partials['Isetpt', 'CP_Isetpt'] = np.tile(B.todense().flat, 12)
Ejemplo n.º 2
0
class BsplineParameters(ExplicitComponent):
    """
    Creates a Bspline interpolant for several CADRE variables
    so that their time histories can be shaped with m control points
    instead of n time points.
    """

    def __init__(self, n, m):
        super(BsplineParameters, self).__init__()

        self.n = n
        self.m = m

        self.deriv_cached = False

    def setup(self):
        m = self.m
        n = self.n

        # Inputs
        self.add_input('t1', 0., units='s', desc='Start time')

        self.add_input('t2', 43200., units='s', desc='End time')

        self.add_input('CP_P_comm', np.zeros((m, )), units='W',
                       desc='Communication power at the control points')

        self.add_input('CP_gamma', np.zeros((m, )), units='rad',
                       desc='Satellite roll angle at control points')

        self.add_input('CP_Isetpt', np.zeros((12, m)), units='A',
                       desc='Currents of the solar panels at the control points')

        # Outputs
        self.add_output('P_comm', np.ones((n, )), units='W',
                        desc='Communication power over time')

        self.add_output('Gamma', 0.1*np.ones((n,)), units='rad',
                        desc='Satellite roll angle over time')

        self.add_output('Isetpt', 0.2*np.ones((12, n)), units='A',
                        desc='Currents of the solar panels over time')

    def compute(self, inputs, outputs):
        """
        Calculate outputs.
        """
        # Only need to do this once.
        if self.deriv_cached is False:
            t1 = inputs['t1']
            t2 = inputs['t2']
            n = self.n

            self.B = MBI(np.zeros(n), [np.linspace(t1, t2, n)], [self.m], [4]).getJacobian(0, 0)
            self.Bdot = MBI(np.zeros(n), [np.linspace(t1, t2, n)], [self.m], [4]).getJacobian(1, 0)

            self.BT = self.B.transpose()
            self.BdotT = self.Bdot.transpose()

            self.deriv_cached = True

        outputs['P_comm'] = self.B.dot(inputs['CP_P_comm'])
        outputs['Gamma'] = self.B.dot(inputs['CP_gamma'])
        for k in range(12):
            outputs['Isetpt'][k, :] = self.B.dot(inputs['CP_Isetpt'][k, :])

    def compute_jacvec_product(self, inputs, d_inputs, d_outputs, mode):
        """
        Matrix-vector product with the Jacobian.
        """
        if mode == 'fwd':
            if 'P_comm' in d_outputs and 'CP_P_comm' in d_inputs:
                d_outputs['P_comm'] += self.B.dot(d_inputs['CP_P_comm'])

            if 'Gamma' in d_outputs and 'CP_gamma' in d_inputs:
                d_outputs['Gamma'] += self.B.dot(d_inputs['CP_gamma'])

            if 'Isetpt' in d_outputs and 'CP_Isetpt' in d_inputs:
                for k in range(12):
                    d_outputs['Isetpt'][k, :] += self.B.dot(d_inputs['CP_Isetpt'][k, :])
        else:
            if 'P_comm' in d_outputs and 'CP_P_comm' in d_inputs:
                d_inputs['CP_P_comm'] += self.BT.dot(d_outputs['P_comm'])

            if 'Gamma' in d_outputs and 'CP_gamma' in d_inputs:
                d_inputs['CP_gamma'] += self.BT.dot(d_outputs['Gamma'])

            if 'Isetpt' in d_outputs and 'CP_Isetpt' in d_inputs:
                for k in range(12):
                    d_inputs['CP_Isetpt'][k, :] += self.BT.dot(d_outputs['Isetpt'][k, :])
Ejemplo n.º 3
0
class BsplineParameters(Component):
    '''Creates a Bspline interpolant for several CADRE variables
       so that their time histories can be shaped with m control points
       instead of n time points.'''

    def __init__(self, n, m):
        super(BsplineParameters, self).__init__()

        self.n = n
        self.m = m

        # Inputs
        self.add_param('t1', 0., units='s', desc='Start time')

        self.add_param('t2', 43200., units='s', desc='End time')

        self.add_param('CP_P_comm', np.zeros((self.m, )), units='W',
                       desc='Communication power at the control points')

        self.add_param('CP_gamma', np.zeros((self.m, )), units='rad',
                       desc='Satellite roll angle at control points')

        self.add_param('CP_Isetpt', np.zeros((12,self.m)), units='A',
                       desc='Currents of the solar panels at the control points')

        # Outputs
        self.add_output('P_comm', np.ones((n, )), units='W',
                        desc='Communication power over time')

        self.add_output('Gamma', 0.1*np.ones((n,)), units='rad',
                        desc='Satellite roll ang le over time')

        self.add_output('Isetpt', 0.2*np.ones((12, n)), units="A",
                        desc="Currents of the solar panels over time")

        self.deriv_cached = False

    def solve_nonlinear(self, params, unknowns, resids):
        """ Calculate output. """

        # Only need to do this once.
        if self.deriv_cached == False:

            t1 = params['t1']
            t2 = params['t2']
            n = self.n

            self.B = MBI(np.zeros(n), [np.linspace(t1, t2, n)],
                         [self.m], [4]).getJacobian(0, 0)

            self.Bdot = MBI(np.zeros(n), [np.linspace(t1, t2, n)],
                            [self.m], [4]).getJacobian(1, 0)

            self.BT = self.B.transpose()
            self.BdotT = self.Bdot.transpose()

            self.deriv_cached = True

        unknowns['P_comm'] = self.B.dot(params['CP_P_comm'])
        unknowns['Gamma'] = self.B.dot(params['CP_gamma'])
        for k in range(12):
            unknowns['Isetpt'][k, :] = self.B.dot(params['CP_Isetpt'][k, :])

    def apply_linear(self, params, unknowns, dparams, dunknowns, dresids, mode):
        """ Matrix-vector product with the Jacobian. """

        if mode == 'fwd':
            if 'P_comm' in dresids and 'CP_P_comm' in dparams:
                dresids['P_comm'] += self.B.dot(dparams['CP_P_comm'])

            if 'Gamma' in dresids and 'CP_gamma' in dparams:
                dresids['Gamma'] += self.B.dot(dparams['CP_gamma'])

            if 'Isetpt' in dresids and 'CP_Isetpt' in dparams:
                for k in range(12):
                    dresids['Isetpt'][k, :] += self.B.dot(dparams['CP_Isetpt'][k, :])

        else:
            if 'P_comm' in dresids and 'CP_P_comm' in dparams:
                dparams['CP_P_comm'] += self.BT.dot(dresids['P_comm'])

            if 'Gamma' in dresids and 'CP_gamma' in dparams:
                dparams['CP_gamma'] += self.BT.dot(dresids['Gamma'])

            if 'Isetpt' in dresids and 'CP_Isetpt' in dparams:
                for k in range(12):
                    dparams['CP_Isetpt'][k, :] += self.BT.dot(dresids['Isetpt'][k, :])
Ejemplo n.º 4
0
class BsplineParameters(ExplicitComponent):
    """
    Creates a Bspline interpolant for several CADRE variables
    so that their time histories can be shaped with m control points
    instead of n time points.
    """
    def __init__(self, n, m):
        super(BsplineParameters, self).__init__()

        self.n = n
        self.m = m

        self.deriv_cached = False

    def setup(self):
        m = self.m
        n = self.n

        # Inputs
        self.add_input('t1', 0., units='s', desc='Start time')

        self.add_input('t2', 43200., units='s', desc='End time')

        self.add_input('CP_P_comm',
                       np.zeros((m, )),
                       units='W',
                       desc='Communication power at the control points')

        self.add_input('CP_gamma',
                       np.zeros((m, )),
                       units='rad',
                       desc='Satellite roll angle at control points')

        self.add_input(
            'CP_Isetpt',
            np.zeros((12, m)),
            units='A',
            desc='Currents of the solar panels at the control points')

        # Outputs
        self.add_output('P_comm',
                        np.ones((n, )),
                        units='W',
                        desc='Communication power over time')

        self.add_output('Gamma',
                        0.1 * np.ones((n, )),
                        units='rad',
                        desc='Satellite roll angle over time')

        self.add_output('Isetpt',
                        0.2 * np.ones((12, n)),
                        units='A',
                        desc='Currents of the solar panels over time')

    def compute(self, inputs, outputs):
        """
        Calculate outputs.
        """
        # Only need to do this once.
        if self.deriv_cached is False:
            t1 = inputs['t1']
            t2 = inputs['t2']
            n = self.n

            self.B = MBI(np.zeros(n), [np.linspace(t1, t2, n)], [self.m],
                         [4]).getJacobian(0, 0)
            self.Bdot = MBI(np.zeros(n), [np.linspace(t1, t2, n)], [self.m],
                            [4]).getJacobian(1, 0)

            self.BT = self.B.transpose()
            self.BdotT = self.Bdot.transpose()

            self.deriv_cached = True

        outputs['P_comm'] = self.B.dot(inputs['CP_P_comm'])
        outputs['Gamma'] = self.B.dot(inputs['CP_gamma'])
        for k in range(12):
            outputs['Isetpt'][k, :] = self.B.dot(inputs['CP_Isetpt'][k, :])

    def compute_jacvec_product(self, inputs, d_inputs, d_outputs, mode):
        """
        Matrix-vector product with the Jacobian.
        """
        if mode == 'fwd':
            if 'P_comm' in d_outputs and 'CP_P_comm' in d_inputs:
                d_outputs['P_comm'] += self.B.dot(d_inputs['CP_P_comm'])

            if 'Gamma' in d_outputs and 'CP_gamma' in d_inputs:
                d_outputs['Gamma'] += self.B.dot(d_inputs['CP_gamma'])

            if 'Isetpt' in d_outputs and 'CP_Isetpt' in d_inputs:
                for k in range(12):
                    d_outputs['Isetpt'][k, :] += self.B.dot(
                        d_inputs['CP_Isetpt'][k, :])
        else:
            if 'P_comm' in d_outputs and 'CP_P_comm' in d_inputs:
                d_inputs['CP_P_comm'] += self.BT.dot(d_outputs['P_comm'])

            if 'Gamma' in d_outputs and 'CP_gamma' in d_inputs:
                d_inputs['CP_gamma'] += self.BT.dot(d_outputs['Gamma'])

            if 'Isetpt' in d_outputs and 'CP_Isetpt' in d_inputs:
                for k in range(12):
                    d_inputs['CP_Isetpt'][k, :] += self.BT.dot(
                        d_outputs['Isetpt'][k, :])
Ejemplo n.º 5
0
class BsplineParameters(Component):
    '''Creates a Bspline interpolant for several CADRE variables
       so that their time histories can be shaped with m control points
       instead of n time points.'''
    def __init__(self, n, m):
        super(BsplineParameters, self).__init__()

        self.n = n
        self.m = m

        # Inputs
        self.add_param('t1', 0., units='s', desc='Start time')

        self.add_param('t2', 43200., units='s', desc='End time')

        self.add_param('CP_P_comm',
                       np.zeros((self.m, )),
                       units='W',
                       desc='Communication power at the control points')

        self.add_param('CP_gamma',
                       np.zeros((self.m, )),
                       units='rad',
                       desc='Satellite roll angle at control points')

        self.add_param(
            'CP_Isetpt',
            np.zeros((12, self.m)),
            units='A',
            desc='Currents of the solar panels at the control points')

        # Outputs
        self.add_output('P_comm',
                        np.ones((n, )),
                        units='W',
                        desc='Communication power over time')

        self.add_output('Gamma',
                        0.1 * np.ones((n, )),
                        units='rad',
                        desc='Satellite roll ang le over time')

        self.add_output('Isetpt',
                        0.2 * np.ones((12, n)),
                        units="A",
                        desc="Currents of the solar panels over time")

        self.deriv_cached = False

    def solve_nonlinear(self, params, unknowns, resids):
        """ Calculate output. """

        # Only need to do this once.
        if self.deriv_cached == False:

            t1 = params['t1']
            t2 = params['t2']
            n = self.n

            self.B = MBI(np.zeros(n), [np.linspace(t1, t2, n)], [self.m],
                         [4]).getJacobian(0, 0)

            self.Bdot = MBI(np.zeros(n), [np.linspace(t1, t2, n)], [self.m],
                            [4]).getJacobian(1, 0)

            self.BT = self.B.transpose()
            self.BdotT = self.Bdot.transpose()

            self.deriv_cached = True

        unknowns['P_comm'] = self.B.dot(params['CP_P_comm'])
        unknowns['Gamma'] = self.B.dot(params['CP_gamma'])
        for k in range(12):
            unknowns['Isetpt'][k, :] = self.B.dot(params['CP_Isetpt'][k, :])

    def apply_linear(self, params, unknowns, dparams, dunknowns, dresids,
                     mode):
        """ Matrix-vector product with the Jacobian. """

        if mode == 'fwd':
            if 'P_comm' in dresids and 'CP_P_comm' in dparams:
                dresids['P_comm'] += self.B.dot(dparams['CP_P_comm'])

            if 'Gamma' in dresids and 'CP_gamma' in dparams:
                dresids['Gamma'] += self.B.dot(dparams['CP_gamma'])

            if 'Isetpt' in dresids and 'CP_Isetpt' in dparams:
                for k in range(12):
                    dresids['Isetpt'][k, :] += self.B.dot(
                        dparams['CP_Isetpt'][k, :])

        else:
            if 'P_comm' in dresids and 'CP_P_comm' in dparams:
                dparams['CP_P_comm'] += self.BT.dot(dresids['P_comm'])

            if 'Gamma' in dresids and 'CP_gamma' in dparams:
                dparams['CP_gamma'] += self.BT.dot(dresids['Gamma'])

            if 'Isetpt' in dresids and 'CP_Isetpt' in dparams:
                for k in range(12):
                    dparams['CP_Isetpt'][k, :] += self.BT.dot(
                        dresids['Isetpt'][k, :])