poisson_frontiere.C

00001 /*
00002  *   Copyright (c) 2000-2001 Philippe Grandclement
00003  *
00004  *   This file is part of LORENE.
00005  *
00006  *   LORENE is free software; you can redistribute it and/or modify
00007  *   it under the terms of the GNU General Public License as published by
00008  *   the Free Software Foundation; either version 2 of the License, or
00009  *   (at your option) any later version.
00010  *
00011  *   LORENE is distributed in the hope that it will be useful,
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *   GNU General Public License for more details.
00015  *
00016  *   You should have received a copy of the GNU General Public License
00017  *   along with LORENE; if not, write to the Free Software
00018  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  *
00020  */
00021 
00022 
00023 char poisson_frontiere_C[] = "$Header: /cvsroot/Lorene/C++/Source/Non_class_members/PDE/poisson_frontiere.C,v 1.3 2004/11/23 12:50:44 f_limousin Exp $" ;
00024 
00025 /*
00026  * $Id: poisson_frontiere.C,v 1.3 2004/11/23 12:50:44 f_limousin Exp $
00027  * $Log: poisson_frontiere.C,v $
00028  * Revision 1.3  2004/11/23 12:50:44  f_limousin
00029  * Intoduce function poisson_dir_neu(...) to solve a scalar poisson
00030  * equation with a mixed boundary condition (Dirichlet + Neumann).
00031  *
00032  * Revision 1.2  2004/09/08 15:12:16  f_limousin
00033  * Delete some assert.
00034  *
00035  * Revision 1.1.1.1  2001/11/20 15:19:28  e_gourgoulhon
00036  * LORENE
00037  *
00038  * Revision 2.4  2000/05/22  16:03:32  phil
00039  * ajout du cas dzpuis = 3
00040  *
00041  * Revision 2.3  2000/05/15  15:46:35  phil
00042  * *** empty log message ***
00043  *
00044  * Revision 2.2  2000/04/27  12:28:56  phil
00045  * correction pour le raccord des differents domaines
00046  *
00047  * Revision 2.1  2000/03/20  13:06:32  phil
00048  * *** empty log message ***
00049  *
00050  * Revision 2.0  2000/03/17  17:24:49  phil
00051  * *** empty log message ***
00052  *
00053  *
00054  * $Header: /cvsroot/Lorene/C++/Source/Non_class_members/PDE/poisson_frontiere.C,v 1.3 2004/11/23 12:50:44 f_limousin Exp $
00055  *
00056  */
00057 
00058 
00059 // Header C : 
00060 #include <stdlib.h>
00061 #include <math.h>
00062 
00063 // Headers Lorene :
00064 #include "matrice.h"
00065 #include "tbl.h"
00066 #include "mtbl_cf.h"
00067 #include "map.h"
00068 #include "base_val.h"
00069 #include "proto.h"
00070 #include "type_parite.h"
00071 #include "utilitaires.h"
00072 #include "valeur.h"
00073 
00074 
00075 
00076         //----------------------------------------------
00077        //       Version Mtbl_cf
00078       //----------------------------------------------
00079 
00080 /*
00081  * 
00082  * Solution de l'equation de poisson avec Boundary condition a 
00083  * l'interieur d'une coquille.
00084  * 
00085  * Entree : mapping :   le mapping affine
00086  *      source : les coefficients de la source qui a ete multipliee par
00087  *          r^4 ou r^2 dans la ZEC.
00088  *          La base de decomposition doit etre Ylm
00089  *      limite : la CL (fonction angulaire) sur une frontiere spherique
00090  *      type_raccord : 1 pour Dirichlet et 2 pour Neumann
00091  *      num_front : indique la frontiere ou on impose la CL : 1 pour la 
00092  * frontiere situee entre le domain 1 et 2.
00093  *      dzpuis : exposant de r dans le factor multiplicatif dans la ZEC
00094  * Sortie : renvoie les coefficients de la solution dans la meme base de 
00095  *      decomposition (a savoir Ylm)
00096  *      
00097  */
00098 
00099 
00100 
00101 Mtbl_cf sol_poisson_frontiere(const Map_af& mapping, const Mtbl_cf& source,
00102         const Mtbl_cf& limite, int type_raccord, int num_front, int dzpuis, double fact_dir, double fact_neu)
00103 
00104 {
00105     
00106     // Verifications d'usage sur les zones
00107     int nz = source.get_mg()->get_nzone() ;
00108     assert (nz>1) ;
00109     assert ((num_front>=0) && (num_front<nz-2)) ;
00110     assert (source.get_mg()->get_type_r(nz-1) == UNSURR) ;
00111     for (int l=num_front+1 ; l<nz-1 ; l++)
00112     assert(source.get_mg()->get_type_r(l) == FIN) ;
00113     
00114     assert (source.get_etat() != ETATNONDEF) ;
00115     assert (limite.get_etat() != ETATNONDEF) ;
00116      
00117     assert ((dzpuis==4) || (dzpuis==2) || (dzpuis==3)) ;
00118     assert ((type_raccord == 1) || (type_raccord == 2)|| (type_raccord == 3)) ;
00119     
00120     // Bases spectrales
00121     const Base_val& base = source.base ;
00122     
00123     // donnees sur la zone
00124     int nr, nt, np ;
00125     int base_r ;
00126     double alpha, beta, echelle ;
00127     int l_quant, m_quant;
00128     
00129     //Rangement des valeurs intermediaires 
00130     Tbl *so ;
00131     Tbl *sol_hom ;
00132     Tbl *sol_part ;
00133     Matrice *operateur ;
00134     Matrice *nondege ;
00135     
00136     
00137     // Rangement des solutions, avant raccordement
00138     Mtbl_cf solution_part(source.get_mg(), base) ;
00139     Mtbl_cf solution_hom_un(source.get_mg(), base) ;
00140     Mtbl_cf solution_hom_deux(source.get_mg(), base) ;
00141     Mtbl_cf resultat(source.get_mg(), base) ;
00142     
00143     solution_part.set_etat_qcq() ;
00144     solution_hom_un.set_etat_qcq() ;
00145     solution_hom_deux.set_etat_qcq() ;
00146     resultat.set_etat_qcq() ;
00147     
00148     for (int l=0 ; l<nz ; l++) {
00149     solution_part.t[l]->set_etat_qcq() ;
00150     solution_hom_un.t[l]->set_etat_qcq() ;
00151     solution_hom_deux.t[l]->set_etat_qcq() ;
00152     resultat.t[l]->set_etat_qcq() ;
00153     for (int k=0 ; k<source.get_mg()->get_np(l)+2 ; k++)
00154         for (int j=0 ; j<source.get_mg()->get_nt(l) ; j++)
00155         for (int i=0 ; i<source.get_mg()->get_nr(l) ; i++)
00156             resultat.set(l, k, j, i) = 0 ;
00157     }
00158     
00159     // nbre maximum de point en theta et en phi :
00160     int np_max = 0 ;
00161     int nt_max = 0 ;
00162     
00163 
00164            //---------------
00165           //--  ZEC   -----
00166          //---------------
00167          
00168     nr = source.get_mg()->get_nr(nz-1) ;
00169     nt = source.get_mg()->get_nt(nz-1) ;
00170     np = source.get_mg()->get_np(nz-1) ;
00171     
00172     if (np > np_max) np_max = np ;
00173     if (nt > nt_max) nt_max = nt ;
00174    
00175     alpha = mapping.get_alpha()[nz-1] ;
00176     beta = mapping.get_beta()[nz-1] ;
00177     
00178     for (int k=0 ; k<np+1 ; k++)
00179     for (int j=0 ; j<nt ; j++) 
00180         if (nullite_plm(j, nt, k, np, base) == 1)
00181         {
00182         
00183         // calcul des nombres quantiques :
00184         donne_lm(nz, nz-1, j, k, base, m_quant, l_quant, base_r) ;
00185         
00186         //Construction operateur
00187         operateur = new Matrice(laplacien_mat(nr, l_quant, 0., dzpuis,
00188                                  base_r)) ;
00189         (*operateur) = combinaison(*operateur, l_quant, 0., dzpuis, base_r) ;
00190         
00191         // Operateur inversible
00192         nondege = new Matrice(prepa_nondege(*operateur, l_quant, 0.,
00193                                  dzpuis, base_r)) ;
00194        
00195         // Calcul de la SH
00196         sol_hom = new Tbl(solh(nr, l_quant, 0., base_r)) ;
00197        
00198         // Calcul de la SP
00199         so = new Tbl(nr) ;
00200         so->set_etat_qcq() ;
00201         for (int i=0 ; i<nr ; i++)
00202         so->set(i) = source(nz-1, k, j, i) ;
00203         sol_part = new Tbl(solp(*operateur, *nondege, alpha, beta, 
00204                 *so, dzpuis, base_r)) ;
00205     
00206         // Rangement
00207         for (int i=0 ; i<nr ; i++) {
00208         solution_part.set(nz-1, k, j, i) = (*sol_part)(i) ;
00209         solution_hom_un.set(nz-1, k, j, i) = (*sol_hom)(i) ;
00210         solution_hom_deux.set(nz-1, k, j, i) = 0. ;
00211         }
00212       
00213         delete operateur ;
00214         delete nondege ;
00215         delete so ;
00216         delete sol_hom ;
00217         delete sol_part ;
00218     }
00219     
00220            //---------------
00221           //- COQUILLES ---
00222          //---------------
00223 
00224     for (int zone=num_front+1 ; zone<nz-1 ; zone++) {
00225     nr = source.get_mg()->get_nr(zone) ;
00226     nt = source.get_mg()->get_nt(zone) ;
00227     np = source.get_mg()->get_np(zone) ;
00228     
00229     if (np > np_max) np_max = np ;
00230     if (nt > nt_max) nt_max = nt ;
00231     
00232     alpha = mapping.get_alpha()[zone] ;
00233     beta = mapping.get_beta()[zone] ;
00234 
00235     for (int k=0 ; k<np+1 ; k++)
00236         for (int j=0 ; j<nt ; j++) 
00237         if (nullite_plm(j, nt, k, np, base) == 1)
00238         {
00239         // calcul des nombres quantiques :
00240         donne_lm(nz, zone, j, k, base, m_quant, l_quant, base_r) ;
00241         
00242         // Construction de l'operateur
00243         operateur = new Matrice(laplacien_mat
00244                     (nr, l_quant, beta/alpha, 0, base_r)) ;
00245         
00246         (*operateur) = combinaison(*operateur, l_quant, beta/alpha, 0, 
00247                                      base_r) ;
00248         
00249          // Operateur inversible
00250         nondege = new Matrice(prepa_nondege(*operateur, l_quant, 
00251                             beta/alpha, 0, base_r)) ;       
00252         
00253         // Calcul DES DEUX SH
00254         sol_hom = new Tbl(solh(nr, l_quant, beta/alpha, base_r)) ;
00255         
00256         // Calcul de la SP
00257         so = new Tbl(nr) ;
00258         so->set_etat_qcq() ;
00259         for (int i=0 ; i<nr ; i++)
00260             so->set(i) = source(zone, k, j, i) ;
00261         
00262         sol_part = new Tbl (solp(*operateur, *nondege, alpha,
00263                      beta, *so, 0, base_r)) ;
00264         
00265         
00266         // Rangement
00267         for (int i=0 ; i<nr ; i++) {
00268             solution_part.set(zone, k, j, i) = (*sol_part)(i) ;
00269             solution_hom_un.set(zone, k, j, i) = (*sol_hom)(0, i) ;
00270             solution_hom_deux.set(zone, k, j, i) = (*sol_hom)(1, i) ;
00271         }
00272             
00273         
00274         delete operateur ;
00275         delete nondege ;
00276         delete so ;
00277         delete sol_hom ;
00278         delete sol_part ;
00279         }
00280     }
00281         
00282          //-------------------------------------------
00283         // On est parti pour imposer la boundary
00284        //-------------------------------------------
00285        
00286     nr = source.get_mg()->get_nr(num_front+1) ;
00287     nt = source.get_mg()->get_nt(num_front+1) ;
00288     np = source.get_mg()->get_np(num_front+1) ;
00289     double facteur ;
00290     double somme ;
00291     
00292     alpha = mapping.get_alpha()[num_front+1] ;
00293     beta = mapping.get_beta()[num_front+1] ;
00294     echelle = beta/alpha ;
00295     
00296     for (int k=0 ; k<np+1 ; k++)
00297     for (int j=0 ; j<nt ; j++) 
00298         if (nullite_plm(j, nt, k, np, base) == 1)
00299         {
00300         // calcul des nombres quantiques :
00301         donne_lm(nz, num_front+1, j, k, base, m_quant, l_quant, base_r) ;
00302         
00303         switch (type_raccord) {
00304         case 1 : 
00305             // Conditions de raccord type Dirichlet :
00306             // Pour la sp :
00307             somme = 0 ;
00308             for (int i=0 ; i<nr ; i++)
00309             if (i%2 == 0)
00310                 somme += solution_part(num_front+1, k, j, i) ;
00311             else
00312                 somme -= solution_part(num_front+1, k, j, i) ;
00313             facteur = (limite(num_front, k, j, 0)-somme)
00314                 * pow(echelle-1, l_quant+1) ;
00315             
00316             for (int i=0 ; i<nr ; i++)
00317             solution_part.set(num_front+1, k, j, i) +=
00318                 facteur*solution_hom_deux(num_front+1, k, j, i) ;
00319             
00320             // pour la solution homogene :
00321             facteur = - pow(echelle-1, 2*l_quant+1) ;
00322             for (int i=0 ; i<nr ; i++)
00323             solution_hom_un.set(num_front+1, k, j, i) +=
00324                 facteur*solution_hom_deux(num_front+1, k, j, i) ;
00325             break ;
00326          
00327          
00328          case 2 :
00329             //Conditions de raccord de type Neumann :
00330              // Pour la sp :
00331             somme = 0 ;
00332             for (int i=0 ; i<nr ; i++)
00333             if (i%2 == 0)
00334                 somme -= i*i/alpha*solution_part(num_front+1, k, j, i) ;
00335             else
00336                 somme += i*i/alpha*solution_part(num_front+1, k, j, i) ;
00337             facteur = (somme-limite(num_front, k, j, 0))
00338                 * alpha*pow(echelle-1, l_quant+2)/(l_quant+1) ;
00339             for (int i=0 ; i<nr ; i++)
00340             solution_part.set(num_front+1, k, j, i) +=
00341                 facteur*solution_hom_deux(num_front+1, k, j, i) ;
00342             
00343             // pour la solution homogene :
00344             facteur = pow(echelle-1, 2*l_quant+1)*l_quant/(l_quant+1) ;
00345             for (int i=0 ; i<nr ; i++)
00346             solution_hom_un.set(num_front+1, k, j, i) +=
00347                 facteur*solution_hom_deux(num_front+1, k, j, i) ;
00348             break ;
00349             
00350         case 3 : 
00351             // Conditions de raccord type Dirichlet-Neumann :
00352             somme = 0 ;
00353             for (int i=0 ; i<nr ; i++)
00354             if (i%2 == 0)
00355                 somme += solution_part(num_front+1, k, j, i) *
00356                 fact_dir - fact_neu *
00357                     i*i/alpha*solution_part(num_front+1, k, j, i) ;
00358             else
00359                 somme += - solution_part(num_front+1, k, j, i) *
00360                 fact_dir + fact_neu *
00361                 i*i/alpha*solution_part(num_front+1, k, j, i) ;
00362 
00363             double somme2 ;
00364             somme2 = fact_dir * pow(echelle-1, -l_quant-1) - 
00365             fact_neu/alpha*pow(echelle-1, -l_quant-2)*(l_quant+1) ;
00366 
00367             facteur = (limite(num_front, k, j, 0)- somme) / somme2 ;
00368 
00369             for (int i=0 ; i<nr ; i++)
00370             solution_part.set(num_front+1, k, j, i) +=
00371                 facteur*solution_hom_deux(num_front+1, k, j, i) ;
00372             
00373             // pour la solution homogene :
00374             double somme1 ;
00375             somme1 = fact_dir * pow(echelle-1, l_quant) + 
00376             fact_neu / alpha * pow(echelle-1, l_quant-1) * 
00377             l_quant ;
00378             facteur = - somme1 / somme2 ;
00379             for (int i=0 ; i<nr ; i++)
00380             solution_hom_un.set(num_front+1, k, j, i) +=
00381                 facteur*solution_hom_deux(num_front+1, k, j, i) ;
00382 
00383             break ;
00384 
00385          default :
00386             cout << "Diantres nous ne devrions pas etre ici ! " << endl ;
00387             abort() ;
00388             break ;
00389         }
00390         
00391         // Securite.
00392         for (int i=0 ; i<nr ; i++)
00393             solution_hom_deux.set(num_front+1, k, j, i) = 0 ;
00394         }
00395         
00396         
00397          //-------------------------------------------
00398         // On est parti pour le raccord des solutions
00399        //-------------------------------------------
00400        
00401     // On 
00402     // Tableau de 0 et 1 sur les zones, indiquant si le Plm considere
00403     // intervient dans le developpement de cette zone.
00404     int * indic = new int [nz] ;
00405     int taille ;
00406     Tbl *sec_membre ; // termes constants du systeme
00407     Matrice *systeme ; //le systeme a resoudre
00408 
00409     // des compteurs pour le remplissage du systeme
00410     int ligne ;
00411     int colonne ;
00412 
00413     // compteurs pour les diagonales du systeme :
00414     int sup ;
00415     int inf ;
00416     int sup_new, inf_new ;
00417 
00418     // on boucle sur le plus grand nombre possible de Plm intervenant...
00419     for (int k=0 ; k<np_max+1 ; k++)
00420     for (int j=0 ; j<nt_max ; j++)
00421         if (nullite_plm(j, nt_max, k, np_max, base) == 1) {
00422         
00423         ligne = 0 ;
00424         colonne = 0 ;
00425         sup = 0 ;
00426         inf = 0 ;
00427         
00428         for (int zone=num_front+1 ; zone<nz ; zone++)
00429             indic[zone] = nullite_plm(j, source.get_mg()->get_nt(zone), 
00430                      k,  source.get_mg()->get_np(zone), base);
00431         
00432         // taille du systeme a resoudre pour ce Plm 
00433         taille = indic[nz-1]+indic[num_front+1] ;
00434         for (int zone=num_front+2 ; zone<nz-1 ; zone++)
00435             taille+=2*indic[zone] ;
00436         
00437         // on verifie que la taille est non-nulle.
00438         // cas pouvant a priori se produire...
00439         
00440         if (taille != 0) {
00441             
00442             sec_membre = new Tbl(taille) ;
00443             sec_membre->set_etat_qcq() ;
00444             for (int l=0 ; l<taille ; l++)
00445             sec_membre->set(l) = 0 ;
00446             
00447             systeme = new Matrice(taille, taille) ;
00448             systeme->set_etat_qcq() ;
00449             for (int l=0 ; l<taille ; l++)
00450             for (int c=0 ; c<taille ; c++)
00451                 systeme->set(l, c) = 0 ;
00452             
00453             //Calcul des nombres quantiques
00454             //base_r est donne dans le noyau, sa valeur dans les autres
00455             //zones etant inutile.
00456             
00457             donne_lm (nz, 0, j, k, base, m_quant, l_quant, base_r) ;
00458             
00459             
00460              //----------------------------------
00461             //      COQUILLE LA + INTERNE 
00462            //------------------------------------
00463             
00464             if (indic[num_front+1] == 1) {
00465             nr = source.get_mg()->get_nr(num_front+1) ;
00466             
00467             alpha = mapping.get_alpha()[num_front+1] ;
00468             beta = mapping.get_beta()[num_front+1] ;
00469             echelle = beta/alpha ;
00470             
00471             // valeur de la solhomogene en 1 :
00472             somme = 0 ;
00473             for (int i=0 ; i<nr ; i++)
00474                 somme += solution_hom_un (num_front+1, k, j, i) ;
00475             systeme->set(ligne, colonne) = somme ;
00476             
00477             // coefficient du Plm dans la solp
00478             for (int i=0 ; i<nr ; i++)
00479                 sec_membre->set(ligne) -= solution_part(num_front+1, k, j, i) ;
00480                 
00481             ligne++ ;
00482             // on prend les derivees que si Plm existe 
00483             //dans la zone suivante
00484             
00485             if (indic[num_front+1] == 1) {
00486 
00487                 // derivee de la solhomogene en 1 :
00488                 somme = 0 ;
00489                 for (int i=0 ; i<nr ; i++)
00490                 somme += i*i/alpha*
00491                     solution_hom_un(num_front+1, k, j, i) ;
00492                 systeme->set(ligne, colonne) = somme ; 
00493             
00494                 // coefficient de la derivee du Plm dans la solp
00495                 for (int i=0 ; i<nr ; i++)
00496                 sec_membre->set(ligne) -= i*i/alpha
00497                         *solution_part(num_front+1, k, j, i) ;
00498                                 
00499                 // on a au moins un diag inferieure dans ce cas ...
00500                 inf = 1 ;
00501             }
00502             colonne++ ; 
00503             }
00504             
00505             //-----------------------------
00506            //        COQUILLES "normales"
00507           //------------------------------
00508           
00509           for (int zone=num_front+2 ; zone<nz-1 ; zone++)
00510             if (indic[zone] == 1) {
00511             
00512             nr = source.get_mg()->get_nr(zone) ;
00513             alpha = mapping.get_alpha()[zone] ;
00514             echelle = mapping.get_beta()[zone]/alpha ;
00515             
00516             //Frontiere avec la zone precedente :
00517             if (indic[zone-1] == 1) ligne -- ;
00518             
00519             //valeur de (x+echelle)^l en -1 :
00520             systeme->set(ligne, colonne) = 
00521                 -pow(echelle-1, double(l_quant)) ;
00522             
00523             // valeur de 1/(x+echelle) ^(l+1) en -1 :
00524             systeme->set(ligne, colonne+1) = 
00525                 -1/pow(echelle-1, double(l_quant+1)) ;
00526             
00527             // la solution particuliere :
00528             for (int i=0 ; i<nr ; i++)
00529                 if (i%2 == 0)
00530                 sec_membre->set(ligne) += solution_part(zone, k, j, i) ;
00531                 else sec_membre->set(ligne) -= solution_part(zone, k, j, i) ;
00532             
00533             // les diagonales :
00534             sup_new = colonne+1-ligne ;
00535             if (sup_new > sup) sup = sup_new ;
00536             
00537             ligne++ ;
00538             
00539             // on prend les derivees si Plm existe dans la zone 
00540             // precedente :
00541             
00542             if (indic[zone-1] == 1) {
00543             // derivee de (x+echelle)^l en -1 :
00544                 systeme->set(ligne, colonne) = 
00545                 -l_quant*pow(echelle-1, double(l_quant-1))/alpha ;
00546             // derivee de 1/(x+echelle)^(l+1) en -1 :
00547                 systeme->set(ligne, colonne+1) = 
00548                 (l_quant+1)/pow(echelle-1, double(l_quant+2))/alpha ;
00549             
00550             
00551             
00552             // la solution particuliere :
00553                 for (int i=0 ; i<nr ; i++)
00554                 if (i%2 == 0)
00555                     sec_membre->set(ligne) -= 
00556                     i*i/alpha*solution_part(zone, k, j, i) ;
00557                 else
00558                     sec_membre->set(ligne) +=
00559                     i*i/alpha*solution_part(zone, k, j, i) ;
00560             
00561             // les diagonales :
00562             sup_new = colonne+1-ligne ;
00563             if (sup_new > sup) sup = sup_new ;
00564             
00565             ligne++ ;
00566             }
00567             
00568             // Frontiere avec la zone suivante :
00569             //valeur de (x+echelle)^l en 1 :
00570             systeme->set(ligne, colonne) = 
00571                 pow(echelle+1, double(l_quant)) ;
00572             
00573             // valeur de 1/(x+echelle)^(l+1) en 1 :
00574             systeme->set(ligne, colonne+1) =
00575                 1/pow(echelle+1, double(l_quant+1)) ;
00576                 
00577             // la solution particuliere :
00578             for (int i=0 ; i<nr ; i++)
00579                 sec_membre->set(ligne) -= solution_part(zone, k, j, i) ;
00580             
00581             // les diagonales inf :
00582             inf_new = ligne-colonne ;
00583             if (inf_new > inf) inf = inf_new ;  
00584             
00585             ligne ++ ;
00586                 
00587             // Utilisation des derivees ssi Plm existe dans la
00588             //zone suivante :
00589             if (indic[zone+1] == 1) {
00590                 
00591                 //derivee de (x+echelle)^l en 1 :
00592                 systeme->set(ligne, colonne) = 
00593                 l_quant*pow(echelle+1, double(l_quant-1))/alpha ;
00594                 
00595                 //derivee de 1/(echelle+x)^(l+1) en 1 :
00596                 systeme->set(ligne, colonne+1) =
00597                 -(l_quant+1)/pow(echelle+1, double(l_quant+2))/alpha ;
00598                 
00599                 // La solution particuliere :
00600                 for (int i=0 ; i<nr ; i++)
00601                 sec_membre->set(ligne) -= 
00602                     i*i/alpha*solution_part(zone, k, j, i) ;
00603                     
00604             // les diagonales inf :
00605             inf_new = ligne-colonne ;
00606             if (inf_new > inf) inf = inf_new ;  
00607                 
00608                  }
00609              colonne += 2 ;
00610              }
00611             
00612             
00613             //--------------------------------
00614            //             ZEC
00615           //---------------------------------
00616           
00617           if (indic[nz-1] == 1) {
00618               
00619               nr = source.get_mg()->get_nr(nz-1) ;
00620               
00621               
00622               alpha = mapping.get_alpha()[nz-1] ;
00623               
00624               if (indic[nz-2] == 1) ligne -- ;
00625               
00626               //valeur de (x-1)^(l+1) en -1 :
00627               systeme->set(ligne, colonne) = -pow(-2, double(l_quant+1)) ;
00628               //solution particuliere :
00629               for (int i=0 ; i<nr ; i++)
00630             if (i%2 == 0)
00631                 sec_membre->set(ligne) += solution_part(nz-1, k, j, i) ;
00632             else sec_membre->set(ligne) -= solution_part(nz-1, k, j, i) ;
00633             
00634             //on prend les derivees ssi Plm existe dans la zone precedente :
00635             if (indic[nz-2] == 1) {
00636             
00637             //derivee de (x-1)^(l+1) en -1 :
00638             systeme->set(ligne+1, colonne) = 
00639                 alpha*(l_quant+1)*pow(-2., double(l_quant+2)) ;
00640             
00641             // Solution particuliere :
00642             for (int i=0 ; i<nr ; i++)
00643                 if (i%2 == 0)
00644                 sec_membre->set(ligne+1) -=
00645                     -4*alpha*i*i*solution_part(nz-1, k, j, i) ;
00646                 else
00647                 sec_membre->set(ligne+1) +=
00648                     -4*alpha*i*i*solution_part(nz-1, k, j, i) ;
00649             
00650             //les diags :
00651             if (sup == 0) sup = 1 ;
00652             }
00653             }
00654             
00655             //-------------------------
00656            //  resolution du systeme 
00657           //--------------------------
00658             
00659             systeme->set_band(sup, inf) ;
00660             systeme->set_lu() ;
00661 
00662             Tbl facteurs(systeme->inverse(*sec_membre)) ;
00663             int conte = 0 ;
00664             
00665          
00666         // rangement dans la coquille interne :
00667             
00668             if (indic[num_front+1] == 1) {
00669             nr = source.get_mg()->get_nr(num_front+1) ;
00670             for (int i=0 ; i<nr ; i++)
00671                 resultat.set(num_front+1, k, j, i) = 
00672                  solution_part(num_front+1, k, j, i)
00673             +facteurs(conte)*solution_hom_un(num_front+1, k, j, i) ;
00674             conte++ ;
00675             }
00676             
00677             // rangement dans les coquilles :
00678             for (int zone=num_front+2 ; zone<nz-1 ; zone++)
00679             if (indic[zone] == 1) {
00680                 nr = source.get_mg()->get_nr(zone) ;
00681                 for (int i=0 ; i<nr ; i++)
00682                 resultat.set(zone, k, j, i) = 
00683                 solution_part(zone, k, j, i)
00684                 +facteurs(conte)*solution_hom_un(zone, k, j, i) 
00685                 +facteurs(conte+1)*solution_hom_deux(zone, k, j, i) ;
00686                 conte+=2 ;
00687             }
00688             
00689             //rangement dans la ZEC :
00690             if (indic[nz-1] == 1) {
00691              nr = source.get_mg()->get_nr(nz-1) ;
00692              for (int i=0 ; i<nr ; i++)
00693              resultat.set(nz-1, k, j, i) = 
00694                solution_part(nz-1, k, j, i)
00695                 +facteurs(conte)*solution_hom_un(nz-1, k, j, i) ;
00696             }
00697             
00698             delete sec_membre ;
00699             delete systeme ;
00700         }
00701     
00702     }
00703     
00704     delete [] indic ;
00705     
00706     // Les trucs les plus internes sont mis a zero ...
00707     for (int l=0 ; l<num_front+1 ; l++)
00708     resultat.t[l]->set_etat_zero() ;
00709     return resultat;
00710 }

Generated on Tue Feb 7 01:35:19 2012 for LORENE by  doxygen 1.4.6