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