Actual source code: product.c

  1: #include <petsc/private/dmproductimpl.h>

  3: static PetscErrorCode DMDestroy_Product(DM dm)
  4: {
  5:   DM_Product *product = (DM_Product *)dm->data;
  6:   PetscInt    d;

  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: }

 14: static PetscErrorCode DMView_Product(DM dm, PetscViewer viewer)
 15: {
 16:   DM_Product *product = (DM_Product *)dm->data;
 17:   PetscInt    d;

 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: }

 33: /*MC
 34:   DMPRODUCT = "product" - a `DM` representing a local Cartesian product of other `DM`

 36:   Level: advanced

 38:   Notes:
 39:   The `DM` is usually used for managing coordinates of other `DM` via `DMGetCoordinateDM()` and `DMSetCoordinateDM()`

 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` coodinate 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`.

 59: .seealso: `DM`, `DMSTAG`, `DMProductGetDM()`, `DMProductSetDimensionIndex()`, `DMProductSetDM()`, `DMStagSetUniformCoordinatesProduct()`,
 60:           `DMStagGetProductCoordinateArrays()`, `DMStagGetProductCoordinateArraysRead()`, `DMGetCoordinateDM()`, `DMSetCoordinateDM()`
 61: M*/

 63: PETSC_EXTERN PetscErrorCode DMCreate_Product(DM dm)
 64: {
 65:   DM_Product *product;
 66:   PetscInt    d;

 68:   PetscFunctionBegin;
 69:   PetscAssertPointer(dm, 1);
 70:   PetscCall(PetscNew(&product));
 71:   dm->data = product;

 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;

 76:   dm->ops->destroy = DMDestroy_Product;
 77:   dm->ops->view    = DMView_Product;
 78:   PetscFunctionReturn(PETSC_SUCCESS);
 79: }