xref: /petsc/src/mat/utils/gcreate.c (revision 98385da56458b548b19cfbbbe20373b1882cb46a)
1 #define PETSCMAT_DLL
2 
3 #include "private/matimpl.h"       /*I "petscmat.h"  I*/
4 
5 #if 0
6 #undef __FUNCT__
7 #define __FUNCT__ "MatPublish_Base"
8 static PetscErrorCode MatPublish_Base(PetscObject obj)
9 {
10   PetscFunctionBegin;
11   PetscFunctionReturn(0);
12 }
13 #endif
14 
15 #undef __FUNCT__
16 #define __FUNCT__ "MatCreate"
17 /*@
18    MatCreate - Creates a matrix where the type is determined
19    from either a call to MatSetType() or from the options database
20    with a call to MatSetFromOptions(). The default matrix type is
21    AIJ, using the routines MatCreateSeqAIJ() or MatCreateMPIAIJ()
22    if you do not set a type in the options database. If you never
23    call MatSetType() or MatSetFromOptions() it will generate an
24    error when you try to use the matrix.
25 
26    Collective on MPI_Comm
27 
28    Input Parameter:
29 .  comm - MPI communicator
30 
31    Output Parameter:
32 .  A - the matrix
33 
34    Options Database Keys:
35 +    -mat_type seqaij   - AIJ type, uses MatCreateSeqAIJ()
36 .    -mat_type mpiaij   - AIJ type, uses MatCreateMPIAIJ()
37 .    -mat_type seqdense - dense type, uses MatCreateSeqDense()
38 .    -mat_type mpidense - dense type, uses MatCreateMPIDense()
39 .    -mat_type seqbaij  - block AIJ type, uses MatCreateSeqBAIJ()
40 -    -mat_type mpibaij  - block AIJ type, uses MatCreateMPIBAIJ()
41 
42    Even More Options Database Keys:
43    See the manpages for particular formats (e.g., MatCreateSeqAIJ())
44    for additional format-specific options.
45 
46    Notes:
47 
48    Level: beginner
49 
50    User manual sections:
51 +   sec_matcreate
52 -   chapter_matrices
53 
54 .keywords: matrix, create
55 
56 .seealso: MatCreateSeqAIJ(), MatCreateMPIAIJ(),
57           MatCreateSeqDense(), MatCreateMPIDense(),
58           MatCreateSeqBAIJ(), MatCreateMPIBAIJ(),
59           MatCreateSeqSBAIJ(), MatCreateMPISBAIJ(),
60           MatConvert()
61 @*/
62 PetscErrorCode PETSCMAT_DLLEXPORT MatCreate(MPI_Comm comm,Mat *A)
63 {
64   Mat            B;
65   PetscErrorCode ierr;
66 
67   PetscFunctionBegin;
68   PetscValidPointer(A,2);
69 
70   *A = PETSC_NULL;
71 #ifndef PETSC_USE_DYNAMIC_LIBRARIES
72   ierr = MatInitializePackage(PETSC_NULL);CHKERRQ(ierr);
73 #endif
74 
75   ierr = PetscHeaderCreate(B,_p_Mat,struct _MatOps,MAT_CLASSID,0,"Mat",comm,MatDestroy,MatView);CHKERRQ(ierr);
76   ierr = PetscLayoutCreate(comm,&B->rmap);CHKERRQ(ierr);
77   ierr = PetscLayoutCreate(comm,&B->cmap);CHKERRQ(ierr);
78   B->preallocated  = PETSC_FALSE;
79   *A               = B;
80   PetscFunctionReturn(0);
81 }
82 
83 #undef __FUNCT__
84 #define __FUNCT__ "MatSetSizes"
85 /*@
86   MatSetSizes - Sets the local and global sizes, and checks to determine compatibility
87 
88   Collective on Mat
89 
90   Input Parameters:
91 +  A - the matrix
92 .  m - number of local rows (or PETSC_DECIDE)
93 .  n - number of local columns (or PETSC_DECIDE)
94 .  M - number of global rows (or PETSC_DETERMINE)
95 -  N - number of global columns (or PETSC_DETERMINE)
96 
97    Notes:
98    m (n) and M (N) cannot be both PETSC_DECIDE
99    If one processor calls this with M (N) of PETSC_DECIDE then all processors must, otherwise the program will hang.
100 
101    If PETSC_DECIDE is not used for the arguments 'm' and 'n', then the
102    user must ensure that they are chosen to be compatible with the
103    vectors. To do this, one first considers the matrix-vector product
104    'y = A x'. The 'm' that is used in the above routine must match the
105    local size used in the vector creation routine VecCreateMPI() for 'y'.
106    Likewise, the 'n' used must match that used as the local size in
107    VecCreateMPI() for 'x'.
108 
109   Level: beginner
110 
111 .seealso: MatGetSize(), PetscSplitOwnership()
112 @*/
113 PetscErrorCode PETSCMAT_DLLEXPORT MatSetSizes(Mat A, PetscInt m, PetscInt n, PetscInt M, PetscInt N)
114 {
115   PetscErrorCode ierr;
116 
117   PetscFunctionBegin;
118   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
119   if (M > 0 && m > M) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local column size %D cannot be larger than global column size %D",m,M);
120   if (N > 0 && n > N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local row size %D cannot be larger than global row size %D",n,N);
121   if (A->ops->setsizes) {
122     /* Since this will not be set until the type has been set, this will NOT be called on the initial
123        call of MatSetSizes() (which must be called BEFORE MatSetType() */
124     ierr = (*A->ops->setsizes)(A,m,n,M,N);CHKERRQ(ierr);
125   } else {
126     if ((A->rmap->n >= 0 || A->rmap->N >= 0) && (A->rmap->n != m || A->rmap->N != M)) SETERRQ4(PETSC_COMM_SELF,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);
127     if ((A->cmap->n >= 0 || A->cmap->N >= 0) && (A->cmap->n != n || A->cmap->N != N)) SETERRQ4(PETSC_COMM_SELF,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);
128   }
129   A->rmap->n = m;
130   A->cmap->n = n;
131   A->rmap->N = M;
132   A->cmap->N = N;
133 
134   PetscFunctionReturn(0);
135 }
136 
137 #undef __FUNCT__
138 #define __FUNCT__ "MatSetFromOptions"
139 /*@
140    MatSetFromOptions - Creates a matrix where the type is determined
141    from the options database. Generates a parallel MPI matrix if the
142    communicator has more than one processor.  The default matrix type is
143    AIJ, using the routines MatCreateSeqAIJ() and MatCreateMPIAIJ() if
144    you do not select a type in the options database.
145 
146    Collective on Mat
147 
148    Input Parameter:
149 .  A - the matrix
150 
151    Options Database Keys:
152 +    -mat_type seqaij   - AIJ type, uses MatCreateSeqAIJ()
153 .    -mat_type mpiaij   - AIJ type, uses MatCreateMPIAIJ()
154 .    -mat_type seqdense - dense type, uses MatCreateSeqDense()
155 .    -mat_type mpidense - dense type, uses MatCreateMPIDense()
156 .    -mat_type seqbaij  - block AIJ type, uses MatCreateSeqBAIJ()
157 -    -mat_type mpibaij  - block AIJ type, uses MatCreateMPIBAIJ()
158 
159    Even More Options Database Keys:
160    See the manpages for particular formats (e.g., MatCreateSeqAIJ())
161    for additional format-specific options.
162 
163    Level: beginner
164 
165 .keywords: matrix, create
166 
167 .seealso: MatCreateSeqAIJ((), MatCreateMPIAIJ(),
168           MatCreateSeqDense(), MatCreateMPIDense(),
169           MatCreateSeqBAIJ(), MatCreateMPIBAIJ(),
170           MatCreateSeqSBAIJ(), MatCreateMPISBAIJ(),
171           MatConvert()
172 @*/
173 PetscErrorCode PETSCMAT_DLLEXPORT MatSetFromOptions(Mat B)
174 {
175   PetscErrorCode ierr;
176   const char     *deft = MATAIJ;
177   char           type[256];
178   PetscTruth     flg;
179 
180   PetscFunctionBegin;
181   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
182 
183   ierr = PetscOptionsBegin(((PetscObject)B)->comm,((PetscObject)B)->prefix,"Matrix options","Mat");CHKERRQ(ierr);
184     ierr = PetscOptionsList("-mat_type","Matrix type","MatSetType",MatList,deft,type,256,&flg);CHKERRQ(ierr);
185     if (flg) {
186       ierr = MatSetType(B,type);CHKERRQ(ierr);
187     } else if (!((PetscObject)B)->type_name) {
188       ierr = MatSetType(B,deft);CHKERRQ(ierr);
189     }
190 
191     if (B->ops->setfromoptions) {
192       ierr = (*B->ops->setfromoptions)(B);CHKERRQ(ierr);
193     }
194 
195   ierr = PetscOptionsEnd();CHKERRQ(ierr);
196 
197   PetscFunctionReturn(0);
198 }
199 
200 #undef __FUNCT__
201 #define __FUNCT__ "MatSetUpPreallocation"
202 /*@
203    MatSetUpPreallocation
204 
205    Collective on Mat
206 
207    Input Parameter:
208 .  A - the matrix
209 
210    Level: beginner
211 
212 .keywords: matrix, create
213 
214 .seealso: MatCreateSeqAIJ((), MatCreateMPIAIJ(),
215           MatCreateSeqDense(), MatCreateMPIDense(),
216           MatCreateSeqBAIJ(), MatCreateMPIBAIJ(),
217           MatCreateSeqSBAIJ(), MatCreateMPISBAIJ(),
218           MatConvert()
219 @*/
220 PetscErrorCode PETSCMAT_DLLEXPORT MatSetUpPreallocation(Mat B)
221 {
222   PetscErrorCode ierr;
223 
224   PetscFunctionBegin;
225   if (!B->preallocated && B->ops->setuppreallocation) {
226     ierr = PetscInfo(B,"Warning not preallocating matrix storage\n");CHKERRQ(ierr);
227     ierr = (*B->ops->setuppreallocation)(B);CHKERRQ(ierr);
228   }
229   B->preallocated = PETSC_TRUE;
230   PetscFunctionReturn(0);
231 }
232 
233 /*
234         Copies from Cs header to A
235 
236         This is somewhat different from MatHeaderReplace() it would be nice to merge the code
237 */
238 #undef __FUNCT__
239 #define __FUNCT__ "MatHeaderCopy"
240 PetscErrorCode MatHeaderCopy(Mat A,Mat C)
241 {
242   PetscErrorCode ierr;
243   PetscInt       refct;
244   PetscOps       *Abops;
245   MatOps         Aops;
246   char           *mtype,*mname;
247   void           *spptr;
248 
249   PetscFunctionBegin;
250   /* save the parts of A we need */
251   Abops = ((PetscObject)A)->bops;
252   Aops  = A->ops;
253   refct = ((PetscObject)A)->refct;
254   mtype = ((PetscObject)A)->type_name;
255   mname = ((PetscObject)A)->name;
256   spptr = A->spptr;
257 
258   /* zero these so the destroy below does not free them */
259   ((PetscObject)A)->type_name = 0;
260   ((PetscObject)A)->name      = 0;
261 
262   /* free all the interior data structures from mat */
263   ierr = (*A->ops->destroy)(A);CHKERRQ(ierr);
264 
265   ierr = PetscFree(C->spptr);CHKERRQ(ierr);
266 
267   ierr = PetscLayoutDestroy(A->rmap);CHKERRQ(ierr);
268   ierr = PetscLayoutDestroy(A->cmap);CHKERRQ(ierr);
269   ierr = PetscFListDestroy(&((PetscObject)A)->qlist);CHKERRQ(ierr);
270   ierr = PetscOListDestroy(((PetscObject)A)->olist);CHKERRQ(ierr);
271 
272   /* copy C over to A */
273   ierr  = PetscMemcpy(A,C,sizeof(struct _p_Mat));CHKERRQ(ierr);
274 
275   /* return the parts of A we saved */
276   ((PetscObject)A)->bops      = Abops;
277   A->ops                      = Aops;
278   ((PetscObject)A)->refct     = refct;
279   ((PetscObject)A)->type_name = mtype;
280   ((PetscObject)A)->name      = mname;
281   A->spptr                    = spptr;
282 
283   /* since these two are copied into A we do not want them destroyed in C */
284   ((PetscObject)C)->qlist = 0;
285   ((PetscObject)C)->olist = 0;
286   ierr = PetscHeaderDestroy(C);CHKERRQ(ierr);
287   PetscFunctionReturn(0);
288 }
289 /*
290         Replace A's header with that of C
291         This is essentially code moved from MatDestroy
292 
293         This is somewhat different from MatHeaderCopy() it would be nice to merge the code
294 */
295 #undef __FUNCT__
296 #define __FUNCT__ "MatHeaderReplace"
297 PetscErrorCode MatHeaderReplace(Mat A,Mat C)
298 {
299   PetscErrorCode ierr;
300 
301   PetscFunctionBegin;
302   if (A == C) PetscFunctionReturn(0);
303 
304   /* free all the interior data structures from mat */
305   ierr = (*A->ops->destroy)(A);CHKERRQ(ierr);
306   ierr = PetscHeaderDestroy_Private((PetscObject)A);CHKERRQ(ierr);
307   ierr = PetscFree(A->ops);CHKERRQ(ierr);
308   ierr = PetscLayoutDestroy(A->rmap);CHKERRQ(ierr);
309   ierr = PetscLayoutDestroy(A->cmap);CHKERRQ(ierr);
310   ierr = PetscFree(A->spptr);CHKERRQ(ierr);
311 
312   /* copy C over to A */
313   if (C) {
314     ierr = PetscMemcpy(A,C,sizeof(struct _p_Mat));CHKERRQ(ierr);
315     ierr = PetscLogObjectDestroy((PetscObject)C);CHKERRQ(ierr);
316     ierr = PetscFree(C);CHKERRQ(ierr);
317   }
318   PetscFunctionReturn(0);
319 }
320