Actual source code: matreg.c

petsc-3.3-p7 2013-05-11
  2: /*
  3:      Mechanism for register PETSc matrix types
  4: */
  5: #include <petsc-private/matimpl.h>      /*I "petscmat.h" I*/
  6: #include <stdarg.h> /* Variable-length arg lists. */

  8: PetscBool  MatRegisterAllCalled = PETSC_FALSE;

 10: /*
 11:    Contains the list of registered Mat routines
 12: */
 13: PetscFList MatList = 0;

 17: /*@C
 18:    MatSetType - Builds matrix object for a particular matrix type

 20:    Collective on Mat

 22:    Input Parameters:
 23: +  mat      - the matrix object
 24: -  matype   - matrix type

 26:    Options Database Key:
 27: .  -mat_type  <method> - Sets the type; use -help for a list 
 28:     of available methods (for instance, seqaij)

 30:    Notes:  
 31:    See "${PETSC_DIR}/include/petscmat.h" for available methods

 33:   Level: intermediate

 35: .keywords: Mat, MatType, set, method

 37: .seealso: PCSetType(), VecSetType(), MatCreate(), MatType, Mat
 38: @*/
 39: PetscErrorCode  MatSetType(Mat mat, const MatType matype)
 40: {
 41:   PetscErrorCode ierr,(*r)(Mat);
 42:   PetscBool      sametype,found;
 43:   MatBaseName    names = MatBaseNameList;


 48:   while (names) {
 49:     PetscStrcmp(matype,names->bname,&found);
 50:     if (found) {
 51:       PetscMPIInt size;
 52:       MPI_Comm_size(((PetscObject)mat)->comm,&size);
 53:       if (size == 1) matype = names->sname;
 54:       else matype = names->mname;
 55:       break;
 56:     }
 57:     names = names->next;
 58:   }

 60:   PetscObjectTypeCompare((PetscObject)mat,matype,&sametype);
 61:   if (sametype) return(0);

 63:    PetscFListFind(MatList,((PetscObject)mat)->comm,matype,PETSC_TRUE,(void(**)(void))&r);
 64:   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown Mat type given: %s",matype);
 65: 
 66:   /* free the old data structure if it existed */
 67:   if (mat->ops->destroy) {
 68:     (*mat->ops->destroy)(mat);
 69:     mat->ops->destroy = PETSC_NULL;
 70:   }
 71:   mat->preallocated = PETSC_FALSE;

 73:   /* create the new data structure */
 74:   (*r)(mat);
 75: #if defined(PETSC_HAVE_AMS)
 76:   if (PetscAMSPublishAll) {
 77:     /*    PetscObjectAMSPublish((PetscObject)mat); */
 78:   }
 79: #endif
 80:   return(0);
 81: }


 86: /*@C
 87:    MatRegisterDestroy - Frees the list of matrix types that were
 88:    registered by MatRegister()/MatRegisterDynamic().

 90:    Not Collective

 92:    Level: advanced

 94: .keywords: Mat, register, destroy

 96: .seealso: MatRegister(), MatRegisterAll(), MatRegisterDynamic()
 97: @*/
 98: PetscErrorCode  MatRegisterDestroy(void)
 99: {

103:   PetscFListDestroy(&MatList);
104:   MatRegisterAllCalled = PETSC_FALSE;
105:   return(0);
106: }

110: /*@C
111:    MatGetType - Gets the matrix type as a string from the matrix object.

113:    Not Collective

115:    Input Parameter:
116: .  mat - the matrix

118:    Output Parameter:
119: .  name - name of matrix type

121:    Level: intermediate

123: .keywords: Mat, MatType, get, method, name

125: .seealso: MatSetType()
126: @*/
127: PetscErrorCode  MatGetType(Mat mat,const MatType *type)
128: {
132:   *type = ((PetscObject)mat)->type_name;
133:   return(0);
134: }


139: /*@C
140:   MatRegister - See MatRegisterDynamic()

142:   Level: advanced
143: @*/
144: PetscErrorCode  MatRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(Mat))
145: {
147:   char           fullname[PETSC_MAX_PATH_LEN];

150:   PetscFListConcat(path,name,fullname);
151:   PetscFListAdd(&MatList,sname,fullname,(void (*)(void))function);
152:   return(0);
153: }

155: MatBaseName MatBaseNameList = 0;

159: /*@C
160:       MatRegisterBaseName - Registers a name that can be used for either a sequential or its corresponding parallel matrix type.

162:   Input Parameters:
163: +     bname - the basename, for example, MATAIJ
164: .     sname - the name of the sequential matrix type, for example, MATSEQAIJ
165: -     mname - the name of the parallel matrix type, for example, MATMPIAIJ


168:   Level: advanced
169: @*/
170: PetscErrorCode  MatRegisterBaseName(const char bname[],const char sname[],const char mname[])
171: {
173:   MatBaseName    names;

176:   PetscNew(struct _p_MatBaseName,&names);
177:   PetscStrallocpy(bname,&names->bname);
178:   PetscStrallocpy(sname,&names->sname);
179:   PetscStrallocpy(mname,&names->mname);
180:   if (!MatBaseNameList) {
181:     MatBaseNameList = names;
182:   } else {
183:     MatBaseName next = MatBaseNameList;
184:     while (next->next) next = next->next;
185:     next->next = names;
186:   }
187:   return(0);
188: }


191: /*
192:    Contains the list of Mat-related operations.
193: */
194: PetscOpFList MatOpList = 0;

198: /*@C
199:       MatRegisterOp - Registers a function via a pointer or a dynamic library url,
200:                       that implements a polymorphic operation that is dispatched
201:                       based on the op name and the declared arguments' type names.

203:   Formally collective on comm.

205:   Input Parameters:
206: +  comm     - processors adding the op
207: .  url      - routine locator  (optional, if not using dynamic libraries and a nonempty fnc)
208: .  function - function pointer (optional, if using dynamic libraries and a nonempty url)
209: .  op       - operation name
210: .  numArgs  - number of op arguments
211: -  ...      - list of argument type names (const char*)

213:   Level: advanced
214: @*/
215: PetscErrorCode  MatRegisterOp(MPI_Comm comm, const char url[], PetscVoidFunction function, const char op[], PetscInt numArgs, ...) {
217:   va_list ap;
218:   PetscInt i;
219:   const char *argType;
220:   char **argTypes = PETSC_NULL;
222:   va_start(ap,numArgs);
223:   if(numArgs) {
224:     PetscMalloc(sizeof(char*)*numArgs, &argTypes);
225:   }
226:   for(i = 0; i < numArgs; ++i) {
227:     argType = va_arg(ap,const char*);
228:     PetscStrallocpy(argType, argTypes+i);
229:   }
230:   va_end(ap);
231:   PetscOpFListAdd(comm, &MatOpList, url, function, op, numArgs, argTypes);
232:   for(i = 0; i < numArgs; ++i) {
233:     PetscFree(argTypes[i]);
234:   }
235:   PetscFree(argTypes);
236:   return(0);
237: }

241: /*@C
242:       MatQueryOp - Finds the function that implements a polymorphic operation that is dispatched
243:                    based on the op name and the declared arguments' type names.

245:   Formally collective on comm.

247:   Input Parameters:
248: +  comm     - processors adding the op
249: .  op       - operation name
250: .  numArgs  - number of op arguments
251: -  ...      - list of argument type names (const char*)

253:   Output Parameters:
254: .  function -- function pointer

256:   Level: advanced
257: @*/
258: PetscErrorCode  MatQueryOp(MPI_Comm comm, PetscVoidFunction* function, const char op[], PetscInt numArgs, ...) {
260:   va_list ap;
261:   PetscInt i;
262:   const char *argType;
263:   char **argTypes = PETSC_NULL;
265:   va_start(ap,numArgs);
266:   if(numArgs) {
267:     PetscMalloc(sizeof(char*)*numArgs, &argTypes);
268:   }
269:   for(i = 0; i < numArgs; ++i) {
270:     argType = va_arg(ap,const char*);
271:     PetscStrallocpy(argType, argTypes+i);
272:   }
273:   va_end(ap);
274:   PetscOpFListFind(comm, MatOpList, function, op, numArgs, argTypes);
275:   for(i = 0; i < numArgs; ++i) {
276:     PetscFree(argTypes[i]);
277:   }
278:   PetscFree(argTypes);
279:   return(0);
280: }