1 
2 #include <petsc/private/vecimpl.h>    /*I "petscvec.h"  I*/
3 
4 PetscFunctionList VecList              = NULL;
5 PetscBool         VecRegisterAllCalled = PETSC_FALSE;
6 
7 /*@C
8   VecSetType - Builds a vector, for a particular vector implementation.
9 
10   Collective on Vec
11 
12   Input Parameters:
13 + vec    - The vector object
14 - method - The name of the vector type
15 
16   Options Database Key:
17 . -vec_type <type> - Sets the vector type; use -help for a list
18                      of available types
19 
20   Notes:
21   See "petsc/include/petscvec.h" for available vector types (for instance, VECSEQ, VECMPI, or VECSHARED).
22 
23   Use VecDuplicate() or VecDuplicateVecs() to form additional vectors of the same type as an existing vector.
24 
25   Level: intermediate
26 
27 .seealso: VecGetType(), VecCreate()
28 @*/
VecSetType(Vec vec,VecType method)29 PetscErrorCode VecSetType(Vec vec, VecType method)
30 {
31   PetscErrorCode (*r)(Vec);
32   PetscBool      match;
33   PetscMPIInt    size;
34   PetscErrorCode ierr;
35 
36   PetscFunctionBegin;
37   PetscValidHeaderSpecific(vec, VEC_CLASSID,1);
38   ierr = PetscObjectTypeCompare((PetscObject) vec, method, &match);CHKERRQ(ierr);
39   if (match) PetscFunctionReturn(0);
40 
41   /* Return if asked for VECSTANDARD and Vec is already VECSEQ on 1 process or VECMPI on more.
42      Otherwise, we free the Vec array in the call to destroy below and never reallocate it,
43      since the VecType will be the same and VecSetType(v,VECSEQ) will return when called from VecCreate_Standard */
44   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)vec),&size);CHKERRQ(ierr);
45   ierr = PetscStrcmp(method,VECSTANDARD,&match);CHKERRQ(ierr);
46   if (match) {
47 
48     ierr = PetscObjectTypeCompare((PetscObject) vec, size > 1 ? VECMPI : VECSEQ, &match);CHKERRQ(ierr);
49     if (match) PetscFunctionReturn(0);
50   }
51   /* same reasons for VECCUDA and VECVIENNACL */
52 #if defined(PETSC_HAVE_CUDA)
53   ierr = PetscStrcmp(method,VECCUDA,&match);CHKERRQ(ierr);
54   if (match) {
55     ierr = PetscObjectTypeCompare((PetscObject) vec, size > 1 ? VECMPICUDA : VECSEQCUDA, &match);CHKERRQ(ierr);
56     if (match) PetscFunctionReturn(0);
57   }
58 #endif
59 #if defined(PETSC_HAVE_VIENNACL)
60   ierr = PetscStrcmp(method,VECVIENNACL,&match);CHKERRQ(ierr);
61   if (match) {
62     ierr = PetscObjectTypeCompare((PetscObject) vec, size > 1 ? VECMPIVIENNACL : VECSEQVIENNACL, &match);CHKERRQ(ierr);
63     if (match) PetscFunctionReturn(0);
64   }
65 #endif
66 #if defined(PETSC_HAVE_KOKKOS_KERNELS)
67   ierr = PetscStrcmp(method,VECKOKKOS,&match);CHKERRQ(ierr);
68   if (match) {
69     ierr = PetscObjectTypeCompare((PetscObject) vec, size > 1 ? VECMPIKOKKOS : VECSEQKOKKOS, &match);CHKERRQ(ierr);
70     if (match) PetscFunctionReturn(0);
71   }
72 #endif
73   ierr = PetscFunctionListFind(VecList,method,&r);CHKERRQ(ierr);
74   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown vector type: %s", method);
75   if (vec->ops->destroy) {
76     ierr = (*vec->ops->destroy)(vec);CHKERRQ(ierr);
77     vec->ops->destroy = NULL;
78   }
79   ierr = PetscMemzero(vec->ops,sizeof(struct _VecOps));CHKERRQ(ierr);
80   if (vec->map->n < 0 && vec->map->N < 0) {
81     vec->ops->create = r;
82     vec->ops->load   = VecLoad_Default;
83   } else {
84     ierr = (*r)(vec);CHKERRQ(ierr);
85   }
86   PetscFunctionReturn(0);
87 }
88 
89 /*@C
90   VecGetType - Gets the vector type name (as a string) from the Vec.
91 
92   Not Collective
93 
94   Input Parameter:
95 . vec  - The vector
96 
97   Output Parameter:
98 . type - The vector type name
99 
100   Level: intermediate
101 
102 .seealso: VecSetType(), VecCreate()
103 @*/
VecGetType(Vec vec,VecType * type)104 PetscErrorCode VecGetType(Vec vec, VecType *type)
105 {
106   PetscErrorCode ierr;
107 
108   PetscFunctionBegin;
109   PetscValidHeaderSpecific(vec, VEC_CLASSID,1);
110   PetscValidPointer(type,2);
111   ierr = VecRegisterAll();CHKERRQ(ierr);
112   *type = ((PetscObject)vec)->type_name;
113   PetscFunctionReturn(0);
114 }
115 
116 
117 /*--------------------------------------------------------------------------------------------------------------------*/
118 
119 /*@C
120   VecRegister -  Adds a new vector component implementation
121 
122   Not Collective
123 
124   Input Parameters:
125 + name        - The name of a new user-defined creation routine
126 - create_func - The creation routine itself
127 
128   Notes:
129   VecRegister() may be called multiple times to add several user-defined vectors
130 
131   Sample usage:
132 .vb
133     VecRegister("my_vec",MyVectorCreate);
134 .ve
135 
136   Then, your vector type can be chosen with the procedural interface via
137 .vb
138     VecCreate(MPI_Comm, Vec *);
139     VecSetType(Vec,"my_vector_name");
140 .ve
141    or at runtime via the option
142 .vb
143     -vec_type my_vector_name
144 .ve
145 
146   Level: advanced
147 
148 .seealso: VecRegisterAll(), VecRegisterDestroy()
149 @*/
VecRegister(const char sname[],PetscErrorCode (* function)(Vec))150 PetscErrorCode VecRegister(const char sname[], PetscErrorCode (*function)(Vec))
151 {
152   PetscErrorCode ierr;
153 
154   PetscFunctionBegin;
155   ierr = VecInitializePackage();CHKERRQ(ierr);
156   ierr = PetscFunctionListAdd(&VecList,sname,function);CHKERRQ(ierr);
157   PetscFunctionReturn(0);
158 }
159