Vous êtes sur la page 1sur 9

Numéro d’anonymat : 1 2014-03-13 14 :35 :20.

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 :

UNIVERSITÉ DE PARIS SUD Centre d’Orsay 2013-2014 première session d’examen

L3 et Magistère 1ère année de Physique fondamentale

Examen d’informatique jeudi 13 mars 2013 9h30 à 11h30 bât. 337 salle 3

Aucun document n’est autorisé.


Les programmes doivent être écrits en C/C++. Les réponses doivent obligatoirement être écrites sur les feuilles de
l’énoncé, dans l’espace réservé. Il est fortement conseillé de rédiger d’abord le plan des réponses au brouillon.
Respecter les notations de l’énoncé : par exemple la variable notée nt dans l’énoncé devra être écrite nt dans un pro-
gramme, n′′ devra être écrite ns.
Ne pas commencer à répondre à un exercice avant d’en avoir entièrement lu l’énoncé.
L’utilisation de fonctions est laissée à l’appréciation de l’étudiant, sauf quelques cas où elle est imposée.
On suppose que tous les #include<stdlib.h> ... #include<bibli fonctions.h> using namespace std ; nécessaires
sont sous-entendus, il n’y a pas à les écrire.
On rappelle qu’on ouvre un fichier en écriture par l’instruction : fstream xxx("nom de fichier.qqc",ios : :out) ;
et en lecture par : fstream yyy("nom de fichier.qqc",ios : :in) ;
Ne pas faire lire les données au clavier ou dans un fichier par un cin >>, ou l’équivalent pour un fichier, sauf si cela est
explicitement demandé. Par défaut, les données seront donc fournies dans le programme lui-même, par des instructions
du type :
dx=0.01;
a=1.7; b=1.1;
etc.
Dans chaque exercice on suppose que le programme principal1 et les fonctions2 sont écrits dans un unique fichier.
Les exercices sont indépendants les uns des autres.
Le nombre d’étoiles (de zéro à trois) donne une indication sur le niveau de l’exercice.
Le nombre de points (sur un total de 40) attribué à chaque exercice est indiqué entre parenthèses après le nom de
l’exercice (c’est un barème indicatif ). Deux points sont réservés à la qualité de la présentation.
A titre indicatif le nombre de lignes du corrigé de chaque question est indiqué entre crochets (tout compris, c’est à dire
avec int main(), les accolades, return 0 ;, des commentaires éventuels).
Le corrigé pourra être consulté sur le site du cours.

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

Comparaison de deux égalités de tableaux-pointeurs * (6)


Question 1 :
est-ce que les deux façons de mettre les mêmes valeurs dans deux tableaux-pointeurs sont strictement équivalentes dans
les programmes (a) et (b) ci-dessous ? Les deux seules lignes qui diffèrent sont signalées par le signe #. Justifier la réponse.
// Programme (a) // Programme (b)
#include<iostream> #include<iostream>
#include<stdlib.h> #include<stdlib.h>
using namespace std; using namespace std;
int main() int main()
{ {
int i,n=3; int i,n=3;
double *x=(double *)malloc(n*sizeof(double)); double *x=(double *)malloc(n*sizeof(double));
double *y=(double *)malloc(n*sizeof(double)); # double *y;
for(i=0;i<n;i++) x[i]=2*i; for(i=0;i<n;i++) x[i]=2*i;
for(i=0;i<n;i++) y[i]=x[i]; # y=x;
for(i=0;i<n;i++) cout << y[i] << " "; for(i=0;i<n;i++) cout << y[i] << " ";
cout << endl; cout << endl;
return 0; return 0;
} }

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.

Échange de valeurs * (4)


Question :
Écrire une fonction qui échange les valeurs contenues dans deux variables, c’est à dire telle que, dans l’exemple
suivant :
double a,b;
a=1.; b=2.;
appel de la fonction
...
après l’appel de la fonction la variable a contienne la valeur 2 et la variable b la valeur 1.
Écrire également un exemple d’appel de cette fonction.

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;
}

Atome soumis à un champ électrique ** (10)


On considère un modèle d’atome dans le cadre de la mécanique classique, constitué d’un noyau fixe de charge Zq placé à
l’origine d’un repère (0, ~ux , ~uy )3 et d’un électron de charge −q en orbite autour du noyau et de rayon vecteur ~r. L’atome
est soumis à un champ électrique extérieur dépendant du temps E(t). ~

y Ex

~
E(t)

~r˙(t=0) E0

u~y
O u~x r0 x O T 2T 3T t

La relation fondamentale de la dynamique appliquée à l’électron s’écrit :


~r q ~
~r¨ = −a 3 − E
r m
où
Zq 2
a=
4πε0 m
3 On se restreint à deux dimensions.

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

On suppose que le champ électrique a pour expression :


~
E(t) = E0 ~ux pour T ≤ t ≤ 2T et 0 sinon

~
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;
}

Les réponses utilisant des tableaux sont tout aussi valables.

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

Dipôles induits *** (10)


Le champ électrique ~e créé en un point quelconque B de l’espace par un dipôle électrostatique de moment dipolaire p~
−−

placé au point A s’écrit, en posant ~r = AB :
 
1 3(~
p.~r)~r
~e = − p~
4πε0 r3 r2
−→ −−→
On pose ~a = OA, ~b = OB, O étant l’origine d’un repère orthonormé Oxyz.
Question 1 :
Écrire une fonction qui calcule le champ électrique ~e en B. Cette fonction aura pour en-tête :
void champ(double *a,double *b,double *p,double *e)
a, b, p étant des arguments d’entrée et e un argument de sortie (le tableau-pointeur a contient les compo-
santes du vecteur ~a, etc.).
1
On rappelle que = 9 109 (SI).
4πε0

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

Réponse d’un photomètre ** (10)


La lecture de l’énoncé de cet exercice demande du temps mais l’écriture de la solution est facile et rapide.
Un photomètre est constitué d’une photodiode et d’un diaphragme schématisés par deux disques. La perpendiculaire au
disque de la photodiode passant par son centre est aussi perpendiculaire au disque du diaphragme et passe aussi par le
centre de ce dernier. Les deux disques sont donc parallèles et « centrés » l’un par rapport à l’autre. La droite joignant les
deux centres est l’axe du photomètre. Le diaphragme est éclairé par le Soleil dont la direction du centre fait un angle α
avec l’axe du photomètre.

direction du
centre du Soleil

direction du
centre du Soleil

diaphragme diaphragme O
D x


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

l étant la distance diaphragme-photodiode et on note rp le rayon de la photodiode.


Les valeurs numériques (en SI) :
l = 0.2
rd = 10−3
rp = 1.25 10−3
α = 0.4◦
β=0
ω = 0.25◦
sont déjà écrites dans la réponse à la question.
Question 1 :
Écrire le programme qui calcule le rapport Np /N en supposant déjà écrites et disponibles les fonctions alea D
et alea s, comme si, par exemple, elle faisaient partie de la bibliothèque des fonctions du Magistère, telles
alea ou rk4.
Réponse à la question :
#include<iostream>
#include<stdlib.h>
#include<cmath>
using namespace std;
//-------------------------------------------------------------------------------------------------------
double dr(double x)
{
return x/180.*M_PI;
}
//-------------------------------------------------------------------------------------------------------
int main()
{
double l=0.2,rd=1.e-3,rp=1.25e-3,alp=dr(0.4),bet=dr(0.),om=dr(0.25); // unités SI
int n=3,j,N=100000,np;
double xD,yD,xP,yP,rp2,lam;
double *s=(double *)malloc(n*sizeof(double));
rp2=rp*rp;
np=0;
// Boucle sur les rayons venant du Soleil
for(j=1;j<=N;j++)
{

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

Vous aimerez peut-être aussi