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 char connection_C[] = "$Header: /cvsroot/Lorene/C++/Source/Connection/connection.C,v 1.17 2004/02/18 18:44:22 e_gourgoulhon Exp $" ;
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
00104
00105 #include "headcpp.h"
00106
00107
00108 #include <stdlib.h>
00109
00110
00111 #include "connection.h"
00112 #include "metric.h"
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 Connection::Connection(const Tensor_sym& delta_i,
00123 const Metric_flat& flat_met_i)
00124 : mp(&(delta_i.get_mp())),
00125 triad(delta_i.get_triad()),
00126 delta(delta_i),
00127 assoc_metric(false),
00128 flat_met(&flat_met_i) {
00129
00130 assert( delta_i.get_valence() == 3 ) ;
00131 assert( delta_i.sym_index1() == 1 ) ;
00132 assert( delta_i.sym_index2() == 2 ) ;
00133 assert( delta_i.get_index_type(0) == CON ) ;
00134 assert( delta_i.get_index_type(1) == COV ) ;
00135 assert( delta_i.get_index_type(2) == COV ) ;
00136
00137 set_der_0x0() ;
00138 }
00139
00140
00141
00142
00143 Connection::Connection(const Metric& met,
00144 const Metric_flat& flat_met_i)
00145 : mp(&(met.get_mp())),
00146 triad(met.cov().get_triad()),
00147 delta(*mp, CON, COV, COV, *triad, 1, 2),
00148 assoc_metric(true),
00149 flat_met(&flat_met_i) {
00150
00151 fait_delta(met) ;
00152
00153 set_der_0x0() ;
00154 }
00155
00156
00157
00158
00159 Connection::Connection(const Connection& conn_i) : mp(conn_i.mp),
00160 triad(conn_i.triad),
00161 delta(conn_i.delta),
00162 assoc_metric(conn_i.assoc_metric),
00163 flat_met(conn_i.flat_met) {
00164
00165 set_der_0x0() ;
00166
00167 }
00168
00169
00170
00171
00172 Connection::Connection(const Map& mpi, const Base_vect& bi) : mp(&mpi),
00173 triad(&bi),
00174 delta(mpi, CON, COV, COV, bi, 1, 2),
00175 assoc_metric(false),
00176 flat_met(0x0){
00177
00178 set_der_0x0() ;
00179
00180 }
00181
00182
00183
00184
00185
00186
00187
00188 Connection::~Connection(){
00189
00190 del_deriv() ;
00191
00192 }
00193
00194
00195
00196
00197
00198 void Connection::del_deriv() const {
00199
00200 if (p_ricci != 0x0) delete p_ricci ;
00201
00202 set_der_0x0() ;
00203
00204 }
00205
00206 void Connection::set_der_0x0() const {
00207
00208 p_ricci = 0x0 ;
00209
00210 }
00211
00212
00213
00214
00215
00216
00217
00218 void Connection::operator=(const Connection& ci) {
00219
00220 assert( triad == ci.triad ) ;
00221 delta = ci.delta ;
00222 flat_met = ci.flat_met ;
00223
00224 del_deriv() ;
00225
00226 }
00227
00228 void Connection::update(const Tensor_sym& delta_i) {
00229
00230 assert(assoc_metric == false) ;
00231
00232 assert(flat_met != 0x0) ;
00233
00234 assert( delta_i.get_valence() == 3 ) ;
00235 assert( delta_i.sym_index1() == 1 ) ;
00236 assert( delta_i.sym_index2() == 2 ) ;
00237 assert( delta_i.get_index_type(0) == CON ) ;
00238 assert( delta_i.get_index_type(1) == COV ) ;
00239 assert( delta_i.get_index_type(2) == COV ) ;
00240
00241 delta = delta_i ;
00242
00243 del_deriv() ;
00244
00245 }
00246
00247
00248 void Connection::update(const Metric& met) {
00249
00250 assert(assoc_metric == true) ;
00251
00252 assert(flat_met != 0x0) ;
00253
00254 fait_delta(met) ;
00255
00256 del_deriv() ;
00257
00258 }
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271 void Connection::fait_delta(const Metric& gam) {
00272
00273 assert(flat_met != 0x0) ;
00274
00275 const Tensor& dgam = gam.cov().derive_cov(*flat_met) ;
00276
00277 for (int k=1; k<=3; k++) {
00278 for (int i=1; i<=3; i++) {
00279 for (int j=1; j<=i; j++) {
00280 Scalar& cc = delta.set(k,i,j) ;
00281 cc = 0 ;
00282 for (int l=1; l<=3; l++) {
00283 cc += gam.con()(k,l) * (
00284 dgam(l,j,i) + dgam(i,l,j) - dgam(i,j,l) ) ;
00285
00286 }
00287 cc = 0.5 * cc ;
00288 }
00289 }
00290 }
00291
00292
00293 }
00294
00295
00296
00297
00298
00299
00300 Tensor* Connection::p_derive_cov(const Tensor& uu) const {
00301
00302
00303
00304
00305 int valence0 = uu.get_valence() ;
00306 int valence1 = valence0 + 1 ;
00307 int valence1m1 = valence1 - 1 ;
00308
00309 int ncomp0 = uu.get_n_comp() ;
00310
00311
00312
00313 if (valence0 >= 1) {
00314 assert(uu.get_triad() == triad) ;
00315 }
00316 assert(flat_met != 0x0) ;
00317
00318
00319
00320 Tensor* resu ;
00321
00322
00323 if (valence0 == 0)
00324 resu = new Vector(*mp, COV, triad) ;
00325 else {
00326
00327
00328 Itbl tipe(valence1) ;
00329 const Itbl& tipeuu = uu.get_index_type() ;
00330 for (int id = 0; id<valence0; id++) {
00331 tipe.set(id) = tipeuu(id) ;
00332 }
00333 tipe.set(valence1m1) = COV ;
00334
00335
00336 const Tensor* puu = &uu ;
00337 const Tensor_sym* puus = dynamic_cast<const Tensor_sym*>(puu) ;
00338 if ( puus != 0x0 ) {
00339 resu = new Tensor_sym(*mp, valence1, tipe, *triad,
00340 puus->sym_index1(), puus->sym_index2()) ;
00341 }
00342 else {
00343 resu = new Tensor(*mp, valence1, tipe, *triad) ;
00344 }
00345 }
00346
00347 int ncomp1 = resu->get_n_comp() ;
00348
00349 Itbl ind1(valence1) ;
00350 Itbl ind0(valence0) ;
00351 Itbl ind(valence0) ;
00352
00353 Scalar tmp(*mp) ;
00354
00355
00356
00357 int dz_in = 0 ;
00358 for (int ic=0; ic<ncomp0; ic++) {
00359 int dzp = uu(uu.indices(ic)).get_dzpuis() ;
00360 assert(dzp >= 0) ;
00361 if (dzp > dz_in) dz_in = dzp ;
00362 }
00363
00364 #ifndef NDEBUG
00365
00366 for (int ic=0; ic<ncomp0; ic++) {
00367 if ( !(uu(uu.indices(ic)).check_dzpuis(dz_in)) ) {
00368 cout << "######## WARNING #######\n" ;
00369 cout << " Connection::p_derive_cov : the tensor components \n"
00370 << " do not have all the same dzpuis ! : \n"
00371 << " ic, dzpuis(ic), dz_in : " << ic << " "
00372 << uu(uu.indices(ic)).get_dzpuis() << " " << dz_in << endl ;
00373 }
00374 }
00375 #endif
00376
00377
00378
00379
00380
00381 *resu = uu.derive_cov(*flat_met) ;
00382
00383
00384
00385
00386 for (int ic=0; ic<ncomp1; ic++) {
00387
00388
00389 ind1 = resu->indices(ic) ;
00390
00391
00392 for (int id = 0; id < valence0; id++) {
00393 ind0.set(id) = ind1(id) ;
00394 }
00395
00396
00397 int k = ind1(valence1m1) ;
00398
00399 tmp = 0 ;
00400
00401
00402 for (int id=0; id<valence0; id++) {
00403
00404 ind = ind0 ;
00405
00406 switch( uu.get_index_type(id) ) {
00407
00408 case CON : {
00409 for (int l=1; l<=3; l++) {
00410 ind.set(id) = l ;
00411 tmp += delta(ind0(id), k, l) * uu(ind) ;
00412 }
00413 break ;
00414 }
00415
00416 case COV : {
00417 for (int l=1; l<=3; l++) {
00418 ind.set(id) = l ;
00419 tmp -= delta(l, k, ind0(id)) * uu(ind) ;
00420 }
00421 break ;
00422 }
00423
00424 default : {
00425 cerr <<
00426 "Connection::p_derive_cov : unexpected type of index !\n" ;
00427 abort() ;
00428 break ;
00429 }
00430
00431 }
00432
00433 }
00434
00435
00436 if (dz_in > 0) tmp.dec_dzpuis() ;
00437
00438
00439 resu->set(ind1) += tmp ;
00440
00441 }
00442
00443
00444
00445
00446 return resu ;
00447
00448 }
00449
00450
00451
00452
00453
00454
00455
00456 Tensor* Connection::p_divergence(const Tensor& uu) const {
00457
00458
00459
00460
00461
00462 int valence0 = uu.get_valence() ;
00463 int valence1 = valence0 - 1 ;
00464 int valence0m1 = valence0 - 1 ;
00465
00466 int ncomp0 = uu.get_n_comp() ;
00467
00468
00469
00470 assert (valence0 >= 1) ;
00471 assert (uu.get_triad() == triad) ;
00472
00473
00474 assert (uu.get_index_type(valence0m1) == CON) ;
00475
00476
00477
00478
00479 Tensor* resu ;
00480
00481 if (valence0 == 1)
00482 resu = new Scalar(*mp) ;
00483 else {
00484
00485
00486 Itbl tipe(valence1) ;
00487 const Itbl& tipeuu = uu.get_index_type() ;
00488 for (int id = 0; id<valence1; id++) {
00489 tipe.set(id) = tipeuu(id) ;
00490 }
00491
00492 if (valence0 == 2) {
00493 resu = new Vector(*mp, tipe(0), *triad) ;
00494 }
00495 else {
00496
00497 const Tensor* puu = &uu ;
00498 const Tensor_sym* puus = dynamic_cast<const Tensor_sym*>(puu) ;
00499 if ( puus != 0x0 ) {
00500
00501 if (puus->sym_index2() != valence0 - 1) {
00502
00503
00504
00505 if (valence1 == 2) {
00506 resu = new Sym_tensor(*mp, tipe, *triad) ;
00507 }
00508 else {
00509 resu = new Tensor_sym(*mp, valence1, tipe, *triad,
00510 puus->sym_index1(), puus->sym_index2()) ;
00511 }
00512 }
00513 else {
00514
00515 resu = new Tensor(*mp, valence1, tipe, *triad) ;
00516 }
00517 }
00518 else {
00519 resu = new Tensor(*mp, valence1, tipe, *triad) ;
00520 }
00521 }
00522
00523 }
00524
00525 int ncomp1 = resu->get_n_comp() ;
00526
00527 Itbl ind0(valence0) ;
00528 Itbl ind1(valence1) ;
00529 Itbl ind(valence0) ;
00530
00531 Scalar tmp(*mp) ;
00532
00533
00534
00535
00536 int dz_in = 0 ;
00537 for (int ic=0; ic<ncomp0; ic++) {
00538 int dzp = uu(uu.indices(ic)).get_dzpuis() ;
00539 assert(dzp >= 0) ;
00540 if (dzp > dz_in) dz_in = dzp ;
00541 }
00542
00543 #ifndef NDEBUG
00544
00545 for (int ic=0; ic<ncomp0; ic++) {
00546 if ( !(uu(uu.indices(ic)).check_dzpuis(dz_in)) ) {
00547 cout << "######## WARNING #######\n" ;
00548 cout << " Connection::p_divergence : the tensor components \n"
00549 << " do not have all the same dzpuis ! : \n"
00550 << " ic, dzpuis(ic), dz_in : " << ic << " "
00551 << uu(uu.indices(ic)).get_dzpuis() << " " << dz_in << endl ;
00552 }
00553 }
00554 #endif
00555
00556
00557
00558
00559 Vector delta_trace = delta.trace(0,2) ;
00560
00561
00562
00563
00564 *resu = uu.divergence(*flat_met) ;
00565
00566
00567
00568
00569
00570 for (int ic=0; ic<ncomp1; ic++) {
00571
00572
00573 ind1 = resu->indices(ic) ;
00574
00575
00576 for (int id = 0; id < valence1; id++) {
00577 ind0.set(id) = ind1(id) ;
00578 }
00579
00580
00581 tmp = 0 ;
00582
00583 for (int l=1; l<=3; l++) {
00584 ind0.set(valence0m1) = l ;
00585 tmp += delta_trace(l) * uu(ind0) ;
00586 }
00587
00588 ind0.set(valence0m1) = -1 ;
00589
00590
00591
00592
00593
00594 for (int id=0; id<valence1; id++) {
00595
00596
00597 ind = ind0 ;
00598
00599 switch( uu.get_index_type(id) ) {
00600
00601 case CON : {
00602 for (int l=1; l<=3; l++) {
00603 ind.set(id) = l ;
00604 for (int k=1; k<=3; k++) {
00605 ind.set(valence0m1) = k ;
00606 tmp += delta(ind0(id), l, k) * uu(ind) ;
00607 }
00608 }
00609 break ;
00610 }
00611
00612 case COV : {
00613 for (int l=1; l<=3; l++) {
00614 ind.set(id) = l ;
00615 for (int k=1; k<=3; k++) {
00616 ind.set(valence0m1) = k ;
00617 tmp -= delta(l, ind0(id), k) * uu(ind) ;
00618 }
00619 }
00620 break ;
00621 }
00622
00623 default : {
00624 cerr <<
00625 "Connection::p_divergence : unexpected type of index !\n" ;
00626 abort() ;
00627 break ;
00628 }
00629
00630 }
00631
00632 }
00633
00634
00635 if (dz_in > 0) tmp.dec_dzpuis() ;
00636
00637
00638 resu->set(ind1) += tmp ;
00639
00640
00641 }
00642
00643
00644
00645
00646 return resu ;
00647
00648 }
00649
00650
00651
00652
00653
00654
00655 const Tensor& Connection::ricci() const {
00656
00657 if (p_ricci == 0x0) {
00658
00659 if (assoc_metric) {
00660
00661 p_ricci = new Sym_tensor(*mp, COV, *triad) ;
00662 }
00663 else {
00664 p_ricci = new Tensor(*mp, 2, COV, *triad) ;
00665 }
00666
00667 const Tensor& d_delta = delta.derive_cov(*flat_met) ;
00668
00669 for (int i=1; i<=3; i++) {
00670
00671 int jmax = assoc_metric ? i : 3 ;
00672
00673 for (int j=1; j<=jmax; j++) {
00674
00675 Scalar tmp1(*mp) ;
00676 tmp1.set_etat_zero() ;
00677 for (int k=1; k<=3; k++) {
00678 tmp1 += d_delta(k,i,j,k) ;
00679 }
00680
00681 Scalar tmp2(*mp) ;
00682 tmp2.set_etat_zero() ;
00683 for (int k=1; k<=3; k++) {
00684 tmp2 += d_delta(k,i,k,j) ;
00685 }
00686
00687 Scalar tmp3(*mp) ;
00688 tmp3.set_etat_zero() ;
00689 for (int k=1; k<=3; k++) {
00690 for (int m=1; m<=3; m++) {
00691 tmp3 += delta(k,k,m) * delta(m,i,j) ;
00692 }
00693 }
00694 tmp3.dec_dzpuis() ;
00695
00696 Scalar tmp4(*mp) ;
00697 tmp4.set_etat_zero() ;
00698 for (int k=1; k<=3; k++) {
00699 for (int m=1; m<=3; m++) {
00700 tmp4 += delta(k,j,m) * delta(m,i,k) ;
00701 }
00702 }
00703 tmp4.dec_dzpuis() ;
00704
00705 p_ricci->set(i,j) = tmp1 - tmp2 + tmp3 - tmp4 ;
00706
00707 }
00708 }
00709
00710 }
00711
00712 return *p_ricci ;
00713
00714 }
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727