valeur_val_propre_1d.C

00001 /*
00002  *   Copyright (c) 2004 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 valeur_val_propre_1d_C[] = "$Header: /cvsroot/Lorene/C++/Source/Valeur/valeur_val_propre_1d.C,v 1.1 2004/08/24 09:14:52 p_grandclement Exp $" ;
00024 
00025 
00026 
00027 /*
00028  * $Id: valeur_val_propre_1d.C,v 1.1 2004/08/24 09:14:52 p_grandclement Exp $
00029  * $Log: valeur_val_propre_1d.C,v $
00030  * Revision 1.1  2004/08/24 09:14:52  p_grandclement
00031  * Addition of some new operators, like Poisson in 2d... It now requieres the
00032  * GSL library to work.
00033  *
00034  * Also, the way a variable change is stored by a Param_elliptic is changed and
00035  * no longer uses Change_var but rather 2 Scalars. The codes using that feature
00036  * will requiere some modification. (It should concern only the ones about monopoles)
00037  *
00038  * 
00039  * $Header: /cvsroot/Lorene/C++/Source/Valeur/valeur_val_propre_1d.C,v 1.1 2004/08/24 09:14:52 p_grandclement Exp $
00040  *
00041  */
00042 
00043 // headers du C
00044 #include <assert.h>
00045 #include <stdlib.h>
00046 
00047 // headers Lorene
00048 
00049 #include "type_parite.h"
00050 #include "valeur.h"
00051 #include "matrice.h"
00052 #include "proto.h"
00053 
00054 
00055 //****************************************************************
00056 //                           CAS PAIR
00057 //****************************************************************
00058 
00059 void rotate_propre_pair (Valeur& so, bool sens) {
00060   
00061   so.coef() ;
00062   so.set_etat_cf_qcq() ;
00063 
00064   static int nt_courant = 0 ;
00065   static Matrice* passage = 0x0 ;
00066   static Matrice* inv = 0x0 ;
00067   
00068   int nt = so.mg->get_nt(0) ;
00069  
00070   
00071   if (nt != nt_courant) {
00072     // On doit calculer les matrices... Pas de la tarte...
00073     if (passage != 0x0) 
00074       delete passage ;
00075     if (inv != 0x0)
00076       delete inv ;
00077 
00078     nt_courant = nt ;
00079     
00080     Matrice ope (nt, nt) ;
00081     ope.set_etat_qcq() ;
00082     for (int i=0 ; i<nt ; i++)
00083       for (int j=0 ; j<nt ; j++)
00084     ope.set(i,j) = 0 ;
00085     
00086     double c_courant = 0 ;
00087     for (int j=0 ; j<nt ; j++) {
00088       ope.set(0, j) = 2*j ;
00089       for (int i=1 ; i<j ; i++)
00090     ope.set(i,j) = 4*j ;
00091       ope.set(j,j) = c_courant ;
00092       c_courant -= 8*j + 2 ;
00093     }
00094 
00095     passage = new Matrice (ope.vect_propre()) ;
00096     passage->set_band(nt-1,0) ;
00097     passage->set_lu() ;
00098     // Un peu nul pour calculer l'inverse mais bon...
00099     inv = new Matrice (nt, nt) ;
00100     inv->set_etat_qcq() ;
00101       
00102     Tbl auxi (nt) ;
00103     auxi.set_etat_qcq() ;
00104 
00105     for (int i=0 ; i<nt ; i++) {
00106       for (int j=0 ; j<nt ; j++)
00107     auxi.set(j) = 0 ;
00108       auxi.set(i) = 1 ;
00109       Tbl sortie (passage->inverse(auxi)) ;
00110       for (int j=0 ; j<nt ; j++)
00111     inv->set(j,i) = sortie(j) ;
00112     }    
00113   }
00114 
00115   // Fin du calcul des matrices...
00116   for (int l=0 ; l<so.mg->get_nzone() ; l++)
00117     if (so.c_cf->t[l]->get_etat() != ETATZERO)
00118       for (int k=0 ; k<so.mg->get_np(l) ; k++)
00119     for (int i=0 ; i<so.mg->get_nr(l) ; i++) {
00120       
00121       Tbl coefs(nt) ;
00122       coefs.set_etat_qcq() ;
00123       for (int j=0 ; j<nt ; j++)
00124         coefs.set(j) = (*so.c_cf)(l,k,j,i) ;
00125       Tbl prod (nt) ;
00126       prod.set_etat_qcq() ;
00127       for (int j=0 ; j<nt ; j++)
00128         prod.set(j) = 0 ;
00129       
00130       if (sens) {
00131         //calcul direct
00132         for (int j=0 ; j<nt ; j++)
00133           for (int jb=0 ; jb<nt ; jb++)
00134         prod.set(j) += (*inv)(j, jb) * coefs(jb) ;
00135       }
00136       else {
00137         //calcul inverse
00138         for (int j=0 ; j<nt ; j++)
00139           for (int jb=0 ; jb<nt ; jb++)
00140         prod.set(j) += (*passage)(j, jb) * coefs(jb) ;
00141       }
00142       
00143       for (int j=0 ; j<nt ; j++)
00144         so.c_cf->set(l,k,j,i) = prod(j) ;
00145       
00146     }
00147   
00148   // On met les bonnes bases :
00149   int base_tet = so.base.get_base_t(0) ;
00150   Base_val new_base (so.base) ;
00151   
00152   if (sens) {
00153     switch (base_tet) {
00154     case T_COS_P:
00155       new_base.set_base_t(T_CL_COS_P) ;
00156       break ;
00157     case T_SIN_P:
00158       new_base.set_base_t(T_CL_SIN_P) ;
00159       break ;
00160     default:
00161       cout << "Problem in rotate_propre_pair" << endl ;
00162       abort() ;
00163       break ;
00164     }
00165   }
00166   else {
00167     switch (base_tet) {
00168     case T_CL_COS_P:
00169       new_base.set_base_t(T_COS_P) ;
00170       break ;
00171     case T_CL_SIN_P:
00172       new_base.set_base_t(T_SIN_P) ;
00173       break ;
00174     default:
00175       cout << "Problem in rotate_propre_pair" << endl ;
00176       abort() ;
00177       break ;
00178     }
00179   }
00180 
00181   so.c_cf->base = new_base ;
00182   so.base = new_base ; 
00183 }
00184 
00185 //****************************************************************
00186 //                           CAS IMPAIR
00187 //****************************************************************
00188 
00189 void rotate_propre_impair (Valeur& so, bool sens) {  
00190   so.coef() ;
00191   so.set_etat_cf_qcq() ;
00192 
00193   static int nt_courant = 0 ;
00194   static Matrice* passage = 0x0 ;
00195   static Matrice* inv = 0x0 ;
00196   
00197   int nt = so.mg->get_nt(0) ;
00198  
00199   
00200   if (nt != nt_courant) {
00201     // On doit calculer les matrices... Pas de la tarte...
00202     if (passage != 0x0) 
00203       delete passage ;
00204     if (inv != 0x0)
00205       delete inv ;
00206 
00207     nt_courant = nt ;
00208     
00209     Matrice ope (nt, nt) ;
00210     ope.set_etat_qcq() ;
00211     for (int i=0 ; i<nt ; i++)
00212       for (int j=0 ; j<nt ; j++)
00213     ope.set(i,j) = 0 ;
00214 
00215     double c_courant = 0 ; 
00216     for (int j=0 ; j<nt ; j++) {
00217       for (int i=0 ; i<j ; i++)
00218     ope.set(i,j) = 2+4*j ;
00219       ope.set(j,j) = c_courant ;
00220       c_courant -= 8*j + 6 ;
00221     }
00222 
00223     passage = new Matrice (ope.vect_propre()) ;
00224     passage->set_band(nt-1,0) ;
00225     passage->set_lu() ;
00226     // Un peu nul pour calculer l'inverse mais bon...
00227     inv = new Matrice (nt, nt) ;
00228     inv->set_etat_qcq() ;
00229       
00230     Tbl auxi (nt) ;
00231     auxi.set_etat_qcq() ;
00232 
00233     for (int i=0 ; i<nt ; i++) {
00234       for (int j=0 ; j<nt ; j++)
00235     auxi.set(j) = 0 ;
00236       auxi.set(i) = 1 ;
00237       Tbl sortie (passage->inverse(auxi)) ;
00238       for (int j=0 ; j<nt ; j++)
00239     inv->set(j,i) = sortie(j) ;
00240     }
00241   }   
00242   
00243   // Fin du calcul des matrices...
00244 
00245   for (int l=0 ; l<so.mg->get_nzone() ; l++)
00246     if (so.c_cf->t[l]->get_etat() != ETATZERO)
00247       for (int k=0 ; k<so.mg->get_np(l) ; k++)
00248     for (int i=0 ; i<so.mg->get_nr(l) ; i++) {
00249       
00250       Tbl coefs(nt) ;
00251       coefs.set_etat_qcq() ;
00252       for (int j=0 ; j<nt ; j++)
00253         coefs.set(j) = (*so.c_cf)(l,k,j,i) ;
00254       Tbl prod (nt) ;
00255       prod.set_etat_qcq() ;
00256       for (int j=0 ; j<nt ; j++)
00257         prod.set(j) = 0 ;
00258       
00259       if (sens) {
00260         //calcul direct
00261         for (int j=0 ; j<nt ; j++)
00262           for (int jb=0 ; jb<nt ; jb++)
00263         prod.set(j) += (*inv)(j, jb) * coefs(jb) ;
00264       }
00265       else {
00266         //calcul inverse
00267         for (int j=0 ; j<nt ; j++)
00268           for (int jb=0 ; jb<nt ; jb++)
00269         prod.set(j) += (*passage)(j, jb) * coefs(jb) ;
00270       }
00271       
00272       for (int j=0 ; j<nt ; j++)
00273         so.c_cf->set(l,k,j,i) = prod(j) ;
00274       
00275     }
00276   
00277   // On met les bonnes bases :
00278   int base_tet = so.base.get_base_t(0) ;
00279   Base_val new_base (so.base) ;
00280   
00281   if (sens) {
00282     switch (base_tet) {
00283     case T_COS_I:
00284       new_base.set_base_t(T_CL_COS_I) ;
00285       break ;
00286     case T_SIN_I:
00287       new_base.set_base_t(T_CL_SIN_I) ;
00288       break ;
00289     default:
00290       cout << "Problem in rotate_propre_impair" << endl ;
00291       abort() ;
00292       break ;
00293     }
00294   }
00295   else {
00296     switch (base_tet) {
00297     case T_CL_COS_I:
00298       new_base.set_base_t(T_COS_I) ;
00299       break ;
00300     case T_CL_SIN_I:
00301       new_base.set_base_t(T_SIN_I) ;
00302       break ;
00303     default:
00304       cout << "Problem in rotate_propre_impair" << endl ;
00305       abort() ;
00306       break ;
00307     }
00308   }
00309 
00310   so.c_cf->base = new_base ;
00311   so.base = new_base ;
00312 }
00313 
00314 
00315 void Valeur::val_propre_1d() {
00316 
00317   // On recupere la base en tet :
00318   int nz = mg->get_nzone() ;
00319   int base_tet = base.get_base_t(0) ;
00320   // On verifie que c'est bien la meme partout...
00321   for (int i=1 ; i<nz ; i++)
00322     assert (base_tet == base.get_base_t(i)) ;
00323 
00324   switch (base_tet) {
00325   case T_COS_P:
00326     rotate_propre_pair (*this, true) ;
00327     break ;
00328   case T_SIN_P:
00329     rotate_propre_pair (*this, true) ;
00330     break ;
00331   case T_COS_I:
00332     rotate_propre_impair (*this, true) ;
00333     break ;
00334   case T_SIN_I:
00335     rotate_propre_impair (*this, true) ;
00336     break ;
00337   case T_CL_COS_P:
00338     break ;
00339   case T_CL_SIN_P:
00340     break ;
00341   case T_CL_COS_I:
00342     break ;
00343   case T_CL_SIN_I:
00344     break ;
00345   default:
00346     cout << "Unknown basis in Valeur::val_propre_1d" << endl ;
00347     abort() ;
00348     break ;
00349   }
00350 }
00351 void Valeur::val_propre_1d_i() {
00352 
00353   // On recupere la base en tet :
00354   int nz = mg->get_nzone() ;
00355   int base_tet = base.get_base_t(0) ;
00356   // On verifie que c'est bien la meme partout...
00357   for (int i=1 ; i<nz ; i++)
00358     assert (base_tet == base.get_base_t(i)) ;
00359 
00360   switch (base_tet) {
00361   case T_CL_COS_P:
00362     rotate_propre_pair (*this, false) ;
00363     break ;
00364   case T_CL_SIN_P:
00365     rotate_propre_pair (*this, false) ;
00366     break ;
00367   case T_CL_COS_I:
00368     rotate_propre_impair (*this, false) ;
00369     break ;
00370   case T_CL_SIN_I:
00371     rotate_propre_impair (*this, false) ;
00372     break ; 
00373   case T_COS_P:
00374     break ;
00375   case T_SIN_P:
00376     break ;
00377   case T_COS_I:
00378     break ;
00379   case T_SIN_I:
00380     break ;
00381   default:
00382     cout << "Unknown basis in Valeur::val_propre_1d_i" << endl ;
00383     abort() ;
00384     break ;
00385   }
00386 }
00387 
00388 

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