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_sym_operateur_C[] = "$Header: /cvsroot/Lorene/C++/Source/Tenseur/tenseur_sym_operateur.C,v 1.6 2003/03/03 19:41:34 f_limousin 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 #include <stdlib.h>
00070 #include <assert.h>
00071 #include <math.h>
00072
00073
00074 #include "tenseur.h"
00075 #include "metrique.h"
00076
00077 Tenseur_sym operator*(const Tenseur& t1, const Tenseur_sym& t2) {
00078
00079 assert ((t1.get_etat() != ETATNONDEF) && (t2.etat != ETATNONDEF)) ;
00080 assert (t1.get_mp() == t2.mp) ;
00081
00082 int val_res = t1.get_valence() + t2.valence ;
00083 double poids_res = t1.get_poids() + t2.poids ;
00084 poids_res = (fabs(poids_res) < 1.e-10 ? 0. : poids_res) ;
00085 const Metrique* met_res = 0x0 ;
00086 if (poids_res != 0.) {
00087
00088 if (t1.get_metric() != 0x0) met_res = t1.get_metric() ;
00089 else met_res = t2.metric ;
00090 }
00091
00092 Itbl tipe (val_res) ;
00093 tipe.set_etat_qcq() ;
00094 for (int i=0 ; i<t1.get_valence() ; i++)
00095 tipe.set(i) = t1.get_type_indice(i) ;
00096 for (int i=0 ; i<t2.valence ; i++)
00097 tipe.set(i+t1.get_valence()) = t2.type_indice(i) ;
00098
00099
00100 if ( t1.get_valence() != 0 ) {
00101 assert ( *(t1.get_triad()) == *(t2.get_triad()) ) ;
00102 }
00103
00104 Tenseur_sym res(*t1.get_mp(), val_res, tipe, *(t2.get_triad()),
00105 met_res, poids_res) ;
00106
00107
00108 if ((t1.get_etat() == ETATZERO) || (t2.etat == ETATZERO))
00109 res.set_etat_zero() ;
00110 else {
00111 res.set_etat_qcq() ;
00112 Itbl jeux_indice_t1 (t1.get_valence()) ;
00113 jeux_indice_t1.set_etat_qcq() ;
00114 Itbl jeux_indice_t2 (t2.valence) ;
00115 jeux_indice_t2.set_etat_qcq() ;
00116
00117 for (int i=0 ; i<res.n_comp ; i++) {
00118 Itbl jeux_indice_res(res.donne_indices(i)) ;
00119 for (int j=0 ; j<t1.get_valence() ; j++)
00120 jeux_indice_t1.set(j) = jeux_indice_res(j) ;
00121 for (int j=0 ; j<t2.valence ; j++)
00122 jeux_indice_t2.set(j) = jeux_indice_res(j+t1.get_valence()) ;
00123
00124 res.set(jeux_indice_res) = t1(jeux_indice_t1)*t2(jeux_indice_t2) ;
00125 }
00126 }
00127 return res ;
00128 }
00129
00130 Tenseur_sym manipule (const Tenseur_sym& t1, const Metrique& met) {
00131
00132 Tenseur* auxi ;
00133 Tenseur* auxi_old = new Tenseur(t1) ;
00134
00135 for (int i=0 ; i<t1.valence ; i++) {
00136 auxi = new Tenseur(manipule(*auxi_old, met, i)) ;
00137 delete auxi_old ;
00138 auxi_old = new Tenseur(*auxi) ;
00139 delete auxi ;
00140 }
00141
00142 Tenseur_sym result(*auxi_old) ;
00143 delete auxi_old ;
00144 return result ;
00145 }
00146
00147 Tenseur_sym lie_derive (const Tenseur_sym& t, const Tenseur& x,
00148 const Metrique* met)
00149 {
00150 assert ( (t.get_etat() != ETATNONDEF) && (x.get_etat() != ETATNONDEF) ) ;
00151 assert(x.get_valence() == 1) ;
00152 assert(x.get_type_indice(0) == CON) ;
00153 assert(x.get_poids() == 0.) ;
00154 assert(t.get_mp() == x.get_mp()) ;
00155
00156 int val = t.get_valence() ;
00157 double poids = t.get_poids() ;
00158 Itbl tipe (val+1) ;
00159 tipe.set_etat_qcq() ;
00160 tipe.set(0) = COV ;
00161 Itbl tipx(2) ;
00162 tipx.set_etat_qcq() ;
00163 tipx.set(0) = COV ;
00164 tipx.set(1) = CON ;
00165 for (int i=0 ; i<val ; i++)
00166 tipe.set(i+1) = t.get_type_indice(i) ;
00167 Tenseur_sym dt(*t.get_mp(), val+1, tipe, *t.get_triad(), t.get_metric(),
00168 poids) ;
00169 Tenseur dx(*x.get_mp(), 2, tipx, x.get_triad()) ;
00170 if (met == 0x0) {
00171 dx = x.gradient() ;
00172 dt = t.gradient() ;
00173 }
00174 else {
00175 dx = x.derive_cov(*met) ;
00176 dt = t.derive_cov(*met) ;
00177 }
00178 Tenseur_sym resu(contract(x,0,dt,0)) ;
00179 Tenseur* auxi ;
00180 if ((val!=0)&&(t.get_etat()!=ETATZERO)&&(x.get_etat()!=ETATZERO)) {
00181 assert(t.get_triad()->identify() == x.get_triad()->identify()) ;
00182
00183 for (int i=0 ; i<val ; i++) {
00184 if (t.get_type_indice(i) == COV) {
00185 auxi = new Tenseur(contract(t,i,dx,1)) ;
00186
00187 Itbl indices_aux(val) ;
00188 indices_aux.set_etat_qcq() ;
00189 for (int j=0 ; j<resu.get_n_comp() ; j++) {
00190
00191 Itbl indices (resu.donne_indices(j)) ;
00192 indices_aux.set(val-1) = indices(i) ;
00193 for (int idx=0 ; idx<val-1 ; idx++)
00194 if (idx<i)
00195 indices_aux.set(idx) = indices(idx) ;
00196 else
00197 indices_aux.set(idx) = indices(idx+1) ;
00198
00199 resu.set(indices) += (*auxi)(indices_aux) ;
00200 }
00201 }
00202 else {
00203 auxi = new Tenseur(contract(t,i,dx,0)) ;
00204
00205 Itbl indices_aux(val) ;
00206 indices_aux.set_etat_qcq() ;
00207
00208
00209 for (int j=0 ; j<resu.get_n_comp() ; j++) {
00210
00211 Itbl indices (resu.donne_indices(j)) ;
00212 indices_aux.set(val-1) = indices(i) ;
00213 for (int idx=0 ; idx<val-1 ; idx++)
00214 if (idx<i)
00215 indices_aux.set(idx) = indices(idx) ;
00216 else
00217 indices_aux.set(idx) = indices(idx+1) ;
00218 resu.set(indices) -= (*auxi)(indices_aux) ;
00219 }
00220 }
00221 delete auxi ;
00222 }
00223 }
00224 if ((poids != 0.)&&(t.get_etat()!=ETATZERO)&&(x.get_etat()!=ETATZERO))
00225 resu = resu + poids*contract(dx,0,1)*t ;
00226
00227 return resu ;
00228 }
00229
00230 Tenseur_sym sans_trace(const Tenseur_sym& t, const Metrique& metre)
00231 {
00232 assert(t.get_etat() != ETATNONDEF) ;
00233 assert(metre.get_etat() != ETATNONDEF) ;
00234 assert(t.get_valence() == 2) ;
00235
00236 Tenseur_sym resu(t) ;
00237 if (resu.get_etat() == ETATZERO) return resu ;
00238 assert(resu.get_etat() == ETATQCQ) ;
00239
00240 int t0 = t.get_type_indice(0) ;
00241 int t1 = t.get_type_indice(1) ;
00242 Itbl mix(2) ;
00243 mix.set_etat_qcq() ;
00244 mix.set(0) = (t0 == t1 ? -t0 : t0) ;
00245 mix.set(1) = t1 ;
00246
00247 Tenseur tmp(*t.get_mp(), 2, mix, *t.get_triad(), t.get_metric(),
00248 t.get_poids()) ;
00249 if (t0 == t1)
00250 tmp = manipule(t, metre, 0) ;
00251 else
00252 tmp = t ;
00253
00254 Tenseur trace(contract(tmp, 0, 1)) ;
00255
00256 if (t0 == t1) {
00257 switch (t0) {
00258 case COV : {
00259 resu = resu - 1./3.*trace * metre.cov() ;
00260 break ;
00261 }
00262 case CON : {
00263 resu = resu - 1./3.*trace * metre.con() ;
00264 break ;
00265 }
00266 default :
00267 cout << "Erreur bizarre dans sans_trace!" << endl ;
00268 abort() ;
00269 break ;
00270 }
00271 }
00272 else {
00273 Tenseur_sym delta(*t.get_mp(), 2, mix, *t.get_triad(),
00274 t.get_metric(), t.get_poids()) ;
00275 delta.set_etat_qcq() ;
00276 for (int i=0; i<3; i++)
00277 for (int j=i; j<3; j++)
00278 delta.set(i,j) = (i==j ? 1 : 0) ;
00279 resu = resu - trace/3. * delta ;
00280 }
00281 resu.set_std_base() ;
00282 return resu ;
00283 }