Hi!
I would like to find the singular value fields of e.g. a gradient tensor of some vector. If u
is some vector field, the gradient is given as
Gij = grad(u)
.
Finding the singular values is the same as finding the square root of the three eigenvalues to the matrix
GTG = grad(u).T*grad(u)
As a solution GTG is now computed by some fast inverse diagonal DG-matrix, then I loop over each cell in the mesh, create a cell local matrix GTG_local
which contains all the values for that specific cell. Then numpy.linalg is applied to solve for the eigenvectors of GTG_local
. Code example:
for cell in cells(mesh):
# Extract cell dofs
dofs_TFS = dofmap_TFS.cell_dofs(cell.index()) # TensorFunctionSpace, DG
dof_DG = dofmap_DG.cell_dofs(cell.index()) # FunctionSpace, DG
# Compute local matrix
for k in xrange(len(dofs)):
i,j = ij_pairs[k] # Extract i,j pairs; e.g. (0,0), (0,1) and so on
GTG_local[i][j] = GTG[dofs_TFS[k]]
# Compute eigenvalues of matrix
w,a = linalg.eig(GTG_local)
# Sort eigenvalues by size and add to arrays
w.sort()
s3[dof_DG], s2[dof_DG], s1[dof_DG] = np.sqrt(w)
This solution seems to work fine, but it is problematic in several ways. The cell loop is slow, and if this process is to be repeated each step in a time loop it will be too time consuming. Even worse is the fact that one needs to solve N number of eigenvalue problems with numpy, where N equals the number of cells in the mesh. Testing shows that the latter is the most time consuming operation.
Does there exist a more elegant and faster solution? Or is the solution here to wrap som C++ code of this approach?
Thanks!