xref: /petsc/src/sys/classes/random/interface/randomc.c (revision 5c6c1daec53e1d9ab0bec9db5309fd8fc7645b8d)
1*5c6c1daeSBarry Smith 
2*5c6c1daeSBarry Smith /*
3*5c6c1daeSBarry Smith     This file contains routines for interfacing to random number generators.
4*5c6c1daeSBarry Smith     This provides more than just an interface to some system random number
5*5c6c1daeSBarry Smith     generator:
6*5c6c1daeSBarry Smith 
7*5c6c1daeSBarry Smith     Numbers can be shuffled for use as random tuples
8*5c6c1daeSBarry Smith 
9*5c6c1daeSBarry Smith     Multiple random number generators may be used
10*5c6c1daeSBarry Smith 
11*5c6c1daeSBarry Smith     We are still not sure what interface we want here.  There should be
12*5c6c1daeSBarry Smith     one to reinitialize and set the seed.
13*5c6c1daeSBarry Smith  */
14*5c6c1daeSBarry Smith 
15*5c6c1daeSBarry Smith #include <../src/sys/classes/random/randomimpl.h>                              /*I "petscsys.h" I*/
16*5c6c1daeSBarry Smith #if defined (PETSC_HAVE_STDLIB_H)
17*5c6c1daeSBarry Smith #include <stdlib.h>
18*5c6c1daeSBarry Smith #endif
19*5c6c1daeSBarry Smith 
20*5c6c1daeSBarry Smith /* Logging support */
21*5c6c1daeSBarry Smith PetscClassId  PETSC_RANDOM_CLASSID;
22*5c6c1daeSBarry Smith 
23*5c6c1daeSBarry Smith #undef __FUNCT__
24*5c6c1daeSBarry Smith #define __FUNCT__ "PetscRandomDestroy"
25*5c6c1daeSBarry Smith /*@
26*5c6c1daeSBarry Smith    PetscRandomDestroy - Destroys a context that has been formed by
27*5c6c1daeSBarry Smith    PetscRandomCreate().
28*5c6c1daeSBarry Smith 
29*5c6c1daeSBarry Smith    Collective on PetscRandom
30*5c6c1daeSBarry Smith 
31*5c6c1daeSBarry Smith    Intput Parameter:
32*5c6c1daeSBarry Smith .  r  - the random number generator context
33*5c6c1daeSBarry Smith 
34*5c6c1daeSBarry Smith    Level: intermediate
35*5c6c1daeSBarry Smith 
36*5c6c1daeSBarry Smith .seealso: PetscRandomGetValue(), PetscRandomCreate(), VecSetRandom()
37*5c6c1daeSBarry Smith @*/
38*5c6c1daeSBarry Smith PetscErrorCode  PetscRandomDestroy(PetscRandom *r)
39*5c6c1daeSBarry Smith {
40*5c6c1daeSBarry Smith   PetscErrorCode ierr;
41*5c6c1daeSBarry Smith   PetscFunctionBegin;
42*5c6c1daeSBarry Smith   if (!*r) PetscFunctionReturn(0);
43*5c6c1daeSBarry Smith   PetscValidHeaderSpecific(*r,PETSC_RANDOM_CLASSID,1);
44*5c6c1daeSBarry Smith   if (--((PetscObject)(*r))->refct > 0) {*r = 0; PetscFunctionReturn(0);}
45*5c6c1daeSBarry Smith   ierr = PetscHeaderDestroy(r);CHKERRQ(ierr);
46*5c6c1daeSBarry Smith   PetscFunctionReturn(0);
47*5c6c1daeSBarry Smith }
48*5c6c1daeSBarry Smith 
49*5c6c1daeSBarry Smith 
50*5c6c1daeSBarry Smith #undef __FUNCT__
51*5c6c1daeSBarry Smith #define __FUNCT__ "PetscRandomGetSeed"
52*5c6c1daeSBarry Smith /*@
53*5c6c1daeSBarry Smith    PetscRandomGetSeed - Gets the random seed.
54*5c6c1daeSBarry Smith 
55*5c6c1daeSBarry Smith    Not collective
56*5c6c1daeSBarry Smith 
57*5c6c1daeSBarry Smith    Input Parameters:
58*5c6c1daeSBarry Smith .  r - The random number generator context
59*5c6c1daeSBarry Smith 
60*5c6c1daeSBarry Smith    Output Parameter:
61*5c6c1daeSBarry Smith .  seed - The random seed
62*5c6c1daeSBarry Smith 
63*5c6c1daeSBarry Smith    Level: intermediate
64*5c6c1daeSBarry Smith 
65*5c6c1daeSBarry Smith    Concepts: random numbers^seed
66*5c6c1daeSBarry Smith 
67*5c6c1daeSBarry Smith .seealso: PetscRandomCreate(), PetscRandomSetSeed(), PetscRandomSeed()
68*5c6c1daeSBarry Smith @*/
69*5c6c1daeSBarry Smith PetscErrorCode  PetscRandomGetSeed(PetscRandom r,unsigned long *seed)
70*5c6c1daeSBarry Smith {
71*5c6c1daeSBarry Smith   PetscFunctionBegin;
72*5c6c1daeSBarry Smith   PetscValidHeaderSpecific(r,PETSC_RANDOM_CLASSID,1);
73*5c6c1daeSBarry Smith   if (seed) {
74*5c6c1daeSBarry Smith     PetscValidPointer(seed,2);
75*5c6c1daeSBarry Smith     *seed = r->seed;
76*5c6c1daeSBarry Smith   }
77*5c6c1daeSBarry Smith   PetscFunctionReturn(0);
78*5c6c1daeSBarry Smith }
79*5c6c1daeSBarry Smith 
80*5c6c1daeSBarry Smith #undef __FUNCT__
81*5c6c1daeSBarry Smith #define __FUNCT__ "PetscRandomSetSeed"
82*5c6c1daeSBarry Smith /*@
83*5c6c1daeSBarry Smith    PetscRandomSetSeed - Sets the random seed. You MUST call PetscRandomSeed() after this call to have the new seed used.
84*5c6c1daeSBarry Smith 
85*5c6c1daeSBarry Smith    Not collective
86*5c6c1daeSBarry Smith 
87*5c6c1daeSBarry Smith    Input Parameters:
88*5c6c1daeSBarry Smith +  r  - The random number generator context
89*5c6c1daeSBarry Smith -  seed - The random seed
90*5c6c1daeSBarry Smith 
91*5c6c1daeSBarry Smith    Level: intermediate
92*5c6c1daeSBarry Smith 
93*5c6c1daeSBarry Smith    Usage:
94*5c6c1daeSBarry Smith       PetscRandomSetSeed(r,a positive integer);
95*5c6c1daeSBarry Smith       PetscRandomSeed(r);  PetscRandomGetValue() will now start with the new seed.
96*5c6c1daeSBarry Smith 
97*5c6c1daeSBarry Smith       PetscRandomSeed(r) without a call to PetscRandomSetSeed() re-initializes
98*5c6c1daeSBarry Smith         the seed. The random numbers generated will be the same as before.
99*5c6c1daeSBarry Smith 
100*5c6c1daeSBarry Smith    Concepts: random numbers^seed
101*5c6c1daeSBarry Smith 
102*5c6c1daeSBarry Smith .seealso: PetscRandomCreate(), PetscRandomGetSeed(), PetscRandomSeed()
103*5c6c1daeSBarry Smith @*/
104*5c6c1daeSBarry Smith PetscErrorCode  PetscRandomSetSeed(PetscRandom r,unsigned long seed)
105*5c6c1daeSBarry Smith {
106*5c6c1daeSBarry Smith   PetscErrorCode ierr;
107*5c6c1daeSBarry Smith 
108*5c6c1daeSBarry Smith   PetscFunctionBegin;
109*5c6c1daeSBarry Smith   PetscValidHeaderSpecific(r,PETSC_RANDOM_CLASSID,1);
110*5c6c1daeSBarry Smith   r->seed = seed;
111*5c6c1daeSBarry Smith   ierr = PetscInfo1(PETSC_NULL,"Setting seed to %d\n",(int)seed);CHKERRQ(ierr);
112*5c6c1daeSBarry Smith   PetscFunctionReturn(0);
113*5c6c1daeSBarry Smith }
114*5c6c1daeSBarry Smith 
115*5c6c1daeSBarry Smith /* ------------------------------------------------------------------- */
116*5c6c1daeSBarry Smith #undef __FUNCT__
117*5c6c1daeSBarry Smith #define __FUNCT__ "PetscRandomSetTypeFromOptions_Private"
118*5c6c1daeSBarry Smith /*
119*5c6c1daeSBarry Smith   PetscRandomSetTypeFromOptions_Private - Sets the type of random generator from user options. Defaults to type PETSCRAND48 or PETSCRAND.
120*5c6c1daeSBarry Smith 
121*5c6c1daeSBarry Smith   Collective on PetscRandom
122*5c6c1daeSBarry Smith 
123*5c6c1daeSBarry Smith   Input Parameter:
124*5c6c1daeSBarry Smith . rnd - The random number generator context
125*5c6c1daeSBarry Smith 
126*5c6c1daeSBarry Smith   Level: intermediate
127*5c6c1daeSBarry Smith 
128*5c6c1daeSBarry Smith .keywords: PetscRandom, set, options, database, type
129*5c6c1daeSBarry Smith .seealso: PetscRandomSetFromOptions(), PetscRandomSetType()
130*5c6c1daeSBarry Smith */
131*5c6c1daeSBarry Smith static PetscErrorCode PetscRandomSetTypeFromOptions_Private(PetscRandom rnd)
132*5c6c1daeSBarry Smith {
133*5c6c1daeSBarry Smith   PetscBool      opt;
134*5c6c1daeSBarry Smith   const char     *defaultType;
135*5c6c1daeSBarry Smith   char           typeName[256];
136*5c6c1daeSBarry Smith   PetscErrorCode ierr;
137*5c6c1daeSBarry Smith 
138*5c6c1daeSBarry Smith   PetscFunctionBegin;
139*5c6c1daeSBarry Smith   if (((PetscObject)rnd)->type_name) {
140*5c6c1daeSBarry Smith     defaultType = ((PetscObject)rnd)->type_name;
141*5c6c1daeSBarry Smith   } else {
142*5c6c1daeSBarry Smith #if defined(PETSC_HAVE_DRAND48)
143*5c6c1daeSBarry Smith     defaultType = PETSCRAND48;
144*5c6c1daeSBarry Smith #elif defined(PETSC_HAVE_RAND)
145*5c6c1daeSBarry Smith     defaultType = PETSCRAND;
146*5c6c1daeSBarry Smith #endif
147*5c6c1daeSBarry Smith   }
148*5c6c1daeSBarry Smith 
149*5c6c1daeSBarry Smith   if (!PetscRandomRegisterAllCalled) {ierr = PetscRandomRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
150*5c6c1daeSBarry Smith   ierr = PetscOptionsList("-random_type","PetscRandom type","PetscRandomSetType",PetscRandomList,defaultType,typeName,256,&opt);CHKERRQ(ierr);
151*5c6c1daeSBarry Smith   if (opt) {
152*5c6c1daeSBarry Smith     ierr = PetscRandomSetType(rnd, typeName);CHKERRQ(ierr);
153*5c6c1daeSBarry Smith   } else {
154*5c6c1daeSBarry Smith     ierr = PetscRandomSetType(rnd, defaultType);CHKERRQ(ierr);
155*5c6c1daeSBarry Smith   }
156*5c6c1daeSBarry Smith   PetscFunctionReturn(0);
157*5c6c1daeSBarry Smith }
158*5c6c1daeSBarry Smith 
159*5c6c1daeSBarry Smith #undef __FUNCT__
160*5c6c1daeSBarry Smith #define __FUNCT__ "PetscRandomSetFromOptions"
161*5c6c1daeSBarry Smith /*@
162*5c6c1daeSBarry Smith   PetscRandomSetFromOptions - Configures the random number generator from the options database.
163*5c6c1daeSBarry Smith 
164*5c6c1daeSBarry Smith   Collective on PetscRandom
165*5c6c1daeSBarry Smith 
166*5c6c1daeSBarry Smith   Input Parameter:
167*5c6c1daeSBarry Smith . rnd - The random number generator context
168*5c6c1daeSBarry Smith 
169*5c6c1daeSBarry Smith   Options Database:
170*5c6c1daeSBarry Smith .  -random_seed <integer> - provide a seed to the random number generater
171*5c6c1daeSBarry Smith 
172*5c6c1daeSBarry Smith   Notes:  To see all options, run your program with the -help option.
173*5c6c1daeSBarry Smith           Must be called after PetscRandomCreate() but before the rnd is used.
174*5c6c1daeSBarry Smith 
175*5c6c1daeSBarry Smith   Level: beginner
176*5c6c1daeSBarry Smith 
177*5c6c1daeSBarry Smith .keywords: PetscRandom, set, options, database
178*5c6c1daeSBarry Smith .seealso: PetscRandomCreate(), PetscRandomSetType()
179*5c6c1daeSBarry Smith @*/
180*5c6c1daeSBarry Smith PetscErrorCode  PetscRandomSetFromOptions(PetscRandom rnd)
181*5c6c1daeSBarry Smith {
182*5c6c1daeSBarry Smith   PetscErrorCode ierr;
183*5c6c1daeSBarry Smith   PetscBool      set;
184*5c6c1daeSBarry Smith   PetscInt       seed;
185*5c6c1daeSBarry Smith 
186*5c6c1daeSBarry Smith   PetscFunctionBegin;
187*5c6c1daeSBarry Smith   PetscValidHeaderSpecific(rnd,PETSC_RANDOM_CLASSID,1);
188*5c6c1daeSBarry Smith 
189*5c6c1daeSBarry Smith   ierr = PetscObjectOptionsBegin((PetscObject)rnd);CHKERRQ(ierr);
190*5c6c1daeSBarry Smith 
191*5c6c1daeSBarry Smith     /* Handle PetscRandom type options */
192*5c6c1daeSBarry Smith     ierr = PetscRandomSetTypeFromOptions_Private(rnd);CHKERRQ(ierr);
193*5c6c1daeSBarry Smith 
194*5c6c1daeSBarry Smith     /* Handle specific random generator's options */
195*5c6c1daeSBarry Smith     if (rnd->ops->setfromoptions) {
196*5c6c1daeSBarry Smith       ierr = (*rnd->ops->setfromoptions)(rnd);CHKERRQ(ierr);
197*5c6c1daeSBarry Smith     }
198*5c6c1daeSBarry Smith     ierr = PetscOptionsInt("-random_seed","Seed to use to generate random numbers","PetscRandomSetSeed",0,&seed,&set);CHKERRQ(ierr);
199*5c6c1daeSBarry Smith     if (set) {
200*5c6c1daeSBarry Smith       ierr = PetscRandomSetSeed(rnd,(unsigned long int)seed);CHKERRQ(ierr);
201*5c6c1daeSBarry Smith       ierr = PetscRandomSeed(rnd);CHKERRQ(ierr);
202*5c6c1daeSBarry Smith     }
203*5c6c1daeSBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
204*5c6c1daeSBarry Smith   ierr = PetscRandomViewFromOptions(rnd, ((PetscObject)rnd)->name);CHKERRQ(ierr);
205*5c6c1daeSBarry Smith   PetscFunctionReturn(0);
206*5c6c1daeSBarry Smith }
207*5c6c1daeSBarry Smith 
208*5c6c1daeSBarry Smith #undef __FUNCT__
209*5c6c1daeSBarry Smith #define __FUNCT__ "PetscRandomView"
210*5c6c1daeSBarry Smith /*@C
211*5c6c1daeSBarry Smith    PetscRandomView - Views a random number generator object.
212*5c6c1daeSBarry Smith 
213*5c6c1daeSBarry Smith    Collective on PetscRandom
214*5c6c1daeSBarry Smith 
215*5c6c1daeSBarry Smith    Input Parameters:
216*5c6c1daeSBarry Smith +  rnd - The random number generator context
217*5c6c1daeSBarry Smith -  viewer - an optional visualization context
218*5c6c1daeSBarry Smith 
219*5c6c1daeSBarry Smith    Notes:
220*5c6c1daeSBarry Smith    The available visualization contexts include
221*5c6c1daeSBarry Smith +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
222*5c6c1daeSBarry Smith -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
223*5c6c1daeSBarry Smith          output where only the first processor opens
224*5c6c1daeSBarry Smith          the file.  All other processors send their
225*5c6c1daeSBarry Smith          data to the first processor to print.
226*5c6c1daeSBarry Smith 
227*5c6c1daeSBarry Smith    You can change the format the vector is printed using the
228*5c6c1daeSBarry Smith    option PetscViewerSetFormat().
229*5c6c1daeSBarry Smith 
230*5c6c1daeSBarry Smith    Level: beginner
231*5c6c1daeSBarry Smith 
232*5c6c1daeSBarry Smith .seealso:  PetscRealView(), PetscScalarView(), PetscIntView()
233*5c6c1daeSBarry Smith @*/
234*5c6c1daeSBarry Smith PetscErrorCode  PetscRandomView(PetscRandom rnd,PetscViewer viewer)
235*5c6c1daeSBarry Smith {
236*5c6c1daeSBarry Smith   PetscErrorCode    ierr;
237*5c6c1daeSBarry Smith   PetscBool         iascii;
238*5c6c1daeSBarry Smith 
239*5c6c1daeSBarry Smith   PetscFunctionBegin;
240*5c6c1daeSBarry Smith   PetscValidHeaderSpecific(rnd,PETSC_RANDOM_CLASSID,1);
241*5c6c1daeSBarry Smith   PetscValidType(rnd,1);
242*5c6c1daeSBarry Smith   if (!viewer) {
243*5c6c1daeSBarry Smith     ierr = PetscViewerASCIIGetStdout(((PetscObject)rnd)->comm,&viewer);CHKERRQ(ierr);
244*5c6c1daeSBarry Smith   }
245*5c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
246*5c6c1daeSBarry Smith   PetscCheckSameComm(rnd,1,viewer,2);
247*5c6c1daeSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
248*5c6c1daeSBarry Smith   if (iascii) {
249*5c6c1daeSBarry Smith     PetscMPIInt rank;
250*5c6c1daeSBarry Smith     ierr = MPI_Comm_rank(((PetscObject)rnd)->comm,&rank);CHKERRQ(ierr);
251*5c6c1daeSBarry Smith     ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_TRUE);CHKERRQ(ierr);
252*5c6c1daeSBarry Smith     ierr = PetscViewerASCIISynchronizedPrintf(viewer,"[%D] Random type %s, seed %D\n",rank,((PetscObject)rnd)->type_name,rnd->seed);CHKERRQ(ierr);
253*5c6c1daeSBarry Smith     ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
254*5c6c1daeSBarry Smith     ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_FALSE);CHKERRQ(ierr);
255*5c6c1daeSBarry Smith   } else {
256*5c6c1daeSBarry Smith     const char *tname;
257*5c6c1daeSBarry Smith     ierr = PetscObjectGetName((PetscObject)viewer,&tname);CHKERRQ(ierr);
258*5c6c1daeSBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Viewer type %s not supported for this object",tname);
259*5c6c1daeSBarry Smith   }
260*5c6c1daeSBarry Smith   PetscFunctionReturn(0);
261*5c6c1daeSBarry Smith }
262*5c6c1daeSBarry Smith 
263*5c6c1daeSBarry Smith #undef  __FUNCT__
264*5c6c1daeSBarry Smith #define __FUNCT__ "PetscRandomViewFromOptions"
265*5c6c1daeSBarry Smith /*@
266*5c6c1daeSBarry Smith   PetscRandomViewFromOptions - This function visualizes the type and the seed of the generated random numbers based upon user options.
267*5c6c1daeSBarry Smith 
268*5c6c1daeSBarry Smith   Collective on PetscRandom
269*5c6c1daeSBarry Smith 
270*5c6c1daeSBarry Smith   Input Parameters:
271*5c6c1daeSBarry Smith . rnd   - The random number generator context
272*5c6c1daeSBarry Smith . title - The title
273*5c6c1daeSBarry Smith 
274*5c6c1daeSBarry Smith   Level: intermediate
275*5c6c1daeSBarry Smith 
276*5c6c1daeSBarry Smith .keywords: PetscRandom, view, options, database
277*5c6c1daeSBarry Smith .seealso: PetscRandomSetFromOptions()
278*5c6c1daeSBarry Smith @*/
279*5c6c1daeSBarry Smith PetscErrorCode  PetscRandomViewFromOptions(PetscRandom rnd, char *title)
280*5c6c1daeSBarry Smith {
281*5c6c1daeSBarry Smith   PetscBool      opt = PETSC_FALSE;
282*5c6c1daeSBarry Smith   PetscViewer    viewer;
283*5c6c1daeSBarry Smith   char           typeName[1024];
284*5c6c1daeSBarry Smith   char           fileName[PETSC_MAX_PATH_LEN];
285*5c6c1daeSBarry Smith   size_t         len;
286*5c6c1daeSBarry Smith 
287*5c6c1daeSBarry Smith   PetscErrorCode ierr;
288*5c6c1daeSBarry Smith 
289*5c6c1daeSBarry Smith   PetscFunctionBegin;
290*5c6c1daeSBarry Smith   ierr = PetscOptionsGetBool(((PetscObject)rnd)->prefix, "-random_view", &opt,PETSC_NULL);CHKERRQ(ierr);
291*5c6c1daeSBarry Smith   if (opt) {
292*5c6c1daeSBarry Smith     ierr = PetscOptionsGetString(((PetscObject)rnd)->prefix, "-random_view", typeName, 1024, &opt);CHKERRQ(ierr);
293*5c6c1daeSBarry Smith     ierr = PetscStrlen(typeName, &len);CHKERRQ(ierr);
294*5c6c1daeSBarry Smith     if (len > 0) {
295*5c6c1daeSBarry Smith       ierr = PetscViewerCreate(((PetscObject)rnd)->comm, &viewer);CHKERRQ(ierr);
296*5c6c1daeSBarry Smith       ierr = PetscViewerSetType(viewer, typeName);CHKERRQ(ierr);
297*5c6c1daeSBarry Smith       ierr = PetscOptionsGetString(((PetscObject)rnd)->prefix, "-random_view_file", fileName, 1024, &opt);CHKERRQ(ierr);
298*5c6c1daeSBarry Smith       if (opt) {
299*5c6c1daeSBarry Smith         ierr = PetscViewerFileSetName(viewer, fileName);CHKERRQ(ierr);
300*5c6c1daeSBarry Smith       } else {
301*5c6c1daeSBarry Smith         ierr = PetscViewerFileSetName(viewer, ((PetscObject)rnd)->name);CHKERRQ(ierr);
302*5c6c1daeSBarry Smith       }
303*5c6c1daeSBarry Smith       ierr = PetscRandomView(rnd, viewer);CHKERRQ(ierr);
304*5c6c1daeSBarry Smith       ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
305*5c6c1daeSBarry Smith       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
306*5c6c1daeSBarry Smith     } else {
307*5c6c1daeSBarry Smith       PetscViewer viewer;
308*5c6c1daeSBarry Smith       ierr = PetscViewerASCIIGetStdout(((PetscObject)rnd)->comm,&viewer);CHKERRQ(ierr);
309*5c6c1daeSBarry Smith       ierr = PetscRandomView(rnd, viewer);CHKERRQ(ierr);
310*5c6c1daeSBarry Smith     }
311*5c6c1daeSBarry Smith   }
312*5c6c1daeSBarry Smith   PetscFunctionReturn(0);
313*5c6c1daeSBarry Smith }
314*5c6c1daeSBarry Smith 
315*5c6c1daeSBarry Smith #if defined(PETSC_HAVE_AMS)
316*5c6c1daeSBarry Smith #undef __FUNCT__
317*5c6c1daeSBarry Smith #define __FUNCT__ "PetscRandomPublish_Petsc"
318*5c6c1daeSBarry Smith static PetscErrorCode PetscRandomPublish_Petsc(PetscObject obj)
319*5c6c1daeSBarry Smith {
320*5c6c1daeSBarry Smith   PetscRandom    rand = (PetscRandom) obj;
321*5c6c1daeSBarry Smith   PetscErrorCode ierr;
322*5c6c1daeSBarry Smith 
323*5c6c1daeSBarry Smith   PetscFunctionBegin;
324*5c6c1daeSBarry Smith   ierr = AMS_Memory_add_field(obj->amem,"Low",&rand->low,1,AMS_DOUBLE,AMS_READ,AMS_COMMON,AMS_REDUCT_UNDEF);CHKERRQ(ierr);
325*5c6c1daeSBarry Smith   PetscFunctionReturn(0);
326*5c6c1daeSBarry Smith }
327*5c6c1daeSBarry Smith #endif
328*5c6c1daeSBarry Smith 
329*5c6c1daeSBarry Smith #undef __FUNCT__
330*5c6c1daeSBarry Smith #define __FUNCT__ "PetscRandomCreate"
331*5c6c1daeSBarry Smith /*@
332*5c6c1daeSBarry Smith    PetscRandomCreate - Creates a context for generating random numbers,
333*5c6c1daeSBarry Smith    and initializes the random-number generator.
334*5c6c1daeSBarry Smith 
335*5c6c1daeSBarry Smith    Collective on MPI_Comm
336*5c6c1daeSBarry Smith 
337*5c6c1daeSBarry Smith    Input Parameters:
338*5c6c1daeSBarry Smith +  comm - MPI communicator
339*5c6c1daeSBarry Smith 
340*5c6c1daeSBarry Smith    Output Parameter:
341*5c6c1daeSBarry Smith .  r  - the random number generator context
342*5c6c1daeSBarry Smith 
343*5c6c1daeSBarry Smith    Level: intermediate
344*5c6c1daeSBarry Smith 
345*5c6c1daeSBarry Smith    Notes:
346*5c6c1daeSBarry Smith    The random type has to be set by PetscRandomSetType().
347*5c6c1daeSBarry Smith 
348*5c6c1daeSBarry Smith    This is only a primative "parallel" random number generator, it should NOT
349*5c6c1daeSBarry Smith    be used for sophisticated parallel Monte Carlo methods since it will very likely
350*5c6c1daeSBarry Smith    not have the correct statistics across processors. You can provide your own
351*5c6c1daeSBarry Smith    parallel generator using PetscRandomRegister();
352*5c6c1daeSBarry Smith 
353*5c6c1daeSBarry Smith    If you create a PetscRandom() using PETSC_COMM_SELF on several processors then
354*5c6c1daeSBarry Smith    the SAME random numbers will be generated on all those processors. Use PETSC_COMM_WORLD
355*5c6c1daeSBarry Smith    or the appropriate parallel communicator to eliminate this issue.
356*5c6c1daeSBarry Smith 
357*5c6c1daeSBarry Smith    Use VecSetRandom() to set the elements of a vector to random numbers.
358*5c6c1daeSBarry Smith 
359*5c6c1daeSBarry Smith    Example of Usage:
360*5c6c1daeSBarry Smith .vb
361*5c6c1daeSBarry Smith       PetscRandomCreate(PETSC_COMM_SELF,&r);
362*5c6c1daeSBarry Smith       PetscRandomSetType(r,PETSCRAND48);
363*5c6c1daeSBarry Smith       PetscRandomGetValue(r,&value1);
364*5c6c1daeSBarry Smith       PetscRandomGetValueReal(r,&value2);
365*5c6c1daeSBarry Smith       PetscRandomDestroy(&r);
366*5c6c1daeSBarry Smith .ve
367*5c6c1daeSBarry Smith 
368*5c6c1daeSBarry Smith    Concepts: random numbers^creating
369*5c6c1daeSBarry Smith 
370*5c6c1daeSBarry Smith .seealso: PetscRandomSetType(), PetscRandomGetValue(), PetscRandomGetValueReal(), PetscRandomSetInterval(),
371*5c6c1daeSBarry Smith           PetscRandomDestroy(), VecSetRandom(), PetscRandomType
372*5c6c1daeSBarry Smith @*/
373*5c6c1daeSBarry Smith 
374*5c6c1daeSBarry Smith PetscErrorCode  PetscRandomCreate(MPI_Comm comm,PetscRandom *r)
375*5c6c1daeSBarry Smith {
376*5c6c1daeSBarry Smith   PetscRandom    rr;
377*5c6c1daeSBarry Smith   PetscErrorCode ierr;
378*5c6c1daeSBarry Smith   PetscMPIInt    rank;
379*5c6c1daeSBarry Smith 
380*5c6c1daeSBarry Smith   PetscFunctionBegin;
381*5c6c1daeSBarry Smith   PetscValidPointer(r,3);
382*5c6c1daeSBarry Smith   *r = PETSC_NULL;
383*5c6c1daeSBarry Smith #ifndef PETSC_USE_DYNAMIC_LIBRARIES
384*5c6c1daeSBarry Smith   ierr = PetscRandomInitializePackage(PETSC_NULL);CHKERRQ(ierr);
385*5c6c1daeSBarry Smith #endif
386*5c6c1daeSBarry Smith 
387*5c6c1daeSBarry Smith   ierr = PetscHeaderCreate(rr,_p_PetscRandom,struct _PetscRandomOps,PETSC_RANDOM_CLASSID,-1,"PetscRandom","Random number generator","Sys",comm,PetscRandomDestroy,0);CHKERRQ(ierr);
388*5c6c1daeSBarry Smith 
389*5c6c1daeSBarry Smith   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
390*5c6c1daeSBarry Smith   rr->data  = PETSC_NULL;
391*5c6c1daeSBarry Smith   rr->low   = 0.0;
392*5c6c1daeSBarry Smith   rr->width = 1.0;
393*5c6c1daeSBarry Smith   rr->iset  = PETSC_FALSE;
394*5c6c1daeSBarry Smith   rr->seed  = 0x12345678 + 76543*rank;
395*5c6c1daeSBarry Smith #if defined(PETSC_HAVE_AMS)
396*5c6c1daeSBarry Smith   ((PetscObject)rr)->bops->publish = PetscRandomPublish_Petsc;
397*5c6c1daeSBarry Smith #endif
398*5c6c1daeSBarry Smith   *r = rr;
399*5c6c1daeSBarry Smith   PetscFunctionReturn(0);
400*5c6c1daeSBarry Smith }
401*5c6c1daeSBarry Smith 
402*5c6c1daeSBarry Smith #undef __FUNCT__
403*5c6c1daeSBarry Smith #define __FUNCT__ "PetscRandomSeed"
404*5c6c1daeSBarry Smith /*@
405*5c6c1daeSBarry Smith    PetscRandomSeed - Seed the generator.
406*5c6c1daeSBarry Smith 
407*5c6c1daeSBarry Smith    Not collective
408*5c6c1daeSBarry Smith 
409*5c6c1daeSBarry Smith    Input Parameters:
410*5c6c1daeSBarry Smith .  r - The random number generator context
411*5c6c1daeSBarry Smith 
412*5c6c1daeSBarry Smith    Level: intermediate
413*5c6c1daeSBarry Smith 
414*5c6c1daeSBarry Smith    Usage:
415*5c6c1daeSBarry Smith       PetscRandomSetSeed(r,a positive integer);
416*5c6c1daeSBarry Smith       PetscRandomSeed(r);  PetscRandomGetValue() will now start with the new seed.
417*5c6c1daeSBarry Smith 
418*5c6c1daeSBarry Smith       PetscRandomSeed(r) without a call to PetscRandomSetSeed() re-initializes
419*5c6c1daeSBarry Smith         the seed. The random numbers generated will be the same as before.
420*5c6c1daeSBarry Smith 
421*5c6c1daeSBarry Smith    Concepts: random numbers^seed
422*5c6c1daeSBarry Smith 
423*5c6c1daeSBarry Smith .seealso: PetscRandomCreate(), PetscRandomGetSeed(), PetscRandomSetSeed()
424*5c6c1daeSBarry Smith @*/
425*5c6c1daeSBarry Smith PetscErrorCode  PetscRandomSeed(PetscRandom r)
426*5c6c1daeSBarry Smith {
427*5c6c1daeSBarry Smith   PetscErrorCode ierr;
428*5c6c1daeSBarry Smith 
429*5c6c1daeSBarry Smith   PetscFunctionBegin;
430*5c6c1daeSBarry Smith   PetscValidHeaderSpecific(r,PETSC_RANDOM_CLASSID,1);
431*5c6c1daeSBarry Smith   PetscValidType(r,1);
432*5c6c1daeSBarry Smith 
433*5c6c1daeSBarry Smith   ierr = (*r->ops->seed)(r);CHKERRQ(ierr);
434*5c6c1daeSBarry Smith   ierr = PetscObjectStateIncrease((PetscObject)r);CHKERRQ(ierr);
435*5c6c1daeSBarry Smith   PetscFunctionReturn(0);
436*5c6c1daeSBarry Smith }
437*5c6c1daeSBarry Smith 
438