xref: /petsc/src/binding/petsc4py/src/petsc4py/PETSc/Scatter.pyx (revision 552edb6364df478b294b3111f33a8f37ca096b20)
1# --------------------------------------------------------------------
2
3class ScatterType(object):
4    """Scatter type.
5
6    See Also
7    --------
8    petsc.VecScatterType
9
10    """
11    BASIC      = S_(PETSCSFBASIC)
12    NEIGHBOR   = S_(PETSCSFNEIGHBOR)
13    ALLGATHERV = S_(PETSCSFALLGATHERV)
14    ALLGATHER  = S_(PETSCSFALLGATHER)
15    GATHERV    = S_(PETSCSFGATHERV)
16    GATHER     = S_(PETSCSFGATHER)
17    ALLTOALL   = S_(PETSCSFALLTOALL)
18    WINDOW     = S_(PETSCSFWINDOW)
19
20# --------------------------------------------------------------------
21
22
23cdef class Scatter(Object):
24    """Scatter object.
25
26    The object used to perform data movement between vectors.
27    Scatter is described in the `PETSc manual <petsc:sec_scatter>`.
28
29    See Also
30    --------
31    Vec, SF, petsc.VecScatter
32
33    """
34
35    Type = ScatterType
36    Mode = ScatterMode
37
38    #
39
40    def __cinit__(self):
41        self.obj = <PetscObject*> &self.sct
42        self.sct = NULL
43
44    def __call__(self, x, y, addv=None, mode=None):
45        """Perform the scatter.
46
47        Collective.
48
49        See Also
50        --------
51        scatter
52
53        """
54        self.scatter(x, y, addv, mode)
55
56    #
57
58    def view(self, Viewer viewer=None) -> None:
59        """View the scatter.
60
61        Collective.
62
63        Parameters
64        ----------
65        viewer
66            A `Viewer` instance or `None` for the default viewer.
67
68        See Also
69        --------
70        petsc.VecScatterView
71
72        """
73        cdef PetscViewer vwr = NULL
74        if viewer is not None: vwr = viewer.vwr
75        CHKERR(VecScatterView(self.sct, vwr))
76
77    def destroy(self) -> Self:
78        """Destroy the scatter.
79
80        Collective.
81
82        See Also
83        --------
84        petsc.VecScatterDestroy
85
86        """
87        CHKERR(VecScatterDestroy(&self.sct))
88        return self
89
90    def create(
91        self,
92        Vec vec_from,
93        IS is_from or None,
94        Vec vec_to,
95        IS is_to or None) -> Self:
96        """Create a scatter object.
97
98        Collective.
99
100        Parameters
101        ----------
102        vec_from
103            Representative vector from which to scatter the data.
104        is_from
105            Indices of ``vec_from`` to scatter. If `None`, use all indices.
106        vec_to
107            Representative vector to which scatter the data.
108        is_to
109            Indices of ``vec_to`` where to receive. If `None`, use all indices.
110
111        Examples
112        --------
113        The scatter object can be used to repeatedly perform data movement.
114        It is the PETSc equivalent of NumPy-like indexing and slicing,
115        with support for parallel communications:
116
117        >>> revmode = PETSc.Scatter.Mode.REVERSE
118        >>> v1 = PETSc.Vec().createWithArray([1, 2, 3])
119        >>> v2 = PETSc.Vec().createWithArray([0, 0, 0])
120        >>> sct = PETSc.Scatter().create(v1,None,v2,None)
121        >>> sct.scatter(v1,v2) # v2[:] = v1[:]
122        >>> sct.scatter(v2,v1,mode=revmode) # v1[:] = v2[:]
123
124        >>> revmode = PETSc.Scatter.Mode.REVERSE
125        >>> v1 = PETSc.Vec().createWithArray([1, 2, 3, 4])
126        >>> v2 = PETSc.Vec().createWithArray([0, 0])
127        >>> is1 = PETSc.IS().createStride(2, 3, -2)
128        >>> sct = PETSc.Scatter().create(v1,is1,v2,None)
129        >>> sct.scatter(v1,v2) # v2[:] = v1[3:0:-2]
130        >>> sct.scatter(v2,v1,mode=revmode) # v1[3:0:-2] = v2[:]
131
132        See Also
133        --------
134        IS, petsc.VecScatterCreate
135
136        """
137        cdef PetscIS cisfrom = NULL, cisto = NULL
138        if is_from is not None: cisfrom = is_from.iset
139        if is_to   is not None: cisto   = is_to.iset
140        cdef PetscScatter newsct = NULL
141        CHKERR(VecScatterCreate(
142                vec_from.vec, cisfrom, vec_to.vec, cisto, &newsct))
143        CHKERR(PetscCLEAR(self.obj)); self.sct = newsct
144        return self
145
146    def setType(self, scatter_type: Type | str) -> None:
147        """Set the type of the scatter.
148
149        Logically collective.
150
151        See Also
152        --------
153        getType, petsc.VecScatterSetType
154
155        """
156        cdef PetscScatterType cval = NULL
157        scatter_type = str2bytes(scatter_type, &cval)
158        CHKERR(VecScatterSetType(self.sct, cval))
159
160    def getType(self) -> str:
161        """Return the type of the scatter.
162
163        Not collective.
164
165        See Also
166        --------
167        setType, petsc.VecScatterGetType
168
169        """
170        cdef PetscScatterType cval = NULL
171        CHKERR(VecScatterGetType(self.sct, &cval))
172        return bytes2str(cval)
173
174    def setFromOptions(self) -> None:
175        """Configure the scatter from the options database.
176
177        Collective.
178
179        See Also
180        --------
181        petsc_options, petsc.VecScatterSetFromOptions
182
183        """
184        CHKERR(VecScatterSetFromOptions(self.sct))
185
186    def setUp(self) -> Self:
187        """Set up the internal data structures for using the scatter.
188
189        Collective.
190
191        See Also
192        --------
193        petsc.VecScatterSetUp
194
195        """
196        CHKERR(VecScatterSetUp(self.sct))
197        return self
198
199    def copy(self) -> Scatter:
200        """Return a copy of the scatter."""
201        cdef Scatter scatter = Scatter()
202        CHKERR(VecScatterCopy(self.sct, &scatter.sct))
203        return scatter
204
205    @classmethod
206    def toAll(cls, Vec vec) -> tuple[Scatter, Vec]:
207        """Create a scatter that communicates a vector to all sharing processes.
208
209        Collective.
210
211        Parameters
212        ----------
213        vec
214            The vector to scatter from.
215
216        Notes
217        -----
218        The created scatter will have the same communicator of ``vec``.
219        The method also returns an output vector of appropriate size to
220        contain the result of the operation.
221
222        See Also
223        --------
224        toZero, petsc.VecScatterCreateToAll
225
226        """
227        cdef Scatter scatter = Scatter()
228        cdef Vec ovec = Vec()
229        CHKERR(VecScatterCreateToAll(
230            vec.vec, &scatter.sct, &ovec.vec))
231        return (scatter, ovec)
232
233    @classmethod
234    def toZero(cls, Vec vec) -> tuple[Scatter, Vec]:
235        """Create a scatter that communicates a vector to rank zero.
236
237        Collective.
238
239        Parameters
240        ----------
241        vec
242            The vector to scatter from.
243
244        Notes
245        -----
246        The created scatter will have the same communicator of ``vec``.
247        The method also returns an output vector of appropriate size to
248        contain the result of the operation.
249
250        See Also
251        --------
252        toAll, petsc.VecScatterCreateToZero
253
254        """
255        cdef Scatter scatter = Scatter()
256        cdef Vec ovec = Vec()
257        CHKERR(VecScatterCreateToZero(
258            vec.vec, &scatter.sct, &ovec.vec))
259        return (scatter, ovec)
260    #
261
262    def begin(
263        self,
264        Vec vec_from,
265        Vec vec_to,
266        addv: InsertModeSpec = None,
267        mode: ScatterModeSpec = None) -> None:
268        """Begin a generalized scatter from one vector into another.
269
270        Collective.
271
272        This call has to be concluded with a call to `end`.
273        For additional details on the Parameters, see `scatter`.
274
275        See Also
276        --------
277        create, end, petsc.VecScatterBegin
278
279        """
280        cdef PetscInsertMode  caddv = insertmode(addv)
281        cdef PetscScatterMode csctm = scattermode(mode)
282        CHKERR(VecScatterBegin(self.sct, vec_from.vec, vec_to.vec,
283                               caddv, csctm))
284
285    def end(
286        self,
287        Vec vec_from,
288        Vec vec_to,
289        addv: InsertModeSpec = None,
290        mode: ScatterModeSpec = None) -> None:
291        """Complete a generalized scatter from one vector into another.
292
293        Collective.
294
295        This call has to be preceded by a call to `begin`.
296        For additional details on the Parameters, see `scatter`.
297
298        See Also
299        --------
300        create, begin, petsc.VecScatterEnd
301
302        """
303        cdef PetscInsertMode  caddv = insertmode(addv)
304        cdef PetscScatterMode csctm = scattermode(mode)
305        CHKERR(VecScatterEnd(self.sct, vec_from.vec, vec_to.vec,
306                             caddv, csctm))
307
308    def scatter(
309        self,
310        Vec vec_from,
311        Vec vec_to,
312        addv: InsertModeSpec = None,
313        mode: ScatterModeSpec = None) -> None:
314        """Perform a generalized scatter from one vector into another.
315
316        Collective.
317
318        Parameters
319        ----------
320        vec_from
321            The source vector.
322        vec_to
323            The destination vector.
324        addv
325            Insertion mode.
326        mode
327            Scatter mode.
328
329        See Also
330        --------
331        create, begin, end, petsc.VecScatterBegin, petsc.VecScatterEnd
332
333        """
334        cdef PetscInsertMode  caddv = insertmode(addv)
335        cdef PetscScatterMode csctm = scattermode(mode)
336        CHKERR(VecScatterBegin(self.sct, vec_from.vec, vec_to.vec,
337                               caddv, csctm))
338        CHKERR(VecScatterEnd(self.sct, vec_from.vec, vec_to.vec,
339                             caddv, csctm))
340
341    scatterBegin = begin
342    scatterEnd = end
343
344# --------------------------------------------------------------------
345
346del ScatterType
347
348# --------------------------------------------------------------------
349