Actual source code: ipbasic.c

  1: /*
  2:      Basic routines

  4:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  5:       SLEPc - Scalable Library for Eigenvalue Problem Computations
  6:       Copyright (c) 2002-2007, Universidad Politecnica de Valencia, Spain

  8:       This file is part of SLEPc. See the README file for conditions of use
  9:       and additional information.
 10:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 11: */

 13: #include "src/ip/ipimpl.h"      /*I "slepcip.h" I*/

 15: PetscCookie IP_COOKIE = 0;
 16: PetscEvent IP_InnerProduct = 0, IP_Orthogonalize = 0, IP_ApplyMatrix = 0;

 20: /*@C
 21:   IPInitializePackage - This function initializes everything in the IP package. It is called
 22:   from PetscDLLibraryRegister() when using dynamic libraries, and on the first call to IPCreate()
 23:   when using static libraries.

 25:   Input Parameter:
 26:   path - The dynamic library path, or PETSC_NULL

 28:   Level: developer

 30: .seealso: SlepcInitialize()
 31: @*/
 32: PetscErrorCode IPInitializePackage(char *path)
 33: {
 34:   static PetscTruth initialized = PETSC_FALSE;
 35:   char              logList[256];
 36:   char              *className;
 37:   PetscTruth        opt;
 38:   PetscErrorCode    ierr;

 41:   if (initialized) return(0);
 42:   initialized = PETSC_TRUE;
 43:   /* Register Classes */
 44:   PetscLogClassRegister(&IP_COOKIE,"Inner product");
 45:   /* Register Events */
 46:   PetscLogEventRegister(&IP_Orthogonalize,"IPOrthogonalize",IP_COOKIE);
 47:   PetscLogEventRegister(&IP_InnerProduct,"IPInnerProduct",IP_COOKIE);
 48:   PetscLogEventRegister(&IP_ApplyMatrix,"IPApplyMatrix",IP_COOKIE);
 49:   /* Process info exclusions */
 50:   PetscOptionsGetString(PETSC_NULL, "-log_info_exclude", logList, 256, &opt);
 51:   if (opt) {
 52:     PetscStrstr(logList, "ip", &className);
 53:     if (className) {
 54:       PetscInfoDeactivateClass(IP_COOKIE);
 55:     }
 56:   }
 57:   /* Process summary exclusions */
 58:   PetscOptionsGetString(PETSC_NULL, "-log_summary_exclude", logList, 256, &opt);
 59:   if (opt) {
 60:     PetscStrstr(logList, "ip", &className);
 61:     if (className) {
 62:       PetscLogEventDeactivateClass(IP_COOKIE);
 63:     }
 64:   }
 65:   return(0);
 66: }

 70: static PetscErrorCode IPPublish_Petsc(PetscObject object)
 71: {
 73:   return(0);
 74: }

 78: /*@C
 79:    IPCreate - Creates an IP context.

 81:    Collective on MPI_Comm

 83:    Input Parameter:
 84: .  comm - MPI communicator

 86:    Output Parameter:
 87: .  newip - location to put the IP context

 89:    Level: beginner

 91:    Note: 
 92:    IP objects are not intended for normal users but only for
 93:    advanced user that for instance implement their own solvers.

 95: .seealso: IPDestroy(), IP
 96: @*/
 97: PetscErrorCode IPCreate(MPI_Comm comm,IP *newip)
 98: {
100:   IP ip;

104:   PetscHeaderCreate(ip,_p_IP,struct _IPOps,IP_COOKIE,-1,"IP",comm,IPDestroy,IPView);
105:   *newip            = ip;
106:   ip->orthog_type   = IP_CGS_ORTH;
107:   ip->orthog_ref    = IP_ORTH_REFINE_IFNEEDED;
108:   ip->orthog_eta    = 0.7071;
109:   ip->bilinear_form = IPINNER_HERMITIAN;
110:   ip->innerproducts = 0;
111:   ip->matrix        = PETSC_NULL;
112:   ip->Bx            = PETSC_NULL;
113:   ip->xid           = 0;
114:   ip->xstate        = 0;

116:   ip->bops->publish = IPPublish_Petsc;
117:   PetscPublishAll(ip);
118:   return(0);
119: }

123: /*@C
124:    IPSetOptionsPrefix - Sets the prefix used for searching for all 
125:    IP options in the database.

127:    Collective on IP

129:    Input Parameters:
130: +  ip - the innerproduct context
131: -  prefix - the prefix string to prepend to all IP option requests

133:    Notes:
134:    A hyphen (-) must NOT be given at the beginning of the prefix name.
135:    The first character of all runtime options is AUTOMATICALLY the
136:    hyphen.

138:    Level: advanced

140: .seealso: IPAppendOptionsPrefix()
141: @*/
142: PetscErrorCode IPSetOptionsPrefix(IP ip,const char *prefix)
143: {
147:   PetscObjectSetOptionsPrefix((PetscObject)ip,prefix);
148:   return(0);
149: }

153: /*@C
154:    IPAppendOptionsPrefix - Appends to the prefix used for searching for all 
155:    IP options in the database.

157:    Collective on IP

159:    Input Parameters:
160: +  ip - the innerproduct context
161: -  prefix - the prefix string to prepend to all IP option requests

163:    Notes:
164:    A hyphen (-) must NOT be given at the beginning of the prefix name.
165:    The first character of all runtime options is AUTOMATICALLY the hyphen.

167:    Level: advanced

169: .seealso: IPSetOptionsPrefix()
170: @*/
171: PetscErrorCode IPAppendOptionsPrefix(IP ip,const char *prefix)
172: {
176:   PetscObjectAppendOptionsPrefix((PetscObject)ip,prefix);
177:   return(0);
178: }

182: /*@
183:    IPSetFromOptions - Sets IP options from the options database.

185:    Collective on IP

187:    Input Parameters:
188: .  ip - the innerproduct context

190:    Notes:  
191:    To see all options, run your program with the -help option.

193:    Level: beginner

195: .seealso: 
196: @*/
197: PetscErrorCode IPSetFromOptions(IP ip)
198: {
200:   const char     *orth_list[3] = { "mgs" , "cgs", "ncgs" };
201:   const char     *ref_list[3] = { "never" , "ifneeded", "always" };
202:   PetscReal      r;
203:   PetscInt       i,j;

207:   PetscOptionsBegin(ip->comm,ip->prefix,"Inner Product (IP) Options","IP");
208:   i = ip->orthog_type;
209:   PetscOptionsEList("-orthog_type","Orthogonalization method","IPSetOrthogonalization",orth_list,3,orth_list[i],&i,PETSC_NULL);
210:   j = ip->orthog_ref;
211:   PetscOptionsEList("-orthog_refinement","Iterative refinement mode during orthogonalization","IPSetOrthogonalization",ref_list,3,ref_list[j],&j,PETSC_NULL);
212:   r = ip->orthog_eta;
213:   PetscOptionsReal("-orthog_eta","Parameter of iterative refinement during orthogonalization","IPSetOrthogonalization",r,&r,PETSC_NULL);
214:   IPSetOrthogonalization(ip,(IPOrthogonalizationType)i,(IPOrthogonalizationRefinementType)j,r);
215:   PetscOptionsEnd();
216:   return(0);
217: }

221: /*@
222:    IPSetOrthogonalization - Specifies the type of orthogonalization technique
223:    to be used (classical or modified Gram-Schmidt with or without refinement).

225:    Collective on IP

227:    Input Parameters:
228: +  ip         - the innerproduct context
229: .  type       - the type of orthogonalization technique
230: .  refinement - type of refinement
231: -  eta        - parameter for selective refinement

233:    Options Database Keys:
234: +  -orthog_type <type> -  Where <type> is cgs for Classical Gram-Schmidt
235:                               orthogonalization (default)
236:                               or mgs for Modified Gram-Schmidt orthogonalization
237: .  -orthog_refinement <type> -  Where <type> is one of never, ifneeded
238:                               (default) or always 
239: -  -orthog_eta <eta> -  For setting the value of eta
240:     
241:    Notes:  
242:    The default settings work well for most problems. 

244:    The parameter eta should be a real value between 0 and 1 (or PETSC_DEFAULT).
245:    The value of eta is used only when the refinement type is "ifneeded". 

247:    When using several processors, MGS is likely to result in bad scalability.

249:    Level: advanced

251: .seealso: IPOrthogonalize(), IPGetOrthogonalization(), IPOrthogonalizationType,
252:           IPOrthogonalizationRefinementType
253: @*/
254: PetscErrorCode IPSetOrthogonalization(IP ip,IPOrthogonalizationType type, IPOrthogonalizationRefinementType refinement, PetscReal eta)
255: {
258:   switch (type) {
259:     case IP_CGS_ORTH:
260:     case IP_MGS_ORTH:
261:       ip->orthog_type = type;
262:       break;
263:     default:
264:       SETERRQ(PETSC_ERR_ARG_WRONG,"Unknown orthogonalization type");
265:   }
266:   switch (refinement) {
267:     case IP_ORTH_REFINE_NEVER:
268:     case IP_ORTH_REFINE_IFNEEDED:
269:     case IP_ORTH_REFINE_ALWAYS:
270:       ip->orthog_ref = refinement;
271:       break;
272:     default:
273:       SETERRQ(PETSC_ERR_ARG_WRONG,"Unknown refinement type");
274:   }
275:   if (eta == PETSC_DEFAULT) {
276:     ip->orthog_eta = 0.7071;
277:   } else {
278:     if (eta <= 0.0 || eta > 1.0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Invalid eta value");
279:     ip->orthog_eta = eta;
280:   }
281:   return(0);
282: }

286: /*@C
287:    IPGetOrthogonalization - Gets the orthogonalization settings from the 
288:    IP object.

290:    Not Collective

292:    Input Parameter:
293: .  ip - inner product context 

295:    Output Parameter:
296: +  type       - type of orthogonalization technique
297: .  refinement - type of refinement
298: -  eta        - parameter for selective refinement

300:    Level: advanced

302: .seealso: IPOrthogonalize(), IPSetOrthogonalization(), IPOrthogonalizationType,
303:           IPOrthogonalizationRefinementType
304: @*/
305: PetscErrorCode IPGetOrthogonalization(IP ip,IPOrthogonalizationType *type,IPOrthogonalizationRefinementType *refinement, PetscReal *eta)
306: {
309:   if (type) *type = ip->orthog_type;
310:   if (refinement) *refinement = ip->orthog_ref;
311:   if (eta) *eta = ip->orthog_eta;
312:   return(0);
313: }

317: /*@C
318:    IPView - Prints the IP data structure.

320:    Collective on IP

322:    Input Parameters:
323: +  ip - the innerproduct context
324: -  viewer - optional visualization context

326:    Note:
327:    The available visualization contexts include
328: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
329: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
330:          output where only the first processor opens
331:          the file.  All other processors send their 
332:          data to the first processor to print. 

334:    The user can open an alternative visualization context with
335:    PetscViewerASCIIOpen() - output to a specified file.

337:    Level: beginner

339: .seealso: IPView(), EPSView(), SVDView(), PetscViewerASCIIOpen()
340: @*/
341: PetscErrorCode IPView(IP ip,PetscViewer viewer)
342: {
344:   PetscTruth     isascii;

348:   if (!viewer) viewer = PETSC_VIEWER_STDOUT_(ip->comm);

352:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
353:   if (isascii) {
354:     PetscViewerASCIIPrintf(viewer,"IP Object:\n");
355:     PetscViewerASCIIPrintf(viewer,"  orthogonalization method: ");
356:     switch (ip->orthog_type) {
357:       case IP_MGS_ORTH:
358:         PetscViewerASCIIPrintf(viewer,"modified Gram-Schmidt\n");
359:         break;
360:       case IP_CGS_ORTH:
361:         PetscViewerASCIIPrintf(viewer,"classical Gram-Schmidt\n");
362:         break;
363:       default: SETERRQ(1,"Wrong value of ip->orth_type");
364:     }
365:     PetscViewerASCIIPrintf(viewer,"  orthogonalization refinement: ");
366:     switch (ip->orthog_ref) {
367:       case IP_ORTH_REFINE_NEVER:
368:         PetscViewerASCIIPrintf(viewer,"never\n");
369:         break;
370:       case IP_ORTH_REFINE_IFNEEDED:
371:         PetscViewerASCIIPrintf(viewer,"if needed (eta: %f)\n",ip->orthog_eta);
372:         break;
373:       case IP_ORTH_REFINE_ALWAYS:
374:         PetscViewerASCIIPrintf(viewer,"always\n");
375:         break;
376:       default: SETERRQ(1,"Wrong value of ip->orth_ref");
377:     }
378:   } else {
379:     SETERRQ1(1,"Viewer type %s not supported for IP",((PetscObject)viewer)->type_name);
380:   }
381:   return(0);
382: }

386: /*@
387:    IPDestroy - Destroys IP context that was created with IPCreate().

389:    Collective on IP

391:    Input Parameter:
392: .  ip - the inner product context

394:    Level: beginner

396: .seealso: IPCreate()
397: @*/
398: PetscErrorCode IPDestroy(IP ip)
399: {

404:   if (ip->matrix) { MatDestroy(ip->matrix); }
405:   if (ip->Bx) { VecDestroy(ip->Bx); }
406:   if (--ip->refct <= 0) PetscHeaderDestroy(ip);
407:   return(0);
408: }

412: /*@
413:    IPGetOperationCounters - Gets the total number of inner product operations 
414:    made by the IP object.

416:    Not Collective

418:    Input Parameter:
419: .  ip - the inner product context

421:    Output Parameter:
422: .  dots - number of inner product operations
423:    
424:    Level: intermediate

426: .seealso: IPResetOperationCounters()
427: @*/
428: PetscErrorCode IPGetOperationCounters(IP ip,int *dots)
429: {
433:   *dots = ip->innerproducts;
434:   return(0);
435: }

439: /*@
440:    IPResetOperationCounters - Resets the counters for inner product operations 
441:    made by of the IP object.

443:    Collective on IP

445:    Input Parameter:
446: .  ip - the inner product context

448:    Level: intermediate

450: .seealso: IPGetOperationCounters()
451: @*/
452: PetscErrorCode IPResetOperationCounters(IP ip)
453: {
456:   ip->innerproducts = 0;
457:   return(0);
458: }