This is a read only copy of the old FEniCS QA forum. Please visit the new QA forum to ask questions

Instant can't set more than two attributes

0 votes

I am developing an Expression with instant to gain speed, and for it I need to load some fields. The expression reads

    my_expression ='''
    class test : public Expression
        {
        public:

        test() : Expression(2) { }

        void eval(Array<double>& values, const Array<double>& x) const {
            //double dx = x[0] - 0.5;
            //double dy = x[1] - 0.5;
            //double R_eval = exp(-dx*dx - dy*dy) - 0.8;
            //u->eval(values, x);
            //dx += values[0];
            //dy += values[1];
            //double T_eval = exp(-0.8*dx*dx - 1.3*dy*dy) - 0.8;
            //values[0] = -2*0.8*dx*(T_eval - R_eval)*T_eval;
            //values[1] = -2*1.3*dy*(T_eval - R_eval)*T_eval;

            double R_val, T_val, dTx_val, dTy_val;
            R->eval(values, x);
            R_val = values[0];

            T->eval(values, x);
            T_val = values[0];

            dTx->eval(values, x);
            dTx_val = values[0];

            dTy->eval(values, x);
            dTy_val = values[0];

            values[0] = (T_val - R_val)*dTx_val;
            values[1] = (T_val - R_val)*dTy_val;
        }

        std::shared_ptr<const Function> u; 
        std::shared_ptr<const Function> R;
        std::shared_ptr<const Function> T;
        std::shared_ptr<const Function> dTx;
        std::shared_ptr<const Function> dTy;
    };
    '''

and after defining it I read the functions (previously saved) and then set them to the expression:

    # Definition of image spaces
    VR = FunctionSpace(UnitSquareMesh(*self.R.arr.shape), "CG", 2)         
    VT = FunctionSpace(UnitSquareMesh(*self.T.arr.shape), "CG", 2)         
    VdT = FunctionSpace(UnitSquareMesh(*self.T.arr.shape), "CG", 1)         
    smooth = True

    # Load I

    Rf = Function(VR)
    hdf5 = HDF5File(mesh.mpi_comm(), "./HDF5/brain_R.h5", "r") 
    hdf5.read(Rf, "brain_R")

    # T


    Tf = Function(VT)
    hdf5 = HDF5File(mesh.mpi_comm(), "./HDF5/brain_T.h5", "r")
    hdf5.read(Tf, "brain_T")

    # grad T


    dTx = Function(VdT)
    hdf5 = HDF5File(mesh.mpi_comm(), "./HDF5/brain_T_x.h5", "r")
    hdf5.read(dTx, "brain_T_x")

    dTy = Function(VdT)        
    hdf5 = HDF5File(mesh.mpi_comm(), "./HDF5/brain_T_y.h5", "r")
    hdf5.read(dTy, "brain_T_y")

    # PICCARD ITERATIONS #

    w = Function(V)
    w_prev = Function(V)
    w.vector()[:] = 0.
    w_prev.vector()[:] = 0.
    element = VectorElement('CG', mesh.ufl_cell(), 2)
    mpiprint("Start iterations...")
    t = time()

    f = Expression(my_expression, element = element)
    f.u = w_prev
    f.R = Rf
    f.T = Tf
    f.dTx = dTx
    f.dTy = dTy

Here, I get the following error:

f.T = Tf
AttributeError: can't set attribute

I have already tried projecting Tf into VR because Rf is correctly loaded, but it still doesn't work. It seems like a bug, but I thought it would be better to ask here first.

asked Apr 4, 2017 by nabarnaf FEniCS User (2,940 points)

1 Answer

0 votes
 
Best answer

The problem seems to be only related to the function T. If you change the lines

T->eval(values, x);
std::shared_ptr<const Function> T;
f.T = Tf

to

TT->eval(values, x);
std::shared_ptr<const Function> TT;
f.TT = Tf

respectively, all works fine. This is a weird behavior (maybe the variable T is reserved?) and I agree with you that this can be a bug.

answered Apr 4, 2017 by hernan_mella FEniCS Expert (19,460 points)
selected Apr 4, 2017 by nabarnaf

Problem solved! Indeed maybe T is reserved, but I'm not sure if I should report it, maybe I just should have known. Thanks!

I had the same problem, I asked one of the developers in person. T is reserved for transposition, see

expr = Expression(...)
help(expr)

or directly

help(ufl.core.expr.Expr)

for

T
Transposed a rank two tensor expression. For more general transpose
operations of higher order tensor expressions, use indexing and Tensor.

...