Beispiel #1
0
    def smallAngleApprox(self, angle_list, extraSubs=[]):
        """ 
        Apply small angle approximation to forcing and mass matrix
        """
        # Forcing
        with Timer('Small angle approx. forcing', True):
            if self._sa_forcing is None:
                self._sa_forcing = self.kane.forcing
            self._sa_forcing = self._sa_forcing.subs(
                self.kdeqsSubs).subs(extraSubs)
            self._sa_forcing = smallAngleApprox(self._sa_forcing, angle_list)
        with Timer('Small angle approx. forcing simplify', True):
            self._sa_forcing.simplify()
        # Mass matrix
        with Timer('Small angle approx. mass matrix', True):
            if self._sa_mass_matrix is None:
                self._sa_mass_matrix = self.kane.mass_matrix
            self._sa_mass_matrix = self._sa_mass_matrix.subs(
                self.kdeqsSubs).subs(extraSubs)
            self._sa_mass_matrix = smallAngleApprox(self._sa_mass_matrix,
                                                    angle_list)
        with Timer('Small angle approx. mass matrix simplify', True):
            self._sa_mass_matrix.simplify()

        self.smallAngleUsed = angle_list
Beispiel #2
0
    def kaneEquations(self, Mform='symbolic', addGravity=True):
        """ 
        Compute equation of motions using Kane's method
        Mform: form to use for mass matrix
        addGravity: include gravity for elastic bodies
        """
        for sa in ['ref', 'coordinates', 'speeds', 'kdeqs', 'bodies', 'loads']:
            if getattr(self, sa) is None:
                raise Exception(
                    'Attribute {} needs to be set before calling `kane` method'
                    .format(sa))

        with Timer('Kane step1', True):
            self.kane = YAMSKanesMethod(self.ref.frame, self.coordinates,
                                        self.speeds, self.kdeqs)

        # --- Expensive kane step
        with Timer('Kane step 2', True):
            #(use  Mform ='symbolic' or 'TaylorExpanded'), Mform='symbolic'
            self.fr, self.frstar = self.kane.kanes_equations(
                self.bodies,
                self.loads,
                Mform=Mform,
                addGravity=addGravity,
                g_vect=self.g_vect)
        self.kane.fr = self.fr
        self.kane.frstar = self.frstar
Beispiel #3
0
def linearizeQ(EOM, q, op_point=[], noAcc=True, noVel=False, extraSubs=[]):
    qd = [qi.diff(dynamicsymbols._t) for qi in q]
    qdd = [qdi.diff(dynamicsymbols._t) for qdi in qd]

    with Timer('Linearization', True):
        # NOTE: order important
        op_point = []
        if noAcc:
            op_point += [(qddi, 0) for qddi in qdd]
        if noVel:
            op_point += [(qdi, 0) for qdi in qd]

        # --- Inputs are dynamic symbols that are not coordinates
        dyn_symbols = find_dynamicsymbols(EOM)
        all_q = q + qd + qdd
        inputs = [s for s in dyn_symbols if s not in all_q]
        II = np.argsort([str(v) for v in inputs])  # sorting for consistency
        inputs = list(np.array(inputs)[II])
        # KEEP ME Alternative
        #M, A, B = linearizer.linearize(op_point=op_point ) #o

        M = -EOM.jacobian(qdd).subs(extraSubs).subs(op_point)
        C = -EOM.jacobian(qd).subs(extraSubs).subs(op_point)
        K = -EOM.jacobian(q).subs(extraSubs).subs(op_point)
        if len(inputs) > 0:
            B = EOM.jacobian(inputs).subs(extraSubs).subs(op_point)
        else:
            B = Matrix([])
    return M, C, K, B, inputs
Beispiel #4
0
 def smallAngleApprox(self, angle_list, order=1):
     """ 
     Apply small angle approximation to EOM
     """
     with Timer('Small angle approx', True):
         self.EOM = smallAngleApprox(self.EOM, angle_list, order=order)
     self.smallAngleUsed += angle_list
Beispiel #5
0
 def smallAngleApproxEOM(self, angle_list, extraSubs=[]):
     """ 
     Apply small angle approximation to equation of motion H(x,xd,xdd,..)=0
     """
     EOM = self.EOM
     with Timer('Small angle approx. EOM', True):
         EOM = EOM.subs(extraSubs)
         EOM = smallAngleApprox(EOM, angle_list).subs(extraSubs)
     #with Timer('Small angle approx. EOM simplify',True):
     #    EOM.simplify()
     self._sa_EOM = EOM
Beispiel #6
0
    def _linearize(self,
                   op_point=[],
                   EOM=None,
                   noAcc=True,
                   noVel=False,
                   extraSubs=[]):
        if EOM is None:
            EOM = self.EOM

        with Timer('Linearization', True):
            # NOTE: order important
            op_point = []
            if noAcc:
                op_point += [(qdd, 0) for qdd in self.coordinates_acc]
                op_point += [(diff(qd, dynamicsymbols._t), 0)
                             for qd in self.speeds]
            if noVel:
                op_point += [(qd, 0) for qd in self.coordinates_speed]
                op_point += [(qd, 0) for qd in self.speeds]

            # ---  Using kane to get "r"...
            linearizer = self.kane.to_linearizer()
            self.var = self.kane._lin_r
            II = np.argsort([str(v) for v in self.var])
            self.var = list(np.array(self.var)[II])
            # KEEP ME Alternative
            #M, A, B = linearizer.linearize(op_point=op_point ) #o

            M = -EOM.jacobian(
                self.coordinates_acc).subs(extraSubs).subs(op_point)
            C = -EOM.jacobian(
                self.coordinates_speed).subs(extraSubs).subs(op_point)
            K = -EOM.jacobian(self.coordinates).subs(extraSubs).subs(op_point)
            if len(self.var) > 0:
                B = EOM.jacobian(self.var).subs(extraSubs).subs(op_point)
            else:
                B = Matrix([])

        return M, C, K, B
Beispiel #7
0
    ax.tick_params(direction='in')
    ax.autoscale(enable=True, axis='both', tight=True)
    ax.set_xlabel('Time [s]')
    ax.set_ylabel(r'Wind speed [m/s]')
    ax.set_title('Wind - wind generation at point')

    ax = axes[1]
    ax.plot(f_fft, S_fft, '-', label='Generated')
    ax.plot(freq, S, 'k', label='Kaimal')
    ax.set_yscale('log')
    ax.set_xscale('log')
    ax.legend()
    ax.set_xlabel('Frequency [Hz]')
    ax.set_ylabel(r'Spectral density [m$^2$ s]')
    ax.tick_params(direction='in')
    ax.autoscale(enable=True, axis='both', tight=True)


if __name__ == '__main__':
    from welib.tools.tictoc import Timer
    with Timer('ifft'):
        generateTSPlot(method='ifft')
    #generateTS(method='sum')
    plt.show()

if __name__ == '__export__':
    generateTSPlot(method='ifft')

    from welib.tools.repo import export_figs_callback
    export_figs_callback(__file__)
Beispiel #8
0
if __name__ == '__main__':

    from welib.tools.spectral import fft_wrap
    from welib.tools.tictoc import Timer

    seed(11)

    U0    = 8      # Wind speed [m/s], for Kaimal spectrum
    I     = 0.14   # Turbulence intensity [-], for Kaimal spectrum
    L     = 340.2  # Length scale [m], for Kaimal spectrum
    tMax  = 800    # Maximum time for time series [s]
    dt    = 0.01   # Time step [s]

    for method in ['sum','ifft']:
        with Timer(method):
            t, u, freq, S =pointTSKaimal(tMax, dt, U0, U0*I, L, method=method)

        # --- Compute FFT of wind speed
        f_fft, S_fft, Info = fft_wrap(t, u, output_type='PSD', averaging='none')

        # --- Plots
        import matplotlib.pyplot as plt
        fig,axes = plt.subplots(2, 1, sharey=False, figsize=(6.4,4.8)) # (6.4,4.8)
        fig.subplots_adjust(left=0.12, right=0.95, top=0.95, bottom=0.11, hspace=0.30, wspace=0.20)

        ax=axes[0]
        ax.plot(t, u)
        ax.tick_params(direction='in')
        ax.autoscale(enable=True, axis='both', tight=True)
        ax.set_xlabel('Time [s]')
Beispiel #9
0
    def savePython(self,
                   prefix='',
                   suffix='',
                   folder='./',
                   extraSubs=[],
                   replaceDict=None,
                   doSimplify=False,
                   velSubs=[(0, 0)]):
        """ Export EOM to a python file (will be rewritten) """

        name = prefix + self.name
        if len(suffix) > 0:
            name = name + '_' + suffix.strip('_')
        filename = os.path.join(folder, name + '.py')
        # --- replace  dict
        if replaceDict is None:
            replaceDict = OrderedDict()
        replaceDict.update(self.bodyReplaceDict)
        #print(replaceDict)

        with Timer('Python to {}'.format(filename), True):
            with open(filename, 'w') as f:
                f.write('"""\n')
                f.write('Equations of motion\n')
                f.write('model name: {}\n'.format(self.name))
                f.write('"""\n')
                f.write('import numpy as np\n')
                f.write('from numpy import cos, sin\n')

                infoToPy(f, self.name, self.q, self.input_vars)

                if self.M is not None:
                    forcingToPy(f,
                                self.q,
                                self.F,
                                replaceDict=replaceDict,
                                extraSubs=extraSubs,
                                velSubs=velSubs,
                                doSimplify=doSimplify)
                    MMToPy(f,
                           self.q,
                           self.M,
                           replaceDict=replaceDict,
                           extraSubs=extraSubs,
                           velSubs=velSubs,
                           doSimplify=doSimplify)

                if self.M0 is not None:
                    M0ToPy(f,
                           self.q,
                           self.M0,
                           replaceDict=replaceDict,
                           extraSubs=extraSubs,
                           velSubs=velSubs,
                           doSimplify=doSimplify)
                    C0ToPy(f,
                           self.q,
                           self.C0,
                           replaceDict=replaceDict,
                           extraSubs=extraSubs,
                           velSubs=velSubs,
                           doSimplify=doSimplify)
                    K0ToPy(f,
                           self.q,
                           self.K0,
                           replaceDict=replaceDict,
                           extraSubs=extraSubs,
                           velSubs=velSubs,
                           doSimplify=doSimplify)
                    B0ToPy(f,
                           self.q,
                           self.B0,
                           self.input_vars,
                           replaceDict=replaceDict,
                           extraSubs=extraSubs,
                           velSubs=velSubs,
                           doSimplify=doSimplify)
Beispiel #10
0
    def saveTex(self,
                prefix='',
                suffix='',
                folder='./',
                extraSubs=[],
                header=True,
                extraHeader=None,
                variables=['M', 'F', 'M0', 'C0', 'K0', 'B0'],
                doSimplify=False,
                velSubs=[(0, 0)]):
        """ 
        Save EOM to a latex file
        """
        name = prefix + self.name
        if len(suffix) > 0:
            name = name + '_' + suffix.strip('_')

        filename = os.path.join(folder, name + '.tex')
        with Timer('Latex to {}'.format(filename), True):
            with open(filename, 'w') as f:
                if header:
                    f.write('Model: {}, \n'.format(self.name.replace(
                        '_', '\_')))
                    f.write('Degrees of freedom: ${}$, \n'.format(
                        cleantex(self.q)))
                    try:
                        f.write('Small angles:       ${}$\\\\ \n'.format(
                            cleantex(self.smallAngleUsed)))
                    except:
                        pass
                    f.write('Free vars:       ${}$\\\\ \n'.format(
                        cleantex(self.input_vars)))

                if extraHeader:
                    f.write('\\clearpage\n{}\\\\\n'.format(extraHeader))

                if 'F' in variables:
                    toTex(f,
                          self.F,
                          label='Forcing',
                          fullPage=True,
                          extraSubs=extraSubs,
                          velSubs=velSubs,
                          doSimplify=doSimplify)
                if 'M' in variables:
                    toTex(f,
                          self.M,
                          label='Mass matrix',
                          fullPage=True,
                          extraSubs=extraSubs,
                          velSubs=velSubs,
                          doSimplify=doSimplify)
                if 'M0' in variables:
                    toTex(f,
                          self.M0,
                          label='Linearized mass matrix',
                          fullPage=True,
                          extraSubs=extraSubs,
                          velSubs=velSubs,
                          doSimplify=doSimplify)
                if 'C0' in variables:
                    toTex(f,
                          self.C0,
                          label='Linearized damping matrix',
                          fullPage=True,
                          extraSubs=extraSubs,
                          velSubs=velSubs,
                          doSimplify=doSimplify)
                if 'K0' in variables:
                    toTex(f,
                          self.K0,
                          label='Linearized stiffness matrix',
                          fullPage=True,
                          extraSubs=extraSubs,
                          velSubs=velSubs,
                          doSimplify=doSimplify)
                if 'B0' in variables:
                    toTex(f,
                          self.B0,
                          label='Linearized forcing matrix',
                          fullPage=True,
                          extraSubs=extraSubs,
                          velSubs=velSubs,
                          doSimplify=doSimplify)
Beispiel #11
0
 def simplify(self):
     """ Simplify equations of motion """
     with Timer('Simplify', True):
         self.EOM.simplify()
Beispiel #12
0
    def savePython(self,
                   prefix='',
                   suffix='',
                   folder='./',
                   extraSubs=[],
                   variables=[
                       'MM', 'FF', 'MMsa', 'FFsa', 'M', 'C', 'K', 'B', 'Msa',
                       'Csa', 'Ksa', 'Bsa'
                   ],
                   replaceDict=None,
                   doSimplify=False,
                   velSubs=[(0, 0)]):
        """ 
        Save forcing, mass matrix and linear model to python package
        """
        name = prefix + self.name
        if len(suffix) > 0:
            name = name + '_' + suffix.strip('_')

        filename = os.path.join(folder, name + '.py')

        # --- replace  dict
        if replaceDict is None:
            replaceDict = OrderedDict()
        for b in self.bodies:
            if isinstance(b, YAMSFlexibleBody):
                b.replaceDict(replaceDict)
        #print(replaceDict)

        with Timer('Python to {}'.format(filename), True):
            with open(filename, 'w') as f:
                f.write('"""\n')
                f.write('{}\n'.format(self.__repr__()))
                f.write('"""\n')
                f.write('import numpy as np\n')
                f.write('from numpy import cos, sin\n')

                infoToPy(f, self.name, self.coordinates, self.var)

                if 'FF' in variables:
                    forcing = self.kane.forcing.subs(self.kdeqsSubs)
                    forcingToPy(f,
                                self.coordinates,
                                forcing,
                                replaceDict=replaceDict,
                                extraSubs=extraSubs,
                                velSubs=velSubs,
                                doSimplify=doSimplify)
                if 'MM' in variables:
                    MM = self.kane.mass_matrix.subs(self.kdeqsSubs)
                    MMToPy(f,
                           self.coordinates,
                           MM,
                           replaceDict=replaceDict,
                           extraSubs=extraSubs,
                           velSubs=velSubs,
                           doSimplify=doSimplify)
                if 'M' in variables:
                    M0ToPy(f,
                           self.coordinates,
                           self.M,
                           replaceDict=replaceDict,
                           extraSubs=extraSubs,
                           velSubs=velSubs,
                           doSimplify=doSimplify)
                if 'C' in variables:
                    C0ToPy(f,
                           self.coordinates,
                           self.M,
                           replaceDict=replaceDict,
                           extraSubs=extraSubs,
                           velSubs=velSubs,
                           doSimplify=doSimplify)
                if 'K' in variables:
                    K0ToPy(f,
                           self.coordinates,
                           self.M,
                           replaceDict=replaceDict,
                           extraSubs=extraSubs,
                           velSubs=velSubs,
                           doSimplify=doSimplify)
                if 'B' in variables:
                    B0ToPy(f,
                           self.coordinates,
                           self.M,
                           self.var,
                           replaceDict=replaceDict,
                           extraSubs=extraSubs,
                           velSubs=velSubs,
                           doSimplify=doSimplify)

                if 'FFsa' in variables:
                    FF = subs_no_diff(self._sa_forcing, extraSubs)
                    FF = FF.subs(velSubs)
                    if doSimplify:
                        FF = FF.simplify()
                    s, params, inputs, sdofs = cleanPy(FF,
                                                       varname='FF',
                                                       dofs=self.coordinates,
                                                       indent=4,
                                                       replDict=replaceDict)
                    f.write(
                        'def forcing_sa(t,q=None,qd=None,p=None,u=None,z=None):\n'
                    )
                    f.write(
                        '    """ Non linear forcing with small angle approximation\n'
                    )
                    f.write(
                        '    q:  degrees of freedom, array-like: {}\n'.format(
                            sdofs))
                    f.write('    qd: dof velocities, array-like\n')
                    f.write('    p:  parameters, dictionary with keys: {}\n'.
                            format(params))
                    f.write(
                        '    u:  inputs, dictionary with keys: {}\n'.format(
                            inputs))
                    f.write(
                        '           where each values is a function of time\n')
                    f.write('    """\n')
                    f.write('    if z is not None:\n')
                    f.write('        q  = z[0:int(len(z)/2)] \n')
                    f.write('        qd = z[int(len(z)/2): ] \n')
                    f.write(s)
                    f.write('    return FF\n\n')

                if 'MMsa' in variables:
                    MM = subs_no_diff(self._sa_mass_matrix, extraSubs)
                    MM = MM.subs(velSubs)
                    if doSimplify:
                        MM.simplify()
                    s, params, inputs, sdofs = cleanPy(MM,
                                                       varname='MM',
                                                       dofs=self.coordinates,
                                                       indent=4,
                                                       replDict=replaceDict)
                    f.write('def mass_matrix_sa(q=None,p=None,z=None):\n')
                    f.write(
                        '    """ Non linear mass matrix with small angle approximation\n'
                    )
                    f.write(
                        '     q:  degrees of freedom, array-like: {}\n'.format(
                            sdofs))
                    f.write('     p:  parameters, dictionary with keys: {}\n'.
                            format(params))
                    f.write('    """\n')
                    f.write('    if z is not None:\n')
                    f.write('        q  = z[0:int(len(z)/2)] \n')
                    f.write(s)
                    f.write('    return MM\n\n')

                if 'Msa' in variables:
                    MM = subs_no_diff(self._sa_M, extraSubs)
                    MM = MM.subs(velSubs)
                    if doSimplify:
                        MM.simplify()
                    s, params, inputs, sdofs = cleanPy(MM,
                                                       varname='MM',
                                                       dofs=self.coordinates,
                                                       indent=4,
                                                       replDict=replaceDict,
                                                       noTimeDep=True)
                    f.write('def M_lin_sa(q=None,p=None,z=None):\n')
                    f.write(
                        '    """ Linear mass matrix with small angle approximation\n'
                    )
                    f.write(
                        '    q:  degrees of freedom at operating point, array-like: {}\n'
                        .format(sdofs))
                    f.write('    p:  parameters, dictionary with keys: {}\n'.
                            format(params))
                    f.write('    """\n')
                    f.write('    if z is not None:\n')
                    f.write('        q  = z[0:int(len(z)/2)] \n')
                    f.write(s)
                    f.write('    return MM\n\n')

                if 'Csa' in variables:
                    MM = subs_no_diff(self._sa_C, extraSubs)
                    MM = MM.subs(velSubs)
                    if doSimplify:
                        MM.simplify()
                    s, params, inputs, sdofs = cleanPy(MM,
                                                       varname='CC',
                                                       dofs=self.coordinates,
                                                       indent=4,
                                                       replDict=replaceDict,
                                                       noTimeDep=True)
                    f.write(
                        'def C_lin_sa(q=None,qd=None,p=None,u=None,z=None):\n')
                    f.write(
                        '    """ Linear damping matrix with small angle approximation\n'
                    )
                    f.write(
                        '    q:  degrees of freedom at operating point, array-like: {}\n'
                        .format(sdofs))
                    f.write(
                        '    qd: dof velocities at operating point, array-like\n'
                    )
                    f.write('    p:  parameters, dictionary with keys: {}\n'.
                            format(params))
                    f.write(
                        '    u:  inputs at operating point, dictionary with keys: {}\n'
                        .format(inputs))
                    f.write('           where each values is a constant!\n')
                    f.write('    """\n')
                    f.write('    if z is not None:\n')
                    f.write('        q  = z[0:int(len(z)/2)] \n')
                    f.write('        qd = z[int(len(z)/2): ] \n')
                    f.write(s)
                    f.write('    return CC\n\n')

                if 'Ksa' in variables:
                    MM = subs_no_diff(self._sa_K, extraSubs)
                    MM = MM.subs(velSubs)
                    if doSimplify:
                        MM.simplify()
                    s, params, inputs, sdofs = cleanPy(MM,
                                                       varname='KK',
                                                       dofs=self.coordinates,
                                                       indent=4,
                                                       replDict=replaceDict,
                                                       noTimeDep=True)
                    f.write(
                        'def K_lin_sa(q=None,qd=None,p=None,u=None,z=None):\n')
                    f.write(
                        '    """ Linear stiffness matrix with small angle approximation\n'
                    )
                    f.write(
                        '    q:  degrees of freedom, array-like: {}\n'.format(
                            sdofs))
                    f.write('    qd: dof velocities, array-like\n')
                    f.write('    p:  parameters, dictionary with keys: {}\n'.
                            format(params))
                    f.write(
                        '    u:  inputs at operating point, dictionary with keys: {}\n'
                        .format(inputs))
                    f.write('           where each values is a constant!\n')
                    f.write('    """\n')
                    f.write('    if z is not None:\n')
                    f.write('        q  = z[0:int(len(z)/2)] \n')
                    f.write('        qd = z[int(len(z)/2): ] \n')
                    f.write(s)
                    f.write('    return KK\n\n')

                if 'Bsa' in variables:
                    MM = subs_no_diff(self._sa_B, extraSubs)
                    MM = MM.subs(velSubs)
                    if doSimplify:
                        MM.simplify()
                    s, params, inputs, sdofs = cleanPy(MM,
                                                       varname='BB',
                                                       dofs=self.coordinates,
                                                       indent=4,
                                                       replDict=replaceDict,
                                                       noTimeDep=True)
                    f.write('def B_lin_sa(q=None,qd=None,p=None,u=None):\n')
                    f.write(
                        '    """ Linear mass matrix with small angle approximation\n'
                    )
                    f.write(
                        '    q:  degrees of freedom at operating point, array-like: {}\n'
                        .format(sdofs))
                    f.write(
                        '    qd: dof velocities at operating point, array-like\n'
                    )
                    f.write('    p:  parameters, dictionary with keys: {}\n'.
                            format(params))
                    f.write(
                        '    u:  inputs at operating point, dictionary with keys: {}\n'
                        .format(inputs))
                    f.write('           where each values is a constant!\n')
                    f.write('    The columns of B correspond to:   {}\\\\ \n'.
                            format(self.var))
                    f.write('    """\n')
                    f.write(s)
                    f.write('    return BB\n\n')
Beispiel #13
0
    def saveTex(self,
                prefix='',
                suffix='',
                folder='./',
                extraSubs=[],
                header=True,
                extraHeader=None,
                variables=[
                    'MM', 'FF', 'M', 'C', 'K', 'B', 'MMsa', 'FFsa', 'Msa',
                    'Csa', 'Ksa', 'Bsa'
                ],
                doSimplify=False,
                velSubs=[(0, 0)]):
        """ 
        Save forcing and mass matrix to latex file
        """
        name = prefix + self.name
        if len(suffix) > 0:
            name = name + '_' + suffix.strip('_')

        filename = os.path.join(folder, name + '.tex')
        with Timer('Latex to {}'.format(filename), True):
            with open(filename, 'w') as f:
                if header:
                    f.write('Model: {}, \n'.format(self.name.replace(
                        '_', '\_')))
                    f.write('Degrees of freedom: ${}$, \n'.format(
                        cleantex(self.coordinates)))
                    try:
                        f.write('Small angles:       ${}$\\\\ \n'.format(
                            cleantex(self.smallAngleUsed)))
                    except:
                        pass
                    f.write('Free vars:       ${}$\\\\ \n'.format(
                        cleantex(self.var)))
                if extraHeader:
                    f.write('\\clearpage\n{}\\\\\n'.format(extraHeader))
                if 'F' in variables:
                    FF = self.kane.forcing.subs(self.kdeqsSubs)
                    toTex(f,
                          FF,
                          label='Forcing',
                          fullPage=True,
                          extraSubs=extraSubs,
                          velSubs=velSubs,
                          doSimplify=doSimplify)
                if 'M' in variables:
                    MM = self.kane.mass_matrix.subs(
                        self.kdeqsSubs)  # NOTE this is wrong
                    toTex(f,
                          MM,
                          label='Mass matrix',
                          fullPage=True,
                          extraSubs=extraSubs,
                          velSubs=velSubs,
                          doSimplify=doSimplify)
                if 'M0' in variables:
                    toTex(f,
                          self.M0,
                          label='Linearized mass matrix',
                          fullPage=True,
                          extraSubs=extraSubs,
                          velSubs=velSubs,
                          doSimplify=doSimplify)
                if 'C0' in variables:
                    toTex(f,
                          self.C0,
                          label='Linearized damping matrix',
                          fullPage=True,
                          extraSubs=extraSubs,
                          velSubs=velSubs,
                          doSimplify=doSimplify)
                if 'K0' in variables:
                    toTex(f,
                          self.K0,
                          label='Linearized stiffness matrix',
                          fullPage=True,
                          extraSubs=extraSubs,
                          velSubs=velSubs,
                          doSimplify=doSimplify)
                if 'B0' in variables:
                    toTex(f,
                          self.B0,
                          label='Linearized forcing matrix',
                          fullPage=True,
                          extraSubs=extraSubs,
                          velSubs=velSubs,
                          doSimplify=doSimplify)
                if 'FFsa' in variables:
                    FF = subs_no_diff(self._sa_forcing, extraSubs)
                    toTex(f,
                          FF,
                          label='Forcing small angle',
                          fullPage=True,
                          extraSubs=extraSubs,
                          velSubs=velSubs,
                          doSimplify=doSimplify)
                if 'MMsa' in variables:
                    toTex(f,
                          self._sa_mass_matrix,
                          label='Mass matrix small angle',
                          fullPage=True,
                          extraSubs=extraSubs,
                          velSubs=velSubs,
                          doSimplify=doSimplify)
                if 'Msa' in variables:
                    toTex(f,
                          self._sa_M,
                          label='Linearized mass matrix small angle',
                          fullPage=True,
                          extraSubs=extraSubs,
                          velSubs=velSubs,
                          doSimplify=doSimplify)
                if 'Csa' in variables:
                    toTex(f,
                          self._sa_C,
                          label='Linearized damping matrix small angle',
                          fullPage=True,
                          extraSubs=extraSubs,
                          velSubs=velSubs,
                          doSimplify=doSimplify)
                if 'Ksa' in variables:
                    toTex(f,
                          self._sa_K,
                          label='Linearized stiffness matrix small angle',
                          fullPage=True,
                          extraSubs=extraSubs,
                          velSubs=velSubs,
                          doSimplify=doSimplify)
                if 'Bsa' in variables:
                    toTex(f,
                          self._sa_K,
                          label='Linearized forcing small angle',
                          fullPage=True,
                          extraSubs=extraSubs,
                          velSubs=velSubs,
                          doSimplify=doSimplify)