message: Modifying hypre_ParCSRMatrixAdd to support matrices with different off-diagonal column mappings.
diff: @@ -1226,20 +1226,29 @@ hypre_ParCSRMatrixAdd(hypre_ParCSRMatrix *A,
  hypre_CSRMatrix *C_offd;
  HYPRE_Int *C_cmap;
  HYPRE_Int im;
  + HYPRE_Int cmap_differ;
  /* Make sure A_cmap and B_cmap are the same. */
  + cmap_differ = 0;
  if (A_cmap_size != B_cmap_size)
  {
  - return NULL; /* error: A and B have different cmap_size */
  + cmap_differ = 1; /* error: A and B have different cmap_size */
  }
  for (im = 0; im < A_cmap_size; im++)
  {
  if (A_cmap[im] != B_cmap[im])
  {
  - return NULL; /* error: A and B have different cmap arrays */
  + cmap_differ = 1; /* error: A and B have different cmap arrays */
  + break;
  }
  }
  + if ( cmap_differ == 0 )
  + {
  + /* A and B have the same column mapping for their off-diagonal
  + blocks so we can sum the diagonal and off-diagonal blocks
  + separately and reduce temporary memory usage. */
  +
  /* Add diagonals, off-diagonals, copy cmap. */
  C_diag = hypre_CSRMatrixAdd(A_diag, B_diag);
  if (!C_diag)
  @@ -1276,6 +1285,47 @@ hypre_ParCSRMatrixAdd(hypre_ParCSRMatrix *A,
  hypre_ParCSRMatrixOffd(C) = C_offd;
  hypre_ParCSRMatrixColMapOffd(C) = C_cmap;
  + }
  + else
  + {
  + /* A and B have different column mappings for their off-diagonal
  + blocks so we need to use the column maps to create full-width
  + CSR matricies. */
  +
  + int ierr = 0;
  + hypre_CSRMatrix * csr_A;
  + hypre_CSRMatrix * csr_B;
  + hypre_CSRMatrix * csr_C_temp;
  +
  + /* merge diag and off-diag portions of A */
  + csr_A = hypre_MergeDiagAndOffd(A);
  +
  + /* merge diag and off-diag portions of B */
  + csr_B = hypre_MergeDiagAndOffd(B);
  +
  + /* add A and B */
  + csr_C_temp = hypre_CSRMatrixAdd(csr_A,csr_B);
  +
  + /* delete CSR versions of A and B */
  + ierr += hypre_CSRMatrixDestroy(csr_A);
  + ierr += hypre_CSRMatrixDestroy(csr_B);
  +
  + /* create a new empty ParCSR matrix to contain the sum */
  + C = hypre_ParCSRMatrixCreate(hypre_ParCSRMatrixComm(A),
  + hypre_ParCSRMatrixGlobalNumRows(A),
  + hypre_ParCSRMatrixGlobalNumCols(A),
  + hypre_ParCSRMatrixRowStarts(A),
  + hypre_ParCSRMatrixColStarts(A),
  + 0, 0, 0);
  +
  + /* split C into diag and off-diag portions */
  + ierr += GenerateDiagAndOffd(csr_C_temp, C,
  + hypre_ParCSRMatrixFirstColDiag(A),
  + hypre_ParCSRMatrixLastColDiag(A));
  +
  + /* delete CSR version of C */
  + ierr += hypre_CSRMatrixDestroy(csr_C_temp);
  + }
  /* hypre_ParCSRMatrixSetNumNonzeros(A); */
  