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
1.4.6