Upload
others
View
18
Download
0
Embed Size (px)
Citation preview
• Limitation de la loi d’Amdahl
T total = T calculs parallélisés / # opérateurs + T gestion
• Données utilisées plusieurs fois
– Localité spatiale et temporelle
– Ré-utilisation croissante avec la taille du problème
• Passage à l’échelle
Multi-cœur, Multi-CPU, Supercalculateurs, GPU
Programmation efficace en C, C++, CUDA…
Puissance de calcul
• Mémoire principale
• Disque dur / SSD
• Réseau
• Caches (niveaux L1, L2 ou L3)
Utiliser plusieurs cœurs, CPU, machines…
• Problématique indépendante des outils de développement
Taille ouBande passante
• Grande latence (en mois ou en années)– Loi de Moore (puissance doublée tous les 18 mois)
• Onéreux 126 k€/an (Paris) à $160k/an (US)– AWS c3.large ponctuelle $0.0158/heure soit $138/an– Facteurs 913x ou 1159x
• Chasse aux bugs– Typiquement 80% de l’effort
« Ce que l'on conçoit bien s'énonce clairement,Et les mots pour le dire arrivent aisément. » Nicolas Boileau, L’Art Poétique (1674)
Développeur
• Fonctionnement en silos, cycle en V
– Compétence métier (biologie, physique…)
– Modélisation mathématique
– Développement informatique
• Obsolescences entre 2 et 5 ans
– Matériel et logiciel
– Fonctionnement plutôt qu’investissement
Python représente un solution attractive
Autres éléments
• Code responsable de la gestion des objets
– Création / destruction
– Ni ré-entrant ni compatible multi-threads
GIL : Global Interpreter Lock
• Modèles de parallélisme de Python
– Utilisation de bibliothèques
– Threads bloqués sur des entrées/sorties
Limitation de Python
• Présentation du problème
• Mise sous forme de système d’équations
• Résolution numérique
• Visualisation des résultats intermédiaires
• Intégration numérique
• Résultat de l’étude numérique
Plan
Problème à traiter
Evaluation et analyse de l’entropie générée par un écoulement anisotherme
Jean-Marc AVELLANEDA1*, Quentin NICOLAU1, Marc DAUMAS1, Françoise BATAILLE1
1PROMES CNRS, Rambla de la thermodynamique, Tecnosud, 66100 Perpignan
*(auteur correspondant : [email protected])
Résumé - Afin d’optimiser les récepteurs solaires des centrales thermodynamiques à concentration, il
importe de comprendre les écoulements turbulents convectifs fortement anisothermes. L’analyse de
l’entropie générée est un moyen d’investigation puis d’optimisation de leur performance. La présente
étude envisage cette problématique dans le cadre simplifié de la couche limite laminaire située au-
dessus d’une plaque à température différente de l’écoulement. Le fluide à vitesse et température fixées
dans la zone d’écoulement libre, subit en proche paroi et dans la couche limite les effets thermiques et
visqueux qui sont générateurs d’entropie. Nous étudions l’influence des paramètres thermiques
(température de paroi et écart de température entre la paroi et l’écoulement libre) sur l’importance et la
composition de la génération d’entropie locale et totale dans la couche limite.
Nomenclature
U ¥ Vitesse de l’écoulement libre,
1.m s-
T¥ Température de l’écoulement libre, K
wT Température de paroi, K
q Température adimensionnée (8)
t Paramètre thermique ( ( )w wT T T¥- )
TD Ecart de température wT T¥- , K
Taux d’entropie générée
genS¢¢¢& volumique, 1 3. .W K m- -
genS¢¢& surfacique, 1 2. .W K m- -
genS¢& linéique, 1 1. .W K m- -
3S , 2S , 1S : taux adimensionnés associés
respectivement à chacun des taux ci-dessus
1. Introduction
L’optimisation des récepteurs solaires de centrales solaires thermodynamiques à
concentration suppose de maximiser l’échange de chaleur entre le fluide caloporteur et les
parois exposées au rayonnement solaire concentré, tout en minimisant les pertes d’énergie par
frottement visqueux. Cet optimum peut être recherché en employant les techniques de
minimisation de l’entropie générée durant le processus d’échange [1], la perte de puissance
utile étant directement liée au taux de production d’entropie du fait des irréversibilités. L’optimum entropique peut par exemple être recherché à l’aide d’une méthode variationnelle
[2]. La connaissance du champ d’entropie au sein de l’écoulement permet de connaître les lieux et paramètres à optimiser. Les récepteurs solaires sont le siège d’écoulements turbulents
fortement anisothermes et asymétriques complexes [3][4][5] et il est utile d’effectuer une analyse du champ d’entropie dans une configuration plus abordable en premier lieu. La
théorie de la couche limite [6] offre un cadre idéal pour une première approche et a été
utilisée, par exemple, pour étudier l’influence de la vitesse de déplacement d’une plaque sur
l’entropie produite par l’écoulement externe d’un fluide [7]. Après avoir rappelé les équations
gouvernant la couche limite laminaire, nous dérivons les expressions de la production d’entropie et étudions son importance, sa composition relative entre facteurs thermiques et
visqueux ainsi que sa dépendance par rapport au rapport entre la température de paroi et
l’écart de température entre la paroi et l’écoulement libre.
• Un changement de variable
• Deux nouvelles équations différentielles
• Avec leurs conditions aux limites
Modélisation mathématique
h = yU
¥
nx
¢¢¢f +1
2f ¢¢f = 0 ¢¢q +
1
2Pr f ¢q = 0
f (0) = 0, ¢f (0) = 0, q(0) = 0
limh®¥
¢f (h) =1, limh®¥
q (h) =1
• Paramètres adimensionnés
• Création d’entropie pour le phénomène
• Existe-t-il un minimum ?
Création d’entropie élémentaire
q =T
w-T
DTt =
Tw
DTDT =T
w-T
¥
S3dxdydzò =
¢q 2
Rex
t -q( )2
h2
4Rex
+1æ
èçç
ö
ø÷÷+
Pr Ec
Rex
t -q( )¢¢f 2
é
ë
êêê
ù
û
úúú
dxdydzò
• Présentation du problème
• Mise sous forme de système d’équations
• Résolution numérique
• Affichage des résultats intermédiaires
• Intégration numérique
• Présentation des résultats
Plan
• On crée une classe équation différentielle et f
– Paramètre C dans l’équation différentielle de f
– Paramètre λ pour les conditions aux limites
– Un constructeur
class bvp_eq_diff:
…
class f(bvp_eq_diff):
def __init__ (self, λ = 0., C = 1.):
self.C, self.λ, f.ordre = C, λ, 3
Groupe d’équations similaires
• On se ramène à un système d’équations différentielles du premier ordre
– F vecteur contenant [f, f’, f’’]
– F’ est exprimé comme une fonction f.eq(η, F)
def eq (self, η, F):
"Vector expression of f'''+Cff'' = 0”
# F = [f , f' , f'' ]
# F' = [f' , f'' , -Cff'' ]
return [F[1], F[2], -self.C*F[0]*F[2]]
Réduire l’ordre de l’équation
• Conditions initiales ou IVP
– Initial Value Problem
• Critères
– Réel ou complexe
– Singularité et raideur
– Ordre de la solution, adaptabilité du pas
• Méthodes dans scipy.integrate.ode
vode, zvode, lsoda, dopri5, dop853
Problème de Cauchy
• BVP (Boundary Value Problem)
– Condition exprimée sous forme de résidu
– Basé sur les valeurs de F aux bornes de l’intervalle
– Le résidu tend vers 0
def bc(self, lower, upper):
"""Boundary condition (residual)
f(0) = 0, f'(0) = λ, f'(∞) = 1"""
return [lower[0], lower[1] - self.λ, upper[1]-1]
Conditions aux limites
• Présentation du problème
• Mise sous forme de système d’équations
• Résolution numérique
• Visualisation des résultats intermédiaires
• Intégration numérique
• Résultat de l’étude numérique
Plan
• Méthode avec les paramètres courants
– Vecteur F partout nul comme point de départ
– Tolérance sur la norme du résidu limitée à 10-8
class bvp_eq_diff:
def solve(self, η, guess = None,
tol = 1e-8, verbose = 0):
"""Solve differential equation with
BVP library function of scipy.integrate"""
if guess is None:
guess = self.guess(η)
Calcul de la solution(1/2)
• Calcul de la solution
• Vérification de l’absence d’erreur
res = solve_bvp(
fun = self.eq, bc = self.bc,
x = η, y = guess, tol = tol, verbose = verbose)
if not(res.success):
print ("Problem solving differential equation",
type(self).__name__,
"with C = %g and λ = %g" % (self.C, self.λ))
return res
Calcul de la solution(2/2)
• Calcul de la solution dont on connaît la forme
– L’infini est ramené à 5 ou 10
– 200 intervalles entre 0 et 5
η = np.linspace(0., 5., 201) # ∞ is 5
f_guess = np.zeros((3, η.size))
for λ in [1.5, 1.397, 1.294, 1.1566, 1.0536, 0.985,
0.5386, 0.1953, -0.107, -0.2511, -0.3198]:
f_res = f(λ).solve(η, f_guess)
plt.plot(η, f_res.sol(η)[1],
label=r"$f'(0) = %g$"%λ )
Création des objets et équations
• Présentation du problème
• Mise sous forme de système d’équations
• Résolution numérique
• Visualisation des résultats intermédiaires
• Intégration numérique
• Résultat de l’étude numérique
Plan
Iteration Max residual Total nodes Nodes added
1 4.58e-02 201 399
2 2.70e-08 600 2
3 7.82e-09 602 0
Solved in 3 iterations, number of nodes 602, maximum
relative residual 7.82e-09.
Iteration Max residual Total nodes Nodes added
1 4.53e+00 201 400
2 7.04e-01 601 (1198)
Number of nodes is exceeded after iteration 2,
maximum relative residual 7.04e-01.
Messages de l’application
plt.plot(η, f_res.sol(η)[0], label="$f$" )
plt.plot(η, f_res.sol(η)[1], label="$f'$" )
plt.plot(η, f_res.sol(η)[2], label="$f''$" )
plt.legend(loc=1)
plt.show()
On continueavec λ = 0
class θ(bvp_eq_diff):
def __init__ (self, f, Pr = 1.):
self.f, self.Pr, θ.ordre = f, Pr, 2
def eq (self, η, TH):
"Vector expression of θ''+1/2Prfθ'= 0"
# TH = [θ , θ']
# TH' = [θ' ,-1/2Prfθ']
return [TH[1], -0.5*self.Pr*self.f(η)*TH[1]]
def bc(self, lower, upper):
"""Boundary condition (residual)
θ(0) = 1, θ(∞) = 0"""
return [lower[0]-1, upper[0]]
Traitement de la 2ème fonction
Rappel
On introduit trois intégrales paramétrées par
Création d’entropie
W1= w
1dh
0
¥
ò =¢q 2h2
t -q( )2
dh0
¥
ò =t
w¢q h
1-twq
æ
èçç
ö
ø÷÷
2
dh0
¥
ò
W2
= w2dh
0
¥
ò =¢q 2
t -q( )2
dh0
¥
ò =t
w¢q
1-twq
æ
èçç
ö
ø÷÷
2
dh0
¥
ò
W3= w
3dh
0
¥
ò =¢¢f 2
t -qdh
0
¥
ò =t
w¢¢f 2
1-twq
dh0
¥
ò
tw
=DT
Tw
S3=
¢q 2
Rex
t -q( )2
h2
4Rex
+1æ
èçç
ö
ø÷÷+
Pr Ec
Rex
t -q( )¢¢f 2
def ω1_fct (η, θ, τw):
return ((τw*θ[1]*η)/(1 - τw*θ[0]))**2
def ω2_fct (η, θ, τw):
return ( τw*θ[1] /(1 - τw*θ[0]))**2
def ω3_fct (f, θ, τw):
return τw*f[2]**2/(1 - τw*θ[0])
τw_min = 0. # python2 proof
τw_max = 1.
τw_steps = 20
τw_pt = np.linspace(τw_min, τw_max, τw_steps+1)
Expression des radicaux en Python
Héritée de FuncAnimation dans matplotlib
class MyAnim(FuncAnimation):
def __init__(self, fig, interval = 100):
self.ax, self.lines = fig.add_subplot(1,1,1), {}
FuncAnimation.__init__(
self, fig, self.toutes,
frames=τw_pt[1:], interval = interval)
Une classe pour nos animations
def etape (self, key, x, y, style = "-",
label = None, w = 0):
if w == 0: w = 1/max(y)
y *= w
if key in self.lines:
self.lines[key].set_ydata(y)
else:
self.lines[key], = self.ax.plot(
x, y, style, label = label)
plt.legend(loc=1)
return w
Dictionnaire des courbes
def toutes (self, τw):
self.ω1 (τw)
self.etape("ω2", η, ω2_fct(η , θ_pt, τw),
label = "$ω2/||ω2||_{\infty}}$")
self.etape("ω3", η, ω3_fct(f_pt, θ_pt, τw),
label = "$ω3/||ω3||_{\infty}}$")
self.ax.set_xlabel("$τ=$ {0:6.2f}".format(1/τw))
Les courbes normales
Comparaison avec une distribution normale
– Calcul des paramètres
– Tracé de la fonctiondef ω1 (self, τw):
y = ω1_fct(η, θ_pt, τw)
Ns_ω, Ns_μ, Ns_σ = norm_approx (y, η, dη)
Ns = Ns_ω*st.norm(Ns_μ, Ns_σ).pdf(η)
w = self.etape("ω1", η, y,
label = "$ω1/||ω1||_{\infty}}$")
w = self.etape("N(ω1)", η, Ns, ':', w = w,
label = "$N(ω1)/||ω1||_{\infty}}$”)
Les courbes de ω1
• Présentation du problème
• Mise sous forme de système d’équations
• Résolution numérique
• Visualisation des résultats intermédiaires
• Intégration numérique
• Résultat de l’étude numérique
Plan
Méthodes disponibles à partir des valeurs
• Trapèzestrapz(ω1_fct(η, θ_pt, τw), dx = dη)
• Simpsonsimps(ω1_fct(η, θ_pt, τw), dx = dη)
• Romberg
Le nombre d’intervalles doit être une puissance de 2romb(ω1_fct(η, θ_pt, τw), dx = dη)
Bibliothèque scipy.integrate
τw_steps = 200
τw_pt = np.linspace(τw_min, τw_max, τw_steps+1)
Ω1 = np.array(
[simps (ω1_fct (η , θ_pt, τw), dx = dη)
for τw in τw_pt])
Ω2 = np.array(
[simps (ω2_fct (η , θ_pt, τw), dx = dη)
for τw in τw_pt])
Ω3 = np.array(
[simps (ω3_fct (f_pt, θ_pt, τw), dx = dη)
for τw in τw_pt])
Bibliothèque scipy.integrate
• Présentation du problème
• Mise sous forme de système d’équations
• Résolution numérique
• Visualisation des résultats intermédiaires
• Intégration numérique
• Résultat de l’étude numérique
Plan
def qpoly_approx (x, y, deg = 4, label = None):
approx = st.linregress(log(x), log(y))
poly = cheb2poly(
chebfit(x, y/(x**(approx.slope)), deg))[::-1]
if label is not None :
print (label % approx.slope)
print (poly1d(poly), "\n")
return approx.slope, poly
Ω1_deg, Ω1_pol = qpoly_approx(τw_pt, Ω1,
label = "Ω1(τ) = P1(1/τ)/τ**%g with P1(x) =”)
Regression linéaire
Ω1(τ) = P1(1/τ)/τ**2.09858 with P1(x) =
4 3 2
46.17 x - 54.15 x + 23.08 x - 3.805 x + 1.124
Ω2(τ) = P2(1/τ)/τ**2.2015 with P2(x) =
4 3 2
56.7 x - 65.2 x + 27.33 x - 4.474 x + 0.6957
Ω3(τ) = P3(1/τ)/τ**1.09734 with P3(x) =
4 3 2
17.1 x - 20 x + 8.53 x - 1.412 x + 0.4194
Bibliothèque scipy.integrate
• L’intégrale initiale se réecrit avec
• Tous les termes sont des puissances de x ou τ
• L’intégration analytique est possible dès que le lien entre x, z et τ est suffisamment simple
• Le minimum de création d‘entropie du phénomène peut être calculé
Création d’entropie du phénomène
S3dxdyò dz=
1
Rex
W1
4Rex
+W2+ Pr EcW
3
æ
èçç
ö
ø÷÷
nx
U¥
dxdzò
Rex
=U
¥x
n
L’inspiration
• Algorithme k-means pour l’enseignement
– Cours Algorithmes et Programmation Parallèle
– Embarrassingly parallel (@scale)
• Recherche parallèle de la valeur de k (trop facile )
• Distribution des données– Diviser pour régner & Introduction à Hadoop
• Parallélisation multi-thread, multi-proc, cluster…
• Bonne préparation d’un stage– Entreprise, association, collectivité territoriale…
– Carte des clients, adhérents, usagers...
Réécriture des fonctions - Exemple
def reevaluate_centers(mu, G, w):
return
[x/w[i] if w[i] else mu[i]
for i, x in enumerate(G)]
def has_converged(mu1, mu2):
return (
set([tuple(a) for a in mu1])
== set([tuple(a) for a in mu2]))
Améliorations
12912261 function calls (12912246 primitive calls) in 9.996 seconds
ncalls tottime percall cumtime percall filename:lineno(function)
1395856 3.525 0.000 6.971 0.000 linalg.py:2022(norm)
116160 1.804 0.000 8.776 0.000 kmeans.py:17(<listcomp>)
1395856 1.034 0.000 1.034 0.000 numpy.core.multiarray.dot
1395856 0.817 0.000 0.817 0.000 ravel
1395856 0.682 0.000 0.846 0.000 numeric.py:463(asarray)
60 0.642 0.011 9.991 0.167 kmeans.py:8(cluster_points)
1395856 0.397 0.000 0.562 0.000 linalg.py:111(isComplexType)
116160 0.396 0.000 0.553 0.000 builtins.min
2791731 0.353 0.000 0.353 0.000 builtins.issubclass
1395856 0.164 0.000 0.164 0.000 numpy.core.multiarray.array
Profilage (avant)
308 function calls in 0.009 seconds
ncalls tottime percall cumtime percall filename:lineno(function)
5 0.009 0.002 0.009 0.002 cymeans.find_centers
5 0.000 0.000 0.000 0.000 builtins.print
5 0.000 0.000 0.000 0.000 random.py:289(sample)
60 0.000 0.000 0.000 0.000 random.py:229(_randbelow)
10 0.000 0.000 0.000 0.000 abc.py:178(__instancecheck__)
10 0.000 0.000 0.000 0.000 builtins.isinstance
15 0.000 0.000 0.000 0.000 _weakrefset.py:70(__contains__)
5 0.000 0.000 0.000 0.000 math.log
62 0.000 0.000 0.000 0.000 'getrandbits' of '_random.Random‘
60 0.000 0.000 0.000 0.000 'add' of 'set‘
Profilage (après)
• Remplacé par un typage statique
cdef int reevaluate_centers(
int K,
double[:,:] mu,
double[:,:] G,
double[:] w) nogil:
Typage dynamique des paramètres
• Déclarations explicites et typées
• Sortir toutes les créations et destructions des boucles intérieures
cdef int changed = 0
cdef double temp
Variables
Evolutions d’un code fonctionnel
Non régressionfor i in range(K):
if w[i]:
temp = G[i,0]/w[i]
if (temp != mu[i,0]):
changed = 1; mu[i,0] = temp
temp = G[i,1]/w[i]
if (temp != mu[i,1]):
changed = 1; mu[i,1] = temp
return changed
Algorithme en place
Quatre fonctions à connaître (6 en C)
from mpi4py import MPI
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
size = comm.Get_size()
if rank == 0:
data = {'a': 7, 'b': 3.14}
comm.send(data, dest=1, tag=11)
elif rank == 1:
data = comm.recv(source=0, tag=11)
Modèlemaître/esclace
data = comm.bcast(data, root=0)
data = comm.scatter(data, root=0)
data = comm.gather(data, root=0)
Traitement spécifique pour les tableaux NumPy
comm.Bcast(data, root=0)
comm.Scatter(sendbuf, recvbuf, root=0)
comm.Gather(sendbuf, recvbuf, root=0)
comm.Allgather([x, MPI.DOUBLE], [xg, MPI.DOUBLE])
Communications globales