2024-06-27 11:12:33 +02:00

172 lines
6.8 KiB
Python

import modele.composants as mc
import modele.elements as me
from modele.exceptions import Dir
from modele.donnees import GraphStructException
class Vecteur(object):
"""
Associe les éléments du graphe à leur rang dans le vecteur correspondant aux rangs dans la matrice.
"""
def __init__(self, elements):
self._liste = [eq_elt for element in elements.values() for eq_elt in element.eq_elts()]
self._index = {} # Associe à un élément son index dans la matrice
for index, element in enumerate(self._liste):
self._index[element] = index
def __len__(self):
return len(self._liste)
def index(self, element):
return self._index[element]
def __iter__(self):
return self._liste.__iter__()
class Graphe(object):
ID_BR = -1
@classmethod
def branch_id(cls):
cls.ID_BR += 1
return f"b{cls.ID_BR}"
def __init__(self, conf):
self.conf = conf
self.elements = None
self.composants = None
self.vecteur = None
self.flag_arret_simulation = False
def load_data_from_schema_reader(self, reader):
self.elements = {}
self.composants = {}
# Construction des éléments et composants
for nom, valeur in reader.composants.items():
if valeur.type == 'Bouton' or valeur.type == 'ContactTravail' or valeur.type == 'ContactRepos' \
or valeur.type == 'Levier':
self.composants[nom] = mc.Contact(self.conf, nom, valeur.type)
elif valeur.type == 'Relais':
if valeur.donnees.get('basculeur') == 'gauche':
self.composants[nom] = mc.DemiRelaisBasculeur(self.conf, nom, self, Dir.GAUCHE)
elif valeur.donnees.get('basculeur') == 'droite':
self.composants[nom] = mc.DemiRelaisBasculeur(self.conf, nom, self, Dir.DROITE)
else:
self.composants[nom] = mc.Relais(self.conf, nom, self)
elif valeur.type == 'Tempo':
self.composants[nom] = mc.Tempo(self.conf, nom, valeur.donnees['tempo_blocage'],
valeur.donnees['tempo_liberation'])
elif valeur.type == 'Resistance':
if 'valeur' not in valeur.donnees:
v = None
else:
v = valeur.donnees['valeur']
self.composants[nom] = mc.Resistance(self.conf, nom, v)
del v
elif valeur.type == 'Lampe':
self.composants[nom] = mc.Lampe(self.conf, nom)
elif valeur.type == 'Diode':
d = mc.Diode(self.conf, nom)
self.composants[nom] = d
self.composants["!" + nom] = d
del d
for nom, valeur in reader.noeuds.items():
if valeur.type == "Noeud":
self.elements[nom] = me.Noeud(self.conf, nom)
elif valeur.type == "P24":
self.elements[nom] = me.Potentiel(self.conf, nom, 24.)
elif valeur.type == "P0":
self.elements[nom] = me.Potentiel(self.conf, nom, 0.)
elif valeur.type == "Pulse":
if "periode" not in valeur.donnees:
p = None
else:
p = valeur.donnees["periode"]
self.elements[nom] = me.PotPulse(self.conf, nom, 24., p)
elif valeur.type == "ContactBasculeur":
self.elements[nom] = me.ContactBasculeur(self.conf, nom, self)
elif valeur.type == "ContactDouble":
self.elements[nom] = me.ContactDouble(self.conf, nom, self, orientation=valeur.donnees['orientation'])
for nom, valeur in reader.condensateurs.items():
cnd = me.Condensateur(self.conf, nom, valeur.donnees['capacite'], valeur.donnees['coef_mul_tension'])
v_amont_schm, v_amont_dir = valeur.get_amont()
v_aval_schm, v_aval_dir = valeur.get_aval()
v_amont = self.elements[v_amont_schm.nom]
v_aval = self.elements[v_aval_schm.nom]
cnd.add_voisins(v_amont, v_aval)
v_amont.add_voisins([(cnd, -1, v_amont_dir)])
v_aval.add_voisins([(cnd, +1, v_aval_dir)])
self.elements[nom] = cnd
del cnd
# Ajout des liens entre relais et contacts
try:
for nom, valeur in reader.composants.items():
if valeur.type == "ContactTravail":
self.composants[valeur.donnees["relais"]].add_travail(nom)
elif valeur.type == "ContactRepos":
self.composants[valeur.donnees["relais"]].add_repos(nom)
for nom, valeur in reader.noeuds.items():
if valeur.type == "ContactBasculeur":
self.composants[valeur.donnees["relais"] + ".gauche"].add_contact(nom)
self.composants[valeur.donnees["relais"] + ".droite"].add_contact(nom)
elif valeur.type == "ContactDouble":
self.composants[valeur.donnees["relais"]].add_double(nom)
except KeyError:
raise GraphStructException("Mauvais identificateur de relais dans un contact")
# Construction des branches
for branche in reader.branches:
nom = self.branch_id()
br = me.Branche(self.conf, nom, [self.composants[x.nom] for x in branche.composants])
[self.composants[x.nom].reverse() for x in branche.composants if x.nom[0] == '!'] # Diode
for c in br.composants:
c.branche = br
v_amont_schm, v_amont_dir = branche.get_amont()
v_aval_schm, v_aval_dir = branche.get_aval()
v_amont = self.elements[v_amont_schm.nom].get_potentiel(v_amont_dir)
v_aval = self.elements[v_aval_schm.nom].get_potentiel(v_aval_dir)
br.add_voisins(v_amont, v_aval)
v_amont.add_voisins([(br, -1, v_amont_dir)])
v_aval.add_voisins([(br, +1, v_aval_dir)])
self.elements[nom] = br
del br
self.vecteur = Vecteur(self.elements)
def __getitem__(self, item):
"""
Retourne un composant
"""
if item in self.composants:
res = self.composants[item]
else:
res = self.elements[item]
return res
def __contains__(self, item):
return item in self.composants or item in self.elements
def init_cycle(self):
[elt.init_cycle() for elt in self.elements.values()]
def passe_calcul(self, solutions):
[elt.passe_calcul(solutions, self.vecteur.index(elt)) for elt in self.elements.values()]
def update(self):
[elt.update() for elt in self.elements.values()]
def coherence(self):
[x.coherence() for x in self.elements.values()]