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
00032 char tensor_C[] = "$Header: /cvsroot/Lorene/C++/Source/Tensor/tensor.C,v 1.39 2007/12/21 16:07:08 j_novak Exp $" ;
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
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175 #include <stdlib.h>
00176 #include <assert.h>
00177 #include <math.h>
00178
00179
00180 #include "metric.h"
00181 #include "utilitaires.h"
00182
00183
00184
00185
00186
00187
00188
00189 Tensor::Tensor(const Map& map, int val, const Itbl& tipe,
00190 const Base_vect& triad_i)
00191 : mp(&map), valence(val), triad(&triad_i), type_indice(tipe),
00192 n_comp(int(pow(3., val))){
00193
00194
00195 assert (valence >= 0) ;
00196 assert (tipe.get_ndim() == 1) ;
00197 assert (valence == tipe.get_dim(0)) ;
00198 for (int i=0 ; i<valence ; i++)
00199 assert ((tipe(i) == COV) || (tipe(i) == CON)) ;
00200
00201 cmp = new Scalar*[n_comp] ;
00202
00203 for (int i=0 ; i<n_comp ; i++)
00204 cmp[i] = new Scalar(map) ;
00205
00206 set_der_0x0() ;
00207
00208 }
00209
00210
00211
00212 Tensor::Tensor(const Map& map, int val, const Itbl& tipe,
00213 const Base_vect* triad_i)
00214 : mp(&map), valence(val), triad(triad_i), type_indice(tipe),
00215 n_comp(int(pow(3., val))){
00216
00217
00218 assert (valence >= 0) ;
00219 assert (tipe.get_ndim() == 1) ;
00220 assert (valence == tipe.get_dim(0)) ;
00221 for (int i=0 ; i<valence ; i++)
00222 assert ((tipe(i) == COV) || (tipe(i) == CON)) ;
00223
00224 cmp = new Scalar*[n_comp] ;
00225
00226 for (int i=0 ; i<n_comp ; i++)
00227 cmp[i] = new Scalar(map) ;
00228
00229 set_der_0x0() ;
00230
00231 }
00232
00233
00234
00235
00236
00237
00238 Tensor::Tensor(const Map& map, int val, int tipe, const Base_vect& triad_i)
00239 : mp(&map), valence(val), triad(&triad_i), type_indice(val),
00240 n_comp(int(pow(3., val))){
00241
00242
00243 assert (valence >= 0) ;
00244 assert ((tipe == COV) || (tipe == CON)) ;
00245
00246 type_indice = tipe ;
00247
00248 cmp = new Scalar*[n_comp] ;
00249
00250 for (int i=0 ; i<n_comp ; i++)
00251 cmp[i] = new Scalar(map) ;
00252
00253 set_der_0x0() ;
00254 }
00255
00256
00257
00258 Tensor::Tensor (const Tensor& source) :
00259 mp(source.mp), valence(source.valence), triad(source.triad),
00260 type_indice(source.type_indice) {
00261
00262 n_comp = int(pow(3., valence)) ;
00263
00264 cmp = new Scalar*[n_comp] ;
00265 for (int i=0 ; i<n_comp ; i++) {
00266
00267
00268
00269
00270
00271 int place_source = source.position(indices(i)) ;
00272 cmp[i] = new Scalar(*source.cmp[place_source]) ;
00273 }
00274
00275 set_der_0x0() ;
00276
00277 }
00278
00279
00280
00281
00282 Tensor::Tensor(const Map& mapping, const Base_vect& triad_i, FILE* fd)
00283 : mp(&mapping), triad(&triad_i), type_indice(fd){
00284
00285 fread_be(&valence, sizeof(int), 1, fd) ;
00286
00287 if (valence != 0) {
00288 Base_vect* triad_fich = Base_vect::bvect_from_file(fd) ;
00289 assert( *triad_fich == *triad) ;
00290 delete triad_fich ;
00291 }
00292 else{
00293 triad = 0x0 ;
00294 }
00295
00296 fread_be(&n_comp, sizeof(int), 1, fd) ;
00297
00298 cmp = new Scalar*[n_comp] ;
00299 for (int i=0 ; i<n_comp ; i++)
00300 cmp[i] = new Scalar(*mp, *(mp->get_mg()), fd) ;
00301
00302 set_der_0x0() ;
00303 }
00304
00305
00306
00307
00308
00309 Tensor::Tensor(const Map& map) : mp(&map), valence(0), triad(0x0),
00310 type_indice(0), n_comp(1) {
00311
00312 cmp = new Scalar*[n_comp] ;
00313 cmp[0] = 0x0 ;
00314
00315 set_der_0x0() ;
00316 }
00317
00318
00319
00320
00321 Tensor::Tensor (const Map& map, int val, const Itbl& tipe, int compo,
00322 const Base_vect& triad_i) :
00323 mp(&map), valence(val), triad(&triad_i), type_indice(tipe), n_comp(compo)
00324 {
00325
00326
00327 assert (valence >= 0) ;
00328 assert (tipe.get_ndim() == 1) ;
00329 assert (n_comp > 0) ;
00330 assert (valence == tipe.get_dim(0)) ;
00331 for (int i=0 ; i<valence ; i++)
00332 assert ((tipe(i) == COV) || (tipe(i) == CON)) ;
00333
00334 cmp = new Scalar*[n_comp] ;
00335
00336 for (int i=0 ; i<n_comp ; i++)
00337 cmp[i] = new Scalar(map) ;
00338
00339 set_der_0x0() ;
00340
00341 }
00342
00343
00344
00345
00346 Tensor::Tensor (const Map& map, int val, int tipe, int compo,
00347 const Base_vect& triad_i) :
00348 mp(&map), valence(val), triad(&triad_i), type_indice(val), n_comp(compo)
00349 {
00350
00351
00352 assert (valence >= 0) ;
00353 assert (n_comp >= 0) ;
00354 assert ((tipe == COV) || (tipe == CON)) ;
00355
00356 type_indice = tipe ;
00357
00358 cmp = new Scalar*[n_comp] ;
00359
00360 for (int i=0 ; i<n_comp ; i++)
00361 cmp[i] = new Scalar(map) ;
00362
00363 set_der_0x0() ;
00364
00365 }
00366
00367
00368
00369
00370
00371
00372 Tensor::~Tensor () {
00373
00374 Tensor::del_deriv() ;
00375
00376 for (int i=0 ; i<n_comp ; i++) {
00377 if (cmp[i] != 0x0)
00378 delete cmp[i] ;
00379 }
00380 delete [] cmp ;
00381 }
00382
00383
00384
00385 void Tensor::del_deriv() const {
00386
00387 for (int i=0; i<N_MET_MAX; i++)
00388 del_derive_met(i) ;
00389
00390 set_der_0x0() ;
00391
00392 }
00393
00394 void Tensor::set_der_0x0() const {
00395
00396 for (int i=0; i<N_MET_MAX; i++)
00397 set_der_met_0x0(i) ;
00398
00399 }
00400
00401 void Tensor::del_derive_met(int j) const {
00402
00403 assert( (j>=0) && (j<N_MET_MAX) ) ;
00404
00405 if (met_depend[j] != 0x0) {
00406 for (int i=0 ; i<N_TENSOR_DEPEND ; i++)
00407 if (met_depend[j]->tensor_depend[i] == this)
00408 met_depend[j]->tensor_depend[i] = 0x0 ;
00409 if (p_derive_cov[j] != 0x0)
00410 delete p_derive_cov[j] ;
00411 if (p_derive_con[j] != 0x0)
00412 delete p_derive_con[j] ;
00413 if (p_divergence[j] != 0x0)
00414 delete p_divergence[j] ;
00415
00416 set_der_met_0x0(j) ;
00417 }
00418 }
00419
00420 void Tensor::set_der_met_0x0(int i) const {
00421
00422 assert( (i>=0) && (i<N_MET_MAX) ) ;
00423 met_depend[i] = 0x0 ;
00424 p_derive_cov[i] = 0x0 ;
00425 p_derive_con[i] = 0x0 ;
00426 p_divergence[i] = 0x0 ;
00427
00428 }
00429
00430 int Tensor::get_place_met(const Metric& metre) const {
00431 int resu = -1 ;
00432 for (int i=0; i<N_MET_MAX; i++)
00433 if (met_depend[i] == &metre) {
00434 resu = i ;
00435 break ;
00436 }
00437 return resu ;
00438 }
00439
00440 void Tensor::set_dependance (const Metric& met) const {
00441
00442 int nmet = 0 ;
00443 bool deja = false ;
00444 for (int i=0; i<N_MET_MAX; i++) {
00445 if (met_depend[i] == &met) deja = true ;
00446 if ((!deja) && (met_depend[i] != 0x0)) nmet++ ;
00447 }
00448 if (nmet == N_MET_MAX) {
00449 cout << "Too many metrics in Tensor::set_dependances" << endl ;
00450 abort() ;
00451 }
00452 if (!deja) {
00453 int conte = 0 ;
00454 while ((conte < N_TENSOR_DEPEND) && (met.tensor_depend[conte] != 0x0))
00455 conte ++ ;
00456
00457 if (conte == N_TENSOR_DEPEND) {
00458 cout << "Too many dependancies in Tensor::set_dependances " << endl ;
00459 abort() ;
00460 }
00461 else {
00462 met.tensor_depend[conte] = this ;
00463 met_depend[nmet] = &met ;
00464 }
00465 }
00466 }
00467
00468 void Tensor::set_etat_qcq() {
00469
00470 del_deriv() ;
00471 for (int i=0 ; i<n_comp ; i++) {
00472 cmp[i]->set_etat_qcq() ;
00473 }
00474 }
00475
00476 void Tensor::set_etat_nondef() {
00477
00478 del_deriv() ;
00479 for (int i=0 ; i<n_comp ; i++) {
00480 cmp[i]->set_etat_nondef() ;
00481 }
00482 }
00483
00484 void Tensor::set_etat_zero() {
00485
00486 del_deriv() ;
00487 for (int i=0 ; i<n_comp ; i++) {
00488 cmp[i]->set_etat_zero() ;
00489 }
00490 }
00491
00492
00493
00494
00495 void Tensor::allocate_all() {
00496
00497 del_deriv() ;
00498 for (int i=0 ; i<n_comp ; i++) {
00499 cmp[i]->allocate_all() ;
00500 }
00501
00502 }
00503
00504
00505
00506 void Tensor::set_triad(const Base_vect& bi) {
00507
00508 triad = &bi ;
00509
00510 }
00511
00512 int Tensor::position (const Itbl& idx) const {
00513
00514 assert (idx.get_ndim() == 1) ;
00515 assert (idx.get_dim(0) == valence) ;
00516
00517 for (int i=0 ; i<valence ; i++)
00518 assert ((idx(i)>=1) && (idx(i)<=3)) ;
00519 int res = 0 ;
00520 for (int i=0 ; i<valence ; i++)
00521 res = 3*res+(idx(i)-1) ;
00522
00523 return res;
00524 }
00525
00526 Itbl Tensor::indices (int place) const {
00527
00528 assert ((place >= 0) && (place < n_comp)) ;
00529
00530 Itbl res(valence) ;
00531
00532 for (int i=valence-1 ; i>=0 ; i--) {
00533 res.set(i) = div(place, 3).rem ;
00534 place = int((place-res(i))/3) ;
00535 res.set(i)++ ;
00536 }
00537 return res ;
00538 }
00539
00540 void Tensor::operator=(const Tensor& t) {
00541
00542 assert (valence == t.valence) ;
00543
00544 triad = t.triad ;
00545
00546 for (int i=0 ; i<valence ; i++)
00547 assert(t.type_indice(i) == type_indice(i)) ;
00548
00549 for (int i=0 ; i<n_comp ; i++) {
00550 int place_t = t.position(indices(i)) ;
00551 *cmp[i] = *t.cmp[place_t] ;
00552 }
00553
00554 del_deriv() ;
00555
00556 }
00557
00558 void Tensor::operator+=(const Tensor& t) {
00559
00560 assert (valence == t.valence) ;
00561 assert (triad == t.triad) ;
00562 for (int i=0 ; i<valence ; i++)
00563 assert(t.type_indice(i) == type_indice(i)) ;
00564
00565 for (int i=0 ; i<n_comp ; i++) {
00566 int place_t = t.position(indices(i)) ;
00567 *cmp[i] += *t.cmp[place_t] ;
00568 }
00569
00570 del_deriv() ;
00571
00572 }
00573
00574 void Tensor::operator-=(const Tensor& t) {
00575
00576 assert (valence == t.valence) ;
00577 assert (triad == t.triad) ;
00578 for (int i=0 ; i<valence ; i++)
00579 assert(t.type_indice(i) == type_indice(i)) ;
00580
00581 for (int i=0 ; i<n_comp ; i++) {
00582 int place_t = t.position(indices(i)) ;
00583 *cmp[i] -= *t.cmp[place_t] ;
00584 }
00585
00586 del_deriv() ;
00587
00588 }
00589
00590
00591
00592
00593 Scalar& Tensor::set(int ind1, int ind2) {
00594
00595 assert (valence == 2) ;
00596
00597 Itbl ind (valence) ;
00598 ind.set(0) = ind1 ;
00599 ind.set(1) = ind2 ;
00600
00601 int place = position(ind) ;
00602
00603 del_deriv() ;
00604 return *cmp[place] ;
00605 }
00606
00607
00608 Scalar& Tensor::set(int ind1, int ind2, int ind3) {
00609
00610 assert (valence == 3) ;
00611
00612 Itbl idx(valence) ;
00613 idx.set(0) = ind1 ;
00614 idx.set(1) = ind2 ;
00615 idx.set(2) = ind3 ;
00616 int place = position(idx) ;
00617 del_deriv() ;
00618
00619 return *cmp[place] ;
00620 }
00621
00622
00623
00624 Scalar& Tensor::set(int ind1, int ind2, int ind3, int ind4) {
00625
00626 assert (valence == 4) ;
00627
00628 Itbl idx(valence) ;
00629 idx.set(0) = ind1 ;
00630 idx.set(1) = ind2 ;
00631 idx.set(2) = ind3 ;
00632 idx.set(3) = ind4 ;
00633 int place = position(idx) ;
00634 del_deriv() ;
00635
00636 return *cmp[place] ;
00637 }
00638
00639
00640
00641 Scalar& Tensor::set(const Itbl& idx) {
00642
00643 assert (idx.get_ndim() == 1) ;
00644 assert (idx.get_dim(0) == valence) ;
00645
00646 int place = position(idx) ;
00647
00648 del_deriv() ;
00649 return *cmp[place] ;
00650 }
00651
00652
00653 void Tensor::annule_domain(int l) {
00654
00655 annule(l, l) ;
00656 }
00657
00658 void Tensor::annule(int l_min, int l_max) {
00659
00660
00661 if ( (l_min == 0) && (l_max == mp->get_mg()->get_nzone()-1) ) {
00662 set_etat_zero() ;
00663 return ;
00664 }
00665
00666
00667 for (int i=0 ; i<n_comp ; i++) {
00668 cmp[i]->annule(l_min, l_max) ;
00669 }
00670
00671
00672 del_deriv() ;
00673
00674 }
00675
00676
00677 void Tensor::annule_extern_cn(int lrac, int deg) {
00678
00679
00680 assert( mp->get_mg()->get_type_r(lrac) == FIN ) ;
00681
00682 int nz = mp->get_mg()->get_nzone() ;
00683 #ifndef NDEBUG
00684 if ((2*deg+1) >= mp->get_mg()->get_nr(lrac))
00685 cout << "Tensor::annule_extern_cn : \n"
00686 << "WARNING!! \n"
00687 << "The number of coefficients in r is too low \n"
00688 << "to do a clean matching..." << endl ;
00689 #endif
00690
00691 double r_min = mp->val_r(lrac, -1., 0., 0.) ;
00692 double r_max = mp->val_r(lrac, 1., 0., 0.) ;
00693
00694
00695 Itbl binom(deg+1, deg+1) ;
00696 binom.annule_hard() ;
00697 binom.set(0,0) = 1 ;
00698 for (int n=1; n<=deg; n++) {
00699 binom.set(n,0) = 1 ;
00700 for (int k=1; k<=n; k++)
00701 binom.set(n,k) = binom(n-1, k) + binom(n-1, k-1) ;
00702 }
00703
00704
00705 Tbl coef(deg+1) ;
00706 coef.set_etat_qcq() ;
00707 coef.set(deg) = 1 ;
00708 int sg = -1 ;
00709 for (int i=deg-1; i>=0; i--) {
00710
00711 coef.set(i) = double(r_max*(i+1)*coef(i+1)
00712 + sg*binom(deg,i)*(2*deg+1)*pow(r_min,deg-i))
00713 / double(deg+i+1) ;
00714 sg *= -1 ;
00715 }
00716
00717
00718 double aa = coef(deg) ;
00719 for (int i = deg-1; i>=0; i--)
00720 aa = r_min*aa + coef(i) ;
00721 aa *= pow(r_min - r_max, deg+1) ;
00722 aa = 1/aa ;
00723
00724 Mtbl mr = mp->r ;
00725 Tbl rr = mr(lrac) ;
00726
00727 Tbl poly(rr) ;
00728 poly = coef(deg) ;
00729 for (int i=deg-1; i>=0; i--)
00730 poly = rr*poly + coef(i) ;
00731 poly *= aa*pow((rr-r_max), deg+1) ;
00732
00733 Scalar rac(*mp) ;
00734 rac.allocate_all() ;
00735 for (int l=0; l<lrac; l++) rac.set_domain(l) = 1 ;
00736 rac.set_domain(lrac) = poly ;
00737 rac.annule(lrac+1,nz-1) ;
00738 rac.std_spectral_base() ;
00739
00740 for (int ic=0; ic<n_comp; ic++) *(cmp[ic]) *= rac ;
00741
00742 del_deriv() ;
00743 }
00744
00745
00746
00747 const Scalar& Tensor::operator()(int indice1, int indice2) const {
00748
00749 assert(valence == 2) ;
00750
00751 Itbl idx(2) ;
00752 idx.set(0) = indice1 ;
00753 idx.set(1) = indice2 ;
00754 return *cmp[position(idx)] ;
00755
00756 }
00757
00758 const Scalar& Tensor::operator()(int indice1, int indice2, int indice3) const {
00759
00760 assert(valence == 3) ;
00761
00762 Itbl idx(3) ;
00763 idx.set(0) = indice1 ;
00764 idx.set(1) = indice2 ;
00765 idx.set(2) = indice3 ;
00766 return *cmp[position(idx)] ;
00767 }
00768
00769
00770 const Scalar& Tensor::operator()(int indice1, int indice2, int indice3,
00771 int indice4) const {
00772
00773 assert(valence == 4) ;
00774
00775 Itbl idx(4) ;
00776 idx.set(0) = indice1 ;
00777 idx.set(1) = indice2 ;
00778 idx.set(2) = indice3 ;
00779 idx.set(3) = indice4 ;
00780 return *cmp[position(idx)] ;
00781 }
00782
00783
00784
00785 const Scalar& Tensor::operator()(const Itbl& ind) const {
00786
00787 assert (ind.get_ndim() == 1) ;
00788 assert (ind.get_dim(0) == valence) ;
00789 return *cmp[position(ind)] ;
00790
00791 }
00792
00793
00794
00795 void Tensor::dec_dzpuis(int decrem) {
00796
00797 for (int i=0 ; i<n_comp ; i++)
00798 cmp[i]->dec_dzpuis(decrem) ;
00799
00800 del_deriv() ;
00801 }
00802
00803 void Tensor::inc_dzpuis(int inc) {
00804
00805 for (int i=0 ; i<n_comp ; i++)
00806 cmp[i]->inc_dzpuis(inc) ;
00807
00808 del_deriv() ;
00809 }
00810
00811
00812
00813 ostream& operator<<(ostream& flux, const Tensor &source ) {
00814
00815 flux << '\n' ;
00816 flux << "Lorene class : " << typeid(source).name()
00817 << " Valence : " << source.valence << '\n' ;
00818
00819 if (source.get_triad() != 0x0) {
00820 flux << "Vectorial basis (triad) on which the components are defined :"
00821 << '\n' ;
00822 flux << *(source.get_triad()) << '\n' ;
00823 }
00824
00825 if (source.valence != 0) {
00826 flux << "Type of the indices : " ;
00827 for (int i=0 ; i<source.valence ; i++) {
00828 flux << "index " << i << " : " ;
00829 if (source.type_indice(i) == CON)
00830 flux << " contravariant." << '\n' ;
00831 else
00832 flux << " covariant." << '\n' ;
00833 if ( i < source.valence-1 ) flux << " " ;
00834 }
00835 flux << '\n' ;
00836 }
00837
00838 for (int i=0 ; i<source.n_comp ; i++) {
00839
00840 if (source.valence == 0) {
00841 flux <<
00842 "===================== Scalar field ========================= \n" ;
00843 }
00844 else {
00845 flux << "================ Component " ;
00846 Itbl num_indices = source.indices(i) ;
00847 for (int j=0 ; j<source.valence ; j++) {
00848 flux << " " << num_indices(j) ;
00849 }
00850 flux << " ================ \n" ;
00851 }
00852 flux << '\n' ;
00853
00854 flux << *source.cmp[i] << '\n' ;
00855 }
00856
00857 return flux ;
00858 }
00859
00860
00861 void Tensor::spectral_display(const char* comment,
00862 double thres, int precis, ostream& ost) const {
00863
00864 if (comment != 0x0) {
00865 ost << comment << " : " << endl ;
00866 }
00867
00868 ost << "Lorene class : " << typeid(*this).name()
00869 << " Valence : " << valence << '\n' ;
00870
00871 for (int ic=0; ic<n_comp; ic++) {
00872
00873 if (valence == 0) {
00874 ost <<
00875 "===================== Scalar field ========================= \n" ;
00876 }
00877 else {
00878 ost << "================ Component " ;
00879 Itbl num_indices = indices(ic) ;
00880 for (int j=0 ; j<valence ; j++) {
00881 ost << " " << num_indices(j) ;
00882 }
00883 ost << " ================ \n" ;
00884 }
00885 ost << '\n' ;
00886
00887 cmp[ic]->spectral_display(0x0, thres, precis, ost) ;
00888 ost << '\n' ;
00889 }
00890 }
00891
00892
00893 void Tensor::sauve(FILE* fd) const {
00894
00895 type_indice.sauve(fd) ;
00896 fwrite_be(&valence, sizeof(int), 1, fd) ;
00897
00898 if (valence != 0) {
00899 triad->sauve(fd) ;
00900 }
00901
00902 fwrite_be(&n_comp, sizeof(int), 1, fd) ;
00903 for (int i=0 ; i<n_comp ; i++)
00904 cmp[i]->sauve(fd) ;
00905
00906 }
00907
00908
00909
00910
00911
00912
00913
00914 void Tensor::std_spectral_base() {
00915
00916 switch (valence) {
00917
00918 case 0 : {
00919 cmp[0]->std_spectral_base() ;
00920 break ;
00921 }
00922
00923 case 1 : {
00924 cout <<
00925 "Tensor::std_spectral_base: should not be called on a Tensor"
00926 << " of valence 1 but on a Vector !" << endl ;
00927 abort() ;
00928 break ;
00929 }
00930
00931 case 2 : {
00932
00933 Base_val** bases = 0x0 ;
00934 if( triad->identify() == (mp->get_bvect_cart()).identify() ) {
00935 bases = mp->get_mg()->std_base_vect_cart() ;
00936 }
00937 else {
00938 assert( triad->identify() == (mp->get_bvect_spher()).identify()) ;
00939 bases = mp->get_mg()->std_base_vect_spher() ;
00940 }
00941
00942 Itbl ind(2) ;
00943 for (int i=0 ; i<n_comp ; i++) {
00944 ind = indices(i) ;
00945 cmp[i]->set_spectral_base( (*bases[ind(0)-1]) *
00946 (*bases[ind(1)-1]) ) ;
00947 }
00948
00949 for (int i=0 ; i<3 ; i++) {
00950 delete bases[i] ;
00951 }
00952 delete [] bases ;
00953 break ;
00954
00955 }
00956
00957
00958 default : {
00959
00960 cout << "Tensor::std_spectral_base: the case valence = " << valence
00961 << " is not treated yet !" << endl ;
00962 abort() ;
00963 break ;
00964 }
00965 }
00966 }
00967
00968
00969
00970 void Tensor::std_spectral_base_odd() {
00971
00972 switch (valence) {
00973
00974 case 0 : {
00975 cmp[0]->std_spectral_base_odd() ;
00976 break ;
00977 }
00978
00979 default : {
00980
00981 cout << "Tensor::std_spectral_base_odd: the case valence = " << valence
00982 << " is not treated yet !" << endl ;
00983 abort() ;
00984 break ;
00985 }
00986 }
00987 }
00988
00989
00990 const Tensor& Tensor::derive_cov(const Metric& metre) const {
00991
00992 set_dependance(metre) ;
00993 int j = get_place_met(metre) ;
00994 assert ((j>=0) && (j<N_MET_MAX)) ;
00995 if (p_derive_cov[j] == 0x0) {
00996 p_derive_cov[j] = metre.connect().p_derive_cov(*this) ;
00997 }
00998 return *p_derive_cov[j] ;
00999 }
01000
01001
01002 const Tensor& Tensor::derive_con(const Metric& metre) const {
01003
01004 set_dependance(metre) ;
01005 int j = get_place_met(metre) ;
01006 assert ((j>=0) && (j<N_MET_MAX)) ;
01007 if (p_derive_con[j] == 0x0) {
01008
01009 if (valence == 0) {
01010 p_derive_con[j] =
01011 new Vector( contract(derive_cov(metre), 0, metre.con(), 0) ) ;
01012 }
01013 else {
01014 const Tensor_sym* tsym = dynamic_cast<const Tensor_sym*>(this) ;
01015
01016 if (tsym != 0x0) {
01017 const Tensor& dercov = derive_cov(metre) ;
01018 Itbl type_ind = dercov.get_index_type() ;
01019 type_ind.set(valence) = CON ;
01020 p_derive_con[j] = new Tensor_sym(*mp, valence+1, type_ind, *triad,
01021 tsym->sym_index1(), tsym->sym_index2()) ;
01022
01023 *(p_derive_con[j]) = contract(dercov, valence, metre.con(), 0) ;
01024
01025
01026 }
01027 else {
01028
01029 p_derive_con[j] = new Tensor( contract(derive_cov(metre), valence,
01030 metre.con(), 0) ) ;
01031
01032
01033 }
01034
01035 }
01036
01037 }
01038
01039 return *p_derive_con[j] ;
01040
01041 }
01042
01043 const Tensor& Tensor::divergence(const Metric& metre) const {
01044
01045 set_dependance(metre) ;
01046 int j = get_place_met(metre) ;
01047 assert ((j>=0) && (j<N_MET_MAX)) ;
01048 if (p_divergence[j] == 0x0) {
01049 p_divergence[j] = metre.connect().p_divergence(*this) ;
01050 }
01051 return *p_divergence[j] ;
01052 }
01053
01054 void Tensor::exponential_filter_r(int lzmin, int lzmax, int p,
01055 double alpha) {
01056 if( triad->identify() == (mp->get_bvect_cart()).identify() )
01057 for (int i=0; i<n_comp; i++)
01058 cmp[i]->exponential_filter_r(lzmin, lzmax, p, alpha) ;
01059 else {
01060 cout << "Tensor::exponential_filter_r : " << endl ;
01061 cout << "Only Cartesian triad is implemented!" << endl ;
01062 cout << "Exiting..." << endl ;
01063 abort() ;
01064 }
01065 }
01066
01067 void Tensor::exponential_filter_ylm(int lzmin, int lzmax, int p,
01068 double alpha) {
01069 if( triad->identify() == (mp->get_bvect_cart()).identify() )
01070 for (int i=0; i<n_comp; i++)
01071 cmp[i]->exponential_filter_ylm(lzmin, lzmax, p, alpha) ;
01072 else {
01073 cout << "Tensor::exponential_filter_ylm : " << endl ;
01074 cout << "Only Cartesian triad is implemented!" << endl ;
01075 cout << "Exiting..." << endl ;
01076 abort() ;
01077 }
01078 }
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092