File: assemble_vector.py

package info (click to toggle)
dolfinx-mpc 0.5.0.post0-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 1,112 kB
  • sloc: python: 5,998; cpp: 5,196; makefile: 67
file content (138 lines) | stat: -rw-r--r-- 3,669 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# Copyright (C) 2020 Jørgen S. Dokken
#
# This file is part of DOLFINX_MPC
#
# SPDX-License-Identifier:    MIT

import contextlib
from typing import List, Sequence

import dolfinx.cpp as _cpp
import dolfinx.fem as _fem
import ufl
from dolfinx.common import Timer
from petsc4py import PETSc as _PETSc

import dolfinx_mpc.cpp

from .multipointconstraint import MultiPointConstraint


def apply_lifting(b: _PETSc.Vec, form: List[_fem.FormMetaClass], bcs: List[List[_fem.DirichletBCMetaClass]],
                  constraint: MultiPointConstraint, x0: List[_PETSc.Vec] = [], scale: float = 1.0):
    """
    Apply lifting to vector b, i.e.

    .. math::
        b <- b - scale * K^T (A_j (g_j - x0_j))

    Parameters
    ----------
    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

    Returns
    -------
    PETSc.Vec
        The assembled linear form
    """
    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())
        dolfinx_mpc.cpp.mpc.apply_lifting(b_local.array_w, form,
                                          bcs, x0_r, scale, constraint._cpp_object)
    t.stop()


def assemble_vector(form: ufl.form.Form, constraint: MultiPointConstraint,
                    b: _PETSc.Vec = None) -> _PETSc.Vec:
    """
    Assemble a linear form into vector b with corresponding multi point constraint

    Parameters
    ----------
    form
        The linear form
    constraint
        The multi point constraint
    b
        PETSc vector to assemble into (optional)

    Returns
    -------
    PETSc.Vec
        The assembled linear form
    """

    if b is None:
        b = _cpp.la.petsc.create_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, form, constraint._cpp_object)
    t.stop()
    return b


def create_vector_nest(
        L: Sequence[_fem.FormMetaClass],
        constraints: Sequence[MultiPointConstraint]) -> _PETSc.Vec:
    """
    Create a PETSc vector of type "nest" appropriate for the provided multi
    point constraints

    Parameters
    ----------
    L
        A sequence of linear forms
    constraints
        An ordered list of multi point constraints

    Returns
    -------
    PETSc.Vec
        A PETSc vector of type "nest"
    """
    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)


def assemble_vector_nest(
        b: _PETSc.Vec,
        L: Sequence[_fem.FormMetaClass],
        constraints: Sequence[MultiPointConstraint]):
    """
    Assemble a linear form into a PETSc vector of type "nest"

    Parameters
    ----------
    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])