xref: /petsc/src/dm/impls/product/product.c (revision eefb368e60eb43c3e08ca0927788b33650449484)
1 #include <petsc/private/dmproductimpl.h>
2 
DMDestroy_Product(DM dm)3 static PetscErrorCode DMDestroy_Product(DM dm)
4 {
5   DM_Product *product = (DM_Product *)dm->data;
6   PetscInt    d;
7 
8   PetscFunctionBeginUser;
9   for (d = 0; d < DMPRODUCT_MAX_DIM; ++d) PetscCall(DMDestroy(&product->dm[d]));
10   PetscCall(PetscFree(product));
11   PetscFunctionReturn(PETSC_SUCCESS);
12 }
13 
DMView_Product(DM dm,PetscViewer viewer)14 static PetscErrorCode DMView_Product(DM dm, PetscViewer viewer)
15 {
16   DM_Product *product = (DM_Product *)dm->data;
17   PetscInt    d;
18 
19   PetscFunctionBegin;
20   for (d = 0; d < DMPRODUCT_MAX_DIM; ++d) {
21     if (product->dm[d]) {
22       PetscCall(PetscViewerASCIIPrintf(viewer, "  DM that defines dimension %" PetscInt_FMT "\n", d));
23       PetscCall(PetscViewerASCIIPushTab(viewer));
24       PetscCall(PetscViewerASCIIPushTab(viewer));
25       PetscCall(DMView(product->dm[d], viewer));
26       PetscCall(PetscViewerASCIIPopTab(viewer));
27       PetscCall(PetscViewerASCIIPopTab(viewer));
28     }
29   }
30   PetscFunctionReturn(PETSC_SUCCESS);
31 }
32 
33 /*MC
34   DMPRODUCT = "product" - a `DM` representing a local Cartesian product of other `DM`
35 
36   Level: advanced
37 
38   Notes:
39   The `DM` is usually used for managing coordinates of other `DM` via `DMGetCoordinateDM()` and `DMSetCoordinateDM()`
40 
41   For each of `dim` dimensions, the `DMPRODUCT` contains a `DM` and a dimension index. The dimensional index, set with `DMProductSetDimensionIndex()`
42   specifies  which dimension of the sub-`DM` coordinates corresponds to a particular dimension of the `DMPRODUCT`. For example,
43 .vb
44   DM da1, da2;
45   DM dm
46   DMCreate(PETSC_COMM_WORLD,&dm);
47   DMSetType(dm,DMPRODUCT);
48   DMSetDimension(dm,3);
49   DMProductSetDM(dm,0,da1);
50   DMProductSetDimensionIndex(dm,0,0);
51   DMProductSetDM(dm,1,da2);
52   DMProductSetDimensionIndex(dm,1,0);
53   DMProductSetDM(dm,2,da1);
54   DMProductSetDimensionIndex(dm,2,1);
55 .ve
56   results in a three-dimensional `DM` whose `x` coordinate values are obtained from the `x` coordinate values of `da1`, whose `y` coordinate values are obtained from
57   the 'x' coordinate values of `da2` and whose `z` coordinate values are obtained from the `y` coordinate values of `da1`.
58 
59 .seealso: `DM`, `DMSTAG`, `DMProductGetDM()`, `DMProductSetDimensionIndex()`, `DMProductSetDM()`, `DMStagSetUniformCoordinatesProduct()`,
60           `DMStagGetProductCoordinateArrays()`, `DMStagGetProductCoordinateArraysRead()`, `DMGetCoordinateDM()`, `DMSetCoordinateDM()`
61 M*/
62 
DMCreate_Product(DM dm)63 PETSC_EXTERN PetscErrorCode DMCreate_Product(DM dm)
64 {
65   DM_Product *product;
66   PetscInt    d;
67 
68   PetscFunctionBegin;
69   PetscAssertPointer(dm, 1);
70   PetscCall(PetscNew(&product));
71   dm->data = product;
72 
73   for (d = 0; d < DMPRODUCT_MAX_DIM; ++d) product->dm[d] = NULL;
74   for (d = 0; d < DMPRODUCT_MAX_DIM; ++d) product->dim[d] = -1;
75 
76   dm->ops->destroy = DMDestroy_Product;
77   dm->ops->view    = DMView_Product;
78   PetscFunctionReturn(PETSC_SUCCESS);
79 }
80