Dear all,


I am trying to understand how the gradient operator works on Firedrake and there is something I misunderstand.


As far as I understood, if I define (in the HORIZONTAL plane):

V = FunctionSpace(mesh,"CG", 1)  and 

W = VectorFunctionSpace(mesh,"CG", 1, dim=N)


such that :

psi_1 = Function (V)  

psi_N = Function(W) (vector of dim (1,N))


then,

grad(psi_1) is a rank 1 tensor of  2 rows or columns (does not matter),

grad(psi_N) is a rank 2 tensor of dim (N, 2) 


1) Is that correct ?


2) Then, I understand that we can compute grad(psi_N)*grad(psi_1) but not grad(psi_1)*grad(psi_N), because the dimensions agree in the first case but not in the second one. 

However,  when taking the transpose of grad(psi_N), I don't understand what happens. 

The product:

grad(psi_1)*(grad(psi_N)).T cannot be computed, and the product 

(grad(psi_N)).T * grad(psi_1) can be computed,

while I would expect the contrary (since I expect (grad(psi_N)).T to be of dimension (2,N) ). 


Moreover, if I print the expression of (grad(psi_N)).T*grad(psi_1), I get :


{ A | A_{i_8} = sum_{i_9} ((grad(w_6))^T)[i_8, i_9] * (grad(w_4))[i_9]  }


which is actually 

A | A_i = sum_{j=1}^{j=2}  (grad(psi_N))^T(i,j) * d psi_1/dxj


But if grad(psi_N) has dimension (N,2), then (grad(psi_N))^T has dimension (2,N) and therefore the expression above would not work if N>2. 


Can someone explain me how the gradient of psi_N and its transpose are evaluated, and what are their rank and dimension ?  Is there a command to print these dimensions ?


Thanks and best regards,

Floriane