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