CFD Online Discussion Forums

CFD Online Discussion Forums (https://www.cfd-online.com/Forums/)
-   Fluent UDF and Scheme Programming (https://www.cfd-online.com/Forums/fluent-udf/)
-   -   random number generation (https://www.cfd-online.com/Forums/fluent-udf/167076-random-number-generation.html)

hwet February 23, 2016 02:39

random number generation
 
Hi
I am trying to generate random numbers using fluent macros from random.h.

I am using
Code:

uniform_random();
which gives values between 0 and 1 but these values are the same everytime they are generated.

For example
Particle A will have 0.05 and B will have 0.75 generated but this will be the same every time the simulation is run.

So added
Code:

set_random_seed(long newseed)
(also in random.h) and set newseed to
Quote:

time(NULL)
for the
Code:

uniform_random()
, this generates a new random number every time but this random number is the same for all the particles.
That is, if it generated 0.567 for particle A, that for particle B will also be 0.567.

I want random numbers which are different every time for different particles. Now there is also another macro listed which I think I need to use but I dont know how.

It is
Code:

getUniformRandom(uniform_random_seed *seed);
.

Also, I have tried using
Code:

srand
and
Code:

rand()
which gives a new seed to the random numbers every time but the problem is the same as with the fluent macros, just that with these the random numbers can be from 1 to upto (~32000) to be exact and this will need more lines to make it between 0 and 1 only, but then again the problem remains as above.

So anyone knows how to put this right?:rolleyes:

pakk February 24, 2016 05:47

I never worked with the Fluent macros for random numbers, for me the following gives a uniform distribution between zero and one:
Code:

((float) rand()/RAND_MAX)
The Fluent macros might have better randomness or be faster, I don't know, but for me this was always sufficient.

hwet February 24, 2016 07:19

With this one and the fluent macros, it gives the same random numbers every time you track the particles.

So if I am tracking particles A and B, they will be given random numbers say 0.1 0.2 but if I track them again they will get the same numbers again.

Adding srand(time(NULL)) gives them all the same random number. So both A and B will have a random number say 0.5 which will change when I track them again to say 0.7 but both will have the same random number.

I want to generate random numbers which are different overtime for all the particles.

pakk February 24, 2016 07:53

Quote:

Originally Posted by hwet (Post 586645)
With this one and the fluent macros, it gives the same random numbers every time you track the particles.

So if I am tracking particles A and B, they will be given random numbers say 0.1 0.2 but if I track them again they will get the same numbers again.

Yes, but for me that is a good thing, this means that results are reproducible.

Quote:

Adding srand(time(NULL)) gives them all the same random number. So both A and B will have a random number say 0.5 which will change when I track them again to say 0.7 but both will have the same random number.

I want to generate random numbers which are different overtime for all the particles.
I understand what you want. And when I add srand(time(NULL)), I get different numbers for A and B. So if I run it now, A=0.1 and B=0.4, and if I do it again A=0.8 and B=0.2.

Maybe you use srand in the wrong way? Your code should call srand only one time, and rand many times. So don't do this pseudo-code:
Code:

for all particles {
  srand(time(NULL));
  A=rand();
}


But do this:
Code:

srand(time(NULL));
for all particles {
  A=rand();
}

The first code does not work as you expect, because time(NULL) changes only once per second, so you reset the random seed every time to the same value, so your "random number" will be the same if your calculation takes much less than one second.

hwet February 24, 2016 19:32

I was wrong, it was actually generating random numbers for the particles,which changed once every second.(makes sense).


The reason for printing the message (which i was printing to make sure the UDF was doing what I wanted) multiple times was because in my UDF i am considering particles to be trapped if they come across a water droplet based on (random number < particle collection efficiency criterion). Since a water droplet may occupy multiple cells the UDF is called again every time the particle position updates and the particle is not collected (random number > particle collection efficiency criterion) but is still in a cell where there is a water droplet.

Can you think of a way, where the particle if not collected as it comes into the first cell the water droplet occupies, does not interact with the water phase anymore. Since in reality the particle if not trapped by the water will actually follow a streamline around the droplet. But in my UDF the particle gets a chance to be captured by the droplet in every cell a single droplet occupies. (droplet occupies multiple cells)

pakk February 25, 2016 02:56

Add a particle-UDM that is initially 0.

If the particle is in a water cell, check if this particle-UDM is zero; if and only if it is zero, do your random thing and set the particle-UDM to one.

If the particle is not in a water cell, set the particle-UDM to zero.


(This is not the most memory-efficient method, since you will be using a float for one bit of information, but unless you have more than hundreds of millions of particles, it won't really matter.)

hwet February 28, 2016 20:53

Thanks for that idea.

I am trying to learn UDM's and going through the DEFINE_DPM_EROSION udf in the manual.

Code:

/* Average diameter of particles that hit the particular wall face:*/
F_UDMI(f,t,AVG_DIAMETER) = (P_DIAM(p)
+ num_in_data * F_UDMI(f,t,AVG_DIAMETER))
/ (num_in_data + 1);

Wondering where AVG_DIAMETER is calculated before being used in the UDM?
Thanks

`e` February 29, 2016 18:38

Quote:

Originally Posted by hwet (Post 587277)
Thanks for that idea.

I am trying to learn UDM's and going through the DEFINE_DPM_EROSION udf in the manual.

Code:

/* Average diameter of particles that hit the particular wall face:*/
F_UDMI(f,t,AVG_DIAMETER) = (P_DIAM(p)
+ num_in_data * F_UDMI(f,t,AVG_DIAMETER))
/ (num_in_data + 1);

Wondering where AVG_DIAMETER is calculated before being used in the UDM?
Thanks

'AVG_DIAMETER' is simply an integer for which UDM it belongs to. For their example, it's defined at the beginning of the source code:

Code:

enum /* Enumeration of used User-Defined Memory Locations. */
{
    NUM_OF_HITS, /* Number of particle hits into wall face considered.*/
    AVG_DIAMETER, /* Average diameter of particles that hit the wall. */
    AVG_RADI_VELO, /* Average radial velocity of "" "" ------------ */
    NUM_OF_USED_UDM
};


hwet February 29, 2016 19:11

So it is just an example and the average diameter is not actually calculated?

Sorry, I know I sound totally dumb...:D

`e` February 29, 2016 19:35

No, the average diameter of the particle parcels (they're using the DPM here) are stored in user-defined memory both at faces (with F_UDMI) and at cell centres (with C_UDMI).

Code:

/* Average diameter of particles that hit the particular wall face:*/
F_UDMI(f,t,AVG_DIAMETER) = (P_DIAM(p) + num_in_data * F_UDMI(f,t,AVG_DIAMETER)) / (num_in_data + 1);
C_UDMI(c0,t0,AVG_DIAMETER) = F_UDMI(f,t,AVG_DIAMETER);

It's a little complicated how to calculate the average diameter for polydispersed particles but if you follow through the code it should hopefully make sense (num_in_data is an integer number of parcels which have deposited on a particular face).


All times are GMT -4. The time now is 13:43.