Académique Documents
Professionnel Documents
Culture Documents
000000000
Reportez votre numéro d’anonymat dans le cadre ci-dessous et en haut à gauche de chaque page de
l’énoncé.
A la fin de l’épreuve glissez ce cahier dans la copie double qui vous a été fournie, qui comporte votre
numéro d’anonymat et sur laquelle vous aurez écrit et masqué votre nom en rabattant dessus et en
collant la languette triangulaire. Vous ne devez rien écrire d’autre sur cette copie double.
Numéro d’anonymat :
Examen d’informatique jeudi 13 mars 2013 9h30 à 11h30 bât. 337 salle 3
1 S’il y en a un.
2 S’il y en a.
Licence et Magistère 1ère année de Physique fondamentale Examen d’informatique 2013-2014 première session
Numéro d’anonymat : 2 2014-03-13 14 :35 :20.000000000
Réponse à la question :
Programme (a) : x et y sont deux tableaux correspondant à des registres mémoire différents (puisque malloc a
fourni deux adresses différentes) donc deux tableaux différents. Ces deux tableaux sont initialisés aux mêmes
valeurs mais ils pourront éventuellement contenir des valeurs différentes dans la suite du programme.
Programme (b) : x et y sont deux tableaux correspondant aux mêmes registres mémoire (puisque x et y
contiennent la même adresse) donc il s’agit d’un seul tableau ayant deux noms différents. Il y a par construction
toujours les mêmes valeurs dans x et y.
Question 2 :
dans le programme (b) le résultat affiché serait-il le même si on intervertissait l’ordre des deux lignes suivantes :
for(i=0;i<n;i++) x[i]=2*i;
# y=x;
? Justifier la réponse.
Réponse à la question :
Oui. Que l’on déclare que les emplacements mémoire correspondant à y sont les mêmes que ceux correspondant
à x avant ou après l’initialisation de x ne change rien au contenu final de y.
Licence et Magistère 1ère année de Physique fondamentale Examen d’informatique 2013-2014 première session
Numéro d’anonymat : 3 2014-03-13 14 :35 :20.000000000
Réponse à la question :
#include<iostream>
#include<stdlib.h>
using namespace std;
void ech(double *a,double *b)
{
double c;
c=*a; *a=*b; *b=c;
}
int main()
{
double a,b;
a=1.; b=2.;
cout << a << " " << b << endl;
ech(&a,&b);
cout << a << " " << b << endl;
return 0;
}
y Ex
~
E(t)
~r˙(t=0) E0
u~y
O u~x r0 x O T 2T 3T t
Licence et Magistère 1ère année de Physique fondamentale Examen d’informatique 2013-2014 première session
Numéro d’anonymat : 4 2014-03-13 14 :35 :20.000000000
~
E0 étant une constante (E(t) est donc une fonction créneau de largeur T , non nulle sur l’intervalle [T, 2T ]).
On pose :
q
b = E0
m
On choisit les conditions initiales (à t = 0) suivantes pour la position et la vitesse de l’électron :
rx = r0 (rayon de Bohr)
ry = 0
ṙx = r
0
a
ṙy =
r0
qui donnent à l’électron une trajectoire circulaire de rayon r0 en l’absence de champ électrique extérieur.
On prend les valeurs numériques suivantes (en unités SI et déjà écrites dans la réponse ci-dessous) :
r0 = 5.29 10−11
a = 253.187
b = 1.75824 1021
T = 1.5193 10−16
Question :
Calculer par la méthode d’Euler la trajectoire de l’électron sur l’intervalle de temps [0, 3T ]4 et écrire dans un
fichier à chaque instant du calcul le temps et les coordonnées rx et ry .
Réponse à la question :
#include<iostream>
#include<fstream>
#include<cmath>
#include<stdlib.h>
using namespace std;
int main()
{
double r0=5.29e-11,a=253.187,b=1.75824e21,T=1.5193e-16; // unités SI
int i,np=100000;
double rx,rxp,rxpp,ry,ryp,rypp,t,dt,r3;
t=0.; rx=r0; ry=0.; rxp=0.; ryp=sqrt(a/r0);
dt=3*T/(np-1);
fstream res("atome_euler_strict.res",ios::out);
for(i=1;i<=np;i++)
{
res << t << " " << rx << " " << ry << endl;
r3=pow(rx*rx+ry*ry,1.5);
rxpp=-a*rx/r3; if(t>=T && t<=2*T) rxpp-=b;
rypp=-a*ry/r3;
rx=rx+dt*rxp; ry=ry+dt*ryp;
rxp=rxp+dt*rxpp; ryp=ryp+dt*rypp;
t+=dt;
}
return 0;
}
4 Ce qui permet de connaı̂tre l’orbite de l’électron une fois que le champ électrique a cessé d’agir.
Licence et Magistère 1ère année de Physique fondamentale Examen d’informatique 2013-2014 première session
Numéro d’anonymat : 5 2014-03-13 14 :35 :20.000000000
Réponse à la question :
Voir réponse à la question 2.
Question 2 :
On place deux dipôles, notés D0 et D1 , de moments dipolaires p~0 et p~1 , aux points de coordonnées respectives
(−l/2, 0, 0) et (l/2, 0, 0).
~0
E
O
D0 D1 x
~ où E
On suppose que les dipôles sont induits : le moment dipolaire du dipôle Di vaut p~i = αE, ~ est le champ
~
total en Di résultant de la superposition d’un champ extérieur uniforme noté E0 supposé parallèle à Oy, et
du champ créé par l’autre dipôle c’est à dire D1−i (α est une constante).
Écrire un programme qui calcule les moments dipolaires p~0 et p~1 en utilisant la méthode itérative suivante
supposée convergente :
– on commence en supposant que les moments dipolaires ne sont induits que par E~0 , cela donne un champ
total E~1
– on recalcule les moments dipolaires induits par E~1 , cela donne un nouveau champ total E~2
– on poursuit ainsi jusqu’à avoir effectué 10 itérations.
On prend les valeurs numériques suivantes (unités SI) :
l = 10−9
α = 8.3 10−41
E0 = 106
Licence et Magistère 1ère année de Physique fondamentale Examen d’informatique 2013-2014 première session
Numéro d’anonymat : 6 2014-03-13 14 :35 :20.000000000
S’il y a plusieurs tableaux-pointeurs de même taille à déclarer on écrira la déclaration explicite pour le premier,
et, en abrégé, trois points (...) pour ce qui se trouve à droite du signe = dans la déclaration des autres.
Réponse à la question :
#include<iostream>
#include<iomanip>
#include<cmath>
#include<stdlib.h>
using namespace std;
int n_=3;
//-------------------------------------------------------------------------------------------------------
double ps(double *u,double *v) // fonction produit scalaire
{
double s; int i;
for(s=0,i=0;i<n_;i++) s+=u[i]*v[i];
return s;
}
//-------------------------------------------------------------------------------------------------------
// Calcule le champ exercé par un dip^
ole
// a, b et p en entrée, e en sortie
void champ(double *a,double *b,double *p,double *e)
{
int i;
double cc=9.e9,nr,nr2,x;
double *r=(double *)malloc(n_*sizeof(double));
for(i=0;i<n_;i++) r[i]=b[i]-a[i];
x=ps(p,r);
nr2=ps(r,r); nr=sqrt(nr2);
for(i=0;i<n_;i++) e[i]=cc/nr2/nr*(3*x*r[i]/nr2-p[i]);
}
//-------------------------------------------------------------------------------------------------------
int main()
{
int i,m,mmax=10;
double alp=8.3e-41,l=1.e-9; // valeur de référence (voir Garing Milieux diélectriques p 69)
double *E0=(double *)malloc(n_*sizeof(double)),
*e0=(double *)malloc(n_*sizeof(double)),*e1=(double *)malloc(n_*sizeof(double)),
*x0=(double *)malloc(n_*sizeof(double)),*x1=(double *)malloc(n_*sizeof(double)),
*p0=(double *)malloc(n_*sizeof(double)),*p1=(double *)malloc(n_*sizeof(double));
E0[0]=0.; E0[1]=0.; E0[2]=1.e6;
x0[0]=l/2; x1[0]=-l/2; x0[1]=0.; x1[1]=0.; x0[2]=0.; x1[2]=0.;
for(i=0;i<n_;i++) {e0[i]=0.; e1[i]=0.;}
cout << setprecision(15);
for(m=0;m<=mmax;m++)
{
cout << "m=" << setw(2) << m << " ";
for(i=0;i<n_;i++) {p0[i]=alp*(E0[i]+e0[i]); p1[i]=alp*(E0[i]+e1[i]); cout << p0[i] << " " << p1[i] << "
cout << endl;
champ(x0,x1,p0,e1); champ(x1,x0,p1,e0);
}
return 0;
}
Licence et Magistère 1ère année de Physique fondamentale Examen d’informatique 2013-2014 première session
Numéro d’anonymat : 7 2014-03-13 14 :35 :20.000000000
direction du
centre du Soleil
direction du
centre du Soleil
diaphragme diaphragme O
D x
2ω
y
~s
w
~
photodiode P
photodiode
z z
Fig. 1 –
On veut calculer le taux de rayons lumineux atteignant la photodiode. Le problème se ramènerait au calcul de l’aire
de l’intersection de deux cercles si on ne tenait pas compte du rayon angulaire apparent ω du Soleil. Pour des raisons
de clarté on a représenté sur la figure de gauche uniquement le faisceau lumineux de rayons parallèles issu du centre du
Soleil. Mais il faut prendre en compte tous les faisceaux analogues dont la direction fait un angle compris entre 0 et ω
avec la direction du centre du Soleil. Pour faire le calcul on procède par tirage de rayons au hasard :
– on tire un point D sur le disque du diaphragme avec une densité de probabilité uniforme
– on tire une direction orientée de rayon, définie par un vecteur unitaire ~s, avec une densité de probabilité uniforme
à l’intérieur d’un cône de révolution dont l’axe est dirigé vers le centre du Soleil et porté par un vecteur unitaire w,
~
et dont le demi-angle au sommet est ω. On note ce cône (w, ~ ω).
La droite passant par D et parallèle au vecteur ~s coupe le plan du disque de la photodiode en un point P . On effectue N
tirages de rayon de ce type en comptant le nombre Np de fois où le point P s’est trouvé sur le disque de la photodiode.
Le résultat cherché est Np /N .
On suppose que :
– pour effectuer le tirage du point D on dispose d’une fonction écrite en C++ dont l’en-tête est :
void alea D(double rd,double *xD,double *yD)
rd est le rayon du diaphragme (rd est un argument d’entrée)
xD et yD sont les coordonnées cartésiennes de D (dans le repère Oxyz) renvoyées à chaque appel
de la fonction alea D et telles que D se répartit aléatoirement avec une distribution uniforme sur
le diaphragme (xD et yD sont des arguments de sortie).
Licence et Magistère 1ère année de Physique fondamentale Examen d’informatique 2013-2014 première session
Numéro d’anonymat : 8 2014-03-13 14 :35 :20.000000000
– pour effectuer le tirage du vecteur ~s on dispose d’une fonction écrite en C++ dont l’en-tête est :
void alea s(double alp,double bet,double om,double *s)
alp et bet sont les angles α et β en coordonnées sphériques (dans le repère Oxyz) du vecteur w ~
parallèle aux rayons provenant du centre du Soleil (alp et bet sont des arguments d’entrée pour
alea s)
om est la demi-ouverture angulaire ω du cône (w, ~ ω) (c’est un argument d’entrée pour alea s)
s est le tableau-pointeur à trois éléments contenant les composantes cartésiennes (dans le repère
Oxyz) du vecteur ~s caractérisant la direction orientée du rayon que l’on tire au hasard (s est un
argument de sortie pour alea s).
À chaque appel de la fonction alea s il est renvoyé dans s trois composantes sx =s[0], sy =s[1], sz =s[2], telles
que ~s se répartit aléatoirement avec une distribution uniforme dans le cône (w,
~ ω).
Avec ces notations les coordonnées de P s’écrivent :
l
xP = xD + sx
sz
l
y P = y D + sy
sz
zP = l
Licence et Magistère 1ère année de Physique fondamentale Examen d’informatique 2013-2014 première session
Numéro d’anonymat : 9 2014-03-13 14 :35 :20.000000000
alea_D(rd,&xD,&yD);
do alea_s(alp,bet,om,s); while(s[2]==0.);
lam=l/s[2];
xP=xD+lam*s[0]; yP=yD+lam*s[1];
if(xP*xP+yP*yP<=rp2) np++;
}
cout << "Taux de rayons atteignant la photodiode :" << (double)np/N << endl;
return 0;
}
Question 2 :
Écrire la fonction alea D.
Réponse à la question :
void alea_D(double rd,double *xD,double *yD)
{
double rho,gam;
rho=rd*sqrt(drand48()); gam=2*M_PI*drand48();
*xD=rho*cos(gam); *yD=rho*sin(gam);
}
Licence et Magistère 1ère année de Physique fondamentale Examen d’informatique 2013-2014 première session