From 8c464edef4e64e7f62413d06c28e87c451791b24 Mon Sep 17 00:00:00 2001
From: Andrew Cramer <andrewdalecramer@gmail.com>
Date: Thu, 18 Jun 2015 13:57:24 +1000
Subject: [PATCH] PCComposite: Add PCCompositeGetNumPC function

Add the PCCompositeGetNumPC function which returns the number of
sub PCs. This function allows PCCompositeGetPC to be used safely.
---
 include/petscpc.h                      |    1 +
 src/ksp/pc/impls/composite/composite.c |   51 +++++++++++++++++++++++++++++++-
 2 files changed, 51 insertions(+), 1 deletions(-)

diff --git a/include/petscpc.h b/include/petscpc.h
index 961712f..644c280 100644
--- a/include/petscpc.h
+++ b/include/petscpc.h
@@ -172,6 +172,7 @@ PETSC_EXTERN PetscErrorCode PCGASMGetSubmatrices(PC,PetscInt*,Mat*[]);
 PETSC_EXTERN PetscErrorCode PCCompositeSetType(PC,PCCompositeType);
 PETSC_EXTERN PetscErrorCode PCCompositeGetType(PC,PCCompositeType*);
 PETSC_EXTERN PetscErrorCode PCCompositeAddPC(PC,PCType);
+PETSC_EXTERN PetscErrorCode PCCompositeGetNumPC(PC,PetscInt *);
 PETSC_EXTERN PetscErrorCode PCCompositeGetPC(PC,PetscInt,PC *);
 PETSC_EXTERN PetscErrorCode PCCompositeSpecialSetAlpha(PC,PetscScalar);
 
diff --git a/src/ksp/pc/impls/composite/composite.c b/src/ksp/pc/impls/composite/composite.c
index 016d195..35efef3 100644
--- a/src/ksp/pc/impls/composite/composite.c
+++ b/src/ksp/pc/impls/composite/composite.c
@@ -368,6 +368,24 @@ static PetscErrorCode  PCCompositeAddPC_Composite(PC pc,PCType type)
 }
 
 #undef __FUNCT__
+#define __FUNCT__ "PCCompositeGetNumPC_Composite"
+static PetscErrorCode  PCCompositeGetNumPC_Composite(PC pc,PetscInt *n)
+{
+  PC_Composite     *jac;
+  PC_CompositeLink next;
+
+  PetscFunctionBegin;
+  jac  = (PC_Composite*)pc->data;
+  next = jac->head;
+  *n = 0;
+  while (next) {
+    next = next->next;
+    (*n) ++;
+  }
+  PetscFunctionReturn(0);
+}
+
+#undef __FUNCT__
 #define __FUNCT__ "PCCompositeGetPC_Composite"
 static PetscErrorCode  PCCompositeGetPC_Composite(PC pc,PetscInt n,PC *subpc)
 {
@@ -499,6 +517,36 @@ PetscErrorCode  PCCompositeAddPC(PC pc,PCType type)
 }
 
 #undef __FUNCT__
+#define __FUNCT__ "PCCompositeGetNumPC"
+/*@
+   PCCompositeGetNumPC - Gets the number of PC objects in the composite PC.
+
+   Not Collective
+
+   Input Parameter:
+.  pc - the preconditioner context
+
+   Output Parameters:
+.  num - the number of sub pcs
+
+   Level: Developer
+
+.keywords: PC, get, composite preconditioner, sub preconditioner
+
+.seealso: PCCompositeGetPC()
+@*/
+PetscErrorCode  PCCompositeGetNumPC(PC pc,PetscInt *num)
+{
+  PetscErrorCode ierr;
+
+  PetscFunctionBegin;
+  PetscValidHeaderSpecific(pc,PC_CLASSID,1);
+  PetscValidIntPointer(num,2);
+  ierr = PetscUseMethod(pc,"PCCompositeGetNumPC_C",(PC,PetscInt*),(pc,num));CHKERRQ(ierr);
+  PetscFunctionReturn(0);
+}
+
+#undef __FUNCT__
 #define __FUNCT__ "PCCompositeGetPC"
 /*@
    PCCompositeGetPC - Gets one of the PC objects in the composite PC.
@@ -516,7 +564,7 @@ PetscErrorCode  PCCompositeAddPC(PC pc,PCType type)
 
 .keywords: PC, get, composite preconditioner, sub preconditioner
 
-.seealso: PCCompositeAddPC()
+.seealso: PCCompositeAddPC(), PCCompositeGetNumPC()
 @*/
 PetscErrorCode  PCCompositeGetPC(PC pc,PetscInt n,PC *subpc)
 {
@@ -583,6 +631,7 @@ PETSC_EXTERN PetscErrorCode PCCreate_Composite(PC pc)
   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCCompositeSetType_C",PCCompositeSetType_Composite);CHKERRQ(ierr);
   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCCompositeGetType_C",PCCompositeGetType_Composite);CHKERRQ(ierr);
   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCCompositeAddPC_C",PCCompositeAddPC_Composite);CHKERRQ(ierr);
+  ierr = PetscObjectComposeFunction((PetscObject)pc,"PCCompositeGetNumPC_C",PCCompositeGetNumPC_Composite);CHKERRQ(ierr);
   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCCompositeGetPC_C",PCCompositeGetPC_Composite);CHKERRQ(ierr);
   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCCompositeSpecialSetAlpha_C",PCCompositeSpecialSetAlpha_Composite);CHKERRQ(ierr);
   PetscFunctionReturn(0);
-- 
1.7.1

