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

write UDF for the dpm model

Register Blogs Community New Posts Updated Threads Search

Like Tree1Likes
  • 1 Post By obscureed

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old   June 19, 2018, 11:21
Default write UDF for the dpm model
  #1
New Member
 
Li Xiaoying
Join Date: Jun 2018
Posts: 8
Rep Power: 8
Lxy2018 is on a distinguished road
hi!
Now I need to write UDF about the dpm model used for post processing. The function of the UDF is to calculate concentration distribution from the trajectories.
1.unfortunately, I couldn't find related macor of the loop of particle trajectories in the user's manual.could someone please provide macor and instruction about it?
2.how to get the particle residence time?
P_TIME (p)-P_TIME 0(p) is right?

Thanks!
Lxy2018 is offline   Reply With Quote

Old   June 19, 2018, 20:53
Smile
  #2
New Member
 
ASA
Join Date: Mar 2017
Location: USA
Posts: 6
Rep Power: 9
haghasa is on a distinguished road
Compile and use this UDF:

Code:
#include "udf.h"
DEFINE_ON_DEMAND(loop_over_injections_particles)
{
	Domain *domain = Get_Domain(1);

        Injection *I;
        Particle *p;

	Injection *Ilist = Get_dpm_injections();  /* get the name of injections and store them in the Ilist */

	loop(I, Ilist)
	{
                loop(p, I->p)
                {
                /* do whatever you want with that particle */
                }
	}
}
For example, you want to calculate the concentration at the end of calculation:
(make sure to add one UDMI)

Code:
#include "udf.h"
#include "dpm.h"

DEFINE_EXECUTE_AT_END(get_dpm_conc)
{
  Domain *d = Get_Domain(1);

  Injection *I;
  Particle *p;

  Injection *Ilist = Get_dpm_injections();
 
  cell_t c;
  Thread *t;

  loop(I, Ilist)
    {
      loop(p,I->p)
		{
		  c = P_CELL(p);
		  t = P_CELL_THREAD(p);  
		  C_UDMI(c, t, 0) += P_N(p) * P_MASS(p)/C_VOLUME(c, t);
		}
    }
}
And for Residence Time:
(make sure to define pointer* p based on previous UDFs)
Code:
(P_TIME(p) - p->time_of_birth)  /* its in the dpm_types header file*/
haghasa is offline   Reply With Quote

Old   June 20, 2018, 00:51
Default
  #3
New Member
 
Li Xiaoying
Join Date: Jun 2018
Posts: 8
Rep Power: 8
Lxy2018 is on a distinguished road
Hi haghase,
Thanks for your reply.
In a paper,I found a formula to calculate the concentration.

C=M*sum(dt (i,j))/Vj
where _M is the number flow rate of each trajectory, V is the volume of a computational cell for use in concentration calculations, dt is the particle residence time, and subscript (i,j) represents the ith trajectory and the jth cell.

so based on your code,I try to write the UDF using the formula,but i don't if it's correct.
Thanks!
#include "udf.h"
#include "dpm.h"

Domain *domain

enum
{
* Concentration
* NUM_OF_USED_UDM

};

int UDM_checked=0;
viod reset_UDM_s(void);

int* check_for_UDM(void)
{
* Thread*t;
* if(UDM_checked)
* return UDM_checked;

* thread_loop_c(t,domain)
** {
**** if(FLUID_THREAD_P(t))
**** if(NULLP(THREAD_STORAGE(t,SV_UDM_I)))
**** return 0;
*** };

** UDM_checked=1;
** reset_UDM_s();
** return UDM_checked;
};

void
reset_UDM_s(void)
{

** Thread*t;
** cell_t c;
** int i;
**
** if(!check_for_UDM())
** return;
**
** Message("Resetting User Defined Memory...\n");

** thread_loop_c(t,domain)
** {
***** if(NNULLP(THREAD_STORAGE(t,SV_UDM_I)))
******* {
********** begin_c_loop(c,t)
*********** {
************** for(i=0;i<NUM_OF_USED_UDM;i++)
************** C_UDMI(c,t,i)=0.;
************ }
*********** end_c_loop(c,t)
******** }
****** else
******** {
*********** Message("Skipping CELL thread no.%d..\n",THREAD_ID(t))
********* }
*** }
***** Message("---Done.\n");
}


DEFINE_DPM_SCALAR_UPDATE(Concentration,cell,thread ,initialize,p)

{
*
* Domain *d=Get_Domain(1);

* real V;
* real M;
* real T;

* Injection *I
* Tracked_Particle *p;

* Injection *Ilist=Get_dpm_injection();

* Thread *t;
* cell_t c;
* int initialize;

** thread_loop_c(t,domain)
* {
*** begin_c_loop(c,t)
*** {
****** loop(I,Ilist)
******** {
************ loop(p,p->p)
************ {
*************
*************** V=C_VOLUME(c,t);
*************** M=P_MASS(p);
*************** T=P_TIME(p)-P_TIME0(p);
*************** C_UDMI(c,t,i)+=M*T/V
************* }
********** }
**** }
**** end_c_loop(c,t)
** }
}

Last edited by Lxy2018; June 20, 2018 at 23:30.
Lxy2018 is offline   Reply With Quote

Old   June 21, 2018, 07:20
Default
  #4
Senior Member
 
Join Date: Sep 2017
Posts: 246
Rep Power: 12
obscureed is on a distinguished road
Hi Lxy2018,

It could be useful to take a step back and consider the bigger picture: The flow model can be steady or transient, and the particle tracking can be steady or unsteady. All four combinations are possible (though, for me, steady flow and unsteady DPM is an unfamiliar one).

There are fundamental differences between steady DPM and unsteady DPM. In steady DPM, when each parcel is released, it is followed from its injection point to its eventual end point (which can be "escape" at an inlet, or "trap" at a wall, or "incomplete" when reaching the maximum number, for example). So, parcels only exist during those bursts of tracking. If you look for parcels at any other moment (for example, DEFINE_ON_DEMAND or DEFINE_ADJUST), there will be none. A parcel represents some fraction of the total mass flowrate released in that injection: each parcel is representative of a certain mass flowrate of particles, in [kg/s] -- look at TP_FLOW_RATE(tp).

In unsteady DPM, each parcel advances in timestepping. When the timestepping stops, parcels are still there, each in a specific fluid cell. (A parcel not in a fluid cell should presumably have died somehow.) A parcel represents some fraction of the injection mass flowrate integrated over a timestep during injection -- so each parcel actually represents a mass of particles, in [kg], or the equivalent number of particles [not necessarily integer] -- look at TP_N(tp).

I mention this distinction because it makes a fundamental difference to when/where you can get information about parcels, and what information you should be looking for. I think your efforts so far have been heading towards unsteady DPM -- is that correct? (But in that case, is it correct to use the formula that you quote from a paper? -- you need to work this out for yourself.)

By the way, in either case, the mass flowrate or number in a parcel may need to be adjusted by a factor of TP_STOCHASTIC_NTRIES(p) if you are using multiple stochastic tries in the turbulent dispersion model of DPM. I don't know why the parcels aren't diluted by this factor at the start, but they aren't.

You may also need to consider what happens when the particles in a parcel change after injection -- for example, losing mass by evaporation; changes due to reaction; breakup etc. I can't offer guidance on all these cases, so the advice has to be to do some very careful test cases that check that the total amounts make sense.

I hope this helps. Good luck!
Ed
yezhonghua likes this.
obscureed is offline   Reply With Quote

Old   June 21, 2018, 07:22
Default
  #5
Senior Member
 
Join Date: Sep 2017
Posts: 246
Rep Power: 12
obscureed is on a distinguished road
Taking a further step back, if you activate "Interaction with Continuous Phase" and re-run, then Fluent automatically calculates DPM Mass Concentration in all fluid cells.
obscureed is offline   Reply With Quote

Old   June 21, 2018, 07:49
Default
  #6
Senior Member
 
Join Date: Sep 2017
Posts: 246
Rep Power: 12
obscureed is on a distinguished road
And now getting into detail:

Please compile and debug your UDF before posting it. Your current code has several typing errors etc that you can and should remove for yourself.

If you wrap the code in your posts with "CODE ... \CODE" tabs (in square brackets), then the indentation spaces will be displayed. The # button in the editor automates this. Adding your own indentation with asterisks is just confusing.

There was a change sometime around Fluent version 17, where the distinction between Tracked_Particle *tp and Particle *p was emphasised. The distinction is rather technical, but the summary is that Tracked_Particle is the normal data structure that UDFs interact with, and so we look up TP_MASS(tp) etc. If you are not using the latest version of Fluent, I advise you to update. We should all start using the recent syntax.

TP_TIME0(tp) is the time when a Tracked_Particle *tp entered the cell that it currently inhabits. (There are also other quantities such as TP_MASS0 etc). The parcel may then take multiple timesteps, and each one will involve a call to any UDFs of type DEFINE_DPM_SCALAR_UPDATE that are actively hooked in. Therefore, you should not do cell-by-cell accumulation in this kind of UDF -- multiple particle timesteps will cause multiple accumulations and double-counting. If you are planning to add parcel effects to cells during the tracking of parcels, you should consider using DEFINE_DPM_SOURCE, which is called when the tp is about to the leave a cell (for example, to enter another).

But then (back to the big picture about steady or unsteady DPM tracking), do you really want to add parcel effects to cells during the tracking of parcels? This is a good plan (probably the only plan) for steady tracking. For unsteady tracking, you might want to calculate the overall concentration only occasionally. For this purpose, the templates provided by Haghasa are a very useful starting-point.

Good luck!
Ed
obscureed is offline   Reply With Quote

Old   June 23, 2018, 11:44
Default
  #7
Member
 
yun
Join Date: Jul 2015
Posts: 37
Rep Power: 11
gush is on a distinguished road
hi i am currently also dealing with similar problem. i think the code is something like below (more or less). i say so because i compared the results of the code itself and fluent (interaction with continuous phase option) but they are not quite same. can anyone also try this and share comments please? thanks in advance!





#include "udf.h"

/*initialize the user defined memory (UDM) for all cells*/

DEFINE_ON_DEMAND(Zero_UDM)
{
Domain *domain;
cell_t c;
Thread *t;

domain=Get_Domain(1);

thread_loop_c(t,domain)
{
begin_c_loop(c,t)
{
C_UDMI(c,t,0) = 0.0;
}
end_c_loop(c,t)
}
Message("\nUser Define memory is now initialized!\n");
}


real dt;
DEFINE_DPM_SCALAR_UPDATE(Part_Con,c,t,initialize,p )
{
Set_User_Memory_Name(0,"UDM0: PSI_C");

dt = (P_TIME(p) - P_TIME0(p));
C_UDMI(c,t,0) += P_FLOW_RATE(p)*dt/C_VOLUME(c,t);
}
gush is offline   Reply With Quote

Old   June 23, 2018, 18:33
Default
  #8
Senior Member
 
Join Date: Sep 2017
Posts: 246
Rep Power: 12
obscureed is on a distinguished road
Hi Gush,

First thing: please see my earlier comment that DEFINE_DPM_SCALAR_UPDATE is definitely not a good plan here. DEFINE_DPM_SOURCE is much better, at least for steady DPM tracking.

What version of Fluent are you using? I'd always advise updating unless you have a good reason not to.

Good luck!
Ed
obscureed is offline   Reply With Quote

Old   June 23, 2018, 19:07
Default
  #9
Member
 
yun
Join Date: Jul 2015
Posts: 37
Rep Power: 11
gush is on a distinguished road
Quote:
Originally Posted by obscureed View Post
Hi Gush,

First thing: please see my earlier comment that DEFINE_DPM_SCALAR_UPDATE is definitely not a good plan here. DEFINE_DPM_SOURCE is much better, at least for steady DPM tracking.

What version of Fluent are you using? I'd always advise updating unless you have a good reason not to.

Good luck!
Ed

hi ed!


thanks for the reply. i am using 16.0.


so you advice to use DEFINE_DPM_SOURCE for this? should i also revise the rest of the code? what do you think?



actually it seems working somehow, but there is something wrong with it! maybe because of the reason you say?!
gush is offline   Reply With Quote

Old   July 17, 2018, 23:38
Default
  #10
New Member
 
Li Xiaoying
Join Date: Jun 2018
Posts: 8
Rep Power: 8
Lxy2018 is on a distinguished road
Quote:
Originally Posted by haghasa View Post
Compile and use this UDF:

Code:
#include "udf.h"
DEFINE_ON_DEMAND(loop_over_injections_particles)
{
	Domain *domain = Get_Domain(1);

        Injection *I;
        Particle *p;

	Injection *Ilist = Get_dpm_injections();  /* get the name of injections and store them in the Ilist */

	loop(I, Ilist)
	{
                loop(p, I->p)
                {
                /* do whatever you want with that particle */
                }
	}
}
For example, you want to calculate the concentration at the end of calculation:
(make sure to add one UDMI)

Code:
#include "udf.h"
#include "dpm.h"

DEFINE_EXECUTE_AT_END(get_dpm_conc)
{
  Domain *d = Get_Domain(1);

  Injection *I;
  Particle *p;

  Injection *Ilist = Get_dpm_injections();
 
  cell_t c;
  Thread *t;

  loop(I, Ilist)
    {
      loop(p,I->p)
		{
		  c = P_CELL(p);
		  t = P_CELL_THREAD(p);  
		  C_UDMI(c, t, 0) += P_N(p) * P_MASS(p)/C_VOLUME(c, t);
		}
    }
}
And for Residence Time:
(make sure to define pointer* p based on previous UDFs)
Code:
(P_TIME(p) - p->time_of_birth)  /* its in the dpm_types header file*/
Hi gush!
I tried to use your code to calculate the concentration ,but under the steady condition using steady particle tracking,I found the value of the contour of concentration is 0 when I clicked "Graphics->particle Tracks->track". So I added "Message" in your code,and the TUI didn't display the content of the "Message".
I'm traping into the problem,please help me.
Thanks!
Lxy2018 is offline   Reply With Quote

Old   July 17, 2018, 23:55
Default
  #11
New Member
 
Li Xiaoying
Join Date: Jun 2018
Posts: 8
Rep Power: 8
Lxy2018 is on a distinguished road
Quote:
Originally Posted by obscureed View Post
And now getting into detail:

Please compile and debug your UDF before posting it. Your current code has several typing errors etc that you can and should remove for yourself.

If you wrap the code in your posts with "CODE ... \CODE" tabs (in square brackets), then the indentation spaces will be displayed. The # button in the editor automates this. Adding your own indentation with asterisks is just confusing.

There was a change sometime around Fluent version 17, where the distinction between Tracked_Particle *tp and Particle *p was emphasised. The distinction is rather technical, but the summary is that Tracked_Particle is the normal data structure that UDFs interact with, and so we look up TP_MASS(tp) etc. If you are not using the latest version of Fluent, I advise you to update. We should all start using the recent syntax.

TP_TIME0(tp) is the time when a Tracked_Particle *tp entered the cell that it currently inhabits. (There are also other quantities such as TP_MASS0 etc). The parcel may then take multiple timesteps, and each one will involve a call to any UDFs of type DEFINE_DPM_SCALAR_UPDATE that are actively hooked in. Therefore, you should not do cell-by-cell accumulation in this kind of UDF -- multiple particle timesteps will cause multiple accumulations and double-counting. If you are planning to add parcel effects to cells during the tracking of parcels, you should consider using DEFINE_DPM_SOURCE, which is called when the tp is about to the leave a cell (for example, to enter another).

But then (back to the big picture about steady or unsteady DPM tracking), do you really want to add parcel effects to cells during the tracking of parcels? This is a good plan (probably the only plan) for steady tracking. For unsteady tracking, you might want to calculate the overall concentration only occasionally. For this purpose, the templates provided by Haghasa are a very useful starting-point.

Good luck!
Ed

Hi Ed!
thanks for your reply!
After reading your message,I think I need to calculate concentration in steady and unsteady condition,respectively.Under the steady condition,I tend to use steady particle tracking.so the formula I found in a paper doesn't suit this case.but it could be used in the unsteady condition with steady particle tracking.Now I have a question.when I use unsteady calculation with steady particle tracking,how do I identify that particle is being calculated?
Thanks
Lxy2018 is offline   Reply With Quote

Old   November 5, 2018, 13:44
Default
  #12
New Member
 
IIT DELHI
Join Date: Nov 2018
Posts: 1
Rep Power: 0
Nitesh_Sahu is on a distinguished road
I am having a problem can somebody help out

Macro - P_INIT_LF is not recognised in UDF for initial liquid fraction in Ansys-19 and the dpm header files also contain only Macro - P_INIT_LMF but what this signifies is not mentioned anywhere can someone help me with this its urgent!!!!
Nitesh_Sahu is offline   Reply With Quote

Old   May 17, 2020, 10:31
Default
  #13
New Member
 
Join Date: Sep 2010
Location: Wuhan, China
Posts: 23
Rep Power: 16
qin chunqiu is on a distinguished road
Quote:
Originally Posted by haghasa View Post
Compile and use this UDF:

Code:
#include "udf.h"
DEFINE_ON_DEMAND(loop_over_injections_particles)
{
	Domain *domain = Get_Domain(1);

        Injection *I;
        Particle *p;

	Injection *Ilist = Get_dpm_injections();  /* get the name of injections and store them in the Ilist */

	loop(I, Ilist)
	{
                loop(p, I->p)
                {
                /* do whatever you want with that particle */
                }
	}
}
For example, you want to calculate the concentration at the end of calculation:
(make sure to add one UDMI)

Code:
#include "udf.h"
#include "dpm.h"

DEFINE_EXECUTE_AT_END(get_dpm_conc)
{
  Domain *d = Get_Domain(1);

  Injection *I;
  Particle *p;

  Injection *Ilist = Get_dpm_injections();
 
  cell_t c;
  Thread *t;

  loop(I, Ilist)
    {
      loop(p,I->p)
		{
		  c = P_CELL(p);
		  t = P_CELL_THREAD(p);  
		  C_UDMI(c, t, 0) += P_N(p) * P_MASS(p)/C_VOLUME(c, t);
		}
    }
}
And for Residence Time:
(make sure to define pointer* p based on previous UDFs)
Code:
(P_TIME(p) - p->time_of_birth)  /* its in the dpm_types header file*/
The P_TIME(p)-p->time_of_birth may present the time from the releasing to current. While the PSI_C method need the residence time of a certain particle in a given cell. This could be get by P_TIME(p)-P_TIME0(p).
The problem I am facing is that when using the P_TIME(p)-p->time_of_birth, the compile is right but the result is not so good, on the other hand, when using the P_TIME(p)-P_TIME0(p), the complining is wrong with words "xxx state xxxx".
qin chunqiu is offline   Reply With Quote

Reply

Tags
udf dpm


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
mesh file for flow over a circular cylinder Ardalan Main CFD Forum 7 December 15, 2020 14:06
[Helyx OS] Helyx-OS (GUI for SnappyHexMesh elvis OpenFOAM Community Contributions 210 January 30, 2017 19:57
Water subcooled boiling Attesz CFX 7 January 5, 2013 04:32
UDF for linear PTT model implementation dpitz Fluent UDF and Scheme Programming 1 February 4, 2011 11:08
UDF for Heat Exchanger model francois louw FLUENT 2 July 16, 2010 03:21


All times are GMT -4. The time now is 15:20.