xref: /petsc/src/mat/utils/gcreate.c (revision e8fb0fc05573aa974b3f79797ad519d0316ca217)
1 #define PETSCMAT_DLL
2 
3 #include "include/private/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->rmap.n             = -1;
81   B->rmap.N             = -1;
82   B->cmap.n             = -1;
83   B->cmap.N             = -1;
84   B->rmap.bs            = 1;
85   B->cmap.bs            = 1;
86   B->preallocated  = PETSC_FALSE;
87   B->bops->publish = MatPublish_Base;
88   *A               = B;
89   PetscFunctionReturn(0);
90 }
91 
92 #undef __FUNCT__
93 #define __FUNCT__ "MatSetSizes"
94 /*@
95   MatSetSizes - Sets the local and global sizes, and checks to determine compatibility
96 
97   Collective on Mat
98 
99   Input Parameters:
100 +  A - the matrix
101 .  m - number of local rows (or PETSC_DECIDE)
102 .  n - number of local columns (or PETSC_DECIDE)
103 .  M - number of global rows (or PETSC_DETERMINE)
104 -  N - number of global columns (or PETSC_DETERMINE)
105 
106    Notes:
107    m (n) and M (N) cannot be both PETSC_DECIDE
108    If one processor calls this with M (N) of PETSC_DECIDE then all processors must, otherwise the program will hang.
109 
110    If PETSC_DECIDE is not used for the arguments 'm' and 'n', then the
111    user must ensure that they are chosen to be compatible with the
112    vectors. To do this, one first considers the matrix-vector product
113    'y = A x'. The 'm' that is used in the above routine must match the
114    local size used in the vector creation routine VecCreateMPI() for 'y'.
115    Likewise, the 'n' used must match that used as the local size in
116    VecCreateMPI() for 'x'.
117 
118   Level: beginner
119 
120 .seealso: MatGetSize(), PetscSplitOwnership()
121 @*/
122 PetscErrorCode PETSCMAT_DLLEXPORT MatSetSizes(Mat A, PetscInt m, PetscInt n, PetscInt M, PetscInt N)
123 {
124   PetscErrorCode ierr;
125 
126   PetscFunctionBegin;
127   PetscValidHeaderSpecific(A,MAT_COOKIE,1);
128   if (M > 0 && m > M) SETERRQ2(PETSC_ERR_ARG_INCOMP,"Local column size %D cannot be larger than global column size %D",m,M);
129   if (N > 0 && n > N) SETERRQ2(PETSC_ERR_ARG_INCOMP,"Local row size %D cannot be larger than global row size %D",n,N);
130   if (A->ops->setsizes) {
131     /* Since this will not be set until the type has been set, this will NOT be called on the initial
132        call of MatSetSizes() (which must be called BEFORE MatSetType() */
133     ierr = (*A->ops->setsizes)(A,m,n,M,N);CHKERRQ(ierr);
134   } else {
135     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);
136     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);
137   }
138   A->rmap.n = m;
139   A->cmap.n = n;
140   A->rmap.N = M;
141   A->cmap.N = N;
142   PetscFunctionReturn(0);
143 }
144 
145 #undef __FUNCT__
146 #define __FUNCT__ "MatSetFromOptions"
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.
153 
154    Collective on Mat
155 
156    Input Parameter:
157 .  A - the matrix
158 
159    Options Database Keys:
160 +    -mat_type seqaij   - AIJ type, uses MatCreateSeqAIJ()
161 .    -mat_type mpiaij   - AIJ type, uses MatCreateMPIAIJ()
162 .    -mat_type seqbdiag - block diagonal type, uses MatCreateSeqBDiag()
163 .    -mat_type mpibdiag - block diagonal type, uses MatCreateMPIBDiag()
164 .    -mat_type mpirowbs - rowbs type, uses MatCreateMPIRowbs()
165 .    -mat_type seqdense - dense type, uses MatCreateSeqDense()
166 .    -mat_type mpidense - dense type, uses MatCreateMPIDense()
167 .    -mat_type seqbaij  - block AIJ type, uses MatCreateSeqBAIJ()
168 -    -mat_type mpibaij  - block AIJ type, uses MatCreateMPIBAIJ()
169 
170    Even More Options Database Keys:
171    See the manpages for particular formats (e.g., MatCreateSeqAIJ())
172    for additional format-specific options.
173 
174    Level: beginner
175 
176 .keywords: matrix, create
177 
178 .seealso: MatCreateSeqAIJ((), MatCreateMPIAIJ(),
179           MatCreateSeqBDiag(),MatCreateMPIBDiag(),
180           MatCreateSeqDense(), MatCreateMPIDense(),
181           MatCreateMPIRowbs(), MatCreateSeqBAIJ(), MatCreateMPIBAIJ(),
182           MatCreateSeqSBAIJ(), MatCreateMPISBAIJ(),
183           MatConvert()
184 @*/
185 PetscErrorCode PETSCMAT_DLLEXPORT MatSetFromOptions(Mat B)
186 {
187   PetscErrorCode ierr;
188   char           mtype[256];
189   PetscTruth     flg;
190 
191   PetscFunctionBegin;
192   ierr = PetscOptionsGetString(B->prefix,"-mat_type",mtype,256,&flg);CHKERRQ(ierr);
193   if (flg) {
194     ierr = MatSetType(B,mtype);CHKERRQ(ierr);
195   }
196   if (!B->type_name) {
197     ierr = MatSetType(B,MATAIJ);CHKERRQ(ierr);
198   }
199   PetscFunctionReturn(0);
200 }
201 
202 #undef __FUNCT__
203 #define __FUNCT__ "MatSetUpPreallocation"
204 /*@C
205    MatSetUpPreallocation
206 
207    Collective on Mat
208 
209    Input Parameter:
210 .  A - the matrix
211 
212    Level: beginner
213 
214 .keywords: matrix, create
215 
216 .seealso: MatCreateSeqAIJ((), MatCreateMPIAIJ(),
217           MatCreateSeqBDiag(),MatCreateMPIBDiag(),
218           MatCreateSeqDense(), MatCreateMPIDense(),
219           MatCreateMPIRowbs(), MatCreateSeqBAIJ(), MatCreateMPIBAIJ(),
220           MatCreateSeqSBAIJ(), MatCreateMPISBAIJ(),
221           MatConvert()
222 @*/
223 PetscErrorCode PETSCMAT_DLLEXPORT MatSetUpPreallocation(Mat B)
224 {
225   PetscErrorCode ierr;
226 
227   PetscFunctionBegin;
228   if (!B->preallocated && B->ops->setuppreallocation) {
229     ierr = PetscInfo(B,"Warning not preallocating matrix storage\n");CHKERRQ(ierr);
230     ierr = (*B->ops->setuppreallocation)(B);CHKERRQ(ierr);
231   }
232   B->preallocated = PETSC_TRUE;
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   /* save the parts of A we need */
252   Abops = A->bops;
253   Aops  = A->ops;
254   refct = A->refct;
255   mtype = A->type_name; A->type_name = 0;
256   mname = A->name; A->name = 0;
257   spptr = A->spptr;
258 
259   /* free all the interior data structures from mat */
260   ierr = (*A->ops->destroy)(A);CHKERRQ(ierr);
261 
262   ierr = PetscFree(C->spptr);CHKERRQ(ierr);
263 
264   ierr = PetscFree(A->rmap.range);CHKERRQ(ierr);
265   ierr = PetscFree(A->cmap.range);CHKERRQ(ierr);
266 
267   /* copy C over to A */
268   ierr  = PetscMemcpy(A,C,sizeof(struct _p_Mat));CHKERRQ(ierr);
269 
270   /* return the parts of A we saved */
271   A->bops      = Abops;
272   A->ops       = Aops;
273   A->qlist     = 0;
274   A->refct     = refct;
275   A->type_name = mtype;
276   A->name      = mname;
277   A->spptr     = spptr;
278 
279   ierr = PetscHeaderDestroy(C);CHKERRQ(ierr);
280   PetscFunctionReturn(0);
281 }
282 /*
283         Replace A's header with that of C
284         This is essentially code moved from MatDestroy
285 */
286 #undef __FUNCT__
287 #define __FUNCT__ "MatHeaderReplace"
288 PetscErrorCode MatHeaderReplace(Mat A,Mat C)
289 {
290   PetscErrorCode ierr;
291 
292   PetscFunctionBegin;
293   /* free all the interior data structures from mat */
294   ierr = (*A->ops->destroy)(A);CHKERRQ(ierr);
295   ierr = PetscHeaderDestroy_Private((PetscObject)A);CHKERRQ(ierr);
296   ierr = PetscFree(A->rmap.range);CHKERRQ(ierr);
297   ierr = PetscFree(A->cmap.range);CHKERRQ(ierr);
298   ierr = PetscFree(A->spptr);CHKERRQ(ierr);
299 
300   /* copy C over to A */
301   if (C) {
302     ierr = PetscMemcpy(A,C,sizeof(struct _p_Mat));CHKERRQ(ierr);
303     ierr = PetscLogObjectDestroy((PetscObject)C);CHKERRQ(ierr);
304     ierr = PetscFree(C);CHKERRQ(ierr);
305   }
306   PetscFunctionReturn(0);
307 }
308