xref: /petsc/src/sys/classes/random/interface/randreg.c (revision 1c84c290429673533d0af1ef36b216eb00726fbb)
1 
2 #include <../src/sys/classes/random/randomimpl.h>         /*I "petscsys.h" I*/
3 
4 PetscFunctionList PetscRandomList              = NULL;
5 PetscBool         PetscRandomRegisterAllCalled = PETSC_FALSE;
6 
7 #undef __FUNCT__
8 #define __FUNCT__ "PetscRandomSetType"
9 /*@C
10   PetscRandomSetType - Builds a context for generating particular type of random numbers.
11 
12   Collective on PetscRandom
13 
14   Input Parameters:
15 + rnd   - The random number generator context
16 - type - The name of the random type
17 
18   Options Database Key:
19 . -random_type <type> - Sets the random type; use -help for a list
20                      of available types
21 
22   Notes:
23   See "petsc/include/petscsys.h" for available random types (for instance, PETSCRAND48, PETSCRAND).
24 
25   Level: intermediate
26 
27 .keywords: random, set, type
28 .seealso: PetscRandomGetType(), PetscRandomCreate()
29 @*/
30 
31 PetscErrorCode  PetscRandomSetType(PetscRandom rnd, PetscRandomType type)
32 {
33   PetscErrorCode (*r)(PetscRandom);
34   PetscBool      match;
35   PetscErrorCode ierr;
36 
37   PetscFunctionBegin;
38   PetscValidHeaderSpecific(rnd, PETSC_RANDOM_CLASSID,1);
39   ierr = PetscObjectTypeCompare((PetscObject)rnd, type, &match);CHKERRQ(ierr);
40   if (match) PetscFunctionReturn(0);
41 
42   ierr = PetscFunctionListFind(PetscObjectComm((PetscObject)rnd),PetscRandomList,  type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr);
43   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown random type: %s", type);
44 
45   if (rnd->ops->destroy) {
46     ierr = (*rnd->ops->destroy)(rnd);CHKERRQ(ierr);
47 
48     rnd->ops->destroy = NULL;
49   }
50   ierr = (*r)(rnd);CHKERRQ(ierr);
51   ierr = PetscRandomSeed(rnd);CHKERRQ(ierr);
52 
53   ierr = PetscObjectChangeTypeName((PetscObject)rnd, type);CHKERRQ(ierr);
54   PetscFunctionReturn(0);
55 }
56 
57 #undef __FUNCT__
58 #define __FUNCT__ "PetscRandomGetType"
59 /*@C
60   PetscRandomGetType - Gets the type name (as a string) from the PetscRandom.
61 
62   Not Collective
63 
64   Input Parameter:
65 . rnd  - The random number generator context
66 
67   Output Parameter:
68 . type - The type name
69 
70   Level: intermediate
71 
72 .keywords: random, get, type, name
73 .seealso: PetscRandomSetType(), PetscRandomCreate()
74 @*/
75 PetscErrorCode  PetscRandomGetType(PetscRandom rnd, PetscRandomType *type)
76 {
77   PetscFunctionBegin;
78   PetscValidHeaderSpecific(rnd, PETSC_RANDOM_CLASSID,1);
79   PetscValidPointer(type,2);
80   *type = ((PetscObject)rnd)->type_name;
81   PetscFunctionReturn(0);
82 }
83 
84 #undef __FUNCT__
85 #define __FUNCT__ "PetscRandomRegister"
86 /*@C
87   PetscRandomRegister -  Adds a new PetscRandom component implementation
88 
89   Not Collective
90 
91   Input Parameters:
92 + name        - The name of a new user-defined creation routine
93 . func_name   - The name of routine to create method context
94 - create_func - The creation routine itself
95 
96   Notes:
97   PetscRandomRegister() may be called multiple times to add several user-defined randome number generators
98 
99   Sample usage:
100 .vb
101     PetscRandomRegister("my_rand", "MyPetscRandomtorCreate", MyPetscRandomtorCreate);
102 .ve
103 
104   Then, your random type can be chosen with the procedural interface via
105 .vb
106     PetscRandomCreate(MPI_Comm, PetscRandom *);
107     PetscRandomSetType(PetscRandom,"my_random_name");
108 .ve
109    or at runtime via the option
110 .vb
111     -random_type my_random_name
112 .ve
113 
114   Notes: For an example of the code needed to interface your own random number generator see
115          src/sys/random/impls/rand/rand.c
116 
117   Level: advanced
118 
119 .keywords: PetscRandom, register
120 
121 .seealso: PetscRandomRegisterAll(), PetscRandomRegisterDestroy(), PetscRandomRegister()
122 @*/
123 PetscErrorCode  PetscRandomRegister(const char sname[], const char path[], const char name[], PetscErrorCode (*function)(PetscRandom))
124 {
125   char           fullname[PETSC_MAX_PATH_LEN];
126   PetscErrorCode ierr;
127 
128   PetscFunctionBegin;
129   ierr = PetscFunctionListConcat(path,name,fullname);CHKERRQ(ierr);
130   ierr = PetscFunctionListAdd(PETSC_COMM_WORLD,&PetscRandomList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
131   PetscFunctionReturn(0);
132 }
133 
134 
135 /*--------------------------------------------------------------------------------------------------------------------*/
136 #undef __FUNCT__
137 #define __FUNCT__ "PetscRandomRegisterDestroy"
138 /*@C
139    PetscRandomRegisterDestroy - Frees the list of Random types that were registered by PetscRandomRegister()/PetscRandomRegister().
140 
141    Not Collective
142 
143    Level: advanced
144 
145 .keywords: PetscRandom, register, destroy
146 .seealso: PetscRandomRegister(), PetscRandomRegisterAll(), PetscRandomRegister()
147 @*/
148 PetscErrorCode  PetscRandomRegisterDestroy(void)
149 {
150   PetscErrorCode ierr;
151 
152   PetscFunctionBegin;
153   ierr = PetscFunctionListDestroy(&PetscRandomList);CHKERRQ(ierr);
154 
155   PetscRandomRegisterAllCalled = PETSC_FALSE;
156   PetscFunctionReturn(0);
157 }
158 
159 #if defined(PETSC_HAVE_RAND)
160 PETSC_EXTERN PetscErrorCode PetscRandomCreate_Rand(PetscRandom);
161 #endif
162 #if defined(PETSC_HAVE_DRAND48)
163 PETSC_EXTERN PetscErrorCode PetscRandomCreate_Rand48(PetscRandom);
164 #endif
165 #if defined(PETSC_HAVE_SPRNG)
166 PETSC_EXTERN PetscErrorCode PetscRandomCreate_Sprng(PetscRandom);
167 #endif
168 
169 #undef __FUNCT__
170 #define __FUNCT__ "PetscRandomRegisterAll"
171 /*@C
172   PetscRandomRegisterAll - Registers all of the components in the PetscRandom package.
173 
174   Not Collective
175 
176   Input parameter:
177 . path - The dynamic library path
178 
179   Level: advanced
180 
181 .keywords: PetscRandom, register, all
182 .seealso:  PetscRandomRegister(), PetscRandomRegisterDestroy(), PetscRandomRegister()
183 @*/
184 PetscErrorCode  PetscRandomRegisterAll(const char path[])
185 {
186   PetscErrorCode ierr;
187 
188   PetscFunctionBegin;
189   PetscRandomRegisterAllCalled = PETSC_TRUE;
190 #if defined(PETSC_HAVE_RAND)
191   ierr = PetscRandomRegister(PETSCRAND,  path,"PetscRandomCreate_Rand",  PetscRandomCreate_Rand);CHKERRQ(ierr);
192 #endif
193 #if defined(PETSC_HAVE_DRAND48)
194   ierr = PetscRandomRegister(PETSCRAND48,path,"PetscRandomCreate_Rand48",PetscRandomCreate_Rand48);CHKERRQ(ierr);
195 #endif
196 #if defined(PETSC_HAVE_SPRNG)
197   ierr = PetscRandomRegister(PETSCSPRNG,path,"PetscRandomCreate_Sprng",PetscRandomCreate_Sprng);CHKERRQ(ierr);
198 #endif
199   PetscFunctionReturn(0);
200 }
201 
202