@@ -232,7 +232,9 @@ void la::petsc::scatter_local_vectors(
232232}
233233// -----------------------------------------------------------------------------
234234Mat la::petsc::create_matrix (MPI_Comm comm, const SparsityPattern& sp,
235- std::optional<std::string> type)
235+ std::optional<std::string> type,
236+ std::optional<ISLocalToGlobalMapping> rlgmap,
237+ std::optional<ISLocalToGlobalMapping> clgmap)
236238{
237239 PetscErrorCode ierr;
238240 Mat A;
@@ -289,63 +291,75 @@ Mat la::petsc::create_matrix(MPI_Comm comm, const SparsityPattern& sp,
289291 _nnz_offdiag[i] = bs[1 ] * sp.nnz_off_diag (i / bs[0 ]);
290292 }
291293
292- // Allocate space for matrix
293- ierr = MatXAIJSetPreallocation (A, _bs, _nnz_diag.data (), _nnz_offdiag.data (),
294- nullptr , nullptr );
295- if (ierr != 0 )
296- petsc::error (ierr, __FILE__, " MatXIJSetPreallocation" );
297-
298- // Set block sizes
299- ierr = MatSetBlockSizes (A, bs[0 ], bs[1 ]);
300- if (ierr != 0 )
301- petsc::error (ierr, __FILE__, " MatSetBlockSizes" );
302-
303294 // Create PETSc local-to-global map/index sets
304- ISLocalToGlobalMapping local_to_global0;
305- const std::vector map0 = maps[0 ]->global_indices ();
306- const std::vector<PetscInt> _map0 (map0.begin (), map0.end ());
307- ierr = ISLocalToGlobalMappingCreate (MPI_COMM_SELF, bs[0 ], _map0.size (),
308- _map0.data (), PETSC_COPY_VALUES,
309- &local_to_global0);
310-
311- if (ierr != 0 )
312- petsc::error (ierr, __FILE__, " ISLocalToGlobalMappingCreate" );
295+ ISLocalToGlobalMapping local_to_global0, local_to_global1 = NULL ;
296+ if (rlgmap)
297+ {
298+ ierr = PetscObjectReference ((PetscObject)rlgmap.value ());
299+ if (ierr != 0 )
300+ petsc::error (ierr, __FILE__, " PetscObjectReference" );
301+ local_to_global0 = rlgmap.value ();
302+ }
303+ else
304+ {
305+ const std::vector map0 = maps[0 ]->global_indices ();
306+ const std::vector<PetscInt> _map0 (map0.begin (), map0.end ());
307+ ierr = ISLocalToGlobalMappingCreate (comm, bs[0 ], _map0.size (),
308+ _map0.data (), PETSC_COPY_VALUES,
309+ &local_to_global0);
310+ if (ierr != 0 )
311+ petsc::error (ierr, __FILE__, " ISLocalToGlobalMappingCreate" );
312+ }
313313
314314 // Check for common index maps
315- if (maps[0 ] == maps[1 ] and bs[0 ] == bs[1 ])
315+ if (maps[0 ] == maps[1 ] and bs[0 ] == bs[1 ] and !clgmap )
316316 {
317317 ierr = MatSetLocalToGlobalMapping (A, local_to_global0, local_to_global0);
318318 if (ierr != 0 )
319319 petsc::error (ierr, __FILE__, " MatSetLocalToGlobalMapping" );
320320 }
321321 else
322322 {
323- ISLocalToGlobalMapping local_to_global1;
324- const std::vector map1 = maps[1 ]->global_indices ();
325- const std::vector<PetscInt> _map1 (map1.begin (), map1.end ());
326- ierr = ISLocalToGlobalMappingCreate (MPI_COMM_SELF, bs[1 ], _map1.size (),
327- _map1.data (), PETSC_COPY_VALUES,
328- &local_to_global1);
329- if (ierr != 0 )
330- petsc::error (ierr, __FILE__, " ISLocalToGlobalMappingCreate" );
323+ if (clgmap)
324+ {
325+ ierr = PetscObjectReference ((PetscObject)clgmap.value ());
326+ if (ierr != 0 )
327+ petsc::error (ierr, __FILE__, " PetscObjectReference" );
328+ local_to_global1 = clgmap.value ();
329+ }
330+ else
331+ {
332+ const std::vector map1 = maps[1 ]->global_indices ();
333+ const std::vector<PetscInt> _map1 (map1.begin (), map1.end ());
334+ ierr = ISLocalToGlobalMappingCreate (comm, bs[1 ], _map1.size (),
335+ _map1.data (), PETSC_COPY_VALUES,
336+ &local_to_global1);
337+ if (ierr != 0 )
338+ petsc::error (ierr, __FILE__, " ISLocalToGlobalMappingCreate" );
339+ }
331340 ierr = MatSetLocalToGlobalMapping (A, local_to_global0, local_to_global1);
332341 if (ierr != 0 )
333342 petsc::error (ierr, __FILE__, " MatSetLocalToGlobalMapping" );
334- ierr = ISLocalToGlobalMappingDestroy (&local_to_global1);
335- if (ierr != 0 )
336- petsc::error (ierr, __FILE__, " ISLocalToGlobalMappingDestroy" );
337343 }
338344
339345 // Clean up local-to-global 0
340346 ierr = ISLocalToGlobalMappingDestroy (&local_to_global0);
347+ if (ierr != 0 )
348+ petsc::error (ierr, __FILE__, " ISLocalToGlobalMappingDestroy" );
349+ ierr = ISLocalToGlobalMappingDestroy (&local_to_global1);
341350 if (ierr != 0 )
342351 petsc::error (ierr, __FILE__, " ISLocalToGlobalMappingDestroy" );
343352
344- // Note: This should be called after having set the local-to-global
345- // map for MATIS (this is a dummy call if A is not of type MATIS)
346- // ierr = MatISSetPreallocation(A, 0, _nnz_diag.data(), 0,
347- // _nnz_offdiag.data()); if (ierr != 0)
348- // error(ierr, __FILE__, "MatISSetPreallocation");
353+ // Allocate space for matrix
354+ ierr = MatXAIJSetPreallocation (A, _bs, _nnz_diag.data (), _nnz_offdiag.data (),
355+ nullptr , nullptr );
356+ if (ierr != 0 )
357+ petsc::error (ierr, __FILE__, " MatXIJSetPreallocation" );
358+
359+ // Set block sizes
360+ ierr = MatSetBlockSizes (A, bs[0 ], bs[1 ]);
361+ if (ierr != 0 )
362+ petsc::error (ierr, __FILE__, " MatSetBlockSizes" );
349363
350364 // Set some options on Mat object
351365 ierr = MatSetOption (A, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_TRUE);
0 commit comments