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