connection_fcart.C

00001 /*
00002  *  Methods of class Connection_fcart.
00003  *
00004  *  (see file connection.h for documentation)
00005  *
00006  */
00007 
00008 /*
00009  *   Copyright (c) 2003-2004 Eric Gourgoulhon & Jerome Novak
00010  *
00011  *   This file is part of LORENE.
00012  *
00013  *   LORENE is free software; you can redistribute it and/or modify
00014  *   it under the terms of the GNU General Public License version 2
00015  *   as published by the Free Software Foundation.
00016  *
00017  *   LORENE is distributed in the hope that it will be useful,
00018  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00019  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020  *   GNU General Public License for more details.
00021  *
00022  *   You should have received a copy of the GNU General Public License
00023  *   along with LORENE; if not, write to the Free Software
00024  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00025  *
00026  */
00027 
00028 char connection_fcart_C[] = "$Header: /cvsroot/Lorene/C++/Source/Connection/connection_fcart.C,v 1.12 2004/01/28 13:25:40 j_novak Exp $" ;
00029 
00030 /*
00031  * $Id: connection_fcart.C,v 1.12 2004/01/28 13:25:40 j_novak Exp $
00032  * $Log: connection_fcart.C,v $
00033  * Revision 1.12  2004/01/28 13:25:40  j_novak
00034  * The ced_mult_r arguments have been suppressed from the Scalar::*dsd* methods.
00035  * In the div/mult _r_dzpuis, there is no more default value.
00036  *
00037  * Revision 1.11  2004/01/04 21:00:50  e_gourgoulhon
00038  * Better handling of tensor symmetries in methods p_derive_cov() and
00039  * p_divergence() (thanks to the new class Tensor_sym).
00040  *
00041  * Revision 1.10  2004/01/01 11:24:04  e_gourgoulhon
00042  * Full reorganization of method p_derive_cov: the main loop is now
00043  * on the indices of the *output* tensor (to take into account
00044  * symmetries in the input and output tensors).
00045  *
00046  * Revision 1.9  2003/12/27 14:59:52  e_gourgoulhon
00047  * -- Method derive_cov() suppressed.
00048  * -- Change of the position of the derivation index from the first one
00049  *    to the last one in methods p_derive_cov() and p_divergence().
00050  *
00051  * Revision 1.8  2003/10/17 13:46:15  j_novak
00052  * The argument is now between 1 and 3 (instead of 0->2)
00053  *
00054  * Revision 1.7  2003/10/16 21:37:08  e_gourgoulhon
00055  * Corrected deriv index in divergence.
00056  *
00057  * Revision 1.6  2003/10/16 15:26:03  e_gourgoulhon
00058  * Suppressed unsued variable
00059  *
00060  * Revision 1.5  2003/10/16 14:21:36  j_novak
00061  * The calculation of the divergence of a Tensor is now possible.
00062  *
00063  * Revision 1.4  2003/10/11 16:45:43  e_gourgoulhon
00064  * Suppressed the call to Itbl::set_etat_qcq() after
00065  * the construction of the Itbl's.
00066  *
00067  * Revision 1.3  2003/10/11 14:39:50  e_gourgoulhon
00068  * Suppressed declaration of unusued arguments in some methods.
00069  *
00070  * Revision 1.2  2003/10/06 13:58:46  j_novak
00071  * The memory management has been improved.
00072  * Implementation of the covariant derivative with respect to the exact Tensor
00073  * type.
00074  *
00075  * Revision 1.1  2003/10/03 14:11:48  e_gourgoulhon
00076  * Methods of class Connection_fcart.
00077  *
00078  * 
00079  *
00080  * $Header: /cvsroot/Lorene/C++/Source/Connection/connection_fcart.C,v 1.12 2004/01/28 13:25:40 j_novak Exp $
00081  *
00082  */
00083 
00084 // C++ headers
00085 #include "headcpp.h"
00086 
00087 // C headers
00088 #include <stdlib.h>
00089 
00090 // Lorene headers
00091 #include "connection.h"
00092 
00093 
00094         //------------------------------//
00095         //          Constructors        //
00096         //------------------------------//
00097 
00098 
00099 
00100 // Contructor from a Cartesian flat-metric-orthonormal basis
00101 
00102 Connection_fcart::Connection_fcart(const Map& mpi, const Base_vect_cart& bi) 
00103   : Connection_flat(mpi, bi) {
00104 
00105 }       
00106 
00107 // Copy constructor
00108 Connection_fcart::Connection_fcart(const Connection_fcart& ci) 
00109   : Connection_flat(ci) {
00110 
00111 }       
00112 
00113     
00114         //----------------------------//
00115         //          Destructor        //
00116         //----------------------------//
00117 
00118 
00119 Connection_fcart::~Connection_fcart(){
00120     
00121 }
00122 
00123 
00124         //--------------------------------//
00125         //      Mutators / assignment     //
00126         //--------------------------------//
00127 
00128 
00129 void Connection_fcart::operator=(const Connection_fcart& ) {
00130     
00131   cout << "Connection_fcart::operator= : not implemented yet !" << endl ; 
00132   abort() ; 
00133 
00134 }   
00135 
00136 
00137 
00138         //-----------------------------//
00139         //    Computational methods    //
00140         //-----------------------------//
00141 
00142 // Covariant derivative, returning a pointer.
00143 //-------------------------------------------
00144 
00145 Tensor* Connection_fcart::p_derive_cov(const Tensor& uu) const {
00146 
00147     // Notations: suffix 0 in name <=> input tensor
00148     //            suffix 1 in name <=> output tensor
00149 
00150     int valence0 = uu.get_valence() ; 
00151     int valence1 = valence0 + 1 ; 
00152     int valence1m1 = valence1 - 1 ; // same as valence0, but introduced for 
00153                                     // the sake of clarity
00154     
00155     // Protections
00156     // -----------
00157     if (valence0 >= 1) {
00158         assert(uu.get_triad() == triad) ; 
00159     }
00160 
00161     // Creation of the result (pointer)
00162     // --------------------------------
00163     Tensor* resu ;
00164 
00165     // If uu is a Scalar, the result is a vector
00166     if (valence0 == 0) 
00167         resu = new Vector(*mp, COV, triad) ;
00168     else {
00169 
00170         // Type of indices of the result :
00171         Itbl tipe(valence1) ; 
00172         const Itbl& tipeuu = uu.get_index_type() ;  
00173         for (int id = 0; id<valence0; id++) {
00174             tipe.set(id) = tipeuu(id) ;   // First indices = same as uu
00175         }
00176         tipe.set(valence1m1) = COV ;  // last index is the derivation index
00177 
00178         // if uu is a Tensor_sym, the result is also a Tensor_sym:
00179         const Tensor* puu = &uu ; 
00180         const Tensor_sym* puus = dynamic_cast<const Tensor_sym*>(puu) ; 
00181         if ( puus != 0x0 ) {    // the input tensor is symmetric
00182             resu = new Tensor_sym(*mp, valence1, tipe, *triad,
00183                                   puus->sym_index1(), puus->sym_index2()) ;
00184         }
00185         else {  
00186             resu = new Tensor(*mp, valence1, tipe, *triad) ;  // no symmetry  
00187         }
00188 
00189     }
00190 
00191     int ncomp1 = resu->get_n_comp() ; 
00192     
00193     Itbl ind1(valence1) ; // working Itbl to store the indices of resu
00194     Itbl ind0(valence0) ; // working Itbl to store the indices of uu
00195     
00196     // Loop on all the components of the output tensor
00197     // -----------------------------------------------
00198     for (int ic=0; ic<ncomp1; ic++) {
00199     
00200         // indices corresponding to the component no. ic in the output tensor
00201         ind1 = resu->indices(ic) ; 
00202     
00203         // Component no. ic:
00204         Scalar& cresu = resu->set(ind1) ; 
00205         
00206         // Indices of the input tensor
00207         for (int id = 0; id < valence0; id++) {
00208             ind0.set(id) = ind1(id) ; 
00209         }
00210  
00211         // Value of last index (derivation index)
00212         int k = ind1(valence1m1) ; 
00213         
00214         // Partial derivation with respect to x^k:
00215 
00216         cresu = (uu(ind0)).deriv(k) ;   
00217 
00218     }
00219 
00220     // C'est fini !
00221     // -----------
00222     return resu ; 
00223 
00224 }
00225 
00226 
00227 
00228 // Divergence, returning a pointer.
00229 //---------------------------------
00230 
00231 Tensor* Connection_fcart::p_divergence(const Tensor& uu) const {
00232 
00233     // Notations: suffix 0 in name <=> input tensor
00234     //            suffix 1 in name <=> output tensor
00235 
00236   int valence0 = uu.get_valence() ; 
00237   int valence1 = valence0 - 1 ; 
00238     
00239   // Protections
00240   // -----------
00241   assert (valence0 >= 1) ;
00242   assert (uu.get_triad() == triad) ; 
00243   
00244   // Last index must be contravariant:
00245   assert (uu.get_index_type(valence0-1) == CON) ;
00246 
00247 
00248   // Creation of the pointer on the result tensor
00249   // --------------------------------------------
00250     Tensor* resu ;
00251 
00252     if (valence0 == 1)      // if u is a Vector, the result is a Scalar
00253         resu = new Scalar(*mp) ;
00254     else {
00255     
00256         // Type of indices of the result :
00257         Itbl tipe(valence1) ; 
00258         const Itbl& tipeuu = uu.get_index_type() ;  
00259         for (int id = 0; id<valence1; id++) {
00260             tipe.set(id) = tipeuu(id) ;     // type of remaining indices = 
00261         }                                   //  same as uu indices
00262 
00263         if (valence0 == 2) {  // if u is a rank 2 tensor, the result is a Vector
00264             resu = new Vector(*mp, tipe(0), *triad) ;
00265         }
00266         else {
00267             // if uu is a Tensor_sym, the result might be also a Tensor_sym:
00268             const Tensor* puu = &uu ; 
00269             const Tensor_sym* puus = dynamic_cast<const Tensor_sym*>(puu) ; 
00270             if ( puus != 0x0 ) {    // the input tensor is symmetric
00271 
00272                 if (puus->sym_index2() != valence0 - 1) {
00273                  
00274                     // the symmetry is preserved: 
00275 
00276                     if (valence1 == 2) {
00277                         resu = new Sym_tensor(*mp, tipe, *triad) ;
00278                     }
00279                     else {
00280                         resu = new Tensor_sym(*mp, valence1, tipe, *triad,
00281                                   puus->sym_index1(), puus->sym_index2()) ;
00282                     }
00283                 }
00284                 else { // the symmetry is lost: 
00285                 
00286                 resu = new Tensor(*mp, valence1, tipe, *triad) ;
00287                 }
00288             }
00289             else { // no symmetry in the input tensor:
00290             resu = new Tensor(*mp, valence1, tipe, *triad) ;
00291             }
00292         }
00293     }
00294 
00295 
00296   int ncomp1 = resu->get_n_comp() ;
00297     
00298   Itbl ind0(valence0) ; // working Itbl to store the indices of uu
00299     
00300   Itbl ind1(valence1) ; // working Itbl to store the indices of resu
00301     
00302   // Loop on all the components of the output tensor
00303   for (int ic=0; ic<ncomp1; ic++) {
00304     
00305     ind1 = resu->indices(ic) ; 
00306     Scalar& cresu = resu->set(ind1) ;
00307     cresu.set_etat_zero() ;
00308 
00309     for (int k=1; k<=3; k++) {
00310       
00311       // indices (ind1,k) in the input tensor
00312       for (int id = 0; id < valence1; id++) {
00313     ind0.set(id) = ind1(id) ; 
00314       }
00315       ind0.set(valence0-1) = k ; 
00316 
00317       cresu += uu(ind0).deriv(k) ; //Addition of dT^i/dx^i
00318     }
00319 
00320   }
00321 
00322   // C'est fini !
00323   // -----------
00324   return resu ; 
00325 
00326 }
00327 

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