def EXTR_MATR_GENE(self, typmat): """ retourne les valeurs des matrices generalisees reelles dans un format numpy typmat='MASS_GENE' pour obtenir la matrice de masse generalisee typmat='RIGI_GENE' pour obtenir la matrice de raideur generalisee typmat='AMOR_GENE' pour obtenir la matrice d'amortissement generalisee Attributs retourne - self.valeurs : numpy.array contenant les valeurs """ import numpy if not self.accessible(): raise AsException( "Erreur dans macr_elem_dyna.EXTR_MATR_GENE en PAR_LOT='OUI'") if (typmat == 'MASS_GENE'): macr_elem = self.sdj.MAEL_MASS elif (typmat == 'RIGI_GENE'): macr_elem = self.sdj.MAEL_RAID elif (typmat == 'AMOR_GENE'): macr_elem = self.sdj.MAEL_AMOR else: raise AsException("Le type de la matrice est incorrect") desc = macr_elem.DESC.get() # On teste si le DESC de la matrice existe if not desc: raise AsException("L'objet matrice {0!r} n'existe pas".format( macr_elem.DESC.nomj())) desc = numpy.array(desc) matrice = VALM_triang2array(macr_elem.VALE.get(), desc[1]) return matrice
def Valeurs(self): """ Retourne deux listes de valeurs : abscisses et ordonnees """ from Utilitai.Utmess import UTMESS if self.accessible(): vale = '%-19s.VALE' % self.get_name() lbl = self.sdj.VALE.get() if lbl == None: UTMESS('F', 'SDVERI_2', valk=[vale]) lbl = list(lbl) dim = len(lbl) / 2 lx = lbl[0:dim] ly = lbl[dim:2 * dim] elif hasattr(self, 'etape') and self.etape.nom == 'DEFI_FONCTION': if self.etape['VALE'] is not None: lbl = list(self.etape['VALE']) dim = len(lbl) lx = [lbl[i] for i in range(0, dim, 2)] ly = [lbl[i] for i in range(1, dim, 2)] elif self.etape['VALE_PARA'] is not None: lx = self.etape['VALE_PARA'].Valeurs() ly = self.etape['VALE_FONC'].Valeurs() elif self.etape['ABSCISSE'] is not None: lx = self.etape['ABSCISSE'] ly = self.etape['ORDONNEE'] else: raise AsException("Erreur (fonction.Valeurs) : ne fonctionne en " "PAR_LOT='OUI' que sur des fonctions produites " "par DEFI_FONCTION dans le jdc courant.") else: raise AsException("Erreur (fonction.Valeurs) : ne fonctionne en " "PAR_LOT='OUI' que sur des fonctions produites " "par DEFI_FONCTION dans le jdc courant.") return [lx, ly]
def RECU_VECT_GENE_C(self, vecteur): """ envoie les valeurs d'un tableau numpy dans un vecteur generalise complexe definie dans jeveux Attributs ne retourne rien """ if not self.accessible(): raise AsException( "Erreur dans vect_asse_gene_c.RECU_VECT_GENE en PAR_LOT='OUI'") import numpy numpy.asarray(vecteur) ncham = self.get_name() ncham = ncham + (8 - len(ncham)) * ' ' desc = self.sdj.DESC.get() # On teste si le DESC de la matrice existe if not desc: raise AsException("L'objet vecteur {0!r} n'existe pas".format( self.sdj.DESC.nomj())) desc = numpy.array(desc) # On teste si la taille de la matrice jeveux et python est identique if desc[1] != numpy.shape(vecteur)[0]: raise AsException("La taille du vecteur python est incorrecte") tmpr = vecteur.real tmpc = vecteur.imag aster.putvectjev(ncham + (19 - len(ncham)) * ' ' + '.VALE', len(tmpr), tuple(range(1, len(tmpr) + 1)), tuple(tmpr), tuple(tmpc), 1) return
def EXTR_MATR_GENE(self) : """ retourne les valeurs de la matrice generalisee reelle dans un format numpyal Array Attributs retourne - self.valeurs : numpy.array contenant les valeurs """ if not self.accessible(): raise AsException("Erreur dans matr_asse_gene.EXTR_MATR_GENE en PAR_LOT='OUI'") import numpy desc = self.sdj.DESC.get() # On teste si le DESC du vecteur existe if not desc: raise AsException("L'objet vecteur {0!r} n'existe pas" .format(self.sdj.DESC.nomj())) desc = numpy.array(desc) # Si le stockage est plein if desc[2]==2 : valeur = VALM_triang2array(self.sdj.VALM.get(), desc[1]) # Si le stockage est diagonal elif desc[2]==1 : valeur = VALM_diag2array(self.sdj.VALM.get(), desc[1]) # Sinon on arrete tout else: raise KeyError return valeur
def __check_input_inoli(self, inoli): if (inoli==-1) : print "Nonlinearity index not specified, by default the first nonlinearity will be considered." inoli = 1 nbnoli = self.__nb_nonl() if nbnoli == 0 : raise AsException("Linear calculation, no information can be retrieved.") if( inoli <= 0) or (inoli > nbnoli): raise AsException("The nonlinearity index should be a comprised between 1 and %d, the total number of nonlinearities."%(nbnoli)) return inoli
def RECU_MATR_GENE(self,matrice) : """ envoie les valeurs d'un tableau numpy dans des matrices generalisees reelles definies dans jeveux Attributs ne retourne rien """ import numpy if not self.accessible(): raise AsException("Erreur dans matr_asse_gene_c.RECU_MATR_GENE en PAR_LOT='OUI'") numpy.asarray(matrice) ncham=self.get_name() desc = self.sdj.DESC.get() # On teste si le DESC de la matrice existe if not desc: raise AsException("L'objet matrice {0!r} n'existe pas" .format(self.sdj.DESC.nomj())) desc = numpy.array(desc) numpy.asarray(matrice) # On teste si la dimension de la matrice python est 2 if (len(numpy.shape(matrice)) != 2) : raise AsException("La dimension de la matrice est incorrecte ") # On teste si la taille de la matrice jeveux et python est identique if (tuple([desc[1],desc[1]]) != numpy.shape(matrice)) : raise AsException("La taille de la matrice est incorrecte ") # Si le stockage est plein if desc[2]==2 : taille=desc[1]*desc[1]/2.0+desc[1]/2.0 tmpr=numpy.zeros([int(taille)]) tmpc=numpy.zeros([int(taille)]) for j in range(desc[1]+1): for i in range(j): k=j*(j-1)/2+i tmpr[k]=matrice[j-1,i].real tmpc[k]=matrice[j-1,i].imag aster.putvectjev('%-19s.VALM' % ncham, len(tmpr), tuple((\ range(1,len(tmpr)+1))),tuple(tmpr),tuple(tmpc),1) # Si le stockage est diagonal elif desc[2]==1 : tmpr=numpy.zeros(desc[1]) tmpc=numpy.zeros(desc[1]) for j in range(desc[1]): tmpr[j]=matrice[j,j].real tmpc[j]=matrice[j,j].imag aster.putvectjev('%-19s.VALM' % ncham,len(tmpr),tuple((\ range(1,len(tmpr)+1))),tuple(tmpr),tuple(tmpc),1) # Sinon on arrete tout else: raise KeyError return
def RCVALE(self, phenomene, nompar=(), valpar=(), nomres=(), stop=1): """Appel à la routine fortran RCVALE pour récupérer les valeurs des propriétés du matériau. """ if not self.accessible(): raise AsException("Erreur dans mater.RCVALE en PAR_LOT='OUI'") from Utilitai.Utmess import UTMESS # vérification des arguments if not type(nompar) in (list, tuple): nompar = [nompar,] if not type(valpar) in (list, tuple): valpar = [valpar,] if not type(nomres) in (list, tuple): nomres = [nomres,] nompar = tuple(nompar) valpar = tuple(valpar) nomres = tuple(nomres) if len(nompar) != len(valpar): vk1=', '.join(nompar) vk2=', '.join([repr(v) for v in valpar]) UTMESS('F','SDVERI_4',valk=[vk1,vk2]) if len(nomres) < 1: UTMESS('F', 'SDVERI_5') # appel à l'interface Python/C return aster.rcvale(self.nom, phenomene, nompar, valpar, nomres, stop)
def VITE_FLUI(self): """ Returns a python list of fluid velocities under which modal paramteres have been successfully calculated under the defined fluid-elastic conditions""" if not self.accessible(): # Method is not allowed for For PAR_LOT = 'OUI' calculations raise AsException( "Erreur dans melas_flu.VITE_FLUIDE() en PAR_LOT='OUI'") vite = self.sdj.VITE.get() freq_obj = self.sdj.FREQ.get() nbv = len(vite) nbm = len(freq_obj) / (2 * nbv) vite_ok = [] for iv in range(nbv): freqs = [ freq_obj[2 * nbm * (iv) + 2 * (im)] for im in range(nbm) ] # Extract a list of all modes for a given fluid velocity no. iv calc_ok = ( [freq > 0 for freq in freqs].count(False) == 0 ) # Check that all frequencies are positive for this velocity if calc_ok: vite_ok.append(vite[iv]) return vite_ok
def Valeurs(self): """ Retourne trois listes de valeurs : abscisses, parties reelles et imaginaires. """ from Utilitai.Utmess import UTMESS if self.accessible(): vale = '%-19s.VALE' % self.get_name() lbl = self.sdj.VALE.get() if lbl == None: UTMESS('F', 'SDVERI_2', valk=[vale]) lbl = list(lbl) dim = len(lbl) / 3 lx = lbl[0:dim] lr = [] li = [] for i in range(dim): lr.append(lbl[dim + 2 * i]) li.append(lbl[dim + 2 * i + 1]) elif hasattr(self, 'etape') and self.etape.nom == 'DEFI_FONCTION' \ and self.etape['VALE_C'] is not None: lbl = list(self.etape['VALE_C']) dim = len(lbl) lx = [lbl[i] for i in range(0, dim, 3)] lr = [lbl[i] for i in range(1, dim, 3)] li = [lbl[i] for i in range(2, dim, 3)] else: raise AsException("Erreur (fonction_c.Valeurs) : ne fonctionne en " "PAR_LOT='OUI' que sur des fonctions produites " "par DEFI_FONCTION dans le jdc courant.") return [lx, lr, li]
def Parametres(self): """ Retourne un dictionnaire contenant les parametres de la nappe, le type jeveux (NAPPE) n'est pas retourne, le dictionnaire peut ainsi etre fourni a CALC_FONC_INTERP tel quel, et une liste de dictionnaire des parametres de chaque fonction. """ from Utilitai.Utmess import UTMESS if not self.accessible(): raise AsException( "Erreur dans nappe.Parametres en PAR_LOT='OUI'") TypeProl = {'E': 'EXCLU', 'L': 'LINEAIRE', 'C': 'CONSTANT'} objev = '%-19s.PROL' % self.get_name() prol = aster.getvectjev(objev) if prol == None: UTMESS('F', 'SDVERI_2', valk=[objev]) dico = { 'INTERPOL': [prol[1][0:3], prol[1][4:7]], 'NOM_PARA': prol[2][0:16].strip(), 'NOM_RESU': prol[3][0:16].strip(), 'PROL_DROITE': TypeProl[prol[4][1]], 'PROL_GAUCHE': TypeProl[prol[4][0]], 'NOM_PARA_FONC': prol[6][0:4].strip(), } lparf = [] nbf = (len(prol) - 7) / 2 for i in range(nbf): dicf = { 'INTERPOL_FONC': [prol[7 + i * 2][0:3], prol[7 + i * 2][4:7]], 'PROL_DROITE_FONC': TypeProl[prol[8 + i * 2][1]], 'PROL_GAUCHE_FONC': TypeProl[prol[8 + i * 2][0]], } lparf.append(dicf) return [dico, lparf]
def RECU_MATR_GENE(self, typmat, matrice): """ envoie les valeurs d'un tableau numpy dans des matrices generalisees reelles definies dans jeveux typmat='MASS_GENE' pour obtenir la matrice de masse generalisee typmat='RIGI_GENE' pour obtenir la matrice de raideur generalisee typmat='AMOR_GENE' pour obtenir la matrice d'amortissement generalisee Attributs ne retourne rien """ import numpy if not self.accessible(): raise AsException( "Erreur dans macr_elem_dyna.RECU_MATR_GENE en PAR_LOT='OUI'") nommacr = self.get_name() if (typmat == 'MASS_GENE'): macr_elem = self.sdj.MAEL_MASS elif (typmat == 'RIGI_GENE'): macr_elem = self.sdj.MAEL_RAID elif (typmat == 'AMOR_GENE'): macr_elem = self.sdj.MAEL_AMOR else: raise AsException("Le type de la matrice est incorrect") nom_vale = macr_elem.VALE.nomj() desc = macr_elem.DESC.get() # On teste si le DESC de la matrice existe if not desc: raise AsException("L'objet matrice {0!r} n'existe pas".format( macr_elem.DESC.nomj())) desc = numpy.array(desc) numpy.asarray(matrice) # On teste si la matrice python est de dimension 2 if (len(numpy.shape(matrice)) <> 2): raise AsException("La dimension de la matrice est incorrecte") # On teste si les tailles de la matrice jeveux et python sont identiques if (tuple([desc[1], desc[1]]) <> numpy.shape(matrice)): raise AsException("La dimension de la matrice est incorrecte") taille = desc[1] * desc[1] / 2.0 + desc[1] / 2.0 tmp = numpy.zeros([int(taille)]) for j in range(desc[1] + 1): for i in range(j): k = j * (j - 1) / 2 + i tmp[k] = matrice[j - 1, i] aster.putvectjev(nom_vale, len(tmp), tuple((range(1, len(tmp) + 1))), tuple(tmp), tuple(tmp), 1)
def FORCE_NORMALE (self, inoli=-1): """ Returns a 1D numpy array giving the evolution of the normal force at the archived instants""" if not self.accessible(): raise AsException("Erreur dans tran_gene.FORCE_NORMALE() en PAR_LOT='OUI'") inoli = self.__check_input_inoli(inoli) nltypes = self.__type_nonl() if not(nltypes[inoli-1] in ('DIS_CHOC', 'FLAMBAGE')) : dummy = self.INFO_NONL() raise AsException("The chosen nonlinearity index (%d) does not correspond to a DIS_CHOC or FLAMBAGE nonlinearity\nThese are the only nonlinearities that save the local normal force."%(inoli)) vint = self.VARI_INTERNE(inoli, describe=False) #The normal force is saved in the first position (ind=0) of the internal variables for DIS_CHOC and FLAMBAGE nonlinearities return vint[:,0]
def LIST_GROUP_NO(self) : """ retourne la liste des groupes de noeuds sous la forme : [ (gno1, nb noeuds gno1), ...] """ if not self.accessible(): raise AsException("Erreur dans maillage.LIST_GROUP_NO en PAR_LOT='OUI'") dic_gpno = self.sdj.GROUPENO.get() if dic_gpno is None: return [] return [(gpno.strip(),len(dic_gpno[gpno])) for gpno in dic_gpno]
def LIST_ARCH (self): """ Returns a python list of all archived frequencies """ if not self.accessible(): raise AsException("Erreur dans harm_gene.LIST_ARCH() en PAR_LOT='OUI'") disc = self.sdj.DISC.get() return list(disc)
def LIST_PAS_TEMPS (self): """ Returns a python list of the integration steps """ if not self.accessible(): raise AsException("Erreur dans tran_gene.PTEM() en PAR_LOT='OUI'") step = self.sdj.PTEM.get() return list(step)
def FORCE_RELATION (self, inoli=-1): """ Returns a 1D numpy array giving the evolution of the forces defined as displacement or velocity relationships""" if not self.accessible(): raise AsException("Erreur dans tran_gene.FORCE_RELATION() en PAR_LOT='OUI'") inoli = self.__check_input_inoli(inoli) nltypes = self.__type_nonl() if not(nltypes[inoli-1] in ('RELA_EFFO_DEPL', 'RELA_EFFO_VITE')) : dummy = self.INFO_NONL() raise AsException("The chosen nonlinearity index (%d) does not correspond to a RELA_EFFO_DEPL or RELA_EFFO_VITE' nonlinearity\nThese are the only nonlinearities that calculate and save a relationship defined force."%(inoli)) vint = self.VARI_INTERNE(inoli, describe=False) #The relationship defined forces are saved in position 2 for RELA_EFFO_DEPL and RELA_EFFO_VITE nonlinearities return vint[:,1]
def LIST_LIAIS_STRUCT(self): """ retourne la liste des liaisons entre sous structures du modele generalise sous la forme : [ (ss1, nom_liais1, ss2 , nom_liais2), ...] """ if not self.accessible(): raise AsException( "Erreur dans modele_gene.LIST_LIAIS_STRUCT en PAR_LOT='OUI'") nommodgen = self.get_name() ncham = nommodgen + (8 - len(nommodgen)) * ' ' lidf = aster.getcolljev(ncham + (14 - len(ncham)) * ' ' + '.MODG.LIDF') return [([(lidf[ind][indb]) for indb in range(4)]) for ind in lidf]
def EXTR_TABLE(self, para=None): """Produit un objet Table à partir du contenu d'une table Aster. On peut limiter aux paramètres listés dans 'para'. """ def Nonefy(l1, l2): if l2 == 0: return None else: return l1 if not self.accessible(): raise AsException("Erreur dans table.EXTR_TABLE en PAR_LOT='OUI'") from Utilitai.Table import Table # titre titr = self.TITRE() # récupération des paramètres #v_tblp = aster.getvectjev('%-19s.TBLP' % self.get_name()) v_tblp = self.sdj.TBLP.get() if v_tblp == None: # retourne une table vide return Table(titr=titr, nom=self.nom) tabnom = list(v_tblp) nparam = len(tabnom) / 4 lparam = [tabnom[4 * i:4 * i + 4] for i in range(nparam)] # restriction aux paramètres demandés if para is not None: if type(para) not in (list, tuple): para = [ para, ] para = [p.strip() for p in para] restr = [] for ip in lparam: if ip[0].strip() in para: restr.append(ip) lparam = restr dval = {} # liste des paramètres et des types lpar = [] ltyp = [] for i in lparam: value = list(aster.getvectjev(i[2])) exist = aster.getvectjev(i[3]) dval[i[0].strip()] = map(Nonefy, value, exist) lpar.append(i[0].strip()) ltyp.append(i[1].strip()) n = len(dval[lpar[0]]) # contenu : liste de dict lisdic = [] for i in range(n): d = {} for p in lpar: d[p] = dval[p][i] lisdic.append(d) return Table(lisdic, lpar, ltyp, titr, self.nom)
def Valeurs(self): """ Retourne la liste des valeurs : [val1, ..., valN] """ if not self.accessible(): raise AsException("Erreur dans listr8.Valeurs en PAR_LOT='OUI'") from Utilitai.Utmess import UTMESS t_vale = self.sdj.VALE.get() if t_vale is None: UTMESS('F', 'SDVERI_2', valk=[self.sdj.VALE.nomj()]) return list(t_vale)
def EXTR_VECT_GENE_R(self): """ retourne les valeurs du vecteur generalisee dans un format numpy Attributs retourne - self.valeurs : numpy.array contenant les valeurs """ import numpy if not self.accessible(): raise AsException( "Erreur dans vect_asse_gene_r.EXTR_VECT_GENE en PAR_LOT='OUI'") valeur = numpy.array(self.sdj.VALE.get()) return valeur
def LIST_SOUS_STRUCT(self): """ retourne la liste des sous structures du modele generalise la liste des macro-elements sous-jacents""" if not self.accessible(): raise AsException( "Erreur dans modele_gene.LIST_SOUS_STRUCT en PAR_LOT='OUI'") nommodgen = self.get_name() ncham = nommodgen + (8 - len(nommodgen)) * ' ' ssno = aster.getvectjev(ncham + (14 - len(ncham)) * ' ' + '.MODG.SSNO') ssme = aster.getcolljev(ncham + (14 - len(ncham)) * ' ' + '.MODG.SSME') return [([ssno[ind], ssme[ind + 1]]) for ind in range(len(ssno))]
def Trace(self, FORMAT='TABLEAU', **kargs): """Tracé d'une fonction""" if not self.accessible(): raise AsException("Erreur dans fonction.Trace en PAR_LOT='OUI'") from Utilitai.Graph import Graph gr = Graph() gr.AjoutCourbe(Val=self.Valeurs(), Lab=[ self.Parametres( )['NOM_PARA'], self.Parametres()['NOM_RESU']], Leg=os.linesep.join(self.sdj.TITR.get())) gr.Trace(FORMAT=FORMAT, **kargs)
def DEPL (self): """ Returns a 2D numpy array of the calculated modal displacements """ if not self.accessible(): raise AsException("Erreur dans tran_gene.DEPL() en PAR_LOT='OUI'") depl = self.sdj.DEPL.get() nbmodes = self.__nb_modes() nbsaves = len(depl)/nbmodes import numpy as np output = np.reshape(depl,(nbsaves,nbmodes)) return output
def VITE (self): """ Returns a 2D numpy array of the calculated modal velocities """ if not self.accessible(): raise AsException("Erreur dans tran_gene.VITE() en PAR_LOT='OUI'") vite = self.sdj.VITE.get() nbmodes = self.__nb_modes() nbsaves = len(vite)/nbmodes import numpy as np output = np.reshape(vite,(nbsaves,nbmodes)) return output
def ACCE (self): """ Returns a 2D numpy array of the calculated modal accelerations """ if not self.accessible(): raise AsException("Erreur dans tran_gene.ACCE() en PAR_LOT='OUI'") acce = self.sdj.ACCE.get() nbmodes = self.__nb_modes() nbsaves = len(acce)/nbmodes import numpy as np output = np.reshape(acce,(nbsaves,nbmodes)) return output
def Trace(self, FORMAT='TABLEAU', **kargs): """Tracé d'une nappe""" if not self.accessible(): raise AsException("Erreur dans nappe.Trace en PAR_LOT='OUI'") from Utilitai.Graph import Graph gr = Graph() lv = self.Valeurs()[1] dp = self.Parametres()[0] for lx, ly in lv: gr.AjoutCourbe( Val=[lx, ly], Lab=[dp['NOM_PARA_FONC'], dp['NOM_RESU']], Leg=os.linesep.join(self.sdj.TITR.get())) gr.Trace(FORMAT=FORMAT, **kargs)
def FORCE_AXIALE (self, inoli=-1): """ Returns a 1D numpy array giving the evolution of the axial force at the archived instants""" if not self.accessible(): raise AsException("Erreur dans tran_gene.FORCE_AXIALE() en PAR_LOT='OUI'") inoli = self.__check_input_inoli(inoli) nltypes = self.__type_nonl() if not(nltypes[inoli-1] in ('ANTI_SISM', 'DIS_VISC', 'DIS_ECRO_TRAC' )) : dummy = self.INFO_NONL() raise AsException("The chosen nonlinearity index (%d) does not correspond to a ANTI_SISM, DIS_VISC, or DIS_ECRO_TRAC' nonlinearity\nThese are the only nonlinearities that calculate and save an axial force."%(inoli)) vint = self.VARI_INTERNE(inoli, describe=False) #The axial forces are saved in position 1 for ANTI_SISM nonlinearities if nltypes[inoli-1] == 'ANTI_SISM' : return vint[:,0] #The axial forces are saved in position 8 for DIS_VISC and DIS_ECRO_TRAC nonlinearities return vint[:,7]
def get_nom_para(self): """Produit une liste des noms des colonnes """ if not self.accessible(): raise AsException( "Erreur dans table.get_nom_para en PAR_LOT='OUI'") l_name = [] shape = self.sdj.TBNP.get() desc = self.sdj.TBLP.get() for n in range(shape[0]): nom = desc[4 * n] l_name.append(nom.strip()) return l_name
def TITRE(self): """Retourne le titre d'une table Aster (Utile pour récupérer le titre et uniquement le titre d'une table dont on souhaite manipuler la dérivée). """ if not self.accessible(): raise AsException("Erreur dans table.TITRE en PAR_LOT='OUI'") #titj = aster.getvectjev('%-19s.TITR' % self.get_name()) titj = self.sdj.TITR.get() if titj != None: titr = '\n'.join(titj) else: titr = '' return titr
def FORCE_TANGENTIELLE (self, inoli=-1): """ Returns a 2D numpy array (2 x nbsaves - 2 : for tangential axes 1 and 2) The evolution of the tangential forces at the archived instants""" if not self.accessible(): raise AsException("Erreur dans tran_gene.FORCE_TANGENTIELLE() en PAR_LOT='OUI'") inoli = self.__check_input_inoli(inoli) nltypes = self.__type_nonl() if not(nltypes[inoli-1] in ('DIS_CHOC', 'ROTOR_FISS')) : dummy = self.INFO_NONL() raise AsException("The chosen nonlinearity index (%d) does not correspond to a DIS_CHOC or ROTOR_FISS nonlinearity\nThese are the only nonlinearities that calculate and save a local tangential force."%(inoli)) vint = self.VARI_INTERNE(inoli, describe=False) #The tangential forces are saved in positions 2 and 3 of the internal variables for DIS_CHOC nonlinearities if nltypes[inoli-1] == 'DIS_CHOC': return vint[:,1:3] #The tangential forces are saved in positions 2 and 3 of the internal variables for ROTOR_FISS nonlinearities if nltypes[inoli-1] == 'ROTOR_FISS': return vint[:,1:3]