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: }