def block_replace_zero(block_form, index, block_function_space): assert len(index) in (1, 2) if len(index) == 2: I = index[0] # noqa J = index[1] assert (isinstance( block_form[I][J], Form ) # this function is always called after flattening, so it cannot be an array or list or (isinstance(block_form[I][J], (float, int)) and block_form[I][J] in zeros)) if block_form[I][J] in zeros: block_form_IJ = block_form[I][J] elif has_exact_type(block_form[I][J], CoefficientDerivative): block_form_IJ = expand_derivatives(block_form[I][J]) else: block_form_IJ = block_form[I][J] if block_form_IJ in zeros or block_form_IJ.empty(): block_form_IJ = _get_zero_form(block_function_space, (I, J)) else: assert not block_form_IJ.empty() return block_form_IJ else: I = index[0] # noqa assert (isinstance( block_form[I], Form ) # this function is always called after flattening, so it cannot be an array or list or (isinstance(block_form[I], (float, int)) and block_form[I] in zeros)) block_form_I = block_form[I] if block_form_I in zeros: block_form_I = _get_zero_form(block_function_space, (I, )) else: assert not block_form_I.empty() return block_form_I
def replace(e, mapping): """Replace subexpressions in expression. @param e: An Expr or Form. @param mapping: A dict with from:to replacements to perform. """ mapping2 = dict((k, as_ufl(v)) for (k, v) in mapping.items()) # Workaround for problem with delayed derivative evaluation # The problem is that J = derivative(f(g, h), g) does not evaluate immediately # So if we subsequently do replace(J, {g: h}) we end up with an expression: # derivative(f(h, h), h) # rather than what were were probably thinking of: # replace(derivative(f(g, h), g), {g: h}) # # To fix this would require one to expand derivatives early (which # is not attractive), or make replace lazy too. if has_exact_type(e, CoefficientDerivative): # Hack to avoid circular dependencies from ufl.algorithms.ad import expand_derivatives e = expand_derivatives(e) return map_integrand_dags(Replacer(mapping2), e)
def __init__(self, block_form, block_function_space, form_compiler_parameters=None): # Store UFL form self._block_form = block_form # Store block function space assert len(block_function_space) == 2 self._block_function_space = block_function_space # Replace UFL form by Dolfin form before passing it to the constructor # (note that we assume that block_form has been already preprocessed, # so we can assume that nested blocks have been unrolled and zero # placeholders have been replaced by zero forms) N = len(block_form) M = len(block_form[0]) assert all([len(block_form_I) == M for block_form_I in block_form]) replaced_block_form = empty((N, M), dtype=object) for I in range(N): for J in range(M): if isinstance(block_form[I, J], Form) and has_exact_type(block_form[I, J], CoefficientDerivative): block_form[I, J] = expand_derivatives(block_form[I, J]) replaced_block_form[I, J] = block_replace_zero(block_form, (I, J), block_function_space) assert isinstance(replaced_block_form[I, J], Form) or _is_zero(replaced_block_form[I, J]) if isinstance(replaced_block_form[I, J], Form): replaced_block_form[I, J] = _create_dolfin_form( form=replaced_block_form[I, J], form_compiler_parameters=form_compiler_parameters ) elif _is_zero(replaced_block_form[I, J]): assert isinstance(replaced_block_form[I, J], cpp_Form) else: raise TypeError("Invalid form") BlockForm2_Base.__init__(self, replaced_block_form.tolist(), [block_function_space_.cpp_object() for block_function_space_ in block_function_space]) # Store sizes for shape method self.N = N self.M = M
def replace(e, mapping): """Replace objects in expression. @param e: An Expr or Form. @param mapping: A dict with from:to replacements to perform. """ mapping2 = dict((k, as_ufl(v)) for (k, v) in mapping.items()) # We have expanded derivative evaluation in ParametrizedTensorFactory assert not has_exact_type(e, CoefficientDerivative) return map_integrand_dags(Replacer(mapping2), e)
def replace(e, mapping): """Replace terminal objects in expression. @param e: An Expr or Form. @param mapping: A dict with from:to replacements to perform. """ mapping2 = dict((k, as_ufl(v)) for (k, v) in mapping.items()) # Workaround for problem with delayed derivative evaluation if has_exact_type(e, CoefficientDerivative): # Hack to avoid circular dependencies from ufl.algorithms.ad import expand_derivatives e = expand_derivatives(e) return map_integrand_dags(Replacer(mapping2), e)
def replace(e, mapping): """Replace terminal objects in expression. @param e: An Expr or Form. @param mapping: A dict with from:to replacements to perform. """ mapping2 = dict((k, as_ufl(v)) for (k, v) in mapping.items()) # Workaround for problem with delayed derivative evaluation if has_exact_type(e, CoefficientDerivative): # Hack to avoid circular dependencies from ufl.algorithms.ad import expand_derivatives e = expand_derivatives(e) return map_integrand_dags(Replacer(mapping2), e)