Subversion Repositories slepc-dev

Rev

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