tenseur_sym.C

00001 /*
00002  *  Methods of class Tenseur_sym
00003  *
00004  *   (see file tenseur.h for documentation)
00005  *
00006  */
00007 
00008 /*
00009  *   Copyright (c) 1999-2001 Philippe Grandclement
00010  *   Copyright (c) 2000-2001 Eric Gourgoulhon
00011  *
00012  *   This file is part of LORENE.
00013  *
00014  *   LORENE is free software; you can redistribute it and/or modify
00015  *   it under the terms of the GNU General Public License as published by
00016  *   the Free Software Foundation; either version 2 of the License, or
00017  *   (at your option) any later version.
00018  *
00019  *   LORENE is distributed in the hope that it will be useful,
00020  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00021  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00022  *   GNU General Public License for more details.
00023  *
00024  *   You should have received a copy of the GNU General Public License
00025  *   along with LORENE; if not, write to the Free Software
00026  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00027  *
00028  */
00029 
00030 
00031 char tenseur_sym_C[] = "$Header: /cvsroot/Lorene/C++/Source/Tenseur/tenseur_sym.C,v 1.6 2003/03/03 19:39:58 f_limousin Exp $" ;
00032 
00033 /*
00034  * $Id: tenseur_sym.C,v 1.6 2003/03/03 19:39:58 f_limousin Exp $
00035  * $Log: tenseur_sym.C,v $
00036  * Revision 1.6  2003/03/03 19:39:58  f_limousin
00037  * Modification of an assert to have a check on a triad and not only on a pointer.
00038  *
00039  * Revision 1.5  2002/10/16 14:37:14  j_novak
00040  * Reorganization of #include instructions of standard C++, in order to
00041  * use experimental version 3 of gcc.
00042  *
00043  * Revision 1.4  2002/09/06 14:49:25  j_novak
00044  * Added method lie_derive for Tenseur and Tenseur_sym.
00045  * Corrected various errors for derive_cov and arithmetic.
00046  *
00047  * Revision 1.3  2002/08/14 13:46:15  j_novak
00048  * Derived quantities of a Tenseur can now depend on several Metrique's
00049  *
00050  * Revision 1.2  2002/08/07 16:14:11  j_novak
00051  * class Tenseur can now also handle tensor densities, this should be transparent to older codes
00052  *
00053  * Revision 1.1.1.1  2001/11/20 15:19:30  e_gourgoulhon
00054  * LORENE
00055  *
00056  * Revision 2.3  2001/10/10  13:55:23  eric
00057  * Modif Joachim: pow(3, *) --> pow(3., *)
00058  *
00059  * Revision 2.2  2000/02/09  19:33:38  eric
00060  * MODIF IMPORTANTE: la triade de decomposition est desormais passee en
00061  * argument des constructeurs.
00062  *
00063  * Revision 2.1  2000/01/11  11:14:41  eric
00064  * Gestion de la base vectorielle (triad).
00065  *
00066  * Revision 2.0  1999/12/02  17:18:37  phil
00067  * *** empty log message ***
00068  *
00069  *
00070  * $Header: /cvsroot/Lorene/C++/Source/Tenseur/tenseur_sym.C,v 1.6 2003/03/03 19:39:58 f_limousin Exp $
00071  *
00072  */
00073 
00074 // Headers C
00075 #include <stdlib.h>
00076 #include <assert.h>
00077 #include <math.h>
00078 
00079 // Headers Lorene
00080 #include "tenseur.h"
00081 #include "metrique.h"
00082 
00083             //--------------//
00084             // Constructors //
00085             //--------------//
00086 
00087 // Standard constructor 
00088 // --------------------
00089 Tenseur_sym::Tenseur_sym(const Map& map, int val, const Itbl& tipe, 
00090              const Base_vect& triad_i, const Metrique* met, 
00091              double weight) 
00092         : Tenseur(map, val, tipe, int(pow(3., val-2)) * 6, triad_i, 
00093               met, weight) {
00094 
00095     assert (val >= 2) ;
00096 }
00097 
00098 // Standard constructor when all the indices are of the same type
00099 // --------------------------------------------------------------
00100 Tenseur_sym::Tenseur_sym(const Map& map, int val, int tipe, 
00101              const Base_vect& triad_i, const Metrique* met,
00102              double weight)  
00103         : Tenseur(map, val, tipe, int(pow(3., val-2)) * 6, triad_i,
00104               met, weight) {
00105 
00106     assert (val >= 2) ;
00107 }
00108 
00109 // Copy constructor
00110 // ----------------
00111 Tenseur_sym::Tenseur_sym (const Tenseur_sym& source) : 
00112     Tenseur (*source.mp, source.valence, source.type_indice, 
00113          int(pow(3., source.valence-2)*6), *(source.triad), source.metric,
00114          source.poids) {
00115     
00116     assert (valence >= 2) ;   
00117     for (int i=0 ; i<n_comp ; i++) {
00118     int place_source = source.donne_place(donne_indices(i)) ;
00119     if (source.c[place_source] == 0x0)
00120         c[i] = 0x0 ;
00121     else
00122         c[i] = new Cmp (*source.c[place_source]) ;
00123     }
00124     etat = source.etat ;
00125     assert(source.met_depend != 0x0) ;
00126     assert(source.p_derive_cov != 0x0) ;
00127     assert(source.p_derive_con != 0x0) ;
00128     assert(source.p_carre_scal != 0x0) ;
00129     
00130     if (source.p_gradient != 0x0)
00131         p_gradient = new Tenseur_sym (*source.p_gradient) ;
00132     
00133     for (int i=0; i<N_MET_MAX; i++) {
00134       met_depend[i] = source.met_depend[i] ;
00135       if (met_depend[i] != 0x0) {
00136     
00137     set_dependance (*met_depend[i]) ;
00138     
00139     if (source.p_derive_cov[i] != 0x0)
00140       p_derive_cov[i] = new Tenseur (*source.p_derive_cov[i]) ;
00141     if (source.p_derive_con[i] != 0x0)
00142       p_derive_con[i] = new Tenseur (*source.p_derive_con[i]) ;
00143     if (source.p_carre_scal[i] != 0x0)
00144         p_carre_scal[i] = new Tenseur (*source.p_carre_scal[i]) ;
00145       }
00146     }
00147 }   
00148 
00149 
00150 // Constructor from a Tenseur
00151 // --------------------------
00152 Tenseur_sym::Tenseur_sym (const Tenseur& source) :
00153    Tenseur (*source.mp, source.valence, source.type_indice, 
00154         int(pow(3., source.valence-2)*6), *(source.triad), source.metric,
00155         source.poids) {
00156     
00157     assert (valence >= 2) ;
00158 
00159     for (int i=0 ; i<n_comp ; i++) {
00160     int place_source = source.donne_place(donne_indices(i)) ;
00161     if (source.c[place_source] == 0x0)
00162         c[i] = 0x0 ;
00163     else
00164             c[i] = new Cmp (*source.c[place_source]) ;
00165     }
00166     
00167     etat = source.etat ;
00168     
00169     assert(source.met_depend != 0x0) ;
00170     assert(source.p_derive_cov != 0x0) ;
00171     assert(source.p_derive_con != 0x0) ;
00172     assert(source.p_carre_scal != 0x0) ;
00173     
00174     if (source.p_gradient != 0x0)
00175         p_gradient = new Tenseur (*source.p_gradient) ;
00176     
00177 }   
00178 
00179     
00180 // Constructor from a file
00181 // -----------------------
00182 Tenseur_sym::Tenseur_sym(const Map& map, const Base_vect& triad_i, FILE* fd,
00183              const Metrique* met)
00184             : Tenseur(map, triad_i, fd, met) {
00185     
00186     assert (valence >= 2) ;
00187     assert (n_comp == int(pow(3., valence-2))*6) ;
00188 }
00189 
00190             //--------------//
00191             //  Destructor  //
00192             //--------------//
00193 
00194 Tenseur_sym::~Tenseur_sym() {}
00195 
00196 
00197 
00198 
00199     
00200 int Tenseur_sym::donne_place (const Itbl& idx) const {
00201     
00202     assert (idx.get_ndim() == 1) ;
00203     assert (idx.get_dim(0) == valence) ;
00204     for (int i=0 ; i<valence ; i++)
00205     assert ((idx(i) >= 0) && (idx(i) < 3)) ;
00206     
00207    
00208      // Gestion des deux derniers indices :
00209     int last = idx(valence-1) ;
00210     int lastm1 = idx(valence-2) ;
00211     if (last < lastm1) {
00212     int auxi = last ;
00213     last = lastm1 ;
00214     lastm1 = auxi ;
00215     }
00216     
00217     int place_fin ;
00218     switch (lastm1) {
00219             case 0 : {
00220                 place_fin = last ;
00221                 break ;
00222                 }
00223             case 1 : {
00224                 place_fin = 2+last ;
00225                 break ;
00226                 }
00227             case 2 : {
00228                 place_fin = 5 ;
00229                 break ;
00230                 }
00231             default : {
00232                 abort() ;
00233                 }
00234             }
00235     
00236     int res = 0 ;
00237     for (int i=0 ; i<valence-2 ; i++)
00238     res = 3*res+idx(i) ;
00239     
00240     res = 6*res + place_fin ;
00241     
00242     return res ;
00243 }
00244 
00245 Itbl Tenseur_sym::donne_indices (int place) const {
00246     Itbl res(valence) ;
00247     res.set_etat_qcq() ;
00248     assert ((place>=0) && (place<n_comp)) ;
00249     
00250     int reste = div(place, 6).rem ;
00251     place = int((place-reste)/6) ;
00252     
00253     for (int i=valence-3 ; i>=0 ; i--) {
00254     res.set(i) = div(place, 3).rem ;
00255     place = int((place-res(i))/3) ;
00256     }
00257     
00258     if (reste<3) {
00259     res.set(valence-2) = 0 ;
00260     res.set(valence-1) = reste ;
00261     }
00262     
00263     if ((reste>2) && (reste<5)) {
00264     res.set(valence-2) = 1 ;
00265     res.set(valence-1) = reste - 2 ;
00266     }
00267     
00268     if (reste == 5) {
00269     res.set(valence-2) = 2 ;
00270     res.set(valence-1) = 2 ;
00271     }
00272  
00273     return res ;
00274 }
00275     
00276 void Tenseur_sym::operator= (const Tenseur& t) {
00277     
00278     assert (valence == t.get_valence()) ;
00279     
00280     triad = t.triad ; 
00281     poids = t.poids ;
00282     metric = t.metric ;
00283     
00284     for (int i=0 ; i<valence ; i++)
00285     assert (type_indice(i) == t.type_indice(i)) ;
00286     
00287     switch (t.get_etat()) {
00288     case ETATNONDEF: {
00289         set_etat_nondef() ;
00290         break ;
00291     }
00292     
00293     case ETATZERO: {
00294         set_etat_zero() ;
00295         break ;
00296     }
00297     
00298     case ETATQCQ: {
00299         set_etat_qcq() ;
00300         for (int i=0 ; i<n_comp ; i++) {
00301         int place_t = t.donne_place(donne_indices(i)) ;
00302         if (t.c[place_t] == 0x0)
00303             c[i] = 0x0 ;
00304         else
00305             *c[i] = *t.c[place_t] ;
00306         }
00307         break ;
00308     }
00309     
00310     default: {
00311         cout << "Unknown state in Tenseur_sym::operator= " << endl ;
00312         abort() ;
00313         break ;
00314         }
00315     }
00316 }
00317 
00318 void Tenseur_sym::fait_gradient () const {
00319     
00320     assert (etat != ETATNONDEF) ;
00321     
00322     if (p_gradient != 0x0)
00323     return ;
00324     else {
00325  
00326     // Construction du resultat :
00327     Itbl tipe (valence+1) ;
00328     tipe.set_etat_qcq() ;
00329     tipe.set(0) = COV ;
00330     for (int i=0 ; i<valence ; i++)
00331         tipe.set(i+1) = type_indice(i) ;
00332 
00333     // Vectorial basis
00334     // ---------------
00335         assert(*triad == mp->get_bvect_cart()) ;
00336 
00337     p_gradient = new Tenseur_sym(*mp, valence+1, tipe, 
00338                      mp->get_bvect_cart(), metric, poids) ;
00339     
00340 
00341     if (etat == ETATZERO)
00342         p_gradient->set_etat_zero() ;
00343     else {
00344         p_gradient->set_etat_qcq() ;
00345         // Boucle sur les indices :
00346     
00347         Itbl indices_source(valence) ;
00348         indices_source.set_etat_qcq() ;
00349     
00350         for (int j=0 ; j<p_gradient->n_comp ; j++) {    
00351         
00352         Itbl indices_res(p_gradient->donne_indices(j)) ;
00353 
00354         for (int m=0 ; m<valence ; m++)
00355             indices_source.set(m) = indices_res(m+1) ;
00356          
00357         p_gradient->set(indices_res) =  
00358             (*this)(indices_source).deriv(indices_res(0)) ;
00359         }
00360       }
00361     }
00362 }
00363 
00364 
00365 void Tenseur_sym::fait_derive_cov (const Metrique& metre, int ind) const {
00366     
00367   assert (etat != ETATNONDEF) ;
00368   assert (valence != 0) ;
00369     
00370   if (p_derive_cov[ind] != 0x0)
00371     return ;
00372   else {
00373     p_derive_cov[ind] = new Tenseur_sym (gradient()) ;
00374     
00375     if ((valence != 0) && (etat != ETATZERO)) {
00376 
00377       assert( *(metre.gamma().get_triad()) == *triad ) ; 
00378 
00379       Tenseur* auxi ;
00380       for (int i=0 ; i<valence ; i++) {
00381     
00382     if (type_indice(i) == COV) {
00383       auxi = new Tenseur(contract(metre.gamma(), 0,(*this), i)) ;
00384 
00385       Itbl indices_gamma(p_derive_cov[ind]->valence) ;
00386       indices_gamma.set_etat_qcq() ;
00387       //On range comme il faut :
00388       for (int j=0 ; j<p_derive_cov[ind]->n_comp ; j++) {
00389             
00390         Itbl indices (p_derive_cov[ind]->donne_indices(j)) ;
00391         indices_gamma.set(0) = indices(0) ;
00392         indices_gamma.set(1) = indices(i+1) ;
00393         for (int idx=2 ; idx<p_derive_cov[ind]->valence ; idx++)
00394           if (idx<=i+1)
00395         indices_gamma.set(idx) = indices(idx-1) ;
00396           else
00397         indices_gamma.set(idx) = indices(idx) ;
00398             
00399         p_derive_cov[ind]->set(indices) -= (*auxi)(indices_gamma) ;
00400       }
00401     }   
00402     else {
00403       auxi = new Tenseur(contract(metre.gamma(), 1, (*this), i)) ;
00404 
00405       Itbl indices_gamma(p_derive_cov[ind]->valence) ;
00406       indices_gamma.set_etat_qcq() ;
00407         
00408       //On range comme il faut :
00409       for (int j=0 ; j<p_derive_cov[ind]->n_comp ; j++) {
00410             
00411         Itbl indices (p_derive_cov[ind]->donne_indices(j)) ;
00412         indices_gamma.set(0) = indices(i+1) ;
00413         indices_gamma.set(1) = indices(0) ;
00414         for (int idx=2 ; idx<p_derive_cov[ind]->valence ; idx++)
00415           if (idx<=i+1)
00416         indices_gamma.set(idx) = indices(idx-1) ;
00417           else
00418         indices_gamma.set(idx) = indices(idx) ;
00419         p_derive_cov[ind]->set(indices) += (*auxi)(indices_gamma) ;
00420       }
00421     }
00422     delete auxi ;
00423       }
00424     }
00425     if ((poids != 0.)&&(etat != ETATZERO)) 
00426       *p_derive_cov[ind] = *p_derive_cov[ind] - 
00427     poids*contract(metre.gamma(), 0, 2) * (*this) ;
00428     
00429   }
00430 }
00431 
00432 
00433 
00434 void Tenseur_sym::fait_derive_con (const Metrique& metre, int ind) const {
00435     
00436     if (p_derive_con[ind] != 0x0)
00437     return ;
00438     else {
00439     // On calcul la derivee covariante :
00440     if (valence != 0)
00441         p_derive_con[ind] = new Tenseur_sym
00442         (contract(metre.con(), 1, derive_cov(metre), 0)) ;
00443     
00444     else
00445     p_derive_con[ind] = new Tenseur_sym
00446         (contract(metre.con(), 1, gradient(), 0)) ;
00447     }
00448 }

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