]> https://gitweb.dealii.org/ - dealii.git/commitdiff
PETScWrappers:BlockSparseMatrix: create PETSc MATNEST
authorStefano Zampini <stefano.zampini@gmail.com>
Thu, 10 Nov 2022 17:22:19 +0000 (18:22 +0100)
committerLuca Heltai <luca.heltai@sissa.it>
Tue, 20 Dec 2022 10:28:10 +0000 (11:28 +0100)
include/deal.II/lac/petsc_block_sparse_matrix.h
source/lac/petsc_parallel_block_sparse_matrix.cc
tests/petsc/block_matrices_01.cc
tests/petsc/block_matrices_01.mpirun=1.output

index 913a694b87c69b99d20703ca39317f8b7286ac7b..8bb025586d1bb278810366039ab4504e0e77d135 100644 (file)
@@ -105,7 +105,7 @@ namespace PETScWrappers
       /**
        * Destructor.
        */
-      ~BlockSparseMatrix() override = default;
+      ~BlockSparseMatrix() override;
 
       /**
        * Pseudo copy operator only copying empty objects. The sizes of the
@@ -271,6 +271,26 @@ namespace PETScWrappers
        * protected.
        */
       using BlockMatrixBase<SparseMatrix>::clear;
+
+      /**
+       * Conversion operator to gain access to the underlying PETSc type. If you
+       * do this, you cut this class off some information it may need, so this
+       * conversion operator should only be used if you know what you do. In
+       * particular, it should only be used for read-only operations into the
+       * matrix.
+       */
+      operator Mat() const;
+
+      /**
+       * Return a reference to the underlying PETSc type. It can be used to
+       * modify the underlying data, so use it only when you know what you
+       * are doing.
+       */
+      Mat &
+      petsc_matrix();
+
+    private:
+      Mat petsc_nest_matrix = nullptr;
     };
 
 
index 6b82eae960ee9540a01b035efafe30a327cdb994..d744d72f2b98d565764cdf0692b9aee32f371b97 100644 (file)
@@ -14,6 +14,7 @@
 // ---------------------------------------------------------------------
 
 #include <deal.II/lac/petsc_block_sparse_matrix.h>
+#include <deal.II/lac/petsc_compatibility.h>
 
 #ifdef DEAL_II_WITH_PETSC
 
@@ -31,6 +32,11 @@ namespace PETScWrappers
       return *this;
     }
 
+    BlockSparseMatrix::~BlockSparseMatrix()
+    {
+      PetscErrorCode ierr = destroy_matrix(petsc_nest_matrix);
+      AssertThrow(ierr == 0, ExcPETScError(ierr));
+    }
 
 #  ifndef DOXYGEN
     void
@@ -111,6 +117,24 @@ namespace PETScWrappers
     BlockSparseMatrix::collect_sizes()
     {
       BaseClass::collect_sizes();
+
+      auto m = this->n_block_cols();
+      auto n = this->n_block_cols();
+
+      PetscErrorCode ierr = destroy_matrix(petsc_nest_matrix);
+      AssertThrow(ierr == 0, ExcPETScError(ierr));
+      std::vector<Mat> psub_objects(m * n);
+      for (unsigned int r = 0; r < m; r++)
+        for (unsigned int c = 0; c < n; c++)
+          psub_objects[r * n + c] = this->sub_objects[r][c]->petsc_matrix();
+      ierr = MatCreateNest(get_mpi_communicator(),
+                           m,
+                           NULL,
+                           n,
+                           NULL,
+                           psub_objects.data(),
+                           &petsc_nest_matrix);
+      AssertThrow(ierr == 0, ExcPETScError(ierr));
     }
 
     std::vector<IndexSet>
@@ -152,6 +176,17 @@ namespace PETScWrappers
       return block(0, 0).get_mpi_communicator();
     }
 
+    BlockSparseMatrix::operator Mat() const
+    {
+      return petsc_nest_matrix;
+    }
+
+    Mat &
+    BlockSparseMatrix::petsc_matrix()
+    {
+      return petsc_nest_matrix;
+    }
+
   } // namespace MPI
 } // namespace PETScWrappers
 
index 51dc0875ddab1b5b81744737975a50551cf810e7..193afc3b653e057f54d5bba132e34a2e3c18b0f8 100644 (file)
@@ -67,6 +67,10 @@ test()
   pbsm.reinit(rows, cols, bdsp, MPI_COMM_WORLD);
   deallog << "nonzeros BlockSparseMatrix: " << pbsm.n_nonzero_elements()
           << std::endl;
+
+  // Extract the PETSc MATNEST and use print from PETScWrappers::MatrixBase
+  PETScWrappers::MatrixBase tmp(pbsm.petsc_matrix());
+  tmp.print(deallog.get_file_stream());
 }
 
 
index a9c5e15408ff9c32fbdc79fa4e78434d87ca4c95..ca11cbdd0235d5cfb685b8614434b43ddd2093cd 100644 (file)
@@ -1,3 +1,12 @@
 
 DEAL::nonzeros BlockSparsityPattern: 9
 DEAL::nonzeros BlockSparseMatrix: 9
+(0,0) 0.00000
+(1,0) 0.00000
+(1,1) 0.00000
+(2,2) 0.00000
+(3,2) 0.00000
+(3,3) 0.00000
+(4,2) 0.00000
+(4,3) 0.00000
+(4,4) 0.00000

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.