def deviatoric(self, o, A):
     sh = self._square_matrix_shape(A)
     if sh[0] == 2:
         return as_matrix([[-1./2*A[1,1]+1./2*A[0,0],A[0,1]],[A[1,0],1./2*A[1,1]-1./2*A[0,0]]])
     elif sh[0] == 3:
         return as_matrix([[-1./3*A[1,1]-1./3*A[2,2]+2./3*A[0,0],A[0,1],A[0,2]],[A[1,0],2./3*A[1,1]-1./3*A[2,2]-1./3*A[0,0],A[1,2]],[A[2,0],A[2,1],-1./3*A[1,1]+2./3*A[2,2]-1./3*A[0,0]]])
     error("dev(A) not implemented for dimension %s." % sh[0])
 def cofactor(self, o, A):
     # TODO: Find common subexpressions here.
     # TODO: Better implementation?
     sh = self._square_matrix_shape(A)
     if sh[0] == 2:
         return as_matrix([[A[1,1],-A[1,0]],[-A[0,1],A[0,0]]])
     elif sh[0] == 3:
         return as_matrix([
             [A[1,1]*A[2,2] - A[2,1]*A[1,2],A[2,0]*A[1,2] - A[1,0]*A[2,2], - A[2,0]*A[1,1] + A[1,0]*A[2,1]],
             [A[2,1]*A[0,2] - A[0,1]*A[2,2],A[0,0]*A[2,2] - A[2,0]*A[0,2], - A[0,0]*A[2,1] + A[2,0]*A[0,1]],
             [A[0,1]*A[1,2] - A[1,1]*A[0,2],A[1,0]*A[0,2] - A[0,0]*A[1,2], - A[1,0]*A[0,1] + A[0,0]*A[1,1]]
             ])
     elif sh[0] == 4:
         return as_matrix([
             [-A[3,1]*A[2,2]*A[1,3] - A[3,2]*A[2,3]*A[1,1] + A[1,3]*A[3,2]*A[2,1] + A[3,1]*A[2,3]*A[1,2] + A[2,2]*A[1,1]*A[3,3] - A[3,3]*A[2,1]*A[1,2],
              -A[1,0]*A[2,2]*A[3,3] + A[2,0]*A[3,3]*A[1,2] + A[2,2]*A[1,3]*A[3,0] - A[2,3]*A[3,0]*A[1,2] + A[1,0]*A[3,2]*A[2,3] - A[1,3]*A[3,2]*A[2,0],
               A[1,0]*A[3,3]*A[2,1] + A[2,3]*A[1,1]*A[3,0] - A[2,0]*A[1,1]*A[3,3] - A[1,3]*A[3,0]*A[2,1] - A[1,0]*A[3,1]*A[2,3] + A[3,1]*A[1,3]*A[2,0],
               A[3,0]*A[2,1]*A[1,2] + A[1,0]*A[3,1]*A[2,2] + A[3,2]*A[2,0]*A[1,1] - A[2,2]*A[1,1]*A[3,0] - A[3,1]*A[2,0]*A[1,2] - A[1,0]*A[3,2]*A[2,1]],
             [ A[3,1]*A[2,2]*A[0,3] + A[0,2]*A[3,3]*A[2,1] + A[0,1]*A[3,2]*A[2,3] - A[3,1]*A[0,2]*A[2,3] - A[0,1]*A[2,2]*A[3,3] - A[3,2]*A[0,3]*A[2,1],
              -A[2,2]*A[0,3]*A[3,0] - A[0,2]*A[2,0]*A[3,3] - A[3,2]*A[2,3]*A[0,0] + A[2,2]*A[3,3]*A[0,0] + A[0,2]*A[2,3]*A[3,0] + A[3,2]*A[2,0]*A[0,3],
               A[3,1]*A[2,3]*A[0,0] - A[0,1]*A[2,3]*A[3,0] - A[3,1]*A[2,0]*A[0,3] - A[3,3]*A[0,0]*A[2,1] + A[0,3]*A[3,0]*A[2,1] + A[0,1]*A[2,0]*A[3,3],
               A[3,2]*A[0,0]*A[2,1] - A[0,2]*A[3,0]*A[2,1] + A[0,1]*A[2,2]*A[3,0] + A[3,1]*A[0,2]*A[2,0] - A[0,1]*A[3,2]*A[2,0] - A[3,1]*A[2,2]*A[0,0]],
             [ A[3,1]*A[1,3]*A[0,2] - A[0,2]*A[1,1]*A[3,3] - A[3,1]*A[0,3]*A[1,2] + A[3,2]*A[1,1]*A[0,3] + A[0,1]*A[3,3]*A[1,2] - A[0,1]*A[1,3]*A[3,2],
               A[1,3]*A[3,2]*A[0,0] - A[1,0]*A[3,2]*A[0,3] - A[1,3]*A[0,2]*A[3,0] + A[0,3]*A[3,0]*A[1,2] + A[1,0]*A[0,2]*A[3,3] - A[3,3]*A[0,0]*A[1,2],
              -A[1,0]*A[0,1]*A[3,3] + A[0,1]*A[1,3]*A[3,0] - A[3,1]*A[1,3]*A[0,0] - A[1,1]*A[0,3]*A[3,0] + A[1,0]*A[3,1]*A[0,3] + A[1,1]*A[3,3]*A[0,0],
               A[0,2]*A[1,1]*A[3,0] - A[3,2]*A[1,1]*A[0,0] - A[0,1]*A[3,0]*A[1,2] - A[1,0]*A[3,1]*A[0,2] + A[3,1]*A[0,0]*A[1,2] + A[1,0]*A[0,1]*A[3,2]],
             [ A[0,3]*A[2,1]*A[1,2] + A[0,2]*A[2,3]*A[1,1] + A[0,1]*A[2,2]*A[1,3] - A[2,2]*A[1,1]*A[0,3] - A[1,3]*A[0,2]*A[2,1] - A[0,1]*A[2,3]*A[1,2],
               A[1,0]*A[2,2]*A[0,3] + A[1,3]*A[0,2]*A[2,0] - A[1,0]*A[0,2]*A[2,3] - A[2,0]*A[0,3]*A[1,2] - A[2,2]*A[1,3]*A[0,0] + A[2,3]*A[0,0]*A[1,2],
              -A[0,1]*A[1,3]*A[2,0] + A[2,0]*A[1,1]*A[0,3] + A[1,3]*A[0,0]*A[2,1] - A[1,0]*A[0,3]*A[2,1] + A[1,0]*A[0,1]*A[2,3] - A[2,3]*A[1,1]*A[0,0],
               A[1,0]*A[0,2]*A[2,1] - A[0,2]*A[2,0]*A[1,1] + A[0,1]*A[2,0]*A[1,2] + A[2,2]*A[1,1]*A[0,0] - A[1,0]*A[0,1]*A[2,2] - A[0,0]*A[2,1]*A[1,2]]
             ])
     error("Cofactor not implemented for dimension %s." % sh[0])
Ejemplo n.º 3
0
def diag(A):
    """UFL operator: Take the diagonal part of rank 2 tensor *A* **or**
    make a diagonal rank 2 tensor from a rank 1 tensor.

    Always returns a rank 2 tensor. See also ``diag_vector``."""

    # TODO: Make a compound type or two for this operator

    # Get and check dimensions
    r = len(A.ufl_shape)
    if r == 1:
        n, = A.ufl_shape
    elif r == 2:
        m, n = A.ufl_shape
        if m != n:
            error("Can only take diagonal of square tensors.")
    else:
        error("Expecting rank 1 or 2 tensor.")

    # Build matrix row by row
    rows = []
    for i in range(n):
        row = [0] * n
        row[i] = A[i] if r == 1 else A[i, i]
        rows.append(row)
    return as_matrix(rows)
Ejemplo n.º 4
0
def diag(A):
    """UFL operator: Take the diagonal part of rank 2 tensor A _or_
    make a diagonal rank 2 tensor from a rank 1 tensor.

    Always returns a rank 2 tensor. See also diag_vector."""

    # TODO: Make a compound type or two for this operator

    # Get and check dimensions
    r = A.rank()
    if r == 1:
        n, = A.shape()
    elif r == 2:
        m, n = A.shape()
        ufl_assert(m == n, "Can only take diagonal of square tensors.")
    else:
        error("Expecting rank 1 or 2 tensor.")

    # Build matrix row by row
    rows = []
    for i in range(n):
        row = [0]*n
        row[i] = A[i] if r == 1 else A[i,i]
        rows.append(row)
    return as_matrix(rows)
Ejemplo n.º 5
0
def adj_expr_4x4(A):
    return as_matrix([
        [
            -A[3, 3] * A[2, 1] * A[1, 2] + A[1, 2] * A[3, 1] * A[2, 3] +
            A[1, 1] * A[3, 3] * A[2, 2] - A[3, 1] * A[2, 2] * A[1, 3] +
            A[2, 1] * A[1, 3] * A[3, 2] - A[1, 1] * A[3, 2] * A[2, 3],
            -A[3, 1] * A[0, 2] * A[2, 3] + A[0, 1] * A[3, 2] * A[2, 3] -
            A[0, 3] * A[2, 1] * A[3, 2] + A[3, 3] * A[2, 1] * A[0, 2] -
            A[3, 3] * A[0, 1] * A[2, 2] + A[0, 3] * A[3, 1] * A[2, 2],
            A[3, 1] * A[1, 3] * A[0, 2] + A[1, 1] * A[0, 3] * A[3, 2] -
            A[0, 3] * A[1, 2] * A[3, 1] - A[0, 1] * A[1, 3] * A[3, 2] +
            A[3, 3] * A[1, 2] * A[0, 1] - A[1, 1] * A[3, 3] * A[0, 2],
            A[1, 1] * A[0, 2] * A[2, 3] - A[2, 1] * A[1, 3] * A[0, 2] +
            A[0, 3] * A[2, 1] * A[1, 2] - A[1, 2] * A[0, 1] * A[2, 3] -
            A[1, 1] * A[0, 3] * A[2, 2] + A[0, 1] * A[2, 2] * A[1, 3]
        ],
        [
            A[3, 3] * A[1, 2] * A[2, 0] - A[3, 0] * A[1, 2] * A[2, 3] +
            A[1, 0] * A[3, 2] * A[2, 3] - A[3, 3] * A[1, 0] * A[2, 2] -
            A[1, 3] * A[3, 2] * A[2, 0] + A[3, 0] * A[2, 2] * A[1, 3],
            A[0, 3] * A[3, 2] * A[2, 0] - A[0, 3] * A[3, 0] * A[2, 2] +
            A[3, 3] * A[0, 0] * A[2, 2] + A[3, 0] * A[0, 2] * A[2, 3] -
            A[0, 0] * A[3, 2] * A[2, 3] - A[3, 3] * A[0, 2] * A[2, 0],
            -A[3, 3] * A[0, 0] * A[1, 2] + A[0, 0] * A[1, 3] * A[3, 2] -
            A[3, 0] * A[1, 3] * A[0, 2] + A[3, 3] * A[1, 0] * A[0, 2] +
            A[0, 3] * A[3, 0] * A[1, 2] - A[0, 3] * A[1, 0] * A[3, 2],
            A[0, 3] * A[1, 0] * A[2, 2] + A[1, 3] * A[0, 2] * A[2, 0] -
            A[0, 0] * A[2, 2] * A[1, 3] - A[0, 3] * A[1, 2] * A[2, 0] +
            A[0, 0] * A[1, 2] * A[2, 3] - A[1, 0] * A[0, 2] * A[2, 3]
        ],
        [
            A[3, 1] * A[1, 3] * A[2, 0] + A[3, 3] * A[2, 1] * A[1, 0] +
            A[1, 1] * A[3, 0] * A[2, 3] - A[1, 0] * A[3, 1] * A[2, 3] -
            A[3, 0] * A[2, 1] * A[1, 3] - A[1, 1] * A[3, 3] * A[2, 0],
            A[3, 3] * A[0, 1] * A[2, 0] - A[3, 3] * A[0, 0] * A[2, 1] -
            A[0, 3] * A[3, 1] * A[2, 0] - A[3, 0] * A[0, 1] * A[2, 3] +
            A[0, 0] * A[3, 1] * A[2, 3] + A[0, 3] * A[3, 0] * A[2, 1],
            -A[0, 0] * A[3, 1] * A[1, 3] + A[0, 3] * A[1, 0] * A[3, 1] -
            A[3, 3] * A[1, 0] * A[0, 1] + A[1, 1] * A[3, 3] * A[0, 0] -
            A[1, 1] * A[0, 3] * A[3, 0] + A[3, 0] * A[0, 1] * A[1, 3],
            A[0, 0] * A[2, 1] * A[1, 3] + A[1, 0] * A[0, 1] * A[2, 3] -
            A[0, 3] * A[2, 1] * A[1, 0] + A[1, 1] * A[0, 3] * A[2, 0] -
            A[1, 1] * A[0, 0] * A[2, 3] - A[0, 1] * A[1, 3] * A[2, 0]
        ],
        [
            -A[1, 2] * A[3, 1] * A[2, 0] - A[2, 1] * A[1, 0] * A[3, 2] +
            A[3, 0] * A[2, 1] * A[1, 2] - A[1, 1] * A[3, 0] * A[2, 2] +
            A[1, 0] * A[3, 1] * A[2, 2] + A[1, 1] * A[3, 2] * A[2, 0],
            -A[3, 0] * A[2, 1] * A[0, 2] - A[0, 1] * A[3, 2] * A[2, 0] +
            A[3, 1] * A[0, 2] * A[2, 0] - A[0, 0] * A[3, 1] * A[2, 2] +
            A[3, 0] * A[0, 1] * A[2, 2] + A[0, 0] * A[2, 1] * A[3, 2],
            A[0, 0] * A[1, 2] * A[3, 1] - A[1, 0] * A[3, 1] * A[0, 2] +
            A[1, 1] * A[3, 0] * A[0, 2] + A[1, 0] * A[0, 1] * A[3, 2] -
            A[3, 0] * A[1, 2] * A[0, 1] - A[1, 1] * A[0, 0] * A[3, 2],
            -A[1, 1] * A[0, 2] * A[2, 0] + A[2, 1] * A[1, 0] * A[0, 2] +
            A[1, 2] * A[0, 1] * A[2, 0] + A[1, 1] * A[0, 0] * A[2, 2] -
            A[1, 0] * A[0, 1] * A[2, 2] - A[0, 0] * A[2, 1] * A[1, 2]
        ],
    ])
Ejemplo n.º 6
0
def deviatoric_expr_3x3(A):
    return as_matrix(
        [[
            -1. / 3 * A[1, 1] - 1. / 3 * A[2, 2] + 2. / 3 * A[0, 0], A[0, 1],
            A[0, 2]
        ],
         [
             A[1, 0], 2. / 3 * A[1, 1] - 1. / 3 * A[2, 2] - 1. / 3 * A[0, 0],
             A[1, 2]
         ],
         [
             A[2, 0], A[2, 1],
             -1. / 3 * A[1, 1] + 2. / 3 * A[2, 2] - 1. / 3 * A[0, 0]
         ]])
Ejemplo n.º 7
0
def adj_expr_3x3(A):
    return as_matrix([
        [
            A[2, 2] * A[1, 1] - A[1, 2] * A[2, 1],
            -A[0, 1] * A[2, 2] + A[0, 2] * A[2, 1],
            A[0, 1] * A[1, 2] - A[0, 2] * A[1, 1]
        ],
        [
            -A[2, 2] * A[1, 0] + A[1, 2] * A[2, 0],
            -A[0, 2] * A[2, 0] + A[2, 2] * A[0, 0],
            A[0, 2] * A[1, 0] - A[1, 2] * A[0, 0]
        ],
        [
            A[1, 0] * A[2, 1] - A[2, 0] * A[1, 1],
            A[0, 1] * A[2, 0] - A[0, 0] * A[2, 1],
            A[0, 0] * A[1, 1] - A[0, 1] * A[1, 0]
        ],
    ])
Ejemplo n.º 8
0
def cofactor_expr_3x3(A):
    return as_matrix([
        [
            A[1, 1] * A[2, 2] - A[2, 1] * A[1, 2],
            A[2, 0] * A[1, 2] - A[1, 0] * A[2, 2],
            -A[2, 0] * A[1, 1] + A[1, 0] * A[2, 1]
        ],
        [
            A[2, 1] * A[0, 2] - A[0, 1] * A[2, 2],
            A[0, 0] * A[2, 2] - A[2, 0] * A[0, 2],
            -A[0, 0] * A[2, 1] + A[2, 0] * A[0, 1]
        ],
        [
            A[0, 1] * A[1, 2] - A[1, 1] * A[0, 2],
            A[1, 0] * A[0, 2] - A[0, 0] * A[1, 2],
            -A[1, 0] * A[0, 1] + A[0, 0] * A[1, 1]
        ],
    ])
Ejemplo n.º 9
0
def cofactor_expr_4x4(A):
    return as_matrix([
        [-A[3, 1] * A[2, 2] * A[1, 3] - A[3, 2] * A[2, 3] * A[1, 1] + A[1, 3] * A[3, 2] * A[2, 1] + A[3, 1] * A[2, 3] * A[1, 2] + A[2, 2] * A[1, 1] * A[3, 3] - A[3, 3] * A[2, 1] * A[1, 2],
         -A[1, 0] * A[2, 2] * A[3, 3] + A[2, 0] * A[3, 3] * A[1, 2] + A[2, 2] * A[1, 3] * A[3, 0] - A[2, 3] * A[3, 0] * A[1, 2] + A[1, 0] * A[3, 2] * A[2, 3] - A[1, 3] * A[3, 2] * A[2, 0],
         A[1, 0] * A[3, 3] * A[2, 1] + A[2, 3] * A[1, 1] * A[3, 0] - A[2, 0] * A[1, 1] * A[3, 3] - A[1, 3] * A[3, 0] * A[2, 1] - A[1, 0] * A[3, 1] * A[2, 3] + A[3, 1] * A[1, 3] * A[2, 0],
         A[3, 0] * A[2, 1] * A[1, 2] + A[1, 0] * A[3, 1] * A[2, 2] + A[3, 2] * A[2, 0] * A[1, 1] - A[2, 2] * A[1, 1] * A[3, 0] - A[3, 1] * A[2, 0] * A[1, 2] - A[1, 0] * A[3, 2] * A[2, 1]],
        [A[3, 1] * A[2, 2] * A[0, 3] + A[0, 2] * A[3, 3] * A[2, 1] + A[0, 1] * A[3, 2] * A[2, 3] - A[3, 1] * A[0, 2] * A[2, 3] - A[0, 1] * A[2, 2] * A[3, 3] - A[3, 2] * A[0, 3] * A[2, 1],
         -A[2, 2] * A[0, 3] * A[3, 0] - A[0, 2] * A[2, 0] * A[3, 3] - A[3, 2] * A[2, 3] * A[0, 0] + A[2, 2] * A[3, 3] * A[0, 0] + A[0, 2] * A[2, 3] * A[3, 0] + A[3, 2] * A[2, 0] * A[0, 3],
         A[3, 1] * A[2, 3] * A[0, 0] - A[0, 1] * A[2, 3] * A[3, 0] - A[3, 1] * A[2, 0] * A[0, 3] - A[3, 3] * A[0, 0] * A[2, 1] + A[0, 3] * A[3, 0] * A[2, 1] + A[0, 1] * A[2, 0] * A[3, 3],
         A[3, 2] * A[0, 0] * A[2, 1] - A[0, 2] * A[3, 0] * A[2, 1] + A[0, 1] * A[2, 2] * A[3, 0] + A[3, 1] * A[0, 2] * A[2, 0] - A[0, 1] * A[3, 2] * A[2, 0] - A[3, 1] * A[2, 2] * A[0, 0]],
        [A[3, 1] * A[1, 3] * A[0, 2] - A[0, 2] * A[1, 1] * A[3, 3] - A[3, 1] * A[0, 3] * A[1, 2] + A[3, 2] * A[1, 1] * A[0, 3] + A[0, 1] * A[3, 3] * A[1, 2] - A[0, 1] * A[1, 3] * A[3, 2],
         A[1, 3] * A[3, 2] * A[0, 0] - A[1, 0] * A[3, 2] * A[0, 3] - A[1, 3] * A[0, 2] * A[3, 0] + A[0, 3] * A[3, 0] * A[1, 2] + A[1, 0] * A[0, 2] * A[3, 3] - A[3, 3] * A[0, 0] * A[1, 2],
         -A[1, 0] * A[0, 1] * A[3, 3] + A[0, 1] * A[1, 3] * A[3, 0] - A[3, 1] * A[1, 3] * A[0, 0] - A[1, 1] * A[0, 3] * A[3, 0] + A[1, 0] * A[3, 1] * A[0, 3] + A[1, 1] * A[3, 3] * A[0, 0],
         A[0, 2] * A[1, 1] * A[3, 0] - A[3, 2] * A[1, 1] * A[0, 0] - A[0, 1] * A[3, 0] * A[1, 2] - A[1, 0] * A[3, 1] * A[0, 2] + A[3, 1] * A[0, 0] * A[1, 2] + A[1, 0] * A[0, 1] * A[3, 2]],
        [A[0, 3] * A[2, 1] * A[1, 2] + A[0, 2] * A[2, 3] * A[1, 1] + A[0, 1] * A[2, 2] * A[1, 3] - A[2, 2] * A[1, 1] * A[0, 3] - A[1, 3] * A[0, 2] * A[2, 1] - A[0, 1] * A[2, 3] * A[1, 2],
         A[1, 0] * A[2, 2] * A[0, 3] + A[1, 3] * A[0, 2] * A[2, 0] - A[1, 0] * A[0, 2] * A[2, 3] - A[2, 0] * A[0, 3] * A[1, 2] - A[2, 2] * A[1, 3] * A[0, 0] + A[2, 3] * A[0, 0] * A[1, 2],
         -A[0, 1] * A[1, 3] * A[2, 0] + A[2, 0] * A[1, 1] * A[0, 3] + A[1, 3] * A[0, 0] * A[2, 1] - A[1, 0] * A[0, 3] * A[2, 1] + A[1, 0] * A[0, 1] * A[2, 3] - A[2, 3] * A[1, 1] * A[0, 0],
         A[1, 0] * A[0, 2] * A[2, 1] - A[0, 2] * A[2, 0] * A[1, 1] + A[0, 1] * A[2, 0] * A[1, 2] + A[2, 2] * A[1, 1] * A[0, 0] - A[1, 0] * A[0, 1] * A[2, 2] - A[0, 0] * A[2, 1] * A[1, 2]]
    ])
Ejemplo n.º 10
0
def adj_expr_3x3(A):
    return as_matrix([
        [A[2, 2] * A[1, 1] - A[1, 2] * A[2, 1], -A[0, 1] * A[2, 2] + A[0, 2] * A[2, 1], A[0, 1] * A[1, 2] - A[0, 2] * A[1, 1]],
        [-A[2, 2] * A[1, 0] + A[1, 2] * A[2, 0], -A[0, 2] * A[2, 0] + A[2, 2] * A[0, 0], A[0, 2] * A[1, 0] - A[1, 2] * A[0, 0]],
        [A[1, 0] * A[2, 1] - A[2, 0] * A[1, 1], A[0, 1] * A[2, 0] - A[0, 0] * A[2, 1], A[0, 0] * A[1, 1] - A[0, 1] * A[1, 0]],
    ])
Ejemplo n.º 11
0
def adj_expr_2x2(A):
    return as_matrix([[A[1, 1], -A[0, 1]],
                      [-A[1, 0], A[0, 0]]])
Ejemplo n.º 12
0
 def sym(self, o, A):
     i, j = indices(2)
     return as_matrix((A[i, j] + A[j, i]) / 2, (i, j))
Ejemplo n.º 13
0
def deviatoric_expr_3x3(A):
    return as_matrix([[-1. / 3 * A[1, 1] - 1. / 3 * A[2, 2] + 2. / 3 * A[0, 0], A[0, 1], A[0, 2]],
                      [A[1, 0], 2. / 3 * A[1, 1] - 1. / 3 * A[2, 2] - 1. / 3 * A[0, 0], A[1, 2]],
                      [A[2, 0], A[2, 1], -1. / 3 * A[1, 1] + 2. / 3 * A[2, 2] - 1. / 3 * A[0, 0]]])
Ejemplo n.º 14
0
def adj_expr_2x2(A):
    return as_matrix([[A[1, 1], -A[0, 1]],
                      [-A[1, 0], A[0, 0]]])
Ejemplo n.º 15
0
def split(v):
    """UFL operator: If v is a Coefficient or Argument in a mixed space, returns
    a tuple with the function components corresponding to the subelements."""
    # Special case: simple element, just return function in a tuple
    element = v.element()
    if not isinstance(element, MixedElement):
        return (v, )

    if isinstance(element, TensorElement):
        s = element.symmetry()
        if s:
            # FIXME: How should this be defined? Should we return one subfunction
            # for each value component or only for those not mapped to another?
            # I think split should ignore the symmetry.
            error("Split not implemented for symmetric tensor elements.")

    # Compute value size
    value_size = product(element.value_shape())
    actual_value_size = value_size

    # Extract sub coefficient
    offset = 0
    sub_functions = []
    for i, e in enumerate(element.sub_elements()):
        shape = e.value_shape()
        rank = len(shape)

        if rank == 0:
            # This subelement is a scalar, always maps to a single value
            subv = v[offset]
            offset += 1

        elif rank == 1:
            # This subelement is a vector, always maps to a sequence of values
            sub_size, = shape
            components = [v[j] for j in range(offset, offset + sub_size)]
            subv = as_vector(components)
            offset += sub_size

        elif rank == 2:
            # This subelement is a tensor, possibly with symmetries, slightly more complicated...

            # Size of this subvalue
            sub_size = product(shape)

            # If this subelement is a symmetric element, subtract symmetric components
            s = None
            if isinstance(e, TensorElement):
                s = e.symmetry()
            s = s or EmptyDict
            # If we do this, we must fix the size computation in MixedElement.__init__ as well
            #actual_value_size -= len(s)
            #sub_size -= len(s)
            #print s
            # Build list of lists of value components
            components = []
            for ii in range(shape[0]):
                row = []
                for jj in range(shape[1]):
                    # Map component (i,j) through symmetry mapping
                    c = (ii, jj)
                    c = s.get(c, c)
                    i, j = c
                    # Extract component c of this subvalue from global tensor v
                    if v.rank() == 1:
                        # Mapping into a flattened vector
                        k = offset + i * shape[1] + j
                        component = v[k]
                        #print "k, offset, i, j, shape, component", k, offset, i, j, shape, component
                    elif v.rank() == 2:
                        # Mapping into a concatenated tensor (is this a figment of my imagination?)
                        error("Not implemented.")
                        row_offset, col_offset = 0, 0  # TODO
                        k = (row_offset + i, col_offset + j)
                        component = v[k]
                    row.append(component)
                components.append(row)

            # Make a matrix of the components
            subv = as_matrix(components)
            offset += sub_size

        else:
            # TODO: Handle rank > 2? Or is there such a thing?
            error(
                "Don't know how to split functions with sub functions of rank %d (yet)."
                % rank)
            #for indices in compute_indices(shape):
            #    #k = offset + sum(i*s for (i,s) in izip(indices, shape[1:] + (1,)))
            #    vs.append(v[indices])

        sub_functions.append(subv)

    ufl_assert(actual_value_size == offset,
               "Logic breach in function splitting.")

    return tuple(sub_functions)
Ejemplo n.º 16
0
def cofactor_expr_2x2(A):
    return as_matrix([[A[1, 1], -A[1, 0]],
                      [-A[0, 1], A[0, 0]]])
Ejemplo n.º 17
0
def cofactor_expr_3x3(A):
    return as_matrix([
        [A[1, 1] * A[2, 2] - A[2, 1] * A[1, 2], A[2, 0] * A[1, 2] - A[1, 0] * A[2, 2], - A[2, 0] * A[1, 1] + A[1, 0] * A[2, 1]],
        [A[2, 1] * A[0, 2] - A[0, 1] * A[2, 2], A[0, 0] * A[2, 2] - A[2, 0] * A[0, 2], - A[0, 0] * A[2, 1] + A[2, 0] * A[0, 1]],
        [A[0, 1] * A[1, 2] - A[1, 1] * A[0, 2], A[1, 0] * A[0, 2] - A[0, 0] * A[1, 2], - A[1, 0] * A[0, 1] + A[0, 0] * A[1, 1]],
    ])
Ejemplo n.º 18
0
def cofactor_expr_2x2(A):
    return as_matrix([[A[1, 1], -A[1, 0]],
                      [-A[0, 1], A[0, 0]]])
Ejemplo n.º 19
0
def deviatoric_expr_2x2(A):
    return as_matrix([[-1. / 2 * A[1, 1] + 1. / 2 * A[0, 0], A[0, 1]],
                      [A[1, 0], 1. / 2 * A[1, 1] - 1. / 2 * A[0, 0]]])
Ejemplo n.º 20
0
def deviatoric_expr_2x2(A):
    return as_matrix([[-1. / 2 * A[1, 1] + 1. / 2 * A[0, 0], A[0, 1]],
                      [A[1, 0], 1. / 2 * A[1, 1] - 1. / 2 * A[0, 0]]])
Ejemplo n.º 21
0
def split(v):
    """UFL operator: If v is a Coefficient or Argument in a mixed space, returns
    a tuple with the function components corresponding to the subelements."""

    # Default range is all of v
    begin = 0
    end = None

    if isinstance(v, Indexed):
        # Special case: split previous output of split again
        # Consistent with simple element, just return function in a tuple
        return (v, )

    elif isinstance(v, ListTensor):
        # Special case: split previous output of split again
        ops = v.ufl_operands
        if all(isinstance(comp, Indexed) for comp in ops):
            args = [comp.ufl_operands[0] for comp in ops]
            if all(args[0] == args[i] for i in range(1, len(args))):
                # Get innermost terminal here and its element
                v = args[0]
                # Get relevant range of v components
                begin, = ops[0].ufl_operands[1]
                end, = ops[-1].ufl_operands[1]
                begin = int(begin)
                end = int(end) + 1
            else:
                error("Don't know how to split %s." % (v, ))
        else:
            error("Don't know how to split %s." % (v, ))

    # Special case: simple element, just return function in a tuple
    element = v.ufl_element()
    if not isinstance(element, MixedElement):
        assert end is None
        return (v, )

    if isinstance(element, TensorElement):
        if element.symmetry():
            error("Split not implemented for symmetric tensor elements.")

    if len(v.ufl_shape) != 1:
        error(
            "Don't know how to split tensor valued mixed functions without flattened index space."
        )

    # Compute value size and set default range end
    value_size = product(element.value_shape())
    if end is None:
        end = value_size
    else:
        # Recursively dive into mixedelement in to subelement
        # corresponding to beginning of range
        j = begin
        while True:
            sub_i, j = element.extract_subelement_component(j)
            element = element.sub_elements()[sub_i]
            # Then break when we find the subelement that covers the whole range
            if product(element.value_shape()) == (end - begin):
                break

    # Build expressions representing the subfunction of v for each subelement
    offset = begin
    sub_functions = []
    for i, e in enumerate(element.sub_elements()):
        # Get shape, size, indices, and v components
        # corresponding to subelement value
        shape = e.value_shape()
        strides = shape_to_strides(shape)
        rank = len(shape)
        sub_size = product(shape)
        subindices = [
            flatten_multiindex(c, strides) for c in compute_indices(shape)
        ]
        components = [v[k + offset] for k in subindices]

        # Shape components into same shape as subelement
        if rank == 0:
            subv, = components
        elif rank <= 1:
            subv = as_vector(components)
        elif rank == 2:
            subv = as_matrix([
                components[i * shape[1]:(i + 1) * shape[1]]
                for i in range(shape[0])
            ])
        else:
            error(
                "Don't know how to split functions with sub functions of rank %d."
                % rank)

        offset += sub_size
        sub_functions.append(subv)

    if end != offset:
        error(
            "Function splitting failed to extract components for whole intended range. Something is wrong."
        )

    return tuple(sub_functions)
Ejemplo n.º 22
0
def split(v):
    """UFL operator: If v is a Coefficient or Argument in a mixed space, returns
    a tuple with the function components corresponding to the subelements."""

    # Default range is all of v
    begin = 0
    end = None

    if isinstance(v, Indexed):
        # Special case: split previous output of split again
        # Consistent with simple element, just return function in a tuple
        return (v,)

    elif isinstance(v, ListTensor):
        # Special case: split previous output of split again
        ops = v.ufl_operands
        if all(isinstance(comp, Indexed) for comp in ops):
            args = [comp.ufl_operands[0] for comp in ops]
            if all(args[0] == args[i] for i in range(1, len(args))):
                # Get innermost terminal here and its element
                v = args[0]
                # Get relevant range of v components
                begin, = ops[0].ufl_operands[1]
                end, = ops[-1].ufl_operands[1]
                begin = int(begin)
                end = int(end) + 1
            else:
                error("Don't know how to split %s." % (v,))
        else:
            error("Don't know how to split %s." % (v,))

    # Special case: simple element, just return function in a tuple
    element = v.ufl_element()
    if not isinstance(element, MixedElement):
        assert end is None
        return (v,)

    if isinstance(element, TensorElement):
        if element.symmetry():
            error("Split not implemented for symmetric tensor elements.")

    if len(v.ufl_shape) != 1:
        error("Don't know how to split tensor valued mixed functions without flattened index space.")

    # Compute value size and set default range end
    value_size = product(element.value_shape())
    if end is None:
        end = value_size
    else:
        # Recursively dive into mixedelement in to subelement
        # corresponding to beginning of range
        j = begin
        while True:
            sub_i, j = element.extract_subelement_component(j)
            element = element.sub_elements()[sub_i]
            # Then break when we find the subelement that covers the whole range
            if product(element.value_shape()) == (end - begin):
                break

    # Build expressions representing the subfunction of v for each subelement
    offset = begin
    sub_functions = []
    for i, e in enumerate(element.sub_elements()):
        # Get shape, size, indices, and v components
        # corresponding to subelement value
        shape = e.value_shape()
        strides = shape_to_strides(shape)
        rank = len(shape)
        sub_size = product(shape)
        subindices = [flatten_multiindex(c, strides)
                      for c in compute_indices(shape)]
        components = [v[k + offset] for k in subindices]

        # Shape components into same shape as subelement
        if rank == 0:
            subv, = components
        elif rank <= 1:
            subv = as_vector(components)
        elif rank == 2:
            subv = as_matrix([components[i*shape[1]: (i+1)*shape[1]]
                              for i in range(shape[0])])
        else:
            error("Don't know how to split functions with sub functions of rank %d." % rank)

        offset += sub_size
        sub_functions.append(subv)

    if end != offset:
        error("Function splitting failed to extract components for whole intended range. Something is wrong.")

    return tuple(sub_functions)
Ejemplo n.º 23
0
 def sym(self, o, A):
     i, j = indices(2)
     return as_matrix((A[i, j] + A[j, i]) / 2, (i, j))
def split(v):
    """UFL operator: If v is a Coefficient or Argument in a mixed space, returns
    a tuple with the function components corresponding to the subelements."""
    # Special case: simple element, just return function in a tuple
    element = v.element()
    if not isinstance(element, MixedElement):
        return (v,)

    if isinstance(element, TensorElement):
        s = element.symmetry()
        if s:
            # FIXME: How should this be defined? Should we return one subfunction
            # for each value component or only for those not mapped to another?
            # I think split should ignore the symmetry.
            error("Split not implemented for symmetric tensor elements.")

    # Compute value size
    value_size = product(element.value_shape())
    actual_value_size = value_size

    # Extract sub coefficient
    offset = 0
    sub_functions = []
    for i, e in enumerate(element.sub_elements()):
        shape = e.value_shape()
        rank = len(shape)

        if rank == 0:
            # This subelement is a scalar, always maps to a single value
            subv = v[offset]
            offset += 1

        elif rank == 1:
            # This subelement is a vector, always maps to a sequence of values
            sub_size, = shape
            components = [v[j] for j in range(offset, offset + sub_size)]
            subv = as_vector(components)
            offset += sub_size

        elif rank == 2:
            # This subelement is a tensor, possibly with symmetries, slightly more complicated...

            # Size of this subvalue
            sub_size = product(shape)

            # If this subelement is a symmetric element, subtract symmetric components
            s = None
            if isinstance(e, TensorElement):
                s = e.symmetry()
            s = s or EmptyDict
            # If we do this, we must fix the size computation in MixedElement.__init__ as well
            #actual_value_size -= len(s)
            #sub_size -= len(s)
            #print s
            # Build list of lists of value components
            components = []
            for ii in range(shape[0]):
                row = []
                for jj in range(shape[1]):
                    # Map component (i,j) through symmetry mapping
                    c = (ii, jj)
                    c = s.get(c, c)
                    i, j = c
                    # Extract component c of this subvalue from global tensor v
                    if v.rank() == 1:
                        # Mapping into a flattened vector
                        k = offset + i*shape[1] + j
                        component = v[k]
                        #print "k, offset, i, j, shape, component", k, offset, i, j, shape, component
                    elif v.rank() == 2:
                        # Mapping into a concatenated tensor (is this a figment of my imagination?)
                        error("Not implemented.")
                        row_offset, col_offset = 0, 0 # TODO
                        k = (row_offset + i, col_offset + j)
                        component = v[k]
                    row.append(component)
                components.append(row)

            # Make a matrix of the components
            subv = as_matrix(components)
            offset += sub_size

        else:
            # TODO: Handle rank > 2? Or is there such a thing?
            error("Don't know how to split functions with sub functions of rank %d (yet)." % rank)
            #for indices in compute_indices(shape):
            #    #k = offset + sum(i*s for (i,s) in izip(indices, shape[1:] + (1,)))
            #    vs.append(v[indices])

        sub_functions.append(subv)

    ufl_assert(actual_value_size == offset, "Logic breach in function splitting.")

    return tuple(sub_functions)