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/)
-   -   Segmentation error in UDF for DPM model particle-wall interactions (https://www.cfd-online.com/Forums/fluent-udf/231131-segmentation-error-udf-dpm-model-particle-wall-interactions.html)

Achini October 22, 2020 14:27

Segmentation error in UDF for DPM model particle-wall interactions
 
Hello!

I wrote the below-mentioned code to model particle wall interactions. the force exerted by the wall only acts on particles injected by one injection(injection 0). i have set a loop to loop over the injections and for each particle, force exerted by the wall is calculted via a loop over the boundary cells.

when I run the code I get a warning and few errors.

warning C4700: uninitialized local variable 'd' used
and,

Error: received a fatal signal (Segmentation fault).
Error Object: #f

Error: Error Occured during handling message in WorkBench: An error occurred in FLUENT during execution of an internal command
An error occurred in FLUENT during execution of an internal command
Error Object: #f


Can someone check the code and help me with this?
Thank you!


#include "udf.h"
#include "dpm.h"
#include "dpm_mem.h"
#define K 0.00003

DEFINE_DPM_BODY_FORCE(particle_body_force,p,i) /* Fluent macro to define particle body force*/
{

double bf,dw,x1,y1,z1,x0,y0,z0,fmag,m,acc;
real bforce[ND_ND];
real xw[ND_ND];
real Force[ND_ND];
real n[ND_ND];
real a[ND_ND];

Domain *d;
/* Particle *p;*/
cell_t c;
Thread *t;
face_t f;

DEFINE_DPM_INJECTION_INIT ( injection0,I); /* Fluent macro to create a loop over the injections*/
{

Injection *Ilist = Get_dpm_injections(); /* to get a list of injections */

Injection *I; /* injection pointer */

Particle *p; /* particle pointer*/

loop(I, Ilist) /* looping over all injections */


loop(p,I->p) /* Standard Fluent Looping Macro to get particle streams in an Injection */
{

c = P_CELL(p); /* Get the cell and thread that the particle
is currently in */
t = P_CELL_THREAD(p);

m=P_MASS(p);

if (I=0)
{
x0 = P_POS(p)[0];
y0 = P_POS(p)[1];
z0 = P_POS(p)[2];

t = Lookup_Thread(d,5); /*create a thread pointing to the wall*/

begin_f_loop(f, t)
{

F_CENTROID(xw,f,t);

x1 = xw[0];
y1 = xw[1];
z1 = xw[2];

dw = sqrt(SQR(x1-x0) + SQR(y1-y0) + SQR(z1-z0)); /* wall to particle distance calculation*/

bf = K/(dw*dw*dw*dw*dw*dw*dw); /* calculation of the resulting force */

Force[0] = x1-x0; /* vector in the direction of the force */
Force[1] = y1-y0;
Force[2] = z1-z0;

fmag = NV_MAG(Force); /* Magnitude of the vector in the direction of the force*/

n[0]=Force[0]/fmag; /* unit vector in the diretion of the force*/
n[1]=Force[1]/fmag;
n[2]=Force[2]/fmag;


NV_V_VS(bforce, =, bforce, +, bforce, *, bf); /* calculates the sum of all interaction forces*/

}

end_f_loop(f, t)
}

else
{
bforce[0] = 0;
bforce[1] = 0;
bforce[2] = 0;
}
}

/*return;*/ /* Not sure whether this return functions needs to be added*/
}

a[0] = bforce[0]/m;
a[1] = bforce[1]/m;
a[2] = bforce[2]/m;

acc = sqrt( a[0]* a[0] + a[1]* a[1] + a[2]* a[2] );
return acc;

}

pakk October 22, 2020 22:38

The warning "uninitialized local variable 'd' used" means that you told Fluent to do something with variable 'd', but you forgot to tell Fluent what this variable is.

Specifically: you informed Fluent that it is a (pointer to) a domain, but not to which domain.

Look at examples in the Fluent manual where they use domains, there is a line with GET_DOMAIN or whatever that they use, I forgot the exact syntax.

AlexanderZ October 23, 2020 03:59

as Pakk said define domain, add following
Code:

d = Get_Domain(1);
also you are not able to define
Code:

DEFINE_DPM_INJECTION_INIT ( injection0,I); /* Fluent macro to create a loop over the injections*/
macro inside DEFINE_DPM_BODY_FORCE(particle_body_force,p,i)
they are two independent macros

Achini October 23, 2020 04:38

Thank you Pakk and AlexanderZ for your replies.

Instead of using the DEFINE_DPM_INJECTION_INIT macro, is there another way I can loop over the particles from a specific injection?

I want to calculate the body force exerted by the boundary wall, on each particle in injection 0.

Please help me with this.

Thank you!

Achini October 23, 2020 13:49

Hello AlexanderZ,

There are two injections in my system and the interaction force applied to the particles varies based on whether they were injected using injection 0 or injection 1.

I'd be grateful if could suggest a method to distinguish them.

Thanks again!

Achini October 23, 2020 17:22

Hello again!

I edited it this way placing the macros separately. What do you think about this?

#include "udf.h"
#include "dpm.h"
#include "dpm_mem.h"
#define K 0.00003


double bf,dw,x1,y1,z1,x0,y0,z0,fmag,m,acc,vec,force;
real bforce[ND_ND];
real xw[ND_ND];
real n[ND_ND];
real a[ND_ND];

Domain *d;

cell_t c;
Thread *t;
face_t f;

DEFINE_DPM_INJECTION_INIT ( injection0,I); /* Fluent macro to create a loop over the injections*/
{

Injection *Ilist = Get_dpm_injections(); /* to get a list of injections */

Injection *I; /* injection pointer */

Particle *p; /* particle pointer*/

loop(I, Ilist) /* looping over all injections */


loop(p,I->p) /* Standard Fluent Looping Macro to get particle streams in an Injection */
{

force=0;
c = P_CELL(p); /* Get the cell and thread that the particle is currently in */
t = P_CELL_THREAD(p);
m=P_MASS(p);

if (I=0)
{
x0 = P_POS(p)[0];
y0 = P_POS(p)[1];
z0 = P_POS(p)[2];

/*create a thread pointing to the wall*/
/* Zone ID for wall-5 zone from Boundary Conditions task page */
Thread *thread = Lookup_Thread(d, 5);

begin_f_loop(f, thread)
{

F_CENTROID(xw,f,thread);
x1 = xw[0];
y1 = xw[1];
z1 = xw[2];

dw = sqrt(SQR(x1-x0) + SQR(y1-y0) + SQR(z1-z0)); /* wall to particle distance calculation*/

bf = K/(dw*dw*dw*dw*dw*dw*dw); /* calculation of the resulting force */

vec[0] = x1-x0; /* vector in the direction of the force */
vec[1] = y1-y0;
vec[2] = z1-z0;

fmag = NV_MAG(vec); /* Magnitude of the vector in the direction of the force*/

n[0]=vec[0]/fmag; /* unit vector in the diretion of the force*/
n[1]=vec[1]/fmag;
n[2]=vec[2]/fmag;


NV_V_VS(force, =, force, +, force, *, bf); /* calculates the sum of all interaction forces*/

}

end_f_loop(f, thread)
}

else
{
force[0] = 0;
force[1] = 0;
force[2] = 0;
}
}

/*return;*/ /* Not sure whether this return functions needs to be added*/
}

DEFINE_DPM_BODY_FORCE(particle_body_force,p,i) /* Fluent macro to define particle body force*/
{

a[0] = force[0]/m;
a[1] = force[1]/m;
a[2] = force[2]/m;

acc = sqrt( a[0]* a[0] + a[1]* a[1] + a[2]* a[2] );
return acc;
}


Thank you!

pakk October 23, 2020 23:38

If this compiles, it will give a zero force.
Code:

NV_V_VS(force, =, force, +, force, *, bf); /* calculates the sum of all interaction forces*/
Force starts at zero, so bf*force will be zero no matter what bf is.
I think you mean force=force+bf.

You calculate now interaction between the particle and all cell faces. It makes no sense, physically. Do you want the closest wall point? Then search for minimum distance first. Do you want an integral? Then multiply with area.

You don't need DEFINE_DPM_INJECTION_INIT at all. Just put everything in DEFINE_DPM_BODY_FORCE. If you want to distinguish injections, give them a particle-UDM. Or give them a slightly different mass, and select by mass. Or a slightly different initial position or velocity. Many options.

You declare variables outside your functions, which makes them global. This is generally considered bad coding. Keep scopes as small as possible, it prevents bugs.

You take square roots, then square the result, and calculate x1-x0 several times. This can be simplified a lot.

Achini October 29, 2020 10:13

Thank you Pakk for your reply.

I will look into particle UDM since the particles should have identical properties and I cannot use different sizes.

pakk October 29, 2020 16:01

If the particles have 100% identical properties, they will follow the same trajectories. Something must distinguish them for your simulation to be useful.

Achini October 30, 2020 02:43

They have different surface functional groups attached to the particle surface. Thus, the attraction force exerted on particles is different for the two injections.

Can you guide me how to use article UDM.

Thank you for yor support!

pakk October 30, 2020 09:54

Are you interested in the effect of the surface forces?
So, is one injection the "control case" where you don't enable the surface forces, and the other injection the real case where you enable the surface forces?

If that is your situation: make it easy for yourself, and just do the simulation in two steps. Step 1 is where you don't enable the surface forces, (just don't load your UDF), and step 2 is where you do enable the surface forces. No need to do any selection in a UDF.

It's hard to imagine a situation where you can't do this (but admittedly my imagination is only limited). Your particles would need to influence the flow in some way, but I can't think of a use case with two identical kinds of particles except for the wall interaction, where particles affect the flow...

Achini October 30, 2020 12:01

You got my problem right and thank you for the suggestion.

Initially, the particles will flow as a mixture and ultimately, they will separate when flowing along the channel.

My objective is to represent the flow path and flow rate variation due to the effect of wall interactions.

And I prefer to model the flow variation of both particles in the same simulation. Is there any possible method of doing that? How about the particle UDm you mentioned before.
Also, this is a separation based on surface chemistry. Like a chromatographic separation.

Thank you so much for your guidance.


All times are GMT -4. The time now is 11:30.