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()]