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
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 _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)