def _(b: PETSc.Vec, L: typing.List[FormMetaClass], a, bcs: typing.List[DirichletBCMetaClass] = [], x0: typing.Optional[PETSc.Vec] = None, scale: float = 1.0, constants_L=None, coeffs_L=None, constants_a=None, coeffs_a=None) -> PETSc.Vec: """Assemble linear forms into a monolithic vector. The vector is not zeroed and it is not finalised, i.e. ghost values are not accumulated. """ maps = [(form.function_spaces[0].dofmap.index_map, form.function_spaces[0].dofmap.index_map_bs) for form in L] if x0 is not None: x0_local = _cpp.la.petsc.get_local_vectors(x0, maps) x0_sub = x0_local else: x0_local = [] x0_sub = [None] * len(maps) constants_L = [form and _pack_constants(form) for form in L] if constants_L is None else constants_L coeffs_L = [{} if form is None else _pack_coefficients(form) for form in L] if coeffs_L is None else coeffs_L constants_a = [[form and _pack_constants(form) for form in forms] for forms in a] if constants_a is None else constants_a coeffs_a = [[{} if form is None else _pack_coefficients(form) for form in forms] for forms in a] if coeffs_a is None else coeffs_a bcs1 = _bcs_by_block(_extract_spaces(a, 1), bcs) b_local = _cpp.la.petsc.get_local_vectors(b, maps) for b_sub, L_sub, a_sub, const_L, coeff_L, const_a, coeff_a in zip( b_local, L, a, constants_L, coeffs_L, constants_a, coeffs_a): _cpp.fem.assemble_vector(b_sub, L_sub, const_L, coeff_L) _cpp.fem.apply_lifting(b_sub, a_sub, const_a, coeff_a, bcs1, x0_local, scale) _cpp.la.petsc.scatter_local_vectors(b, b_local, maps) b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE) bcs0 = _bcs_by_block(_extract_spaces(L), bcs) offset = 0 b_array = b.getArray(readonly=False) for submap, bc, _x0 in zip(maps, bcs0, x0_sub): size = submap[0].size_local * submap[1] _cpp.fem.set_bc(b_array[offset:offset + size], bc, _x0, scale) offset += size return b
def _(b: PETSc.Vec, L: typing.List[typing.Union[Form, cpp.fem.Form]], a, bcs: typing.List[DirichletBC] = [], x0: typing.Optional[PETSc.Vec] = None, scale: float = 1.0) -> PETSc.Vec: """Assemble linear forms into a monolithic vector. The vector is not zeroed and it is not finalised, i.e. ghost values are not accumulated. """ maps = [ form.function_spaces[0].dofmap.index_map for form in _create_cpp_form(L) ] if x0 is not None: x0_local = cpp.la.get_local_vectors(x0, maps) x0_sub = x0_local else: x0_local = [] x0_sub = [None] * len(maps) bcs1 = cpp.fem.bcs_cols(_create_cpp_form(a), bcs) b_local = cpp.la.get_local_vectors(b, maps) for b_sub, L_sub, a_sub, bc in zip(b_local, L, a, bcs1): cpp.fem.assemble_vector(b_sub, _create_cpp_form(L_sub)) cpp.fem.apply_lifting(b_sub, _create_cpp_form(a_sub), bc, x0_local, scale) cpp.la.scatter_local_vectors(b, b_local, maps) b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE) bcs0 = cpp.fem.bcs_rows(_create_cpp_form(L), bcs) offset = 0 b_array = b.getArray(readonly=False) for submap, bc, _x0 in zip(maps, bcs0, x0_sub): size = submap.size_local * submap.block_size cpp.fem.set_bc(b_array[offset:offset + size], bc, _x0, scale) offset += size return b