1 laboratorio di calcolo II AA 2003/04 terza settimana a cura di Domizia Orestano Dipartimento di...

22
1 laboratorio di calcolo II AA 2003/04 terza settimana a cura di Domizia Orestano Dipartimento di Fisica Stanza 159 - tel. (06 5517) 7281 www.fis.uniroma3.it/~orestano orestano@fis.uniroma3.it UNIVERSITA’ DEGLI STUDI ROMA TRE DIPARTIMENTO DI FISICA “E. AMALDI”

Transcript of 1 laboratorio di calcolo II AA 2003/04 terza settimana a cura di Domizia Orestano Dipartimento di...

Page 1: 1 laboratorio di calcolo II AA 2003/04 terza settimana a cura di Domizia Orestano Dipartimento di Fisica Stanza 159 - tel. (06 5517) 7281 orestano.

1

laboratorio di calcolo IIAA 2003/04

terza settimana

a cura di

Domizia Orestano

Dipartimento di FisicaStanza 159 - tel. (06 5517) 7281

www.fis.uniroma3.it/[email protected]

UNIVERSITA’ DEGLI STUDI ROMA TRE

DIPARTIMENTO DI FISICA “E. AMALDI”

Page 2: 1 laboratorio di calcolo II AA 2003/04 terza settimana a cura di Domizia Orestano Dipartimento di Fisica Stanza 159 - tel. (06 5517) 7281 orestano.

2

L’operatore & reference

float x = 2.5;

float& a = x;

float &b = x ;

a e b sono chiamati reference e sono due “etichette” equivalenti all’etichetta x, che fanno riferimento allo stesso oggetto.

Non confondere reference con puntatore:

int i = 3; // oggetto i

int &j = i; // reference a i

int *p = &i; // puntatore a i

i ha un indirizzo in memoria che contiene il valore 3

j ha lo stesso indirizzo

p contiene l’indirizzo di i

Page 3: 1 laboratorio di calcolo II AA 2003/04 terza settimana a cura di Domizia Orestano Dipartimento di Fisica Stanza 159 - tel. (06 5517) 7281 orestano.

3

# include <iostream.h>  int main() {  int i=5; int *p; int *q;  p = &i; q = new int(i);  cout << i << " " << *p << " " << *q << " " << &i << " " << p << " " << q << endl;  i=8;  cout << i << " " << *p << " " << *q << " " << &i << " " << p << " " << q << endl;   return 0; }

  5 5 5 0xbffffa34 0xbffffa34 0x8049a80

8 8 5 0xbffffa34 0xbffffa34 0x8049a80

Uso di & reference (I)

Page 4: 1 laboratorio di calcolo II AA 2003/04 terza settimana a cura di Domizia Orestano Dipartimento di Fisica Stanza 159 - tel. (06 5517) 7281 orestano.

4

# include <iostream.h>  int main() {  int i=5; int &j=i; int *q;  q = new int(i);  cout << i << " " << j << " " << *q << " " << &i << " " << &j << " " << q << endl;  i=8;  cout << i << " " << j << " " << *q << " " << &i << " " << &j << " " << q << endl;   return 0; }

  5 5 5 0xbffffa34 0xbffffa34 0x8049a80

8 8 5 0xbffffa34 0xbffffa34 0x8049a80

Uso di & reference (II)

Page 5: 1 laboratorio di calcolo II AA 2003/04 terza settimana a cura di Domizia Orestano Dipartimento di Fisica Stanza 159 - tel. (06 5517) 7281 orestano.

5

Passaggio dei parametri ad una funzione (I)

I parametri di una funzione possono essere trasmessi per valore:

void swap_value(int i1, int i2); // prototipo di una funzione che riceve due parametri per valore

o per reference:

void swap_ref(int &i1, int &i2); // prototipo di una funzione che riceve due parametri per reference

Page 6: 1 laboratorio di calcolo II AA 2003/04 terza settimana a cura di Domizia Orestano Dipartimento di Fisica Stanza 159 - tel. (06 5517) 7281 orestano.

6

Per valore:

void swap_value(int i1,int i2) {

// quando viene chiamata questa funzione con una // istruzione del tipo// swap(a,b);// tutto va come se il compilatore eseguisse le istruzioni// int i1=a;// int i2=b;

int temp = i1;

i1 = i2;

i2 = temp;

}

Passaggio dei parametri ad una funzione (II)

Page 7: 1 laboratorio di calcolo II AA 2003/04 terza settimana a cura di Domizia Orestano Dipartimento di Fisica Stanza 159 - tel. (06 5517) 7281 orestano.

7

Per reference:

void swap_ref(int &i1,int &i2) {

// quando viene chiamata questa funzione con una

// istruzione del tipo// swap(a,b);// tutto va come se il compilatore eseguisse le istruzioni// int &i1=a;// int &i2=b;

int temp = i1;

i1 = i2;

i2 = temp;

}

 

 

Passaggio dei parametri ad una funzione (III)

Page 8: 1 laboratorio di calcolo II AA 2003/04 terza settimana a cura di Domizia Orestano Dipartimento di Fisica Stanza 159 - tel. (06 5517) 7281 orestano.

8

con i puntatori (“alla maniera del C”):

void swap_point(int *i1,int *i2) {

// quando viene chiamata questa funzione con una

// istruzione del tipo// swap(&a,&b);// tutto va come se il compilatore eseguisse le istruzioni// int *i1=&a;// int *i2=&b;

int temp = *i1;

*i1 = *i2;

*i2 = temp;

}

 

 

Passaggio dei parametri ad una funzione (IV)

Page 9: 1 laboratorio di calcolo II AA 2003/04 terza settimana a cura di Domizia Orestano Dipartimento di Fisica Stanza 159 - tel. (06 5517) 7281 orestano.

9

int main() {  int a = 2; int b = 3;  cout << endl; cout << endl << " a = " << a << "; b = " << b << endl ;  swap_value(a,b); cout << endl << " a = " << a << "; b = " << b << endl ; swap_ref(a,b); cout << endl << " a = " << a << "; b = " << b << endl ;  swap_point(&a,&b); cout << endl << " a = " << a << "; b = " << b << endl ;

return 0;  }

a = 2; b = 3

a = 2; b = 3

a = 3; b = 2

a = 2; b = 3

Passaggio dei parametri ad una funzione (V)

Page 10: 1 laboratorio di calcolo II AA 2003/04 terza settimana a cura di Domizia Orestano Dipartimento di Fisica Stanza 159 - tel. (06 5517) 7281 orestano.

10

Passaggio dei parametri ad una funzione (VI)

Funzioni che hanno come parametro un vettore:

void modulo2(double * vect, int dim) {double mod = 0;

for(int I=0; I<dim; I++){

mod += vect[I]*vect[I]; // uso vect[I]

vect[I] = 0; // modifico vect[I]

}

return mod;

}Un vettore viene identificato mediante il puntatore al suo primo elemento, quindi la funzione riceve sempre un puntatore e potrebbe andare ad alterare il contenuto del vettore... Come si realizza in questo caso il passaggio per valore? Cambiando il prototipo della funzione in:

void modulo2(const double * vect, int dim);

Page 11: 1 laboratorio di calcolo II AA 2003/04 terza settimana a cura di Domizia Orestano Dipartimento di Fisica Stanza 159 - tel. (06 5517) 7281 orestano.

11

Stato della simulazione del sistema solare

• Abbiamo creato la classe Corpo Celeste

• Abbiamo scritto diverse versioni del programma main che instanzia direttamente degli oggetti di questa classe

• Prima di proseguire sarà bene soffermarsi a verificare la correttezza del codice prodotto: nel corso dell’esercitazione effetturete un esercizio di “debug” del metodo CorpoCeleste::CalcolaPosizione

• Ora torniamo al diagramma UML delle classi previste e effettuiamo la dichiarazione della classe SistemaSolare e la sua implementazione

• Infine scriviamo il programma principale, simula.cc

Page 12: 1 laboratorio di calcolo II AA 2003/04 terza settimana a cura di Domizia Orestano Dipartimento di Fisica Stanza 159 - tel. (06 5517) 7281 orestano.

12

relazione di aggregazione

Page 13: 1 laboratorio di calcolo II AA 2003/04 terza settimana a cura di Domizia Orestano Dipartimento di Fisica Stanza 159 - tel. (06 5517) 7281 orestano.

13

La classe SistemaSolare

SistemaSolare

????????? pianetiint N

SistemaSolare(int n)

~SistemaSolare()

int aggiungiPianeta(CorpoCeleste * unPianeta)

void evolvi(float T, float dt)

int nPianeti()

Page 14: 1 laboratorio di calcolo II AA 2003/04 terza settimana a cura di Domizia Orestano Dipartimento di Fisica Stanza 159 - tel. (06 5517) 7281 orestano.

14

#include "CorpoCeleste.h"

#define G 6.673e-11

class SistemaSolare {

protected:

?????????? pianeti; // lista dei pianeti

int N; // numero dei pianeti

public:

SistemaSolare(int n);

~SistemaSolare();

int aggiungiPianeta(CorpoCeleste *unPianeta);

int nPianeti() {return N;};

void evolvi(float T, float dt);

};

SistemaSolare.h

Page 15: 1 laboratorio di calcolo II AA 2003/04 terza settimana a cura di Domizia Orestano Dipartimento di Fisica Stanza 159 - tel. (06 5517) 7281 orestano.

15

Page 16: 1 laboratorio di calcolo II AA 2003/04 terza settimana a cura di Domizia Orestano Dipartimento di Fisica Stanza 159 - tel. (06 5517) 7281 orestano.

16

Page 17: 1 laboratorio di calcolo II AA 2003/04 terza settimana a cura di Domizia Orestano Dipartimento di Fisica Stanza 159 - tel. (06 5517) 7281 orestano.

17

#include "CorpoCeleste.h"

#define G 6.673e-11

class SistemaSolare {

protected:

CorpoCeleste ** pianeti; // lista dei pianeti

int N; // numero dei pianeti

public:

SistemaSolare(int n);

~SistemaSolare();

int aggiungiPianeta(CorpoCeleste *unPianeta);

int nPianeti() {return N;};

void evolvi(float T, float dt);

};

SistemaSolare.h

Page 18: 1 laboratorio di calcolo II AA 2003/04 terza settimana a cura di Domizia Orestano Dipartimento di Fisica Stanza 159 - tel. (06 5517) 7281 orestano.

18

#include "SistemaSolare.h" #include <stdlib.h>#include <math.h>#include <iostream.h> SistemaSolare::SistemaSolare(int n) {

pianeti = new CorpoCeleste*[n]; // si alloca un vettore di puntatori a oggetti di tipo // CorpoCeleste: n puntatori a CorpoCeleste N = 0; // si pone il numero iniziale di pianeti pari a 0} SistemaSolare::~SistemaSolare() { delete [] pianeti;} int SistemaSolare::aggiungiPianeta(CorpoCeleste *unPianeta) {

pianeti[N++] = unPianeta; // si aggiunge unPianeta

//alla lista dei pianeti e si incrementa N di uno.

return N;}

SistemaSolare.ccPrima parte

Page 19: 1 laboratorio di calcolo II AA 2003/04 terza settimana a cura di Domizia Orestano Dipartimento di Fisica Stanza 159 - tel. (06 5517) 7281 orestano.

19

void SistemaSolare::evolvi(float T, float dt) {

float t = 0 ; //tempo dall’inizio della simulazione

// ripeti fino a che t<=T while (t <= T) {

// loop sui pianeti

for (int i=0; i<N; i++) {

double fx = 0.; double fy = 0.;

// calcola la forza esercitata sul pianeta // i-esimo da parte di tutti gli altri // pianeti j-esimi

for (int j=0; j<N; j++) {

// calcola la distanza tra i e j

double d = sqrt( (pianeti[i]->X()-pianeti[j]->X())* (pianeti[i]->X()-pianeti[j]->X())+

(pianeti[i]->Y()-pianeti[j]->Y())* (pianeti[i]->Y()-pianeti[j]->Y()) );

SistemaSolare.ccSeconda parte

Page 20: 1 laboratorio di calcolo II AA 2003/04 terza settimana a cura di Domizia Orestano Dipartimento di Fisica Stanza 159 - tel. (06 5517) 7281 orestano.

20

if (d!=0) { //Somma a fx e fy agenti sull i-esimo corpo //la forza dovuta al corpo j-esimo

fx += -G*pianeti[i]->M()*pianeti[j]->M()* ( pianeti[i]->X() – pianeti[j]->X() ) / (d*d*d) ;

fy += -G*pianeti[i]->M()*pianeti[j]->M()* ( pianeti[i]->Y() – pianeti[j]->Y()) / (d*d*d) ;

} // termina l’if su d!=0

} // termina il loop sul j-esimo pianeta // ora conosco la forza che agisce sul- // l’i-esimo pianeta e posso invocare // calcolaPosizione sull’i-esimo pianeta pianeti[i]->calcolaPosizione((float)fx, (float)fy, dt); pianeti[i]->stampaPosizione();

} // termina il loop sull’iesimo pianeta

cout << endl; t += dt; // viene incrementato il tempo

} // while ripeti fino a che t<=T} // l’implementazione del metodo evolvi e’ conclusa

SistemaSolare.ccTerza parte

Page 21: 1 laboratorio di calcolo II AA 2003/04 terza settimana a cura di Domizia Orestano Dipartimento di Fisica Stanza 159 - tel. (06 5517) 7281 orestano.

21

Interaction Diagram (semplificato)

Page 22: 1 laboratorio di calcolo II AA 2003/04 terza settimana a cura di Domizia Orestano Dipartimento di Fisica Stanza 159 - tel. (06 5517) 7281 orestano.

22

 

#include “SistemaSolare.h” int main() { //NB si usano unita’ MKS // instanzio un oggetto SistemaSolare ss con 2 corpi SistemaSolare ss(2);

// instanzio due oggetti CoproCeleste, sole e terra

CorpoCeleste sole(“Il Sole”, 1.98e30, 0., 0., 0., 0.); CorpoCeleste terra(“La Terra”, 5.98e24, 1.52e11, 0., 0., 29476.35);

// li aggiungo al Sistemasolare ss ss.aggiungiPianeta(&sole); ss.aggiungiPianeta(&terra);

// faccio evolvere il sistema per 1 anno in passi di un giorno ss.evolvi(86400*365, 86400);

return 0;}

 

simula.cc