def block_adjoint(block_form): assert isinstance(block_form, (array, list, BlockForm2)) if isinstance(block_form, (array, list)): input_type = array (block_form, block_function_space, block_form_rank) = _block_form_preprocessing(block_form) assert block_form_rank == 2 N = len(block_form) M = len(block_form[0]) block_adjoint_function_space = [block_function_space[1], block_function_space[0]] else: input_type = BlockForm2 N = block_form.block_size(0) M = block_form.block_size(1) block_adjoint_function_space = [block_form.block_function_spaces(1), block_form.block_function_spaces(0)] block_test_function_adjoint = BlockTestFunction(block_adjoint_function_space[0]) block_trial_function_adjoint = BlockTrialFunction(block_adjoint_function_space[1]) block_adjoint_form = empty((M, N), dtype=object) for I in range(N): for J in range(M): assert isinstance(block_form[I, J], Form) or _is_zero(block_form[I, J]) if isinstance(block_form[I, J], Form): block_adjoint_form[J, I] = adjoint(block_form[I, J], (block_test_function_adjoint[J], block_trial_function_adjoint[I])) elif _is_zero(block_form[I, J]): block_adjoint_form[J, I] = 0 else: raise TypeError("Invalid form") if input_type is array: return block_adjoint_form elif input_type is BlockForm2: return BlockForm2(block_adjoint_form, block_function_space=block_adjoint_function_space)
def block_derivative(F, u, du): assert isinstance(F, (array, list, BlockForm1)) if isinstance(F, (array, list)): input_type = array (F, block_V, block_form_rank) = _block_form_preprocessing(F) assert block_form_rank == 1 else: input_type = BlockForm1 block_V = F.block_function_spaces() assert len(block_V) == 1 block_V = block_V[0] # Compute the derivative assert len(F) == len(u) == len(du) J = empty((len(F), len(u)), dtype=object) for i in range(len(F)): if not _is_zero(F[i]): for j in range(len(u)): J[i, j] = derivative(F[i], u[j], du[j]) else: J[i, :] = 0 if input_type is array: return J elif input_type is BlockForm1: return BlockForm2(J, block_function_space=[du.block_function_space(), block_V])
def block_restrict(block_input, block_function_sub_space): assert isinstance( block_input, (array, list, BlockDirichletBC, BlockForm1, BlockForm2, BlockFunction)) if isinstance(block_input, (array, list, BlockForm1, BlockForm2)): if isinstance(block_input, (array, list)): (block_form, _, block_form_rank) = _block_form_preprocessing(block_input) elif isinstance(block_input, BlockForm2): block_form = block_input block_form_rank = 2 elif isinstance(block_input, BlockForm1): block_form = block_input block_form_rank = 1 if block_form_rank == 2: assert isinstance(block_function_sub_space, list) assert len(block_function_sub_space) == 2 assert isinstance(block_function_sub_space[0], BlockFunctionSpace) assert isinstance(block_function_sub_space[1], BlockFunctionSpace) N_sub_space = block_function_sub_space[0].num_sub_spaces() M_sub_space = block_function_sub_space[1].num_sub_spaces() sub_block_form = zeros((N_sub_space, M_sub_space), dtype=object) for I_sub_space in range(N_sub_space): I_space = _sub_component_to_component( block_function_sub_space[0], I_sub_space) for J_sub_space in range(M_sub_space): J_space = _sub_component_to_component( block_function_sub_space[1], J_sub_space) sub_block_form[I_sub_space, J_sub_space] = block_form[I_space, J_space] return BlockForm2(sub_block_form, block_function_sub_space) elif block_form_rank == 1: assert isinstance(block_function_sub_space, (BlockFunctionSpace, list)) if isinstance(block_function_sub_space, BlockFunctionSpace): block_function_sub_space = [block_function_sub_space] assert len(block_function_sub_space) == 1 assert isinstance(block_function_sub_space[0], BlockFunctionSpace) N_sub_space = block_function_sub_space[0].num_sub_spaces() sub_block_form = zeros((N_sub_space, ), dtype=object) for I_sub_space in range(N_sub_space): I_space = _sub_component_to_component( block_function_sub_space[0], I_sub_space) sub_block_form[I_sub_space] = block_form[I_space] return BlockForm1(sub_block_form, block_function_sub_space) elif isinstance(block_input, BlockFunction): assert isinstance(block_function_sub_space, (BlockFunctionSpace, list)) if isinstance(block_function_sub_space, list): assert len(block_function_sub_space) == 1 block_function_sub_space = block_function_sub_space[0] assert isinstance(block_function_sub_space, BlockFunctionSpace) N_sub_space = block_function_sub_space.num_sub_spaces() sub_functions = list() for I_sub_space in range(N_sub_space): I_space = _sub_component_to_component(block_function_sub_space, I_sub_space) sub_functions.append(block_input[I_space]) return BlockFunction(block_function_sub_space, sub_functions) elif isinstance(block_input, BlockDirichletBC): assert isinstance(block_function_sub_space, (BlockFunctionSpace, list)) if isinstance(block_function_sub_space, list): assert len(block_function_sub_space) == 1 block_function_sub_space = block_function_sub_space[0] assert isinstance(block_function_sub_space, BlockFunctionSpace) N_sub_space = block_function_sub_space.num_sub_spaces() sub_bcs = list() for I_sub_space in range(N_sub_space): I_space = _sub_component_to_component(block_function_sub_space, I_sub_space) sub_bcs.append(block_input[I_space]) return BlockDirichletBC(sub_bcs, block_function_sub_space) else: raise AssertionError("Invalid arguments to block_restrict")