LORENE
tenseur.C
1/*
2 * Methods of class Tenseur
3 *
4 * (see file tenseur.h for documentation)
5 *
6 */
7
8/*
9 * Copyright (c) 1999-2001 Philippe Grandclement
10 * Copyright (c) 2000-2001 Eric Gourgoulhon
11 * Copyright (c) 2002 Jerome Novak
12 *
13 * This file is part of LORENE.
14 *
15 * LORENE is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * LORENE is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with LORENE; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 *
29 */
30
31
32
33
34/*
35 * $Id: tenseur.C,v 1.17 2018/11/16 14:34:37 j_novak Exp $
36 * $Log: tenseur.C,v $
37 * Revision 1.17 2018/11/16 14:34:37 j_novak
38 * Changed minor points to avoid some compilation warnings.
39 *
40 * Revision 1.16 2016/12/05 16:18:16 j_novak
41 * Suppression of some global variables (file names, loch, ...) to prevent redefinitions
42 *
43 * Revision 1.15 2014/10/13 08:53:41 j_novak
44 * Lorene classes and functions now belong to the namespace Lorene.
45 *
46 * Revision 1.14 2014/10/06 15:13:18 j_novak
47 * Modified #include directives to use c++ syntax.
48 *
49 * Revision 1.13 2003/03/03 19:37:31 f_limousin
50 * Suppression of many assert(verif()).
51 *
52 * Revision 1.12 2002/10/16 14:37:14 j_novak
53 * Reorganization of #include instructions of standard C++, in order to
54 * use experimental version 3 of gcc.
55 *
56 * Revision 1.11 2002/09/06 14:49:25 j_novak
57 * Added method lie_derive for Tenseur and Tenseur_sym.
58 * Corrected various errors for derive_cov and arithmetic.
59 *
60 * Revision 1.10 2002/08/30 13:21:38 j_novak
61 * Corrected error in constructor
62 *
63 * Revision 1.9 2002/08/14 13:46:15 j_novak
64 * Derived quantities of a Tenseur can now depend on several Metrique's
65 *
66 * Revision 1.8 2002/08/13 08:02:45 j_novak
67 * Handling of spherical vector/tensor components added in the classes
68 * Mg3d and Tenseur. Minor corrections for the class Metconf.
69 *
70 * Revision 1.7 2002/08/08 15:10:45 j_novak
71 * The flag "plat" has been added to the class Metrique to show flat metrics.
72 *
73 * Revision 1.6 2002/08/07 16:14:11 j_novak
74 * class Tenseur can now also handle tensor densities, this should be transparent to older codes
75 *
76 * Revision 1.5 2002/08/02 15:07:41 j_novak
77 * Member function determinant has been added to the class Metrique.
78 * A better handling of spectral bases is now implemented for the class Tenseur.
79 *
80 * Revision 1.4 2002/05/07 07:36:03 e_gourgoulhon
81 * Compatibilty with xlC compiler on IBM SP2:
82 * suppressed the parentheses around argument of instruction new:
83 * e.g. t = new (Tbl *[nzone]) --> t = new Tbl*[nzone]
84 *
85 * Revision 1.3 2002/05/02 15:16:22 j_novak
86 * Added functions for more general bi-fluid EOS
87 *
88 * Revision 1.2 2001/12/04 21:27:54 e_gourgoulhon
89 *
90 * All writing/reading to a binary file are now performed according to
91 * the big endian convention, whatever the system is big endian or
92 * small endian, thanks to the functions fwrite_be and fread_be
93 *
94 * Revision 1.1.1.1 2001/11/20 15:19:30 e_gourgoulhon
95 * LORENE
96 *
97 * Revision 2.21 2001/10/10 13:54:40 eric
98 * Modif Joachim: pow(3, *) --> pow(3., *)
99 *
100 * Revision 2.20 2000/12/20 09:50:08 eric
101 * Correction erreur dans operator<< : la sortie doit etre flux et non cout !
102 *
103 * Revision 2.19 2000/10/12 13:11:23 eric
104 * Methode set_std_base(): traitement du cas etat = ETATZERO (return).
105 *
106 * Revision 2.18 2000/09/13 12:11:40 eric
107 * Ajout de la fonction allocate_all().
108 *
109 * Revision 2.17 2000/05/22 14:40:09 phil
110 * ajout de inc_dzpuis et dec_dzpuis
111 *
112 * Revision 2.16 2000/03/22 09:18:57 eric
113 * Traitement du cas ETATZERO dans dec2_dzpuis, inc2_dzpuis et mult_r_zec.
114 *
115 * Revision 2.15 2000/02/12 11:35:58 eric
116 * Modif de la fonction set_std_base : appel de Valeur::set_base plutot
117 * que l'affectation directe du membre Valeur::base.
118 *
119 * Revision 2.14 2000/02/10 18:30:47 eric
120 * La fonction set_triad ne fait plus que l'affectation du membre triad.
121 *
122 * Revision 2.13 2000/02/10 16:11:07 eric
123 * Ajout de la fonction change_triad.
124 *
125 * Revision 2.12 2000/02/09 19:32:39 eric
126 * MODIF IMPORTANTE: la triade de decomposition est desormais passee en
127 * argument des constructeurs.
128 *
129 * Revision 2.11 2000/01/24 13:02:39 eric
130 * Traitement du cas triad = 0x0 dans la sauvegarde/lecture fichier
131 * Constructeur par lecture de fichier: met_depend est desormais initialise
132 * a 0x0.
133 *
134 * Revision 2.10 2000/01/20 16:02:57 eric
135 * Ajout des operator=(double ) et operator=(int ).
136 *
137 * Revision 2.9 2000/01/20 15:34:39 phil
138 * changement traid dans fait_gradient()
139 *
140 * Revision 2.8 2000/01/14 14:07:26 eric
141 * Ajout de la fonction annule.
142 *
143 * Revision 2.7 2000/01/13 14:10:53 eric
144 * Ajout du constructeur par copie d'un Cmp (pour un scalaire)
145 * ainsi que l'affectation a un Cmp.
146 *
147 * Revision 2.6 2000/01/13 13:46:38 eric
148 * Ajout du membre p_gradient_spher et des fonctions fait_gradient_spher(),
149 * gradient_spher() pour le calcul du gradient d'un scalaire en
150 * coordonnees spheriques sur la triade spherique associee.
151 *
152 * Revision 2.5 2000/01/12 13:19:04 eric
153 * Les operator::(...) renvoient desormais une reference const sur le c[...]
154 * correspondant et non plus un Cmp copie de c[...].
155 * (ceci grace a la nouvelle fonction Map::cmp_zero()).
156 *
157 * Revision 2.4 2000/01/11 11:13:59 eric
158 * Changement de nom pour la base vectorielle : base --> triad
159 *
160 * Revision 2.3 2000/01/10 17:23:07 eric
161 * Modif affichage.
162 * Methode fait_derive_cov : ajout de
163 * assert( metre.gamma().get_base() == base )
164 * Methode set_std_base : ajout de
165 * assert( *base == mp->get_bvect_cart() )
166 *
167 * Revision 2.2 2000/01/10 15:15:26 eric
168 * Ajout du membre base (base vectorielle sur laquelle sont definies
169 * les composantes).
170 *
171 * Revision 2.1 1999/12/09 12:39:23 phil
172 * changement prototypage des derivees
173 *
174 * Revision 2.0 1999/12/02 17:18:31 phil
175 * *** empty log message ***
176 *
177 *
178 * $Header: /cvsroot/Lorene/C++/Source/Tenseur/tenseur.C,v 1.17 2018/11/16 14:34:37 j_novak Exp $
179 *
180 */
181
182// Headers C
183#include <cstdlib>
184#include <cassert>
185#include <cmath>
186
187// Headers Lorene
188#include "tenseur.h"
189#include "metrique.h"
190#include "utilitaires.h"
191
192 //--------------//
193 // Constructors //
194 //--------------//
195// Consistency check for tensor densities
196//---------------------------------------
197namespace Lorene {
198bool Tenseur::verif() const {
199 return ( (poids == 0.) || (metric != 0x0) ) ;
200}
201
203 met_depend = new const Metrique*[N_MET_MAX] ;
204 p_derive_cov = new Tenseur*[N_MET_MAX] ;
205 p_derive_con = new Tenseur*[N_MET_MAX] ;
206 p_carre_scal = new Tenseur*[N_MET_MAX] ;
207 for (int i=0; i<N_MET_MAX; i++) {
208 met_depend[i] = 0x0 ;
209 }
210 set_der_0x0() ;
211}
212
213// Constructor for a scalar field
214// ------------------------------
215Tenseur::Tenseur (const Map& map, const Metrique* met, double weight) :
216 mp(&map), valence(0), triad(0x0),
217 type_indice(0), n_comp(1), etat(ETATNONDEF), poids(weight),
218 metric(met) {
219
220 // assert(verif()) ;
221 c = new Cmp*[n_comp] ;
222 c[0] = 0x0 ;
223 new_der_met() ;
224}
225
226
227
228// Constructor for a scalar field and from a {\tt Cmp}
229// ---------------------------------------------------
230Tenseur::Tenseur (const Cmp& ci, const Metrique* met, double weight) :
231 mp(ci.get_mp()), valence(0), triad(0x0),
232 type_indice(0), n_comp(1), etat(ci.get_etat()), poids(weight),
233 metric(met){
234
235 assert(ci.get_etat() != ETATNONDEF) ;
236 assert(verif()) ;
237
238 c = new Cmp*[n_comp] ;
239
240 if ( ci.get_etat() != ETATZERO ) {
241 assert( ci.get_etat() == ETATQCQ ) ;
242 c[0] = new Cmp(ci) ;
243 }
244 else {
245 c[0] = 0x0 ;
246 }
247 new_der_met() ;
248}
249
250// Standard constructor
251// --------------------
252Tenseur::Tenseur(const Map& map, int val, const Itbl& tipe,
253 const Base_vect& triad_i, const Metrique* met, double weight)
254 : mp(&map), valence(val), triad(&triad_i), type_indice(tipe),
255 n_comp(int(pow(3., val))), etat(ETATNONDEF), poids(weight),
256 metric(met){
257
258 // Des verifs :
259 assert (valence >= 0) ;
260 assert (tipe.get_ndim() == 1) ;
261 assert (valence == tipe.get_dim(0)) ;
262 for (int i=0 ; i<valence ; i++)
263 assert ((tipe(i) == COV) || (tipe(i) == CON)) ;
264 assert(verif()) ;
265
266 c = new Cmp*[n_comp] ;
267 for (int i=0 ; i<n_comp ; i++)
268 c[i] = 0x0 ;
269 new_der_met() ;
270}
271
272// Standard constructor with the triad passed as a pointer
273// -------------------------------------------------------
274Tenseur::Tenseur(const Map& map, int val, const Itbl& tipe,
275 const Base_vect* triad_i, const Metrique* met, double weight)
276 : mp(&map), valence(val), triad(triad_i), type_indice(tipe),
277 n_comp(int(pow(3., val))), etat(ETATNONDEF), poids(weight),
278 metric(met){
279
280 // Des verifs :
281 assert (valence >= 0) ;
282 assert (tipe.get_ndim() == 1) ;
283 assert (valence == tipe.get_dim(0)) ;
284 for (int i=0 ; i<valence ; i++)
285 assert ((tipe(i) == COV) || (tipe(i) == CON)) ;
286 // assert(verif()) ;
287
288 if (valence == 0) { // particular case of a scalar
289 triad = 0x0 ;
290 }
291
292 c = new Cmp*[n_comp] ;
293 for (int i=0 ; i<n_comp ; i++)
294 c[i] = 0x0 ;
295 new_der_met() ;
296}
297
298
299
300
301// Standard constructor when all the indices are of the same type
302// --------------------------------------------------------------
303Tenseur::Tenseur(const Map& map, int val, int tipe, const Base_vect& triad_i,
304 const Metrique* met, double weight)
305 : mp(&map), valence(val), triad(&triad_i), type_indice(val),
306 n_comp(int(pow(3., val))), etat (ETATNONDEF), poids(weight),
307 metric(met){
308
309 // Des verifs :
310 assert (valence >= 0) ;
311 assert ((tipe == COV) || (tipe == CON)) ;
312 assert(verif()) ;
313 type_indice.set_etat_qcq() ;
314 type_indice = tipe ;
315
316 c = new Cmp*[n_comp] ;
317 for (int i=0 ; i<n_comp ; i++)
318 c[i] = 0x0 ;
319 new_der_met() ;
320}
321
322// Copy constructor
323// ----------------
324Tenseur::Tenseur (const Tenseur& source) :
325 mp(source.mp), valence(source.valence), triad(source.triad),
326 type_indice(source.type_indice), etat (source.etat), poids(source.poids),
327 metric(source.metric) {
328
329 // assert(verif()) ;
330
331 n_comp = int(pow(3., valence)) ;
332
333 c = new Cmp*[n_comp] ;
334 for (int i=0 ; i<n_comp ; i++) {
335 int place_source = source.donne_place(donne_indices(i)) ;
336 if (source.c[place_source] == 0x0)
337 c[i] = 0x0 ;
338 else
339 c[i] = new Cmp(*source.c[place_source]) ;
340 }
341
342 assert(source.met_depend != 0x0) ;
343 assert(source.p_derive_cov != 0x0) ;
344 assert(source.p_derive_con != 0x0) ;
345 assert(source.p_carre_scal != 0x0) ;
346 new_der_met() ;
347
348 if (source.p_gradient != 0x0)
349 p_gradient = new Tenseur (*source.p_gradient) ;
350
351 if (source.p_gradient_spher != 0x0)
353
354 for (int i=0; i<N_MET_MAX; i++) {
355 met_depend[i] = source.met_depend[i] ;
356 if (met_depend[i] != 0x0) {
357
359
360 if (source.p_derive_cov[i] != 0x0)
361 p_derive_cov[i] = new Tenseur (*source.p_derive_cov[i]) ;
362 if (source.p_derive_con[i] != 0x0)
363 p_derive_con[i] = new Tenseur (*source.p_derive_con[i]) ;
364 if (source.p_carre_scal[i] != 0x0)
365 p_carre_scal[i] = new Tenseur (*source.p_carre_scal[i]) ;
366 }
367 }
368}
369
370// Constructor from a symmetric tensor
371// -----------------------------------
372Tenseur::Tenseur (const Tenseur_sym& source) :
373 mp(source.mp), valence(source.valence), triad(source.triad),
374 type_indice(source.type_indice), etat(source.etat),
375 poids(source.poids), metric(source.metric) {
376
377 assert(verif()) ;
378 n_comp = int(pow(3., valence)) ;
379
380 c = new Cmp*[n_comp] ;
381 for (int i=0 ; i<n_comp ; i++) {
382 int place_source = source.donne_place(donne_indices(i)) ;
383 if (source.c[place_source] == 0x0)
384 c[i] = 0x0 ;
385 else
386 c[i] = new Cmp(*source.c[place_source]) ;
387 }
388
389 assert(source.met_depend != 0x0) ;
390 assert(source.p_derive_cov != 0x0) ;
391 assert(source.p_derive_con != 0x0) ;
392 assert(source.p_carre_scal != 0x0) ;
393 new_der_met() ;
394
395 if (source.p_gradient != 0x0)
396 p_gradient = new Tenseur_sym (*source.p_gradient) ;
397
398 for (int i=0; i<N_MET_MAX; i++) {
399 met_depend[i] = source.met_depend[i] ;
400 if (met_depend[i] != 0x0) {
401
403
404 if (source.p_derive_cov[i] != 0x0)
405 p_derive_cov[i] = new Tenseur (*source.p_derive_cov[i]) ;
406 if (source.p_derive_con[i] != 0x0)
407 p_derive_con[i] = new Tenseur (*source.p_derive_con[i]) ;
408 if (source.p_carre_scal[i] != 0x0)
409 p_carre_scal[i] = new Tenseur (*source.p_carre_scal[i]) ;
410 }
411 }
412
413}
414
415// Constructor from a file
416// -----------------------
417Tenseur::Tenseur(const Map& mapping, const Base_vect& triad_i, FILE* fd,
418 const Metrique* met)
419 : mp(&mapping), triad(&triad_i), type_indice(fd),
420 metric(met) {
421
422 fread_be(&valence, sizeof(int), 1, fd) ;
423
424 if (valence != 0) {
425 Base_vect* triad_fich = Base_vect::bvect_from_file(fd) ;
426 assert( *triad_fich == *triad) ;
427 delete triad_fich ;
428 }
429 else{
430 triad = 0x0 ;
431 }
432
433 fread_be(&n_comp, sizeof(int), 1, fd) ;
434 fread_be(&etat, sizeof(int), 1, fd) ;
435
436 c = new Cmp*[n_comp] ;
437 for (int i=0 ; i<n_comp ; i++)
438 c[i] = 0x0 ;
439 if (etat == ETATQCQ)
440 for (int i=0 ; i<n_comp ; i++)
441 c[i] = new Cmp(*mp, *mp->get_mg(), fd) ;
442
443 new_der_met() ;
444
445 if (met == 0x0)
446 poids = 0. ;
447 else
448 fread_be(&poids, sizeof(double), 1, fd) ;
449}
450
451
452// Constructor from a file for a scalar field
453// ------------------------------------------
454Tenseur::Tenseur (const Map& mapping, FILE* fd, const Metrique* met)
455 : mp(&mapping), type_indice(fd), metric(met){
456
457 fread_be(&valence, sizeof(int), 1, fd) ;
458
459 assert(valence == 0) ;
460
461 triad = 0x0 ;
462
463 fread_be(&n_comp, sizeof(int), 1, fd) ;
464
465 assert(n_comp == 1) ;
466
467 fread_be(&etat, sizeof(int), 1, fd) ;
468
469 c = new Cmp*[n_comp] ;
470
471 if (etat == ETATQCQ) {
472 c[0] = new Cmp(*mp, *mp->get_mg(), fd) ;
473 }
474 else{
475 c[0] = 0x0 ;
476 }
477
478 new_der_met() ;
479
480 if (met == 0x0)
481 poids = 0. ;
482 else
483 fread_be(&poids, sizeof(double), 1, fd) ;
484}
485
486
487
488
489// Constructor used by the derived classes
490// ---------------------------------------
491Tenseur::Tenseur (const Map& map, int val, const Itbl& tipe, int compo,
492 const Base_vect& triad_i, const Metrique* met, double weight) :
493 mp(&map), valence(val), triad(&triad_i), type_indice(tipe), n_comp(compo),
494 etat (ETATNONDEF), poids(weight), metric(met) {
495
496 // Des verifs :
497 assert (valence >= 0) ;
498 assert (tipe.get_ndim() == 1) ;
499 assert (n_comp > 0) ;
500 assert (valence == tipe.get_dim(0)) ;
501 for (int i=0 ; i<valence ; i++)
502 assert ((tipe(i) == COV) || (tipe(i) == CON)) ;
503 //assert(verif()) ;
504
505 c = new Cmp*[n_comp] ;
506 for (int i=0 ; i<n_comp ; i++)
507 c[i] = 0x0 ;
508
509 new_der_met() ;
510}
511
512// Constructor used by the derived classes when all the indices are of
513// the same type.
514// -------------------------------------------------------------------
515Tenseur::Tenseur (const Map& map, int val, int tipe, int compo,
516 const Base_vect& triad_i, const Metrique* met, double weight) :
517 mp(&map), valence(val), triad(&triad_i), type_indice(val), n_comp(compo),
518 etat (ETATNONDEF), poids(weight), metric(met) {
519 // Des verifs :
520 assert (valence >= 0) ;
521 assert (n_comp >= 0) ;
522 assert ((tipe == COV) || (tipe == CON)) ;
523 //assert(verif()) ;
524 type_indice.set_etat_qcq() ;
525 type_indice = tipe ;
526
527 c = new Cmp*[n_comp] ;
528 for (int i=0 ; i<n_comp ; i++)
529 c[i] = 0x0 ;
530
531 new_der_met() ;
532}
533
534 //--------------//
535 // Destructor //
536 //--------------//
537
538
540
541 del_t() ;
542 delete [] met_depend ;
543 delete [] p_derive_cov ;
544 delete [] p_derive_con ;
545 delete [] p_carre_scal ;
546 delete [] c ;
547}
548
549
550
552 del_derive() ;
553 for (int i=0 ; i<n_comp ; i++)
554 if (c[i] != 0x0) {
555 delete c[i] ;
556 c[i] = 0x0 ;
557 }
558}
559
560void Tenseur::del_derive_met(int j) const {
561
562 assert( (j>=0) && (j<N_MET_MAX) ) ;
563 // On gere la metrique ...
564 if (met_depend[j] != 0x0) {
565 for (int i=0 ; i<N_DEPEND ; i++)
566 if (met_depend[j]->dependances[i] == this)
567 met_depend[j]->dependances[i] = 0x0 ;
568 if (p_derive_cov[j] != 0x0)
569 delete p_derive_cov[j] ;
570 if (p_derive_con[j] != 0x0)
571 delete p_derive_con[j] ;
572 if (p_carre_scal[j] != 0x0)
573 delete p_carre_scal[j] ;
574 set_der_met_0x0(j) ;
575 }
576}
577
578
579void Tenseur::del_derive () const {
580 for (int i=0; i<N_MET_MAX; i++)
581 del_derive_met(i) ;
582 if (p_gradient != 0x0)
583 delete p_gradient ;
584 if (p_gradient_spher != 0x0)
585 delete p_gradient_spher ;
586 set_der_0x0() ;
587}
588
589void Tenseur::set_der_met_0x0(int i) const {
590 met_depend[i] = 0x0 ;
591 p_derive_cov[i] = 0x0 ;
592 p_derive_con[i] = 0x0 ;
593 p_carre_scal[i] = 0x0 ;
594}
595
596
598 for (int i=0; i<N_MET_MAX; i++)
599 set_der_met_0x0(i) ;
600 p_gradient = 0x0 ;
601 p_gradient_spher = 0x0 ;
602}
603
604int Tenseur::get_place_met(const Metrique& metre) const {
605 int resu = -1 ;
606 for (int i=0; i<N_MET_MAX; i++)
607 if (met_depend[i] == &metre) {
608 assert(resu == -1) ;
609 resu = i ;
610 }
611 return resu ;
612}
613
614void Tenseur::set_dependance (const Metrique& met) const {
615
616 int nmet = 0 ;
617 bool deja = false ;
618 for (int i=0; i<N_MET_MAX; i++) {
619 if (met_depend[i] == &met) deja = true ;
620 if ((!deja) && (met_depend[i] != 0x0)) nmet++ ;
621 }
622 if (nmet == N_MET_MAX) {
623 cout << "Too many metrics in Tenseur::set_dependances" << endl ;
624 abort() ;
625 }
626 if (!deja) {
627 int conte = 0 ;
628 while ((conte < N_DEPEND) && (met.dependances[conte] != 0x0))
629 conte ++ ;
630
631 if (conte == N_DEPEND) {
632 cout << "Too many dependancies in Tenseur::set_dependances " << endl ;
633 abort() ;
634 }
635 else {
636 met.dependances[conte] = this ;
637 met_depend[nmet] = &met ;
638 }
639 }
640}
641
643
644 del_derive() ;
645 for (int i=0 ; i<n_comp ; i++)
646 if (c[i] == 0x0)
647 c[i] = new Cmp(mp) ;
648 etat = ETATQCQ ;
649}
650
652 del_t() ;
653 etat = ETATZERO ;
654}
655
657 del_t() ;
658 etat = ETATNONDEF ;
659}
660
661// Allocates everything
662// --------------------
664
665 set_etat_qcq() ;
666 for (int i=0 ; i<n_comp ; i++) {
667 c[i]->allocate_all() ;
668 }
669
670}
671
672
673
675
676 bi.change_basis(*this) ;
677
678}
679
681
682 triad = &bi ;
683
684}
685
686void Tenseur::set_poids(double weight) {
687
688 poids = weight ;
689}
690
691void Tenseur::set_metric(const Metrique& met) {
692
693 metric = &met ;
694}
695
696int Tenseur::donne_place (const Itbl& idx) const {
697
698 assert (idx.get_ndim() == 1) ;
699 assert (idx.get_dim(0) == valence) ;
700
701 for (int i=0 ; i<valence ; i++)
702 assert ((idx(i)>=0) && (idx(i)<3)) ;
703 int res = 0 ;
704 for (int i=0 ; i<valence ; i++)
705 res = 3*res+idx(i) ;
706
707 return res;
708}
709
710Itbl Tenseur::donne_indices (int place) const {
711
712 assert ((place >= 0) && (place < n_comp)) ;
713
714 Itbl res(valence) ;
715 res.set_etat_qcq() ;
716
717 for (int i=valence-1 ; i>=0 ; i--) {
718 res.set(i) = div(place, 3).rem ;
719 place = int((place-res(i))/3) ;
720 }
721 return res ;
722}
723
725
726 assert (valence == t.valence) ;
727
728 triad = t.triad ;
729 poids = t.poids ;
730 metric = t.metric ;
731
732 for (int i=0 ; i<valence ; i++)
733 assert (t.type_indice(i) == type_indice(i)) ;
734
735 switch (t.etat) {
736 case ETATNONDEF: {
738 break ;
739 }
740
741 case ETATZERO: {
742 set_etat_zero() ;
743 break ;
744 }
745
746 case ETATQCQ: {
747 set_etat_qcq() ;
748 for (int i=0 ; i<n_comp ; i++) {
749 int place_t = t.donne_place(donne_indices(i)) ;
750 if (t.c[place_t] == 0x0)
751 c[i] = 0x0 ;
752 else
753 *c[i] = *t.c[place_t] ;
754 }
755 break ;
756 }
757
758 default: {
759 cout << "Unknown state in Tenseur::operator= " << endl ;
760 abort() ;
761 break ;
762 }
763 }
764}
765
766
767void Tenseur::operator=(const Cmp& ci) {
768
769 assert (valence == 0) ;
770 poids = 0. ;
771 metric = 0x0 ;
772
773 switch (ci.get_etat()) {
774 case ETATNONDEF: {
776 break ;
777 }
778
779 case ETATZERO: {
780 set_etat_zero() ;
781 break ;
782 }
783
784 case ETATQCQ: {
785 set_etat_qcq() ;
786 *(c[0]) = ci ;
787 break ;
788 }
789
790 default: {
791 cout << "Unknown state in Tenseur::operator= " << endl ;
792 abort() ;
793 break ;
794 }
795 }
796}
797
798void Tenseur::operator=(double x) {
799
800 poids = 0. ;
801 metric = 0x0 ;
802 if (x == double(0)) {
803 set_etat_zero() ;
804 }
805 else {
806 assert(valence == 0) ;
807 set_etat_qcq() ;
808 *(c[0]) = x ;
809 }
810
811}
812
814
815 poids = 0. ;
816 metric = 0x0 ;
817 if (x == 0) {
818 set_etat_zero() ;
819 }
820 else {
821 assert(valence == 0) ;
822 set_etat_qcq() ;
823 *(c[0]) = x ;
824 }
825
826}
827
828
829// Affectation d'un scalaire ...
831
832 del_derive() ;
833 assert(etat == ETATQCQ) ;
834 assert (valence == 0) ;
835 return *c[0] ;
836}
837
838
839// Affectation d'un vecteur :
840Cmp& Tenseur::set (int ind) {
841
842 del_derive() ;
843 assert(valence == 1) ;
844 assert (etat == ETATQCQ) ;
845 assert ((ind >= 0) && (ind < 3)) ;
846
847 return *c[ind] ;
848}
849
850// Affectation d'un tenseur d'ordre 2 :
851Cmp& Tenseur::set (int ind1, int ind2) {
852
853 del_derive() ;
854 assert (valence == 2) ;
855 assert (etat == ETATQCQ) ;
856 assert ((ind1 >= 0) && (ind1 < 3)) ;
857 assert ((ind2 >= 0) && (ind2 < 3)) ;
858
859 Itbl ind (valence) ;
860 ind.set_etat_qcq() ;
861 ind.set(0) = ind1 ;
862 ind.set(1) = ind2 ;
863
864 int place = donne_place(ind) ;
865
866 return *c[place] ;
867}
868
869// Affectation d'un tenseur d'ordre 3 :
870Cmp& Tenseur::set (int ind1, int ind2, int ind3) {
871
872 del_derive() ;
873 assert (valence == 3) ;
874 assert (etat == ETATQCQ) ;
875 assert ((ind1 >= 0) && (ind1 < 3)) ;
876 assert ((ind2 >= 0) && (ind2 < 3)) ;
877 assert ((ind3 >= 0) && (ind3 < 3)) ;
878
879 Itbl indices(valence) ;
880 indices.set_etat_qcq() ;
881 indices.set(0) = ind1 ;
882 indices.set(1) = ind2 ;
883 indices.set(2) = ind3 ;
884 int place = donne_place(indices) ;
885
886 return *c[place] ;
887}
888
889// Affectation cas general
890Cmp& Tenseur::set(const Itbl& indices) {
891
892 assert (indices.get_ndim() == 1) ;
893 assert (indices.get_dim(0) == valence) ;
894
895 del_derive() ;
896 assert (etat == ETATQCQ) ;
897 for (int i=0 ; i<valence ; i++)
898 assert ((indices(i)>=0) && (indices(i)<3)) ;
899
900 int place = donne_place(indices) ;
901
902 return *c[place] ;
903}
904
905// Annulation dans des domaines
906void Tenseur::annule(int l) {
907
908 annule(l, l) ;
909}
910
911void Tenseur::annule(int l_min, int l_max) {
912
913 // Cas particulier: annulation globale :
914 if ( (l_min == 0) && (l_max == mp->get_mg()->get_nzone()-1) ) {
915 set_etat_zero() ;
916 return ;
917 }
918
919 assert( etat != ETATNONDEF ) ;
920
921 if ( etat == ETATZERO ) {
922 return ; // rien n'a faire si c'est deja zero
923 }
924 else {
925 assert( etat == ETATQCQ ) ; // sinon...
926
927 // Annulation des composantes:
928 for (int i=0 ; i<n_comp ; i++) {
929 c[i]->annule(l_min, l_max) ;
930 }
931
932 // Annulation des membres derives
933 if (p_gradient != 0x0) p_gradient->annule(l_min, l_max) ;
934 if (p_gradient_spher != 0x0) p_gradient_spher->annule(l_min, l_max) ;
935 for (int j=0; j<N_MET_MAX; j++) {
936 if (p_derive_cov[j] != 0x0) p_derive_cov[j]->annule(l_min, l_max) ;
937 if (p_derive_con[j] != 0x0) p_derive_con[j]->annule(l_min, l_max) ;
938 if (p_carre_scal[j] != 0x0) p_carre_scal[j]->annule(l_min, l_max) ;
939 }
940
941 }
942
943}
944
945
946
947
948// Exctraction :
949const Cmp& Tenseur::operator()() const {
950
951 assert(valence == 0) ;
952
953 if (etat == ETATQCQ) return *c[0] ; // pour la performance,
954 // ce cas est traite en premier,
955 // en dehors du switch
956 switch (etat) {
957
958 case ETATNONDEF : {
959 cout << "Undefined Tensor in Tenseur::operator() ..." << endl ;
960 abort() ;
961 return *c[0] ; // bidon pour satisfaire le compilateur
962 }
963
964 case ETATZERO : {
965 return mp->cmp_zero() ;
966 }
967
968
969 default : {
970 cout <<"Unknown state in Tenseur::operator()" << endl ;
971 abort() ;
972 return *c[0] ; // bidon pour satisfaire le compilateur
973 }
974 }
975}
976
977
978const Cmp& Tenseur::operator() (int indice) const {
979
980 assert ((indice>=0) && (indice<3)) ;
981 assert(valence == 1) ;
982
983 if (etat == ETATQCQ) return *c[indice] ; // pour la performance,
984 // ce cas est traite en premier,
985 // en dehors du switch
986 switch (etat) {
987
988 case ETATNONDEF : {
989 cout << "Undefined Tensor in Tenseur::operator(int) ..." << endl ;
990 abort() ;
991 return *c[0] ; // bidon pour satisfaire le compilateur
992 }
993
994 case ETATZERO : {
995 return mp->cmp_zero() ;
996 }
997
998 default : {
999 cout <<"Unknown state in Tenseur::operator(int)" << endl ;
1000 abort() ;
1001 return *c[0] ; // bidon pour satisfaire le compilateur
1002 }
1003 }
1004}
1005
1006const Cmp& Tenseur::operator() (int indice1, int indice2) const {
1007
1008 assert ((indice1>=0) && (indice1<3)) ;
1009 assert ((indice2>=0) && (indice2<3)) ;
1010 assert(valence == 2) ;
1011
1012 if (etat == ETATQCQ) { // pour la performance,
1013 Itbl idx(2) ; // ce cas est traite en premier,
1014 idx.set_etat_qcq() ; // en dehors du switch
1015 idx.set(0) = indice1 ;
1016 idx.set(1) = indice2 ;
1017 return *c[donne_place(idx)] ;
1018 }
1019
1020 switch (etat) {
1021
1022 case ETATNONDEF : {
1023 cout << "Undefined Tensor in Tenseur::operator(int, int) ..." << endl ;
1024 abort() ;
1025 return *c[0] ; // bidon pour satisfaire le compilateur
1026 }
1027
1028 case ETATZERO : {
1029 return mp->cmp_zero() ;
1030 }
1031
1032 default : {
1033 cout <<"Unknown state in Tenseur::operator(int, int)" << endl ;
1034 abort() ;
1035 return *c[0] ; // bidon pour satisfaire le compilateur
1036 }
1037 }
1038}
1039
1040const Cmp& Tenseur::operator() (int indice1, int indice2, int indice3) const {
1041
1042 assert ((indice1>=0) && (indice1<3)) ;
1043 assert ((indice2>=0) && (indice2<3)) ;
1044 assert ((indice3>=0) && (indice3<3)) ;
1045 assert(valence == 3) ;
1046
1047 if (etat == ETATQCQ) { // pour la performance,
1048 Itbl idx(3) ; // ce cas est traite en premier,
1049 idx.set_etat_qcq() ; // en dehors du switch
1050 idx.set(0) = indice1 ;
1051 idx.set(1) = indice2 ;
1052 idx.set(2) = indice3 ;
1053 return *c[donne_place(idx)] ;
1054 }
1055
1056 switch (etat) {
1057
1058 case ETATNONDEF : {
1059 cout << "Undefined Tensor in Tenseur::operator(int, int, int) ..." << endl ;
1060 abort() ;
1061 return *c[0] ; // bidon pour satisfaire le compilateur
1062 }
1063
1064 case ETATZERO : {
1065 return mp->cmp_zero() ;
1066 }
1067
1068 default : {
1069 cout <<"Unknown state in Tenseur::operator(int, int, int)" << endl ;
1070 abort() ;
1071 return *c[0] ; // bidon pour satisfaire le compilateur
1072 }
1073 }
1074}
1075
1076
1077const Cmp& Tenseur::operator() (const Itbl& indices) const {
1078
1079 assert (indices.get_ndim() == 1) ;
1080 assert (indices.get_dim(0) == valence) ;
1081 for (int i=0 ; i<valence ; i++)
1082 assert ((indices(i)>=0) && (indices(i)<3)) ;
1083
1084 if (etat == ETATQCQ) { // pour la performance,
1085 return *c[donne_place(indices)] ; // ce cas est traite en premier,
1086 } // en dehors du switch
1087
1088 switch (etat) {
1089
1090 case ETATNONDEF : {
1091 cout << "Undefined Tensor in Tenseur::operator(const Itbl&) ..." << endl ;
1092 abort() ;
1093 return *c[0] ; // bidon pour satisfaire le compilateur
1094 }
1095
1096 case ETATZERO : {
1097 return mp->cmp_zero() ;
1098 }
1099
1100 default : {
1101 cout <<"Unknown state in Tenseur::operator(const Itbl& )" << endl ;
1102 abort() ;
1103 return *c[0] ; // bidon pour satisfaire le compilateur
1104 }
1105 }
1106
1107}
1108
1109// Gestion de la ZEC :
1111
1112 if (etat == ETATZERO) {
1113 return ;
1114 }
1115
1116 assert(etat == ETATQCQ) ;
1117
1118 for (int i=0 ; i<n_comp ; i++)
1119 if (c[i] != 0x0)
1120 c[i]->dec_dzpuis() ;
1121}
1122
1124
1125 if (etat == ETATZERO) {
1126 return ;
1127 }
1128
1129 assert(etat == ETATQCQ) ;
1130
1131 for (int i=0 ; i<n_comp ; i++)
1132 if (c[i] != 0x0)
1133 c[i]->inc_dzpuis() ;
1134}
1135
1137
1138 if (etat == ETATZERO) {
1139 return ;
1140 }
1141
1142 assert(etat == ETATQCQ) ;
1143
1144 for (int i=0 ; i<n_comp ; i++)
1145 if (c[i] != 0x0)
1146 c[i]->dec2_dzpuis() ;
1147}
1148
1150
1151 if (etat == ETATZERO) {
1152 return ;
1153 }
1154
1155 assert(etat == ETATQCQ) ;
1156
1157 for (int i=0 ; i<n_comp ; i++)
1158 if (c[i] != 0x0)
1159 c[i]->inc2_dzpuis() ;
1160}
1161
1163
1164 if (etat == ETATZERO) {
1165 return ;
1166 }
1167
1168 assert(etat == ETATQCQ) ;
1169
1170 for (int i=0 ; i<n_comp ; i++)
1171 if (c[i] != 0x0)
1172 c[i]->mult_r_zec() ;
1173}
1174
1175// Gestion des bases spectrales (valence <= 2)
1177
1178 if (etat == ETATZERO) {
1179 return ;
1180 }
1181
1182 assert(etat == ETATQCQ) ;
1183 switch (valence) {
1184
1185 case 0 : {
1186 c[0]->std_base_scal() ;
1187 break ;
1188 }
1189
1190 case 1 : {
1191
1192 if ( triad->identify() == (mp->get_bvect_cart()).identify() ) {
1193
1194 Base_val** bases = mp->get_mg()->std_base_vect_cart() ;
1195
1196 for (int i=0 ; i<3 ; i++)
1197 (c[i]->va).set_base( *bases[i] ) ;
1198 for (int i=0 ; i<3 ; i++)
1199 delete bases[i] ;
1200 delete [] bases ;
1201 }
1202 else {
1203 assert( triad->identify() == (mp->get_bvect_spher()).identify()) ;
1204 Base_val** bases = mp->get_mg()->std_base_vect_spher() ;
1205
1206 for (int i=0 ; i<3 ; i++)
1207 (c[i]->va).set_base( *bases[i] ) ;
1208 for (int i=0 ; i<3 ; i++)
1209 delete bases[i] ;
1210 delete [] bases ;
1211 }
1212 break ;
1213
1214 }
1215
1216 case 2 : {
1217
1218 if( triad->identify() == (mp->get_bvect_cart()).identify() ) {
1219
1220 Base_val** bases = mp->get_mg()->std_base_vect_cart() ;
1221
1222 Itbl indices (2) ;
1223 indices.set_etat_qcq() ;
1224 for (int i=0 ; i<n_comp ; i++) {
1225 indices = donne_indices(i) ;
1226 (c[i]->va).set_base( (*bases[indices(0)]) *
1227 (*bases[indices(1)]) ) ;
1228 }
1229 for (int i=0 ; i<3 ; i++)
1230 delete bases[i] ;
1231 delete [] bases ;
1232 }
1233 else {
1234 assert( triad->identify() == (mp->get_bvect_spher()).identify()) ;
1235 Base_val** bases = mp->get_mg()->std_base_vect_spher() ;
1236
1237 Itbl indices (2) ;
1238 indices.set_etat_qcq() ;
1239 for (int i=0 ; i<n_comp ; i++) {
1240 indices = donne_indices(i) ;
1241 (c[i]->va).set_base( (*bases[indices(0)]) *
1242 (*bases[indices(1)]) ) ;
1243 }
1244 for (int i=0 ; i<3 ; i++)
1245 delete bases[i] ;
1246 delete [] bases ;
1247 }
1248 break ;
1249 }
1250
1251 default : {
1252 cout <<
1253 "Tenseur::set_std_base() : the case valence = " << valence
1254 << " is not treated !" << endl ;
1255 abort() ;
1256 break ;
1257 }
1258 }
1259}
1260
1261 // Le cout :
1262ostream& operator<<(ostream& flux, const Tenseur &source ) {
1263
1264 flux << "Valence : " << source.valence << endl ;
1265 if (source.get_poids() != 0.)
1266 flux << "Tensor density of weight " << source.poids << endl ;
1267
1268 if (source.get_triad() != 0x0) {
1269 flux << "Vectorial basis (triad) on which the components are defined :"
1270 << endl ;
1271 flux << *(source.get_triad()) << endl ;
1272 }
1273
1274 if (source.valence != 0)
1275 flux << "Type of the indices : " << endl ;
1276 for (int i=0 ; i<source.valence ; i++) {
1277 flux << "Index " << i << " : " ;
1278 if (source.type_indice(i) == CON)
1279 flux << " contravariant." << endl ;
1280 else
1281 flux << " covariant." << endl ;
1282 }
1283
1284 switch (source.etat) {
1285
1286 case ETATZERO : {
1287 flux << "Null Tenseur. " << endl ;
1288 break ;
1289 }
1290
1291 case ETATNONDEF : {
1292 flux << "Undefined Tenseur. " << endl ;
1293 break ;
1294 }
1295
1296 case ETATQCQ : {
1297 for (int i=0 ; i<source.n_comp ; i++) {
1298
1299 Itbl num_indices (source.donne_indices(i)) ;
1300 flux << "Component " ;
1301
1302 if (source.valence != 0) {
1303 for (int j=0 ; j<source.valence ; j++)
1304 flux << " " << num_indices(j) ;
1305 }
1306 else
1307 flux << " " << 0 ;
1308 flux << " : " << endl ;
1309 flux << "-------------" << endl ;
1310
1311
1312 if (source.c[i] != 0x0)
1313 flux << *source.c[i] << endl ;
1314 else
1315 flux << "Unknown component ... " << endl ;
1316
1317 }
1318 break ;
1319 }
1320 default : {
1321 cout << "Unknown case in operator<< (ostream&, const Tenseur&)" << endl ;
1322 abort() ;
1323 break ;
1324 }
1325 }
1326
1327 flux << " -----------------------------------------------------" << endl ;
1328 return flux ;
1329}
1330
1331void Tenseur::sauve(FILE* fd) const {
1332
1333 type_indice.sauve(fd) ; // type des composantes
1334 fwrite_be(&valence, sizeof(int), 1, fd) ; // la valence
1335
1336 if (valence != 0) {
1337 triad->sauve(fd) ; // Vectorial basis
1338 }
1339
1340 fwrite_be(&n_comp, sizeof(int), 1, fd) ; // nbre composantes
1341 fwrite_be(&etat, sizeof(int), 1, fd) ; // etat
1342
1343 if (etat == ETATQCQ)
1344 for (int i=0 ; i<n_comp ; i++)
1345 c[i]->sauve(fd) ;
1346 if (poids != 0.)
1347 fwrite_be(&poids, sizeof(double), 1, fd) ; //poids, si pertinent
1348}
1349
1350
1352
1353 assert (etat != ETATNONDEF) ;
1354
1355 if (p_gradient != 0x0)
1356 return ;
1357 else {
1358
1359 // Construction du resultat :
1360 Itbl tipe (valence+1) ;
1361 tipe.set_etat_qcq() ;
1362 tipe.set(0) = COV ;
1363 for (int i=0 ; i<valence ; i++)
1364 tipe.set(i+1) = type_indice(i) ;
1365
1366 // Vectorial basis
1367 // ---------------
1368 if (valence != 0) {
1369 // assert (*triad == mp->get_bvect_cart()) ;
1370 }
1371
1372 p_gradient = new Tenseur(*mp, valence+1, tipe, mp->get_bvect_cart(),
1373 metric, poids) ;
1374
1375 if (etat == ETATZERO)
1376 p_gradient->set_etat_zero() ;
1377 else {
1378 p_gradient->set_etat_qcq() ;
1379 // Boucle sur les indices :
1380
1381 Itbl indices_source(valence) ;
1382 indices_source.set_etat_qcq() ;
1383
1384 for (int j=0 ; j<p_gradient->n_comp ; j++) {
1385
1386 Itbl indices_res(p_gradient->donne_indices(j)) ;
1387
1388 for (int m=0 ; m<valence ; m++)
1389 indices_source.set(m) = indices_res(m+1) ;
1390
1391 p_gradient->set(indices_res) =
1392 (*this)(indices_source).deriv(indices_res(0)) ;
1393 }
1394 }
1395 }
1396}
1397
1399
1400 assert (etat != ETATNONDEF) ;
1401
1402 if (p_gradient_spher != 0x0)
1403 return ;
1404 else {
1405
1406 // Construction du resultat :
1407
1408 if (valence != 0) {
1409 cout <<
1410 "Tenseur::fait_gradient_spher : the valence must be zero !"
1411 << endl ;
1412 abort() ;
1413 }
1414
1415 p_gradient_spher = new Tenseur(*mp, 1, COV, mp->get_bvect_spher(),
1416 metric, poids) ;
1417
1418 if (etat == ETATZERO) {
1419 p_gradient_spher->set_etat_zero() ;
1420 }
1421 else {
1422 assert( etat == ETATQCQ ) ;
1423 p_gradient_spher->set_etat_qcq() ;
1424
1425 p_gradient_spher->set(0) = c[0]->dsdr() ; // d/dr
1426 p_gradient_spher->set(1) = c[0]->srdsdt() ; // 1/r d/dtheta
1427 p_gradient_spher->set(2) = c[0]->srstdsdp() ; // 1/(r sin(theta))
1428 // d/dphi
1429
1430 }
1431 }
1432}
1433
1434
1435void Tenseur::fait_derive_cov (const Metrique& metre, int ind) const {
1436
1437 assert (etat != ETATNONDEF) ;
1438 assert (valence != 0) ;
1439
1440 if (p_derive_cov[ind] != 0x0)
1441 return ;
1442 else {
1443
1444 p_derive_cov[ind] = new Tenseur (gradient()) ;
1445
1446 if ((valence != 0) && (etat != ETATZERO)) {
1447
1448
1449 // assert( *(metre.gamma().get_triad()) == *triad ) ;
1450 Tenseur* auxi ;
1451 for (int i=0 ; i<valence ; i++) {
1452
1453 if (type_indice(i) == COV) {
1454 auxi = new Tenseur(contract(metre.gamma(), 0,(*this), i)) ;
1455
1456 Itbl indices_gamma(p_derive_cov[ind]->valence) ;
1457 indices_gamma.set_etat_qcq() ;
1458 //On range comme il faut :
1459 for (int j=0 ; j<p_derive_cov[ind]->n_comp ; j++) {
1460
1461 Itbl indices (p_derive_cov[ind]->donne_indices(j)) ;
1462 indices_gamma.set(0) = indices(0) ;
1463 indices_gamma.set(1) = indices(i+1) ;
1464 for (int idx=2 ; idx<p_derive_cov[ind]->valence ; idx++)
1465 if (idx<=i+1)
1466 indices_gamma.set(idx) = indices(idx-1) ;
1467 else
1468 indices_gamma.set(idx) = indices(idx) ;
1469
1470 p_derive_cov[ind]->set(indices) -= (*auxi)(indices_gamma) ;
1471 }
1472 }
1473 else {
1474 auxi = new Tenseur(contract(metre.gamma(), 1, (*this), i)) ;
1475
1476 Itbl indices_gamma(p_derive_cov[ind]->valence) ;
1477 indices_gamma.set_etat_qcq() ;
1478
1479 //On range comme il faut :
1480 for (int j=0 ; j<p_derive_cov[ind]->n_comp ; j++) {
1481
1482 Itbl indices (p_derive_cov[ind]->donne_indices(j)) ;
1483 indices_gamma.set(0) = indices(i+1) ;
1484 indices_gamma.set(1) = indices(0) ;
1485 for (int idx=2 ; idx<p_derive_cov[ind]->valence ; idx++)
1486 if (idx<=i+1)
1487 indices_gamma.set(idx) = indices(idx-1) ;
1488 else
1489 indices_gamma.set(idx) = indices(idx) ;
1490 p_derive_cov[ind]->set(indices) += (*auxi)(indices_gamma) ;
1491 }
1492 }
1493 delete auxi ;
1494 }
1495 }
1496 if ((poids != 0.)&&(etat != ETATZERO))
1497 *p_derive_cov[ind] = *p_derive_cov[ind] -
1498 poids*contract(metre.gamma(), 0, 2) * (*this) ;
1499
1500 }
1501}
1502
1503
1504
1505void Tenseur::fait_derive_con (const Metrique& metre, int ind) const {
1506
1507 if (p_derive_con[ind] != 0x0)
1508 return ;
1509 else {
1510 // On calcul la derivee covariante :
1511 if (valence != 0)
1512 p_derive_con[ind] = new Tenseur
1513 (contract(metre.con(), 1, derive_cov(metre), 0)) ;
1514
1515 else {
1516 Tenseur grad (gradient()) ;
1517 grad.change_triad( *(metre.con().get_triad()) ) ;
1518 p_derive_con[ind] = new Tenseur (contract(metre.con(), 1, grad, 0)) ;
1519 }
1520 }
1521}
1522
1523void Tenseur::fait_carre_scal (const Metrique& met, int ind) const {
1524
1525 if (p_carre_scal[ind] != 0x0)
1526 return ;
1527 else {
1528 assert (valence != 0) ; // A ne pas appeler sur un scalaire ;
1529
1530 // On bouge tous les indices :
1531 Tenseur op_t(manipule(*this, met)) ;
1532
1533 Tenseur* auxi = new Tenseur(contract(*this, 0, op_t, 0)) ;
1534 Tenseur* auxi_old ;
1535
1536 // On contracte tous les indices restant :
1537 for (int indice=1 ; indice<valence ; indice++) {
1538 auxi_old = new Tenseur(contract(*auxi, 0, valence-indice)) ;
1539 delete auxi ;
1540 auxi = new Tenseur(*auxi_old) ;
1541 delete auxi_old ;
1542 }
1543 p_carre_scal[ind] = new Tenseur (*auxi) ;
1544 delete auxi ;
1545 }
1546}
1547
1549 if (p_gradient == 0x0)
1550 fait_gradient() ;
1551 return *p_gradient ;
1552}
1553
1555 if (p_gradient_spher == 0x0)
1557 return *p_gradient_spher ;
1558}
1559
1560const Tenseur& Tenseur::derive_cov (const Metrique& metre) const {
1561
1562 if (valence == 0)
1563 return gradient() ;
1564 else {
1565 set_dependance(metre) ;
1566 int j = get_place_met(metre) ;
1567 assert(j!=-1) ;
1568 if (p_derive_cov[j] == 0x0)
1569 fait_derive_cov (metre,j) ;
1570 return *p_derive_cov[j] ;
1571 }
1572}
1573
1574const Tenseur& Tenseur::derive_con (const Metrique& metre) const {
1575 set_dependance(metre) ;
1576 int j = get_place_met(metre) ;
1577 assert(j!=-1) ;
1578 if (p_derive_con[j] == 0x0)
1579 fait_derive_con (metre, j) ;
1580 return *p_derive_con[j] ;
1581}
1582
1583const Tenseur& Tenseur::carre_scal (const Metrique& metre) const {
1584 set_dependance(metre) ;
1585 int j = get_place_met(metre) ;
1586 assert(j!=-1) ;
1587 if (p_carre_scal[j] == 0x0)
1588 fait_carre_scal (metre, j) ;
1589 return *p_carre_scal[j] ;
1590}
1591}
Bases of the spectral expansions.
Definition base_val.h:325
Vectorial bases (triads) with respect to which the tensorial components are defined.
Definition base_vect.h:105
static Base_vect * bvect_from_file(FILE *)
Construction of a vectorial basis from a file (see sauve(FILE* ) ).
virtual void change_basis(Tenseur &) const =0
Change the basis in which the components of a tensor are expressed.
Component of a tensorial field *** DEPRECATED : use class Scalar instead ***.
Definition cmp.h:446
int get_etat() const
Returns the logical state.
Definition cmp.h:899
Basic integer array class.
Definition itbl.h:122
void set_etat_qcq()
Sets the logical state to ETATQCQ (ordinary state).
Definition itbl.C:264
int get_dim(int i) const
Gives the i th dimension (ie {tt dim.dim[i] ).
Definition itbl.h:326
int & set(int i)
Read/write of a particular element (index i ) (1D case).
Definition itbl.h:247
int get_ndim() const
Gives the number of dimensions (ie dim.ndim ).
Definition itbl.h:323
virtual int donne_place(const Itbl &idx) const
Returns the position in the Cmp 1-D array c of a component given by its indices.
Tensor handling *** DEPRECATED : use class Tensor instead ***.
Definition tenseur.h:304
const Base_vect * get_triad() const
Returns the vectorial basis (triad) on which the components are defined.
Definition tenseur.h:707
virtual Itbl donne_indices(int place) const
Returns the indices of a component given by its position in the Cmp 1-D array c .
Definition tenseur.C:710
Cmp & set()
Read/write for a scalar (see also operator=(const Cmp&) ).
Definition tenseur.C:830
Tenseur ** p_derive_con
Array of pointers on the contravariant derivatives of *this with respect to the corresponding metri...
Definition tenseur.h:368
void fait_carre_scal(const Metrique &, int i) const
Calculates, if needed, the scalar square of *this , with respect to met .
Definition tenseur.C:1523
void allocate_all()
Sets the logical state to ETATQCQ (ordinary state) and performs the memory allocation of all the elem...
Definition tenseur.C:663
const Metrique * metric
For tensor densities: the metric defining the conformal factor.
Definition tenseur.h:328
void fait_gradient_spher() const
Calculates, if needed, the gradient of *this in a spherical orthonormal basis (scalar field only).
Definition tenseur.C:1398
void sauve(FILE *) const
Save in a file.
Definition tenseur.C:1331
Cmp ** c
The components.
Definition tenseur.h:325
virtual void operator=(const Tenseur &tens)
Assignment to another Tenseur.
Definition tenseur.C:724
Tenseur * p_gradient_spher
Pointer on the gradient of *this in a spherical orthonormal basis (scalar field only).
Definition tenseur.h:353
const Map *const mp
Reference mapping.
Definition tenseur.h:309
void inc_dzpuis()
dzpuis += 1 ;
Definition tenseur.C:1123
virtual void fait_gradient() const
Calculates, if needed, the gradient of *this .
Definition tenseur.C:1351
const Metrique ** met_depend
Array of pointers on the Metrique 's used to calculate derivatives members.
Definition tenseur.h:340
virtual int donne_place(const Itbl &idx) const
Returns the position in the Cmp 1-D array c of a component given by its indices.
Definition tenseur.C:696
const Tenseur & derive_cov(const Metrique &met) const
Returns the covariant derivative of *this , with respect to met .
Definition tenseur.C:1560
void set_etat_qcq()
Sets the logical state to ETATQCQ (ordinary state).
Definition tenseur.C:642
Tenseur(const Map &map, const Metrique *met=0x0, double weight=0)
Constructor for a scalar field.
Definition tenseur.C:215
void annule(int l)
Sets the Tenseur to zero in a given domain.
Definition tenseur.C:906
const Map * get_mp() const
Returns pointer on the mapping.
Definition tenseur.h:702
void dec2_dzpuis()
dzpuis -= 2 ;
Definition tenseur.C:1136
Tenseur ** p_carre_scal
Array of pointers on the scalar squares of *this with respect to the corresponding metric in *met_d...
Definition tenseur.h:375
double get_poids() const
Returns the weight.
Definition tenseur.h:741
int get_place_met(const Metrique &metre) const
Returns the position of the pointer on metre in the array met_depend .
Definition tenseur.C:604
void dec_dzpuis()
dzpuis -= 1 ;
Definition tenseur.C:1110
const Tenseur & derive_con(const Metrique &) const
Returns the contravariant derivative of *this , with respect to met .
Definition tenseur.C:1574
const Base_vect * triad
Vectorial basis (triad) with respect to which the tensor components are defined.
Definition tenseur.h:315
const Tenseur & gradient() const
Returns the gradient of *this (Cartesian coordinates).
Definition tenseur.C:1548
virtual ~Tenseur()
Destructor.
Definition tenseur.C:539
friend Tenseur contract(const Tenseur &, int id1, int id2)
Self contraction of two indices of a Tenseur .
int n_comp
Number of components, depending on the symmetry.
Definition tenseur.h:323
void new_der_met()
Builds the arrays met_depend , p_derive_cov , p_derive_con and p_carre_scal and fills them with null ...
Definition tenseur.C:202
void set_std_base()
Set the standard spectal basis of decomposition for each component.
Definition tenseur.C:1176
void set_etat_zero()
Sets the logical state to ETATZERO (zero state).
Definition tenseur.C:651
void set_poids(double weight)
Sets the weight for a tensor density.
Definition tenseur.C:686
void mult_r_zec()
Multiplication by r in the external zone.
Definition tenseur.C:1162
Itbl type_indice
Array of size valence contening the type of each index, COV for a covariant one and CON for a contrav...
Definition tenseur.h:321
void del_derive() const
Logical destructor of all the derivatives.
Definition tenseur.C:579
bool verif() const
Returns false for a tensor density without a defined metric.
Definition tenseur.C:198
const Cmp & operator()() const
Read only for a scalar.
Definition tenseur.C:949
void set_metric(const Metrique &met)
Sets the pointer on the metric for a tensor density.
Definition tenseur.C:691
int valence
Valence.
Definition tenseur.h:310
void inc2_dzpuis()
dzpuis += 2 ;
Definition tenseur.C:1149
const Tenseur & gradient_spher() const
Returns the gradient of *this (Spherical coordinates) (scalar field only).
Definition tenseur.C:1554
void del_derive_met(int i) const
Logical destructor of the derivatives depending on the i-th element of *met_depend .
Definition tenseur.C:560
int etat
Logical state ETATZERO , ETATQCQ or ETATNONDEF.
Definition tenseur.h:324
double poids
For tensor densities: the weight.
Definition tenseur.h:326
void set_der_met_0x0(int i) const
Sets the pointers of the derivatives depending on the i-th element of *met_depend to zero (as well as...
Definition tenseur.C:589
Tenseur ** p_derive_cov
Array of pointers on the covariant derivatives of *this with respect to the corresponding metric in...
Definition tenseur.h:361
friend Tenseur manipule(const Tenseur &, const Metrique &, int idx)
Raise or lower the index idx depending on its type, using the given Metrique .
void set_der_0x0() const
Sets the pointers of all the derivatives to zero.
Definition tenseur.C:597
void change_triad(const Base_vect &new_triad)
Sets a new vectorial basis (triad) of decomposition and modifies the components accordingly.
Definition tenseur.C:674
void set_triad(const Base_vect &new_triad)
Assigns a new vectorial basis (triad) of decomposition.
Definition tenseur.C:680
void set_etat_nondef()
Sets the logical state to ETATNONDEF (undefined state).
Definition tenseur.C:656
Tenseur * p_gradient
Pointer on the gradient of *this .
Definition tenseur.h:346
void set_dependance(const Metrique &met) const
To be used to describe the fact that the derivatives members have been calculated with met .
Definition tenseur.C:614
void del_t()
Logical destructor.
Definition tenseur.C:551
virtual void fait_derive_cov(const Metrique &met, int i) const
Calculates, if needed, the covariant derivative of *this , with respect to met .
Definition tenseur.C:1435
int get_etat() const
Returns the logical state.
Definition tenseur.h:710
const Tenseur & carre_scal(const Metrique &) const
Returns the scalar square of *this , with respect to met .
Definition tenseur.C:1583
virtual void fait_derive_con(const Metrique &, int i) const
Calculates, if needed, the contravariant derivative of *this , with respect to met .
Definition tenseur.C:1505
Cmp pow(const Cmp &, int)
Power .
Definition cmp_math.C:351
int fread_be(int *aa, int size, int nb, FILE *fich)
Reads integer(s) from a binary file according to the big endian convention.
Definition fread_be.C:72
int fwrite_be(const int *aa, int size, int nb, FILE *fich)
Writes integer(s) into a binary file according to the big endian convention.
Definition fwrite_be.C:73
Lorene prototypes.
Definition app_hor.h:67
Map(const Mg3d &)
Constructor from a multi-domain 3D grid.
Definition map.C:142
Coord x
x coordinate centered on the grid
Definition map.h:738