Arcane  v3.14.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
PDESRandomNumberGeneratorService.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2022 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* PDESRandomNumberGeneratorService.cc (C) 2000-2022 */
9/* */
10/* Implémentation d'un générateur de nombres aléatoires LCG. */
11/* Inspiré du générateur de Quicksilver (LLNL) et des pages 302-304 */
12/* du livre : */
13/* */
14/* Numerical Recipes in C */
15/* The Art of Scientific Computing */
16/* Second Edition */
17/*---------------------------------------------------------------------------*/
18/*---------------------------------------------------------------------------*/
19
20#include "arcane/std/PDESRandomNumberGeneratorService.h"
21
22/*---------------------------------------------------------------------------*/
23/*---------------------------------------------------------------------------*/
24
25namespace Arcane
26{
27
28/*---------------------------------------------------------------------------*/
29/*---------------------------------------------------------------------------*/
30
33{
34 if (m_with_option) {
35 m_seed = options()->getInitialSeed();
36 }
37 else {
38 m_seed = 4294967297;
39 }
40 return true;
41}
42
45{
47 if (helper.sizeOfSeed() != m_size_of_seed) {
48 return false;
49 }
50 helper.value(m_seed);
51 return true;
52}
53
59
65
68{
69 return m_size_of_seed;
70}
71
72// Les sauts négatifs sont supportés.
75{
76 // Pas besoin de faire de saut si leap == 0.
77 if (leap != 0) {
78 _ran4(&m_seed, leap - 1);
79 }
80 Int64 spawned_seed = _hashState(m_seed);
81 _ran4(&m_seed, 0);
82
84}
85
86// Les sauts négatifs sont supportés.
89{
90 if(parent_seed.size() != m_size_of_seed) {
91 ARCANE_FATAL("Erreur de taille de graine.");
92 }
93 Int64* i_seed = (Int64*)parent_seed.data();
94
95 // Pas besoin de faire de saut si leap == 0.
96 if (leap != 0) {
97 _ran4(i_seed, leap - 1);
98 }
100 _ran4(i_seed, 0);
102}
103
104// Les sauts négatifs sont supportés.
107{
108 return _ran4(&m_seed, leap);
109}
110
111// Les sauts négatifs sont supportés.
114{
115 if(seed.size() != m_size_of_seed) {
116 ARCANE_FATAL("Erreur de taille de graine.");
117 }
118 Int64* i_seed = (Int64*)seed.data();
119 Real fin = _ran4(i_seed, leap);
120 return fin;
121}
122
123/*---------------------------------------------------------------------------*/
124/*---------------------------------------------------------------------------*/
125
139
149{
151 reconstructed = static_cast<uint64_t>(front_bits);
152 temp = static_cast<uint64_t>(back_bits);
153
154 // shift first bits 32 bits to left
156
157 // temp must be masked to kill leading 1's. Then 'or' with reconstructed
158 // to get the last bits in
159 reconstructed |= (temp & 0x00000000ffffffff);
160
161 return reconstructed;
162}
163
177{
178 const Integer NITER = 4;
179 const uint32_t c1[] = { 0xbaa96887L, 0x1e17d32cL, 0x03bcdc3cL, 0x0f33d1b2L };
180 const uint32_t c2[] = { 0x4b0f3b58L, 0xe874f0c3L, 0x6955c5a6L, 0x55a7ca46L };
181
182 for (Integer i = 0; i < NITER; i++) {
183 uint32_t iswap = (*irword);
184 uint32_t ia = iswap ^ c1[i];
185 uint32_t itmpl = ia & 0xffff;
186 uint32_t itmph = ia >> 16;
187 uint32_t ib = itmpl * itmpl + ~(itmph * itmph);
188
189 *irword = (*lword) ^ (((ia = (ib >> 16) | ((ib & 0xffff) << 16)) ^ c2[i]) + itmpl * itmph);
190 *lword = iswap;
191 }
192}
193
212
228_ran4(Int64* seed, Integer leap)
229{
232 front_bits += leap;
233
236 _psdes(&lword, &irword);
237
238 *seed = (Int64)_reconstructUInt64(++front_bits, back_bits);
239
240 volatile Real fin = 5.4210108624275222e-20 * (Real)_reconstructUInt64(lword, irword);
241 return fin;
242}
243
244/*---------------------------------------------------------------------------*/
245/*---------------------------------------------------------------------------*/
246
247} // End namespace Arcane
248
249/*---------------------------------------------------------------------------*/
250/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
CaseOptionsPDESRandomNumberGenerator * options() const
Options du jeu de données du service.
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
ByteConstArrayView viewSeed() override
Méthode permettant de récupérer une vue constante sur la graine actuelle.
ByteUniqueArray generateRandomSeed(Integer leap=0) override
Méthode permettant de générer une graine "enfant" à partir d'une graine "parent".
uint64_t _hashState(uint64_t initial_number)
Méthode permettant de générer une nouvelle graine avec l'algorithme pseudo-DES.
Real generateRandomNumber(Integer leap) override
Méthode permettant de générer un nombre aléatoire avec la graine en mémoire.
Integer neededSizeOfSeed() override
Méthode permettant de connaitre la taille de seed nécessaire pour l'implémentation.
bool initSeed() override
Méthode permettant d'initialiser le service.
void _psdes(uint32_t *lword, uint32_t *irword)
Algorithme Pseudo-DES du livre : Numerical Recipes in C The Art of Scientific Computing Second Editio...
uint64_t _reconstructUInt64(uint32_t front_bits, uint32_t back_bits)
Méthode permettant de regrouper deux uint32 en un uint64.
ByteUniqueArray emptySeed() override
Méthode permettant de récupérer une graine vide de bonne taille.
void _breakupUInt64(uint64_t uint64_in, uint32_t *front_bits, uint32_t *back_bits)
Méthode permettant de découper un uint64 en deux uint32.
Real _ran4(Int64 *seed, Integer leap)
Méthode permettant de générer des nombres pseudo-aléatoire à partir d'une graine.
Classe permettant de manipuler facilement une graine.
ByteConstArrayView constView() const
Méthode permettant de récupérer une vue constante.
ByteUniqueArray copy()
Méthode permettant de récupérer une copie du tableau de Byte.
Vue modifiable d'un tableau d'un type T.
constexpr Integer size() const noexcept
Retourne la taille du tableau.
constexpr const_pointer data() const noexcept
Pointeur sur le début de la vue.
Vue constante d'un tableau de type T.
Vecteur 1D de données avec sémantique par valeur (style STL).
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
UniqueArray< Byte > ByteUniqueArray
Tableau dynamique à une dimension de caractères.
Definition UtilsTypes.h:509