CFD Online Discussion Forums

CFD Online Discussion Forums (http://www.cfd-online.com/Forums/)
-   Fluent UDF and Scheme Programming (http://www.cfd-online.com/Forums/fluent-udf/)
-   -   UDF to measure Mass Flow Rate (http://www.cfd-online.com/Forums/fluent-udf/74052-udf-measure-mass-flow-rate.html)

a.lynchy March 23, 2010 12:47

UDF to measure Mass Flow Rate
 
Hi everyone,
I am trying to measure the mass flow rate through a pressure outlet using a UDF. I realise there are easier way to get the mass flow rate at the outlet, rather than using the UDF but this is to be incorperated into a larger UDF later (hopefully :o). I have attached the code below that i have writen. The UDF interpetes okay and runs, however the problem is this code is giving me the mass flow rate throughout the whole volume and not at the pressure outlet ID 12 as required. I believe the problem is to do with the line: Lookup_Thread(d, 12);

#include "udf.h"
DEFINE_EXECUTE_AT_END(measure_mass_flow)
{
Domain *d;
real flow=0.;
face_t f;
Thread *t;
t= Lookup_Thread(d, 12);
d = Get_Domain(1);

thread_loop_f(t,d)
{
begin_f_loop(f,t)
{
flow+=F_FLUX(f,t);
}
end_f_loop(f,t)
}
printf("MASS Flow Rate: %g\n",flow);
flow=0.;
}

Please can anyone point me in the right direction?

coglione March 24, 2010 03:35

1) thread_loop_f(d,t) loops over all face threads in your domain and neglects your previous specification of t as the pointer to outlet. Skip this loop.
2) You have to retrieve *d before using it in Lookup_Thread: Switch corresponding lines 8 and 9

cheers

a.lynchy March 24, 2010 08:05

Thanks a million Coglione. That worked great!
Cheers

a.lynchy March 25, 2010 11:58

Continuing on from the above UDF. I am trying to measure the flow rate and pressure at a pressure outlet. The goal is to compare the measured mass flow rate to a set value and if diffferent adjust the pressure at the outlet until the mass flow rate reaches the desire value. Therefore i want to know what pressure is required to give me a desired flow rate. I am also using a pressure inlet. The code i ahve writen is shown below.

#include "udf.h"
real flow=0.;
real p=0;
DEFINE_EXECUTE_AT_END(funny)
{
Domain *d;
cell_t c;
face_t f;
Thread *t;
d = Get_Domain(1);
t= Lookup_Thread(d, 12);
begin_f_loop(f,t)
{
flow+=F_FLUX(f,t);
}
end_f_loop(f,t)
p=C_P(c,t);
printf("Static Pressure at outlet: %f\n",p);
printf("MASS Flow Rate: %f\n",flow);
}

DEFINE_PROFILE(pressure_out,t,i)
{
real set_point=1;
real pressure;
face_t f;

if (flow < set_point)

pressure=p-1;
else if (flow > set_point)
pressure=p+1;

else
pressure=p;
begin_f_loop(f,t)
{
F_PROFILE(f,t,i) = pressure;
}
end_f_loop(f,t)
printf("Adjusted pressure: %f\n",pressure);
flow = 0;
}

This UDF measure the correct pressure and mass flow rate, but the problem is that, no matter whether the flow rate is greater than or less than the set point, the pressure still reduces by 1. I believe this is something to do with the way the global variables are used but can manage to fix it.
Can anyone shed some light on this problem for me, please:confused:.

a.lynchy August 10, 2010 11:30

Thanks for the help.

I manage to solve the problem and write the code;)!

kartn September 6, 2010 14:43

Hi Lynch,

I am trying to write a UDF too where in the boundary condition at one zone affects the BC at the other which is similar to yours.
Could you tell me how u resolved the problem? Did you set the global variables as STATIC or was there something else to be modified?

a.lynchy September 10, 2010 07:16

Hi Kartn
The problem with the previous code that I posted was in getting the value for the variable “flow” from the DEFINE_EXECUTE_AT_END section and using it in the DEFINE_PROFILE. The way it was set as a global variable was okay but what was happening was it was been set to zero after the DEFINE_EXECTUE_AT_END loop so the DEFINE_PROFILE function was seeing a value of flow=0. Sorry if what I am saying is hard to follow, but I have attached the working code below and maybe from comparing the two you will be able to understand.
The only real different is in introducing the flow_tot variable as the global variable instead of using the flow variable.

#include"udf.h"
real flow_tot;
real p ;

DEFINE_EXECUTE_AT_END(funny)
{
Domain *d;

real flow;
cell_t c;
Thread *t;
face_t f;
d = Get_Domain(1);
t= Lookup_Thread(d, 12);

begin_f_loop(f,t)
{
flow+=F_FLUX(f,t);
}
end_f_loop(f,t)
p = C_P(c,t);
printf(
"static pressure = %g\n", p);
printf(
"MASS Flow Rate: %g\n",flow);
flow_tot =flow;
flow=0.;
}

DEFINE_PROFILE(pressure_out,t,i)
{
real set_point = 1;
real pressure;
face_t f;




printf(
"MASS Flow Rate: %g\n",flow_tot);
if (flow_tot < set_point)

pressure = p - 1;

elseif (flow_tot > set_point)

pressure = p + 1;

else
pressure = p;



begin_f_loop(f,t)
{
F_PROFILE(f,t,i) = pressure;
}
end_f_loop(f,t)
printf(
"Adjusted pressure = %g\n", pressure);
}

Hope this helps!:)

mdzubairmanipal@gmail.com February 22, 2011 03:48

Udf for applying transient mass flow rate
 
I am trying to figure out how to write a udf for applying a transient mass flow rate at the inlet. In my case study the mass flow rate varies with time from 0 to 40L/min and then comes down to zero in one cycle that ranges from 0 to 4 sec.

If anybody have a ready made udf, i wud be grateful if u could plz post it in this link or pass on through my email id.

I admit i am have a bad programming knowledge but since it is bit urgent, i have to seek ur opinion and help without having to take the pain to learn it myself.

Plz do help

aleisia June 8, 2011 19:30

What I'm curious is how you can find out the ID=12 for your t? Can you please tell me? I need to do sort of the same thing.
Thanks



Quote:

Originally Posted by a.lynchy (Post 251638)
Continuing on from the above UDF. I am trying to measure the flow rate and pressure at a pressure outlet. The goal is to compare the measured mass flow rate to a set value and if diffferent adjust the pressure at the outlet until the mass flow rate reaches the desire value. Therefore i want to know what pressure is required to give me a desired flow rate. I am also using a pressure inlet. The code i ahve writen is shown below.

#include "udf.h"
real flow=0.;
real p=0;
DEFINE_EXECUTE_AT_END(funny)
{
Domain *d;
cell_t c;
face_t f;
Thread *t;
d = Get_Domain(1);
t= Lookup_Thread(d, 12);
begin_f_loop(f,t)
{
flow+=F_FLUX(f,t);
}
end_f_loop(f,t)
p=C_P(c,t);
printf("Static Pressure at outlet: %f\n",p);
printf("MASS Flow Rate: %f\n",flow);
}

DEFINE_PROFILE(pressure_out,t,i)
{
real set_point=1;
real pressure;
face_t f;

if (flow < set_point)

pressure=p-1;
else if (flow > set_point)
pressure=p+1;

else
pressure=p;
begin_f_loop(f,t)
{
F_PROFILE(f,t,i) = pressure;
}
end_f_loop(f,t)
printf("Adjusted pressure: %f\n",pressure);
flow = 0;
}

This UDF measure the correct pressure and mass flow rate, but the problem is that, no matter whether the flow rate is greater than or less than the set point, the pressure still reduces by 1. I believe this is something to do with the way the global variables are used but can manage to fix it.
Can anyone shed some light on this problem for me, please:confused:.


kartn June 9, 2011 11:38

Hi aleisia,

The ID (=12 in this case) could be found from the FLUENT GUI in the "Boundary Conditions" section. Every boundary zone has its own ID.

a.lynchy June 9, 2011 12:04

Hi aleisia,

Yes like Kartn said i found the ID in the Boundary Conditions section of Fluent. Just highlight the zone you require and below the the list you will see the ID No. in box.
Best of Luck with the Work!:)

aleisia June 21, 2011 21:31

Quote:

Originally Posted by a.lynchy (Post 311313)
Hi aleisia,

Yes like Kartn said i found the ID in the Boundary Conditions section of Fluent. Just highlight the zone you require and below the the list you will see the ID No. in box.
Best of Luck with the Work!:)

Thank you for your post, and I found it following your direction, and thanks Kartn too.

Actually I'm working on modelling an imperfect filter, say, there is a cuboid (four side walls being 'wall', one inlet and one outlet as 'interior')in a room with SO2-air gaseous mixture. I model the cuboid as an imperfect filter in the following way: I first got the mass flow rate of SO2 from the inlet surface of the cuboid, and multiply this mass flow rate with a factor (<1) and set it as the volumetric sink rate (kg/m^3/s), below is the code and some errors I found:

#include "udf.h"
#include "mem.h"
#include "unsteady.h"

#define inlet_ID 12;
#define filter_ID 2;

real source;
real tepflowrate;
real vol_tot;
real ti;
Thread *t;
Thread *thread;
face_t f;
cell_t c;


DEFINE_ADJUST(adjust, d)
{
#if !RP_HOST

int i=0;
/* real A[ND_ND]; */
/* real flux[ND_ND]; */
real NV_VEC(flux);
real NV_VEC(A); /* declaring vectors flux and A */
/* real source; */
real massflowrate=0.;
real vol=0.;
/* real ti = RP_Get_Real("flow-time"); */ /* ti = CURRENT_TIME;*/

/* Thread *t; */
thread=Lookup_Thread(d,filter_ID);
t=Lookup_Thread(d,inlet_ID);

/* defining the filter volume thread by specifying the Zone_ID*/
/* defining the inlet surface thread by specifying the Zone_ID*/

/* Send the ID value to all the nodes */
/* host_to_node_real_4(f, t, c, thread);Does nothing in serial, t is the thread of inlet surface, thread is the thread of the filter volume */

/*Start to calculate the mass flow rate through the inlet surface and store it in UDM*/
/* begin_f_loop(f,t) */
if PRINCIPAL_FACE_P(f,t) /* tests if the face is the principle face FOR COMPILED UDFs ONLY */
{
NV_D(flux, =, F_U(f,t), F_V(f,t), F_W(f,t)); /* defining flux in terms of velocity field */
NV_S(flux, *=, F_R(f,t)); /* multiplying density to get flux vector */
F_AREA(A,f,t); /* face normal vector returned from F_AREA */
massflowrate = F_YI(f,t,i)*NV_DOT(flux,A); /* dot product of the inlet surface flux and area vector, multiplied by the mass fraction of species i */
}
/* end_f_loop(f,t) */

# if RP_NODE /* Perform node synchronized actions here, Does nothing in Serial */
massflowrate = PRF_GRSUM1(massflowrate);
# endif /* RP_NODE */


begin_f_loop(f,t)
if PRINCIPAL_FACE_P(f,t) /* tests if the face is the principle face FOR COMPILED UDFs ONLY */
{
F_UDMI(f, t, 0)= massflowrate; /* YOU MAY NEED TO CHECK THE NODE AS THE SUMMED UP VALUE OF massflowrate IS DONE AT node0. */
}
end_f_loop(f,t)

/*Start to calculate the total volume of filter volume and store it in UDM */
begin_c_loop(c,thread)
{
vol += C_VOLUME(c,thread); /* get cell volume */
}
end_c_loop(c,thread)

#if RP_NODE /* Perform node synchronized actions here, Does nothing in Serial */
vol= PRF_GRSUM1(vol);
# endif /* RP_NODE */

begin_c_loop(c,thread)
{
C_UDMI(c, thread, 1)= vol; /* YOU MAY NEED TO CHECK THE NODE AS THE SUMMED UP VALUE OF massflowrate IS DONE AT node0. */
}
end_c_loop(c,thread)
#endif /* !RP_HOST */
}

DEFINE_SOURCE(cell_SO2mass_source, c, thread, dS, eqn)
{
#if !RP_HOST


/* face_t f; */
/* int i; */
/* real A[ND_ND]; */
/* real flux[ND_ND]; */
/* real NV_VEC(flux); */
/* real NV_VEC(A); */ /* declaring vectors flux and A */

/* Thread *thread=Lookup_Thread(d,filter_ID); */


Domain *d;

d=Get_Domain(1);
t=Lookup_Thread(d,inlet_ID);
ti=RP_Get_Real("flow-time"); /* ti = CURRENT_TIME;*/
/* Thread *thread; */

/* #endif */ /* !RP_HOST */

/* #if !RP_HOST */

tepflowrate= F_UDMI(f, t, 0);
vol_tot = C_UDMI(c, thread, 1);

#endif /* !RP_HOST */

/* Pass the node's SO2 mass flow rate and volume to the Host for calculating source */
node_to_host_real_2(tepflowrate, vol_tot); /* Does nothing in SERIAL */

#if !RP_NODE /* SERIAL or HOST */
source=-0.999989*tepflowrate/vol_tot;
dS[eqn]=0.0;
return source;
Message("Sink Rate in Filter %d is %f (kg/m^3/s)\n", filter_ID, source);
#endif /* !RP_NODE */

}

Deleted old libudf\win64\3d_host\libudf.dll
libudf\win64\3d_node\libudf.dll
1 file(s) copied.
(system "copy "c:\ANSYSI~1\v121\fluent"\fluent12.1.4\src\makefil e_nt.udf libudf\win64\3d_host\makefile")
1 file(s) copied.
(chdir "libudf")()
(chdir "win64\3d_host")()
# Generating ud_io1.h
udfsource1.c
..\..\src\udfsource1.c(121) : error C2143: syntax error : missing ')' before ';'
..\..\src\udfsource1.c(121) : error C2143: syntax error : missing ';' before ','
..\..\src\udfsource1.c(121) : error C2059: syntax error : ')'
(system "copy "c:\ANSYSI~1\v121\fluent"\fluent12.1.4\src\makefil e_nt.udf libudf\win64\3d_node\makefile")
1 file(s) copied.
(chdir "libudf")()
(chdir "win64\3d_node")()
# Generating ud_io1.h
udfsource1.c
..\..\src\udfsource1.c(33) : error C2143: syntax error : missing ')' before ';'
..\..\src\udfsource1.c(33) : error C2059: syntax error : ')'
..\..\src\udfsource1.c(34) : error C2143: syntax error : missing ')' before ';'
..\..\src\udfsource1.c(34) : error C2059: syntax error : ')'
..\..\src\udfsource1.c(101) : error C2143: syntax error : missing ')' before ';'
..\..\src\udfsource1.c(101) : error C2059: syntax error : ')'

Done.

The four errors are in red color, if convenient, can you please take a look at it? thanks!

aleisia June 21, 2011 21:33

Quote:

Originally Posted by kartn (Post 311308)
Hi aleisia,

The ID (=12 in this case) could be found from the FLUENT GUI in the "Boundary Conditions" section. Every boundary zone has its own ID.

Hi Kartn, thanks for your reply and I found it out.
BTW, if convenient, can you please check out my problem? I post it by replying to a.lynchy's post. thanks!

aleisia June 21, 2011 21:43

Quote:

Originally Posted by a.lynchy (Post 274733)
Hi Kartn
The problem with the previous code that I posted was in getting the value for the variable “flow” from the DEFINE_EXECUTE_AT_END section and using it in the DEFINE_PROFILE. The way it was set as a global variable was okay but what was happening was it was been set to zero after the DEFINE_EXECTUE_AT_END loop so the DEFINE_PROFILE function was seeing a value of flow=0. Sorry if what I am saying is hard to follow, but I have attached the working code below and maybe from comparing the two you will be able to understand.
The only real different is in introducing the flow_tot variable as the global variable instead of using the flow variable.

#include"udf.h"
real flow_tot;
real p ;

DEFINE_EXECUTE_AT_END(funny)
{
Domain *d;

real flow;
cell_t c;
Thread *t;
face_t f;
d = Get_Domain(1);
t= Lookup_Thread(d, 12);

begin_f_loop(f,t)
{
flow+=F_FLUX(f,t);
}
end_f_loop(f,t)
p = C_P(c,t);
printf(
"static pressure = %g\n", p);
printf(
"MASS Flow Rate: %g\n",flow);
flow_tot =flow;
flow=0.;
}

DEFINE_PROFILE(pressure_out,t,i)
{
real set_point = 1;
real pressure;
face_t f;




printf(
"MASS Flow Rate: %g\n",flow_tot);
if (flow_tot < set_point)

pressure = p - 1;

elseif (flow_tot > set_point)

pressure = p + 1;

else
pressure = p;



begin_f_loop(f,t)
{
F_PROFILE(f,t,i) = pressure;
}
end_f_loop(f,t)
printf(
"Adjusted pressure = %g\n", pressure);
}

Hope this helps!:)

I think about it again, and found this in your code:
begin_f_loop(f,t)
{
flow+=F_FLUX(f,t);
}
end_f_loop(f,t)

Here the F_FLUX(f,t) is a vector, I believe, so what if you want to get the mass flow rate, instead of the flux, can I write:
begin_f_loop(f,t)
{
flow+=F_YI(f,t,i)*F_FLUX(f,t)*F_AREA(A,f,t);
}
end_f_loop(f,t)


or

real A[ND_ND], flux(ND_ND)
begin_f_loop(f,t)
{
flux=
F_FLUX(f,t);
F_AREA(A,f,t);
mf=F_YI(f,t,i);
flow+=mf*NV_DOT(flux, A);
}
end_f_loop(f,t)


As I understand, F_YI(f,t,i), F_FLUX(f,t) and F_AREA(A,f,t) just get one patch of the surface 'f' corresponding to the thread 't', so the area 'A' is the area of that patch, that's why we need the begin_f_loop and end_f_loop, am I getting this right?

thanks!

kartn June 24, 2011 16:30

Quote:

Originally Posted by aleisia (Post 312999)
I think about it again, and found this in your code:
begin_f_loop(f,t)
{
flow+=F_FLUX(f,t);
}
end_f_loop(f,t)

Here the F_FLUX(f,t) is a vector, I believe, so what if you want to get the mass flow rate, instead of the flux, can I write:
begin_f_loop(f,t)
{
flow+=F_YI(f,t,i)*F_FLUX(f,t)*F_AREA(A,f,t);
}
end_f_loop(f,t)


or

real A[ND_ND], flux(ND_ND)
begin_f_loop(f,t)
{
flux=
F_FLUX(f,t);
F_AREA(A,f,t);
mf=F_YI(f,t,i);
flow+=mf*NV_DOT(flux, A);
}
end_f_loop(f,t)


As I understand, F_YI(f,t,i), F_FLUX(f,t) and F_AREA(A,f,t) just get one patch of the surface 'f' corresponding to the thread 't', so the area 'A' is the area of that patch, that's why we need the begin_f_loop and end_f_loop, am I getting this right?

thanks!

Hi Aleisia,

F_FLUX(f,t) by itself outputs the mass flow rate entering or leaving a face in a cell. It is a scalar quantity and it outputs the result of the dot product of the mass flux vector and area normal vector.
So all u have to do in order to calculate the mass flow rate of a particular species is find the product of total flux of the mass flux vector and the mass fraction.

begin_f_loop(f,t)
{
flow+=F_FLUX(f,t)*F_YI(f,t);
}
end_f_loop(f,t)

aleisia June 25, 2011 01:04

Thanks a million Kartn!

So, if I have some fluid entering into a surface, F_FLUX should be a negative scalar, right?

I remembered I've seen it somewhere, the result we see from the GUI values are actually the opposite of the F_FLUX , because they have different definitions of the 'normal' direction.
What I mean, from GUI, the value should be positive, because the fluid is entering into the surface, so it should be positive, but according to the definition of F_FLUX, it should be negative. Am I getting this right?

Thanks!

Quote:

Originally Posted by kartn (Post 313468)
Hi Aleisia,

F_FLUX(f,t) by itself outputs the mass flow rate entering or leaving a face in a cell. It is a scalar quantity and it outputs the result of the dot product of the mass flux vector and area normal vector.
So all u have to do in order to calculate the mass flow rate of a particular species is find the product of total flux of the mass flux vector and the mass fraction.

begin_f_loop(f,t)
{
flow+=F_FLUX(f,t)*F_YI(f,t);
}
end_f_loop(f,t)


elcino May 4, 2012 06:58

Good morning everybody,

I was reading your post and I think I've the same problem as all of you. I'm analyzing journal bearings. The problems seams easy but i can't have the convergence if the "pressure-inlet" vs "pressure-outlet" are imposed. If I try to impose "mass flow inlet" vs "pressure-outlet" i can reach a good convergence. The problem is: I don't know the mass flow!!!! My idea is: impose a mass flow, calculate the total pressure (known data) and then recompute the mass flow at any iteration.

I've to write an UDF like yours:

1. Calculate the total average total pressure on the inlet and with an algorithm calculate the next mass flow (this is easy like a bisection algorithm will work sure, remember i had an aimed total pressure).

2. Input the new mass flow.

So the first UDF must be an DEFINE_EXECUTE_AT_END, to calculate for example "mass_flow", and the next will be an DEFINE_PROFILE.

My question is: how to calculate the average total pressure on a face (of course Ptot=Pstat+0.5*rho*v^2) but i don't know how to implement it as an average on the boundary.

when u do this:

begin_f_loop(f,t)
{
flow+=F_FLUX(f,t);
}
end_f_loop(f,t)


means that fluent is going to give u "flow" as the summatory of all the face fluxes of the boundary with the same ID?

thanks for your help!

mm.abdollahzadeh June 20, 2012 12:53

Quote:

Originally Posted by a.lynchy (Post 274733)
Hi Kartn
The problem with the previous code that I posted was in getting the value for the variable “flow” from the DEFINE_EXECUTE_AT_END section and using it in the DEFINE_PROFILE. The way it was set as a global variable was okay but what was happening was it was been set to zero after the DEFINE_EXECTUE_AT_END loop so the DEFINE_PROFILE function was seeing a value of flow=0. Sorry if what I am saying is hard to follow, but I have attached the working code below and maybe from comparing the two you will be able to understand.
The only real different is in introducing the flow_tot variable as the global variable instead of using the flow variable.

#include"udf.h"
real flow_tot;
real p ;

DEFINE_EXECUTE_AT_END(funny)
{
Domain *d;

real flow;
cell_t c;
Thread *t;
face_t f;
d = Get_Domain(1);
t= Lookup_Thread(d, 12);

begin_f_loop(f,t)
{
flow+=F_FLUX(f,t);
}
end_f_loop(f,t)
p = C_P(c,t);
printf(
"static pressure = %g\n", p);
printf(
"MASS Flow Rate: %g\n",flow);
flow_tot =flow;
flow=0.;
}

DEFINE_PROFILE(pressure_out,t,i)
{
real set_point = 1;
real pressure;
face_t f;




printf(
"MASS Flow Rate: %g\n",flow_tot);
if (flow_tot < set_point)

pressure = p - 1;

elseif (flow_tot > set_point)

pressure = p + 1;

else
pressure = p;



begin_f_loop(f,t)
{
F_PROFILE(f,t,i) = pressure;
}
end_f_loop(f,t)
printf(
"Adjusted pressure = %g\n", pressure);
}

Hope this helps!:)

Dear Adrian

Thanks For sharing your work. Could you please help me.
I want to calaculate the mass flow rate on a surface diffrent that the outlet boundary and then i want to modify the pressure at outlet according to that mass flow.
I dont have that surface as a boundary seprately. I just creat that surface as an isosurface in Fluent and I was calculataing the mass flow in GUI.

I appriciate your help.

Best
Mehdi

Kanarya November 21, 2012 06:35

Hi Adrian,

I would like to read the massflow in outlet and save it in UDMI. I used similiar code to yours but it seems nothing happens. is it possible to save the outlet mass flow and use it as in inlet mass flow. thanks in advance!!!!!!

Kanarya November 29, 2012 06:25

Hi ALL,

I want to calculate solid phase mass flow rate at outlet and I wrote following code to it but it only read primary phase even though I pointed secondary phase. is there any one to help me why?
thanks a lot!!
#include "udf.h"
DEFINE_EXECUTE_AT_END(measure_mass_flow)
{
real mass_flow;
real abs_v;
Domain *d=Get_Domain(2);
face_t f;
Thread *mixture_thread = Lookup_Thread(d,2);
Thread **pt = THREAD_SUB_THREADS(mixture_thread);
Thread *tp = pt[0];
Thread *ts = pt[1];

mass_flow=0.;
mp_thread_loop_f(tp,d,pt)
{
if( THREAD_ID(tp) == 4 )

{
begin_f_loop(f,tp)
{

mass_flow+=F_FLUX(f,tp);

}
end_f_loop(f,tp)
}



}
Message("mass_flow:%g/n",mass_flow);
}
thanks again..


All times are GMT -4. The time now is 21:06.