Source code for dolfinx_mpc.assemble_vector

# Copyright (C) 2020 Jørgen S. Dokken
#
# This file is part of DOLFINX_MPC
#
# SPDX-License-Identifier:    MIT
from __future__ import annotations

import contextlib
from typing import List, Optional, Sequence

from petsc4py import PETSc as _PETSc

import dolfinx.cpp as _cpp
import dolfinx.fem as _fem
import dolfinx.la as _la
import numpy
import ufl
from dolfinx import default_scalar_type
from dolfinx.common import Timer

import dolfinx_mpc.cpp

from .multipointconstraint import MultiPointConstraint, _float_classes


[docs] def apply_lifting( b: _PETSc.Vec, # type: ignore form: List[_fem.Form], bcs: List[List[_fem.DirichletBC]], constraint: MultiPointConstraint, x0: List[_PETSc.Vec] = [], # type: ignore scale: _float_classes = default_scalar_type(1.0), ): # type: ignore """ Apply lifting to vector b, i.e. :math:`b = b - scale \\cdot K^T (A_j (g_j - x0_j))` Args: b: PETSc vector to assemble into form: The linear form bcs: List of Dirichlet boundary conditions constraint: The multi point constraint x0: List of vectors scale: Scaling for lifting """ if isinstance(scale, numpy.generic): # nanobind conversion of numpy dtypes to general Python types scale = scale.item() # type: ignore t = Timer("~MPC: Apply lifting (C++)") with contextlib.ExitStack() as stack: x0 = [stack.enter_context(x.localForm()) for x in x0] x0_r = [x.array_r for x in x0] b_local = stack.enter_context(b.localForm()) _forms = [f._cpp_object for f in form] _bcs = [[bc._cpp_object for bc in bcs0] for bcs0 in bcs] dolfinx_mpc.cpp.mpc.apply_lifting(b_local.array_w, _forms, _bcs, x0_r, scale, constraint._cpp_object) t.stop()
[docs] def assemble_vector( form: ufl.form.Form, constraint: MultiPointConstraint, b: Optional[_PETSc.Vec] = None, # type: ignore ) -> _PETSc.Vec: # type: ignore """ Assemble a linear form into vector `b` with corresponding multi point constraint Args: form: The linear form constraint: The multi point constraint b: PETSc vector to assemble Returns: The vector with the assembled linear form (`b` if supplied) """ if b is None: b = _la.create_petsc_vector( constraint.function_space.dofmap.index_map, constraint.function_space.dofmap.index_map_bs, ) t = Timer("~MPC: Assemble vector (C++)") with b.localForm() as b_local: b_local.set(0.0) dolfinx_mpc.cpp.mpc.assemble_vector(b_local.array_w, form._cpp_object, constraint._cpp_object) t.stop() return b
[docs] def create_vector_nest(L: Sequence[_fem.Form], constraints: Sequence[MultiPointConstraint]) -> _PETSc.Vec: # type: ignore """ Create a PETSc vector of type "nest" appropriate for the provided multi point constraints Args: L: A sequence of linear forms constraints: An ordered list of multi point constraints Returns: PETSc.Vec: A PETSc vector of type "nest" #type: ignore """ assert len(constraints) == len(L) maps = [ (constraint.function_space.dofmap.index_map, constraint.function_space.dofmap.index_map_bs) for constraint in constraints ] return _cpp.fem.petsc.create_vector_nest(maps)
[docs] def assemble_vector_nest( b: _PETSc.Vec, # type: ignore L: Sequence[_fem.Form], constraints: Sequence[MultiPointConstraint], ): """ Assemble a linear form into a PETSc vector of type "nest" Args: b: A PETSc vector of type "nest" L: A sequence of linear forms constraints: An ordered list of multi point constraints """ assert len(constraints) == len(L) assert b.getType() == "nest" b_sub_vecs = b.getNestSubVecs() for i, L_row in enumerate(L): assemble_vector(L_row, constraints[i], b=b_sub_vecs[i])