Subversion Repositories slepc-dev

Rev

Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2757 jroman 1
/*
2
   Basic PS routines
3
 
4
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
5
   SLEPc - Scalable Library for Eigenvalue Problem Computations
6
   Copyright (c) 2002-2011, Universitat Politecnica de Valencia, Spain
7
 
8
   This file is part of SLEPc.
9
 
10
   SLEPc is free software: you can redistribute it and/or modify it under  the
11
   terms of version 3 of the GNU Lesser General Public License as published by
12
   the Free Software Foundation.
13
 
14
   SLEPc  is  distributed in the hope that it will be useful, but WITHOUT  ANY
15
   WARRANTY;  without even the implied warranty of MERCHANTABILITY or  FITNESS
16
   FOR  A  PARTICULAR PURPOSE. See the GNU Lesser General Public  License  for
17
   more details.
18
 
19
   You  should have received a copy of the GNU Lesser General  Public  License
20
   along with SLEPc. If not, see <http://www.gnu.org/licenses/>.
21
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
22
*/
23
 
24
#include <slepc-private/psimpl.h>      /*I "slepcps.h" I*/
25
 
26
PetscFList       PSList = 0;
27
PetscBool        PSRegisterAllCalled = PETSC_FALSE;
28
PetscClassId     PS_CLASSID = 0;
2771 jroman 29
PetscLogEvent    PS_Solve = 0,PS_Sort = 0,PS_Other = 0;
2757 jroman 30
static PetscBool PSPackageInitialized = PETSC_FALSE;
2777 jroman 31
const char       *PSMatName[PS_NUM_MAT] = {"A","B","C","T","Q","X","Y","U","VT","W"};
2757 jroman 32
 
33
#undef __FUNCT__  
34
#define __FUNCT__ "PSFinalizePackage"
35
/*@C
36
   PSFinalizePackage - This function destroys everything in the Slepc interface
37
   to the PS package. It is called from SlepcFinalize().
38
 
39
   Level: developer
40
 
41
.seealso: SlepcFinalize()
42
@*/
43
PetscErrorCode PSFinalizePackage(void)
44
{
45
  PetscFunctionBegin;
46
  PSPackageInitialized = PETSC_FALSE;
47
  PSList               = 0;
48
  PSRegisterAllCalled  = PETSC_FALSE;
49
  PetscFunctionReturn(0);
50
}
51
 
52
#undef __FUNCT__  
53
#define __FUNCT__ "PSInitializePackage"
54
/*@C
55
  PSInitializePackage - This function initializes everything in the PS package.
56
  It is called from PetscDLLibraryRegister() when using dynamic libraries, and
57
  on the first call to PSCreate() when using static libraries.
58
 
59
  Input Parameter:
60
  path - The dynamic library path, or PETSC_NULL
61
 
62
  Level: developer
63
 
64
.seealso: SlepcInitialize()
65
@*/
66
PetscErrorCode PSInitializePackage(const char *path)
67
{
68
  char             logList[256];
69
  char             *className;
70
  PetscBool        opt;
71
  PetscErrorCode   ierr;
72
 
73
  PetscFunctionBegin;
74
  if (PSPackageInitialized) PetscFunctionReturn(0);
75
  PSPackageInitialized = PETSC_TRUE;
76
  /* Register Classes */
77
  ierr = PetscClassIdRegister("Projected system",&PS_CLASSID);CHKERRQ(ierr);
78
  /* Register Constructors */
79
  ierr = PSRegisterAll(path);CHKERRQ(ierr);
80
  /* Register Events */
81
  ierr = PetscLogEventRegister("PSSolve",PS_CLASSID,&PS_Solve);CHKERRQ(ierr);
82
  ierr = PetscLogEventRegister("PSSort",PS_CLASSID,&PS_Sort);CHKERRQ(ierr);
2771 jroman 83
  ierr = PetscLogEventRegister("PSOther",PS_CLASSID,&PS_Other);CHKERRQ(ierr);
2757 jroman 84
  /* Process info exclusions */
85
  ierr = PetscOptionsGetString(PETSC_NULL,"-info_exclude",logList,256,&opt);CHKERRQ(ierr);
86
  if (opt) {
87
    ierr = PetscStrstr(logList,"ps",&className);CHKERRQ(ierr);
88
    if (className) {
89
      ierr = PetscInfoDeactivateClass(PS_CLASSID);CHKERRQ(ierr);
90
    }
91
  }
92
  /* Process summary exclusions */
93
  ierr = PetscOptionsGetString(PETSC_NULL,"-log_summary_exclude",logList,256,&opt);CHKERRQ(ierr);
94
  if (opt) {
95
    ierr = PetscStrstr(logList,"ps",&className);CHKERRQ(ierr);
96
    if (className) {
97
      ierr = PetscLogEventDeactivateClass(PS_CLASSID);CHKERRQ(ierr);
98
    }
99
  }
100
  ierr = PetscRegisterFinalize(PSFinalizePackage);CHKERRQ(ierr);
101
  PetscFunctionReturn(0);
102
}
103
 
104
#undef __FUNCT__  
105
#define __FUNCT__ "PSCreate"
106
/*@C
107
   PSCreate - Creates a PS context.
108
 
109
   Collective on MPI_Comm
110
 
111
   Input Parameter:
112
.  comm - MPI communicator
113
 
114
   Output Parameter:
115
.  newps - location to put the PS context
116
 
117
   Level: beginner
118
 
119
   Note:
120
   PS objects are not intended for normal users but only for
121
   advanced user that for instance implement their own solvers.
122
 
123
.seealso: PSDestroy(), PS
124
@*/
125
PetscErrorCode PSCreate(MPI_Comm comm,PS *newps)
126
{
127
  PS             ps;
128
  PetscInt       i;
129
  PetscErrorCode ierr;
130
 
131
  PetscFunctionBegin;
132
  PetscValidPointer(newps,2);
133
  ierr = PetscHeaderCreate(ps,_p_PS,struct _PSOps,PS_CLASSID,-1,"PS","Projected System","PS",comm,PSDestroy,PSView);CHKERRQ(ierr);
2794 jroman 134
  *newps      = ps;
135
  ps->state   = PS_STATE_RAW;
136
  ps->method  = 0;
137
  ps->nmeth   = 1;
138
  ps->compact = PETSC_FALSE;
139
  ps->ld      = 0;
140
  ps->l       = 0;
141
  ps->n       = 0;
142
  ps->k       = 0;
2757 jroman 143
  for (i=0;i<PS_NUM_MAT;i++) {
2758 jroman 144
    ps->mat[i]  = PETSC_NULL;
2757 jroman 145
    ps->rmat[i] = PETSC_NULL;
146
  }
2770 jroman 147
  ps->work   = PETSC_NULL;
148
  ps->rwork  = PETSC_NULL;
149
  ps->iwork  = PETSC_NULL;
150
  ps->lwork  = 0;
151
  ps->lrwork = 0;
152
  ps->liwork = 0;
2757 jroman 153
  PetscFunctionReturn(0);
154
}
155
 
156
#undef __FUNCT__  
157
#define __FUNCT__ "PSSetOptionsPrefix"
158
/*@C
159
   PSSetOptionsPrefix - Sets the prefix used for searching for all
160
   PS options in the database.
161
 
162
   Logically Collective on PS
163
 
164
   Input Parameters:
165
+  ps - the projected system context
166
-  prefix - the prefix string to prepend to all PS option requests
167
 
168
   Notes:
169
   A hyphen (-) must NOT be given at the beginning of the prefix name.
170
   The first character of all runtime options is AUTOMATICALLY the
171
   hyphen.
172
 
173
   Level: advanced
174
 
175
.seealso: PSAppendOptionsPrefix()
176
@*/
177
PetscErrorCode PSSetOptionsPrefix(PS ps,const char *prefix)
178
{
179
  PetscErrorCode ierr;
180
 
181
  PetscFunctionBegin;
182
  PetscValidHeaderSpecific(ps,PS_CLASSID,1);
183
  ierr = PetscObjectSetOptionsPrefix((PetscObject)ps,prefix);CHKERRQ(ierr);
184
  PetscFunctionReturn(0);
185
}
186
 
187
#undef __FUNCT__  
188
#define __FUNCT__ "PSAppendOptionsPrefix"
189
/*@C
190
   PSAppendOptionsPrefix - Appends to the prefix used for searching for all
191
   PS options in the database.
192
 
193
   Logically Collective on PS
194
 
195
   Input Parameters:
196
+  ps - the projected system context
197
-  prefix - the prefix string to prepend to all PS option requests
198
 
199
   Notes:
200
   A hyphen (-) must NOT be given at the beginning of the prefix name.
201
   The first character of all runtime options is AUTOMATICALLY the hyphen.
202
 
203
   Level: advanced
204
 
205
.seealso: PSSetOptionsPrefix()
206
@*/
207
PetscErrorCode PSAppendOptionsPrefix(PS ps,const char *prefix)
208
{
209
  PetscErrorCode ierr;
210
 
211
  PetscFunctionBegin;
212
  PetscValidHeaderSpecific(ps,PS_CLASSID,1);
213
  ierr = PetscObjectAppendOptionsPrefix((PetscObject)ps,prefix);CHKERRQ(ierr);
214
  PetscFunctionReturn(0);
215
}
216
 
217
#undef __FUNCT__
218
#define __FUNCT__ "PSGetOptionsPrefix"
219
/*@C
220
   PSGetOptionsPrefix - Gets the prefix used for searching for all
221
   PS options in the database.
222
 
223
   Not Collective
224
 
225
   Input Parameters:
226
.  ps - the projected system context
227
 
228
   Output Parameters:
229
.  prefix - pointer to the prefix string used is returned
230
 
231
   Notes: On the fortran side, the user should pass in a string 'prefix' of
232
   sufficient length to hold the prefix.
233
 
234
   Level: advanced
235
 
236
.seealso: PSSetOptionsPrefix(), PSAppendOptionsPrefix()
237
@*/
238
PetscErrorCode PSGetOptionsPrefix(PS ps,const char *prefix[])
239
{
240
  PetscErrorCode ierr;
241
 
242
  PetscFunctionBegin;
243
  PetscValidHeaderSpecific(ps,PS_CLASSID,1);
244
  PetscValidPointer(prefix,2);
245
  ierr = PetscObjectGetOptionsPrefix((PetscObject)ps,prefix);CHKERRQ(ierr);
246
  PetscFunctionReturn(0);
247
}
248
 
249
#undef __FUNCT__  
250
#define __FUNCT__ "PSSetType"
251
/*@C
252
   PSSetType - Selects the type for the PS object.
253
 
254
   Logically Collective on PS
255
 
256
   Input Parameter:
2793 jroman 257
+  ps   - the projected system context
2757 jroman 258
-  type - a known type
259
 
260
   Level: advanced
261
 
262
.seealso: PSGetType()
263
@*/
264
PetscErrorCode PSSetType(PS ps,const PSType type)
265
{
266
  PetscErrorCode ierr,(*r)(PS);
267
  PetscBool      match;
268
 
269
  PetscFunctionBegin;
270
  PetscValidHeaderSpecific(ps,PS_CLASSID,1);
271
  PetscValidCharPointer(type,2);
272
 
273
  ierr = PetscTypeCompare((PetscObject)ps,type,&match);CHKERRQ(ierr);
274
  if (match) PetscFunctionReturn(0);
275
 
276
  ierr =  PetscFListFind(PSList,((PetscObject)ps)->comm,type,PETSC_TRUE,(void (**)(void))&r);CHKERRQ(ierr);
277
  if (!r) SETERRQ1(((PetscObject)ps)->comm,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested PS type %s",type);
278
 
279
  ierr = PetscMemzero(ps->ops,sizeof(struct _PSOps));CHKERRQ(ierr);
280
 
281
  ierr = PetscObjectChangeTypeName((PetscObject)ps,type);CHKERRQ(ierr);
282
  ierr = (*r)(ps);CHKERRQ(ierr);
283
  PetscFunctionReturn(0);
284
}
285
 
286
#undef __FUNCT__  
287
#define __FUNCT__ "PSGetType"
288
/*@C
289
   PSGetType - Gets the PS type name (as a string) from the PS context.
290
 
291
   Not Collective
292
 
293
   Input Parameter:
294
.  ps - the projected system context
295
 
296
   Output Parameter:
297
.  name - name of the projected system
298
 
299
   Level: advanced
300
 
301
.seealso: PSSetType()
302
@*/
303
PetscErrorCode PSGetType(PS ps,const PSType *type)
304
{
305
  PetscFunctionBegin;
306
  PetscValidHeaderSpecific(ps,PS_CLASSID,1);
307
  PetscValidPointer(type,2);
308
  *type = ((PetscObject)ps)->type_name;
309
  PetscFunctionReturn(0);
310
}
311
 
312
#undef __FUNCT__  
2793 jroman 313
#define __FUNCT__ "PSSetMethod"
2794 jroman 314
/*@
2793 jroman 315
   PSSetMethod - Selects the method to be used to solve the problem.
316
 
317
   Logically Collective on PS
318
 
319
   Input Parameter:
320
+  ps   - the projected system context
321
-  meth - an index indentifying the method
322
 
323
   Level: advanced
324
 
325
.seealso: PSGetMethod()
326
@*/
327
PetscErrorCode PSSetMethod(PS ps,PetscInt meth)
328
{
329
  PetscFunctionBegin;
330
  PetscValidHeaderSpecific(ps,PS_CLASSID,1);
331
  PetscValidLogicalCollectiveInt(ps,meth,2);
332
  if (meth<0) SETERRQ(((PetscObject)ps)->comm,PETSC_ERR_ARG_OUTOFRANGE,"The method must be a non-negative integer");
333
  ps->method = meth;
334
  PetscFunctionReturn(0);
335
}
336
 
337
#undef __FUNCT__  
338
#define __FUNCT__ "PSGetMethod"
2794 jroman 339
/*@
2793 jroman 340
   PSGetMethod - Gets the method currently used in the PS.
341
 
342
   Not Collective
343
 
344
   Input Parameter:
345
.  ps - the projected system context
346
 
347
   Output Parameter:
348
.  meth - identifier of the method
349
 
350
   Level: advanced
351
 
352
.seealso: PSSetMethod()
353
@*/
354
PetscErrorCode PSGetMethod(PS ps,PetscInt *meth)
355
{
356
  PetscFunctionBegin;
357
  PetscValidHeaderSpecific(ps,PS_CLASSID,1);
358
  PetscValidPointer(meth,2);
359
  *meth = ps->method;
360
  PetscFunctionReturn(0);
361
}
362
 
363
#undef __FUNCT__  
2794 jroman 364
#define __FUNCT__ "PSSetCompact"
365
/*@
366
   PSSetCompact - Switch to compact storage of matrices.
367
 
368
   Logically Collective on PS
369
 
370
   Input Parameter:
371
+  ps   - the projected system context
372
-  comp - a boolean flag
373
 
374
   Notes:
375
   Compact storage is used in some PS types such as PSHEP when the matrix
376
   is tridiagonal. This flag can be used to indicate whether the user
377
   provides the matrix entries via the compact form (the tridiagonal PS_MAT_T)
378
   or the non-compact one (PS_MAT_A).
379
 
380
   The default is PETSC_FALSE.
381
 
382
   Level: advanced
383
 
384
.seealso: PSGetCompact()
385
@*/
386
PetscErrorCode PSSetCompact(PS ps,PetscBool comp)
387
{
388
  PetscFunctionBegin;
389
  PetscValidHeaderSpecific(ps,PS_CLASSID,1);
390
  PetscValidLogicalCollectiveBool(ps,comp,2);
391
  ps->compact = comp;
392
  PetscFunctionReturn(0);
393
}
394
 
395
#undef __FUNCT__  
396
#define __FUNCT__ "PSGetCompact"
397
/*@
398
   PSGetCompact - Gets the compact storage flag.
399
 
400
   Not Collective
401
 
402
   Input Parameter:
403
.  ps - the projected system context
404
 
405
   Output Parameter:
406
.  comp - the flag
407
 
408
   Level: advanced
409
 
410
.seealso: PSSetCompact()
411
@*/
412
PetscErrorCode PSGetCompact(PS ps,PetscBool *comp)
413
{
414
  PetscFunctionBegin;
415
  PetscValidHeaderSpecific(ps,PS_CLASSID,1);
416
  PetscValidPointer(comp,2);
417
  *comp = ps->compact;
418
  PetscFunctionReturn(0);
419
}
420
 
421
#undef __FUNCT__  
2757 jroman 422
#define __FUNCT__ "PSSetFromOptions"
423
/*@
424
   PSSetFromOptions - Sets PS options from the options database.
425
 
426
   Collective on PS
427
 
428
   Input Parameters:
429
.  ps - the projected system context
430
 
431
   Notes:  
432
   To see all options, run your program with the -help option.
433
 
434
   Level: beginner
435
@*/
436
PetscErrorCode PSSetFromOptions(PS ps)
437
{
438
  PetscErrorCode ierr;
2795 jroman 439
  PetscInt       meth;
2757 jroman 440
 
441
  PetscFunctionBegin;
442
  PetscValidHeaderSpecific(ps,PS_CLASSID,1);
443
  if (!PSRegisterAllCalled) { ierr = PSRegisterAll(PETSC_NULL);CHKERRQ(ierr); }
444
  /* Set default type (we do not allow changing it with -ps_type) */
445
  if (!((PetscObject)ps)->type_name) {
2758 jroman 446
    ierr = PSSetType(ps,PSNHEP);CHKERRQ(ierr);
2757 jroman 447
  }
448
  ierr = PetscOptionsBegin(((PetscObject)ps)->comm,((PetscObject)ps)->prefix,"Projecte System (PS) Options","PS");CHKERRQ(ierr);
2795 jroman 449
    meth = 0;
450
    ierr = PetscOptionsInt("-ps_method","Method to be used for the projected system","PSSetMethod",ps->method,&meth,PETSC_NULL);CHKERRQ(ierr);
451
    ierr = PSSetMethod(ps,meth);CHKERRQ(ierr);
2757 jroman 452
    ierr = PetscObjectProcessOptionsHandlers((PetscObject)ps);CHKERRQ(ierr);
453
  ierr = PetscOptionsEnd();CHKERRQ(ierr);
454
  PetscFunctionReturn(0);
455
}
456
 
457
#undef __FUNCT__  
458
#define __FUNCT__ "PSView"
459
/*@C
460
   PSView - Prints the PS data structure.
461
 
462
   Collective on PS
463
 
464
   Input Parameters:
465
+  ps - the projected system context
466
-  viewer - optional visualization context
467
 
468
   Note:
469
   The available visualization contexts include
470
+     PETSC_VIEWER_STDOUT_SELF - standard output (default)
471
-     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
472
         output where only the first processor opens
473
         the file.  All other processors send their
474
         data to the first processor to print.
475
 
476
   The user can open an alternative visualization context with
477
   PetscViewerASCIIOpen() - output to a specified file.
478
 
479
   Level: beginner
480
 
481
.seealso: PetscViewerASCIIOpen()
482
@*/
483
PetscErrorCode PSView(PS ps,PetscViewer viewer)
484
{
2777 jroman 485
  PetscBool         isascii;
486
  const char        *state;
487
  PetscViewerFormat format;
488
  PetscErrorCode    ierr;
2757 jroman 489
 
490
  PetscFunctionBegin;
491
  PetscValidHeaderSpecific(ps,PS_CLASSID,1);
492
  if (!viewer) viewer = PETSC_VIEWER_STDOUT_(((PetscObject)ps)->comm);
493
  PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
494
  PetscCheckSameComm(ps,1,viewer,2);
495
  ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr);
496
  if (isascii) {
2777 jroman 497
    ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
2757 jroman 498
    ierr = PetscObjectPrintClassNamePrefixType((PetscObject)ps,viewer,"PS Object");CHKERRQ(ierr);
2777 jroman 499
    if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
500
      switch (ps->state) {
501
        case PS_STATE_RAW:          state = "raw"; break;
502
        case PS_STATE_INTERMEDIATE: state = "intermediate"; break;
503
        case PS_STATE_CONDENSED:    state = "condensed"; break;
504
        case PS_STATE_SORTED:       state = "sorted"; break;
505
        default: SETERRQ(((PetscObject)ps)->comm,1,"Wrong value of ps->state");
506
      }
507
      ierr = PetscViewerASCIIPrintf(viewer,"  current state: %s\n",state);CHKERRQ(ierr);
508
      ierr = PetscViewerASCIIPrintf(viewer,"  dimensions: ld=%d, n=%d, l=%d, k=%d\n",ps->ld,ps->n,ps->l,ps->k);CHKERRQ(ierr);
509
    }
510
    if (ps->ops->view) {
511
      ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
512
      ierr = (*ps->ops->view)(ps,viewer);CHKERRQ(ierr);
513
      ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
514
    }
2762 jroman 515
  } else SETERRQ1(((PetscObject)ps)->comm,1,"Viewer type %s not supported for PS",((PetscObject)viewer)->type_name);
2757 jroman 516
  PetscFunctionReturn(0);
517
}
518
 
519
#undef __FUNCT__  
2758 jroman 520
#define __FUNCT__ "PSAllocate"
521
/*@
522
   PSAllocate - Allocates memory for internal storage or matrices in PS.
523
 
524
   Collective on PS
525
 
526
   Input Parameters:
527
+  ps - the projected system context
528
-  ld - leading dimension (maximum allowed dimension for the matrices)
529
 
530
   Level: advanced
531
 
532
.seealso: PSGetLeadingDimension(), PSSetDimensions()
533
@*/
534
PetscErrorCode PSAllocate(PS ps,PetscInt ld)
535
{
536
  PetscErrorCode ierr;
537
 
538
  PetscFunctionBegin;
539
  PetscValidHeaderSpecific(ps,PS_CLASSID,1);
540
  PetscValidLogicalCollectiveInt(ps,ld,2);
541
  if (ld<1) SETERRQ(((PetscObject)ps)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Leading dimension should be at least one");
542
  ps->ld = ld;
543
  ierr = (*ps->ops->allocate)(ps,ld);CHKERRQ(ierr);
544
  PetscFunctionReturn(0);
545
}
546
 
547
#undef __FUNCT__  
548
#define __FUNCT__ "PSAllocateMat_Private"
549
PetscErrorCode PSAllocateMat_Private(PS ps,PSMatType m)
550
{
2764 jroman 551
  PetscInt       sz;
2758 jroman 552
  PetscErrorCode ierr;
553
 
554
  PetscFunctionBegin;
2775 jroman 555
  if (m==PS_MAT_T) sz = 3*ps->ld*sizeof(PetscScalar);
556
  else sz = ps->ld*ps->ld*sizeof(PetscScalar);
2770 jroman 557
  if (ps->mat[m]) { ierr = PetscFree(ps->mat[m]);CHKERRQ(ierr); }
558
  else { ierr = PetscLogObjectMemory(ps,sz);CHKERRQ(ierr); }
2758 jroman 559
  ierr = PetscMalloc(sz,&ps->mat[m]);CHKERRQ(ierr);
560
  ierr = PetscMemzero(ps->mat[m],sz);CHKERRQ(ierr);
561
  PetscFunctionReturn(0);
562
}
563
 
564
#undef __FUNCT__  
2775 jroman 565
#define __FUNCT__ "PSAllocateMatReal_Private"
566
PetscErrorCode PSAllocateMatReal_Private(PS ps,PSMatType m)
567
{
568
  PetscInt       sz;
569
  PetscErrorCode ierr;
570
 
571
  PetscFunctionBegin;
572
  if (m==PS_MAT_T) sz = 3*ps->ld*sizeof(PetscReal);
573
  else sz = ps->ld*ps->ld*sizeof(PetscReal);
574
  if (ps->rmat[m]) { ierr = PetscFree(ps->rmat[m]);CHKERRQ(ierr); }
575
  else { ierr = PetscLogObjectMemory(ps,sz);CHKERRQ(ierr); }
576
  ierr = PetscMalloc(sz,&ps->rmat[m]);CHKERRQ(ierr);
577
  ierr = PetscMemzero(ps->rmat[m],sz);CHKERRQ(ierr);
578
  PetscFunctionReturn(0);
579
}
580
 
581
#undef __FUNCT__  
2770 jroman 582
#define __FUNCT__ "PSAllocateWork_Private"
583
PetscErrorCode PSAllocateWork_Private(PS ps,PetscInt s,PetscInt r,PetscInt i)
584
{
585
  PetscErrorCode ierr;
586
 
587
  PetscFunctionBegin;
588
  if (s>ps->lwork) {
589
    ierr = PetscFree(ps->work);CHKERRQ(ierr);
590
    ierr = PetscMalloc(s*sizeof(PetscScalar),&ps->work);CHKERRQ(ierr);
591
    ierr = PetscLogObjectMemory(ps,(s-ps->lwork)*sizeof(PetscScalar));CHKERRQ(ierr);
592
    ps->lwork = s;
593
  }
594
  if (r>ps->lrwork) {
595
    ierr = PetscFree(ps->rwork);CHKERRQ(ierr);
596
    ierr = PetscMalloc(r*sizeof(PetscReal),&ps->rwork);CHKERRQ(ierr);
597
    ierr = PetscLogObjectMemory(ps,(r-ps->lrwork)*sizeof(PetscReal));CHKERRQ(ierr);
598
    ps->lrwork = r;
599
  }
600
  if (i>ps->liwork) {
601
    ierr = PetscFree(ps->iwork);CHKERRQ(ierr);
602
    ierr = PetscMalloc(i*sizeof(PetscBLASInt),&ps->iwork);CHKERRQ(ierr);
603
    ierr = PetscLogObjectMemory(ps,(i-ps->liwork)*sizeof(PetscBLASInt));CHKERRQ(ierr);
604
    ps->liwork = i;
605
  }
606
  PetscFunctionReturn(0);
607
}
608
 
609
#undef __FUNCT__  
2777 jroman 610
#define __FUNCT__ "PSViewMat_Private"
611
PetscErrorCode PSViewMat_Private(PS ps,PetscViewer viewer,PSMatType m)
612
{
2785 jroman 613
  PetscErrorCode    ierr;
614
  PetscInt          i,j;
615
  PetscScalar       *v;
2783 jroman 616
  PetscViewerFormat format;
2785 jroman 617
#if defined(PETSC_USE_COMPLEX)
618
  PetscBool         allreal = PETSC_TRUE;
619
#endif
2777 jroman 620
 
621
  PetscFunctionBegin;
2783 jroman 622
  ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
623
  if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) PetscFunctionReturn(0);
2785 jroman 624
  ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
625
#if defined(PETSC_USE_COMPLEX)
626
  /* determine if matrix has all real values */
627
  v = ps->mat[m];
628
  for (i=0;i<ps->n;i++)
629
    for (j=0;j<ps->n;j++)
630
      if (PetscImaginaryPart(v[i+j*ps->ld])) { allreal = PETSC_FALSE; break; }
631
#endif
632
  if (format == PETSC_VIEWER_ASCII_MATLAB) {
633
    ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D\n",ps->n,ps->n);CHKERRQ(ierr);
634
    ierr = PetscViewerASCIIPrintf(viewer,"%s = [\n",PSMatName[m]);CHKERRQ(ierr);
635
  } else {
636
    ierr = PetscViewerASCIIPrintf(viewer,"Matrix %s =\n",PSMatName[m]);CHKERRQ(ierr);
637
  }
638
 
639
  for (i=0;i<ps->n;i++) {
640
    v = ps->mat[m]+i;
641
    for (j=0;j<ps->n;j++) {
642
#if defined(PETSC_USE_COMPLEX)
643
      if (allreal) {
644
        ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",PetscRealPart(*v));CHKERRQ(ierr);
645
      } else {
646
        ierr = PetscViewerASCIIPrintf(viewer,"%18.16e + %18.16ei ",PetscRealPart(*v),PetscImaginaryPart(*v));CHKERRQ(ierr);
647
      }
648
#else
649
      ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",*v);CHKERRQ(ierr);
650
#endif
651
      v += ps->ld;
652
    }
653
    ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
654
  }
655
 
656
  if (format == PETSC_VIEWER_ASCII_MATLAB) {
657
    ierr = PetscViewerASCIIPrintf(viewer,"];\n");CHKERRQ(ierr);
658
  }
659
  ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
660
  ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
2777 jroman 661
  PetscFunctionReturn(0);
662
}
663
 
664
#undef __FUNCT__  
2780 jroman 665
#define __FUNCT__ "PSSortEigenvaluesReal_Private"
666
PetscErrorCode PSSortEigenvaluesReal_Private(PS ps,PetscInt n,PetscReal *eig,PetscInt *perm,PetscErrorCode (*comp_func)(PetscScalar,PetscScalar,PetscScalar,PetscScalar,PetscInt*,void*),void *comp_ctx)
667
{
668
  PetscErrorCode ierr;
669
  PetscScalar    re;
670
  PetscInt       i,j,result,tmp;
671
 
672
  PetscFunctionBegin;
673
  for (i=0;i<n;i++) perm[i] = i;
674
  /* insertion sort */
675
  for (i=1;i<n;i++) {
676
    re = eig[perm[i]];
677
    j = i-1;
678
    ierr = (*comp_func)(re,0.0,eig[perm[j]],0.0,&result,comp_ctx);CHKERRQ(ierr);
679
    while (result<=0 && j>=0) {
680
      tmp = perm[j]; perm[j] = perm[j+1]; perm[j+1] = tmp; j--;
681
      if (j>=0) {
682
        ierr = (*comp_func)(re,0.0,eig[perm[j]],0.0,&result,comp_ctx);CHKERRQ(ierr);
683
      }
684
    }
685
  }
686
  PetscFunctionReturn(0);
687
}
688
 
689
#undef __FUNCT__  
2792 jroman 690
#define __FUNCT__ "PSPermuteColumns_Private"
2791 jroman 691
PetscErrorCode PSPermuteColumns_Private(PS ps,PetscInt n,PSMatType m,PetscInt *perm)
692
{
693
  PetscInt    i,j,k,p,ld;
694
  PetscScalar *Q,rtmp;
695
 
696
  PetscFunctionBegin;
697
  ld = ps->ld;
698
  Q  = ps->mat[PS_MAT_Q];
699
  for (i=0;i<n;i++) {
700
    p = perm[i];
701
    if (p != i) {
702
      j = i + 1;
703
      while (perm[j] != i) j++;
704
      perm[j] = p; perm[i] = i;
705
      /* swap eigenvectors i and j */
706
      for (k=0;k<n;k++) {
707
        rtmp = Q[k+p*ld]; Q[k+p*ld] = Q[k+i*ld]; Q[k+i*ld] = rtmp;
708
      }
709
    }
710
  }
711
  PetscFunctionReturn(0);
712
}
713
 
714
#undef __FUNCT__  
2757 jroman 715
#define __FUNCT__ "PSReset"
2758 jroman 716
/*@
2757 jroman 717
   PSReset - Resets the PS context to the initial state.
718
 
719
   Collective on PS
720
 
721
   Input Parameter:
722
.  ps - the projected system context
723
 
724
   Level: advanced
725
 
726
.seealso: PSDestroy()
727
@*/
728
PetscErrorCode PSReset(PS ps)
729
{
730
  PetscInt       i;
731
  PetscErrorCode ierr;
732
 
733
  PetscFunctionBegin;
734
  PetscValidHeaderSpecific(ps,PS_CLASSID,1);
2794 jroman 735
  ps->state   = PS_STATE_RAW;
2796 jroman 736
  ps->method  = 0;
2794 jroman 737
  ps->compact = PETSC_FALSE;
738
  ps->ld      = 0;
739
  ps->l       = 0;
740
  ps->n       = 0;
741
  ps->k       = 0;
2757 jroman 742
  for (i=0;i<PS_NUM_MAT;i++) {
743
    ierr = PetscFree(ps->mat[i]);CHKERRQ(ierr);
744
    ierr = PetscFree(ps->rmat[i]);CHKERRQ(ierr);
745
  }
746
  ierr = PetscFree(ps->work);CHKERRQ(ierr);
747
  ierr = PetscFree(ps->rwork);CHKERRQ(ierr);
2766 jroman 748
  ierr = PetscFree(ps->iwork);CHKERRQ(ierr);
2770 jroman 749
  ps->lwork  = 0;
750
  ps->lrwork = 0;
751
  ps->liwork = 0;
2757 jroman 752
  PetscFunctionReturn(0);
753
}
754
 
755
#undef __FUNCT__  
756
#define __FUNCT__ "PSDestroy"
757
/*@C
758
   PSDestroy - Destroys PS context that was created with PSCreate().
759
 
760
   Collective on PS
761
 
762
   Input Parameter:
763
.  ps - the projected system context
764
 
765
   Level: beginner
766
 
767
.seealso: PSCreate()
768
@*/
769
PetscErrorCode PSDestroy(PS *ps)
770
{
771
  PetscErrorCode ierr;
772
 
773
  PetscFunctionBegin;
774
  if (!*ps) PetscFunctionReturn(0);
775
  PetscValidHeaderSpecific(*ps,PS_CLASSID,1);
776
  if (--((PetscObject)(*ps))->refct > 0) { *ps = 0; PetscFunctionReturn(0); }
777
  ierr = PSReset(*ps);CHKERRQ(ierr);
778
  ierr = PetscHeaderDestroy(ps);CHKERRQ(ierr);
779
  PetscFunctionReturn(0);
780
}
781
 
782
#undef __FUNCT__  
783
#define __FUNCT__ "PSRegister"
784
/*@C
785
   PSRegister - See PSRegisterDynamic()
786
 
787
   Level: advanced
788
@*/
789
PetscErrorCode PSRegister(const char *sname,const char *path,const char *name,PetscErrorCode (*function)(PS))
790
{
791
  PetscErrorCode ierr;
792
  char           fullname[PETSC_MAX_PATH_LEN];
793
 
794
  PetscFunctionBegin;
795
  ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
796
  ierr = PetscFListAdd(&PSList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
797
  PetscFunctionReturn(0);
798
}
799
 
800
#undef __FUNCT__  
801
#define __FUNCT__ "PSRegisterDestroy"
802
/*@
803
   PSRegisterDestroy - Frees the list of PS methods that were
804
   registered by PSRegisterDynamic().
805
 
806
   Not Collective
807
 
808
   Level: advanced
809
 
810
.seealso: PSRegisterDynamic(), PSRegisterAll()
811
@*/
812
PetscErrorCode PSRegisterDestroy(void)
813
{
814
  PetscErrorCode ierr;
815
 
816
  PetscFunctionBegin;
817
  ierr = PetscFListDestroy(&PSList);CHKERRQ(ierr);
818
  PSRegisterAllCalled = PETSC_FALSE;
819
  PetscFunctionReturn(0);
820
}
821
 
822
EXTERN_C_BEGIN
2783 jroman 823
extern PetscErrorCode PSCreate_HEP(PS);
2758 jroman 824
extern PetscErrorCode PSCreate_NHEP(PS);
2757 jroman 825
EXTERN_C_END
826
 
827
#undef __FUNCT__  
828
#define __FUNCT__ "PSRegisterAll"
829
/*@C
830
   PSRegisterAll - Registers all of the projected systems in the PS package.
831
 
832
   Not Collective
833
 
834
   Input Parameter:
835
.  path - the library where the routines are to be found (optional)
836
 
837
   Level: advanced
838
@*/
839
PetscErrorCode PSRegisterAll(const char *path)
840
{
841
  PetscErrorCode ierr;
842
 
843
  PetscFunctionBegin;
844
  PSRegisterAllCalled = PETSC_TRUE;
2783 jroman 845
  ierr = PSRegisterDynamic(PSHEP,path,"PSCreate_HEP",PSCreate_HEP);CHKERRQ(ierr);
2758 jroman 846
  ierr = PSRegisterDynamic(PSNHEP,path,"PSCreate_NHEP",PSCreate_NHEP);CHKERRQ(ierr);
2757 jroman 847
  PetscFunctionReturn(0);
848
}
849