OOFEM  2.4
OOFEM.org - Object Oriented Finite Element Solver
localgaussianrandomfunction.C
Go to the documentation of this file.
1 /*
2  *
3  * ##### ##### ###### ###### ### ###
4  * ## ## ## ## ## ## ## ### ##
5  * ## ## ## ## #### #### ## # ##
6  * ## ## ## ## ## ## ## ##
7  * ## ## ## ## ## ## ## ##
8  * ##### ##### ## ###### ## ##
9  *
10  *
11  * OOFEM : Object Oriented Finite Element Code
12  *
13  * Copyright (C) 1993 - 2013 Borek Patzak
14  *
15  *
16  *
17  * Czech Technical University, Faculty of Civil Engineering,
18  * Department of Structural Mechanics, 166 29 Prague, Czech Republic
19  *
20  * This library is free software; you can redistribute it and/or
21  * modify it under the terms of the GNU Lesser General Public
22  * License as published by the Free Software Foundation; either
23  * version 2.1 of the License, or (at your option) any later version.
24  *
25  * This program is distributed in the hope that it will be useful,
26  * but WITHOUT ANY WARRANTY; without even the implied warranty of
27  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28  * Lesser General Public License for more details.
29  *
30  * You should have received a copy of the GNU Lesser General Public
31  * License along with this library; if not, write to the Free Software
32  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
33  */
34 
36 #include "mathfem.h"
37 #include "classfactory.h"
38 
39 #include <ctime>
40 
41 namespace oofem {
42 REGISTER_Function(LocalGaussianRandomFunction);
43 
45 { }
46 
48 { }
49 
50 void
51 LocalGaussianRandomFunction :: evaluate(FloatArray &answer, const std :: map< std :: string, FunctionArgument > &valDict, GaussPoint *gp, double param)
52 {
53  answer = FloatArray{evaluateAtTime(0)};
54 }
55 
56 double
58 {
60 }
61 
62 double
64 {
65  OOFEM_ERROR("Can't generate velocity of random number");
66  return 0.;
67 }
68 
69 double
71 {
72  OOFEM_ERROR("Can't generate acceleration of random number");
73  return 0.;
74 }
75 
78 {
79  IRResultType result; // Required by IR_GIVE_FIELD macro
80 
83  randomInteger = ( long ) ( -time(NULL) );
84  int seed = 0;
86  if ( seed ) {
87  randomInteger = seed;
88  }
89 
90  return IRRT_OK;
91 }
92 
93 #define IA 16807
94 #define IM 2147483647
95 #define AM ( 1.0 / IM )
96 #define IQ 127773
97 #define IR 2836
98 #define NTAB 32
99 #define NDIV ( 1 + ( IM - 1 ) / NTAB )
100 #define EPS 1.2e-7
101 #define RNMX ( 1.0 - EPS )
102 
104 {
105  long k;
106  static long iy = 0;
107  static long iv [ NTAB ];
108  double temp;
109 
110  if ( * idum <= 0 || !iy ) {
111  if ( -( * idum ) < 1 ) {
112  * idum = 1;
113  } else {
114  * idum = -( * idum );
115  }
116 
117  for ( int j = NTAB + 7; j >= 0; j-- ) {
118  k = ( * idum ) / IQ;
119  * idum = IA * ( * idum - k * IQ ) - IR * k;
120  if ( * idum < 0 ) {
121  * idum += IM;
122  }
123 
124  if ( j < NTAB ) {
125  iv [ j ] = * idum;
126  }
127  }
128 
129  iy = iv [ 0 ];
130  }
131 
132  k = ( * idum ) / IQ;
133  * idum = IA * ( * idum - k * IQ ) - IR * k;
134  if ( * idum < 0 ) {
135  * idum += IM;
136  }
137 
138  int j = iy / NDIV;
139  iy = iv [ j ];
140  iv [ j ] = * idum;
141  if ( ( temp = AM * iy ) > RNMX ) {
142  return RNMX;
143  } else {
144  return temp;
145  }
146 }
147 
148 double LocalGaussianRandomFunction :: normalCdfInverse(double cdf, double a, double b)
149 {
150  double x;
151  double x2;
152  if ( cdf < 0.0 || 1.0 < cdf ) {
153  OOFEM_ERROR("NORMAL_CDF_INV - Fatal error!\nCDF < 0 or 1 < CDF.");
154  }
155 
156  x2 = normal01CdfInverse(cdf);
157  x = a + b * x2;
158  return x;
159 }
160 
162 {
163  double a [ 8 ] = {
164  3.3871328727963666080, 1.3314166789178437745e+2,
165  1.9715909503065514427e+3, 1.3731693765509461125e+4,
166  4.5921953931549871457e+4, 6.7265770927008700853e+4,
167  3.3430575583588128105e+4, 2.5090809287301226727e+3
168  };
169  double b [ 8 ] = {
170  1.0, 4.2313330701600911252e+1,
171  6.8718700749205790830e+2, 5.3941960214247511077e+3,
172  2.1213794301586595867e+4, 3.9307895800092710610e+4,
173  2.8729085735721942674e+4, 5.2264952788528545610e+3
174  };
175  double c [ 8 ] = {
176  1.42343711074968357734, 4.63033784615654529590,
177  5.76949722146069140550, 3.64784832476320460504,
178  1.27045825245236838258, 2.41780725177450611770e-1,
179  2.27238449892691845833e-2, 7.74545014278341407640e-4
180  };
181  double const1 = 0.180625;
182  double const2 = 1.6;
183  double d [ 8 ] = {
184  1.0, 2.05319162663775882187,
185  1.67638483018380384940, 6.89767334985100004550e-1,
186  1.48103976427480074590e-1, 1.51986665636164571966e-2,
187  5.47593808499534494600e-4, 1.05075007164441684324e-9
188  };
189  double e [ 8 ] = {
190  6.65790464350110377720, 5.46378491116411436990,
191  1.78482653991729133580, 2.96560571828504891230e-1,
192  2.65321895265761230930e-2, 1.24266094738807843860e-3,
193  2.71155556874348757815e-5, 2.01033439929228813265e-7
194  };
195  double f [ 8 ] = {
196  1.0, 5.99832206555887937690e-1,
197  1.36929880922735805310e-1, 1.48753612908506148525e-2,
198  7.86869131145613259100e-4, 1.84631831751005468180e-5,
199  1.42151175831644588870e-7, 2.04426310338993978564e-15
200  };
201  double q;
202  double r;
203  double split1 = 0.425;
204  double split2 = 5.0;
205  double value;
206 
207  if ( p <= 0.0 ) {
208  value = -HUGE_VAL;
209  return value;
210  }
211 
212  if ( 1.0 <= p ) {
213  value = HUGE_VAL;
214  return value;
215  }
216 
217  q = p - 0.5;
218 
219  if ( fabs(q) <= split1 ) {
220  r = const1 - q * q;
221  value = q * dpolyValue(8, a, r) / dpolyValue(8, b, r);
222  } else {
223  if ( q < 0.0 ) {
224  r = p;
225  } else {
226  r = 1.0 - p;
227  }
228 
229  if ( r <= 0.0 ) {
230  OOFEM_ERROR("r < 0.0!");
231  return -1.0;
232  }
233 
234  r = sqrt( -log(r) );
235  if ( r <= split2 ) {
236  r = r - const2;
237  value = dpolyValue(8, c, r) / dpolyValue(8, d, r);
238  } else {
239  r = r - split2;
240  value = dpolyValue(8, e, r) / dpolyValue(8, f, r);
241  }
242 
243  if ( q < 0.0 ) {
244  value = -value;
245  }
246  }
247 
248  return value;
249 }
250 
251 
252 double LocalGaussianRandomFunction :: dpolyValue(int n, double a[], double x)
253 {
254  int i;
255  double value;
256  value = 0.0;
257  for ( i = n - 1; 0 <= i; i-- ) {
258  value = value * x + a [ i ];
259  }
260 
261  return value;
262 }
263 } // end namespace oofem
virtual void evaluate(FloatArray &answer, const std::map< std::string, FunctionArgument > &valDict, GaussPoint *gp=NULL, double param=0.)
Returns the value of the function for given input.
Class and object Domain.
Definition: domain.h:115
double normal01CdfInverse(double p)
Computes the inverse of the normal distribution.
LocalGaussianRandomFunction(int n, Domain *d)
Constructor.
#define NDIV
virtual double evaluateAtTime(double t)
Returns the value of the function at given time.
REGISTER_Function(CalculatorFunction)
virtual double evaluateVelocityAtTime(double t)
Returns the first time derivative of the function at given time.
double mean
Gauss distribution parameters.
virtual double evaluateAccelerationAtTime(double t)
Returns the second time derivative of the function at given time.
#define _IFT_LocalGaussianRandomFunction_variance
#define OOFEM_ERROR(...)
Definition: error.h:61
long randomInteger
Integer which is the input of the pseudo-random number generator.
#define NTAB
Class representing vector of real numbers.
Definition: floatarray.h:82
#define _IFT_LocalGaussianRandomFunction_mean
virtual IRResultType initializeFrom(InputRecord *ir)
Initializes receiver according to object description stored in input record.
Abstract base class representing a function with vector input and output.
Definition: function.h:88
IRResultType
Type defining the return values of InputRecord reading operations.
Definition: irresulttype.h:47
Class representing the general Input Record.
Definition: inputrecord.h:101
double normalCdfInverse(double cdf, double a, double b)
Computes the inverse of the Gaussian CDF.
#define IR_GIVE_OPTIONAL_FIELD(__ir, __value, __id)
Macro facilitating the use of input record reading methods.
Definition: inputrecord.h:78
the oofem namespace is to define a context or scope in which all oofem names are defined.
#define IR_GIVE_FIELD(__ir, __value, __id)
Macro facilitating the use of input record reading methods.
Definition: inputrecord.h:69
#define _IFT_LocalGaussianRandomFunction_seed
double ran1(long *idum)
Computes pseudo-random numbers.
Class representing integration point in finite element program.
Definition: gausspoint.h:93
double dpolyValue(int n, double a[], double x)

This page is part of the OOFEM documentation. Copyright (c) 2011 Borek Patzak
Project e-mail: info@oofem.org
Generated at Tue Jan 2 2018 20:07:29 for OOFEM by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2011