16dd63270SBarry Smith #include <petsc/private/ftnimpl.h> 245c38901SJed Brown #include <petscmat.h> 345c38901SJed Brown 445c38901SJed Brown #if defined(PETSC_HAVE_FORTRAN_CAPS) 545c38901SJed Brown #define matcreatenest_ MATCREATENEST 658ad77e8SBarry Smith #define matnestsetsubmats_ MATNESTSETSUBMATS 7ffa9b3b1SVincent Le Chenadec #define matnestgetsubmats_ MATNESTGETSUBMATS 845c38901SJed Brown #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE) 945c38901SJed Brown #define matcreatenest_ matcreatenest 1058ad77e8SBarry Smith #define matnestsetsubmats_ matnestsetsubmats 11ffa9b3b1SVincent Le Chenadec #define matnestgetsubmats_ matnestgetsubmats 1245c38901SJed Brown #endif 1345c38901SJed Brown 1458ad77e8SBarry Smith PETSC_EXTERN void matcreatenest_(MPI_Fint *comm, PetscInt *nr, IS is_row[], PetscInt *nc, IS is_col[], Mat a[], Mat *B, PetscErrorCode *ierr) 1545c38901SJed Brown { 162f6eced2SAlex Fikl Mat *m, *tmp; 172f6eced2SAlex Fikl PetscInt i; 182f6eced2SAlex Fikl 1945c38901SJed Brown CHKFORTRANNULLOBJECT(is_row); 2045c38901SJed Brown CHKFORTRANNULLOBJECT(is_col); 212f6eced2SAlex Fikl 225975b3b6SBarry Smith *ierr = PetscMalloc1((*nr) * (*nc), &m); 235975b3b6SBarry Smith if (*ierr) return; 242f6eced2SAlex Fikl for (i = 0; i < (*nr) * (*nc); i++) { 25f4f49eeaSPierre Jolivet tmp = &a[i]; 262f6eced2SAlex Fikl CHKFORTRANNULLOBJECT(tmp); 2758ad77e8SBarry Smith if (a[i] == (Mat)-2 || a[i] == (Mat)-3) { 2858ad77e8SBarry Smith (void)PetscError(MPI_Comm_f2c(*comm), __LINE__, PETSC_FUNCTION_NAME, __FILE__, PETSC_ERR_ARG_WRONG, PETSC_ERROR_INITIAL, "Use PETSC_NULL_MAT for missing blocks"); 2958ad77e8SBarry Smith *ierr = PETSC_ERR_ARG_WRONG; 3058ad77e8SBarry Smith return; 3158ad77e8SBarry Smith } 322f6eced2SAlex Fikl m[i] = (tmp == NULL ? NULL : a[i]); 332f6eced2SAlex Fikl } 345975b3b6SBarry Smith *ierr = MatCreateNest(MPI_Comm_f2c(*comm), *nr, is_row, *nc, is_col, m, B); 355975b3b6SBarry Smith if (*ierr) return; 362f6eced2SAlex Fikl *ierr = PetscFree(m); 3745c38901SJed Brown } 383a4d7b9aSSatish Balay 3958ad77e8SBarry Smith PETSC_EXTERN void matnestsetsubmats_(Mat *B, PetscInt *nr, IS is_row[], PetscInt *nc, IS is_col[], Mat a[], PetscErrorCode *ierr) 4058ad77e8SBarry Smith { 4158ad77e8SBarry Smith Mat *m, *tmp; 4258ad77e8SBarry Smith PetscInt i; 4358ad77e8SBarry Smith MPI_Comm comm; 4458ad77e8SBarry Smith 4558ad77e8SBarry Smith CHKFORTRANNULLOBJECT(is_row); 4658ad77e8SBarry Smith CHKFORTRANNULLOBJECT(is_col); 4758ad77e8SBarry Smith 4858ad77e8SBarry Smith *ierr = PetscMalloc1((*nr) * (*nc), &m); 4958ad77e8SBarry Smith if (*ierr) return; 5058ad77e8SBarry Smith for (i = 0; i < (*nr) * (*nc); i++) { 5158ad77e8SBarry Smith tmp = &a[i]; 5258ad77e8SBarry Smith CHKFORTRANNULLOBJECT(tmp); 5358ad77e8SBarry Smith if (a[i] == (Mat)-2 || a[i] == (Mat)-3) { 5458ad77e8SBarry Smith *ierr = PetscObjectGetComm((PetscObject)*B, &comm); 5558ad77e8SBarry Smith if (*ierr) return; 5658ad77e8SBarry Smith (void)PetscError(comm, __LINE__, PETSC_FUNCTION_NAME, __FILE__, PETSC_ERR_ARG_WRONG, PETSC_ERROR_INITIAL, "Use PETSC_NULL_MAT for missing blocks"); 5758ad77e8SBarry Smith *ierr = PETSC_ERR_ARG_WRONG; 5858ad77e8SBarry Smith return; 5958ad77e8SBarry Smith } 6058ad77e8SBarry Smith m[i] = (tmp == NULL ? NULL : a[i]); 6158ad77e8SBarry Smith } 6258ad77e8SBarry Smith *ierr = MatNestSetSubMats(*B, *nr, is_row, *nc, is_col, m); 6358ad77e8SBarry Smith if (*ierr) return; 6458ad77e8SBarry Smith *ierr = PetscFree(m); 6558ad77e8SBarry Smith } 6658ad77e8SBarry Smith 6758ad77e8SBarry Smith PETSC_EXTERN void matnestgetsubmats_(Mat *A, PetscInt *M, PetscInt *N, Mat *sub, PetscErrorCode *ierr) 68ffa9b3b1SVincent Le Chenadec { 69351962e3SVincent Le Chenadec PetscInt i, j, m, n; 70ffa9b3b1SVincent Le Chenadec Mat **mat; 71351962e3SVincent Le Chenadec 72351962e3SVincent Le Chenadec CHKFORTRANNULLINTEGER(M); 73351962e3SVincent Le Chenadec CHKFORTRANNULLINTEGER(N); 74351962e3SVincent Le Chenadec CHKFORTRANNULLOBJECT(sub); 75351962e3SVincent Le Chenadec 76351962e3SVincent Le Chenadec *ierr = MatNestGetSubMats(*A, &m, &n, &mat); 77351962e3SVincent Le Chenadec 78*ac530a7eSPierre Jolivet if (M) *M = m; 79*ac530a7eSPierre Jolivet if (N) *N = n; 80351962e3SVincent Le Chenadec if (sub) { 81351962e3SVincent Le Chenadec for (i = 0; i < m; i++) { 82351962e3SVincent Le Chenadec for (j = 0; j < n; j++) { 832f6eced2SAlex Fikl if (mat[i][j]) { 84351962e3SVincent Le Chenadec sub[j + n * i] = mat[i][j]; 852f6eced2SAlex Fikl } else { 861c8b34f3SBarry Smith sub[j + n * i] = (Mat)-1; 872f6eced2SAlex Fikl } 88351962e3SVincent Le Chenadec } 89ffa9b3b1SVincent Le Chenadec } 90ffa9b3b1SVincent Le Chenadec } 91ffa9b3b1SVincent Le Chenadec } 92