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