예제 #1
0
 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) == 1
     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)
     replaced_block_form = empty((N, ), dtype=object)
     for I in range(N):
         replaced_block_form[I] = block_replace_zero(block_form, (I, ), block_function_space)
         assert isinstance(replaced_block_form[I], Form) or _is_zero(replaced_block_form[I])
         if isinstance(replaced_block_form[I], Form):
             replaced_block_form[I] = _create_dolfin_form(
                 form=replaced_block_form[I],
                 form_compiler_parameters=form_compiler_parameters
             )
         elif _is_zero(replaced_block_form[I]):
             assert isinstance(replaced_block_form[I], cpp_Form)
         else:
             raise TypeError("Invalid form")
     BlockForm1_Base.__init__(self, replaced_block_form.tolist(), [block_function_space_.cpp_object() for block_function_space_ in block_function_space])
     # Store size for len and shape method
     self.N = N
예제 #2
0
 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
예제 #3
0
def _block_form_preprocessing(block_form,
                              block_function_space=None,
                              block_form_rank=None):
    assert isinstance(block_form, (array, list))
    if block_form_rank is None:
        block_form_rank = _get_block_form_rank(block_form)
        assert block_form_rank is not None, \
            "A block form rank should be provided when assemblying a zero block vector/matrix."
    assert block_form_rank in (1, 2)
    if block_form_rank is 2:
        # Extract BlockFunctionSpace from the current form, if required
        if not block_function_space:
            assert not all([_is_zero(block_form_I_J) for block_form_I in block_form for block_form_I_J in block_form_I]), \
                "A BlockFunctionSpace should be provided when assemblying a zero block matrix."
            block_function_space = _extract_block_function_space_2(block_form)
            assert len(block_function_space) == 2
            assert block_function_space[0] is not None
            assert block_function_space[1] is not None
            block_function_space = [
                block_function_space[0], block_function_space[1]
            ]  # convert from dict to list
        else:
            assert isinstance(block_function_space, list)
            assert len(block_function_space) is 2
            assert isinstance(block_function_space[0], BlockFunctionSpace)
            assert isinstance(block_function_space[1], BlockFunctionSpace)

        # Flatten nested blocks, if any
        block_form = block_flatten_nested(block_form, block_function_space)
        # ... and compute size accordingly
        if block_function_space[0] == block_function_space[1]:
            _assert_flattened_form_2_is_square(block_form)
        N = len(block_form)
        M = len(block_form[0])

        # Replace zero blocks, if any
        replaced_block_form = empty((N, M), dtype=object)
        for I in range(N):
            for J in range(M):
                replaced_block_form[I, J] = block_replace_zero(
                    block_form, (I, J), block_function_space)

        # Return preprocessed data
        return (replaced_block_form, block_function_space, block_form_rank)
    elif block_form_rank is 1:
        # Extract BlockFunctionSpace from the current form, if required
        if not block_function_space:
            assert not all([_is_zero(block_form_I) for block_form_I in block_form]), \
                "A BlockFunctionSpace should be provided when assemblying a zero block vector."
            block_function_space = _extract_block_function_space_1(block_form)
            assert len(block_function_space) == 1
            assert block_function_space[0] is not None
            block_function_space = [block_function_space[0]
                                    ]  # convert from dict to list
        else:
            assert isinstance(block_function_space, BlockFunctionSpace)
            block_function_space = [block_function_space]

        # Flatten nested blocks, if any
        block_form = block_flatten_nested(block_form, block_function_space)
        # ... and compute size accordingly
        N = len(block_form)

        # Replace zero blocks, if any
        replaced_block_form = empty((N, ), dtype=object)
        for I in range(N):
            replaced_block_form[I] = block_replace_zero(
                block_form, (I, ), block_function_space)

        # Return preprocessed data
        return (replaced_block_form, block_function_space, block_form_rank)