def __init__(self, spatial_dim, cache=None): ForwardAD.__init__(self, spatial_dim, var_shape=(spatial_dim, ), var_free_indices=(), var_index_dimensions={}, cache=cache) self._Id = Identity(spatial_dim)
def _make_ones_diff(self, o): ufl_assert(o.shape() == self._var_shape, "This is only used by VariableDerivative, yes?") # Define a scalar value with the right indices # (kind of cumbersome this... any simpler way?) sh = o.shape() fi = o.free_indices() idims = dict(o.index_dimensions()) if self._var_free_indices: # Currently assuming only one free variable index i, = self._var_free_indices if i not in idims: fi = unique_indices(fi + (i, )) idims[i] = self._var_index_dimensions[i] # Create a 1 with index annotations one = IntValue(1, (), fi, idims) res = None if sh == (): return one elif len(sh) == 1: # FIXME: If sh == (1,), I think this will get the wrong shape? # I think we should make sure sh=(1,...,1) is always converted to () early. fp = Identity(sh[0]) else: ind1 = () ind2 = () for d in sh: i, j = indices(2) dij = Identity(d)[i, j] if res is None: res = dij else: res *= dij ind1 += (i, ) ind2 += (j, ) fp = as_tensor(res, ind1 + ind2) # Apply index annotations if fi: fp *= one return fp
def dyad(d, *iota): "TODO: Develop this concept, can e.g. write A[i,j]*dyad(j,i) for the transpose." from ufl.constantvalue import Identity from ufl.operators import outer # a bit of circular dependency issue here I = Identity(d) i = iota[0] e = as_vector(I[i, :], i) for i in iota[1:]: e = outer(e, as_vector(I[i, :], i)) return e
def unit_indexed_tensor(shape, component): from ufl.constantvalue import Identity from ufl.operators import outer # a bit of circular dependency issue here r = len(shape) if r == 0: return 0, () jj = indices(r) es = [] for i in range(r): s = shape[i] c = component[i] j = jj[i] e = Identity(s)[c, j] es.append(e) E = es[0] for e in es[1:]: E = outer(E, e) return E, jj
def stress(mu, lmbda, u): Eps = sym(grad(u)) return 2.0 * mu * Eps + lmbda * tr(Eps) * Identity(len(u))