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 char tenseur_operateur_C[] = "$Header: /cvsroot/Lorene/C++/Source/Tenseur/tenseur_operateur.C,v 1.8 2004/05/27 07:17:19 p_grandclement Exp $" ;
00026
00027
00028
00029
00030
00031
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
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103 #include <stdlib.h>
00104 #include <assert.h>
00105 #include <math.h>
00106
00107
00108 #include "tenseur.h"
00109 #include "metrique.h"
00110
00111
00112 Tenseur operator*(const Tenseur& t1, const Tenseur& t2) {
00113
00114 assert ((t1.etat != ETATNONDEF) && (t2.etat != ETATNONDEF)) ;
00115 assert (t1.mp == t2.mp) ;
00116
00117 int val_res = t1.valence + t2.valence ;
00118 double poids_res = t1.poids + t2.poids ;
00119 poids_res = (fabs(poids_res) < 1.e-10 ? 0. : poids_res) ;
00120 const Metrique* met_res = 0x0 ;
00121 if (poids_res != 0.) {
00122
00123 if (t1.metric != 0x0) met_res = t1.metric ;
00124 else met_res = t2.metric ;
00125 }
00126
00127
00128 if (val_res == 0) {
00129 Tenseur scal(*t1.mp, met_res, poids_res) ;
00130
00131 if ((t1.etat == ETATZERO) || (t2.etat == ETATZERO))
00132 scal.set_etat_zero() ;
00133 else {
00134 scal.set_etat_qcq() ;
00135 scal.set() = t1() * t2() ;
00136 }
00137 return scal ;
00138 }
00139
00140 else {
00141
00142 Itbl tipe (val_res) ;
00143 tipe.set_etat_qcq() ;
00144 for (int i=0 ; i<t1.valence ; i++)
00145 tipe.set(i) = t1.type_indice(i) ;
00146 for (int i=0 ; i<t2.valence ; i++)
00147 tipe.set(i+t1.valence) = t2.type_indice(i) ;
00148
00149
00150 if ( (t1.valence != 0) && (t2.valence != 0) ) {
00151 assert ( *(t1.get_triad()) == *(t2.get_triad()) ) ;
00152 }
00153
00154 const Base_vect* triad_res ;
00155 if (t1.valence != 0) {
00156 triad_res = t1.get_triad() ;
00157 }
00158 else{
00159 triad_res = t2.get_triad() ;
00160 }
00161
00162 Tenseur res(*t1.mp, val_res, tipe, triad_res, met_res, poids_res) ;
00163
00164 if ((t1.etat == ETATZERO) || (t2.etat == ETATZERO))
00165 res.set_etat_zero() ;
00166 else {
00167 res.set_etat_qcq() ;
00168 Itbl jeux_indice_t1 (t1.valence) ;
00169 jeux_indice_t1.set_etat_qcq() ;
00170 Itbl jeux_indice_t2 (t2.valence) ;
00171 jeux_indice_t2.set_etat_qcq() ;
00172
00173 for (int i=0 ; i<res.n_comp ; i++) {
00174 Itbl jeux_indice_res(res.donne_indices(i)) ;
00175 for (int j=0 ; j<t1.valence ; j++)
00176 jeux_indice_t1.set(j) = jeux_indice_res(j) ;
00177 for (int j=0 ; j<t2.valence ; j++)
00178 jeux_indice_t2.set(j) = jeux_indice_res(j+t1.valence) ;
00179
00180 res.set(jeux_indice_res) = t1(jeux_indice_t1)*t2(jeux_indice_t2) ;
00181 }
00182 }
00183 return res ;
00184 }
00185 }
00186
00187
00188
00189
00190
00191
00192 Tenseur operator%(const Tenseur& t1, const Tenseur& t2) {
00193
00194 assert ((t1.etat != ETATNONDEF) && (t2.etat != ETATNONDEF)) ;
00195 assert (t1.mp == t2.mp) ;
00196
00197 int val_res = t1.valence + t2.valence ;
00198 double poids_res = t1.poids + t2.poids ;
00199 poids_res = (fabs(poids_res) < 1.e-10 ? 0. : poids_res) ;
00200 const Metrique* met_res = 0x0 ;
00201 if (poids_res != 0.) {
00202
00203 if (t1.metric != 0x0) met_res = t1.metric ;
00204 else met_res = t2.metric ;
00205 }
00206
00207
00208 if (val_res == 0) {
00209 Tenseur scal(*t1.mp, met_res, poids_res) ;
00210
00211 if ((t1.etat == ETATZERO) || (t2.etat == ETATZERO))
00212 scal.set_etat_zero() ;
00213 else {
00214 scal.set_etat_qcq() ;
00215 scal.set() = t1() % t2() ;
00216 }
00217 return scal ;
00218 }
00219
00220 else {
00221
00222 Itbl tipe (val_res) ;
00223 tipe.set_etat_qcq() ;
00224 for (int i=0 ; i<t1.valence ; i++)
00225 tipe.set(i) = t1.type_indice(i) ;
00226 for (int i=0 ; i<t2.valence ; i++)
00227 tipe.set(i+t1.valence) = t2.type_indice(i) ;
00228
00229
00230 if ( (t1.valence != 0) && (t2.valence != 0) ) {
00231 assert ( *(t1.get_triad()) == *(t2.get_triad()) ) ;
00232 }
00233
00234 const Base_vect* triad_res ;
00235 if (t1.valence != 0) {
00236 triad_res = t1.get_triad() ;
00237 }
00238 else{
00239 triad_res = t2.get_triad() ;
00240 }
00241
00242 Tenseur res(*t1.mp, val_res, tipe, triad_res, met_res, poids_res) ;
00243
00244
00245
00246 if ((t1.etat == ETATZERO) || (t2.etat == ETATZERO))
00247 res.set_etat_zero() ;
00248 else {
00249 res.set_etat_qcq() ;
00250 Itbl jeux_indice_t1 (t1.valence) ;
00251 jeux_indice_t1.set_etat_qcq() ;
00252 Itbl jeux_indice_t2 (t2.valence) ;
00253 jeux_indice_t2.set_etat_qcq() ;
00254
00255 for (int i=0 ; i<res.n_comp ; i++) {
00256 Itbl jeux_indice_res(res.donne_indices(i)) ;
00257 for (int j=0 ; j<t1.valence ; j++)
00258 jeux_indice_t1.set(j) = jeux_indice_res(j) ;
00259 for (int j=0 ; j<t2.valence ; j++)
00260 jeux_indice_t2.set(j) = jeux_indice_res(j+t1.valence) ;
00261
00262 res.set(jeux_indice_res) = t1(jeux_indice_t1) %
00263 t2(jeux_indice_t2) ;
00264 }
00265 }
00266 return res ;
00267 }
00268 }
00269
00270
00271
00272 Tenseur contract(const Tenseur& source, int ind_1, int ind_2) {
00273
00274
00275
00276 assert (source.etat != ETATNONDEF) ;
00277 assert ((ind_1 >= 0) && (ind_1 < source.valence)) ;
00278 assert ((ind_2 >= 0) && (ind_2 < source.valence)) ;
00279 assert (source.type_indice(ind_1) != source.type_indice(ind_2)) ;
00280
00281
00282 if (ind_1 > ind_2) {
00283 int auxi = ind_2 ;
00284 ind_2 = ind_1 ;
00285 ind_1 = auxi ;
00286 }
00287
00288
00289 int val_res = source.valence - 2 ;
00290
00291 Itbl tipe (val_res) ;
00292 tipe.set_etat_qcq() ;
00293 for (int i=0 ; i<ind_1 ; i++)
00294 tipe.set(i) = source.type_indice(i) ;
00295 for (int i=ind_1 ; i<ind_2-1 ; i++)
00296 tipe.set(i) = source.type_indice(i+1) ;
00297 for (int i = ind_2-1 ; i<val_res ; i++)
00298 tipe.set(i) = source.type_indice(i+2) ;
00299
00300 Tenseur res(*source.mp, val_res, tipe, source.triad, source.metric,
00301 source.poids) ;
00302
00303
00304 if (source.etat == ETATZERO) {
00305 res.set_etat_zero() ;
00306 return res ;
00307 }
00308
00309 res.set_etat_qcq() ;
00310
00311 Cmp work(source.mp) ;
00312
00313
00314
00315 Itbl jeux_indice_source(source.valence) ;
00316 jeux_indice_source.set_etat_qcq() ;
00317
00318 for (int i=0 ; i<res.n_comp ; i++) {
00319 Itbl jeux_indice_res (res.donne_indices(i)) ;
00320 for (int j=0 ; j<ind_1 ; j++)
00321 jeux_indice_source.set(j) = jeux_indice_res(j) ;
00322 for (int j=ind_1+1 ; j<ind_2 ; j++)
00323 jeux_indice_source.set(j) = jeux_indice_res(j-1) ;
00324 for (int j=ind_2+1 ; j<source.valence ; j++)
00325 jeux_indice_source.set(j) = jeux_indice_res(j-2) ;
00326
00327
00328 work.set_etat_zero() ;
00329 for (int j=0 ; j<3 ; j++) {
00330 jeux_indice_source.set(ind_1) = j ;
00331 jeux_indice_source.set(ind_2) = j ;
00332 work = work + source(jeux_indice_source) ;
00333 }
00334
00335 res.set(jeux_indice_res) = work ;
00336 }
00337 return res ;
00338 }
00339
00340
00341 Tenseur contract (const Tenseur& t1, int ind1, const Tenseur& t2, int ind2) {
00342
00343 assert ((t1.etat != ETATNONDEF) && (t2.etat != ETATNONDEF)) ;
00344
00345 assert ((ind1>=0) && (ind1<t1.valence)) ;
00346 assert ((ind2>=0) && (ind2<t2.valence)) ;
00347 assert (*(t1.mp) == *(t2.mp)) ;
00348
00349
00350 if ( (t1.valence != 0) && (t2.valence != 0) ) {
00351 assert ( *(t1.get_triad()) == *(t2.get_triad()) ) ;
00352 }
00353 assert (t1.type_indice(ind1) != t2.type_indice(ind2)) ;
00354
00355 int val_res = t1.valence + t2.valence - 2;
00356 double poids_res = t1.poids + t2.poids ;
00357 poids_res = (fabs(poids_res) < 1.e-10 ? 0. : poids_res) ;
00358 const Metrique* met_res = 0x0 ;
00359 if (poids_res != 0.) {
00360
00361 if (t1.metric != 0x0) met_res = t1.metric ;
00362 else met_res = t2.metric ;
00363 }
00364 Itbl tipe(val_res) ;
00365 tipe.set_etat_qcq() ;
00366 for (int i=0 ; i<ind1 ; i++)
00367 tipe.set(i) = t1.type_indice(i) ;
00368 for (int i=ind1 ; i<t1.valence-1 ; i++)
00369 tipe.set(i) = t1.type_indice(i+1) ;
00370 for (int i=t1.valence-1 ; i<t1.valence+ind2-1 ; i++)
00371 tipe.set(i) = t2.type_indice(i-t1.valence+1) ;
00372 for (int i = t1.valence+ind2-1 ; i<val_res ; i++)
00373 tipe.set(i) = t2.type_indice(i-t1.valence+2) ;
00374
00375 const Base_vect* triad_res = (val_res == 0) ? 0x0 : t1.get_triad() ;
00376
00377 Tenseur res(*t1.mp, val_res, tipe, triad_res, met_res, poids_res) ;
00378
00379
00380 if ( (t1.etat == ETATZERO) || (t2.etat == ETATZERO) ) {
00381 res.set_etat_zero() ;
00382 return res ;
00383 }
00384
00385 res.set_etat_qcq() ;
00386
00387 Cmp work(t1.mp) ;
00388
00389
00390
00391 Itbl jeux_indice_t1(t1.valence) ;
00392 Itbl jeux_indice_t2(t2.valence) ;
00393 jeux_indice_t1.set_etat_qcq() ;
00394 jeux_indice_t2.set_etat_qcq() ;
00395
00396 for (int comp=0 ; comp<res.n_comp ; comp++) {
00397 Itbl jeux_indice_res (res.donne_indices(comp)) ;
00398 for (int i=0 ; i<ind1 ; i++)
00399 jeux_indice_t1.set(i) = jeux_indice_res(i) ;
00400 for (int i=ind1+1 ; i<t1.valence ; i++)
00401 jeux_indice_t1.set(i) = jeux_indice_res(i-1) ;
00402 for (int i=0 ; i<ind2 ; i++)
00403 jeux_indice_t2.set(i) = jeux_indice_res(t1.valence+i-1) ;
00404 for (int i=ind2+1 ; i<t2.valence ; i++)
00405 jeux_indice_t2.set(i) = jeux_indice_res(t1.valence+i-2) ;
00406
00407
00408
00409 work.set_etat_zero() ;
00410 for (int j=0 ; j<3 ; j++) {
00411 jeux_indice_t1.set(ind1) = j ;
00412 jeux_indice_t2.set(ind2) = j ;
00413 work = work + t1(jeux_indice_t1)*t2(jeux_indice_t2) ;
00414 }
00415
00416 res.set(jeux_indice_res) = work ;
00417 }
00418 return res ;
00419 }
00420
00421 Tenseur contract_desal (const Tenseur& t1, int ind1, const Tenseur& t2, int ind2) {
00422
00423 assert ((t1.etat != ETATNONDEF) && (t2.etat != ETATNONDEF)) ;
00424
00425 assert ((ind1>=0) && (ind1<t1.valence)) ;
00426 assert ((ind2>=0) && (ind2<t2.valence)) ;
00427 assert (t1.mp == t2.mp) ;
00428
00429
00430 if ( (t1.valence != 0) && (t2.valence != 0) ) {
00431 assert ( *(t1.get_triad()) == *(t2.get_triad()) ) ;
00432 }
00433 assert (t1.type_indice(ind1) != t2.type_indice(ind2)) ;
00434
00435 int val_res = t1.valence + t2.valence - 2;
00436 double poids_res = t1.poids + t2.poids ;
00437 poids_res = (fabs(poids_res) < 1.e-10 ? 0. : poids_res) ;
00438 const Metrique* met_res = 0x0 ;
00439 if (poids_res != 0.) {
00440
00441 if (t1.metric != 0x0) met_res = t1.metric ;
00442 else met_res = t2.metric ;
00443 }
00444 Itbl tipe(val_res) ;
00445 tipe.set_etat_qcq() ;
00446 for (int i=0 ; i<ind1 ; i++)
00447 tipe.set(i) = t1.type_indice(i) ;
00448 for (int i=ind1 ; i<t1.valence-1 ; i++)
00449 tipe.set(i) = t1.type_indice(i+1) ;
00450 for (int i=t1.valence-1 ; i<t1.valence+ind2-1 ; i++)
00451 tipe.set(i) = t2.type_indice(i-t1.valence+1) ;
00452 for (int i = t1.valence+ind2-1 ; i<val_res ; i++)
00453 tipe.set(i) = t2.type_indice(i-t1.valence+2) ;
00454
00455 const Base_vect* triad_res = (val_res == 0) ? 0x0 : t1.get_triad() ;
00456
00457 Tenseur res(*t1.mp, val_res, tipe, triad_res, met_res, poids_res) ;
00458
00459
00460 if ( (t1.etat == ETATZERO) || (t2.etat == ETATZERO) ) {
00461 res.set_etat_zero() ;
00462 return res ;
00463 }
00464
00465 res.set_etat_qcq() ;
00466
00467 Cmp work(t1.mp) ;
00468
00469
00470
00471 Itbl jeux_indice_t1(t1.valence) ;
00472 Itbl jeux_indice_t2(t2.valence) ;
00473 jeux_indice_t1.set_etat_qcq() ;
00474 jeux_indice_t2.set_etat_qcq() ;
00475
00476 for (int comp=0 ; comp<res.n_comp ; comp++) {
00477 Itbl jeux_indice_res (res.donne_indices(comp)) ;
00478 for (int i=0 ; i<ind1 ; i++)
00479 jeux_indice_t1.set(i) = jeux_indice_res(i) ;
00480 for (int i=ind1+1 ; i<t1.valence ; i++)
00481 jeux_indice_t1.set(i) = jeux_indice_res(i-1) ;
00482 for (int i=0 ; i<ind2 ; i++)
00483 jeux_indice_t2.set(i) = jeux_indice_res(t1.valence+i-1) ;
00484 for (int i=ind2+1 ; i<t2.valence ; i++)
00485 jeux_indice_t2.set(i) = jeux_indice_res(t1.valence+i-2) ;
00486
00487
00488
00489 work.set_etat_zero() ;
00490 for (int j=0 ; j<3 ; j++) {
00491 jeux_indice_t1.set(ind1) = j ;
00492 jeux_indice_t2.set(ind2) = j ;
00493 work = work + t1(jeux_indice_t1)%t2(jeux_indice_t2) ;
00494 }
00495
00496 res.set(jeux_indice_res) = work ;
00497 }
00498 return res ;
00499 }
00500
00501
00502 Tenseur manipule(const Tenseur& t1, const Metrique& met, int place) {
00503
00504 assert (t1.etat != ETATNONDEF) ;
00505 assert (met.get_etat() != ETATNONDEF) ;
00506
00507 int valen = t1.valence ;
00508 assert (valen != 0) ;
00509 assert ((place >=0) && (place < valen)) ;
00510
00511 Itbl tipe (valen) ;
00512 tipe.set_etat_qcq() ;
00513 tipe.set(0) = -t1.type_indice(place) ;
00514 for (int i=1 ; i<place+1 ; i++)
00515 tipe.set(i) = t1.type_indice(i-1) ;
00516 for (int i=place+1 ; i<valen ; i++)
00517 tipe.set(i) = t1.type_indice(i) ;
00518
00519 Tenseur auxi(*t1.mp, valen, tipe, t1.triad) ;
00520
00521 if (t1.type_indice(place) == COV)
00522 auxi = contract (met.con(), 1, t1, place) ;
00523 else
00524 auxi = contract (met.cov(), 1, t1, place) ;
00525
00526
00527
00528 for (int i=0 ; i<valen ; i++)
00529 tipe.set(i) = t1.type_indice(i) ;
00530 tipe.set(place) *= -1 ;
00531
00532 Tenseur res(*t1.mp, valen, tipe, t1.triad, auxi.metric, auxi.poids) ;
00533 res.set_etat_qcq() ;
00534
00535 Itbl place_auxi(valen) ;
00536 place_auxi.set_etat_qcq() ;
00537
00538 for (int i=0 ; i<res.n_comp ; i++) {
00539
00540 Itbl place_res (res.donne_indices(i)) ;
00541
00542 place_auxi.set(0) = place_res(place) ;
00543 for (int j=1 ; j<place+1 ; j++)
00544 place_auxi.set(j) = place_res(j-1) ;
00545 place_res.set(place) = place_auxi(0) ;
00546 for (int j=place+1 ; j<valen ; j++)
00547 place_auxi.set(j) = place_res(j);
00548
00549
00550 res.set(place_res) = auxi(place_auxi) ;
00551 }
00552 return res ;
00553 }
00554
00555 Tenseur manipule (const Tenseur& t1, const Metrique& met) {
00556
00557 Tenseur* auxi ;
00558 Tenseur* auxi_old = new Tenseur(t1) ;
00559
00560 for (int i=0 ; i<t1.valence ; i++) {
00561 auxi = new Tenseur(manipule(*auxi_old, met, i)) ;
00562 delete auxi_old ;
00563 auxi_old = new Tenseur(*auxi) ;
00564 delete auxi ;
00565 }
00566
00567 Tenseur result(*auxi_old) ;
00568 delete auxi_old ;
00569 return result ;
00570 }
00571
00572
00573 Tenseur skxk(const Tenseur& source) {
00574
00575
00576 assert (source.valence > 0) ;
00577 assert (source.etat != ETATNONDEF) ;
00578 assert (*source.triad == source.mp->get_bvect_cart()) ;
00579
00580
00581 int val_res = source.valence-1 ;
00582 Itbl tipe (val_res) ;
00583 tipe.set_etat_qcq() ;
00584 for (int i=0 ; i<val_res ; i++)
00585 tipe.set(i) = source.type_indice(i) ;
00586
00587
00588 Tenseur res (*source.mp, val_res, tipe, source.triad, source.metric,
00589 source.poids) ;
00590
00591 if (source.etat == ETATZERO)
00592 res.set_etat_zero() ;
00593 else {
00594 res.set_etat_qcq() ;
00595
00596 for (int i=0 ; i<res.n_comp ; i++) {
00597 Itbl indices_res (res.donne_indices(i)) ;
00598 Itbl indices_so (val_res+1) ;
00599 indices_so.set_etat_qcq() ;
00600 for (int j=0 ; j<val_res ; j++)
00601 indices_so.set(j) = indices_res(j) ;
00602
00603
00604 indices_so.set(val_res) = 0 ;
00605 Cmp resu(source(indices_so)) ;
00606
00607 resu.mult_r() ;
00608
00609
00610 assert( dynamic_cast<const Map_radial*>(source.get_mp()) != 0x0) ;
00611
00612 resu.va = (resu.va).mult_st() ;
00613 resu.va = (resu.va).mult_cp() ;
00614
00615
00616
00617 indices_so.set(val_res) = 1 ;
00618 Cmp auxiliaire (source(indices_so)) ;
00619
00620 auxiliaire.mult_r() ;
00621
00622 auxiliaire.va = (auxiliaire.va).mult_st() ;
00623 auxiliaire.va = (auxiliaire.va).mult_sp() ;
00624
00625 resu = resu + auxiliaire ;
00626
00627
00628
00629 indices_so.set(val_res) = 2 ;
00630 auxiliaire = source(indices_so) ;
00631
00632 auxiliaire.mult_r() ;
00633
00634 auxiliaire.va = (auxiliaire.va).mult_ct() ;
00635
00636 resu = resu + auxiliaire ;
00637
00638 res.set(indices_res) = resu ;
00639
00640
00641 }
00642 }
00643 return res ;
00644 }
00645
00646 Tenseur flat_scalar_prod(const Tenseur& t1, const Tenseur& t2) {
00647
00648 assert ((t1.etat != ETATNONDEF) && (t2.etat != ETATNONDEF)) ;
00649
00650 assert (t1.mp == t2.mp) ;
00651
00652
00653 if ( (t1.valence != 0) && (t2.valence != 0) ) {
00654 assert ( *(t1.get_triad()) == *(t2.get_triad()) ) ;
00655 }
00656
00657 int val_res = t1.valence + t2.valence - 2;
00658 double poids_res = t1.poids + t2.poids ;
00659 poids_res = (fabs(poids_res) < 1.e-10 ? 0. : poids_res) ;
00660 const Metrique* met_res = 0x0 ;
00661 if (poids_res != 0.) {
00662 assert((t1.metric != 0x0) || (t2.metric != 0x0)) ;
00663 if (t1.metric != 0x0) met_res = t1.metric ;
00664 else met_res = t2.metric ;
00665 }
00666 Itbl tipe(val_res) ;
00667 tipe.set_etat_qcq() ;
00668
00669 for (int i=0 ; i<t1.valence - 1 ; i++)
00670 tipe.set(i) = t1.type_indice(i) ;
00671 for (int i = t1.valence-1 ; i<val_res ; i++)
00672 tipe.set(i) = t2.type_indice(i-t1.valence+2) ;
00673
00674 Tenseur res(*t1.mp, val_res, tipe, t1.triad, met_res, poids_res) ;
00675
00676
00677 if ( (t1.etat == ETATZERO) || (t2.etat == ETATZERO) ) {
00678 res.set_etat_zero() ;
00679 return res ;
00680 }
00681
00682 res.set_etat_qcq() ;
00683
00684 Cmp work(t1.mp) ;
00685
00686
00687
00688 Itbl jeux_indice_t1(t1.valence) ;
00689 Itbl jeux_indice_t2(t2.valence) ;
00690 jeux_indice_t1.set_etat_qcq() ;
00691 jeux_indice_t2.set_etat_qcq() ;
00692
00693 for (int ir=0 ; ir<res.n_comp ; ir++) {
00694
00695
00696
00697 Itbl jeux_indice_res = res.donne_indices(ir) ;
00698
00699
00700 for (int i=0 ; i<t1.valence - 1 ; i++) {
00701 jeux_indice_t1.set(i) = jeux_indice_res(i) ;
00702 }
00703
00704
00705 for (int i=1 ; i<t2.valence ; i++) {
00706 jeux_indice_t2.set(i) = jeux_indice_res(t1.valence+i-2) ;
00707 }
00708
00709 work.set_etat_zero() ;
00710
00711
00712
00713 for (int j=0 ; j<3 ; j++) {
00714 jeux_indice_t1.set(t1.valence - 1) = j ;
00715 jeux_indice_t2.set(0) = j ;
00716 work = work + t1(jeux_indice_t1)*t2(jeux_indice_t2) ;
00717 }
00718
00719 res.set(jeux_indice_res) = work ;
00720
00721 }
00722
00723 return res ;
00724 }
00725
00726
00727
00728 Tenseur flat_scalar_prod_desal(const Tenseur& t1, const Tenseur& t2) {
00729
00730 assert ((t1.etat != ETATNONDEF) && (t2.etat != ETATNONDEF)) ;
00731
00732 assert (t1.mp == t2.mp) ;
00733
00734
00735 if ( (t1.valence != 0) && (t2.valence != 0) ) {
00736 assert ( *(t1.get_triad()) == *(t2.get_triad()) ) ;
00737 }
00738
00739 int val_res = t1.valence + t2.valence - 2;
00740 double poids_res = t1.poids + t2.poids ;
00741 poids_res = (fabs(poids_res) < 1.e-10 ? 0. : poids_res) ;
00742 const Metrique* met_res = 0x0 ;
00743 if (poids_res != 0.) {
00744 assert((t1.metric != 0x0) || (t2.metric != 0x0)) ;
00745 if (t1.metric != 0x0) met_res = t1.metric ;
00746 else met_res = t2.metric ;
00747 }
00748 Itbl tipe(val_res) ;
00749 tipe.set_etat_qcq() ;
00750
00751 for (int i=0 ; i<t1.valence - 1 ; i++)
00752 tipe.set(i) = t1.type_indice(i) ;
00753 for (int i = t1.valence-1 ; i<val_res ; i++)
00754 tipe.set(i) = t2.type_indice(i-t1.valence+2) ;
00755
00756 Tenseur res(*t1.mp, val_res, tipe, t1.triad, met_res, poids_res) ;
00757
00758
00759 if ( (t1.etat == ETATZERO) || (t2.etat == ETATZERO) ) {
00760 res.set_etat_zero() ;
00761 return res ;
00762 }
00763
00764 res.set_etat_qcq() ;
00765
00766 Cmp work(t1.mp) ;
00767
00768
00769
00770 Itbl jeux_indice_t1(t1.valence) ;
00771 Itbl jeux_indice_t2(t2.valence) ;
00772 jeux_indice_t1.set_etat_qcq() ;
00773 jeux_indice_t2.set_etat_qcq() ;
00774
00775 for (int ir=0 ; ir<res.n_comp ; ir++) {
00776
00777
00778
00779 Itbl jeux_indice_res = res.donne_indices(ir) ;
00780
00781
00782 for (int i=0 ; i<t1.valence - 1 ; i++) {
00783 jeux_indice_t1.set(i) = jeux_indice_res(i) ;
00784 }
00785
00786
00787 for (int i=1 ; i<t2.valence ; i++) {
00788 jeux_indice_t2.set(i) = jeux_indice_res(t1.valence+i-2) ;
00789 }
00790
00791 work.set_etat_zero() ;
00792
00793
00794
00795 for (int j=0 ; j<3 ; j++) {
00796 jeux_indice_t1.set(t1.valence - 1) = j ;
00797 jeux_indice_t2.set(0) = j ;
00798 work = work + t1(jeux_indice_t1) % t2(jeux_indice_t2) ;
00799 }
00800
00801 res.set(jeux_indice_res) = work ;
00802
00803 }
00804
00805 return res ;
00806 }
00807
00808
00809 Tenseur lie_derive (const Tenseur& t, const Tenseur& x, const Metrique* met)
00810 {
00811 assert ( (t.get_etat() != ETATNONDEF) && (x.get_etat() != ETATNONDEF) ) ;
00812 assert(x.get_valence() == 1) ;
00813 assert(x.get_type_indice(0) == CON) ;
00814 assert(x.get_poids() == 0.) ;
00815 assert(t.get_mp() == x.get_mp()) ;
00816
00817 int val = t.get_valence() ;
00818 double poids = t.get_poids() ;
00819 Itbl tipe (val+1) ;
00820 tipe.set_etat_qcq() ;
00821 tipe.set(0) = COV ;
00822 Itbl tipx(2) ;
00823 tipx.set_etat_qcq() ;
00824 tipx.set(0) = COV ;
00825 tipx.set(1) = CON ;
00826 for (int i=0 ; i<val ; i++)
00827 tipe.set(i+1) = t.get_type_indice(i) ;
00828 Tenseur dt(*t.get_mp(), val+1, tipe, t.get_triad(), t.get_metric(), poids) ;
00829 Tenseur dx(*x.get_mp(), 2, tipx, x.get_triad()) ;
00830 if (met == 0x0) {
00831 dx = x.gradient() ;
00832 dt = t.gradient() ;
00833 }
00834 else {
00835 dx = x.derive_cov(*met) ;
00836 dt = t.derive_cov(*met) ;
00837 }
00838 Tenseur resu(contract(x,0,dt,0)) ;
00839 Tenseur* auxi ;
00840 if ((val!=0)&&(t.get_etat()!=ETATZERO)&&(x.get_etat()!=ETATZERO)) {
00841 assert(t.get_triad()->identify() == x.get_triad()->identify()) ;
00842
00843 for (int i=0 ; i<val ; i++) {
00844 if (t.get_type_indice(i) == COV) {
00845 auxi = new Tenseur(contract(t,i,dx,1)) ;
00846
00847 Itbl indices_aux(val) ;
00848 indices_aux.set_etat_qcq() ;
00849 for (int j=0 ; j<resu.get_n_comp() ; j++) {
00850
00851 Itbl indices (resu.donne_indices(j)) ;
00852 indices_aux.set(val-1) = indices(i) ;
00853 for (int idx=0 ; idx<val-1 ; idx++)
00854 if (idx<i)
00855 indices_aux.set(idx) = indices(idx) ;
00856 else
00857 indices_aux.set(idx) = indices(idx+1) ;
00858
00859 resu.set(indices) += (*auxi)(indices_aux) ;
00860 }
00861 }
00862 else {
00863 auxi = new Tenseur(contract(t,i,dx,0)) ;
00864
00865 Itbl indices_aux(val) ;
00866 indices_aux.set_etat_qcq() ;
00867
00868
00869 for (int j=0 ; j<resu.get_n_comp() ; j++) {
00870
00871 Itbl indices (resu.donne_indices(j)) ;
00872 indices_aux.set(val-1) = indices(i) ;
00873 for (int idx=0 ; idx<val-1 ; idx++)
00874 if (idx<i)
00875 indices_aux.set(idx) = indices(idx) ;
00876 else
00877 indices_aux.set(idx) = indices(idx+1) ;
00878 resu.set(indices) -= (*auxi)(indices_aux) ;
00879 }
00880 }
00881 delete auxi ;
00882 }
00883 }
00884 if ((poids != 0.)&&(t.get_etat()!=ETATZERO)&&(x.get_etat()!=ETATZERO))
00885 resu = resu + poids*contract(dx,0,1)*t ;
00886
00887 return resu ;
00888 }
00889
00890 Tenseur sans_trace(const Tenseur& t, const Metrique& metre)
00891 {
00892 assert(t.get_etat() != ETATNONDEF) ;
00893 assert(metre.get_etat() != ETATNONDEF) ;
00894 assert(t.get_valence() == 2) ;
00895
00896 Tenseur resu(t) ;
00897 if (resu.get_etat() == ETATZERO) return resu ;
00898 assert(resu.get_etat() == ETATQCQ) ;
00899
00900 int t0 = t.get_type_indice(0) ;
00901 int t1 = t.get_type_indice(1) ;
00902 Itbl mix(2) ;
00903 mix.set_etat_qcq() ;
00904 mix.set(0) = (t0 == t1 ? -t0 : t0) ;
00905 mix.set(1) = t1 ;
00906
00907 Tenseur tmp(*t.get_mp(), 2, mix, *t.get_triad(), t.get_metric(),
00908 t.get_poids()) ;
00909 if (t0 == t1)
00910 tmp = manipule(t, metre, 0) ;
00911 else
00912 tmp = t ;
00913
00914 Tenseur trace(contract(tmp, 0, 1)) ;
00915
00916 if (t0 == t1) {
00917 switch (t0) {
00918 case COV : {
00919 resu = resu - 1./3.*trace * metre.cov() ;
00920 break ;
00921 }
00922 case CON : {
00923 resu = resu - 1./3.*trace * metre.con() ;
00924 break ;
00925 }
00926 default :
00927 cout << "Erreur bizarre dans sans_trace!" << endl ;
00928 abort() ;
00929 break ;
00930 }
00931 }
00932 else {
00933 Tenseur_sym delta(*t.get_mp(), 2, mix, *t.get_triad(),
00934 t.get_metric(), t.get_poids()) ;
00935 delta.set_etat_qcq() ;
00936 for (int i=0; i<3; i++)
00937 for (int j=i; j<3; j++)
00938 delta.set(i,j) = (i==j ? 1 : 0) ;
00939 resu = resu - trace/3. * delta ;
00940 }
00941 resu.set_std_base() ;
00942 return resu ;
00943 }
00944
00945
00946