LORENE
metric.C
1/*
2 * Definition of methods for the class Metric.
3 *
4 */
5
6/*
7 * Copyright (c) 2003 Eric Gourgoulhon & Jerome Novak
8 *
9 * Copyright (c) 1999-2001 Philippe Grandclement (for previous class Metrique)
10 *
11 * This file is part of LORENE.
12 *
13 * LORENE is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2
15 * as published by the Free Software Foundation.
16 *
17 * LORENE is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with LORENE; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 *
26 */
27
28
29
30/*
31 * $Id: metric.C,v 1.14 2016/12/05 16:17:59 j_novak Exp $
32 * $Log: metric.C,v $
33 * Revision 1.14 2016/12/05 16:17:59 j_novak
34 * Suppression of some global variables (file names, loch, ...) to prevent redefinitions
35 *
36 * Revision 1.13 2014/10/13 08:53:07 j_novak
37 * Lorene classes and functions now belong to the namespace Lorene.
38 *
39 * Revision 1.12 2014/10/06 15:13:14 j_novak
40 * Modified #include directives to use c++ syntax.
41 *
42 * Revision 1.11 2005/03/02 15:03:46 f_limousin
43 * p_radial_vect is added in del_deriv() and set_der_0x0.
44 *
45 * Revision 1.10 2004/11/18 12:22:33 jl_jaramillo
46 * Method to compute the unit radial vector field with respect
47 * spherical surfaces
48 *
49 * Revision 1.9 2004/02/18 18:45:36 e_gourgoulhon
50 * Computation of p_ricci_scal thanks to the new method
51 * Tensor::trace(const Metric& ).
52 *
53 * Revision 1.8 2004/01/22 14:35:23 e_gourgoulhon
54 * Corrected bug in operator=(const Sym_tensor& ): adresses of deleted
55 * p_met_cov and p_met_con are now set to 0x0.
56 *
57 * Revision 1.7 2004/01/20 09:51:40 f_limousin
58 * Correction in metric::determinant() : indices of tensors go now from 1 to
59 * 3 !
60 *
61 * Revision 1.6 2003/12/30 23:06:30 e_gourgoulhon
62 * Important reorganization of class Metric:
63 * -- suppression of virtual methods fait_* : the actual computations
64 * are now performed via the virtual methods con(), cov(), connect(),
65 * ricci(), ricci_scal(), determinant()
66 * -- the member p_connect is now treated as an ordinary derived data
67 * member
68 * -- the construction of the associated connection (member p_connect)
69 * is performed thanks to the new methods Map::flat_met_spher() and
70 * Map::flat_met_cart().
71 *
72 * Revision 1.5 2003/10/28 21:23:59 e_gourgoulhon
73 * Method Tensor::contract(int, int) renamed Tensor::scontract(int, int).
74 *
75 * Revision 1.4 2003/10/06 16:17:30 j_novak
76 * Calculation of contravariant derivative and Ricci scalar.
77 *
78 * Revision 1.3 2003/10/06 13:58:47 j_novak
79 * The memory management has been improved.
80 * Implementation of the covariant derivative with respect to the exact Tensor
81 * type.
82 *
83 * Revision 1.2 2003/10/03 11:21:47 j_novak
84 * More methods for the class Metric
85 *
86 * Revision 1.1 2003/10/02 15:45:50 j_novak
87 * New class Metric
88 *
89 *
90 *
91 * $Header: /cvsroot/Lorene/C++/Source/Metric/metric.C,v 1.14 2016/12/05 16:17:59 j_novak Exp $
92 *
93 */
94
95// C headers
96#include <cstdlib>
97
98// Lorene headers
99#include "metric.h"
100#include "utilitaires.h"
101
102 //-----------------//
103 // Constructors //
104 //-----------------//
105
106namespace Lorene {
107Metric::Metric(const Sym_tensor& symti) : mp(&symti.get_mp()),
108 p_met_cov(0x0),
109 p_met_con(0x0) {
110
111 int type_index = symti.get_index_type(0) ;
112 assert (symti.get_index_type(1) == type_index) ;
113
114 if (type_index == COV) {
115 p_met_cov = new Sym_tensor(symti) ;
116 }
117 else {
118 assert(type_index == CON) ;
119 p_met_con = new Sym_tensor(symti) ;
120 }
121
122 set_der_0x0() ;
124
125}
126
127
128Metric::Metric(const Metric& meti) : mp(meti.mp),
129 p_met_cov(0x0),
130 p_met_con(0x0) {
131
132 if (meti.p_met_cov != 0x0) p_met_cov = new Sym_tensor(*meti.p_met_cov) ;
133
134 if (meti.p_met_con != 0x0) p_met_con = new Sym_tensor(*meti.p_met_con) ;
135
136 set_der_0x0() ;
138
139}
140
141Metric::Metric(const Map& mpi, FILE* ) : mp(&mpi),
142 p_met_cov(0x0),
143 p_met_con(0x0) {
144
145 cout << "Metric::Metric(FILE*) : not implemented yet!" << endl ;
146
147 abort() ;
148}
149
150Metric::Metric(const Map& mpi) : mp(&mpi),
151 p_met_cov(0x0),
152 p_met_con(0x0) {
153 set_der_0x0() ;
155
156}
157
158
159 //---------------//
160 // Destructor //
161 //---------------//
162
164
165 if (p_met_cov != 0x0) delete p_met_cov ;
166
167 if (p_met_con != 0x0) delete p_met_con ;
168
169 del_deriv() ;
170
172
173}
174
175 //-------------------//
176 // Memory management //
177 //-------------------//
178
179void Metric::del_deriv() const {
180
181 if (p_connect != 0x0) delete p_connect ;
182 if (p_ricci_scal != 0x0) delete p_ricci_scal ;
183 if (p_determinant != 0x0) delete p_determinant ;
184 if (p_radial_vect != 0x0) delete p_radial_vect ;
185
186 set_der_0x0() ;
187
188 //## call to del_tensor_depend() ?
189}
190
192
193 p_connect = 0x0 ;
194 p_ricci_scal = 0x0 ;
195 p_determinant = 0x0 ;
196 p_radial_vect = 0x0 ;
197
198}
199
201
202 for (int i=0 ; i<N_TENSOR_DEPEND ; i++)
203 if (tensor_depend[i] != 0x0) {
204 int j = tensor_depend[i]->get_place_met(*this) ;
205 if (j!=-1) tensor_depend[i]->del_derive_met(j) ;
206 }
208
209}
210
212
213 for (int i=0 ; i<N_TENSOR_DEPEND ; i++) {
214 tensor_depend[i] = 0x0 ;
215 }
216}
217
218
219 //-----------------------//
220 // Mutators / assignment //
221 //-----------------------//
222
223void Metric::operator=(const Metric& meti) {
224
225 assert( mp == meti.mp) ;
226
227 if (p_met_cov != 0x0) {
228 delete p_met_cov ;
229 p_met_cov = 0x0 ;
230 }
231
232 if (p_met_con != 0x0) {
233 delete p_met_con ;
234 p_met_con = 0x0 ;
235 }
236
237 if (meti.p_met_cov != 0x0) {
238 p_met_cov = new Sym_tensor(*meti.p_met_cov) ;
239 }
240
241 if (meti.p_met_con != 0x0) {
242 p_met_con = new Sym_tensor(*meti.p_met_con) ;
243 }
244
245 del_deriv() ;
246
247}
248
249void Metric::operator=(const Sym_tensor& symti) {
250
251 assert(mp == &symti.get_mp()) ;
252
253 int type_index = symti.get_index_type(0) ;
254 assert (symti.get_index_type(1) == type_index) ;
255
256 if (p_met_cov != 0x0) {
257 delete p_met_cov ;
258 p_met_cov = 0x0 ;
259 }
260
261 if (p_met_con != 0x0) {
262 delete p_met_con ;
263 p_met_con = 0x0 ;
264 }
265
266 if (type_index == COV) {
267 p_met_cov = new Sym_tensor(symti) ;
268 }
269 else {
270 assert(type_index == CON) ;
271 p_met_con = new Sym_tensor(symti) ;
272 }
273
274 del_deriv() ;
275
276}
277
278 //----------------//
279 // Accessors //
280 //----------------//
281
282
283const Sym_tensor& Metric::cov() const {
284
285 if (p_met_cov == 0x0) { // a new computation is necessary
286 assert( p_met_con != 0x0 ) ;
287 p_met_cov = p_met_con->inverse() ;
288 }
289
290 return *p_met_cov ;
291}
292
293const Sym_tensor& Metric::con() const {
294
295 if (p_met_con == 0x0) { // a new computation is necessary
296 assert( p_met_cov != 0x0 ) ;
297 p_met_con = p_met_cov->inverse() ;
298 }
299
300 return *p_met_con ;
301}
302
303
305
306 if (p_connect == 0x0) { // a new computation is necessary
307
308 // The triad is obtained from the covariant or contravariant representation:
309 const Base_vect_spher* triad_s ;
310 const Base_vect_cart* triad_c ;
311 if (p_met_cov != 0x0) {
312 triad_s =
313 dynamic_cast<const Base_vect_spher*>(p_met_cov->get_triad()) ;
314 triad_c =
315 dynamic_cast<const Base_vect_cart*>(p_met_cov->get_triad()) ;
316 }
317 else {
318 assert(p_met_con != 0x0) ;
319 triad_s =
320 dynamic_cast<const Base_vect_spher*>(p_met_con->get_triad()) ;
321 triad_c =
322 dynamic_cast<const Base_vect_cart*>(p_met_con->get_triad()) ;
323 }
324
325 // Background flat metric in spherical or Cartesian components
326 if ( triad_s != 0x0 ) {
327 p_connect = new Connection(*this, mp->flat_met_spher()) ;
328 }
329 else {
330 assert( triad_c != 0x0 ) ;
331 p_connect = new Connection(*this, mp->flat_met_cart()) ;
332 }
333
334 }
335
336 return *p_connect ;
337
338}
339
340
341const Sym_tensor& Metric::ricci() const {
342
343 const Tensor& ricci_connect = connect().ricci() ;
344
345 // Check: the Ricci tensor of the connection associated with
346 // the metric must be symmetric:
347 assert( typeid(ricci_connect) == typeid(const Sym_tensor&) ) ;
348
349 return dynamic_cast<const Sym_tensor&>( ricci_connect ) ;
350}
351
352
354
355 if (p_ricci_scal == 0x0) { // a new computation is necessary
356
357 p_ricci_scal = new Scalar( ricci().trace(*this) ) ;
358
359 }
360
361 return *p_ricci_scal ;
362
363}
364
366
367 if (p_radial_vect == 0x0) { // a new computation is necessary
368
369
370 p_radial_vect = new Vector ((*this).get_mp(), CON, *((*this).con().get_triad()) ) ;
371
372 Scalar prov ( sqrt((*this).con()(1,1)) ) ;
373
374 prov.std_spectral_base() ;
375
376
377 p_radial_vect->set(1) = (*this).con()(1,1)/ prov ;
378
379 p_radial_vect->set(2) = (*this).con()(1,2)/ prov ;
380
381 p_radial_vect->set(3) = (*this).con()(1,3)/ prov ;
382
383
384
385 // p_radial_vect.std_spectral_base() ;
386
387
388 }
389
390 return *p_radial_vect ;
391
392}
393
394
396
397 if (p_determinant == 0x0) { // a new computation is necessary
398
399 p_determinant = new Scalar(*mp) ;
400 *p_determinant = cov()(1, 1)*cov()(2, 2)*cov()(3, 3)
401 + cov()(1, 2)*cov()(2, 3)*cov()(3, 1)
402 + cov()(1, 3)*cov()(2, 1)*cov()(3, 2)
403 - cov()(3, 1)*cov()(2, 2)*cov()(1, 3)
404 - cov()(3, 2)*cov()(2, 3)*cov()(1, 1)
405 - cov()(3, 3)*cov()(2, 1)*cov()(1, 2) ;
406 }
407
408 return *p_determinant ;
409}
410
411
412
413 //---------//
414 // Outputs //
415 //---------//
416
417void Metric::sauve(FILE* fd) const {
418
419 // Which representation is to be saved
420 int indic ;
421 if (p_met_cov != 0x0)
422 indic = COV ;
423 else if (p_met_con != 0x0)
424 indic = CON ;
425 else indic = 0 ;
426 fwrite_be(&indic, sizeof(int), 1, fd) ;
427 switch (indic) {
428 case COV : {
429 p_met_cov->sauve(fd) ;
430 break ;
431 }
432 case CON : {
433 p_met_con->sauve(fd) ;
434 break ;
435 }
436 default : {
437 break ;
438 }
439 }
440}
441
442ostream& operator<<(ostream& ost, const Metric& meti) {
443
444 meti >> ost ;
445 return ost ;
446}
447
448
449ostream& Metric::operator>>(ostream& ost) const {
450
451 ost << '\n' ;
452
453 ost << "General type metric" << '\n' ;
454 ost << "-------------------" << '\n' ;
455 ost << '\n' ;
456
457 if (p_met_cov == 0x0) {
458 ost << "Covariant representation unknown!" << '\n' ;
459 assert( p_met_con != 0x0) ;
460 ost << "CONTRA-variant representation: " << '\n' ;
461 ost << *p_met_con ;
462 }
463 else {
464 ost << "Covariant representation: " << '\n' ;
465 ost << *p_met_cov ;
466 }
467
468
469 if (p_connect == 0x0)
470 ost << "Associated connection not computed yet." << '\n' ;
471 else
472 ost << "Associated connection computed." << '\n' ;
473
474 if (p_ricci_scal == 0x0)
475 ost << "Ricci scalar not computed yet." << '\n' ;
476 else
477 ost << "Ricci scalar computed." << '\n' ;
478
479 if (p_determinant == 0x0)
480 ost << "determinant not computed yet." << '\n' ;
481 else
482 ost << "determinant computed." << '\n' ;
483
484 ost << endl ;
485 return ost ;
486}
487
488}
Cartesian vectorial bases (triads).
Definition base_vect.h:201
Spherical orthonormal vectorial bases (triads).
Definition base_vect.h:308
Class Connection.
Definition connection.h:113
virtual const Tensor & ricci() const
Computes (if not up to date) and returns the Ricci tensor associated with the current connection.
Definition connection.C:665
void del_tensor_depend() const
Deletes all the derivative members of the Tensor contained in tensor_depend .
Definition metric.C:200
void del_deriv() const
Deletes all the derived quantities.
Definition metric.C:179
virtual ~Metric()
Destructor.
Definition metric.C:163
virtual const Sym_tensor & con() const
Read-only access to the contravariant representation.
Definition metric.C:293
virtual const Vector & radial_vect() const
Returns the radial vector normal to a spherical slicing and pointing toward spatial infinity.
Definition metric.C:365
Metric(const Sym_tensor &tens)
Standard constructor from a Sym_tensor .
Definition metric.C:107
const Map *const mp
Reference mapping.
Definition metric.h:95
const Map & get_mp() const
Returns the mapping.
Definition metric.h:202
virtual const Sym_tensor & cov() const
Read-only access to the covariant representation.
Definition metric.C:283
void set_tensor_depend_0x0() const
Sets all elements of tensor_depend to 0x0.
Definition metric.C:211
void set_der_0x0() const
Sets to 0x0 all the pointers on derived quantities.
Definition metric.C:191
const Sym_tensor & ricci() const
Returns the Ricci tensor (given by the Connection p_connect ).
Definition metric.C:341
Sym_tensor * p_met_con
Pointer on the covariant representation.
Definition metric.h:105
Vector * p_radial_vect
Pointer to the radial vector normal to a spherical slicing and pointing toward spatial infinity.
Definition metric.h:125
virtual const Connection & connect() const
Returns the connection.
Definition metric.C:304
virtual const Scalar & determinant() const
Returns the determinant.
Definition metric.C:395
Sym_tensor * p_met_cov
Pointer on the contravariant representation.
Definition metric.h:100
virtual ostream & operator>>(ostream &) const
Operator >> (virtual function called by the operator <<).
Definition metric.C:449
Scalar * p_determinant
Pointer on the determinant.
Definition metric.h:132
virtual const Scalar & ricci_scal() const
Returns the Ricci scalar.
Definition metric.C:353
friend ostream & operator<<(ostream &, const Metric &)
Display.
Definition metric.C:442
void operator=(const Metric &met)
Assignment to another Metric.
Definition metric.C:223
virtual void sauve(FILE *) const
Save in a file.
Definition metric.C:417
const Tensor * tensor_depend[N_TENSOR_DEPEND]
Pointer on the dependancies, that means the array contains pointers on all the Tensor whom derivative...
Definition metric.h:139
Scalar * p_ricci_scal
Pointer on the Ricci scalar.
Definition metric.h:119
Connection * p_connect
Connection associated with the metric.
Definition metric.h:112
Tensor field of valence 0 (or component of a tensorial field).
Definition scalar.h:393
virtual void std_spectral_base()
Sets the spectral bases of the Valeur va to the standard ones for a scalar field.
Definition scalar.C:790
Class intended to describe valence-2 symmetric tensors.
Definition sym_tensor.h:226
Tensor field of valence 1.
Definition vector.h:188
Cmp sqrt(const Cmp &)
Square root.
Definition cmp_math.C:223
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
const Map & get_mp() const
Returns the mapping.
Definition tensor.h:874
int get_index_type(int i) const
Gives the type (covariant or contravariant) of the index number i .
Definition tensor.h:899
Lorene prototypes.
Definition app_hor.h:67
Map(const Mg3d &)
Constructor from a multi-domain 3D grid.
Definition map.C:142