xref: /petsc/src/tao/bound/utils/isutil.c (revision 53506e15f4c198475be287552ae23f63a4890445)
1a7e14dcfSSatish Balay #include "tao.h" /*I "tao.h" I*/
2a7e14dcfSSatish Balay #include "petsc-private/matimpl.h"
3f89ca46fSSatish Balay #include "../src/tao/matrix/submatfree.h"
4a7e14dcfSSatish Balay #include "tao_util.h" /*I "tao_util.h" I*/
5a7e14dcfSSatish Balay 
6a7e14dcfSSatish Balay 
7a7e14dcfSSatish Balay #undef __FUNCT__
8a7e14dcfSSatish Balay #define __FUNCT__ "VecWhichEqual"
9a7e14dcfSSatish Balay /*@
10a7e14dcfSSatish Balay   VecWhichEqual - Creates an index set containing the indices
11a7e14dcfSSatish Balay              where the vectors Vec1 and Vec2 have identical elements.
12a7e14dcfSSatish Balay 
13*53506e15SBarry Smith   Collective on Vec
14a7e14dcfSSatish Balay 
15a7e14dcfSSatish Balay   Input Parameters:
16a7e14dcfSSatish Balay . Vec1, Vec2 - the two vectors to compare
17a7e14dcfSSatish Balay 
18a7e14dcfSSatish Balay   OutputParameter:
19a7e14dcfSSatish Balay . S - The index set containing the indices i where vec1[i] == vec2[i]
20a7e14dcfSSatish Balay 
21a7e14dcfSSatish Balay   Level: advanced
22a7e14dcfSSatish Balay @*/
23a7e14dcfSSatish Balay PetscErrorCode VecWhichEqual(Vec Vec1, Vec Vec2, IS * S)
24a7e14dcfSSatish Balay {
25a7e14dcfSSatish Balay   PetscErrorCode  ierr;
26a7e14dcfSSatish Balay   PetscInt        i,n_same = 0;
27a7e14dcfSSatish Balay   PetscInt        n,low,high,low2,high2;
28*53506e15SBarry Smith   PetscInt        *same = NULL;
29a7e14dcfSSatish Balay   PetscReal       *v1,*v2;
30a7e14dcfSSatish Balay   MPI_Comm        comm;
31a7e14dcfSSatish Balay 
32a7e14dcfSSatish Balay   PetscFunctionBegin;
33a7e14dcfSSatish Balay   PetscValidHeaderSpecific(Vec1,VEC_CLASSID,1);
34a7e14dcfSSatish Balay   PetscValidHeaderSpecific(Vec2,VEC_CLASSID,2);
35a7e14dcfSSatish Balay   PetscCheckSameComm(Vec1,1,Vec2,2);
36a7e14dcfSSatish Balay 
37a7e14dcfSSatish Balay   ierr = VecGetOwnershipRange(Vec1, &low, &high);CHKERRQ(ierr);
38a7e14dcfSSatish Balay   ierr = VecGetOwnershipRange(Vec2, &low2, &high2);CHKERRQ(ierr);
39*53506e15SBarry Smith   if ( low != low2 || high != high2 ) SETERRQ(PETSC_COMM_SELF,1,"Vectors must have identical layout");
40a7e14dcfSSatish Balay 
41a7e14dcfSSatish Balay   ierr = VecGetLocalSize(Vec1,&n);CHKERRQ(ierr);
42a7e14dcfSSatish Balay   if (n>0){
43a7e14dcfSSatish Balay     if (Vec1 == Vec2){
44a7e14dcfSSatish Balay       ierr = VecGetArray(Vec1,&v1);CHKERRQ(ierr);
45a7e14dcfSSatish Balay       v2=v1;
46a7e14dcfSSatish Balay     } else {
47a7e14dcfSSatish Balay       ierr = VecGetArray(Vec1,&v1);CHKERRQ(ierr);
48a7e14dcfSSatish Balay       ierr = VecGetArray(Vec2,&v2);CHKERRQ(ierr);
49a7e14dcfSSatish Balay     }
50a7e14dcfSSatish Balay 
51a7e14dcfSSatish Balay     ierr = PetscMalloc( n*sizeof(PetscInt),&same );CHKERRQ(ierr);
52a7e14dcfSSatish Balay 
53a7e14dcfSSatish Balay     for (i=0; i<n; i++){
54a7e14dcfSSatish Balay       if (v1[i] == v2[i]) {same[n_same]=low+i; n_same++;}
55a7e14dcfSSatish Balay     }
56a7e14dcfSSatish Balay 
57a7e14dcfSSatish Balay     if (Vec1 == Vec2){
58a7e14dcfSSatish Balay       ierr = VecRestoreArray(Vec1,&v1);CHKERRQ(ierr);
59a7e14dcfSSatish Balay     } else {
60a7e14dcfSSatish Balay       ierr = VecRestoreArray(Vec1,&v1);CHKERRQ(ierr);
61a7e14dcfSSatish Balay       ierr = VecRestoreArray(Vec2,&v2);CHKERRQ(ierr);
62a7e14dcfSSatish Balay     }
63a7e14dcfSSatish Balay   }
64a7e14dcfSSatish Balay   ierr = PetscObjectGetComm((PetscObject)Vec1,&comm);CHKERRQ(ierr);
65*53506e15SBarry Smith   ierr = ISCreateGeneral(comm,n_same,same,PETSC_OWN_POINTER,S);CHKERRQ(ierr);
66a7e14dcfSSatish Balay   PetscFunctionReturn(0);
67a7e14dcfSSatish Balay }
68a7e14dcfSSatish Balay 
69a7e14dcfSSatish Balay #undef __FUNCT__
70a7e14dcfSSatish Balay #define __FUNCT__ "VecWhichLessThan"
71a7e14dcfSSatish Balay /*@
72a7e14dcfSSatish Balay   VecWhichLessThan - Creates an index set containing the indices
73a7e14dcfSSatish Balay   where the vectors Vec1 < Vec2
74a7e14dcfSSatish Balay 
75a7e14dcfSSatish Balay   Collective on S
76a7e14dcfSSatish Balay 
77a7e14dcfSSatish Balay   Input Parameters:
78a7e14dcfSSatish Balay . Vec1, Vec2 - the two vectors to compare
79a7e14dcfSSatish Balay 
80a7e14dcfSSatish Balay   OutputParameter:
81a7e14dcfSSatish Balay . S - The index set containing the indices i where vec1[i] < vec2[i]
82a7e14dcfSSatish Balay 
83a7e14dcfSSatish Balay   Level: advanced
84a7e14dcfSSatish Balay @*/
85a7e14dcfSSatish Balay PetscErrorCode VecWhichLessThan(Vec Vec1, Vec Vec2, IS * S)
86a7e14dcfSSatish Balay {
87*53506e15SBarry Smith   PetscErrorCode ierr;
88a7e14dcfSSatish Balay   PetscInt       i;
89a7e14dcfSSatish Balay   PetscInt       n,low,high,low2,high2,n_lt=0;
90*53506e15SBarry Smith   PetscInt       *lt = NULL;
91a7e14dcfSSatish Balay   PetscReal      *v1,*v2;
92a7e14dcfSSatish Balay   MPI_Comm       comm;
93a7e14dcfSSatish Balay 
94a7e14dcfSSatish Balay   PetscFunctionBegin;
95a7e14dcfSSatish Balay   PetscValidHeaderSpecific(Vec1,VEC_CLASSID,1);
96a7e14dcfSSatish Balay   PetscValidHeaderSpecific(Vec2,VEC_CLASSID,2);
97a7e14dcfSSatish Balay   PetscCheckSameComm(Vec1,1,Vec2,2);
98a7e14dcfSSatish Balay 
99a7e14dcfSSatish Balay   ierr = VecGetOwnershipRange(Vec1, &low, &high);CHKERRQ(ierr);
100a7e14dcfSSatish Balay   ierr = VecGetOwnershipRange(Vec2, &low2, &high2);CHKERRQ(ierr);
101*53506e15SBarry Smith   if ( low != low2 || high != high2 ) SETERRQ(PETSC_COMM_SELF,1,"Vectors must haveidentical layout");
102a7e14dcfSSatish Balay 
103a7e14dcfSSatish Balay   ierr = VecGetLocalSize(Vec1,&n);CHKERRQ(ierr);
104a7e14dcfSSatish Balay   if (n>0){
105a7e14dcfSSatish Balay     if (Vec1 == Vec2){
106a7e14dcfSSatish Balay       ierr = VecGetArray(Vec1,&v1);CHKERRQ(ierr);
107a7e14dcfSSatish Balay       v2=v1;
108a7e14dcfSSatish Balay     } else {
109a7e14dcfSSatish Balay       ierr = VecGetArray(Vec1,&v1);CHKERRQ(ierr);
110a7e14dcfSSatish Balay       ierr = VecGetArray(Vec2,&v2);CHKERRQ(ierr);
111a7e14dcfSSatish Balay     }
112a7e14dcfSSatish Balay     ierr = PetscMalloc( n*sizeof(PetscInt),&lt );CHKERRQ(ierr);
113a7e14dcfSSatish Balay 
114a7e14dcfSSatish Balay     for (i=0; i<n; i++){
115a7e14dcfSSatish Balay       if (v1[i] < v2[i]) {lt[n_lt]=low+i; n_lt++;}
116a7e14dcfSSatish Balay     }
117a7e14dcfSSatish Balay 
118a7e14dcfSSatish Balay     if (Vec1 == Vec2){
119a7e14dcfSSatish Balay       ierr = VecRestoreArray(Vec1,&v1);CHKERRQ(ierr);
120a7e14dcfSSatish Balay     } else {
121a7e14dcfSSatish Balay       ierr = VecRestoreArray(Vec1,&v1);CHKERRQ(ierr);
122a7e14dcfSSatish Balay       ierr = VecRestoreArray(Vec2,&v2);CHKERRQ(ierr);
123a7e14dcfSSatish Balay     }
124a7e14dcfSSatish Balay   }
125a7e14dcfSSatish Balay   ierr = PetscObjectGetComm((PetscObject)Vec1,&comm);CHKERRQ(ierr);
126*53506e15SBarry Smith   ierr = ISCreateGeneral(comm,n_lt,lt,PETSC_OWN_POINTER,S);CHKERRQ(ierr);
127a7e14dcfSSatish Balay   PetscFunctionReturn(0);
128a7e14dcfSSatish Balay }
129a7e14dcfSSatish Balay 
130a7e14dcfSSatish Balay #undef __FUNCT__
131a7e14dcfSSatish Balay #define __FUNCT__ "VecWhichGreaterThan"
132a7e14dcfSSatish Balay /*@
133a7e14dcfSSatish Balay   VecWhichGreaterThan - Creates an index set containing the indices
134a7e14dcfSSatish Balay   where the vectors Vec1 > Vec2
135a7e14dcfSSatish Balay 
136a7e14dcfSSatish Balay   Collective on S
137a7e14dcfSSatish Balay 
138a7e14dcfSSatish Balay   Input Parameters:
139a7e14dcfSSatish Balay . Vec1, Vec2 - the two vectors to compare
140a7e14dcfSSatish Balay 
141a7e14dcfSSatish Balay   OutputParameter:
142a7e14dcfSSatish Balay . S - The index set containing the indices i where vec1[i] > vec2[i]
143a7e14dcfSSatish Balay 
144a7e14dcfSSatish Balay   Level: advanced
145a7e14dcfSSatish Balay @*/
146a7e14dcfSSatish Balay PetscErrorCode VecWhichGreaterThan(Vec Vec1, Vec Vec2, IS * S)
147a7e14dcfSSatish Balay {
148*53506e15SBarry Smith   PetscErrorCode ierr;
149a7e14dcfSSatish Balay   PetscInt       n,low,high,low2,high2,n_gt=0,i;
150a7e14dcfSSatish Balay   PetscInt       *gt=NULL;
151a7e14dcfSSatish Balay   PetscReal      *v1,*v2;
152a7e14dcfSSatish Balay   MPI_Comm       comm;
153a7e14dcfSSatish Balay 
154a7e14dcfSSatish Balay   PetscFunctionBegin;
155a7e14dcfSSatish Balay   PetscValidHeaderSpecific(Vec1,VEC_CLASSID,1);
156a7e14dcfSSatish Balay   PetscValidHeaderSpecific(Vec2,VEC_CLASSID,2);
157a7e14dcfSSatish Balay   PetscCheckSameComm(Vec1,1,Vec2,2);
158a7e14dcfSSatish Balay 
159a7e14dcfSSatish Balay   ierr = VecGetOwnershipRange(Vec1, &low, &high);CHKERRQ(ierr);
160a7e14dcfSSatish Balay   ierr = VecGetOwnershipRange(Vec2, &low2, &high2);CHKERRQ(ierr);
161*53506e15SBarry Smith   if ( low != low2 || high != high2 ) SETERRQ(PETSC_COMM_SELF,1,"Vectors must be have identical layout");
162a7e14dcfSSatish Balay 
163a7e14dcfSSatish Balay   ierr = VecGetLocalSize(Vec1,&n);CHKERRQ(ierr);
164a7e14dcfSSatish Balay 
165a7e14dcfSSatish Balay   if (n>0){
166a7e14dcfSSatish Balay 
167a7e14dcfSSatish Balay     if (Vec1 == Vec2){
168a7e14dcfSSatish Balay       ierr = VecGetArray(Vec1,&v1);CHKERRQ(ierr);
169a7e14dcfSSatish Balay       v2=v1;
170a7e14dcfSSatish Balay     } else {
171a7e14dcfSSatish Balay       ierr = VecGetArray(Vec1,&v1);CHKERRQ(ierr);
172a7e14dcfSSatish Balay       ierr = VecGetArray(Vec2,&v2);CHKERRQ(ierr);
173a7e14dcfSSatish Balay     }
174a7e14dcfSSatish Balay 
175a7e14dcfSSatish Balay     ierr = PetscMalloc( n*sizeof(PetscInt), &gt );CHKERRQ(ierr);
176a7e14dcfSSatish Balay 
177a7e14dcfSSatish Balay     for (i=0; i<n; i++){
178a7e14dcfSSatish Balay       if (v1[i] > v2[i]) {gt[n_gt]=low+i; n_gt++;}
179a7e14dcfSSatish Balay     }
180a7e14dcfSSatish Balay 
181a7e14dcfSSatish Balay     if (Vec1 == Vec2){
182a7e14dcfSSatish Balay       ierr = VecRestoreArray(Vec1,&v1);CHKERRQ(ierr);
183a7e14dcfSSatish Balay     } else {
184a7e14dcfSSatish Balay       ierr = VecRestoreArray(Vec1,&v1);CHKERRQ(ierr);
185a7e14dcfSSatish Balay       ierr = VecRestoreArray(Vec2,&v2);CHKERRQ(ierr);
186a7e14dcfSSatish Balay     }
187a7e14dcfSSatish Balay   }
188a7e14dcfSSatish Balay   ierr = PetscObjectGetComm((PetscObject)Vec1,&comm);CHKERRQ(ierr);
189*53506e15SBarry Smith   ierr = ISCreateGeneral(comm,n_gt,gt,PETSC_OWN_POINTER,S);CHKERRQ(ierr);
190a7e14dcfSSatish Balay   PetscFunctionReturn(0);
191a7e14dcfSSatish Balay }
192a7e14dcfSSatish Balay 
193a7e14dcfSSatish Balay #undef __FUNCT__
194a7e14dcfSSatish Balay #define __FUNCT__ "VecWhichBetween"
195a7e14dcfSSatish Balay /*@
196a7e14dcfSSatish Balay   VecWhichBetween - Creates an index set containing the indices
197a7e14dcfSSatish Balay                where  VecLow < V < VecHigh
198a7e14dcfSSatish Balay 
199a7e14dcfSSatish Balay   Collective on S
200a7e14dcfSSatish Balay 
201a7e14dcfSSatish Balay   Input Parameters:
202a7e14dcfSSatish Balay + VecLow - lower bound
203a7e14dcfSSatish Balay . V - Vector to compare
204a7e14dcfSSatish Balay - VecHigh - higher bound
205a7e14dcfSSatish Balay 
206a7e14dcfSSatish Balay   OutputParameter:
207a7e14dcfSSatish Balay . S - The index set containing the indices i where veclow[i] < v[i] < vechigh[i]
208a7e14dcfSSatish Balay 
209a7e14dcfSSatish Balay   Level: advanced
210a7e14dcfSSatish Balay @*/
211a7e14dcfSSatish Balay PetscErrorCode VecWhichBetween(Vec VecLow, Vec V, Vec VecHigh, IS *S)
212a7e14dcfSSatish Balay {
213a7e14dcfSSatish Balay 
214a7e14dcfSSatish Balay   PetscErrorCode ierr;
215a7e14dcfSSatish Balay   PetscInt       n,low,high,low2,high2,low3,high3,n_vm=0;
216a7e14dcfSSatish Balay   PetscInt       *vm,i;
217a7e14dcfSSatish Balay   PetscReal      *v1,*v2,*vmiddle;
218a7e14dcfSSatish Balay   MPI_Comm       comm;
219a7e14dcfSSatish Balay 
220a7e14dcfSSatish Balay   PetscValidHeaderSpecific(V,VEC_CLASSID,2);
221a7e14dcfSSatish Balay   PetscCheckSameComm(V,2,VecLow,1); PetscCheckSameComm(V,2,VecHigh,3);
222a7e14dcfSSatish Balay 
223a7e14dcfSSatish Balay   ierr = VecGetOwnershipRange(VecLow, &low, &high);CHKERRQ(ierr);
224a7e14dcfSSatish Balay   ierr = VecGetOwnershipRange(VecHigh, &low2, &high2);CHKERRQ(ierr);
225a7e14dcfSSatish Balay   ierr = VecGetOwnershipRange(V, &low3, &high3);CHKERRQ(ierr);
226*53506e15SBarry Smith   if ( low!=low2 || high!=high2 || low!=low3 || high!=high3) SETERRQ(PETSC_COMM_SELF,1,"Vectors must have identical layout");
227a7e14dcfSSatish Balay 
228a7e14dcfSSatish Balay   ierr = VecGetLocalSize(VecLow,&n);CHKERRQ(ierr);
229a7e14dcfSSatish Balay   if (n>0){
230a7e14dcfSSatish Balay     ierr = VecGetArray(VecLow,&v1);CHKERRQ(ierr);
231a7e14dcfSSatish Balay     if (VecLow != VecHigh){
232a7e14dcfSSatish Balay       ierr = VecGetArray(VecHigh,&v2);CHKERRQ(ierr);
233a7e14dcfSSatish Balay     } else {
234a7e14dcfSSatish Balay       v2=v1;
235a7e14dcfSSatish Balay     }
236a7e14dcfSSatish Balay     if ( V != VecLow && V != VecHigh){
237a7e14dcfSSatish Balay       ierr = VecGetArray(V,&vmiddle);CHKERRQ(ierr);
238a7e14dcfSSatish Balay     } else if ( V==VecLow ){
239a7e14dcfSSatish Balay       vmiddle=v1;
240a7e14dcfSSatish Balay     } else {
241a7e14dcfSSatish Balay       vmiddle =v2;
242a7e14dcfSSatish Balay     }
243a7e14dcfSSatish Balay 
244a7e14dcfSSatish Balay     ierr = PetscMalloc( n*sizeof(PetscInt), &vm );CHKERRQ(ierr);
245a7e14dcfSSatish Balay 
246a7e14dcfSSatish Balay     for (i=0; i<n; i++){
247a7e14dcfSSatish Balay       if (v1[i] < vmiddle[i] && vmiddle[i] < v2[i]) {vm[n_vm]=low+i; n_vm++;}
248a7e14dcfSSatish Balay     }
249a7e14dcfSSatish Balay 
250a7e14dcfSSatish Balay     ierr = VecRestoreArray(VecLow,&v1);CHKERRQ(ierr);
251a7e14dcfSSatish Balay     if (VecLow != VecHigh){
252a7e14dcfSSatish Balay       ierr = VecRestoreArray(VecHigh,&v2);CHKERRQ(ierr);
253a7e14dcfSSatish Balay     }
254a7e14dcfSSatish Balay     if ( V != VecLow && V != VecHigh){
255a7e14dcfSSatish Balay       ierr = VecRestoreArray(V,&vmiddle);CHKERRQ(ierr);
256a7e14dcfSSatish Balay     }
257a7e14dcfSSatish Balay   }
258a7e14dcfSSatish Balay   ierr = PetscObjectGetComm((PetscObject)V,&comm);CHKERRQ(ierr);
259*53506e15SBarry Smith   ierr = ISCreateGeneral(comm,n_vm,vm,PETSC_OWN_POINTER,S);CHKERRQ(ierr);
260a7e14dcfSSatish Balay   PetscFunctionReturn(0);
261a7e14dcfSSatish Balay }
262a7e14dcfSSatish Balay 
263a7e14dcfSSatish Balay 
264a7e14dcfSSatish Balay #undef __FUNCT__
265a7e14dcfSSatish Balay #define __FUNCT__ "VecWhichBetweenOrEqual"
266a7e14dcfSSatish Balay /*@
267a7e14dcfSSatish Balay   VecWhichBetweenOrEqual - Creates an index set containing the indices
268a7e14dcfSSatish Balay   where  VecLow <= V <= VecHigh
269a7e14dcfSSatish Balay 
270a7e14dcfSSatish Balay   Collective on S
271a7e14dcfSSatish Balay 
272a7e14dcfSSatish Balay   Input Parameters:
273a7e14dcfSSatish Balay + VecLow - lower bound
274a7e14dcfSSatish Balay . V - Vector to compare
275a7e14dcfSSatish Balay - VecHigh - higher bound
276a7e14dcfSSatish Balay 
277a7e14dcfSSatish Balay   OutputParameter:
278a7e14dcfSSatish Balay . S - The index set containing the indices i where veclow[i] <= v[i] <= vechigh[i]
279a7e14dcfSSatish Balay 
280a7e14dcfSSatish Balay   Level: advanced
281a7e14dcfSSatish Balay @*/
282a7e14dcfSSatish Balay 
283a7e14dcfSSatish Balay PetscErrorCode VecWhichBetweenOrEqual(Vec VecLow, Vec V, Vec VecHigh, IS * S)
284a7e14dcfSSatish Balay {
285a7e14dcfSSatish Balay   PetscErrorCode ierr;
286a7e14dcfSSatish Balay   PetscInt       n,low,high,low2,high2,low3,high3,n_vm=0,i;
287*53506e15SBarry Smith   PetscInt       *vm = NULL;
288a7e14dcfSSatish Balay   PetscReal      *v1,*v2,*vmiddle;
289a7e14dcfSSatish Balay   MPI_Comm       comm;
290a7e14dcfSSatish Balay 
291a7e14dcfSSatish Balay   PetscValidHeaderSpecific(V,VEC_CLASSID,2);
292a7e14dcfSSatish Balay   PetscCheckSameComm(V,2,VecLow,1); PetscCheckSameComm(V,2,VecHigh,3);
293a7e14dcfSSatish Balay 
294a7e14dcfSSatish Balay   ierr = VecGetOwnershipRange(VecLow, &low, &high);CHKERRQ(ierr);
295a7e14dcfSSatish Balay   ierr = VecGetOwnershipRange(VecHigh, &low2, &high2);CHKERRQ(ierr);
296a7e14dcfSSatish Balay   ierr = VecGetOwnershipRange(V, &low3, &high3);CHKERRQ(ierr);
297*53506e15SBarry Smith   if ( low!=low2 || high!=high2 || low!=low3 || high!=high3 ) SETERRQ(PETSC_COMM_SELF,1,"Vectors must have identical layout");
298a7e14dcfSSatish Balay 
299a7e14dcfSSatish Balay   ierr = VecGetLocalSize(VecLow,&n);CHKERRQ(ierr);
300a7e14dcfSSatish Balay 
301a7e14dcfSSatish Balay   if (n>0){
302a7e14dcfSSatish Balay     ierr = VecGetArray(VecLow,&v1);CHKERRQ(ierr);
303a7e14dcfSSatish Balay     if (VecLow != VecHigh){
304a7e14dcfSSatish Balay       ierr = VecGetArray(VecHigh,&v2);CHKERRQ(ierr);
305a7e14dcfSSatish Balay     } else {
306a7e14dcfSSatish Balay       v2=v1;
307a7e14dcfSSatish Balay     }
308a7e14dcfSSatish Balay     if ( V != VecLow && V != VecHigh){
309a7e14dcfSSatish Balay       ierr = VecGetArray(V,&vmiddle);CHKERRQ(ierr);
310a7e14dcfSSatish Balay     } else if ( V==VecLow ){
311a7e14dcfSSatish Balay       vmiddle=v1;
312a7e14dcfSSatish Balay     } else {
313a7e14dcfSSatish Balay       vmiddle =v2;
314a7e14dcfSSatish Balay     }
315a7e14dcfSSatish Balay 
316a7e14dcfSSatish Balay     ierr = PetscMalloc( n*sizeof(PetscInt), &vm );CHKERRQ(ierr);
317a7e14dcfSSatish Balay 
318a7e14dcfSSatish Balay     for (i=0; i<n; i++){
319a7e14dcfSSatish Balay       if (v1[i] <= vmiddle[i] && vmiddle[i] <= v2[i]) {vm[n_vm]=low+i; n_vm++;}
320a7e14dcfSSatish Balay     }
321a7e14dcfSSatish Balay 
322a7e14dcfSSatish Balay     ierr = VecRestoreArray(VecLow,&v1);CHKERRQ(ierr);
323a7e14dcfSSatish Balay     if (VecLow != VecHigh){
324a7e14dcfSSatish Balay       ierr = VecRestoreArray(VecHigh,&v2);CHKERRQ(ierr);
325a7e14dcfSSatish Balay     }
326a7e14dcfSSatish Balay     if ( V != VecLow && V != VecHigh){
327a7e14dcfSSatish Balay       ierr = VecRestoreArray(V,&vmiddle);CHKERRQ(ierr);
328a7e14dcfSSatish Balay     }
329a7e14dcfSSatish Balay   }
330a7e14dcfSSatish Balay   ierr = PetscObjectGetComm((PetscObject)V,&comm);CHKERRQ(ierr);
331*53506e15SBarry Smith   ierr = ISCreateGeneral(comm,n_vm,vm,PETSC_OWN_POINTER,S);CHKERRQ(ierr);
332a7e14dcfSSatish Balay   PetscFunctionReturn(0);
333a7e14dcfSSatish Balay }
334a7e14dcfSSatish Balay 
335a7e14dcfSSatish Balay 
336a7e14dcfSSatish Balay #undef __FUNCT__
337a7e14dcfSSatish Balay #define __FUNCT__ "VecGetSubVec"
338a7e14dcfSSatish Balay /*@
339a7e14dcfSSatish Balay   VecGetSubVec - Gets a subvector using the IS
340a7e14dcfSSatish Balay 
341a7e14dcfSSatish Balay   Input Parameters:
342a7e14dcfSSatish Balay + vfull - the full matrix
343a7e14dcfSSatish Balay . is - the index set for the subvector
344a7e14dcfSSatish Balay . reduced_type - the method TAO is using for subsetting (TAO_SUBSET_SUBVEC, TAO_SUBSET_MASK,  TAO_SUBSET_MATRIXFREE)
345a7e14dcfSSatish Balay - maskvalue - the value to set the unused vector elements to (for TAO_SUBSET_MASK or TAO_SUBSET_MATRIXFREE)
346a7e14dcfSSatish Balay 
347a7e14dcfSSatish Balay   Output Parameters:
348a7e14dcfSSatish Balay . vreduced - the subvector
349a7e14dcfSSatish Balay 
350a7e14dcfSSatish Balay   Note:
351a7e14dcfSSatish Balay   maskvalue should usually be 0.0, unless a pointwise divide will be used.
352a7e14dcfSSatish Balay @*/
353a7e14dcfSSatish Balay PetscErrorCode VecGetSubVec(Vec vfull, IS is, PetscInt reduced_type, PetscReal maskvalue, Vec *vreduced)
354a7e14dcfSSatish Balay {
355a7e14dcfSSatish Balay   PetscErrorCode ierr;
356a7e14dcfSSatish Balay   PetscInt       nfull,nreduced,nreduced_local,rlow,rhigh,flow,fhigh;
357a7e14dcfSSatish Balay   PetscInt       i,nlocal;
358a7e14dcfSSatish Balay   PetscReal      *fv,*rv;
359a7e14dcfSSatish Balay   const PetscInt *s;
360a7e14dcfSSatish Balay   IS             ident;
361a7e14dcfSSatish Balay   VecType        vtype;
362a7e14dcfSSatish Balay   VecScatter     scatter;
363a7e14dcfSSatish Balay   MPI_Comm       comm;
364a7e14dcfSSatish Balay 
365a7e14dcfSSatish Balay   PetscFunctionBegin;
366a7e14dcfSSatish Balay   PetscValidHeaderSpecific(vfull,VEC_CLASSID,1);
367a7e14dcfSSatish Balay   PetscValidHeaderSpecific(is,IS_CLASSID,2);
368a7e14dcfSSatish Balay 
369a7e14dcfSSatish Balay   ierr = VecGetSize(vfull, &nfull);CHKERRQ(ierr);
370a7e14dcfSSatish Balay   ierr = ISGetSize(is, &nreduced);CHKERRQ(ierr);
371a7e14dcfSSatish Balay 
372a7e14dcfSSatish Balay   if (nreduced == nfull) {
373a7e14dcfSSatish Balay     ierr = VecDestroy(vreduced);CHKERRQ(ierr);
374a7e14dcfSSatish Balay     ierr = VecDuplicate(vfull,vreduced);CHKERRQ(ierr);
375a7e14dcfSSatish Balay     ierr = VecCopy(vfull,*vreduced);CHKERRQ(ierr);
376a7e14dcfSSatish Balay   } else {
377a7e14dcfSSatish Balay     switch (reduced_type) {
378a7e14dcfSSatish Balay     case TAO_SUBSET_SUBVEC:
379a7e14dcfSSatish Balay       ierr = VecGetType(vfull,&vtype);CHKERRQ(ierr);
380a7e14dcfSSatish Balay       ierr = VecGetOwnershipRange(vfull,&flow,&fhigh);CHKERRQ(ierr);
381a7e14dcfSSatish Balay       ierr = ISGetLocalSize(is,&nreduced_local);CHKERRQ(ierr);
382a7e14dcfSSatish Balay       ierr = PetscObjectGetComm((PetscObject)vfull,&comm);CHKERRQ(ierr);
383a7e14dcfSSatish Balay       if (*vreduced) {
384a7e14dcfSSatish Balay         ierr = VecDestroy(vreduced);CHKERRQ(ierr);
385a7e14dcfSSatish Balay       }
386a7e14dcfSSatish Balay       ierr = VecCreate(comm,vreduced);CHKERRQ(ierr);
387a7e14dcfSSatish Balay       ierr = VecSetType(*vreduced,vtype);CHKERRQ(ierr);
388a7e14dcfSSatish Balay 
389a7e14dcfSSatish Balay       ierr = VecSetSizes(*vreduced,nreduced_local,nreduced);CHKERRQ(ierr);
390a7e14dcfSSatish Balay       ierr = VecGetOwnershipRange(*vreduced,&rlow,&rhigh);CHKERRQ(ierr);
391a7e14dcfSSatish Balay       ierr = ISCreateStride(comm,nreduced_local,rlow,1,&ident);CHKERRQ(ierr);
392a7e14dcfSSatish Balay       ierr = VecScatterCreate(vfull,is,*vreduced,ident,&scatter);CHKERRQ(ierr);
393a7e14dcfSSatish Balay       ierr = VecScatterBegin(scatter,vfull,*vreduced,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
394a7e14dcfSSatish Balay       ierr = VecScatterEnd(scatter,vfull,*vreduced,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
395a7e14dcfSSatish Balay       ierr = VecScatterDestroy(&scatter);CHKERRQ(ierr);
396a7e14dcfSSatish Balay       ierr = ISDestroy(&ident);CHKERRQ(ierr);
397a7e14dcfSSatish Balay       break;
398a7e14dcfSSatish Balay 
399a7e14dcfSSatish Balay     case TAO_SUBSET_MASK:
400a7e14dcfSSatish Balay     case TAO_SUBSET_MATRIXFREE:
401a7e14dcfSSatish Balay       /* vr[i] = vf[i]   if i in is
402a7e14dcfSSatish Balay        vr[i] = 0       otherwise */
4036c23d075SBarry Smith       if (*vreduced == NULL) {
404a7e14dcfSSatish Balay         ierr = VecDuplicate(vfull,vreduced);CHKERRQ(ierr);
405a7e14dcfSSatish Balay       }
406a7e14dcfSSatish Balay 
407a7e14dcfSSatish Balay       ierr = VecSet(*vreduced,maskvalue);CHKERRQ(ierr);
408a7e14dcfSSatish Balay       ierr = ISGetLocalSize(is,&nlocal);CHKERRQ(ierr);
409a7e14dcfSSatish Balay       ierr = VecGetOwnershipRange(vfull,&flow,&fhigh);CHKERRQ(ierr);
410a7e14dcfSSatish Balay       ierr = VecGetArray(vfull,&fv);CHKERRQ(ierr);
411a7e14dcfSSatish Balay       ierr = VecGetArray(*vreduced,&rv);CHKERRQ(ierr);
412a7e14dcfSSatish Balay       ierr = ISGetIndices(is,&s);CHKERRQ(ierr);
413*53506e15SBarry Smith       if (nlocal > (fhigh-flow)) SETERRQ2(PETSC_COMM_WORLD,1,"IS local size %d > Vec local size %d",nlocal,fhigh-flow);
414a7e14dcfSSatish Balay       for (i=0;i<nlocal;i++) {
415a7e14dcfSSatish Balay         rv[s[i]-flow] = fv[s[i]-flow];
416a7e14dcfSSatish Balay       }
417a7e14dcfSSatish Balay       ierr = ISRestoreIndices(is,&s);CHKERRQ(ierr);
418a7e14dcfSSatish Balay       ierr = VecRestoreArray(vfull,&fv);CHKERRQ(ierr);
419a7e14dcfSSatish Balay       ierr = VecRestoreArray(*vreduced,&rv);CHKERRQ(ierr);
420a7e14dcfSSatish Balay       break;
421a7e14dcfSSatish Balay     }
422a7e14dcfSSatish Balay   }
423a7e14dcfSSatish Balay   PetscFunctionReturn(0);
424a7e14dcfSSatish Balay }
425a7e14dcfSSatish Balay 
426a7e14dcfSSatish Balay #undef __FUNCT__
427a7e14dcfSSatish Balay #define __FUNCT__ "VecReducedXPY"
428a7e14dcfSSatish Balay /*@
429a7e14dcfSSatish Balay   VecReducedXPY - Adds a reduced vector to the appropriate elements of a full-space vector.
430a7e14dcfSSatish Balay 
431a7e14dcfSSatish Balay   Input Parameters:
432a7e14dcfSSatish Balay + vfull - the full-space vector
433a7e14dcfSSatish Balay . vreduced - the reduced-space vector
434a7e14dcfSSatish Balay - is - the index set for the reduced space
435a7e14dcfSSatish Balay 
436a7e14dcfSSatish Balay   Output Parameters:
437a7e14dcfSSatish Balay . vfull - the sum of the full-space vector and reduced-space vector
438a7e14dcfSSatish Balay @*/
439a7e14dcfSSatish Balay PetscErrorCode VecReducedXPY(Vec vfull, Vec vreduced, IS is)
440a7e14dcfSSatish Balay {
441a7e14dcfSSatish Balay   VecScatter     scatter;
442a7e14dcfSSatish Balay   IS             ident;
443a7e14dcfSSatish Balay   PetscInt       nfull,nreduced,rlow,rhigh;
444a7e14dcfSSatish Balay   MPI_Comm       comm;
445a7e14dcfSSatish Balay   PetscErrorCode ierr;
446a7e14dcfSSatish Balay 
447a7e14dcfSSatish Balay   PetscFunctionBegin;
448a7e14dcfSSatish Balay   PetscValidHeaderSpecific(vfull,VEC_CLASSID,1);
449a7e14dcfSSatish Balay   PetscValidHeaderSpecific(vreduced,VEC_CLASSID,2);
450a7e14dcfSSatish Balay   PetscValidHeaderSpecific(is,IS_CLASSID,3);
451a7e14dcfSSatish Balay   ierr = VecGetSize(vfull,&nfull);CHKERRQ(ierr);
452a7e14dcfSSatish Balay   ierr = VecGetSize(vreduced,&nreduced);CHKERRQ(ierr);
453a7e14dcfSSatish Balay 
454a7e14dcfSSatish Balay   if (nfull == nreduced) { /* Also takes care of masked vectors */
455a7e14dcfSSatish Balay     ierr = VecAXPY(vfull,1.0,vreduced);CHKERRQ(ierr);
456a7e14dcfSSatish Balay   } else {
457a7e14dcfSSatish Balay     ierr = PetscObjectGetComm((PetscObject)vfull,&comm);CHKERRQ(ierr);
458a7e14dcfSSatish Balay     ierr = VecGetOwnershipRange(vreduced,&rlow,&rhigh);CHKERRQ(ierr);
459a7e14dcfSSatish Balay     ierr = ISCreateStride(comm,rhigh-rlow,rlow,1,&ident);CHKERRQ(ierr);
460a7e14dcfSSatish Balay     ierr = VecScatterCreate(vreduced,ident,vfull,is,&scatter);CHKERRQ(ierr);
461a7e14dcfSSatish Balay     ierr = VecScatterBegin(scatter,vreduced,vfull,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
462a7e14dcfSSatish Balay     ierr = VecScatterEnd(scatter,vreduced,vfull,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
463a7e14dcfSSatish Balay     ierr = VecScatterDestroy(&scatter);CHKERRQ(ierr);
464a7e14dcfSSatish Balay     ierr = ISDestroy(&ident);CHKERRQ(ierr);
465a7e14dcfSSatish Balay   }
466a7e14dcfSSatish Balay   PetscFunctionReturn(0);
467a7e14dcfSSatish Balay }
468a7e14dcfSSatish Balay 
469a7e14dcfSSatish Balay 
470a7e14dcfSSatish Balay #undef __FUNCT__
471a7e14dcfSSatish Balay #define __FUNCT__ "ISCreateComplement"
472a7e14dcfSSatish Balay /*@
473a7e14dcfSSatish Balay    ISCreateComplement - Creates the complement of the the index set
474a7e14dcfSSatish Balay 
475a7e14dcfSSatish Balay    Collective on IS
476a7e14dcfSSatish Balay 
477a7e14dcfSSatish Balay    Input Parameter:
478a7e14dcfSSatish Balay +  S -  a PETSc IS
479a7e14dcfSSatish Balay -  V - the reference vector space
480a7e14dcfSSatish Balay 
481a7e14dcfSSatish Balay    Output Parameter:
482a7e14dcfSSatish Balay .  T -  the complement of S
483a7e14dcfSSatish Balay 
484a7e14dcfSSatish Balay 
485a7e14dcfSSatish Balay .seealso ISCreateGeneral()
486a7e14dcfSSatish Balay 
487a7e14dcfSSatish Balay    Level: advanced
488a7e14dcfSSatish Balay @*/
489*53506e15SBarry Smith PetscErrorCode ISCreateComplement(IS S, Vec V, IS *T)
490*53506e15SBarry Smith {
491a7e14dcfSSatish Balay   PetscErrorCode ierr;
492a7e14dcfSSatish Balay   PetscInt       i,nis,nloc,high,low,n=0;
493a7e14dcfSSatish Balay   const PetscInt *s;
494a7e14dcfSSatish Balay   PetscInt       *tt,*ss;
495a7e14dcfSSatish Balay   MPI_Comm       comm;
496a7e14dcfSSatish Balay 
497a7e14dcfSSatish Balay   PetscFunctionBegin;
498a7e14dcfSSatish Balay   PetscValidHeaderSpecific(S,IS_CLASSID,1);
499a7e14dcfSSatish Balay   PetscValidHeaderSpecific(V,VEC_CLASSID,2);
500a7e14dcfSSatish Balay 
501a7e14dcfSSatish Balay   ierr = VecGetOwnershipRange(V,&low,&high);CHKERRQ(ierr);
502a7e14dcfSSatish Balay   ierr = VecGetLocalSize(V,&nloc);CHKERRQ(ierr);
503a7e14dcfSSatish Balay   ierr = ISGetLocalSize(S,&nis);CHKERRQ(ierr);
504a7e14dcfSSatish Balay   ierr = PetscMalloc( nloc*sizeof(PetscInt),&tt );CHKERRQ(ierr);
505a7e14dcfSSatish Balay   ierr = PetscMalloc( nloc*sizeof(PetscInt),&ss );CHKERRQ(ierr);
506a7e14dcfSSatish Balay 
507*53506e15SBarry Smith   ierr = ISGetIndices(S, &s);CHKERRQ(ierr);
508a7e14dcfSSatish Balay   for (i=low; i<high; i++){ tt[i-low]=i; }
509a7e14dcfSSatish Balay   for (i=0; i<nis; i++){ tt[s[i]-low] = -2; }
510a7e14dcfSSatish Balay 
511a7e14dcfSSatish Balay   for (i=0; i<nloc; i++){
512a7e14dcfSSatish Balay     if (tt[i]>-1){ ss[n]=tt[i]; n++; }
513a7e14dcfSSatish Balay   }
514a7e14dcfSSatish Balay   ierr = ISRestoreIndices(S, &s);CHKERRQ(ierr);
515a7e14dcfSSatish Balay 
516a7e14dcfSSatish Balay   ierr = PetscObjectGetComm((PetscObject)S,&comm);CHKERRQ(ierr);
517a7e14dcfSSatish Balay   ierr = ISCreateGeneral(comm,n,ss,PETSC_COPY_VALUES,T);CHKERRQ(ierr);
518a7e14dcfSSatish Balay   ierr = PetscFree(tt);CHKERRQ(ierr);
519a7e14dcfSSatish Balay   ierr = PetscFree(ss);CHKERRQ(ierr);
520a7e14dcfSSatish Balay   PetscFunctionReturn(0);
521a7e14dcfSSatish Balay }
522a7e14dcfSSatish Balay 
523a7e14dcfSSatish Balay #undef __FUNCT__
524a7e14dcfSSatish Balay #define __FUNCT__ "VecISSetToConstant"
525a7e14dcfSSatish Balay /*@
526a7e14dcfSSatish Balay    VecISSetToConstant - Sets the elements of a vector, specified by an index set, to a constant
527a7e14dcfSSatish Balay 
528a7e14dcfSSatish Balay    Input Parameter:
529a7e14dcfSSatish Balay +  S -  a PETSc IS
530a7e14dcfSSatish Balay .  c - the constant
531a7e14dcfSSatish Balay -  V - a Vec
532a7e14dcfSSatish Balay 
533a7e14dcfSSatish Balay .seealso VecSet()
534a7e14dcfSSatish Balay 
535a7e14dcfSSatish Balay    Level: advanced
536a7e14dcfSSatish Balay @*/
537*53506e15SBarry Smith PetscErrorCode VecISSetToConstant(IS S, PetscReal c, Vec V)
538*53506e15SBarry Smith {
539a7e14dcfSSatish Balay   PetscErrorCode ierr;
540a7e14dcfSSatish Balay   PetscInt       nloc,low,high,i;
541a7e14dcfSSatish Balay   const PetscInt *s;
542a7e14dcfSSatish Balay   PetscReal      *v;
543*53506e15SBarry Smith 
544a7e14dcfSSatish Balay   PetscFunctionBegin;
545a7e14dcfSSatish Balay   PetscValidHeaderSpecific(V,VEC_CLASSID,3);
546a7e14dcfSSatish Balay   PetscValidHeaderSpecific(S,IS_CLASSID,1);
547a7e14dcfSSatish Balay   PetscValidType(V,3);
548a7e14dcfSSatish Balay   PetscCheckSameComm(V,3,S,1);
549a7e14dcfSSatish Balay 
550a7e14dcfSSatish Balay   ierr = VecGetOwnershipRange(V, &low, &high);CHKERRQ(ierr);
551a7e14dcfSSatish Balay   ierr = ISGetLocalSize(S,&nloc);CHKERRQ(ierr);
552a7e14dcfSSatish Balay   ierr = ISGetIndices(S, &s);CHKERRQ(ierr);
553a7e14dcfSSatish Balay   ierr = VecGetArray(V,&v);CHKERRQ(ierr);
554a7e14dcfSSatish Balay   for (i=0; i<nloc; i++){
555a7e14dcfSSatish Balay     v[s[i]-low] = c;
556a7e14dcfSSatish Balay   }
557a7e14dcfSSatish Balay   ierr = ISRestoreIndices(S, &s);CHKERRQ(ierr);
558a7e14dcfSSatish Balay   ierr = VecRestoreArray(V,&v);CHKERRQ(ierr);
559a7e14dcfSSatish Balay   PetscFunctionReturn(0);
560a7e14dcfSSatish Balay }
561a7e14dcfSSatish Balay 
562a7e14dcfSSatish Balay #undef __FUNCT__
563a7e14dcfSSatish Balay #define __FUNCT__ "MatGetSubMat"
564a7e14dcfSSatish Balay /*@
565a7e14dcfSSatish Balay   MatGetSubMat - Gets a submatrix using the IS
566a7e14dcfSSatish Balay 
567a7e14dcfSSatish Balay   Input Parameters:
568a7e14dcfSSatish Balay + M - the full matrix (n x n)
569a7e14dcfSSatish Balay . is - the index set for the submatrix (both row and column index sets need to be the same)
570a7e14dcfSSatish Balay . v1 - work vector of dimension n, needed for TAO_SUBSET_MASK option
571a7e14dcfSSatish Balay - subset_type - the method TAO is using for subsetting (TAO_SUBSET_SUBVEC, TAO_SUBSET_MASK,
572a7e14dcfSSatish Balay   TAO_SUBSET_MATRIXFREE)
573a7e14dcfSSatish Balay 
574a7e14dcfSSatish Balay   Output Parameters:
575a7e14dcfSSatish Balay . Msub - the submatrix
576a7e14dcfSSatish Balay @*/
577a7e14dcfSSatish Balay PetscErrorCode MatGetSubMat(Mat M, IS is, Vec v1, TaoSubsetType subset_type, Mat *Msub)
578a7e14dcfSSatish Balay {
579a7e14dcfSSatish Balay   PetscErrorCode ierr;
580a7e14dcfSSatish Balay   IS             iscomp;
581a7e14dcfSSatish Balay   PetscBool      flg;
582*53506e15SBarry Smith 
583a7e14dcfSSatish Balay   PetscFunctionBegin;
584a7e14dcfSSatish Balay   PetscValidHeaderSpecific(M,MAT_CLASSID,1);
585a7e14dcfSSatish Balay   PetscValidHeaderSpecific(is,IS_CLASSID,2);
586a7e14dcfSSatish Balay   ierr = MatDestroy(Msub);CHKERRQ(ierr);
587a7e14dcfSSatish Balay   switch (subset_type) {
588a7e14dcfSSatish Balay   case TAO_SUBSET_SUBVEC:
589a7e14dcfSSatish Balay     ierr = MatGetSubMatrix(M, is, is, MAT_INITIAL_MATRIX, Msub);CHKERRQ(ierr);
590a7e14dcfSSatish Balay     break;
591a7e14dcfSSatish Balay 
592a7e14dcfSSatish Balay   case TAO_SUBSET_MASK:
593a7e14dcfSSatish Balay     /* Get Reduced Hessian
594a7e14dcfSSatish Balay      Msub[i,j] = M[i,j] if i,j in Free_Local or i==j
595a7e14dcfSSatish Balay      Msub[i,j] = 0      if i!=j and i or j not in Free_Local
596a7e14dcfSSatish Balay      */
5976c23d075SBarry Smith     ierr = PetscOptionsBool("-different_submatrix","use separate hessian matrix when computing submatrices","TaoSubsetType",PETSC_FALSE,&flg,NULL);
598a7e14dcfSSatish Balay     if (flg == PETSC_TRUE) {
599a7e14dcfSSatish Balay       ierr = MatDuplicate(M, MAT_COPY_VALUES, Msub);CHKERRQ(ierr);
600a7e14dcfSSatish Balay     } else {
601a7e14dcfSSatish Balay       /* Act on hessian directly (default) */
602a7e14dcfSSatish Balay       ierr = PetscObjectReference((PetscObject)M);CHKERRQ(ierr);
603a7e14dcfSSatish Balay       *Msub = M;
604a7e14dcfSSatish Balay     }
605a7e14dcfSSatish Balay     /* Save the diagonal to temporary vector */
606a7e14dcfSSatish Balay     ierr = MatGetDiagonal(*Msub,v1);CHKERRQ(ierr);
607a7e14dcfSSatish Balay 
608a7e14dcfSSatish Balay     /* Zero out rows and columns */
609a7e14dcfSSatish Balay     ierr = ISCreateComplement(is,v1,&iscomp);CHKERRQ(ierr);
610a7e14dcfSSatish Balay 
611a7e14dcfSSatish Balay     /* Use v1 instead of 0 here because of PETSc bug */
612a7e14dcfSSatish Balay     ierr = MatZeroRowsColumnsIS(*Msub,iscomp,1.0,v1,v1);CHKERRQ(ierr);
613a7e14dcfSSatish Balay 
614a7e14dcfSSatish Balay     ierr = ISDestroy(&iscomp);CHKERRQ(ierr);
615a7e14dcfSSatish Balay     break;
616a7e14dcfSSatish Balay   case TAO_SUBSET_MATRIXFREE:
617a7e14dcfSSatish Balay     ierr = ISCreateComplement(is,v1,&iscomp);CHKERRQ(ierr);
618a7e14dcfSSatish Balay     ierr = MatCreateSubMatrixFree(M,iscomp,iscomp,Msub);CHKERRQ(ierr);
619a7e14dcfSSatish Balay     ierr = ISDestroy(&iscomp);CHKERRQ(ierr);
620a7e14dcfSSatish Balay     break;
621a7e14dcfSSatish Balay   }
622a7e14dcfSSatish Balay   PetscFunctionReturn(0);
623a7e14dcfSSatish Balay }
624