tensor_sym.C

00001 /*
00002  *  Methods of class Tensor_sym
00003  *
00004  *   (see file tensor.h for documentation)
00005  *
00006  */
00007 
00008 /*
00009  *   Copyright (c) 2004 Eric Gourgoulhon & Jerome Novak
00010  *
00011  *   Copyright (c) 1999-2001 Philippe Grandclement (for preceding class Tenseur)
00012  *
00013  *   This file is part of LORENE.
00014  *
00015  *   LORENE is free software; you can redistribute it and/or modify
00016  *   it under the terms of the GNU General Public License as published by
00017  *   the Free Software Foundation; either version 2 of the License, or
00018  *   (at your option) any later version.
00019  *
00020  *   LORENE is distributed in the hope that it will be useful,
00021  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00022  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023  *   GNU General Public License for more details.
00024  *
00025  *   You should have received a copy of the GNU General Public License
00026  *   along with LORENE; if not, write to the Free Software
00027  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00028  *
00029  */
00030 
00031 
00032 char tensor_sym_C[] = "$Header: /cvsroot/Lorene/C++/Source/Tensor/tensor_sym.C,v 1.1 2004/01/04 20:51:45 e_gourgoulhon Exp $" ;
00033 
00034 /*
00035  * $Id: tensor_sym.C,v 1.1 2004/01/04 20:51:45 e_gourgoulhon Exp $
00036  * $Log: tensor_sym.C,v $
00037  * Revision 1.1  2004/01/04 20:51:45  e_gourgoulhon
00038  * New class to deal with general tensors which are symmetric with
00039  * respect to two of their indices.
00040  *
00041  *
00042  * $Header: /cvsroot/Lorene/C++/Source/Tensor/tensor_sym.C,v 1.1 2004/01/04 20:51:45 e_gourgoulhon Exp $
00043  *
00044  */
00045 
00046 // Headers C
00047 #include <stdlib.h>
00048 #include <assert.h>
00049 #include <math.h>
00050 
00051 // Headers Lorene
00052 #include "tensor.h"
00053 #include "utilitaires.h"
00054 
00055 
00056             //--------------//
00057             // Constructors //
00058             //--------------//
00059 
00060 // Standard constructor 
00061 // --------------------
00062 Tensor_sym::Tensor_sym(const Map& map, int val, const Itbl& tipe, 
00063          const Base_vect& triad_i, int index_sym1, int index_sym2) 
00064             : Tensor(map, val, tipe, 6*int(pow(3.,val-2)), triad_i),
00065               id_sym1(index_sym1),    
00066               id_sym2(index_sym2) {    
00067         
00068     // Des verifs :
00069     assert( valence >= 2 ) ;
00070     assert( (id_sym1 >=0) && (id_sym1 < valence) ) ;  
00071     assert( (id_sym2 >=0) && (id_sym2 < valence) ) ;  
00072     assert( id_sym1 != id_sym2 ) ; 
00073 
00074     // The symmetry indices must be of same type: 
00075     assert( tipe(id_sym1) == tipe(id_sym2) ) ; 
00076     
00077     // Possible re-ordering of the symmetry indices
00078     if (id_sym1 > id_sym2) {
00079         int tmp = id_sym1 ; 
00080         id_sym1 = id_sym2 ; 
00081         id_sym2 = tmp ; 
00082     }
00083         
00084 }
00085 
00086 
00087 
00088 // Standard constructor when all the indices are of the same type
00089 // --------------------------------------------------------------
00090 Tensor_sym::Tensor_sym(const Map& map, int val, int tipe, 
00091          const Base_vect& triad_i, int index_sym1, int index_sym2) 
00092             : Tensor(map, val, tipe, 6*int(pow(3.,val-2)), triad_i),
00093               id_sym1(index_sym1),    
00094               id_sym2(index_sym2) {    
00095         
00096     // Des verifs :
00097     assert( valence >= 2 ) ;
00098     assert( (id_sym1 >=0) && (id_sym1 < valence) ) ;  
00099     assert( (id_sym2 >=0) && (id_sym2 < valence) ) ;  
00100     assert( id_sym1 != id_sym2 ) ; 
00101 
00102     // Possible re-ordering of the symmetry indices
00103     if (id_sym1 > id_sym2) {
00104         int tmp = id_sym1 ; 
00105         id_sym1 = id_sym2 ; 
00106         id_sym2 = tmp ; 
00107     }
00108         
00109 }
00110 
00111 // Constructor for a valence 3 symmetric tensor
00112 // --------------------------------------------
00113 Tensor_sym::Tensor_sym(const Map& map, int tipe0, int tipe1, int tipe2, 
00114                    const Base_vect& triad_i,
00115                    int index_sym1, int index_sym2) 
00116             : Tensor(map, 3, tipe0, 18, triad_i),
00117               id_sym1(index_sym1),    
00118               id_sym2(index_sym2) {    
00119     
00120     assert( (tipe0==COV) || (tipe0==CON) ) ;        
00121     assert( (tipe1==COV) || (tipe1==CON) ) ;        
00122     assert( (tipe2==COV) || (tipe2==CON) ) ;        
00123 
00124     type_indice.set(1) = tipe1 ; 
00125     type_indice.set(2) = tipe2 ; 
00126 
00127     assert( (id_sym1 >=0) && (id_sym1 < 3) ) ;  
00128     assert( (id_sym2 >=0) && (id_sym2 < 3) ) ;  
00129     assert( id_sym1 != id_sym2 ) ; 
00130     assert( type_indice(id_sym1) == type_indice(id_sym2) ) ; 
00131 
00132     // Possible re-ordering of the symmetry indices
00133     if (id_sym1 > id_sym2) {
00134         int tmp = id_sym1 ; 
00135         id_sym1 = id_sym2 ; 
00136         id_sym2 = tmp ; 
00137     }
00138         
00139 }
00140 
00141 
00142 
00143 // Copy constructor
00144 // ----------------
00145 Tensor_sym::Tensor_sym(const Tensor_sym& source) 
00146             : Tensor(*source.mp, source.valence, source.type_indice, 
00147                      6*int(pow(3.,source.valence-2)) , *(source.triad)),
00148               id_sym1(source.id_sym1),    
00149               id_sym2(source.id_sym2) {    
00150                      
00151     for (int i=0 ; i<n_comp ; i++) {
00152 
00153         int posi = source.position(indices(i)) ;  // in case source belongs to
00154                                                   // a derived class of 
00155                                                   // Tensor_sym with a different
00156                                                   // storage of components 
00157     *(cmp[i]) = *(source.cmp[posi]) ;
00158     }
00159 }   
00160 
00161 
00162 
00163     
00164 
00165 // Constructor from a file
00166 // -----------------------
00167 Tensor_sym::Tensor_sym(const Map& map, const Base_vect& triad_i, FILE* fd)
00168             : Tensor(map, triad_i, fd) {
00169     
00170     fread_be(&id_sym1, sizeof(int), 1, fd) ;
00171     fread_be(&id_sym2, sizeof(int), 1, fd) ;
00172     
00173     assert( type_indice(id_sym1) == type_indice(id_sym2) ) ; 
00174     
00175 }
00176 
00177 
00178             //--------------//
00179             //  Destructor  //
00180             //--------------//
00181 
00182 Tensor_sym::~Tensor_sym() {
00183 
00184 }
00185 
00186             //--------------//
00187             //  Assignment  //
00188             //--------------//
00189 
00190 
00191 void Tensor_sym::operator=(const Tensor_sym& tt) {
00192     
00193     assert (valence == tt.valence) ;
00194 
00195     triad = tt.triad ; 
00196     id_sym1 = tt.id_sym1 ; 
00197     id_sym2 = tt.id_sym2 ; 
00198 
00199     for (int id=0 ; id<valence ; id++)
00200       assert(tt.type_indice(id) == type_indice(id)) ;
00201     
00202     for (int ic=0 ; ic<n_comp ; ic++) {
00203         int posi = tt.position(indices(ic)) ;
00204         *cmp[ic] = *(tt.cmp[posi]) ;
00205     }
00206 
00207     del_deriv() ;
00208 
00209 }
00210 
00211 void Tensor_sym::operator=(const Tensor& tt) {
00212     
00213     assert (valence == tt.get_valence()) ;
00214 
00215     triad = tt.get_triad() ; 
00216 
00217     for (int id=0 ; id<valence ; id++)
00218       assert(tt.type_indice(id) == type_indice(id)) ;
00219 
00220     // The symmetry indices must be of same type: 
00221     assert( tt.type_indice(id_sym1) == tt.type_indice(id_sym2) ) ; 
00222 
00223     
00224     for (int ic=0 ; ic<n_comp ; ic++) {
00225         int posi = tt.position(indices(ic)) ;
00226         *cmp[ic] = *(tt.cmp[posi]) ;
00227     }
00228 
00229     del_deriv() ;
00230 
00231 }
00232 
00233 
00234             //--------------//
00235             //   Accessor   //
00236             //--------------//
00237 
00238 int Tensor_sym::position(const Itbl& idx) const {
00239     
00240     // Protections:
00241     assert (idx.get_ndim() == 1) ;
00242     assert (idx.get_dim(0) == valence) ;
00243     for (int i=0 ; i<valence ; i++) {
00244     assert( (idx(i)>=1) && (idx(i)<=3) ) ;
00245     }
00246     
00247     // The two symmetric indices are moved to the end --> new index array idx0
00248     Itbl idx0(valence) ; 
00249     if (valence > 2) {
00250         for (int id=0 ; id<id_sym1; id++) {
00251             idx0.set(id) = idx(id) ; 
00252         }
00253         for (int id=id_sym1; id<id_sym2-1; id++) {
00254             idx0.set(id) = idx(id+1) ;
00255         }
00256         for (int id=id_sym2-1; id<valence-2; id++) {
00257             idx0.set(id) = idx(id+2) ; 
00258         }
00259         idx0.set(valence-2) = idx(id_sym1) ;  //## not used
00260         idx0.set(valence-1) = idx(id_sym2) ;  //## in what follows
00261     }
00262     
00263     // Values of the symmetric indices:
00264     int is1 = idx(id_sym1) ; 
00265     int is2 = idx(id_sym2) ; 
00266     
00267     // Reordering to ensure is1 <= is2 :
00268     if (is2 < is1) {
00269         int aux = is1 ; 
00270         is1 = is2 ; 
00271         is2 = aux ; 
00272     }
00273 
00274     // Position in the cmp array :
00275     int pos = 0 ; 
00276     for (int id=0 ; id<valence-2 ; id++) {
00277         pos = 3 * pos + idx0(id) - 1 ;  // all the values of each non symmetric
00278                                         // index occupy 3 "boxes"
00279     }
00280     
00281     pos = 6 * pos  ;   // all the values of the two symmetric
00282                        // indices occupy 6 "boxes"
00283     switch (is1) {
00284         case 1 : {
00285             pos += is2 - 1 ;     // (1,1), (1,2) and (1,3) stored respectively
00286             break ;              // in relative position 0, 1 and 2
00287         }        
00288         case 2 : {
00289             pos += is2 + 1 ;     // (2,2) and (2,3) stored respectively
00290             break ;              // in relative position 3 and  4
00291         }
00292         case 3 : {
00293             pos += 5 ;           // (3,3) stored in relative position 5
00294             break ; 
00295         }
00296     }
00297     
00298     return pos ;
00299 }
00300 
00301 
00302 
00303 Itbl Tensor_sym::indices(int place) const {
00304 
00305     assert( (place>=0) && (place<n_comp) ) ;
00306     
00307     // Index set with the two symmetric indices at the end:
00308 
00309     Itbl idx0(valence) ; 
00310     
00311     int reste = div(place, 6).rem ;
00312     place = int((place-reste)/6) ;
00313     
00314     if (reste<3) {
00315         idx0.set(valence-2) = 1 ;
00316     idx0.set(valence-1) = reste + 1 ;
00317     }
00318     
00319     if ( (reste>2) && (reste<5) ) {
00320     idx0.set(valence-2) = 2 ;
00321     idx0.set(valence-1) = reste - 1 ;
00322     }
00323     
00324     if (reste == 5) {
00325         idx0.set(valence-2) = 3 ;
00326         idx0.set(valence-1) = 3 ;
00327     }
00328     
00329     // The output is ready in the case of a valence 2 tensor: 
00330     if (valence == 2) return idx0 ; 
00331     
00332     for (int id=valence-3 ; id>=0 ; id--) {
00333     int ind = div(place, 3).rem ;
00334     place = int((place-ind)/3) ;
00335     idx0.set(id) = ind + 1 ; 
00336     }
00337     
00338     // Reorganization of the index set to put the two symmetric indices at
00339     // their correct positions:
00340     
00341     Itbl idx(valence) ; 
00342     
00343     for (int id=0 ; id<id_sym1; id++) {
00344         idx.set(id) = idx0(id) ; 
00345     }
00346     idx.set(id_sym1) = idx0(valence-2) ; 
00347     
00348     for (int id=id_sym1+1; id<id_sym2; id++) {
00349         idx.set(id) = idx0(id-1) ;
00350     }
00351     idx.set(id_sym2) = idx0(valence-1) ; 
00352     
00353     for (int id=id_sym2+1; id<valence; id++) {
00354         idx.set(id) = idx0(id-2) ; 
00355     }
00356 
00357     return idx ;
00358 }
00359     
00360 
00361             //--------------//
00362             //    Outputs   //
00363             //--------------//
00364 
00365 void Tensor_sym::sauve(FILE* fd) const {
00366 
00367     Tensor::sauve(fd) ; 
00368     
00369     fwrite_be(&id_sym1, sizeof(int), 1, fd) ;   
00370     fwrite_be(&id_sym2, sizeof(int), 1, fd) ;   
00371 
00372 }
00373 
00374 
00375 
00376 
00377 
00378 
00379 
00380 
00381 

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