Example #1
0
def splitUFLForm(form):
    phi = form.arguments()[0]
    dphi = Grad(phi)

    source = ExprTensor(phi.ufl_shape)
    flux = ExprTensor(dphi.ufl_shape)
    boundarySource = ExprTensor(phi.ufl_shape)

    form = expand_indices(expand_derivatives(expand_compounds(form)))
    for integral in form.integrals():
        if integral.integral_type() == 'cell':
            fluxExprs = splitMultiLinearExpr(integral.integrand(), [phi])
            for op in fluxExprs:
                if op[0] == phi:
                    source = source + fluxExprs[op]
                elif op[0] == dphi:
                    flux = flux + fluxExprs[op]
                else:
                    raise Exception('Invalid derivative encountered in bulk integral: ' + str(op[0]))
        elif integral.integral_type() == 'exterior_facet':
            fluxExprs = splitMultiLinearExpr(integral.integrand(), [phi])
            for op in fluxExprs:
                if op[0] == phi:
                    boundarySource = boundarySource + fluxExprs[op]
                else:
                    raise Exception('Invalid derivative encountered in boundary integral: ' + str(op[0]))
        else:
            raise NotImplementedError('Integrals of type ' + integral.integral_type() + ' are not supported.')

    return source, flux, boundarySource
Example #2
0
def is_zero_ufl_expression(expr, return_val=False):
    """
    Is the given expression always identically zero or not
    Returns a boolean by default, but will return the actual
    evaluated expression value if return_val=True

    This function is somewhat brittle. If the ufl library
    changes how forms are processed (additional steps or other
    complexity is added) then this function must be extended
    to be able to break the expressions down into the smallest
    possible parts.
    """
    # Reduce the complexity of the expression as much as possible
    expr = expand_derivatives(expr)
    expr = expand_compounds(expr)
    expr = expand_indices(expr)
    expr = IndexSimplificator().visit(expr)

    # Perform the zero-form estimation
    val = EstimateZeroForms().visit(expr)
    val = int(val)

    # val > 0 if the form is (likely) non-Zero and 0 if it is
    # provably identically Zero()
    if return_val:
        return val
    else:
        return val == 0
Example #3
0
def codeDG(self):
    code = self._code()

    u = self.trialFunction
    ubar = Coefficient(u.ufl_function_space())
    penalty = self.penalty
    if penalty is None:
        penalty = 1
    if isinstance(penalty, Expr):
        if penalty.ufl_shape == ():
            penalty = as_vector([penalty])
        try:
            penalty = expand_indices(
                expand_derivatives(expand_compounds(penalty)))
        except:
            pass
        assert penalty.ufl_shape == u.ufl_shape
        dmPenalty = as_vector([
            replace(
                expand_derivatives(diff(replace(penalty, {u: ubar}),
                                        ubar))[i, i], {ubar: u})
            for i in range(u.ufl_shape[0])
        ])
    else:
        dmPenalty = None

    code.append(AccessModifier("public"))
    x = SpatialCoordinate(self.space.cell())
    predefined = {}
    self.predefineCoefficients(predefined, x)
    spatial = Variable('const auto', 'y')
    predefined.update({
        x:
        UnformattedExpression(
            'auto', 'entity().geometry().global( Dune::Fem::coordinate( x ) )')
    })
    generateMethod(code,
                   penalty,
                   'RRangeType',
                   'penalty',
                   args=['const Point &x', 'const DRangeType &u'],
                   targs=['class Point', 'class DRangeType'],
                   static=False,
                   const=True,
                   predefined=predefined)
    generateMethod(code,
                   dmPenalty,
                   'RRangeType',
                   'linPenalty',
                   args=['const Point &x', 'const DRangeType &u'],
                   targs=['class Point', 'class DRangeType'],
                   static=False,
                   const=True,
                   predefined=predefined)
    return code
Example #4
0
def test_mixed_tensor_symmetries():
    from ufl.algorithms import expand_indices, expand_compounds

    S = FiniteElement('CG', triangle, 1)
    V = VectorElement('CG', triangle, 1)
    T = TensorElement('CG', triangle, 1, symmetry=True)

    # M has dimension 4+1, symmetries are 2->1
    M = T * S
    P = Coefficient(M)
    M = inner(P, P) * dx

    M2 = expand_indices(expand_compounds(M))
    assert '[1]' in str(M2)
    assert '[2]' not in str(M2)

    # M has dimension 2+(1+4), symmetries are 5->4
    M = V * (S * T)
    P = Coefficient(M)
    M = inner(P, P) * dx

    M2 = expand_indices(expand_compounds(M))
    assert '[4]' in str(M2)
    assert '[5]' not in str(M2)
Example #5
0
def test_mixed_tensor_symmetries():
    from ufl.algorithms import expand_indices, expand_compounds

    S = FiniteElement('CG', triangle, 1)
    V = VectorElement('CG', triangle, 1)
    T = TensorElement('CG', triangle, 1, symmetry=True)

    # M has dimension 4+1, symmetries are 2->1
    M = T * S
    P = Coefficient(M)
    M = inner(P, P) * dx

    M2 = expand_indices(expand_compounds(M))
    assert '[1]' in str(M2)
    assert '[2]' not in str(M2)

    # M has dimension 2+(1+4), symmetries are 5->4
    M = V * (S * T)
    P = Coefficient(M)
    M = inner(P, P) * dx

    M2 = expand_indices(expand_compounds(M))
    assert '[4]' in str(M2)
    assert '[5]' not in str(M2)