CFD Online Logo CFD Online URL
www.cfd-online.com
[Sponsors]
Home > Forums > Software User Forums > ANSYS > FLUENT > Fluent UDF and Scheme Programming

UDF for DPM modelling to simulate ammonia absorption

Register Blogs Members List Search Today's Posts Mark Forums Read

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old   March 29, 2021, 04:17
Default UDF for DPM modelling to simulate ammonia absorption
  #1
New Member
 
Join Date: Mar 2021
Posts: 22
Rep Power: 2
Jack0210Jack is on a distinguished road
Hi,

I am new to udf and c programming. Currently I am working on a project to simulate ammonia absorption into water droplets using two-film theory and DPM. I have read the udf manuals and researching online for examples but I am not sure whether my functions are correct. Below is the code:

Quote:
#include "udf.h"

DEFINE_DPM_HEAT_MASS(nh3absorption, tp, Cp, hgas, hvap, cvap_surf, Z, dydt, dzdt)
{
int is;
int nc = TP_N_COMPONENTS(tp); /*number of particle components*/
real gas_index;
printf("\n######");
for (is = 0; is < nc; is++)
{
int gas_index = TP_COMPONENT_INDEX_I(tp, is); /* index of vaporizing component in the gas phase */
printf(" gas_index=%d is=%d TP_COMPONENT_I=%e ", gas_index, is, TP_COMPONENT_I(tp, is));
}
printf("#######$\n");
Thread* t0 = P_CELL_THREAD(tp); /*thread where the particle is in*/
cell_t c0 = P_CELL(tp); /*cell where the particle is in*/
Material* gas_mix = THREAD_MATERIAL(DPM_THREAD(t0, tp)); /*gas mixture material*/
Material* cond_mix = P_MATERIAL(tp); /*particle mixture material*/
cphase_state_t* c = &(tp->cphase); /*cell information of particle location*/\
real mp = P_MASS(tp); /* particle mass */
real Dp = DPM_DIAM_FROM_VOL(mp / P_RHO(tp)); /* particle diameter */
real Ap = DPM_AREA(Dp); /*particle surface area*/
real v = P_VEL(tp);/*water droplet velocity*/
real vg = 15.69e-6; /*kinematic viscosity of air*//*[m2/s]*/
real Re = Dp * v / vg;

real D = 1.64e-7; /*molecular diffusivity coefficient*//*[m/s]*/
real Sc = vg / D;

real ky = 2.0 + 0.6 * sqrt(Re) * pow(Sc, 1. / 3.); /*mass transfer coefficient in liquid phase*/

real T = 300; /*Temperature*//*[K]*/

real H = 0.59 * exp(4200 * ((1 / T) - 1 / (298.15))); /*Henry Constant*//*[mol/(m3*Pa)]*/

real MW_NH3 = 17.031e-3; /*Molecular mass of ammonia*//*[kg/mol]*/

real den_g = C_R(c, gas_index); /*density of gas in air*/
real yi_NH3_g = C_YI(c, gas_index, 4); /*mass fraction of ammonia in air*/
real C_g = yi_NH3_g * den_g / MW_NH3; /*molar concentration of NH3 in air*//*[mol/m3]*/
real P_g = C_g * 8.314 * T; /*partial pressure of ammonia in air*/

real den_l = P_RHO(tp); /*density of particle*/
real yi_NH3_l; /*mass fraction of ammonia in particle*/

for (yi_NH3_l = 0; yi_NH3_l < 1; ++TP_COMPONENT_I(tp, is))
{
real C_l = yi_NH3_l * den_l / MW_NH3; /*molar concentration of ammonia in water droplet*//*[mol/m3]*/
real NA = ky * (P_g - H * C_l); /*Mass transfer flux of ammonia*/
dydt[2] = NA;
}
return 0;
}
Below are the errors shown after compiled.

Quote:
..\..\src\two-film.c(38): error C2223: left of '->storage' must point to struct/union
..\..\src\two-film.c(39): error C2223: left of '->storage' must point to struct/union
..\..\src\two-film.c(52): warning C4098: 'nh3absorption': 'void' function returning a value
..\..\src\two-film.c(19): warning C4047: 'initializing': 'cphase_state_t *' differs in levels of indirection from 'cphase_state_t **'
..\..\src\two-film.c(23): error C2440: 'initializing': cannot convert from 'real *' to 'real'
The idea of this project is to simulate the ammonia absorption into water droplet. Water droplet will be injected via DPM and ammonia absorption will be added via udf. When the ammonia mass fraction in water droplet is less than 1, the ammonia will be absorbed into the water droplet and the mass transfer rate is based on the mass fraction of ammonia in water droplet.

Does anyone know how to solve the errors? Thanks a lot

Last edited by Jack0210Jack; March 30, 2021 at 14:37.
Jack0210Jack is offline   Reply With Quote

Old   March 29, 2021, 08:58
Default
  #2
Senior Member
 
Join Date: Nov 2013
Posts: 1,785
Rep Power: 22
pakk will become famous soon enough
Compile them, load them, try them.

Do you get errors? Does it do what you want? That is the best test.
__________________
"The UDF library you are trying to load (libudf) is not compiled for parallel use on the current platform" is NOT the error after compiling. It is the error after loading. To see compiler errors, look at your screen after you click "build".
pakk is offline   Reply With Quote

Old   March 29, 2021, 09:00
Default
  #3
New Member
 
Join Date: Mar 2021
Posts: 22
Rep Power: 2
Jack0210Jack is on a distinguished road
Quote:
Originally Posted by pakk View Post
Compile them, load them, try them.

Do you get errors? Does it do what you want? That is the best test.
I see. Sure. Will reply here if I get errors that I can't solve. Thanks.
Jack0210Jack is offline   Reply With Quote

Old   March 29, 2021, 11:03
Default
  #4
New Member
 
Join Date: Mar 2021
Posts: 22
Rep Power: 2
Jack0210Jack is on a distinguished road
Quote:
Originally Posted by pakk View Post
Compile them, load them, try them.

Do you get errors? Does it do what you want? That is the best test.
Below are the errors shown after compiled.

Quote:
..\..\src\two-film.c(38): error C2223: left of '->storage' must point to struct/union
..\..\src\two-film.c(39): error C2223: left of '->storage' must point to struct/union
..\..\src\two-film.c(52): warning C4098: 'nh3absorption': 'void' function returning a value
..\..\src\two-film.c(19): warning C4047: 'initializing': 'cphase_state_t *' differs in levels of indirection from 'cphase_state_t **'
..\..\src\two-film.c(23): error C2440: 'initializing': cannot convert from 'real *' to 'real'
Do you have any ideas how to solve them? Thanks

Last edited by Jack0210Jack; March 29, 2021 at 13:37.
Jack0210Jack is offline   Reply With Quote

Old   March 30, 2021, 00:32
Default
  #5
Senior Member
 
Alexander
Join Date: Apr 2013
Posts: 1,645
Rep Power: 23
AlexanderZ will become famous soon enough
line 19
was
Code:
cphase_state_t* c = &(p->cphase);
to be
Code:
cphase_state_t *c = &(p->cphase);
P_VEL(tp) is a vector, which contains P_VEL(tp) [0] - velocity in x direction, P_VEL(tp) [1] - in y direction and P_VEL(tp) [2] in z direction.
in case you need velocity magnitude, you can use this
Code:
real v = NV_MAG(P_VEL(tp));
__________________
best regards


******************************
press LIKE if this message was helpful
AlexanderZ is offline   Reply With Quote

Old   March 30, 2021, 00:44
Default
  #6
New Member
 
Join Date: Mar 2021
Posts: 22
Rep Power: 2
Jack0210Jack is on a distinguished road
Quote:
Originally Posted by AlexanderZ View Post
line 19
was
Code:
cphase_state_t* c = &(p->cphase);
to be
Code:
cphase_state_t *c = &(p->cphase);
tbh every time I close the line, it will change from
Code:
cphase_state_t *c = &(p->cphase);
to
Code:
cphase_state_t* c = &(p->cphase);
so I assume second line is the correct one. Btw, it still has error for line 19 even if I use
Code:
cphase_state_t *c = &(p->cphase);
but line 23 is fixed.

Actually the variable I used is "tp" because in some posts I saw people using "tp" instead of "p" and I assumed because "tp" is the latest format. Should I change all "tp" variable to "p" variable?

Thank you.
Jack0210Jack is offline   Reply With Quote

Old   March 30, 2021, 00:47
Default
  #7
New Member
 
Join Date: Mar 2021
Posts: 22
Rep Power: 2
Jack0210Jack is on a distinguished road
Wait a min, after I change
Code:
cphase_state_t* c = &(p->cphase);
to
Code:
cphase_state_t** c = &(p->cphase);
It somehow has been solved.
Jack0210Jack is offline   Reply With Quote

Old   March 30, 2021, 14:53
Default
  #8
New Member
 
Join Date: Mar 2021
Posts: 22
Rep Power: 2
Jack0210Jack is on a distinguished road
The errors I face currently are:
Quote:
..\..\src\nh3absorption.c(38): error C2223: left of '->storage' must point to struct/union
..\..\src\nh3absorption.c(39): error C2223: left of '->storage' must point to struct/union
which reflect on these 2 lines:
Code:
real den_g = C_R(c, gas_index); /*density of air*/
Code:
real yi_NH3_g = C_YI(c, gas_index, 4); /*mass fraction of ammonia in air*/
I suppose the errors are due to the DEFINE macros do not have "c" variable. If that's the case what changes should I make? I tried pointing "c->rho", "c->mu", and "c->mut" for density (line 38) but it doesn't work.

I also tried to add in another macro "DEFINE_PROPERTY" for those 4 lines (38~41) but P_g in line 41 cannot be linked to P_g in line 49.

Any helps will appreciated. Thanks.
Jack0210Jack is offline   Reply With Quote

Old   March 30, 2021, 15:45
Default
  #9
Senior Member
 
Join Date: Nov 2013
Posts: 1,785
Rep Power: 22
pakk will become famous soon enough
I guess you want info of the cell that your particle is in, and you call that c0, not c.
__________________
"The UDF library you are trying to load (libudf) is not compiled for parallel use on the current platform" is NOT the error after compiling. It is the error after loading. To see compiler errors, look at your screen after you click "build".
pakk is offline   Reply With Quote

Old   March 30, 2021, 15:48
Default
  #10
New Member
 
Join Date: Mar 2021
Posts: 22
Rep Power: 2
Jack0210Jack is on a distinguished road
Thanks but not really. I want the info of the cell where particle is not in.
Jack0210Jack is offline   Reply With Quote

Old   March 31, 2021, 00:52
Default
  #11
Senior Member
 
Join Date: Nov 2013
Posts: 1,785
Rep Power: 22
pakk will become famous soon enough
But which cell is c then referring to? I don't know, and neither does fluent.
__________________
"The UDF library you are trying to load (libudf) is not compiled for parallel use on the current platform" is NOT the error after compiling. It is the error after loading. To see compiler errors, look at your screen after you click "build".
pakk is offline   Reply With Quote

Old   March 31, 2021, 01:37
Default
  #12
New Member
 
Join Date: Mar 2021
Posts: 22
Rep Power: 2
Jack0210Jack is on a distinguished road
Quote:
Originally Posted by pakk View Post
But which cell is c then referring to? I don't know, and neither does fluent.
That's the issue. I don't know how should I point the cell to.
Jack0210Jack is offline   Reply With Quote

Old   March 31, 2021, 01:54
Default
  #13
New Member
 
Join Date: Mar 2021
Posts: 22
Rep Power: 2
Jack0210Jack is on a distinguished road
Code:
#include "udf.h"

DEFINE_DPM_HEAT_MASS(nh3absorption, tp, Cp, hgas, hvap, cvap_surf, Z, dydt, dzdt)
{
	int is;
	int nc = TP_N_COMPONENTS(tp); /*number of particle components*/
	real gas_index;
	printf("\n######");
	for (is = 0; is < nc; is++)
	{
		int gas_index = TP_COMPONENT_INDEX_I(tp, is); /* index of vaporizing component in the gas phase */
		printf(" gas_index=%d is=%d TP_COMPONENT_I=%e ", gas_index, is, TP_COMPONENT_I(tp, is));
	}
	printf("#######$\n");
	Thread* t0 = P_CELL_THREAD(tp); /*thread where the particle is in*/
	Material* gas_mix = THREAD_MATERIAL(DPM_THREAD(t0, tp)); /*gas mixture material*/
	Material* cond_mix = P_MATERIAL(tp); /*particle mixture material*/
	cphase_state_t** c0 = &(tp->cphase); /*cell information of particle location*/
	real mp = P_MASS(tp); /* particle mass */
	real Dp = DPM_DIAM_FROM_VOL(mp / P_RHO(tp)); /* particle diameter */
	real Ap = DPM_AREA(Dp); /*particle surface area*/
	real v = NV_MAG(P_VEL(tp)); /*water droplet velocity*/
	real vg = 15.69e-6;	/*kinematic viscosity of air*//*[m2/s]*/
	real Re = Dp * v / vg;

	real D = 1.64e-7; /*molecular diffusivity coefficient*//*[m/s]*/
	real Sc = vg / D;

	real ky = 2.0 + 0.6 * sqrt(Re) * pow(Sc, 1. / 3.); /*mass transfer coefficient in liquid phase*/

	real T = 300; /*Temperature*//*[K]*/

	real H = 0.59 * exp(4200 * ((1 / T) - 1 / (298.15)));	/*Henry Constant*//*[mol/(m3*Pa)]*/

	real MW_NH3 = 17.031e-3; /*Molecular mass of ammonia*//*[kg/mol]*/

	Domain* domain = Get_Domain(1); /* Get domain pointer */
	Thread* t;
	cell_t c;
	int i;
	/* Loop over all cell threads in domain */
	thread_loop_c(t, domain)
	{
		/* Loop over all cells */
		begin_c_loop(c, t)
		{
			{
				C_R(c, t) = 0.0;
				C_YI(c, t, i) = 0.0;
			}
		}
		end_c_loop(c, t);
	}

	real yi_NH3_g = C_YI(c, gas_index, 4); /*mass fraction of ammonia in air*/
	real den_g = C_R(c, gas_index); /*density of air*/
	real C_g = yi_NH3_g * den_g / MW_NH3; /*molar concentration of NH3 in air*//*[mol/m3]*/
	real P_g = C_g * 8.314 * T; /*partial pressure of ammonia in air*/

	real den_l = P_RHO(tp); /*density of particle*/
	real yi_NH3_l; /*mass fraction of ammonia in particle*/
		
	for (yi_NH3_l = 0; yi_NH3_l < 1; ++TP_COMPONENT_I(tp, is))
	{
		real C_l = yi_NH3_l * den_l / MW_NH3; /*molar concentration of ammonia in water droplet*//*[mol/m3]*/
		real NA = ky * (P_g - H * C_l); /*Mass transfer flux of ammonia*/
		dydt[2] = NA;
	}
	return;
}
I have added a get domain which I referred from Ansys udf manual but it still has the same error message. Btw, I removed "cell_t c0" because I didn't use "c0" in any lives below and "cphase_state_t** c" has changed to "cphase_state_t** c0" to avoid "c" variable being defined in 2 places.
Jack0210Jack is offline   Reply With Quote

Old   March 31, 2021, 07:10
Default
  #14
Senior Member
 
Alexander
Join Date: Apr 2013
Posts: 1,645
Rep Power: 23
AlexanderZ will become famous soon enough
if you look at definition of macros C_YI and C_R you will see, that they are using treads inside: C_R(c, t)
t has type thread not int

so based on expamle from manual Ansys Fluent Customization manual -> DEFINE_DPM_HEAT_MASS
I think you should change
Code:
real yi_NH3_g = C_YI(c, gas_index, 4); /*mass fraction of ammonia in air*/
real den_g = C_R(c, gas_index); /*density of air*/
to

Code:
real den_g = c->rho; /*density of gas*/
real yi_NH3_g = yi[gas_index]; /*mass fraction of ammonia*/
and in that case you need
Code:
cphase_state_t *c = &(p->cphase); /* cell information of particle location*/
with 1 star
__________________
best regards


******************************
press LIKE if this message was helpful
AlexanderZ is offline   Reply With Quote

Old   March 31, 2021, 07:46
Default
  #15
New Member
 
Join Date: Mar 2021
Posts: 22
Rep Power: 2
Jack0210Jack is on a distinguished road
Hi AlexanderZ,

Thanks for your reply. It actually works for once (no error) but I don't know what happen afterward, it cannot work. Below are the errors shown:

Quote:
..\..\src\nh3absorption_v1.c(56): error C2065: 'yi': undeclared identifier
..\..\src\nh3absorption_v1.c(56): error C2109: subscript requires array or pointer type
..\..\src\nh3absorption_v1.c(57): error C2223: left of '->rho' must point to struct/union
for the line with
Code:
cphase_state_t *c = &(p->cphase); /* cell information of particle location*/
it shows this error instead
Quote:
..\..\src\nh3absorption_v1.c(18): warning C4047: 'initializing': 'cphase_state_t *' differs in levels of indirection from 'cphase_state_t **'
which is why I changed to using 2 stars.

Thanks.
Jack0210Jack is offline   Reply With Quote

Old   March 31, 2021, 12:16
Default
  #16
Senior Member
 
Join Date: Nov 2013
Posts: 1,785
Rep Power: 22
pakk will become famous soon enough
Quote:
Originally Posted by Jack0210Jack View Post
That's the issue. I don't know how should I point the cell to.
Which cell?

After you tell me which cell it should point to, I can help. But all I know now is that it should not be the cell of the particle. That's not enough information.
__________________
"The UDF library you are trying to load (libudf) is not compiled for parallel use on the current platform" is NOT the error after compiling. It is the error after loading. To see compiler errors, look at your screen after you click "build".
pakk is offline   Reply With Quote

Old   March 31, 2021, 12:23
Default
  #17
Senior Member
 
Join Date: Nov 2013
Posts: 1,785
Rep Power: 22
pakk will become famous soon enough
Based on your description in your other question, I think you want the UDF from here, but then c0 in stead of c.

You said that you don't want the cell that the particle is in, but that statement makes no sense. Just use c0.
__________________
"The UDF library you are trying to load (libudf) is not compiled for parallel use on the current platform" is NOT the error after compiling. It is the error after loading. To see compiler errors, look at your screen after you click "build".
pakk is offline   Reply With Quote

Old   March 31, 2021, 13:17
Default
  #18
New Member
 
Join Date: Mar 2021
Posts: 22
Rep Power: 2
Jack0210Jack is on a distinguished road
I have made a huge modification since I messed up the steps. If anyone would like to continue helping me, please visit the link below:

UDF for DPM modelling to simulate ammonia absorption into water droplets

Thank you very much.
Jack0210Jack is offline   Reply With Quote

Reply

Tags
absorption, dpm, fluent, heat_mass, udf

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
UDF for absorption coefficient paolofug87 Fluent UDF and Scheme Programming 0 August 11, 2017 04:20
UDF for modelling heat loss in 2D Shrinand Fluent UDF and Scheme Programming 2 February 29, 2016 05:50
Modelling filter cake growing with UDF? skumanov Fluent UDF and Scheme Programming 1 February 20, 2013 02:23
modelling heat flux in udf dzuodoka Fluent UDF and Scheme Programming 0 November 24, 2010 05:10
Constant velocity of the material Sas CFX 15 July 13, 2010 08:56


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