# ------------------------------------------------------------------------- # # PYTHON for DUMMIES 23-24 # Problème 4 # # Script de test # Vincent Legat # Nathan Coppin # Nicolas Roisin # # Largement inspiré d'un code préliminaire de Nicolas Roisin :-) # Ou les méthodes numériques pour obtenir la solution du projet P2 ! # # ------------------------------------------------------------------------- # from numpy import * import numpy as np from scipy.special import roots_legendre import matplotlib.pyplot as plt # ============================================================ # FONCTIONS A MODIFIER [begin] # # # ------------------------------------------------------------------------------------ # # Calcul des composantes radiales et verticales # du champ magnétique généré # par une série de boucles circulaires de courants ! # # X,Z : tableaux numpy des coordonnées x,z des points en [m] # Rsource : liste des rayons des boucles en [m] # Zsource : liste de hauteurs des boucles en [m] # Isource : liste des courants des boucles en [A] # data : structure contenant les paramètres matériels # # La fonction renvoie une liste [Bx,Bz] où Bx,Bz sont des tableaux/variables # du même type que X,Z. Le résultat est exprimé en [Tesla] ou [kg /s2 A] # def inductanceMegneticField(X,Z,Rsource,Zsource,Isource,data): # # A COMPLETER / MODIFIER # Bx = ones(shape(X)) Bz = ones(shape(X)) # # A COMPLETER / MODIFIER # return [Bx,Bz] # ------------------------------------------------------------------------------------ # # Calcul des points et points d'intégration # pour une intégration double de Gauss-Legendre # afin de calculer les flux du champs magnétique # # X0,Xf : intervalle radial d'intégration # Z0,Zf = intervalle vertical de moyenne du flux # nX : nombre de sous-intervalles en x # nZ : nombre de sous-intervalles en z # nGL : nombre de points de Gauss-Legendre par intervalle (en x et en z) # # La fonction renvoie une liste [X,Z,W] contenant les abscisses et les poids. # Ce seront des tableaux unidimensionnels de taille n*nGL*m*nGL # Si n ou m sont nuls, on fera une intégration unidimensionnelle en utilisant # X0 ou Z0 et les tableaux auront une taille m*nGL ou n*nGL respectivement # def inductanceGaussLegendre(X0,Xf,Z0,Zf,n,m,nGaussLegendre): # # A COMPLETER / MODIFIER # xi,we = roots_legendre(nGaussLegendre) size = max(n*nGaussLegendre,1)*max(m*nGaussLegendre,1) X = Xf * ones(size) Z = Zf * ones(size) W = ones(size) # # A COMPLETER / MODIFIER # return [X,Z,W] # ------------------------------------------------------------------------------------ # # Calcul des points et points d'intégration # pour une intégration double de Simpson # afin de calculer les flux du champs magnétique # # X0,Xf : intervalle radial d'intégration # Z0,Zf = intervalle vertical de moyenne du flux # nX : nombre de sous-intervalles en x # nZ : nombre de sous-intervalles en z # # La fonction renvoie une liste [X,Z,W] contenant les abscisses et les poids. # Ce seront des tableaux unidimensionnels de taille (2nX+1)*(2nZ+1) # Si nX ou nZ sont nuls, on fera une intégration unidimensionnelle en utilisant # X0 ou Z0 et les tableaux auront une taille (2nZ+1), (2nX/1) ou 1 respectivement # def inductanceSimpson(X0,Xf,Z0,Zf,n,m): # # A COMPLETER / MODIFIER # size = (n+1)*(m+1) X = Xf * ones(size) Z = Zf * ones(size) W = ones(size) # # A COMPLETER / MODIFIER # return [X,Z,W] # # FONCTIONS A MODIFIER [end] # ============================================================ # ------------------------------------------------------------------------------------ # # Classe du projet P2 # class MutualInductanceProject: mu0 = 4e-7*pi # permeabilité du vide en [H/m] Rcoil = 1.0e-2 # rayon des bobines [m] Hcoil = 1.0e-2 # épaisseur des bobines [m] Zcoil = -0.5e-2 # position verticale de la bobine primaire [m] nSpires = 200 # nombre de spires I = 0.1 # courant dans la bobine [A] Hsecond = 2.0e-2 # position relative de la bobine secondaire [m] nZcoil = 20 # discrétisation vertical de la bobine nTheta = 8 # discrétisation du cercle Theta = linspace(0,2*pi,nTheta+1)[:-1] + pi / nTheta Xcircle = cos(Theta) Ycircle = sin(Theta) def streamPlot(self,X,Z,Bx,Bz,colorStream,colorIplate): plt.streamplot(X,Z,Bx,Bz,density=1.0,linewidth=None,color=colorStream) x = array([-self.Rcoil,self.Rcoil]) z = repeat([linspace(0,-self.Hcoil,self.nZcoil)],2,axis=0) plt.plot(x,z,"o-r",linewidth=2) plt.plot(x,z+self.Hsecond,"o-b",linewidth=2) plt.xlim((-0.03,0.03)); plt.ylim((-0.03,0.03)) def main(): # ------------------------------------------------------------------------------------ # # Script de test # # # -0- Initialisation du projet # # ------------------------------------------------------------------------------------ p = MutualInductanceProject() # ------------------------------------------------------------------------------------ # # -1- Calcul de l'inductance, inductance mutuelle, inductance induite # et inductance effective pour Mr. Oestges ! # # ------------------------------------------------------------------------------------ Zcoil = -linspace(0,p.Hcoil,p.nZcoil) Rcoil = p.Rcoil * ones_like(Zcoil) Icoil = p.I * ones_like(Zcoil) * p.nSpires / p.nZcoil # # -1.1- Flux dans la bobine primaire du champs induit par la bobine primaire # nX = 10; nZ = 3; nGL = 2 X,Z,W = inductanceGaussLegendre(0,p.Rcoil,0,-p.Hcoil/2,nX,nZ,nGL) Bz = inductanceMegneticField(X,Z,Rcoil,Zcoil,Icoil,p)[1] flux = W @ Bz L = p.nSpires * (flux/p.I) print("Using Gauss-Legendre integration rule (nX = %d nZ = %d):-)" % (nX,nZ)) print("Flux across primary = %14.7e [Tesla m2]" % flux) print("Inductance = %14.7e [Henry]" % L) nX = 10; nZ = 3 X,Z,W = inductanceSimpson(0,p.Rcoil,0,-p.Hcoil/2,nX,nZ) Bz = inductanceMegneticField(X,Z,Rcoil,Zcoil,Icoil,p)[1] flux = W @ Bz L = p.nSpires * (flux/p.I) print("Using Simpson integration rule (nX = %d nZ = %d):-)" % (nX,nZ)) print("Flux across primary = %14.7e [Tesla m2]" % flux) print("Inductance = %14.7e [Henry]" % L) nX = 20; nZ = 5 X,Z,W = inductanceSimpson(0,p.Rcoil,0,-p.Hcoil/2,nX,nZ) Bz = inductanceMegneticField(X,Z,Rcoil,Zcoil,Icoil,p)[1] flux = W @ Bz L = p.nSpires * (flux/p.I) print("Using Simpson integration rule (nX = %d nZ = %d):-)" % (nX,nZ)) print("Flux across primary = %14.7e [Tesla m2]" % flux) print("Inductance = %14.7e [Henry]" % L) # # -1.2- Flux dans la bobine secondaire du champs induit par la bobine primaire # nX = 20; nZ = 0; nGL = 1 X,Z,W = inductanceGaussLegendre(0,p.Rcoil,p.Hsecond,-p.Hcoil+p.Hsecond,nX,nZ,nGL) Bz = inductanceMegneticField(X,Z,Rcoil,Zcoil,Icoil,p)[1] flux = W @ Bz M = p.nSpires * (flux/p.I) print("Flux across secondary = %14.7e [Tesla m2]" % flux) print("Mutual inductance = %14.7e [Henry]" % M) # ------------------------------------------------------------------------------------ # # -2- Représentation du champ magnétique # # ------------------------------------------------------------------------------------ plt.rcParams['toolbar'] = 'None' n = 20 X,Z = meshgrid(linspace(-0.03,0.03,n),linspace(-0.03,0.03,n)) Bcoilx,Bcoilz = inductanceMegneticField(X,Z,Rcoil,Zcoil,Icoil,p) plt.figure("Mutal induction :-)",figsize=(10, 10)) p.streamPlot(X,Z,Bcoilx,Bcoilz,'blue','gray') plt.title('Electromagnetic field generated by the primary coil') # ------------------------------------------------------------------------------------ # # -3- Bz dans la bobine et la plaque # # ------------------------------------------------------------------------------------ plt.figure("Champ magnétique : Bz dans les bobines primaire et secondaire") n = 100 X = linspace(0,p.Rcoil,n) Z = p.Zcoil * ones_like(X) Bz = inductanceMegneticField(X,Z,Rcoil,Zcoil,Icoil,p)[1] plt.plot(X,Bz,'-b') Z = (p.Zcoil - p.Hcoil/2) * ones_like(X) Bz = inductanceMegneticField(X,Z,Rcoil,Zcoil,Icoil,p)[1] plt.plot(X,Bz,'-b') Z = (p.Zcoil + p.Hcoil/2) * ones_like(X) Bz = inductanceMegneticField(X,Z,Rcoil,Zcoil,Icoil,p)[1] plt.plot(X,Bz,'-b') X = linspace(0,p.Rcoil,n) Z = p.Zcoil * ones_like(X) + p.Hsecond Bz = inductanceMegneticField(X,Z,Rcoil,Zcoil,Icoil,p)[1] plt.plot(X,Bz,'-r') Z = (p.Zcoil - p.Hcoil/2) * ones_like(X) + p.Hsecond Bz = inductanceMegneticField(X,Z,Rcoil,Zcoil,Icoil,p)[1] plt.plot(X,Bz,'-r') Z = (p.Zcoil + p.Hcoil/2) * ones_like(X) + p.Hsecond Bz = inductanceMegneticField(X,Z,Rcoil,Zcoil,Icoil,p)[1] plt.plot(X,Bz,'-r') plt.grid() # ------------------------------------------------------------------------------------ # # -4- Points d'intégration de Gauss-Legendre # # ------------------------------------------------------------------------------------ # plt.rcParams['toolbar'] = 'None' # plt.rcParams['toolbar'] = 'None' # plt.rcParams['figure.facecolor'] = 'lavender' # plt.rcParams['axes.facecolor'] = 'lavender' plt.figure("Integration Gauss-Legendre nodes") nX = 5; nZ = 4; nGL = 3 X,Z,W = inductanceGaussLegendre(0,p.Rcoil,0,-p.Hcoil,nX,nZ,nGL) plt.plot(X,Z,'ob',markersize=5) x = array([0,p.Rcoil]) z = repeat([linspace(0,-p.Hcoil,nZ+1)],2,axis=0) plt.plot(x,z,'-k') x = array([-0.003,p.Rcoil]) z = repeat([linspace(0,-p.Hcoil,nZ+1)],2,axis=0) plt.plot(x,z,'--k') z = array([0,-p.Hcoil]) x = repeat([linspace(0,p.Rcoil,nX+1)],2,axis=0) plt.plot(x,z,'-k') z = array([0.003,-p.Hcoil]) x = repeat([linspace(0,p.Rcoil,nX+1)],2,axis=0) plt.plot(x,z,'--k') X,Z,W = inductanceGaussLegendre(0,p.Rcoil,0.002,0.002,nX,0,nGL) plt.plot(X,Z,'or',markersize=5) X,Z,W = inductanceGaussLegendre(-0.002,-0.002,0,-p.Hcoil,0,nZ,nGL) plt.plot(X,Z,'or',markersize=5) plt.axis('equal') plt.axis('off') # ------------------------------------------------------------------------------------ # # -5- Points d'intégration de Simpson # Oui : il faudrait ecrire une fonction et ne pas tout recopier ! # Mais, c'est dimanche.... et j'ai autre chose à faire :-) # # ------------------------------------------------------------------------------------ plt.figure("Integration Simpson nodes") X,Z,W = inductanceSimpson(0,p.Rcoil,0,-p.Hcoil,nX,nZ) plt.plot(X,Z,'ob',markersize=5) x = array([0,p.Rcoil]) z = repeat([linspace(0,-p.Hcoil,nZ+1)],2,axis=0) plt.plot(x,z,'-k') x = array([-0.003,p.Rcoil]) z = repeat([linspace(0,-p.Hcoil,nZ+1)],2,axis=0) plt.plot(x,z,'--k') z = array([0,-p.Hcoil]) x = repeat([linspace(0,p.Rcoil,nX+1)],2,axis=0) plt.plot(x,z,'-k') z = array([0.003,-p.Hcoil]) x = repeat([linspace(0,p.Rcoil,nX+1)],2,axis=0) plt.plot(x,z,'--k') X,Z,W = inductanceSimpson(0,p.Rcoil,0.002,0.002,nX,0) plt.plot(X,Z,'or',markersize=5) X,Z,W = inductanceSimpson(-0.002,-0.002,0,-p.Hcoil,0,nZ) plt.plot(X,Z,'or',markersize=5) plt.axis('equal') plt.axis('off') # ------------------------------------------------------------------------------------ # # -6- La jolie courbe pour Claude Oestges et Nicolas Roisin # # ------------------------------------------------------------------------------------ nD = 21 nX = 5; nZ = 5; nGL = 3 distances = linspace(0,5e-2,nD) M = zeros(nD) for i in range(nD) : h = distances[i] + 0.01 X,Z,W = inductanceGaussLegendre(0,p.Rcoil,h,h-p.Hcoil,nX,nZ,nGL) Bz = inductanceMegneticField(X,Z,Rcoil,Zcoil,Icoil,p)[1] flux = W @ Bz M[i] = p.nSpires * (flux/p.I) plt.figure("Inductuance mutuelle en fonction de la distance") plt.plot(distances*1e2,M*1e3,'ob-') ax = plt.gca() ax.set_ylabel("Inductance mutuelle : M [mH]") ax.set_xlabel("Distance bobines : d [cm]") ax.grid() plt.show() main()