xref: /petsc/src/sys/classes/random/impls/sprng/sprng.c (revision 98d129c30f3ee9fdddc40fdbc5a989b7be64f888)
1 #include <petsc/private/randomimpl.h>
2 
3 #define USE_MPI
4 #define SIMPLE_SPRNG
5 EXTERN_C_BEGIN
6 #include <sprng.h>
7 EXTERN_C_END
8 
9 static PetscErrorCode PetscRandomSeed_Sprng(PetscRandom r)
10 {
11   PetscFunctionBegin;
12   init_sprng(r->seed, SPRNG_DEFAULT);
13   PetscFunctionReturn(PETSC_SUCCESS);
14 }
15 
16 static PetscErrorCode PetscRandomGetValue_Sprng(PetscRandom r, PetscScalar *val)
17 {
18   PetscFunctionBegin;
19 #if defined(PETSC_USE_COMPLEX)
20   if (r->iset) {
21     *val = PetscRealPart(r->width) * sprng() + PetscRealPart(r->low) + (PetscImaginaryPart(r->width) * sprng() + PetscImaginaryPart(r->low)) * PETSC_i;
22   } else {
23     *val = sprng() + sprng() * PETSC_i;
24   }
25 #else
26   if (r->iset) *val = r->width * sprng() + r->low;
27   else *val = sprng();
28 #endif
29   PetscFunctionReturn(PETSC_SUCCESS);
30 }
31 
32 static PetscErrorCode PetscRandomGetValueReal_Sprng(PetscRandom r, PetscReal *val)
33 {
34   PetscFunctionBegin;
35 #if defined(PETSC_USE_COMPLEX)
36   if (r->iset) *val = PetscRealPart(r->width) * sprng() + PetscRealPart(r->low);
37   else *val = sprng();
38 #else
39   if (r->iset) *val = r->width * sprng() + r->low;
40   else *val = sprng();
41 #endif
42   PetscFunctionReturn(PETSC_SUCCESS);
43 }
44 
45 static struct _PetscRandomOps PetscRandomOps_Values = {
46   PetscDesignatedInitializer(seed, PetscRandomSeed_Sprng),
47   PetscDesignatedInitializer(getvalue, PetscRandomGetValue_Sprng),
48   PetscDesignatedInitializer(getvaluereal, PetscRandomGetValueReal_Sprng),
49 };
50 
51 /*MC
52    PETSCSPRNG - access to the publicly available random number generator sprng
53 
54    Options Database Key:
55 . -random_type <rand,rand48,sprng> - select the random number generator at runtime
56 
57   Level: beginner
58 
59    Note:
60    PETSc must be ./configure with the option --download-sprng to use this random number generator.
61 
62    Developer Note:
63    This is NOT currently using a parallel random number generator. Sprng does have
64    an MPI version we should investigate.
65 
66 .seealso: `RandomCreate()`, `RandomSetType()`, `PETSCRAND`, `PETSCRAND48`, `PetscRandomSetFromOptions()`
67 M*/
68 
69 PETSC_EXTERN PetscErrorCode PetscRandomCreate_Sprng(PetscRandom r)
70 {
71   PetscFunctionBegin;
72   r->ops[0] = PetscRandomOps_Values;
73   PetscCall(PetscObjectChangeTypeName((PetscObject)r, PETSCSPRNG));
74   PetscFunctionReturn(PETSC_SUCCESS);
75 }
76