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 //---------------------------------------
197 namespace Lorene {
198 bool 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 // ------------------------------
215 Tenseur::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 // ---------------------------------------------------
230 Tenseur::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 // --------------------
252 Tenseur::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 // -------------------------------------------------------
274 Tenseur::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 // --------------------------------------------------------------
303 Tenseur::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()) ;
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 // ----------------
324 Tenseur::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)
352  p_gradient_spher = new Tenseur (*source.p_gradient_spher) ;
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 
358  set_dependance (*met_depend[i]) ;
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 // -----------------------------------
372 Tenseur::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 
402  set_dependance (*met_depend[i]) ;
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 // -----------------------
417 Tenseur::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 // ------------------------------------------
454 Tenseur::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 // ---------------------------------------
491 Tenseur::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 // -------------------------------------------------------------------
515 Tenseur::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()) ;
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 
560 void 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 
579 void 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 
589 void 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 
597 void Tenseur::set_der_0x0() const {
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 
604 int 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 
614 void 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 
680 void Tenseur::set_triad(const Base_vect& bi) {
681 
682  triad = &bi ;
683 
684 }
685 
686 void Tenseur::set_poids(double weight) {
687 
688  poids = weight ;
689 }
690 
691 void Tenseur::set_metric(const Metrique& met) {
692 
693  metric = &met ;
694 }
695 
696 int 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 
710 Itbl 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 
724 void Tenseur::operator=(const Tenseur& t) {
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: {
737  set_etat_nondef() ;
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 
767 void 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: {
775  set_etat_nondef() ;
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 
798 void 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 
813 void Tenseur::operator=(int x) {
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 :
840 Cmp& 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 :
851 Cmp& 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 :
870 Cmp& 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
890 Cmp& 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
906 void Tenseur::annule(int l) {
907 
908  annule(l, l) ;
909 }
910 
911 void 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 :
949 const 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 
978 const 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 
1006 const 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 
1040 const 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 
1077 const 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 :
1262 ostream& 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 
1331 void 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 
1351 void Tenseur::fait_gradient () const {
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)
1377  else {
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) {
1420  }
1421  else {
1422  assert( etat == ETATQCQ ) ;
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 
1435 void 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 
1505 void 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 
1523 void 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 
1548 const Tenseur& Tenseur::gradient () const {
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 
1560 const 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 
1574 const 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 
1583 const 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 }
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
const Cmp & dsdr() const
Returns of *this .
Definition: cmp_deriv.C:87
const Map *const mp
Reference mapping.
Definition: tenseur.h:309
double get_poids() const
Returns the weight.
Definition: tenseur.h:741
const Base_vect * triad
Vectorial basis (triad) with respect to which the tensor components are defined.
Definition: tenseur.h:315
Base_val ** std_base_vect_cart() const
Returns the standard spectral bases for the Cartesian components of a vector.
virtual ~Tenseur()
Destructor.
Definition: tenseur.C:539
void annule(int l)
Sets the Tenseur to zero in a given domain.
Definition: tenseur.C:906
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
Component of a tensorial field *** DEPRECATED : use class Scalar instead ***.
Definition: cmp.h:446
int & set(int i)
Read/write of a particular element (index i ) (1D case)
Definition: itbl.h:247
Cmp ** c
The components.
Definition: tenseur.h:325
void dec2_dzpuis()
dzpuis -= 2 ;
Definition: tenseur.C:1136
const Tenseur & gradient_spher() const
Returns the gradient of *this (Spherical coordinates) (scalar field only).
Definition: tenseur.C:1554
void set_triad(const Base_vect &new_triad)
Assigns a new vectorial basis (triad) of decomposition.
Definition: tenseur.C:680
const Cmp & cmp_zero() const
Returns the null Cmp defined on *this.
Definition: map.h:819
int n_comp
Number of components, depending on the symmetry.
Definition: tenseur.h:323
void dec_dzpuis()
Decreases by 1 the value of dzpuis and changes accordingly the values of the Cmp in the external comp...
Definition: cmp_r_manip.C:157
void annule(int l)
Sets the Cmp to zero in a given domain.
Definition: cmp.C:351
void set_poids(double weight)
Sets the weight for a tensor density.
Definition: tenseur.C:686
void set_std_base()
Set the standard spectal basis of decomposition for each component.
Definition: tenseur.C:1176
Class intended to describe tensors with a symmetry on the two last indices *** DEPRECATED : use class...
Definition: tenseur.h:1256
const Cmp & srstdsdp() const
Returns of *this .
Definition: cmp_deriv.C:130
const Base_vect_spher & get_bvect_spher() const
Returns the orthonormal vectorial basis associated with the coordinates of the mapping.
Definition: map.h:795
int get_ndim() const
Gives the number of dimensions (ie dim.ndim )
Definition: itbl.h:323
Lorene prototypes.
Definition: app_hor.h:67
const Mg3d * get_mg() const
Gives the Mg3d on which the mapping is defined.
Definition: map.h:777
int get_etat() const
Returns the logical state.
Definition: cmp.h:899
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
virtual void sauve(FILE *) const
Save in a file.
Definition: base_vect.C:153
Base class for coordinate mappings.
Definition: map.h:682
int etat
Logical state ETATZERO , ETATQCQ or ETATNONDEF.
Definition: tenseur.h:324
const Cmp & srdsdt() const
Returns of *this .
Definition: cmp_deriv.C:108
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
void mult_r_zec()
Multiplication by r in the external compactified domain (ZEC)
Definition: cmp_r_manip.C:106
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
Basic integer array class.
Definition: itbl.h:122
const Tenseur & derive_con(const Metrique &) const
Returns the contravariant derivative of *this , with respect to met .
Definition: tenseur.C:1574
Vectorial bases (triads) with respect to which the tensorial components are defined.
Definition: base_vect.h:105
virtual void change_basis(Tenseur &) const =0
Change the basis in which the components of a tensor are expressed.
virtual void fait_gradient() const
Calculates, if needed, the gradient of *this .
Definition: tenseur.C:1351
void inc_dzpuis()
dzpuis += 1 ;
Definition: tenseur.C:1123
const Cmp & operator()() const
Read only for a scalar.
Definition: tenseur.C:949
static Base_vect * bvect_from_file(FILE *)
Construction of a vectorial basis from a file (see sauve(FILE* ) ).
void inc2_dzpuis()
dzpuis += 2 ;
Definition: tenseur.C:1149
void del_t()
Logical destructor.
Definition: tenseur.C:551
virtual void operator=(const Tenseur &tens)
Assignment to another Tenseur.
Definition: tenseur.C:724
void set_metric(const Metrique &met)
Sets the pointer on the metric for a tensor density.
Definition: tenseur.C:691
void inc_dzpuis()
Increases by the value of dzpuis and changes accordingly the values of the Cmp in the external compac...
Definition: cmp_r_manip.C:169
Tenseur * p_gradient_spher
Pointer on the gradient of *this in a spherical orthonormal basis (scalar field only).
Definition: tenseur.h:353
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
Cmp & set()
Read/write for a scalar (see also operator=(const Cmp&) ).
Definition: tenseur.C:830
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
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
void sauve(FILE *) const
Save in a file.
Definition: tenseur.C:1331
Tenseur * p_gradient
Pointer on the gradient of *this .
Definition: tenseur.h:346
void mult_r_zec()
Multiplication by r in the external zone.
Definition: tenseur.C:1162
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_sym.C:216
int valence
Valence.
Definition: tenseur.h:310
const Base_vect * get_triad() const
Returns the vectorial basis (triad) on which the components are defined.
Definition: tenseur.h:707
bool verif() const
Returns false for a tensor density without a defined metric.
Definition: tenseur.C:198
void sauve(FILE *) const
Save in a file.
Definition: itbl.C:229
double poids
For tensor densities: the weight.
Definition: tenseur.h:326
Base_val ** std_base_vect_spher() const
Returns the standard spectral bases for the spherical components of a vector.
int get_nzone() const
Returns the number of domains.
Definition: grilles.h:465
virtual int identify() const =0
Returns a number to identify the sub-classe of Base_vect the object belongs to.
Tenseur ** p_derive_con
Array of pointers on the contravariant derivatives of *this with respect to the corresponding metric...
Definition: tenseur.h:368
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
void set_etat_qcq()
Sets the logical state to ETATQCQ (ordinary state).
Definition: itbl.C:264
friend Tenseur contract(const Tenseur &, int id1, int id2)
Self contraction of two indices of a Tenseur .
void dec2_dzpuis()
Decreases by 2 the value of dzpuis and changes accordingly the values of the Cmp in the external comp...
Definition: cmp_r_manip.C:183
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
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
Cmp pow(const Cmp &, int)
Power .
Definition: cmp_math.C:351
const Metrique ** met_depend
Array of pointers on the Metrique &#39;s used to calculate derivatives members.
Definition: tenseur.h:340
void inc2_dzpuis()
Increases by 2 the value of dzpuis and changes accordingly the values of the Cmp in the external comp...
Definition: cmp_r_manip.C:195
void std_base_scal()
Sets the spectral bases of the Valeur va to the standard ones for a scalar.
Definition: cmp.C:647
void set_der_0x0() const
Sets the pointers of all the derivatives to zero.
Definition: tenseur.C:597
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
Tenseur(const Map &map, const Metrique *met=0x0, double weight=0)
Constructor for a scalar field.
Definition: tenseur.C:215
void allocate_all()
Sets the logical state to ETATQCQ (ordinary state) and performs the memory allocation of all the elem...
Definition: cmp.C:326
Bases of the spectral expansions.
Definition: base_val.h:325
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 Base_vect_cart & get_bvect_cart() const
Returns the Cartesian basis associated with the coordinates (x,y,z) of the mapping, i.e.
Definition: map.h:803
void dec_dzpuis()
dzpuis -= 1 ;
Definition: tenseur.C:1110
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 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
const Metrique * metric
For tensor densities: the metric defining the conformal factor.
Definition: tenseur.h:328
friend Tenseur manipule(const Tenseur &, const Metrique &, int idx)
Raise or lower the index idx depending on its type, using the given Metrique .
int get_dim(int i) const
Gives the i th dimension (ie {tt dim.dim[i] )
Definition: itbl.h:326
Tenseur ** p_derive_cov
Array of pointers on the covariant derivatives of *this with respect to the corresponding metric in ...
Definition: tenseur.h:361
const Tenseur & carre_scal(const Metrique &) const
Returns the scalar square of *this , with respect to met .
Definition: tenseur.C:1583
void set_etat_qcq()
Sets the logical state to ETATQCQ (ordinary state).
Definition: tenseur.C:642
const Tenseur & derive_cov(const Metrique &met) const
Returns the covariant derivative of *this , with respect to met .
Definition: tenseur.C:1560
void del_derive() const
Logical destructor of all the derivatives.
Definition: tenseur.C:579
void set_etat_zero()
Sets the logical state to ETATZERO (zero state).
Definition: tenseur.C:651
Valeur va
The numerical value of the Cmp.
Definition: cmp.h:464
Tenseur ** p_carre_scal
Array of pointers on the scalar squares of *this with respect to the corresponding metric in *met_de...
Definition: tenseur.h:375
void fait_gradient_spher() const
Calculates, if needed, the gradient of *this in a spherical orthonormal basis (scalar field only)...
Definition: tenseur.C:1398
Tensor handling *** DEPRECATED : use class Tensor instead ***.
Definition: tenseur.h:304
void set_etat_nondef()
Sets the logical state to ETATNONDEF (undefined state).
Definition: tenseur.C:656
const Tenseur & gradient() const
Returns the gradient of *this (Cartesian coordinates)
Definition: tenseur.C:1548