Slicing Tensors using subset of Free Indices or multiple free indices

I have a problem where I would like to separate out portions of a 4th order tensor. It’s perfectly clear to me (1) how to use free indices in UFL and (2) how to use a single fixed index. However, what I would like to do is select one portion of this fourth order tensor using two out of the three indices. This involves having a “free index” that covers a subset of the free indices I’ve already designed.

A minimum working example illustrating what I’m trying to do is:

from ufl import as_tensor,indices,Identity

#geometric dimension
d = 3
#indices
i,j,k,l=indices(4)
#d x d indentity matrix
delta = Identity(d)

#4th order tensor (shape 3x3x3x3)
C = as_tensor(delta[i,k]*delta[j,l] + delta[j,k]*delta[i,l],(i,j,k,l))
print(C.ufl_shape)

#2nd order tensor (shape 3x3)
Ci1k1 = as_tensor(C[i,0,k,0],(i,k))
print(Ci1k1.ufl_shape)

#3rd order tensor desired (shape 3x3x2)
Ci1kB = as_tensor(C[i,0,k,1:2],(i,k))
print(Ci1kB)

This gives the following output and error:

(3, 3, 3, 3)
(3, 3)
Only full slices (:) allowed.
Traceback (most recent call last):
  File "/home/jkrokowski/indexing_MWE.py", line 19, in <module>
    Ci1kB = as_tensor(C[i,0,k,1:2],(i,k))
  File "/home/jkrokowski/anaconda3/envs/fenicsx/lib/python3.9/site-packages/ufl/exproperators.py", line 438, in _getitem
    all_indices, slice_indices, repeated_indices = create_slice_indices(component, shape, self.ufl_free_indices)
  File "/home/jkrokowski/anaconda3/envs/fenicsx/lib/python3.9/site-packages/ufl/index_combination_utils.py", line 156, in create_slice_indices
    error("Only full slices (:) allowed.")
  File "/home/jkrokowski/anaconda3/envs/fenicsx/lib/python3.9/site-packages/ufl/log.py", line 135, in error
    raise self._exception_type(self._format_raw(*message))
ufl.log.UFLException: Only full slices (:) allowed.

Is there some other notation for this process? If not can someone suggest a method to get this 3x3x2 tensor?

Consider the following:

from ufl import as_tensor, indices, Identity

# geometric dimension
d = 3
# indices
i, j, k, l = indices(4)
# d x d indentity matrix
delta = Identity(d)

# 4th order tensor (shape 3x3x3x3)
C = as_tensor(delta[i, k]*delta[j, l] + delta[j, k]*delta[i, l], (i, j, k, l))


D = as_tensor([[[C[i, 0, k, l] for l in range(1, 3)]
              for k in range(d)] for i in range(d)])
print(D.ufl_shape)
1 Like