34
PROGRAMMAZIONE AVANZATA PER IL CALCOLO S CIENTIFICO Codice C++ per il calcolo delle intersezioni tra griglie Corner Point e Faglie Author: Luca Turconi 766492 6 ottobre 2012

Codice C++ per il calcolo delle intersezioni tra griglie ...forma/Didattica/ProgettiPacs/Turconi13-14/... · Introduzione L’obiettivo di questo progetto è lo sviluppo di una libreria

  • Upload
    others

  • View
    1

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Codice C++ per il calcolo delle intersezioni tra griglie ...forma/Didattica/ProgettiPacs/Turconi13-14/... · Introduzione L’obiettivo di questo progetto è lo sviluppo di una libreria

PROGRAMMAZIONE AVANZATA PER IL CALCOLO SCIENTIFICO

Codice C++ per il calcolo delle intersezioni tragriglie Corner Point e Faglie

Author:Luca Turconi

766492

6 ottobre 2012

Page 2: Codice C++ per il calcolo delle intersezioni tra griglie ...forma/Didattica/ProgettiPacs/Turconi13-14/... · Introduzione L’obiettivo di questo progetto è lo sviluppo di una libreria

Indice

1. Griglie Corner Point 51.1. Definire la griglia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

1.1.1. Pilastri Coordinati . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61.1.2. Definizione delle Celle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

2. Descrizione del Codice 82.1. Namespace Geometry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

2.1.1. Oggetti geometrici fondamentali . . . . . . . . . . . . . . . . . . . . . . . . 82.1.2. Calcolo delle intersezioni tra oggetti fondamentali . . . . . . . . . . . . . 92.1.3. Oggetti geometrici legati alla griglia Corner Point . . . . . . . . . . . . . . 172.1.4. Calcolo delle intersezioni tra oggetti Corner Point . . . . . . . . . . . . . . 18

2.2. Namespace Intersect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212.3. IntersectionSolver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222.4. Breve Tutorial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

3. Risultati Numerici 253.1. Valutazione dell’algoritmo APPROXREFINED . . . . . . . . . . . . . . . . . . . . . 253.2. Un caso reale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

3.2.1. Confronto degli algoritmi per il calcolo delle intersezioni . . . . . . . . . 273.2.2. Confronto delle strategie di visita della griglia . . . . . . . . . . . . . . . . 28

A. Appendice di geometria delle superfici 29A.1. Piano tangente . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29A.2. Prima forma fondamentale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30A.3. Curvatura Normale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30A.4. Seconda forma fondamentale e Mappa di Weingarten . . . . . . . . . . . . . . . 31A.5. Curvatura Media e Curvatura Gaussiana . . . . . . . . . . . . . . . . . . . . . . . 32A.6. Curvature Principali . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

2

Page 3: Codice C++ per il calcolo delle intersezioni tra griglie ...forma/Didattica/ProgettiPacs/Turconi13-14/... · Introduzione L’obiettivo di questo progetto è lo sviluppo di una libreria

IntroduzioneL’obiettivo di questo progetto è lo sviluppo di una libreria C++ che consenta la gestione dellegriglie di tipo Corner Point e permetta il calcolo delle intersezioni di tali griglie con delle faglie.L’interesse per un codice che fornisca gli strumenti necessari a condurre queste operazionirisulta di particolare interesse nell’ambito della geofisica e della petroleum engineering. Infatti,per condurre simulazioni che coinvolgono dei mezzi porosi, è importante conoscere in detta-glio le proprietà e la conformazione del materiale in cui i fenomeni si svolgono. Il sottosuoloè spesso caratterizzato dalla presenza di faglie che possono condizionare in modo moltomarcato il comportamento del fluido. Non potendo usare una descrizione troppo dettagliatadella roccia per condurre le simulazioni numeriche, sono state proposte numerose tecniche diUpscaling che permettono di riassumere nel migliore dei modi la grande quantità di informa-zione necessaria a descrivere i giacimenti. In presenza di faglie queste tecniche risultano peròpoco affidabili per via della forte anisotropia che queste particolari conformazioni geologicheinducono nel mezzo. Per risolvere questo problema l’idea è quella di utilizzare modelli adhoc per le gestione delle faglie. Nella definizione di tali modelli è importante conoscere leproprietà geometriche e fisiche della faglia. In questo senso è fondamentale sapere come lefaglie intersechino le celle della griglia di calcolo. Questo permette di calcolare le quantitànecessarie per far comunicare il modello della faglia con quello globale del giacimento.

Uno dei software di simulazione più diffusi nell’ambito della petroleum engineering èEclipse della Schlumberger. Uno degli obiettivi di questo progetto è quello di garantire lacompatibilità dei dati di input e output con tale piattaforma. Questo simulatore utilizza grigliedi tipo Corner Point che riescono ad adattarsi facilmente all’andamento spesso stratificatodelle rocce dei giacimenti. La flessibilità concessa da tale struttura si riflette però sulla difficoltànello svincolarsi da una visione cell centered nella gestione della struttura e, per questo motivo,sulla difficoltà a costruire metodi particolarmente performanti.

Il codice sviluppato in questo progetto si pone dunque l’obiettivo fornire uno strumentocapace di gestire griglie di tipo Corner Point, e di calcolarne in modo efficiente le intersezionicon le faglie.

Per la descrizione di queste conformazioni geologiche si utilizzano delle superfici bilinearidefinite da quattro punti nello spazio. Questo permette una facile implementazione e assicurauna buona descrizione di come si posizionano nello spazio.

La relazione del lavoro comincia con una breve introduzione sulle griglie Corner Point in cuiviene descritto il formato di gestione dei dati usato dal simulatore Eclipse. Si procede quindicon la descrizione del codice e delle sue parti principali. Vengono in particolare presentati imetodi implementati per il calcolo delle intersezioni e le strategie proposte per lo scorrimentodella griglia. Nella sezione successiva saranno presentati alcuni casi test con l’obiettivo dimostrare il funzionamento del codice in termini di performance, e di accuratezza dei metodi.Per finire si riporta un breve tutorial che illustra le principali funzionalità della libreria.

3

Page 4: Codice C++ per il calcolo delle intersezioni tra griglie ...forma/Didattica/ProgettiPacs/Turconi13-14/... · Introduzione L’obiettivo di questo progetto è lo sviluppo di una libreria

RIASSUNTO DEGLI OBIETTIVI

Possiamo riassumere in modo schematico gli obiettivi di questo progetto:

1. mantenere la compatibilità con il simulatore Eclipse (Schlumberger)

2. fornire le funzionalità per la gestione e la visualizzazione di griglie Corner Point

3. fornire classi e metodi per la definizione della geometria delle faglie

4. proporre e analizzare diversi algoritmi per il calcolo delle intersezioni tra un segmento euna superficie Bilineare

5. proporre delle strategie per lo scorrimento della griglia durante il calcolo delle interse-zioni

4

Page 5: Codice C++ per il calcolo delle intersezioni tra griglie ...forma/Didattica/ProgettiPacs/Turconi13-14/... · Introduzione L’obiettivo di questo progetto è lo sviluppo di una libreria

1. Griglie Corner PointUna griglia di tipo Corner Point è un particolare tipo di griglia tridimensionale, formata dacelle a 6 facce (esaedri). Come vedremo nel seguito questo tipo di mesh è particolarmenteindicato per l’implementazione di modelli geologici.

La struttura di una griglia Corner Point è definita specificando un insieme di rette cheprendono il nome di pilastri (pillars). Questi pilastri sono ordinati attraverso due indici (i,j)che permettono di identificare la loro reciproca posizione. Le celle sono invece identificateattraverso la terna (i,j,k) e rappresentano il volume racchiuso tra 4 pilastri adiacenti e delimitatoda due superfici orizzontali. Queste sono definite identificando due punti su ogni pilastro.Una cella è dunque definita specificando l’altezza di ogni suo vertice lungo il relativo pilastro.

In generale facendo riferimento ad una griglia Nx ×Ny ×Nz si intende una griglia formatada Nx celle in direzione x, Ny celle in direzione y ed Nz celle in direzione z. In questo casodovremo quindi definire (Nx +1)× (Ny +1) pilastri.

Questa struttura risulta molto versatile permettendo la presenza di celle degeneri in cuiuna o più coppie di vertici definiti sullo stesso pilastro collassano in un unico punto. Questaproprietà è particolarmente apprezzata nella costruzione dei modelli geologici e viene spessoutilizzata per descrivere i diversi strati delle rocce che spesso, muovendosi all’interno delgiacimento, si assottigliano fino a scomparire.

Una griglia di tipo Corner Point presenta una struttura logica a tre indici ijk che ne rende piùfacile la gestione. Tuttavia questa struttura non rispecchia esattamente la struttura fisica chela griglia può assumere. Dato che ogni cella viene definita in modo indipendente dalle altre,celle adiacenti nello spazio ijk non devono necessariamente essere adiacenti nello spaziofisico. Per questo motivo i simulatori che si basano su questo tipo di geometrie supportano leNON-NEIGHBORING CONNECTIONS: cioè la possibilità di far comunicare tra loro celle nonadiacenti nello spazio ijk, ed eventualmente neppure nello spazio fisico.

5

Page 6: Codice C++ per il calcolo delle intersezioni tra griglie ...forma/Didattica/ProgettiPacs/Turconi13-14/... · Introduzione L’obiettivo di questo progetto è lo sviluppo di una libreria

1.1. DEFINIRE LA GRIGLIA

Descriviamo ora il formato utilizzato dal software Eclipse nella definizione delle griglie CornerPoint.

1.1.1. Pilastri Coordinati

Ogni pilastro è individuato da due punti distinti, p1 e p2, ognuno dei quali è identificatoattraverso le sue coordinate (x,y,z).

I pilastri vengono definiti in sequenza in modo ordinato al variare degli indici: i più veloce ej più lento:

(1,1), (2,1), ...(Nx +1,1), (1,2), ...(Nx +1, Ny +1).

Se consideriamo una griglia Nx ×Ny ×Nz , i pilastri saranno (Nx +1)× (Ny +1). Per definirliavremo dunque bisogno di specificare 6(Nx +1)(Ny +1) valori.

In Eclipse i pilastri della griglia sono definiti attraverso il comando COORD:

COORD

x(1,1)1 y (1,1)

1 z(1,1)1 x(1,1)

2 y (1,1)2 z(1,1)

2

...

x(Nx+1,1)1 y (Nx+1,1)

1 z(Nx+1,1)1 x(Nx+1,1)

2 y (Nx+1,1)2 z(Nx+1,1)

2

1° fila di pilastri (j=1)

x(1,2)1 y (1,2)

1 z(1,2)1 x(1,2)

2 y (1,2)2 z(1,2)

2...x

(Nx+1,Ny+1)1 y

(Nx+1,Ny+1)1 z

(Nx+1,Ny+1)1 x

(Nx+1,Ny+1)2 y

(Nx+1,Ny+1)2 z

(Nx+1,Ny+1)2

/

6

Page 7: Codice C++ per il calcolo delle intersezioni tra griglie ...forma/Didattica/ProgettiPacs/Turconi13-14/... · Introduzione L’obiettivo di questo progetto è lo sviluppo di una libreria

1.1.2. Definizione delle Celle

Ogni cella è individuata dai 4 pilastri corrispondenti, sui quali giacciono gli spigoli laterali, edall’altezza alla quale si trovano gli 8 vertici. Per ogni cella devono quindi essere specificati 8valori: le coordinate in direzione z dei vertici, i quali si muovono lungo le linee coordinate.

Se consideriamo una griglia Nx ×Ny ×Nz , per la definizione delle celle è necessario fornire8Nx Ny Nz valori.

In Eclipse tali valori sono definiti attraverso il comando ZCORN:

ZCORN

z(1,1,1)1 z(1,1,1)

2 . . . . . . z(Nx ,1,1)1 z(Nx ,1,1)

2

z(1,1,1)3 z(1,1,1)

4 . . . . . . z(Nx ,1,1)3 z(Nx ,1,1)

4

z(1,2,1)1 z(1,2,1)

2 . . . . . . z(Nx ,2,1)1 z(Nx ,2,1)

2

z(1,2,1)3 z(1,2,1)

4 . . . . . . z(Nx ,2,1)3 z(Nx ,2,1)

4

...

z(1,Ny ,1)1 z

(1,Ny ,1)2 . . . . . . z

(Nx ,Ny ,1)1 z

(Nx ,Ny ,1)2

z(1,Ny ,1)3 z

(1,Ny ,1)4 . . . . . . z

(Nx ,Ny ,1)3 z

(Nx ,Ny ,1)4

z(1,1,1)5 z(1,1,1)

6 . . . . . . z(Nx ,1,1)5 z(Nx ,1,1)

6

z(1,1,1)7 z(1,1,1)

8 . . . . . . z(Nx ,1,1)7 z(Nx ,1,1)

8

...

z(1,Ny ,1)5 z

(1,Ny ,1)6 . . . . . . z

(Nx ,Ny ,1)5 z

(Nx ,Ny ,1)6

z(1,Ny ,1)7 z

(1,Ny ,1)8 . . . . . . z

(Nx ,Ny ,1)7 z

(Nx ,Ny ,1)8

1° strato di celle (k=1)

z(1,1,2)1 z(1,1,2)

2 . . . . . . z(Nx ,1,2)1 z(Nx ,1,2)

2

z(1,1,2)3 z(1,1,2)

4 . . . . . . z(Nx ,1,2)3 z(Nx ,1,2)

4...z

(1,Ny ,Nz )7 z

(1,Ny ,Nz )8 . . . . . . z

(Nx ,Ny ,Nz )7 z

(Nx ,Ny ,Nz )8

/

7

Page 8: Codice C++ per il calcolo delle intersezioni tra griglie ...forma/Didattica/ProgettiPacs/Turconi13-14/... · Introduzione L’obiettivo di questo progetto è lo sviluppo di una libreria

2. Descrizione del CodiceLa prima necessità che si incontra, volendo costruire una libreria capace di affrontare ilproblema del calcolo delle intersezioni tra oggetti tridimensionali, è ovviamente quello diavere gli strumenti necessari a gestire i principali oggetti geometrici. Si è pensato quindi disviluppare una serie di classi che permettessero di gestire in modo agevole tali elementi.

Partendo dal concetto di punto vengono definiti gli oggetti via via più complessi: linea,segmento, triangolo e superficie bilineare. Ovviamente l’attenzione principale nello svilupparequesti oggetti è quella di dotarli della capacità di intersecarsi tra loro, creando metodi efficientiper testare l’esistenza di tali intersezioni e calcolarle.

Terminata la costruzione delle classi per gli elementi geometrici fondamentali, si procedecon l’implementazione degli oggeti più complessi legati alla griglia Corner Point.

L’obiettivo è quello di fornire una struttura dati adatta a gestire la griglia, garantendo lacompatibilità con il formato dei file usato dal software di simulazione Eclipse. Per questomotivo nella libraria sono state introdotte la classi CPgrid, CPcell e CPpillar. Le due classiaggiuntive PermeabilityField e TransmissibilityField permettono di immagazzinare,insieme alla griglia, anche le proprietà fisiche del dominio da essa descritto.

Tutti gli oggetti geometrici definiti nella libreria sono contenuti nel namespace Geometry.

La seconda parte della libreria fornisce alcune strutture dati progettate per il salvatag-gio e il post-processing delle intersezioni. In particolare le strutture CellIntersections eGridIntersections adottano un punto di vista che chiameremo cell centered, in quantosalvano per ogni cella le intersezioni trovate.

Le altre due strutture GridEdgeMap e GridIntersectionMap permettono invece di im-magazzinare i lati della griglia e le intersezioni evitando di creare più copie dello stessoelemento.

Le classi che implementano questi concetti sono contenute nel namespace Intersect.

Procediamo ora con una descrizione più dettagliata delle funzionalità offerte dalla libreria.

2.1. NAMESPACE GEOMETRY

2.1.1. Oggetti geometrici fondamentali

La prima unità fondamentale nella costruzione di una geometria è il punto. Per l’implemen-tazione di questo concetto è stata creata la struct Point3D. Nella logica del codice i puntivengono assimilati ai corrispondenti vettori posizione ed è per questo motivo che per essisono definite le principali operazioni vettoriali, quali: prodotto scalare, prodotto vettoriale ecalcolo della norma euclidea. Questa possibilità rende particolarmente agevole eseguire lamaggior parte dei calcoli geometrici che saranno richiesti per determinare le intersezioni. Inquesto modo è possibile definire i vettori nello spazio tridimensionale attraverso un semplicealias:

typedef Point3D Vector3D;

8

Page 9: Codice C++ per il calcolo delle intersezioni tra griglie ...forma/Didattica/ProgettiPacs/Turconi13-14/... · Introduzione L’obiettivo di questo progetto è lo sviluppo di una libreria

Partendo dal concetto di punto vengono costruite le classi: Line, per la gestione delle rette,e Segment, per i segmenti.

Una retta è definita a partire da una coppia di punti generatori. La classe Line fornisce deimetodi per ottenere, a partire dal valore di una qualunque coordinata, il punto corrispondentesulla retta.

La struttura implementata per la gestione dei segmenti è invece più articolata. Oltre adalcuni metodi di base che implementano la parametrizzazione e che permettono di estrarre al-cune caratteristiche geometriche dell’oggetto, come ad esempio gli estremi o la sua lunghezza,vengono forniti anche metodi che permettono di eseguire operazioni e test legati al problemadell’intersezione. Queste funzionalità verranno descritte in dettaglio una volta introdotti tuttigli oggetti geometrici convolti.

Il codice procede quindi verso la definizione di oggetti più complessi. Il prossimo passo èquello di considerare un oggetto definito da tre punti nello spazio: il triangolo.

La classe Triangle si occupa di questo: essa permette il salvataggio dei tre vertici comemembri privati e fornisce le principali operazioni su questo tipo di oggetti. Oltre ai metodiget e set per la gestione dei vertici, vengono forniti dei metodi per calcolare le proprietà geo-metriche di base, quali il perimetro, l’area e il vettore normale al piano generato dal triangolo.La possibilità di estrarre facilmente la normale verrà fortemente sfruttata dai metodi per ilcalcolo dell’intersezione con altri oggetti.

Aumentando ancora la complessità si giunge alla definizione della superficie bilineare.Una superficie di questo tipo è detta anche superficie rigata, in quanto può essere ottenutadisegnando i segmenti che uniscono i punti corrispondenti dei lati opposti. Per definire unoggetto di questo tipo è sufficiente specificare 4 punti nello spazio. Nell’implementare laclasse BilinearSurface si è utilizzata la convenzione che identifica le coppie A-C e B-Dcome vertici rispettivamente opposti. La classe fornisce anche i metodi che consentono divalutare la parametrizzazione della superficie per qualunque valore ammissibile dei parametrie le rispettive derivate prime e seconde rispetto ad u e v. E’ inoltre possibile estrarre in modoagevole il vettore normale alla superficie in ogni punto. Questo è di fondamentale importanzanell’implementazione dei metodi per il calcolo della curvatura della superficie. In particolaresono implementati metodi che consentono il calcolo della curvatura in un punto e dellacurvatura max raggiunta sulla superficie. Le formule utilizzate nell’implementazione di questimetodi sono descritte dettagliatamente nell’appendice di geometria delle superfici. Vengonoinfine forniti i metodi per il calcolo dell’intersezione tra tale superficie e un segmento.

2.1.2. Calcolo delle intersezioni tra oggetti fondamentali

Avendo definito gli oggetti geometrici fondamentali descriviamo ora i metodi implementatiper risolvere il problema dell’intersezione.

La prima classe dotata di metodi di questo tipo è Segment. Le funzionalità fornite permet-tono di trattare il problema dell’intersezione con il piano generato da un triangolo. Per primacosa descriviamo il test che permette di sapere l’intersezione tra il segmento e il piano esiste.

9

Page 10: Codice C++ per il calcolo delle intersezioni tra griglie ...forma/Didattica/ProgettiPacs/Turconi13-14/... · Introduzione L’obiettivo di questo progetto è lo sviluppo di una libreria

bool Segment :: intersectThePlaneOf(const Triangle & t) const{

Vector3D v1( M_pA - t.A() );Vector3D v2( M_pB - t.A() );

Vector3D v3( this ->param (0.5) - t.A() );

if( std::fabs( v1.dot(t.normal ()) ) <= eps*t.Lmax() &&std::fabs( v2.dot(t.normal ()) ) <= eps*t.Lmax() &&std::fabs( v3.dot(t.normal ()) ) <= eps*t.Lmax() )

{// coplanar segmentreturn 0;

}

if( std::fabs( v1.dot(t.normal ()) ) <= eps*t.Lmax() )return 1;

if( std::fabs( v2.dot(t.normal ()) ) <= eps*t.Lmax() )return 1;

if( v1.dot(t.normal ())*v2.dot(t.normal ()) <= eps*t.Lmax() )return 1;

return 0;}

Il segmento interseca il piano se i suoi due estremi A e B appartengono ai due diversi semi-spazi generati dal piano stesso. Sia x un qualunque punto del piano (nell’implementazionex = vertice A del triangolo). Costruiamo i vettori che da x puntano negli estremi del segmento.Confrontando il segno del prodotto scalare di questi vettori con la normale al piano è possibilecapire se i due punti appartengono o meno allo stesso semispazio.

Se il segmento AB interseca il piano deve quindi valere la relazione :

[(A−x) ·n][(B−x) ·n] < 0 (2.1)

Il metodo Segment::intersectThePlaneOf è quindi in grado di risolvere il predicatologico e di restituire una variabile bool contenente la risposta. In questo caso le configurazionipossibili sono 3:

• Esiste una unica intersezione: il metodo restituisce TRUE

• Non esistono intersezioni: il metodo restituisce FALSE

• Il segmento è complanare al triangolo, esistono quindi infinite intersezioni: per conven-zione il metodo restituisce FALSE

Oltre al test di esistenza è fornito il metodo per il calcolo esplicito dell’intersezione.

Point3D Segment :: intersectionWithThePlaneOf(const Triangle & t) const{

Point3D inter(std:: numeric_limits <Real >:: quiet_NaN(),std:: numeric_limits <Real >:: quiet_NaN(),std:: numeric_limits <Real >:: quiet_NaN () );

10

Page 11: Codice C++ per il calcolo delle intersezioni tra griglie ...forma/Didattica/ProgettiPacs/Turconi13-14/... · Introduzione L’obiettivo di questo progetto è lo sviluppo di una libreria

Vector3D v1( M_pA - t.A() );Vector3D v2( M_pB - t.A() );

Vector3D v3( this ->param (0.5) - t.A() );

if( std::fabs( v1.dot(t.normal ()) ) <= eps*t.Lmax() &&std::fabs( v2.dot(t.normal ()) ) <= eps*t.Lmax() &&std::fabs( v3.dot(t.normal ()) ) <= eps*t.Lmax() )

{// coplanar segmentreturn inter;

}

if( std::fabs( v1.dot(t.normal ()) ) <= eps*t.Lmax() )// M_pA is the intersectioninter = M_pA;

if( std::fabs( v2.dot(t.normal ()) ) <= eps*t.Lmax() )// M_pB is the intersectioninter = M_pB;

if( v1.dot(t.normal ())*v2.dot(t.normal ())<= eps*t.Lmax() )

{// compute the intersection ...Real coeff = std::fabs(v1.dot(t.normal ()));if( v1.dot(t.normal ())>0 )

coeff /= (M_pA -M_pB).dot(t.normal ());if( v1.dot(t.normal ())<0 )

coeff /= (M_pB -M_pA).dot(t.normal ());

inter = M_pA + (M_pB -M_pA) * coeff;}

return inter;}

La formula usata per il calcolo dell’intersezione è:

p = A+ (B−A) ·{ |v1·n|

(A−B)·n v1 ·n > 0|v1·n|

(B−A)·n v1 ·n < 0

La seconda classe che possiede dei metodi per il calcolo delle intersezioni è la classeTriangle. Questi metodi permettono di calcolare l’intersezione tra il triangolo ed un seg-mento dato. Per fare ciò si sfruttano i metodi della classe Segment: prima si verifica che ilsegmento intersechi il piano generato dal triangolo e, successivamente, si valuta se il punto diintersezione con il piano è interno al triangolo.

La valutazione dell’appartenenza di un punto al triangolo viene fatta attraverso le coordinatebaricentriche:

bool Triangle :: containPoint(const Point3D & p) const{

if( !this ->coplanarWithPoint(p) ){ return 0; }

Real s(this ->area ());

Triangle tri1(p,M_pA ,M_pB);

11

Page 12: Codice C++ per il calcolo delle intersezioni tra griglie ...forma/Didattica/ProgettiPacs/Turconi13-14/... · Introduzione L’obiettivo di questo progetto è lo sviluppo di una libreria

Real s1(tri1.area ());

Triangle tri2(p,M_pA ,M_pC);Real s2(tri2.area ());

Triangle tri3(p,M_pB ,M_pC);Real s3(tri3.area ());

return ( (s1+s2+s3)/s <= 1+eps );}

Mentre il metodo:inline bool coplanarWithPoint(const Point3D & p) const

{ return ( std::fabs(this ->normal (). dot(p-M_pA)) <= eps*M_Lmax ); }

controlla che il punto p sia complanare al triangolo.I metodi per il test di esistenza dell’intersezione e per eseguire il calcolo sono riportati di

seguito:bool Triangle :: isIntersectedBy(const Segment & s) const{

if( !s.intersectThePlaneOf (*this) )return 0;

if( !this ->containPoint( s.intersectionWithThePlaneOf (*this) ) )return 0;

return 1;}

Point3D Triangle :: intersectionWith(const Segment & s) const{

Point3D p(std:: numeric_limits <Real >:: quiet_NaN(),std:: numeric_limits <Real >:: quiet_NaN(),std:: numeric_limits <Real >:: quiet_NaN () );

if( !s.intersectThePlaneOf (*this) )return p;

Point3D inter;inter = s.intersectionWithThePlaneOf (*this);

if( !this ->containPoint(inter) )return p;

return inter;}

Per convenzione: nel caso l’intersezione non esista il metodo intersectionWith restitui-sce il punto (NaN,NaN,NaN).

L’ultimo oggetto geometrico che possiede metodi per il calcolo delle intersezioni è la super-ficie bilineare. In questo caso per il calcolo delle intersezioni sono state proposte differentistrategie.

Algoritmo Approx L’idea è quella di sfruttare le semplici formule sviluppate precedente-mente per il calcolo delle intersezioni tra un segmento e un triangolo. In questo caso è infatti

12

Page 13: Codice C++ per il calcolo delle intersezioni tra griglie ...forma/Didattica/ProgettiPacs/Turconi13-14/... · Introduzione L’obiettivo di questo progetto è lo sviluppo di una libreria

possibile testare con facilità l’esistenza di tali intersezioni senza doverne eseguire il calcolo.Inoltre il loro effettivo calcolo risulta poco oneroso dal punto di vista computazionale. Lasuperficie viene quindi approssimata attraverso due triangoli ottenuti tracciando una delledue diagonali che collegano vertici opposti. Ovviamente le possibili approssimazioni sono duee, in caso di superfici con curvatura non nulla, la scelta può incidere anche in modo notevolesull’accuratezza del risultato finale. In particolare quando la curvatura della superficie risultaparticolarmente elevata questa approssimazione può sbagliare anche grossolanamente. Diseguito è riportato il codice che implementa questo approccio.

Point3D BilinearSurface :: approxIntersectionWith(const Segment & s, const bool & stdDivision) const

{// split bilinear surface in two triangles (two different ways)Triangle t1(M_pA ,M_pB ,M_pC);Triangle t2(M_pA ,M_pC ,M_pD);

if(! stdDivision){

Triangle t(M_pA ,M_pB ,M_pD);t1=t;Triangle tt(M_pB ,M_pC ,M_pD);t2=tt;

}

Point3D inter( t1.intersectionWith(s) );if( inter.x==inter.x && inter.y==inter.y && inter.z==inter.z )

return inter;

inter = t2.intersectionWith(s);return inter;

}

L’espressione logica

if( inter.x==inter.x && inter.y==inter.y && inter.z==inter.z )

risulta falsa solo nel caso in cui una delle componenti di inter sia uguale ad NaN. Infatti NaNè l’unico numero ad essere diverso da se stesso.

Come per i metodi precedentemente implementati, se l’intersezione non esiste il metodorestituisce il punto (NaN,NaN,NaN).

Algoritmo Newton Il secondo metodo sviluppato è invece un metodo esatto. Esso nonfa altro che risolvere il problema geometrico dell’intersezione tra la superficie bilineare eil segmento dato. La stesura delle equazioni per il calcolo della soluzione conduce ad unsistema non lineare nello spazio dei parametri. Per la risoluzione di tale sistema è statoquindi implementato l’algoritmo di newton. Questo approccio risulta molto più preciso delprecedente ed è in grado di calcolare le intersezioni per qualunque valore della curvaturadella superficie. Tuttavia usando questo algoritmo non è possibile eseguire a priori un testdi esistenza dell’intersezione: l’intersezione non esiste se il metodo non converge o se lasoluzione trovata non appartiene allo spazio dei parametri ammissibili. Questo comportauna grossa spesa in termini computazionali che influenza notevolmente la performance delmetodo.

13

Page 14: Codice C++ per il calcolo delle intersezioni tra griglie ...forma/Didattica/ProgettiPacs/Turconi13-14/... · Introduzione L’obiettivo di questo progetto è lo sviluppo di una libreria

Point3D BilinearSurface :: newtonIntersectionWith(const Segment & s, const Real & toll , const UInt & maxIter) const

{Point3D inter;

std::vector <Real > res (3);res [0]=1;std::vector <Real > dx(3,0), xNew(3,0), x(3, 0.5);// x = (u,v,l) : CI x = (0.5 ,0.5 ,0.5)std::vector <Real > b(3);

// columns matrix A = Jacobian matrixstd::vector <Real > a1(3); // first columnstd::vector <Real > a2(3);std::vector <Real > a3(3);Real normRes(toll +1);

Real detA , detA1 , detA2 , detA3;

UInt it=0;

// Newton Method// std::cout << " Newton START " << std::endl;

while( normRes >toll && it<maxIter){

// Build Matrixa1[0] = (1-x[1])*( M_pB.x-M_pA.x) + x[1]*( M_pC.x-M_pD.x);a2[0] = (1-x[0])*( M_pD.x-M_pA.x) + x[0]*( M_pC.x-M_pB.x);a3[0] = s.A().x-s.B().x;

a1[1] = (1-x[1])*( M_pB.y-M_pA.y) + x[1]*( M_pC.y-M_pD.y);a2[1] = (1-x[0])*( M_pD.y-M_pA.y) + x[0]*( M_pC.y-M_pB.y);a3[1] = s.A().y-s.B().y;

a1[2] = (1-x[1])*( M_pB.z-M_pA.z) + x[1]*( M_pC.z-M_pD.z);a2[2] = (1-x[0])*( M_pD.z-M_pA.z) + x[0]*( M_pC.z-M_pB.z);a3[2] = s.A().z-s.B().z;

// Build b = -Fb[0] = s.param(x[2]).x - this ->param(x[0],x[1]).x;b[1] = s.param(x[2]).y - this ->param(x[0],x[1]).y;b[2] = s.param(x[2]).z - this ->param(x[0],x[1]).z;

// Solving linear sistem (Cramer ’s rule)

detA = a1[0]*a2[1]*a3[2] + a1[2]*a2[0]*a3[1] + a1[1]*a2[2]*a3[0]- a1[2]*a2[1]*a3[0] - a1[0]*a2[2]*a3[1] - a1[1]*a2[0]*a3[2];

detA1 = b[0]*a2[1]*a3[2] + b[2]*a2[0]*a3[1] + b[1]*a2[2]*a3[0]- b[2]*a2[1]*a3[0] - b[0]*a2[2]*a3[1] - b[1]*a2[0]*a3[2];

detA2 = a1[0]*b[1]*a3[2] + a1[2]*b[0]*a3[1] + a1[1]*b[2]*a3[0]- a1[2]*b[1]*a3[0] - a1[0]*b[2]*a3[1] - a1[1]*b[0]*a3[2];

detA3 = a1[0]*a2[1]*b[2] + a1[2]*a2[0]*b[1] + a1[1]*a2[2]*b[0]- a1[2]*a2[1]*b[0] - a1[0]*a2[2]*b[1] - a1[1]*a2[0]*b[2];

dx[0] = detA1 / detA;dx[1] = detA2 / detA;dx[2] = detA3 / detA;

// x + dx --> xNew

14

Page 15: Codice C++ per il calcolo delle intersezioni tra griglie ...forma/Didattica/ProgettiPacs/Turconi13-14/... · Introduzione L’obiettivo di questo progetto è lo sviluppo di una libreria

xNew [0] = x[0] + dx[0];xNew [1] = x[1] + dx[1];xNew [2] = x[2] + dx[2];

// xNew - x --> resres [0] = xNew [0] - x[0];res [1] = xNew [1] - x[1];res [2] = xNew [2] - x[2];

normRes = std::sqrt( res [0]* res [0] + res [1]* res[1] + res [2]* res[2] );

x = xNew;

it++;}

if(it >= maxIter){

inter.x = std:: numeric_limits <Real >:: quiet_NaN ();inter.y = std:: numeric_limits <Real >:: quiet_NaN ();inter.z = std:: numeric_limits <Real >:: quiet_NaN ();return inter;

}

if( x[0]<(-toll) || x[0] >(1+ toll) ||x[1]<(-toll) || x[1] >(1+ toll) ||x[2]<(-toll) || x[2] >(1+ toll) )

{inter.x = std:: numeric_limits <Real >:: quiet_NaN ();inter.y = std:: numeric_limits <Real >:: quiet_NaN ();inter.z = std:: numeric_limits <Real >:: quiet_NaN ();return inter;

}

// std::cout << " Newton END " << std::endl;// std::cout << " -- Newton Iterations: " << it << std::endl;

inter = this ->param(x[0],x[1]);

return inter;}

Anche in questo caso la convenzione adottata prevede di restituire il punto (NaN,NaN,NaN) incaso di non esistenza dell’intersezione.

Algoritmo ApproxNewton Il terzo metodo propone un approccio ibrido tra i primi due.L’idea è quella di sfruttare l’approssimazione della superficie mediante i due triangoli pereseguire il test di esistenza dell’intersezione. Poiché, come già detto, esistono due possibilimodi per approssimare la superficie, questi vengono sfruttati entrambi. Nel caso il test producaun risultato affermativo, si procede al calcolo del punto di intersezione attraverso l’algoritmodi Newton. Questo metodo, come il primo algoritmo proposto, risulta adatto solamente nelcaso di superfici poco curvate. Tuttavia, se questa condizione è soddisfatta, offre risultatianaloghi al metodo esatto.

Point3D BilinearSurface :: approxNewtonIntersectionWith(const Segment & s, const Real & toll , const UInt & maxIter) const

{Point3D p( std:: numeric_limits <Real >:: quiet_NaN (),

15

Page 16: Codice C++ per il calcolo delle intersezioni tra griglie ...forma/Didattica/ProgettiPacs/Turconi13-14/... · Introduzione L’obiettivo di questo progetto è lo sviluppo di una libreria

std:: numeric_limits <Real >:: quiet_NaN(),std:: numeric_limits <Real >:: quiet_NaN () );

if( !this ->approxIsIntersectedBy(s,0) && !this ->approxIsIntersectedBy(s,1) )return p;

return this ->newtonIntersectionWith(s,toll ,maxIter );}

Si adotta sempre la convenzione di restituire il punto (NaN,NaN,NaN) in caso di non esi-stenza dell’intersezione. Riportiamo il codice del metodo usato per implementare il testapprossimato di esistenza dell’intersezione:bool BilinearSurface :: approxIsIntersectedBy

(const Segment & s, const bool & stdDivision) const{

// split bilinear surface in two triangles (two different ways)Triangle t1(M_pA ,M_pB ,M_pC);Triangle t2(M_pA ,M_pC ,M_pD);

if(! stdDivision){

Triangle t(M_pA ,M_pB ,M_pD);t1=t;Triangle tt(M_pB ,M_pC ,M_pD);t2=tt;

}

// Testif( t1.isIntersectedBy(s) || t2.isIntersectedBy(s) )

return 1;

return 0;}

Algoritmo ApproxRefined Il quarto ed ultimo algoritmo proposto è invece un tentativo diraffinamento dell’approssimazione effettuata nel primo metodo. Esso prevede di approssi-mare la superficie attraverso un numero maggiore di triangoli. Il numero dei triangoli usati èscelto in modo da mantenere sotto controllo l’errore commesso.Point3D BilinearSurface :: approxRefinedIntersectionWith

(const Segment & s, const Real & toll){

if(! M_Triangulated || toll != M_TriangulationToll)this ->buildTriangulation(toll);

Point3D p( std:: numeric_limits <Real >:: quiet_NaN (),std:: numeric_limits <Real >:: quiet_NaN(),std:: numeric_limits <Real >:: quiet_NaN () );

std::vector <Triangle >:: const_iterator it;for(it=M_TriangulatedSurface.begin ();

it!= M_TriangulatedSurface.end() && !(p.x==p.x && p.y==p.y && p.z==p.z);++it)

{p = (*it). intersectionWith(s);

}

return p;}

16

Page 17: Codice C++ per il calcolo delle intersezioni tra griglie ...forma/Didattica/ProgettiPacs/Turconi13-14/... · Introduzione L’obiettivo di questo progetto è lo sviluppo di una libreria

La formula utilizzata per tale scopo è:

h <√

2εLmax

ρmax

dove h è la dimensione dei triangoli utilizzati nella triangolazione, εLmax è il massimo errore diapprossimazione ammissibile e ρmax è la massima curvatura raggiunta sulla superficie. Comein tutti gli altri metodi anche questo riceve in input una tolleranza relativa, rappresentatanella formula da ε. Per ottenere la tolleranza reale, deve quindi essere riscalata rispetto a Lmax ,cioè la massima dimensione della superficie da triangolare. Una volta nota la dimensione deitriangoli viene determinato il numero di triangoli da usare nella triangolazione della faglia.Questa formula tuttavia risulta molto conservativa e può quindi portare alla costruzione diuna triangolazione della superficie eccessivamente fitta. Nel seguito verranno proposti alcunicasi test in cui analizzare nel dettaglio il comportamento del metodo.

Il metodo

void BilinearSurface :: buildTriangulation(const Real & toll)

esegue questi calcoli. L’operazione di costruzione della triangolazione viene eseguita in paral-lelo attraverso le direttive OpenMP.

Questi metodi sono alla base dei metodi che verranno poi sviluppati per il calcolo delleintersezione tra le faglie e le griglie.

2.1.3. Oggetti geometrici legati alla griglia Corner Point

Dopo aver introdotto gli oggetti geometrici di base si passa alla definizione delle griglie CornerPoint.

Nel file geomCPgridElements.hpp sono contenute le classi per la gestione dei pilastri edelle celle della griglia. I pilastri sono derivati dalle rette e in più contengono gli indici ne-cessari ad associarli alla loro posizione nella griglia. Sono inoltre provvisti di un metodo perestrarre il segmento di retta relativo al dominio. Il secondo elemento estraibile dalle griglieCorner Point sono le celle. Queste hanno la forma di esaedri definiti attraverso i loro otto ver-tici. Da un cella è possibile ovviamente estrarre un qualunque spigolo sotto forma di segmento.

A questo punto viene introdotta la classe CPgrid in cui vengono salvati tutti i dati relativialla struttura della griglia e i campi di permeabilità e trasmissibilità. Questa classe è provvistadi metodi di import/export che permettono di importare ed esportare la griglia in formatoEclipse. I dati geometrici della griglia sono salvati nei due vettori M_coord e M_zcorn. Laclasse è inoltre dotata di metodi che permettono di estrarre in modo diretto le celle e i pilastri.Per salvare i campi di permeabilità e trasmissibilità sono state costruite delle classi apposite:PermeabilityField e TransmissibilityField.

L’ultima classe da presentare è una delle principali ed è la classe Fault. Poiché le fagliesono descritte attraverso delle superfici bilineari, la classe utilizzata per gestirle è derivata

17

Page 18: Codice C++ per il calcolo delle intersezioni tra griglie ...forma/Didattica/ProgettiPacs/Turconi13-14/... · Introduzione L’obiettivo di questo progetto è lo sviluppo di una libreria

dalla classe BilinearSurface. Rispetto ad una semplice superficie bilineare gli oggetti ditipo Fault permettono di calcolare direttamente le intersezione con le griglie Corner Point ele loro celle.

2.1.4. Calcolo delle intersezioni tra oggetti Corner Point

Il calcolo delle intersezioni tra una faglia e un oggetto di tipo CPcell, può essere eseguitoapplicando i diversi metodi ereditati nella classe BilinearSurface. Lo schema generale diquesti metodi è proposto di seguito. La procedura scorre tutti i lati della cella e ne calcolarele intersezioni con la faglia attraverso uno degli algoritmi descritti in precedenza. Le interse-zioni trovate vengono inserite in un oggetto di tipo CellIntersections, che ne permette ilsalvataggio. Riportiamo qui lo schema generico di questi metodi:

void Fault ::[ ALGORITHM_NAME]IntersectionWithCell( const CPcell & c, Intersect :: CellIntersections & cellinter ,

[ALGORITHM_ATTRIBUTE] ) const{

cellinter.i() = c.i();cellinter.j() = c.j();cellinter.k() = c.k();Intersect :: Intersection inter;Point3D interPoint;

for(UInt i=1; i <=12; ++i){

interPoint = this ->[ ALGORITHM_NAME]IntersectionWith(c.getEdge(i),[ ALGORITHM_ATTRIBUTE ]);

if( interPoint.x== interPoint.x &&interPoint.y== interPoint.y &&interPoint.z== interPoint.z )

{inter.first = i;inter.second = interPoint;cellinter.insert(inter );

}}

}

Per il calcolo delle intersezioni tra una faglia ed una griglia Corner Point sono state sviluppatedue famiglie di algoritmi. La differenza tra i due gruppi dipende dalla strategia usata per lavisita della griglia. I due approcci usati sono chiamati:

• strategia FOR3

• strategia EDGEMAP

FOR3 Il metodo FOR3 procede con un semplice loop su tutte le celle attive della griglia. Ilparametro M_actnum di ogni cella è posto uguale ad 0 per le celle disattivate e uguale ad 1per le celle attive (si noti che il formato Eclipse prevede altri valori possibili oltre a 0 e 1). Perogni cella vengono calcolate le intersezioni con la faglia adottando i metodi precedentementedescritti. Questa strategia adotta quindi una visione cell centered. I due principali vantaggidi questa procedura sono: la facilità e scalabilità della parallelizzazione e il salvataggio delle

18

Page 19: Codice C++ per il calcolo delle intersezioni tra griglie ...forma/Didattica/ProgettiPacs/Turconi13-14/... · Introduzione L’obiettivo di questo progetto è lo sviluppo di una libreria

intersezioni direttamente nella struttura dati usata per la loro manipolazione. Anche in questocaso la parallelizzazione del codice è stata effettuata attraverso le direttive fornite da OpenMP.Lo schema generale di questi algoritmi è il seguente:

void Fault ::[ ALGORITHM_NAME]IntersectionWithGrid_FOR3( const CPgrid & g, Intersect :: GridIntersections & gridInter ,

[ALGORITHM_ATTRIBUTE ]) const{

#pragma omp parallel shared(g,gridInter ,toll , maxIter){

Intersect :: CellIntersections cellInter;

#pragma omp for schedule(dynamic ,1)for(UInt i=1; i<=g.Nx(); ++i){

for(UInt j=1; j<=g.Ny(); ++j){

for(UInt k=1; k<=g.Nz(); ++k){

if( g.cell(i,j,k). getActnum () ){

this ->[ ALGORITHM_NAME]IntersectionWithCell(g.cell(i,j,k), cellInter , [ALGORITHM_ATTRIBUTE ]);

if(cellInter.size ()>0){

#pragma omp critical{ gridInter.insert(cellInter ); }

}cellInter.clearIntersections ();

}}

}}

}}

EDGEMAP Il metodo EDGEMAP procede invece iterando sui lati della griglia. Questo per-mette di non ricalcolare più volte le intersezioni condivise da più celle. Per fare ciò l’algoritmousa delle strutture dati basate su mappe che permettono di salvare senza repliche gli spigolidelle celle. Queste strutture consentono al tempo stesso di ricordare la posizione dei lati all’in-terno delle celle della griglia. Anche questo algoritmo è parallelizzato, ma richiede maggioreaccortezza rispetto al precedente. Il vantaggio nell’usare questo approccio risulta notevole seapplicato a griglie non eccessivamente distorte. In linea teorica su griglie con celle non disalli-neate tra loro il guadagno in termini di performance è notevole. L’unico punto problematicoin questo caso potrebbe risiedere nel passaggio dalle strutture dati senza repliche a quelle cellcentered. Riportiamo il codice di base degli algoritmi che implementano questa strategia divisita.

void Fault ::[ ALGORITHM_NAME]IntersectionWithGridEdge( const Intersect :: GridEdgeMap & gridEdge ,

Intersect :: GridIntersectionMap & gridInter ,[ALGORITHM_ATTRIBUTE] ) const

{#pragma omp parallel shared(gridEdge ,gridInter ,toll ,maxIter){

#ifdef _OPENMP

19

Page 20: Codice C++ per il calcolo delle intersezioni tra griglie ...forma/Didattica/ProgettiPacs/Turconi13-14/... · Introduzione L’obiettivo di questo progetto è lo sviluppo di una libreria

int numThreads = omp_get_num_threads ();int threadID = omp_get_thread_num (); // from 0 to numThreads -1

#elseint numThreads = 1;int threadID = 0;

#endif

Intersect :: GridIntersectionMapElement elem;

Intersect :: GridEdgeMap_Const_Iterator_Type it = gridEdge.begin ();it = Intersect :: safe_advancer(it,gridEdge.end(),threadID );

while( it != gridEdge.end ()){

elem.first = this ->[ ALGORITHM_NAME]IntersectionWith(it ->first ,[ ALGORITHM_ATTRIBUTE ]);

if( elem.first.x==elem.first.x &&elem.first.y==elem.first.y &&elem.first.z==elem.first.z )

{elem.second = it->second;#pragma omp critical{ gridInter.insert(elem); }

}it = Intersect :: safe_advancer(it,gridEdge.end(), numThreads );

}}

}

Per implementare la versione parallela di questo algoritmo è stata definita la funzione templatetemplate <typename Itr >Itr safe_advancer(Itr it , Itr end , UInt delta){

while(it != end && delta --)it++;

return it;}

Questa funzione permette di incrementare un qualunque iteratore facendolo scorrere in avantidi delta elementi. E’ necessaria in questo caso perché gli iteratori definiti per le mappe sonodei Bidirectional_iterator, i quali non supportano gli operatori + e -.

Vengono infine forniti i metodi che implementano la strategia EDGEMAP ricevendo ininput un oggetto di tipo CPgrid e salvando le intersezioni trovate in un oggetto di tipoGridIntersections.

Lo schema generale di questi metodi è:void Fault ::[ ALGORITHM_NAME]IntersectionWithGrid_EDGEMAP

( const CPgrid & g, Intersect :: GridIntersections & gridInter ,[ALGORITHM_ATTRIBUTE ]) const

{Intersect :: GridEdgeMap gridEdge(g);Intersect :: GridIntersectionMap gridInterMap(g);

this ->[ ALGORITHM_NAME]IntersectionWithGridEdge(gridEdge ,gridInterMap ,[ ALGORITHM_ATTRIBUTE ]);

gridInterMap.exportToGridIntersections(gridInter );}

20

Page 21: Codice C++ per il calcolo delle intersezioni tra griglie ...forma/Didattica/ProgettiPacs/Turconi13-14/... · Introduzione L’obiettivo di questo progetto è lo sviluppo di una libreria

2.2. NAMESPACE INTERSECT

Questo namespace contiene le strutture dati utilizzate dagli algoritmi di intersezione. Inparticolare le quattro strutture fondamentali sono:

• CellIntersections

• GridIntersections

• GridIntersectionMap

• gridEdgeMap

CellIntersections La classe CellIntersections crea un oggetto, riferito ad una specificacella, che permette di salvare le intersezioni trovate sui suoi lati. Tale struttura permette disalvare una sola intersezione per ogni lato della cella. Questo è giustificato dal fatto che lesuperfici bilineari considerate sono generalmente poco curvate e che quindi la possibilità cheesistano due intersezioni su un singolo lato è molto remota. Inoltre nella maggior parte deicasi reali la lunghezza dei lati della griglia è molto inferiore rispetto alle dimensioni della fagliae questo incentiva l’esistenza di un’unica intersezione per ogni lato. La classe è dotata anchedi metodi per il calcolo degli errori. Il metodo computeError() riceve in input un oggettodella stessa classe contenente le intersezioni esatte e calcola:

• l’errore medio commesso tra le intersezioni su lati corrispondenti

• la posizione e il valore dell’errore massimo

• il numero di intersezioni mancanti o in più rispetto alla soluzione esatta

GridIntersections La classe Gridintersections raccoglie tutti gli oggetti CellIntersectionsrelativi ad una stessa griglia e permette la valutazione degli errori commessi globalmen-te sull’intera griglia. Questa struttura è pensata per poter agevolmente estrarre le carat-teristiche di ogni cella e calcolare le quantità geometriche richieste. Come per la classeCellIntersections è presente il metodo computeError() che riceve in input un oggettodella stessa classe contenente le intersezioni esatte e calcola:

• l’errore medio commesso tra le intersezioni corrispondenti sulla griglia

• la posizione e il valore dell’errore massimo

• il numero di celle mancanti o in più rispetto alla soluzione esatta

GridIntersectionMap La classe GridIntersectionMap permette il salvataggio delle inter-sezioni di una griglia senza repliche. Questa struttura dati si basa su una mappa e usa comechiave le intersezioni stesse. Per rendere possibile ciò, è introdotta una relazione d’ordinetra gli oggetti della classe Point3D. Questa relazione d’ordine è stata definita attraverso unoverloading dell’operatore <.

21

Page 22: Codice C++ per il calcolo delle intersezioni tra griglie ...forma/Didattica/ProgettiPacs/Turconi13-14/... · Introduzione L’obiettivo di questo progetto è lo sviluppo di una libreria

Gli elementi della mappa sono dunque delle coppie (std::pair) che come primo elementocontengono la chiave, quindi il punto, e come secondo elemento un Linker.

La classe Linker è una lista contenente tutte le informazioni necessarie per assegnare ognielemento della mappa alle corrispondenti celle della griglia. Un LinkerElement è di fattouna coppia di 2 interi positivi. Il primo intero rappresenta l’id della cella a cui l’oggetto siriferise, mentre il secondo rappresenta l’id interno alla cella che specifica lo spigolo interessato.L’implementazione è condotta costruendo una lista di LinkerElement.

GridEdgeMap La GridEdgeMap è una struttura dati che immagazzina i lati di una grigliaCorner Point senza ripetizioni. Concretamente viene implementata attravero una mappache utilizza come chiave i lati stessi. Anche in questo caso deve essere definita una relazioned’ordine tra i segmenti, la quale si basa su quella precedentemente implementata per i punti.Affinché questa relazione d’ordine sia ben definita, cioè sia una relazione d’ordine totale, ènecessario considerare i segmenti orientati. Come primo estremo viene considerato l’estremominore, mentre come secondo estremo il maggiore. In questo modo i segmenti vengonoorientati sempre nello stesso modo e ciò previene a possibili incongruenza della relazioned’ordine. Se non fosse eseguita questa operazione di orientazione, il segmento AB e il segmentoBA non verrebbero considerati uguali. Anche in questo caso l’implementazione della relazioned’ordine è eseguita attraverso l’overloading dell’operatore <.

Anche in questo caso gli elementi della mappa sono dunque delle coppie (std::pair) checome primo elemento contengono la chiave, quindi il segmento, e come secondo elementoun Linker.

2.3. INTERSECTIONSOLVER

Per rendere più agevole e intuitivo l’utilizzo delle funzionalità sviluppate dalla libreria vienefornita la classe IntersectionSolver. Questa classe permette di scegliere facilmente l’al-goritmo per il calcolo delle intersezioni e la strategia di visita della griglia Corner Point. Glioggetti di questa classe sono implementati come funtori attraverso differenti overloadingdell’operatore ().

void operator ()( Fault & f, const CPgrid & g,Intersect :: GridIntersections & gridInter) const;

void operator ()( Fault & f, const CPcell & c,Intersect :: CellIntersections & cellInter) const;

Point3D operator ()( Fault & f, const Segment & s) const;

La classe permette ovviamente di modificare le impostazioni con cui ogni metodo vienelanciato. La strategia da adottare e l’algoritmo per il calcolo delle intersezioni possono esserescelte solo al momento della costruzione di ogni singolo oggetto.

// Constructor , getting algorithm typeIntersectionSolver(IntersectionAlgorithm alg , GridStrategy strategy );

Le informazioni necessarie ai diversi metodi possono invece essere modificate in qualunquemomento utilizzando i metodi: setTolerance, setMaxIteration, setStdDivision.

22

Page 23: Codice C++ per il calcolo delle intersezioni tra griglie ...forma/Didattica/ProgettiPacs/Turconi13-14/... · Introduzione L’obiettivo di questo progetto è lo sviluppo di una libreria

2.4. BREVE TUTORIAL

Riportiamo ora un semplice esempio per illustrare il funzionamento della libreria dinamicalibCPgeom.so.1.0. Consideriamo il caso in cui si dispone di una griglia Corner Point definita informato Eclipse. Immaginiamo inoltre di conoscere i 4 punti che generano la faglia, e di volercalcolare le intersezioni tra questa e la griglia.

Uso di libCPgeom.so.1.0 Partiamo creando il file main_tutorial.cpp in cui sviluppare ilnostro codice. Ricordiamo che per includere velocemente tutti gli header file della libreriabasta aggiungere #include “CPgeom.hpp ”.

Dobbiamo ora definire il main del nostro programma. Per prima cosa (0) richiamiamonello spazio dei nomi corrente i due namespace della libreria: Geometry e Intersect. Perimportare i dati procediamo secondo i seguenti passi:

(1) Creiamo un oggetto CPgrid per gestire la griglia di calcolo, importando direttamentei dati. Per farlo passiamo al costruttore il nome del file contenente le informazionigeometriche della griglia.

(2) Definiamo i vertici della faglia passando le loro coordinate al costruttore della classePoint3D.

(3) Usando i 4 punti definiamo l’oggetto di tipo Fault che permetterà di gestire la faglia.

(4) Definiamo l’oggetto di tipo GridIntersections che conterrà le intersezioni trovate.

Abbiamo ora a disposizione tutte le strutture necessarie e possiamo procedere con il calcolovero e proprio.

Procediamo ora costruendo un IntersectionSolver (5). Gli oggetti di questo tipo permet-tono di lanciare i diversi algoritmi per il calcolo delle intersezioni e di impostarne i parametri.Nel momento della costruzione dobbiamo quindi specificare:

• il tipo di algoritmo da utilizzare per il calcolo di ogni singola intersezione;si possono usare le keyword: NEWTON, APPROX, APPROXNEWTON, APPROXREFINED.

• il tipo di strategia da utilizzare per scorrere la griglia;utilizzando le keyword: FOR3, EDGEMAP.

Le caratteristiche dei metodi, quali tolleranza e numero di iterazioni, possono esseremodificati attraverso i metodi set dalla classe (6).

Una volta creato il nostro solutore, possiamo lanciarlo (7), attraverso l’operatore (), passan-dogli in input la griglia, la faglia e il contenitore per salvare le intersezioni calcolate.

Terminato il calcolo esportiamo la griglia, la faglia e i punti di intersezione in formato VTKper consentirne la visualizzazione (8).

Per maggiore chiarezza riportiamo il codice appena descritto:

23

Page 24: Codice C++ per il calcolo delle intersezioni tra griglie ...forma/Didattica/ProgettiPacs/Turconi13-14/... · Introduzione L’obiettivo di questo progetto è lo sviluppo di una libreria

#include "./src/CPgeom.hpp"

int main (){

// (0) load namespaceusing namespace Geometry;using namespace Intersect;

// (1) Import gridCPgrid grid("./data/gridTest" ,0);

// (2) Points definitionPoint3D A(-1,-1,0.5);Point3D B(-1,5,0.5);Point3D C(5 ,5 ,0.5);Point3D D(5,-1,0.5);

// (3) Fault definitionFault f(A,B,C,D);

// (4) To store computed intersectionGridIntersections intersectionStore(grid.Nx(),grid.Ny(),grid.Nz());

// (5) Solver definitionIntersectionSolver newton_FOR3(NEWTON ,FOR3);

// (6) Set solver propertiesnewton_FOR3.setMaxIteration (100);

// (7) Solve intersection problemnewton_FOR3(f,grid ,intersectionStore );

// (8) Export solutionsgrid.exportVtk("./data/Tutorial/grid.vtk");f.exportVtk("./data/Tutorial/fault.vtk");intersectionStore.exportVtk("./data/Tutorial/intersections.vtk");

return 0;

}

24

Page 25: Codice C++ per il calcolo delle intersezioni tra griglie ...forma/Didattica/ProgettiPacs/Turconi13-14/... · Introduzione L’obiettivo di questo progetto è lo sviluppo di una libreria

3. Risultati NumericiIn questa sezione presentiamo alcuni casi test per la valutazione delle prestazioni deglialgoritmi implementati nella libreria CPgeom.

3.1. VALUTAZIONE DELL’ALGORITMO APPROXREFINED

Consideriamo una griglia tridimensionale 4x4x4 e un sistema di 10 faglie con curvaturacrescente. Calcoliamo quindi le intersezioni che ogni faglia definisce sulla griglia.

(a) f1: ρmax = 0.0416667 (b) f9: ρmax = 0.111111

Utilizziamo gli algoritmi: NEWTON, che calcola le intersezioni esatte, e APPROXREFINED, checalcola le intersezioni attraverso una triangolazione della faglia.

Riportiamo nel seguito i grafici dell’andamento dell’errore commesso e del numero dielementi usati per la triangolazione al variare della curvatura.

(a) Errore Medio (b) Errore Massimo

Per ottenere un elevato grado di accuratezza l’algoritmo approssimato costruisce triangola-zioni con molti elementi. Questo comportamento risulta problematico in quanto porta ad unveloce degrado delle prestazioni dell’algoritmo all’aumentare della curvatura. Per migliorarequesto comportamento si può pensare di fornire una formula più accurata per il controllodell’errore commesso oppure di costruire triangolazioni non uniformi. Nel secondo caso èessenziale valutare se questo porti ad un effettivo miglioramento delle prestazioni.

25

Page 26: Codice C++ per il calcolo delle intersezioni tra griglie ...forma/Didattica/ProgettiPacs/Turconi13-14/... · Introduzione L’obiettivo di questo progetto è lo sviluppo di una libreria

Figura 3.1: Al crescere della curvatura della faglia, il numero di elementi usati nellatriangolazione aumenta notevolmente

3.2. UN CASO REALE

In questo test vengono considerati una griglia ed un sistema di faglie reali. Rispetto al casoprecedente le dimensioni sono notevolmente maggiori. Questo permette di eseguire unavalutazione delle performance dei vari algoritmi per il calcolo delle intersezioni.

Figura 3.2: Il grid Bashkirian

Analogamente è possibile confrontare le due diverse strategie di visita della griglia imple-mentate dalla libreria. Le faglie utilizzate sono 3 e presentano valori di curvatura diversi.

Curvatura Faglie

Faglia 1 Faglia 2 Faglia 3

0 5.18296e-7 4.95174e-6

I dati sono stati raccolti ripetendo più volte le stesse simulazioni, per ottenere una migliorestima delle performance. Nei grafici è riportata la durata media delle simulazioni.

26

Page 27: Codice C++ per il calcolo delle intersezioni tra griglie ...forma/Didattica/ProgettiPacs/Turconi13-14/... · Introduzione L’obiettivo di questo progetto è lo sviluppo di una libreria

3.2.1. Confronto degli algoritmi per il calcolo delle intersezioni

(a) Strategia FOR3 (b) Strategia EDGEMAP

Osservando i grafici risulta evidente che al crescere della curvatura l’algoritmo APPROXREFINEDrisulta essere molto inefficiente rispetto agli altri.

Si nota inoltre che gli algoritmi APPROX e APPROXNEWTON sembrano risentire molto pocodell’aumento della curvatura. Questo in realtà non è completamente vero e nasconde inveceun grosso limite. Se osserviamo il grafico delle intersezioni mancanti si capisce subito ilproblema alla base di questi algoritmi.

Mentre NEWTON e APPROXREFINED riescono a catturare tutte le intersezioni, gli algoritmiAPPROX e APPROXNEWTON non riescono a farlo. Questo perchè si basano su una approssi-mazionie della faglia che all’aumentare della curvatura diventa sempre meno accurata. E’proprio per mantenere l’accuratezza che gli altri due metodi pagano in termini di performance.

Possiamo quindi concludere che se le faglie dovessero fossero perfettamente piane, l’algo-ritmo APPROX offrirebbe una valida alternativa a NEWTON consentendo tempi di calcolo minori.Tuttavia l’accuratezza dei risultati di questo algoritmo può degradare anche in modo moltomarcato all’aumentare della curvatura della superficie.

27

Page 28: Codice C++ per il calcolo delle intersezioni tra griglie ...forma/Didattica/ProgettiPacs/Turconi13-14/... · Introduzione L’obiettivo di questo progetto è lo sviluppo di una libreria

3.2.2. Confronto delle strategie di visita della griglia

Analizziamo ora le performance legate alla strategia di visita della griglia. Riportiamo in ungrafico il rapporto:

τ= tEDGE M AP

tFOR3

ottenuto nelle diverse simulazioni. Per valori minori di 1 di questo indice, il metodo EDGEMAPrisulta più performante rispetto al metodo FOR3.

Il valore di τ che idealmente dovrebbe attestarsi intorno al 25% è in realtà più elevato.Questo è dovuto al fatto che l’algoritmo EDGEMAP utilizza delle strutture dati ausiliarie perla visita della griglia. Questo gli permette di calcolare meno intersezioni, tuttavia richiede iltrasferimento dei dati in tali strutture e la successiva estrazione dei risultati. Nei casi in cuil’onere computazionale del calcolo delle intersezioni non risulta elevato, la strategia EDGEMAPnon porta notevoli miglioramenti. Viceversa possiamo osservare come, per i casi in cui iltempo di calcolo necessario per determinare una intersezione sia sufficientemente elevato, ilmetodo EDGEMAP risulti effettivamente più performante della strategia FOR3. Questo accadead esempio per il metodo NEWTON (e anche APPROXNEWTON) e risulta evidente osservando ilcaso dell’algoritmo APPROXREFINED.

In presenza di griglie con un gran numero di celle disallineate le due strategie dovrebberorisultare teoricamente equivalenti. Tuttavia, sempre per il motivo esposto sopra, la strategiaEDGEMAP risulterebbe meno performante.

Dalla discussione dei casi test risulta evidente come la scelta dei metodi ottimali dipenda inbuona parte dalle caratteristiche geometriche della griglia e delle faglie considerate. Il migliorcompromesso per il calcolo delle intersezioni sembra essere l’accoppiamento dell’algoritmoNEWTON, per il calcolo delle singole intersezioni, con la strategia EDGEMAP, per la visita dellagriglia.

28

Page 29: Codice C++ per il calcolo delle intersezioni tra griglie ...forma/Didattica/ProgettiPacs/Turconi13-14/... · Introduzione L’obiettivo di questo progetto è lo sviluppo di una libreria

A. Appendice di geometria delle superficiUna superficie immersa nello spazio fisico tridimensionale E 3, può essere descritta attraversouna parametrizzazione:

S : A −→R3 ←→ E 3

cioè un’applicazione da un sottoinsieme A del piano R2 verso R3. Questa applicazione puòessere definita in modo semplice attraverso una tripletta di funzioni:

x = x(u, v)y = y(u, v)z = z(u, v)

In generale viene richiesto che S sia almeno C 1(A). E’ inoltre opportuno che l’applicazioneS sia iniettiva, in modo che l’immagine di tale applicazione non si autointersechi mai.

Un’ulteriore condizione di regolarità che spesso viene richiesta è:

Su ∧Sv 6= 0 ∀(u, v) ∈ A

Questa condizione garantisce che in ogni punto della superficie considerata sia definito inmaniera univoca un piano tangente. Un punto che soddisfa tale condizione viene chiamatopunto regolare.

Se questa condizione è verificata possiamo definire in ogni punto il versore normale allasuperficie:

n(u, v) = Su ∧Sv

‖Su ∧Sv‖

A.1. PIANO TANGENTE

Definizione 1. Il piano tangente nel punto S, TS, è l’unico piano di E 3 che passa per S ed èperpendicolare al versore normale.

Questo piano è detto piano tangente perchè raccoglie tutte le rette tangenti nel punto S atutte le curve regolari tracciate sulla superficie e passanti per tale punto.

Se consideriamo una curva u = u(t), v = v(t) nel dominio parametrico A della superficieS(u, v). Allora S = S(t ) = S(u(t ), v(t )) è una curva parametrica sulla superficie S(u, v). Il vettoretangente a tale curva, S(t ) = Suu+Sv v , è anche tangente alla suparficie e dunque appartenenteal piano tangente.

Osserviamo che i due vettori Su e Sv rappresentano una base (non ortonormale, poichè nonsono versori e neppure ortogonali) dello spazio tangente.

Se consideriamo quindi un generico vettore a dello spazio tangente, questo avrà quindi unacoppia di coordinate:

a =αSu +βSv a ↔[α

β

]

29

Page 30: Codice C++ per il calcolo delle intersezioni tra griglie ...forma/Didattica/ProgettiPacs/Turconi13-14/... · Introduzione L’obiettivo di questo progetto è lo sviluppo di una libreria

A.2. PRIMA FORMA FONDAMENTALE

Volendo calcolare la lunghezza di un arco infinitesimo della curva S(t ) = S(u(t ), v(t )) apparte-nente alla superficie S(u, v) si trova:

d s =∣∣∣∣dS

d t

∣∣∣∣d t =∣∣∣∣Su

du

d t+Sv

d v

d t

∣∣∣∣d t =√

(Suu +Sv v) · (Suu +Sv v)d t = (A.1)

=√

E du2 +2F dud v +Gd v2 (A.2)

doveE = Su ·Su F = Su ·Sv G = Sv ·Sv

Definizione 2. La prima forma fondamentale di una superficie S(u, v) è definita come

I = d s2 = dS ·dS = E du2 +2F dud v +Gd v2

E, F, G sono chiamati coefficienti della prima forma fondamentale e giocano un ruolo moltoimportante nella descrizione delle proprietà intrinseche di una superficie.

Tali coefficienti possono essere raggruppati per formare la matrice della prima formafondamentale:

G =[

g11(u, v) g12(u, v)g21(u, v) g22(u, v)

]=

[Su ·Su Su ·Sv

Sv ·Su Sv ·Sv

]=

[E FF G

]Tale matrice permette di definire un prodotto scalare tra i vettori dello spazio tangente e per

questo motivo viene spesso indicata con il nome di matrice metrica.

A.3. CURVATURA NORMALE

Per poter quantificare la curvatura di una superficie S, consideriamo una generica curva C suS passante per il punto P. Il versore tangente t e il versore normale n alla curva C nel punto Psono legati dalla seguente relazione:

k = dt

d s= kn = kn +kg

dove kn è detta curvature normale e kg è detta curvatura geodetica. Queste quantità sono lecomponenti del vettore curvatura k della curva C nella direzione normale alla superficie enella direzione del piano tangente perpendicolare a t, rispettivamente.

La curvatura normale può quindi essere espressa come

kn = knn

dove kn è detta curvatura normale della superficie in P in direzione t. Il segno di kn dipendeovviamente dalla direzione della normale alla superficie.

Considerando l’espressione n · t = 0 e derivandola rispetto ad s, otteniamo:

dt

d s·n+ t · dn

d s= 0

30

Page 31: Codice C++ per il calcolo delle intersezioni tra griglie ...forma/Didattica/ProgettiPacs/Turconi13-14/... · Introduzione L’obiettivo di questo progetto è lo sviluppo di una libreria

Possiamo quindi scrivere:

kn = dt

d s·n =−t · dn

d s=−dS

d s· dn

d s=−dS ·dn

dS ·dS= Ldu2 +2Mdud v +N d v2

E du2 +2F dud v +Gd v2

dove

L = Su ·nu M =−1

2(Su ·nv +Sv ·nu) =−Su ·nv =−Sv ·nu N =−Sv ·nv

A.4. SECONDA FORMA FONDAMENTALE E MAPPA DI WEINGARTEN

Poichè Su e Sv sono perpendicolare a n, si ha che Su ·n = 0 e Sv ·n = 0. Possiamo quindiriscrivere i coefficienti L, M ed N in modo equivalente:

L = Suu ·n M = Suv ·n N = Sv v ·n

Definizione 3. La seconda forma fondamentale di una superficie S(u, v) è definita come

I I = Ldu2 +2Mdud v +N d v2

L, M, N sono chiamati coefficienti della seconda forma fondamentale.Anche in questo caso i coefficienti possono essere raggruppati per formare la matrice della

seconda forma fondamentale:

B =[

b11(u, v) b12(u, v)b21(u, v) b22(u, v)

]=

[Suu ·n(u, v) Suv ·n(u, v)Svu ·n(u, v) Sv v ·n(u, v)

]=

[L MM N

]Consideriamo ora il sistema di riferimento solidale alla superficie definito in ogni punto

dalla terna di vettori Su , Sv e n. La base formata da questi tre vettori è detta base mobile.Esprimendo rispetto a questa base i vettori Suu , Suv , Sv v riusciamo a dare un significato piùpreciso ai coefficienti della seconda forma fondamentale, infatti:

Suu = Γ111Su +Γ2

11Sv +b11n (A.3)

Suv = Γ112Su +Γ2

12Sv +b12n (A.4)

Svu = Γ121Su +Γ2

21Sv +b21n (A.5)

Sv v = Γ122Su +Γ2

22Sv +b22n (A.6)

Abbiamo già osservato in precedenza che nu ed nv risultano perpendicolari ad n. Quan-do andremo a calcolare queste derivate esprimendole rispetto alla base mobile, questepresenteranno solamente le componenti lungo Su e lungo Sv :

nu =−x11Su −x12Sv

nv =−x21Su −x22Sv

31

Page 32: Codice C++ per il calcolo delle intersezioni tra griglie ...forma/Didattica/ProgettiPacs/Turconi13-14/... · Introduzione L’obiettivo di questo progetto è lo sviluppo di una libreria

Raggruppiamo questi coefficienti a formare la matrice X:

X =[

x11 x12

x21 x22

]Questa matrice in realtà non è una novità rispetto a quanto già conosciamo, perchè esiste

una relazione, detta relazione di Weingarten, che lega le matrici B ed X:

X = BG−1

La matrice X esprime, rispetto alla base dello spazio tangente, la trasformazione LP : TP(S) →TP(S). Tale applicazione è detta Mappa di Weingarten; essa trasforma linearmente lo spaziotangente in se stesso: fa la derivata rispetto ad una direzione tangente del versore normale e laproietta nello spazio tangente.

X e B esprimo quindi in modo diverso la stessa informazione, cioè come varia la direzionedel versore normale alla superficie se ci si sposta in direzione tangente alla superficie stessa.La differenza è che B rappresenta questa variazione lungo la direzione individuata dalla stessanormale n, mentre X la esprime proiettandola nello spazio tangente, ovvero lungo le direzioniindividuate da Su e Sv .

In sostanza quindi l’informazione contenuta in X e B è la stessa e rappresenta l’informa-zione contenuta nella mappa di Wiengarten, la quale è, punto per punto, un invariante dellasuperficie e non fa altro che descrivere il modo in cui essa è immersa nello spazio ambiente.

Ovviamente il concetto di curvatura di una superficie è strettamente legato a come questa èposizionata nello spazio, si evince quindi che deve essere strettamente legato alla mappa diWeingarten.

A.5. CURVATURA MEDIA E CURVATURA GAUSSIANA

In particolare si possono dare le seguenti definizioni:

Definizione 4. Si dice curvatura media la funzione

H(u, v) = 1

2tr (L) = 1

2tr (X )

Definizione 5. Si dice curvatura di Gauss (o Gaussiana) la funzione

K (u, v) = det (L) = det (X )

Poichè traccia e determinante sono degli invarianti per l’applicazione LP, essi non dipendo-no dalla particolare rappresentazione X scelta.

Sfruttando la Relazione di Weingarten possiamo ricavare la formula:

K (u, v) = det (X ) = det (B)

det (G)= LN −M 2

EG −F 2

32

Page 33: Codice C++ per il calcolo delle intersezioni tra griglie ...forma/Didattica/ProgettiPacs/Turconi13-14/... · Introduzione L’obiettivo di questo progetto è lo sviluppo di una libreria

Allo stesso modo possiamo scrivere anche la curvatura media rispetto ai coefficienti di B eG. Sempre grazie alla relazione di Weingarten si ricava che:

x11 = b11[G−1]11 +b12[G−1]21 = 1

det (G)(b11[G]22 −b12[G]12) =

= 1

EG −F 2 (LG −MF )

x22 = b21[G−1]12 +b22[G−1]22 = 1

det (G)(−b21[G]21 +b22[G]11) =

= 1

EG −F 2 (−MF +N E)

Da cui segue la formula:

H(u, v) = 1

2tr (X ) = 1

2

E N +GL−2F M

EG −F 2

A.6. CURVATURE PRINCIPALI

Come abbiamo visto in uno dei paragrafi precedenti la curvatura normale dipende dalladirezione t del vettore tangente alla curva C considerata.

Definizione 6. Le curvature principali della superficie S(u, v) nel punto P sono il valore massi-mo e il valore minimo che la curvatura normale può assumere in tale punto al variare delladirezione t considerata:

k1 = maxt

kn(t)

k2 = mint

kn(t)

Si può dimostrare che le due curvature principali sono gli autovalori della Mappa diWeingarten LP:

H(u, v) = 1

2tr (L) = 1

2(k1 +k2)

K (u, v) = det (L) = k1k2

Ne consegue che una volta note la Curvatura Media H(u, v) e la Curvatura GaussianaK (u, v), possiamo ricavare le curvature principali risolvendo la semplice equazione di secondogrado:

k2 −2Hk +K = 0

da cui seguono le formule:

k1 = H +√

H 2 −K

k2 = H −√

H 2 −K

33

Page 34: Codice C++ per il calcolo delle intersezioni tra griglie ...forma/Didattica/ProgettiPacs/Turconi13-14/... · Introduzione L’obiettivo di questo progetto è lo sviluppo di una libreria

Riferimenti bibliografici[1] A. Alexandrescu, Modern C++ Design: Generic Programming and Design Patterns Applied,

Addison-Wesley Professional, 2001.

[2] www.cplusplus.com, 2000-2012

[3] Blaise Barney, OpenMP: https://computing.llnl.gov/tutorials/openMP/, Law-rence Livermore National Laboratory

[4] VTK File Formats: www.vtk.org, LANL, NLM, NA-MIC, DOE-ASC, Sandia National Lab,ARL

[5] Oeystein Pettersen, Basics of Reservoir Simulation with the Eclipse Reservoir Simulator:Lecture notes, Dept. of Mathematics, University of Bergen, 2006

[6] A. Quarteroni, Matematica Numerica, Springer, 2008

[7] N.M. Patrikalakis, T. Maekawa, W. Cho, Shape Interrogation for Computer AidedDesign and Manufacturing, Hyperbook Edition, http://web.mit.edu/hyperbook/Patrikalakis-Maekawa-Cho/

34