xref: /petsc/src/mat/utils/gcreate.c (revision 699b0258665d57c8f862c93d1d62d2bc140c87c9)
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->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   /* also set rmap/cmap.bs here? */
143   /*
144   ierr = PetscMapInitialize(A->comm,&A->rmap);CHKERRQ(ierr);
145   ierr = PetscMapInitialize(A->comm,&A->cmap);CHKERRQ(ierr);
146   */
147   PetscFunctionReturn(0);
148 }
149 
150 #undef __FUNCT__
151 #define __FUNCT__ "MatSetFromOptions"
152 /*@
153    MatSetFromOptions - Creates a matrix where the type is determined
154    from the options database. Generates a parallel MPI matrix if the
155    communicator has more than one processor.  The default matrix type is
156    AIJ, using the routines MatCreateSeqAIJ() and MatCreateMPIAIJ() if
157    you do not select a type in the options database.
158 
159    Collective on Mat
160 
161    Input Parameter:
162 .  A - the matrix
163 
164    Options Database Keys:
165 +    -mat_type seqaij   - AIJ type, uses MatCreateSeqAIJ()
166 .    -mat_type mpiaij   - AIJ type, uses MatCreateMPIAIJ()
167 .    -mat_type seqbdiag - block diagonal type, uses MatCreateSeqBDiag()
168 .    -mat_type mpibdiag - block diagonal type, uses MatCreateMPIBDiag()
169 .    -mat_type mpirowbs - rowbs type, uses MatCreateMPIRowbs()
170 .    -mat_type seqdense - dense type, uses MatCreateSeqDense()
171 .    -mat_type mpidense - dense type, uses MatCreateMPIDense()
172 .    -mat_type seqbaij  - block AIJ type, uses MatCreateSeqBAIJ()
173 -    -mat_type mpibaij  - block AIJ type, uses MatCreateMPIBAIJ()
174 
175    Even More Options Database Keys:
176    See the manpages for particular formats (e.g., MatCreateSeqAIJ())
177    for additional format-specific options.
178 
179    Level: beginner
180 
181 .keywords: matrix, create
182 
183 .seealso: MatCreateSeqAIJ((), MatCreateMPIAIJ(),
184           MatCreateSeqBDiag(),MatCreateMPIBDiag(),
185           MatCreateSeqDense(), MatCreateMPIDense(),
186           MatCreateMPIRowbs(), MatCreateSeqBAIJ(), MatCreateMPIBAIJ(),
187           MatCreateSeqSBAIJ(), MatCreateMPISBAIJ(),
188           MatConvert()
189 @*/
190 PetscErrorCode PETSCMAT_DLLEXPORT MatSetFromOptions(Mat B)
191 {
192   PetscErrorCode ierr;
193   char           mtype[256];
194   PetscTruth     flg;
195 
196   PetscFunctionBegin;
197   ierr = PetscOptionsGetString(B->prefix,"-mat_type",mtype,256,&flg);CHKERRQ(ierr);
198   if (flg) {
199     ierr = MatSetType(B,mtype);CHKERRQ(ierr);
200   }
201   if (!B->type_name) {
202     ierr = MatSetType(B,MATAIJ);CHKERRQ(ierr);
203   }
204   PetscFunctionReturn(0);
205 }
206 
207 #undef __FUNCT__
208 #define __FUNCT__ "MatSetUpPreallocation"
209 /*@C
210    MatSetUpPreallocation
211 
212    Collective on Mat
213 
214    Input Parameter:
215 .  A - the matrix
216 
217    Level: beginner
218 
219 .keywords: matrix, create
220 
221 .seealso: MatCreateSeqAIJ((), MatCreateMPIAIJ(),
222           MatCreateSeqBDiag(),MatCreateMPIBDiag(),
223           MatCreateSeqDense(), MatCreateMPIDense(),
224           MatCreateMPIRowbs(), MatCreateSeqBAIJ(), MatCreateMPIBAIJ(),
225           MatCreateSeqSBAIJ(), MatCreateMPISBAIJ(),
226           MatConvert()
227 @*/
228 PetscErrorCode PETSCMAT_DLLEXPORT MatSetUpPreallocation(Mat B)
229 {
230   PetscErrorCode ierr;
231 
232   PetscFunctionBegin;
233   if (B->ops->setuppreallocation) {
234     ierr = PetscInfo(B,"Warning not preallocating matrix storage\n");CHKERRQ(ierr);
235     ierr = (*B->ops->setuppreallocation)(B);CHKERRQ(ierr);
236     B->ops->setuppreallocation = 0;
237   }
238   B->preallocated = PETSC_TRUE;
239   PetscFunctionReturn(0);
240 }
241 
242 /*
243         Copies from Cs header to A
244 */
245 #undef __FUNCT__
246 #define __FUNCT__ "MatHeaderCopy"
247 PetscErrorCode MatHeaderCopy(Mat A,Mat C)
248 {
249   PetscErrorCode ierr;
250   PetscInt       refct;
251   PetscOps       *Abops;
252   MatOps         Aops;
253   char           *mtype,*mname;
254   void           *spptr;
255 
256   PetscFunctionBegin;
257   /* free all the interior data structures from mat */
258   ierr = (*A->ops->destroy)(A);CHKERRQ(ierr);
259 
260   /* save the parts of A we need */
261   Abops = A->bops;
262   Aops  = A->ops;
263   refct = A->refct;
264   mtype = A->type_name;
265   mname = A->name;
266   spptr = A->spptr;
267 
268   ierr = PetscFree(C->spptr);CHKERRQ(ierr);
269 
270   ierr = PetscFree(A->rmap.range);CHKERRQ(ierr);
271   ierr = PetscFree(A->cmap.range);CHKERRQ(ierr);
272 
273   /* copy C over to A */
274   ierr  = PetscMemcpy(A,C,sizeof(struct _p_Mat));CHKERRQ(ierr);
275 
276   /* return the parts of A we saved */
277   A->bops      = Abops;
278   A->ops       = Aops;
279   A->qlist     = 0;
280   A->refct     = refct;
281   A->type_name = mtype;
282   A->name      = mname;
283   A->spptr     = spptr;
284 
285   ierr = PetscHeaderDestroy(C);CHKERRQ(ierr);
286   PetscFunctionReturn(0);
287 }
288 /*
289         Replace A's header with that of C
290         This is essentially code moved from MatDestroy
291 */
292 #undef __FUNCT__
293 #define __FUNCT__ "MatHeaderReplace"
294 PetscErrorCode MatHeaderReplace(Mat A,Mat C)
295 {
296   PetscErrorCode ierr;
297 
298   PetscFunctionBegin;
299   /* free all the interior data structures from mat */
300   ierr = (*A->ops->destroy)(A);CHKERRQ(ierr);
301   ierr = PetscHeaderDestroy_Private((PetscObject)A);CHKERRQ(ierr);
302   ierr = PetscFree(A->rmap.range);CHKERRQ(ierr);
303   ierr = PetscFree(A->cmap.range);CHKERRQ(ierr);
304   ierr = PetscFree(A->spptr);CHKERRQ(ierr);
305 
306   /* copy C over to A */
307   if (C) {
308     ierr = PetscMemcpy(A,C,sizeof(struct _p_Mat));CHKERRQ(ierr);
309     ierr = PetscLogObjectDestroy((PetscObject)C);CHKERRQ(ierr);
310     ierr = PetscFree(C);CHKERRQ(ierr);
311   }
312   PetscFunctionReturn(0);
313 }
314