00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 char tensor_calculus_C[] = "$Header: /cvsroot/Lorene/C++/Source/Tensor/tensor_calculus.C,v 1.8 2004/02/26 22:49:45 e_gourgoulhon Exp $" ;
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 #include "headcpp.h"
00071
00072
00073 #include <stdlib.h>
00074 #include <assert.h>
00075 #include <math.h>
00076
00077
00078 #include "tensor.h"
00079 #include "metric.h"
00080
00081
00082
00083
00084
00085
00086
00087 Tensor Tensor::trace(int ind_1, int ind_2) const {
00088
00089
00090 assert( (ind_1 >= 0) && (ind_1 < valence) ) ;
00091 assert( (ind_2 >= 0) && (ind_2 < valence) ) ;
00092 assert( ind_1 != ind_2 ) ;
00093 assert( type_indice(ind_1) != type_indice(ind_2) ) ;
00094
00095
00096 if (ind_1 > ind_2) {
00097 int auxi = ind_2 ;
00098 ind_2 = ind_1 ;
00099 ind_1 = auxi ;
00100 }
00101
00102
00103 int val_res = valence - 2 ;
00104
00105 Itbl tipe(val_res) ;
00106
00107 for (int i=0 ; i<ind_1 ; i++)
00108 tipe.set(i) = type_indice(i) ;
00109 for (int i=ind_1 ; i<ind_2-1 ; i++)
00110 tipe.set(i) = type_indice(i+1) ;
00111 for (int i = ind_2-1 ; i<val_res ; i++)
00112 tipe.set(i) = type_indice(i+2) ;
00113
00114 Tensor res(*mp, val_res, tipe, triad) ;
00115
00116
00117
00118 Itbl jeux_indice_source(valence) ;
00119
00120 for (int i=0 ; i<res.get_n_comp() ; i++) {
00121
00122 Itbl jeux_indice_res(res.indices(i)) ;
00123
00124 for (int j=0 ; j<ind_1 ; j++)
00125 jeux_indice_source.set(j) = jeux_indice_res(j) ;
00126 for (int j=ind_1+1 ; j<ind_2 ; j++)
00127 jeux_indice_source.set(j) = jeux_indice_res(j-1) ;
00128 for (int j=ind_2+1 ; j<valence ; j++)
00129 jeux_indice_source.set(j) = jeux_indice_res(j-2) ;
00130
00131 Scalar& work = res.set(jeux_indice_res) ;
00132 work.set_etat_zero() ;
00133
00134 for (int j=1 ; j<=3 ; j++) {
00135 jeux_indice_source.set(ind_1) = j ;
00136 jeux_indice_source.set(ind_2) = j ;
00137 work += (*cmp[position(jeux_indice_source)]) ;
00138 }
00139
00140 }
00141
00142 return res ;
00143 }
00144
00145
00146 Tensor Tensor::trace(int ind1, int ind2, const Metric& gam) const {
00147
00148
00149 assert( (ind1 >= 0) && (ind1 < valence) ) ;
00150 assert( (ind2 >= 0) && (ind2 < valence) ) ;
00151 assert( ind1 != ind2 ) ;
00152
00153 if ( type_indice(ind1) != type_indice(ind2) ) {
00154 cout << "Tensor::trace(int, int, const Metric&) : Warning : \n"
00155 << " the two indices for the trace have opposite types,\n"
00156 << " hence the metric is useless !\n" ;
00157
00158 return trace(ind1, ind2) ;
00159 }
00160 else {
00161 if ( type_indice(ind1) == COV ) {
00162 return contract(gam.con(), 0, 1, *this, ind1, ind2) ;
00163 }
00164 else{
00165 return contract(gam.cov(), 0, 1, *this, ind1, ind2) ;
00166 }
00167 }
00168
00169 }
00170
00171
00172
00173 Scalar Tensor::trace() const {
00174
00175
00176 assert( valence == 2 ) ;
00177 assert( type_indice(0) != type_indice(1) ) ;
00178
00179 Scalar res(*mp) ;
00180 res.set_etat_zero() ;
00181
00182 for (int i=1; i<=3; i++) {
00183 res += operator()(i,i) ;
00184 }
00185
00186 return res ;
00187 }
00188
00189
00190 Scalar Tensor::trace(const Metric& gam) const {
00191
00192 assert( valence == 2 ) ;
00193
00194 if ( type_indice(0) != type_indice(1) ) {
00195 cout << "Tensor::trace(const Metric&) : Warning : \n"
00196 << " the two indices have opposite types,\n"
00197 << " hence the metric is useless to get the trace !\n" ;
00198
00199 return trace() ;
00200 }
00201 else {
00202 if ( type_indice(0) == COV ) {
00203 return contract(gam.con(), 0, 1, *this, 0, 1) ;
00204 }
00205 else{
00206 return contract(gam.cov(), 0, 1, *this, 0, 1) ;
00207 }
00208 }
00209
00210 }
00211
00212
00213
00214
00215
00216
00217
00218 Tensor Tensor::up(int place, const Metric& met) const {
00219
00220 assert (valence != 0) ;
00221 assert ((place >=0) && (place < valence)) ;
00222
00223
00224 Tensor auxi = ::contract(met.con(), 1, *this, place) ;
00225
00226
00227
00228 Itbl tipe(valence) ;
00229
00230 for (int i=0 ; i<valence ; i++)
00231 tipe.set(i) = type_indice(i) ;
00232 tipe.set(place) = CON ;
00233
00234 Tensor res(*mp, valence, tipe, triad) ;
00235
00236 Itbl place_auxi(valence) ;
00237
00238 for (int i=0 ; i<res.n_comp ; i++) {
00239
00240 Itbl place_res(res.indices(i)) ;
00241
00242 place_auxi.set(0) = place_res(place) ;
00243 for (int j=1 ; j<place+1 ; j++)
00244 place_auxi.set(j) = place_res(j-1) ;
00245 place_res.set(place) = place_auxi(0) ;
00246
00247 for (int j=place+1 ; j<valence ; j++)
00248 place_auxi.set(j) = place_res(j);
00249
00250 res.set(place_res) = auxi(place_auxi) ;
00251 }
00252
00253 return res ;
00254
00255 }
00256
00257
00258 Tensor Tensor::down(int place, const Metric& met) const {
00259
00260 assert (valence != 0) ;
00261 assert ((place >=0) && (place < valence)) ;
00262
00263 Tensor auxi = ::contract(met.cov(), 1, *this, place) ;
00264
00265
00266
00267 Itbl tipe(valence) ;
00268
00269 for (int i=0 ; i<valence ; i++)
00270 tipe.set(i) = type_indice(i) ;
00271 tipe.set(place) = COV ;
00272
00273 Tensor res(*mp, valence, tipe, triad) ;
00274
00275 Itbl place_auxi(valence) ;
00276
00277 for (int i=0 ; i<res.n_comp ; i++) {
00278
00279 Itbl place_res(res.indices(i)) ;
00280
00281 place_auxi.set(0) = place_res(place) ;
00282 for (int j=1 ; j<place+1 ; j++)
00283 place_auxi.set(j) = place_res(j-1) ;
00284 place_res.set(place) = place_auxi(0) ;
00285
00286 for (int j=place+1 ; j<valence ; j++)
00287 place_auxi.set(j) = place_res(j);
00288
00289 res.set(place_res) = auxi(place_auxi) ;
00290 }
00291
00292 return res ;
00293
00294 }
00295
00296
00297
00298 Tensor Tensor::up_down(const Metric& met) const {
00299
00300 Tensor* auxi ;
00301 Tensor* auxi_old = new Tensor(*this) ;
00302
00303 for (int i=0 ; i<valence ; i++) {
00304
00305 if (type_indice(i) == COV) {
00306 auxi = new Tensor( auxi_old->up(i, met) ) ;
00307 }
00308 else{
00309 auxi = new Tensor( auxi_old->down(i, met) ) ;
00310 }
00311
00312 delete auxi_old ;
00313 auxi_old = new Tensor(*auxi) ;
00314 delete auxi ;
00315
00316 }
00317
00318 Tensor result(*auxi_old) ;
00319 delete auxi_old ;
00320
00321 return result ;
00322 }
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332 void Tensor::compute_derive_lie(const Vector& vv, Tensor& resu) const {
00333
00334
00335
00336
00337 if (valence > 0) {
00338 assert(vv.get_triad() == triad) ;
00339 assert(resu.get_triad() == triad) ;
00340 }
00341
00342
00343
00344
00345
00346 const Metric_flat* fmet ;
00347
00348 if (valence == 0) {
00349 fmet = &(mp->flat_met_spher()) ;
00350 }
00351 else {
00352 assert( triad != 0x0 ) ;
00353
00354 const Base_vect_spher* bvs =
00355 dynamic_cast<const Base_vect_spher*>(triad) ;
00356 if (bvs != 0x0) {
00357 fmet = &(mp->flat_met_spher()) ;
00358 }
00359 else {
00360 const Base_vect_cart* bvc =
00361 dynamic_cast<const Base_vect_cart*>(triad) ;
00362 if (bvc != 0x0) {
00363 fmet = &(mp->flat_met_cart()) ;
00364 }
00365 else {
00366 cerr << "Tensor::compute_derive_lie : unknown triad type !\n" ;
00367 abort() ;
00368 }
00369 }
00370 }
00371
00372
00373
00374 int dz_in = 0 ;
00375 for (int ic=0; ic<n_comp; ic++) {
00376 int dzp = cmp[ic]->get_dzpuis() ;
00377 assert(dzp >= 0) ;
00378 if (dzp > dz_in) dz_in = dzp ;
00379 }
00380
00381 #ifndef NDEBUG
00382
00383 for (int ic=0; ic<n_comp; ic++) {
00384 if ( !(cmp[ic]->check_dzpuis(dz_in)) ) {
00385 cout << "######## WARNING #######\n" ;
00386 cout << " Tensor::compute_derive_lie: the tensor components \n"
00387 << " do not have all the same dzpuis ! : \n"
00388 << " ic, dzpuis(ic), dz_in : " << ic << " "
00389 << cmp[ic]->get_dzpuis() << " " << dz_in << endl ;
00390 }
00391 }
00392 #endif
00393
00394
00395
00396
00397
00398 resu = contract(vv, 0, derive_cov(*fmet), valence) ;
00399
00400
00401
00402
00403
00404 if (valence > 0) {
00405
00406 const Tensor& dv = vv.derive_cov(*fmet) ;
00407
00408 Itbl ind1(valence) ;
00409 Itbl ind0(valence) ;
00410 Scalar tmp(*mp) ;
00411
00412
00413
00414 int ncomp_resu = resu.get_n_comp() ;
00415
00416 for (int ic=0; ic<ncomp_resu; ic++) {
00417
00418
00419 ind1 = resu.indices(ic) ;
00420
00421 tmp = 0 ;
00422
00423
00424 for (int id=0; id<valence; id++) {
00425
00426 ind0 = ind1 ;
00427
00428 switch( type_indice(id) ) {
00429
00430 case CON : {
00431 for (int k=1; k<=3; k++) {
00432 ind0.set(id) = k ;
00433 tmp -= operator()(ind0) * dv(ind1(id), k) ;
00434 }
00435 break ;
00436 }
00437
00438 case COV : {
00439 for (int k=1; k<=3; k++) {
00440 ind0.set(id) = k ;
00441 tmp += operator()(ind0) * dv(k, ind1(id)) ;
00442 }
00443 break ;
00444 }
00445
00446 default : {
00447 cerr <<
00448 "Tensor::compute_derive_lie: unexpected type of index !\n" ;
00449 abort() ;
00450 break ;
00451 }
00452
00453 }
00454
00455 }
00456
00457
00458 if (dz_in > 0) tmp.dec_dzpuis() ;
00459
00460
00461 resu.set(ind1) += tmp ;
00462
00463
00464 }
00465
00466 }
00467
00468 }
00469
00470
00471
00472
00473
00474 Tensor Tensor::derive_lie(const Vector& vv) const {
00475
00476 Tensor resu(*mp, valence, type_indice, triad) ;
00477
00478 compute_derive_lie(vv, resu) ;
00479
00480 return resu ;
00481
00482 }
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493