Actual source code: gcreate.c

  1: #define PETSCMAT_DLL

 3:  #include private/matimpl.h
 4:  #include petscsys.h

  6: #if 0
  9: static PetscErrorCode MatPublish_Base(PetscObject obj)
 10: {
 12:   return(0);
 13: }
 14: #endif

 18: /*@
 19:    MatCreate - Creates a matrix where the type is determined
 20:    from either a call to MatSetType() or from the options database
 21:    with a call to MatSetFromOptions(). The default matrix type is
 22:    AIJ, using the routines MatCreateSeqAIJ() or MatCreateMPIAIJ()
 23:    if you do not set a type in the options database. If you never
 24:    call MatSetType() or MatSetFromOptions() it will generate an 
 25:    error when you try to use the matrix.

 27:    Collective on MPI_Comm

 29:    Input Parameter:
 30: .  comm - MPI communicator
 31:  
 32:    Output Parameter:
 33: .  A - the matrix

 35:    Options Database Keys:
 36: +    -mat_type seqaij   - AIJ type, uses MatCreateSeqAIJ()
 37: .    -mat_type mpiaij   - AIJ type, uses MatCreateMPIAIJ()
 38: .    -mat_type mpirowbs - rowbs type, uses MatCreateMPIRowbs()
 39: .    -mat_type seqdense - dense type, uses MatCreateSeqDense()
 40: .    -mat_type mpidense - dense type, uses MatCreateMPIDense()
 41: .    -mat_type seqbaij  - block AIJ type, uses MatCreateSeqBAIJ()
 42: -    -mat_type mpibaij  - block AIJ type, uses MatCreateMPIBAIJ()

 44:    Even More Options Database Keys:
 45:    See the manpages for particular formats (e.g., MatCreateSeqAIJ())
 46:    for additional format-specific options.

 48:    Notes:

 50:    Level: beginner

 52:    User manual sections:
 53: +   Section 3.1 Creating and Assembling Matrices
 54: -   Chapter 3 Matrices

 56: .keywords: matrix, create

 58: .seealso: MatCreateSeqAIJ(), MatCreateMPIAIJ(), 
 59:           MatCreateSeqDense(), MatCreateMPIDense(), 
 60:           MatCreateMPIRowbs(), MatCreateSeqBAIJ(), MatCreateMPIBAIJ(),
 61:           MatCreateSeqSBAIJ(), MatCreateMPISBAIJ(),
 62:           MatConvert()
 63: @*/
 64: PetscErrorCode  MatCreate(MPI_Comm comm,Mat *A)
 65: {
 66:   Mat            B;


 72:   *A = PETSC_NULL;
 73: #ifndef PETSC_USE_DYNAMIC_LIBRARIES
 74:   MatInitializePackage(PETSC_NULL);
 75: #endif

 77:   PetscHeaderCreate(B,_p_Mat,struct _MatOps,MAT_COOKIE,0,"Mat",comm,MatDestroy,MatView);
 78:   PetscNew(PetscMap,&B->rmap);
 79:   PetscNew(PetscMap,&B->cmap);
 80:   PetscMapInitialize(comm,B->rmap);
 81:   PetscMapInitialize(comm,B->cmap);
 82:   B->preallocated  = PETSC_FALSE;
 83:   *A               = B;
 84:   return(0);
 85: }

 89: /*@
 90:   MatSetSizes - Sets the local and global sizes, and checks to determine compatibility

 92:   Collective on Mat

 94:   Input Parameters:
 95: +  A - the matrix
 96: .  m - number of local rows (or PETSC_DECIDE)
 97: .  n - number of local columns (or PETSC_DECIDE)
 98: .  M - number of global rows (or PETSC_DETERMINE)
 99: -  N - number of global columns (or PETSC_DETERMINE)

101:    Notes:
102:    m (n) and M (N) cannot be both PETSC_DECIDE
103:    If one processor calls this with M (N) of PETSC_DECIDE then all processors must, otherwise the program will hang.

105:    If PETSC_DECIDE is not used for the arguments 'm' and 'n', then the
106:    user must ensure that they are chosen to be compatible with the
107:    vectors. To do this, one first considers the matrix-vector product 
108:    'y = A x'. The 'm' that is used in the above routine must match the 
109:    local size used in the vector creation routine VecCreateMPI() for 'y'.
110:    Likewise, the 'n' used must match that used as the local size in
111:    VecCreateMPI() for 'x'.

113:   Level: beginner

115: .seealso: MatGetSize(), PetscSplitOwnership()
116: @*/
117: PetscErrorCode  MatSetSizes(Mat A, PetscInt m, PetscInt n, PetscInt M, PetscInt N)
118: {

123:   if (M > 0 && m > M) SETERRQ2(PETSC_ERR_ARG_INCOMP,"Local column size %D cannot be larger than global column size %D",m,M);
124:   if (N > 0 && n > N) SETERRQ2(PETSC_ERR_ARG_INCOMP,"Local row size %D cannot be larger than global row size %D",n,N);
125:   if (A->ops->setsizes) {
126:     /* Since this will not be set until the type has been set, this will NOT be called on the initial
127:        call of MatSetSizes() (which must be called BEFORE MatSetType() */
128:     (*A->ops->setsizes)(A,m,n,M,N);
129:   } else {
130:     if ((A->rmap->n >= 0 || A->rmap->N >= 0) && (A->rmap->n != m || A->rmap->N != M)) SETERRQ4(PETSC_ERR_SUP,"Cannot change/reset row sizes to %D local %D global after previously setting them to %D local %D global",m,M,A->rmap->n,A->rmap->N);
131:     if ((A->cmap->n >= 0 || A->cmap->N >= 0) && (A->cmap->n != n || A->cmap->N != N)) SETERRQ4(PETSC_ERR_SUP,"Cannot change/reset column sizes to %D local %D global after previously setting them to %D local %D global",n,N,A->cmap->n,A->cmap->N);
132:   }
133:   A->rmap->n = m;
134:   A->cmap->n = n;
135:   A->rmap->N = M;
136:   A->cmap->N = N;
137:   if (A->ops->create) {
138:     (*A->ops->create)(A);
139:     A->ops->create = 0;
140:   }

142:   return(0);
143: }

147: /*@
148:    MatSetFromOptions - Creates a matrix where the type is determined
149:    from the options database. Generates a parallel MPI matrix if the
150:    communicator has more than one processor.  The default matrix type is
151:    AIJ, using the routines MatCreateSeqAIJ() and MatCreateMPIAIJ() if
152:    you do not select a type in the options database.

154:    Collective on Mat

156:    Input Parameter:
157: .  A - the matrix

159:    Options Database Keys:
160: +    -mat_type seqaij   - AIJ type, uses MatCreateSeqAIJ()
161: .    -mat_type mpiaij   - AIJ type, uses MatCreateMPIAIJ()
162: .    -mat_type mpirowbs - rowbs type, uses MatCreateMPIRowbs()
163: .    -mat_type seqdense - dense type, uses MatCreateSeqDense()
164: .    -mat_type mpidense - dense type, uses MatCreateMPIDense()
165: .    -mat_type seqbaij  - block AIJ type, uses MatCreateSeqBAIJ()
166: -    -mat_type mpibaij  - block AIJ type, uses MatCreateMPIBAIJ()

168:    Even More Options Database Keys:
169:    See the manpages for particular formats (e.g., MatCreateSeqAIJ())
170:    for additional format-specific options.

172:    Level: beginner

174: .keywords: matrix, create

176: .seealso: MatCreateSeqAIJ((), MatCreateMPIAIJ(), 
177:           MatCreateSeqDense(), MatCreateMPIDense(), 
178:           MatCreateMPIRowbs(), MatCreateSeqBAIJ(), MatCreateMPIBAIJ(),
179:           MatCreateSeqSBAIJ(), MatCreateMPISBAIJ(),
180:           MatConvert()
181: @*/
182: PetscErrorCode  MatSetFromOptions(Mat B)
183: {
185:   const char     *deft = MATAIJ;
186:   char           type[256];
187:   PetscTruth     flg;


192:   PetscOptionsBegin(((PetscObject)B)->comm,((PetscObject)B)->prefix,"Matrix options","Mat");
193:     PetscOptionsList("-mat_type","Matrix type","MatSetType",MatList,deft,type,256,&flg);
194:     if (flg) {
195:       MatSetType(B,type);
196:     } else if (!((PetscObject)B)->type_name) {
197:       MatSetType(B,deft);
198:     }

200:     if (B->ops->setfromoptions) {
201:       (*B->ops->setfromoptions)(B);
202:     }

204:   PetscOptionsEnd();

206:   return(0);
207: }

211: /*@
212:    MatSetUpPreallocation

214:    Collective on Mat

216:    Input Parameter:
217: .  A - the matrix

219:    Level: beginner

221: .keywords: matrix, create

223: .seealso: MatCreateSeqAIJ((), MatCreateMPIAIJ(), 
224:           MatCreateSeqDense(), MatCreateMPIDense(), 
225:           MatCreateMPIRowbs(), MatCreateSeqBAIJ(), MatCreateMPIBAIJ(),
226:           MatCreateSeqSBAIJ(), MatCreateMPISBAIJ(),
227:           MatConvert()
228: @*/
229: PetscErrorCode  MatSetUpPreallocation(Mat B)
230: {

234:   if (!B->preallocated && B->ops->setuppreallocation) {
235:     PetscInfo(B,"Warning not preallocating matrix storage\n");
236:     (*B->ops->setuppreallocation)(B);
237:   }
238:   B->preallocated = PETSC_TRUE;
239:   return(0);
240: }

242: /*
243:         Copies from Cs header to A

245:         This is somewhat different from MatHeaderReplace() it would be nice to merge the code
246: */
249: PetscErrorCode MatHeaderCopy(Mat A,Mat C)
250: {
252:   PetscInt       refct;
253:   PetscOps       *Abops;
254:   MatOps         Aops;
255:   char           *mtype,*mname;
256:   void           *spptr;

259:   /* save the parts of A we need */
260:   Abops = ((PetscObject)A)->bops;
261:   Aops  = A->ops;
262:   refct = ((PetscObject)A)->refct;
263:   mtype = ((PetscObject)A)->type_name;
264:   mname = ((PetscObject)A)->name;
265:   spptr = A->spptr;

267:   /* zero these so the destroy below does not free them */
268:   ((PetscObject)A)->type_name = 0;
269:   ((PetscObject)A)->name      = 0;

271:   /* free all the interior data structures from mat */
272:   (*A->ops->destroy)(A);

274:   PetscFree(C->spptr);

276:   PetscMapDestroy(A->rmap);
277:   PetscMapDestroy(A->cmap);
278:   PetscFListDestroy(&((PetscObject)A)->qlist);
279:   PetscOListDestroy(((PetscObject)A)->olist);

281:   /* copy C over to A */
282:   PetscMemcpy(A,C,sizeof(struct _p_Mat));

284:   /* return the parts of A we saved */
285:   ((PetscObject)A)->bops      = Abops;
286:   A->ops                      = Aops;
287:   ((PetscObject)A)->refct     = refct;
288:   ((PetscObject)A)->type_name = mtype;
289:   ((PetscObject)A)->name      = mname;
290:   A->spptr                    = spptr;

292:   /* since these two are copied into A we do not want them destroyed in C */
293:   ((PetscObject)C)->qlist = 0;
294:   ((PetscObject)C)->olist = 0;
295:   PetscHeaderDestroy(C);
296:   return(0);
297: }
298: /*
299:         Replace A's header with that of C
300:         This is essentially code moved from MatDestroy

302:         This is somewhat different from MatHeaderCopy() it would be nice to merge the code
303: */
306: PetscErrorCode MatHeaderReplace(Mat A,Mat C)
307: {

311:   if (A == C) return(0);

313:   /* free all the interior data structures from mat */
314:   (*A->ops->destroy)(A);
315:   PetscHeaderDestroy_Private((PetscObject)A);
316:   PetscFree(A->ops);
317:   PetscMapDestroy(A->rmap);
318:   PetscMapDestroy(A->cmap);
319:   PetscFree(A->spptr);
320: 
321:   /* copy C over to A */
322:   if (C) {
323:     PetscMemcpy(A,C,sizeof(struct _p_Mat));
324:     PetscLogObjectDestroy((PetscObject)C);
325:     PetscFree(C);
326:   }
327:   return(0);
328: }