[LORENE] Cmp/Tenseur: bug or feature?

Eric Gourgoulhon Eric.Gourgoulhon at obspm.fr
Wed Nov 12 11:16:32 CET 2003


Dear Reinhard,

What you mention is not a bug, but a feature of Cmp/Tenseur in Lorene,
which is slightly odd in terms of "user-friendliness" but is  motivated
by  code efficiency  considerations.

Indeed, the Tenseur objects, as almost all Lorene objects, have a state
flag (member "etat"), such that when in the zero state (etat=ETATZERO),
all sub-objects (like the Cmp's in the Tenseur) are not allocated
(to preserve memory) and the corresponding pointers are set to 0x0.
Therefore when the Tenseur uuu is in the zero state, uuu.c[0] = 0x0.
The problem you have faced arises from the fact that, for
efficiency reasons, the function Tenseur::set() does not perform
any memory allocation: it therefore assumes that the state is
ETATQCQ (ordinary state) and returns a reference onto
the Cmp located at the address c[0]. The memory allocation for this
Cmp must be performed outside set(), by a call to the
method Tenseur::set_etat_qcq().
This explains why your first example works (the Tenseur uuu
has remained in the state ETATQCQ during the assignement
    uuu.set() = (omega - nphi() ) / nnn();
whereas the second example does not work: the
assignement
    uuu = (omega - nphi() ) / nnn();
sets uuu in the state ETATZERO because the rhs is null.
But even in this last case, if you had used
    cout << uuu() << endl;
instead of
    cout << uuu.set() << endl;
it would have been OK. As a general rule, it is preferable
to use Tenseur::operator()() than Tenseur::set() for
read-only operations.

Note that the new classes Tensor and Scalar (cf. my messages on
lorene.list on 24 October) does not have this kind of
problem: in order to improve user-friendliness, the
components of a Tensor are always allocated at the
Tensor construction and remain allocated during all
the Tensor life. In fact the Tensor class does not have
any state flag, only the Scalar class (storing the
Tensor components) have one. Moreover, the fact
that Scalar (to replace Cmp) is now a derived class
of Tensor (to replace Tenseur) facilitates greatly the
manipulations of the kind you are speaking about.

Best wishes,

    Eric.


Reinhard Prix wrote:

>Hi,
>
>I've just noticed a slightly odd 'feature' in using scalar Tenseurs,
>and I'm not sure if it is intended, or how one is supposed to deal with this.
>
>
>Given a scalar nphi, which has ETATZERO, but nphi.c[0] = 0x0
>(as appears in hydro_euler in the Newtonian case). 
>
>When doing an assignment to another scalar, the Tensor uuu say, 
>by using Cmp's like this  (where omega=0)
>  
>
>>uuu.set() = (omega - nphi() ) / nnn();
>>    
>>
>then uuu seems to be setup properly, namely one can do
>  
>
>> cout << uuu.set() << endl;
>>    
>>
>and gets
>  
>
>>*** Cmp IDENTICALLY ZERO
>>    
>>
>
>but if you do the same via tensor-assignment, namely 
>  
>
>>uuu = (omega - nphi() ) / nnn();
>>    
>>
>then trying to access the Cmp of uuu 
>  
>
>>cout << uuu.set() << endl;
>>    
>>
>yields
>  
>
>>tenseur.C:820: Cmp &Tenseur::set (): Assertion `etat == 2' failed
>>    
>>
>apparently because of uuu.c[0] = 0x0, propagated from nphi...
>
>
>Now, I'm not sure if that's the way it's supposed to be, but it does
>seem rather confusing to me...
>I would think that either .set() should survive a .c[0]==0x0 if it
>has ETATZERO, or the Cmp c[0] should be created also when doing a
>tensor-assignment. 
>
>Furthermore, I'm not even sure if the fact that nphi has
>ETATZERO but c[0] == 0x0 is not an anomalie to begin with...
>
>Thanks for any hints ;)
>
>Cheers,
>Reinhard
>
>  
>


-- 
Eric Gourgoulhon
Laboratoire de l'Univers et de ses THeories (LUTH)
UMR 8102 du CNRS / Observatoire de Paris, F-92195 Meudon Cedex, France
tel: +33 1.45.07.74.33 (secretariat : +33 1.45.07.75.10)
e-mail: Eric.Gourgoulhon at obspm.fr    WWW: http://www.luth.obspm.fr/






More information about the Lorene.list mailing list