--- LaplaceRobin.cpp 2004-01-27 23:51:15.000000000 +0100 +++ LaplaceProjet2d.cpp 2004-01-19 01:29:27.000000000 +0100 @@ -1,11 +1,3 @@ -//Fichier Laplace.cpp modifie par Alain Perronnet -// a partir de l'original ecrit par Frederic HECHT fem-v5/Laplace1.cpp -//------------------------------------------------------------------------------ - -//Resolution du Laplacien : Solution exacte U(x,y)=3*x+5*y - -//------------------------------------------------------------------------------ - int verbosity =2; //Definit le niveau des impressions #include <cmath> @@ -27,24 +19,31 @@ /* * Labels: */ -#if 0 -// testfrontiere.msh : -// 1 {est le NUMERO ou LABEL dans LIGNE de } C1 -// 2 {est le NUMERO ou LABEL dans LIGNE de } C2 -// que du robin -#define isRobin( x ) ((x)==2) -#define isNeumann( x ) ( false ) -#define isDirichlet( x ) ((x)==1) -#define MESHFILE "testfrontiere.msh" +// choose one : + +#define USEROBIN +//#undef USEROBIN + +// from piece.msh / piecerobin.msh +// 21 {est le NUMERO ou LABEL dans LIGNE de } DIRICHLET +// 23 {est le NUMERO ou LABEL dans LIGNE de } NEUMANNINT +// 22 {est le NUMERO ou LABEL dans LIGNE de } NEUMANNEXT +// 33 {est le NUMERO ou LABEL dans LIGNE de } RAD +// +#ifdef USEROBIN +// avec condition de robin +#define isDirichlet( x ) ((x)==21 || (x)==23) +#define isRobin( x ) ( (x)==33) +#define isNeumann( x ) ( (x)==22 ) +#define MESHFILE "piecerobin.msh" #else -// testfrontiere_big.msh : -// 3 {est le NUMERO ou LABEL dans LIGNE de } C1B -// 4 {est le NUMERO ou LABEL dans LIGNE de } C2B -#define isDirichlet( x ) ((x)==3) -#define isRobin( x ) ((x)==4) -#define isNeumann( x ) ( false ) -#define MESHFILE "testfrontiere_big.msh" +// sans condition de robin +#define isDirichlet( x ) ((x)==21 || (x)==23) +#define isRobin( x ) (false) +#define isNeumann( x ) ( (x)==22 ) +//#define isNeumann( x ) ( (x)==23 || (x)==22 ) +#define MESHFILE "piece.msh" #endif /* @@ -52,15 +51,25 @@ * tenseurConductivite[i] est la diagonale du tenseur pour * le label "i" */ -#define MaxLabel 4 +// from piece.msh +// 2 {est le NUMERO dans SURFACE de }MUR1 +// 3 {est le NUMERO dans SURFACE de }MUR2 +// 6 {est le NUMERO dans SURFACE de }MUR3 +// 5 {est le NUMERO dans SURFACE de }SURFINT +// 7 {est le NUMERO dans SURFACE de }SURFINTRAD + +#define MaxLabel 7 +#define ConductiviteMur 0.05 +#define ConductiviteAir 2. R tenseurConductivite[][ 2 ] = { - {1.,1.}, // idendite, le plus classique - {1.,1.}, // idendite, le plus classique - {1.,1.}, // idendite, le plus classique - {1.,1.}, // idendite, le plus classique - {.5,2.}, // surtout sur l'axe des y - {2.,.5}, // surtout sur l'axe des x - {0.,1.}, // rien selon l'ace des x + {ConductiviteAir,ConductiviteAir}, // ne devrait pas etre utilise // 0 + {ConductiviteAir,ConductiviteAir}, // ne devrait pas etre utilise // 1 + {ConductiviteMur,ConductiviteMur}, // mur 1; + {ConductiviteMur,ConductiviteMur}, // mur 2; + {ConductiviteAir,ConductiviteAir}, // ne devrait pas etre utilise // 4 + {ConductiviteAir,ConductiviteAir}, // Surfint + {ConductiviteMur,ConductiviteMur}, // mur 3; + {ConductiviteAir,ConductiviteAir}, // Surfintrad (avec radiateur) // 7 }; //------------------------------------------------------------------------------ @@ -91,21 +100,26 @@ } //------------------------------------------------------------------------------ -// -// on prends l'exemple de teta(x,y) = x*x + y*y -#define rayon1 ( 4. ) -#define rayon2 ( 10. ) - -#define TetaRobin ( 200. ) -#define G ( -2.*rayon2/( rayon2*rayon2-TetaRobin ) ) -R TetaExact ( R2 & P ) { return P.x*P.x + P.y*P.y; } - -R UDirichlet( R2 & P) { return rayon1*rayon1; } -R UNeumann( R2 & P) { return rayon2 * 2.; } -R fOmega( R2 & P) { return -4.;} // laplacien constant = 4 -R GRobin( R2 & P ) { return G; } // coefficient d'echange pour la frontiere de Robin -R TetaExtRobin( R2 & P ) { return TetaRobin; } // temperature exterieur, frontiere de Robin +R UDirichlet( R2 & P, Label label) { + switch ( label.lab ) { + default: assert( false ); + case 23: return 20; // murs interieurs + case 21: return 0; // murs exterieurs + } +} +R UNeumann( R2 & P, Label label) { + switch ( label.lab ) { + default: assert( false ); + case 23: return 0; // NEUMANNINT : pas de chaleur traversant les murs interieurs + case 22: return .5; // NEUMANNEXT le soleil chauffe la piece + } +} +R fOmega( R2 & P) { return 0;} // Pas de creation de chaleur a l'interieur +#ifdef USEROBIN +R GRobin( R2 & P ) { return 0.5; } // coefficient d'echange pour la frontiere de Robin +R TetaExtRobin( R2 & P ) { return 60; } // temperature interieur du radiateur +#endif //------------------------------------------------------------------------------ //Le programme principal @@ -203,13 +217,14 @@ R w0(PI.x), w1(1-PI.x); // valeurs des fonctions chapeaux R2 P = ((R2)edge[0])*w0 + ((R2)edge[1])*w1; // point courant - R N = length * UNeumann(P) * PI.p; // contribution de ce point + R N = length * UNeumann(P,label) * PI.p; // contribution de ce point Ug[i0] += N * w0 ; //vecteur global partie interne Ug[i1] += N * w1 ; //assemble a partir du vecteur elementaire } } +#ifdef USEROBIN /* * Frontiere de Robin */ @@ -248,6 +263,7 @@ Ug[i1] += N * w1; } } +#endif /* * Frontiere de Dirichlet @@ -255,7 +271,7 @@ const R tgv = 1e30; for (int i=0; i<Th.nv; i++) //Traitement des noeuds sur la frontiere Dirichlet if ( isDirichlet( ((Label)Th(i)).lab ) ) - Ug[i] = UDirichlet( Th(i) ) * (Ag.D[i] = tgv); + Ug[i] = UDirichlet( Th(i), (Label)Th(i) ) * (Ag.D[i] = tgv); @@ -274,30 +290,6 @@ rattente(1); closegraphique(); - // test de validite - R max = 0.; - R tetamax =0.; R tetamin =0.; - R tetamax_real =0.; R tetamin_real =0.; - assert ( Ug.N() == Th.nv ); - for ( int i = 0 ; i< Th.nv; i++ ) // on parcours l'ensemble des points - { - R diff; - R2 V; - - V = (R2)(Th.vertices[i]); - diff = Ug[i]-TetaExact(V) ; - diff *= diff; // on prends le carre - if ( diff>max ) max= diff; - if ( Ug[i]>tetamax ) tetamax= Ug[i]; - if ( Ug[i]<tetamin ) tetamin= Ug[i]; - if ( TetaExact(V)>tetamax_real) tetamax_real= TetaExact(V); - if ( TetaExact(V)<tetamin_real ) tetamin_real= TetaExact(V); - } - printf("\nMax des carres obtenu : %f\n", max); - printf("\nMin,Max des tetas obtenu : %f, %f", tetamin, tetamax); - printf("\nMin,Max des tetas reels : %f, %f", tetamin_real, tetamax_real); - printf("\n\n"); - return 0; }