# DMGetCompatibility
determine if two `DM`s are compatible 
## Synopsis
```
#include "petscdm.h"          
#include "petscdmlabel.h"     
#include "petscds.h"     
PetscErrorCode DMGetCompatibility(DM dm1, DM dm2, PetscBool *compatible, PetscBool *set)
```
Collective


## Input Parameters

- ***dm1 -*** the first `DM`
- ***dm2 -*** the second `DM`



## Output Parameters

- ***compatible -*** whether or not the two `DM`s are compatible
- ***set -*** whether or not the compatible value was actually determined and set



## Notes
Two `DM`s are deemed compatible if they represent the same parallel decomposition
of the same topology. This implies that the section (field data) on one
"makes sense" with respect to the topology and parallel decomposition of the other.
Loosely speaking, compatible `DM`s represent the same domain and parallel
decomposition, but hold different data.

Typically, one would confirm compatibility if intending to simultaneously iterate
over a pair of vectors obtained from different `DM`s.

For example, two `DMDA` objects are compatible if they have the same local
and global sizes and the same stencil width. They can have different numbers
of degrees of freedom per node. Thus, one could use the node numbering from
either `DM` in bounds for a loop over vectors derived from either `DM`.

Consider the operation of summing data living on a 2-dof `DMDA` to data living
on a 1-dof `DMDA`, which should be compatible, as in the following snippet.
```none
  ...
  PetscCall(DMGetCompatibility(da1,da2,&compatible,&set));
  if (set && compatible)  {
    PetscCall(DMDAVecGetArrayDOF(da1,vec1,&arr1));
    PetscCall(DMDAVecGetArrayDOF(da2,vec2,&arr2));
    PetscCall(DMDAGetCorners(da1,&x,&y,NULL,&m,&n,NULL));
    for (j=y; j<y+n; ++j) {
      for (i=x; i<x+m, ++i) {
        arr1[j][i][0] = arr2[j][i][0] + arr2[j][i][1];
      }
    }
    PetscCall(DMDAVecRestoreArrayDOF(da1,vec1,&arr1));
    PetscCall(DMDAVecRestoreArrayDOF(da2,vec2,&arr2));
  } else {
    SETERRQ(PetscObjectComm((PetscObject)da1,PETSC_ERR_ARG_INCOMP,"DMDA objects incompatible");
  }
  ...
```


Checking compatibility might be expensive for a given implementation of `DM`,
or might be impossible to unambiguously confirm or deny. For this reason,
this function may decline to determine compatibility, and hence users should
always check the "set" output parameter.

A `DM` is always compatible with itself.

In the current implementation, `DM`s which live on "unequal" communicators
(MPI_UNEQUAL in the terminology of MPI_Comm_compare()) are always deemed
incompatible.

This function is labeled "Collective," as information about all subdomains
is required on each rank. However, in `DM` implementations which store all this
information locally, this function may be merely "Logically Collective".


## Developer Note
Compatibility is assumed to be a symmetric concept; `DM` A is compatible with `DM` B
iff B is compatible with A. Thus, this function checks the implementations
of both dm and dmc (if they are of different types), attempting to determine
compatibility. It is left to `DM` implementers to ensure that symmetry is
preserved. The simplest way to do this is, when implementing type-specific
logic for this function, is to check for existing logic in the implementation
of other `DM` types and let *set = PETSC_FALSE if found.




## See Also
 `DM`, `DMDACreateCompatibleDMDA()`, `DMStagCreateCompatibleDMStag()`

## Level
advanced

## Location
<A HREF="PETSC_DOC_OUT_ROOT_PLACEHOLDER/src/dm/interface/dm.c.html#DMGetCompatibility">src/dm/interface/dm.c</A>

## Implementations

<A HREF="PETSC_DOC_OUT_ROOT_PLACEHOLDER/src/dm/impls/da/da.c.html#DMGetCompatibility_DA">DMGetCompatibility_DA in src/dm/impls/da/da.c</A><BR>
<A HREF="PETSC_DOC_OUT_ROOT_PLACEHOLDER/src/dm/impls/stag/stag.c.html#DMGetCompatibility_Stag">DMGetCompatibility_Stag in src/dm/impls/stag/stag.c</A><BR>


---
[Edit on GitLab](https://gitlab.com/petsc/petsc/-/edit/release/src/dm/interface/dm.c)


[Index of all DM routines](index.md)  
[Table of Contents for all manual pages](/docs/manualpages/index.md)  
[Index of all manual pages](/docs/manualpages/singleindex.md)  
